You are here

function schema_compare_schemas in Schema 7

Same name and namespace in other branches
  1. 8 schema.module \schema_compare_schemas()
  2. 5 schema.module \schema_compare_schemas()
  3. 6 schema.module \schema_compare_schemas()

Compares two complete schemas.

Parameters

$ref is considered the reference copy:

$inspect is compared against it. If $inspect is NULL, a: schema for the active database is generated and used.

3 calls to schema_compare_schemas()
drush_schema_compare in ./schema.drush.inc
Implements drush_COMMANDFILE_COMMANDNAME().
schema_compare in ./schema.pages.inc
"Compare" menu callback.
schema_requirements in ./schema.install
Implementation of hook_requirements(). Checks installation requirements and do status reporting.

File

./schema.module, line 396
The Schema module provides functionality built on the Schema API.

Code

function schema_compare_schemas($ref, $inspect = NULL) {
  if (!isset($inspect)) {
    $inspect = schema_dbobject()
      ->inspect();
  }
  $info = array();

  // Error checks to consider adding:
  // All type serial columns must be in an index or key.
  // All columns in a primary or unique key must be NOT NULL.
  // Error check: column type and default type must match
  foreach ($ref as $t_name => $table) {
    if (!isset($table['fields']) || !is_array($table['fields'])) {
      drupal_set_message(t('Table %table: Missing or invalid \'fields\' array.', array(
        '%table' => $t_name,
      )), 'warning');
      continue;
    }
    foreach ($table['fields'] as $c_name => $col) {
      switch ($col['type']) {
        case 'int':
        case 'float':
        case 'numeric':
          if (isset($col['default']) && (!is_numeric($col['default']) || is_string($col['default']))) {
            $info['warn'][] = t('%table.%column is type %type but its default %default is PHP type %phptype', array(
              '%table' => $t_name,
              '%column' => $c_name,
              '%type' => $col['type'],
              '%default' => $col['default'],
              '%phptype' => gettype($col['default']),
            ));
          }
          break;
        default:
          if (isset($col['default']) && !is_string($col['default'])) {
            $info['warn'][] = t('%table.%column is type %type but its default %default is PHP type %phptype', array(
              '%table' => $t_name,
              '%column' => $c_name,
              '%type' => $col['type'],
              '%default' => $col['default'],
              '%phptype' => gettype($col['default']),
            ));
          }
          break;
      }
    }
  }

  // Error check: 'text' and 'blob' columns cannot have a default value
  foreach ($ref as $t_name => $table) {
    if (!isset($table['fields'])) {
      continue;
    }
    foreach ($table['fields'] as $c_name => $col) {
      switch ($col['type']) {
        case 'text':
        case 'blob':
          if (isset($col['default'])) {
            $info['warn'][] = t('%table.%column is type %type and may not have a default value', array(
              '%table' => $t_name,
              '%column' => $c_name,
              '%type' => $col['type'],
            ));
          }
          break;
      }
    }
  }

  // Error check: primary keys must be 'not null'
  foreach ($ref as $t_name => $table) {
    if (isset($table['primary key'])) {
      $keys = db_field_names($table['primary key']);
      foreach ($keys as $key) {
        if (!isset($table['fields'][$key]['not null']) || $table['fields'][$key]['not null'] != TRUE) {
          $info['warn'][] = t('%table.%column is part of the primary key but is not specified to be \'not null\'.', array(
            '%table' => $t_name,
            '%column' => $key,
          ));
        }
      }
    }
  }
  foreach ($ref as $name => $table) {
    if (isset($table['module'])) {
      $module = $table['module'];
    }
    else {
      $module = '';
    }
    if (!isset($inspect[$name])) {
      $info['missing'][$module][$name] = array(
        'status' => 'missing',
      );
    }
    else {
      $status = schema_compare_table($table, $inspect[$name]);
      $info[$status['status']][$module][$name] = $status;
      unset($inspect[$name]);
    }
  }
  foreach ($inspect as $name => $table) {
    $info['extra'][] = $name;
  }
  return $info;
}