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

Compare commits

..

59 Commits

Author SHA1 Message Date
David Grudl
e8559898f1 Released version 3.0.9 2018-03-09 12:56:49 +01:00
David Grudl
ece85e8b48 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:53:10 +01:00
David Grudl
acd5ac8616 loader: fixed missing class 'dibi.php' 2018-02-15 11:54:37 +01:00
David Grudl
44876973f5 Translator: fixed %dt with DateTimeInterface object [Closes #263] 2017-09-21 14:05:20 +02:00
David Grudl
0e5d951dfb Released version 3.0.8 2017-06-10 03:05:18 +02:00
David Grudl
126422ad7e strict fixes 2017-06-10 03:05:18 +02:00
David Grudl
277f52c928 appveyor: is unable to start MSSQL 2012 & 2014 together 2017-06-10 02:58:47 +02:00
David Grudl
80ac569621 fixed phpDoc 2017-06-10 02:58:47 +02:00
David Grudl
d9628f933d coding style: removed space after reference & 2017-06-10 02:58:47 +02:00
David Grudl
f7009f3e0c Tracy\Panel: better typography 2017-06-10 02:58:47 +02:00
Jiří Trávníček
36d30c1fcf Dibi\Bridges\Tracy\Panel: host added to tracy panel [closes #250] (#251) 2017-06-10 02:58:44 +02:00
David Grudl
ae6c8756b6 Tracy\Panel: one panel is used per connection 2017-06-10 02:58:06 +02:00
David Grudl
6b2c996b16 Tracy\Panel: dump() may fails
related: https://forum.nette.org/cs/26790-error-dibi-bridges-tracy-panel-oracle
917971992f (commitcomment-18444224)
2017-06-09 12:12:07 +02:00
David Grudl
718c617764 travis: removed HHVM 2017-06-09 12:12:07 +02:00
David Grudl
6194152e67 examples: tracy is loaded before output [Closes #248] 2017-06-09 12:12:07 +02:00
David Grudl
d39603e23d updated .gitattributes 2017-06-09 12:12:07 +02:00
David Grudl
22e6ea4e40 Released version 3.0.7 2017-01-04 15:18:17 +01:00
David Grudl
f0d2c3f414 travis: removed PHP 7.1 from allowed failures 2017-01-04 15:18:17 +01:00
David Grudl
873ed3115d Connection::translateArgs() is protected [Closes #237] 2017-01-04 15:18:17 +01:00
Martin Dzíbela
73289d0569 PostgreSQL: add support for more than one schema in search_path (#239) 2017-01-04 15:18:17 +01:00
David Grudl
7b899ddda5 updated contributing.md, added GitHub templates 2017-01-04 15:18:17 +01:00
Ondřej Mirtes
8860268791 typos (#243) 2016-12-03 19:29:29 +01:00
Honza Machala
551b576271 Typos (#242) 2016-11-14 13:47:45 +01:00
David Grudl
74d0a78ec2 Result, Row: added support for datetime like 'Jun 17 2015 12:00:00:000AM' [Closes #180] 2016-09-02 17:36:37 +02:00
Aleš Culek
be7c3f095d Implemented OracleDriver::getColumns() (#233) 2016-08-09 22:37:45 +02:00
Radovan Kepák
3a6dc07da8 FirebirdDriver: Fixed DriverException throw (#231)
Fixed fetch Dibi\DriverException throw and more PHP warnings silenced
2016-08-09 22:36:44 +02:00
David Grudl
9b070bb737 Released version 3.0.6 2016-07-31 16:50:07 +02:00
David Grudl
917971992f Bridges\Tracy\Panel: silenced PHP warning
https://forum.nette.org/cs/26790-error-dibi-bridges-tracy-panel-oracle
2016-07-27 14:01:46 +02:00
Radovan Kepák
bc564555f8 FirebirdDriver: silenced PHP warning
If fetch have error, PHP show Warning, this is error by my opinion as Dibi Throw Exception with information, so the Warning is useless, and even more, if we catch exception, we still have warning.
2016-07-27 13:55:15 +02:00
David Grudl
3e20a6b8fc Dibi\DateTime::__wakeup() doesn't call parent after 8e8e6dfd [Closes #228] 2016-07-27 13:28:23 +02:00
David Grudl
c019e7cac2 tests: fixed compatibility with PHP 7.1 2016-07-21 14:38:56 +02:00
David Grudl
2294c195f4 Released version 3.0.5 2016-07-20 16:15:13 +02:00
David Grudl
25246529f7 Translator, Fluent: preserve dot in name after AS [Closes #224] 2016-07-20 16:13:33 +02:00
David Grudl
d405ec369b Translator: added %N 2016-07-20 16:13:32 +02:00
David Grudl
b7974fe192 travis: added PHP 7.1 2016-07-20 15:54:58 +02:00
David Grudl
80f1898e1b tests: removed deprecated 'storage_engine' 2016-07-20 15:50:33 +02:00
Roman Pavlík
8e8e6dfdca Dibi\DateTime: provides BC for serialized older versions [Closes #226] (#227) 2016-07-20 15:50:33 +02:00
Milan Pála
6510fcce25 Disconnect on not connected driver not fail (#222)
Sometimes database go away and Connection::isConnected() is returning TRUE. Prevent this should be posibble to disconnect on closed connection without error.
2016-07-20 15:50:32 +02:00
aldria
b7d84b90ef Correct limit and offset for Firebird Driver (#221)
SELECT [FIRST (<int-expr>)] [SKIP (<int-expr>)] <columns> FROM ...
2016-05-27 03:48:06 +02:00
David Grudl
2571e54f3c composer.json: replaces all dg/dibi versions 2016-05-04 20:13:50 +02:00
Aleš Culek
15e6d9f738 Implemented OracleDriver::getAffectedRows() 2016-05-03 08:55:22 +02:00
David Grudl
ddfd4a0f1a tests/travis: reports code coverage to Coveralls 2016-04-21 11:29:10 +02:00
David Grudl
4e838fc2b5 Released version 3.0.4 2016-04-06 19:09:24 +02:00
David Grudl
37487816db removed Strict from exceptions [Closes #216] 2016-04-06 18:52:42 +02:00
David Grudl
0c099bb2bc tests: a different .ini for PHP 5 and PHP 7 2016-03-20 19:23:57 +01:00
David Grudl
1786c861b9 Merge pull request #213 from castamir/php7sqlsrv
SqlsrvDriver: php7 compatibility
2016-03-20 16:34:36 +01:00
Mira Paulik
bc0578928f SqlsrvDriver: php7 compatibility 2016-03-20 13:50:10 +01:00
David Grudl
12a07ff6ad Merge pull request #212 from soukiii/master
Fluent: missing annotation
2016-03-18 17:16:23 +01:00
Petr Soukup
b50f59c64c Fluent: missing annotation 2016-03-18 15:40:16 +01:00
David Grudl
fdebf349f5 appveyor: test under PHP 7 2016-03-18 15:07:45 +01:00
David Grudl
954c2f25d0 Merge pull request #209 from castamir/sqlsrv_insert
SqlsrvDriver::getInsertId() last inserted id is from last statement instead of last inserted row
2016-02-29 23:37:17 +01:00
Mira Paulik
43dccb1ba2 SqlsrvDriver::getInsertId() last inserted id is from last statement instead of last inserted row regardless of the table that produced the value 2016-02-29 16:10:59 +01:00
David Grudl
352a683ec1 Released version 3.0.3 2016-02-21 02:07:19 +01:00
David Grudl
f4638796fb Helpers::detectType() detects VAR_STRING as Type::TEXT 2016-02-20 21:08:01 +01:00
David Grudl
4659f4550e DibiExtension22: added options 'explain' & 'filter' [Closes #203] 2016-02-10 00:08:27 +01:00
David Grudl
c3548465fb Merge pull request #204 from castamir/sqlsrv
SqlsrvDriver: fixed: sql server does not respond on non-string password
2016-02-09 23:19:53 +01:00
David Grudl
dda0bdbd67 Merge pull request #208 from ondrej-tuhacek/master
FirebirdDriver::delimite - Quotation marks for escaping identifiers
2016-02-04 16:08:25 +01:00
Ondřej Tuháček
7142be254b FirebirdDriver::delimite - Quotation marks for escaping identifiers 2016-02-04 13:29:06 +01:00
Mira Paulik
3b00115ee5 SqlsrvDriver: fixed: sql server does not respond on non-string credentials 2016-01-22 17:14:12 +01:00
51 changed files with 744 additions and 304 deletions

2
.gitattributes vendored
View File

@@ -1,4 +1,6 @@
.gitattributes export-ignore .gitattributes export-ignore
.gitignore export-ignore .gitignore export-ignore
.github export-ignore
.travis.yml export-ignore .travis.yml export-ignore
appveyor.yml export-ignore
tests/ export-ignore tests/ export-ignore

16
.github/issue_template.md vendored Normal file
View File

@@ -0,0 +1,16 @@
- bug report? yes/no
- feature request? yes/no
- version: ?.?.? <!-- exact release version, for bug reports -->
### Description
...
### Steps To Reproduce
... If possible a minimal demo of the problem ...
<!--
REMEMBER, AN ISSUE IS NOT THE PLACE TO ASK QUESTIONS. We will be happy to help you on Gitter https://gitter.im/nette/nette
A good bug report shouldn't leave others needing to chase you up for more information. Please try to be as detailed as possible in your report.
Feature requests are welcome. Explain your intentions. It's up to you to make a strong case to convince the project's developers of the merits of this feature.
-->

11
.github/pull_request_template.md vendored Normal file
View File

@@ -0,0 +1,11 @@
- bug fix? yes/no <!-- #issue numbers, if any -->
- new feature? yes/no
- BC break? yes/no
<!--
Describe your changes here to communicate to the maintainers why we should accept this pull request.
Please add new tests to show the fix or feature works.
Thanks for contributing!
-->

View File

@@ -4,14 +4,10 @@ php:
- 5.5 - 5.5
- 5.6 - 5.6
- 7.0 - 7.0
- hhvm - 7.1
matrix:
allow_failures:
- php: hhvm
script: script:
- vendor/bin/tester tests -s -p php -c tests/php-unix.ini - vendor/bin/tester tests -s -p php -c tests/php-unix.ini $COVERAGE
- php temp/code-checker/src/code-checker.php --short-arrays - php temp/code-checker/src/code-checker.php --short-arrays
after_failure: after_failure:
@@ -22,6 +18,7 @@ before_script:
# Install Nette Tester & Code Checker # Install Nette Tester & Code Checker
- travis_retry composer install --no-interaction - travis_retry composer install --no-interaction
- travis_retry composer create-project nette/code-checker temp/code-checker ~2.5 --no-interaction - travis_retry composer create-project nette/code-checker temp/code-checker ~2.5 --no-interaction
- if [ $TRAVIS_PHP_VERSION == "7.0" ]; then COVERAGE="-p phpdbg --coverage ./coverage.xml --coverage-src ./src"; fi
# Create databases.ini # Create databases.ini
- cp ./tests/databases.travis.ini ./tests/databases.ini - cp ./tests/databases.travis.ini ./tests/databases.ini
@@ -29,6 +26,14 @@ before_script:
# Create Postgre database # Create Postgre database
- psql -c 'CREATE DATABASE dibi_test' -U postgres - psql -c 'CREATE DATABASE dibi_test' -U postgres
after_script:
# Report Code Coverage
- >
if [ "$COVERAGE" != "" ]; then
wget https://github.com/satooshi/php-coveralls/releases/download/v1.0.1/coveralls.phar
&& php coveralls.phar --verbose --config tests/.coveralls.yml
|| true; fi
sudo: false sudo: false
cache: cache:

View File

@@ -1,26 +1,27 @@
build: off build: off
cache: cache:
- c:\php -> appveyor.yml - c:\php5 -> appveyor.yml
- c:\php7 -> appveyor.yml
- '%LOCALAPPDATA%\Composer\files -> appveyor.yml' - '%LOCALAPPDATA%\Composer\files -> appveyor.yml'
clone_folder: c:\projects\dibi clone_folder: c:\projects\dibi
services: services:
- mssql2012sp1 - mssql2012sp1
- mssql2014 # - mssql2014
- mysql - mysql
init: init:
- SET PATH=c:\php;%PATH% - SET PATH=c:\php5;%PATH%
- SET PHP=1
- SET ANSICON=121x90 (121x90) - SET ANSICON=121x90 (121x90)
install: install:
# Install PHP # Install PHP 5
- IF EXIST c:\php (SET PHP=0) ELSE (mkdir c:\php) - IF EXIST c:\php5 (SET PHP=0) ELSE (SET PHP=1)
- IF %PHP%==1 cd c:\php - IF %PHP%==1 mkdir 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 cd c:\php5
- 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_dir=ext >> php.ini
- IF %PHP%==1 echo extension=php_openssl.dll >> 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 - IF %PHP%==1 appveyor DownloadFile https://files.nette.org/misc/php-sqlsrv.zip
@@ -28,9 +29,21 @@ install:
- IF %PHP%==1 copy SQLSRV\php_sqlsrv_56_ts.dll ext\php_sqlsrv_ts.dll - IF %PHP%==1 copy SQLSRV\php_sqlsrv_56_ts.dll ext\php_sqlsrv_ts.dll
- IF %PHP%==1 copy SQLSRV\php_pdo_sqlsrv_56_ts.dll ext\php_pdo_sqlsrv_ts.dll - IF %PHP%==1 copy SQLSRV\php_pdo_sqlsrv_56_ts.dll ext\php_pdo_sqlsrv_ts.dll
- IF %PHP%==1 del /Q *.zip - IF %PHP%==1 del /Q *.zip
- cd c:\projects\dibi
# Install PHP 7
- 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 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
- IF %PHP%==1 copy SQLSRV\php_sqlsrv_7_ts.dll ext\php_sqlsrv_ts.dll
- IF %PHP%==1 del /Q *.zip
# Install Nette Tester # Install Nette Tester
- cd c:\projects\dibi
- appveyor DownloadFile https://getcomposer.org/composer.phar - appveyor DownloadFile https://getcomposer.org/composer.phar
- php composer.phar install --prefer-dist --no-interaction --no-progress - php composer.phar install --prefer-dist --no-interaction --no-progress
@@ -38,7 +51,8 @@ install:
- copy tests\databases.appveyor.ini tests\databases.ini - copy tests\databases.appveyor.ini tests\databases.ini
test_script: test_script:
- vendor\bin\tester tests -s -p php -c tests\php-win.ini - vendor\bin\tester tests -s -p c:\php5\php -c tests\php5-win.ini
- vendor\bin\tester tests -s -p c:\php7\php -c tests\php7-win.ini
on_failure: on_failure:
# Print *.actual content # Print *.actual content

View File

@@ -15,10 +15,10 @@
}, },
"require-dev": { "require-dev": {
"tracy/tracy": "~2.2", "tracy/tracy": "~2.2",
"nette/tester": "~1.3" "nette/tester": "~1.7"
}, },
"replace": { "replace": {
"dg/dibi": "self.version" "dg/dibi": "*"
}, },
"autoload": { "autoload": {
"classmap": ["src/"], "classmap": ["src/"],

View File

@@ -1,27 +1,31 @@
How to contribute & use the issue tracker How to contribute & use the issue tracker
========================================= =========================================
The issue tracker is the preferred channel for bug reports, features requests Dibi welcomes your contributions. There are several ways to help out:
and submitting pull requests, but please respect the following restrictions:
* Please **do not** use the issue tracker for personal support requests (use * Create an issue on GitHub, if you have found a bug
[dibi forum](https://forum.dibiphp.com) or [Stack Overflow](http://stackoverflow.com)). * Write test cases for open bug issues
* Write fixes for open bug/feature issues, preferably with test cases included
* Contribute to the documentation
* Please **do not** derail or troll issues. Keep the discussion on topic and Issues
respect the opinions of others. ------
* Use the GitHub **issue search** &mdash; check if the issue has already been Please **do not use the issue tracker to ask questions**. We will be happy to help you
reported. on [Dibi forum](https://forum.dibiphp.com).
A good **bug report** shouldn't leave others needing to chase you up for more A good bug report shouldn't leave others needing to chase you up for more
information. Please try to be as detailed as possible in your report. information. Please try to be as detailed as possible in your report.
**Feature requests** are welcome. But take a moment to find out whether your idea **Feature requests** are welcome. But take a moment to find out whether your idea
fits with the scope and aims of the project. It's up to *you* to make a strong fits with the scope and aims of the project. It's up to *you* to make a strong
case to convince the project's developers of the merits of this feature. case to convince the project's developers of the merits of this feature.
We welcome **pull requests**. If you'd like to contribute, please take a moment Contributing
to [read the guidelines](https://nette.org/en/contributing) in order to make ------------
the contribution process easy and effective for everyone involved.
Thanks! The best way to propose a feature is to discuss your ideas on [Dibi forum](https://forum.dibiphp.com) before implementing them.
Please do not fix whitespace, format code, or make a purely cosmetic patch.
Thanks! :heart:

View File

@@ -1,7 +1,3 @@
<!DOCTYPE html><link rel="stylesheet" href="data/style.css">
<h1>Fetching Examples | dibi</h1>
<?php <?php
if (@!include __DIR__ . '/../vendor/autoload.php') { if (@!include __DIR__ . '/../vendor/autoload.php') {
@@ -10,6 +6,12 @@ if (@!include __DIR__ . '/../vendor/autoload.php') {
Tracy\Debugger::enable(); Tracy\Debugger::enable();
?>
<!DOCTYPE html><link rel="stylesheet" href="data/style.css">
<h1>Fetching Examples | dibi</h1>
<?php
dibi::connect([ dibi::connect([
'driver' => 'sqlite3', 'driver' => 'sqlite3',

View File

@@ -1,7 +1,3 @@
<!DOCTYPE html><link rel="stylesheet" href="data/style.css">
<h1>Result Set Data Types | dibi</h1>
<?php <?php
use Dibi\Type; use Dibi\Type;
@@ -14,6 +10,12 @@ Tracy\Debugger::enable();
date_default_timezone_set('Europe/Prague'); date_default_timezone_set('Europe/Prague');
?>
<!DOCTYPE html><link rel="stylesheet" href="data/style.css">
<h1>Result Set Data Types | dibi</h1>
<?php
dibi::connect([ dibi::connect([
'driver' => 'sqlite3', 'driver' => 'sqlite3',

View File

@@ -1,9 +1,3 @@
<!DOCTYPE html><link rel="stylesheet" href="data/style.css">
<h1>Tracy & SQL Exceptions | dibi</h1>
<p>Dibi can display and log exceptions via <a href="https://tracy.nette.org">Tracy</a>.</p>
<?php <?php
if (@!include __DIR__ . '/../vendor/autoload.php') { if (@!include __DIR__ . '/../vendor/autoload.php') {
@@ -31,3 +25,9 @@ $panel->register($connection);
// throws error because SQL is bad // 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">
<h1>Tracy & SQL Exceptions | dibi</h1>
<p>Dibi can display and log exceptions via <a href="https://tracy.nette.org">Tracy</a>.</p>

View File

@@ -1,11 +1,3 @@
<!DOCTYPE html><link rel="stylesheet" href="data/style.css">
<style> html { background: url(data/arrow.png) no-repeat bottom right; height: 100%; } </style>
<h1>Tracy | dibi</h1>
<p>Dibi can log queries and dump variables to the <a href="https://tracy.nette.org">Tracy</a>.</p>
<?php <?php
if (@!include __DIR__ . '/../vendor/autoload.php') { if (@!include __DIR__ . '/../vendor/autoload.php') {
@@ -36,3 +28,13 @@ dibi::query('SELECT 123');
// result set will be dumped // 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]');
?>
<!DOCTYPE html><link rel="stylesheet" href="data/style.css">
<style> html { background: url(data/arrow.png) no-repeat bottom right; height: 100%; } </style>
<h1>Tracy | dibi</h1>
<p>Dibi can log queries and dump variables to the <a href="https://tracy.nette.org">Tracy</a>.</p>

View File

@@ -1,7 +1,3 @@
<!DOCTYPE html><link rel="stylesheet" href="data/style.css">
<h1>Using Extension Methods | dibi</h1>
<?php <?php
if (@!include __DIR__ . '/../vendor/autoload.php') { if (@!include __DIR__ . '/../vendor/autoload.php') {
@@ -10,6 +6,12 @@ if (@!include __DIR__ . '/../vendor/autoload.php') {
Tracy\Debugger::enable(); Tracy\Debugger::enable();
?>
<!DOCTYPE html><link rel="stylesheet" href="data/style.css">
<h1>Using Extension Methods | dibi</h1>
<?php
dibi::connect([ dibi::connect([
'driver' => 'sqlite3', 'driver' => 'sqlite3',

View File

@@ -7,6 +7,7 @@
namespace Dibi\Bridges\Nette; namespace Dibi\Bridges\Nette;
use Dibi;
use Nette; use Nette;
@@ -47,7 +48,10 @@ class DibiExtension22 extends Nette\DI\CompilerExtension
} }
if ($useProfiler) { if ($useProfiler) {
$panel = $container->addDefinition($this->prefix('panel')) $panel = $container->addDefinition($this->prefix('panel'))
->setClass('Dibi\Bridges\Tracy\Panel'); ->setClass('Dibi\Bridges\Tracy\Panel', [
isset($config['explain']) ? $config['explain'] : TRUE,
isset($config['filter']) && $config['filter'] === FALSE ? Dibi\Event::ALL : Dibi\Event::QUERY,
]);
$connection->addSetup([$panel, 'register'], [$connection]); $connection->addSetup([$panel, 'register'], [$connection]);
} }
} }

View File

@@ -63,7 +63,7 @@ class Panel implements Tracy\IBarPanel
/** /**
* Returns blue-screen custom tab. * Returns blue-screen custom tab.
* @return mixed * @return array|NULL
*/ */
public static function renderException($e) public static function renderException($e)
{ {
@@ -78,7 +78,7 @@ class Panel implements Tracy\IBarPanel
/** /**
* Returns HTML code for custom tab. (Tracy\IBarPanel) * Returns HTML code for custom tab. (Tracy\IBarPanel)
* @return mixed * @return string
*/ */
public function getTab() public function getTab()
{ {
@@ -88,35 +88,39 @@ class Panel implements Tracy\IBarPanel
$totalTime += $event->time; $totalTime += $event->time;
} }
return '<span title="dibi"><svg viewBox="0 0 2048 2048" style="vertical-align: bottom; width:1.23em; height:1.55em"><path fill="' . ($count ? '#b079d6' : '#aaa') . '" d="M1024 896q237 0 443-43t325-127v170q0 69-103 128t-280 93.5-385 34.5-385-34.5-280-93.5-103-128v-170q119 84 325 127t443 43zm0 768q237 0 443-43t325-127v170q0 69-103 128t-280 93.5-385 34.5-385-34.5-280-93.5-103-128v-170q119 84 325 127t443 43zm0-384q237 0 443-43t325-127v170q0 69-103 128t-280 93.5-385 34.5-385-34.5-280-93.5-103-128v-170q119 84 325 127t443 43zm0-1152q208 0 385 34.5t280 93.5 103 128v128q0 69-103 128t-280 93.5-385 34.5-385-34.5-280-93.5-103-128v-128q0-69 103-128t280-93.5 385-34.5z"/></svg><span class="tracy-label">' return '<span title="dibi"><svg viewBox="0 0 2048 2048" style="vertical-align: bottom; width:1.23em; height:1.55em"><path fill="' . ($count ? '#b079d6' : '#aaa') . '" d="M1024 896q237 0 443-43t325-127v170q0 69-103 128t-280 93.5-385 34.5-385-34.5-280-93.5-103-128v-170q119 84 325 127t443 43zm0 768q237 0 443-43t325-127v170q0 69-103 128t-280 93.5-385 34.5-385-34.5-280-93.5-103-128v-170q119 84 325 127t443 43zm0-384q237 0 443-43t325-127v170q0 69-103 128t-280 93.5-385 34.5-385-34.5-280-93.5-103-128v-170q119 84 325 127t443 43zm0-1152q208 0 385 34.5t280 93.5 103 128v128q0 69-103 128t-280 93.5-385 34.5-385-34.5-280-93.5-103-128v-128q0-69 103-128t280-93.5 385-34.5z"/></svg><span class="tracy-label">'
. $count . ' queries' . $count . ' queries'
. ($totalTime ? sprintf(' / %0.1f ms', $totalTime * 1000) : '') . ($totalTime ? ' / ' . number_format($totalTime * 1000, 1, '.', '') . 'ms' : '')
. '</span></span>'; . '</span></span>';
} }
/** /**
* Returns HTML code for custom panel. (Tracy\IBarPanel) * Returns HTML code for custom panel. (Tracy\IBarPanel)
* @return mixed * @return string|NULL
*/ */
public function getPanel() public function getPanel()
{ {
if (!$this->events) {
return NULL;
}
$totalTime = $s = NULL; $totalTime = $s = NULL;
$h = 'htmlSpecialChars';
foreach ($this->events as $event) { foreach ($this->events as $event) {
$totalTime += $event->time; $totalTime += $event->time;
$connection = $event->connection;
$explain = NULL; // EXPLAIN is called here to work SELECT FOUND_ROWS() $explain = NULL; // EXPLAIN is called here to work SELECT FOUND_ROWS()
if ($this->explain && $event->type === Event::SELECT) { if ($this->explain && $event->type === Event::SELECT) {
try { try {
$backup = [$event->connection->onEvent, \dibi::$numOfQueries, \dibi::$totalTime]; $backup = [$connection->onEvent, \dibi::$numOfQueries, \dibi::$totalTime];
$event->connection->onEvent = NULL; $connection->onEvent = NULL;
$cmd = is_string($this->explain) ? $this->explain : ($event->connection->getConfig('driver') === 'oracle' ? 'EXPLAIN PLAN FOR' : 'EXPLAIN'); $cmd = is_string($this->explain) ? $this->explain : ($connection->getConfig('driver') === 'oracle' ? 'EXPLAIN PLAN FOR' : 'EXPLAIN');
$explain = Helpers::dump($event->connection->nativeQuery("$cmd $event->sql"), TRUE); $explain = @Helpers::dump($connection->nativeQuery("$cmd $event->sql"), TRUE);
} catch (Dibi\Exception $e) { } catch (Dibi\Exception $e) {
} }
list($event->connection->onEvent, \dibi::$numOfQueries, \dibi::$totalTime) = $backup; list($connection->onEvent, \dibi::$numOfQueries, \dibi::$totalTime) = $backup;
} }
$s .= '<tr><td>' . sprintf('%0.3f', $event->time * 1000); $s .= '<tr><td>' . number_format($event->time * 1000, 3, '.', '');
if ($explain) { if ($explain) {
static $counter; static $counter;
$counter++; $counter++;
@@ -131,17 +135,19 @@ class Panel implements Tracy\IBarPanel
$s .= Tracy\Helpers::editorLink($event->source[0], $event->source[1]);//->class('tracy-DibiProfiler-source'); $s .= Tracy\Helpers::editorLink($event->source[0], $event->source[1]);//->class('tracy-DibiProfiler-source');
} }
$s .= "</td><td>{$event->count}</td><td>{$h($event->connection->getConfig('driver') . '/' . $event->connection->getConfig('name'))}</td></tr>"; $s .= "</td><td>{$event->count}</td></tr>";
} }
return empty($this->events) ? '' : return '<style> #tracy-debug td.tracy-DibiProfiler-sql { background: white !important }
'<style> #tracy-debug td.tracy-DibiProfiler-sql { background: white !important }
#tracy-debug .tracy-DibiProfiler-source { color: #999 !important } #tracy-debug .tracy-DibiProfiler-source { color: #999 !important }
#tracy-debug tracy-DibiProfiler tr table { margin: 8px 0; max-height: 150px; overflow:auto } </style> #tracy-debug tracy-DibiProfiler tr table { margin: 8px 0; max-height: 150px; overflow:auto } </style>
<h1>Queries: ' . count($this->events) . ($totalTime === NULL ? '' : sprintf(', time: %0.3f ms', $totalTime * 1000)) . '</h1> <h1>Queries: ' . count($this->events)
. ($totalTime === NULL ? '' : ', time: ' . number_format($totalTime * 1000, 1, '.', '') . 'ms') . ', '
. htmlSpecialChars($connection->getConfig('driver') . ($connection->getConfig('name') ? '/' . $connection->getConfig('name') : '')
. ($connection->getConfig('host') ? '@' . $connection->getConfig('host') : '')) . '</h1>
<div class="tracy-inner tracy-DibiProfiler"> <div class="tracy-inner tracy-DibiProfiler">
<table> <table>
<tr><th>Time&nbsp;ms</th><th>SQL Statement</th><th>Rows</th><th>Connection</th></tr>' . $s . ' <tr><th>Time&nbsp;ms</th><th>SQL Statement</th><th>Rows</th></tr>' . $s . '
</table> </table>
</div>'; </div>';
} }

View File

@@ -225,7 +225,7 @@ class Connection
/** /**
* Generates (translates) and executes SQL query. * Generates (translates) and executes SQL query.
* @param array|mixed one or more arguments * @param array|mixed one or more arguments
* @return Result|int result set object (if any) * @return Result|int result set or number of affected rows
* @throws Exception * @throws Exception
*/ */
final public function query($args) final public function query($args)
@@ -289,7 +289,7 @@ class Connection
* @param array * @param array
* @return string * @return string
*/ */
private function translateArgs($args) protected function translateArgs($args)
{ {
$this->connected || $this->connect(); $this->connected || $this->connect();
if (!$this->translator) { if (!$this->translator) {
@@ -303,7 +303,7 @@ class Connection
/** /**
* Executes the SQL query. * Executes the SQL query.
* @param string SQL statement. * @param string SQL statement.
* @return Result|int result set object (if any) * @return Result|int result set or number of affected rows
* @throws Exception * @throws Exception
*/ */
final public function nativeQuery($sql) final public function nativeQuery($sql)
@@ -473,7 +473,7 @@ class Connection
/** /**
* @param string column name * @param mixed column name
* @return Fluent * @return Fluent
*/ */
public function select($args) public function select($args)
@@ -555,7 +555,7 @@ class Connection
/** /**
* Executes SQL query and fetch result - shortcut for query() & fetch(). * Executes SQL query and fetch result - shortcut for query() & fetch().
* @param array|mixed one or more arguments * @param array|mixed one or more arguments
* @return Row * @return Row|FALSE
* @throws Exception * @throws Exception
*/ */
public function fetch($args) public function fetch($args)
@@ -581,7 +581,7 @@ class Connection
/** /**
* Executes SQL query and fetch first column - shortcut for query() & fetchSingle(). * Executes SQL query and fetch first column - shortcut for query() & fetchSingle().
* @param array|mixed one or more arguments * @param array|mixed one or more arguments
* @return string * @return mixed
* @throws Exception * @throws Exception
*/ */
public function fetchSingle($args) public function fetchSingle($args)
@@ -594,7 +594,7 @@ class Connection
/** /**
* Executes SQL query and fetch pairs - shortcut for query() & fetchPairs(). * Executes SQL query and fetch pairs - shortcut for query() & fetchPairs().
* @param array|mixed one or more arguments * @param array|mixed one or more arguments
* @return string * @return array
* @throws Exception * @throws Exception
*/ */
public function fetchPairs($args) public function fetchPairs($args)

View File

@@ -40,10 +40,10 @@ class DataSource implements IDataSource
/** @var array */ /** @var array */
private $conds = []; private $conds = [];
/** @var int */ /** @var int|NULL */
private $offset; private $offset;
/** @var int */ /** @var int|NULL */
private $limit; private $limit;
@@ -118,7 +118,7 @@ class DataSource implements IDataSource
/** /**
* Limits number of rows. * Limits number of rows.
* @param int limit * @param int|NULL limit
* @param int offset * @param int offset
* @return self * @return self
*/ */
@@ -168,7 +168,7 @@ class DataSource implements IDataSource
/** /**
* Generates, executes SQL query and fetches the single row. * Generates, executes SQL query and fetches the single row.
* @return Row|FALSE array on success, FALSE if no next record * @return Row|FALSE
*/ */
public function fetch() public function fetch()
{ {

View File

@@ -15,6 +15,9 @@ class DateTime extends \DateTime
{ {
use Strict; use Strict;
/**
* @param string|int
*/
public function __construct($time = 'now', \DateTimeZone $timezone = NULL) public function __construct($time = 'now', \DateTimeZone $timezone = NULL)
{ {
if (is_numeric($time)) { if (is_numeric($time)) {
@@ -55,4 +58,18 @@ class DateTime extends \DateTime
return $this->format('Y-m-d H:i:s'); return $this->format('Y-m-d H:i:s');
} }
public function __wakeup()
{
if (isset($this->fix, $this->fix[1])) {
$this->__construct($this->fix[0], new \DateTimeZone($this->fix[1]));
unset($this->fix);
} elseif (isset($this->fix)) {
$this->__construct($this->fix[0]);
unset($this->fix);
} else {
parent::__wakeup();
}
}
} }

View File

@@ -28,16 +28,16 @@ class FirebirdDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
const ERROR_EXCEPTION_THROWN = -836; const ERROR_EXCEPTION_THROWN = -836;
/** @var resource Connection resource */ /** @var resource|NULL */
private $connection; private $connection;
/** @var resource Resultset resource */ /** @var resource|NULL */
private $resultSet; private $resultSet;
/** @var bool */ /** @var bool */
private $autoFree = TRUE; private $autoFree = TRUE;
/** @var resource Resultset resource */ /** @var resource|NULL */
private $transaction; private $transaction;
/** @var bool */ /** @var bool */
@@ -78,9 +78,9 @@ class FirebirdDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
]; ];
if (empty($config['persistent'])) { if (empty($config['persistent'])) {
$this->connection = ibase_connect($config['database'], $config['username'], $config['password'], $config['charset'], $config['buffers']); // intentionally @ $this->connection = @ibase_connect($config['database'], $config['username'], $config['password'], $config['charset'], $config['buffers']); // intentionally @
} else { } else {
$this->connection = ibase_pconnect($config['database'], $config['username'], $config['password'], $config['charset'], $config['buffers']); // intentionally @ $this->connection = @ibase_pconnect($config['database'], $config['username'], $config['password'], $config['charset'], $config['buffers']); // intentionally @
} }
if (!is_resource($this->connection)) { if (!is_resource($this->connection)) {
@@ -96,7 +96,7 @@ class FirebirdDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
*/ */
public function disconnect() public function disconnect()
{ {
ibase_close($this->connection); @ibase_close($this->connection); // @ - connection can be already disconnected
} }
@@ -123,6 +123,7 @@ class FirebirdDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
} elseif (is_resource($res)) { } elseif (is_resource($res)) {
return $this->createResultDriver($res); return $this->createResultDriver($res);
} }
return NULL;
} }
@@ -215,7 +216,7 @@ class FirebirdDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
/** /**
* Returns the connection resource. * Returns the connection resource.
* @return resource * @return resource|NULL
*/ */
public function getResource() public function getResource()
{ {
@@ -260,24 +261,40 @@ class FirebirdDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
} }
/**
* @param string
* @return string
*/
public function escapeBinary($value) public function escapeBinary($value)
{ {
return "'" . str_replace("'", "''", $value) . "'"; return "'" . str_replace("'", "''", $value) . "'";
} }
/**
* @param string
* @return string
*/
public function escapeIdentifier($value) public function escapeIdentifier($value)
{ {
return $value; return '"' . str_replace('"', '""', $value). '"';
} }
/**
* @param bool
* @return string
*/
public function escapeBool($value) public function escapeBool($value)
{ {
return $value ? 1 : 0; return $value ? '1' : '0';
} }
/**
* @param \DateTime|\DateTimeInterface|string|int
* @return string
*/
public function escapeDate($value) public function escapeDate($value)
{ {
if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) { if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) {
@@ -287,6 +304,10 @@ class FirebirdDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
} }
/**
* @param \DateTime|\DateTimeInterface|string|int
* @return string
*/
public function escapeDateTime($value) public function escapeDateTime($value)
{ {
if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) { if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) {
@@ -329,13 +350,16 @@ class FirebirdDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
/** /**
* Injects LIMIT/OFFSET to the SQL query. * Injects LIMIT/OFFSET to the SQL query.
* @param string
* @param int|NULL
* @param int|NULL
* @return void * @return void
*/ */
public function applyLimit(&$sql, $limit, $offset) public function applyLimit(&$sql, $limit, $offset)
{ {
if ($limit >= 0 && $offset > 0) { if ($limit > 0 || $offset > 0) {
// see http://scott.yang.id.au/2004/01/limit-in-select-statements-in-firebird/ // http://www.firebirdsql.org/refdocs/langrefupd20-select.html
$sql = 'SELECT FIRST ' . (int) $limit . ($offset > 0 ? ' SKIP ' . (int) $offset : '') . ' * FROM (' . $sql . ')'; $sql = 'SELECT ' . ($limit > 0 ? 'FIRST ' . (int) $limit : '') . ($offset > 0 ? ' SKIP ' . (int) $offset : '') . ' * FROM (' . $sql . ')';
} }
} }
@@ -370,7 +394,7 @@ class FirebirdDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
*/ */
public function fetch($assoc) public function fetch($assoc)
{ {
$result = $assoc ? ibase_fetch_assoc($this->resultSet, IBASE_TEXT) : ibase_fetch_row($this->resultSet, IBASE_TEXT); // intentionally @ $result = $assoc ? @ibase_fetch_assoc($this->resultSet, IBASE_TEXT) : @ibase_fetch_row($this->resultSet, IBASE_TEXT); // intentionally @
if (ibase_errcode()) { if (ibase_errcode()) {
if (ibase_errcode() == self::ERROR_EXCEPTION_THROWN) { if (ibase_errcode() == self::ERROR_EXCEPTION_THROWN) {
@@ -378,7 +402,7 @@ class FirebirdDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
throw new Dibi\ProcedureException($match[3], $match[1], $match[2]); throw new Dibi\ProcedureException($match[3], $match[1], $match[2]);
} else { } else {
throw new Dibi\DriverException($msg, ibase_errcode()); throw new Dibi\DriverException(ibase_errmsg(), ibase_errcode());
} }
} }
@@ -411,7 +435,7 @@ class FirebirdDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
/** /**
* Returns the result set resource. * Returns the result set resource.
* @return resource * @return resource|NULL
*/ */
public function getResultResource() public function getResultResource()
{ {

View File

@@ -26,10 +26,10 @@ class MsSqlDriver implements Dibi\Driver, Dibi\ResultDriver
{ {
use Dibi\Strict; use Dibi\Strict;
/** @var resource Connection resource */ /** @var resource|NULL */
private $connection; private $connection;
/** @var resource Resultset resource */ /** @var resource|NULL */
private $resultSet; private $resultSet;
/** @var bool */ /** @var bool */
@@ -78,7 +78,7 @@ class MsSqlDriver implements Dibi\Driver, Dibi\ResultDriver
*/ */
public function disconnect() public function disconnect()
{ {
mssql_close($this->connection); @mssql_close($this->connection); // @ - connection can be already disconnected
} }
@@ -98,6 +98,7 @@ class MsSqlDriver implements Dibi\Driver, Dibi\ResultDriver
} elseif (is_resource($res)) { } elseif (is_resource($res)) {
return $this->createResultDriver($res); return $this->createResultDriver($res);
} }
return NULL;
} }
@@ -164,7 +165,7 @@ class MsSqlDriver implements Dibi\Driver, Dibi\ResultDriver
/** /**
* Returns the connection resource. * Returns the connection resource.
* @return mixed * @return resource|NULL
*/ */
public function getResource() public function getResource()
{ {
@@ -200,7 +201,7 @@ class MsSqlDriver implements Dibi\Driver, Dibi\ResultDriver
/** /**
* Encodes data for use in a SQL statement. * Encodes data for use in a SQL statement.
* @param mixed value * @param string value
* @return string encoded value * @return string encoded value
*/ */
public function escapeText($value) public function escapeText($value)
@@ -209,12 +210,20 @@ class MsSqlDriver implements Dibi\Driver, Dibi\ResultDriver
} }
/**
* @param string
* @return string
*/
public function escapeBinary($value) public function escapeBinary($value)
{ {
return "'" . str_replace("'", "''", $value) . "'"; return "'" . str_replace("'", "''", $value) . "'";
} }
/**
* @param string
* @return string
*/
public function escapeIdentifier($value) public function escapeIdentifier($value)
{ {
// @see https://msdn.microsoft.com/en-us/library/ms176027.aspx // @see https://msdn.microsoft.com/en-us/library/ms176027.aspx
@@ -222,12 +231,20 @@ class MsSqlDriver implements Dibi\Driver, Dibi\ResultDriver
} }
/**
* @param bool
* @return string
*/
public function escapeBool($value) public function escapeBool($value)
{ {
return $value ? 1 : 0; return $value ? '1' : '0';
} }
/**
* @param \DateTime|\DateTimeInterface|string|int
* @return string
*/
public function escapeDate($value) public function escapeDate($value)
{ {
if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) { if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) {
@@ -237,6 +254,10 @@ class MsSqlDriver implements Dibi\Driver, Dibi\ResultDriver
} }
/**
* @param \DateTime|\DateTimeInterface|string|int
* @return string
*/
public function escapeDateTime($value) public function escapeDateTime($value)
{ {
if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) { if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) {
@@ -280,6 +301,9 @@ class MsSqlDriver implements Dibi\Driver, Dibi\ResultDriver
/** /**
* Injects LIMIT/OFFSET to the SQL query. * Injects LIMIT/OFFSET to the SQL query.
* @param string
* @param int|NULL
* @param int|NULL
* @return void * @return void
*/ */
public function applyLimit(&$sql, $limit, $offset) public function applyLimit(&$sql, $limit, $offset)
@@ -375,7 +399,7 @@ class MsSqlDriver implements Dibi\Driver, Dibi\ResultDriver
/** /**
* Returns the result set resource. * Returns the result set resource.
* @return mixed * @return resource|NULL
*/ */
public function getResultResource() public function getResultResource()
{ {

View File

@@ -36,10 +36,10 @@ class MySqlDriver implements Dibi\Driver, Dibi\ResultDriver
const ERROR_DUPLICATE_ENTRY = 1062; const ERROR_DUPLICATE_ENTRY = 1062;
const ERROR_DATA_TRUNCATED = 1265; const ERROR_DATA_TRUNCATED = 1265;
/** @var resource Connection resource */ /** @var resource|NULL */
private $connection; private $connection;
/** @var resource Resultset resource */ /** @var resource|NULL */
private $resultSet; private $resultSet;
/** @var bool */ /** @var bool */
@@ -139,7 +139,7 @@ class MySqlDriver implements Dibi\Driver, Dibi\ResultDriver
*/ */
public function disconnect() public function disconnect()
{ {
mysql_close($this->connection); @mysql_close($this->connection); // @ - connection can be already disconnected
} }
@@ -243,7 +243,7 @@ class MySqlDriver implements Dibi\Driver, Dibi\ResultDriver
/** /**
* Returns the connection resource. * Returns the connection resource.
* @return mixed * @return resource|NULL
*/ */
public function getResource() public function getResource()
{ {
@@ -279,7 +279,7 @@ class MySqlDriver implements Dibi\Driver, Dibi\ResultDriver
/** /**
* Encodes data for use in a SQL statement. * Encodes data for use in a SQL statement.
* @param mixed value * @param string value
* @return string encoded value * @return string encoded value
*/ */
public function escapeText($value) public function escapeText($value)
@@ -291,6 +291,10 @@ class MySqlDriver implements Dibi\Driver, Dibi\ResultDriver
} }
/**
* @param string
* @return string
*/
public function escapeBinary($value) public function escapeBinary($value)
{ {
if (!is_resource($this->connection)) { if (!is_resource($this->connection)) {
@@ -300,6 +304,10 @@ class MySqlDriver implements Dibi\Driver, Dibi\ResultDriver
} }
/**
* @param string
* @return string
*/
public function escapeIdentifier($value) public function escapeIdentifier($value)
{ {
// @see http://dev.mysql.com/doc/refman/5.0/en/identifiers.html // @see http://dev.mysql.com/doc/refman/5.0/en/identifiers.html
@@ -307,12 +315,20 @@ class MySqlDriver implements Dibi\Driver, Dibi\ResultDriver
} }
/**
* @param bool
* @return string
*/
public function escapeBool($value) public function escapeBool($value)
{ {
return $value ? 1 : 0; return $value ? 1 : 0;
} }
/**
* @param \DateTime|\DateTimeInterface|string|int
* @return string
*/
public function escapeDate($value) public function escapeDate($value)
{ {
if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) { if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) {
@@ -322,6 +338,10 @@ class MySqlDriver implements Dibi\Driver, Dibi\ResultDriver
} }
/**
* @param \DateTime|\DateTimeInterface|string|int
* @return string
*/
public function escapeDateTime($value) public function escapeDateTime($value)
{ {
if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) { if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) {
@@ -365,6 +385,9 @@ class MySqlDriver implements Dibi\Driver, Dibi\ResultDriver
/** /**
* Injects LIMIT/OFFSET to the SQL query. * Injects LIMIT/OFFSET to the SQL query.
* @param string
* @param int|NULL
* @param int|NULL
* @return void * @return void
*/ */
public function applyLimit(&$sql, $limit, $offset) public function applyLimit(&$sql, $limit, $offset)
@@ -469,7 +492,7 @@ class MySqlDriver implements Dibi\Driver, Dibi\ResultDriver
/** /**
* Returns the result set resource. * Returns the result set resource.
* @return mixed * @return resource|NULL
*/ */
public function getResultResource() public function getResultResource()
{ {

View File

@@ -37,10 +37,10 @@ class MySqliDriver implements Dibi\Driver, Dibi\ResultDriver
const ERROR_DUPLICATE_ENTRY = 1062; const ERROR_DUPLICATE_ENTRY = 1062;
const ERROR_DATA_TRUNCATED = 1265; const ERROR_DATA_TRUNCATED = 1265;
/** @var mysqli Connection resource */ /** @var \mysqli|NULL */
private $connection; private $connection;
/** @var mysqli_result Resultset resource */ /** @var \mysqli_result|NULL */
private $resultSet; private $resultSet;
/** @var bool */ /** @var bool */
@@ -138,7 +138,7 @@ class MySqliDriver implements Dibi\Driver, Dibi\ResultDriver
*/ */
public function disconnect() public function disconnect()
{ {
mysqli_close($this->connection); @mysqli_close($this->connection); // @ - connection can be already disconnected
} }
@@ -158,6 +158,7 @@ class MySqliDriver implements Dibi\Driver, Dibi\ResultDriver
} elseif (is_object($res)) { } elseif (is_object($res)) {
return $this->createResultDriver($res); return $this->createResultDriver($res);
} }
return NULL;
} }
@@ -258,7 +259,7 @@ class MySqliDriver implements Dibi\Driver, Dibi\ResultDriver
/** /**
* Returns the connection resource. * Returns the connection resource.
* @return mysqli * @return \mysqli
*/ */
public function getResource() public function getResource()
{ {
@@ -278,7 +279,6 @@ class MySqliDriver implements Dibi\Driver, Dibi\ResultDriver
/** /**
* Result set driver factory. * Result set driver factory.
* @param mysqli_result
* @return Dibi\ResultDriver * @return Dibi\ResultDriver
*/ */
public function createResultDriver(\mysqli_result $resource) public function createResultDriver(\mysqli_result $resource)
@@ -294,7 +294,7 @@ class MySqliDriver implements Dibi\Driver, Dibi\ResultDriver
/** /**
* Encodes data for use in a SQL statement. * Encodes data for use in a SQL statement.
* @param mixed value * @param string value
* @return string encoded value * @return string encoded value
*/ */
public function escapeText($value) public function escapeText($value)
@@ -303,24 +303,40 @@ class MySqliDriver implements Dibi\Driver, Dibi\ResultDriver
} }
/**
* @param string
* @return string
*/
public function escapeBinary($value) public function escapeBinary($value)
{ {
return "_binary'" . mysqli_real_escape_string($this->connection, $value) . "'"; return "_binary'" . mysqli_real_escape_string($this->connection, $value) . "'";
} }
/**
* @param string
* @return string
*/
public function escapeIdentifier($value) public function escapeIdentifier($value)
{ {
return '`' . str_replace('`', '``', $value) . '`'; return '`' . str_replace('`', '``', $value) . '`';
} }
/**
* @param bool
* @return string
*/
public function escapeBool($value) public function escapeBool($value)
{ {
return $value ? 1 : 0; return $value ? '1' : '0';
} }
/**
* @param \DateTime|\DateTimeInterface|string|int
* @return string
*/
public function escapeDate($value) public function escapeDate($value)
{ {
if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) { if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) {
@@ -330,6 +346,10 @@ class MySqliDriver implements Dibi\Driver, Dibi\ResultDriver
} }
/**
* @param \DateTime|\DateTimeInterface|string|int
* @return string
*/
public function escapeDateTime($value) public function escapeDateTime($value)
{ {
if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) { if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) {
@@ -373,6 +393,9 @@ class MySqliDriver implements Dibi\Driver, Dibi\ResultDriver
/** /**
* Injects LIMIT/OFFSET to the SQL query. * Injects LIMIT/OFFSET to the SQL query.
* @param string
* @param int|NULL
* @param int|NULL
* @return void * @return void
*/ */
public function applyLimit(&$sql, $limit, $offset) public function applyLimit(&$sql, $limit, $offset)
@@ -488,7 +511,7 @@ class MySqliDriver implements Dibi\Driver, Dibi\ResultDriver
/** /**
* Returns the result set resource. * Returns the result set resource.
* @return mysqli_result * @return \mysqli_result|NULL
*/ */
public function getResultResource() public function getResultResource()
{ {

View File

@@ -25,10 +25,10 @@ class OdbcDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
{ {
use Dibi\Strict; use Dibi\Strict;
/** @var resource Connection resource */ /** @var resource|NULL */
private $connection; private $connection;
/** @var resource Resultset resource */ /** @var resource|NULL */
private $resultSet; private $resultSet;
/** @var bool */ /** @var bool */
@@ -88,7 +88,7 @@ class OdbcDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
*/ */
public function disconnect() public function disconnect()
{ {
odbc_close($this->connection); @odbc_close($this->connection); // @ - connection can be already disconnected
} }
@@ -110,6 +110,7 @@ class OdbcDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
$this->affectedRows = odbc_num_rows($res); $this->affectedRows = odbc_num_rows($res);
return $this->createResultDriver($res); return $this->createResultDriver($res);
} }
return NULL;
} }
@@ -189,7 +190,7 @@ class OdbcDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
/** /**
* Returns the connection resource. * Returns the connection resource.
* @return mixed * @return resource|NULL
*/ */
public function getResource() public function getResource()
{ {
@@ -225,7 +226,7 @@ class OdbcDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
/** /**
* Encodes data for use in a SQL statement. * Encodes data for use in a SQL statement.
* @param mixed value * @param string value
* @return string encoded value * @return string encoded value
*/ */
public function escapeText($value) public function escapeText($value)
@@ -234,24 +235,40 @@ class OdbcDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
} }
/**
* @param string
* @return string
*/
public function escapeBinary($value) public function escapeBinary($value)
{ {
return "'" . str_replace("'", "''", $value) . "'"; return "'" . str_replace("'", "''", $value) . "'";
} }
/**
* @param string
* @return string
*/
public function escapeIdentifier($value) public function escapeIdentifier($value)
{ {
return '[' . str_replace(['[', ']'], ['[[', ']]'], $value) . ']'; return '[' . str_replace(['[', ']'], ['[[', ']]'], $value) . ']';
} }
/**
* @param bool
* @return string
*/
public function escapeBool($value) public function escapeBool($value)
{ {
return $value ? 1 : 0; return $value ? '1' : '0';
} }
/**
* @param \DateTime|\DateTimeInterface|string|int
* @return string
*/
public function escapeDate($value) public function escapeDate($value)
{ {
if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) { if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) {
@@ -261,6 +278,10 @@ class OdbcDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
} }
/**
* @param \DateTime|\DateTimeInterface|string|int
* @return string
*/
public function escapeDateTime($value) public function escapeDateTime($value)
{ {
if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) { if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) {
@@ -304,6 +325,9 @@ class OdbcDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
/** /**
* Injects LIMIT/OFFSET to the SQL query. * Injects LIMIT/OFFSET to the SQL query.
* @param string
* @param int|NULL
* @param int|NULL
* @return void * @return void
*/ */
public function applyLimit(&$sql, $limit, $offset) public function applyLimit(&$sql, $limit, $offset)
@@ -413,7 +437,7 @@ class OdbcDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
/** /**
* Returns the result set resource. * Returns the result set resource.
* @return mixed * @return resource|NULL
*/ */
public function getResultResource() public function getResultResource()
{ {

View File

@@ -29,10 +29,10 @@ class OracleDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
{ {
use Dibi\Strict; use Dibi\Strict;
/** @var resource Connection resource */ /** @var resource|NULL */
private $connection; private $connection;
/** @var resource Resultset resource */ /** @var resource|NULL */
private $resultSet; private $resultSet;
/** @var bool */ /** @var bool */
@@ -44,6 +44,9 @@ class OracleDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
/** @var string Date and datetime format */ /** @var string Date and datetime format */
private $fmtDate, $fmtDateTime; private $fmtDate, $fmtDateTime;
/** @var int|FALSE Number of affected rows */
private $affectedRows = FALSE;
/** /**
* @throws Dibi\NotSupportedException * @throws Dibi\NotSupportedException
@@ -92,7 +95,7 @@ class OracleDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
*/ */
public function disconnect() public function disconnect()
{ {
oci_close($this->connection); @oci_close($this->connection); // @ - connection can be already disconnected
} }
@@ -104,6 +107,7 @@ class OracleDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
*/ */
public function query($sql) public function query($sql)
{ {
$this->affectedRows = FALSE;
$res = oci_parse($this->connection, $sql); $res = oci_parse($this->connection, $sql);
if ($res) { if ($res) {
@oci_execute($res, $this->autocommit ? OCI_COMMIT_ON_SUCCESS : OCI_DEFAULT); @oci_execute($res, $this->autocommit ? OCI_COMMIT_ON_SUCCESS : OCI_DEFAULT);
@@ -112,12 +116,14 @@ class OracleDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
throw self::createException($err['message'], $err['code'], $sql); throw self::createException($err['message'], $err['code'], $sql);
} elseif (is_resource($res)) { } elseif (is_resource($res)) {
$this->affectedRows = oci_num_rows($res);
return $this->createResultDriver($res); return $this->createResultDriver($res);
} }
} else { } else {
$err = oci_error($this->connection); $err = oci_error($this->connection);
throw new Dibi\DriverException($err['message'], $err['code'], $sql); throw new Dibi\DriverException($err['message'], $err['code'], $sql);
} }
return NULL;
} }
@@ -147,7 +153,7 @@ class OracleDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
*/ */
public function getAffectedRows() public function getAffectedRows()
{ {
throw new Dibi\NotImplementedException; return $this->affectedRows;
} }
@@ -207,7 +213,7 @@ class OracleDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
/** /**
* Returns the connection resource. * Returns the connection resource.
* @return mixed * @return resource|NULL
*/ */
public function getResource() public function getResource()
{ {
@@ -243,7 +249,7 @@ class OracleDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
/** /**
* Encodes data for use in a SQL statement. * Encodes data for use in a SQL statement.
* @param mixed value * @param string value
* @return string encoded value * @return string encoded value
*/ */
public function escapeText($value) public function escapeText($value)
@@ -252,12 +258,20 @@ class OracleDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
} }
/**
* @param string
* @return string
*/
public function escapeBinary($value) public function escapeBinary($value)
{ {
return "'" . str_replace("'", "''", $value) . "'"; // TODO: not tested return "'" . str_replace("'", "''", $value) . "'"; // TODO: not tested
} }
/**
* @param string
* @return string
*/
public function escapeIdentifier($value) public function escapeIdentifier($value)
{ {
// @see http://download.oracle.com/docs/cd/B10500_01/server.920/a96540/sql_elements9a.htm // @see http://download.oracle.com/docs/cd/B10500_01/server.920/a96540/sql_elements9a.htm
@@ -265,12 +279,20 @@ class OracleDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
} }
/**
* @param bool
* @return string
*/
public function escapeBool($value) public function escapeBool($value)
{ {
return $value ? 1 : 0; return $value ? '1' : '0';
} }
/**
* @param \DateTime|\DateTimeInterface|string|int
* @return string
*/
public function escapeDate($value) public function escapeDate($value)
{ {
if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) { if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) {
@@ -280,6 +302,10 @@ class OracleDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
} }
/**
* @param \DateTime|\DateTimeInterface|string|int
* @return string
*/
public function escapeDateTime($value) public function escapeDateTime($value)
{ {
if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) { if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) {
@@ -324,6 +350,9 @@ class OracleDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
/** /**
* Injects LIMIT/OFFSET to the SQL query. * Injects LIMIT/OFFSET to the SQL query.
* @param string
* @param int|NULL
* @param int|NULL
* @return void * @return void
*/ */
public function applyLimit(&$sql, $limit, $offset) public function applyLimit(&$sql, $limit, $offset)
@@ -422,7 +451,7 @@ class OracleDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
/** /**
* Returns the result set resource. * Returns the result set resource.
* @return mixed * @return resource|NULL
*/ */
public function getResultResource() public function getResultResource()
{ {
@@ -461,7 +490,20 @@ class OracleDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
*/ */
public function getColumns($table) public function getColumns($table)
{ {
throw new Dibi\NotImplementedException; $res = $this->query('SELECT * FROM "ALL_TAB_COLUMNS" WHERE "TABLE_NAME" = ' . $this->escapeText($table));
$columns = [];
while ($row = $res->fetch(TRUE)) {
$columns[] = [
'table' => $row['TABLE_NAME'],
'name' => $row['COLUMN_NAME'],
'nativetype' => $row['DATA_TYPE'],
'size' => isset($row['DATA_LENGTH']) ? $row['DATA_LENGTH'] : NULL,
'nullable' => $row['NULLABLE'] === 'Y',
'default' => $row['DATA_DEFAULT'],
'vendor' => $row,
];
}
return $columns;
} }

View File

@@ -30,7 +30,7 @@ class PdoDriver implements Dibi\Driver, Dibi\ResultDriver
/** @var PDO Connection resource */ /** @var PDO Connection resource */
private $connection; private $connection;
/** @var \PDOStatement Resultset resource */ /** @var \PDOStatement|NULL Resultset resource */
private $resultSet; private $resultSet;
/** @var int|FALSE Affected rows */ /** @var int|FALSE Affected rows */
@@ -40,7 +40,7 @@ class PdoDriver implements Dibi\Driver, Dibi\ResultDriver
private $driverName; private $driverName;
/** @var string */ /** @var string */
private $serverVersion; private $serverVersion = '';
/** /**
@@ -112,7 +112,7 @@ class PdoDriver implements Dibi\Driver, Dibi\ResultDriver
if (isset($list[$cmd])) { if (isset($list[$cmd])) {
$this->affectedRows = $this->connection->exec($sql); $this->affectedRows = $this->connection->exec($sql);
if ($this->affectedRows !== FALSE) { if ($this->affectedRows !== FALSE) {
return; return NULL;
} }
} else { } else {
$res = $this->connection->query($sql); $res = $this->connection->query($sql);
@@ -254,7 +254,7 @@ class PdoDriver implements Dibi\Driver, Dibi\ResultDriver
/** /**
* Encodes data for use in a SQL statement. * Encodes data for use in a SQL statement.
* @param mixed value * @param string value
* @return string encoded value * @return string encoded value
*/ */
public function escapeText($value) public function escapeText($value)
@@ -267,6 +267,10 @@ class PdoDriver implements Dibi\Driver, Dibi\ResultDriver
} }
/**
* @param string
* @return string
*/
public function escapeBinary($value) public function escapeBinary($value)
{ {
if ($this->driverName === 'odbc') { if ($this->driverName === 'odbc') {
@@ -277,6 +281,10 @@ class PdoDriver implements Dibi\Driver, Dibi\ResultDriver
} }
/**
* @param string
* @return string
*/
public function escapeIdentifier($value) public function escapeIdentifier($value)
{ {
switch ($this->driverName) { switch ($this->driverName) {
@@ -304,16 +312,24 @@ class PdoDriver implements Dibi\Driver, Dibi\ResultDriver
} }
/**
* @param bool
* @return string
*/
public function escapeBool($value) public function escapeBool($value)
{ {
if ($this->driverName === 'pgsql') { if ($this->driverName === 'pgsql') {
return $value ? 'TRUE' : 'FALSE'; return $value ? 'TRUE' : 'FALSE';
} else { } else {
return $value ? 1 : 0; return $value ? '1' : '0';
} }
} }
/**
* @param \DateTime|\DateTimeInterface|string|int
* @return string
*/
public function escapeDate($value) public function escapeDate($value)
{ {
if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) { if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) {
@@ -323,6 +339,10 @@ class PdoDriver implements Dibi\Driver, Dibi\ResultDriver
} }
/**
* @param \DateTime|\DateTimeInterface|string|int
* @return string
*/
public function escapeDateTime($value) public function escapeDateTime($value)
{ {
if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) { if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) {
@@ -394,6 +414,9 @@ class PdoDriver implements Dibi\Driver, Dibi\ResultDriver
/** /**
* Injects LIMIT/OFFSET to the SQL query. * Injects LIMIT/OFFSET to the SQL query.
* @param string
* @param int|NULL
* @param int|NULL
* @return void * @return void
*/ */
public function applyLimit(&$sql, $limit, $offset) public function applyLimit(&$sql, $limit, $offset)
@@ -548,7 +571,7 @@ class PdoDriver implements Dibi\Driver, Dibi\ResultDriver
/** /**
* Returns the result set resource. * Returns the result set resource.
* @return \PDOStatement * @return \PDOStatement|NULL
*/ */
public function getResultResource() public function getResultResource()
{ {

View File

@@ -26,10 +26,10 @@ class PostgreDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
{ {
use Dibi\Strict; use Dibi\Strict;
/** @var resource Connection resource */ /** @var resource|NULL */
private $connection; private $connection;
/** @var resource Resultset resource */ /** @var resource|NULL */
private $resultSet; private $resultSet;
/** @var bool */ /** @var bool */
@@ -100,7 +100,7 @@ class PostgreDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
} }
if (isset($config['schema'])) { if (isset($config['schema'])) {
$this->query('SET search_path TO "' . $config['schema'] . '"'); $this->query('SET search_path TO "' . implode('", "', (array) $config['schema']) . '"');
} }
} }
@@ -111,7 +111,7 @@ class PostgreDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
*/ */
public function disconnect() public function disconnect()
{ {
pg_close($this->connection); @pg_close($this->connection); // @ - connection can be already disconnected
} }
@@ -145,6 +145,7 @@ class PostgreDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
return $this->createResultDriver($res); return $this->createResultDriver($res);
} }
} }
return NULL;
} }
@@ -256,7 +257,7 @@ class PostgreDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
/** /**
* Returns the connection resource. * Returns the connection resource.
* @return mixed * @return resource|NULL
*/ */
public function getResource() public function getResource()
{ {
@@ -292,7 +293,7 @@ class PostgreDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
/** /**
* Encodes data for use in a SQL statement. * Encodes data for use in a SQL statement.
* @param mixed value * @param string value
* @return string encoded value * @return string encoded value
*/ */
public function escapeText($value) public function escapeText($value)
@@ -304,6 +305,10 @@ class PostgreDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
} }
/**
* @param string
* @return string
*/
public function escapeBinary($value) public function escapeBinary($value)
{ {
if (!is_resource($this->connection)) { if (!is_resource($this->connection)) {
@@ -313,6 +318,10 @@ class PostgreDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
} }
/**
* @param string
* @return string
*/
public function escapeIdentifier($value) public function escapeIdentifier($value)
{ {
// @see http://www.postgresql.org/docs/8.2/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS // @see http://www.postgresql.org/docs/8.2/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS
@@ -320,12 +329,20 @@ class PostgreDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
} }
/**
* @param bool
* @return string
*/
public function escapeBool($value) public function escapeBool($value)
{ {
return $value ? 'TRUE' : 'FALSE'; return $value ? 'TRUE' : 'FALSE';
} }
/**
* @param \DateTime|\DateTimeInterface|string|int
* @return string
*/
public function escapeDate($value) public function escapeDate($value)
{ {
if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) { if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) {
@@ -335,6 +352,10 @@ class PostgreDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
} }
/**
* @param \DateTime|\DateTimeInterface|string|int
* @return string
*/
public function escapeDateTime($value) public function escapeDateTime($value)
{ {
if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) { if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) {
@@ -380,6 +401,9 @@ class PostgreDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
/** /**
* Injects LIMIT/OFFSET to the SQL query. * Injects LIMIT/OFFSET to the SQL query.
* @param string
* @param int|NULL
* @param int|NULL
* @return void * @return void
*/ */
public function applyLimit(&$sql, $limit, $offset) public function applyLimit(&$sql, $limit, $offset)
@@ -475,7 +499,7 @@ class PostgreDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
/** /**
* Returns the result set resource. * Returns the result set resource.
* @return mixed * @return resource|NULL
*/ */
public function getResultResource() public function getResultResource()
{ {

View File

@@ -27,10 +27,10 @@ class Sqlite3Driver implements Dibi\Driver, Dibi\ResultDriver
{ {
use Dibi\Strict; use Dibi\Strict;
/** @var SQLite3 Connection resource */ /** @var SQLite3|NULL */
private $connection; private $connection;
/** @var \SQLite3Result Resultset resource */ /** @var \SQLite3Result|NULL */
private $resultSet; private $resultSet;
/** @var bool */ /** @var bool */
@@ -118,6 +118,7 @@ class Sqlite3Driver implements Dibi\Driver, Dibi\ResultDriver
} elseif ($res instanceof \SQLite3Result) { } elseif ($res instanceof \SQLite3Result) {
return $this->createResultDriver($res); return $this->createResultDriver($res);
} }
return NULL;
} }
@@ -209,7 +210,7 @@ class Sqlite3Driver implements Dibi\Driver, Dibi\ResultDriver
/** /**
* Returns the connection resource. * Returns the connection resource.
* @return mixed * @return SQLite3
*/ */
public function getResource() public function getResource()
{ {
@@ -245,7 +246,7 @@ class Sqlite3Driver implements Dibi\Driver, Dibi\ResultDriver
/** /**
* Encodes data for use in a SQL statement. * Encodes data for use in a SQL statement.
* @param mixed value * @param string value
* @return string encoded value * @return string encoded value
*/ */
public function escapeText($value) public function escapeText($value)
@@ -254,24 +255,40 @@ class Sqlite3Driver implements Dibi\Driver, Dibi\ResultDriver
} }
/**
* @param string
* @return string
*/
public function escapeBinary($value) public function escapeBinary($value)
{ {
return "X'" . bin2hex((string) $value) . "'"; return "X'" . bin2hex((string) $value) . "'";
} }
/**
* @param string
* @return string
*/
public function escapeIdentifier($value) public function escapeIdentifier($value)
{ {
return '[' . strtr($value, '[]', ' ') . ']'; return '[' . strtr($value, '[]', ' ') . ']';
} }
/**
* @param bool
* @return string
*/
public function escapeBool($value) public function escapeBool($value)
{ {
return $value ? 1 : 0; return $value ? '1' : '0';
} }
/**
* @param \DateTime|\DateTimeInterface|string|int
* @return string
*/
public function escapeDate($value) public function escapeDate($value)
{ {
if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) { if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) {
@@ -281,6 +298,10 @@ class Sqlite3Driver implements Dibi\Driver, Dibi\ResultDriver
} }
/**
* @param \DateTime|\DateTimeInterface|string|int
* @return string
*/
public function escapeDateTime($value) public function escapeDateTime($value)
{ {
if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) { if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) {
@@ -324,6 +345,9 @@ class Sqlite3Driver implements Dibi\Driver, Dibi\ResultDriver
/** /**
* Injects LIMIT/OFFSET to the SQL query. * Injects LIMIT/OFFSET to the SQL query.
* @param string
* @param int|NULL
* @param int|NULL
* @return void * @return void
*/ */
public function applyLimit(&$sql, $limit, $offset) public function applyLimit(&$sql, $limit, $offset)
@@ -431,7 +455,7 @@ class Sqlite3Driver implements Dibi\Driver, Dibi\ResultDriver
/** /**
* Returns the result set resource. * Returns the result set resource.
* @return mixed * @return \SQLite3Result|NULL
*/ */
public function getResultResource() public function getResultResource()
{ {

View File

@@ -29,10 +29,10 @@ class SqlsrvDriver implements Dibi\Driver, Dibi\ResultDriver
{ {
use Dibi\Strict; use Dibi\Strict;
/** @var resource Connection resource */ /** @var resource|NULL */
private $connection; private $connection;
/** @var resource Resultset resource */ /** @var resource|NULL */
private $resultSet; private $resultSet;
/** @var bool */ /** @var bool */
@@ -42,7 +42,7 @@ class SqlsrvDriver implements Dibi\Driver, Dibi\ResultDriver
private $affectedRows = FALSE; private $affectedRows = FALSE;
/** @var string */ /** @var string */
private $version; private $version = '';
/** /**
@@ -72,12 +72,17 @@ class SqlsrvDriver implements Dibi\Driver, Dibi\ResultDriver
$this->connection = $config['resource']; $this->connection = $config['resource'];
} else { } else {
// Default values $options = $config['options'];
if (!isset($config['options']['CharacterSet'])) {
$config['options']['CharacterSet'] = 'UTF-8';
}
$this->connection = sqlsrv_connect($config['host'], (array) $config['options']); // Default values
if (!isset($options['CharacterSet'])) {
$options['CharacterSet'] = 'UTF-8';
}
$options['PWD'] = (string) $options['PWD'];
$options['UID'] = (string) $options['UID'];
$options['Database'] = (string) $options['Database'];
$this->connection = sqlsrv_connect($config['host'], $options);
} }
if (!is_resource($this->connection)) { if (!is_resource($this->connection)) {
@@ -94,7 +99,7 @@ class SqlsrvDriver implements Dibi\Driver, Dibi\ResultDriver
*/ */
public function disconnect() public function disconnect()
{ {
sqlsrv_close($this->connection); @sqlsrv_close($this->connection); // @ - connection can be already disconnected
} }
@@ -117,6 +122,7 @@ class SqlsrvDriver implements Dibi\Driver, Dibi\ResultDriver
$this->affectedRows = sqlsrv_rows_affected($res); $this->affectedRows = sqlsrv_rows_affected($res);
return $this->createResultDriver($res); return $this->createResultDriver($res);
} }
return NULL;
} }
@@ -136,7 +142,7 @@ class SqlsrvDriver implements Dibi\Driver, Dibi\ResultDriver
*/ */
public function getInsertId($sequence) public function getInsertId($sequence)
{ {
$res = sqlsrv_query($this->connection, 'SELECT @@IDENTITY'); $res = sqlsrv_query($this->connection, 'SELECT SCOPE_IDENTITY()');
if (is_resource($res)) { if (is_resource($res)) {
$row = sqlsrv_fetch_array($res, SQLSRV_FETCH_NUMERIC); $row = sqlsrv_fetch_array($res, SQLSRV_FETCH_NUMERIC);
return $row[0]; return $row[0];
@@ -183,7 +189,7 @@ class SqlsrvDriver implements Dibi\Driver, Dibi\ResultDriver
/** /**
* Returns the connection resource. * Returns the connection resource.
* @return mixed * @return resource|NULL
*/ */
public function getResource() public function getResource()
{ {
@@ -219,7 +225,7 @@ class SqlsrvDriver implements Dibi\Driver, Dibi\ResultDriver
/** /**
* Encodes data for use in a SQL statement. * Encodes data for use in a SQL statement.
* @param mixed value * @param string value
* @return string encoded value * @return string encoded value
*/ */
public function escapeText($value) public function escapeText($value)
@@ -228,12 +234,20 @@ class SqlsrvDriver implements Dibi\Driver, Dibi\ResultDriver
} }
/**
* @param string
* @return string
*/
public function escapeBinary($value) public function escapeBinary($value)
{ {
return "'" . str_replace("'", "''", $value) . "'"; return "'" . str_replace("'", "''", $value) . "'";
} }
/**
* @param string
* @return string
*/
public function escapeIdentifier($value) public function escapeIdentifier($value)
{ {
// @see https://msdn.microsoft.com/en-us/library/ms176027.aspx // @see https://msdn.microsoft.com/en-us/library/ms176027.aspx
@@ -241,12 +255,20 @@ class SqlsrvDriver implements Dibi\Driver, Dibi\ResultDriver
} }
/**
* @param bool
* @return string
*/
public function escapeBool($value) public function escapeBool($value)
{ {
return $value ? 1 : 0; return $value ? '1' : '0';
} }
/**
* @param \DateTime|\DateTimeInterface|string|int
* @return string
*/
public function escapeDate($value) public function escapeDate($value)
{ {
if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) { if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) {
@@ -256,6 +278,10 @@ class SqlsrvDriver implements Dibi\Driver, Dibi\ResultDriver
} }
/**
* @param \DateTime|\DateTimeInterface|string|int
* @return string
*/
public function escapeDateTime($value) public function escapeDateTime($value)
{ {
if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) { if (!$value instanceof \DateTime && !$value instanceof \DateTimeInterface) {
@@ -299,6 +325,9 @@ class SqlsrvDriver implements Dibi\Driver, Dibi\ResultDriver
/** /**
* Injects LIMIT/OFFSET to the SQL query. * Injects LIMIT/OFFSET to the SQL query.
* @param string
* @param int|NULL
* @param int|NULL
* @return void * @return void
*/ */
public function applyLimit(&$sql, $limit, $offset) public function applyLimit(&$sql, $limit, $offset)
@@ -306,7 +335,7 @@ class SqlsrvDriver implements Dibi\Driver, Dibi\ResultDriver
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 } elseif (version_compare($this->version, '11', '<')) { // 11 == SQL Server 2012
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.');
@@ -400,7 +429,7 @@ class SqlsrvDriver implements Dibi\Driver, Dibi\ResultDriver
/** /**
* Returns the result set resource. * Returns the result set resource.
* @return mixed * @return resource|NULL
*/ */
public function getResultResource() public function getResultResource()
{ {

View File

@@ -25,6 +25,7 @@ namespace Dibi;
* @method Fluent innerJoin(...$table) * @method Fluent innerJoin(...$table)
* @method Fluent rightJoin(...$table) * @method Fluent rightJoin(...$table)
* @method Fluent outerJoin(...$table) * @method Fluent outerJoin(...$table)
* @method Fluent as(...$field)
* @method Fluent on(...$cond) * @method Fluent on(...$cond)
* @method Fluent using(...$cond) * @method Fluent using(...$cond)
*/ */
@@ -180,7 +181,7 @@ class Fluent implements IDataSource
return $this; return $this;
} elseif (is_string($arg) && preg_match('#^[a-z:_][a-z0-9_.:]*\z#i', $arg)) { // identifier } elseif (is_string($arg) && preg_match('#^[a-z:_][a-z0-9_.:]*\z#i', $arg)) { // identifier
$args = ['%n', $arg]; $args = [$clause === 'AS' ? '%N' : '%n', $arg];
} elseif (is_array($arg) || ($arg instanceof \Traversable && !$arg instanceof self)) { // any array } elseif (is_array($arg) || ($arg instanceof \Traversable && !$arg instanceof self)) { // any array
if (isset(self::$modifiers[$clause])) { if (isset(self::$modifiers[$clause])) {
@@ -299,7 +300,7 @@ class Fluent implements IDataSource
/** /**
* Generates and executes SQL query. * Generates and executes SQL query.
* @param mixed what to return? * @param mixed what to return?
* @return Result|int result set object (if any) * @return Result|int result set or number of affected rows
* @throws Exception * @throws Exception
*/ */
public function execute($return = NULL) public function execute($return = NULL)
@@ -318,7 +319,7 @@ class Fluent implements IDataSource
/** /**
* Generates, executes SQL query and fetches the single row. * Generates, executes SQL query and fetches the single row.
* @return Row|FALSE array on success, FALSE if no next record * @return Row|FALSE
*/ */
public function fetch() public function fetch()
{ {

View File

@@ -50,14 +50,14 @@ class Helpers
if ($i === 0) { if ($i === 0) {
echo "\n<table class=\"dump\">\n<thead>\n\t<tr>\n\t\t<th>#row</th>\n"; echo "\n<table class=\"dump\">\n<thead>\n\t<tr>\n\t\t<th>#row</th>\n";
foreach ($row as $col => $foo) { foreach ($row as $col => $foo) {
echo "\t\t<th>" . htmlSpecialChars($col) . "</th>\n"; echo "\t\t<th>" . htmlSpecialChars((string) $col) . "</th>\n";
} }
echo "\t</tr>\n</thead>\n<tbody>\n"; echo "\t</tr>\n</thead>\n<tbody>\n";
} }
echo "\t<tr>\n\t\t<th>", $i, "</th>\n"; echo "\t<tr>\n\t\t<th>", $i, "</th>\n";
foreach ($row as $col) { foreach ($row as $col) {
echo "\t\t<td>", htmlSpecialChars($col), "</td>\n"; echo "\t\t<td>", htmlSpecialChars((string) $col), "</td>\n";
} }
echo "\t</tr>\n"; echo "\t</tr>\n";
} }
@@ -183,7 +183,7 @@ class Helpers
static $patterns = [ static $patterns = [
'^_' => Type::TEXT, // PostgreSQL arrays '^_' => Type::TEXT, // PostgreSQL arrays
'BYTEA|BLOB|BIN' => Type::BINARY, 'BYTEA|BLOB|BIN' => Type::BINARY,
'TEXT|CHAR|POINT|INTERVAL' => Type::TEXT, 'TEXT|CHAR|POINT|INTERVAL|STRING' => Type::TEXT,
'YEAR|BYTE|COUNTER|SERIAL|INT|LONG|SHORT|^TINY$' => Type::INTEGER, 'YEAR|BYTE|COUNTER|SERIAL|INT|LONG|SHORT|^TINY$' => Type::INTEGER,
'CURRENCY|REAL|MONEY|FLOAT|DOUBLE|DECIMAL|NUMERIC|NUMBER' => Type::FLOAT, 'CURRENCY|REAL|MONEY|FLOAT|DOUBLE|DECIMAL|NUMERIC|NUMBER' => Type::FLOAT,
'^TIME$' => Type::TIME, '^TIME$' => Type::TIME,

View File

@@ -19,10 +19,10 @@ use Dibi\Type;
* @property-read Table $table * @property-read Table $table
* @property-read string $type * @property-read string $type
* @property-read mixed $nativeType * @property-read mixed $nativeType
* @property-read int $size * @property-read int|NULL $size
* @property-read bool $unsigned * @property-read bool|NULL $unsigned
* @property-read bool $nullable * @property-read bool|NULL $nullable
* @property-read bool $autoIncrement * @property-read bool|NULL $autoIncrement
* @property-read mixed $default * @property-read mixed $default
*/ */
class Column class Column
@@ -83,7 +83,7 @@ class Column
/** /**
* @return string * @return string|NULL
*/ */
public function getTableName() public function getTableName()
{ {
@@ -101,7 +101,7 @@ class Column
/** /**
* @return mixed * @return string
*/ */
public function getNativeType() public function getNativeType()
{ {
@@ -110,7 +110,7 @@ class Column
/** /**
* @return int * @return int|NULL
*/ */
public function getSize() public function getSize()
{ {
@@ -119,7 +119,7 @@ class Column
/** /**
* @return bool * @return bool|NULL
*/ */
public function isUnsigned() public function isUnsigned()
{ {
@@ -128,7 +128,7 @@ class Column
/** /**
* @return bool * @return bool|NULL
*/ */
public function isNullable() public function isNullable()
{ {
@@ -137,7 +137,7 @@ class Column
/** /**
* @return bool * @return bool|NULL
*/ */
public function isAutoIncrement() public function isAutoIncrement()
{ {

View File

@@ -184,7 +184,7 @@ class Result implements IDataSource
/** /**
* Fetches the row at current position, process optional type conversion. * Fetches the row at current position, process optional type conversion.
* and moves the internal cursor to the next position * and moves the internal cursor to the next position
* @return Row|FALSE array on success, FALSE if no next record * @return Row|FALSE
*/ */
final public function fetch() final public function fetch()
{ {
@@ -271,7 +271,7 @@ class Result implements IDataSource
} }
$data = NULL; $data = NULL;
$assoc = preg_split('#(\[\]|->|=|\|)#', $assoc, NULL, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); $assoc = preg_split('#(\[\]|->|=|\|)#', $assoc, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
// check columns // check columns
foreach ($assoc as $as) { foreach ($assoc as $as) {
@@ -499,7 +499,7 @@ class Result implements IDataSource
: $tmp; : $tmp;
} elseif ($type === Type::FLOAT) { } elseif ($type === Type::FLOAT) {
$value = ltrim($value, '0'); $value = ltrim((string) $value, '0');
$p = strpos($value, '.'); $p = strpos($value, '.');
if ($p !== FALSE) { if ($p !== FALSE) {
$value = rtrim(rtrim($value, '0'), '.'); $value = rtrim(rtrim($value, '0'), '.');
@@ -515,7 +515,7 @@ class Result implements IDataSource
$row[$key] = ((bool) $value) && $value !== 'f' && $value !== 'F'; $row[$key] = ((bool) $value) && $value !== 'f' && $value !== 'F';
} elseif ($type === Type::DATETIME || $type === Type::DATE || $type === Type::TIME) { } elseif ($type === Type::DATETIME || $type === Type::DATE || $type === Type::TIME) {
if ((int) $value !== 0 || substr((string) $value, 0, 3) === '00:') { // '', NULL, FALSE, '0000-00-00', ... if ($value && substr((string) $value, 0, 3) !== '000') { // '', NULL, FALSE, '0000-00-00', ...
$value = new DateTime($value); $value = new DateTime($value);
$row[$key] = empty($this->formats[$type]) ? $value : $value->format($this->formats[$type]); $row[$key] = empty($this->formats[$type]) ? $value : $value->format($this->formats[$type]);
} else { } else {
@@ -558,9 +558,9 @@ class Result implements IDataSource
/** /**
* Sets data format. * Sets date format.
* @param string type (use constant Type::*) * @param string
* @param string format * @param string|NULL format
* @return self * @return self
*/ */
final public function setFormat($type, $format) final public function setFormat($type, $format)
@@ -572,7 +572,7 @@ class Result implements IDataSource
/** /**
* Returns data format. * Returns data format.
* @return string * @return string|NULL
*/ */
final public function getFormat($type) final public function getFormat($type)
{ {

View File

@@ -27,7 +27,7 @@ class ResultIterator implements \Iterator, \Countable
/** @var Result */ /** @var Result */
private $result; private $result;
/** @var int */ /** @var mixed */
private $row; private $row;
/** @var int */ /** @var int */

View File

@@ -38,7 +38,7 @@ class Row implements \ArrayAccess, \IteratorAggregate, \Countable
{ {
$time = $this[$key]; $time = $this[$key];
if (!$time instanceof DateTime) { if (!$time instanceof DateTime) {
if ((int) $time === 0 && substr((string) $time, 0, 3) !== '00:') { // '', NULL, FALSE, '0000-00-00', ... if (!$time || substr((string) $time, 0, 3) === '000') { // '', NULL, FALSE, '0000-00-00', ...
return NULL; return NULL;
} }
$time = new DateTime($time); $time = new DateTime($time);

View File

@@ -105,7 +105,7 @@ trait Strict
/** /**
* @param string method name * @param string method name
* @param callabke * @param callable
* @return mixed * @return mixed
*/ */
public static function extensionMethod($name, $callback = NULL) public static function extensionMethod($name, $callback = NULL)

View File

@@ -225,7 +225,7 @@ final class Translator
case 'n': // key, key, ... identifier names case 'n': // key, key, ... identifier names
foreach ($value as $k => $v) { foreach ($value as $k => $v) {
if (is_string($k)) { if (is_string($k)) {
$vx[] = $this->identifiers->$k . (empty($v) ? '' : ' AS ' . $this->identifiers->$v); $vx[] = $this->identifiers->$k . (empty($v) ? '' : ' AS ' . $this->driver->escapeIdentifier($v));
} else { } else {
$pair = explode('%', $v, 2); // split into identifier & modifier $pair = explode('%', $v, 2); // split into identifier & modifier
$vx[] = $this->identifiers->{$pair[0]}; $vx[] = $this->identifiers->{$pair[0]};
@@ -246,7 +246,7 @@ final class Translator
case 'in':// replaces scalar %in modifier! case 'in':// replaces scalar %in modifier!
case 'l': // (val, val, ...) case 'l': // (val, val, ...)
foreach ($value as $k => $v) { foreach ($value as $k => $v) {
$pair = explode('%', $k, 2); // split into identifier & modifier $pair = explode('%', (string) $k, 2); // split into identifier & modifier
$vx[] = $this->formatValue($v, isset($pair[1]) ? $pair[1] : (is_array($v) ? 'ex' : FALSE)); $vx[] = $this->formatValue($v, isset($pair[1]) ? $pair[1] : (is_array($v) ? 'ex' : FALSE));
} }
return '(' . (($vx || $modifier === 'l') ? implode(', ', $vx) : 'NULL') . ')'; return '(' . (($vx || $modifier === 'l') ? implode(', ', $vx) : 'NULL') . ')';
@@ -316,7 +316,7 @@ final class Translator
if ($value !== NULL && !is_scalar($value)) { // array is already processed if ($value !== NULL && !is_scalar($value)) { // array is already processed
if ($value instanceof Literal && ($modifier === 'sql' || $modifier === 'SQL')) { if ($value instanceof Literal && ($modifier === 'sql' || $modifier === 'SQL')) {
$modifier = 'SQL'; $modifier = 'SQL';
} elseif (($value instanceof \DateTime || $value instanceof \DateTimeInterface) && ($modifier === 'd' || $modifier === 't')) { } elseif (($value instanceof \DateTime || $value instanceof \DateTimeInterface) && ($modifier === 'd' || $modifier === 't' || $modifier === 'dt')) {
// continue // continue
} else { } else {
$type = is_object($value) ? get_class($value) : gettype($value); $type = is_object($value) ? get_class($value) : gettype($value);
@@ -326,7 +326,7 @@ final class Translator
switch ($modifier) { switch ($modifier) {
case 's': // string case 's': // string
return $value === NULL ? 'NULL' : $this->driver->escapeText($value); return $value === NULL ? 'NULL' : $this->driver->escapeText((string) $value);
case 'bin':// binary case 'bin':// binary
return $value === NULL ? 'NULL' : $this->driver->escapeBinary($value); return $value === NULL ? 'NULL' : $this->driver->escapeBinary($value);
@@ -336,7 +336,7 @@ final class Translator
case 'sN': // string or NULL case 'sN': // string or NULL
case 'sn': case 'sn':
return $value == '' ? 'NULL' : $this->driver->escapeText($value); // notice two equal signs return $value == '' ? 'NULL' : $this->driver->escapeText((string) $value); // notice two equal signs
case 'in': // deprecated case 'in': // deprecated
trigger_error('Modifier %in is deprecated, use %iN.', E_USER_DEPRECATED); trigger_error('Modifier %in is deprecated, use %iN.', E_USER_DEPRECATED);
@@ -380,9 +380,12 @@ final class Translator
} }
case 'by': case 'by':
case 'n': // identifier name case 'n': // composed identifier name
return $this->identifiers->$value; return $this->identifiers->$value;
case 'N': // identifier name
return $this->driver->escapeIdentifier($value);
case 'ex': case 'ex':
case 'sql': // preserve as dibi-SQL (TODO: leave only %ex) case 'sql': // preserve as dibi-SQL (TODO: leave only %ex)
$value = (string) $value; $value = (string) $value;

View File

@@ -22,8 +22,8 @@ class dibi
/** version */ /** version */
const const
VERSION = '3.0.2', VERSION = '3.0.9',
REVISION = 'released on 2016-01-29'; REVISION = 'released on 2018-03-09';
/** sorting order */ /** sorting order */
const const
@@ -90,7 +90,7 @@ class dibi
* @return Dibi\Connection * @return Dibi\Connection
* @throws Dibi\Exception * @throws Dibi\Exception
*/ */
public static function connect($config = [], $name = 0) public static function connect($config = [], $name = '0')
{ {
return self::$connection = self::$registry[$name] = new Dibi\Connection($config, $name); return self::$connection = self::$registry[$name] = new Dibi\Connection($config, $name);
} }
@@ -167,7 +167,7 @@ class dibi
/** /**
* Generates and executes SQL query - Monostate for Dibi\Connection::query(). * Generates and executes SQL query - Monostate for Dibi\Connection::query().
* @param array|mixed one or more arguments * @param array|mixed one or more arguments
* @return Dibi\Result|int result set object (if any) * @return Dibi\Result|int result set or number of affected rows
* @throws Dibi\Exception * @throws Dibi\Exception
*/ */
public static function query($args) public static function query($args)
@@ -180,7 +180,7 @@ class dibi
/** /**
* Executes the SQL query - Monostate for Dibi\Connection::nativeQuery(). * Executes the SQL query - Monostate for Dibi\Connection::nativeQuery().
* @param string SQL statement. * @param string SQL statement.
* @return Dibi\Result|int result set object (if any) * @return Dibi\Result|int result set or number of affected rows
*/ */
public static function nativeQuery($sql) public static function nativeQuery($sql)
{ {
@@ -241,7 +241,7 @@ class dibi
/** /**
* Executes SQL query and fetch first column - Monostate for Dibi\Connection::query() & fetchSingle(). * Executes SQL query and fetch first column - Monostate for Dibi\Connection::query() & fetchSingle().
* @param array|mixed one or more arguments * @param array|mixed one or more arguments
* @return string * @return mixed
* @throws Dibi\Exception * @throws Dibi\Exception
*/ */
public static function fetchSingle($args) public static function fetchSingle($args)
@@ -254,7 +254,7 @@ class dibi
/** /**
* Executes SQL query and fetch pairs - Monostate for Dibi\Connection::query() & fetchPairs(). * Executes SQL query and fetch pairs - Monostate for Dibi\Connection::query() & fetchPairs().
* @param array|mixed one or more arguments * @param array|mixed one or more arguments
* @return string * @return array
* @throws Dibi\Exception * @throws Dibi\Exception
*/ */
public static function fetchPairs($args) public static function fetchPairs($args)
@@ -382,7 +382,7 @@ class dibi
/** /**
* @param string column name * @param mixed column name
* @return Dibi\Fluent * @return Dibi\Fluent
*/ */
public static function select($args) public static function select($args)

View File

@@ -13,8 +13,6 @@ namespace Dibi;
*/ */
class Exception extends \Exception class Exception extends \Exception
{ {
use Strict;
/** @var string|NULL */ /** @var string|NULL */
private $sql; private $sql;
@@ -25,7 +23,7 @@ class Exception extends \Exception
* @param mixed * @param mixed
* @param string SQL command * @param string SQL command
*/ */
public function __construct($message = NULL, $code = 0, $sql = NULL) public function __construct($message = '', $code = 0, $sql = NULL)
{ {
parent::__construct($message); parent::__construct($message);
$this->code = $code; $this->code = $code;
@@ -66,7 +64,6 @@ class DriverException extends Exception
*/ */
class PcreException extends Exception class PcreException extends Exception
{ {
use Strict;
public function __construct($message = '%msg.') public function __construct($message = '%msg.')
{ {

View File

@@ -97,19 +97,39 @@ interface Driver
/** /**
* Encodes data for use in a SQL statement. * Encodes data for use in a SQL statement.
* @param mixed value * @param string value
* @return string encoded value * @return string encoded value
*/ */
function escapeText($value); function escapeText($value);
/**
* @param string
* @return string
*/
function escapeBinary($value); function escapeBinary($value);
/**
* @param string
* @return string
*/
function escapeIdentifier($value); function escapeIdentifier($value);
/**
* @param bool
* @return string
*/
function escapeBool($value); function escapeBool($value);
/**
* @param \DateTime|\DateTimeInterface|string|int
* @return string
*/
function escapeDate($value); function escapeDate($value);
/**
* @param \DateTime|\DateTimeInterface|string|int
* @return string
*/
function escapeDateTime($value); function escapeDateTime($value);
/** /**
@@ -122,6 +142,9 @@ interface Driver
/** /**
* Injects LIMIT/OFFSET to the SQL query. * Injects LIMIT/OFFSET to the SQL query.
* @param string
* @param int|NULL
* @param int|NULL
* @return void * @return void
*/ */
function applyLimit(&$sql, $limit, $offset); function applyLimit(&$sql, $limit, $offset);

View File

@@ -66,7 +66,6 @@ spl_autoload_register(function ($class) {
'Dibi\Translator' => 'Translator.php', 'Dibi\Translator' => 'Translator.php',
'Dibi\Type' => 'Type.php', 'Dibi\Type' => 'Type.php',
], $old2new = [ ], $old2new = [
'Dibi' => 'dibi.php',
'DibiColumnInfo' => 'Dibi\Reflection\Column', 'DibiColumnInfo' => 'Dibi\Reflection\Column',
'DibiConnection' => 'Dibi\Connection', 'DibiConnection' => 'Dibi\Connection',
'DibiDatabaseInfo' => 'Dibi\Reflection\Database', 'DibiDatabaseInfo' => 'Dibi\Reflection\Database',

4
tests/.coveralls.yml Normal file
View File

@@ -0,0 +1,4 @@
# for php-coveralls
service_name: travis-ci
coverage_clover: coverage.xml
json_path: coverage.json

View File

@@ -73,13 +73,13 @@ system = sqlsrv
;password = "Password12!" ;password = "Password12!"
;system = sqlsrv ;system = sqlsrv
[sqlsrv 2014] ;[sqlsrv 2014]
driver = sqlsrv ;driver = sqlsrv
host = "(local)\SQL2014" ;host = "(local)\SQL2014"
database = master ;database = master
username = sa ;username = sa
password = "Password12!" ;password = "Password12!"
system = sqlsrv ;system = sqlsrv
;[sqlsrv 2014-pdo] ;[sqlsrv 2014-pdo]
;driver = pdo ;driver = pdo

View File

@@ -29,10 +29,22 @@ test(function () use ($config) { // lazy
test(function () use ($config) { // query string test(function () use ($config) { // query string
$conn = new Connection(http_build_query($config, NULL, '&')); $conn = new Connection(http_build_query($config, '', '&'));
Assert::true($conn->isConnected()); Assert::true($conn->isConnected());
Assert::null($conn->getConfig('lazy')); Assert::null($conn->getConfig('lazy'));
Assert::same($config['driver'], $conn->getConfig('driver')); Assert::same($config['driver'], $conn->getConfig('driver'));
Assert::type('Dibi\Driver', $conn->getDriver()); Assert::type('Dibi\Driver', $conn->getDriver());
}); });
test(function () use ($config) {
$conn = new Connection($config);
Assert::true($conn->isConnected());
$conn->disconnect();
Assert::false($conn->isConnected());
$conn->disconnect();
Assert::false($conn->isConnected());
});

View File

@@ -26,19 +26,19 @@ Assert::same(
(string) $fluent (string) $fluent
); );
$fluent->from('table')->as('tableAlias') $fluent->from('table')->as('table.Alias')
->innerJoin('table1')->on('table.col = table1.col') ->innerJoin('table1')->on('table.col = table1.col')
->innerJoin('table2')->on('table.col = table2.col'); ->innerJoin('table2')->on('table.col = table2.col');
Assert::same( Assert::same(
reformat('SELECT * , [a] , [b] AS [bAlias] , [c], [d], [e] , [d] FROM [table] AS [tableAlias] INNER JOIN [table1] ON table.col = table1.col INNER JOIN [table2] ON table.col = table2.col'), reformat('SELECT * , [a] , [b] AS [bAlias] , [c], [d], [e] , [d] FROM [table] AS [table.Alias] INNER JOIN [table1] ON table.col = table1.col INNER JOIN [table2] ON table.col = table2.col'),
(string) $fluent (string) $fluent
); );
$fluent->from('anotherTable'); $fluent->from('anotherTable');
Assert::same( Assert::same(
reformat('SELECT * , [a] , [b] AS [bAlias] , [c], [d], [e] , [d] FROM [table] AS [tableAlias] INNER JOIN [table1] ON table.col = table1.col INNER JOIN [table2] ON table.col = table2.col , [anotherTable]'), reformat('SELECT * , [a] , [b] AS [bAlias] , [c], [d], [e] , [d] FROM [table] AS [table.Alias] INNER JOIN [table1] ON table.col = table1.col INNER JOIN [table2] ON table.col = table2.col , [anotherTable]'),
(string) $fluent (string) $fluent
); );

View File

@@ -139,7 +139,7 @@ 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]));
Assert::same(['col' => 0], $result->test(['col' => ''])); Assert::same(['col' => 0], @$result->test(['col' => ''])); // triggers warning in PHP 7.1
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']));
Assert::same(['col' => 10], $result->test(['col' => '10'])); Assert::same(['col' => 10], $result->test(['col' => '10']));

View File

@@ -0,0 +1,28 @@
<?php
/**
* @dataProvider? ../databases.ini sqlsrv
*/
use Tester\Assert;
require __DIR__ . '/bootstrap.php';
$conn = new Dibi\Connection($config);
$conn->loadFile(__DIR__ . "/data/sqlsrv.insert.sql");
for ($i = 1; $i <= 5; $i++) {
$conn->query('INSERT INTO %n DEFAULT VALUES', 'aaa');
Assert::equal($i, $conn->getInsertId());
}
$conn->query('INSERT INTO %n DEFAULT VALUES', 'aab');
Assert::equal(1, $conn->getInsertId());
$conn->query(
'CREATE TRIGGER %n ON %n AFTER INSERT AS INSERT INTO %n DEFAULT VALUES',
'UpdAAB', 'aab', 'aaa'
);
$conn->query('INSERT INTO %n DEFAULT VALUES', 'aab');
Assert::equal(2, $conn->getInsertId());

View File

@@ -280,7 +280,7 @@ $array2 = ['one', 'two', 'three'];
$array3 = [ $array3 = [
'col1' => 'one', 'col1' => 'one',
'col2' => 'two', 'col2' => 'two',
'col3' => 'three', 'col3' => 'thr.ee',
]; ];
$array4 = [ $array4 = [
'a' => 12, 'a' => 12,
@@ -301,8 +301,8 @@ WHERE (`test`.`a` LIKE '1995-03-01'
OR `b2` IN ('1', '2', '3' ) OR `b2` IN ('1', '2', '3' )
OR `b3` IN ( ) OR `b3` IN ( )
OR `b4` IN ( 'one', 'two', 'three' ) OR `b4` IN ( 'one', 'two', 'three' )
OR `b5` IN (`col1` AS `one`, `col2` AS `two`, `col3` AS `three` ) OR `b5` IN (`col1` AS `one`, `col2` AS `two`, `col3` AS `thr.ee` )
OR `b6` IN ('one', 'two', 'three') OR `b6` IN ('one', 'two', 'thr.ee')
OR `b7` IN (NULL) OR `b7` IN (NULL)
OR `b8` IN (RAND() `col1` > `col2` ) OR `b8` IN (RAND() `col1` > `col2` )
OR `b9` IN (RAND(), [col1] > [col2] ) OR `b9` IN (RAND(), [col1] > [col2] )
@@ -322,8 +322,8 @@ WHERE ("test"."a" LIKE \'1995-03-01\'
OR "b2" IN (\'1\', \'2\', \'3\' ) OR "b2" IN (\'1\', \'2\', \'3\' )
OR "b3" IN ( ) OR "b3" IN ( )
OR "b4" IN ( \'one\', \'two\', \'three\' ) OR "b4" IN ( \'one\', \'two\', \'three\' )
OR "b5" IN ("col1" AS "one", "col2" AS "two", "col3" AS "three" ) OR "b5" IN ("col1" AS "one", "col2" AS "two", "col3" AS "thr.ee" )
OR "b6" IN (\'one\', \'two\', \'three\') OR "b6" IN (\'one\', \'two\', \'thr.ee\')
OR "b7" IN (NULL) OR "b7" IN (NULL)
OR "b8" IN (RAND() "col1" > "col2" ) OR "b8" IN (RAND() "col1" > "col2" )
OR "b9" IN (RAND(), [col1] > [col2] ) OR "b9" IN (RAND(), [col1] > [col2] )
@@ -343,8 +343,8 @@ WHERE ([test].[a] LIKE #03/01/1995#
OR [b2] IN ('1', '2', '3' ) OR [b2] IN ('1', '2', '3' )
OR [b3] IN ( ) OR [b3] IN ( )
OR [b4] IN ( 'one', 'two', 'three' ) OR [b4] IN ( 'one', 'two', 'three' )
OR [b5] IN ([col1] AS [one], [col2] AS [two], [col3] AS [three] ) OR [b5] IN ([col1] AS [one], [col2] AS [two], [col3] AS [thr.ee] )
OR [b6] IN ('one', 'two', 'three') OR [b6] IN ('one', 'two', 'thr.ee')
OR [b7] IN (NULL) OR [b7] IN (NULL)
OR [b8] IN (RAND() [col1] > [col2] ) OR [b8] IN (RAND() [col1] > [col2] )
OR [b9] IN (RAND(), [col1] > [col2] ) OR [b9] IN (RAND(), [col1] > [col2] )
@@ -364,8 +364,8 @@ WHERE ([test].[a] LIKE '1995-03-01'
OR [b2] IN ('1', '2', '3' ) OR [b2] IN ('1', '2', '3' )
OR [b3] IN ( ) OR [b3] IN ( )
OR [b4] IN ( 'one', 'two', 'three' ) OR [b4] IN ( 'one', 'two', 'three' )
OR [b5] IN ([col1] AS [one], [col2] AS [two], [col3] AS [three] ) OR [b5] IN ([col1] AS [one], [col2] AS [two], [col3] AS [thr.ee] )
OR [b6] IN ('one', 'two', 'three') OR [b6] IN ('one', 'two', 'thr.ee')
OR [b7] IN (NULL) OR [b7] IN (NULL)
OR [b8] IN (RAND() [col1] > [col2] ) OR [b8] IN (RAND() [col1] > [col2] )
OR [b9] IN (RAND(), [col1] > [col2] ) OR [b9] IN (RAND(), [col1] > [col2] )
@@ -522,7 +522,7 @@ Assert::same(
Assert::same( Assert::same(
reformat('INSERT INTO 0'), reformat('INSERT INTO 0'),
$conn->translate('INSERT INTO %f', 'ahoj') @$conn->translate('INSERT INTO %f', 'ahoj') // triggers warning in PHP 7.1
); );
@@ -542,6 +542,12 @@ Assert::same(
); );
Assert::same(
reformat('SELECT [a].[b] AS [c.d]'),
$conn->translate('SELECT %n AS %N', 'a.b', 'c.d')
);
setLocale(LC_ALL, 'czech'); setLocale(LC_ALL, 'czech');
Assert::same( Assert::same(

View File

@@ -1,5 +1,3 @@
/*!40102 SET storage_engine = InnoDB */;
DROP DATABASE IF EXISTS dibi_test; DROP DATABASE IF EXISTS dibi_test;
CREATE DATABASE dibi_test; CREATE DATABASE dibi_test;
USE dibi_test; USE dibi_test;

View File

@@ -0,0 +1,5 @@
IF OBJECT_ID('aaa', 'U') IS NOT NULL DROP TABLE aaa;
IF OBJECT_ID('aab', 'U') IS NOT NULL DROP TABLE aab;
CREATE TABLE aaa ( [id] int NOT NULL IDENTITY PRIMARY KEY )
CREATE TABLE aab ( [id] int NOT NULL IDENTITY PRIMARY KEY )

17
tests/php7-win.ini Normal file
View File

@@ -0,0 +1,17 @@
[PHP]
extension_dir = "./ext"
;extension=php_mssql.dll
extension=php_mysqli.dll
;extension=php_oci8.dll
;extension=php_oci8_11g.dll
;extension=php_pdo_firebird.dll
;extension=php_pdo_mssql.dll
extension=php_pdo_mysql.dll
;extension=php_pdo_oci.dll
extension=php_pdo_odbc.dll
extension=php_pdo_pgsql.dll
extension=php_pdo_sqlite.dll
extension=php_pgsql.dll
extension=php_sqlite3.dll
extension=php_sqlsrv_ts.dll
extension=php_odbc.dll