You are here

function _demo_dump_table_schema in Demonstration site (Sandbox / Snapshot) 8

Same name and namespace in other branches
  1. 6 database_mysql_dump.inc \_demo_dump_table_schema()
  2. 7 database_mysql_dump.inc \_demo_dump_table_schema()

Dump table schema.

Parameters

$fp: The file handle of the output file.

$table: A table name to export the schema for.

1 call to _demo_dump_table_schema()
demo_dump_db in ./demo.module
Dump active database.

File

./demo.module, line 237

Code

function _demo_dump_table_schema($fp, $table) {
  $output = "\n";
  $output .= "--\n";
  $output .= "-- Table structure for table '{$table}'\n";
  $output .= "--\n\n";
  $connection = \Drupal::database();
  $data = $connection
    ->query('SHOW CREATE TABLE ' . $table)
    ->fetchAssoc();
  $status = $connection
    ->query('SHOW TABLE STATUS LIKE :table', [
    ':table' => $table,
  ])
    ->fetchAssoc();

  // Column keys in $status start with a lower-case letter in PDO and with a
  // upper-case letter otherwise. We convert all to lower-case.
  foreach ($status as $key => $value) {
    $key_lower = strtolower($key);
    if ($key[0] != $key_lower[0]) {
      $status[$key_lower] = $value;
      unset($status[$key]);
    }
  }

  // Add IF NOT EXISTS to CREATE TABLE, replace double quotes with MySQL quotes.
  $pattern_regex = [
    '/^CREATE TABLE/',
    '/"/',
  ];
  $replacement_regex = [
    'CREATE TABLE IF NOT EXISTS',
    '`',
  ];
  $text = $data['Create Table'];
  $output .= preg_replace($pattern_regex, $replacement_regex, $text);

  // @todo Rethink the following code. Perhaps try to strip + parse the existing
  //   table definition (after leading ")" on last line) and merge anything
  //   missing into it, and re-append it again. There are too many differences
  //   between MySQL 5.0 and 5.1+, and PHP mysql(i) and pdo_mysql extensions.
  // PDO is missing the table engine.
  if (!strpos($output, ' ENGINE=')) {
    $output .= ' ENGINE=' . $status['engine'];
  }

  // Always add charset and collation info to table definitions.
  // SHOW CREATE TABLE does not contain collation information, if the collation
  // is equal to the default collation of the connection. Since dumps can be
  // moved across servers, we need to ensure correct collations.
  // Note that [DEFAULT] CHARSET or [DEFAULT] CHARACTER SET is always contained
  // on MySQL 5.1, even if it is equal to the default.
  // This addition assumes that a collation specified for a table is taken over
  // for the table's columns. The MySQL manual does not state whether this is
  // the case, but manual tests confirmed that it works that way.
  // Like Drupal core, we need to enforce UTF8 as character set and
  // utf8_general_ci as default database collation, if not overridden via
  // settings.php.
  // if (!strpos($output, 'COLLATE=')) {
  //   // Only if the collation contains a underscore, the first string up to the
  //   // first underscore is the character set.
  //   // @see PMA_exportDBCreate()
  //   if (strpos($status['collation'], '_')) {
  //     $collate = 'COLLATE=' . $status['Collation'];
  //   }
  //   // If there is a character set defined already, just append the collation.
  //   if (strpos($output, 'CHARSET') || strpos($output, 'CHARACTER SET')) {
  //     // @todo This may also hit column definitions instead of the table
  //     //   definition only. Should technically also be case-insensitive.
  //     $output = preg_replace('@((?:DEFAULT )?(?:CHARSET|CHARACTER SET) \w+)@', '$1 ' . $collate, $output);
  //   }
  //   else {
  //     $output .= ' DEFAULT CHARSET=utf8 ' . $collate;
  //   }
  // }.
  // Add the table comment, if any.
  if (!preg_match('@^\\) .*COMMENT.+$@', $output) && !empty($status['comment'])) {

    // On PHP 5.2.6/Win32 with PDO MySQL 5.0 with InnoDB, the table comment has
    // a trailing "; InnoDB free: 84992 kB".
    $status['comment'] = preg_replace([
      '@; InnoDB free: .+$@',
      "/\\'/",
    ], [
      '',
      '`',
    ], $status['comment']);
    $output .= " COMMENT='" . $status['comment'] . "'";
  }

  // @todo Depends on whether we dump data and table existence on import.
  if (!empty($status['auto_increment'])) {
    $output .= ' AUTO_INCREMENT=' . $status['auto_increment'];
  }
  $output .= ";\n";
  fwrite($fp, $output);
}