mirror of
https://github.com/dg/dibi.git
synced 2025-09-03 19:12:33 +02:00
Compare commits
15 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
32b6976209 | ||
|
f484630e56 | ||
|
611e051c02 | ||
|
7595a6d5bd | ||
|
494d7c1c21 | ||
|
658dbe388a | ||
|
c7fe0fef21 | ||
|
9151d1eb9c | ||
|
d76f40c2a4 | ||
|
befde664fe | ||
|
e1c4cbaece | ||
|
1df20ced10 | ||
|
ce1ba4668b | ||
|
0f21a6ab3d | ||
|
78f552fe8e |
4
.github/workflows/coding-style.yml
vendored
4
.github/workflows/coding-style.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: shivammathur/setup-php@v2
|
- uses: shivammathur/setup-php@v2
|
||||||
with:
|
with:
|
||||||
php-version: 8.0
|
php-version: 8.3
|
||||||
coverage: none
|
coverage: none
|
||||||
|
|
||||||
- run: composer create-project nette/code-checker temp/code-checker ^3 --no-progress
|
- run: composer create-project nette/code-checker temp/code-checker ^3 --no-progress
|
||||||
@@ -24,7 +24,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: shivammathur/setup-php@v2
|
- uses: shivammathur/setup-php@v2
|
||||||
with:
|
with:
|
||||||
php-version: 8.0
|
php-version: 8.3
|
||||||
coverage: none
|
coverage: none
|
||||||
|
|
||||||
- run: composer create-project nette/coding-standard temp/coding-standard ^3 --no-progress
|
- run: composer create-project nette/coding-standard temp/coding-standard ^3 --no-progress
|
||||||
|
2
.github/workflows/static-analysis.yml
vendored
2
.github/workflows/static-analysis.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: shivammathur/setup-php@v2
|
- uses: shivammathur/setup-php@v2
|
||||||
with:
|
with:
|
||||||
php-version: 8.0
|
php-version: 8.2
|
||||||
coverage: none
|
coverage: none
|
||||||
|
|
||||||
- run: composer install --no-progress --prefer-dist
|
- run: composer install --no-progress --prefer-dist
|
||||||
|
8
.github/workflows/tests.yml
vendored
8
.github/workflows/tests.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
php: ['8.0', '8.1', '8.2', '8.3', '8.4']
|
php: ['8.2', '8.3', '8.4', '8.5']
|
||||||
|
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
|
||||||
@@ -105,14 +105,14 @@ jobs:
|
|||||||
- run: composer install --no-progress --prefer-dist
|
- run: composer install --no-progress --prefer-dist
|
||||||
- run: vendor/bin/tester -p phpdbg tests -s -C --coverage ./coverage.xml --coverage-src ./src
|
- run: vendor/bin/tester -p phpdbg tests -s -C --coverage ./coverage.xml --coverage-src ./src
|
||||||
- if: failure()
|
- if: failure()
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: output
|
name: output-${{ matrix.php }}
|
||||||
path: tests/**/output
|
path: tests/**/output
|
||||||
|
|
||||||
|
|
||||||
- name: Save Code Coverage
|
- name: Save Code Coverage
|
||||||
if: ${{ matrix.php == '8.0' }}
|
if: ${{ matrix.php == '8.2' }}
|
||||||
env:
|
env:
|
||||||
COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
run: |
|
run: |
|
||||||
|
@@ -11,20 +11,23 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": "8.0 - 8.4"
|
"php": "8.2 - 8.5"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"tracy/tracy": "^2.9",
|
"tracy/tracy": "^2.9",
|
||||||
"nette/tester": "^2.5",
|
"nette/tester": "^2.5",
|
||||||
"nette/di": "^3.1",
|
"nette/di": "^3.1",
|
||||||
"phpstan/phpstan": "^1.0",
|
"phpstan/phpstan-nette": "^2.0@stable",
|
||||||
"jetbrains/phpstorm-attributes": "^1.0"
|
"jetbrains/phpstorm-attributes": "^1.0"
|
||||||
},
|
},
|
||||||
"replace": {
|
"replace": {
|
||||||
"dg/dibi": "*"
|
"dg/dibi": "*"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"classmap": ["src/"]
|
"classmap": ["src/"],
|
||||||
|
"psr-4": {
|
||||||
|
"Dibi\\": "src/Dibi"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"minimum-stability": "dev",
|
"minimum-stability": "dev",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -33,7 +36,7 @@
|
|||||||
},
|
},
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-master": "5.0-dev"
|
"dev-master": "5.1-dev"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -45,7 +45,7 @@ function substFallBack($expr)
|
|||||||
|
|
||||||
|
|
||||||
// define callback
|
// define callback
|
||||||
$dibi->getSubstitutes()->setCallback('substFallBack');
|
$dibi->getSubstitutes()->setCallback(substFallBack(...));
|
||||||
|
|
||||||
// define substitutes as constants
|
// define substitutes as constants
|
||||||
define('SUBST_ACCOUNT', 'eshop_');
|
define('SUBST_ACCOUNT', 'eshop_');
|
||||||
|
@@ -34,7 +34,7 @@ Install Dibi via Composer:
|
|||||||
composer require dibi/dibi
|
composer require dibi/dibi
|
||||||
```
|
```
|
||||||
|
|
||||||
The Dibi 5.0 requires PHP version 8.0 and supports PHP up to 8.4.
|
The Dibi 5.1 requires PHP version 8.2 and supports PHP up to 8.5.
|
||||||
|
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
|
@@ -19,14 +19,10 @@ use Tracy;
|
|||||||
*/
|
*/
|
||||||
class DibiExtension22 extends Nette\DI\CompilerExtension
|
class DibiExtension22 extends Nette\DI\CompilerExtension
|
||||||
{
|
{
|
||||||
private ?bool $debugMode;
|
public function __construct(
|
||||||
private ?bool $cliMode;
|
private ?bool $debugMode = null,
|
||||||
|
private ?bool $cliMode = null,
|
||||||
|
) {
|
||||||
public function __construct(?bool $debugMode = null, ?bool $cliMode = null)
|
|
||||||
{
|
|
||||||
$this->debugMode = $debugMode;
|
|
||||||
$this->cliMode = $cliMode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -13,6 +13,7 @@ use Dibi;
|
|||||||
use Nette;
|
use Nette;
|
||||||
use Nette\Schema\Expect;
|
use Nette\Schema\Expect;
|
||||||
use Tracy;
|
use Tracy;
|
||||||
|
use function is_array;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -20,14 +21,10 @@ use Tracy;
|
|||||||
*/
|
*/
|
||||||
class DibiExtension3 extends Nette\DI\CompilerExtension
|
class DibiExtension3 extends Nette\DI\CompilerExtension
|
||||||
{
|
{
|
||||||
private ?bool $debugMode;
|
public function __construct(
|
||||||
private ?bool $cliMode;
|
private ?bool $debugMode = null,
|
||||||
|
private ?bool $cliMode = null,
|
||||||
|
) {
|
||||||
public function __construct(?bool $debugMode = null, ?bool $cliMode = null)
|
|
||||||
{
|
|
||||||
$this->debugMode = $debugMode;
|
|
||||||
$this->cliMode = $cliMode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -13,6 +13,7 @@ use Dibi;
|
|||||||
use Dibi\Event;
|
use Dibi\Event;
|
||||||
use Dibi\Helpers;
|
use Dibi\Helpers;
|
||||||
use Tracy;
|
use Tracy;
|
||||||
|
use function count, is_string, strlen;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -21,23 +22,22 @@ use Tracy;
|
|||||||
class Panel implements Tracy\IBarPanel
|
class Panel implements Tracy\IBarPanel
|
||||||
{
|
{
|
||||||
public static int $maxLength = 1000;
|
public static int $maxLength = 1000;
|
||||||
public bool|string $explain;
|
|
||||||
public int $filter;
|
|
||||||
private array $events = [];
|
private array $events = [];
|
||||||
|
|
||||||
|
|
||||||
public function __construct(bool $explain = true, ?int $filter = null)
|
public function __construct(
|
||||||
{
|
public bool|string $explain = true,
|
||||||
$this->filter = $filter ?: Event::QUERY;
|
public int $filter = Event::QUERY,
|
||||||
$this->explain = $explain;
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function register(Dibi\Connection $connection): void
|
public function register(Dibi\Connection $connection): void
|
||||||
{
|
{
|
||||||
Tracy\Debugger::getBar()->addPanel($this);
|
Tracy\Debugger::getBar()->addPanel($this);
|
||||||
Tracy\Debugger::getBlueScreen()->addPanel([self::class, 'renderException']);
|
Tracy\Debugger::getBlueScreen()->addPanel(self::renderException(...));
|
||||||
$connection->onEvent[] = [$this, 'logEvent'];
|
$connection->onEvent[] = $this->logEvent(...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -11,6 +11,8 @@ namespace Dibi;
|
|||||||
|
|
||||||
use JetBrains\PhpStorm\Language;
|
use JetBrains\PhpStorm\Language;
|
||||||
use Traversable;
|
use Traversable;
|
||||||
|
use function array_key_exists, is_array, sprintf;
|
||||||
|
use const PHP_SAPI;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -673,7 +675,7 @@ class Connection implements IConnection
|
|||||||
/**
|
/**
|
||||||
* Prevents unserialization.
|
* Prevents unserialization.
|
||||||
*/
|
*/
|
||||||
public function __wakeup()
|
public function __unserialize($_)
|
||||||
{
|
{
|
||||||
throw new NotSupportedException('You cannot serialize or unserialize ' . static::class . ' instances.');
|
throw new NotSupportedException('You cannot serialize or unserialize ' . static::class . ' instances.');
|
||||||
}
|
}
|
||||||
@@ -682,7 +684,7 @@ class Connection implements IConnection
|
|||||||
/**
|
/**
|
||||||
* Prevents serialization.
|
* Prevents serialization.
|
||||||
*/
|
*/
|
||||||
public function __sleep()
|
public function __serialize()
|
||||||
{
|
{
|
||||||
throw new NotSupportedException('You cannot serialize or unserialize ' . static::class . ' instances.');
|
throw new NotSupportedException('You cannot serialize or unserialize ' . static::class . ' instances.');
|
||||||
}
|
}
|
||||||
|
@@ -9,14 +9,16 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Dibi;
|
namespace Dibi;
|
||||||
|
|
||||||
|
use function func_get_args, is_array, strpbrk;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default implementation of IDataSource.
|
* Default implementation of IDataSource.
|
||||||
*/
|
*/
|
||||||
class DataSource implements IDataSource
|
class DataSource implements IDataSource
|
||||||
{
|
{
|
||||||
private Connection $connection;
|
private readonly Connection $connection;
|
||||||
private string $sql;
|
private readonly string $sql;
|
||||||
private ?Result $result = null;
|
private ?Result $result = null;
|
||||||
private ?int $count = null;
|
private ?int $count = null;
|
||||||
private ?int $totalCount = null;
|
private ?int $totalCount = null;
|
||||||
|
@@ -11,6 +11,7 @@ namespace Dibi\Drivers;
|
|||||||
|
|
||||||
use Dibi;
|
use Dibi;
|
||||||
use Dibi\Helpers;
|
use Dibi\Helpers;
|
||||||
|
use function is_resource;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -17,12 +17,9 @@ use Dibi;
|
|||||||
*/
|
*/
|
||||||
class FirebirdReflector implements Dibi\Reflector
|
class FirebirdReflector implements Dibi\Reflector
|
||||||
{
|
{
|
||||||
private Dibi\Driver $driver;
|
public function __construct(
|
||||||
|
private readonly Dibi\Driver $driver,
|
||||||
|
) {
|
||||||
public function __construct(Dibi\Driver $driver)
|
|
||||||
{
|
|
||||||
$this->driver = $driver;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -11,6 +11,7 @@ namespace Dibi\Drivers;
|
|||||||
|
|
||||||
use Dibi;
|
use Dibi;
|
||||||
use Dibi\Helpers;
|
use Dibi\Helpers;
|
||||||
|
use function is_resource;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -18,16 +19,10 @@ use Dibi\Helpers;
|
|||||||
*/
|
*/
|
||||||
class FirebirdResult implements Dibi\ResultDriver
|
class FirebirdResult implements Dibi\ResultDriver
|
||||||
{
|
{
|
||||||
/** @var resource */
|
public function __construct(
|
||||||
private $resultSet;
|
/** @var resource */
|
||||||
|
private $resultSet,
|
||||||
|
) {
|
||||||
/**
|
|
||||||
* @param resource $resultSet
|
|
||||||
*/
|
|
||||||
public function __construct($resultSet)
|
|
||||||
{
|
|
||||||
$this->resultSet = $resultSet;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -18,12 +18,9 @@ use Dibi;
|
|||||||
*/
|
*/
|
||||||
class MySqlReflector implements Dibi\Reflector
|
class MySqlReflector implements Dibi\Reflector
|
||||||
{
|
{
|
||||||
private Dibi\Driver $driver;
|
public function __construct(
|
||||||
|
private readonly Dibi\Driver $driver,
|
||||||
|
) {
|
||||||
public function __construct(Dibi\Driver $driver)
|
|
||||||
{
|
|
||||||
$this->driver = $driver;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -10,6 +10,8 @@ declare(strict_types=1);
|
|||||||
namespace Dibi\Drivers;
|
namespace Dibi\Drivers;
|
||||||
|
|
||||||
use Dibi;
|
use Dibi;
|
||||||
|
use function in_array;
|
||||||
|
use const MYSQLI_REPORT_OFF, MYSQLI_STORE_RESULT, MYSQLI_USE_RESULT, PREG_SET_ORDER;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -10,6 +10,7 @@ declare(strict_types=1);
|
|||||||
namespace Dibi\Drivers;
|
namespace Dibi\Drivers;
|
||||||
|
|
||||||
use Dibi;
|
use Dibi;
|
||||||
|
use const MYSQLI_TYPE_LONG, MYSQLI_TYPE_SHORT, MYSQLI_TYPE_TIME, MYSQLI_TYPE_TINY;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -17,14 +18,10 @@ use Dibi;
|
|||||||
*/
|
*/
|
||||||
class MySqliResult implements Dibi\ResultDriver
|
class MySqliResult implements Dibi\ResultDriver
|
||||||
{
|
{
|
||||||
private \mysqli_result $resultSet;
|
public function __construct(
|
||||||
private bool $buffered;
|
private readonly \mysqli_result $resultSet,
|
||||||
|
private readonly bool $buffered,
|
||||||
|
) {
|
||||||
public function __construct(\mysqli_result $resultSet, bool $buffered)
|
|
||||||
{
|
|
||||||
$this->resultSet = $resultSet;
|
|
||||||
$this->buffered = $buffered;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -17,12 +17,9 @@ use Dibi;
|
|||||||
*/
|
*/
|
||||||
class NoDataResult implements Dibi\ResultDriver
|
class NoDataResult implements Dibi\ResultDriver
|
||||||
{
|
{
|
||||||
private int $rows;
|
public function __construct(
|
||||||
|
private readonly int $rows,
|
||||||
|
) {
|
||||||
public function __construct(int $rows)
|
|
||||||
{
|
|
||||||
$this->rows = $rows;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -10,6 +10,7 @@ declare(strict_types=1);
|
|||||||
namespace Dibi\Drivers;
|
namespace Dibi\Drivers;
|
||||||
|
|
||||||
use Dibi;
|
use Dibi;
|
||||||
|
use function is_resource;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -17,12 +17,9 @@ use Dibi;
|
|||||||
*/
|
*/
|
||||||
class OdbcReflector implements Dibi\Reflector
|
class OdbcReflector implements Dibi\Reflector
|
||||||
{
|
{
|
||||||
private Dibi\Driver $driver;
|
public function __construct(
|
||||||
|
private readonly Dibi\Driver $driver,
|
||||||
|
) {
|
||||||
public function __construct(Dibi\Driver $driver)
|
|
||||||
{
|
|
||||||
$this->driver = $driver;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -10,6 +10,7 @@ declare(strict_types=1);
|
|||||||
namespace Dibi\Drivers;
|
namespace Dibi\Drivers;
|
||||||
|
|
||||||
use Dibi;
|
use Dibi;
|
||||||
|
use function is_resource;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -17,17 +18,13 @@ use Dibi;
|
|||||||
*/
|
*/
|
||||||
class OdbcResult implements Dibi\ResultDriver
|
class OdbcResult implements Dibi\ResultDriver
|
||||||
{
|
{
|
||||||
/** @var resource */
|
|
||||||
private $resultSet;
|
|
||||||
private int $row = 0;
|
private int $row = 0;
|
||||||
|
|
||||||
|
|
||||||
/**
|
public function __construct(
|
||||||
* @param resource $resultSet
|
/** @var resource */
|
||||||
*/
|
private $resultSet,
|
||||||
public function __construct($resultSet)
|
) {
|
||||||
{
|
|
||||||
$this->resultSet = $resultSet;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -10,6 +10,7 @@ declare(strict_types=1);
|
|||||||
namespace Dibi\Drivers;
|
namespace Dibi\Drivers;
|
||||||
|
|
||||||
use Dibi;
|
use Dibi;
|
||||||
|
use function in_array, is_resource;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -17,12 +17,9 @@ use Dibi;
|
|||||||
*/
|
*/
|
||||||
class OracleReflector implements Dibi\Reflector
|
class OracleReflector implements Dibi\Reflector
|
||||||
{
|
{
|
||||||
private Dibi\Driver $driver;
|
public function __construct(
|
||||||
|
private readonly Dibi\Driver $driver,
|
||||||
|
) {
|
||||||
public function __construct(Dibi\Driver $driver)
|
|
||||||
{
|
|
||||||
$this->driver = $driver;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -10,6 +10,7 @@ declare(strict_types=1);
|
|||||||
namespace Dibi\Drivers;
|
namespace Dibi\Drivers;
|
||||||
|
|
||||||
use Dibi;
|
use Dibi;
|
||||||
|
use function is_resource;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -17,16 +18,10 @@ use Dibi;
|
|||||||
*/
|
*/
|
||||||
class OracleResult implements Dibi\ResultDriver
|
class OracleResult implements Dibi\ResultDriver
|
||||||
{
|
{
|
||||||
/** @var resource */
|
public function __construct(
|
||||||
private $resultSet;
|
/** @var resource */
|
||||||
|
private $resultSet,
|
||||||
|
) {
|
||||||
/**
|
|
||||||
* @param resource $resultSet
|
|
||||||
*/
|
|
||||||
public function __construct($resultSet)
|
|
||||||
{
|
|
||||||
$this->resultSet = $resultSet;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -12,6 +12,7 @@ namespace Dibi\Drivers;
|
|||||||
use Dibi;
|
use Dibi;
|
||||||
use Dibi\Helpers;
|
use Dibi\Helpers;
|
||||||
use PDO;
|
use PDO;
|
||||||
|
use function sprintf;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -23,14 +24,12 @@ use PDO;
|
|||||||
* - 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 */
|
||||||
@@ -65,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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -179,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,
|
||||||
@@ -359,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.');
|
||||||
|
@@ -19,14 +19,10 @@ use PDO;
|
|||||||
*/
|
*/
|
||||||
class PdoResult implements Dibi\ResultDriver
|
class PdoResult implements Dibi\ResultDriver
|
||||||
{
|
{
|
||||||
private ?\PDOStatement $resultSet;
|
public function __construct(
|
||||||
private string $driverName;
|
private ?\PDOStatement $resultSet,
|
||||||
|
private readonly string $driverName,
|
||||||
|
) {
|
||||||
public function __construct(\PDOStatement $resultSet, string $driverName)
|
|
||||||
{
|
|
||||||
$this->resultSet = $resultSet;
|
|
||||||
$this->driverName = $driverName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -12,6 +12,7 @@ namespace Dibi\Drivers;
|
|||||||
use Dibi;
|
use Dibi;
|
||||||
use Dibi\Helpers;
|
use Dibi\Helpers;
|
||||||
use PgSql;
|
use PgSql;
|
||||||
|
use function in_array, is_array, is_resource, strlen;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -23,13 +24,12 @@ use PgSql;
|
|||||||
* - schema => the schema search path
|
* - schema => the schema search path
|
||||||
* - charset => character encoding to set (default is utf8)
|
* - charset => character encoding to set (default is utf8)
|
||||||
* - persistent (bool) => try to find a persistent link?
|
* - persistent (bool) => try to find a persistent link?
|
||||||
* - resource (resource) => existing connection resource
|
* - resource (PgSql\Connection) => existing connection resource
|
||||||
* - connect_type (int) => see pg_connect()
|
* - connect_type (int) => see pg_connect()
|
||||||
*/
|
*/
|
||||||
class PostgreDriver implements Dibi\Driver
|
class PostgreDriver implements Dibi\Driver
|
||||||
{
|
{
|
||||||
/** @var resource|PgSql\Connection */
|
private PgSql\Connection $connection;
|
||||||
private $connection;
|
|
||||||
private ?int $affectedRows;
|
private ?int $affectedRows;
|
||||||
|
|
||||||
|
|
||||||
@@ -72,7 +72,7 @@ class PostgreDriver implements Dibi\Driver
|
|||||||
restore_error_handler();
|
restore_error_handler();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_resource($this->connection) && !$this->connection instanceof PgSql\Connection) {
|
if (!$this->connection instanceof PgSql\Connection) {
|
||||||
throw new Dibi\DriverException($error ?: 'Connecting error.');
|
throw new Dibi\DriverException($error ?: 'Connecting error.');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,7 +118,7 @@ class PostgreDriver implements Dibi\Driver
|
|||||||
if ($res === false) {
|
if ($res === false) {
|
||||||
throw static::createException(pg_last_error($this->connection), null, $sql);
|
throw static::createException(pg_last_error($this->connection), null, $sql);
|
||||||
|
|
||||||
} elseif (is_resource($res) || $res instanceof PgSql\Result) {
|
} elseif ($res instanceof PgSql\Result) {
|
||||||
$this->affectedRows = Helpers::false2Null(pg_affected_rows($res));
|
$this->affectedRows = Helpers::false2Null(pg_affected_rows($res));
|
||||||
if (pg_num_fields($res)) {
|
if (pg_num_fields($res)) {
|
||||||
return $this->createResultDriver($res);
|
return $this->createResultDriver($res);
|
||||||
@@ -222,13 +222,10 @@ class PostgreDriver implements Dibi\Driver
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the connection resource.
|
* Returns the connection resource.
|
||||||
* @return resource|null
|
|
||||||
*/
|
*/
|
||||||
public function getResource(): mixed
|
public function getResource(): PgSql\Connection
|
||||||
{
|
{
|
||||||
return is_resource($this->connection) || $this->connection instanceof PgSql\Connection
|
return $this->connection;
|
||||||
? $this->connection
|
|
||||||
: null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -237,15 +234,14 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Result set driver factory.
|
* Result set driver factory.
|
||||||
* @param resource $resource
|
|
||||||
*/
|
*/
|
||||||
public function createResultDriver($resource): PostgreResult
|
public function createResultDriver(PgSql\Result $resource): PostgreResult
|
||||||
{
|
{
|
||||||
return new PostgreResult($resource);
|
return new PostgreResult($resource);
|
||||||
}
|
}
|
||||||
|
@@ -17,14 +17,9 @@ use Dibi;
|
|||||||
*/
|
*/
|
||||||
class PostgreReflector implements Dibi\Reflector
|
class PostgreReflector implements Dibi\Reflector
|
||||||
{
|
{
|
||||||
private Dibi\Driver $driver;
|
public function __construct(
|
||||||
private string $version;
|
private readonly Dibi\Driver $driver,
|
||||||
|
) {
|
||||||
|
|
||||||
public function __construct(Dibi\Driver $driver, string $version)
|
|
||||||
{
|
|
||||||
$this->driver = $driver;
|
|
||||||
$this->version = $version;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -43,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 = [];
|
||||||
|
@@ -19,16 +19,9 @@ use PgSql;
|
|||||||
*/
|
*/
|
||||||
class PostgreResult implements Dibi\ResultDriver
|
class PostgreResult implements Dibi\ResultDriver
|
||||||
{
|
{
|
||||||
/** @var resource|PgSql\Result */
|
public function __construct(
|
||||||
private $resultSet;
|
private readonly PgSql\Result $resultSet,
|
||||||
|
) {
|
||||||
|
|
||||||
/**
|
|
||||||
* @param resource|PgSql\Result $resultSet
|
|
||||||
*/
|
|
||||||
public function __construct($resultSet)
|
|
||||||
{
|
|
||||||
$this->resultSet = $resultSet;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -94,13 +87,10 @@ class PostgreResult implements Dibi\ResultDriver
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the result set resource.
|
* Returns the result set resource.
|
||||||
* @return resource|PgSql\Result|null
|
|
||||||
*/
|
*/
|
||||||
public function getResultResource(): mixed
|
public function getResultResource(): PgSql\Result
|
||||||
{
|
{
|
||||||
return is_resource($this->resultSet) || $this->resultSet instanceof PgSql\Result
|
return $this->resultSet;
|
||||||
? $this->resultSet
|
|
||||||
: null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -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');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -17,12 +17,9 @@ use Dibi;
|
|||||||
*/
|
*/
|
||||||
class SqliteReflector implements Dibi\Reflector
|
class SqliteReflector implements Dibi\Reflector
|
||||||
{
|
{
|
||||||
private Dibi\Driver $driver;
|
public function __construct(
|
||||||
|
private readonly Dibi\Driver $driver,
|
||||||
|
) {
|
||||||
public function __construct(Dibi\Driver $driver)
|
|
||||||
{
|
|
||||||
$this->driver = $driver;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -11,6 +11,7 @@ namespace Dibi\Drivers;
|
|||||||
|
|
||||||
use Dibi;
|
use Dibi;
|
||||||
use Dibi\Helpers;
|
use Dibi\Helpers;
|
||||||
|
use const SQLITE3_ASSOC, SQLITE3_BLOB, SQLITE3_FLOAT, SQLITE3_INTEGER, SQLITE3_NULL, SQLITE3_NUM, SQLITE3_TEXT;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -18,12 +19,9 @@ use Dibi\Helpers;
|
|||||||
*/
|
*/
|
||||||
class SqliteResult implements Dibi\ResultDriver
|
class SqliteResult implements Dibi\ResultDriver
|
||||||
{
|
{
|
||||||
private \SQLite3Result $resultSet;
|
public function __construct(
|
||||||
|
private readonly \SQLite3Result $resultSet,
|
||||||
|
) {
|
||||||
public function __construct(\SQLite3Result $resultSet)
|
|
||||||
{
|
|
||||||
$this->resultSet = $resultSet;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -11,6 +11,7 @@ namespace Dibi\Drivers;
|
|||||||
|
|
||||||
use Dibi;
|
use Dibi;
|
||||||
use Dibi\Helpers;
|
use Dibi\Helpers;
|
||||||
|
use function is_resource, sprintf;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -30,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 */
|
||||||
@@ -68,8 +68,6 @@ class SqlsrvDriver implements Dibi\Driver
|
|||||||
|
|
||||||
sqlsrv_configure('WarningsReturnAsErrors', 1);
|
sqlsrv_configure('WarningsReturnAsErrors', 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->version = sqlsrv_server_info($this->connection)['SQLServerVersion'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -256,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);
|
||||||
|
@@ -10,6 +10,7 @@ declare(strict_types=1);
|
|||||||
namespace Dibi\Drivers;
|
namespace Dibi\Drivers;
|
||||||
|
|
||||||
use Dibi;
|
use Dibi;
|
||||||
|
use function sprintf;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -17,12 +18,9 @@ use Dibi;
|
|||||||
*/
|
*/
|
||||||
class SqlsrvReflector implements Dibi\Reflector
|
class SqlsrvReflector implements Dibi\Reflector
|
||||||
{
|
{
|
||||||
private Dibi\Driver $driver;
|
public function __construct(
|
||||||
|
private readonly Dibi\Driver $driver,
|
||||||
|
) {
|
||||||
public function __construct(Dibi\Driver $driver)
|
|
||||||
{
|
|
||||||
$this->driver = $driver;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -10,6 +10,7 @@ declare(strict_types=1);
|
|||||||
namespace Dibi\Drivers;
|
namespace Dibi\Drivers;
|
||||||
|
|
||||||
use Dibi;
|
use Dibi;
|
||||||
|
use function is_resource;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -17,16 +18,10 @@ use Dibi;
|
|||||||
*/
|
*/
|
||||||
class SqlsrvResult implements Dibi\ResultDriver
|
class SqlsrvResult implements Dibi\ResultDriver
|
||||||
{
|
{
|
||||||
/** @var resource */
|
public function __construct(
|
||||||
private $resultSet;
|
/** @var resource */
|
||||||
|
private $resultSet,
|
||||||
|
) {
|
||||||
/**
|
|
||||||
* @param resource $resultSet
|
|
||||||
*/
|
|
||||||
public function __construct($resultSet)
|
|
||||||
{
|
|
||||||
$this->resultSet = $resultSet;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -9,6 +9,9 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Dibi;
|
namespace Dibi;
|
||||||
|
|
||||||
|
use function count, dirname, microtime, preg_match, str_starts_with, strtoupper, trim;
|
||||||
|
use const DIRECTORY_SEPARATOR;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Profiler & logger event.
|
* Profiler & logger event.
|
||||||
@@ -29,10 +32,10 @@ class Event
|
|||||||
TRANSACTION = 448, // BEGIN | COMMIT | ROLLBACK
|
TRANSACTION = 448, // BEGIN | COMMIT | ROLLBACK
|
||||||
ALL = 1023;
|
ALL = 1023;
|
||||||
|
|
||||||
public Connection $connection;
|
public readonly Connection $connection;
|
||||||
public int $type;
|
public int $type;
|
||||||
public string $sql;
|
public readonly string $sql;
|
||||||
public Result|DriverException|null $result;
|
public readonly Result|DriverException|null $result;
|
||||||
public float $time;
|
public float $time;
|
||||||
public ?int $count = null;
|
public ?int $count = null;
|
||||||
public ?array $source = null;
|
public ?array $source = null;
|
||||||
|
@@ -15,7 +15,7 @@ namespace Dibi;
|
|||||||
*/
|
*/
|
||||||
class Expression
|
class Expression
|
||||||
{
|
{
|
||||||
private array $values;
|
private readonly array $values;
|
||||||
|
|
||||||
|
|
||||||
public function __construct(...$values)
|
public function __construct(...$values)
|
||||||
|
@@ -9,6 +9,8 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Dibi;
|
namespace Dibi;
|
||||||
|
|
||||||
|
use function array_key_exists, count, func_get_args, is_array, is_string;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SQL builder via fluent interfaces.
|
* SQL builder via fluent interfaces.
|
||||||
@@ -97,7 +99,7 @@ class Fluent implements IDataSource
|
|||||||
'RIGHT JOIN' => 'FROM',
|
'RIGHT JOIN' => 'FROM',
|
||||||
];
|
];
|
||||||
|
|
||||||
private Connection $connection;
|
private readonly Connection $connection;
|
||||||
private array $setups = [];
|
private array $setups = [];
|
||||||
private ?string $command = null;
|
private ?string $command = null;
|
||||||
private array $clauses = [];
|
private array $clauses = [];
|
||||||
@@ -113,7 +115,7 @@ class Fluent implements IDataSource
|
|||||||
$this->connection = $connection;
|
$this->connection = $connection;
|
||||||
|
|
||||||
if (!isset(self::$normalizer)) {
|
if (!isset(self::$normalizer)) {
|
||||||
self::$normalizer = new HashMap([self::class, '_formatClause']);
|
self::$normalizer = new HashMap(self::_formatClause(...));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -9,6 +9,9 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Dibi;
|
namespace Dibi;
|
||||||
|
|
||||||
|
use function array_map, array_unique, explode, fclose, fgets, fopen, fstat, getenv, htmlspecialchars, is_float, is_int, is_string, levenshtein, max, mb_strlen, ob_end_flush, ob_get_clean, ob_start, preg_match, preg_replace, preg_replace_callback, rtrim, set_time_limit, str_ends_with, str_repeat, str_starts_with, strlen, strtoupper, substr, trim, wordwrap;
|
||||||
|
use const PHP_SAPI;
|
||||||
|
|
||||||
|
|
||||||
class Helpers
|
class Helpers
|
||||||
{
|
{
|
||||||
@@ -208,7 +211,7 @@ class Helpers
|
|||||||
public static function getTypeCache(): HashMap
|
public static function getTypeCache(): HashMap
|
||||||
{
|
{
|
||||||
if (!isset(self::$types)) {
|
if (!isset(self::$types)) {
|
||||||
self::$types = new HashMap([self::class, 'detectType']);
|
self::$types = new HashMap(self::detectType(...));
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::$types;
|
return self::$types;
|
||||||
|
@@ -15,7 +15,7 @@ namespace Dibi;
|
|||||||
*/
|
*/
|
||||||
class Literal
|
class Literal
|
||||||
{
|
{
|
||||||
private string $value;
|
private readonly string $value;
|
||||||
|
|
||||||
|
|
||||||
public function __construct($value)
|
public function __construct($value)
|
||||||
|
@@ -10,6 +10,8 @@ declare(strict_types=1);
|
|||||||
namespace Dibi\Loggers;
|
namespace Dibi\Loggers;
|
||||||
|
|
||||||
use Dibi;
|
use Dibi;
|
||||||
|
use function sprintf;
|
||||||
|
use const FILE_APPEND, LOCK_EX;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -17,17 +19,11 @@ use Dibi;
|
|||||||
*/
|
*/
|
||||||
class FileLogger
|
class FileLogger
|
||||||
{
|
{
|
||||||
/** Name of the file where SQL errors should be logged */
|
public function __construct(
|
||||||
public string $file;
|
public string $file,
|
||||||
public int $filter;
|
public int $filter = Dibi\Event::QUERY,
|
||||||
private bool $errorsOnly;
|
private bool $errorsOnly = false,
|
||||||
|
) {
|
||||||
|
|
||||||
public function __construct(string $file, ?int $filter = null, bool $errorsOnly = false)
|
|
||||||
{
|
|
||||||
$this->file = $file;
|
|
||||||
$this->filter = $filter ?: Dibi\Event::QUERY;
|
|
||||||
$this->errorsOnly = $errorsOnly;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -27,17 +27,10 @@ use Dibi;
|
|||||||
*/
|
*/
|
||||||
class Column
|
class Column
|
||||||
{
|
{
|
||||||
/** when created by Result */
|
public function __construct(
|
||||||
private ?Dibi\Reflector $reflector;
|
private readonly ?Dibi\Reflector $reflector,
|
||||||
|
private array $info,
|
||||||
/** @var array (name, nativetype, [table], [fullname], [size], [nullable], [default], [autoincrement], [vendor]) */
|
) {
|
||||||
private array $info;
|
|
||||||
|
|
||||||
|
|
||||||
public function __construct(?Dibi\Reflector $reflector, array $info)
|
|
||||||
{
|
|
||||||
$this->reflector = $reflector;
|
|
||||||
$this->info = $info;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -10,6 +10,7 @@ declare(strict_types=1);
|
|||||||
namespace Dibi\Reflection;
|
namespace Dibi\Reflection;
|
||||||
|
|
||||||
use Dibi;
|
use Dibi;
|
||||||
|
use function array_values, strtolower;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -21,17 +22,14 @@ use Dibi;
|
|||||||
*/
|
*/
|
||||||
class Database
|
class Database
|
||||||
{
|
{
|
||||||
private Dibi\Reflector $reflector;
|
|
||||||
private ?string $name;
|
|
||||||
|
|
||||||
/** @var Table[] */
|
/** @var Table[] */
|
||||||
private array $tables;
|
private array $tables;
|
||||||
|
|
||||||
|
|
||||||
public function __construct(Dibi\Reflector $reflector, ?string $name = null)
|
public function __construct(
|
||||||
{
|
private readonly Dibi\Reflector $reflector,
|
||||||
$this->reflector = $reflector;
|
private ?string $name = null,
|
||||||
$this->name = $name;
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -19,16 +19,10 @@ namespace Dibi\Reflection;
|
|||||||
*/
|
*/
|
||||||
class ForeignKey
|
class ForeignKey
|
||||||
{
|
{
|
||||||
private string $name;
|
public function __construct(
|
||||||
|
private readonly string $name,
|
||||||
/** @var array of [local, foreign, onDelete, onUpdate] */
|
private readonly array $references,
|
||||||
private array $references;
|
) {
|
||||||
|
|
||||||
|
|
||||||
public function __construct(string $name, array $references)
|
|
||||||
{
|
|
||||||
$this->name = $name;
|
|
||||||
$this->references = $references;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -21,13 +21,9 @@ namespace Dibi\Reflection;
|
|||||||
*/
|
*/
|
||||||
class Index
|
class Index
|
||||||
{
|
{
|
||||||
/** @var array (name, columns, [unique], [primary]) */
|
public function __construct(
|
||||||
private array $info;
|
private readonly array $info,
|
||||||
|
) {
|
||||||
|
|
||||||
public function __construct(array $info)
|
|
||||||
{
|
|
||||||
$this->info = $info;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -10,6 +10,7 @@ declare(strict_types=1);
|
|||||||
namespace Dibi\Reflection;
|
namespace Dibi\Reflection;
|
||||||
|
|
||||||
use Dibi;
|
use Dibi;
|
||||||
|
use function array_values, strtolower;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -20,8 +21,6 @@ use Dibi;
|
|||||||
*/
|
*/
|
||||||
class Result
|
class Result
|
||||||
{
|
{
|
||||||
private Dibi\ResultDriver $driver;
|
|
||||||
|
|
||||||
/** @var Column[]|null */
|
/** @var Column[]|null */
|
||||||
private ?array $columns;
|
private ?array $columns;
|
||||||
|
|
||||||
@@ -29,9 +28,9 @@ class Result
|
|||||||
private ?array $names;
|
private ?array $names;
|
||||||
|
|
||||||
|
|
||||||
public function __construct(Dibi\ResultDriver $driver)
|
public function __construct(
|
||||||
{
|
private readonly Dibi\ResultDriver $driver,
|
||||||
$this->driver = $driver;
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -10,6 +10,7 @@ declare(strict_types=1);
|
|||||||
namespace Dibi\Reflection;
|
namespace Dibi\Reflection;
|
||||||
|
|
||||||
use Dibi;
|
use Dibi;
|
||||||
|
use function array_values, strtolower;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -25,7 +26,7 @@ use Dibi;
|
|||||||
*/
|
*/
|
||||||
class Table
|
class Table
|
||||||
{
|
{
|
||||||
private Dibi\Reflector $reflector;
|
private readonly Dibi\Reflector $reflector;
|
||||||
private string $name;
|
private string $name;
|
||||||
private bool $view;
|
private bool $view;
|
||||||
|
|
||||||
|
@@ -9,6 +9,9 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Dibi;
|
namespace Dibi;
|
||||||
|
|
||||||
|
use function array_keys, array_pop, count, explode, is_float, is_string, json_decode, ltrim, preg_match, preg_split, property_exists, reset, rtrim, str_contains, str_replace, str_starts_with, strpos;
|
||||||
|
use const PREG_SPLIT_DELIM_CAPTURE, PREG_SPLIT_NO_EMPTY;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query result.
|
* Query result.
|
||||||
|
@@ -15,14 +15,13 @@ namespace Dibi;
|
|||||||
*/
|
*/
|
||||||
class ResultIterator implements \Iterator, \Countable
|
class ResultIterator implements \Iterator, \Countable
|
||||||
{
|
{
|
||||||
private Result $result;
|
|
||||||
private mixed $row;
|
private mixed $row;
|
||||||
private int $pointer = 0;
|
private int $pointer = 0;
|
||||||
|
|
||||||
|
|
||||||
public function __construct(Result $result)
|
public function __construct(
|
||||||
{
|
private readonly Result $result,
|
||||||
$this->result = $result;
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -9,6 +9,8 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Dibi;
|
namespace Dibi;
|
||||||
|
|
||||||
|
use function array_keys, count, str_starts_with;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Result set single row.
|
* Result set single row.
|
||||||
|
@@ -9,14 +9,16 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Dibi;
|
namespace Dibi;
|
||||||
|
|
||||||
|
use function array_filter, array_keys, array_splice, array_values, count, explode, get_debug_type, gettype, implode, is_array, is_bool, is_float, is_int, is_numeric, is_object, is_scalar, is_string, iterator_to_array, key, ltrim, number_format, preg_last_error, preg_match, preg_replace_callback, reset, rtrim, str_contains, str_replace, strcspn, strlen, strncasecmp, strtoupper, substr, trim;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SQL translator.
|
* SQL translator.
|
||||||
*/
|
*/
|
||||||
final class Translator
|
final class Translator
|
||||||
{
|
{
|
||||||
private Connection $connection;
|
private readonly Connection $connection;
|
||||||
private Driver $driver;
|
private readonly Driver $driver;
|
||||||
private int $cursor = 0;
|
private int $cursor = 0;
|
||||||
private array $args;
|
private array $args;
|
||||||
|
|
||||||
@@ -34,7 +36,7 @@ final class Translator
|
|||||||
{
|
{
|
||||||
$this->connection = $connection;
|
$this->connection = $connection;
|
||||||
$this->driver = $connection->getDriver();
|
$this->driver = $connection->getDriver();
|
||||||
$this->identifiers = new HashMap([$this, 'delimite']);
|
$this->identifiers = new HashMap($this->delimite(...));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -88,7 +90,7 @@ final class Translator
|
|||||||
(\?) ## 11) placeholder
|
(\?) ## 11) placeholder
|
||||||
)/xs
|
)/xs
|
||||||
XX,
|
XX,
|
||||||
[$this, 'cb'],
|
$this->cb(...),
|
||||||
substr($arg, $toSkip),
|
substr($arg, $toSkip),
|
||||||
);
|
);
|
||||||
if (preg_last_error()) {
|
if (preg_last_error()) {
|
||||||
@@ -434,7 +436,7 @@ final class Translator
|
|||||||
:(\S*?:)([a-zA-Z0-9._]?)
|
:(\S*?:)([a-zA-Z0-9._]?)
|
||||||
)/sx
|
)/sx
|
||||||
XX,
|
XX,
|
||||||
[$this, 'cb'],
|
$this->cb(...),
|
||||||
substr($value, $toSkip),
|
substr($value, $toSkip),
|
||||||
);
|
);
|
||||||
if (preg_last_error()) {
|
if (preg_last_error()) {
|
||||||
|
@@ -37,7 +37,7 @@ declare(strict_types=1);
|
|||||||
*/
|
*/
|
||||||
class dibi
|
class dibi
|
||||||
{
|
{
|
||||||
public const Version = '5.0.2';
|
public const Version = '5.1-dev';
|
||||||
|
|
||||||
/** @deprecated use dibi::Version */
|
/** @deprecated use dibi::Version */
|
||||||
public const VERSION = self::Version;
|
public const VERSION = self::Version;
|
||||||
|
@@ -11,7 +11,7 @@ namespace Dibi;
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dibi common exception.
|
* A database operation failed.
|
||||||
*/
|
*/
|
||||||
class Exception extends \Exception
|
class Exception extends \Exception
|
||||||
{
|
{
|
||||||
@@ -44,7 +44,7 @@ class Exception extends \Exception
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* database server exception.
|
* The database server reported an error.
|
||||||
*/
|
*/
|
||||||
class DriverException extends Exception
|
class DriverException extends Exception
|
||||||
{
|
{
|
||||||
@@ -52,7 +52,7 @@ class DriverException extends Exception
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PCRE exception.
|
* Regular expression pattern or execution failed.
|
||||||
*/
|
*/
|
||||||
class PcreException extends Exception
|
class PcreException extends Exception
|
||||||
{
|
{
|
||||||
@@ -63,18 +63,24 @@ class PcreException extends Exception
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The requested feature is not implemented.
|
||||||
|
*/
|
||||||
class NotImplementedException extends Exception
|
class NotImplementedException extends Exception
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The requested operation is not supported.
|
||||||
|
*/
|
||||||
class NotSupportedException extends Exception
|
class NotSupportedException extends Exception
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Database procedure exception.
|
* A database stored procedure failed.
|
||||||
*/
|
*/
|
||||||
class ProcedureException extends Exception
|
class ProcedureException extends Exception
|
||||||
{
|
{
|
||||||
@@ -102,7 +108,7 @@ class ProcedureException extends Exception
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for all constraint violation related exceptions.
|
* A database constraint was violated.
|
||||||
*/
|
*/
|
||||||
class ConstraintViolationException extends DriverException
|
class ConstraintViolationException extends DriverException
|
||||||
{
|
{
|
||||||
@@ -110,7 +116,7 @@ class ConstraintViolationException extends DriverException
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception for a foreign key constraint violation.
|
* The foreign key constraint check failed.
|
||||||
*/
|
*/
|
||||||
class ForeignKeyConstraintViolationException extends ConstraintViolationException
|
class ForeignKeyConstraintViolationException extends ConstraintViolationException
|
||||||
{
|
{
|
||||||
@@ -118,7 +124,7 @@ class ForeignKeyConstraintViolationException extends ConstraintViolationExceptio
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception for a NOT NULL constraint violation.
|
* The NOT NULL constraint check failed.
|
||||||
*/
|
*/
|
||||||
class NotNullConstraintViolationException extends ConstraintViolationException
|
class NotNullConstraintViolationException extends ConstraintViolationException
|
||||||
{
|
{
|
||||||
@@ -126,7 +132,7 @@ class NotNullConstraintViolationException extends ConstraintViolationException
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception for a unique constraint violation.
|
* The unique constraint check failed.
|
||||||
*/
|
*/
|
||||||
class UniqueConstraintViolationException extends ConstraintViolationException
|
class UniqueConstraintViolationException extends ConstraintViolationException
|
||||||
{
|
{
|
||||||
|
@@ -12,7 +12,7 @@ use Tester\Assert;
|
|||||||
require __DIR__ . '/bootstrap.php';
|
require __DIR__ . '/bootstrap.php';
|
||||||
|
|
||||||
|
|
||||||
test('', function () use ($config) {
|
test('immediate connection and disconnection state', function () use ($config) {
|
||||||
$conn = new Connection($config);
|
$conn = new Connection($config);
|
||||||
Assert::true($conn->isConnected());
|
Assert::true($conn->isConnected());
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ test('', function () use ($config) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
test('lazy', function () use ($config) {
|
test('lazy connection initiated on first query', function () use ($config) {
|
||||||
$conn = new Connection($config + ['lazy' => true]);
|
$conn = new Connection($config + ['lazy' => true]);
|
||||||
Assert::false($conn->isConnected());
|
Assert::false($conn->isConnected());
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ test('lazy', function () use ($config) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
test('', function () use ($config) {
|
test('config retrieval and driver instance access', function () use ($config) {
|
||||||
$conn = new Connection($config);
|
$conn = new Connection($config);
|
||||||
Assert::true($conn->isConnected());
|
Assert::true($conn->isConnected());
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ test('', function () use ($config) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
test('', function () use ($config) {
|
test('idempotent disconnect calls', function () use ($config) {
|
||||||
$conn = new Connection($config);
|
$conn = new Connection($config);
|
||||||
Assert::true($conn->isConnected());
|
Assert::true($conn->isConnected());
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ test('', function () use ($config) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
test('', function () use ($config) {
|
test('reconnect after disconnection', function () use ($config) {
|
||||||
$conn = new Connection($config);
|
$conn = new Connection($config);
|
||||||
Assert::equal('hello', $conn->query('SELECT %s', 'hello')->fetchSingle());
|
Assert::equal('hello', $conn->query('SELECT %s', 'hello')->fetchSingle());
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ test('', function () use ($config) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
test('', function () use ($config) {
|
test('destructor disconnects active connection', function () use ($config) {
|
||||||
$conn = new Connection($config);
|
$conn = new Connection($config);
|
||||||
Assert::true($conn->isConnected());
|
Assert::true($conn->isConnected());
|
||||||
|
|
||||||
@@ -72,7 +72,7 @@ test('', function () use ($config) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
test('', function () use ($config) {
|
test('invalid onConnect option triggers exceptions', function () use ($config) {
|
||||||
Assert::exception(
|
Assert::exception(
|
||||||
fn() => new Connection($config + ['onConnect' => '']),
|
fn() => new Connection($config + ['onConnect' => '']),
|
||||||
InvalidArgumentException::class,
|
InvalidArgumentException::class,
|
||||||
|
@@ -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(
|
||||||
|
@@ -36,5 +36,5 @@ Assert::exception(
|
|||||||
|
|
||||||
test(
|
test(
|
||||||
'PDO error mode: explicitly set silent',
|
'PDO error mode: explicitly set silent',
|
||||||
fn() => buildPdoDriver(PDO::ERRMODE_SILENT)
|
fn() => buildPdoDriver(PDO::ERRMODE_SILENT),
|
||||||
);
|
);
|
||||||
|
@@ -18,9 +18,9 @@ $tests = function ($conn) {
|
|||||||
Assert::false($conn->query("SELECT 'AAxBB' LIKE %~like~", 'A%B')->fetchSingle());
|
Assert::false($conn->query("SELECT 'AAxBB' LIKE %~like~", 'A%B')->fetchSingle());
|
||||||
Assert::true($conn->query("SELECT 'AA%BB' LIKE %~like~", 'A%B')->fetchSingle());
|
Assert::true($conn->query("SELECT 'AA%BB' LIKE %~like~", 'A%B')->fetchSingle());
|
||||||
|
|
||||||
Assert::same('AA\\BB', $conn->query("SELECT 'AA\\BB'")->fetchSingle());
|
Assert::same('AA\BB', $conn->query("SELECT 'AA\\BB'")->fetchSingle());
|
||||||
Assert::false($conn->query("SELECT 'AAxBB' LIKE %~like~", 'A\\B')->fetchSingle());
|
Assert::false($conn->query("SELECT 'AAxBB' LIKE %~like~", 'A\B')->fetchSingle());
|
||||||
Assert::true($conn->query("SELECT 'AA\\BB' LIKE %~like~", 'A\\B')->fetchSingle());
|
Assert::true($conn->query("SELECT 'AA\\BB' LIKE %~like~", 'A\B')->fetchSingle());
|
||||||
};
|
};
|
||||||
|
|
||||||
$conn = new Dibi\Connection($config);
|
$conn = new Dibi\Connection($config);
|
||||||
|
@@ -25,7 +25,7 @@ class MockResult extends Dibi\Result
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
test('', function () {
|
test('native text conversion preserves boolean values', function () {
|
||||||
$result = new MockResult;
|
$result = new MockResult;
|
||||||
$result->setType('col', Type::Text);
|
$result->setType('col', Type::Text);
|
||||||
$result->setFormat(Type::Text, 'native');
|
$result->setFormat(Type::Text, 'native');
|
||||||
@@ -36,7 +36,7 @@ test('', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
test('', function () {
|
test('boolean conversion from diverse representations', function () {
|
||||||
$result = new MockResult;
|
$result = new MockResult;
|
||||||
$result->setType('col', Type::Bool);
|
$result->setType('col', Type::Bool);
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ test('', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
test('', function () {
|
test('text conversion of booleans and numerics', function () {
|
||||||
$result = new MockResult;
|
$result = new MockResult;
|
||||||
$result->setType('col', Type::Text);
|
$result->setType('col', Type::Text);
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ test('', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
test('', function () {
|
test('float conversion with various numeric formats', function () {
|
||||||
$result = new MockResult;
|
$result = new MockResult;
|
||||||
$result->setType('col', Type::Float);
|
$result->setType('col', Type::Float);
|
||||||
|
|
||||||
@@ -214,7 +214,7 @@ test('', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
test('', function () {
|
test('strict integer conversion with error on empty string', function () {
|
||||||
$result = new MockResult;
|
$result = new MockResult;
|
||||||
$result->setType('col', Type::Integer);
|
$result->setType('col', Type::Integer);
|
||||||
|
|
||||||
@@ -222,14 +222,10 @@ test('', function () {
|
|||||||
Assert::same(['col' => 1], $result->test(['col' => true]));
|
Assert::same(['col' => 1], $result->test(['col' => true]));
|
||||||
Assert::same(['col' => 0], $result->test(['col' => false]));
|
Assert::same(['col' => 0], $result->test(['col' => false]));
|
||||||
|
|
||||||
if (PHP_VERSION_ID < 80000) {
|
Assert::exception(
|
||||||
Assert::same(['col' => 0], @$result->test(['col' => ''])); // triggers warning since PHP 7.1
|
fn() => Assert::same(['col' => 0], $result->test(['col' => ''])),
|
||||||
} else {
|
TypeError::class,
|
||||||
Assert::exception(
|
);
|
||||||
fn() => Assert::same(['col' => 0], $result->test(['col' => ''])),
|
|
||||||
TypeError::class,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Assert::same(['col' => 0], $result->test(['col' => '0']));
|
Assert::same(['col' => 0], $result->test(['col' => '0']));
|
||||||
Assert::same(['col' => 1], $result->test(['col' => '1']));
|
Assert::same(['col' => 1], $result->test(['col' => '1']));
|
||||||
@@ -248,7 +244,7 @@ test('', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
test('', function () {
|
test('dateTime conversion with object instantiation', function () {
|
||||||
$result = new MockResult;
|
$result = new MockResult;
|
||||||
$result->setType('col', Type::DateTime);
|
$result->setType('col', Type::DateTime);
|
||||||
|
|
||||||
@@ -267,7 +263,7 @@ test('', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
test('', function () {
|
test('dateTime conversion using custom format', function () {
|
||||||
$result = new MockResult;
|
$result = new MockResult;
|
||||||
$result->setType('col', Type::DateTime);
|
$result->setType('col', Type::DateTime);
|
||||||
$result->setFormat(Type::DateTime, 'Y-m-d H:i:s');
|
$result->setFormat(Type::DateTime, 'Y-m-d H:i:s');
|
||||||
@@ -287,7 +283,7 @@ test('', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
test('', function () {
|
test('date conversion to DateTime instance', function () {
|
||||||
$result = new MockResult;
|
$result = new MockResult;
|
||||||
$result->setType('col', Type::Date);
|
$result->setType('col', Type::Date);
|
||||||
|
|
||||||
@@ -304,7 +300,7 @@ test('', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
test('', function () {
|
test('time conversion to DateTime instance', function () {
|
||||||
$result = new MockResult;
|
$result = new MockResult;
|
||||||
$result->setType('col', Type::Time);
|
$result->setType('col', Type::Time);
|
||||||
|
|
||||||
|
@@ -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);
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @phpVersion 8.1
|
|
||||||
* @dataProvider ../databases.ini
|
* @dataProvider ../databases.ini
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@@ -32,7 +32,7 @@ Assert::truthy($conn->fetchSingle('SELECT ? LIKE %like~', "a'a", "a'"));
|
|||||||
Assert::falsey($conn->fetchSingle('SELECT ? LIKE %like~', "b'", "%'"));
|
Assert::falsey($conn->fetchSingle('SELECT ? LIKE %like~', "b'", "%'"));
|
||||||
Assert::truthy($conn->fetchSingle('SELECT ? LIKE %like~', "%'", "%'"));
|
Assert::truthy($conn->fetchSingle('SELECT ? LIKE %like~', "%'", "%'"));
|
||||||
|
|
||||||
Assert::truthy($conn->fetchSingle('SELECT ? LIKE %like~', 'a\\a', 'a\\'));
|
Assert::truthy($conn->fetchSingle('SELECT ? LIKE %like~', 'a\a', 'a\\'));
|
||||||
Assert::falsey($conn->fetchSingle('SELECT ? LIKE %like~', 'b\\', '%\\'));
|
Assert::falsey($conn->fetchSingle('SELECT ? LIKE %like~', 'b\\', '%\\'));
|
||||||
Assert::truthy($conn->fetchSingle('SELECT ? LIKE %like~', '%\\', '%\\'));
|
Assert::truthy($conn->fetchSingle('SELECT ? LIKE %like~', '%\\', '%\\'));
|
||||||
|
|
||||||
@@ -60,9 +60,9 @@ Assert::truthy($conn->fetchSingle('SELECT ? LIKE %~like', "a'a", "'a"));
|
|||||||
Assert::falsey($conn->fetchSingle('SELECT ? LIKE %~like', "'b", "'%"));
|
Assert::falsey($conn->fetchSingle('SELECT ? LIKE %~like', "'b", "'%"));
|
||||||
Assert::truthy($conn->fetchSingle('SELECT ? LIKE %~like', "'%", "'%"));
|
Assert::truthy($conn->fetchSingle('SELECT ? LIKE %~like', "'%", "'%"));
|
||||||
|
|
||||||
Assert::truthy($conn->fetchSingle('SELECT ? LIKE %~like', 'a\\a', '\\a'));
|
Assert::truthy($conn->fetchSingle('SELECT ? LIKE %~like', 'a\a', '\a'));
|
||||||
Assert::falsey($conn->fetchSingle('SELECT ? LIKE %~like', '\\b', '\\%'));
|
Assert::falsey($conn->fetchSingle('SELECT ? LIKE %~like', '\b', '\%'));
|
||||||
Assert::truthy($conn->fetchSingle('SELECT ? LIKE %~like', '\\%', '\\%'));
|
Assert::truthy($conn->fetchSingle('SELECT ? LIKE %~like', '\%', '\%'));
|
||||||
|
|
||||||
|
|
||||||
// contains
|
// contains
|
||||||
|
Reference in New Issue
Block a user