package store import ( "context" "database/sql" "fmt" "strings" "time" ) type PendingPackage struct { ID int64 RepoID int64 Name string Version string Arch string Location string Checksum string ChecksumType string Size int64 CreatedAt time.Time } type PendingPackageStore interface { UpsertPending(ctx context.Context, pkgs []PendingPackage) error ListPending(ctx context.Context, repoID int64) ([]PendingPackage, error) DeletePending(ctx context.Context, ids []int64) error DeleteAllPending(ctx context.Context, repoID int64) error } type SQLitePendingPackageStore struct { db *sql.DB } func NewPendingPackageStore(db *sql.DB) *SQLitePendingPackageStore { return &SQLitePendingPackageStore{db: db} } func (s *SQLitePendingPackageStore) UpsertPending(ctx context.Context, pkgs []PendingPackage) error { for _, p := range pkgs { _, err := s.db.ExecContext(ctx, `INSERT OR IGNORE INTO pending_packages (repo_id, name, version, arch, location, checksum, checksum_type, size) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, p.RepoID, p.Name, p.Version, p.Arch, p.Location, p.Checksum, p.ChecksumType, p.Size, ) if err != nil { return err } } return nil } func (s *SQLitePendingPackageStore) ListPending(ctx context.Context, repoID int64) ([]PendingPackage, error) { rows, err := s.db.QueryContext(ctx, `SELECT id, repo_id, name, version, arch, location, checksum, checksum_type, size, created_at FROM pending_packages WHERE repo_id = ? ORDER BY created_at ASC`, repoID) if err != nil { return nil, err } defer rows.Close() var pkgs []PendingPackage for rows.Next() { var p PendingPackage if err := rows.Scan(&p.ID, &p.RepoID, &p.Name, &p.Version, &p.Arch, &p.Location, &p.Checksum, &p.ChecksumType, &p.Size, &p.CreatedAt); err != nil { return nil, err } pkgs = append(pkgs, p) } return pkgs, rows.Err() } func (s *SQLitePendingPackageStore) DeletePending(ctx context.Context, ids []int64) error { if len(ids) == 0 { return nil } placeholders := strings.Join(strings.Fields(strings.Repeat("? ", len(ids))), ", ") query := fmt.Sprintf("DELETE FROM pending_packages WHERE id IN (%s)", placeholders) args := make([]any, len(ids)) for i, id := range ids { args[i] = id } _, err := s.db.ExecContext(ctx, query, args...) return err } func (s *SQLitePendingPackageStore) DeleteAllPending(ctx context.Context, repoID int64) error { _, err := s.db.ExecContext(ctx, `DELETE FROM pending_packages WHERE repo_id = ?`, repoID) return err }