You are here

protected function Schema::introspectSchema in Drupal 10

Find out the schema of a table.

This function uses introspection methods provided by the database to create a schema array. This is useful, for example, during update when the old schema is not available.

Parameters

$table: Name of the table.

Return value

An array representing the schema.

Throws

\Exception If a column of the table could not be parsed.

9 calls to Schema::introspectSchema()
Schema::addField in core/modules/sqlite/src/Driver/Database/sqlite/Schema.php
Add a new field to a table.
Schema::addPrimaryKey in core/modules/sqlite/src/Driver/Database/sqlite/Schema.php
Add a primary key.
Schema::changeField in core/modules/sqlite/src/Driver/Database/sqlite/Schema.php
Change a field definition.
Schema::dropField in core/modules/sqlite/src/Driver/Database/sqlite/Schema.php
Drop a field.
Schema::dropPrimaryKey in core/modules/sqlite/src/Driver/Database/sqlite/Schema.php
Drop the primary key.

... See full list

File

core/modules/sqlite/src/Driver/Database/sqlite/Schema.php, line 484

Class

Schema
SQLite implementation of \Drupal\Core\Database\Schema.

Namespace

Drupal\sqlite\Driver\Database\sqlite

Code

protected function introspectSchema($table) {
  $mapped_fields = array_flip($this
    ->getFieldTypeMap());
  $schema = [
    'fields' => [],
    'primary key' => [],
    'unique keys' => [],
    'indexes' => [],
  ];
  $info = $this
    ->getPrefixInfo($table);
  $result = $this->connection
    ->query('PRAGMA ' . $info['schema'] . '.table_info(' . $info['table'] . ')');
  foreach ($result as $row) {
    if (preg_match('/^([^(]+)\\((.*)\\)$/', $row->type, $matches)) {
      $type = $matches[1];
      $length = $matches[2];
    }
    else {
      $type = $row->type;
      $length = NULL;
    }
    if (isset($mapped_fields[$type])) {
      [
        $type,
        $size,
      ] = explode(':', $mapped_fields[$type]);
      $schema['fields'][$row->name] = [
        'type' => $type,
        'size' => $size,
        'not null' => !empty($row->notnull) || $row->pk !== "0",
      ];
      if ($length) {
        $schema['fields'][$row->name]['length'] = $length;
      }

      // Convert the default into a properly typed value.
      if ($row->dflt_value === 'NULL') {
        $schema['fields'][$row->name]['default'] = NULL;
      }
      elseif (is_string($row->dflt_value) && $row->dflt_value[0] === '\'') {

        // Remove the wrapping single quotes. And replace duplicate single
        // quotes with a single quote.
        $schema['fields'][$row->name]['default'] = str_replace("''", "'", substr($row->dflt_value, 1, -1));
      }
      elseif (is_numeric($row->dflt_value)) {

        // Adding 0 to a string will cause PHP to convert it to a float or
        // an integer depending on what the string is. For example:
        // - '1' + 0 = 1
        // - '1.0' + 0 = 1.0
        $schema['fields'][$row->name]['default'] = $row->dflt_value + 0;
      }
      else {
        $schema['fields'][$row->name]['default'] = $row->dflt_value;
      }

      // $row->pk contains a number that reflects the primary key order. We
      // use that as the key and sort (by key) below to return the primary key
      // in the same order that it is stored in.
      if ($row->pk) {
        $schema['primary key'][$row->pk] = $row->name;
      }
    }
    else {
      throw new \Exception("Unable to parse the column type " . $row->type);
    }
  }
  ksort($schema['primary key']);

  // Re-key the array because $row->pk starts counting at 1.
  $schema['primary key'] = array_values($schema['primary key']);
  $indexes = [];
  $result = $this->connection
    ->query('PRAGMA ' . $info['schema'] . '.index_list(' . $info['table'] . ')');
  foreach ($result as $row) {
    if (strpos($row->name, 'sqlite_autoindex_') !== 0) {
      $indexes[] = [
        'schema_key' => $row->unique ? 'unique keys' : 'indexes',
        'name' => $row->name,
      ];
    }
  }
  foreach ($indexes as $index) {
    $name = $index['name'];

    // Get index name without prefix.
    $index_name = substr($name, strlen($info['table']) + 1);
    $result = $this->connection
      ->query('PRAGMA ' . $info['schema'] . '.index_info(' . $name . ')');
    foreach ($result as $row) {
      $schema[$index['schema_key']][$index_name][] = $row->name;
    }
  }
  return $schema;
}