// PostProblemSetBundle handles requests to /v2/problem_set/bundles,
// creating a new problem set.
func PostProblemSetBundle(w http.ResponseWriter, tx *sql.Tx, bundle ProblemSetBundle, render render.Render) {
	now := time.Now()

	if bundle.ProblemSet == nil {
		loggedHTTPErrorf(w, http.StatusBadRequest, "bundle must contain a problem set")
		return
	}
	set := bundle.ProblemSet
	if set.ID != 0 {
		loggedHTTPErrorf(w, http.StatusBadRequest, "a new problem set must not have an ID")
		return
	}
	if len(bundle.ProblemIDs) == 0 {
		loggedHTTPErrorf(w, http.StatusBadRequest, "a problem set must have at least one problem")
		return
	}
	if len(bundle.Weights) != len(bundle.ProblemIDs) {
		loggedHTTPErrorf(w, http.StatusBadRequest, "each problem must have exactly one associated weight")
		return
	}

	// clean up basic fields and do some checks
	if err := set.Normalize(now); err != nil {
		loggedHTTPErrorf(w, http.StatusBadRequest, "%v", err)
		return
	}

	// save the problem set object
	if err := meddler.Insert(tx, "problem_sets", set); err != nil {
		loggedHTTPErrorf(w, http.StatusInternalServerError, "db error: %v", err)
		return
	}

	// save the problem set problem list
	for i := 0; i < len(bundle.ProblemIDs); i++ {
		problemID, weight := bundle.ProblemIDs[i], bundle.Weights[i]
		if weight <= 0.0 {
			bundle.Weights[i] = 1.0
			weight = 1.0
		}
		psp := &ProblemSetProblem{
			ProblemSetID: set.ID,
			ProblemID:    problemID,
			Weight:       weight,
		}
		if err := meddler.Insert(tx, "problem_set_problems", psp); err != nil {
			loggedHTTPErrorf(w, http.StatusInternalServerError, "db error: %v", err)
			return
		}
	}

	log.Printf("problem set %s (%d) with %d problem(s) created", set.Unique, set.ID, len(bundle.ProblemIDs))

	render.JSON(http.StatusOK, bundle)
}
Beispiel #2
0
// createAccountSnapshot creates an AccountSnapshot object.
func (a *AccountFeed) createAccountSnapshot(accountId int64) (core.AccountSnapshot, error) {
	snap := &core.AccountSnapshot{}
	snap.AccountId = accountId
	snap.Created = a.created
	err := meddler.Insert(a.tx, "account_snapshot", snap)
	return *snap, err
}
Beispiel #3
0
func CreateLabel(db meddler.DB, name string) (*Label, error) {
	label := new(Label)
	label.Name = name

	err := meddler.Insert(db, "labels", label)
	return label, err
}
Beispiel #4
0
func CreateUser(db meddler.DB, name string, email string, balance int) (*User, error) {
	user := new(User)
	user.Name = name
	user.Email = email
	user.Balance = balance

	err := meddler.Insert(db, "users", user)
	return user, err
}
Beispiel #5
0
func (s *mySQLStore) CreateFeature(feature *models.Feature) error {
	feature.CreatedAt = time.Now()

	if err := meddler.Insert(s.db, "feature", feature); err != nil {
		return err
	}

	// update the feature to create all the status
	return s.UpdateFeature(feature)
}
Beispiel #6
0
// store writes the full updates into the database in a single transaction.
func (a *AccountFeed) store() error {
	for _, amt := range a.amounts {
		err := meddler.Insert(a.tx, "account_amount", &amt)
		if err != nil {
			return err
		}
	}

	for _, pos := range a.positions {
		for _, p := range pos {
			err := meddler.Insert(a.tx, "account_position", &p)
			if err != nil {
				return err
			}
		}
	}

	return nil
}
Beispiel #7
0
// Creates the expense in the db and gives it an ID
func CreateExpense(db meddler.DB, amount *MoneyAmount, label *Label, comment string, date time.Time) (*Expense, error) {
	expense := new(Expense)
	expense.Amount = amount.Int()
	expense.LabelId = label.Id
	expense.Comment = comment
	expense.Date = date.Format(DATE_FMT)

	err := meddler.Insert(db, "expenses", expense)
	return expense, err
}
Beispiel #8
0
func (db *buildstore) Create(build *model.Build, jobs ...*model.Job) error {
	var number int
	db.QueryRow(rebind(buildNumberLast), build.RepoID).Scan(&number)
	build.Number = number + 1
	build.Created = time.Now().UTC().Unix()
	build.Enqueued = build.Created
	err := meddler.Insert(db, buildTable, build)
	if err != nil {
		return err
	}
	for i, job := range jobs {
		job.BuildID = build.ID
		job.Number = i + 1
		job.Enqueued = build.Created
		err = meddler.Insert(db, jobTable, job)
		if err != nil {
			return err
		}
	}
	return nil
}
Beispiel #9
0
func (s *mySQLStore) CreateUser(user *models.User) error {
	passwordHash, err := bcrypt.GenerateFromPassword([]byte(user.Password), bcrypt.DefaultCost)
	if err != nil {
		return err
	}

	user.Password = ""
	user.PasswordHash = string(passwordHash)

	user.CreatedAt = time.Now()
	return meddler.Insert(s.db, "user", user)
}
Beispiel #10
0
// getSecurityType returns the SecurityType object, creating a database record if needed.
func (a *AccountFeed) getSecurityType(desc string) (core.SecurityType, error) {
	existing := new(core.SecurityType)
	err := meddler.QueryRow(a.tx, existing, "SELECT * FROM security_type WHERE security_type = $1", desc)
	if err != nil && err != sql.ErrNoRows {
		return *existing, err
	}

	if existing.Id != 0 {
		return *existing, nil
	}

	st := &core.SecurityType{}
	st.SecurityType = desc
	err = meddler.Insert(a.tx, "security_type", st)
	return *st, err
}
Beispiel #11
0
// getAccount returns the Account object, creating a database record if needed.
func (a *AccountFeed) getAccount(accountKey string) (core.Account, error) {
	existing := new(core.Account)
	err := meddler.QueryRow(a.tx, existing, "SELECT * FROM account WHERE account_code = $1", accountKey)
	if err != nil && err != sql.ErrNoRows {
		return *existing, err
	}

	if existing.Id != 0 {
		return *existing, nil
	}

	acct := &core.Account{}
	acct.AccountCode = accountKey
	err = meddler.Insert(a.tx, "account", acct)
	return *acct, err
}
Beispiel #12
0
// getSymbol returns the Symbol object, creating a database record if needed.
func (a *AccountFeed) getSymbol(desc string) (core.Symbol, error) {
	existing := new(core.Symbol)
	err := meddler.QueryRow(a.tx, existing, "SELECT * FROM symbol WHERE symbol = $1", desc)
	if err != nil && err != sql.ErrNoRows {
		return *existing, err
	}

	if existing.Id != 0 {
		return *existing, nil
	}

	s := &core.Symbol{}
	s.Symbol = desc
	err = meddler.Insert(a.tx, "symbol", s)
	return *s, err
}
Beispiel #13
0
// getAccountType returns the AccountType object, creating a database record if needed.
func (a *AccountFeed) getAccountType(desc string) (core.AccountType, error) {
	existing := new(core.AccountType)
	err := meddler.QueryRow(a.tx, existing, "SELECT * FROM account_type WHERE type_desc = $1", desc)
	if err != nil && err != sql.ErrNoRows {
		return *existing, err
	}

	if existing.Id != 0 {
		return *existing, nil
	}

	at := &core.AccountType{}
	at.TypeDescription = desc
	err = meddler.Insert(a.tx, "account_type", at)
	return *at, err
}
Beispiel #14
0
// getExchange returns the Exchange object, creating a database record if needed.
func (a *AccountFeed) getExchange(desc string) (core.Exchange, error) {
	existing := new(core.Exchange)
	err := meddler.QueryRow(a.tx, existing, "SELECT * FROM exchange WHERE exchange = $1", desc)
	if err != nil && err != sql.ErrNoRows {
		return *existing, err
	}

	if existing.Id != 0 {
		return *existing, nil
	}

	e := &core.Exchange{}
	e.Exchange = desc
	err = meddler.Insert(a.tx, "exchange", e)
	return *e, err
}
// Adds a transaction to the db, and updates the user's balances accordingly
func addTransaction(db meddler.DB, lender *User, debtor *User, amount int, expense *Expense) (*Transaction, error) {
	trans := new(Transaction)
	trans.LenderId = lender.Id
	trans.DebtorId = debtor.Id
	trans.Amount = amount
	trans.Date = expense.Date
	trans.ExpenseId = expense.Id

	err := meddler.Insert(db, "transactions", trans)
	if err != nil {
		return nil, err
	}

	lender.UpdateBalance(db, amount)
	debtor.UpdateBalance(db, -amount)

	return trans, nil
}
Beispiel #16
0
func (sr *SQL) Create(r *Request, src *Record) (RecordCreatedStatus, error) {
	lp, psql := sr.GetPromise(r)
	defer lp.Release()
	r.API.Logger.Debugf("CREATE GOT CONTEXT: %#v\n", psql)
	if src.Id != "" {
		return StatusFailed, errors.New("SQL does not support specifying an ID for Create() requests.") // TODO: it should
	}
	tx, err := psql.GetSQLTransaction(sr.DB)
	if err != nil {
		return StatusFailed, err
	}
	SetId(src.Attributes, src.Id)
	err = meddler.Insert(tx, sr.Table, src.Attributes)
	if err != nil {
		return StatusFailed, err
	}
	return StatusCreated, err
}
Beispiel #17
0
func doMoneyTest(t *testing.T, curr string, amt string, expectedIso int16, expectedAmount int64) {
	c := NewTestConfig(t)
	ctx, err := NewContext(c)
	if err != nil {
		t.Fatal(err)
	}
	defer ctx.Close()

	_, err = ctx.DB.Exec("CREATE TEMPORARY TABLE money_test (id BIGSERIAL PRIMARY KEY, cash monetary)")
	if err != nil {
		t.Fatal(err)
	}

	cash, err := NewMonetary(ctx.DB, curr, amt)
	if err != nil {
		if expectedIso == 0 && expectedAmount == 0 {
			return
		}
		t.Fatal(err)
	}

	m := moneyTest{0, cash}

	err = meddler.Insert(ctx.DB, "money_test", &m)
	if err != nil {
		t.Fatal(err)
	}

	m2 := moneyTest{}
	err = meddler.Load(ctx.DB, "money_test", &m2, m.Id)
	if err != nil {
		t.Fatal(err)
	}

	if m2.Cash.Iso4217Code != expectedIso {
		t.Fatal("ISO code incorrect")
	}

	if m2.Cash.Amount != expectedAmount {
		t.Fatal("Amount incorrect")
	}
}
Beispiel #18
0
// getContract returns the Contract object, creating a database record if needed.
func (a *AccountFeed) getContract(criteria core.Contract) (core.Contract, error) {
	existing := new(core.Contract)
	err := meddler.QueryRow(a.tx, existing,
		"SELECT * FROM contract WHERE ib_contract_id = $1 AND "+
			"iso_4217_code = $2 AND symbol_id = $3 AND local_symbol_id = $4 AND "+
			"security_type_id = $5 AND primary_exchange_id = $6",
		criteria.IbContractId, criteria.Iso4217Code, criteria.SymbolId,
		criteria.LocalSymbolId, criteria.SecurityTypeId, criteria.PrimaryExchangeId)
	if err != nil && err != sql.ErrNoRows {
		return *existing, err
	}

	if existing.Id != 0 {
		return *existing, nil
	}

	criteria.Created = a.created
	err = meddler.Insert(a.tx, "contract", &criteria)
	return criteria, err
}
Beispiel #19
0
// PostUser saves a User in the datastore.
func (db *Userstore) PostUser(user *model.User) error {
	user.Created = time.Now().UTC().Unix()
	user.Updated = time.Now().UTC().Unix()
	return meddler.Insert(db, userTable, user)
}
Beispiel #20
0
func (db *jobstore) Create(job *model.Job) error {
	return meddler.Insert(db, jobTable, job)
}
Beispiel #21
0
func (db *datastore) CreateUser(user *model.User) error {
	return meddler.Insert(db, userTable, user)
}
func saveProblemBundleCommon(w http.ResponseWriter, tx *sql.Tx, bundle *ProblemBundle, render render.Render) {
	now := time.Now()

	// clean up basic fields and do some checks
	problem, steps := bundle.Problem, bundle.ProblemSteps
	if err := problem.Normalize(now, steps); err != nil {
		loggedHTTPErrorf(w, http.StatusBadRequest, "%v", err)
		return
	}

	// note: unique constraint will be checked by the database

	// verify the signature
	sig := problem.ComputeSignature(Config.DaycareSecret, steps)
	if sig != bundle.ProblemSignature {
		loggedHTTPErrorf(w, http.StatusBadRequest, "problem signature does not check out: found %s but expected %s", bundle.ProblemSignature, sig)
		return
	}

	// verify all the commits
	if len(steps) != len(bundle.Commits) {
		loggedHTTPErrorf(w, http.StatusBadRequest, "problem must have exactly one commit for each problem step")
		return
	}
	if len(bundle.CommitSignatures) != len(bundle.Commits) {
		loggedHTTPErrorf(w, http.StatusBadRequest, "problem must have exactly one commit signature for each commit")
		return
	}
	for i, commit := range bundle.Commits {
		// check the commit signature
		csig := commit.ComputeSignature(Config.DaycareSecret, bundle.ProblemSignature)
		if csig != bundle.CommitSignatures[i] {
			loggedHTTPErrorf(w, http.StatusBadRequest, "commit for step %d has a bad signature", commit.Step)
			return
		}

		if commit.Step != steps[i].Step {
			loggedHTTPErrorf(w, http.StatusBadRequest, "commit for step %d says it is for step %d", steps[i].Step, commit.Step)
			return
		}

		// make sure this step passed
		if commit.Score != 1.0 || commit.ReportCard == nil || !commit.ReportCard.Passed {
			loggedHTTPErrorf(w, http.StatusBadRequest, "commit for step %d did not pass", i+1)
			return
		}
	}

	isUpdate := problem.ID != 0
	if err := meddler.Save(tx, "problems", problem); err != nil {
		loggedHTTPErrorf(w, http.StatusInternalServerError, "db error: %v", err)
		return
	}
	for _, step := range steps {
		step.ProblemID = problem.ID
		if isUpdate {
			// meddler does not understand updating rows without a single integer primary key
			raw, err := json.Marshal(step.Files)
			if err != nil {
				loggedHTTPErrorf(w, http.StatusInternalServerError, "json error: %v", err)
				return
			}
			if _, err = tx.Exec(`UPDATE problem_steps SET note=$1,instructions=$2,weight=$3,files=$4 WHERE problem_id=$5 AND step=$6`,
				step.Note, step.Instructions, step.Weight, raw, step.ProblemID, step.Step); err != nil {
				loggedHTTPErrorf(w, http.StatusInternalServerError, "db error: %v", err)
				return
			}
		} else {
			if err := meddler.Insert(tx, "problem_steps", step); err != nil {
				loggedHTTPErrorf(w, http.StatusInternalServerError, "db error: %v", err)
				return
			}
		}
	}
	if isUpdate {
		log.Printf("problem %s (%d) with %d step(s) updated", problem.Unique, problem.ID, len(steps))
	} else {
		log.Printf("problem %s (%d) with %d step(s) created", problem.Unique, problem.ID, len(steps))
	}

	render.JSON(http.StatusOK, bundle)
}
Beispiel #23
0
func (db *nodestore) Create(node *model.Node) error {
	return meddler.Insert(db, nodeTable, node)
}
Beispiel #24
0
func (db *userStore) Create(user *model.User) error {
	return meddler.Insert(db, userTable, user)
}
Beispiel #25
0
func (s *mySQLStore) createStatus(status *status) error {
	status.CreatedAt = time.Now()
	return meddler.Insert(s.db, "feature_status", status)
}
Beispiel #26
0
func (s *mySQLStore) CreateEnvironment(environment *models.Environment) error {
	environment.CreatedAt = time.Now()
	return meddler.Insert(s.db, "environment", environment)
}
Beispiel #27
0
func (db *repostore) Create(repo *model.Repo) error {
	return meddler.Insert(db, repoTable, repo)
}
Beispiel #28
0
// InsertCommand inserts a Command object into the commands table.
func (s *Store) InsertCommand(cmd *Command) error {
	return meddler.Insert(s.sqlDB, "commands", cmd)
}
Beispiel #29
0
// InsertSession inserts a Session object into the sessions table.
func (s *Store) InsertSession(sess *Session) error {
	return meddler.Insert(s.sqlDB, "sessions", sess)
}
Beispiel #30
0
// InsertUpload inserts an Upload object into the uploads table.
func (s *Store) InsertUpload(u *Upload) error {
	return meddler.Insert(s.sqlDB, "uploads", u)
}