2016-01-17 18:00:44 +00:00
|
|
|
// © 2013 the CatBase Authors under the WTFPL. See AUTHORS for the list of authors.
|
2013-12-10 23:37:07 +00:00
|
|
|
|
2012-08-17 20:38:15 +00:00
|
|
|
package config
|
|
|
|
|
2017-07-25 17:58:04 +00:00
|
|
|
import (
|
|
|
|
"database/sql"
|
|
|
|
"fmt"
|
|
|
|
"log"
|
2019-01-20 20:21:26 +00:00
|
|
|
"os"
|
2017-07-25 17:58:04 +00:00
|
|
|
"regexp"
|
2019-01-20 20:21:26 +00:00
|
|
|
"strconv"
|
|
|
|
"strings"
|
2017-07-25 17:58:04 +00:00
|
|
|
|
|
|
|
"github.com/jmoiron/sqlx"
|
|
|
|
sqlite3 "github.com/mattn/go-sqlite3"
|
|
|
|
)
|
2012-08-17 20:38:15 +00:00
|
|
|
|
|
|
|
// Config stores any system-wide startup information that cannot be easily configured via
|
|
|
|
// the database
|
|
|
|
type Config struct {
|
2019-01-20 20:21:26 +00:00
|
|
|
*sqlx.DB
|
2017-07-25 17:58:04 +00:00
|
|
|
|
2019-01-20 20:21:26 +00:00
|
|
|
DBFile string
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetFloat64 returns the config value for a string key
|
|
|
|
// It will first look in the env vars for the key
|
|
|
|
// It will check the DB for the key if an env DNE
|
|
|
|
// Finally, it will return a zero value if the key does not exist
|
|
|
|
// It will attempt to convert the value to a float64 if it exists
|
|
|
|
func (c *Config) GetFloat64(key string) float64 {
|
|
|
|
f, err := strconv.ParseFloat(c.GetString(key), 64)
|
|
|
|
if err != nil {
|
|
|
|
return 0.0
|
2017-07-25 18:44:36 +00:00
|
|
|
}
|
2019-01-20 20:21:26 +00:00
|
|
|
return f
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetInt returns the config value for a string key
|
|
|
|
// It will first look in the env vars for the key
|
|
|
|
// It will check the DB for the key if an env DNE
|
|
|
|
// Finally, it will return a zero value if the key does not exist
|
|
|
|
// It will attempt to convert the value to an int if it exists
|
|
|
|
func (c *Config) GetInt(key string) int {
|
|
|
|
i, err := strconv.Atoi(c.GetString(key))
|
|
|
|
if err != nil {
|
|
|
|
return 0
|
2017-08-30 17:41:58 +00:00
|
|
|
}
|
2019-01-20 20:21:26 +00:00
|
|
|
return i
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get is a shortcut for GetString
|
|
|
|
func (c *Config) Get(key string) string {
|
|
|
|
return c.GetString(key)
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetString returns the config value for a string key
|
|
|
|
// It will first look in the env vars for the key
|
|
|
|
// It will check the DB for the key if an env DNE
|
|
|
|
// Finally, it will return a zero value if the key does not exist
|
|
|
|
// It will convert the value to a string if it exists
|
|
|
|
func (c *Config) GetString(key string) string {
|
|
|
|
key = strings.ToLower(key)
|
|
|
|
if v, found := os.LookupEnv(key); found {
|
|
|
|
return v
|
|
|
|
}
|
|
|
|
var configValue string
|
|
|
|
q := `select value from config where key=?`
|
|
|
|
err := c.DB.Get(&configValue, q, key)
|
|
|
|
if err != nil {
|
|
|
|
return ""
|
2017-09-29 04:58:21 +00:00
|
|
|
}
|
2019-01-20 20:21:26 +00:00
|
|
|
return configValue
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetArray returns the string slice config value for a string key
|
|
|
|
// It will first look in the env vars for the key with ;; separated values
|
|
|
|
// Look, I'm too lazy to do parsing to ensure that a comma is what the user meant
|
|
|
|
// It will check the DB for the key if an env DNE
|
|
|
|
// Finally, it will return a zero value if the key does not exist
|
|
|
|
// This will do no conversion.
|
|
|
|
func (c *Config) GetArray(key string) []string {
|
|
|
|
val := c.GetString(key)
|
|
|
|
return strings.Split(val, ";;")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set changes the value for a configuration in the database
|
|
|
|
// Note, this is always a string. Use the SetArray for an array helper
|
|
|
|
func (c *Config) Set(key, value string) error {
|
|
|
|
key = strings.ToLower(key)
|
|
|
|
q := (`insert into config (key,value) values (?, ?);`)
|
|
|
|
_, err := c.Exec(q, key, value)
|
|
|
|
if err != nil {
|
|
|
|
q := (`update config set value=? where key=?);`)
|
|
|
|
_, err = c.Exec(q, value, key)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2017-11-06 19:32:49 +00:00
|
|
|
}
|
2019-01-20 20:21:26 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Config) SetArray(key string, values []string) error {
|
|
|
|
vals := strings.Join(values, ";;")
|
|
|
|
return c.Set(key, vals)
|
2012-08-17 21:37:49 +00:00
|
|
|
}
|
2012-08-17 20:38:15 +00:00
|
|
|
|
2017-07-25 17:58:04 +00:00
|
|
|
func init() {
|
|
|
|
regex := func(re, s string) (bool, error) {
|
|
|
|
return regexp.MatchString(re, s)
|
|
|
|
}
|
|
|
|
sql.Register("sqlite3_custom",
|
|
|
|
&sqlite3.SQLiteDriver{
|
|
|
|
ConnectHook: func(conn *sqlite3.SQLiteConn) error {
|
|
|
|
return conn.RegisterFunc("REGEXP", regex, true)
|
|
|
|
},
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2012-08-17 21:37:49 +00:00
|
|
|
// Readconfig loads the config data out of a JSON file located in cfile
|
2019-01-20 20:21:26 +00:00
|
|
|
func ReadConfig(dbpath string) *Config {
|
|
|
|
if dbpath == "" {
|
|
|
|
dbpath = "catbase.db"
|
2012-08-17 20:38:15 +00:00
|
|
|
}
|
2019-01-20 20:21:26 +00:00
|
|
|
fmt.Printf("Using %s as database file.\n", dbpath)
|
2012-08-17 20:38:15 +00:00
|
|
|
|
2019-01-20 20:21:26 +00:00
|
|
|
sqlDB, err := sqlx.Open("sqlite3_custom", dbpath)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
2012-08-17 20:38:15 +00:00
|
|
|
}
|
2019-01-20 20:21:26 +00:00
|
|
|
c := Config{
|
|
|
|
DBFile: dbpath,
|
2016-03-10 18:37:07 +00:00
|
|
|
}
|
2019-01-20 20:21:26 +00:00
|
|
|
c.DB = sqlDB
|
2016-03-10 18:37:07 +00:00
|
|
|
|
2019-01-20 20:21:26 +00:00
|
|
|
if _, err := c.Exec(`create table if not exists config (
|
|
|
|
key string,
|
|
|
|
value string,
|
|
|
|
primary key (key)
|
|
|
|
);`); err != nil {
|
|
|
|
panic(err)
|
2017-07-25 17:58:04 +00:00
|
|
|
}
|
2019-01-20 20:21:26 +00:00
|
|
|
|
|
|
|
fmt.Printf("catbase is running.\n")
|
2017-07-25 17:58:04 +00:00
|
|
|
|
2012-08-17 20:38:15 +00:00
|
|
|
return &c
|
|
|
|
}
|