Skip to content
Draft
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
18 changes: 18 additions & 0 deletions docs/en/reference/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,24 @@ pdo_pgsql / pgsql
- ``persistent`` (boolean): Whether to establish a persistent connection (currently supported only by ``pdo_pgsql``).
- ``application_name`` (string): Name of the application that is
connecting to database. Optional. It will be displayed at ``pg_stat_activity``.
- ``connect_timeout`` (integer): Maximum time to wait while connecting, in seconds.
See `www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNECT-CONNECT-TIMEOUT <https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNECT-CONNECT-TIMEOUT>`_
- ``keepalives`` (integer): Controls whether client-side TCP keepalives are used (``1`` to
enable, ``0`` to disable).
See `www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNECT-KEEPALIVES <https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNECT-KEEPALIVES>`_
- ``keepalives_idle`` (integer): Number of seconds of inactivity after which a TCP keepalive
message is sent to the server.
- ``keepalives_interval`` (integer): Number of seconds after which an unacknowledged TCP
keepalive message is retransmitted.
- ``keepalives_count`` (integer): Number of TCP keepalives that can be lost before the
connection is considered dead.
- ``tcp_user_timeout`` (integer): Number of milliseconds that transmitted data may remain
unacknowledged before the connection is forcibly closed. Useful to bound how long a
query blocks when a connection is silently dropped.
See `www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNECT-TCP-USER-TIMEOUT <https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNECT-TCP-USER-TIMEOUT>`_

These keepalive and timeout parameters are forwarded to libpq and apply to both the
``pdo_pgsql`` and ``pgsql`` drivers.

PostgreSQL behaves differently with regard to booleans when you use
``PDO::ATTR_EMULATE_PREPARES`` or not. To switch from using ``'true'``
Expand Down
24 changes: 24 additions & 0 deletions src/Driver/PDO/PgSQL/Driver.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,30 @@ private function constructPdoDsn(array $params): string
$dsn .= 'gssencmode=' . $params['gssencmode'] . ';';
}

if (isset($params['connect_timeout'])) {
$dsn .= 'connect_timeout=' . $params['connect_timeout'] . ';';
}

if (isset($params['keepalives'])) {
$dsn .= 'keepalives=' . $params['keepalives'] . ';';
}

if (isset($params['keepalives_idle'])) {
$dsn .= 'keepalives_idle=' . $params['keepalives_idle'] . ';';
}

if (isset($params['keepalives_interval'])) {
$dsn .= 'keepalives_interval=' . $params['keepalives_interval'] . ';';
}

if (isset($params['keepalives_count'])) {
$dsn .= 'keepalives_count=' . $params['keepalives_count'] . ';';
}

if (isset($params['tcp_user_timeout'])) {
$dsn .= 'tcp_user_timeout=' . $params['tcp_user_timeout'] . ';';
}

return $dsn;
}
}
6 changes: 6 additions & 0 deletions src/Driver/PgSQL/Driver.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ private function constructConnectionString(
'password' => $params['password'] ?? null,
'sslmode' => $params['sslmode'] ?? null,
'gssencmode' => $params['gssencmode'] ?? null,
'connect_timeout' => $params['connect_timeout'] ?? null,
'keepalives' => $params['keepalives'] ?? null,
'keepalives_idle' => $params['keepalives_idle'] ?? null,
'keepalives_interval' => $params['keepalives_interval'] ?? null,
'keepalives_count' => $params['keepalives_count'] ?? null,
'tcp_user_timeout' => $params['tcp_user_timeout'] ?? null,
],
static fn (int|string|null $value) => $value !== '' && $value !== null,
);
Expand Down
17 changes: 17 additions & 0 deletions tests/Driver/PDO/PgSQL/DriverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,23 @@ public function testConnectionDisablePreparesWhenDisablePreparesIsExplicitlyDefi
);
}

public function testConnectionWithTcpKeepaliveParameters(): void
{
self::expectNotToPerformAssertions();

$this->createDriver()->connect(array_merge(
TestUtil::getConnectionParams(),
[
'connect_timeout' => 5,
'keepalives' => 1,
'keepalives_idle' => 10,
'keepalives_interval' => 5,
'keepalives_count' => 3,
'tcp_user_timeout' => 15000,
],
));
}

public function testUserIsFalse(): void
{
$this->expectException(InvalidConfiguration::class);
Expand Down
18 changes: 18 additions & 0 deletions tests/Driver/PgSQL/DriverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Doctrine\DBAL\Tests\Driver\AbstractDriverTestCase;
use Doctrine\DBAL\Tests\TestUtil;

use function array_merge;
use function in_array;

class DriverTest extends AbstractDriverTestCase
Expand Down Expand Up @@ -42,6 +43,23 @@ public function testConnectionIPv6(): void
$this->driver->connect($params);
}

public function testConnectionWithTcpKeepaliveParameters(): void
{
self::expectNotToPerformAssertions();

$this->driver->connect(array_merge(
TestUtil::getConnectionParams(),
[
'connect_timeout' => 5,
'keepalives' => 1,
'keepalives_idle' => 10,
'keepalives_interval' => 5,
'keepalives_count' => 3,
'tcp_user_timeout' => 15000,
],
));
}

protected function createDriver(): DriverInterface
{
return new Driver();
Expand Down