install
[ class tree: install ] [ index: install ] [ all elements ]

Source for file migrate_database.php

Documentation is available at migrate_database.php

  1. <?php
  2. /**
  3.  * Migrate database to new schema.
  4.  *
  5.  * @copyright 2004-15 Stephan Borg, bitweaver.org
  6.  *
  7.  * @package install
  8.  * @subpackage upgrade
  9.  */
  10.  
  11. /**
  12.  * Initialization
  13.  */
  14. $gBitSmarty->assign( 'next_step', $step );
  15. require_once( 'install_inc.php' );
  16. require_once( "get_databases_inc.php" );
  17.  
  18. // set the maximum execution time to very high
  19. ini_set( "max_execution_time", "86400" );
  20.  
  21. if( isset( $_REQUEST['db_src'] ) ) {
  22.     // source database settings
  23.     $gBitSmarty->assign( 'db_src', $_REQUEST['db_src'] );
  24.     $gBitSmarty->assign( 'host_src', $_REQUEST['host_src'] );
  25.     $gBitSmarty->assign( 'user_src', $_REQUEST['user_src'] );
  26.     $gBitSmarty->assign( 'pass_src', $_REQUEST['pass_src'] );
  27.     $gBitSmarty->assign( 'name_src', $_REQUEST['name_src'] );
  28.     $gBitSmarty->assign( 'prefix_src', $_REQUEST['prefix_src'] );
  29.  
  30.     // destination database settings
  31.     $gBitSmarty->assign( 'db_dst', $_REQUEST['db_dst'] );
  32.     $gBitSmarty->assign( 'host_dst', $_REQUEST['host_dst'] );
  33.     $gBitSmarty->assign( 'user_dst', $_REQUEST['user_dst'] );
  34.     $gBitSmarty->assign( 'pass_dst', $_REQUEST['pass_dst'] );
  35.     $gBitSmarty->assign( 'name_dst', $_REQUEST['name_dst'] );
  36.     $gBitSmarty->assign( 'prefix_dst', $_REQUEST['prefix_dst'] );
  37.  
  38.     $skip_tables = isset($_REQUEST['skip_tables']) ? $_REQUEST['skip_tables'] : array();
  39.     $gBitSmarty->assign( 'skip_tables_select', $skip_tables );
  40.     $empty_tables = isset($_REQUEST['empty_tables']);
  41.     $gBitSmarty->assign( 'empty_tables', $empty_tables );
  42.     $convert_blobs = isset($_REQUEST['convert_blobs']);
  43.     $gBitSmarty->assign( 'convert_blobs', $convert_blobs );
  44.     $stop_on_errors = isset($_REQUEST['stop_on_errors']);
  45.     $gBitSmarty->assign( 'stop_on_errors', $stop_on_errors );
  46.     $debug = isset($_REQUEST['debug']);
  47.     $gBitSmarty->assign( 'debug', $debug );
  48. } else {
  49.     //defaults
  50.     $gBitSmarty->assign( 'convert_blobs', TRUE );
  51.     $gBitSmarty->assign( 'stop_on_errors', TRUE );
  52. }
  53.  
  54. if (isset($_REQUEST['fSubmitDatabase']) || isset($_REQUEST['fUpdateTables'])) {
  55.     global $gBitDbType, $gBitDbHost, $gBitDbUser, $gBitDbPassword, $gBitDbName;
  56.     global $gDb_src, $prefix_src, $gDb_dst, $prefix_dst;
  57.     // source database settings
  58.     $gBitDbType = $_REQUEST['db_src'];
  59.     $gBitDbHost = $_REQUEST['host_src'];
  60.     $gBitDbUser = $_REQUEST['user_src'];
  61.     $gBitDbPassword = $_REQUEST['pass_src'];
  62.     $gBitDbName = $_REQUEST['name_src'];
  63.     $prefix_src = $_REQUEST['prefix_src'];
  64.     if (testDatabase()) {
  65.         $gBitSmarty->assign( 'error_src', TRUE );
  66.         return;
  67.     } else {
  68.         $gDb_src = new BitDb();
  69.     }
  70.  
  71.     $tables_src = $gDb_src->MetaTables();
  72.  
  73.     if (isset($_REQUEST['fUpdateTables'])) {
  74.         $gBitSmarty->assign_by_ref( 'skip_tables', $tables_src );
  75.         return;
  76.     }
  77.  
  78.     // destination database settings
  79.     $gBitDbType = $_REQUEST['db_dst'];
  80.     $gBitDbHost = $_REQUEST['host_dst'];
  81.     $gBitDbUser = $_REQUEST['user_dst'];
  82.     $gBitDbPassword = $_REQUEST['pass_dst'];
  83.     $gBitDbName = $_REQUEST['name_dst'];
  84.     $prefix_dst = $_REQUEST['prefix_dst'];
  85.     if (testDatabase()) {
  86.         $gBitSmarty->assign( 'error_dst', TRUE );
  87.         return;
  88.     } else {
  89.         $gDb_dst = new BitDb();
  90.     }
  91.  
  92.     require_once( 'create_config_inc.php' );
  93.     $createHash = array(
  94.         "gBitDbType"            => $_REQUEST['db_dst'],
  95.         "gBitDbHost"            => $tmpHost,
  96.         "gBitDbUser"            => $_REQUEST['user_dst'],
  97.         "gBitDbPassword"        => $_REQUEST['pass_dst'],
  98.         "gBitDbName"            => $_REQUEST['name_dst'],
  99.         //"gBitDbCaseSensitivity" => $_REQUEST['dbcase'],
  100.         "bit_db_prefix"         => $_REQUEST['prefix_dst'],
  101.         "bit_root_url"          => $_REQUEST['baseurl'],
  102.         "auto_bug_submit"       => isset( $_REQUEST['auto_bug_submit'] ) ? 'TRUE' : 'FALSE',
  103.         "is_live"               => isset( $_REQUEST['is_live'] ) ? 'TRUE' : 'FALSE',
  104.     );
  105.     create_config( $createHash );
  106.  
  107.     // init db connections
  108.     //vd($gDb_src);
  109.     //vd($gDb_dst);die;
  110.  
  111.     if($debug) {
  112.         $gDb_dst->debug();
  113.     }
  114.  
  115.     // list source tables list
  116.     $tables_src = array($tables_src[2]);
  117.     $tables_dst = getTables($gDb_dst);
  118.     print_r($tables_src);die;
  119.  
  120.     $table_schema = array();
  121.     // iterate through source tables
  122.     foreach($tables_src as $table) {
  123.         if (array_search($table, $skip_tables) !== FALSE) {
  124.             if ($debug)
  125.                 echo "Skipping $table<br>\n";
  126.             continue;
  127.         }
  128.         if ($debug)
  129.             echo "Creating $table<br>\n";
  130.  
  131.         if ($empty_tables && $gDb_dst->tableExists($table))
  132.             $gDb_dst->dropTables(array($table));
  133.  
  134.         $schema = $gDb_src->MetaColumns( $table, false, true );
  135.         $t = "";
  136.         $first = true;
  137.         foreach(array_keys($schema) as $col) {
  138.             $t .= (!$first) ? ",\n" : "";
  139.             $x = $schema[$col];
  140.             $t .= $x->name . " ";
  141.             switch($x->type) {
  142.                 case "tinyint":
  143.                 case "int":
  144.                     $i = abs(( ( (int)$x->max_length ^ 2) - 1 ));
  145.                     $i = ($i == 5) ? 4 : $i;
  146.                     $i = ($i == 0) ? 1 : $i;
  147.                     $t .= "I" . $i;
  148.                     break;
  149.  
  150.                 case "double":
  151.                     $t .= "N";
  152.                     break;
  153.                 
  154.                 case "varchar":
  155.                 case "char":
  156.                 case "enum":
  157.                 case "decimal":
  158.                     $t .= "C(" . $x->max_length . ")";
  159.                     break;
  160.                 
  161.                 case "time":
  162.                 case "timestamp":
  163.                 case "datetime":
  164.                     $t .= "T";
  165.                     break;
  166.                 
  167.                 case "date":
  168.                     $t .= "D";
  169.                     break;
  170.                 
  171.                 case "blob":
  172.                 case "longblob":
  173.                 case "tinyblob":
  174.                     $t .= "B";
  175.                     break;
  176.  
  177.                 case "text":
  178.                     $t .= "X";
  179.                     break;
  180.                 default:
  181.                     die(tra("No support for type '".$x->type."' - please log a bug at http://sf.net/projects/bitweaver"));
  182.             }
  183.             $default = (!$x->binary) ? $x->has_default : false;
  184.             $t .= " " . ( ($x->unsigned) ? "UNSIGNED" : "" ) . " "
  185.                  . ( ($x->not_null) ? "NOTNULL" : "" ) . " "
  186.                  . ( ($x->auto_increment) ? "AUTO" : "" ) . " "
  187.                 . ( ($x->primary_key) ? "PRIMARY" : "" ) . " "
  188.                 . ( ($default) ? "DEFAULT ". $x->default_value : "" );
  189.             $table_schema[$table] = $t;
  190.             $first = false;
  191.         }
  192.         $indices[$table] = $gDb_src->MetaIndexes( $table, false, false );
  193.     }
  194.  
  195.     //vd($table_schema);
  196.     //vd($indices);
  197.  
  198.     $pOptions = array();
  199.     if ($empty_tables)
  200.         $pOptions[] = "REPLACE";
  201.  
  202.     switch ($gDb_dst->mType) {
  203.         case "mysql":
  204.         // SHOULD HANDLE INNODB so foreign keys are cool - XOXO spiderr
  205.         $pOptions['mysql'] = 'TYPE=INNODB';
  206.         default:
  207.         //$pOptions[] = 'REPLACE';
  208.     }
  209.  
  210.     $dict = NewDataDictionary($gDb_dst->mDb);
  211.     $result = true;
  212.     foreach(array_keys($table_schema) AS $tableName)
  213.     {
  214.         $completeTableName = $prefix_dst.$tableName;
  215.         $sql = $dict->CreateTableSQL($completeTableName, $table_schema[$tableName], $pOptions);
  216.         if ($sql && ($dict->ExecuteSQLArray($sql) > 0))
  217.         {
  218.             // Success
  219.         }
  220.         else
  221.         {
  222.             // Failure
  223.             array_push($gDb_dst->mFailed, $gDb_dst->mDb->ErrorMsg());
  224.             if ($stop_on_errors)
  225.                 break;
  226.         }
  227.  
  228.         foreach( array_keys( $indices ) as $index ) {
  229.             foreach( array_keys( $indices[$index] ) as $col) {
  230.                 $completeTableName = $prefix_dst.$index;
  231.                 $flds = implode(",", $indices[$index][$col]["columns"]);
  232.                 $name = implode("_", $indices[$index][$col]["columns"]);
  233.                 $sql = $dict->CreateIndexSQL( $index."_".$name, $completeTableName, $flds, (($indices[$index][$col]["unique"]) ? array("UNIQUE") : NULL) );
  234.                 if( $sql && ($dict->ExecuteSQLArray($sql) > 0))
  235.                 {
  236.                     // Success
  237.                 } else {
  238.                     // Failure
  239.                     array_push( $gDb_dst->mFailed, $gDb_dst->mDb->ErrorMsg());
  240.                     if ($stop_on_errors)
  241.                         break;
  242.                 }
  243.             }
  244.         }
  245.  
  246.     }
  247.  
  248. //vd($gDb_dst->mFailed);die;
  249.     foreach(array_keys($table_schema) as $table) {
  250.         $q = 0;
  251.         $c = 0;
  252.         $gDb_dst->StartTrans();
  253.         // get source data
  254.         $result = $gDb_src->Execute("SELECT * FROM $table");
  255.         // identify blob fields
  256.         //echo "$table\n";
  257.         //print_r($encoded_tables);
  258.         //var_dump(array_search($table, $encoded_tables));die;
  259.         $blobs = BitInstaller::identifyBlobs($result);
  260.         //print_r($blobs);
  261.  
  262.         while ($res = $result->FetchRow()) {
  263.             //var_dump($res);die;
  264.             // convert blobs
  265.             if($convert_blobs && !empty($blobs)) {
  266.                 $c++;
  267.                 BitInstaller::convertBlobs($gDb_dst, $res, $blobs);
  268.             }
  269.             $q++;
  270.             // insert data into destination
  271.             if($gDb_dst->associateInsert( $table, $res) === false) {
  272.                 array_push( $gDb_dst->mFailed, $gDb_dst->mDb->ErrorMsg());
  273.                 if ($stop_on_errors)
  274.                     break;
  275.             }
  276.         }
  277.  
  278.         $gDb_dst->CompleteTrans();
  279.         $results[]= "$table: migrated $q records".(($c > 0) ? "and converted $c blobs" : "");
  280.     }
  281. //vd($gDb_dst->mFailed);die;
  282.     $gBitSmarty->assign_by_ref( 'results', $results );
  283.     $gBitSmarty->assign_by_ref( 'errors', $gDb_dst->mFailed );
  284.     $app = "_done";
  285.     $gBitSmarty->assign( 'next_step', $step + 1 );
  286.  
  287. }
  288.  
  289. function testDatabase() {
  290.     global $gBitDbType, $gBitDbHost, $gBitDbUser, $gBitDbPassword, $gBitDbName, $gBitSmarty;
  291.     if( $gBitDbType == 'sybase' ) {
  292.         // avoid database change messages
  293.         ini_set('sybct.min_server_severity', '11');
  294.     }
  295.  
  296.     $gBitDb = &ADONewConnection($gBitDbType);
  297.  
  298.     if( !$gBitDb->Connect($gBitDbHost, $gBitDbUser, $gBitDbPassword, $gBitDbName) ) {
  299.         return TRUE;
  300.     }
  301.     return FALSE;
  302. }
  303.  
  304. ?>

Documentation generated on Wed, 29 Jul 2015 13:57:05 +0000 by phpDocumentor 1.5.0-lsces