package models import ( "fmt" "strconv" "time" "github.com/jmoiron/sqlx" "github.com/taosdata/alert/utils" "github.com/taosdata/alert/utils/log" ) var db *sqlx.DB func Init() error { xdb, e := sqlx.Connect("sqlite3", utils.Cfg.Database) if e == nil { db = xdb } return upgrade() } func Uninit() error { db.Close() return nil } func getStringOption(tx *sqlx.Tx, name string) (string, error) { const qs = "SELECT * FROM `option` WHERE `name`=?" var ( e error o struct { Name string `db:"name"` Value string `db:"value"` } ) if tx != nil { e = tx.Get(&o, qs, name) } else { e = db.Get(&o, qs, name) } if e != nil { return "", e } return o.Value, nil } func getIntOption(tx *sqlx.Tx, name string) (int, error) { s, e := getStringOption(tx, name) if e != nil { return 0, e } v, e := strconv.ParseInt(s, 10, 64) return int(v), e } func setOption(tx *sqlx.Tx, name string, value interface{}) error { const qs = "REPLACE INTO `option`(`name`, `value`) VALUES(?, ?);" var ( e error sv string ) switch v := value.(type) { case time.Time: sv = v.Format(time.RFC3339) default: sv = fmt.Sprint(value) } if tx != nil { _, e = tx.Exec(qs, name, sv) } else { _, e = db.Exec(qs, name, sv) } return e } var upgradeScripts = []struct { ver int stmts []string }{ { ver: 0, stmts: []string{ "CREATE TABLE `option`( `name` VARCHAR(63) PRIMARY KEY, `value` VARCHAR(255) NOT NULL) WITHOUT ROWID;", "CREATE TABLE `rule`( `name` VARCHAR(63) PRIMARY KEY, `enabled` TINYINT(1) NOT NULL, `created_at` DATETIME NOT NULL, `updated_at` DATETIME NOT NULL, `content` TEXT(65535) NOT NULL);", }, }, } func upgrade() error { const dbVersion = "database version" ver, e := getIntOption(nil, dbVersion) if e != nil { // regards all errors as schema not created ver = -1 // set ver to -1 to execute all statements } tx, e := db.Beginx() if e != nil { return e } for _, us := range upgradeScripts { if us.ver <= ver { continue } log.Info("upgrading database to version: ", us.ver) for _, s := range us.stmts { if _, e = tx.Exec(s); e != nil { tx.Rollback() return e } } ver = us.ver } if e = setOption(tx, dbVersion, ver); e != nil { tx.Rollback() return e } return tx.Commit() }