1
0
mirror of https://github.com/aclindsa/moneygo.git synced 2025-06-13 21:48:39 -04:00

Store currency/security values/prices using big.Rat natively

This adds 'shadow' types used only by the store/db internal package whch
handle converting these types to their DB-equivalent values. This change
should allow reports to be generated significantly faster since it
allows a large portion of the computation to be shifted to the database
engines.
This commit is contained in:
2017-12-12 19:40:38 -05:00
parent 483adb5c56
commit a357d38eee
22 changed files with 695 additions and 201 deletions

View File

@ -147,18 +147,12 @@ func luaAccount__index(L *lua.LState) int {
return 1
}
func balanceFromSplits(splits *[]*models.Split) (*big.Rat, error) {
var balance, tmp big.Rat
func balanceFromSplits(splits *[]*models.Split) *big.Rat {
var balance big.Rat
for _, s := range *splits {
rat_amount, err := models.GetBigAmount(s.Amount)
if err != nil {
return nil, err
}
tmp.Add(&balance, rat_amount)
balance.Set(&tmp)
balance.Add(&balance, &s.Amount.Rat)
}
return &balance, nil
return &balance
}
func luaAccountBalance(L *lua.LState) int {
@ -196,14 +190,12 @@ func luaAccountBalance(L *lua.LState) int {
if err != nil {
panic("Failed to fetch splits for account:" + err.Error())
}
rat, err := balanceFromSplits(splits)
if err != nil {
panic("Failed to calculate balance for account:" + err.Error())
}
rat := balanceFromSplits(splits)
b := &Balance{
Amount: rat,
Amount: models.Amount{*rat},
Security: security,
}
L.Push(BalanceToLua(L, b))
return 1

View File

@ -3,12 +3,11 @@ package reports
import (
"github.com/aclindsa/moneygo/internal/models"
"github.com/yuin/gopher-lua"
"math/big"
)
type Balance struct {
Security *models.Security
Amount *big.Rat
Amount models.Amount
}
const luaBalanceTypeName = "balance"
@ -66,10 +65,8 @@ func luaGetBalanceOperands(L *lua.LState, m int, n int) (*Balance, *Balance) {
} else if bm != nil {
nn := L.CheckNumber(n)
var balance Balance
var rat big.Rat
balance.Security = bm.Security
balance.Amount = rat.SetFloat64(float64(nn))
if balance.Amount == nil {
if balance.Amount.SetFloat64(float64(nn)) == nil {
L.ArgError(n, "non-finite float invalid for operand to balance arithemetic")
return nil, nil
}
@ -77,10 +74,8 @@ func luaGetBalanceOperands(L *lua.LState, m int, n int) (*Balance, *Balance) {
} else if bn != nil {
nm := L.CheckNumber(m)
var balance Balance
var rat big.Rat
balance.Security = bn.Security
balance.Amount = rat.SetFloat64(float64(nm))
if balance.Amount == nil {
if balance.Amount.SetFloat64(float64(nm)) == nil {
L.ArgError(m, "non-finite float invalid for operand to balance arithemetic")
return nil, nil
}
@ -110,7 +105,7 @@ func luaBalance__index(L *lua.LState) int {
func luaBalance__tostring(L *lua.LState) int {
b := luaCheckBalance(L, 1)
L.Push(lua.LString(b.Security.Symbol + " " + b.Amount.FloatString(b.Security.Precision)))
L.Push(lua.LString(b.Security.Symbol + " " + b.Amount.FloatString(int(b.Security.Precision))))
return 1
}
@ -119,7 +114,7 @@ func luaBalance__eq(L *lua.LState) int {
a := luaCheckBalance(L, 1)
b := luaCheckBalance(L, 2)
L.Push(lua.LBool(a.Security.SecurityId == b.Security.SecurityId && a.Amount.Cmp(b.Amount) == 0))
L.Push(lua.LBool(a.Security.SecurityId == b.Security.SecurityId && a.Amount.Cmp(&b.Amount.Rat) == 0))
return 1
}
@ -131,7 +126,7 @@ func luaBalance__lt(L *lua.LState) int {
L.ArgError(2, "Can't compare balances with different securities")
}
L.Push(lua.LBool(a.Amount.Cmp(b.Amount) < 0))
L.Push(lua.LBool(a.Amount.Cmp(&b.Amount.Rat) < 0))
return 1
}
@ -143,7 +138,7 @@ func luaBalance__le(L *lua.LState) int {
L.ArgError(2, "Can't compare balances with different securities")
}
L.Push(lua.LBool(a.Amount.Cmp(b.Amount) <= 0))
L.Push(lua.LBool(a.Amount.Cmp(&b.Amount.Rat) <= 0))
return 1
}
@ -156,9 +151,8 @@ func luaBalance__add(L *lua.LState) int {
}
var balance Balance
var rat big.Rat
balance.Security = a.Security
balance.Amount = rat.Add(a.Amount, b.Amount)
balance.Amount.Add(&a.Amount.Rat, &b.Amount.Rat)
L.Push(BalanceToLua(L, &balance))
return 1
@ -172,9 +166,8 @@ func luaBalance__sub(L *lua.LState) int {
}
var balance Balance
var rat big.Rat
balance.Security = a.Security
balance.Amount = rat.Sub(a.Amount, b.Amount)
balance.Amount.Sub(&a.Amount.Rat, &b.Amount.Rat)
L.Push(BalanceToLua(L, &balance))
return 1
@ -188,9 +181,8 @@ func luaBalance__mul(L *lua.LState) int {
}
var balance Balance
var rat big.Rat
balance.Security = a.Security
balance.Amount = rat.Mul(a.Amount, b.Amount)
balance.Amount.Mul(&a.Amount.Rat, &b.Amount.Rat)
L.Push(BalanceToLua(L, &balance))
return 1
@ -204,9 +196,8 @@ func luaBalance__div(L *lua.LState) int {
}
var balance Balance
var rat big.Rat
balance.Security = a.Security
balance.Amount = rat.Quo(a.Amount, b.Amount)
balance.Amount.Quo(&a.Amount.Rat, &b.Amount.Rat)
L.Push(BalanceToLua(L, &balance))
return 1
@ -216,9 +207,8 @@ func luaBalance__unm(L *lua.LState) int {
b := luaCheckBalance(L, 1)
var balance Balance
var rat big.Rat
balance.Security = b.Security
balance.Amount = rat.Neg(b.Amount)
balance.Amount.Neg(&b.Amount.Rat)
L.Push(BalanceToLua(L, &balance))
return 1

View File

@ -60,11 +60,7 @@ func luaPrice__index(L *lua.LState) int {
}
L.Push(SecurityToLua(L, c))
case "Value", "value":
amt, err := models.GetBigAmount(p.Value)
if err != nil {
panic(err)
}
float, _ := amt.Float64()
float, _ := p.Value.Float64()
L.Push(lua.LNumber(float))
default:
L.ArgError(2, "unexpected price attribute: "+field)
@ -86,7 +82,7 @@ func luaPrice__tostring(L *lua.LState) int {
panic("Price's currency or security not found for user")
}
L.Push(lua.LString(p.Value + " " + c.Symbol + " (" + s.Symbol + ")"))
L.Push(lua.LString(p.Value.String() + " " + c.Symbol + " (" + s.Symbol + ")"))
return 1
}