Files
spend-sparrow/db/account.go

135 lines
3.2 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 Account interface {
Insert(userId uuid.UUID, account *types.Account) error
Update(userId uuid.UUID, account *types.Account) error
GetAll(userId uuid.UUID) ([]*types.Account, error)
Get(userId uuid.UUID, id uuid.UUID) (*types.Account, error)
Delete(userId uuid.UUID, id uuid.UUID) error
}
type AccountSqlite struct {
db *sqlx.DB
}
func NewAccountSqlite(db *sqlx.DB) *AccountSqlite {
return &AccountSqlite{db: db}
}
func (db AccountSqlite) Insert(userId uuid.UUID, account *types.Account) error {
_, err := db.db.Exec(`
INSERT INTO account (id, user_id, name, current_balance, oink_balance, created_at, created_by)
VALUES (?,?,?,?,?,?,?)`, account.Id, userId, account.Name, 0, 0, account.CreatedAt, account.CreatedBy)
if err != nil {
log.Error("account Insert: %v", err)
return types.ErrInternal
}
return nil
}
func (db AccountSqlite) Update(userId uuid.UUID, account *types.Account) error {
r, err := db.db.Exec(`
UPDATE account
SET
name = ?,
current_balance = ?,
last_transaction = ?,
oink_balance = ?,
updated_at = ?,
updated_by = ?
WHERE id = ?
AND user_id = ?`, account.Name, account.CurrentBalance, account.LastTransaction, account.OinkBalance, account.UpdatedAt, account.UpdatedBy, account.Id, userId)
if err != nil {
log.Error("account Update: %v", err)
return types.ErrInternal
}
rows, err := r.RowsAffected()
if err != nil {
log.Error("account Update: %v", err)
return types.ErrInternal
}
if rows == 0 {
log.Info("account Update: not found")
return ErrNotFound
}
return nil
}
func (db AccountSqlite) GetAll(userId uuid.UUID) ([]*types.Account, error) {
accounts := make([]*types.Account, 0)
err := db.db.Select(&accounts, `
SELECT
id, user_id, name,
current_balance, last_transaction, oink_balance,
created_at, created_by, updated_at, updated_by
FROM account
WHERE user_id = ?
ORDER BY name`, userId)
if err != nil {
log.Error("account GetAll: %v", err)
return nil, types.ErrInternal
}
return accounts, nil
}
func (db AccountSqlite) Get(userId uuid.UUID, id uuid.UUID) (*types.Account, error) {
account := &types.Account{}
err := db.db.Get(account, `
SELECT
id, user_id, name,
current_balance, last_transaction, oink_balance,
created_at, created_by, updated_at, updated_by
FROM account
WHERE user_id = ?
AND id = ?`, userId, id)
if err != nil {
if err == sql.ErrNoRows {
return nil, ErrNotFound
}
log.Error("account Get: %v", err)
return nil, types.ErrInternal
}
return account, nil
}
func (db AccountSqlite) Delete(userId uuid.UUID, id uuid.UUID) error {
res, err := db.db.Exec("DELETE FROM account WHERE id = ? and user_id = ?", id, userId)
if err != nil {
log.Error("account Delete: %v", err)
return types.ErrInternal
}
rows, err := res.RowsAffected()
if err != nil {
log.Error("account Delete: %v", err)
return types.ErrInternal
}
if rows == 0 {
log.Info("account Delete: not found")
return ErrNotFound
}
return nil
}