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:
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
Reference in New Issue
Block a user