@@ -324,6 +324,115 @@ func TestEnsureBackupDir(t *testing.T) {
324324 }
325325}
326326
327+ func TestReadSchemaVersion_AfterInitSchema (t * testing.T ) {
328+ _ , dbPath , cleanup := setupTestStore (t )
329+ defer cleanup ()
330+
331+ ver , err := ReadSchemaVersion (dbPath )
332+ if err != nil {
333+ t .Fatalf ("ReadSchemaVersion failed: %v" , err )
334+ }
335+ if ver != sqlite .SchemaVersion {
336+ t .Errorf ("expected schema version %d, got %d" , sqlite .SchemaVersion , ver )
337+ }
338+ }
339+
340+ func TestReadSchemaVersion_FreshDB (t * testing.T ) {
341+ // A fresh SQLite DB with no PRAGMA user_version set returns 0.
342+ dir := t .TempDir ()
343+ dbPath := filepath .Join (dir , "fresh.db" )
344+
345+ db , err := sql .Open ("sqlite" , dbPath )
346+ if err != nil {
347+ t .Fatalf ("failed to open fresh db: %v" , err )
348+ }
349+ // Create at least one table so the file exists on disk.
350+ if _ , err := db .Exec ("CREATE TABLE t(id INTEGER)" ); err != nil {
351+ t .Fatalf ("failed to create table: %v" , err )
352+ }
353+ _ = db .Close ()
354+
355+ ver , err := ReadSchemaVersion (dbPath )
356+ if err != nil {
357+ t .Fatalf ("ReadSchemaVersion failed: %v" , err )
358+ }
359+ if ver != 0 {
360+ t .Errorf ("expected version 0 for fresh DB, got %d" , ver )
361+ }
362+ }
363+
364+ func TestPruneOldBackups (t * testing.T ) {
365+ dir := t .TempDir ()
366+
367+ // Create 5 fake pre-migration backups with distinct timestamps.
368+ names := []string {
369+ "pre_migrate_2026-01-01_100000.db" ,
370+ "pre_migrate_2026-01-02_100000.db" ,
371+ "pre_migrate_2026-01-03_100000.db" ,
372+ "pre_migrate_2026-01-04_100000.db" ,
373+ "pre_migrate_2026-01-05_100000.db" ,
374+ }
375+ for _ , n := range names {
376+ if err := os .WriteFile (filepath .Join (dir , n ), []byte ("fake" ), 0644 ); err != nil {
377+ t .Fatalf ("failed to create %s: %v" , n , err )
378+ }
379+ }
380+
381+ // Also create a non-matching file that should NOT be pruned.
382+ if err := os .WriteFile (filepath .Join (dir , "backup_2026-01-01.json" ), []byte ("keep" ), 0644 ); err != nil {
383+ t .Fatal (err )
384+ }
385+
386+ if err := PruneOldBackups (dir , 3 ); err != nil {
387+ t .Fatalf ("PruneOldBackups failed: %v" , err )
388+ }
389+
390+ entries , err := os .ReadDir (dir )
391+ if err != nil {
392+ t .Fatal (err )
393+ }
394+
395+ var remaining []string
396+ for _ , e := range entries {
397+ remaining = append (remaining , e .Name ())
398+ }
399+
400+ // Should have 3 pre_migrate files + 1 json file = 4 total
401+ if len (remaining ) != 4 {
402+ t .Errorf ("expected 4 files remaining, got %d: %v" , len (remaining ), remaining )
403+ }
404+
405+ // The oldest two should be gone.
406+ for _ , name := range remaining {
407+ if name == names [0 ] || name == names [1 ] {
408+ t .Errorf ("old backup %s should have been pruned" , name )
409+ }
410+ }
411+ }
412+
413+ func TestPruneOldBackups_FewFiles (t * testing.T ) {
414+ dir := t .TempDir ()
415+
416+ // Only 2 backups, keep=3 — nothing should be deleted.
417+ for _ , n := range []string {"pre_migrate_2026-01-01_100000.db" , "pre_migrate_2026-01-02_100000.db" } {
418+ if err := os .WriteFile (filepath .Join (dir , n ), []byte ("fake" ), 0644 ); err != nil {
419+ t .Fatal (err )
420+ }
421+ }
422+
423+ if err := PruneOldBackups (dir , 3 ); err != nil {
424+ t .Fatalf ("PruneOldBackups failed: %v" , err )
425+ }
426+
427+ entries , err := os .ReadDir (dir )
428+ if err != nil {
429+ t .Fatal (err )
430+ }
431+ if len (entries ) != 2 {
432+ t .Errorf ("expected 2 files, got %d" , len (entries ))
433+ }
434+ }
435+
327436// jsonContains checks if a JSON string contains a given substring.
328437func jsonContains (jsonStr , substr string ) bool {
329438 return len (jsonStr ) > 0 && contains (jsonStr , substr )
0 commit comments