Files
spend-sparrow/db/transaction.go

137 lines
3.6 KiB
Go

package db
import (
"database/sql"
"spend-sparrow/log"
"spend-sparrow/types"
"github.com/google/uuid"
"github.com/jmoiron/sqlx"
)
// While it may be duplicated to check for userId in the database access, it serves as a security layer
type Transaction interface {
Insert(userId uuid.UUID, transaction *types.Transaction) error
Update(userId uuid.UUID, transaction *types.Transaction) error
GetAll(userId uuid.UUID) ([]*types.Transaction, error)
Get(userId uuid.UUID, id uuid.UUID) (*types.Transaction, error)
Delete(userId uuid.UUID, id uuid.UUID) error
}
type TransactionSqlite struct {
db *sqlx.DB
}
func NewTransactionSqlite(db *sqlx.DB) *TransactionSqlite {
return &TransactionSqlite{db: db}
}
func (db TransactionSqlite) Insert(userId uuid.UUID, transaction *types.Transaction) error {
_, err := db.db.Exec(`
INSERT INTO transaction (id, user_id, account_id, treasure_chest_id, internal, value, timestamp, note, created_at, created_by)
VALUES (?,?,?,?,?,?,?,?,?,?)`, transaction.Id, userId, transaction.AccountId, transaction.TreasureChestId, transaction.Internal, transaction.Value, transaction.Timestamp, transaction.Note, transaction.CreatedAt, transaction.CreatedBy)
if err != nil {
log.Error("transaction Insert: %v", err)
return types.ErrInternal
}
return nil
}
func (db TransactionSqlite) Update(userId uuid.UUID, transaction *types.Transaction) error {
r, err := db.db.Exec(`
UPDATE transaction
SET
account_id = ?,
treasure_chest_id = ?,
internal = ?,
value = ?,
timestamp = ?,
note = ?,
updated_at = ?,
updated_by = ?
WHERE id = ?
AND user_id = ?`, transaction.AccountId, transaction.TreasureChestId, transaction.Internal, transaction.Value, transaction.Timestamp, transaction.UpdatedBy, transaction.Id, userId)
if err != nil {
log.Error("transaction Update: %v", err)
return types.ErrInternal
}
rows, err := r.RowsAffected()
if err != nil {
log.Error("transaction Update: %v", err)
return types.ErrInternal
}
if rows == 0 {
log.Info("transaction Update: not found")
return ErrNotFound
}
return nil
}
func (db TransactionSqlite) GetAll(userId uuid.UUID) ([]*types.Transaction, error) {
transactions := make([]*types.Transaction, 0)
err := db.db.Select(&transactions, `
SELECT
id, user_id,
account_id, treasure_chest_id, internal, value, timestamp, note,
created_at, created_by, updated_at, updated_by
FROM transaction
WHERE user_id = ?
ORDER BY name`, userId)
if err != nil {
log.Error("transaction GetAll: %v", err)
return nil, types.ErrInternal
}
return transactions, nil
}
func (db TransactionSqlite) Get(userId uuid.UUID, id uuid.UUID) (*types.Transaction, error) {
transaction := &types.Transaction{}
err := db.db.Get(transaction, `
SELECT
id, user_id,
account_id, treasure_chest_id, internal, value, timestamp, note,
created_at, created_by, updated_at, updated_by
FROM transaction
WHERE user_id = ?
AND id = ?`, userId, id)
if err != nil {
if err == sql.ErrNoRows {
return nil, ErrNotFound
}
log.Error("transaction Get: %v", err)
return nil, types.ErrInternal
}
return transaction, nil
}
func (db TransactionSqlite) Delete(userId uuid.UUID, id uuid.UUID) error {
res, err := db.db.Exec("DELETE FROM transaction WHERE id = ? and user_id = ?", id, userId)
if err != nil {
log.Error("transaction Delete: %v", err)
return types.ErrInternal
}
rows, err := res.RowsAffected()
if err != nil {
log.Error("transaction Delete: %v", err)
return types.ErrInternal
}
if rows == 0 {
log.Info("transaction Delete: not found")
return ErrNotFound
}
return nil
}