From 1eac8dc44ec11730213e61364e20112de9ced13b Mon Sep 17 00:00:00 2001 From: Dan Feder Date: Tue, 24 May 2022 11:11:21 -0400 Subject: [PATCH] Turn off strict mode on import (#3784) --- .codeclimate.yml | 2 +- .../src/Storage/AbstractDatabaseTable.php | 4 +- .../src/Service/MysqlImport.php | 4 +- .../datastore/src/Storage/DatabaseTable.php | 15 ++++++ .../Functional/Storage/DatabaseTableTest.php | 48 +++++++++++++++++++ 5 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 modules/datastore/tests/src/Functional/Storage/DatabaseTableTest.php diff --git a/.codeclimate.yml b/.codeclimate.yml index 982772090b..890420be65 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -38,4 +38,4 @@ exclude_patterns: - "**/*.module" - ".circleci/" - ".gitignore" - + \ No newline at end of file diff --git a/modules/common/src/Storage/AbstractDatabaseTable.php b/modules/common/src/Storage/AbstractDatabaseTable.php index bd804f9536..42ac27c04d 100644 --- a/modules/common/src/Storage/AbstractDatabaseTable.php +++ b/modules/common/src/Storage/AbstractDatabaseTable.php @@ -266,9 +266,9 @@ private function sanitizedErrorMessage(string $unsanitizedMessage) { } /** - * Private. + * Create the table in the db if it does not yet exist. */ - private function setTable() { + protected function setTable() { if (!$this->tableExist($this->getTableName())) { if ($this->schema) { $this->tableCreate($this->getTableName(), $this->schema); diff --git a/modules/datastore/modules/datastore_mysql_import/src/Service/MysqlImport.php b/modules/datastore/modules/datastore_mysql_import/src/Service/MysqlImport.php index fdbd5f6df0..9f777f70c0 100644 --- a/modules/datastore/modules/datastore_mysql_import/src/Service/MysqlImport.php +++ b/modules/datastore/modules/datastore_mysql_import/src/Service/MysqlImport.php @@ -115,10 +115,10 @@ protected function runIt() { $spec = $this->generateTableSpec($columns); $this->dataStorage->setSchema(['fields' => $spec]); - // Call `count` on database table in order to ensure a database table has - // been created for the datastore. // @todo Find a better way to ensure creation of datastore tables. + $this->dataStorage->innodbStrictMode(FALSE); $this->dataStorage->count(); + $this->dataStorage->innodbStrictMode(TRUE); // Construct and execute a SQL import statement using the information // gathered from the CSV file being imported. $this->getDatabaseConnectionCapableOfDataLoad()->query( diff --git a/modules/datastore/src/Storage/DatabaseTable.php b/modules/datastore/src/Storage/DatabaseTable.php index e6b315f987..4c8de4a32b 100755 --- a/modules/datastore/src/Storage/DatabaseTable.php +++ b/modules/datastore/src/Storage/DatabaseTable.php @@ -6,6 +6,7 @@ use Dkan\Datastore\Resource; use Drupal\common\LoggerTrait; use Drupal\common\Storage\AbstractDatabaseTable; +use Drupal\Core\Database\Driver\mysql\Connection as MysqlConnection; /** * Database storage object. @@ -158,6 +159,20 @@ public function setSchema($schema) { parent::setSchema($schema); } + /** + * Disable/enable InnoDB strict mode for the given database connection. + * + * @param bool $on + * Whether strict mode should be "ON" or "OFF". + */ + public function innodbStrictMode(bool $on) { + $value = $on ? "ON" : "OFF"; + // Only if we're using MySQL. + if ($this->connection instanceof MysqlConnection) { + $this->connection->query("SET SESSION innodb_strict_mode=:value", [':value' => $value]); + } + } + /** * Get table schema. * diff --git a/modules/datastore/tests/src/Functional/Storage/DatabaseTableTest.php b/modules/datastore/tests/src/Functional/Storage/DatabaseTableTest.php new file mode 100644 index 0000000000..2c7e87812f --- /dev/null +++ b/modules/datastore/tests/src/Functional/Storage/DatabaseTableTest.php @@ -0,0 +1,48 @@ +query("SHOW SESSION VARIABLES LIKE 'innodb_strict_mode'")->fetchObject(); + $this->assertEquals($result->Value, "ON"); + + $resource = new Resource('123', '/tmp', 'text/csv'); + + $databaseTable = new DatabaseTable($connection, $resource); + $databaseTable->innodbStrictMode(FALSE); + + $result = $connection->query("SHOW SESSION VARIABLES LIKE 'innodb_strict_mode'")->fetchObject(); + $this->assertEquals($result->Value, "OFF"); + + // Other database connection not affected. + $connection2 = \Drupal::service('database'); + $result = $connection2->query("SHOW SESSION VARIABLES LIKE 'innodb_strict_mode'")->fetchObject(); + $this->assertEquals($result->Value, "ON"); + + // Safe mode can be turned back on. + $databaseTable->innodbStrictMode(TRUE); + $result = $connection->query("SHOW SESSION VARIABLES LIKE 'innodb_strict_mode'")->fetchObject(); + $this->assertEquals($result->Value, "ON"); + } + +}