function schema_compare_table in Schema 5
Same name and namespace in other branches
- 8 schema.module \schema_compare_table()
- 6 schema.module \schema_compare_table()
- 7 schema.module \schema_compare_table()
1 call to schema_compare_table()
File
- ./
schema.module, line 269
Code
function schema_compare_table($ref, $inspect = NULL) {
global $db_type;
$_db_type = $db_type;
if ($_db_type == 'mysqli') {
$_db_type = 'mysql';
}
if (!isset($inspect)) {
$inspect = schema_invoke('inspect', $ref['name']);
$inspect = $inspect[$ref['name']];
}
if (!isset($inspect)) {
return array(
'status' => 'missing',
);
}
$reasons = $notes = array();
$col_keys = array_flip(array(
'type',
'size',
'not null',
'length',
'unsigned',
'default',
));
foreach ($ref['fields'] as $colname => $col) {
// Many Schema types can map to the same engine type (e.g. in
// PostgresSQL, text:{small,medium,big} are all just text). When
// we inspect the database, we see the common type, but the
// reference we are comparing against can have a specific type.
// We therefore run the reference's specific type through the
// type conversion cycle to get its common type for comparison.
//
// Sadly, we need a special-case hack for 'serial'.
$serial = $col['type'] == 'serial' ? TRUE : FALSE;
$dbtype = schema_engine_type($col, $ref['name'], $colname);
list($col['type'], $col['size']) = schema_schema_type($dbtype, $ref['name'], $colname);
if ($serial) {
$col['type'] = 'serial';
}
// If an engine-specific type is specified, use it. XXX $inspect
// will contain the schema type for the engine type, if one
// exists, whereas dbtype_type contains the engine type.
if (isset($col[$_db_type . '_type'])) {
$col['type'] = $col[$_db_type . '_type'];
}
$col = array_intersect_key($col, $col_keys);
if (!isset($inspect['fields'][$colname])) {
$reasons[] = "{$colname}: not in database";
continue;
}
// XXX These should be unified so one reason contains all
// mismatches between the columns.
$colcmp1 = array_diff_assoc($col, $inspect['fields'][$colname]);
if (count($colcmp1) != 0) {
foreach ($colcmp1 as $key => $val) {
$reasons[] = "column {$colname}:<br/>declared: " . schema_phpprint_column($col) . '<br/>actual: ' . schema_phpprint_column($inspect['fields'][$colname]);
}
}
$colcmp2 = array_diff_assoc($inspect['fields'][$colname], $col);
if (count($colcmp2) != 0) {
foreach ($colcmp2 as $key => $val) {
if (isset($col_keys[$key]) && !isset($colcmp1[$key])) {
if (!isset($col['key']) && isset($inspect['fields'][$colname]) && $inspect['fields'][$colname][$key] === FALSE) {
$notes[] = "column {$colname}: key '{$key}' not set, ignoring inspected default value";
}
else {
$reasons[] = "column {$colname}:<br/>declared: " . schema_phpprint_column($col) . '<br/>actual: ' . schema_phpprint_column($inspect['fields'][$colname]);
}
}
}
}
unset($inspect['fields'][$colname]);
}
foreach ($inspect['fields'] as $colname => $col) {
$reasons[] = "{$colname}: unexpected column in database";
}
if (isset($ref['primary key'])) {
if (!isset($inspect['primary key'])) {
$reasons[] = "primary key: missing in database";
}
else {
if ($ref['primary key'] !== $inspect['primary key']) {
$reasons[] = "primary key:<br />declared: " . schema_phpprint_key($ref['primary key']) . '<br />actual: ' . schema_phpprint_key($inspect['primary key']);
}
}
}
else {
if (isset($inspect['primary key'])) {
$reasons[] = "primary key: missing in schema";
}
}
foreach (array(
'unique keys',
'indexes',
) as $type) {
if (isset($ref[$type])) {
foreach ($ref[$type] as $keyname => $key) {
if (!isset($inspect[$type][$keyname])) {
$reasons[] = "{$type} {$keyname}: missing in database";
continue;
}
// $key is column list
if ($key !== $inspect[$type][$keyname]) {
$reasons[] = "{$type} {$keyname}:<br />declared: " . schema_phpprint_key($key) . '<br />actual: ' . schema_phpprint_key($inspect[$type][$keyname]);
}
unset($inspect[$type][$keyname]);
}
}
if (isset($inspect[$type])) {
foreach ($inspect[$type] as $keyname => $col) {
// this is not an error, the dba might have added it on purpose
$notes[] = "{$type} {$keyname}: unexpected (not an error)";
}
}
}
$status = count($reasons) ? 'different' : 'same';
return array(
'status' => $status,
'reasons' => $reasons,
'notes' => $notes,
);
}