diff --git a/src/db/schema.go b/src/db/schema.go new file mode 100644 index 0000000..a55d77d --- /dev/null +++ b/src/db/schema.go @@ -0,0 +1,40 @@ +package db + +import ( + "context" + "fmt" + "strings" + "time" +) + +func InitializeSchema(ctx context.Context, k string, mods []string) error { + if err := Exec(ctx, fmt.Sprintf(`CREATE TABLE IF NOT EXISTS "database_version.%s" (v NUMBER, t TIMESTAMP)`, k)); err != nil { + return fmt.Errorf(`failed to create "database_version.%s" table: %w`, k, err) + } + + type DatabaseVersion struct { + V int `json:"v"` + T time.Time `json:"t"` + } + vs, err := Query[DatabaseVersion](ctx, fmt.Sprintf(`SELECT v, t FROM "database_version.%s" ORDER BY v DESC LIMIT 1`, k)) + if err != nil { + return err + } + var v DatabaseVersion + if len(vs) > 0 { + v = vs[0] + } + + mods = append([]string{""}, mods...) + for i := v.V + 1; i < len(mods); i++ { + q := mods[i] + q = strings.TrimSpace(q) + q = strings.TrimSuffix(q, ";") + q = fmt.Sprintf(`BEGIN; %s; INSERT INTO "database_version.%s" (v, t) VALUES (?, ?); COMMIT;`, q, k) + if err := Exec(ctx, q, i, time.Now()); err != nil { + return fmt.Errorf("[%s][%d] failed mod %s: %w", k, i, mods[i], err) + } + } + + return nil +} diff --git a/src/feeds/db.go b/src/feeds/db.go index 7bab751..3be1226 100644 --- a/src/feeds/db.go +++ b/src/feeds/db.go @@ -2,10 +2,8 @@ package feeds import ( "context" - "fmt" "io" "show-rss/src/db" - "strings" "time" "github.com/google/uuid" @@ -203,24 +201,7 @@ func getEntry(ctx context.Context, id string) (Entry, error) { } func initDB(ctx context.Context) error { - if err := db.Exec(ctx, `CREATE TABLE IF NOT EXISTS database_version (v NUMBER, t TIMESTAMP)`); err != nil { - return fmt.Errorf("failed to create database_version table: %w", err) - } - - type DatabaseVersion struct { - V int `json:"v"` - T time.Time `json:"t"` - } - vs, err := db.Query[DatabaseVersion](ctx, `SELECT v, t FROM database_version ORDER BY v DESC LIMIT 1`) - if err != nil { - return err - } - var v DatabaseVersion - if len(vs) > 0 { - v = vs[0] - } - - mods := []string{ + return db.InitializeSchema(ctx, "feeds", []string{ `CREATE TABLE "feed.entries" ( id TEXT PRIMARY KEY NOT NULL, created_at TIMESTAMP NOT NULL, @@ -247,17 +228,5 @@ func initDB(ctx context.Context) error { executed_at TIMESTAMP, FOREIGN KEY (entries_id, versions_created_at) REFERENCES "feed.versions" (entries_id, created_at) )`, - } - mods = append([]string{""}, mods...) - for i := v.V + 1; i < len(mods); i++ { - q := mods[i] - q = strings.TrimSpace(q) - q = strings.TrimSuffix(q, ";") - q = fmt.Sprintf("BEGIN; %s; INSERT INTO database_version (v, t) VALUES (?, ?); COMMIT;", q) - if err := db.Exec(ctx, q, i, time.Now()); err != nil { - return fmt.Errorf("[%d] failed mod %s: %w", i, mods[i], err) - } - } - - return nil + }) }