Пример #1
0
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
}
Пример #2
0
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

}
Пример #3
0
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
}
Пример #4
0
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
}