| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 | 
							- // 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 migrate
 
- import (
 
- 	"os"
 
- 	"log"
 
- 	"github.com/lifei6671/godoc/models"
 
- 	"container/list"
 
- 	"fmt"
 
- 	"github.com/astaxie/beego"
 
- 	"github.com/astaxie/beego/orm"
 
- )
 
- 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())
 
- }
 
 
  |