You are here

function SchemaTest::testIndexLength in Zircon Profile 8

Same name and namespace in other branches
  1. 8.0 core/modules/system/src/Tests/Database/SchemaTest.php \Drupal\system\Tests\Database\SchemaTest::testIndexLength()

Tests that indexes on string fields are limited to 191 characters on MySQL.

See also

\Drupal\Core\Database\Driver\mysql\Schema::getNormalizedIndexes()

File

core/modules/system/src/Tests/Database/SchemaTest.php, line 247
Contains \Drupal\system\Tests\Database\SchemaTest.

Class

SchemaTest
Tests table creation and modification via the schema API.

Namespace

Drupal\system\Tests\Database

Code

function testIndexLength() {
  if (Database::getConnection()
    ->databaseType() != 'mysql') {
    return;
  }
  $table_specification = array(
    'fields' => array(
      'id' => array(
        'type' => 'int',
        'default' => NULL,
      ),
      'test_field_text' => array(
        'type' => 'text',
        'not null' => TRUE,
      ),
      'test_field_string_long' => array(
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
      ),
      'test_field_string_ascii_long' => array(
        'type' => 'varchar_ascii',
        'length' => 255,
      ),
      'test_field_string_short' => array(
        'type' => 'varchar',
        'length' => 128,
        'not null' => TRUE,
      ),
    ),
    'indexes' => array(
      'test_regular' => array(
        'test_field_text',
        'test_field_string_long',
        'test_field_string_ascii_long',
        'test_field_string_short',
      ),
      'test_length' => array(
        array(
          'test_field_text',
          128,
        ),
        array(
          'test_field_string_long',
          128,
        ),
        array(
          'test_field_string_ascii_long',
          128,
        ),
        array(
          'test_field_string_short',
          128,
        ),
      ),
      'test_mixed' => array(
        array(
          'test_field_text',
          200,
        ),
        'test_field_string_long',
        array(
          'test_field_string_ascii_long',
          200,
        ),
        'test_field_string_short',
      ),
    ),
  );
  db_create_table('test_table_index_length', $table_specification);
  $schema_object = Database::getConnection()
    ->schema();

  // Ensure expected exception thrown when adding index with missing info.
  $expected_exception_message = "MySQL needs the 'test_field_text' field specification in order to normalize the 'test_regular' index";
  $missing_field_spec = $table_specification;
  unset($missing_field_spec['fields']['test_field_text']);
  try {
    $schema_object
      ->addIndex('test_table_index_length', 'test_separate', [
      [
        'test_field_text',
        200,
      ],
    ], $missing_field_spec);
    $this
      ->fail('SchemaException not thrown when adding index with missing information.');
  } catch (SchemaException $e) {
    $this
      ->assertEqual($expected_exception_message, $e
      ->getMessage());
  }

  // Add a separate index.
  $schema_object
    ->addIndex('test_table_index_length', 'test_separate', [
    [
      'test_field_text',
      200,
    ],
  ], $table_specification);
  $table_specification_with_new_index = $table_specification;
  $table_specification_with_new_index['indexes']['test_separate'] = [
    [
      'test_field_text',
      200,
    ],
  ];

  // Ensure that the exceptions of addIndex are thrown as expected.
  try {
    $schema_object
      ->addIndex('test_table_index_length', 'test_separate', [
      [
        'test_field_text',
        200,
      ],
    ], $table_specification);
    $this
      ->fail('\\Drupal\\Core\\Database\\SchemaObjectExistsException exception missed.');
  } catch (SchemaObjectExistsException $e) {
    $this
      ->pass('\\Drupal\\Core\\Database\\SchemaObjectExistsException thrown when index already exists.');
  }
  try {
    $schema_object
      ->addIndex('test_table_non_existing', 'test_separate', [
      [
        'test_field_text',
        200,
      ],
    ], $table_specification);
    $this
      ->fail('\\Drupal\\Core\\Database\\SchemaObjectDoesNotExistException exception missed.');
  } catch (SchemaObjectDoesNotExistException $e) {
    $this
      ->pass('\\Drupal\\Core\\Database\\SchemaObjectDoesNotExistException thrown when index already exists.');
  }

  // Get index information.
  $results = db_query('SHOW INDEX FROM {test_table_index_length}');
  $expected_lengths = array(
    'test_regular' => array(
      'test_field_text' => 191,
      'test_field_string_long' => 191,
      'test_field_string_ascii_long' => NULL,
      'test_field_string_short' => NULL,
    ),
    'test_length' => array(
      'test_field_text' => 128,
      'test_field_string_long' => 128,
      'test_field_string_ascii_long' => 128,
      'test_field_string_short' => NULL,
    ),
    'test_mixed' => array(
      'test_field_text' => 191,
      'test_field_string_long' => 191,
      'test_field_string_ascii_long' => 200,
      'test_field_string_short' => NULL,
    ),
    'test_separate' => array(
      'test_field_text' => 191,
    ),
  );

  // Count the number of columns defined in the indexes.
  $column_count = 0;
  foreach ($table_specification_with_new_index['indexes'] as $index) {
    foreach ($index as $field) {
      $column_count++;
    }
  }
  $test_count = 0;
  foreach ($results as $result) {
    $this
      ->assertEqual($result->Sub_part, $expected_lengths[$result->Key_name][$result->Column_name], 'Index length matches expected value.');
    $test_count++;
  }
  $this
    ->assertEqual($test_count, $column_count, 'Number of tests matches expected value.');
}