moneygo/internal/store/db/accounts.go

134 lines
3.3 KiB
Go

package db
import (
"errors"
"github.com/aclindsa/moneygo/internal/models"
"github.com/aclindsa/moneygo/internal/store"
)
func (tx *Tx) GetAccount(accountid int64, userid int64) (*models.Account, error) {
var account models.Account
err := tx.SelectOne(&account, "SELECT * from accounts where UserId=? AND AccountId=?", userid, accountid)
if err != nil {
return nil, err
}
return &account, nil
}
func (tx *Tx) GetAccounts(userid int64) (*[]*models.Account, error) {
var accounts []*models.Account
_, err := tx.Select(&accounts, "SELECT * from accounts where UserId=?", userid)
if err != nil {
return nil, err
}
return &accounts, nil
}
func (tx *Tx) FindMatchingAccounts(account *models.Account) (*[]*models.Account, error) {
var accounts []*models.Account
_, err := tx.Select(&accounts, "SELECT * from accounts where UserId=? AND SecurityId=? AND Type=? AND Name=? AND ParentAccountId=? ORDER BY AccountId ASC", account.UserId, account.SecurityId, account.Type, account.Name, account.ParentAccountId)
if err != nil {
return nil, err
}
return &accounts, nil
}
func (tx *Tx) insertUpdateAccount(account *models.Account, insert bool) error {
found := make(map[int64]bool)
if !insert {
found[account.AccountId] = true
}
parentid := account.ParentAccountId
depth := 0
for parentid != -1 {
depth += 1
if depth > 100 {
return store.TooMuchNestingError{}
}
var a models.Account
err := tx.SelectOne(&a, "SELECT * from accounts where AccountId=?", parentid)
if err != nil {
return store.ParentAccountMissingError{}
}
// Insertion by itself can never result in circular dependencies
if insert {
break
}
found[parentid] = true
parentid = a.ParentAccountId
if _, ok := found[parentid]; ok {
return store.CircularAccountsError{}
}
}
if insert {
err := tx.Insert(account)
if err != nil {
return err
}
} else {
oldacct, err := tx.GetAccount(account.AccountId, account.UserId)
if err != nil {
return err
}
account.AccountVersion = oldacct.AccountVersion + 1
count, err := tx.Update(account)
if err != nil {
return err
}
if count != 1 {
return errors.New("Updated more than one account")
}
}
return nil
}
func (tx *Tx) InsertAccount(account *models.Account) error {
return tx.insertUpdateAccount(account, true)
}
func (tx *Tx) UpdateAccount(account *models.Account) error {
return tx.insertUpdateAccount(account, false)
}
func (tx *Tx) DeleteAccount(account *models.Account) error {
if account.ParentAccountId != -1 {
// Re-parent splits to this account's parent account if this account isn't a root account
_, err := tx.Exec("UPDATE splits SET AccountId=? WHERE AccountId=?", account.ParentAccountId, account.AccountId)
if err != nil {
return err
}
} else {
// Delete splits if this account is a root account
_, err := tx.Exec("DELETE FROM splits WHERE AccountId=?", account.AccountId)
if err != nil {
return err
}
}
// Re-parent child accounts to this account's parent account
_, err := tx.Exec("UPDATE accounts SET ParentAccountId=? WHERE ParentAccountId=?", account.ParentAccountId, account.AccountId)
if err != nil {
return err
}
count, err := tx.Delete(account)
if err != nil {
return err
}
if count != 1 {
return errors.New("Was going to delete more than one account")
}
return nil
}