function SchemaTest::testIndexLength

Same name and namespace in other branches
  1. 9 core/modules/mysql/tests/src/Kernel/mysql/SchemaTest.php \Drupal\Tests\mysql\Kernel\mysql\SchemaTest::testIndexLength()
  2. 10 core/modules/mysql/tests/src/Kernel/mysql/SchemaTest.php \Drupal\Tests\mysql\Kernel\mysql\SchemaTest::testIndexLength()
  3. 11.x core/modules/mysql/tests/src/Kernel/mysql/SchemaTest.php \Drupal\Tests\mysql\Kernel\mysql\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/tests/Drupal/KernelTests/Core/Database/SchemaTest.php, line 360

Class

SchemaTest
Tests table creation and modification via the schema API.

Namespace

Drupal\KernelTests\Core\Database

Code

public function testIndexLength() {
    if ($this->connection
        ->databaseType() !== 'mysql') {
        $this->markTestSkipped("The '{$this->connection->databaseType()}' database type does not support setting column length for indexes.");
    }
    $table_specification = [
        'fields' => [
            'id' => [
                'type' => 'int',
                'default' => NULL,
            ],
            'test_field_text' => [
                'type' => 'text',
                'not null' => TRUE,
            ],
            'test_field_string_long' => [
                'type' => 'varchar',
                'length' => 255,
                'not null' => TRUE,
            ],
            'test_field_string_ascii_long' => [
                'type' => 'varchar_ascii',
                'length' => 255,
            ],
            'test_field_string_short' => [
                'type' => 'varchar',
                'length' => 128,
                'not null' => TRUE,
            ],
        ],
        'indexes' => [
            'test_regular' => [
                'test_field_text',
                'test_field_string_long',
                'test_field_string_ascii_long',
                'test_field_string_short',
            ],
            'test_length' => [
                [
                    'test_field_text',
                    128,
                ],
                [
                    'test_field_string_long',
                    128,
                ],
                [
                    'test_field_string_ascii_long',
                    128,
                ],
                [
                    'test_field_string_short',
                    128,
                ],
            ],
            'test_mixed' => [
                [
                    'test_field_text',
                    200,
                ],
                'test_field_string_long',
                [
                    'test_field_string_ascii_long',
                    200,
                ],
                'test_field_string_short',
            ],
        ],
    ];
    $this->schema
        ->createTable('test_table_index_length', $table_specification);
    // 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 {
        $this->schema
            ->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.
    $this->schema
        ->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 {
        $this->schema
            ->addIndex('test_table_index_length', 'test_separate', [
            [
                'test_field_text',
                200,
            ],
        ], $table_specification);
        $this->fail('\\Drupal\\Core\\Database\\SchemaObjectExistsException exception missed.');
    } catch (SchemaObjectExistsException $e) {
        // Expected exception; just continue testing.
    }
    try {
        $this->schema
            ->addIndex('test_table_non_existing', 'test_separate', [
            [
                'test_field_text',
                200,
            ],
        ], $table_specification);
        $this->fail('\\Drupal\\Core\\Database\\SchemaObjectDoesNotExistException exception missed.');
    } catch (SchemaObjectDoesNotExistException $e) {
        // Expected exception; just continue testing.
    }
    // Get index information.
    $results = $this->connection
        ->query('SHOW INDEX FROM {test_table_index_length}');
    $expected_lengths = [
        'test_regular' => [
            'test_field_text' => 191,
            'test_field_string_long' => 191,
            'test_field_string_ascii_long' => NULL,
            'test_field_string_short' => NULL,
        ],
        'test_length' => [
            'test_field_text' => 128,
            'test_field_string_long' => 128,
            'test_field_string_ascii_long' => 128,
            'test_field_string_short' => NULL,
        ],
        'test_mixed' => [
            'test_field_text' => 191,
            'test_field_string_long' => 191,
            'test_field_string_ascii_long' => 200,
            'test_field_string_short' => NULL,
        ],
        'test_separate' => [
            '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.');
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.