mirror of
https://github.com/codeigniter4/CodeIgniter4.git
synced 2025-02-20 11:44:28 +08:00
fix: [Postgre] Semicolon in the connection parameters break the DSN string (#7552)
move all related code to the convertDSN() method
This commit is contained in:
parent
0798239a59
commit
99b93bf671
@ -64,14 +64,11 @@ class Connection extends BaseConnection
|
||||
$this->buildDSN();
|
||||
}
|
||||
|
||||
// Strip pgsql if exists
|
||||
// Convert DSN string
|
||||
if (mb_strpos($this->DSN, 'pgsql:') === 0) {
|
||||
$this->DSN = mb_substr($this->DSN, 6);
|
||||
$this->convertDSN();
|
||||
}
|
||||
|
||||
// Convert semicolons to spaces.
|
||||
$this->DSN = str_replace(';', ' ', $this->DSN);
|
||||
|
||||
$this->connID = $persistent === true ? pg_pconnect($this->DSN) : pg_connect($this->DSN);
|
||||
|
||||
if ($this->connID !== false) {
|
||||
@ -92,6 +89,44 @@ class Connection extends BaseConnection
|
||||
return $this->connID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the DSN with semicolon syntax.
|
||||
*/
|
||||
private function convertDSN()
|
||||
{
|
||||
// Strip pgsql
|
||||
$this->DSN = mb_substr($this->DSN, 6);
|
||||
|
||||
// Convert semicolons to spaces in DSN format like:
|
||||
// pgsql:host=localhost;port=5432;dbname=database_name
|
||||
// https://www.php.net/manual/en/function.pg-connect.php
|
||||
$allowedParams = ['host', 'port', 'dbname', 'user', 'password', 'connect_timeout', 'options', 'sslmode', 'service'];
|
||||
|
||||
$parameters = explode(';', $this->DSN);
|
||||
|
||||
$output = '';
|
||||
$previousParameter = '';
|
||||
|
||||
foreach ($parameters as $parameter) {
|
||||
[$key, $value] = explode('=', $parameter, 2);
|
||||
if (in_array($key, $allowedParams, true)) {
|
||||
if ($previousParameter !== '') {
|
||||
if (array_search($key, $allowedParams, true) < array_search($previousParameter, $allowedParams, true)) {
|
||||
$output .= ';';
|
||||
} else {
|
||||
$output .= ' ';
|
||||
}
|
||||
}
|
||||
$output .= $parameter;
|
||||
$previousParameter = $key;
|
||||
} else {
|
||||
$output .= ';' . $parameter;
|
||||
}
|
||||
}
|
||||
|
||||
$this->DSN = $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep or establish the connection if no queries have been sent for
|
||||
* a length of time exceeding the server's idle timeout.
|
||||
|
@ -13,6 +13,7 @@ namespace CodeIgniter\Database;
|
||||
|
||||
use CodeIgniter\Test\CIUnitTestCase;
|
||||
use CodeIgniter\Test\ReflectionHelper;
|
||||
use Generator;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
@ -190,4 +191,47 @@ final class ConfigTest extends CIUnitTestCase
|
||||
$this->assertTrue($this->getPrivateProperty($conn, 'strictOn'));
|
||||
$this->assertSame([], $this->getPrivateProperty($conn, 'failover'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider convertDSNProvider
|
||||
*
|
||||
* @see https://github.com/codeigniter4/CodeIgniter4/issues/7550
|
||||
*/
|
||||
public function testConvertDSN(string $input, string $expected)
|
||||
{
|
||||
$this->dsnGroupPostgreNative['DSN'] = $input;
|
||||
$conn = Config::connect($this->dsnGroupPostgreNative, false);
|
||||
$this->assertInstanceOf(BaseConnection::class, $conn);
|
||||
|
||||
$method = $this->getPrivateMethodInvoker($conn, 'convertDSN');
|
||||
$method();
|
||||
|
||||
$this->assertSame($expected, $this->getPrivateProperty($conn, 'DSN'));
|
||||
}
|
||||
|
||||
public function convertDSNProvider(): Generator
|
||||
{
|
||||
yield from [
|
||||
[
|
||||
'pgsql:host=localhost;port=5432;dbname=database_name;user=username;password=password',
|
||||
'host=localhost port=5432 dbname=database_name user=username password=password',
|
||||
],
|
||||
[
|
||||
'pgsql:host=localhost;port=5432;dbname=database_name;user=username;password=we;port=we',
|
||||
'host=localhost port=5432 dbname=database_name user=username password=we;port=we',
|
||||
],
|
||||
[
|
||||
'pgsql:host=localhost;port=5432;dbname=database_name',
|
||||
'host=localhost port=5432 dbname=database_name',
|
||||
],
|
||||
[
|
||||
"pgsql:host=localhost;port=5432;dbname=database_name;options='--client_encoding=UTF8'",
|
||||
"host=localhost port=5432 dbname=database_name options='--client_encoding=UTF8'",
|
||||
],
|
||||
[
|
||||
'pgsql:host=localhost;port=5432;dbname=database_name;something=stupid',
|
||||
'host=localhost port=5432 dbname=database_name;something=stupid',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ Bugs Fixed
|
||||
the value of a placeholder.
|
||||
- **Validation:** Fixed a bug that ``check()`` cannot specify non-default
|
||||
database group.
|
||||
- **Database:** Fixed a bug where semicolon character (``;``) in one of the Postgre connection parameters would break the DSN string.
|
||||
|
||||
See the repo's
|
||||
`CHANGELOG.md <https://github.com/codeigniter4/CodeIgniter4/blob/develop/CHANGELOG.md>`_
|
||||
|
Loading…
x
Reference in New Issue
Block a user