diff --git a/config/config.go b/config/config.go index bd3a3d2..e0b0c93 100644 --- a/config/config.go +++ b/config/config.go @@ -1,5 +1,40 @@ package config -func Init() { +import ( + "log" + "github.com/spf13/viper" +) + +func Init() { + // Read global config + viper.SetConfigFile("config.yaml") + viper.SetDefault("Server", serverDef) + viper.SetDefault("Database", databaseDef) + conf := &config{} + if err := viper.ReadInConfig(); err != nil { + log.Println("Can't read config, trying to modify!") + if err := viper.WriteConfig(); err != nil { + log.Fatal("[Config] Error writing config: ", err) + } + } + if err := viper.Unmarshal(conf); err != nil { + log.Fatal(err) + } +} + +func Get(key string) any { + viper.SetConfigFile("config.yaml") + if err := viper.ReadInConfig(); err != nil { + log.Fatal("[Config] Error reading config: ", err) + } + return viper.Get(key) +} + +func Set(key string, value any) { + viper.SetConfigFile("config.yaml") + if err := viper.ReadInConfig(); err != nil { + log.Fatal("[Config] Error reading config: ", err) + } + viper.Set(key, value) } diff --git a/config/default.go b/config/default.go new file mode 100644 index 0000000..8fee6c8 --- /dev/null +++ b/config/default.go @@ -0,0 +1,15 @@ +package config + +var serverDef = server{ + Address: ":8000", + DebugMode: false, + FileLogger: false, +} + +var databaseDef = database{ + Type: "postgres", + Host: "", + Name: "", + Username: "", + Password: "", +} diff --git a/config/env.go b/config/env.go new file mode 100644 index 0000000..0c9972b --- /dev/null +++ b/config/env.go @@ -0,0 +1,72 @@ +package config + +import ( + "log" + "os" + "strconv" + "strings" + + "github.com/joho/godotenv" +) + +func GetEnv(Key string) string { + _ = godotenv.Load() + return os.Getenv(Key) +} + +func SetEnvConf(ConfKey string, ConfSub string) { + var Config = []string{ConfKey, ConfSub} + var EnvKey = strings.Join(Config, "_") + env := GetEnv(EnvKey) + var orig = Get(ConfKey + "." + ConfSub) + if env != "" { + switch orig.(type) { + case string: + Set(ConfKey, env) + case int: + conv, err := strconv.Atoi(env) + if err != nil { + log.Panic("[Config] Error converting string to int: ", err) + } + Set(ConfKey, conv) + case bool: + switch env { + case "true": + Set(ConfKey, true) + case "false": + Set(ConfKey, false) + } + case []string: + trim := strings.TrimSpace(env) + trim = strings.TrimPrefix(trim, "[") + trim = strings.TrimSuffix(trim, "]") + var envArray []string + for _, v := range strings.Split(trim, ",") { + trimSub := strings.TrimPrefix(v, "\"") + trimSub = strings.TrimSuffix(trimSub, "\"") + envArray = append(envArray, trimSub) + } + Set(ConfKey, envArray) + } + } +} + +func EnvInit() { + var dict = map[string][]string{ + "server": {"address", "debug_mode", "file_logger"}, + "database": {"type", "host", "name", "username", "password"}, + } + for key, value := range dict { + for _, sub := range value { + SetEnvConf(key, sub) + } + } +} + +func TZ() string { + tz := GetEnv("TZ") + if tz == "" { + return "Asia/Shanghai" + } + return tz +} diff --git a/config/types.go b/config/types.go new file mode 100644 index 0000000..274db3e --- /dev/null +++ b/config/types.go @@ -0,0 +1,20 @@ +package config + +type config struct { + Server server `yaml:"server"` + Database database `yaml:"database"` +} + +type server struct { + Address string `yaml:"address"` + DebugMode bool `yaml:"debug_mode"` + FileLogger bool `yaml:"file_logger"` +} + +type database struct { + Type string `yaml:"type"` + Host string `yaml:"host"` + Name string `yaml:"name"` + Username string `yaml:"username"` + Password string `yaml:"password"` +} diff --git a/data/drivers/postgres.go b/data/drivers/postgres.go new file mode 100644 index 0000000..be96afb --- /dev/null +++ b/data/drivers/postgres.go @@ -0,0 +1,24 @@ +package drivers + +import ( + "nixcn-cms/config" + "strings" + + "gorm.io/driver/postgres" + "gorm.io/gorm" +) + +func SplitHostPort(url string) (host, port string) { + if !strings.Contains(url, ":") { + return url, "5432" + } + split := strings.Split(url, ":") + return split[0], split[1] +} + +func Postgres(dsn ExternalDSN) (*DBClient, error) { + host, port := SplitHostPort(dsn.Host) + conn := "host=" + host + " user=" + dsn.Username + " password=" + dsn.Password + " dbname=" + dsn.Name + " port=" + port + " sslmode=disable TimeZone=" + config.TZ() + db, err := gorm.Open(postgres.Open(conn), &gorm.Config{}) + return &DBClient{db}, err +} diff --git a/data/drivers/types.go b/data/drivers/types.go new file mode 100644 index 0000000..3936553 --- /dev/null +++ b/data/drivers/types.go @@ -0,0 +1,16 @@ +package drivers + +import ( + "gorm.io/gorm" +) + +type ExternalDSN struct { + Host string + Name string + Username string + Password string +} + +type DBClient struct { + *gorm.DB +} diff --git a/go.mod b/go.mod index dd334f5..54bb075 100644 --- a/go.mod +++ b/go.mod @@ -23,6 +23,7 @@ require ( github.com/jackc/puddle/v2 v2.2.2 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect + github.com/joho/godotenv v1.5.1 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect diff --git a/go.sum b/go.sum index 633e1e6..92cbdce 100644 --- a/go.sum +++ b/go.sum @@ -41,6 +41,8 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= diff --git a/logger/logrus.go b/logger/logrus.go index e4578ff..1ff2e7b 100644 --- a/logger/logrus.go +++ b/logger/logrus.go @@ -1,6 +1,7 @@ package logger import ( + "nixcn-cms/config" "os" "time" @@ -9,8 +10,8 @@ import ( ) func Init() { - FileLogger := false - DebugMode := true + FileLogger := config.Get("server.file_logger").(bool) + DebugMode := config.Get("server.debug_mode").(bool) if FileLogger { gin.DisableConsoleColor() diff --git a/main.go b/main.go index 1775c9a..994fe0b 100644 --- a/main.go +++ b/main.go @@ -1,11 +1,13 @@ package main import ( + "nixcn-cms/config" "nixcn-cms/logger" "nixcn-cms/server" ) func main() { + config.Init() logger.Init() - server.Start(":8000") + server.Start() } diff --git a/server/server.go b/server/server.go index 66aceac..cdc28b2 100644 --- a/server/server.go +++ b/server/server.go @@ -2,6 +2,7 @@ package server import ( "net/http" + "nixcn-cms/config" "nixcn-cms/logger" "time" @@ -9,7 +10,7 @@ import ( log "github.com/sirupsen/logrus" ) -func Start(addr string) { +func Start() { r := gin.Default() r.Use(logger.Gin(), gin.Recovery()) @@ -17,14 +18,14 @@ func Start(addr string) { // Start http server server := &http.Server{ - Addr: addr, + Addr: config.Get("server.address").(string), Handler: r, ReadTimeout: 10 * time.Second, WriteTimeout: 10 * time.Second, MaxHeaderBytes: 1 << 20, } - log.Info("Starting server on :8080...") + log.Info("Starting server on " + config.Get("server.address").(string)) if err := server.ListenAndServe(); err != nil { log.Errorf("Error starting server: %v\n", err) }