mirror of
https://github.com/dg/dibi.git
synced 2025-09-03 02:52:47 +02:00
Compare commits
19 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
7762da1bbb | ||
|
6f6a63881a | ||
|
999f51a7bd | ||
|
64b3d0c6f4 | ||
|
06440ab6dc | ||
|
b341b66d43 | ||
|
aac83ba849 | ||
|
2de32b66e1 | ||
|
1829366fc9 | ||
|
94f34a2a33 | ||
|
a3e5ac86f7 | ||
|
89d7148b04 | ||
|
38aa393dc3 | ||
|
84f9a6fdd8 | ||
|
eb64adeb05 | ||
|
3779a5034a | ||
|
090bb2f182 | ||
|
056c0702a1 | ||
|
020b15c0e2 |
27
contributing.md
Normal file
27
contributing.md
Normal file
@@ -0,0 +1,27 @@
|
||||
How to contribute & use the issue tracker
|
||||
=========================================
|
||||
|
||||
The issue tracker is the preferred channel for bug reports, features requests
|
||||
and submitting pull requests, but please respect the following restrictions:
|
||||
|
||||
* Please **do not** use the issue tracker for personal support requests (use
|
||||
[dibi forum](http://forum.dibiphp.com) or [Stack Overflow](http://stackoverflow.com)).
|
||||
|
||||
* Please **do not** derail or troll issues. Keep the discussion on topic and
|
||||
respect the opinions of others.
|
||||
|
||||
* Use the GitHub **issue search** — check if the issue has already been
|
||||
reported.
|
||||
|
||||
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. 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
|
||||
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
|
||||
to [read the guidelines](http://nette.org/en/contributing) in order to make
|
||||
the contribution process easy and effective for everyone involved.
|
||||
|
||||
Thanks!
|
@@ -36,7 +36,8 @@ class DibiNette21Extension extends Nette\DI\CompilerExtension
|
||||
}
|
||||
|
||||
$connection = $container->addDefinition($this->prefix('connection'))
|
||||
->setClass('DibiConnection', array($config));
|
||||
->setClass('DibiConnection', array($config))
|
||||
->setAutowired(isset($config['autowired']) ? $config['autowired'] : TRUE);
|
||||
|
||||
if ($useProfiler) {
|
||||
$panel = $container->addDefinition($this->prefix('panel'))
|
||||
|
@@ -104,7 +104,7 @@ class DibiNettePanel extends DibiObject implements Nette\Diagnostics\IBarPanel
|
||||
try {
|
||||
$backup = array($event->connection->onEvent, dibi::$numOfQueries, dibi::$totalTime);
|
||||
$event->connection->onEvent = NULL;
|
||||
$cmd = is_string($this->explain) ? $this->explain : ($event->connection->getConfig('driver') === 'oracle' ? 'EXPLAIN PLAN' : 'EXPLAIN');
|
||||
$cmd = is_string($this->explain) ? $this->explain : ($event->connection->getConfig('driver') === 'oracle' ? 'EXPLAIN PLAN FOR' : 'EXPLAIN');
|
||||
$explain = dibi::dump($event->connection->nativeQuery("$cmd $event->sql"), TRUE);
|
||||
} catch (DibiException $e) {}
|
||||
list($event->connection->onEvent, dibi::$numOfQueries, dibi::$totalTime) = $backup;
|
||||
|
@@ -40,7 +40,8 @@ class DibiExtension22 extends Nette\DI\CompilerExtension
|
||||
}
|
||||
|
||||
$connection = $container->addDefinition($this->prefix('connection'))
|
||||
->setClass('DibiConnection', array($config));
|
||||
->setClass('DibiConnection', array($config))
|
||||
->setAutowired(isset($config['autowired']) ? $config['autowired'] : TRUE);
|
||||
|
||||
if ($useProfiler) {
|
||||
$panel = $container->addDefinition($this->prefix('panel'))
|
||||
|
@@ -81,13 +81,14 @@ class Panel extends \DibiObject implements Tracy\IBarPanel
|
||||
public function getTab()
|
||||
{
|
||||
$totalTime = 0;
|
||||
$count = count($this->events);
|
||||
foreach ($this->events as $event) {
|
||||
$totalTime += $event->time;
|
||||
}
|
||||
return '<span title="dibi"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAEYSURBVBgZBcHPio5hGAfg6/2+R980k6wmJgsJ5U/ZOAqbSc2GnXOwUg7BESgLUeIQ1GSjLFnMwsKGGg1qxJRmPM97/1zXFAAAAEADdlfZzr26miup2svnelq7d2aYgt3rebl585wN6+K3I1/9fJe7O/uIePP2SypJkiRJ0vMhr55FLCA3zgIAOK9uQ4MS361ZOSX+OrTvkgINSjS/HIvhjxNNFGgQsbSmabohKDNoUGLohsls6BaiQIMSs2FYmnXdUsygQYmumy3Nhi6igwalDEOJEjPKP7CA2aFNK8Bkyy3fdNCg7r9/fW3jgpVJbDmy5+PB2IYp4MXFelQ7izPrhkPHB+P5/PjhD5gCgCenx+VR/dODEwD+A3T7nqbxwf1HAAAAAElFTkSuQmCC" />'
|
||||
. count($this->events) . ' queries'
|
||||
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'
|
||||
. ($totalTime ? sprintf(' / %0.1f ms', $totalTime * 1000) : '')
|
||||
. '</span>';
|
||||
. '</span></span>';
|
||||
}
|
||||
|
||||
|
||||
@@ -106,7 +107,7 @@ class Panel extends \DibiObject implements Tracy\IBarPanel
|
||||
try {
|
||||
$backup = array($event->connection->onEvent, dibi::$numOfQueries, dibi::$totalTime);
|
||||
$event->connection->onEvent = NULL;
|
||||
$cmd = is_string($this->explain) ? $this->explain : ($event->connection->getConfig('driver') === 'oracle' ? 'EXPLAIN PLAN' : 'EXPLAIN');
|
||||
$cmd = is_string($this->explain) ? $this->explain : ($event->connection->getConfig('driver') === 'oracle' ? 'EXPLAIN PLAN FOR' : 'EXPLAIN');
|
||||
$explain = dibi::dump($event->connection->nativeQuery("$cmd $event->sql"), TRUE);
|
||||
} catch (\DibiException $e) {}
|
||||
list($event->connection->onEvent, dibi::$numOfQueries, dibi::$totalTime) = $backup;
|
||||
|
@@ -103,7 +103,7 @@ class DibiOracleDriver extends DibiObject implements IDibiDriver, IDibiResultDri
|
||||
{
|
||||
$res = oci_parse($this->connection, $sql);
|
||||
if ($res) {
|
||||
oci_execute($res, $this->autocommit ? OCI_COMMIT_ON_SUCCESS : OCI_DEFAULT);
|
||||
@oci_execute($res, $this->autocommit ? OCI_COMMIT_ON_SUCCESS : OCI_DEFAULT);
|
||||
$err = oci_error($res);
|
||||
if ($err) {
|
||||
throw new DibiDriverException($err['message'], $err['code'], $sql);
|
||||
@@ -365,11 +365,12 @@ class DibiOracleDriver extends DibiObject implements IDibiDriver, IDibiResultDri
|
||||
$count = oci_num_fields($this->resultSet);
|
||||
$columns = array();
|
||||
for ($i = 1; $i <= $count; $i++) {
|
||||
$type = oci_field_type($this->resultSet, $i);
|
||||
$columns[] = array(
|
||||
'name' => oci_field_name($this->resultSet, $i),
|
||||
'table' => NULL,
|
||||
'fullname' => oci_field_name($this->resultSet, $i),
|
||||
'nativetype'=> oci_field_type($this->resultSet, $i),
|
||||
'nativetype' => $type === 'NUMBER' && oci_field_scale($this->resultSet, $i) === 0 ? 'INTEGER' : $type,
|
||||
);
|
||||
}
|
||||
return $columns;
|
||||
|
@@ -19,6 +19,7 @@ require_once dirname(__FILE__) . '/DibiSqliteReflector.php';
|
||||
* - password (or pass)
|
||||
* - options (array) => driver specific options {@see PDO::__construct}
|
||||
* - resource (PDO) => existing connection
|
||||
* - version
|
||||
* - lazy, profiler, result, substitutes, ... => see DibiConnection options
|
||||
*
|
||||
* @author David Grudl
|
||||
@@ -38,6 +39,9 @@ class DibiPdoDriver extends DibiObject implements IDibiDriver, IDibiResultDriver
|
||||
/** @var string */
|
||||
private $driverName;
|
||||
|
||||
/** @var string */
|
||||
private $serverVersion;
|
||||
|
||||
|
||||
/**
|
||||
* @throws DibiNotSupportedException
|
||||
@@ -75,6 +79,9 @@ class DibiPdoDriver extends DibiObject implements IDibiDriver, IDibiResultDriver
|
||||
}
|
||||
|
||||
$this->driverName = $this->connection->getAttribute(PDO::ATTR_DRIVER_NAME);
|
||||
$this->serverVersion = isset($config['version'])
|
||||
? $config['version']
|
||||
: @$this->connection->getAttribute(PDO::ATTR_SERVER_VERSION); // @ - may be not supported
|
||||
}
|
||||
|
||||
|
||||
@@ -268,6 +275,7 @@ class DibiPdoDriver extends DibiObject implements IDibiDriver, IDibiResultDriver
|
||||
case 'mssql':
|
||||
return '[' . str_replace(array('[', ']'), array('[[', ']]'), $value) . ']';
|
||||
|
||||
case 'dblib':
|
||||
case 'sqlsrv':
|
||||
return '[' . str_replace(']', ']]', $value) . ']';
|
||||
|
||||
@@ -330,6 +338,7 @@ class DibiPdoDriver extends DibiObject implements IDibiDriver, IDibiResultDriver
|
||||
|
||||
case 'odbc':
|
||||
case 'mssql':
|
||||
case 'dblib':
|
||||
case 'sqlsrv':
|
||||
$value = strtr($value, array("'" => "''", '%' => '[%]', '_' => '[_]', '[' => '[[]'));
|
||||
return ($pos <= 0 ? "'%" : "'") . $value . ($pos >= 0 ? "%'" : "'");
|
||||
@@ -396,10 +405,19 @@ class DibiPdoDriver extends DibiObject implements IDibiDriver, IDibiResultDriver
|
||||
}
|
||||
break;
|
||||
|
||||
case 'odbc':
|
||||
case 'dblib':
|
||||
case 'mssql':
|
||||
case 'sqlsrv':
|
||||
case 'dblib':
|
||||
if (version_compare($this->serverVersion, '11.0') >= 0) {
|
||||
if ($offset >= 0 || $limit >= 0) {
|
||||
$sql .= ' OFFSET ' . (int) $offset . ' ROWS'
|
||||
. ($limit > 0 ? ' FETCH NEXT ' . (int) $limit . ' ROWS ONLY' : '');
|
||||
}
|
||||
break;
|
||||
}
|
||||
// intentionally break omitted
|
||||
|
||||
case 'odbc':
|
||||
if ($offset < 1) {
|
||||
$sql = 'SELECT TOP ' . (int) $limit . ' * FROM (' . $sql . ') t';
|
||||
break;
|
||||
|
@@ -39,8 +39,8 @@ class dibi
|
||||
FIELD_TIME = dibi::TIME;
|
||||
|
||||
/** version */
|
||||
const VERSION = '2.3.0',
|
||||
REVISION = 'released on 2015-01-23';
|
||||
const VERSION = '2.3.2',
|
||||
REVISION = 'released on 2015-04-18';
|
||||
|
||||
/** sorting order */
|
||||
const ASC = 'ASC',
|
||||
@@ -86,14 +86,12 @@ class dibi
|
||||
/**
|
||||
* Creates a new DibiConnection object and connects it to specified database.
|
||||
* @param mixed connection parameters
|
||||
* @param string connection name
|
||||
* @return DibiConnection
|
||||
* @throws DibiException
|
||||
*/
|
||||
public static function connect($config = array(), $name = 0)
|
||||
{
|
||||
if ($name) {
|
||||
trigger_error(__METHOD__ . '(): named connections are deprecated.', E_USER_DEPRECATED);
|
||||
}
|
||||
return self::$connection = self::$registry[$name] = new DibiConnection($config, $name);
|
||||
}
|
||||
|
||||
@@ -120,6 +118,7 @@ class dibi
|
||||
|
||||
/**
|
||||
* Retrieve active connection.
|
||||
* @param string connection registy name
|
||||
* @return DibiConnection
|
||||
* @throws DibiException
|
||||
*/
|
||||
@@ -133,8 +132,6 @@ class dibi
|
||||
return self::$connection;
|
||||
}
|
||||
|
||||
trigger_error(__METHOD__ . '(): named connections are deprecated.', E_USER_DEPRECATED);
|
||||
|
||||
if (!isset(self::$registry[$name])) {
|
||||
throw new DibiException("There is no connection named '$name'.");
|
||||
}
|
||||
@@ -472,7 +469,7 @@ class dibi
|
||||
$sql = self::$sql;
|
||||
}
|
||||
|
||||
static $keywords1 = 'SELECT|(?:ON\s+DUPLICATE\s+KEY)?UPDATE|INSERT(?:\s+INTO)?|REPLACE(?:\s+INTO)?|DELETE|CALL|UNION|FROM|WHERE|HAVING|GROUP\s+BY|ORDER\s+BY|LIMIT|OFFSET|SET|VALUES|LEFT\s+JOIN|INNER\s+JOIN|TRUNCATE|START\s+TRANSACTION|BEGIN|COMMIT|ROLLBACK(?:\s+TO\s+SAVEPOINT)?|(?:RELEASE\s+)?SAVEPOINT';
|
||||
static $keywords1 = 'SELECT|(?:ON\s+DUPLICATE\s+KEY)?UPDATE|INSERT(?:\s+INTO)?|REPLACE(?:\s+INTO)?|DELETE|CALL|UNION|FROM|WHERE|HAVING|GROUP\s+BY|ORDER\s+BY|LIMIT|OFFSET|FETCH\s+NEXT|SET|VALUES|LEFT\s+JOIN|INNER\s+JOIN|TRUNCATE|START\s+TRANSACTION|BEGIN|COMMIT|ROLLBACK(?:\s+TO\s+SAVEPOINT)?|(?:RELEASE\s+)?SAVEPOINT';
|
||||
static $keywords2 = 'ALL|DISTINCT|DISTINCTROW|IGNORE|AS|USING|ON|AND|OR|IN|IS|NOT|NULL|LIKE|RLIKE|REGEXP|TRUE|FALSE';
|
||||
|
||||
// insert new lines
|
||||
|
80
tests/dibi/PdoMssql.limits.phpt
Normal file
80
tests/dibi/PdoMssql.limits.phpt
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @dataProvider ../databases.ini
|
||||
*/
|
||||
|
||||
use Tester\Assert;
|
||||
|
||||
require __DIR__ . '/bootstrap.php';
|
||||
|
||||
if ($config['system'] !== 'mssql' || $config['driver'] !== 'pdo') {
|
||||
Tester\Environment::skip("Not supported system '$config[system]'.");
|
||||
}
|
||||
|
||||
$tests = function($conn){
|
||||
$version = $conn->getDriver()->getResource()->getAttribute(PDO::ATTR_SERVER_VERSION);
|
||||
|
||||
// MsSQL2012+
|
||||
if(version_compare($version, '11.0') >= 0) {
|
||||
// Limit and offset
|
||||
Assert::same(
|
||||
'SELECT 1 OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY',
|
||||
$conn->translate('SELECT 1 %ofs %lmt', 10, 10)
|
||||
);
|
||||
|
||||
// Limit only
|
||||
Assert::same(
|
||||
'SELECT 1 OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY',
|
||||
$conn->translate('SELECT 1 %lmt', 10)
|
||||
);
|
||||
|
||||
// Offset only
|
||||
Assert::same(
|
||||
'SELECT 1 OFFSET 10 ROWS',
|
||||
$conn->translate('SELECT 1 %ofs', 10)
|
||||
);
|
||||
|
||||
// Offset invalid
|
||||
Assert::same(
|
||||
'SELECT 1',
|
||||
$conn->translate('SELECT 1 %ofs', -10)
|
||||
);
|
||||
|
||||
// Limit invalid
|
||||
Assert::same(
|
||||
'SELECT 1',
|
||||
$conn->translate('SELECT 1 %lmt', -10)
|
||||
);
|
||||
|
||||
// Limit invalid, offset valid
|
||||
Assert::same(
|
||||
'SELECT 1',
|
||||
$conn->translate('SELECT 1 %ofs %lmt', 10, -10)
|
||||
);
|
||||
|
||||
// Limit valid, offset invalid
|
||||
Assert::same(
|
||||
'SELECT 1',
|
||||
$conn->translate('SELECT 1 %ofs %lmt', -10, 10)
|
||||
);
|
||||
} else {
|
||||
Assert::same(
|
||||
'SELECT TOP 1 * FROM (SELECT 1) t',
|
||||
$conn->translate('SELECT 1 %lmt', 1)
|
||||
);
|
||||
|
||||
Assert::same(
|
||||
'SELECT 1',
|
||||
$conn->translate('SELECT 1 %lmt', -10)
|
||||
);
|
||||
|
||||
Assert::exception(
|
||||
$conn->translate('SELECT 1 %ofs %lmt', 10, 10),
|
||||
'DibiNotSupportedException'
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
$conn = new DibiConnection($config);
|
||||
$tests($conn);
|
@@ -1 +0,0 @@
|
||||
Dibi 2.3.0 (released on 2015-01-23)
|
Reference in New Issue
Block a user