Part of per-user profile isolation: profile rows are no longer a global singleton, so every read/write requires the caller's userID. This also requires scoping ListActivities, ListWorkoutKinds, UpsertActivity, CreateWorkoutKind, GetSyncState, UpdateSyncState, and ResetAllSyncedData to userID, plus updating all related tests in the store package.
37 lines
1.4 KiB
Go
37 lines
1.4 KiB
Go
package store
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
)
|
|
|
|
// SyncState tracks how far back into Garmin history a backfill has already
|
|
// reached. Since activities are immutable once recorded, this lets a repeat
|
|
// backfill skip everything already covered instead of re-fetching it.
|
|
type SyncState struct {
|
|
EarliestSyncedDate *string // "YYYY-MM-DD", nil if backfill has never run
|
|
BackfillComplete bool // true once backfill has reached the configured horizon (or Garmin's own history start)
|
|
}
|
|
|
|
// GetSyncState returns the current backfill watermark for userID.
|
|
func (db *DB) GetSyncState(ctx context.Context, userID int64) (SyncState, error) {
|
|
var s SyncState
|
|
err := db.QueryRowContext(ctx, `SELECT earliest_synced_date, backfill_complete FROM sync_state WHERE user_id = ?`, userID).
|
|
Scan(&s.EarliestSyncedDate, &s.BackfillComplete)
|
|
if err != nil {
|
|
return SyncState{}, fmt.Errorf("get sync state for user %d: %w", userID, err)
|
|
}
|
|
return s, nil
|
|
}
|
|
|
|
// UpdateSyncState records progress of a backfill run for userID.
|
|
func (db *DB) UpdateSyncState(ctx context.Context, userID int64, earliestSyncedDate string, complete bool) error {
|
|
_, err := db.ExecContext(ctx, `
|
|
UPDATE sync_state SET earliest_synced_date = ?, backfill_complete = ? WHERE user_id = ?`,
|
|
earliestSyncedDate, complete, userID)
|
|
if err != nil {
|
|
return fmt.Errorf("update sync state for user %d: %w", userID, err)
|
|
}
|
|
return nil
|
|
}
|