日期:2014-05-16 浏览次数:20676 次
<?php
Core_Autoloader::loadFile(COREPATH . '/vendor/SingleTableCRUD.class.php',true);
/**
* 迁移操作入口
*
* @package pkg
*
*/
class Pkg_Gen_Table_Migration {
private static $migrationTable = 'sql_table_migration';
/**
* @var Pkg_Gen_Table_MigrationLog
*/
static $logger = null;
/**
* @return TplEngine
*/
private static function getTplEngine(){
static $tplEngine = null;
if (!$tplEngine){
Core_Autoloader::loadFile(COREPATH . '/vendor/TplEngine.class.php');
$tplConfig = array(
'templateDir' => dirname(__FILE__) . '/_views',
'enableCache' => false,
);
$tplEngine = new TplEngine($tplConfig);
}
return $tplEngine;
}
private static function getMigrations($migrationDir,$tableClassPrefix){
static $migrations = null;
if ($migrations) return $migrations;
$migrations = array();
$index = 1;
// 获取迁移类对象
foreach (glob("{$migrationDir}/*.php") as $filename) {
$id = basename($filename,'.php');
$className = "{$tableClassPrefix}{$id}";
// 加载迁移类到系统
Core_Autoloader::loadClass($className);
$obj = new $className();
// 校验迁移类是否实现了Pkg_Gen_Table_MigrationElement接口
if ( !($obj instanceof Pkg_Gen_Table_MigrationElement) ){
throw new Core_Exception_TypeMismatch('迁移类对象','Pkg_Gen_Table_MigrationElement',$className);
}
$migrations[$index] = array('id' =>$id,'class' => $className ,'instance' => $obj);
$index ++;
}
return $migrations;
}
private static function initMigrationTable(Core_DB $dbo){
static $is = false;
if (!$is){
$row = $dbo->getRow( sprintf("SHOW TABLES LIKE '%s'",self::$migrationTable) );
if (!empty($row)){
$is = true;
return;
}
$tb = Pkg_Gen_Table_DML::newInstance($dbo,self::$migrationTable);
$tb->struct(array(
$tb->combindColumnParams('version','int',true,6),
))
->setPrimaryKey('version')
->setOptions(array(
Pkg_Gen_Table_DML::ENGINE => Pkg_Gen_Table_DML::ENGINE_INNODB,
))->create();
$tb->execute();
$is = SingleTableCRUD::insert(self::$migrationTable,array('version'=>0));
self::$logger->append($dbo->lastsql);
}
}
static function ls(Core_DB $dbo,$migrationDir,$tableClassPrefix,$saveUrl){
if ( !(is_readable($migrationDir) && is_dir($migrationDir)) )
throw new Exception("无效的迁移类文件存放路径: {$migrationDir}");
self::initMigrationTable($dbo);
$migrations = self::getMigrations($migrationDir,$tableClassPrefix);
// 得到当前版本号,缺省为0
$curversion = (int) $dbo->getOne(sprintf('select version from %s',self::$migrationTable));
self::getTplEngine()->assign('database',$dbo->getDSN('database'));
self::getTplEngine()->assign('migrations',$migrations);
self::getTplEngine()->assign('version',$curversion);
self::getTplEngine()->assign('saveurl',$saveUrl);
self::getTplEngine()->display('migrations.php');
}
static function change(Core_DB $dbo,$migrationDir,$tableClassPrefix,$newversion,$lastversion){
if ( !(is_readable($migrationDir) && is_dir($migrationDir)) )
throw new Exception("无效的迁移类文件存放路径: {$migrationDir}");
self::initMigrationTable($dbo);
$migrations = self::getMigrations($migrationDir,$tableClassPrefix);
// 得到当前版本号,缺省为0
$curversion = (int) $dbo->getOne(sprintf('select version from %s',self::$migrationTable));
if ($curversion != $lastversion) throw new Exception("无效的参数 lastversion: {$lastversion}");
if ($curversion == $newversion) throw new Exception("版本无需迁移操作");
if ($newversion > 0){
if (!isset($migrations[$newversion])) throw new Exception("无效的参数 newversion: {$newversion}");
}
// 开始进行版本迁移操作
if ($curversion > $newversion){
// 反向
for($start=$curversion,$end = $newversion; $start > $end; $start --){
$instance = $migrations[$start]['instance'];
/* @var $instance Pkg_Gen_Table_MigrationElement */
self::$logger->append($migrations[$start]['class'] . '::down()');
try {