eZ Publish  [4.0]
ezsqldiff.php
Go to the documentation of this file.
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 ?>