package postgres import ( "context" "fmt" "github.com/jackc/pgx/v5/pgxpool" "cryptoHermes/internal/entity" ) type LongShortRatioRepo struct { pool *pgxpool.Pool } func NewLongShortRatioRepo(pool *pgxpool.Pool) *LongShortRatioRepo { return &LongShortRatioRepo{pool: pool} } const lsUpsertSQL = ` INSERT INTO long_short_ratio ( source, symbol, period, ratio_type, timestamp, long_short_ratio, long_value, short_value ) VALUES ( $1, $2, $3, $4, $5, $6, NULLIF($7, '')::NUMERIC, NULLIF($8, '')::NUMERIC ) ON CONFLICT (source, symbol, period, ratio_type, timestamp) DO UPDATE SET long_short_ratio = EXCLUDED.long_short_ratio, long_value = EXCLUDED.long_value, short_value = EXCLUDED.short_value ` func (r *LongShortRatioRepo) UpsertMany(ctx context.Context, items []entity.LongShortRatio) error { if len(items) == 0 { return nil } tx, err := r.pool.Begin(ctx) if err != nil { return err } defer tx.Rollback(ctx) for _, ls := range items { if ls.LongShortRatio == "" || ls.Timestamp == 0 { continue } if _, err := tx.Exec(ctx, lsUpsertSQL, ls.Source, ls.Symbol, ls.Period, ls.RatioType, ls.Timestamp, ls.LongShortRatio, ls.LongValue, ls.ShortValue, ); err != nil { return fmt.Errorf("upsert ls %s/%s/%s@%d: %w", ls.Symbol, ls.Period, ls.RatioType, ls.Timestamp, err) } } return tx.Commit(ctx) } const lsFindSQL = ` SELECT source, symbol, period, ratio_type, timestamp, long_short_ratio::text, COALESCE(long_value::text, ''), COALESCE(short_value::text, '') FROM long_short_ratio WHERE symbol = $1 AND period = $2 AND ratio_type = $3 ORDER BY timestamp DESC LIMIT $4 ` func (r *LongShortRatioRepo) FindRecent(ctx context.Context, symbol, period, ratioType string, limit int) ([]entity.LongShortRatio, error) { if limit <= 0 { limit = 100 } rows, err := r.pool.Query(ctx, lsFindSQL, symbol, period, ratioType, limit) if err != nil { return nil, err } defer rows.Close() out := make([]entity.LongShortRatio, 0, limit) for rows.Next() { var ls entity.LongShortRatio if err := rows.Scan(&ls.Source, &ls.Symbol, &ls.Period, &ls.RatioType, &ls.Timestamp, &ls.LongShortRatio, &ls.LongValue, &ls.ShortValue); err != nil { return nil, err } out = append(out, ls) } for i, j := 0, len(out)-1; i < j; i, j = i+1, j-1 { out[i], out[j] = out[j], out[i] } return out, rows.Err() }