255 lines
8.3 KiB
Go
255 lines
8.3 KiB
Go
package models
|
||
|
||
import (
|
||
"database/sql"
|
||
"errors"
|
||
"fmt"
|
||
"github.com/astaxie/beego"
|
||
"github.com/astaxie/beego/logs"
|
||
"github.com/phachon/mm-wiki/app/utils"
|
||
"github.com/phachon/mm-wiki/global"
|
||
"time"
|
||
)
|
||
|
||
type Upgrade struct {
|
||
}
|
||
|
||
type upgradeHandleFunc func() error
|
||
|
||
type upgradeHandle struct {
|
||
Version string
|
||
Func upgradeHandleFunc
|
||
}
|
||
|
||
var (
|
||
UpgradeModel = Upgrade{}
|
||
|
||
upgradeMap = []*upgradeHandle{}
|
||
)
|
||
|
||
// upgrade handle func
|
||
func (up *Upgrade) initHandleFunc() {
|
||
// v0 ~ v0.1.2
|
||
upgradeMap = append(upgradeMap, &upgradeHandle{Version: "v0.1.2", Func: up.v0ToV012})
|
||
|
||
// v0.1.2 ~ v0.1.3
|
||
upgradeMap = append(upgradeMap, &upgradeHandle{Version: "v0.1.3", Func: up.v012ToV013})
|
||
|
||
// v0.1.3 ~ v0.1.8
|
||
upgradeMap = append(upgradeMap, &upgradeHandle{Version: "v0.1.8", Func: up.v013ToV018})
|
||
|
||
// v0.1.8 ~ v0.2.0
|
||
upgradeMap = append(upgradeMap, &upgradeHandle{Version: "v0.2.0", Func: up.v018ToV020})
|
||
|
||
// v0.2.1 ~ v0.2.7
|
||
//upgradeMap = append(upgradeMap, &upgradeHandle{Version: "v0.2.7", Func: up.v021ToV027})
|
||
// v0.2.7 ~ v0.3.3
|
||
//upgradeMap = append(upgradeMap, &upgradeHandle{Version: "v0.3.3", Func: up.v027ToV033})
|
||
}
|
||
|
||
// upgrade start
|
||
func (up *Upgrade) Start(dbVersion string) (err error) {
|
||
up.initHandleFunc()
|
||
|
||
var tmpVersion = dbVersion
|
||
for _, upHandle := range upgradeMap {
|
||
// upgrade now version, exit
|
||
if tmpVersion == global.SYSTEM_VERSION {
|
||
break
|
||
}
|
||
// tmpVersion < upHandle.version
|
||
if utils.VersionCompare.Lt(tmpVersion, upHandle.Version) {
|
||
// upgrade handle
|
||
err = upHandle.Func()
|
||
if err != nil {
|
||
logs.Error("upgrade to " + upHandle.Version + " error: " + err.Error())
|
||
return errors.New("upgrade to " + upHandle.Version + " error: " + err.Error())
|
||
}
|
||
// update system database version
|
||
err = up.upgradeAfter(upHandle.Version)
|
||
if err != nil {
|
||
logs.Error("upgrade to database " + upHandle.Version + " error: " + err.Error())
|
||
return errors.New("upgrade to database " + upHandle.Version + " error: " + err.Error())
|
||
}
|
||
logs.Info("upgrade to " + upHandle.Version + " success")
|
||
// update version record
|
||
tmpVersion = upHandle.Version
|
||
}
|
||
}
|
||
// last update current version
|
||
err = up.upgradeAfter(global.SYSTEM_VERSION)
|
||
if err != nil {
|
||
logs.Error("upgrade to database " + global.SYSTEM_VERSION + " error: " + err.Error())
|
||
return errors.New("upgrade to database " + global.SYSTEM_VERSION + " error: " + err.Error())
|
||
}
|
||
logs.Info("upgrade finish, version: " + global.SYSTEM_VERSION)
|
||
|
||
return nil
|
||
}
|
||
|
||
// upgrade v0.0.0 ~ v0.1.2
|
||
func (up *Upgrade) v0ToV012() (err error) {
|
||
|
||
// 1. add privilege '/email/test'
|
||
// INSERT INTO mw_privilege (name, parent_id, type, controller, action, icon, target, is_display, sequence, create_time, update_time) VALUES ('测试邮件服务器', 53, 'controller', 'email', 'test', 'glyphicon-list', 0, 80, unix_timestamp(now()), unix_timestamp(now()));
|
||
privilege := map[string]interface{}{
|
||
"name": "测试邮件服务器",
|
||
"type": "controller",
|
||
"parent_id": 53,
|
||
"controller": "email",
|
||
"action": "test",
|
||
"target": "",
|
||
"icon": "glyphicon-list",
|
||
"is_display": 0,
|
||
"sequence": 80,
|
||
}
|
||
_, err = PrivilegeModel.InsertNotExists(privilege)
|
||
if err != nil {
|
||
return
|
||
}
|
||
|
||
// 2. table mw_email add field 'is_ssl'
|
||
// alter table mw_email add `is_ssl` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否使用ssl, 0 默认不使用 1 使用' after `password`
|
||
db := G.DB()
|
||
db.Exec(db.AR().Raw("alter table mw_email DROP COLUMN `is_ssl`"))
|
||
_, err = db.Exec(db.AR().Raw("alter table mw_email add `is_ssl` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否使用ssl, 0 默认不使用 1 使用' after `password`"))
|
||
|
||
return
|
||
}
|
||
|
||
// upgrade v0.1.2 ~ v0.1.3
|
||
func (up *Upgrade) v012ToV013() error {
|
||
|
||
// create attachment table
|
||
sql := "DROP TABLE IF EXISTS `mw_attachment`;" +
|
||
"CREATE TABLE `mw_attachment` (" +
|
||
"`attachment_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '附件 id'," +
|
||
"`user_id` int(10) NOT NULL DEFAULT '0' COMMENT '创建用户id'," +
|
||
"`document_id` int(10) NOT NULL DEFAULT '0' COMMENT '所属文档id'," +
|
||
"`name` varchar(50) NOT NULL DEFAULT '' COMMENT '附件名称'," +
|
||
"`path` varchar(100) NOT NULL DEFAULT '' COMMENT '附件路径'," +
|
||
"`source` tinyint(1) NOT NULL DEFAULT '0' COMMENT '附件来源, 0 默认是附件 1 图片'," +
|
||
"`create_time` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间'," +
|
||
"`update_time` int(11) NOT NULL DEFAULT '0' COMMENT '更新时间'," +
|
||
"PRIMARY KEY (`attachment_id`)," +
|
||
"KEY (`document_id`, `source`)" +
|
||
") ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='附件信息表';"
|
||
|
||
return up.createTable(sql)
|
||
}
|
||
|
||
// upgrade v0.1.3 ~ v0.1.8
|
||
func (up *Upgrade) v013ToV018() error {
|
||
db := G.DB()
|
||
|
||
// 1. 文档日志表增加 space_id 字段
|
||
// `space_id` int(10) NOT NULL DEFAULT '0' COMMENT '空间id'
|
||
_, err := db.Exec(db.AR().Raw("alter table mw_log_document add `space_id` int(10) NOT NULL DEFAULT '0' COMMENT '空间ID'"))
|
||
if err == nil {
|
||
// 文档日志表里的 space_id
|
||
_, err = db.Exec(db.AR().Raw("update mw_log_document as logDocment, mw_document as document set logDocment.space_id = document.space_id WHERE logDocment.document_id = document.document_id"))
|
||
if err != nil {
|
||
return err
|
||
}
|
||
}
|
||
|
||
// 2. 修改文档表里的排序号,需要先判断排序号是否已经修改过(只修改sequence=0)
|
||
_, err = db.Exec(db.AR().Raw("update mw_document set mw_document.sequence = mw_document.document_id WHERE sequence=0"))
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// upgrade v0.1.8 ~ v0.2.0
|
||
func (up *Upgrade) v018ToV020() error {
|
||
// 配置表增加数据
|
||
db := G.DB()
|
||
updateTime := time.Now().Unix()
|
||
// 1. 配置表增加全文搜索开关
|
||
insertSql := fmt.Sprintf("INSERT INTO `mw_config` (name, `key`, value, create_time, update_time) VALUES ('开启全文搜索', 'fulltext_search_open', '1', %d, %d)", updateTime, updateTime)
|
||
_, err := db.Exec(db.AR().Raw(insertSql))
|
||
if err != nil {
|
||
return err
|
||
}
|
||
// 2. 配置表增加搜索索引时间间隔
|
||
insertSql = fmt.Sprintf("INSERT INTO `mw_config` (name, `key`, value, create_time, update_time) VALUES ('索引更新间隔', 'doc_search_timer', '3600', %d, %d)", updateTime, updateTime)
|
||
_, err = db.Exec(db.AR().Raw(insertSql))
|
||
if err != nil {
|
||
return err
|
||
}
|
||
// 3. 配置表增加系统名称配置
|
||
insertSql = fmt.Sprintf("INSERT INTO `mw_config` (name, `key`, value, create_time, update_time) VALUES ('系统名称', 'system_name', 'Markdown Mini Wiki', %d, %d)", updateTime, updateTime)
|
||
_, err = db.Exec(db.AR().Raw(insertSql))
|
||
if err != nil {
|
||
return err
|
||
}
|
||
// 4. 权限表增加导入联系人权限
|
||
// INSERT INTO mw_privilege (privilege_id, name, parent_id, type, controller, action, icon, target, is_display, sequence, create_time, update_time) VALUES (93, '导入联系人', 71, 'controller', 'contact', 'import', 'glyphicon-list', '', 0, 97, unix_timestamp(now()), unix_timestamp(now()));
|
||
privilege := map[string]interface{}{
|
||
"name": "导入联系人",
|
||
"type": "controller",
|
||
"parent_id": 71,
|
||
"controller": "contact",
|
||
"action": "import",
|
||
"target": "",
|
||
"icon": "glyphicon-list",
|
||
"is_display": 0,
|
||
"sequence": 97,
|
||
}
|
||
_, err = PrivilegeModel.InsertNotExists(privilege)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// upgrade v0.2.1 ~ v0.2.7
|
||
func (up *Upgrade) v021ToV027() error {
|
||
return nil
|
||
}
|
||
|
||
// upgrade v0.2.7 ~ v0.3.3
|
||
func (up *Upgrade) v027ToV033() error {
|
||
return nil
|
||
}
|
||
|
||
func (up *Upgrade) createTable(sqlTable string) error {
|
||
host := beego.AppConfig.String("db::host")
|
||
port, _ := beego.AppConfig.Int("db::port")
|
||
user := beego.AppConfig.String("db::user")
|
||
pass := beego.AppConfig.String("db::pass")
|
||
name := beego.AppConfig.String("db::name")
|
||
db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&multiStatements=true", user, pass, host, port, name))
|
||
if err != nil {
|
||
return err
|
||
}
|
||
defer db.Close()
|
||
_, err = db.Exec(sqlTable)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
return nil
|
||
}
|
||
|
||
func (up *Upgrade) upgradeAfter(version string) (err error) {
|
||
// update system version
|
||
config, err := ConfigModel.GetConfigByKey(ConfigKeySystemVersion)
|
||
if err != nil {
|
||
return
|
||
}
|
||
if len(config) == 0 {
|
||
configValue := map[string]interface{}{
|
||
"name": "系统版本号",
|
||
"key": "system_version",
|
||
"value": version,
|
||
}
|
||
_, err = ConfigModel.Insert(configValue)
|
||
} else {
|
||
_, err = ConfigModel.UpdateByKey(ConfigKeySystemVersion, version)
|
||
}
|
||
|
||
return err
|
||
}
|