diff --git a/.gitignore b/.gitignore index fdd594f..a476064 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ lucifer-server !cmd/**/* -vendor \ No newline at end of file +vendor +/config.yaml +/sqlite3.db \ No newline at end of file diff --git a/Gopkg.lock b/Gopkg.lock index 3698146..ef14900 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -1,6 +1,21 @@ # This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. +[[projects]] + name = "github.com/jmoiron/sqlx" + packages = [ + ".", + "reflectx" + ] + revision = "d161d7a76b5661016ad0b085869f77fd410f3e6a" + version = "v1.2.0" + +[[projects]] + name = "github.com/mattn/go-sqlite3" + packages = ["."] + revision = "c7c4067b79cc51e6dfdcef5c702e74b1e0fa7c75" + version = "v1.10.0" + [[projects]] branch = "master" name = "golang.org/x/crypto" @@ -13,6 +28,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "a0b0b08de3e66a9e5558eaca40ab59cab7d27dbafe9eaf33270a314437c749a0" + inputs-digest = "8237f2aa046d402c0ec32f98a3e48419917aeab2979b0b394ce6f7873bc989c2" solver-name = "gps-cdcl" solver-version = 1 diff --git a/cmd/lucifer-server/main.go b/cmd/lucifer-server/main.go index 7905807..b96bd4b 100644 --- a/cmd/lucifer-server/main.go +++ b/cmd/lucifer-server/main.go @@ -1,5 +1,20 @@ package main +import ( + "log" + + "git.aiterp.net/lucifer/lucifer/database/sqlite" + "git.aiterp.net/lucifer/lucifer/internal/config" +) + func main() { + conf, err := config.Load("./config.yaml", "/etc/lucifer/lucifer.yaml") + if err != nil { + log.Fatalln("Failed to load configuration:", err) + } + err = sqlite.Initialize(conf.DB.FileName) + if err != nil { + log.Fatalln("Failed to set up database:", err) + } } diff --git a/database/sqlite/init.go b/database/sqlite/init.go index 365a63a..f2981ce 100644 --- a/database/sqlite/init.go +++ b/database/sqlite/init.go @@ -1,5 +1,60 @@ package sqlite -func Initialize() { +import ( + "strings" + "github.com/jmoiron/sqlx" + + // sqlite driver + _ "github.com/mattn/go-sqlite3" +) + +var db *sqlx.DB + +// Initialize sets up the sqlite database. +func Initialize(filename string) (err error) { + if db != nil { + panic("sqlite.Initialize called twice!") + } + + db, err = sqlx.Open("sqlite3", filename) + if err != nil { + db = nil + return err + } + + err = db.Ping() + if err != nil { + db.Close() + db = nil + return err + } + + tableDefs := strings.Split(tableDefStr, ";") + for _, tableDef := range tableDefs { + _, err := db.Exec(strings.Trim(tableDef, "\n  ")) + if err != nil { + db.Close() + db = nil + return err + } + } + + return nil } + +const tableDefStr = ` + +CREATE TABLE IF NOT EXISTS "user" ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name VARCHAR(64) NOT NULL UNIQUE, + hash VARCHAR(128) NOT NULL +); + +CREATE TABLE IF NOT EXISTS "session" ( + id CHAR(64) PRIMARY KEY, + user_id INTEGER NOT NULL, + expire_date DATE NOT NULL +); + +` diff --git a/internal/config/config.go b/internal/config/config.go new file mode 100644 index 0000000..7d49179 --- /dev/null +++ b/internal/config/config.go @@ -0,0 +1,38 @@ +package config + +import ( + "os" + + "gopkg.in/yaml.v2" +) + +// Config is application configuration. +type Config struct { + DB struct { + FileName string `yaml:"file_name"` + } `yaml:"db"` +} + +// Load loads the first valid config file from the list of file paths. +func Load(filePaths ...string) (Config, error) { + file, err := os.Open(filePaths[0]) + if err != nil { + if len(filePaths) > 1 { + return Load(filePaths[1:]...) + } + + return Config{}, err + } + + config := Config{} + err = yaml.NewDecoder(file).Decode(&config) + if err != nil { + if len(filePaths) > 1 { + return Load(filePaths[1:]...) + } + + return Config{}, err + } + + return config, nil +}