| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 | // Copyright 2013 bee authors//// Licensed under the Apache License, Version 2.0 (the "License"): you may// not use this file except in compliance with the License. You may obtain// a copy of the License at////     http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the// License for the specific language governing permissions and limitations// under the License.package migrateimport (	"os"	"container/list"	"fmt"	"github.com/astaxie/beego"	"github.com/astaxie/beego/orm"	"github.com/lifei6671/mindoc/models"	"log")var (	migrationList = &migrationCache{})type MigrationDatabase interface {	//获取当前的版本	Version() int64	//校验当前是否可更新	ValidUpdate(version int64) error	//校验并备份表结构	ValidForBackupTableSchema() error	//校验并更新表结构	ValidForUpdateTableSchema() error	//恢复旧数据	MigrationOldTableData() error	//插入新数据	MigrationNewTableData() error	//增加迁移记录	AddMigrationRecord(version int64) error	//最后的清理工作	MigrationCleanup() error	//回滚本次迁移	RollbackMigration() error}type migrationCache struct {	items *list.List}func RunMigration() {	if len(os.Args) >= 2 && os.Args[1] == "migrate" {		migrate, err := models.NewMigration().FindFirst()		if err != nil {			//log.Fatalf("migrations table %s", err)			migrate = models.NewMigration()		}		fmt.Println("Start migration databae... ")		for el := migrationList.items.Front(); el != nil; el = el.Next() {			//如果存在比当前版本大的版本,则依次升级			if item, ok := el.Value.(MigrationDatabase); ok && item.Version() > migrate.Version {				err := item.ValidUpdate(migrate.Version)				if err != nil {					log.Fatal(err)				}				err = item.ValidForBackupTableSchema()				if err != nil {					item.RollbackMigration()					log.Fatal(err)				}				err = item.ValidForUpdateTableSchema()				if err != nil {					item.RollbackMigration()					log.Fatal(err)				}				err = item.MigrationOldTableData()				if err != nil {					item.RollbackMigration()					log.Fatal(err)				}				err = item.MigrationNewTableData()				if err != nil {					item.RollbackMigration()					log.Fatal(err)				}				err = item.AddMigrationRecord(item.Version())				if err != nil {					item.RollbackMigration()					log.Fatal(err)				}				err = item.MigrationCleanup()				if err != nil {					item.RollbackMigration()					log.Fatal(err)				}			}		}		fmt.Println("Migration successfull.")		os.Exit(0)	}}//导出数据库的表结构func ExportDatabaseTable() ([]string, error) {	db_adapter := beego.AppConfig.String("db_adapter")	db_database := beego.AppConfig.String("db_database")	tables := make([]string, 0)	o := orm.NewOrm()	switch db_adapter {	case "mysql":		{			var lists []orm.Params			_, err := o.Raw(fmt.Sprintf("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '%s'", db_database)).Values(&lists)			if err != nil {				return tables, err			}			for _, table := range lists {				var results []orm.Params				_, err = o.Raw(fmt.Sprintf("show create table %s", table["TABLE_NAME"])).Values(&results)				if err != nil {					return tables, err				}				tables = append(tables, results[0]["Create Table"].(string))			}			break		}	case "sqlite3":		{			var results []orm.Params			_, err := o.Raw("SELECT sql FROM sqlite_master WHERE sql IS NOT NULL ORDER BY rootpage ASC").Values(&results)			if err != nil {				return tables, err			}			for _, item := range results {				if sql, ok := item["sql"]; ok {					tables = append(tables, sql.(string))				}			}			break		}	}	return tables, nil}func RegisterMigration() {	migrationList.items = list.New()	migrationList.items.PushBack(NewMigrationVersion03())}
 |