package db import ( "database/sql" "time" ) // PathTraceSessionRow is one persisted Path Tracer session blob. type PathTraceSessionRow struct { ID string CreatedAt time.Time Payload []byte } // UpsertPathTraceSession stores or replaces a session JSON blob. func (d *Database) UpsertPathTraceSession(id string, createdAt time.Time, payload []byte) error { _, err := d.Exec( `INSERT INTO pathtrace_sessions (id, created_at, payload) VALUES (?, ?, ?) ON CONFLICT(id) DO UPDATE SET created_at = excluded.created_at, payload = excluded.payload`, id, createdAt.UTC().Format(time.RFC3339Nano), payload, ) return err } // ListPathTraceSessions returns all session rows ordered by age. func (d *Database) ListPathTraceSessions() ([]PathTraceSessionRow, error) { rows, err := d.Query(`SELECT id, created_at, payload FROM pathtrace_sessions ORDER BY created_at ASC`) if err != nil { return nil, err } defer rows.Close() var out []PathTraceSessionRow for rows.Next() { var row PathTraceSessionRow var created string if err := rows.Scan(&row.ID, &created, &row.Payload); err != nil { return nil, err } row.CreatedAt, _ = time.Parse(time.RFC3339Nano, created) if row.CreatedAt.IsZero() { row.CreatedAt, _ = time.Parse("2006-01-02 15:04:05", created) } out = append(out, row) } return out, rows.Err() } // DeletePathTraceSession removes one session row. func (d *Database) DeletePathTraceSession(id string) error { _, err := d.Exec(`DELETE FROM pathtrace_sessions WHERE id = ?`, id) return err } // DeleteExpiredPathTraceSessions removes rows older than cutoff. func (d *Database) DeleteExpiredPathTraceSessions(cutoff time.Time) (int64, error) { res, err := d.Exec(`DELETE FROM pathtrace_sessions WHERE created_at < ?`, cutoff.UTC().Format(time.RFC3339Nano)) if err != nil { return 0, err } return res.RowsAffected() } // PathTraceSessionCount returns how many session rows exist. func (d *Database) PathTraceSessionCount() (int, error) { var n int err := d.QueryRow(`SELECT COUNT(*) FROM pathtrace_sessions`).Scan(&n) if err == sql.ErrNoRows { return 0, nil } return n, err }