* @license New BSD License */ abstract class Shuffler_DB_Refactor { /** * @var Shuffler_Db_Factory */ protected $factory; public function __construct( Shuffler_Db_Factory $factory ) { $this->factory = $factory; } /** * @return integer */ abstract protected function getCurrentVersion(); /** * @return array */ abstract protected function getTables(); abstract protected function createDatabases(); abstract protected function dropDatabases(); abstract protected function createVersionTable(); abstract protected function getSchemaNameForVersionTable(); abstract protected function getMysqlCommand(); public function execute( $pathToScripts, $reset = false, $toVersion = null ) { try { $currentVersion = $this->getCurrentVersion(); } catch ( Exception $e ) { $this->createDatabases(); $currentVersion = 0; } if( $reset || $currentVersion == 0 ) { $this->dropDatabases(); $this->createDatabases(); $this->createVersionTable(); $currentVersion = 0; } self::migrate( $pathToScripts, $currentVersion, $toVersion ); } /** * Bring the database to a requested version # */ function migrate( $pathToScripts, $fromVersion = 0, $toVersion = NULL ) { // get all the database refactoring scripts $files = glob( $pathToScripts . '/*' ); foreach( $files as $key => $val ) { $files[ $key ] = basename( $val ); } // sort the files in version order asort( $files, SORT_NUMERIC ); foreach( $files as $file ) { // get the version # from the filename preg_match( '#^([0-9]+)_#', basename( $file ), $matches ); if( !isset( $matches[1] ) ) { continue; } $version = $matches[1]; if( $version <= $fromVersion ) { // already loaded this version, skip it continue; } if( !is_null( $toVersion ) ) { if( $version > $toVersion ) { echo 'stopping short at version ' . $toVersion; break; } } self::runScript( $version, $pathToScripts . '/' . $file ); } } /** * run the version + script as php or SQL * updates the version table */ function runScript( $version, $file ) { ob_implicit_flush(); echo basename($file) . "\n"; $schema = ''; if( $version != 1 ) { $schema = $this->getSchemaNameForVersionTable(); } if( substr( $file, -3 ) == 'php' ) { if( $version != 1 ) { mysql_select_db( $schema ); } require( $file ); } else // or as sql { $cmd = $this->getMysqlCommand() . ' ' . $schema . ' < "' . $file . '"'; //echo( $cmd ); passthru( $cmd ); } mysql_query( 'UPDATE `version` SET `version` = ' . (int)$version ); } /** * Drop requested tables * * @param Shuffler_Factory * @param array of tables */ function dropTables( $factory, $tables ) { foreach( $tables as $table ) { mysql_query( 'DROP TABLE `' . $table . '`' ); } } }