package qso import ( "context" "database/sql" "path/filepath" "testing" "time" _ "modernc.org/sqlite" ) // OrderedIDs against a real SQLite file, with qso_date stored the way the repo // actually writes it. // // The first version scanned that column straight into a time.Time. It compiles, // it reads correctly, and it fails at run time — the column holds a formatted // STRING. The error was swallowed into "the column will be empty", which is // exactly what shipped: a column that was always blank. func TestOrderedIDsAgainstRealSQLite(t *testing.T) { conn, err := sql.Open("sqlite", "file:"+filepath.Join(t.TempDir(), "t.db")) if err != nil { t.Fatal(err) } t.Cleanup(func() { conn.Close() }) if _, err := conn.Exec(`CREATE TABLE qso ( id INTEGER PRIMARY KEY AUTOINCREMENT, callsign TEXT NOT NULL, qso_date TEXT NOT NULL )`); err != nil { t.Fatal(err) } // Inserted NEWEST first, so the ids run opposite to the dates — what an // imported ADIF produces, and the whole reason the id is not the number. for _, row := range []struct { call string at time.Time }{ {"NEWEST", time.Date(2026, 8, 13, 10, 0, 0, 0, time.UTC)}, {"MIDDLE", time.Date(2020, 1, 1, 10, 0, 0, 0, time.UTC)}, {"OLDEST", time.Date(1999, 5, 5, 10, 0, 0, 0, time.UTC)}, } { if _, err := conn.Exec(`INSERT INTO qso (callsign, qso_date) VALUES (?, ?)`, row.call, row.at.UTC().Format(isoMillis)); err != nil { t.Fatal(err) } } ids, newest, err := NewRepo(conn).OrderedIDs(context.Background()) if err != nil { t.Fatalf("OrderedIDs: %v — this is the failure that emptied the column", err) } if len(ids) != 3 { t.Fatalf("got %d ids, want 3", len(ids)) } // Rows 1,2,3 were inserted newest→oldest, so chronological order is 3,2,1. if ids[0] != 3 || ids[1] != 2 || ids[2] != 1 { t.Errorf("order = %v, want the oldest contact first (3,2,1)", ids) } if newest.Year() != 2026 { t.Errorf("newest = %v, want the 2026 contact", newest) } }