Add database schema versioning & migration skeleton (#382)
This commit is contained in:
parent
30f8b77c25
commit
7c71a68da5
@ -6,6 +6,7 @@ package data
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/owncast/owncast/config"
|
"github.com/owncast/owncast/config"
|
||||||
@ -13,13 +14,17 @@ import (
|
|||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
schemaVersion = 0
|
||||||
|
)
|
||||||
|
|
||||||
var _db *sql.DB
|
var _db *sql.DB
|
||||||
|
|
||||||
func GetDatabase() *sql.DB {
|
func GetDatabase() *sql.DB {
|
||||||
return _db
|
return _db
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetupPersistence() {
|
func SetupPersistence() error {
|
||||||
file := config.Config.DatabaseFilePath
|
file := config.Config.DatabaseFilePath
|
||||||
|
|
||||||
// Create empty DB file if it doesn't exist.
|
// Create empty DB file if it doesn't exist.
|
||||||
@ -32,6 +37,66 @@ func SetupPersistence() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sqliteDatabase, _ := sql.Open("sqlite3", file)
|
db, err := sql.Open("sqlite3", file)
|
||||||
_db = sqliteDatabase
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := db.Exec(`CREATE TABLE IF NOT EXISTS config (
|
||||||
|
"key" string NOT NULL PRIMARY KEY,
|
||||||
|
"value" TEXT
|
||||||
|
);`); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var version int
|
||||||
|
err = db.QueryRow("SELECT value FROM config WHERE key='version'").
|
||||||
|
Scan(&version)
|
||||||
|
if err != nil {
|
||||||
|
if err != sql.ErrNoRows {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// fresh database: initialize it with the current schema version
|
||||||
|
_, err := db.Exec("INSERT INTO config(key, value) VALUES(?, ?)", "version", schemaVersion)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
version = schemaVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
// is database from a newer Owncast version?
|
||||||
|
if version > schemaVersion {
|
||||||
|
return fmt.Errorf("incompatible database version %d (versions up to %d are supported)",
|
||||||
|
version, schemaVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
// is database schema outdated?
|
||||||
|
if version < schemaVersion {
|
||||||
|
if err := migrateDatabase(db, version, schemaVersion); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_db = db
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func migrateDatabase(db *sql.DB, from, to int) error {
|
||||||
|
log.Printf("Migrating database from version %d to %d\n", from, to)
|
||||||
|
for v := from; v < to; v++ {
|
||||||
|
switch v {
|
||||||
|
case 0:
|
||||||
|
log.Printf("Migration step from %d to %d\n", v, v+1)
|
||||||
|
default:
|
||||||
|
panic("missing database migration step")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := db.Exec("UPDATE config SET value = ? WHERE key = ?", to, "version")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
5
main.go
5
main.go
@ -63,7 +63,10 @@ func main() {
|
|||||||
|
|
||||||
go metrics.Start()
|
go metrics.Start()
|
||||||
|
|
||||||
data.SetupPersistence()
|
err := data.SetupPersistence()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln("failed to open database", err)
|
||||||
|
}
|
||||||
|
|
||||||
// starts the core
|
// starts the core
|
||||||
if err := core.Start(); err != nil {
|
if err := core.Start(); err != nil {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user