assign( 'next_step', $step );
require_once 'includes/install_inc.php';
require_once 'includes/get_databases_inc.php';
// set the maximum execution time to very high
ini_set( "max_execution_time", "86400" );
if( isset( $_REQUEST['db_src'] ) ) {
// source database settings
$gBitSmarty->assign( 'db_src', $_REQUEST['db_src'] );
$gBitSmarty->assign( 'host_src', $_REQUEST['host_src'] );
$gBitSmarty->assign( 'user_src', $_REQUEST['user_src'] );
$gBitSmarty->assign( 'pass_src', $_REQUEST['pass_src'] );
$gBitSmarty->assign( 'name_src', $_REQUEST['name_src'] );
$gBitSmarty->assign( 'prefix_src', $_REQUEST['prefix_src'] );
// destination database settings
$gBitSmarty->assign( 'db_dst', $_REQUEST['db_dst'] );
$gBitSmarty->assign( 'host_dst', $_REQUEST['host_dst'] );
$gBitSmarty->assign( 'user_dst', $_REQUEST['user_dst'] );
$gBitSmarty->assign( 'pass_dst', $_REQUEST['pass_dst'] );
$gBitSmarty->assign( 'name_dst', $_REQUEST['name_dst'] );
$gBitSmarty->assign( 'prefix_dst', $_REQUEST['prefix_dst'] );
$skip_tables = $_REQUEST['skip_tables'] ?? [];
$gBitSmarty->assign( 'skip_tables_select', $skip_tables );
$empty_tables = isset($_REQUEST['empty_tables']);
$gBitSmarty->assign( 'empty_tables', $empty_tables );
$convert_blobs = isset($_REQUEST['convert_blobs']);
$gBitSmarty->assign( 'convert_blobs', $convert_blobs );
$stop_on_errors = isset($_REQUEST['stop_on_errors']);
$gBitSmarty->assign( 'stop_on_errors', $stop_on_errors );
$debug = isset($_REQUEST['debug']);
$gBitSmarty->assign( 'debug', $debug );
} else {
//defaults
$gBitSmarty->assign( 'convert_blobs', true );
$gBitSmarty->assign( 'stop_on_errors', true );
}
if (isset($_REQUEST['fSubmitDatabase']) || isset($_REQUEST['fUpdateTables'])) {
global $gBitDbType, $gBitDbHost, $gBitDbUser, $gBitDbPassword, $gBitDbName;
global $gDb_src, $prefix_src, $gDb_dst, $prefix_dst;
// source database settings
$gBitDbType = $_REQUEST['db_src'];
$gBitDbHost = $_REQUEST['host_src'];
$gBitDbUser = $_REQUEST['user_src'];
$gBitDbPassword = $_REQUEST['pass_src'];
$gBitDbName = $_REQUEST['name_src'];
$prefix_src = $_REQUEST['prefix_src'];
if (testDatabase()) {
$gBitSmarty->assign( 'error_src', true );
return;
}
$gDb_src = new BitDb();
$tables_src = $gDb_src->MetaTables();
if (isset($_REQUEST['fUpdateTables'])) {
$gBitSmarty->assign( 'skip_tables', $tables_src );
return;
}
// destination database settings
$gBitDbType = $_REQUEST['db_dst'];
$gBitDbHost = $_REQUEST['host_dst'];
$gBitDbUser = $_REQUEST['user_dst'];
$gBitDbPassword = $_REQUEST['pass_dst'];
$gBitDbName = $_REQUEST['name_dst'];
$prefix_dst = $_REQUEST['prefix_dst'];
if (testDatabase()) {
$gBitSmarty->assign( 'error_dst', true );
return;
}
$gDb_dst = new BitDb();
require_once 'create_config_inc.php';
$createHash = [
"gBitDbType" => $_REQUEST['db_dst'],
"gBitDbHost" => $tmpHost,
"gBitDbUser" => $_REQUEST['user_dst'],
"gBitDbPassword" => $_REQUEST['pass_dst'],
"gBitDbName" => $_REQUEST['name_dst'],
//"gBitDbCaseSensitivity" => $_REQUEST['dbcase'],
"bit_db_prefix" => $_REQUEST['prefix_dst'],
"bit_root_url" => $_REQUEST['baseurl'],
"auto_bug_submit" => isset( $_REQUEST['auto_bug_submit'] ) ? 'true' : 'false',
"is_live" => isset( $_REQUEST['is_live'] ) ? 'true' : 'false',
];
create_config( $createHash );
// init db connections
//vd($gDb_src);
//vd($gDb_dst);die;
if ($debug) {
$gDb_dst->debug();
}
// list source tables list
$tables_src = [ $tables_src[2] ];
$tables_dst = $gDb_dst->MetaTables( );
print_r( $tables_src );
die;
$table_schema = [];
// iterate through source tables
foreach ( $tables_src as $table ) {
if (array_search( $table, $skip_tables ) !== false) {
if ($debug)
echo "Skipping $table
\n";
continue;
}
if ($debug)
echo "Creating $table
\n";
if ($empty_tables && $gDb_dst->tableExists( $table ))
$gDb_dst->dropTables( [ $table ] );
$schema = $gDb_src->MetaColumns( $table, false, true );
$t = "";
$first = true;
foreach ( array_keys( $schema ) as $col ) {
$t .= ( !$first ) ? ",\n" : "";
$x = $schema[$col];
$t .= $x->name . " ";
switch ($x->type) {
case "tinyint":
case "int":
$i = abs( ( (int) $x->max_length ^ 2 ) - 1 );
$i = ( $i == 5 ) ? 4 : $i;
$i = ( $i == 0 ) ? 1 : $i;
$t .= "I" . $i;
break;
case "double":
$t .= "N";
break;
case "varchar":
case "char":
case "enum":
case "decimal":
$t .= "C(" . $x->max_length . ")";
break;
case "time":
case "timestamp":
case "datetime":
$t .= "T";
break;
case "date":
$t .= "D";
break;
case "blob":
case "longblob":
case "tinyblob":
$t .= "B";
break;
case "text":
$t .= "X";
break;
default:
die( KernelTools::tra( "No support for type '" . $x->type . "' - please log a bug at http://sf.net/projects/bitweaver" ) );
}
$default = ( !$x->binary ) ? $x->has_default : false;
$t .= " " . ( $x->unsigned ? "UNSIGNED" : "" ) . " "
. ( $x->not_null ? "NOTNULL" : "" ) . " "
. ( $x->auto_increment ? "AUTO" : "" ) . " "
. ( $x->primary_key ? "PRIMARY" : "" ) . " "
. ( $default ? "DEFAULT " . $x->default_value : "" );
$table_schema[$table] = $t;
$first = false;
}
$indices[$table] = $gDb_src->MetaIndexes( $table, false, false );
}
//vd($table_schema);
//vd($indices);
$pOptions = [];
if ($empty_tables)
$pOptions[] = "REPLACE";
switch ($gDb_dst->mType) {
case "mysql":
// SHOULD HANDLE INNODB so foreign keys are cool - XOXO spiderr
$pOptions['mysql'] = 'TYPE=INNODB';
default:
//$pOptions[] = 'REPLACE';
}
$dict = NewDataDictionary( $gDb_dst->mDb, 'firebird' );
$result = true;
foreach ( array_keys( $table_schema ) as $tableName ) {
$completeTableName = $prefix_dst . $tableName;
$sql = $dict->CreateTableSQL( $completeTableName, $table_schema[$tableName], $pOptions );
if ($sql && ( $dict->ExecuteSQLArray( $sql ) > 0 )) {
// Success
}
else {
// Failure
array_push( $gDb_dst->mFailed, $gDb_dst->mDb->ErrorMsg() );
if ($stop_on_errors)
break;
}
foreach ( array_keys( $indices ) as $index ) {
foreach ( array_keys( $indices[$index] ) as $col ) {
$completeTableName = $prefix_dst . $index;
$flds = implode( ",", $indices[$index][$col]["columns"] );
$name = implode( "_", $indices[$index][$col]["columns"] );
$sql = $dict->CreateIndexSQL( "{$index}_$name", $completeTableName, $flds, ( $indices[$index][$col]["unique"] ) ? [ "UNIQUE" ] : null );
if ($sql && ($dict->ExecuteSQLArray($sql) > 0))
{
// Success
} else {
// Failure
array_push( $gDb_dst->mFailed, $gDb_dst->mDb->ErrorMsg());
if ($stop_on_errors)
break;
}
}
}
}
//vd($gDb_dst->mFailed);die;
foreach(array_keys($table_schema) as $table) {
$q = 0;
$c = 0;
$gDb_dst->StartTrans();
// get source data
$result = $gDb_src->Execute("SELECT * FROM $table");
// identify blob fields
//echo "$table\n";
//print_r($encoded_tables);
//var_dump(array_search($table, $encoded_tables));die;
$blobs = BitInstaller::identifyBlobs($result);
//print_r($blobs);
while ($res = $result->FetchRow()) {
//var_dump($res);die;
// convert blobs
if($convert_blobs && !empty($blobs)) {
$c++;
BitInstaller::convertBlobs($gDb_dst, $res, $blobs);
}
$q++;
// insert data into destination
if($gDb_dst->associateInsert( $table, $res) === false) {
array_push( $gDb_dst->mFailed, $gDb_dst->mDb->ErrorMsg());
if ($stop_on_errors)
break;
}
}
$gDb_dst->CompleteTrans();
$results[]= "$table: migrated $q records".(($c > 0) ? "and converted $c blobs" : "");
}
//vd($gDb_dst->mFailed);die;
$gBitSmarty->assign( 'results', $results );
$gBitSmarty->assign( 'errors', $gDb_dst->mFailed );
$app = "_done";
$gBitSmarty->assign( 'next_step', $step + 1 );
}
function testDatabase() {
global $gBitDbType, $gBitDbHost, $gBitDbUser, $gBitDbPassword, $gBitDbName, $gBitSmarty;
if( $gBitDbType == 'sybase' ) {
// avoid database change messages
ini_set('sybct.min_server_severity', '11');
}
$gBitDb = ADONewConnection($gBitDbType);
if( !$gBitDb->Connect($gBitDbHost, $gBitDbUser, $gBitDbPassword, $gBitDbType != 'pdo' ? $gBitDbName : NULL ) ) {
return true;
}
return false;
}