114 lines
2.5 KiB
Go
114 lines
2.5 KiB
Go
package db
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/pheinrich/aitrade/pkg/model"
|
|
)
|
|
|
|
type BalanceRepository struct {
|
|
db Database
|
|
}
|
|
|
|
func NewBalanceRepository(db Database) *BalanceRepository {
|
|
return &BalanceRepository{db: db}
|
|
}
|
|
|
|
func (r *BalanceRepository) Create(ctx context.Context, balance *model.Balance) error {
|
|
query := `
|
|
INSERT INTO balances (timestamp, total_value, cash_balance, buying_power, unrealized_pnl, realized_pnl)
|
|
VALUES (?, ?, ?, ?, ?, ?)
|
|
`
|
|
|
|
result, err := r.db.ExecContext(ctx, query,
|
|
balance.Timestamp,
|
|
balance.TotalValue,
|
|
balance.CashBalance,
|
|
balance.BuyingPower,
|
|
balance.UnrealizedPnL,
|
|
balance.RealizedPnL,
|
|
)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to insert balance: %w", err)
|
|
}
|
|
|
|
id, err := result.LastInsertId()
|
|
if err != nil {
|
|
return fmt.Errorf("failed to get last insert id: %w", err)
|
|
}
|
|
|
|
balance.ID = id
|
|
return nil
|
|
}
|
|
|
|
func (r *BalanceRepository) GetLatest(ctx context.Context) (*model.Balance, error) {
|
|
query := `
|
|
SELECT id, timestamp, total_value, cash_balance, buying_power, unrealized_pnl, realized_pnl
|
|
FROM balances
|
|
ORDER BY timestamp DESC
|
|
LIMIT 1
|
|
`
|
|
|
|
var balance model.Balance
|
|
err := r.db.QueryRowContext(ctx, query).Scan(
|
|
&balance.ID,
|
|
&balance.Timestamp,
|
|
&balance.TotalValue,
|
|
&balance.CashBalance,
|
|
&balance.BuyingPower,
|
|
&balance.UnrealizedPnL,
|
|
&balance.RealizedPnL,
|
|
)
|
|
|
|
if err == sql.ErrNoRows {
|
|
return nil, nil
|
|
}
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get latest balance: %w", err)
|
|
}
|
|
|
|
return &balance, nil
|
|
}
|
|
|
|
func (r *BalanceRepository) GetHistory(ctx context.Context, since time.Time, limit int) ([]*model.Balance, error) {
|
|
query := `
|
|
SELECT id, timestamp, total_value, cash_balance, buying_power, unrealized_pnl, realized_pnl
|
|
FROM balances
|
|
WHERE timestamp >= ?
|
|
ORDER BY timestamp DESC
|
|
LIMIT ?
|
|
`
|
|
|
|
rows, err := r.db.QueryContext(ctx, query, since, limit)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to query balance history: %w", err)
|
|
}
|
|
defer rows.Close()
|
|
|
|
var balances []*model.Balance
|
|
for rows.Next() {
|
|
var balance model.Balance
|
|
if err := rows.Scan(
|
|
&balance.ID,
|
|
&balance.Timestamp,
|
|
&balance.TotalValue,
|
|
&balance.CashBalance,
|
|
&balance.BuyingPower,
|
|
&balance.UnrealizedPnL,
|
|
&balance.RealizedPnL,
|
|
); err != nil {
|
|
return nil, fmt.Errorf("failed to scan balance: %w", err)
|
|
}
|
|
balances = append(balances, &balance)
|
|
}
|
|
|
|
if err := rows.Err(); err != nil {
|
|
return nil, fmt.Errorf("error iterating balance rows: %w", err)
|
|
}
|
|
|
|
return balances, nil
|
|
}
|