diff --git a/.gitignore b/.gitignore index 423daee..c840f86 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,7 @@ *.out # Development enviroment -.idea/ \ No newline at end of file +.idea/ + +# Version control +version.lock \ No newline at end of file diff --git a/conf/conf.ini b/conf/conf.ini index 0ce3ce3..0663538 100644 --- a/conf/conf.ini +++ b/conf/conf.ini @@ -1,3 +1,6 @@ +[System] +Debug = true + [Database] Type = mysql User = root diff --git a/go.mod b/go.mod index d7a110b..3b04447 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module Cloudreve +module cloudreve go 1.12 @@ -10,6 +10,7 @@ require ( github.com/go-playground/universal-translator v0.16.0 // indirect github.com/jinzhu/gorm v1.9.11 github.com/leodido/go-urn v1.2.0 // indirect + github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2 github.com/pkg/errors v0.8.0 github.com/stretchr/testify v1.4.0 gopkg.in/go-playground/validator.v8 v8.18.2 diff --git a/main.go b/main.go index 7c79a84..3e05eed 100644 --- a/main.go +++ b/main.go @@ -1,18 +1,23 @@ package main import ( - "Cloudreve/models" - "Cloudreve/pkg/conf" - "Cloudreve/routers" + "cloudreve/models" + "cloudreve/pkg/conf" + "cloudreve/routers" + "github.com/gin-gonic/gin" ) func init() { conf.Init("conf/conf.ini") model.Init() + + // Debug 关闭时,切换为生产模式 + if !conf.SystemConfig.Debug { + gin.SetMode(gin.ReleaseMode) + } } func main() { - api := routers.InitRouter() api.Run(":5000") diff --git a/models/init.go b/models/init.go index 6968833..7db3ca1 100644 --- a/models/init.go +++ b/models/init.go @@ -1,8 +1,8 @@ package model import ( - "Cloudreve/pkg/conf" - "Cloudreve/pkg/util" + "cloudreve/pkg/conf" + "cloudreve/pkg/util" "fmt" "github.com/jinzhu/gorm" "time" @@ -15,7 +15,6 @@ var DB *gorm.DB // Database 在中间件中初始化mysql链接 func Init() { - //TODO 从配置文件中读取 包括DEBUG模式 util.Log().Info("初始化数据库连接\n") var ( @@ -37,7 +36,11 @@ func Init() { return conf.DatabaseConfig.TablePrefix + defaultTableName } - db.LogMode(true) + // Debug 模式下,输出所有 SQL 日志 + if conf.SystemConfig.Debug { + db.LogMode(true) + } + //db.SetLogger(util.Log()) if err != nil { util.Log().Panic("连接数据库不成功", err) diff --git a/models/migration.go b/models/migration.go index 4561c1b..abdcf3d 100644 --- a/models/migration.go +++ b/models/migration.go @@ -1,14 +1,31 @@ package model import ( - "Cloudreve/pkg/util" + "cloudreve/pkg/conf" + "cloudreve/pkg/util" "github.com/jinzhu/gorm" + "github.com/mcuadros/go-version" + "io/ioutil" ) //执行数据迁移 func migration() { + // 检查 version.lock 确认是否需要执行迁移 + // Debug 模式下一定会执行迁移 + if !conf.SystemConfig.Debug { + if util.Exists("version.lock") { + versionLock, _ := ioutil.ReadFile("version.lock") + if version.Compare(string(versionLock), conf.BackendVersion, "=") { + util.Log().Info("后端版本匹配,跳过数据库迁移") + return + } + } + } + + util.Log().Info("开始进行数据库自动迁移...") + // 自动迁移模式 - DB.Set("gorm:table_options", "ENGINE=InnoDB").AutoMigrate(&User{}) + DB.Set("gorm:table_options", "ENGINE=InnoDB").AutoMigrate(&User{}, &Setting{}) // 添加初始用户 _, err := GetUser(1) @@ -29,4 +46,10 @@ func migration() { } } + // 迁移完毕后写入版本锁 version.lock + err = conf.WriteVersionLock() + if err != nil { + util.Log().Warning("无法写入版本控制锁 version.lock, ", err) + } + } diff --git a/models/setting.go b/models/setting.go new file mode 100644 index 0000000..7e7932c --- /dev/null +++ b/models/setting.go @@ -0,0 +1,26 @@ +package model + +import ( + "github.com/jinzhu/gorm" +) + +// Setting 系统设置模型 +type Setting struct { + gorm.Model + Type string `gorm:"not null"` + Name string `gorm:"unique;not null;index:setting_key"` + Value string `gorm:"size:‎65535"` +} + +// GetSettingByName 用 Name 获取设置值 +func GetSettingByName(name string) (Setting, error) { + var setting Setting + + // 优先尝试数据库中查找 + result := DB.Where("name = ?", name).First(&setting) + if result.Error == nil { + return setting, nil + } + + return setting, result.Error +} diff --git a/models/user.go b/models/user.go index c9962c4..4013134 100644 --- a/models/user.go +++ b/models/user.go @@ -1,8 +1,8 @@ package model import ( - "Cloudreve/pkg/serializer" - "Cloudreve/pkg/util" + "cloudreve/pkg/serializer" + "cloudreve/pkg/util" "crypto/sha1" "encoding/hex" "encoding/json" diff --git a/pkg/conf/conf.go b/pkg/conf/conf.go index fe051f3..c516db4 100644 --- a/pkg/conf/conf.go +++ b/pkg/conf/conf.go @@ -1,11 +1,11 @@ package conf import ( - "Cloudreve/pkg/util" + "cloudreve/pkg/util" "github.com/go-ini/ini" ) -// Database 数据库 +// database 数据库 type database struct { Type string User string @@ -19,6 +19,13 @@ var DatabaseConfig = &database{ Type: "UNSET", } +// system 系统通用配置 +type system struct { + Debug bool +} + +var SystemConfig = &system{} + var cfg *ini.File // Init 初始化配置文件 @@ -30,9 +37,16 @@ func Init(path string) { if err != nil { util.Log().Panic("无法解析配置文件 '%s': ", path, err) } - err = mapSection("Database", DatabaseConfig) - if err != nil { - util.Log().Warning("配置文件 %s 分区解析失败: ", "Database", err) + + sections := map[string]interface{}{ + "Database": DatabaseConfig, + "System": SystemConfig, + } + for sectionName, sectionStruct := range sections { + err = mapSection(sectionName, sectionStruct) + if err != nil { + util.Log().Warning("配置文件 %s 分区解析失败: ", sectionName, err) + } } } diff --git a/pkg/conf/conf_test.go b/pkg/conf/conf_test.go index 0eb2073..3a30578 100644 --- a/pkg/conf/conf_test.go +++ b/pkg/conf/conf_test.go @@ -78,5 +78,4 @@ TablePrefix = v3_` err = mapSection("Database", DatabaseConfig) asserts.NoError(err) - // TODO 类型不匹配测试 } diff --git a/pkg/conf/version.go b/pkg/conf/version.go new file mode 100644 index 0000000..e7c7724 --- /dev/null +++ b/pkg/conf/version.go @@ -0,0 +1,11 @@ +package conf + +import "io/ioutil" + +const BackendVersion = string("3.0.0-b") + +// WriteVersionLock 将当前版本信息写入 version.lock +func WriteVersionLock() error { + err := ioutil.WriteFile("version.lock", []byte(BackendVersion), 0644) + return err +} diff --git a/pkg/util/io.go b/pkg/util/io.go new file mode 100644 index 0000000..c6426eb --- /dev/null +++ b/pkg/util/io.go @@ -0,0 +1,13 @@ +package util + +import "os" + +// Exists reports whether the named file or directory exists. +func Exists(name string) bool { + if _, err := os.Stat(name); err != nil { + if os.IsNotExist(err) { + return false + } + } + return true +} diff --git a/routers/controllers/main.go b/routers/controllers/main.go index 7890b87..4be49f8 100644 --- a/routers/controllers/main.go +++ b/routers/controllers/main.go @@ -1,7 +1,7 @@ package controllers import ( - "Cloudreve/pkg/serializer" + "cloudreve/pkg/serializer" "encoding/json" "gopkg.in/go-playground/validator.v8" ) diff --git a/routers/controllers/main_test.go b/routers/controllers/main_test.go index 6111d5c..9c6eab1 100644 --- a/routers/controllers/main_test.go +++ b/routers/controllers/main_test.go @@ -1,7 +1,7 @@ package controllers import ( - "Cloudreve/pkg/serializer" + "cloudreve/pkg/serializer" "encoding/json" "errors" "github.com/stretchr/testify/assert" diff --git a/routers/controllers/ping.go b/routers/controllers/ping.go index 6f4b27c..27de994 100644 --- a/routers/controllers/ping.go +++ b/routers/controllers/ping.go @@ -1,7 +1,7 @@ package controllers import ( - "Cloudreve/pkg/serializer" + "cloudreve/pkg/serializer" "github.com/gin-gonic/gin" ) diff --git a/routers/controllers/user.go b/routers/controllers/user.go index c9b1435..162a740 100644 --- a/routers/controllers/user.go +++ b/routers/controllers/user.go @@ -1,7 +1,7 @@ package controllers import ( - "Cloudreve/service/user" + "cloudreve/service/user" "github.com/gin-gonic/gin" ) diff --git a/routers/router.go b/routers/router.go index a8332b6..8cc0f3e 100644 --- a/routers/router.go +++ b/routers/router.go @@ -1,7 +1,7 @@ package routers import ( - "Cloudreve/routers/controllers" + "cloudreve/routers/controllers" "github.com/gin-gonic/gin" ) diff --git a/service/user/user_login.go b/service/user/user_login.go index 8c9930e..24b5c78 100644 --- a/service/user/user_login.go +++ b/service/user/user_login.go @@ -1,7 +1,7 @@ package service import ( - "Cloudreve/pkg/serializer" + "cloudreve/pkg/serializer" "github.com/gin-gonic/gin" )