package main import ( // External "github.com/jmoiron/sqlx" _ "github.com/lib/pq" // Standard "embed" "errors" "fmt" "log" "strconv" ) var ( dbConn string db *sqlx.DB //go:embed sql/* embedded embed.FS ) func dbInit() (err error) {// {{{ dbConn = fmt.Sprintf( "host=%s port=%d user=%s password=%s dbname=%s sslmode=disable", config.Database.Host, config.Database.Port, config.Database.Username, config.Database.Password, config.Database.Name, ) log.Printf( "\x1b[32mNotes\x1b[0m Connecting to database %s:%d\n", config.Database.Host, config.Database.Port, ) if db, err = sqlx.Connect("postgres", dbConn); err != nil { return } if err = dbVerifyInternals(); err != nil { return } err = dbUpdate() return }// }}} func dbVerifyInternals() (err error) {// {{{ var rows *sqlx.Rows if rows, err = db.Queryx( `SELECT EXISTS ( SELECT FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE n.nspname = '_internal' AND c.relname = 'db' )`, ); err != nil { return } defer rows.Close() var exists bool rows.Next() if err = rows.Scan(&exists); err != nil { return } if !exists { log.Printf("\x1b[32mNotes\x1b[0m Creating _internal.db\n") if _, err = db.Exec(` CREATE SCHEMA "_internal"; CREATE TABLE "_internal".db ( "key" varchar NOT NULL, value varchar NULL, CONSTRAINT db_pk PRIMARY KEY (key) ); INSERT INTO _internal.db("key", "value") VALUES('schema', '0'); `, ); err != nil { return } } return }// }}} func dbUpdate() (err error) {// {{{ /* Current schema revision is read from database. * Used to iterate through the embedded SQL updates * up to the DB_SCHEMA version currently compiled * program is made for. */ var rows *sqlx.Rows var schemaStr string var schema int rows, err = db.Queryx(`SELECT value FROM _internal.db WHERE "key"='schema'`) if err != nil { return } defer rows.Close() if !rows.Next() { return errors.New("Table _interval.db missing schema row") } if err = rows.Scan(&schemaStr); err != nil { return } // Run updates schema, err = strconv.Atoi(schemaStr) if err != nil { return err } for i := (schema+1); i <= DB_SCHEMA; i++ { log.Printf("\x1b[32mNotes\x1b[0m Upgrading SQL schema to revision %d\n", i) sql, _ := embedded.ReadFile( fmt.Sprintf("sql/%04d.sql", i), ) _, err = db.Exec(string(sql)) if err != nil { return } _, err = db.Exec(`UPDATE _internal.db SET "value"=$1 WHERE "key"='schema'`, i) if err != nil { return } } return }// }}} // vim: foldmethod=marker