diff --git a/.gitignore b/.gitignore index 0152739..f42f2a0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ config.yml .vscode .idea +module/schema/static.go \ No newline at end of file diff --git a/main.go b/main.go index e02e7bf..d9f13c4 100644 --- a/main.go +++ b/main.go @@ -10,6 +10,7 @@ import ( "strconv" "strings" + "git.trj.tw/golang/mtfosbot/module/cmd" "git.trj.tw/golang/mtfosbot/module/options" "git.trj.tw/golang/mtfosbot/module/utils" @@ -41,13 +42,6 @@ func main() { log.Fatal(err) } - registerTypes() - background.SetBackground() - - // create http server - server = routes.NewServ() - routes.SetRoutes(server) - // connect to database db, err := model.NewDB() if err != nil { @@ -55,6 +49,17 @@ func main() { } defer db.Close() + if runOptions.DBTool { + cmd.DBTool() + } + + registerTypes() + background.SetBackground() + + // create http server + server = routes.NewServ() + routes.SetRoutes(server) + go twitchirc.InitIRC() // create thumbnail directory diff --git a/model/model.go b/model/model.go index 34be550..40295ef 100644 --- a/model/model.go +++ b/model/model.go @@ -4,6 +4,7 @@ import ( "fmt" "log" + "git.trj.tw/golang/mtfosbot/module/config" "github.com/jmoiron/sqlx" _ "github.com/lib/pq" ) @@ -13,7 +14,8 @@ var x *sqlx.DB // NewDB - connect to database func NewDB() (*sqlx.DB, error) { var err error - connStr := fmt.Sprintf("user=%s host=%s sslmode=disable dbname=%s port=%d", "postgres", "localhost", "mtfosbot", 5432) + conf := config.GetConf() + connStr := fmt.Sprintf("user=%s password=%s host=%s sslmode=disable dbname=%s port=%d", conf.Database.User, conf.Database.Pass, conf.Database.Host, conf.Database.DB, conf.Database.Port) x, err = sqlx.Connect("postgres", connStr) if err != nil { log.Fatal(err) @@ -26,3 +28,8 @@ func NewDB() (*sqlx.DB, error) { } return x, err } + +// GetDB - +func GetDB() *sqlx.DB { + return x +} diff --git a/module/cmd/cmd.go b/module/cmd/cmd.go index 88eedce..46052e6 100644 --- a/module/cmd/cmd.go +++ b/module/cmd/cmd.go @@ -1,6 +1,83 @@ package cmd +import ( + "database/sql" + "errors" + "fmt" + "log" + + "git.trj.tw/golang/mtfosbot/module/schema" + + "git.trj.tw/golang/mtfosbot/model" +) + // DBTool - deploy database schemas func DBTool() { + db := model.GetDB() + if db == nil { + log.Fatal(errors.New("database object is nil")) + } + dbver, err := schema.ReadVersions() + if err != nil { + log.Fatal(err) + } + + version := -1 + + vcExists := false + // check version_ctrl table exists + row := db.QueryRowx(`select exists(select 1 from "information_schema"."tables" where "table_schema" = $1 and "table_name" = $2) as exists`, "public", "version_ctrl") + err = row.Scan(&vcExists) + if err != nil && err != sql.ErrNoRows { + log.Fatal(err) + } + + // read max version + if vcExists { + row := db.QueryRowx(`select max(version) as version from "public"."version_ctrl"`) + err := row.Scan(&version) + if err != nil && err != sql.ErrNoRows { + log.Fatal(err) + } + } + + fmt.Println("Database Schema Version is ", version) + var vers []schema.VersionInfo + for _, v := range dbver.Versions { + if v.Version > version { + vers = append(vers, v) + } + } + if len(vers) == 0 { + return + } + + tx, err := db.Beginx() + if err != nil { + log.Fatal(err) + } + + for _, v := range vers { + fmt.Printf("Run Version: %d, FileName: %s\n", v.Version, v.File) + query, err := schema.ReadSchema(v.File) + if err != nil { + tx.Rollback() + log.Fatal(err) + } + // run schema file + _, err = tx.Exec(query) + if err != nil { + tx.Rollback() + log.Fatal(err) + } + // insert version ctrl + _, err = tx.Exec(`insert into "public"."version_ctrl" ("version", "ctime", "querystr") values ($1, now(), $2)`, v.Version, query) + if err != nil { + tx.Rollback() + log.Fatal(err) + } + } + + tx.Commit() } diff --git a/module/schema/schema.go b/module/schema/schema.go new file mode 100644 index 0000000..b932f39 --- /dev/null +++ b/module/schema/schema.go @@ -0,0 +1,43 @@ +package schema + +import ( + "encoding/json" + "errors" + "fmt" +) + +// DBVersions - +type DBVersions struct { + Versions []VersionInfo `json:"versions"` + Test []VersionInfo `json:"test"` +} + +// VersionInfo - +type VersionInfo struct { + File string `json:"file"` + Version int `json:"version"` +} + +// ReadVersions - +func ReadVersions() (dbver DBVersions, err error) { + f, err := Asset("schema/dbVersion.json") + if err != nil { + return dbver, err + } + + err = json.Unmarshal(f, &dbver) + return +} + +// ReadSchema - +func ReadSchema(name string) (q string, err error) { + if len(name) == 0 { + return "", errors.New("name is empty") + } + f, err := Asset(fmt.Sprintf("schema/%s", name)) + if err != nil { + return + } + q = string(f) + return +}