Move balance calculations into DBs

This commit is contained in:
Aaron Lindsay 2017-12-12 20:17:39 -05:00
parent a357d38eee
commit 0372f0488f
3 changed files with 33 additions and 55 deletions

View File

@ -6,7 +6,6 @@ import (
"github.com/aclindsa/moneygo/internal/models" "github.com/aclindsa/moneygo/internal/models"
"github.com/aclindsa/moneygo/internal/store" "github.com/aclindsa/moneygo/internal/store"
"github.com/yuin/gopher-lua" "github.com/yuin/gopher-lua"
"math/big"
"strings" "strings"
) )
@ -147,14 +146,6 @@ func luaAccount__index(L *lua.LState) int {
return 1 return 1
} }
func balanceFromSplits(splits *[]*models.Split) *big.Rat {
var balance big.Rat
for _, s := range *splits {
balance.Add(&balance, &s.Amount.Rat)
}
return &balance
}
func luaAccountBalance(L *lua.LState) int { func luaAccountBalance(L *lua.LState) int {
a := luaCheckAccount(L, 1) a := luaCheckAccount(L, 1)
@ -176,23 +167,22 @@ func luaAccountBalance(L *lua.LState) int {
panic("SecurityId not in lua security_map") panic("SecurityId not in lua security_map")
} }
date := luaWeakCheckTime(L, 2) date := luaWeakCheckTime(L, 2)
var splits *[]*models.Split var balance *models.Amount
if date != nil { if date != nil {
end := luaWeakCheckTime(L, 3) end := luaWeakCheckTime(L, 3)
if end != nil { if end != nil {
splits, err = tx.GetAccountSplitsDateRange(user, a.AccountId, date, end) balance, err = tx.GetAccountBalanceDateRange(user, a.AccountId, date, end)
} else { } else {
splits, err = tx.GetAccountSplitsDate(user, a.AccountId, date) balance, err = tx.GetAccountBalanceDate(user, a.AccountId, date)
} }
} else { } else {
splits, err = tx.GetAccountSplits(user, a.AccountId) balance, err = tx.GetAccountBalance(user, a.AccountId)
} }
if err != nil { if err != nil {
panic("Failed to fetch splits for account:" + err.Error()) panic("Failed to fetch balance for account:" + err.Error())
} }
rat := balanceFromSplits(splits)
b := &Balance{ b := &Balance{
Amount: models.Amount{*rat}, Amount: *balance,
Security: security, Security: security,
} }

View File

@ -305,53 +305,41 @@ func (tx *Tx) DeleteTransaction(t *models.Transaction, user *models.User) error
return nil return nil
} }
func (tx *Tx) GetAccountSplits(user *models.User, accountid int64) (*[]*models.Split, error) {
var modelsplits []*models.Split
var splits []*Split
sql := "SELECT DISTINCT splits.* FROM splits INNER JOIN transactions ON transactions.TransactionId = splits.TransactionId WHERE splits.AccountId=? AND transactions.UserId=?"
_, err := tx.Select(&splits, sql, accountid, user.UserId)
if err != nil {
return nil, err
}
for _, s := range splits {
modelsplits = append(modelsplits, s.Split())
}
return &modelsplits, nil
}
// Assumes accountid is valid and is owned by the current user // Assumes accountid is valid and is owned by the current user
func (tx *Tx) GetAccountSplitsDate(user *models.User, accountid int64, date *time.Time) (*[]*models.Split, error) { func (tx *Tx) getAccountBalance(xtrasql string, args ...interface{}) (*models.Amount, error) {
var modelsplits []*models.Split var balance models.Amount
var splits []*Split
sql := "SELECT DISTINCT splits.* FROM splits INNER JOIN transactions ON transactions.TransactionId = splits.TransactionId WHERE splits.AccountId=? AND transactions.UserId=? AND transactions.Date < ?" sql := "FROM splits INNER JOIN transactions ON transactions.TransactionId = splits.TransactionId WHERE splits.AccountId=? AND transactions.UserId=?" + xtrasql
_, err := tx.Select(&splits, sql, accountid, user.UserId, date) count, err := tx.SelectInt("SELECT splits.SplitId "+sql+" LIMIT 1", args...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if count > 0 {
type bal struct {
Whole, Fractional int64
}
var b bal
err := tx.SelectOne(&b, "SELECT sum(splits.WholeAmount) AS Whole, sum(splits.FractionalAmount) AS Fractional "+sql, args...)
if err != nil {
return nil, err
}
for _, s := range splits { balance.FromParts(b.Whole, b.Fractional, MaxPrecision)
modelsplits = append(modelsplits, s.Split())
} }
return &modelsplits, nil
return &balance, nil
} }
func (tx *Tx) GetAccountSplitsDateRange(user *models.User, accountid int64, begin, end *time.Time) (*[]*models.Split, error) { func (tx *Tx) GetAccountBalance(user *models.User, accountid int64) (*models.Amount, error) {
var modelsplits []*models.Split return tx.getAccountBalance("", accountid, user.UserId)
var splits []*Split }
sql := "SELECT DISTINCT splits.* FROM splits INNER JOIN transactions ON transactions.TransactionId = splits.TransactionId WHERE splits.AccountId=? AND transactions.UserId=? AND transactions.Date >= ? AND transactions.Date < ?" func (tx *Tx) GetAccountBalanceDate(user *models.User, accountid int64, date *time.Time) (*models.Amount, error) {
_, err := tx.Select(&splits, sql, accountid, user.UserId, begin, end) return tx.getAccountBalance(" AND transactions.date < ?", accountid, user.UserId, date)
if err != nil { }
return nil, err
}
for _, s := range splits { func (tx *Tx) GetAccountBalanceDateRange(user *models.User, accountid int64, begin, end *time.Time) (*models.Amount, error) {
modelsplits = append(modelsplits, s.Split()) return tx.getAccountBalance(" AND transactions.date >= ? AND transactions.Date < ?", accountid, user.UserId, begin, end)
}
return &modelsplits, nil
} }
func (tx *Tx) transactionsBalanceDifference(accountid int64, transactions []*models.Transaction) (*big.Rat, error) { func (tx *Tx) transactionsBalanceDifference(accountid int64, transactions []*models.Transaction) (*big.Rat, error) {

View File

@ -89,9 +89,9 @@ type TransactionStore interface {
GetTransactions(userid int64) (*[]*models.Transaction, error) GetTransactions(userid int64) (*[]*models.Transaction, error)
UpdateTransaction(t *models.Transaction, user *models.User) error UpdateTransaction(t *models.Transaction, user *models.User) error
DeleteTransaction(t *models.Transaction, user *models.User) error DeleteTransaction(t *models.Transaction, user *models.User) error
GetAccountSplits(user *models.User, accountid int64) (*[]*models.Split, error) GetAccountBalance(user *models.User, accountid int64) (*models.Amount, error)
GetAccountSplitsDate(user *models.User, accountid int64, date *time.Time) (*[]*models.Split, error) GetAccountBalanceDate(user *models.User, accountid int64, date *time.Time) (*models.Amount, error)
GetAccountSplitsDateRange(user *models.User, accountid int64, begin, end *time.Time) (*[]*models.Split, error) GetAccountBalanceDateRange(user *models.User, accountid int64, begin, end *time.Time) (*models.Amount, error)
GetAccountTransactions(user *models.User, accountid int64, sort string, page uint64, limit uint64) (*models.AccountTransactionsList, error) GetAccountTransactions(user *models.User, accountid int64, sort string, page uint64, limit uint64) (*models.AccountTransactionsList, error)
} }