1
0
mirror of https://github.com/dg/dibi.git synced 2025-09-01 18:12:51 +02:00

Compare commits

...

48 Commits

Author SHA1 Message Date
David Grudl
d571460a6f Released version 3.2.4 2020-03-26 04:05:01 +01:00
David Grudl
dc3e1cda19 SqliteResult: workaround for PHP bug 79414 2020-03-26 04:02:26 +01:00
David Grudl
21039ff379 Result: does not drop the value if detection fails 2020-03-26 04:00:52 +01:00
David Grudl
22b15d9859 travis: fixed databases 2020-03-26 04:00:52 +01:00
Chrudos Vorlicek
6aa8a431c2 Result::normalize() Fix select float in format of e-notation (#317) v3.2 (#320) 2018-10-25 22:33:22 +02:00
David Grudl
69ea60cc16 travis: added PHP 7.3 2018-10-17 17:47:42 +02:00
David Grudl
906e1f2407 Released version 3.2.3 2018-09-17 13:47:10 +02:00
David Grudl
6a4f77b684 test: fix for PHP 7.3 2018-09-17 13:36:50 +02:00
Jan Kuchař
689597a237 PdoDriver: check for misconfigured PDO connections resource (#294) 2018-09-17 13:36:50 +02:00
David Grudl
a8ed2a34e5 travis: uses NCS 2 2018-09-13 03:28:20 +02:00
David Grudl
c8e5f5c8d1 loader: added missing classes [Closes #310] 2018-08-22 15:38:20 +02:00
David Grudl
4bfd314225 OdbcDriver: added option 'microseconds' 2018-08-09 22:54:00 +02:00
David Grudl
2b4ea9abe7 updated donation links 2018-06-22 11:48:18 +02:00
Miroslav Koula
3711b1739f DibiExtension: compatibility with Nette DI 3.x (#297)
Nette DI 3.x require $container->setFactory() usage except of $container->setClass()
2018-06-19 11:56:01 +02:00
David Grudl
45d7e0b365 cs 2018-06-13 15:39:54 +02:00
Josef Drábek
7d07db1f12 PdoDriver::getInsertId() fixed 2018-06-13 11:49:27 +02:00
Jan Endel
34bdd5f267 typo
for example fluent:

$dibiConnection->select(‘id’)
    ->from(‘users’);

will not pass static analysis although is completely valid code.
2018-06-13 11:48:28 +02:00
David Grudl
5a7543a5a6 Released version 3.2.2 2018-05-10 21:55:12 +02:00
David Grudl
2848c965f9 Result: added getColumnCount() 2018-05-10 21:55:12 +02:00
David Grudl
3660f26e03 improved phpDoc, capitalized Dibi 2018-05-10 21:54:30 +02:00
David Grudl
f474abfeda type improvements 2018-05-02 10:49:01 +02:00
David Grudl
809386edf8 added dibi::stripMicroseconds 2018-04-19 13:04:47 +02:00
David Grudl
1909c98e6d Sqlite3Driver: for SQLite 3 is not needed to strip [] from column names 2018-04-19 13:04:47 +02:00
David Grudl
8985c71276 refactoring 2018-04-19 13:04:39 +02:00
David Grudl
0d5fd9d65b type fixes 2018-04-17 13:09:27 +02:00
David Grudl
4049ea4717 examples: dibi:: replaced with $dibi-> 2018-04-17 13:09:27 +02:00
David Grudl
cec699af0f Released version 3.2.1 2018-04-14 20:49:54 +02:00
David Grudl
59a4cc2fe0 Revert "loader: uses only Composer's autoloader"
This reverts commit 5c806ea517.
2018-04-14 20:49:14 +02:00
David Grudl
985f09417e Translator: improved Expression usage 2018-04-14 20:49:14 +02:00
David Grudl
729d133d70 PdoDriver: improved detection of query result [Closes #279] 2018-03-28 18:04:35 +02:00
David Grudl
759c63bca0 appveyor: improved 2018-03-23 17:53:22 +01:00
David Grudl
f9fc7e330d examples: added notice when vendor/autoload.php not found 2018-03-23 11:57:59 +01:00
jahudka
dbca915bfe Firebird: fix datetime precision (#277) (#273) 2018-03-18 10:49:20 +01:00
Miloslav Hůla
1bae6eae08 tests: connection removed from bootstrap 2018-03-09 15:09:48 +01:00
David Grudl
34b7e22d40 readme.md: static -> object 2018-03-09 15:09:48 +01:00
David Grudl
369f5ee7d6 readme: updated installation and requirements 2018-03-09 15:09:48 +01:00
David Grudl
2d74bb3da0 examples: uses composer autoload 2018-03-09 14:50:36 +01:00
David Grudl
a5422a65c9 loader: old class names triggers E_USER_DEPRECATED, removed preloading (BC break) 2018-03-09 14:44:06 +01:00
David Grudl
5c806ea517 loader: uses only Composer's autoloader
# Conflicts:
#	src/loader.php
2018-03-09 14:38:18 +01:00
David Grudl
ecafed6246 opened 3.2-dev 2018-03-09 14:37:31 +01:00
David Grudl
504b7725c7 Released version 3.1.1 2018-03-09 13:00:25 +01:00
David Grudl
822405b478 appveyor: PHP is downloaded using cURL
"03/mar/2018: We've upgraded the server bandwidth. This is however still not sufficient to handle all empty user agent connections. Please update the user agent in your scripts accordingly or contact us so we can discuss it."
2018-03-08 13:52:54 +01:00
David Grudl
43d3b57a8d Microsoft SQL Server and MSSQL support for microseconds fix cont. 2018-02-25 16:59:37 +01:00
hubipe
4f0566ece7 Microsoft SQL Server and MSSQL support for microseconds fix (#249) 2018-02-25 16:59:36 +01:00
Korney Czukowski
67521084d9 Previous exception can now be passed to Dibi\Exception constructor (#276) 2018-02-16 14:12:33 +01:00
David Grudl
22ac601502 loader: fixed missing class 'dibi.php' 2018-02-15 11:53:57 +01:00
Petr Bugyík
b740b70f18 drivers: changed self:: to static:: 2018-02-14 13:05:35 +01:00
David Grudl
44fc3f4553 coding style 2018-02-11 22:47:22 +01:00
72 changed files with 577 additions and 413 deletions

View File

@@ -6,6 +6,11 @@ php:
- 7.0
- 7.1
- 7.2
- 7.3
services:
- mysql
- postgresql
before_install:
# turn off XDebug
@@ -33,12 +38,12 @@ jobs:
php: 7.1
install:
# Install Nette Code Checker
- travis_retry composer create-project nette/code-checker temp/code-checker ~2 --no-progress
- travis_retry composer create-project nette/code-checker temp/code-checker ^3 --no-progress
# Install Nette Coding Standard
- travis_retry composer create-project nette/coding-standard temp/coding-standard --no-progress
- travis_retry composer create-project nette/coding-standard temp/coding-standard ^2 --no-progress
script:
- php temp/code-checker/src/code-checker.php --short-arrays
- php temp/coding-standard/ecs check src tests examples --config temp/coding-standard/coding-standard-php56.neon
- php temp/code-checker/code-checker
- php temp/coding-standard/ecs check src tests examples --config temp/coding-standard/coding-standard-php56.yml
- stage: Code Coverage
@@ -63,3 +68,5 @@ cache:
notifications:
email: false
dist: trusty

View File

@@ -20,8 +20,8 @@ install:
- IF EXIST c:\php5 (SET PHP=0) ELSE (SET PHP=1)
- IF %PHP%==1 mkdir c:\php5
- IF %PHP%==1 cd c:\php5
- IF %PHP%==1 appveyor DownloadFile http://windows.php.net/downloads/releases/archives/php-5.6.14-Win32-VC11-x86.zip
- IF %PHP%==1 7z x php-5.6.14-Win32-VC11-x86.zip >nul
- IF %PHP%==1 curl https://windows.php.net/downloads/releases/archives/php-5.6.14-Win32-VC11-x86.zip --output php.zip
- IF %PHP%==1 7z x php.zip >nul
- IF %PHP%==1 echo extension_dir=ext >> php.ini
- IF %PHP%==1 echo extension=php_openssl.dll >> php.ini
- IF %PHP%==1 appveyor DownloadFile https://files.nette.org/misc/php-sqlsrv.zip
@@ -34,8 +34,8 @@ install:
- IF EXIST c:\php7 (SET PHP=0) ELSE (SET PHP=1)
- IF %PHP%==1 mkdir c:\php7
- IF %PHP%==1 cd c:\php7
- IF %PHP%==1 appveyor DownloadFile http://windows.php.net/downloads/releases/archives/php-7.0.3-Win32-VC14-x86.zip
- IF %PHP%==1 7z x php-7.0.3-Win32-VC14-x86.zip >nul
- IF %PHP%==1 curl https://windows.php.net/downloads/releases/archives/php-7.0.3-Win32-VC14-x86.zip --output php.zip
- IF %PHP%==1 7z x php.zip >nul
- IF %PHP%==1 echo extension_dir=ext >> php.ini
- IF %PHP%==1 appveyor DownloadFile https://files.nette.org/misc/php-sqlsrv.zip
- IF %PHP%==1 7z x php-sqlsrv.zip >nul
@@ -56,4 +56,4 @@ test_script:
on_failure:
# Print *.actual content
- type tests\dibi\output\*.actual
- for /r %%x in (*.actual) do ( type "%%x" )

View File

@@ -26,7 +26,7 @@
},
"extra": {
"branch-alias": {
"dev-master": "3.1-dev"
"dev-master": "3.2-dev"
}
}
}

View File

@@ -1,13 +1,15 @@
<!DOCTYPE html><link rel="stylesheet" href="data/style.css">
<h1>Connecting to Databases | dibi</h1>
<h1>Connecting to Databases | Dibi</h1>
<?php
require __DIR__ . '/../src/loader.php';
if (@!include __DIR__ . '/../vendor/autoload.php') {
die('Install packages using `composer install`');
}
// connects to SQlite using dibi class
// connects to SQlite using Dibi class
echo '<p>Connecting to Sqlite: ';
try {
dibi::connect([

View File

@@ -1,20 +1,22 @@
<!DOCTYPE html><link rel="stylesheet" href="data/style.css">
<h1>Database Reflection | dibi</h1>
<h1>Database Reflection | Dibi</h1>
<?php
require __DIR__ . '/../src/loader.php';
if (@!include __DIR__ . '/../vendor/autoload.php') {
die('Install packages using `composer install`');
}
dibi::connect([
$dibi = new Dibi\Connection([
'driver' => 'sqlite3',
'database' => 'data/sample.s3db',
]);
// retrieve database reflection
$database = dibi::getDatabaseInfo();
$database = $dibi->getDatabaseInfo();
echo "<h2>Database '{$database->getName()}'</h2>\n";
echo "<ul>\n";

View File

@@ -1,19 +1,21 @@
<!DOCTYPE html><link rel="stylesheet" href="data/style.css">
<h1>Dumping SQL and Result Set | dibi</h1>
<h1>Dumping SQL and Result Set | Dibi</h1>
<?php
require __DIR__ . '/../src/loader.php';
if (@!include __DIR__ . '/../vendor/autoload.php') {
die('Install packages using `composer install`');
}
dibi::connect([
$dibi = new Dibi\Connection([
'driver' => 'sqlite3',
'database' => 'data/sample.s3db',
]);
$res = dibi::query('
$res = $dibi->query('
SELECT * FROM products
INNER JOIN orders USING (product_id)
INNER JOIN customers USING (customer_id)

View File

@@ -9,11 +9,11 @@ Tracy\Debugger::enable();
?>
<!DOCTYPE html><link rel="stylesheet" href="data/style.css">
<h1>Fetching Examples | dibi</h1>
<h1>Fetching Examples | Dibi</h1>
<?php
dibi::connect([
$dibi = new Dibi\Connection([
'driver' => 'sqlite3',
'database' => 'data/sample.s3db',
]);
@@ -33,46 +33,46 @@ product_id | title
// fetch a single row
echo "<h2>fetch()</h2>\n";
$row = dibi::fetch('SELECT title FROM products');
$row = $dibi->fetch('SELECT title FROM products');
Tracy\Dumper::dump($row); // Chair
// fetch a single value
echo "<h2>fetchSingle()</h2>\n";
$value = dibi::fetchSingle('SELECT title FROM products');
$value = $dibi->fetchSingle('SELECT title FROM products');
Tracy\Dumper::dump($value); // Chair
// fetch complete result set
echo "<h2>fetchAll()</h2>\n";
$all = dibi::fetchAll('SELECT * FROM products');
$all = $dibi->fetchAll('SELECT * FROM products');
Tracy\Dumper::dump($all);
// fetch complete result set like association array
echo "<h2>fetchAssoc('title')</h2>\n";
$res = dibi::query('SELECT * FROM products');
$res = $dibi->query('SELECT * FROM products');
$assoc = $res->fetchAssoc('title'); // key
Tracy\Dumper::dump($assoc);
// fetch complete result set like pairs key => value
echo "<h2>fetchPairs('product_id', 'title')</h2>\n";
$res = dibi::query('SELECT * FROM products');
$res = $dibi->query('SELECT * FROM products');
$pairs = $res->fetchPairs('product_id', 'title');
Tracy\Dumper::dump($pairs);
// fetch row by row
echo "<h2>using foreach</h2>\n";
$res = dibi::query('SELECT * FROM products');
$res = $dibi->query('SELECT * FROM products');
foreach ($res as $n => $row) {
Tracy\Dumper::dump($row);
}
// more complex association array
$res = dibi::query('
$res = $dibi->query('
SELECT *
FROM products
INNER JOIN orders USING (product_id)
@@ -84,11 +84,11 @@ $assoc = $res->fetchAssoc('name|title'); // key
Tracy\Dumper::dump($assoc);
echo "<h2>fetchAssoc('name[]title')</h2>\n";
$res = dibi::query('SELECT * FROM products INNER JOIN orders USING (product_id) INNER JOIN customers USING (customer_id)');
$res = $dibi->query('SELECT * FROM products INNER JOIN orders USING (product_id) INNER JOIN customers USING (customer_id)');
$assoc = $res->fetchAssoc('name[]title'); // key
Tracy\Dumper::dump($assoc);
echo "<h2>fetchAssoc('name->title')</h2>\n";
$res = dibi::query('SELECT * FROM products INNER JOIN orders USING (product_id) INNER JOIN customers USING (customer_id)');
$res = $dibi->query('SELECT * FROM products INNER JOIN orders USING (product_id) INNER JOIN customers USING (customer_id)');
$assoc = $res->fetchAssoc('name->title'); // key
Tracy\Dumper::dump($assoc);

View File

@@ -1,18 +1,20 @@
<!DOCTYPE html><link rel="stylesheet" href="data/style.css">
<h1>Importing SQL Dump from File | dibi</h1>
<h1>Importing SQL Dump from File | Dibi</h1>
<?php
require __DIR__ . '/../src/loader.php';
if (@!include __DIR__ . '/../vendor/autoload.php') {
die('Install packages using `composer install`');
}
dibi::connect([
$dibi = new Dibi\Connection([
'driver' => 'sqlite3',
'database' => 'data/sample.s3db',
]);
$count = dibi::loadFile('compress.zlib://data/sample.dump.sql.gz');
$count = $dibi->loadFile('compress.zlib://data/sample.dump.sql.gz');
echo 'Number of SQL commands:', $count;

View File

@@ -1,13 +1,15 @@
<!DOCTYPE html><link rel="stylesheet" href="data/style.css">
<h1>Query Language & Conditions | dibi</h1>
<h1>Query Language & Conditions | Dibi</h1>
<?php
require __DIR__ . '/../src/loader.php';
if (@!include __DIR__ . '/../vendor/autoload.php') {
die('Install packages using `composer install`');
}
dibi::connect([
$dibi = new Dibi\Connection([
'driver' => 'sqlite3',
'database' => 'data/sample.s3db',
]);
@@ -23,7 +25,7 @@ $bar = 2;
$name = $cond1 ? 'K%' : null;
// if & end
dibi::test('
$dibi->test('
SELECT *
FROM customers
%if', isset($name), 'WHERE name LIKE ?', $name, '%end'
@@ -32,7 +34,7 @@ dibi::test('
// if & else & (optional) end
dibi::test('
$dibi->test('
SELECT *
FROM people
WHERE id > 0
@@ -43,7 +45,7 @@ dibi::test('
// nested condition
dibi::test('
$dibi->test('
SELECT *
FROM customers
WHERE
@@ -55,7 +57,7 @@ dibi::test('
// IF()
dibi::test('UPDATE products SET', [
'price' => ['IF(price_fixed, price, ?)', 123],
$dibi->test('UPDATE products SET', [
'price' => $dibi->expression('IF(price_fixed, price, ?)', 123),
]);
// -> SELECT * FROM customers WHERE LIMIT 10

View File

@@ -1,15 +1,17 @@
<!DOCTYPE html><link rel="stylesheet" href="data/style.css">
<h1>Query Language Basic Examples | dibi</h1>
<h1>Query Language Basic Examples | Dibi</h1>
<?php
require __DIR__ . '/../src/loader.php';
if (@!include __DIR__ . '/../vendor/autoload.php') {
die('Install packages using `composer install`');
}
date_default_timezone_set('Europe/Prague');
dibi::connect([
$dibi = new Dibi\Connection([
'driver' => 'sqlite3',
'database' => 'data/sample.s3db',
]);
@@ -19,7 +21,7 @@ dibi::connect([
$ipMask = '192.168.%';
$timestamp = mktime(0, 0, 0, 10, 13, 1997);
dibi::test('
$dibi->test('
SELECT COUNT(*) as [count]
FROM [comments]
WHERE [ip] LIKE ?', $ipMask, '
@@ -29,7 +31,7 @@ dibi::test('
// dibi detects INSERT or REPLACE command
dibi::test('
$dibi->test('
REPLACE INTO products', [
'title' => 'Super product',
'price' => 318,
@@ -45,12 +47,12 @@ $array = [
'brand' => null,
'created' => new DateTime,
];
dibi::test('INSERT INTO products', $array, $array, $array);
$dibi->test('INSERT INTO products', $array, $array, $array);
// -> INSERT INTO products ([title], [price], [brand], [created]) VALUES ('Super Product', ...) , (...) , (...)
// dibi detects UPDATE command
dibi::test('
$dibi->test('
UPDATE colors SET', [
'color' => 'blue',
'order' => 12,
@@ -61,7 +63,7 @@ dibi::test('
// modifier applied to array
$array = [1, 2, 3];
dibi::test('
$dibi->test('
SELECT *
FROM people
WHERE id IN (?)', $array
@@ -74,7 +76,7 @@ $order = [
'field1' => 'asc',
'field2' => 'desc',
];
dibi::test('
$dibi->test('
SELECT *
FROM people
ORDER BY %by', $order, '
@@ -83,5 +85,5 @@ dibi::test('
// indentifiers and strings syntax mix
dibi::test('UPDATE [table] SET `item` = "5 1/4"" diskette"');
$dibi->test('UPDATE [table] SET `item` = "5 1/4"" diskette"');
// -> UPDATE [table] SET [item] = '5 1/4" diskette'

View File

@@ -13,18 +13,18 @@ date_default_timezone_set('Europe/Prague');
?>
<!DOCTYPE html><link rel="stylesheet" href="data/style.css">
<h1>Result Set Data Types | dibi</h1>
<h1>Result Set Data Types | Dibi</h1>
<?php
dibi::connect([
$dibi = new Dibi\Connection([
'driver' => 'sqlite3',
'database' => 'data/sample.s3db',
]);
// using manual hints
$res = dibi::query('SELECT * FROM [customers]');
$res = $dibi->query('SELECT * FROM [customers]');
$res->setType('customer_id', Type::INTEGER)
->setType('added', Type::DATETIME)
@@ -40,7 +40,7 @@ Tracy\Dumper::dump($res->fetch());
// using auto-detection (works well with MySQL or other strictly typed databases)
$res = dibi::query('SELECT * FROM [customers]');
$res = $dibi->query('SELECT * FROM [customers]');
Tracy\Dumper::dump($res->fetch());
// outputs:

View File

@@ -9,7 +9,7 @@ if (@!include __DIR__ . '/../vendor/autoload.php') {
Tracy\Debugger::enable();
$connection = dibi::connect([
$dibi = new Dibi\Connection([
'driver' => 'sqlite3',
'database' => 'data/sample.s3db',
'profiler' => [
@@ -20,11 +20,11 @@ $connection = dibi::connect([
// add panel to debug bar
$panel = new Dibi\Bridges\Tracy\Panel;
$panel->register($connection);
$panel->register($dibi);
// throws error because SQL is bad
dibi::query('SELECT FROM customers WHERE customer_id < ?', 38);
$dibi->query('SELECT FROM customers WHERE customer_id < ?', 38);
?><!DOCTYPE html><link rel="stylesheet" href="data/style.css">

View File

@@ -9,7 +9,7 @@ if (@!include __DIR__ . '/../vendor/autoload.php') {
Tracy\Debugger::enable();
$connection = dibi::connect([
$dibi = new Dibi\Connection([
'driver' => 'sqlite3',
'database' => 'data/sample.s3db',
'profiler' => [
@@ -20,14 +20,14 @@ $connection = dibi::connect([
// add panel to debug bar
$panel = new Dibi\Bridges\Tracy\Panel;
$panel->register($connection);
$panel->register($dibi);
// query will be logged
dibi::query('SELECT 123');
$dibi->query('SELECT 123');
// result set will be dumped
Tracy\Debugger::barDump(dibi::fetchAll('SELECT * FROM customers WHERE customer_id < ?', 38), '[customers]');
Tracy\Debugger::barDump($dibi->fetchAll('SELECT * FROM customers WHERE customer_id < ?', 38), '[customers]');
?>

View File

@@ -1,16 +1,18 @@
<!DOCTYPE html><link rel="stylesheet" href="data/style.css">
<h1>Using DateTime | dibi</h1>
<h1>Using DateTime | Dibi</h1>
<?php
require __DIR__ . '/../src/loader.php';
if (@!include __DIR__ . '/../vendor/autoload.php') {
die('Install packages using `composer install`');
}
date_default_timezone_set('Europe/Prague');
// CHANGE TO REAL PARAMETERS!
dibi::connect([
$dibi = new Dibi\Connection([
'driver' => 'sqlite3',
'database' => 'data/sample.s3db',
'formatDate' => "'Y-m-d'",
@@ -19,7 +21,7 @@ dibi::connect([
// generate and dump SQL
dibi::test('
$dibi->test('
INSERT INTO [mytable]', [
'id' => 123,
'date' => new DateTime('12.3.2007'),

View File

@@ -9,11 +9,11 @@ Tracy\Debugger::enable();
?>
<!DOCTYPE html><link rel="stylesheet" href="data/style.css">
<h1>Using Extension Methods | dibi</h1>
<h1>Using Extension Methods | Dibi</h1>
<?php
dibi::connect([
$dibi = new Dibi\Connection([
'driver' => 'sqlite3',
'database' => 'data/sample.s3db',
]);
@@ -28,6 +28,6 @@ Dibi\Result::extensionMethod('fetchShuffle', function (Dibi\Result $obj) {
// fetch complete result set shuffled
$res = dibi::query('SELECT * FROM [customers]');
$res = $dibi->query('SELECT * FROM [customers]');
$all = $res->fetchShuffle();
Tracy\Dumper::dump($all);

View File

@@ -1,15 +1,17 @@
<!DOCTYPE html><link rel="stylesheet" href="data/style.css">
<h1>Using Fluent Syntax | dibi</h1>
<h1>Using Fluent Syntax | Dibi</h1>
<?php
require __DIR__ . '/../src/loader.php';
if (@!include __DIR__ . '/../vendor/autoload.php') {
die('Install packages using `composer install`');
}
date_default_timezone_set('Europe/Prague');
dibi::connect([
$dibi = new Dibi\Connection([
'driver' => 'sqlite3',
'database' => 'data/sample.s3db',
]);
@@ -23,7 +25,7 @@ $record = [
];
// SELECT ...
dibi::select('product_id')->as('id')
$dibi->select('product_id')->as('id')
->select('title')
->from('products')
->innerJoin('orders')->using('(product_id)')
@@ -35,35 +37,35 @@ dibi::select('product_id')->as('id')
// SELECT ...
echo dibi::select('title')->as('id')
echo $dibi->select('title')->as('id')
->from('products')
->fetchSingle();
// -> Chair (as result of query: SELECT [title] AS [id] FROM [products])
// INSERT ...
dibi::insert('products', $record)
$dibi->insert('products', $record)
->setFlag('IGNORE')
->test();
// -> INSERT IGNORE INTO [products] ([title], [price], [active]) VALUES ('Super product', 318, 1)
// UPDATE ...
dibi::update('products', $record)
$dibi->update('products', $record)
->where('product_id = ?', $id)
->test();
// -> UPDATE [products] SET [title]='Super product', [price]=318, [active]=1 WHERE product_id = 10
// DELETE ...
dibi::delete('products')
$dibi->delete('products')
->where('product_id = ?', $id)
->test();
// -> DELETE FROM [products] WHERE product_id = 10
// custom commands
dibi::command()
$dibi->command()
->update('products')
->where('product_id = ?', $id)
->set($record)
@@ -71,7 +73,7 @@ dibi::command()
// -> UPDATE [products] SET [title]='Super product', [price]=318, [active]=1 WHERE product_id = 10
dibi::command()
$dibi->command()
->truncate('products')
->test();
// -> TRUNCATE [products]

View File

@@ -1,28 +1,30 @@
<!DOCTYPE html><link rel="stylesheet" href="data/style.css">
<h1>Using Limit & Offset | dibi</h1>
<h1>Using Limit & Offset | Dibi</h1>
<?php
require __DIR__ . '/../src/loader.php';
if (@!include __DIR__ . '/../vendor/autoload.php') {
die('Install packages using `composer install`');
}
dibi::connect([
$dibi = new Dibi\Connection([
'driver' => 'sqlite3',
'database' => 'data/sample.s3db',
]);
// no limit
dibi::test('SELECT * FROM [products]');
$dibi->test('SELECT * FROM [products]');
// -> SELECT * FROM [products]
// with limit = 2
dibi::test('SELECT * FROM [products] %lmt', 2);
$dibi->test('SELECT * FROM [products] %lmt', 2);
// -> SELECT * FROM [products] LIMIT 2
// with limit = 2, offset = 1
dibi::test('SELECT * FROM [products] %lmt %ofs', 2, 1);
$dibi->test('SELECT * FROM [products] %lmt %ofs', 2, 1);
// -> SELECT * FROM [products] LIMIT 2 OFFSET 1

View File

@@ -1,15 +1,17 @@
<!DOCTYPE html><link rel="stylesheet" href="data/style.css">
<h1>Using Logger | dibi</h1>
<h1>Using Logger | Dibi</h1>
<?php
require __DIR__ . '/../src/loader.php';
if (@!include __DIR__ . '/../vendor/autoload.php') {
die('Install packages using `composer install`');
}
date_default_timezone_set('Europe/Prague');
dibi::connect([
$dibi = new Dibi\Connection([
'driver' => 'sqlite3',
'database' => 'data/sample.s3db',
// enable query logging to this file
@@ -21,11 +23,11 @@ dibi::connect([
try {
$res = dibi::query('SELECT * FROM [customers] WHERE [customer_id] = ?', 1);
$res = $dibi->query('SELECT * FROM [customers] WHERE [customer_id] = ?', 1);
$res = dibi::query('SELECT * FROM [customers] WHERE [customer_id] < ?', 5);
$res = $dibi->query('SELECT * FROM [customers] WHERE [customer_id] < ?', 5);
$res = dibi::query('SELECT FROM [customers] WHERE [customer_id] < ?', 38);
$res = $dibi->query('SELECT FROM [customers] WHERE [customer_id] < ?', 38);
} catch (Dibi\Exception $e) {
echo '<p>', get_class($e), ': ', $e->getMessage(), '</p>';
}

View File

@@ -2,14 +2,16 @@
<!DOCTYPE html><link rel="stylesheet" href="data/style.css">
<h1>Using Profiler | dibi</h1>
<h1>Using Profiler | Dibi</h1>
<?php
require __DIR__ . '/../src/loader.php';
if (@!include __DIR__ . '/../vendor/autoload.php') {
die('Install packages using `composer install`');
}
dibi::connect([
$dibi = new Dibi\Connection([
'driver' => 'sqlite3',
'database' => 'data/sample.s3db',
'profiler' => [
@@ -20,7 +22,7 @@ dibi::connect([
// execute some queries...
for ($i = 0; $i < 20; $i++) {
$res = dibi::query('SELECT * FROM [customers] WHERE [customer_id] < ?', $i);
$res = $dibi->query('SELECT * FROM [customers] WHERE [customer_id] < ?', $i);
}
// display output

View File

@@ -1,29 +1,31 @@
<!DOCTYPE html><link rel="stylesheet" href="data/style.css">
<h1>Using Substitutions | dibi</h1>
<h1>Using Substitutions | Dibi</h1>
<?php
require __DIR__ . '/../src/loader.php';
if (@!include __DIR__ . '/../vendor/autoload.php') {
die('Install packages using `composer install`');
}
dibi::connect([
$dibi = new Dibi\Connection([
'driver' => 'sqlite3',
'database' => 'data/sample.s3db',
]);
// create new substitution :blog: ==> wp_
dibi::getSubstitutes()->blog = 'wp_';
$dibi->getSubstitutes()->blog = 'wp_';
dibi::test('SELECT * FROM [:blog:items]');
$dibi->test('SELECT * FROM [:blog:items]');
// -> SELECT * FROM [wp_items]
// create new substitution :: (empty) ==> my_
dibi::getSubstitutes()->{''} = 'my_';
$dibi->getSubstitutes()->{''} = 'my_';
dibi::test("UPDATE ::table SET [text]='Hello World'");
$dibi->test("UPDATE ::table SET [text]='Hello World'");
// -> UPDATE my_table SET [text]='Hello World'
@@ -40,13 +42,13 @@ function substFallBack($expr)
// define callback
dibi::getSubstitutes()->setCallback('substFallBack');
$dibi->getSubstitutes()->setCallback('substFallBack');
// define substitutes as constants
define('SUBST_ACCOUNT', 'eshop_');
define('SUBST_ACTIVE', 7);
dibi::test("
$dibi->test("
UPDATE :account:user
SET name='John Doe', status=:active:
WHERE id=", 7

View File

@@ -1,34 +1,36 @@
<!DOCTYPE html><link rel="stylesheet" href="data/style.css">
<h1>Using Transactions | dibi</h1>
<h1>Using Transactions | Dibi</h1>
<?php
require __DIR__ . '/../src/loader.php';
if (@!include __DIR__ . '/../vendor/autoload.php') {
die('Install packages using `composer install`');
}
dibi::connect([
$dibi = new Dibi\Connection([
'driver' => 'sqlite3',
'database' => 'data/sample.s3db',
]);
echo "<h2>Before</h2>\n";
dibi::query('SELECT * FROM [products]')->dump();
$dibi->query('SELECT * FROM [products]')->dump();
// -> 3 rows
dibi::begin();
dibi::query('INSERT INTO [products]', [
$dibi->begin();
$dibi->query('INSERT INTO [products]', [
'title' => 'Test product',
]);
echo "<h2>After INSERT</h2>\n";
dibi::query('SELECT * FROM [products]')->dump();
$dibi->query('SELECT * FROM [products]')->dump();
dibi::rollback(); // or dibi::commit();
$dibi->rollback(); // or $dibi->commit();
echo "<h2>After rollback</h2>\n";
dibi::query('SELECT * FROM [products]')->dump();
$dibi->query('SELECT * FROM [products]')->dump();
// -> 3 rows again

View File

@@ -1,4 +1,4 @@
[Dibi](https://dibiphp.com) - smart database layer for PHP [![Buy me a coffee](https://files.nette.org/images/coffee1s.png)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=9XXL5ZJHAYQUN)
[Dibi](https://dibiphp.com) - smart database layer for PHP [![Buy me a coffee](https://files.nette.org/images/coffee1s.png)](https://nette.org/make-donation?to=dibi)
=========================================================
[![Downloads this Month](https://img.shields.io/packagist/dm/dibi/dibi.svg)](https://packagist.org/packages/dibi/dibi)
@@ -7,22 +7,30 @@
[![Latest Stable Version](https://poser.pugx.org/dibi/dibi/v/stable)](https://github.com/dg/dibi/releases)
[![License](https://img.shields.io/badge/license-New%20BSD-blue.svg)](https://github.com/dg/dibi/blob/master/license.md)
Introduction
------------
Database access functions in PHP are not standardised. This library
hides the differences between them, and above all, it gives you a very handy interface.
The best way to install Dibi is to use a [Composer](https://getcomposer.org/download):
php composer.phar require dibi/dibi
Or you can download the latest package from https://dibiphp.com. In this
package is also `Dibi.minified`, shrinked single-file version of whole Dibi,
useful when you don't want to modify the library, but just use it.
Dibi requires PHP 5.4.4 or later. It has been tested with PHP 7 too.
If you like Dibi, **[please make a donation now](https://nette.org/make-donation?to=dibi)**. Thank you!
Examples
--------
Installation
------------
The recommended way to install Dibi is via Composer (alternatively you can [download package](https://github.com/dg/dibi/releases)):
```bash
composer require dibi/dibi
```
The Dibi 3.x requires PHP version 5.4.4 and supports PHP up to 7.2.
Usage
-----
Refer to the `examples` directory for examples. Dibi documentation is
available on the [homepage](https://dibiphp.com).
@@ -30,34 +38,34 @@ available on the [homepage](https://dibiphp.com).
Connect to database:
```php
// connect to database (static way)
dibi::connect([
'driver' => 'mysql',
$dibi = new Dibi\Connection([
'driver' => 'mysqli',
'host' => 'localhost',
'username' => 'root',
'password' => '***',
]);
// or object way; in all other examples use $connection-> instead of dibi::
$connection = new DibiConnection($options);
// or static way; in all other examples use dibi:: instead of $dibi->
dibi::connect($options);
```
SELECT, INSERT, UPDATE
```php
dibi::query('SELECT * FROM users WHERE id = ?', $id);
$dibi->query('SELECT * FROM users WHERE id = ?', $id);
$arr = [
'name' => 'John',
'is_admin' => true,
];
dibi::query('INSERT INTO users', $arr);
$dibi->query('INSERT INTO users', $arr);
// INSERT INTO users (`name`, `is_admin`) VALUES ('John', 1)
dibi::query('UPDATE users SET', $arr, 'WHERE `id`=?', $x);
$dibi->query('UPDATE users SET', $arr, 'WHERE `id`=?', $x);
// UPDATE users SET `name`='John', `is_admin`=1 WHERE `id` = 123
dibi::query('UPDATE users SET', [
$dibi->query('UPDATE users SET', [
'title' => array('SHA1(?)', 'tajneheslo'),
]);
// UPDATE users SET 'title' = SHA1('tajneheslo')
@@ -66,7 +74,7 @@ dibi::query('UPDATE users SET', [
Getting results
```php
$result = dibi::query('SELECT * FROM users');
$result = $dibi->query('SELECT * FROM users');
$value = $result->fetchSingle(); // single value
$all = $result->fetchAll(); // all rows
@@ -82,7 +90,7 @@ foreach ($result as $n => $row) {
Modifiers for arrays:
```php
dibi::query('SELECT * FROM users WHERE %and', [
$dibi->query('SELECT * FROM users WHERE %and', [
array('number > ?', 10),
array('number < ?', 100),
]);
@@ -105,7 +113,7 @@ dibi::query('SELECT * FROM users WHERE %and', [
Modifiers for LIKE
```php
dibi::query("SELECT * FROM table WHERE name LIKE %like~", $query);
$dibi->query("SELECT * FROM table WHERE name LIKE %like~", $query);
```
<table>
@@ -117,7 +125,7 @@ dibi::query("SELECT * FROM table WHERE name LIKE %like~", $query);
DateTime:
```php
dibi::query('UPDATE users SET', [
$dibi->query('UPDATE users SET', [
'time' => new DateTime,
]);
// UPDATE users SET ('2008-01-01 01:08:10')

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -50,7 +50,7 @@ class DibiExtension22 extends Nette\DI\CompilerExtension
}
$connection = $container->addDefinition($this->prefix('connection'))
->setClass('Dibi\Connection', [$config])
->setFactory('Dibi\Connection', [$config])
->setAutowired(isset($config['autowired']) ? $config['autowired'] : true);
if (class_exists('Tracy\Debugger')) {
@@ -61,7 +61,7 @@ class DibiExtension22 extends Nette\DI\CompilerExtension
}
if ($useProfiler) {
$panel = $container->addDefinition($this->prefix('panel'))
->setClass('Dibi\Bridges\Tracy\Panel', [
->setFactory('Dibi\Bridges\Tracy\Panel', [
isset($config['explain']) ? $config['explain'] : true,
isset($config['filter']) && $config['filter'] === false ? Dibi\Event::ALL : Dibi\Event::QUERY,
]);

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -23,7 +23,7 @@ class Panel implements Tracy\IBarPanel
/** @var int maximum SQL length */
public static $maxLength = 1000;
/** @var bool explain queries? */
/** @var bool|string explain queries? */
public $explain;
/** @var int */
@@ -110,10 +110,10 @@ class Panel implements Tracy\IBarPanel
$connection = $event->connection;
$explain = null; // EXPLAIN is called here to work SELECT FOUND_ROWS()
if ($this->explain && $event->type === Event::SELECT) {
$backup = [$connection->onEvent, \dibi::$numOfQueries, \dibi::$totalTime];
$connection->onEvent = null;
$cmd = is_string($this->explain) ? $this->explain : ($connection->getConfig('driver') === 'oracle' ? 'EXPLAIN PLAN FOR' : 'EXPLAIN');
try {
$backup = [$connection->onEvent, \dibi::$numOfQueries, \dibi::$totalTime];
$connection->onEvent = null;
$cmd = is_string($this->explain) ? $this->explain : ($connection->getConfig('driver') === 'oracle' ? 'EXPLAIN PLAN FOR' : 'EXPLAIN');
$explain = @Helpers::dump($connection->nativeQuery("$cmd $event->sql"), true);
} catch (Dibi\Exception $e) {
}

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -11,7 +11,7 @@ use Traversable;
/**
* dibi connection.
* Dibi connection.
*
* @property-read int $affectedRows
* @property-read int $insertId
@@ -29,7 +29,7 @@ class Connection
/** @var Driver */
private $driver;
/** @var Translator */
/** @var Translator|null */
private $translator;
/** @var bool Is connected? */
@@ -131,8 +131,9 @@ class Connection
*/
public function __destruct()
{
// disconnects and rolls back transaction - do not rely on auto-disconnect and rollback!
$this->connected && $this->driver->getResource() && $this->disconnect();
if ($this->connected && $this->driver->getResource()) {
$this->disconnect();
}
}
@@ -146,10 +147,14 @@ class Connection
try {
$this->driver->connect($this->config);
$this->connected = true;
$event && $this->onEvent($event->done());
if ($event) {
$this->onEvent($event->done());
}
} catch (Exception $e) {
$event && $this->onEvent($event->done($e));
if ($event) {
$this->onEvent($event->done($e));
}
throw $e;
}
}
@@ -211,7 +216,9 @@ class Connection
*/
final public function getDriver()
{
$this->connected || $this->connect();
if (!$this->connected) {
$this->connect();
}
return $this->driver;
}
@@ -285,7 +292,9 @@ class Connection
*/
protected function translateArgs($args)
{
$this->connected || $this->connect();
if (!$this->connected) {
$this->connect();
}
if (!$this->translator) {
$this->translator = new Translator($this);
}
@@ -302,7 +311,9 @@ class Connection
*/
final public function nativeQuery($sql)
{
$this->connected || $this->connect();
if (!$this->connected) {
$this->connect();
}
\dibi::$sql = $sql;
$event = $this->onEvent ? new Event($this, Event::QUERY, $sql) : null;
@@ -310,7 +321,9 @@ class Connection
$res = $this->driver->query($sql);
} catch (Exception $e) {
$event && $this->onEvent($event->done($e));
if ($event) {
$this->onEvent($event->done($e));
}
throw $e;
}
@@ -320,7 +333,9 @@ class Connection
$res = $this->driver->getAffectedRows();
}
$event && $this->onEvent($event->done($res));
if ($event) {
$this->onEvent($event->done($res));
}
return $res;
}
@@ -332,7 +347,9 @@ class Connection
*/
public function getAffectedRows()
{
$this->connected || $this->connect();
if (!$this->connected) {
$this->connect();
}
$rows = $this->driver->getAffectedRows();
if (!is_int($rows) || $rows < 0) {
throw new Exception('Cannot retrieve number of affected rows.');
@@ -359,7 +376,9 @@ class Connection
*/
public function getInsertId($sequence = null)
{
$this->connected || $this->connect();
if (!$this->connected) {
$this->connect();
}
$id = $this->driver->getInsertId($sequence);
if ($id < 1) {
throw new Exception('Cannot retrieve last generated ID.');
@@ -385,14 +404,20 @@ class Connection
*/
public function begin($savepoint = null)
{
$this->connected || $this->connect();
if (!$this->connected) {
$this->connect();
}
$event = $this->onEvent ? new Event($this, Event::BEGIN, $savepoint) : null;
try {
$this->driver->begin($savepoint);
$event && $this->onEvent($event->done());
if ($event) {
$this->onEvent($event->done());
}
} catch (Exception $e) {
$event && $this->onEvent($event->done($e));
if ($event) {
$this->onEvent($event->done($e));
}
throw $e;
}
}
@@ -405,14 +430,20 @@ class Connection
*/
public function commit($savepoint = null)
{
$this->connected || $this->connect();
if (!$this->connected) {
$this->connect();
}
$event = $this->onEvent ? new Event($this, Event::COMMIT, $savepoint) : null;
try {
$this->driver->commit($savepoint);
$event && $this->onEvent($event->done());
if ($event) {
$this->onEvent($event->done());
}
} catch (Exception $e) {
$event && $this->onEvent($event->done($e));
if ($event) {
$this->onEvent($event->done($e));
}
throw $e;
}
}
@@ -425,14 +456,20 @@ class Connection
*/
public function rollback($savepoint = null)
{
$this->connected || $this->connect();
if (!$this->connected) {
$this->connect();
}
$event = $this->onEvent ? new Event($this, Event::ROLLBACK, $savepoint) : null;
try {
$this->driver->rollback($savepoint);
$event && $this->onEvent($event->done());
if ($event) {
$this->onEvent($event->done());
}
} catch (Exception $e) {
$event && $this->onEvent($event->done($e));
if ($event) {
$this->onEvent($event->done($e));
}
throw $e;
}
}
@@ -559,7 +596,7 @@ class Connection
/**
* Executes SQL query and fetch results - shortcut for query() & fetchAll().
* @param array|mixed one or more arguments
* @return Row[]
* @return Row[]|array[]
* @throws Exception
*/
public function fetchAll($args)
@@ -625,7 +662,9 @@ class Connection
*/
public function getDatabaseInfo()
{
$this->connected || $this->connect();
if (!$this->connected) {
$this->connect();
}
return new Reflection\Database($this->driver->getReflector(), isset($this->config['database']) ? $this->config['database'] : null);
}

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -9,7 +9,7 @@ namespace Dibi;
/**
* Default implementation of IDataSource for dibi.
* Default implementation of IDataSource.
*/
class DataSource implements IDataSource
{
@@ -21,13 +21,13 @@ class DataSource implements IDataSource
/** @var string */
private $sql;
/** @var Result */
/** @var Result|null */
private $result;
/** @var int */
/** @var int|null */
private $count;
/** @var int */
/** @var int|null */
private $totalCount;
/** @var array */
@@ -131,7 +131,6 @@ class DataSource implements IDataSource
/**
* Returns the dibi connection.
* @return Connection
*/
final public function getConnection()

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -22,7 +22,7 @@ class DateTime extends \DateTime
{
if (is_numeric($time)) {
parent::__construct('@' . $time);
$this->setTimeZone($timezone ? $timezone : new \DateTimeZone(date_default_timezone_get()));
$this->setTimeZone($timezone ?: new \DateTimeZone(date_default_timezone_get()));
} elseif ($timezone === null) {
parent::__construct($time);
} else {

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -11,7 +11,7 @@ use Dibi;
/**
* The dibi driver for Firebird/InterBase database.
* The driver for Firebird/InterBase database.
*
* Driver options:
* - database => the path to database file (server:/path/database.fdb)
@@ -20,7 +20,6 @@ use Dibi;
* - charset => character encoding to set
* - buffers (int) => buffers is the number of database buffers to allocate for the server-side cache. If 0 or omitted, server chooses its own default.
* - resource (resource) => existing connection resource
* - lazy, profiler, result, substitutes, ... => see Dibi\Connection options
*/
class FirebirdDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
{
@@ -313,7 +312,7 @@ class FirebirdDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) {
$value = new Dibi\DateTime($value);
}
return $value->format("'Y-m-d H:i:s.u'");
return "'" . substr($value->format('Y-m-d H:i:s.u'), 0, -2) . "'";
}
@@ -375,7 +374,9 @@ class FirebirdDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
*/
public function __destruct()
{
$this->autoFree && $this->getResultResource() && $this->free();
if ($this->autoFree && $this->getResultResource()) {
$this->free();
}
}

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -11,7 +11,7 @@ use Dibi;
/**
* The dibi driver for MS SQL database.
* The driver for MS SQL database.
*
* Driver options:
* - host => the MS SQL server host name. It can also include a port number (hostname:port)
@@ -263,7 +263,7 @@ class MsSqlDriver implements Dibi\Driver, Dibi\ResultDriver
if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) {
$value = new Dibi\DateTime($value);
}
return $value->format("'Y-m-d H:i:s.u'");
return 'CONVERT(DATETIME2(7), ' . $value->format("'Y-m-d H:i:s.u'") . ')';
}
@@ -329,7 +329,9 @@ class MsSqlDriver implements Dibi\Driver, Dibi\ResultDriver
*/
public function __destruct()
{
$this->autoFree && $this->getResultResource() && $this->free();
if ($this->autoFree && $this->getResultResource()) {
$this->free();
}
}

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -11,7 +11,7 @@ use Dibi;
/**
* The dibi reflector for MS SQL databases.
* The reflector for MS SQL databases.
* @internal
*/
class MsSqlReflector implements Dibi\Reflector
@@ -96,10 +96,7 @@ class MsSqlReflector implements Dibi\Reflector
");
$columns = [];
while ($row = $res->fetch(true)) {
$size = false;
$type = strtoupper($row['DATA_TYPE']);
$size_cols = [
static $size_cols = [
'DATETIME' => 'DATETIME_PRECISION',
'DECIMAL' => 'NUMERIC_PRECISION',
'CHAR' => 'CHARACTER_MAXIMUM_LENGTH',
@@ -108,17 +105,13 @@ class MsSqlReflector implements Dibi\Reflector
'VARCHAR' => 'CHARACTER_OCTET_LENGTH',
];
if (isset($size_cols[$type])) {
if ($size_cols[$type]) {
$size = $row[$size_cols[$type]];
}
}
$type = strtoupper($row['DATA_TYPE']);
$columns[] = [
'name' => $row['COLUMN_NAME'],
'table' => $table,
'nativetype' => $type,
'size' => $size,
'size' => isset($size_cols[$type], $row[$size_cols[$type]]) ? $row[$size_cols[$type]] : null,
'unsigned' => null,
'nullable' => $row['IS_NULLABLE'] === 'YES',
'default' => $row['COLUMN_DEFAULT'],

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -11,7 +11,7 @@ use Dibi;
/**
* The dibi driver for MySQL database.
* The driver for MySQL database.
*
* Driver options:
* - host => the MySQL server host name
@@ -33,7 +33,9 @@ class MySqlDriver implements Dibi\Driver, Dibi\ResultDriver
use Dibi\Strict;
const ERROR_ACCESS_DENIED = 1045;
const ERROR_DUPLICATE_ENTRY = 1062;
const ERROR_DATA_TRUNCATED = 1265;
/** @var resource|null */

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -11,7 +11,7 @@ use Dibi;
/**
* The dibi reflector for MySQL databases.
* The reflector for MySQL databases.
* @internal
*/
class MySqlReflector implements Dibi\Reflector

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -11,7 +11,7 @@ use Dibi;
/**
* The dibi driver for MySQL database via improved extension.
* The driver for MySQL database.
*
* Driver options:
* - host => the MySQL server host name
@@ -27,14 +27,15 @@ use Dibi;
* - unbuffered (bool) => sends query without fetching and buffering the result rows automatically?
* - sqlmode => see http://dev.mysql.com/doc/refman/5.0/en/server-sql-mode.html
* - resource (mysqli) => existing connection resource
* - lazy, profiler, result, substitutes, ... => see Dibi\Connection options
*/
class MySqliDriver implements Dibi\Driver, Dibi\ResultDriver
{
use Dibi\Strict;
const ERROR_ACCESS_DENIED = 1045;
const ERROR_DUPLICATE_ENTRY = 1062;
const ERROR_DATA_TRUNCATED = 1265;
/** @var \mysqli|null */
@@ -148,7 +149,7 @@ class MySqliDriver implements Dibi\Driver, Dibi\ResultDriver
$res = @mysqli_query($this->connection, $sql, $this->buffered ? MYSQLI_STORE_RESULT : MYSQLI_USE_RESULT); // intentionally @
if ($code = mysqli_errno($this->connection)) {
throw self::createException(mysqli_error($this->connection), $code, $sql);
throw static::createException(mysqli_error($this->connection), $code, $sql);
} elseif (is_object($res)) {
return $this->createResultDriver($res);
@@ -254,7 +255,7 @@ class MySqliDriver implements Dibi\Driver, Dibi\ResultDriver
/**
* Returns the connection resource.
* @return \mysqli
* @return \mysqli|null
*/
public function getResource()
{
@@ -415,7 +416,9 @@ class MySqliDriver implements Dibi\Driver, Dibi\ResultDriver
*/
public function __destruct()
{
$this->autoFree && $this->getResultResource() && @$this->free();
if ($this->autoFree && $this->getResultResource()) {
@$this->free();
}
}

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -11,7 +11,7 @@ use Dibi;
/**
* The dibi driver interacting with databases via ODBC connections.
* The driver interacting with databases via ODBC connections.
*
* Driver options:
* - dsn => driver specific DSN
@@ -19,7 +19,7 @@ use Dibi;
* - password (or pass)
* - persistent (bool) => try to find a persistent link?
* - resource (resource) => existing connection resource
* - lazy, profiler, result, substitutes, ... => see Dibi\Connection options
* - microseconds (bool) => use microseconds in datetime format?
*/
class OdbcDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
{
@@ -34,6 +34,9 @@ class OdbcDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
/** @var bool */
private $autoFree = true;
/** @var bool */
private $microseconds = true;
/** @var int|false Affected rows */
private $affectedRows = false;
@@ -79,6 +82,10 @@ class OdbcDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
if (!is_resource($this->connection)) {
throw new Dibi\DriverException(odbc_errormsg() . ' ' . odbc_error());
}
if (isset($config['microseconds'])) {
$this->microseconds = (bool) $config['microseconds'];
}
}
@@ -287,7 +294,7 @@ class OdbcDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) {
$value = new Dibi\DateTime($value);
}
return $value->format('#m/d/Y H:i:s.u#');
return $value->format($this->microseconds ? '#m/d/Y H:i:s.u#' : '#m/d/Y H:i:s#');
}
@@ -353,7 +360,9 @@ class OdbcDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
*/
public function __destruct()
{
$this->autoFree && $this->getResultResource() && $this->free();
if ($this->autoFree && $this->getResultResource()) {
$this->free();
}
}

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -11,7 +11,7 @@ use Dibi;
/**
* The dibi driver for Oracle database.
* The driver for Oracle database.
*
* Driver options:
* - database => the name of the local Oracle instance or the name of the entry in tnsnames.ora
@@ -22,7 +22,6 @@ use Dibi;
* - nativeDate => use native date format (defaults to false)
* - resource (resource) => existing connection resource
* - persistent => Creates persistent connections with oci_pconnect instead of oci_new_connect
* - lazy, profiler, result, substitutes, ... => see Dibi\Connection options
*/
class OracleDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
{
@@ -42,6 +41,7 @@ class OracleDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
/** @var string Date and datetime format */
private $fmtDate;
private $fmtDateTime;
/** @var int|false Number of affected rows */
@@ -119,7 +119,7 @@ class OracleDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
@oci_execute($res, $this->autocommit ? OCI_COMMIT_ON_SUCCESS : OCI_DEFAULT);
$err = oci_error($res);
if ($err) {
throw self::createException($err['message'], $err['code'], $sql);
throw static::createException($err['message'], $err['code'], $sql);
} elseif (is_resource($res)) {
$this->affectedRows = oci_num_rows($res);
@@ -391,7 +391,9 @@ class OracleDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
*/
public function __destruct()
{
$this->autoFree && $this->getResultResource() && $this->free();
if ($this->autoFree && $this->getResultResource()) {
$this->free();
}
}

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -12,7 +12,7 @@ use PDO;
/**
* The dibi driver for PDO.
* The driver for PDO.
*
* Driver options:
* - dsn => driver specific DSN
@@ -21,13 +21,12 @@ use PDO;
* - options (array) => driver specific options {@see PDO::__construct}
* - resource (PDO) => existing connection
* - version
* - lazy, profiler, result, substitutes, ... => see Dibi\Connection options
*/
class PdoDriver implements Dibi\Driver, Dibi\ResultDriver
{
use Dibi\Strict;
/** @var PDO Connection resource */
/** @var PDO|null Connection resource */
private $connection;
/** @var \PDOStatement|null Resultset resource */
@@ -79,6 +78,10 @@ class PdoDriver implements Dibi\Driver, Dibi\ResultDriver
}
}
if ($this->connection->getAttribute(PDO::ATTR_ERRMODE) !== PDO::ERRMODE_SILENT) {
throw new Dibi\DriverException('PDO connection in exception or warning error mode is not supported.');
}
$this->driverName = $this->connection->getAttribute(PDO::ATTR_DRIVER_NAME);
$this->serverVersion = isset($config['version'])
? $config['version']
@@ -104,23 +107,14 @@ class PdoDriver implements Dibi\Driver, Dibi\ResultDriver
*/
public function query($sql)
{
// must detect if SQL returns result set or num of affected rows
$cmd = strtoupper(substr(ltrim($sql), 0, 6));
static $list = ['UPDATE' => 1, 'DELETE' => 1, 'INSERT' => 1, 'REPLAC' => 1];
$this->affectedRows = false;
if (isset($list[$cmd])) {
$this->affectedRows = $this->connection->exec($sql);
if ($this->affectedRows !== false) {
return null;
}
} else {
$res = $this->connection->query($sql);
if ($res) {
return $this->createResultDriver($res);
}
$res = $this->connection->query($sql);
if ($res) {
$this->affectedRows = $res->rowCount();
return $res->columnCount() ? $this->createResultDriver($res) : null;
}
$this->affectedRows = false;
list($sqlState, $code, $message) = $this->connection->errorInfo();
$message = "SQLSTATE[$sqlState]: $message";
switch ($this->driverName) {
@@ -158,7 +152,7 @@ class PdoDriver implements Dibi\Driver, Dibi\ResultDriver
*/
public function getInsertId($sequence)
{
return $this->connection->lastInsertId();
return $this->connection->lastInsertId($sequence);
}
@@ -209,7 +203,7 @@ class PdoDriver implements Dibi\Driver, Dibi\ResultDriver
/**
* Returns the connection resource.
* @return PDO
* @return PDO|null
*/
public function getResource()
{
@@ -348,7 +342,15 @@ class PdoDriver implements Dibi\Driver, Dibi\ResultDriver
if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) {
$value = new Dibi\DateTime($value);
}
return $value->format($this->driverName === 'odbc' ? '#m/d/Y H:i:s.u#' : "'Y-m-d H:i:s.u'");
switch ($this->driverName) {
case 'odbc':
return $value->format('#m/d/Y H:i:s.u#');
case 'mssql':
case 'sqlsrv':
return 'CONVERT(DATETIME2(7), ' . $value->format("'Y-m-d H:i:s.u'") . ')';
default:
return $value->format("'Y-m-d H:i:s.u'");
}
}

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -11,7 +11,7 @@ use Dibi;
/**
* The dibi driver for PostgreSQL database.
* The driver for PostgreSQL database.
*
* Driver options:
* - host, hostaddr, port, dbname, user, password, connect_timeout, options, sslmode, service => see PostgreSQL API
@@ -20,7 +20,6 @@ use Dibi;
* - charset => character encoding to set (default is utf8)
* - persistent (bool) => try to find a persistent link?
* - resource (resource) => existing connection resource
* - lazy, profiler, result, substitutes, ... => see Dibi\Connection options
*/
class PostgreDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
{
@@ -96,7 +95,7 @@ class PostgreDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
pg_set_error_verbosity($this->connection, PGSQL_ERRORS_VERBOSE);
if (isset($config['charset']) && pg_set_client_encoding($this->connection, $config['charset'])) {
throw self::createException(pg_last_error($this->connection));
throw static::createException(pg_last_error($this->connection));
}
if (isset($config['schema'])) {
@@ -137,7 +136,7 @@ class PostgreDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
$res = @pg_query($this->connection, $sql); // intentionally @
if ($res === false) {
throw self::createException(pg_last_error($this->connection), null, $sql);
throw static::createException(pg_last_error($this->connection), null, $sql);
} elseif (is_resource($res)) {
$this->affectedRows = pg_affected_rows($res);
@@ -429,7 +428,9 @@ class PostgreDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
*/
public function __destruct()
{
$this->autoFree && $this->getResultResource() && $this->free();
if ($this->autoFree && $this->getResultResource()) {
$this->free();
}
}
@@ -547,7 +548,7 @@ class PostgreDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
$res = $this->query($query);
$tables = pg_fetch_all($res->resultSet);
return $tables ? $tables : [];
return $tables ?: [];
}

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -12,7 +12,7 @@ use SQLite3;
/**
* The dibi driver for SQLite3 database.
* The driver for SQLite3 database.
*
* Driver options:
* - database (or file) => the filename of the SQLite3 database
@@ -21,7 +21,6 @@ use SQLite3;
* - dbcharset => database character encoding (will be converted to 'charset')
* - charset => character encoding to set (default is UTF-8)
* - resource (SQLite3) => existing connection resource
* - lazy, profiler, result, substitutes, ... => see Dibi\Connection options
*/
class Sqlite3Driver implements Dibi\Driver, Dibi\ResultDriver
{
@@ -36,12 +35,15 @@ class Sqlite3Driver implements Dibi\Driver, Dibi\ResultDriver
/** @var bool */
private $autoFree = true;
/** @var string Date and datetime format */
/** @var string Date format */
private $fmtDate;
/** @var string Datetime format */
private $fmtDateTime;
/** @var string character encoding */
private $dbcharset;
private $charset;
@@ -115,7 +117,7 @@ class Sqlite3Driver implements Dibi\Driver, Dibi\ResultDriver
$res = @$this->connection->query($sql); // intentionally @
if ($code = $this->connection->lastErrorCode()) {
throw self::createException($this->connection->lastErrorMsg(), $code, $sql);
throw static::createException($this->connection->lastErrorMsg(), $code, $sql);
} elseif ($res instanceof \SQLite3Result && $res->numColumns()) {
return $this->createResultDriver($res);
@@ -212,7 +214,7 @@ class Sqlite3Driver implements Dibi\Driver, Dibi\ResultDriver
/**
* Returns the connection resource.
* @return SQLite3
* @return SQLite3|null
*/
public function getResource()
{
@@ -373,7 +375,9 @@ class Sqlite3Driver implements Dibi\Driver, Dibi\ResultDriver
*/
public function __destruct()
{
$this->autoFree && $this->resultSet && @$this->free();
if ($this->autoFree && $this->getResultResource()) {
@$this->free();
}
}
@@ -397,15 +401,12 @@ class Sqlite3Driver implements Dibi\Driver, Dibi\ResultDriver
{
$row = $this->resultSet->fetchArray($assoc ? SQLITE3_ASSOC : SQLITE3_NUM);
$charset = $this->charset === null ? null : $this->charset . '//TRANSLIT';
if ($row && ($assoc || $charset)) {
$tmp = [];
if ($row && $charset) {
foreach ($row as $k => $v) {
if ($charset !== null && is_string($v)) {
$v = iconv($this->dbcharset, $charset, $v);
if (is_string($v)) {
$row[$k] = iconv($this->dbcharset, $charset, $v);
}
$tmp[str_replace(['[', ']'], '', $k)] = $v;
}
return $tmp;
}
return $row;
}
@@ -444,11 +445,12 @@ class Sqlite3Driver implements Dibi\Driver, Dibi\ResultDriver
$columns = [];
static $types = [SQLITE3_INTEGER => 'int', SQLITE3_FLOAT => 'float', SQLITE3_TEXT => 'text', SQLITE3_BLOB => 'blob', SQLITE3_NULL => 'null'];
for ($i = 0; $i < $count; $i++) {
$type = $this->resultSet->columnType($i); // buggy in PHP 7.4.4 & 7.3.16, bug 79414
$columns[] = [
'name' => $this->resultSet->columnName($i),
'table' => null,
'fullname' => $this->resultSet->columnName($i),
'nativetype' => $types[$this->resultSet->columnType($i)],
'nativetype' => $type ? $types[$type] : null,
];
}
return $columns;

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -11,7 +11,7 @@ use Dibi;
/**
* The dibi reflector for SQLite database.
* The reflector for SQLite database.
* @internal
*/
class SqliteReflector implements Dibi\Reflector

View File

@@ -1,19 +1,18 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
namespace Dibi\Drivers;
use Dibi;
use Dibi\Connection;
use Dibi\Helpers;
/**
* The dibi driver for Microsoft SQL Server and SQL Azure databases.
* The driver for Microsoft SQL Server and SQL Azure databases.
*
* Driver options:
* - host => the MS SQL server host name. It can also include a port number (hostname:port)
@@ -23,7 +22,6 @@ use Dibi\Helpers;
* - options (array) => connection options {@link https://msdn.microsoft.com/en-us/library/cc296161(SQL.90).aspx}
* - charset => character encoding to set (default is UTF-8)
* - resource (resource) => existing connection resource
* - lazy, profiler, result, substitutes, ... => see Dibi\Connection options
*/
class SqlsrvDriver implements Dibi\Driver, Dibi\ResultDriver
{
@@ -287,7 +285,7 @@ class SqlsrvDriver implements Dibi\Driver, Dibi\ResultDriver
if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) {
$value = new Dibi\DateTime($value);
}
return $value->format("'Y-m-d H:i:s.u'");
return 'CONVERT(DATETIME2(7), ' . $value->format("'Y-m-d H:i:s.u'") . ')';
}
@@ -362,7 +360,9 @@ class SqlsrvDriver implements Dibi\Driver, Dibi\ResultDriver
*/
public function __destruct()
{
$this->autoFree && $this->getResultResource() && $this->free();
if ($this->autoFree && $this->getResultResource()) {
$this->free();
}
}

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -11,7 +11,7 @@ use Dibi;
/**
* The dibi reflector for Microsoft SQL Server and SQL Azure databases.
* The reflector for Microsoft SQL Server and SQL Azure databases.
* @internal
*/
class SqlsrvReflector implements Dibi\Reflector

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -43,10 +43,10 @@ class Event
/** @var float */
public $time;
/** @var int */
/** @var int|null */
public $count;
/** @var array */
/** @var array|null */
public $source;
@@ -74,12 +74,15 @@ class Event
}
}
\dibi::$elapsedTime = false;
\dibi::$elapsedTime = null;
\dibi::$numOfQueries++;
\dibi::$sql = $sql;
}
/**
* @param Result|DriverException|null
*/
public function done($result = null)
{
$this->result = $result;

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -9,11 +9,11 @@ namespace Dibi;
/**
* dibi SQL builder via fluent interfaces. EXPERIMENTAL!
* SQL builder via fluent interfaces.
*
* @method Fluent select(...$field)
* @method Fluent distinct()
* @method Fluent from($table)
* @method Fluent from($table, ...$args = null)
* @method Fluent where(...$cond)
* @method Fluent groupBy(...$field)
* @method Fluent having(...$cond)
@@ -86,7 +86,7 @@ class Fluent implements IDataSource
/** @var array */
private $setups = [];
/** @var string */
/** @var string|null */
private $command;
/** @var array */
@@ -95,7 +95,7 @@ class Fluent implements IDataSource
/** @var array */
private $flags = [];
/** @var array */
/** @var array|null */
private $cursor;
/** @var HashMap normalized clauses */
@@ -272,7 +272,6 @@ class Fluent implements IDataSource
/**
* Returns the dibi connection.
* @return Connection
*/
final public function getConnection()

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -14,6 +14,7 @@ namespace Dibi;
*/
abstract class HashMapBase
{
/** @var callable */
private $callback;
@@ -38,14 +39,13 @@ abstract class HashMapBase
/**
* Lazy cached storage.
*
* @internal
*/
final class HashMap extends HashMapBase
{
public function __set($nm, $val)
{
if ($nm == '') {
if ($nm === '') {
$nm = "\xFF";
}
$this->$nm = $val;
@@ -54,7 +54,7 @@ final class HashMap extends HashMapBase
public function __get($nm)
{
if ($nm == '') {
if ($nm === '') {
$nm = "\xFF";
return isset($this->$nm) ? $this->$nm : $this->$nm = call_user_func($this->getCallback(), '');
} else {

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -12,7 +12,7 @@ class Helpers
{
use Strict;
/** @var array */
/** @var HashMap */
private static $types;

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -11,7 +11,7 @@ use Dibi;
/**
* dibi file logger.
* Dibi file logger.
*/
class FileLogger
{

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -11,7 +11,7 @@ use Dibi;
/**
* dibi FirePHP logger.
* FirePHP logger.
*/
class FirePhpLogger
{
@@ -29,7 +29,7 @@ class FirePhpLogger
/** @var int */
public $filter;
/** @var int Elapsed time for all queries */
/** @var float Elapsed time for all queries */
public $totalTime = 0;
/** @var int Number of all queries */

View File

@@ -1,14 +1,13 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
namespace Dibi\Reflection;
use Dibi;
use Dibi\Type;
/**

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -24,10 +24,10 @@ class Database
/** @var Dibi\Reflector */
private $reflector;
/** @var string */
/** @var string|null */
private $name;
/** @var array */
/** @var Table[]|null */
private $tables;
@@ -39,7 +39,7 @@ class Database
/**
* @return string
* @return string|null
*/
public function getName()
{

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -23,10 +23,10 @@ class Result
/** @var Dibi\ResultDriver */
private $driver;
/** @var array */
/** @var Column[]|null */
private $columns;
/** @var array */
/** @var string[]|null */
private $names;

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -34,16 +34,16 @@ class Table
/** @var bool */
private $view;
/** @var array */
/** @var Column[]|null */
private $columns;
/** @var array */
/** @var ForeignKey[]|null */
private $foreignKeys;
/** @var array */
/** @var Index[]|null */
private $indexes;
/** @var Index */
/** @var Index|null */
private $primaryKey;

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -9,20 +9,7 @@ namespace Dibi;
/**
* dibi result set.
*
* <code>
* $result = dibi::query('SELECT * FROM [table]');
*
* $row = $result->fetch();
* $value = $result->fetchSingle();
* $table = $result->fetchAll();
* $pairs = $result->fetchPairs();
* $assoc = $result->fetchAssoc('col1');
* $assoc = $result->fetchAssoc('col1[]col2->col3');
*
* unset($result);
* </code>
* Query result.
*
* @property-read int $rowCount
*/
@@ -42,10 +29,10 @@ class Result implements IDataSource
/** @var bool Already fetched? Used for allowance for first seek(0) */
private $fetched = false;
/** @var string returned object class */
/** @var string|null returned object class */
private $rowClass = 'Dibi\Row';
/** @var callable returned object factory*/
/** @var callable|null returned object factory */
private $rowFactory;
/** @var array format */
@@ -147,6 +134,16 @@ class Result implements IDataSource
}
/**
* Returns the number of columns in a result set.
* @return int
*/
final public function getColumnCount()
{
return count($this->types);
}
/********************* fetching rows ****************d*g**/
@@ -225,7 +222,7 @@ class Result implements IDataSource
* Fetches all records from table.
* @param int offset
* @param int limit
* @return Row[]
* @return Row[]|array[]
*/
final public function fetchAll($offset = null, $limit = null)
{
@@ -501,8 +498,11 @@ class Result implements IDataSource
} elseif ($type === Type::FLOAT) {
$value = ltrim((string) $value, '0');
$p = strpos($value, '.');
if ($p !== false) {
$e = strpos($value, 'e');
if ($p !== false && $e === false) {
$value = rtrim(rtrim($value, '0'), '.');
} elseif ($p !== false && $e !== false) {
$value = rtrim($value, '.');
}
if ($value === '' || $value[0] === '.') {
$value = '0' . $value;
@@ -529,6 +529,9 @@ class Result implements IDataSource
} elseif ($type === Type::BINARY) {
$row[$key] = $this->getResultDriver()->unescapeBinary($value);
} else {
$row[$key] = $value;
}
}
}

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -10,15 +10,6 @@ namespace Dibi;
/**
* External result set iterator.
*
* This can be returned by Result::getIterator() method or using foreach
* <code>
* $result = dibi::query('SELECT * FROM table');
* foreach ($result as $row) {
* print_r($row);
* }
* unset($result);
* </code>
*/
class ResultIterator implements \Iterator, \Countable
{
@@ -31,7 +22,7 @@ class ResultIterator implements \Iterator, \Countable
private $row;
/** @var int */
private $pointer;
private $pointer = 0;
/**

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -31,7 +31,7 @@ class Row implements \ArrayAccess, \IteratorAggregate, \Countable
* Converts value to DateTime object.
* @param string key
* @param string format
* @return \DateTime
* @return DateTime|string|null
*/
public function asDateTime($key, $format = null)
{

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -9,7 +9,7 @@ namespace Dibi;
/**
* dibi SQL translator.
* SQL translator.
*/
final class Translator
{
@@ -39,10 +39,10 @@ final class Translator
/** @var int */
private $ifLevelStart = 0;
/** @var int */
/** @var int|null */
private $limit;
/** @var int */
/** @var int|null */
private $offset;
/** @var HashMap */
@@ -70,6 +70,7 @@ final class Translator
$args = array_values($args[0]);
}
$this->args = $args;
$this->errors = [];
$commandIns = null;
$lastArr = null;
@@ -315,7 +316,11 @@ final class Translator
if ($modifier) {
if ($value !== null && !is_scalar($value)) { // array is already processed
if ($value instanceof Literal && ($modifier === 'sql' || $modifier === 'SQL')) {
$modifier = 'SQL';
return (string) $value;
} elseif ($value instanceof Expression && $modifier === 'ex') {
return call_user_func_array([$this->connection, 'translate'], $value->getValues());
} elseif (($value instanceof \DateTime || $value instanceof \DateTimeInterface) && ($modifier === 'd' || $modifier === 't' || $modifier === 'dt')) {
// continue
} else {

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -9,8 +9,7 @@ use Dibi\Type;
/**
* This class is static container class for creating DB objects and
* store connections info.
* Static container class for Dibi connections.
*/
class dibi
{
@@ -22,8 +21,8 @@ class dibi
/** version */
const
VERSION = '3.1.0',
REVISION = 'released on 2017-09-25';
VERSION = '3.2.4',
REVISION = 'released on 2020-03-26';
/** sorting order */
const
@@ -49,13 +48,13 @@ class dibi
FIELD_DATETIME = Type::DATETIME,
FIELD_TIME = Type::TIME;
/** @var string Last SQL command @see dibi::query() */
/** @var string|null Last SQL command @see dibi::query() */
public static $sql;
/** @var int Elapsed time for last query */
/** @var float|null Elapsed time for last query */
public static $elapsedTime;
/** @var int Elapsed time for all queries */
/** @var float Elapsed time for all queries */
public static $totalTime;
/** @var int Number or queries */
@@ -64,7 +63,7 @@ class dibi
/** @var string Default dibi driver */
public static $defaultDriver = 'mysqli';
/** @var Dibi\Connection[] Connection registry storage for DibiConnection objects */
/** @var Dibi\Connection[] Connection registry storage for Dibi\Connection objects */
private static $registry = [];
/** @var Dibi\Connection Current connection */
@@ -85,7 +84,7 @@ class dibi
/**
* Creates a new Connection object and connects it to specified database.
* @param mixed connection parameters
* @param array|string connection parameters
* @param string connection name
* @return Dibi\Connection
* @throws Dibi\Exception
@@ -441,10 +440,22 @@ class dibi
* Prints out a syntax highlighted version of the SQL command or Result.
* @param string|Result
* @param bool return output instead of printing it?
* @return string
* @return string|null
*/
public static function dump($sql = null, $return = false)
{
return Dibi\Helpers::dump($sql, $return);
}
/**
* Strips microseconds part.
* @param \DateTime|\DateTimeInterface
* @return \DateTime|\DateTimeInterface
*/
public static function stripMicroseconds($dt)
{
$class = get_class($dt);
return new $class($dt->format('Y-m-d H:i:s'), $dt->getTimezone());
}
}

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -9,7 +9,7 @@ namespace Dibi;
/**
* dibi common exception.
* Dibi common exception.
*/
class Exception extends \Exception
{
@@ -18,14 +18,14 @@ class Exception extends \Exception
/**
* Construct a dibi exception.
* @param string Message describing the exception
* @param mixed
* @param string|int
* @param string SQL command
* @param \Exception
*/
public function __construct($message = '', $code = 0, $sql = null)
public function __construct($message = '', $code = 0, $sql = null, \Exception $previous = null)
{
parent::__construct($message);
parent::__construct($message, 0, $previous);
$this->code = $code;
$this->sql = $sql;
}
@@ -103,7 +103,7 @@ class ProcedureException extends Exception
* @param int Some code
* @param string SQL command
*/
public function __construct($message = null, $code = 0, $severity = null, $sql = null)
public function __construct($message = '', $code = 0, $severity = '', $sql = null)
{
parent::__construct($message, (int) $code, $sql);
$this->severity = $severity;
@@ -116,7 +116,7 @@ class ProcedureException extends Exception
*/
public function getSeverity()
{
$this->severity;
return $this->severity;
}
}

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -19,11 +19,10 @@ interface IDataSource extends \Countable, \IteratorAggregate
/**
* dibi driver interface.
* Driver interface.
*/
interface Driver
{
/**
* Connects to a database.
* @param array
@@ -152,11 +151,10 @@ interface Driver
/**
* dibi result set driver interface.
* Result set driver interface.
*/
interface ResultDriver
{
/**
* Returns the number of rows in a result set.
* @return int
@@ -208,11 +206,10 @@ interface ResultDriver
/**
* dibi driver reflection.
* Reflection driver.
*/
interface Reflector
{
/**
* Returns list of tables.
* @return array of {name [, (bool) view ]}

View File

@@ -1,7 +1,7 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* This file is part of the Dibi, smart database abstraction layer (https://dibiphp.com)
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
@@ -17,27 +17,30 @@ spl_autoload_register(function ($class) {
'Dibi\Bridges\Nette\DibiExtension22' => 'Bridges/Nette/DibiExtension22.php',
'Dibi\Bridges\Tracy\Panel' => 'Bridges/Tracy/Panel.php',
'Dibi\Connection' => 'Connection.php',
'Dibi\ConstraintViolationException' => 'exceptions.php',
'Dibi\DataSource' => 'DataSource.php',
'Dibi\DateTime' => 'DateTime.php',
'Dibi\Driver' => 'interfaces.php',
'Dibi\DriverException' => 'exceptions.php',
'Dibi\Drivers\FirebirdDriver' => 'Drivers/FirebirdDriver.php',
'Dibi\Drivers\SqlsrvDriver' => 'Drivers/SqlsrvDriver.php',
'Dibi\Drivers\SqlsrvReflector' => 'Drivers/SqlsrvReflector.php',
'Dibi\Drivers\MsSqlDriver' => 'Drivers/MsSqlDriver.php',
'Dibi\Drivers\MsSqlReflector' => 'Drivers/MsSqlReflector.php',
'Dibi\Drivers\MySqlDriver' => 'Drivers/MySqlDriver.php',
'Dibi\Drivers\MySqliDriver' => 'Drivers/MySqliDriver.php',
'Dibi\Drivers\MySqlReflector' => 'Drivers/MySqlReflector.php',
'Dibi\Drivers\MySqliDriver' => 'Drivers/MySqliDriver.php',
'Dibi\Drivers\OdbcDriver' => 'Drivers/OdbcDriver.php',
'Dibi\Drivers\OracleDriver' => 'Drivers/OracleDriver.php',
'Dibi\Drivers\PdoDriver' => 'Drivers/PdoDriver.php',
'Dibi\Drivers\PostgreDriver' => 'Drivers/PostgreDriver.php',
'Dibi\Drivers\Sqlite3Driver' => 'Drivers/Sqlite3Driver.php',
'Dibi\Drivers\SqliteReflector' => 'Drivers/SqliteReflector.php',
'Dibi\Drivers\SqlsrvDriver' => 'Drivers/SqlsrvDriver.php',
'Dibi\Drivers\SqlsrvReflector' => 'Drivers/SqlsrvReflector.php',
'Dibi\Event' => 'Event.php',
'Dibi\Exception' => 'exceptions.php',
'Dibi\Expression' => 'Expression.php',
'Dibi\Fluent' => 'Fluent.php',
'Dibi\ForeignKeyConstraintViolationException' => 'exceptions.php',
'Dibi\HashMap' => 'HashMap.php',
'Dibi\HashMapBase' => 'HashMap.php',
'Dibi\Helpers' => 'Helpers.php',
@@ -46,6 +49,7 @@ spl_autoload_register(function ($class) {
'Dibi\Loggers\FileLogger' => 'Loggers/FileLogger.php',
'Dibi\Loggers\FirePhpLogger' => 'Loggers/FirePhpLogger.php',
'Dibi\NotImplementedException' => 'exceptions.php',
'Dibi\NotNullConstraintViolationException' => 'exceptions.php',
'Dibi\NotSupportedException' => 'exceptions.php',
'Dibi\PcreException' => 'exceptions.php',
'Dibi\ProcedureException' => 'exceptions.php',
@@ -63,8 +67,8 @@ spl_autoload_register(function ($class) {
'Dibi\Strict' => 'Strict.php',
'Dibi\Translator' => 'Translator.php',
'Dibi\Type' => 'Type.php',
'Dibi\UniqueConstraintViolationException' => 'exceptions.php',
], $old2new = [
'Dibi' => 'dibi.php',
'DibiColumnInfo' => 'Dibi\Reflection\Column',
'DibiConnection' => 'Dibi\Connection',
'DibiDatabaseInfo' => 'Dibi\Reflection\Database',
@@ -115,26 +119,9 @@ spl_autoload_register(function ($class) {
if (isset($map[$class])) {
require __DIR__ . '/Dibi/' . $map[$class];
} elseif (isset($old2new[$class])) {
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
$location = isset($trace[1]['file']) ? 'used in ' . $trace[1]['file'] . ':' . $trace[1]['line'] : '';
trigger_error("Class $class $location has been renamed to {$old2new[$class]}.", E_USER_DEPRECATED);
class_alias($old2new[$class], $class);
}
});
// preload for compatiblity
array_map('class_exists', [
'DibiConnection',
'DibiDateTime',
'DibiDriverException',
'DibiEvent',
'DibiException',
'DibiFluent',
'DibiLiteral',
'DibiNotImplementedException',
'DibiNotSupportedException',
'DibiPcreException',
'DibiProcedureException',
'DibiResult',
'DibiRow',
'IDataSource',
'IDibiDriver',
]);

View File

@@ -0,0 +1,41 @@
<?php
use Tester\Assert;
require __DIR__ . '/bootstrap.php';
function buildPdoDriver($errorMode)
{
$pdo = new PDO('sqlite::memory:');
if ($errorMode !== null) {
$pdo->setAttribute(PDO::ATTR_ERRMODE, $errorMode);
}
$config = ['resource' => $pdo];
$driver = new Dibi\Drivers\PdoDriver;
$driver->connect($config);
}
// PDO error mode: exception
Assert::exception(function () {
buildPdoDriver(PDO::ERRMODE_EXCEPTION);
}, 'Dibi\DriverException', 'PDO connection in exception or warning error mode is not supported.');
// PDO error mode: warning
Assert::exception(function () {
buildPdoDriver(PDO::ERRMODE_WARNING);
}, 'Dibi\DriverException', 'PDO connection in exception or warning error mode is not supported.');
// PDO error mode: explicitly set silent
test(function () {
buildPdoDriver(PDO::ERRMODE_SILENT);
});
// PDO error mode: implicitly set silent
test(function () {
buildPdoDriver(null);
});

View File

@@ -11,12 +11,17 @@ require __DIR__ . '/bootstrap.php';
$conn = new Dibi\Connection($config);
$conn->loadFile(__DIR__ . "/data/$config[system].sql");
$info = $conn->query('
$res = $conn->query('
SELECT products.product_id, orders.order_id, customers.name, products.product_id + 1 AS [xXx]
FROM ([products]
INNER JOIN [orders] ON [products.product_id] = [orders.product_id])
INNER JOIN [customers] ON [orders.customer_id] = [customers.customer_id]
')->getInfo();
');
$info = $res->getInfo();
Assert::same(4, $res->getColumnCount());
Assert::same(

View File

@@ -99,6 +99,11 @@ test(function () {
Assert::same(['col' => 1.0], $result->test(['col' => 1]));
Assert::same(['col' => 1.0], $result->test(['col' => 1.0]));
Assert::same(['col' => '1.1e+10'], $result->test(['col' => '1.1e+10']));
Assert::same(['col' => '1.1e-10'], $result->test(['col' => '1.1e-10']));
Assert::same(['col' => '1.1e+10'], $result->test(['col' => '001.1e+10']));
Assert::notSame(['col' => '1.1e+1'], $result->test(['col' => '1.1e+10']));
setlocale(LC_ALL, 'de_DE@euro', 'de_DE', 'deu_deu');
Assert::same(['col' => 0.0], $result->test(['col' => '']));
Assert::same(['col' => 0.0], $result->test(['col' => '0']));

View File

@@ -12,7 +12,7 @@ require __DIR__ . '/bootstrap.php';
$conn = new Dibi\Connection($config + ['formatDateTime' => "'Y-m-d H:i:s.u'", 'formatDate' => "'Y-m-d'"]);
// dibi detects INSERT or REPLACE command & booleans
// Dibi detects INSERT or REPLACE command & booleans
Assert::same(
reformat("REPLACE INTO [products] ([title], [price]) VALUES ('Drticka', 318)"),
$conn->translate('REPLACE INTO [products]', [
@@ -46,7 +46,7 @@ Assert::same(
);
// dibi detects UPDATE command
// Dibi detects UPDATE command
Assert::same(
reformat("UPDATE [colors] SET [color]='blue', [order]=12 WHERE [id]=123"),
$conn->translate('UPDATE [colors] SET', [
@@ -181,6 +181,8 @@ if ($config['system'] === 'odbc') {
Assert::same(
reformat([
'odbc' => 'INSERT INTO test ([a2], [a4], [b1], [b2], [b3], [b4], [b5], [b6], [b7], [b8], [b9], [c1]) VALUES (#09/26/1212 00:00:00.000000#, #12/31/1969 22:13:20.000000#, #09/26/1212#, #09/26/1212 00:00:00.000000#, #12/31/1969#, #12/31/1969 22:13:20.000000#, #09/26/1212 00:00:00.000000#, #09/26/1212#, #09/26/1212 00:00:00.000000#, NULL, NULL, #09/26/1212 16:51:34.012400#)',
'mssql' => "INSERT INTO test ([a2], [a4], [b1], [b2], [b3], [b4], [b5], [b6], [b7], [b8], [b9], [c1]) VALUES (CONVERT(DATETIME2(7), '1212-09-26 00:00:00.000000'), CONVERT(DATETIME2(7), '1969-12-31 22:13:20.000000'), '1212-09-26', CONVERT(DATETIME2(7), '1212-09-26 00:00:00.000000'), '1969-12-31', CONVERT(DATETIME2(7), '1969-12-31 22:13:20.000000'), CONVERT(DATETIME2(7), '1212-09-26 00:00:00.000000'), '1212-09-26', CONVERT(DATETIME2(7), '1212-09-26 00:00:00.000000'), NULL, NULL, CONVERT(DATETIME2(7), '1212-09-26 16:51:34.012400'))",
'sqlsrv' => "INSERT INTO test ([a2], [a4], [b1], [b2], [b3], [b4], [b5], [b6], [b7], [b8], [b9], [c1]) VALUES (CONVERT(DATETIME2(7), '1212-09-26 00:00:00.000000'), CONVERT(DATETIME2(7), '1969-12-31 22:13:20.000000'), '1212-09-26', CONVERT(DATETIME2(7), '1212-09-26 00:00:00.000000'), '1969-12-31', CONVERT(DATETIME2(7), '1969-12-31 22:13:20.000000'), CONVERT(DATETIME2(7), '1212-09-26 00:00:00.000000'), '1212-09-26', CONVERT(DATETIME2(7), '1212-09-26 00:00:00.000000'), NULL, NULL, CONVERT(DATETIME2(7), '1212-09-26 16:51:34.012400'))",
"INSERT INTO test ([a2], [a4], [b1], [b2], [b3], [b4], [b5], [b6], [b7], [b8], [b9], [c1]) VALUES ('1212-09-26 00:00:00.000000', '1969-12-31 22:13:20.000000', '1212-09-26', '1212-09-26 00:00:00.000000', '1969-12-31', '1969-12-31 22:13:20.000000', '1212-09-26 00:00:00.000000', '1212-09-26', '1212-09-26 00:00:00.000000', NULL, NULL, '1212-09-26 16:51:34.012400')",
]),
$conn->translate('INSERT INTO test', [
@@ -503,6 +505,18 @@ Assert::same(
);
Assert::same(
reformat('SELECT * FROM [table] WHERE (([left] = 1) OR ([top] = 2)) AND (number < 100)'),
$conn->translate('SELECT * FROM `table` WHERE %and', [
new Dibi\Expression('%or', [
'left' => 1,
'top' => 2,
]),
new Dibi\Expression('number < %i', 100),
])
);
$e = Assert::exception(function () use ($conn) {
$array6 = [
'id' => [1, 2, 3, 4],

View File

@@ -40,9 +40,6 @@ if ($config['driver'] === 'mysql' && PHP_VERSION_ID >= 70000) {
}
$conn = new Dibi\Connection($config);
function test(Closure $function)
{
$function();

View File

@@ -0,0 +1,11 @@
<?php
use Tester\Assert;
require __DIR__ . '/bootstrap.php';
$dt = new DateTime('2018-04-18 13:40:09.123456');
$res = dibi::stripMicroseconds($dt);
Assert::same('2018-04-18 13:40:09.123456', $dt->format('Y-m-d H:i:s.u'));
Assert::same('2018-04-18 13:40:09.000000', $res->format('Y-m-d H:i:s.u'));

View File

@@ -15,7 +15,7 @@ $conn->loadFile(__DIR__ . "/data/$config[system].sql");
$e = Assert::exception(function () use ($conn) {
$conn->query('SELECT');
}, 'Dibi\DriverException', '%a% syntax error', 1);
}, 'Dibi\DriverException', '%a%', 1);
Assert::same('SELECT', $e->getSql());