Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[11.x] Improve MySQL connect init time by setting all our variables in a single shot #50044

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 21, 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
20 changes: 16 additions & 4 deletions 20 src/Illuminate/Database/Connectors/MariaDbConnector.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,26 @@
class MariaDbConnector extends MySqlConnector implements ConnectorInterface
{
/**
* Get the query to enable strict mode.
* Get the sql_mode value.
*
* @param \PDO $connection
* @param array $config
* @return string
* @return string|null
*/
protected function strictMode(PDO $connection, $config)
protected function getSqlMode(PDO $connection, array $config)
{
return "set session sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'";
if (isset($config['modes'])) {
return implode(',', $config['modes']);
}

if (! isset($config['strict'])) {
return null;
}

if (! $config['strict']) {
return 'NO_ENGINE_SUBSTITUTION';
}

return 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
}
}
138 changes: 42 additions & 96 deletions 138 src/Illuminate/Database/Connectors/MySqlConnector.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,81 +27,11 @@ public function connect(array $config)
$connection->exec("use `{$config['database']}`;");
}

$this->configureIsolationLevel($connection, $config);

$this->configureEncoding($connection, $config);

// Next, we will check to see if a timezone has been specified in this config
// and if it has we will issue a statement to modify the timezone with the
// database. Setting this DB timezone is an optional configuration item.
$this->configureTimezone($connection, $config);

$this->setModes($connection, $config);
$this->configureConnection($connection, $config);

return $connection;
}

/**
* Set the connection transaction isolation level.
*
* @param \PDO $connection
* @param array $config
* @return void
*/
protected function configureIsolationLevel($connection, array $config)
{
if (! isset($config['isolation_level'])) {
return;
}

$connection->prepare(
"SET SESSION TRANSACTION ISOLATION LEVEL {$config['isolation_level']}"
)->execute();
}

/**
* Set the connection character set and collation.
*
* @param \PDO $connection
* @param array $config
* @return void|\PDO
*/
protected function configureEncoding($connection, array $config)
{
if (! isset($config['charset'])) {
return $connection;
}

$connection->prepare(
"set names '{$config['charset']}'".$this->getCollation($config)
)->execute();
}

/**
* Get the collation for the configuration.
*
* @param array $config
* @return string
*/
protected function getCollation(array $config)
{
return isset($config['collation']) ? " collate '{$config['collation']}'" : '';
}

/**
* Set the timezone on the connection.
*
* @param \PDO $connection
* @param array $config
* @return void
*/
protected function configureTimezone($connection, array $config)
{
if (isset($config['timezone'])) {
$connection->prepare('set time_zone="'.$config['timezone'].'"')->execute();
}
}

/**
* Create a DSN string from a configuration.
*
Expand Down Expand Up @@ -155,54 +85,70 @@ protected function getHostDsn(array $config)
}

/**
* Set the modes for the connection.
* Configure the given PDO connection.
*
* @param \PDO $connection
* @param array $config
* @return void
*/
protected function setModes(PDO $connection, array $config)
protected function configureConnection(PDO $connection, array $config)
{
if (isset($config['modes'])) {
$this->setCustomModes($connection, $config);
} elseif (isset($config['strict'])) {
if ($config['strict']) {
$connection->prepare($this->strictMode($connection, $config))->execute();
$statements = [];

if (isset($config['isolation_level'])) {
$statements[] = sprintf('SESSION TRANSACTION ISOLATION LEVEL %s', $config['isolation_level']);
}

if (isset($config['charset'])) {
if (isset($config['collation'])) {
$statements[] = sprintf("NAMES '%s' COLLATE '%s'", $config['charset'], $config['collation']);
} else {
$connection->prepare("set session sql_mode='NO_ENGINE_SUBSTITUTION'")->execute();
$statements[] = sprintf("NAMES '%s'", $config['charset']);
}
}
}

/**
* Set the custom modes on the connection.
*
* @param \PDO $connection
* @param array $config
* @return void
*/
protected function setCustomModes(PDO $connection, array $config)
{
$modes = implode(',', $config['modes']);
if (isset($config['timezone'])) {
$statements[] = sprintf("time_zone='%s'", $config['timezone']);
}

$connection->prepare("set session sql_mode='{$modes}'")->execute();
$sqlMode = $this->getSqlMode($connection, $config);

if ($sqlMode !== null) {
$statements[] = sprintf("SESSION sql_mode='%s'", $sqlMode);
}

if ($statements !== []) {
$connection->exec(sprintf('SET %s;', implode(', ', $statements)));
}
}

/**
* Get the query to enable strict mode.
* Get the sql_mode value.
*
* @param \PDO $connection
* @param array $config
* @return string
* @return string|null
*/
protected function strictMode(PDO $connection, $config)
protected function getSqlMode(PDO $connection, array $config)
{
if (isset($config['modes'])) {
return implode(',', $config['modes']);
}

if (! isset($config['strict'])) {
return null;
}

if (! $config['strict']) {
return 'NO_ENGINE_SUBSTITUTION';
}

$version = $config['version'] ?? $connection->getAttribute(PDO::ATTR_SERVER_VERSION);

if (version_compare($version, '8.0.11') >= 0) {
return "set session sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'";
return 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
}

return "set session sql_mode='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'";
return 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
}
}
13 changes: 4 additions & 9 deletions 13 tests/Database/DatabaseConnectorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,8 @@ public function testMySqlConnectCallsCreateConnectionWithProperArguments($dsn, $
$connection = m::mock(PDO::class);
$connector->expects($this->once())->method('getOptions')->with($this->equalTo($config))->willReturn(['options']);
$connector->expects($this->once())->method('createConnection')->with($this->equalTo($dsn), $this->equalTo($config), $this->equalTo(['options']))->willReturn($connection);
$statement = m::mock(PDOStatement::class);
$connection->shouldReceive('prepare')->once()->with('set names \'utf8\' collate \'utf8_unicode_ci\'')->andReturn($statement);
$statement->shouldReceive('execute')->once();
$connection->shouldReceive('exec')->zeroOrMoreTimes();
$connection->shouldReceive('exec')->once()->with('use `bar`;')->andReturn(true);
$connection->shouldReceive('exec')->once()->with("SET NAMES 'utf8' COLLATE 'utf8_unicode_ci';")->andReturn(true);
$result = $connector->connect($config);

$this->assertSame($result, $connection);
Expand All @@ -63,11 +61,8 @@ public function testMySqlConnectCallsCreateConnectionWithIsolationLevel()
$connection = m::mock(PDO::class);
$connector->expects($this->once())->method('getOptions')->with($this->equalTo($config))->willReturn(['options']);
$connector->expects($this->once())->method('createConnection')->with($this->equalTo($dsn), $this->equalTo($config), $this->equalTo(['options']))->willReturn($connection);
$statement = m::mock(PDOStatement::class);
$connection->shouldReceive('prepare')->once()->with('set names \'utf8\' collate \'utf8_unicode_ci\'')->andReturn($statement);
$connection->shouldReceive('prepare')->once()->with('SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ')->andReturn($statement);
$statement->shouldReceive('execute')->zeroOrMoreTimes();
$connection->shouldReceive('exec')->zeroOrMoreTimes();
$connection->shouldReceive('exec')->once()->with('use `bar`;')->andReturn(true);
$connection->shouldReceive('exec')->once()->with("SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ, NAMES 'utf8' COLLATE 'utf8_unicode_ci';")->andReturn(true);
$result = $connector->connect($config);

$this->assertSame($result, $connection);
Expand Down
Morty Proxy This is a proxified and sanitized view of the page, visit original site.