eZ Publish  [4.0]
ezdbschemachecker.php
Go to the documentation of this file.
00001 <?php
00002 //
00003 // Created on: <28-Jan-2004 16:10:44 dr>
00004 //
00005 // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
00006 // SOFTWARE NAME: eZ Publish
00007 // SOFTWARE RELEASE: 4.0.x
00008 // COPYRIGHT NOTICE: Copyright (C) 1999-2008 eZ Systems AS
00009 // SOFTWARE LICENSE: GNU General Public License v2.0
00010 // NOTICE: >
00011 //   This program is free software; you can redistribute it and/or
00012 //   modify it under the terms of version 2.0  of the GNU General
00013 //   Public License as published by the Free Software Foundation.
00014 //
00015 //   This program is distributed in the hope that it will be useful,
00016 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 //   GNU General Public License for more details.
00019 //
00020 //   You should have received a copy of version 2.0 of the GNU General
00021 //   Public License along with this program; if not, write to the Free
00022 //   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00023 //   MA 02110-1301, USA.
00024 //
00025 //
00026 // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
00027 //
00028 
00029 /*!
00030   \class eZDbSchemaChecker ezdbschemachecker.php
00031   \ingroup eZDbSchema
00032   \brief Checks differences between schemas
00033 
00034 */
00035 
00036 class eZDbSchemaChecker
00037 {
00038     /*!
00039      \static
00040      Finds the difference between the scemas \a $schema1 and \a $schema2.
00041      \return An array containing:
00042              - new_tables - A list of new tables that have been added
00043              - removed_tables - A list of tables that have been removed
00044              - table_changes - Changes in table definition
00045                - added_fields - A list of new fields in the table
00046                - removed_fields - A list of removed fields in the table
00047                - changed_fields - A list of fields that have changed definition
00048                - added_indexes - A list of new indexes in the table
00049                - removed_indexes - A list of removed indexes in the table
00050                - changed_indexes - A list of indexes that have changed definition
00051     */
00052     static function diff( $schema1, $schema2 = array(), $schema1Type = false, $schema2Type = false )
00053     {
00054         if ( !is_array( $schema1 ) )
00055         {
00056             return false;
00057         }
00058         $diff = array();
00059 
00060         foreach ( $schema2 as $name => $def )
00061         {
00062             // Skip the info structure, this is not a table
00063             if ( $name == '_info' )
00064                 continue;
00065 
00066             if ( !isset( $schema1[$name] ) )
00067             {
00068                 $diff['new_tables'][$name] = $def;
00069             }
00070             else
00071             {
00072                 $table_diff = eZDbSchemaChecker::diffTable( $schema1[$name], $def, $schema1Type, $schema2Type );
00073                 if ( count( $table_diff ) )
00074                 {
00075                     $diff['table_changes'][$name] = $table_diff;
00076                 }
00077             }
00078         }
00079 
00080         /* Check if there are tables removed */
00081         foreach ( $schema1 as $name => $def )
00082         {
00083             // Skip the info structure, this is not a table
00084             if ( $name == '_info' )
00085                 continue;
00086 
00087             if ( !isset( $schema2[$name] ) )
00088             {
00089                 $diff['removed_tables'][$name] = $def;
00090             }
00091             else if ( isset( $schema2[$name]['removed'] ) and
00092                       isset( $schema2[$name]['removed'] ) )
00093             {
00094                 $diff['removed_tables'][$name] = $def;
00095             }
00096         }
00097 
00098         return $diff;
00099     }
00100 
00101     /*!
00102      \static
00103      Finds the difference between the tables \a $table1 and \a $table2 by looking
00104      at the fields and indexes.
00105 
00106      \return An array containing:
00107              - added_fields - A list of new fields in the table
00108              - removed_fields - A list of removed fields in the table
00109              - changed_fields - A list of fields that have changed definition
00110              - added_indexes - A list of new indexes in the table
00111              - removed_indexes - A list of removed indexes in the table
00112              - changed_indexes - A list of indexes that have changed definition
00113     */
00114     static function diffTable( $table1, $table2, $schema1Type, $schema2Type )
00115     {
00116         $table_diff = array();
00117 
00118         /* See if all the fields in table 1 exist in table 2 */
00119         foreach ( $table2['fields'] as $name => $def )
00120         {
00121             if ( !isset( $table1['fields'][$name] ) )
00122             {
00123                 $table_diff['added_fields'][$name] = $def;
00124             }
00125         }
00126         /* See if there are any removed fields in table 2 */
00127         foreach ( $table1['fields'] as $name => $def )
00128         {
00129             if ( !isset( $table2['fields'][$name] ) )
00130             {
00131                 $table_diff['removed_fields'][$name] = true;
00132             }
00133             else if ( isset( $table2['fields'][$name]['removed'] ) and
00134                       $table2['fields'][$name]['removed'] )
00135             {
00136                 $table_diff['removed_fields'][$name] = true;
00137             }
00138         }
00139         /* See if there are any changed definitions */
00140         foreach ( $table1['fields'] as $name => $def )
00141         {
00142             if ( isset( $table2['fields'][$name] ) )
00143             {
00144                 if ( is_array( $field_diff = eZDbSchemaChecker::diffField( $def, $table2['fields'][$name], $schema1Type, $schema2Type ) ) )
00145                 {
00146                     $table_diff['changed_fields'][$name] = $field_diff;
00147                 }
00148             }
00149         }
00150 
00151         $table1Indexes = $table1['indexes'];
00152         $table2Indexes = $table2['indexes'];
00153 
00154         /* See if all the indexes in table 1 exist in table 2 */
00155         foreach ( $table2Indexes as $name => $def )
00156         {
00157             if ( !isset( $table1Indexes[$name] ) )
00158             {
00159                 $table_diff['added_indexes'][$name] = $def;
00160             }
00161         }
00162         /* See if there are any removed indexes in table 2 */
00163         foreach ( $table1Indexes as $name => $def )
00164         {
00165             if ( !isset( $table2Indexes[$name] ) )
00166             {
00167                 $table_diff['removed_indexes'][$name] = $def;
00168             }
00169             else if ( isset( $table2Indexes[$name]['removed'] ) and
00170                       $table2Indexes[$name]['removed'] )
00171             {
00172                 if ( isset( $table2Indexes[$name]['comments'] ) )
00173                     $def['comments'] = array_merge( isset( $def['comments'] ) ? $def['comments'] : array(),
00174                                                     $table2Indexes[$name]['comments'] );
00175                 $table_diff['removed_indexes'][$name] = $def;
00176             }
00177         }
00178         /* See if there are any changed definitions */
00179         foreach ( $table1Indexes as $name => $def )
00180         {
00181             if ( isset( $table2Indexes[$name] ) )
00182             {
00183                 if ( is_array( $index_diff = eZDbSchemaChecker::diffIndex( $def, $table2Indexes[$name], $schema1Type, $schema2Type ) ) )
00184                 {
00185                     $table_diff['changed_indexes'][$name] = $index_diff;
00186                 }
00187             }
00188         }
00189 
00190         return $table_diff;
00191     }
00192 
00193     /*!
00194      \static
00195      Finds the difference between the field \a $field1 and \a $field2.
00196 
00197      \return The field definition of the changed field or \c false if there are no changes.
00198     */
00199     static function diffField( $field1, $field2, $schema1Type, $schema2Type )
00200     {
00201         /* Type is always available */
00202         if ( $field1['type'] != $field2['type'] )
00203         {
00204             return array( 'different-options' => array( 'type' ), 'field-def' => $field2 );
00205             return $field2;
00206         }
00207 
00208         $test_fields = array( 'length', 'default', 'not_null' );
00209         $different_options = array();
00210 
00211         foreach ( $test_fields as $test_field )
00212         {
00213             if ( isset( $field1[$test_field] ) )
00214             {
00215                 if ( !isset( $field2[$test_field] ) ||
00216                      ( $field1[$test_field] != $field2[$test_field] ) )
00217                 {
00218                     $different_options[] = $test_field;
00219                 }
00220             }
00221             else
00222             {
00223                 if ( isset( $field2[$test_field] ) )
00224                 {
00225                     $different_options[] = $test_field;
00226                 }
00227             }
00228         }
00229 
00230         if ( $different_options )
00231             return array( 'different-options' => $different_options, 'field-def' => $field2 );
00232         else
00233             return false;
00234     }
00235 
00236     /*!
00237      \static
00238      Finds the difference between the indexes \a $index1 and \a $index2.
00239 
00240      \return The index definition of the changed index or \c false if there are no changes.
00241     */
00242     static function diffIndex( $index1, $index2, $schema1Type, $schema2Type )
00243     {
00244         if ( ( $index1['type'] != $index2['type'] ) ||
00245              count( array_diff( $index1, $index2 ) ) )
00246         {
00247             return $index2;
00248         }
00249 
00250         $test_fields = array( 'link_table' );
00251         foreach ( $test_fields as $test_field )
00252         {
00253             if ( isset($index1[$test_field] ) )
00254             {
00255                 if ( !isset( $index2[$test_field] ) ||
00256                      ( $index1[$test_field] != $index2[$test_field] ) )
00257                 {
00258                     return $index2;
00259                 }
00260             }
00261             else
00262             {
00263                 if ( isset($index2[$test_field] ) )
00264                 {
00265                     return $index2;
00266                 }
00267             }
00268         }
00269 
00270         $test_fields = array( 'fields', 'link_fields' );
00271         foreach ( $test_fields as $test_field )
00272         {
00273             if ( isset( $index1[$test_field] ) )
00274             {
00275                 if ( !isset( $index2[$test_field] ) ||
00276                      !( $index1[$test_field] == $index2[$test_field] ) )
00277                 {
00278                     return $index2;
00279                 }
00280             }
00281             else
00282             {
00283                 if ( isset( $index2[$test_field] ) )
00284                 {
00285                     return $index2;
00286                 }
00287             }
00288         }
00289     }
00290 }
00291 ?>