<?php
/**
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
*
* @copyright Copyright (c) 2008-2009 Ne8, LLC <josh.ribakoff@gmail.com>
* @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 . '`' );
}
}
}