diff --git a/db.go b/db.go new file mode 100644 index 0000000..a40cea4 --- /dev/null +++ b/db.go @@ -0,0 +1,60 @@ +package main + +import ( + "database/sql" + + _ "github.com/mattn/go-sqlite3" +) + +func InitDatabase(db *sql.DB) error { + db.Exec(` + create table migrations (name text) strict; + `) + + return nil +} + +func MigrateDatabase(db *sql.DB) error { + rows, err := db.Query(` + select name from migrations; + `) + if err != nil { + return err + } + + complete := map[string]bool{} + + for rows.Next() { + var name string + err = rows.Scan(&name) + if err != nil { + return err + } + complete[name] = true + } + + if !complete["0000_initial_schema"] { + _, err = db.Exec(` + create table sources(name text) strict; + create table items( + source text not null, + id text not null, + created int not null default (unixepoch()), + active int, + title text, + author text, + body text, + link text, + time int, + primary key (source, id), + foreign key (source) references sources (name) on delete cascade + ) strict; + insert into migrations (name) values ('0000_initial_schema'); + `) + if err != nil { + return err + } + } + + return nil +} diff --git a/db_test.go b/db_test.go new file mode 100644 index 0000000..8f80e4d --- /dev/null +++ b/db_test.go @@ -0,0 +1,32 @@ +package main + +import ( + "database/sql" + "testing" + + _ "github.com/mattn/go-sqlite3" +) + +func TestMigrations(t *testing.T) { + db, err := sql.Open("sqlite3", ":memory:") + if err != nil { + t.Fatal(err) + } + defer db.Close() + + err = InitDatabase(db) + if err != nil { + t.Fatal(err) + } + err = MigrateDatabase(db) + if err != nil { + t.Fatal(err) + } + + var count int + row := db.QueryRow("select count(name) from migrations") + row.Scan(&count) + if count != 1 { + t.Fatalf("Unexpected migration count: %d", count) + } +} diff --git a/go.mod b/go.mod index 30e6e5e..404370e 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,8 @@ go 1.23.4 require github.com/spf13/cobra v1.8.1 +require github.com/mattn/go-sqlite3 v1.14.24 + require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect diff --git a/go.sum b/go.sum index 912390a..fc8e536 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM= +github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=