|
eZ Publish
[4.0]
|
00001 #!/usr/bin/env php 00002 <?php 00003 // 00004 // Created on: <21-Apr-2004 09:51:56 kk> 00005 // 00006 // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ## 00007 // SOFTWARE NAME: eZ Publish 00008 // SOFTWARE RELEASE: 4.0.x 00009 // COPYRIGHT NOTICE: Copyright (C) 1999-2008 eZ Systems AS 00010 // SOFTWARE LICENSE: GNU General Public License v2.0 00011 // NOTICE: > 00012 // This program is free software; you can redistribute it and/or 00013 // modify it under the terms of version 2.0 of the GNU General 00014 // Public License as published by the Free Software Foundation. 00015 // 00016 // This program is distributed in the hope that it will be useful, 00017 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 // GNU General Public License for more details. 00020 // 00021 // You should have received a copy of version 2.0 of the GNU General 00022 // Public License along with this program; if not, write to the Free 00023 // Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 00024 // MA 02110-1301, USA. 00025 // 00026 // 00027 // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ## 00028 // 00029 00030 //include_once( 'lib/ezutils/classes/ezcli.php' ); 00031 //include_once( 'kernel/classes/ezscript.php' ); 00032 00033 require 'autoload.php'; 00034 00035 $cli = eZCLI::instance(); 00036 $script = eZScript::instance( array( 'description' => ( "eZ Publish Database Converter\n\n" . 00037 "Convert the database to the given type\n". 00038 "ezconvertmysqltabletype.php [--host=VALUE --user=VALUE --database=VALUE [--password=VALUE]] [--list] [--newtype=TYPE] [--usecopy]" ), 00039 'use-session' => false, 00040 'use-modules' => false, 00041 'use-extensions' => false ) ); 00042 00043 $script->startup(); 00044 00045 $options = $script->getOptions( "[host:][user:][password:][database:][list][newtype:][usecopy]", 00046 "", 00047 array( 00048 'list' => "List the table types", 00049 'host' => "Connect to host database", 00050 'user' => "User for login to the database", 00051 'password' => "Password to use when connecting to the database", 00052 'newtype' => "Convert the database to the given type.\nType can either be: myisam or innodb\n". 00053 "Make sure that you have made a BACKUP UP of YOUR DATABASE!", 00054 'usecopy' => "To convert the table we rename the original table and copy the data to the new table structure.\n". 00055 "This conversion method is much slower and has a higher risk to corrupt the data in the database.\n". 00056 "However this option may circumvent the MySQL crash on the ALTER query." ) 00057 ); 00058 $script->initialize(); 00059 00060 $host = $options['host']; 00061 $user = $options['user']; 00062 00063 $password = is_string( $options['password'] ) ? $options['password'] : ""; 00064 $database = $options['database']; 00065 $listMode = $options['list']; 00066 $newType = $options["newtype"]; 00067 $usecopy = $options["usecopy"]; 00068 00069 checkParameters( $cli, $script, $options, $host, $user, $password, $database, $listMode, $newType ); 00070 $db = connectToDatabase( $cli, $script, $host, $user, $password, $database ); 00071 00072 // If the listMode parameter is set or no newType is assigned then show the list. 00073 if ( $listMode || !isset( $newType ) ) 00074 { 00075 listTypes( $cli, $db ); 00076 } 00077 else 00078 { 00079 setNewType( $cli, $db, $newType, $usecopy ); 00080 } 00081 00082 /** 00083 * Check whether the parameters are correctly set. 00084 **/ 00085 function checkParameters( $cli, $script, $options, $host, $user, $password, $database, $listMode, $newType ) 00086 { 00087 // Extra parameters are not tolerated. 00088 if ( count ( $options['arguments'] ) != 0 ) 00089 { 00090 $cli->error( "Unknown parameters" ); 00091 $script->shutdown( 1 ); 00092 } 00093 00094 // Host, User, and database are like the three musketeers. 00095 // Either the three parameters must be set or none. 00096 if ( isset( $host ) || isset( $user ) || isset( $database ) ) 00097 { 00098 if ( !isset( $host ) || !isset( $user ) || !isset( $database ) ) 00099 { 00100 $cli->error( "Use the host, user, database, and optionally a password together." ); 00101 $script->shutdown( 1 ); 00102 } 00103 } 00104 00105 // If the newType is set, check whether the given type exist. 00106 if ( $newType ) 00107 { 00108 switch ( strtolower( $newType ) ) 00109 { 00110 case "innodb": break; 00111 case "myisam": break; 00112 00113 default: $cli->error( "New table type not supported." ); 00114 $script->shutDown( 1 ); 00115 } 00116 } 00117 } 00118 00119 // Creates a displayable string for the end-user explaining 00120 // which database, host, user and password which were tried 00121 function eZTriedDatabaseString( $database, $host, $user, $password ) 00122 { 00123 $msg = "'$database'"; 00124 if ( strlen( $host ) > 0 ) 00125 { 00126 $msg .= " at host '$host'"; 00127 } 00128 else 00129 { 00130 $msg .= " locally"; 00131 } 00132 if ( strlen( $user ) > 0 ) 00133 { 00134 $msg .= " with user '$user'"; 00135 } 00136 if ( strlen( $password ) > 0 ) 00137 $msg .= " and with a password"; 00138 return $msg; 00139 } 00140 00141 /** 00142 * Connect to the database 00143 **/ 00144 function connectToDatabase( $cli, $script, $host, $user, $password, $database ) 00145 { 00146 //include_once( 'lib/ezdb/classes/ezdb.php' ); 00147 00148 if ( $user ) 00149 { 00150 $db = eZDB::instance( "mysql", 00151 array( 'server' => $host, 00152 'user' => $user, 00153 'password' => $password, 00154 'database' => $database ) ); 00155 } else 00156 { 00157 $db = eZDB::instance(); 00158 if ( $db->databaseName() != "mysql" ) 00159 { 00160 $cli->error( 'This script can only show and convert mysql databases.' ); 00161 $script->shutdown( 1 ); 00162 } 00163 } 00164 00165 if ( !is_object( $db ) ) 00166 { 00167 $cli->error( 'Could not initialize database:' ); 00168 $cli->error( '* No database handler was found for mysql' ); 00169 $script->shutdown( 1 ); 00170 } 00171 if ( !$db or !$db->isConnected() ) 00172 { 00173 $cli->error( "Could not initialize database:" ); 00174 $cli->error( "* Tried database " . eZTriedDatabaseString( $database, $host, $user, $password ) ); 00175 00176 // Fetch the database error message if there is one 00177 // It will give more feedback to the user what is wrong 00178 $msg = $db->errorMessage(); 00179 if ( $msg ) 00180 { 00181 $number = $db->errorNumber(); 00182 if ( $number > 0 ) 00183 $msg .= '(' . $number . ')'; 00184 $cli->error( '* ' . $msg ); 00185 } 00186 $script->shutdown( 1 ); 00187 } 00188 00189 return $db; 00190 } 00191 00192 function getTableType( $db, $tableName ) 00193 { 00194 $res = $db->arrayQuery( "SHOW CREATE TABLE `$tableName`" ); 00195 preg_match( '/(?:TYPE|ENGINE)=(\w*)/', $res[0]["Create Table"], $grep ); 00196 return $grep[1]; 00197 } 00198 00199 function listTypes( $cli, $db ) 00200 { 00201 $tables = $db->arrayQuery( "show tables" ); 00202 00203 $spaces = str_pad ( ' ', 35 ); 00204 $cli->notice( "Table $spaces Type" ); 00205 $cli->notice( "----- $spaces ----" ); 00206 foreach ( $tables as $table ) 00207 { 00208 $tableName = current( $table ); 00209 $tableType = getTableType( $db, $tableName ); 00210 00211 $spaces = str_pad(' ', 40 - strlen( $tableName ) ); 00212 $eZpublishTable = strncmp( $tableName, "ez", 2 ) == 0 ? "" : "(non eZ Publish)"; 00213 $cli->notice( "$tableName $spaces $tableType $eZpublishTable" ); 00214 } 00215 } 00216 00217 function alterType( $db, $tableName, $newType ) 00218 { 00219 $db->query( "ALTER TABLE $tableName ENGINE=$newType" ); 00220 } 00221 00222 function renameTable( $db, $tableFrom, $tableTo ) 00223 { 00224 $db->query( "ALTER TABLE $tableFrom RENAME $tableTo" ); 00225 } 00226 00227 function copyTable( $db, $tableFrom, $tableTo ) 00228 { 00229 $db->query( "INSERT INTO $tableTo SELECT * FROM $tableFrom" ); 00230 } 00231 00232 function createTableStructure( $db, $tableFrom, $tableTo, $newType ) 00233 { 00234 $res = $db->arrayQuery( "SHOW CREATE TABLE `$tableFrom`" ); 00235 00236 $pattern = array( "/(TYPE|ENGINE)=(\w*)/", "/TABLE `$tableFrom`/" ); 00237 $replacement = array( "ENGINE=$newType", "TABLE `$tableTo`" ); 00238 $structure = preg_replace( $pattern, $replacement, $res[0]["Create Table"] ); 00239 00240 $db->query( $structure ); 00241 } 00242 00243 function dropTable( $db, $tableName ) 00244 { 00245 $db->query( "DROP TABLE $tableName" ); 00246 } 00247 00248 function setNewType( $cli, $db, $newType, $usecopy ) 00249 { 00250 $tables = $db->arrayQuery( "show tables" ); 00251 00252 foreach ( $tables as $table ) 00253 { 00254 $tableName = current( $table ); 00255 00256 // Checking if it is necessary to convert the table. 00257 if ( strncmp( $tableName, "ez", 2 ) != 0 ) 00258 { 00259 $cli->notice( "Skipping table $tableName because it is not an eZ Publish table" ); 00260 } 00261 else if ( strcasecmp( getTableType( $db, $tableName ), $newType ) == 0 ) 00262 { 00263 $cli->notice( "Skipping table $tableName because it has already the $newType type" ); 00264 } 00265 else 00266 { 00267 // Yes, convert. 00268 $cli->notice( "Converting table $tableName ... " ); 00269 00270 if ( !$usecopy ) 00271 { 00272 // The simple one 00273 alterType( $db, $tableName, $newType ); 00274 } 00275 else 00276 { 00277 renameTable( $db, $tableName, "eztemp__$tableName" ); 00278 createTableStructure( $db, "eztemp__$tableName", $tableName, $newType ); 00279 copyTable( $db, "eztemp__$tableName", $tableName ); 00280 dropTable( $db, "eztemp__$tableName" ); 00281 } 00282 } 00283 } 00284 } 00285 00286 $script->shutdown(); 00287 ?>