func (s *postgresStore) UpdateExpense(e *models.Expense, userIDs []int64) error { if e.ID == 0 { return models.ErrStructNotSaved } eas, err := e.Assign(userIDs) if err != nil { return errors.Annotate(err, "Could not assign expense") } tx, err := s.db.Beginx() if err != nil { return errors.Annotate(err, "Could not create transaction") } stmt, err := tx.PrepareNamed(deleteExpenseAssignmentsStr) if err != nil { _ = tx.Rollback() return errors.Annotate(err, "Error preparing delete expense assignments statement") } r, err := stmt.Exec(e) if err != nil { _ = tx.Rollback() return errors.Annotate(err, "Error deleting expense assignments") } n, _ := r.RowsAffected() if n == 0 { _ = tx.Rollback() return errors.New("expense does not have any associated assignments") } stmt, err = tx.PrepareNamed(updateExpenseStr) if err != nil { _ = tx.Rollback() return errors.Annotate(err, "Error preparing update expense statement") } r, err = stmt.Exec(e) if err != nil { _ = tx.Rollback() return errors.Annotate(err, "Error updating expense") } err = s.insertExpenseAssignments(eas, tx) if err != nil { _ = tx.Rollback() return errors.Trace(err) } // updated expense and created new assignments err = tx.Commit() if err != nil { return errors.Annotate(err, "error committing expense update") } e.Assignments = eas return nil }
func (s *postgresStore) ExpenseByID(id int64) (*models.Expense, error) { e := models.Expense{ ID: id, } tx, err := s.db.Beginx() if err != nil { return nil, errors.Annotate(err, "could not create transaction") } stmt, err := tx.PrepareNamed(expenseByIDStr) if err != nil { _ = tx.Rollback() return nil, errors.Annotate(err, "could not create expense by ID statement") } err = stmt.Get(&e, e) if err != nil { _ = tx.Rollback() return nil, errors.Annotate(err, "could not get expense by id") } var eas []*models.ExpenseAssignment stmt, err = tx.PrepareNamed(assingmentsByExpenseStr) if err != nil { _ = tx.Rollback() return nil, errors.Annotate(err, "could not prepare assignments by expense statement") } err = stmt.Select(&eas, e) if err != nil { _ = tx.Rollback() return nil, errors.Annotate(err, "could not get assignments for expense") } err = tx.Commit() if err != nil { return nil, errors.Annotate(err, "could not commit") } e.Assignments = eas return &e, nil }
func (s *postgresStore) InsertExpense(e *models.Expense, userIDs []int64) error { // Assign expense and commit everything to the db within the same transaction if e.ID != 0 { return models.ErrAlreadySaved } tx, err := s.db.Beginx() if err != nil { return errors.Annotate(err, "Could not create transaction") } stmt, err := tx.PrepareNamed(insertExpeseStr) if err != nil { _ = tx.Rollback() return errors.Annotate(err, "Error preparing insert expense statement") } err = stmt.Get(e, e) if err != nil { _ = tx.Rollback() return errors.Annotate(err, "Error inserting expense") } eas, err := e.Assign(userIDs) if err != nil { _ = tx.Rollback() return errors.Annotate(err, "Error assigning expense") } err = s.insertExpenseAssignments(eas, tx) if err != nil { _ = tx.Rollback() return errors.Trace(err) } // Sucessfully inserted expense and assignments. err = tx.Commit() if err != nil { return errors.Annotate(err, "Error committing to database") } e.Assignments = eas return nil }
func (s *postgresStore) DeleteExpense(e *models.Expense) error { r, err := s.deleteExpenseStmt.Exec(e) // Delete expense deletes all associated assignments due to CASCADE if err != nil { return errors.Annotatef(err, "Could not delete expense with ID=%d", e.ID) } n, _ := r.RowsAffected() if n == 0 { return errors.New("Expense does not exist") } e.ID = 0 return nil }