Skip to content

Instantly share code, notes, and snippets.

@leric
Created September 15, 2011 08:50
Show Gist options
  • Save leric/1218848 to your computer and use it in GitHub Desktop.
Save leric/1218848 to your computer and use it in GitHub Desktop.
Database migrate tool using Doctrine2 DBAL
<?php
/**
* Dump database schema to schema config files
*
*/
$env = 'test';
if (empty($_SERVER['argv'][1])) {
echo "Usage: php dump.php (production|test|dev) \n";
exit();
} else {
$env = $_SERVER['argv'][1];
}
$conn = require('init.php');
$path = __DIR__ . '/' . date('YmdHis', time()) . '';
mkdir($path);
$sm = $conn->getSchemaManager();
$schema = $sm->createSchema();
foreach ($schema->getTables() as $tableName => $tableSchema) {
$sql = "SELECT `engine` FROM information_schema.tables WHERE table_schema='cms' AND table_name='acl_menu_url'";
$engine = $conn->fetchColumn($sql);
writeTableSchema($tableName, $tableSchema, $path, $engine);
}
function writeTableSchema($tableName, $tableSchema, $path, $engine) {
$code = "<?php \n\n";
$code .= "\$user_table = \$to_schema->createTable(\"{$tableName}\"); \n";
// Add columns
foreach ($tableSchema->getColumns() as $column) {
$col = $column->toArray();
$name = $col['name'];
$type = $col['type']->getName();
$options = array();
if ($col['notnull']) {
$options[] = '"notnull"=>true';
} else {
$options[] = '"notnull"=>false';
}
if ($col['default'] !== null) {
$options[] = '"default"=>"' . $col['default'] . '"';
}
if ($type != 'decimal' && $col['length'] !== null) {
$options[] = '"length"=>' . $col['length'];
} else if ($type == 'decimal' && $col['precision'] && $col['scale']) {
$options[] = '"precision"=>' . $col['precision'];
$options[] = '"scale"=>' . $col['scale'];
}
if ($col['fixed']) {
$options[] = '"fixed"=>true';
}
if ($col['unsigned']) {
$options[] = '"unsigned"=>true';
}
if ($col['autoincrement']) {
$options[] = '"autoincrement"=>true';
}
if (!empty($col['comment'])) {
$options[] = '"comment"=>"' . addslashes($col['comment']) . '"';
}
$code .= "\$user_table->addColumn(\"{$name}\", \"{$type}\", array(" . implode(',', $options) . ")); \n";
}
// Add primary key
$pk = $tableSchema->getPrimaryKey();
if ($pk) {
$pkcols = $pk->getColumns();
$cols = array();
if (count($pkcols)) {
foreach ($pkcols as $col) {
$cols[] = '"' . $col . '"';
}
$code .= "\$user_table->setPrimaryKey(array(" . implode(',', $cols) . ")); \n";
}
}
// Add indexes
$indexes = $tableSchema->getIndexes();
foreach ($indexes as $indexName => $index) {
if ($index->isPrimary()) continue;
$idxcols = $index->getColumns();
$cols = array();
foreach ($idxcols as $col) {
$cols[] = '"' . $col . '"';
}
if ($index->isUnique() == false) {
$code .= "\$user_table->addIndex(array(" . implode(',', $cols) . "), \"{$indexName}\"); \n";
} else {
$code .= "\$user_table->addUniqueIndex(array(" . implode(',', $cols) . "), \"{$indexName}\"); \n";
}
}
// Add foreign keys
$fkeys = $tableSchema->getForeignKeys();
foreach ($fkeys as $fk) {
$name = $fk->getName();
$foreignTable = $fk->getForeignTableName();
$localCols = array();
foreach ($fk->getLocalColumns() as $lc) {
$localCols[] = '"{$lc}"';
}
$foreignCols = array();
foreach ($fk->getForeignColumns() as $fc) {
$foreignCols[] = '"{$fc}"';
}
$options = array();
if ($action = $fk->onUpdate()) {
$options[] = '"onUpdate"=>"'.$action.'"';
}
if ($action = $fk->onDelete()) {
$options[] = '"onDelete"=>"'.$action.'"';
}
$code .= "\$user_table->addNamedForeignKeyConstraint(\"{$name}\", \"{$foreignTable}\", array(". implode(',', $localCols) ."), array(". implode(',', $foreignCols) ."), array(". implode(',', $options) .")); \n";
}
// Add options (Not implemented)
$options = $tableSchema->getOptions();
foreach ($options as $k => $v) {
$code .= "\$user_table->addOption(\"{$k}\", \"{$v}\"); \n";
}
$code .= "\$user_table->addOption(\"engine\", \"{$engine}\"); \n";
echo $code . "\n\n";
$file = $path . '/' . $tableName . '.table.php';
file_put_contents($file, $code);
}
<?php
/**
* Get database connection
*/
use Doctrine\Common\ClassLoader;
require __DIR__ . '/../library/Doctrine/Common/ClassLoader.php';
$classLoader = new ClassLoader('Doctrine', __DIR__ . '/../library');
$classLoader->register();
// Change this part to get config your way:BEGIN
require 'Zend/Config/Ini.php';
$config = new Zend_Config_Ini(__DIR__ . '/../application/Config/Application.ini');
$config = $config->toArray();
if (isset($config[$env])) {
$config = $config[$env];
} else {
echo "Invalid Env";
exit();
}
$config = $config['resources']['dbcms'];
// Change this part to get config your way:END
$dbconfig = new \Doctrine\DBAL\Configuration();
$connectionParams = array(
'dbname' => $config['params']['dbname'],
'user' => $config['params']['username'],
'password' => $config['params']['password'],
'host' => $config['params']['host'],
'driver' => 'pdo_mysql',
);
$conn = \Doctrine\DBAL\DriverManager::getConnection($connectionParams, $dbconfig);
return $conn;
<?php
/**
* Migrate database to status represented by schema config files under ./schema/
* schema config files can be generated from database using dump.php
*/
$env = 'test';
if (empty($_SERVER['argv'][1])) {
echo "Usage: php migrate.php (production|test|dev) [execute] \n";
exit();
} else {
$env = $_SERVER['argv'][1];
}
$conn = require('init.php');
$sm = $conn->getSchemaManager();
$from_schema = $sm->createSchema();
$to_schema = new Doctrine\DBAL\Schema\Schema();
$files = scandir(__DIR__ . "/schema");
foreach ($files as $file) {
if (preg_match('/^.*\.table\.php$/', $file)) {
require __DIR__ . "/schema/" . $file;
}
}
$sql = $from_schema->getMigrateToSql($to_schema, $conn->getDatabasePlatform());
if ($argc == 3 && $argv[2] == 'execute') {
foreach ($sql as $ddl) {
echo $ddl . "\n";
$conn->exec($ddl);
}
} else {
foreach ($sql as $ddl) {
echo $ddl . "\n";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment