This commit is contained in:
parent
13774eec7d
commit
45fcecdc04
29 changed files with 2865 additions and 3867 deletions
|
|
@ -32,29 +32,24 @@ func NewBudgetRepository(db *sqlx.DB) BudgetRepository {
|
|||
}
|
||||
|
||||
func (r *budgetRepository) Create(budget *model.Budget, tagIDs []string) error {
|
||||
tx, err := r.db.Beginx()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
return WithTx(r.db, func(tx *sqlx.Tx) error {
|
||||
query := `INSERT INTO budgets (id, space_id, amount_cents, period, start_date, end_date, is_active, created_by, created_at, updated_at)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10);`
|
||||
if _, err := tx.Exec(query, budget.ID, budget.SpaceID, budget.AmountCents, budget.Period, budget.StartDate, budget.EndDate, budget.IsActive, budget.CreatedBy, budget.CreatedAt, budget.UpdatedAt); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
query := `INSERT INTO budgets (id, space_id, amount_cents, period, start_date, end_date, is_active, created_by, created_at, updated_at)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10);`
|
||||
_, err = tx.Exec(query, budget.ID, budget.SpaceID, budget.AmountCents, budget.Period, budget.StartDate, budget.EndDate, budget.IsActive, budget.CreatedBy, budget.CreatedAt, budget.UpdatedAt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(tagIDs) > 0 {
|
||||
tagQuery := `INSERT INTO budget_tags (budget_id, tag_id) VALUES ($1, $2);`
|
||||
for _, tagID := range tagIDs {
|
||||
if _, err := tx.Exec(tagQuery, budget.ID, tagID); err != nil {
|
||||
return err
|
||||
if len(tagIDs) > 0 {
|
||||
tagQuery := `INSERT INTO budget_tags (budget_id, tag_id) VALUES ($1, $2);`
|
||||
for _, tagID := range tagIDs {
|
||||
if _, err := tx.Exec(tagQuery, budget.ID, tagID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (r *budgetRepository) GetByID(id string) (*model.Budget, error) {
|
||||
|
|
@ -136,36 +131,37 @@ func (r *budgetRepository) GetTagsByBudgetIDs(budgetIDs []string) (map[string][]
|
|||
}
|
||||
|
||||
func (r *budgetRepository) Update(budget *model.Budget, tagIDs []string) error {
|
||||
tx, err := r.db.Beginx()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
return WithTx(r.db, func(tx *sqlx.Tx) error {
|
||||
query := `UPDATE budgets SET amount_cents = $1, period = $2, start_date = $3, end_date = $4, is_active = $5, updated_at = $6 WHERE id = $7;`
|
||||
if _, err := tx.Exec(query, budget.AmountCents, budget.Period, budget.StartDate, budget.EndDate, budget.IsActive, budget.UpdatedAt, budget.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
query := `UPDATE budgets SET amount_cents = $1, period = $2, start_date = $3, end_date = $4, is_active = $5, updated_at = $6 WHERE id = $7;`
|
||||
_, err = tx.Exec(query, budget.AmountCents, budget.Period, budget.StartDate, budget.EndDate, budget.IsActive, budget.UpdatedAt, budget.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := tx.Exec(`DELETE FROM budget_tags WHERE budget_id = $1;`, budget.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Replace tags: delete old, insert new
|
||||
if _, err := tx.Exec(`DELETE FROM budget_tags WHERE budget_id = $1;`, budget.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(tagIDs) > 0 {
|
||||
tagQuery := `INSERT INTO budget_tags (budget_id, tag_id) VALUES ($1, $2);`
|
||||
for _, tagID := range tagIDs {
|
||||
if _, err := tx.Exec(tagQuery, budget.ID, tagID); err != nil {
|
||||
return err
|
||||
if len(tagIDs) > 0 {
|
||||
tagQuery := `INSERT INTO budget_tags (budget_id, tag_id) VALUES ($1, $2);`
|
||||
for _, tagID := range tagIDs {
|
||||
if _, err := tx.Exec(tagQuery, budget.ID, tagID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (r *budgetRepository) Delete(id string) error {
|
||||
_, err := r.db.Exec(`DELETE FROM budgets WHERE id = $1;`, id)
|
||||
result, err := r.db.Exec(`DELETE FROM budgets WHERE id = $1;`, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rows, err := result.RowsAffected()
|
||||
if err == nil && rows == 0 {
|
||||
return ErrBudgetNotFound
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,43 +40,34 @@ func NewExpenseRepository(db *sqlx.DB) ExpenseRepository {
|
|||
}
|
||||
|
||||
func (r *expenseRepository) Create(expense *model.Expense, tagIDs []string, itemIDs []string) error {
|
||||
tx, err := r.db.Beginx()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
return WithTx(r.db, func(tx *sqlx.Tx) error {
|
||||
queryExpense := `INSERT INTO expenses (id, space_id, created_by, description, amount_cents, type, date, payment_method_id, recurring_expense_id, created_at, updated_at)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11);`
|
||||
_, err := tx.Exec(queryExpense, expense.ID, expense.SpaceID, expense.CreatedBy, expense.Description, expense.AmountCents, expense.Type, expense.Date, expense.PaymentMethodID, expense.RecurringExpenseID, expense.CreatedAt, expense.UpdatedAt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Insert Expense
|
||||
queryExpense := `INSERT INTO expenses (id, space_id, created_by, description, amount_cents, type, date, payment_method_id, recurring_expense_id, created_at, updated_at)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11);`
|
||||
_, err = tx.Exec(queryExpense, expense.ID, expense.SpaceID, expense.CreatedBy, expense.Description, expense.AmountCents, expense.Type, expense.Date, expense.PaymentMethodID, expense.RecurringExpenseID, expense.CreatedAt, expense.UpdatedAt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Insert Tags
|
||||
if len(tagIDs) > 0 {
|
||||
queryTags := `INSERT INTO expense_tags (expense_id, tag_id) VALUES ($1, $2);`
|
||||
for _, tagID := range tagIDs {
|
||||
_, err := tx.Exec(queryTags, expense.ID, tagID)
|
||||
if err != nil {
|
||||
return err
|
||||
if len(tagIDs) > 0 {
|
||||
queryTags := `INSERT INTO expense_tags (expense_id, tag_id) VALUES ($1, $2);`
|
||||
for _, tagID := range tagIDs {
|
||||
if _, err := tx.Exec(queryTags, expense.ID, tagID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Insert Items
|
||||
if len(itemIDs) > 0 {
|
||||
queryItems := `INSERT INTO expense_items (expense_id, item_id) VALUES ($1, $2);`
|
||||
for _, itemID := range itemIDs {
|
||||
_, err := tx.Exec(queryItems, expense.ID, itemID)
|
||||
if err != nil {
|
||||
return err
|
||||
if len(itemIDs) > 0 {
|
||||
queryItems := `INSERT INTO expense_items (expense_id, item_id) VALUES ($1, $2);`
|
||||
for _, itemID := range itemIDs {
|
||||
if _, err := tx.Exec(queryItems, expense.ID, itemID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (r *expenseRepository) GetByID(id string) (*model.Expense, error) {
|
||||
|
|
@ -223,38 +214,38 @@ func (r *expenseRepository) GetPaymentMethodsByExpenseIDs(expenseIDs []string) (
|
|||
}
|
||||
|
||||
func (r *expenseRepository) Update(expense *model.Expense, tagIDs []string) error {
|
||||
tx, err := r.db.Beginx()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
return WithTx(r.db, func(tx *sqlx.Tx) error {
|
||||
query := `UPDATE expenses SET description = $1, amount_cents = $2, type = $3, date = $4, payment_method_id = $5, updated_at = $6 WHERE id = $7;`
|
||||
if _, err := tx.Exec(query, expense.Description, expense.AmountCents, expense.Type, expense.Date, expense.PaymentMethodID, expense.UpdatedAt, expense.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
query := `UPDATE expenses SET description = $1, amount_cents = $2, type = $3, date = $4, payment_method_id = $5, updated_at = $6 WHERE id = $7;`
|
||||
_, err = tx.Exec(query, expense.Description, expense.AmountCents, expense.Type, expense.Date, expense.PaymentMethodID, expense.UpdatedAt, expense.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := tx.Exec(`DELETE FROM expense_tags WHERE expense_id = $1;`, expense.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Replace tags: delete all existing, re-insert
|
||||
_, err = tx.Exec(`DELETE FROM expense_tags WHERE expense_id = $1;`, expense.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(tagIDs) > 0 {
|
||||
insertTag := `INSERT INTO expense_tags (expense_id, tag_id) VALUES ($1, $2);`
|
||||
for _, tagID := range tagIDs {
|
||||
if _, err := tx.Exec(insertTag, expense.ID, tagID); err != nil {
|
||||
return err
|
||||
if len(tagIDs) > 0 {
|
||||
insertTag := `INSERT INTO expense_tags (expense_id, tag_id) VALUES ($1, $2);`
|
||||
for _, tagID := range tagIDs {
|
||||
if _, err := tx.Exec(insertTag, expense.ID, tagID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (r *expenseRepository) Delete(id string) error {
|
||||
_, err := r.db.Exec(`DELETE FROM expenses WHERE id = $1;`, id)
|
||||
result, err := r.db.Exec(`DELETE FROM expenses WHERE id = $1;`, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rows, err := result.RowsAffected()
|
||||
if err == nil && rows == 0 {
|
||||
return ErrExpenseNotFound
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
|||
18
internal/repository/helpers.go
Normal file
18
internal/repository/helpers.go
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
package repository
|
||||
|
||||
import "github.com/jmoiron/sqlx"
|
||||
|
||||
// WithTx runs fn inside a transaction. If fn returns an error, the transaction
|
||||
// is rolled back; otherwise it is committed.
|
||||
func WithTx(db *sqlx.DB, fn func(*sqlx.Tx) error) error {
|
||||
tx, err := db.Beginx()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
if err := fn(tx); err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.Commit()
|
||||
}
|
||||
|
|
@ -1,105 +0,0 @@
|
|||
package repository
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"git.juancwu.dev/juancwu/budgit/internal/model"
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrRecurringDepositNotFound = errors.New("recurring deposit not found")
|
||||
)
|
||||
|
||||
type RecurringDepositRepository interface {
|
||||
Create(rd *model.RecurringDeposit) error
|
||||
GetByID(id string) (*model.RecurringDeposit, error)
|
||||
GetBySpaceID(spaceID string) ([]*model.RecurringDeposit, error)
|
||||
Update(rd *model.RecurringDeposit) error
|
||||
Delete(id string) error
|
||||
SetActive(id string, active bool) error
|
||||
GetDueRecurrences(now time.Time) ([]*model.RecurringDeposit, error)
|
||||
GetDueRecurrencesForSpace(spaceID string, now time.Time) ([]*model.RecurringDeposit, error)
|
||||
UpdateNextOccurrence(id string, next time.Time) error
|
||||
Deactivate(id string) error
|
||||
}
|
||||
|
||||
type recurringDepositRepository struct {
|
||||
db *sqlx.DB
|
||||
}
|
||||
|
||||
func NewRecurringDepositRepository(db *sqlx.DB) RecurringDepositRepository {
|
||||
return &recurringDepositRepository{db: db}
|
||||
}
|
||||
|
||||
func (r *recurringDepositRepository) Create(rd *model.RecurringDeposit) error {
|
||||
query := `INSERT INTO recurring_deposits (id, space_id, account_id, amount_cents, frequency, start_date, end_date, next_occurrence, is_active, title, created_by, created_at, updated_at)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13);`
|
||||
_, err := r.db.Exec(query, rd.ID, rd.SpaceID, rd.AccountID, rd.AmountCents, rd.Frequency, rd.StartDate, rd.EndDate, rd.NextOccurrence, rd.IsActive, rd.Title, rd.CreatedBy, rd.CreatedAt, rd.UpdatedAt)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *recurringDepositRepository) GetByID(id string) (*model.RecurringDeposit, error) {
|
||||
rd := &model.RecurringDeposit{}
|
||||
query := `SELECT * FROM recurring_deposits WHERE id = $1;`
|
||||
err := r.db.Get(rd, query, id)
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, ErrRecurringDepositNotFound
|
||||
}
|
||||
return rd, err
|
||||
}
|
||||
|
||||
func (r *recurringDepositRepository) GetBySpaceID(spaceID string) ([]*model.RecurringDeposit, error) {
|
||||
var results []*model.RecurringDeposit
|
||||
query := `SELECT * FROM recurring_deposits WHERE space_id = $1 ORDER BY is_active DESC, next_occurrence ASC;`
|
||||
err := r.db.Select(&results, query, spaceID)
|
||||
return results, err
|
||||
}
|
||||
|
||||
func (r *recurringDepositRepository) Update(rd *model.RecurringDeposit) error {
|
||||
query := `UPDATE recurring_deposits SET account_id = $1, amount_cents = $2, frequency = $3, start_date = $4, end_date = $5, next_occurrence = $6, title = $7, updated_at = $8 WHERE id = $9;`
|
||||
result, err := r.db.Exec(query, rd.AccountID, rd.AmountCents, rd.Frequency, rd.StartDate, rd.EndDate, rd.NextOccurrence, rd.Title, rd.UpdatedAt, rd.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rows, err := result.RowsAffected()
|
||||
if err == nil && rows == 0 {
|
||||
return ErrRecurringDepositNotFound
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *recurringDepositRepository) Delete(id string) error {
|
||||
_, err := r.db.Exec(`DELETE FROM recurring_deposits WHERE id = $1;`, id)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *recurringDepositRepository) SetActive(id string, active bool) error {
|
||||
_, err := r.db.Exec(`UPDATE recurring_deposits SET is_active = $1, updated_at = $2 WHERE id = $3;`, active, time.Now(), id)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *recurringDepositRepository) GetDueRecurrences(now time.Time) ([]*model.RecurringDeposit, error) {
|
||||
var results []*model.RecurringDeposit
|
||||
query := `SELECT * FROM recurring_deposits WHERE is_active = true AND next_occurrence <= $1;`
|
||||
err := r.db.Select(&results, query, now)
|
||||
return results, err
|
||||
}
|
||||
|
||||
func (r *recurringDepositRepository) GetDueRecurrencesForSpace(spaceID string, now time.Time) ([]*model.RecurringDeposit, error) {
|
||||
var results []*model.RecurringDeposit
|
||||
query := `SELECT * FROM recurring_deposits WHERE is_active = true AND space_id = $1 AND next_occurrence <= $2;`
|
||||
err := r.db.Select(&results, query, spaceID, now)
|
||||
return results, err
|
||||
}
|
||||
|
||||
func (r *recurringDepositRepository) UpdateNextOccurrence(id string, next time.Time) error {
|
||||
_, err := r.db.Exec(`UPDATE recurring_deposits SET next_occurrence = $1, updated_at = $2 WHERE id = $3;`, next, time.Now(), id)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *recurringDepositRepository) Deactivate(id string) error {
|
||||
return r.SetActive(id, false)
|
||||
}
|
||||
|
|
@ -37,29 +37,24 @@ func NewRecurringExpenseRepository(db *sqlx.DB) RecurringExpenseRepository {
|
|||
}
|
||||
|
||||
func (r *recurringExpenseRepository) Create(re *model.RecurringExpense, tagIDs []string) error {
|
||||
tx, err := r.db.Beginx()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
return WithTx(r.db, func(tx *sqlx.Tx) error {
|
||||
query := `INSERT INTO recurring_expenses (id, space_id, created_by, description, amount_cents, type, payment_method_id, frequency, start_date, end_date, next_occurrence, is_active, created_at, updated_at)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14);`
|
||||
if _, err := tx.Exec(query, re.ID, re.SpaceID, re.CreatedBy, re.Description, re.AmountCents, re.Type, re.PaymentMethodID, re.Frequency, re.StartDate, re.EndDate, re.NextOccurrence, re.IsActive, re.CreatedAt, re.UpdatedAt); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
query := `INSERT INTO recurring_expenses (id, space_id, created_by, description, amount_cents, type, payment_method_id, frequency, start_date, end_date, next_occurrence, is_active, created_at, updated_at)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14);`
|
||||
_, err = tx.Exec(query, re.ID, re.SpaceID, re.CreatedBy, re.Description, re.AmountCents, re.Type, re.PaymentMethodID, re.Frequency, re.StartDate, re.EndDate, re.NextOccurrence, re.IsActive, re.CreatedAt, re.UpdatedAt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(tagIDs) > 0 {
|
||||
tagQuery := `INSERT INTO recurring_expense_tags (recurring_expense_id, tag_id) VALUES ($1, $2);`
|
||||
for _, tagID := range tagIDs {
|
||||
if _, err := tx.Exec(tagQuery, re.ID, tagID); err != nil {
|
||||
return err
|
||||
if len(tagIDs) > 0 {
|
||||
tagQuery := `INSERT INTO recurring_expense_tags (recurring_expense_id, tag_id) VALUES ($1, $2);`
|
||||
for _, tagID := range tagIDs {
|
||||
if _, err := tx.Exec(tagQuery, re.ID, tagID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (r *recurringExpenseRepository) GetByID(id string) (*model.RecurringExpense, error) {
|
||||
|
|
@ -165,37 +160,38 @@ func (r *recurringExpenseRepository) GetPaymentMethodsByRecurringExpenseIDs(ids
|
|||
}
|
||||
|
||||
func (r *recurringExpenseRepository) Update(re *model.RecurringExpense, tagIDs []string) error {
|
||||
tx, err := r.db.Beginx()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
return WithTx(r.db, func(tx *sqlx.Tx) error {
|
||||
query := `UPDATE recurring_expenses SET description = $1, amount_cents = $2, type = $3, payment_method_id = $4, frequency = $5, start_date = $6, end_date = $7, next_occurrence = $8, updated_at = $9 WHERE id = $10;`
|
||||
if _, err := tx.Exec(query, re.Description, re.AmountCents, re.Type, re.PaymentMethodID, re.Frequency, re.StartDate, re.EndDate, re.NextOccurrence, re.UpdatedAt, re.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
query := `UPDATE recurring_expenses SET description = $1, amount_cents = $2, type = $3, payment_method_id = $4, frequency = $5, start_date = $6, end_date = $7, next_occurrence = $8, updated_at = $9 WHERE id = $10;`
|
||||
_, err = tx.Exec(query, re.Description, re.AmountCents, re.Type, re.PaymentMethodID, re.Frequency, re.StartDate, re.EndDate, re.NextOccurrence, re.UpdatedAt, re.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := tx.Exec(`DELETE FROM recurring_expense_tags WHERE recurring_expense_id = $1;`, re.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = tx.Exec(`DELETE FROM recurring_expense_tags WHERE recurring_expense_id = $1;`, re.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(tagIDs) > 0 {
|
||||
tagQuery := `INSERT INTO recurring_expense_tags (recurring_expense_id, tag_id) VALUES ($1, $2);`
|
||||
for _, tagID := range tagIDs {
|
||||
if _, err := tx.Exec(tagQuery, re.ID, tagID); err != nil {
|
||||
return err
|
||||
if len(tagIDs) > 0 {
|
||||
tagQuery := `INSERT INTO recurring_expense_tags (recurring_expense_id, tag_id) VALUES ($1, $2);`
|
||||
for _, tagID := range tagIDs {
|
||||
if _, err := tx.Exec(tagQuery, re.ID, tagID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (r *recurringExpenseRepository) Delete(id string) error {
|
||||
_, err := r.db.Exec(`DELETE FROM recurring_expenses WHERE id = $1;`, id)
|
||||
result, err := r.db.Exec(`DELETE FROM recurring_expenses WHERE id = $1;`, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rows, err := result.RowsAffected()
|
||||
if err == nil && rows == 0 {
|
||||
return ErrRecurringExpenseNotFound
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue