1
0
mirror of https://github.com/dg/dibi.git synced 2025-08-06 06:07:39 +02:00

removed support for SQLServer < 2012, PostgreSQL < 9.3

This commit is contained in:
David Grudl
2024-09-03 18:27:03 +02:00
parent cd0718fa91
commit 65c8021312
7 changed files with 76 additions and 121 deletions

View File

@@ -24,14 +24,12 @@ use function sprintf;
* - password (or pass) * - password (or pass)
* - options (array) => driver specific options {@see PDO::__construct} * - options (array) => driver specific options {@see PDO::__construct}
* - resource (PDO) => existing connection * - resource (PDO) => existing connection
* - version
*/ */
class PdoDriver implements Dibi\Driver class PdoDriver implements Dibi\Driver
{ {
private ?PDO $connection; private ?PDO $connection;
private ?int $affectedRows; private ?int $affectedRows;
private string $driverName; private string $driverName;
private string $serverVersion = '';
/** @throws Dibi\NotSupportedException */ /** @throws Dibi\NotSupportedException */
@@ -66,7 +64,6 @@ class PdoDriver implements Dibi\Driver
} }
$this->driverName = $this->connection->getAttribute(PDO::ATTR_DRIVER_NAME); $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
} }
@@ -180,7 +177,7 @@ class PdoDriver implements Dibi\Driver
return match ($this->driverName) { return match ($this->driverName) {
'mysql' => new MySqlReflector($this), 'mysql' => new MySqlReflector($this),
'oci' => new OracleReflector($this), 'oci' => new OracleReflector($this),
'pgsql' => new PostgreReflector($this, $this->connection->getAttribute(PDO::ATTR_SERVER_VERSION)), 'pgsql' => new PostgreReflector($this),
'sqlite' => new SqliteReflector($this), 'sqlite' => new SqliteReflector($this),
'mssql', 'dblib', 'sqlsrv' => new SqlsrvReflector($this), 'mssql', 'dblib', 'sqlsrv' => new SqlsrvReflector($this),
default => throw new Dibi\NotSupportedException, default => throw new Dibi\NotSupportedException,
@@ -360,17 +357,15 @@ class PdoDriver implements Dibi\Driver
case 'mssql': case 'mssql':
case 'sqlsrv': case 'sqlsrv':
case 'dblib': 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
// requires ORDER BY, see https://technet.microsoft.com/en-us/library/gg699618(v=sql.110).aspx if ($limit !== null) {
if ($limit !== null) { $sql = sprintf('%s OFFSET %d ROWS FETCH NEXT %d ROWS ONLY', rtrim($sql), $offset, $limit);
$sql = sprintf('%s OFFSET %d ROWS FETCH NEXT %d ROWS ONLY', rtrim($sql), $offset, $limit); } elseif ($offset) {
} elseif ($offset) { $sql = sprintf('%s OFFSET %d ROWS', rtrim($sql), $offset);
$sql = sprintf('%s OFFSET %d ROWS', rtrim($sql), $offset);
}
break;
} }
// break omitted
break;
case 'odbc': case 'odbc':
if ($offset) { if ($offset) {
throw new Dibi\NotSupportedException('Offset is not supported by this database.'); throw new Dibi\NotSupportedException('Offset is not supported by this database.');

View File

@@ -234,7 +234,7 @@ class PostgreDriver implements Dibi\Driver
*/ */
public function getReflector(): Dibi\Reflector public function getReflector(): Dibi\Reflector
{ {
return new PostgreReflector($this, pg_parameter_status($this->connection, 'server_version')); return new PostgreReflector($this);
} }

View File

@@ -19,7 +19,6 @@ class PostgreReflector implements Dibi\Reflector
{ {
public function __construct( public function __construct(
private readonly Dibi\Driver $driver, private readonly Dibi\Driver $driver,
private readonly string $version,
) { ) {
} }
@@ -39,18 +38,15 @@ class PostgreReflector implements Dibi\Reflector
FROM FROM
information_schema.tables information_schema.tables
WHERE WHERE
table_schema = ANY (current_schemas(false))"; table_schema = ANY (current_schemas(false))
if ($this->version >= 9.3) { UNION ALL
$query .= ' SELECT
UNION ALL matviewname, 1
SELECT FROM
matviewname, 1 pg_matviews
FROM WHERE
pg_matviews schemaname = ANY (current_schemas(false))";
WHERE
schemaname = ANY (current_schemas(false))';
}
$res = $this->driver->query($query); $res = $this->driver->query($query);
$tables = []; $tables = [];

View File

@@ -56,10 +56,7 @@ class SqliteDriver implements Dibi\Driver
} }
// enable foreign keys support (defaultly disabled; if disabled then foreign key constraints are not enforced) // enable foreign keys support (defaultly disabled; if disabled then foreign key constraints are not enforced)
$version = SQLite3::version(); $this->query('PRAGMA foreign_keys = ON');
if ($version['versionNumber'] >= '3006019') {
$this->query('PRAGMA foreign_keys = ON');
}
} }

View File

@@ -31,7 +31,6 @@ class SqlsrvDriver implements Dibi\Driver
/** @var resource */ /** @var resource */
private $connection; private $connection;
private ?int $affectedRows; private ?int $affectedRows;
private string $version = '';
/** @throws Dibi\NotSupportedException */ /** @throws Dibi\NotSupportedException */
@@ -69,8 +68,6 @@ class SqlsrvDriver implements Dibi\Driver
sqlsrv_configure('WarningsReturnAsErrors', 1); sqlsrv_configure('WarningsReturnAsErrors', 1);
} }
$this->version = sqlsrv_server_info($this->connection)['SQLServerVersion'];
} }
@@ -257,13 +254,6 @@ class SqlsrvDriver implements Dibi\Driver
if ($limit < 0 || $offset < 0) { if ($limit < 0 || $offset < 0) {
throw new Dibi\NotSupportedException('Negative offset or limit.'); 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) { } elseif ($limit !== null) {
// requires ORDER BY, see https://technet.microsoft.com/en-us/library/gg699618(v=sql.110).aspx // 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); $sql = sprintf('%s OFFSET %d ROWS FETCH NEXT %d ROWS ONLY', rtrim($sql), $offset, $limit);

View File

@@ -57,28 +57,28 @@ $fluent = $conn->select('*')
->orderBy('customer_id'); ->orderBy('customer_id');
Assert::same( 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, (string) $fluent,
); );
$fluent->fetch(); $fluent->fetch();
Assert::same( 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, dibi::$sql,
); );
$fluent->fetchSingle(); $fluent->fetchSingle();
Assert::same( 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, dibi::$sql,
); );
$fluent->fetchAll(0, 3); $fluent->fetchAll(0, 3);
Assert::same( 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, dibi::$sql,
); );
Assert::same( 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, (string) $fluent,
); );
@@ -86,16 +86,16 @@ Assert::same(
$fluent->limit(0); $fluent->limit(0);
$fluent->fetch(); $fluent->fetch();
Assert::same( 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, dibi::$sql,
); );
$fluent->fetchSingle(); $fluent->fetchSingle();
Assert::same( 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, dibi::$sql,
); );
Assert::same( 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, (string) $fluent,
); );
@@ -104,12 +104,12 @@ $fluent->removeClause('limit');
$fluent->removeClause('offset'); $fluent->removeClause('offset');
$fluent->fetch(); $fluent->fetch();
Assert::same( 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, dibi::$sql,
); );
$fluent->fetchSingle(); $fluent->fetchSingle();
Assert::same( 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, dibi::$sql,
); );
Assert::same( Assert::same(

View File

@@ -11,82 +11,59 @@ use Tester\Assert;
require __DIR__ . '/bootstrap.php'; require __DIR__ . '/bootstrap.php';
$tests = function ($conn) { $tests = function ($conn) {
$resource = $conn->getDriver()->getResource(); // Limit and offset
$version = is_resource($resource) Assert::same(
? sqlsrv_server_info($resource)['SQLServerVersion'] 'SELECT 1 OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY',
: $resource->getAttribute(PDO::ATTR_SERVER_VERSION); $conn->translate('SELECT 1 %ofs %lmt', 10, 10),
);
// MsSQL2012+ // Limit only
if (version_compare($version, '11.0') >= 0) { Assert::same(
// Limit and offset 'SELECT 1 OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY',
Assert::same( $conn->translate('SELECT 1 %lmt', 10),
'SELECT 1 OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY', );
$conn->translate('SELECT 1 %ofs %lmt', 10, 10),
);
// Limit only // Offset only
Assert::same( Assert::same(
'SELECT 1 OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY', 'SELECT 1 OFFSET 10 ROWS',
$conn->translate('SELECT 1 %lmt', 10), $conn->translate('SELECT 1 %ofs', 10),
); );
// Offset only // Offset invalid
Assert::same( Assert::error(
'SELECT 1 OFFSET 10 ROWS', function () use ($conn) {
$conn->translate('SELECT 1 %ofs', 10), $conn->translate('SELECT 1 %ofs', -10);
); },
Dibi\NotSupportedException::class,
'Negative offset or limit.',
);
// Offset invalid // Limit invalid
Assert::error( Assert::error(
function () use ($conn) { function () use ($conn) {
$conn->translate('SELECT 1 %ofs', -10); $conn->translate('SELECT 1 %lmt', -10);
}, },
Dibi\NotSupportedException::class, Dibi\NotSupportedException::class,
'Negative offset or limit.', 'Negative offset or limit.',
); );
// Limit invalid // Limit invalid, offset valid
Assert::error( Assert::error(
function () use ($conn) { function () use ($conn) {
$conn->translate('SELECT 1 %lmt', -10); $conn->translate('SELECT 1 %ofs %lmt', 10, -10);
}, },
Dibi\NotSupportedException::class, Dibi\NotSupportedException::class,
'Negative offset or limit.', 'Negative offset or limit.',
); );
// Limit invalid, offset valid // Limit valid, offset invalid
Assert::error( Assert::error(
function () use ($conn) { function () use ($conn) {
$conn->translate('SELECT 1 %ofs %lmt', 10, -10); $conn->translate('SELECT 1 %ofs %lmt', -10, 10);
}, },
Dibi\NotSupportedException::class, Dibi\NotSupportedException::class,
'Negative offset or limit.', '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,
);
}
}; };
$conn = new Dibi\Connection($config); $conn = new Dibi\Connection($config);