You are here

protected function DbDumpCommand::getTableSchema in Drupal 9

Same name and namespace in other branches
  1. 8 core/lib/Drupal/Core/Command/DbDumpCommand.php \Drupal\Core\Command\DbDumpCommand::getTableSchema()

Returns a schema array for a given table.

@todo This implementation is hard-coded for MySQL.

Parameters

\Drupal\Core\Database\Connection $connection: The database connection to use.

string $table: The table name.

Return value

array A schema array (as defined by hook_schema()).

1 call to DbDumpCommand::getTableSchema()
DbDumpCommand::generateScript in core/lib/Drupal/Core/Command/DbDumpCommand.php
Generates the database script.

File

core/lib/Drupal/Core/Command/DbDumpCommand.php, line 144

Class

DbDumpCommand
Provides a command to dump the current database to a script.

Namespace

Drupal\Core\Command

Code

protected function getTableSchema(Connection $connection, $table) {

  // Check this is MySQL.
  if ($connection
    ->databaseType() !== 'mysql') {
    throw new \RuntimeException('This script can only be used with MySQL database backends.');
  }
  $query = $connection
    ->query("SHOW FULL COLUMNS FROM {" . $table . "}");
  $definition = [];
  while (($row = $query
    ->fetchAssoc()) !== FALSE) {
    $name = $row['Field'];

    // Parse out the field type and meta information.
    preg_match('@([a-z]+)(?:\\((\\d+)(?:,(\\d+))?\\))?\\s*(unsigned)?@', $row['Type'], $matches);
    $type = $this
      ->fieldTypeMap($connection, $matches[1]);
    if ($row['Extra'] === 'auto_increment') {

      // If this is an auto increment, then the type is 'serial'.
      $type = 'serial';
    }
    $definition['fields'][$name] = [
      'type' => $type,
      'not null' => $row['Null'] === 'NO',
    ];
    if ($size = $this
      ->fieldSizeMap($connection, $matches[1])) {
      $definition['fields'][$name]['size'] = $size;
    }
    if (isset($matches[2]) && $type === 'numeric') {

      // Add precision and scale.
      $definition['fields'][$name]['precision'] = $matches[2];
      $definition['fields'][$name]['scale'] = $matches[3];
    }
    elseif ($type === 'time') {

      // @todo Core doesn't support these, but copied from `migrate-db.sh` for now.
      // Convert to varchar.
      $definition['fields'][$name]['type'] = 'varchar';
      $definition['fields'][$name]['length'] = '100';
    }
    elseif ($type === 'datetime') {

      // Adjust for other database types.
      $definition['fields'][$name]['mysql_type'] = 'datetime';
      $definition['fields'][$name]['pgsql_type'] = 'timestamp without time zone';
      $definition['fields'][$name]['sqlite_type'] = 'varchar';
      $definition['fields'][$name]['sqlsrv_type'] = 'smalldatetime';
    }
    elseif (!isset($definition['fields'][$name]['size'])) {

      // Try use the provided length, if it doesn't exist default to 100. It's
      // not great but good enough for our dumps at this point.
      $definition['fields'][$name]['length'] = isset($matches[2]) ? $matches[2] : 100;
    }
    if (isset($row['Default'])) {
      $definition['fields'][$name]['default'] = $row['Default'];
    }
    if (isset($matches[4])) {
      $definition['fields'][$name]['unsigned'] = TRUE;
    }

    // Check for the 'varchar_ascii' type that should be 'binary'.
    if (isset($row['Collation']) && $row['Collation'] == 'ascii_bin') {
      $definition['fields'][$name]['type'] = 'varchar_ascii';
      $definition['fields'][$name]['binary'] = TRUE;
    }

    // Check for the non-binary 'varchar_ascii'.
    if (isset($row['Collation']) && $row['Collation'] == 'ascii_general_ci') {
      $definition['fields'][$name]['type'] = 'varchar_ascii';
    }

    // Check for the 'utf8_bin' collation.
    if (isset($row['Collation']) && $row['Collation'] == 'utf8_bin') {
      $definition['fields'][$name]['binary'] = TRUE;
    }
  }

  // Set primary key, unique keys, and indexes.
  $this
    ->getTableIndexes($connection, $table, $definition);

  // Set table collation.
  $this
    ->getTableCollation($connection, $table, $definition);
  return $definition;
}