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.
This commit is contained in:
Jeremie Fraeys 2026-03-12 16:38:01 -04:00
parent 7ff2c6c487
commit 939faeb8e4
No known key found for this signature in database
2 changed files with 19 additions and 28 deletions

View file

@ -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()
}

View file

@ -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)
}