mirror of https://github.com/cloudreve/Cloudreve
Feat: Decide whether to do database migration based on `version.lock`
parent
c5493fd1f1
commit
e858cbe2cf
|
@ -13,3 +13,6 @@
|
||||||
|
|
||||||
# Development enviroment
|
# Development enviroment
|
||||||
.idea/
|
.idea/
|
||||||
|
|
||||||
|
# Version control
|
||||||
|
version.lock
|
|
@ -1,3 +1,6 @@
|
||||||
|
[System]
|
||||||
|
Debug = true
|
||||||
|
|
||||||
[Database]
|
[Database]
|
||||||
Type = mysql
|
Type = mysql
|
||||||
User = root
|
User = root
|
||||||
|
|
3
go.mod
3
go.mod
|
@ -1,4 +1,4 @@
|
||||||
module Cloudreve
|
module cloudreve
|
||||||
|
|
||||||
go 1.12
|
go 1.12
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ require (
|
||||||
github.com/go-playground/universal-translator v0.16.0 // indirect
|
github.com/go-playground/universal-translator v0.16.0 // indirect
|
||||||
github.com/jinzhu/gorm v1.9.11
|
github.com/jinzhu/gorm v1.9.11
|
||||||
github.com/leodido/go-urn v1.2.0 // indirect
|
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/pkg/errors v0.8.0
|
||||||
github.com/stretchr/testify v1.4.0
|
github.com/stretchr/testify v1.4.0
|
||||||
gopkg.in/go-playground/validator.v8 v8.18.2
|
gopkg.in/go-playground/validator.v8 v8.18.2
|
||||||
|
|
13
main.go
13
main.go
|
@ -1,18 +1,23 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Cloudreve/models"
|
"cloudreve/models"
|
||||||
"Cloudreve/pkg/conf"
|
"cloudreve/pkg/conf"
|
||||||
"Cloudreve/routers"
|
"cloudreve/routers"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
conf.Init("conf/conf.ini")
|
conf.Init("conf/conf.ini")
|
||||||
model.Init()
|
model.Init()
|
||||||
|
|
||||||
|
// Debug 关闭时,切换为生产模式
|
||||||
|
if !conf.SystemConfig.Debug {
|
||||||
|
gin.SetMode(gin.ReleaseMode)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
api := routers.InitRouter()
|
api := routers.InitRouter()
|
||||||
|
|
||||||
api.Run(":5000")
|
api.Run(":5000")
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Cloudreve/pkg/conf"
|
"cloudreve/pkg/conf"
|
||||||
"Cloudreve/pkg/util"
|
"cloudreve/pkg/util"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
"time"
|
"time"
|
||||||
|
@ -15,7 +15,6 @@ var DB *gorm.DB
|
||||||
|
|
||||||
// Database 在中间件中初始化mysql链接
|
// Database 在中间件中初始化mysql链接
|
||||||
func Init() {
|
func Init() {
|
||||||
//TODO 从配置文件中读取 包括DEBUG模式
|
|
||||||
util.Log().Info("初始化数据库连接\n")
|
util.Log().Info("初始化数据库连接\n")
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -37,7 +36,11 @@ func Init() {
|
||||||
return conf.DatabaseConfig.TablePrefix + defaultTableName
|
return conf.DatabaseConfig.TablePrefix + defaultTableName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Debug 模式下,输出所有 SQL 日志
|
||||||
|
if conf.SystemConfig.Debug {
|
||||||
db.LogMode(true)
|
db.LogMode(true)
|
||||||
|
}
|
||||||
|
|
||||||
//db.SetLogger(util.Log())
|
//db.SetLogger(util.Log())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.Log().Panic("连接数据库不成功", err)
|
util.Log().Panic("连接数据库不成功", err)
|
||||||
|
|
|
@ -1,14 +1,31 @@
|
||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Cloudreve/pkg/util"
|
"cloudreve/pkg/conf"
|
||||||
|
"cloudreve/pkg/util"
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
|
"github.com/mcuadros/go-version"
|
||||||
|
"io/ioutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
//执行数据迁移
|
//执行数据迁移
|
||||||
func migration() {
|
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)
|
_, err := GetUser(1)
|
||||||
|
@ -29,4 +46,10 @@ func migration() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 迁移完毕后写入版本锁 version.lock
|
||||||
|
err = conf.WriteVersionLock()
|
||||||
|
if err != nil {
|
||||||
|
util.Log().Warning("无法写入版本控制锁 version.lock, ", err)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -1,8 +1,8 @@
|
||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Cloudreve/pkg/serializer"
|
"cloudreve/pkg/serializer"
|
||||||
"Cloudreve/pkg/util"
|
"cloudreve/pkg/util"
|
||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package conf
|
package conf
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Cloudreve/pkg/util"
|
"cloudreve/pkg/util"
|
||||||
"github.com/go-ini/ini"
|
"github.com/go-ini/ini"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Database 数据库
|
// database 数据库
|
||||||
type database struct {
|
type database struct {
|
||||||
Type string
|
Type string
|
||||||
User string
|
User string
|
||||||
|
@ -19,6 +19,13 @@ var DatabaseConfig = &database{
|
||||||
Type: "UNSET",
|
Type: "UNSET",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// system 系统通用配置
|
||||||
|
type system struct {
|
||||||
|
Debug bool
|
||||||
|
}
|
||||||
|
|
||||||
|
var SystemConfig = &system{}
|
||||||
|
|
||||||
var cfg *ini.File
|
var cfg *ini.File
|
||||||
|
|
||||||
// Init 初始化配置文件
|
// Init 初始化配置文件
|
||||||
|
@ -30,9 +37,16 @@ func Init(path string) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.Log().Panic("无法解析配置文件 '%s': ", path, err)
|
util.Log().Panic("无法解析配置文件 '%s': ", path, err)
|
||||||
}
|
}
|
||||||
err = mapSection("Database", DatabaseConfig)
|
|
||||||
|
sections := map[string]interface{}{
|
||||||
|
"Database": DatabaseConfig,
|
||||||
|
"System": SystemConfig,
|
||||||
|
}
|
||||||
|
for sectionName, sectionStruct := range sections {
|
||||||
|
err = mapSection(sectionName, sectionStruct)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.Log().Warning("配置文件 %s 分区解析失败: ", "Database", err)
|
util.Log().Warning("配置文件 %s 分区解析失败: ", sectionName, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,5 +78,4 @@ TablePrefix = v3_`
|
||||||
err = mapSection("Database", DatabaseConfig)
|
err = mapSection("Database", DatabaseConfig)
|
||||||
asserts.NoError(err)
|
asserts.NoError(err)
|
||||||
|
|
||||||
// TODO 类型不匹配测试
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
package controllers
|
package controllers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Cloudreve/pkg/serializer"
|
"cloudreve/pkg/serializer"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"gopkg.in/go-playground/validator.v8"
|
"gopkg.in/go-playground/validator.v8"
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package controllers
|
package controllers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Cloudreve/pkg/serializer"
|
"cloudreve/pkg/serializer"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package controllers
|
package controllers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Cloudreve/pkg/serializer"
|
"cloudreve/pkg/serializer"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package controllers
|
package controllers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Cloudreve/service/user"
|
"cloudreve/service/user"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package routers
|
package routers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Cloudreve/routers/controllers"
|
"cloudreve/routers/controllers"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"Cloudreve/pkg/serializer"
|
"cloudreve/pkg/serializer"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue