From 939faeb8e4c8f008662b177b3675d0da3335e4c6 Mon Sep 17 00:00:00 2001 From: Jeremie Fraeys Date: Thu, 12 Mar 2026 16:38:01 -0400 Subject: [PATCH] refactor: relocate store package from cmd/tui/internal to internal Move store package to improve reusability and follow Go project conventions: - cmd/tui/internal/store/store.go -> internal/store/store.go - cmd/tui/internal/store/store_test.go -> internal/store/store_test.go This makes the store package available to other components beyond the TUI, reducing coupling and enabling future reuse by API server, CLI, or other tools. --- {cmd/tui/internal => internal}/store/store.go | 5 --- .../internal => internal}/store/store_test.go | 42 +++++++++---------- 2 files changed, 19 insertions(+), 28 deletions(-) rename {cmd/tui/internal => internal}/store/store.go (97%) rename {cmd/tui/internal => internal}/store/store_test.go (76%) diff --git a/cmd/tui/internal/store/store.go b/internal/store/store.go similarity index 97% rename from cmd/tui/internal/store/store.go rename to internal/store/store.go index 7b847e7..c1b2a01 100644 --- a/cmd/tui/internal/store/store.go +++ b/internal/store/store.go @@ -43,7 +43,6 @@ type Param struct { // Open opens the SQLite database at the given path func Open(dbPath string) (*Store, error) { - // Ensure directory exists dir := filepath.Dir(dbPath) if err := os.MkdirAll(dir, 0750); err != nil { return nil, fmt.Errorf("failed to create directory: %w", err) @@ -54,13 +53,11 @@ func Open(dbPath string) (*Store, error) { return nil, fmt.Errorf("failed to open database: %w", err) } - // Enable WAL mode for better concurrency if _, err := db.Exec("PRAGMA journal_mode=WAL;"); err != nil { _ = db.Close() return nil, fmt.Errorf("failed to enable WAL: %w", err) } - // Set synchronous mode for performance if _, err := db.Exec("PRAGMA synchronous=NORMAL;"); err != nil { _ = db.Close() return nil, fmt.Errorf("failed to set synchronous: %w", err) @@ -71,7 +68,6 @@ func Open(dbPath string) (*Store, error) { dbPath: dbPath, } - // Initialize schema if needed if err := store.initSchema(); err != nil { _ = db.Close() return nil, fmt.Errorf("failed to init schema: %w", err) @@ -83,7 +79,6 @@ func Open(dbPath string) (*Store, error) { // Close closes the database connection func (s *Store) Close() error { if s.db != nil { - // Checkpoint WAL before closing _, _ = s.db.Exec("PRAGMA wal_checkpoint(TRUNCATE);") return s.db.Close() } diff --git a/cmd/tui/internal/store/store_test.go b/internal/store/store_test.go similarity index 76% rename from cmd/tui/internal/store/store_test.go rename to internal/store/store_test.go index d481580..609509d 100644 --- a/cmd/tui/internal/store/store_test.go +++ b/internal/store/store_test.go @@ -1,30 +1,27 @@ -package store +package store_test import ( "os" "testing" + + "github.com/jfraeys/fetch_ml/internal/store" ) func TestOpen(t *testing.T) { - // Create a temporary database dbPath := "/tmp/test_fetchml.db" defer os.Remove(dbPath) defer os.Remove(dbPath + "-wal") defer os.Remove(dbPath + "-shm") - store, err := Open(dbPath) + s, err := store.Open(dbPath) if err != nil { t.Fatalf("Failed to open database: %v", err) } - defer store.Close() + defer s.Close() - if store.db == nil { + if s.DB() == nil { t.Fatal("Database connection is nil") } - - if store.dbPath != dbPath { - t.Fatalf("Expected dbPath %s, got %s", dbPath, store.dbPath) - } } func TestGetUnsyncedRuns(t *testing.T) { @@ -33,21 +30,21 @@ func TestGetUnsyncedRuns(t *testing.T) { defer os.Remove(dbPath + "-wal") defer os.Remove(dbPath + "-shm") - store, err := Open(dbPath) + s, err := store.Open(dbPath) if err != nil { t.Fatalf("Failed to open database: %v", err) } - defer store.Close() + defer s.Close() - // Insert test data - _, err = store.db.Exec(` + // Insert test data using exported DB() + _, err = s.DB().Exec(` INSERT INTO ml_experiments (experiment_id, name) VALUES ('exp1', 'Test Experiment'); `) if err != nil { t.Fatalf("Failed to insert experiment: %v", err) } - _, err = store.db.Exec(` + _, err = s.DB().Exec(` INSERT INTO ml_runs (run_id, experiment_id, name, status, synced) VALUES ('run1', 'exp1', 'Test Run', 'FINISHED', 0); `) @@ -55,8 +52,7 @@ func TestGetUnsyncedRuns(t *testing.T) { t.Fatalf("Failed to insert run: %v", err) } - // Test GetUnsyncedRuns - runs, err := store.GetUnsyncedRuns() + runs, err := s.GetUnsyncedRuns() if err != nil { t.Fatalf("Failed to get unsynced runs: %v", err) } @@ -76,21 +72,21 @@ func TestMarkRunSynced(t *testing.T) { defer os.Remove(dbPath + "-wal") defer os.Remove(dbPath + "-shm") - store, err := Open(dbPath) + s, err := store.Open(dbPath) if err != nil { t.Fatalf("Failed to open database: %v", err) } - defer store.Close() + defer s.Close() // Insert test data - _, err = store.db.Exec(` + _, err = s.DB().Exec(` INSERT INTO ml_experiments (experiment_id, name) VALUES ('exp1', 'Test Experiment'); `) if err != nil { t.Fatalf("Failed to insert experiment: %v", err) } - _, err = store.db.Exec(` + _, err = s.DB().Exec(` INSERT INTO ml_runs (run_id, experiment_id, name, status, synced) VALUES ('run1', 'exp1', 'Test Run', 'FINISHED', 0); `) @@ -99,14 +95,14 @@ func TestMarkRunSynced(t *testing.T) { } // Mark as synced - err = store.MarkRunSynced("run1") + err = s.MarkRunSynced("run1") if err != nil { t.Fatalf("Failed to mark run as synced: %v", err) } - // Verify + // Verify using exported DB() var synced int - err = store.db.QueryRow("SELECT synced FROM ml_runs WHERE run_id = 'run1'").Scan(&synced) + err = s.DB().QueryRow("SELECT synced FROM ml_runs WHERE run_id = 'run1'").Scan(&synced) if err != nil { t.Fatalf("Failed to query run: %v", err) }