|
eZ Publish
[4.0]
|
00001 #!/usr/bin/env php 00002 <?php 00003 // 00004 // Created on: <19-Mar-2004 09:51:56 amos> 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 SQL diff\n\n" . 00037 "Displays differences between two database schemas,\n" . 00038 "and sets exit code based whether there is a difference or not\n" . 00039 "\n" . 00040 "ezsqldiff.php --type mysql --user=root stable32 stable33" ), 00041 'use-session' => false, 00042 'use-modules' => true, 00043 'use-extensions' => true ) ); 00044 00045 $script->startup(); 00046 00047 $options = $script->getOptions( "[source-type:][source-host:][source-user:][source-password;][source-socket:]" . 00048 "[match-type:][match-host:][match-user:][match-password;][match-socket:]" . 00049 "[t:|type:][host:][u:|user:][p:|password;][socket:]" . 00050 "[lint-check]" . 00051 "[reverse][check-only]", 00052 "[source][match]", 00053 array( 'source-type' => ( "Which database type to use for source, can be one of:\n" . 00054 "mysql, postgresql" ), 00055 'source-host' => "Connect to host source database", 00056 'source-user' => "User for login to source database", 00057 'source-password' => "Password to use when connecting to source database", 00058 'source-socket' => 'Socket to connect to source database (only for MySQL)', 00059 'match-type' => ( "Which database type to use for match, can be one of:\n" . 00060 "mysql, postgresql" ), 00061 'match-host' => "Connect to host match database", 00062 'match-user' => "User for login to match database", 00063 'match-password' => "Password to use when connecting to match database", 00064 'match-socket' => 'Socket to connect to match database (only for MySQL)', 00065 'type' => ( "Which database type to use for match and source, can be one of:\n" . 00066 "mysql, postgresql" ), 00067 'host' => "Connect to host match and source database", 00068 'user' => "User for login to match and source database", 00069 'password' => "Password to use when connecting to match and source database", 00070 'socket' => 'Socket to connect to match and source database (only for MySQL)', 00071 'reverse' => "Reverse the differences", 00072 'check-only' => "Don't show SQLs for the differences, just set exit code and return" 00073 ) ); 00074 $script->initialize(); 00075 00076 if ( count( $options['arguments'] ) < 1 ) 00077 { 00078 $cli->error( "Missing source database" ); 00079 $script->shutdown( 1 ); 00080 } 00081 00082 if ( count( $options['arguments'] ) < 2 and 00083 !$options['lint-check'] ) 00084 { 00085 $cli->error( "Missing match database" ); 00086 $script->shutdown( 1 ); 00087 } 00088 00089 $sourceType = $options['source-type'] ? $options['source-type'] : $options['type']; 00090 $sourceDBHost = $options['source-host'] ? $options['source-host'] : $options['host']; 00091 $sourceDBUser = $options['source-user'] ? $options['source-user'] : $options['user']; 00092 $sourceDBPassword = $options['source-password'] ? $options['source-password'] : $options['password']; 00093 $sourceDBSocket = $options['source-socket'] ? $options['source-socket'] : $options['socket']; 00094 $sourceDB = $options['arguments'][0]; 00095 00096 if( !is_string( $sourceDBPassword ) ) 00097 $sourceDBPassword = ''; 00098 00099 $matchType = $options['match-type'] ? $options['match-type'] : $options['type']; 00100 $matchDBHost = $options['match-host'] ? $options['match-host'] : $options['host']; 00101 $matchDBUser = $options['match-user'] ? $options['match-user'] : $options['user']; 00102 $matchDBPassword = $options['match-password'] ? $options['match-password'] : $options['password']; 00103 $matchDBSocket = $options['match-socket'] ? $options['match-socket'] : $options['socket']; 00104 $matchDB = count( $options['arguments'] ) >= 2 ? $options['arguments'][1] : ''; 00105 00106 if ( !is_string( $matchDBPassword ) ) 00107 $matchDBPassword = ''; 00108 00109 if ( strlen( trim( $sourceType ) ) == 0 ) 00110 { 00111 $cli->error( "No source type chosen" ); 00112 $script->shutdown( 1 ); 00113 } 00114 if ( strlen( trim( $matchType ) ) == 0 ) 00115 { 00116 if ( !$options['lint-check'] ) 00117 { 00118 $cli->error( "No match type chosen" ); 00119 $script->shutdown( 1 ); 00120 } 00121 } 00122 00123 $ini = eZINI::instance(); 00124 00125 function loadDatabaseSchema( $type, $host, $user, $password, $socket, $db, $cli ) 00126 { 00127 $dbSchema = false; 00128 if ( file_exists( $db ) and is_file( $db ) ) 00129 { 00130 //include_once( 'lib/ezdbschema/classes/ezdbschema.php' ); 00131 $dbSchema = eZDbSchema::instance( array( 'type' => $type, 00132 'schema' => eZDbSchema::read( $db ) ) ); 00133 return $dbSchema; 00134 } 00135 else 00136 { 00137 //include_once( 'lib/ezdbschema/classes/ezdbschema.php' ); 00138 //include_once( 'lib/ezdb/classes/ezdb.php' ); 00139 $parameters = array( 'use_defaults' => false, 00140 'server' => $host, 00141 'user' => $user, 00142 'password' => $password, 00143 'database' => $db ); 00144 if ( $socket ) 00145 $parameters['socket'] = $socket; 00146 $dbInstance = eZDB::instance( 'ez' . $type, 00147 $parameters, 00148 true ); 00149 00150 if ( !is_object( $dbInstance ) ) 00151 { 00152 $cli->error( 'Could not initialize database:' ); 00153 $cli->error( '* No database handler was found for $type' ); 00154 return $dbSchema; 00155 } 00156 if ( !$dbInstance->isConnected() ) 00157 { 00158 $cli->error( "Could not initialize database:" ); 00159 $msg = "* Tried database '$db'"; 00160 if ( strlen( $host ) > 0 ) 00161 { 00162 $msg .= " at host '$host'"; 00163 } 00164 else 00165 { 00166 $msg .= " locally"; 00167 } 00168 if ( strlen( $user ) > 0 ) 00169 { 00170 $msg .= " with user '$user'"; 00171 } 00172 if ( strlen( $password ) > 0 ) 00173 $msg .= " and with a password"; 00174 $cli->error( $msg ); 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 = $dbInstance->errorMessage(); 00179 if ( $msg ) 00180 { 00181 $number = $dbInstance->errorNumber(); 00182 if ( $number > 0 ) 00183 $msg .= '(' . $number . ')'; 00184 $cli->error( '* ' . $msg ); 00185 } 00186 return $dbSchema; 00187 } 00188 00189 return eZDbSchema::instance( $dbInstance ); 00190 } 00191 } 00192 00193 function loadLintSchema( $dbSchema, $cli ) 00194 { 00195 //include_once( 'lib/ezdbschema/classes/ezlintschema.php' ); 00196 return new eZLintSchema( false, $dbSchema ); 00197 } 00198 00199 $sourceSchema = loadDatabaseSchema( $sourceType, $sourceDBHost, $sourceDBUser, $sourceDBPassword, $sourceDBSocket, $sourceDB, $cli ); 00200 if ( !$sourceSchema ) 00201 { 00202 $cli->error( "Failed to load schema from source database" ); 00203 $script->shutdown( 1 ); 00204 } 00205 00206 if ( $options['lint-check'] ) 00207 { 00208 $matchType = $sourceType; 00209 $matchSchema = $sourceSchema; 00210 unset( $sourceSchema ); 00211 $sourceSchema = loadLintSchema( $matchSchema, $cli ); 00212 } 00213 else 00214 { 00215 $matchSchema = loadDatabaseSchema( $matchType, $matchDBHost, $matchDBUser, $matchDBPassword, $matchDBSocket, $matchDB, $cli ); 00216 if ( !$matchSchema ) 00217 { 00218 $cli->error( "Failed to load schema from match database" ); 00219 $script->shutdown( 1 ); 00220 } 00221 } 00222 00223 //include_once( 'lib/ezdbschema/classes/ezdbschemachecker.php' ); 00224 00225 if ( $options['reverse'] ) 00226 { 00227 $differences = eZDbSchemaChecker::diff( $sourceSchema->schema(), $matchSchema->schema(), $sourceType, $matchType ); 00228 if ( !$options['check-only'] ) 00229 { 00230 $cli->output( "-- Difference in SQL commands for " . $sourceSchema->schemaName() ); 00231 $sql = $sourceSchema->generateUpgradeFile( $differences ); 00232 $cli->output( $sql ); 00233 } 00234 } 00235 else 00236 { 00237 $differences = eZDbSchemaChecker::diff( $matchSchema->schema(), $sourceSchema->schema(), $matchType, $sourceType ); 00238 if ( !$options['check-only'] ) 00239 { 00240 $cli->output( "-- Difference in SQL commands from " . $sourceSchema->schemaName() . " to " . $matchSchema->schemaName() ); 00241 $sql = $matchSchema->generateUpgradeFile( $differences ); 00242 $cli->output( $sql ); 00243 } 00244 } 00245 00246 if ( count( $differences ) > 0 ) 00247 $script->setExitCode( 1 ); 00248 00249 $script->shutdown(); 00250 00251 ?>