|
eZ Publish
[4.0]
|
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 ?>