diff --git a/modules/config/config.go b/modules/config/config.go index b74912427..4ba64625d 100644 --- a/modules/config/config.go +++ b/modules/config/config.go @@ -16,160 +16,12 @@ import ( "sync" "sync/atomic" - "github.com/GoAdminGroup/go-admin/modules/logger" "github.com/GoAdminGroup/go-admin/modules/utils" "github.com/GoAdminGroup/go-admin/plugins/admin/modules/form" "gopkg.in/ini.v1" "gopkg.in/yaml.v2" ) -// Database is a type of database connection config. -// -// Because a little difference of different database driver. -// The Config has multiple options but may not be used. -// Such as the sqlite driver only use the File option which -// can be ignored when the driver is mysql. -// -// If the Dsn is configured, when driver is mysql/postgresql/ -// mssql, the other configurations will be ignored, except for -// MaxIdleCon and MaxOpenCon. -type Database struct { - Host string `json:"host,omitempty" yaml:"host,omitempty" ini:"host,omitempty"` - Port string `json:"port,omitempty" yaml:"port,omitempty" ini:"port,omitempty"` - User string `json:"user,omitempty" yaml:"user,omitempty" ini:"user,omitempty"` - Pwd string `json:"pwd,omitempty" yaml:"pwd,omitempty" ini:"pwd,omitempty"` - Name string `json:"name,omitempty" yaml:"name,omitempty" ini:"name,omitempty"` - MaxIdleCon int `json:"max_idle_con,omitempty" yaml:"max_idle_con,omitempty" ini:"max_idle_con,omitempty"` - MaxOpenCon int `json:"max_open_con,omitempty" yaml:"max_open_con,omitempty" ini:"max_open_con,omitempty"` - Driver string `json:"driver,omitempty" yaml:"driver,omitempty" ini:"driver,omitempty"` - DriverMode string `json:"driver_mode,omitempty" yaml:"driver_mode,omitempty" ini:"driver_mode,omitempty"` - File string `json:"file,omitempty" yaml:"file,omitempty" ini:"file,omitempty"` - Dsn string `json:"dsn,omitempty" yaml:"dsn,omitempty" ini:"dsn,omitempty"` - Params map[string]string `json:"params,omitempty" yaml:"params,omitempty" ini:"params,omitempty"` -} - -func (d Database) GetDSN() string { - if d.Dsn != "" { - return d.Dsn - } - - if d.Driver == DriverMysql { - return d.User + ":" + d.Pwd + "@tcp(" + d.Host + ":" + d.Port + ")/" + - d.Name + d.ParamStr() - } - if d.Driver == DriverPostgresql { - return fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s"+d.ParamStr(), - d.Host, d.Port, d.User, d.Pwd, d.Name) - } - if d.Driver == DriverMssql { - return fmt.Sprintf("user id=%s;password=%s;server=%s;port=%s;database=%s;"+d.ParamStr(), - d.User, d.Pwd, d.Host, d.Port, d.Name) - } - if d.Driver == DriverSqlite { - return d.File + d.ParamStr() - } - return "" -} - -func (d Database) ParamStr() string { - p := "" - if d.Params == nil { - d.Params = make(map[string]string) - } - if d.Driver == DriverMysql || d.Driver == DriverSqlite { - if d.Driver == DriverMysql { - if _, ok := d.Params["charset"]; !ok { - d.Params["charset"] = "utf8mb4" - } - } - if len(d.Params) > 0 { - p = "?" - for k, v := range d.Params { - p += k + "=" + v + "&" - } - p = p[:len(p)-1] - } - } - if d.Driver == DriverMssql { - if _, ok := d.Params["encrypt"]; !ok { - d.Params["encrypt"] = "disable" - } - for k, v := range d.Params { - p += k + "=" + v + ";" - } - p = p[:len(p)-1] - } - if d.Driver == DriverPostgresql { - if _, ok := d.Params["sslmode"]; !ok { - d.Params["sslmode"] = "disable" - } - p = " " - for k, v := range d.Params { - p += k + "=" + v + " " - } - p = p[:len(p)-1] - } - return p -} - -// DatabaseList is a map of Database. -type DatabaseList map[string]Database - -// GetDefault get the default Database. -func (d DatabaseList) GetDefault() Database { - return d["default"] -} - -// Add add a Database to the DatabaseList. -func (d DatabaseList) Add(key string, db Database) { - d[key] = db -} - -// GroupByDriver group the Databases with the drivers. -func (d DatabaseList) GroupByDriver() map[string]DatabaseList { - drivers := make(map[string]DatabaseList) - for key, item := range d { - if driverList, ok := drivers[item.Driver]; ok { - driverList.Add(key, item) - } else { - drivers[item.Driver] = make(DatabaseList) - drivers[item.Driver].Add(key, item) - } - } - return drivers -} - -func (d DatabaseList) JSON() string { - return utils.JSON(d) -} - -func (d DatabaseList) Copy() DatabaseList { - var c = make(DatabaseList) - for k, v := range d { - c[k] = v - } - return c -} - -func (d DatabaseList) Connections() []string { - conns := make([]string, len(d)) - count := 0 - for key := range d { - conns[count] = key - count++ - } - return conns -} - -func GetDatabaseListFromJSON(m string) DatabaseList { - var d = make(DatabaseList) - if m == "" { - panic("wrong config") - } - _ = json.Unmarshal([]byte(m), &d) - return d -} - const ( // EnvTest is a const value of test environment. EnvTest = "test" @@ -177,68 +29,8 @@ const ( EnvLocal = "local" // EnvProd is a const value of production environment. EnvProd = "prod" - - // DriverMysql is a const value of mysql driver. - DriverMysql = "mysql" - // DriverSqlite is a const value of sqlite driver. - DriverSqlite = "sqlite" - // DriverPostgresql is a const value of postgresql driver. - DriverPostgresql = "postgresql" - // DriverMssql is a const value of mssql driver. - DriverMssql = "mssql" ) -// Store is the file store config. Path is the local store path. -// and prefix is the url prefix used to visit it. -type Store struct { - Path string `json:"path,omitempty" yaml:"path,omitempty" ini:"path,omitempty"` - Prefix string `json:"prefix,omitempty" yaml:"prefix,omitempty" ini:"prefix,omitempty"` -} - -func (s Store) URL(suffix string) string { - if len(suffix) > 4 && suffix[:4] == "http" { - return suffix - } - if s.Prefix == "" { - if suffix[0] == '/' { - return suffix - } - return "/" + suffix - } - if s.Prefix[0] == '/' { - if suffix[0] == '/' { - return s.Prefix + suffix - } - return s.Prefix + "/" + suffix - } - if suffix[0] == '/' { - if len(s.Prefix) > 4 && s.Prefix[:4] == "http" { - return s.Prefix + suffix - } - return "/" + s.Prefix + suffix - } - if len(s.Prefix) > 4 && s.Prefix[:4] == "http" { - return s.Prefix + "/" + suffix - } - return "/" + s.Prefix + "/" + suffix -} - -func (s Store) JSON() string { - if s.Path == "" && s.Prefix == "" { - return "" - } - return utils.JSON(s) -} - -func GetStoreFromJSON(m string) Store { - var s Store - if m == "" { - return s - } - _ = json.Unmarshal([]byte(m), &s) - return s -} - // Config type is the global config of goAdmin. It will be // initialized in the engine. type Config struct { @@ -399,33 +191,6 @@ type Config struct { lock sync.RWMutex `json:"-" yaml:"-" ini:"-"` } -type Logger struct { - Encoder EncoderCfg `json:"encoder,omitempty" yaml:"encoder,omitempty" ini:"encoder,omitempty"` - Rotate RotateCfg `json:"rotate,omitempty" yaml:"rotate,omitempty" ini:"rotate,omitempty"` - Level int8 `json:"level,omitempty" yaml:"level,omitempty" ini:"level,omitempty"` -} - -type EncoderCfg struct { - TimeKey string `json:"time_key,omitempty" yaml:"time_key,omitempty" ini:"time_key,omitempty"` - LevelKey string `json:"level_key,omitempty" yaml:"level_key,omitempty" ini:"level_key,omitempty"` - NameKey string `json:"name_key,omitempty" yaml:"name_key,omitempty" ini:"name_key,omitempty"` - CallerKey string `json:"caller_key,omitempty" yaml:"caller_key,omitempty" ini:"caller_key,omitempty"` - MessageKey string `json:"message_key,omitempty" yaml:"message_key,omitempty" ini:"message_key,omitempty"` - StacktraceKey string `json:"stacktrace_key,omitempty" yaml:"stacktrace_key,omitempty" ini:"stacktrace_key,omitempty"` - Level string `json:"level,omitempty" yaml:"level,omitempty" ini:"level,omitempty"` - Time string `json:"time,omitempty" yaml:"time,omitempty" ini:"time,omitempty"` - Duration string `json:"duration,omitempty" yaml:"duration,omitempty" ini:"duration,omitempty"` - Caller string `json:"caller,omitempty" yaml:"caller,omitempty" ini:"caller,omitempty"` - Encoding string `json:"encoding,omitempty" yaml:"encoding,omitempty" ini:"encoding,omitempty"` -} - -type RotateCfg struct { - MaxSize int `json:"max_size,omitempty" yaml:"max_size,omitempty" ini:"max_size,omitempty"` - MaxBackups int `json:"max_backups,omitempty" yaml:"max_backups,omitempty" ini:"max_backups,omitempty"` - MaxAge int `json:"max_age,omitempty" yaml:"max_age,omitempty" ini:"max_age,omitempty"` - Compress bool `json:"compress,omitempty" yaml:"compress,omitempty" ini:"compress,omitempty"` -} - type URLFormat struct { Info string `json:"info,omitempty" yaml:"info,omitempty" ini:"info,omitempty"` Detail string `json:"detail,omitempty" yaml:"detail,omitempty" ini:"detail,omitempty"` @@ -469,31 +234,6 @@ func (p PageAnimation) JSON() string { return utils.JSON(p) } -// FileUploadEngine is a file upload engine. -type FileUploadEngine struct { - Name string `json:"name,omitempty" yaml:"name,omitempty" ini:"name,omitempty"` - Config map[string]interface{} `json:"config,omitempty" yaml:"config,omitempty" ini:"config,omitempty"` -} - -func (f FileUploadEngine) JSON() string { - if f.Name == "" { - return "" - } - if len(f.Config) == 0 { - f.Config = nil - } - return utils.JSON(f) -} - -func GetFileUploadEngineFromJSON(m string) FileUploadEngine { - var f FileUploadEngine - if m == "" { - return f - } - _ = json.Unmarshal([]byte(m), &f) - return f -} - // GetIndexURL get the index url with prefix. func (c *Config) GetIndexURL() string { index := c.Index() @@ -930,40 +670,6 @@ func Initialize(cfg *Config) *Config { return _global } -func initLogger(cfg *Config) { - logger.InitWithConfig(logger.Config{ - InfoLogOff: cfg.InfoLogOff, - ErrorLogOff: cfg.ErrorLogOff, - AccessLogOff: cfg.AccessLogOff, - SqlLogOpen: cfg.SqlLog, - InfoLogPath: cfg.InfoLogPath, - ErrorLogPath: cfg.ErrorLogPath, - AccessLogPath: cfg.AccessLogPath, - AccessAssetsLogOff: cfg.AccessAssetsLogOff, - Rotate: logger.RotateCfg{ - MaxSize: cfg.Logger.Rotate.MaxSize, - MaxBackups: cfg.Logger.Rotate.MaxBackups, - MaxAge: cfg.Logger.Rotate.MaxAge, - Compress: cfg.Logger.Rotate.Compress, - }, - Encode: logger.EncoderCfg{ - TimeKey: cfg.Logger.Encoder.TimeKey, - LevelKey: cfg.Logger.Encoder.LevelKey, - NameKey: cfg.Logger.Encoder.NameKey, - CallerKey: cfg.Logger.Encoder.CallerKey, - MessageKey: cfg.Logger.Encoder.MessageKey, - StacktraceKey: cfg.Logger.Encoder.StacktraceKey, - Level: cfg.Logger.Encoder.Level, - Time: cfg.Logger.Encoder.Time, - Duration: cfg.Logger.Encoder.Duration, - Caller: cfg.Logger.Encoder.Caller, - Encoding: cfg.Logger.Encoder.Encoding, - }, - Debug: cfg.Debug, - Level: cfg.Logger.Level, - }) -} - // AssertPrefix return the prefix of assert. func AssertPrefix() string { return _global.AssertPrefix() @@ -1152,7 +858,7 @@ func GetDebug() bool { func GetEnv() string { _global.lock.RLock() defer _global.lock.RUnlock() - return _global.Env + return string(_global.Env) } func GetInfoLogPath() string { diff --git a/modules/config/database.go b/modules/config/database.go new file mode 100644 index 000000000..81053175b --- /dev/null +++ b/modules/config/database.go @@ -0,0 +1,307 @@ +package config + +import ( + "encoding/json" + "fmt" + "github.com/GoAdminGroup/go-admin/modules/utils" + "sort" + "strings" +) + +const ( + // DriverMysql is a const value of mysql driver. + DriverMysql = "mysql" + // DriverSqlite is a const value of sqlite driver. + DriverSqlite = "sqlite" + // DriverPostgresql is a const value of postgresql driver. + DriverPostgresql = "postgresql" + // DriverMssql is a const value of mssql driver. + DriverMssql = "mssql" +) + +// defining database Functional Options that modify Database instance +type DatabaseOption func(*Database) + +func DatabaseMaxIdleConOption(maxIdleCon int) DatabaseOption { + return func(db *Database) { + db.MaxIdleCon = maxIdleCon + } +} + +func DatabaseMaxOpenConOption(maxOpenCon int) DatabaseOption { + return func(db *Database) { + db.MaxOpenCon = maxOpenCon + } +} + +func DatabaseMysqlOption(host, port, user, pwd, name string, param map[string]string) DatabaseOption { + return func(db *Database) { + db.Driver = DriverMysql + db.Host = host + db.Port = port + db.User = user + db.Pwd = pwd + db.Name = name + + if param == nil { + param = db.Params + } + if _, has := param["parseTime"]; !has { + param["parseTime"] = "True" + } + if _, has := param["loc"]; !has { + param["loc"] = "Local" + } + if _, has := param["charset"]; !has { + param["charset"] = "utf8mb4" + } + + paramArr := make([]string, 0) + for k, v := range param { + paramArr = append(paramArr, k+"="+v) + } + sort.Strings(paramArr) + + db.Params = param + db.Dsn = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?%s", + user, pwd, host, port, name, strings.Join(paramArr, "&")) + } +} + +func DatabasePostgresqlOption(host, port, user, pwd, name string, param map[string]string) DatabaseOption { + return func(db *Database) { + db.Driver = DriverPostgresql + db.Host = host + db.Port = port + db.User = user + db.Pwd = pwd + db.Name = name + + if param == nil { + param = db.Params + } + if _, has := param["sslmode"]; !has { + param["sslmode"] = "disable" + } + + paramArr := make([]string, 0) + for k, v := range param { + paramArr = append(paramArr, k+"="+v) + } + sort.Strings(paramArr) + + db.Params = param + db.Dsn = fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s %s", + user, pwd, host, port, name, strings.Join(paramArr, " ")) + } +} + +func DatabaseSqliteOption(filepath string, param map[string]string) DatabaseOption { + return func(db *Database) { + db.Driver = DriverSqlite + db.File = filepath + + if param != nil { + param = db.Params + } + paramArr := make([]string, 0) + for k, v := range param { + paramArr = append(paramArr, k+"="+v) + } + sort.Strings(paramArr) + + db.Params = param + if len(paramArr) > 0 { + filepath += "?" + } + db.Dsn = filepath + strings.Join(paramArr, "&") + } +} + +func DatabaseMssql(host, port, user, pwd, dbName string, param map[string]string) DatabaseOption { + return func(db *Database) { + db.Driver = DriverMssql + db.Host = host + db.Port = port + db.User = user + db.Pwd = pwd + db.Name = dbName + + if param == nil { + param = db.Params + } + if _, has := param["encrypt"]; !has { + param["encrypt"] = "disable" + } + paramArr := make([]string, 0) + for k, v := range param { + paramArr = append(paramArr, k+"="+v) + } + sort.Strings(paramArr) + + db.Params = param + db.Dsn = fmt.Sprintf("user id=%s;password=%s;server=%s;port=%s;database=%s;%s", + user, pwd, host, port, dbName, strings.Join(paramArr, ";")) + } +} + +// Database is a type of database connection config. +// +// Because a little difference of different database driver. +// The Config has multiple options but may not be used. +// Such as the sqlite driver only use the File option which +// can be ignored when the driver is mysql. +// +// If the Dsn is configured, when driver is mysql/postgresql/ +// mssql, the other configurations will be ignored, except for +// MaxIdleCon and MaxOpenCon. +type Database struct { + Host string `json:"host,omitempty" yaml:"host,omitempty" ini:"host,omitempty"` + Port string `json:"port,omitempty" yaml:"port,omitempty" ini:"port,omitempty"` + User string `json:"user,omitempty" yaml:"user,omitempty" ini:"user,omitempty"` + Pwd string `json:"pwd,omitempty" yaml:"pwd,omitempty" ini:"pwd,omitempty"` + Name string `json:"name,omitempty" yaml:"name,omitempty" ini:"name,omitempty"` + MaxIdleCon int `json:"max_idle_con,omitempty" yaml:"max_idle_con,omitempty" ini:"max_idle_con,omitempty"` + MaxOpenCon int `json:"max_open_con,omitempty" yaml:"max_open_con,omitempty" ini:"max_open_con,omitempty"` + Driver string `json:"driver,omitempty" yaml:"driver,omitempty" ini:"driver,omitempty"` + DriverMode string `json:"driver_mode,omitempty" yaml:"driver_mode,omitempty" ini:"driver_mode,omitempty"` + File string `json:"file,omitempty" yaml:"file,omitempty" ini:"file,omitempty"` + Dsn string `json:"dsn,omitempty" yaml:"dsn,omitempty" ini:"dsn,omitempty"` + Params map[string]string `json:"params,omitempty" yaml:"params,omitempty" ini:"params,omitempty"` +} + +func (d Database) GetDSN() string { + if d.Dsn != "" { + return d.Dsn + } + + if d.Driver == DriverMysql { + return d.User + ":" + d.Pwd + "@tcp(" + d.Host + ":" + d.Port + ")/" + + d.Name + d.ParamStr() + } + if d.Driver == DriverPostgresql { + return fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s"+d.ParamStr(), + d.Host, d.Port, d.User, d.Pwd, d.Name) + } + if d.Driver == DriverMssql { + return fmt.Sprintf("user id=%s;password=%s;server=%s;port=%s;database=%s;"+d.ParamStr(), + d.User, d.Pwd, d.Host, d.Port, d.Name) + } + if d.Driver == DriverSqlite { + return d.File + d.ParamStr() + } + return "" +} + +func (d Database) ParamStr() string { + p := "" + if d.Params == nil { + d.Params = make(map[string]string) + } + if d.Driver == DriverMysql || d.Driver == DriverSqlite { + if d.Driver == DriverMysql { + if _, ok := d.Params["charset"]; !ok { + d.Params["charset"] = "utf8mb4" + } + } + if len(d.Params) > 0 { + p = "?" + for k, v := range d.Params { + p += k + "=" + v + "&" + } + p = p[:len(p)-1] + } + } + if d.Driver == DriverMssql { + if _, ok := d.Params["encrypt"]; !ok { + d.Params["encrypt"] = "disable" + } + for k, v := range d.Params { + p += k + "=" + v + ";" + } + p = p[:len(p)-1] + } + if d.Driver == DriverPostgresql { + if _, ok := d.Params["sslmode"]; !ok { + d.Params["sslmode"] = "disable" + } + p = " " + for k, v := range d.Params { + p += k + "=" + v + " " + } + p = p[:len(p)-1] + } + return p +} + +// DatabaseList is a map of Database. +type DatabaseList map[string]Database + +// GetDefault get the default Database. +func (d DatabaseList) GetDefault() Database { + return d["default"] +} + +// Add add a Database to the DatabaseList. +func (d DatabaseList) Add(key string, db Database) { + d[key] = db +} + +// GroupByDriver group the Databases with the drivers. +func (d DatabaseList) GroupByDriver() map[string]DatabaseList { + drivers := make(map[string]DatabaseList) + for key, item := range d { + if driverList, ok := drivers[item.Driver]; ok { + driverList.Add(key, item) + } else { + drivers[item.Driver] = make(DatabaseList) + drivers[item.Driver].Add(key, item) + } + } + return drivers +} + +func (d DatabaseList) JSON() string { + return utils.JSON(d) +} + +func (d DatabaseList) Copy() DatabaseList { + var c = make(DatabaseList) + for k, v := range d { + c[k] = v + } + return c +} + +func (d DatabaseList) Connections() []string { + conns := make([]string, len(d)) + count := 0 + for key := range d { + conns[count] = key + count++ + } + return conns +} + +func GetDatabaseListFromJSON(m string) DatabaseList { + var d = make(DatabaseList) + if m == "" { + panic("wrong config") + } + _ = json.Unmarshal([]byte(m), &d) + return d +} + +func NewDatabase(opts ...DatabaseOption) *Database { + database := &Database{ + MaxIdleCon: 50, + MaxOpenCon: 150, + Params: make(map[string]string), + } + + for _, opt := range opts { + opt(database) + } + + return database +} diff --git a/modules/config/database_test.go b/modules/config/database_test.go new file mode 100644 index 000000000..11a510f18 --- /dev/null +++ b/modules/config/database_test.go @@ -0,0 +1,45 @@ +package config + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestConfigDatabase(t *testing.T) { + // sqlite config + sqliteDbCfg := NewDatabase( + DatabaseMaxIdleConOption(150), + DatabaseMaxOpenConOption(50), + DatabaseSqliteOption("data/admin.db", nil), + ) + + assert.Equal(t, sqliteDbCfg.Driver, DriverSqlite) + assert.Equal(t, sqliteDbCfg.MaxIdleCon, 150) + assert.Equal(t, sqliteDbCfg.MaxOpenCon, 50) + assert.Equal(t, sqliteDbCfg.File, "data/admin.db") + assert.Equal(t, sqliteDbCfg.Dsn, "data/admin.db") + + // mysql config + mysqlDbCfg := NewDatabase( + DatabaseMysqlOption("127.0.0.1", "3306", "root", "root", "go_admin", nil), + ) + + assert.Equal(t, mysqlDbCfg.Driver, DriverMysql) + assert.Equal(t, mysqlDbCfg.MaxIdleCon, 50) + assert.Equal(t, mysqlDbCfg.MaxOpenCon, 150) + assert.Equal(t, mysqlDbCfg.Dsn, "root:root@tcp(127.0.0.1:3306)/go_admin?charset=utf8mb4&loc=Local&parseTime=True") + + // postgresql config + postgresqlCfg := NewDatabase( + DatabasePostgresqlOption("127.0.0.1", "3306", "root", "root", "go_admin", nil), + ) + assert.Equal(t, postgresqlCfg.Driver, DriverPostgresql) + assert.Equal(t, postgresqlCfg.Dsn, "host=root port=root user=127.0.0.1 password=3306 dbname=go_admin sslmode=disable") + + // mssql config + mssqlCfg := NewDatabase( + DatabaseMssql("127.0.0.1", "3306", "root", "root", "go_admin", map[string]string{}), + ) + assert.Equal(t, mssqlCfg.Driver, DriverMssql) + assert.Equal(t, mssqlCfg.Dsn, "user id=root;password=root;server=127.0.0.1;port=3306;database=go_admin;encrypt=disable") +} diff --git a/modules/config/file_upload_engine.go b/modules/config/file_upload_engine.go new file mode 100644 index 000000000..8ec1d5ae9 --- /dev/null +++ b/modules/config/file_upload_engine.go @@ -0,0 +1,31 @@ +package config + +import ( + "encoding/json" + "github.com/GoAdminGroup/go-admin/modules/utils" +) + +// FileUploadEngine is a file upload engine. +type FileUploadEngine struct { + Name string `json:"name,omitempty" yaml:"name,omitempty" ini:"name,omitempty"` + Config map[string]interface{} `json:"config,omitempty" yaml:"config,omitempty" ini:"config,omitempty"` +} + +func (f FileUploadEngine) JSON() string { + if f.Name == "" { + return "" + } + if len(f.Config) == 0 { + f.Config = nil + } + return utils.JSON(f) +} + +func GetFileUploadEngineFromJSON(m string) FileUploadEngine { + var f FileUploadEngine + if m == "" { + return f + } + _ = json.Unmarshal([]byte(m), &f) + return f +} diff --git a/modules/config/logger.go b/modules/config/logger.go new file mode 100644 index 000000000..0d4b7ca36 --- /dev/null +++ b/modules/config/logger.go @@ -0,0 +1,64 @@ +package config + +import "github.com/GoAdminGroup/go-admin/modules/logger" + +type Logger struct { + Encoder EncoderCfg `json:"encoder,omitempty" yaml:"encoder,omitempty" ini:"encoder,omitempty"` + Rotate RotateCfg `json:"rotate,omitempty" yaml:"rotate,omitempty" ini:"rotate,omitempty"` + Level int8 `json:"level,omitempty" yaml:"level,omitempty" ini:"level,omitempty"` +} + +type EncoderCfg struct { + TimeKey string `json:"time_key,omitempty" yaml:"time_key,omitempty" ini:"time_key,omitempty"` + LevelKey string `json:"level_key,omitempty" yaml:"level_key,omitempty" ini:"level_key,omitempty"` + NameKey string `json:"name_key,omitempty" yaml:"name_key,omitempty" ini:"name_key,omitempty"` + CallerKey string `json:"caller_key,omitempty" yaml:"caller_key,omitempty" ini:"caller_key,omitempty"` + MessageKey string `json:"message_key,omitempty" yaml:"message_key,omitempty" ini:"message_key,omitempty"` + StacktraceKey string `json:"stacktrace_key,omitempty" yaml:"stacktrace_key,omitempty" ini:"stacktrace_key,omitempty"` + Level string `json:"level,omitempty" yaml:"level,omitempty" ini:"level,omitempty"` + Time string `json:"time,omitempty" yaml:"time,omitempty" ini:"time,omitempty"` + Duration string `json:"duration,omitempty" yaml:"duration,omitempty" ini:"duration,omitempty"` + Caller string `json:"caller,omitempty" yaml:"caller,omitempty" ini:"caller,omitempty"` + Encoding string `json:"encoding,omitempty" yaml:"encoding,omitempty" ini:"encoding,omitempty"` +} + +type RotateCfg struct { + MaxSize int `json:"max_size,omitempty" yaml:"max_size,omitempty" ini:"max_size,omitempty"` + MaxBackups int `json:"max_backups,omitempty" yaml:"max_backups,omitempty" ini:"max_backups,omitempty"` + MaxAge int `json:"max_age,omitempty" yaml:"max_age,omitempty" ini:"max_age,omitempty"` + Compress bool `json:"compress,omitempty" yaml:"compress,omitempty" ini:"compress,omitempty"` +} + +func initLogger(cfg *Config) { + logger.InitWithConfig(logger.Config{ + InfoLogOff: cfg.InfoLogOff, + ErrorLogOff: cfg.ErrorLogOff, + AccessLogOff: cfg.AccessLogOff, + SqlLogOpen: cfg.SqlLog, + InfoLogPath: cfg.InfoLogPath, + ErrorLogPath: cfg.ErrorLogPath, + AccessLogPath: cfg.AccessLogPath, + AccessAssetsLogOff: cfg.AccessAssetsLogOff, + Rotate: logger.RotateCfg{ + MaxSize: cfg.Logger.Rotate.MaxSize, + MaxBackups: cfg.Logger.Rotate.MaxBackups, + MaxAge: cfg.Logger.Rotate.MaxAge, + Compress: cfg.Logger.Rotate.Compress, + }, + Encode: logger.EncoderCfg{ + TimeKey: cfg.Logger.Encoder.TimeKey, + LevelKey: cfg.Logger.Encoder.LevelKey, + NameKey: cfg.Logger.Encoder.NameKey, + CallerKey: cfg.Logger.Encoder.CallerKey, + MessageKey: cfg.Logger.Encoder.MessageKey, + StacktraceKey: cfg.Logger.Encoder.StacktraceKey, + Level: cfg.Logger.Encoder.Level, + Time: cfg.Logger.Encoder.Time, + Duration: cfg.Logger.Encoder.Duration, + Caller: cfg.Logger.Encoder.Caller, + Encoding: cfg.Logger.Encoder.Encoding, + }, + Debug: cfg.Debug, + Level: cfg.Logger.Level, + }) +} diff --git a/modules/config/store.go b/modules/config/store.go new file mode 100644 index 000000000..8f0141ded --- /dev/null +++ b/modules/config/store.go @@ -0,0 +1,57 @@ +package config + +import ( + "encoding/json" + "github.com/GoAdminGroup/go-admin/modules/utils" +) + +// Store is the file store config. Path is the local store path. +// and prefix is the url prefix used to visit it. +type Store struct { + Path string `json:"path,omitempty" yaml:"path,omitempty" ini:"path,omitempty"` + Prefix string `json:"prefix,omitempty" yaml:"prefix,omitempty" ini:"prefix,omitempty"` +} + +func (s Store) URL(suffix string) string { + if len(suffix) > 4 && suffix[:4] == "http" { + return suffix + } + if s.Prefix == "" { + if suffix[0] == '/' { + return suffix + } + return "/" + suffix + } + if s.Prefix[0] == '/' { + if suffix[0] == '/' { + return s.Prefix + suffix + } + return s.Prefix + "/" + suffix + } + if suffix[0] == '/' { + if len(s.Prefix) > 4 && s.Prefix[:4] == "http" { + return s.Prefix + suffix + } + return "/" + s.Prefix + suffix + } + if len(s.Prefix) > 4 && s.Prefix[:4] == "http" { + return s.Prefix + "/" + suffix + } + return "/" + s.Prefix + "/" + suffix +} + +func (s Store) JSON() string { + if s.Path == "" && s.Prefix == "" { + return "" + } + return utils.JSON(s) +} + +func GetStoreFromJSON(m string) Store { + var s Store + if m == "" { + return s + } + _ = json.Unmarshal([]byte(m), &s) + return s +}