Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Run fulltext index alters one at at time #4288

Merged
merged 6 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -514,12 +514,41 @@ protected function buildAddIndexOptions(array $indexes, string $table, array $ty
$comment = addslashes($description);

// Build add index option list.
$add_index_options[] = "ADD {$mysql_index_type} INDEX {$name} ({$formatted_field_options}) COMMENT '{$comment}'";
if ($index_type == 'index') {
$add_index_options[] = "ADD {$mysql_index_type} INDEX {$name} ({$formatted_field_options}) COMMENT '{$comment}'";
}
if ($index_type == 'fulltext') {
$this->executeFulltextAlter($table, $name, $formatted_field_options, $comment);
}
}

return $add_index_options;
}

/**
* Execute fulltext index table alters.
*
* @param string $table
* Table name.
* @param string $name
* Index name.
* @param string $formatted_field_options
* Fields to be indexed.
* @param string $comment
* Description of the index.
*/
protected function executeFulltextAlter(string $table, string $name, string $formatted_field_options, string $comment): void {
try {
// Innodb only allows adding one fulltext index at a time.
$command = $this->connection->prepareStatement("ALTER TABLE {{$table}} ADD FULLTEXT INDEX {$name} ({$formatted_field_options}) COMMENT '{$comment}';", []);
// Execute alter command.
$command->execute();
}
catch (\Exception) {
\Drupal::logger('Data Dictionary')->error("Error applying fulltext index to dataset {$comment}");
}
}

/**
* Convert Frictionless to MySQL index types.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?php

declare(strict_types=1);

namespace Drupal\Tests\datastore\Kernel\DataDictionary\AlterTableQuery;

use Drupal\Core\Database\Connection;
use Drupal\Core\Logger\LoggerChannelFactory;
use Drupal\Core\Logger\LoggerChannelInterface;
use Drupal\datastore\DataDictionary\AlterTableQuery\MySQLQuery;
use Drupal\KernelTests\KernelTestBase;

/**
* @coversDefaultClass \Drupal\datastore\DataDictionary\AlterTableQuery\MySQLQuery
*
* @group dkan
* @group datastore
* @group kernel
*/
class MySQLQueryTest extends KernelTestBase {

protected static $modules = [
'common',
'datastore',
'metastore',
];

/**
* @covers ::executeFulltextAlter
*/
public function testExecuteFullTextAlterWithException(): void {
$exception_message = 'Test exception message.';
$comment_message = 'comment message';

// Throw an exception from the connection object.
$connection = $this->getMockBuilder(Connection::class)
->disableOriginalConstructor()
->onlyMethods(['prepareStatement'])
->getMockForAbstractClass();
$connection->expects($this->once())
->method('prepareStatement')
->willThrowException(new \Exception($exception_message));

$this->container->set('database', $connection);

// Set up a logger channel to expect our log message.
$logger = $this->getMockBuilder(LoggerChannelInterface::class)
->onlyMethods(['error'])
->getMockForAbstractClass();
// Error() must be called once, with our special message.
$logger->expects($this->once())
->method('error')
->with('Error applying fulltext index to dataset ' . $comment_message);

// Mock a logger factory to return our special mocked logger.
$logger_factory = $this->getMockBuilder(LoggerChannelFactory::class)
->disableOriginalConstructor()
->onlyMethods(['get'])
->getMock();
$logger_factory->expects($this->once())
->method('get')
->willReturn($logger);

$this->container->set('logger.factory', $logger_factory);

// Get a MySQLQuery object to test.
$table = 'foo';
$mysql_query = new MySQLQuery(
$connection,
$this->container->get('pdlt.converter.strptime_to_mysql'),
$table,
[],
[]
);

// Set executeFulltextAlter() to be public and run it.
$ref_full_text_alter = new \ReflectionMethod($mysql_query, 'executeFulltextAlter');
$ref_full_text_alter->setAccessible(TRUE);
$ref_full_text_alter->invokeArgs($mysql_query, ['', '', '', $comment_message]);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,9 @@ public function testExecute(): void {
$this->assertEquals("ALTER TABLE {" . $table . "} MODIFY COLUMN foo TEXT COMMENT 'Foo', " .
"MODIFY COLUMN bar DECIMAL(10, 5) COMMENT 'Bar', " .
"MODIFY COLUMN baz DATE COMMENT 'Baz', " .
"ADD INDEX index1 (foo (12), bar, baz) COMMENT 'Fizz', " .
"ADD FULLTEXT INDEX index2 (foo (6), baz) COMMENT '';", $query);
"ADD INDEX index1 (foo (12), bar, baz) COMMENT 'Fizz';", $query);
}


/**
* Ensure alter fails when attempting to apply decimal type to large numbers.
*/
Expand Down