日期:2014-05-16 浏览次数:20618 次
<?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 {