diff --git a/src/Dibi/Drivers/PdoDriver.php b/src/Dibi/Drivers/PdoDriver.php index e0944d8..d0b8a5d 100644 --- a/src/Dibi/Drivers/PdoDriver.php +++ b/src/Dibi/Drivers/PdoDriver.php @@ -23,14 +23,12 @@ use PDO; * - password (or pass) * - options (array) => driver specific options {@see PDO::__construct} * - resource (PDO) => existing connection - * - version */ class PdoDriver implements Dibi\Driver { private ?PDO $connection; private ?int $affectedRows; private string $driverName; - private string $serverVersion = ''; /** @throws Dibi\NotSupportedException */ @@ -65,7 +63,6 @@ class PdoDriver implements Dibi\Driver } $this->driverName = $this->connection->getAttribute(PDO::ATTR_DRIVER_NAME); - $this->serverVersion = (string) ($config['version'] ?? @$this->connection->getAttribute(PDO::ATTR_SERVER_VERSION)); // @ - may be not supported } @@ -179,7 +176,7 @@ class PdoDriver implements Dibi\Driver return match ($this->driverName) { 'mysql' => new MySqlReflector($this), 'oci' => new OracleReflector($this), - 'pgsql' => new PostgreReflector($this, $this->connection->getAttribute(PDO::ATTR_SERVER_VERSION)), + 'pgsql' => new PostgreReflector($this), 'sqlite' => new SqliteReflector($this), 'mssql', 'dblib', 'sqlsrv' => new SqlsrvReflector($this), default => throw new Dibi\NotSupportedException, @@ -359,17 +356,15 @@ class PdoDriver implements Dibi\Driver case 'mssql': case 'sqlsrv': case 'dblib': - if (version_compare($this->serverVersion, '11.0') >= 0) { // 11 == SQL Server 2012 - // requires ORDER BY, see https://technet.microsoft.com/en-us/library/gg699618(v=sql.110).aspx - if ($limit !== null) { - $sql = sprintf('%s OFFSET %d ROWS FETCH NEXT %d ROWS ONLY', rtrim($sql), $offset, $limit); - } elseif ($offset) { - $sql = sprintf('%s OFFSET %d ROWS', rtrim($sql), $offset); - } - - break; + // requires ORDER BY, see https://technet.microsoft.com/en-us/library/gg699618(v=sql.110).aspx + if ($limit !== null) { + $sql = sprintf('%s OFFSET %d ROWS FETCH NEXT %d ROWS ONLY', rtrim($sql), $offset, $limit); + } elseif ($offset) { + $sql = sprintf('%s OFFSET %d ROWS', rtrim($sql), $offset); } - // break omitted + + break; + case 'odbc': if ($offset) { throw new Dibi\NotSupportedException('Offset is not supported by this database.'); diff --git a/src/Dibi/Drivers/PostgreDriver.php b/src/Dibi/Drivers/PostgreDriver.php index ce3aa43..b9b0603 100644 --- a/src/Dibi/Drivers/PostgreDriver.php +++ b/src/Dibi/Drivers/PostgreDriver.php @@ -233,7 +233,7 @@ class PostgreDriver implements Dibi\Driver */ public function getReflector(): Dibi\Reflector { - return new PostgreReflector($this, pg_parameter_status($this->connection, 'server_version')); + return new PostgreReflector($this); } diff --git a/src/Dibi/Drivers/PostgreReflector.php b/src/Dibi/Drivers/PostgreReflector.php index 68679d3..ab93130 100644 --- a/src/Dibi/Drivers/PostgreReflector.php +++ b/src/Dibi/Drivers/PostgreReflector.php @@ -19,7 +19,6 @@ class PostgreReflector implements Dibi\Reflector { public function __construct( private readonly Dibi\Driver $driver, - private readonly string $version, ) { } @@ -39,18 +38,15 @@ class PostgreReflector implements Dibi\Reflector FROM information_schema.tables WHERE - table_schema = ANY (current_schemas(false))"; + table_schema = ANY (current_schemas(false)) - if ($this->version >= 9.3) { - $query .= ' - UNION ALL - SELECT - matviewname, 1 - FROM - pg_matviews - WHERE - schemaname = ANY (current_schemas(false))'; - } + UNION ALL + SELECT + matviewname, 1 + FROM + pg_matviews + WHERE + schemaname = ANY (current_schemas(false))"; $res = $this->driver->query($query); $tables = []; diff --git a/src/Dibi/Drivers/SqliteDriver.php b/src/Dibi/Drivers/SqliteDriver.php index c1b4b22..d8ef49d 100644 --- a/src/Dibi/Drivers/SqliteDriver.php +++ b/src/Dibi/Drivers/SqliteDriver.php @@ -56,10 +56,7 @@ class SqliteDriver implements Dibi\Driver } // enable foreign keys support (defaultly disabled; if disabled then foreign key constraints are not enforced) - $version = SQLite3::version(); - if ($version['versionNumber'] >= '3006019') { - $this->query('PRAGMA foreign_keys = ON'); - } + $this->query('PRAGMA foreign_keys = ON'); } diff --git a/src/Dibi/Drivers/SqlsrvDriver.php b/src/Dibi/Drivers/SqlsrvDriver.php index 523fd19..0a99933 100644 --- a/src/Dibi/Drivers/SqlsrvDriver.php +++ b/src/Dibi/Drivers/SqlsrvDriver.php @@ -30,7 +30,6 @@ class SqlsrvDriver implements Dibi\Driver /** @var resource */ private $connection; private ?int $affectedRows; - private string $version = ''; /** @throws Dibi\NotSupportedException */ @@ -68,8 +67,6 @@ class SqlsrvDriver implements Dibi\Driver sqlsrv_configure('WarningsReturnAsErrors', 1); } - - $this->version = sqlsrv_server_info($this->connection)['SQLServerVersion']; } @@ -256,13 +253,6 @@ class SqlsrvDriver implements Dibi\Driver if ($limit < 0 || $offset < 0) { throw new Dibi\NotSupportedException('Negative offset or limit.'); - } elseif (version_compare($this->version, '11', '<')) { // 11 == SQL Server 2012 - if ($offset) { - throw new Dibi\NotSupportedException('Offset is not supported by this database.'); - - } elseif ($limit !== null) { - $sql = sprintf('SELECT TOP (%d) * FROM (%s) t', $limit, $sql); - } } elseif ($limit !== null) { // requires ORDER BY, see https://technet.microsoft.com/en-us/library/gg699618(v=sql.110).aspx $sql = sprintf('%s OFFSET %d ROWS FETCH NEXT %d ROWS ONLY', rtrim($sql), $offset, $limit); diff --git a/tests/dibi/Fluent.fetch.limit.mssql.phpt b/tests/dibi/Fluent.fetch.limit.mssql.phpt index 7df79eb..d07ce4e 100644 --- a/tests/dibi/Fluent.fetch.limit.mssql.phpt +++ b/tests/dibi/Fluent.fetch.limit.mssql.phpt @@ -57,28 +57,28 @@ $fluent = $conn->select('*') ->orderBy('customer_id'); Assert::same( - reformat('SELECT TOP (1) * FROM (SELECT * FROM [customers] ORDER BY [customer_id]) t'), + reformat('SELECT * FROM [customers] ORDER BY [customer_id] OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY'), (string) $fluent, ); $fluent->fetch(); Assert::same( - 'SELECT TOP (1) * FROM (SELECT * FROM [customers] ORDER BY [customer_id]) t', + 'SELECT * FROM [customers] ORDER BY [customer_id] OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY', dibi::$sql, ); $fluent->fetchSingle(); Assert::same( - reformat('SELECT TOP (1) * FROM (SELECT * FROM [customers] ORDER BY [customer_id]) t'), + reformat('SELECT * FROM [customers] ORDER BY [customer_id] OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY'), dibi::$sql, ); $fluent->fetchAll(0, 3); Assert::same( - reformat('SELECT TOP (3) * FROM (SELECT * FROM [customers] ORDER BY [customer_id]) t'), + reformat('SELECT * FROM [customers] ORDER BY [customer_id] OFFSET 0 ROWS FETCH NEXT 3 ROWS ONLY'), dibi::$sql, ); Assert::same( - reformat('SELECT TOP (1) * FROM (SELECT * FROM [customers] ORDER BY [customer_id]) t'), + reformat('SELECT * FROM [customers] ORDER BY [customer_id] OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY'), (string) $fluent, ); @@ -86,16 +86,16 @@ Assert::same( $fluent->limit(0); $fluent->fetch(); Assert::same( - reformat('SELECT TOP (0) * FROM (SELECT * FROM [customers] ORDER BY [customer_id]) t'), + reformat('SELECT * FROM [customers] ORDER BY [customer_id] OFFSET 0 ROWS FETCH NEXT 0 ROWS ONLY'), dibi::$sql, ); $fluent->fetchSingle(); Assert::same( - reformat('SELECT TOP (0) * FROM (SELECT * FROM [customers] ORDER BY [customer_id]) t'), + reformat('SELECT * FROM [customers] ORDER BY [customer_id] OFFSET 0 ROWS FETCH NEXT 0 ROWS ONLY'), dibi::$sql, ); Assert::same( - reformat('SELECT TOP (0) * FROM (SELECT * FROM [customers] ORDER BY [customer_id]) t'), + reformat('SELECT * FROM [customers] ORDER BY [customer_id] OFFSET 0 ROWS FETCH NEXT 0 ROWS ONLY'), (string) $fluent, ); @@ -104,12 +104,12 @@ $fluent->removeClause('limit'); $fluent->removeClause('offset'); $fluent->fetch(); Assert::same( - reformat('SELECT TOP (1) * FROM (SELECT * FROM [customers] ORDER BY [customer_id]) t'), + reformat('SELECT * FROM [customers] ORDER BY [customer_id] OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY'), dibi::$sql, ); $fluent->fetchSingle(); Assert::same( - reformat('SELECT TOP (1) * FROM (SELECT * FROM [customers] ORDER BY [customer_id]) t'), + reformat('SELECT * FROM [customers] ORDER BY [customer_id] OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY'), dibi::$sql, ); Assert::same( diff --git a/tests/dibi/Sqlsrv.limits.phpt b/tests/dibi/Sqlsrv.limits.phpt index f70ea19..cc0c8a1 100644 --- a/tests/dibi/Sqlsrv.limits.phpt +++ b/tests/dibi/Sqlsrv.limits.phpt @@ -11,82 +11,59 @@ use Tester\Assert; require __DIR__ . '/bootstrap.php'; $tests = function ($conn) { - $resource = $conn->getDriver()->getResource(); - $version = is_resource($resource) - ? sqlsrv_server_info($resource)['SQLServerVersion'] - : $resource->getAttribute(PDO::ATTR_SERVER_VERSION); + // Limit and offset + Assert::same( + 'SELECT 1 OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY', + $conn->translate('SELECT 1 %ofs %lmt', 10, 10), + ); - // MsSQL2012+ - if (version_compare($version, '11.0') >= 0) { - // Limit and offset - Assert::same( - 'SELECT 1 OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY', - $conn->translate('SELECT 1 %ofs %lmt', 10, 10), - ); + // Limit only + Assert::same( + 'SELECT 1 OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY', + $conn->translate('SELECT 1 %lmt', 10), + ); - // Limit only - Assert::same( - 'SELECT 1 OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY', - $conn->translate('SELECT 1 %lmt', 10), - ); + // Offset only + Assert::same( + 'SELECT 1 OFFSET 10 ROWS', + $conn->translate('SELECT 1 %ofs', 10), + ); - // Offset only - Assert::same( - 'SELECT 1 OFFSET 10 ROWS', - $conn->translate('SELECT 1 %ofs', 10), - ); + // Offset invalid + Assert::error( + function () use ($conn) { + $conn->translate('SELECT 1 %ofs', -10); + }, + Dibi\NotSupportedException::class, + 'Negative offset or limit.', + ); - // Offset invalid - Assert::error( - function () use ($conn) { - $conn->translate('SELECT 1 %ofs', -10); - }, - Dibi\NotSupportedException::class, - 'Negative offset or limit.', - ); + // Limit invalid + Assert::error( + function () use ($conn) { + $conn->translate('SELECT 1 %lmt', -10); + }, + Dibi\NotSupportedException::class, + 'Negative offset or limit.', + ); - // Limit invalid - Assert::error( - function () use ($conn) { - $conn->translate('SELECT 1 %lmt', -10); - }, - Dibi\NotSupportedException::class, - 'Negative offset or limit.', - ); + // Limit invalid, offset valid + Assert::error( + function () use ($conn) { + $conn->translate('SELECT 1 %ofs %lmt', 10, -10); + }, + Dibi\NotSupportedException::class, + 'Negative offset or limit.', + ); - // Limit invalid, offset valid - Assert::error( - function () use ($conn) { - $conn->translate('SELECT 1 %ofs %lmt', 10, -10); - }, - Dibi\NotSupportedException::class, - 'Negative offset or limit.', - ); - - // Limit valid, offset invalid - Assert::error( - function () use ($conn) { - $conn->translate('SELECT 1 %ofs %lmt', -10, 10); - }, - Dibi\NotSupportedException::class, - 'Negative offset or limit.', - ); - } else { - Assert::same( - 'SELECT TOP (1) * FROM (SELECT 1) t', - $conn->translate('SELECT 1 %lmt', 1), - ); - - Assert::same( - 'SELECT 1', - $conn->translate('SELECT 1 %lmt', -10), - ); - - Assert::exception( - fn() => $conn->translate('SELECT 1 %ofs %lmt', 10, 10), - Dibi\NotSupportedException::class, - ); - } + // Limit valid, offset invalid + Assert::error( + function () use ($conn) { + $conn->translate('SELECT 1 %ofs %lmt', -10, 10); + }, + Dibi\NotSupportedException::class, + 'Negative offset or limit.', + ); }; $conn = new Dibi\Connection($config);