Files
aitrade/pkg/db/balances.go
T
kaedwen ea141eb012
Build and Push Docker Image / build-and-push (push) Failing after 1m41s
initial
2026-07-02 20:09:44 +02:00

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
}