164 lines
5.9 KiB
Go
164 lines
5.9 KiB
Go
package sqlite
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
type ImportRun struct {
|
|
RunID string
|
|
HostID string
|
|
Mode string
|
|
AccessMode string
|
|
SubscriptionUsersJSON string
|
|
SubscriptionDays int
|
|
ProbeAPIKey string
|
|
State string
|
|
TotalItems int
|
|
CompletedItems int
|
|
ActiveItems int
|
|
DegradedItems int
|
|
BrokenItems int
|
|
WarningItems int
|
|
StartedAt string
|
|
UpdatedAt string
|
|
FinishedAt string
|
|
}
|
|
|
|
type ImportRunsRepo struct {
|
|
db execQuerier
|
|
}
|
|
|
|
func newImportRunsRepo(db execQuerier) *ImportRunsRepo {
|
|
return &ImportRunsRepo{db: db}
|
|
}
|
|
|
|
func (r *ImportRunsRepo) Create(ctx context.Context, run ImportRun) error {
|
|
runID := strings.TrimSpace(run.RunID)
|
|
hostID := strings.TrimSpace(run.HostID)
|
|
mode := strings.TrimSpace(run.Mode)
|
|
accessMode := strings.TrimSpace(run.AccessMode)
|
|
subscriptionUsersJSON := defaultJSON(run.SubscriptionUsersJSON, "[]")
|
|
probeAPIKey := strings.TrimSpace(run.ProbeAPIKey)
|
|
state := strings.TrimSpace(run.State)
|
|
|
|
switch {
|
|
case runID == "":
|
|
return fmt.Errorf("run_id is required")
|
|
case hostID == "":
|
|
return fmt.Errorf("host_id is required")
|
|
case mode == "":
|
|
return fmt.Errorf("mode is required")
|
|
case accessMode == "":
|
|
return fmt.Errorf("access_mode is required")
|
|
case state == "":
|
|
return fmt.Errorf("state is required")
|
|
}
|
|
|
|
if _, err := r.db.ExecContext(ctx, `INSERT INTO import_runs (run_id, host_id, mode, access_mode, subscription_users_json, subscription_days, probe_api_key, state, total_items, completed_items, active_items, degraded_items, broken_items, warning_items) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
runID, hostID, mode, accessMode, subscriptionUsersJSON, run.SubscriptionDays, probeAPIKey, state, run.TotalItems, run.CompletedItems, run.ActiveItems, run.DegradedItems, run.BrokenItems, run.WarningItems); err != nil {
|
|
return fmt.Errorf("insert import run %q: %w", runID, err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (r *ImportRunsRepo) Update(ctx context.Context, run ImportRun) error {
|
|
runID := strings.TrimSpace(run.RunID)
|
|
hostID := strings.TrimSpace(run.HostID)
|
|
mode := strings.TrimSpace(run.Mode)
|
|
accessMode := strings.TrimSpace(run.AccessMode)
|
|
subscriptionUsersJSON := defaultJSON(run.SubscriptionUsersJSON, "[]")
|
|
probeAPIKey := strings.TrimSpace(run.ProbeAPIKey)
|
|
state := strings.TrimSpace(run.State)
|
|
finishedAt := strings.TrimSpace(run.FinishedAt)
|
|
|
|
switch {
|
|
case runID == "":
|
|
return fmt.Errorf("run_id is required")
|
|
case hostID == "":
|
|
return fmt.Errorf("host_id is required")
|
|
case mode == "":
|
|
return fmt.Errorf("mode is required")
|
|
case accessMode == "":
|
|
return fmt.Errorf("access_mode is required")
|
|
case state == "":
|
|
return fmt.Errorf("state is required")
|
|
}
|
|
|
|
if _, err := r.db.ExecContext(ctx, `UPDATE import_runs
|
|
SET host_id = ?, mode = ?, access_mode = ?, subscription_users_json = ?, subscription_days = ?, probe_api_key = ?, state = ?, total_items = ?, completed_items = ?, active_items = ?, degraded_items = ?, broken_items = ?, warning_items = ?, finished_at = ?, updated_at = CURRENT_TIMESTAMP
|
|
WHERE run_id = ?`,
|
|
hostID, mode, accessMode, subscriptionUsersJSON, run.SubscriptionDays, probeAPIKey, state, run.TotalItems, run.CompletedItems, run.ActiveItems, run.DegradedItems, run.BrokenItems, run.WarningItems, nullableString(finishedAt), runID); err != nil {
|
|
return fmt.Errorf("update import run %q: %w", runID, err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (r *ImportRunsRepo) GetByRunID(ctx context.Context, runID string) (ImportRun, error) {
|
|
runID = strings.TrimSpace(runID)
|
|
if runID == "" {
|
|
return ImportRun{}, fmt.Errorf("run_id is required")
|
|
}
|
|
|
|
var run ImportRun
|
|
if err := r.db.QueryRowContext(ctx, `SELECT run_id, host_id, mode, access_mode, subscription_users_json, subscription_days, COALESCE(probe_api_key, ''), state, total_items, completed_items, active_items, degraded_items, broken_items, warning_items, started_at, updated_at, COALESCE(finished_at, '') FROM import_runs WHERE run_id = ?`, runID).
|
|
Scan(&run.RunID, &run.HostID, &run.Mode, &run.AccessMode, &run.SubscriptionUsersJSON, &run.SubscriptionDays, &run.ProbeAPIKey, &run.State, &run.TotalItems, &run.CompletedItems, &run.ActiveItems, &run.DegradedItems, &run.BrokenItems, &run.WarningItems, &run.StartedAt, &run.UpdatedAt, &run.FinishedAt); err != nil {
|
|
return ImportRun{}, err
|
|
}
|
|
return run, nil
|
|
}
|
|
|
|
func (r *ImportRunsRepo) List(ctx context.Context, limit int) ([]ImportRun, error) {
|
|
if limit <= 0 {
|
|
limit = 50
|
|
}
|
|
|
|
rows, err := r.db.QueryContext(ctx, `SELECT run_id, host_id, mode, access_mode, subscription_users_json, subscription_days, COALESCE(probe_api_key, ''), state, total_items, completed_items, active_items, degraded_items, broken_items, warning_items, started_at, updated_at, COALESCE(finished_at, '') FROM import_runs ORDER BY started_at DESC LIMIT ?`, limit)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("list import runs: %w", err)
|
|
}
|
|
defer rows.Close()
|
|
|
|
runs := make([]ImportRun, 0)
|
|
for rows.Next() {
|
|
var run ImportRun
|
|
if err := rows.Scan(&run.RunID, &run.HostID, &run.Mode, &run.AccessMode, &run.SubscriptionUsersJSON, &run.SubscriptionDays, &run.ProbeAPIKey, &run.State, &run.TotalItems, &run.CompletedItems, &run.ActiveItems, &run.DegradedItems, &run.BrokenItems, &run.WarningItems, &run.StartedAt, &run.UpdatedAt, &run.FinishedAt); err != nil {
|
|
return nil, fmt.Errorf("scan import run: %w", err)
|
|
}
|
|
runs = append(runs, run)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, fmt.Errorf("iterate import runs: %w", err)
|
|
}
|
|
return runs, nil
|
|
}
|
|
|
|
type sqlNullInt64 struct {
|
|
Int64 int64
|
|
Valid bool
|
|
}
|
|
|
|
func (n sqlNullInt64) ptr() *int64 {
|
|
if !n.Valid {
|
|
return nil
|
|
}
|
|
value := n.Int64
|
|
return &value
|
|
}
|
|
|
|
func nullableString(value string) any {
|
|
if strings.TrimSpace(value) == "" {
|
|
return nil
|
|
}
|
|
return value
|
|
}
|
|
|
|
func defaultJSON(value, fallback string) string {
|
|
value = strings.TrimSpace(value)
|
|
if value == "" {
|
|
return fallback
|
|
}
|
|
return value
|
|
}
|