Files
Havline/internal/traffic/store.go
T

64 lines
1.4 KiB
Go
Raw Normal View History

2026-09-23 09:40:59 +08:00
package traffic
import (
"context"
"database/sql"
"strings"
"time"
)
type Store struct {
db *sql.DB
}
func NewStore(db *sql.DB) *Store {
return &Store{db: db}
}
func (s *Store) LoadTotals(ctx context.Context) (map[string]hostTotals, error) {
rows, err := s.db.QueryContext(ctx, `SELECT host, upload_bytes, download_bytes FROM proxy_traffic`)
if err != nil {
return nil, err
}
defer rows.Close()
out := map[string]hostTotals{}
for rows.Next() {
var host string
var up, down int64
if err := rows.Scan(&host, &up, &down); err != nil {
return nil, err
}
key := strings.ToLower(strings.TrimSpace(host))
out[key] = hostTotals{Upload: up, Download: down}
}
return out, rows.Err()
}
func (s *Store) SaveTotals(ctx context.Context, hosts map[string]hostTotals) error {
tx, err := s.db.BeginTx(ctx, nil)
if err != nil {
return err
}
for host, totals := range hosts {
_, err := tx.ExecContext(ctx, `
INSERT INTO proxy_traffic(host, upload_bytes, download_bytes, updated_at)
VALUES (?, ?, ?, ?)
ON CONFLICT(host) DO UPDATE SET
upload_bytes = excluded.upload_bytes,
download_bytes = excluded.download_bytes,
updated_at = excluded.updated_at
`, host, totals.Upload, totals.Download, time.Now().UTC().Format(time.RFC3339))
if err != nil {
_ = tx.Rollback()
return err
}
}
return tx.Commit()
}
type hostTotals struct {
Upload int64
Download int64
}