diff --git a/CHANGELOG b/CHANGELOG index 0105d44..2cebd7a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -51,6 +51,21 @@ c. 在github上发布新版本。 3.更新tank-doc 下载内容 +TO RELEASE +tank-3.1.0 +1. Add prop column into tank31_matter + + +ALTER TABLE `tank`.`tank30_matter` +ADD COLUMN `prop` VARCHAR(1024) NULL DEFAULT '{}' AFTER `times`; + +2. Remove Migrate 20To30 + + + + + + 2019-10-13 tank-3.0.6 1. Fix the Bug of limit size. diff --git a/code/core/config.go b/code/core/config.go index 93da257..5b5a1cc 100644 --- a/code/core/config.go +++ b/code/core/config.go @@ -9,10 +9,10 @@ const ( DEFAULT_SERVER_PORT = 6010 - //db table's prefix. tank30_ means current version is tank:3.0.x - TABLE_PREFIX = "tank30_" + //db table's prefix. tank31_ means current version is tank:3.1.x + TABLE_PREFIX = "tank31_" - VERSION = "3.0.6" + VERSION = "3.1.0" ) type Config interface { diff --git a/code/rest/base_model.go b/code/rest/base_model.go index 9af7ffd..2ae5965 100644 --- a/code/rest/base_model.go +++ b/code/rest/base_model.go @@ -11,6 +11,9 @@ const ( DIRECTION_ASC = "ASC" DIRECTION_DESC = "DESC" + + EMPTY_JSON_MAP = "{}" + EMPTY_JSON_ARRAY = "[]" ) type IBase interface { diff --git a/code/rest/matter_model.go b/code/rest/matter_model.go index 608cc39..a9564f6 100644 --- a/code/rest/matter_model.go +++ b/code/rest/matter_model.go @@ -41,6 +41,7 @@ type Matter struct { Times int64 `json:"times" gorm:"type:bigint(20) not null;default:0"` Parent *Matter `json:"parent" gorm:"-"` Children []*Matter `json:"-" gorm:"-"` + Prop string `json:"prop" gorm:"type:varchar(1024) not null;default:''{}''"` } // set File's table name to be `profiles` diff --git a/code/rest/matter_service.go b/code/rest/matter_service.go index 974dc03..eaae0ac 100644 --- a/code/rest/matter_service.go +++ b/code/rest/matter_service.go @@ -351,6 +351,7 @@ func (this *MatterService) Upload(request *http.Request, file io.Reader, user *U Size: fileSize, Privacy: privacy, Path: fileRelativePath, + Prop: EMPTY_JSON_MAP, } matter = this.matterDao.Create(matter) @@ -685,6 +686,7 @@ func (this *MatterService) copy(request *http.Request, srcMatter *Matter, destDi Size: srcMatter.Size, Privacy: srcMatter.Privacy, Path: destDirMatter.Path + "/" + name, + Prop: EMPTY_JSON_MAP, } newMatter = this.matterDao.Create(newMatter) @@ -716,6 +718,7 @@ func (this *MatterService) copy(request *http.Request, srcMatter *Matter, destDi Size: srcMatter.Size, Privacy: srcMatter.Privacy, Path: destDirMatter.Path + "/" + name, + Prop: EMPTY_JSON_MAP, } newMatter = this.matterDao.Create(newMatter) diff --git a/code/rest/preference_controller.go b/code/rest/preference_controller.go index f89ce04..e327e31 100644 --- a/code/rest/preference_controller.go +++ b/code/rest/preference_controller.go @@ -42,7 +42,6 @@ func (this *PreferenceController) RegisterRoutes() map[string]func(writer http.R routeMap["/api/preference/fetch"] = this.Wrap(this.Fetch, USER_ROLE_GUEST) routeMap["/api/preference/edit"] = this.Wrap(this.Edit, USER_ROLE_ADMINISTRATOR) routeMap["/api/preference/system/cleanup"] = this.Wrap(this.SystemCleanup, USER_ROLE_ADMINISTRATOR) - routeMap["/api/preference/migrate20to30"] = this.Wrap(this.Migrate20to30, USER_ROLE_ADMINISTRATOR) return routeMap } @@ -144,12 +143,3 @@ func (this *PreferenceController) SystemCleanup(writer http.ResponseWriter, requ return this.Success("OK") } - -//migrate 2.0's db data and file data to 3.0 -func (this *PreferenceController) Migrate20to30(writer http.ResponseWriter, request *http.Request) *result.WebResult { - - this.logger.Info("start migrating from 2.0 to 3.0") - - this.preferenceService.Migrate20to30(writer, request) - return this.Success("OK") -} diff --git a/code/rest/preference_service.go b/code/rest/preference_service.go index 5f00a60..743e911 100644 --- a/code/rest/preference_service.go +++ b/code/rest/preference_service.go @@ -1,15 +1,7 @@ package rest import ( - "fmt" "github.com/eyebluecn/tank/code/core" - "github.com/eyebluecn/tank/code/tool/i18n" - "github.com/eyebluecn/tank/code/tool/result" - "github.com/eyebluecn/tank/code/tool/util" - "net/http" - "os" - "regexp" - "strings" ) //@Service @@ -71,191 +63,3 @@ func (this *PreferenceService) Cleanup() { this.Reset() } - -//migrate 2.0's db data and file data to 3.0 -func (this *PreferenceService) Migrate20to30(writer http.ResponseWriter, request *http.Request) { - - matterPath := request.FormValue("matterPath") - - if matterPath == "" { - panic(result.BadRequest("matterPath required")) - } - - this.logger.Info("start migrating from 2.0 to 3.0") - - //lock - if this.migrating { - panic(result.BadRequest("migrating work is processing")) - } else { - this.migrating = true - } - defer func() { - this.migrating = false - }() - - //delete all users with _20 - this.userDao.DeleteUsers20() - - migrateDashboardSql := "INSERT INTO `tank`.`tank30_download_token` ( `uuid`, `sort`, `update_time`, `create_time`, `user_uuid`, `matter_uuid`, `expire_time`, `ip` ) ( SELECT `uuid`, `sort`, `update_time`, `create_time`, `user_uuid`, `matter_uuid`, `expire_time`, `ip` FROM `tank`.`tank20_download_token`)" - this.logger.Info(migrateDashboardSql) - db := core.CONTEXT.GetDB().Exec(migrateDashboardSql) - if db.Error != nil { - this.logger.Error("%v", db.Error) - } - - migrateDownloadTokenSql := "INSERT INTO `tank`.`tank30_dashboard` ( `uuid`, `sort`, `update_time`, `create_time`, `invoke_num`, `total_invoke_num`, `uv`, `total_uv`, `matter_num`, `total_matter_num`, `file_size`, `total_file_size`, `avg_cost`, `dt` ) ( SELECT `uuid`, `sort`, `update_time`, `create_time`, `invoke_num`, `total_invoke_num`, `uv`, `total_uv`, `matter_num`, `total_matter_num`, `file_size`, `total_file_size`, `avg_cost`, `dt` FROM `tank`.`tank20_dashboard` )" - this.logger.Info(migrateDownloadTokenSql) - db = core.CONTEXT.GetDB().Exec(migrateDownloadTokenSql) - if db.Error != nil { - this.logger.Error("%v", db.Error) - } - - migrateMatterSql := "INSERT INTO `tank`.`tank30_matter` ( `uuid`, `sort`, `update_time`, `create_time`, `puuid`, `user_uuid`, `username`, `dir`, `name`, `md5`, `size`, `privacy`, `path`, `times` ) ( SELECT `uuid`, `sort`, `update_time`, `create_time`, `puuid`, `user_uuid`, '', `dir`, `name`, `md5`, `size`, `privacy`, `path`, `times` FROM `tank`.`tank20_matter` ) " - this.logger.Info(migrateMatterSql) - db = core.CONTEXT.GetDB().Exec(migrateMatterSql) - if db.Error != nil { - this.logger.Error("%v", db.Error) - } - - migrateUploadTokenSql := "INSERT INTO `tank`.`tank30_upload_token` ( `uuid`, `sort`, `update_time`, `create_time`, `user_uuid`, `folder_uuid`, `matter_uuid`, `expire_time`, `filename`, `privacy`, `size`, `ip` ) ( SELECT `uuid`, `sort`, `update_time`, `create_time`, `user_uuid`, `folder_uuid`, `matter_uuid`, `expire_time`, `filename`, `privacy`, `size`, `ip` FROM `tank`.`tank20_upload_token` ) " - this.logger.Info(migrateUploadTokenSql) - db = core.CONTEXT.GetDB().Exec(migrateUploadTokenSql) - if db.Error != nil { - this.logger.Error("%v", db.Error) - } - - //username in tank2.0 add _20. - migrateUserSql := "INSERT INTO `tank`.`tank30_user` ( `uuid`, `sort`, `update_time`, `create_time`, `role`, `username`, `password`, `avatar_url`, `last_ip`, `last_time`, `size_limit`, `total_size_limit`, `total_size`, `status` ) ( SELECT `uuid`, `sort`, `update_time`, `create_time`, `role`, CONCAT(`username`,'_20') as `username`, `password`, `avatar_url`, `last_ip`, `last_time`, `size_limit`, -1, 0, `status` FROM `tank`.`tank20_user` )" - this.logger.Info(migrateUserSql) - db = core.CONTEXT.GetDB().Exec(migrateUserSql) - if db.Error != nil { - this.logger.Error("%v", db.Error) - } - - //find all 2.0 users. - users := this.userDao.FindUsers20() - for _, user := range users { - this.logger.Info("start handling matters for user %s %s", user.Uuid, user.Username) - rootMatter := NewRootMatter(user) - firstLevelMatters := this.matterDao.FindByPuuidAndUserUuid(MATTER_ROOT, user.Uuid, nil) - for _, firstLevelMatter := range firstLevelMatters { - this.HandleMatter20(request, matterPath, rootMatter, firstLevelMatter, user) - } - - //adjust all the size. - this.matterService.ComputeAllDirSize(user) - } -} - -//handle matter from 2.0 -func (this *PreferenceService) HandleMatter20(request *http.Request, matterPath string, dirMatter *Matter, matter *Matter, user *User) { - defer func() { - if err := recover(); err != nil { - this.logger.Warn("HandleMatter20 occur error %v when handle matter %s %s. Ignore the error and continue. \r\n", err, matter.Uuid, matter.Name) - } - }() - - this.logger.Info("start handling matter %s", matter.Name) - - if matter == nil { - panic(result.BadRequest("matter cannot be nil.")) - } - - if user == nil { - panic(result.BadRequest("user cannot be nil.")) - } - - if dirMatter == nil { - panic(result.BadRequest("dirMatter cannot be nil")) - } - - if !dirMatter.Dir { - panic(result.BadRequest("dirMatter must be directory")) - } - - if dirMatter.UserUuid != user.Uuid { - - panic(result.BadRequest("file's user not the same")) - } - - name := matter.Name - filename := name - if name == "" { - panic(result.BadRequest("name cannot be blank")) - } - - if len(name) > MATTER_NAME_MAX_LENGTH { - - panic(result.BadRequestI18n(request, i18n.MatterNameLengthExceedLimit, len(name), MATTER_NAME_MAX_LENGTH)) - - } - - //if directory. Create it. - if matter.Dir { - - if m, _ := regexp.MatchString(MATTER_NAME_PATTERN, name); m { - panic(result.BadRequestI18n(request, i18n.MatterNameContainSpecialChars)) - } - - parts := strings.Split(dirMatter.Path, "/") - - if len(parts) > MATTER_NAME_MAX_DEPTH { - panic(result.BadRequestI18n(request, i18n.MatterDepthExceedLimit, len(parts), MATTER_NAME_MAX_DEPTH)) - } - - absolutePath := GetUserMatterRootDir(user.Username) + dirMatter.Path + "/" + name - - relativePath := dirMatter.Path + "/" + name - - //crate directory on disk. - dirPath := util.MakeDirAll(absolutePath) - this.logger.Info("Create Directory: %s", dirPath) - - //change matter info. - matter.Username = user.Username - matter.Path = relativePath - - matter = this.matterDao.Save(matter) - - //handle its children. - children := this.matterDao.FindByPuuidAndUserUuid(matter.Uuid, user.Uuid, nil) - for _, child := range children { - this.HandleMatter20(request, matterPath, matter, child, user) - } - - } else { - - //if file. copy and adjust it. - - dirAbsolutePath := dirMatter.AbsolutePath() - dirRelativePath := dirMatter.Path - - fileAbsolutePath := dirAbsolutePath + "/" + filename - fileRelativePath := dirRelativePath + "/" + filename - - util.MakeDirAll(dirAbsolutePath) - - //if exist, panic it. - exist := util.PathExists(fileAbsolutePath) - if exist { - this.logger.Error("%s exits, overwrite it.", fileAbsolutePath) - removeError := os.Remove(fileAbsolutePath) - this.PanicError(removeError) - } - - srcAbsolutePath := fmt.Sprintf("%s%s", matterPath, matter.Path) - - //find the 2.0 disk file. - fileSize := util.CopyFile(srcAbsolutePath, fileAbsolutePath) - - this.logger.Info("copy %s %v ", filename, util.HumanFileSize(fileSize)) - - //update info. - matter.Path = fileRelativePath - matter.Username = user.Username - - matter = this.matterDao.Save(matter) - - } - -} diff --git a/code/support/tank_application.go b/code/support/tank_application.go index 6c12415..9467372 100644 --- a/code/support/tank_application.go +++ b/code/support/tank_application.go @@ -25,8 +25,6 @@ const ( MODE_CRAWL = "crawl" //Current version. MODE_VERSION = "version" - //migrate 2.0 to 3.0 - MODE_MIGRATE_20_TO_30 = "migrate20to30" ) type TankApplication struct { @@ -120,10 +118,6 @@ func (this *TankApplication) Start() { this.HandleMirror() - } else if strings.ToLower(this.mode) == MODE_MIGRATE_20_TO_30 { - - this.HandleMigrate20to30() - } else if strings.ToLower(this.mode) == MODE_CRAWL { this.HandleCrawl() @@ -260,41 +254,3 @@ func (this *TankApplication) HandleVersion() { fmt.Printf("EyeblueTank %s\r\n", core.VERSION) } - -//migrate 2.0 to 3.0 -func (this *TankApplication) HandleMigrate20to30() { - - if this.src == "" { - panic("src is required") - } - - fmt.Printf("start migrating 2.0 to 3.0. MatterPath2.0 = %s \r\n", this.src) - - urlString := fmt.Sprintf("%s/api/preference/migrate20to30", this.host) - - params := url.Values{ - "matterPath": {this.src}, - core.USERNAME_KEY: {this.username}, - core.PASSWORD_KEY: {this.password}, - } - - response, err := http.PostForm(urlString, params) - core.PanicError(err) - - bodyBytes, err := ioutil.ReadAll(response.Body) - - webResult := &result.WebResult{} - - err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(bodyBytes, webResult) - if err != nil { - fmt.Printf("error response format %s \r\n", err.Error()) - return - } - - if webResult.Code == result.OK.Code { - fmt.Println("success") - } else { - fmt.Printf("error %s\r\n", webResult.Msg) - } - -}