$def ) { // Skip the info structure, this is not a table if ( $name == '_info' ) continue; if ( !isset( $schema1['tables'][$name] ) ) { $diff['new_tables'][$name] = $def; } else { $table_diff = self::diffTable( $schema1['tables'][$name], $def ); if ( count( $table_diff ) ) { $diff['table_changes'][$name] = $table_diff; } } } /* Check if there are tables removed */ foreach ( $schema1['tables'] as $name => $def ) { // Skip the info structure, this is not a table if ( $name == '_info' ) continue; if ( !isset( $schema2['tables'][$name] ) ) { $diff['removed_tables'][$name] = $def; } else if ( isset( $schema2['tables'][$name]['removed'] ) and $schema2['tables'][$name]['removed'] ) { $diff['removed_tables'][$name] = $def; } } return $diff; } /** * Finds the difference between the tables \a $table1 and \a $table2 by looking * at the fields and indexes. * * @returns array(mixed) an array containing: * - added_fields - A list of new fields in the table * - removed_fields - A list of removed fields in the table * - changed_fields - A list of fields that have changed definition * - added_indexes - A list of new indexes in the table * - removed_indexes - A list of removed indexes in the table * - changed_indexes - A list of indexes that have changed definition */ private static final function diffTable( $table1, $table2 ) { $table_diff = array(); /* See if all the fields in table 1 exist in table 2 */ foreach ( $table2['fields'] as $name => $def ) { if ( !isset( $table1['fields'][$name] ) ) { $table_diff['added_fields'][$name] = $def; } } /* See if there are any removed fields in table 2 */ foreach ( $table1['fields'] as $name => $def ) { if ( !isset( $table2['fields'][$name] ) ) { $table_diff['removed_fields'][$name] = true; } else if ( isset( $table2['fields'][$name]['removed'] ) and $table2['fields'][$name]['removed'] ) { $table_diff['removed_fields'][$name] = true; } } /* See if there are any changed definitions */ foreach ( $table1['fields'] as $name => $def ) { if ( isset( $table2['fields'][$name] ) ) { if ( is_array( $field_diff = self::diffField( $def, $table2['fields'][$name] ) ) ) { $table_diff['changed_fields'][$name] = $field_diff; } } } $table1Indexes = $table1['indexes']; $table2Indexes = $table2['indexes']; /* See if all the indexes in table 1 exist in table 2 */ foreach ( $table2Indexes as $name => $def ) { if ( !isset( $table1Indexes[$name] ) ) { $table_diff['added_indexes'][$name] = $def; } } /* See if there are any removed indexes in table 2 */ foreach ( $table1Indexes as $name => $def ) { if ( !isset( $table2Indexes[$name] ) ) { $table_diff['removed_indexes'][$name] = $def; } else if ( isset( $table2Indexes[$name]['removed'] ) and $table2Indexes[$name]['removed'] ) { if ( isset( $table2Indexes[$name]['comments'] ) ) $def['comments'] = array_merge( isset( $def['comments'] ) ? $def['comments'] : array(), $table2Indexes[$name]['comments'] ); $table_diff['removed_indexes'][$name] = $def; } } /* See if there are any changed definitions */ foreach ( $table1Indexes as $name => $def ) { if ( isset( $table2Indexes[$name] ) ) { if ( is_array( $index_diff = self::diffIndex( $def, $table2Indexes[$name] ) ) ) { $table_diff['changed_indexes'][$name] = $index_diff; } } } return $table_diff; } /** * Finds the difference between the field \a $field1 and \a $field2. * * @returns The field definition of the changed field or \c false if there are no changes. */ private static final function diffField( $field1, $field2 ) { /* Type is always available */ if ( $field1['type'] != $field2['type'] ) { return array( 'different-options' => array( 'type' ), 'field-def' => $field2 ); return $field2; } $test_fields = array( 'length', 'default', 'not_null' ); $different_options = array(); foreach ( $test_fields as $test_field ) { if ( isset( $field1[$test_field] ) ) { if ( !isset( $field2[$test_field] ) || ( $field1[$test_field] != $field2[$test_field] ) ) { $different_options[] = $test_field; } } else { if ( isset( $field2[$test_field] ) ) { $different_options[] = $test_field; } } } if ( $different_options ) return array( 'different-options' => $different_options, 'field-def' => $field2 ); else return false; } /** * Finds the difference between the indexes \a $index1 and \a $index2. * * @returns The index definition of the changed index or \c false if there are no changes. */ private static final function diffIndex( $index1, $index2 ) { if ( ( $index1['type'] != $index2['type'] ) || count( array_diff( $index1, $index2 ) ) ) { return $index2; } $test_fields = array( 'link_table' ); foreach ( $test_fields as $test_field ) { if ( isset($index1[$test_field] ) ) { if ( !isset( $index2[$test_field] ) || ( $index1[$test_field] != $index2[$test_field] ) ) { return $index2; } } else { if ( isset($index2[$test_field] ) ) { return $index2; } } } $test_fields = array( 'fields', 'link_fields' ); foreach ( $test_fields as $test_field ) { if ( isset( $index1[$test_field] ) ) { if ( !isset( $index2[$test_field] ) || !( $index1[$test_field] == $index2[$test_field] ) ) { return $index2; } } else { if ( isset( $index2[$test_field] ) ) { return $index2; } } } } } ?>