mirror of
https://github.com/dg/dibi.git
synced 2025-08-06 14:16:39 +02:00
support for 64bit numbers on 32bit platform [Closes #253] (BC break)
throws exception when given argument is not a number
This commit is contained in:
@@ -365,7 +365,7 @@ class Connection
|
||||
if ($id < 1) {
|
||||
throw new Exception('Cannot retrieve last generated ID.');
|
||||
}
|
||||
return (int) $id;
|
||||
return Helpers::intVal($id);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -283,9 +283,9 @@ FROM %SQL', $this->sql, '
|
||||
{
|
||||
if ($this->count === null) {
|
||||
$this->count = $this->conds || $this->offset || $this->limit
|
||||
? (int) $this->connection->nativeQuery(
|
||||
? Helpers::intVal($this->connection->nativeQuery(
|
||||
'SELECT COUNT(*) FROM (' . $this->__toString() . ') t'
|
||||
)->fetchSingle()
|
||||
)->fetchSingle())
|
||||
: $this->getTotalCount();
|
||||
}
|
||||
return $this->count;
|
||||
@@ -299,9 +299,9 @@ FROM %SQL', $this->sql, '
|
||||
public function getTotalCount()
|
||||
{
|
||||
if ($this->totalCount === null) {
|
||||
$this->totalCount = (int) $this->connection->nativeQuery(
|
||||
$this->totalCount = Helpers::intVal($this->connection->nativeQuery(
|
||||
'SELECT COUNT(*) FROM ' . $this->sql
|
||||
)->fetchSingle();
|
||||
)->fetchSingle());
|
||||
}
|
||||
return $this->totalCount;
|
||||
}
|
||||
|
@@ -359,7 +359,9 @@ class FirebirdDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
|
||||
{
|
||||
if ($limit > 0 || $offset > 0) {
|
||||
// http://www.firebirdsql.org/refdocs/langrefupd20-select.html
|
||||
$sql = 'SELECT ' . ($limit > 0 ? 'FIRST ' . (int) $limit : '') . ($offset > 0 ? ' SKIP ' . (int) $offset : '') . ' * FROM (' . $sql . ')';
|
||||
$sql = 'SELECT ' . ($limit > 0 ? 'FIRST ' . Dibi\Helpers::intVal($limit) : '')
|
||||
. ($offset > 0 ? ' SKIP ' . Dibi\Helpers::intVal($offset) : '')
|
||||
. ' * FROM (' . $sql . ')';
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -315,7 +315,7 @@ class MsSqlDriver implements Dibi\Driver, Dibi\ResultDriver
|
||||
throw new Dibi\NotSupportedException('Negative offset or limit.');
|
||||
|
||||
} elseif ($limit !== null) {
|
||||
$sql = 'SELECT TOP ' . (int) $limit . ' * FROM (' . $sql . ') t';
|
||||
$sql = 'SELECT TOP ' . Dibi\Helpers::intVal($limit) . ' * FROM (' . $sql . ') t';
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -69,12 +69,12 @@ class MsSqlReflector implements Dibi\Reflector
|
||||
if (!is_array($row) || count($row) < 1) {
|
||||
if ($fallback) {
|
||||
$row = $this->driver->query("SELECT COUNT(*) FROM {$this->driver->escapeIdentifier($table)}")->fetch(false);
|
||||
$count = (int) ($row[0]);
|
||||
$count = Dibi\Helpers::intVal($row[0]);
|
||||
} else {
|
||||
$count = false;
|
||||
}
|
||||
} else {
|
||||
$count = (int) ($row[0]);
|
||||
$count = Dibi\Helpers::intVal($row[0]);
|
||||
}
|
||||
|
||||
return $count;
|
||||
|
@@ -397,8 +397,8 @@ class MySqlDriver implements Dibi\Driver, Dibi\ResultDriver
|
||||
|
||||
} elseif ($limit !== null || $offset) {
|
||||
// see http://dev.mysql.com/doc/refman/5.0/en/select.html
|
||||
$sql .= ' LIMIT ' . ($limit === null ? '18446744073709551615' : (int) $limit)
|
||||
. ($offset ? ' OFFSET ' . (int) $offset : '');
|
||||
$sql .= ' LIMIT ' . ($limit === null ? '18446744073709551615' : Dibi\Helpers::intVal($limit))
|
||||
. ($offset ? ' OFFSET ' . Dibi\Helpers::intVal($offset) : '');
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -405,8 +405,8 @@ class MySqliDriver implements Dibi\Driver, Dibi\ResultDriver
|
||||
|
||||
} elseif ($limit !== null || $offset) {
|
||||
// see http://dev.mysql.com/doc/refman/5.0/en/select.html
|
||||
$sql .= ' LIMIT ' . ($limit === null ? '18446744073709551615' : (int) $limit)
|
||||
. ($offset ? ' OFFSET ' . (int) $offset : '');
|
||||
$sql .= ' LIMIT ' . ($limit === null ? '18446744073709551615' : Dibi\Helpers::intVal($limit))
|
||||
. ($offset ? ' OFFSET ' . Dibi\Helpers::intVal($offset) : '');
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -339,7 +339,7 @@ class OdbcDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
|
||||
throw new Dibi\NotSupportedException('Negative offset or limit.');
|
||||
|
||||
} elseif ($limit !== null) {
|
||||
$sql = 'SELECT TOP ' . (int) $limit . ' * FROM (' . $sql . ') t';
|
||||
$sql = 'SELECT TOP ' . Dibi\Helpers::intVal($limit) . ' * FROM (' . $sql . ') t';
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -170,7 +170,7 @@ class OracleDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
|
||||
public function getInsertId($sequence)
|
||||
{
|
||||
$row = $this->query("SELECT $sequence.CURRVAL AS ID FROM DUAL")->fetch(true);
|
||||
return isset($row['ID']) ? (int) $row['ID'] : false;
|
||||
return isset($row['ID']) ? Dibi\Helpers::intVal($row['ID']) : false;
|
||||
}
|
||||
|
||||
|
||||
@@ -374,10 +374,10 @@ class OracleDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
|
||||
// see http://www.oracle.com/technology/oramag/oracle/06-sep/o56asktom.html
|
||||
$sql = 'SELECT * FROM (SELECT t.*, ROWNUM AS "__rnum" FROM (' . $sql . ') t '
|
||||
. ($limit !== null ? 'WHERE ROWNUM <= ' . ((int) $offset + (int) $limit) : '')
|
||||
. ') WHERE "__rnum" > ' . (int) $offset;
|
||||
. ') WHERE "__rnum" > ' . $offset;
|
||||
|
||||
} elseif ($limit !== null) {
|
||||
$sql = 'SELECT * FROM (' . $sql . ') WHERE ROWNUM <= ' . (int) $limit;
|
||||
$sql = 'SELECT * FROM (' . $sql . ') WHERE ROWNUM <= ' . Dibi\Helpers::intVal($limit);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -429,24 +429,24 @@ class PdoDriver implements Dibi\Driver, Dibi\ResultDriver
|
||||
case 'mysql':
|
||||
if ($limit !== null || $offset) {
|
||||
// see http://dev.mysql.com/doc/refman/5.0/en/select.html
|
||||
$sql .= ' LIMIT ' . ($limit === null ? '18446744073709551615' : (int) $limit)
|
||||
. ($offset ? ' OFFSET ' . (int) $offset : '');
|
||||
$sql .= ' LIMIT ' . ($limit === null ? '18446744073709551615' : Dibi\Helpers::intVal($limit))
|
||||
. ($offset ? ' OFFSET ' . Dibi\Helpers::intVal($offset) : '');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'pgsql':
|
||||
if ($limit !== null) {
|
||||
$sql .= ' LIMIT ' . (int) $limit;
|
||||
$sql .= ' LIMIT ' . Dibi\Helpers::intVal($limit);
|
||||
}
|
||||
if ($offset) {
|
||||
$sql .= ' OFFSET ' . (int) $offset;
|
||||
$sql .= ' OFFSET ' . Dibi\Helpers::intVal($offset);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'sqlite':
|
||||
if ($limit !== null || $offset) {
|
||||
$sql .= ' LIMIT ' . ($limit === null ? '-1' : (int) $limit)
|
||||
. ($offset ? ' OFFSET ' . (int) $offset : '');
|
||||
$sql .= ' LIMIT ' . ($limit === null ? '-1' : Dibi\Helpers::intVal($limit))
|
||||
. ($offset ? ' OFFSET ' . Dibi\Helpers::intVal($offset) : '');
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -455,10 +455,10 @@ class PdoDriver implements Dibi\Driver, Dibi\ResultDriver
|
||||
// see http://www.oracle.com/technology/oramag/oracle/06-sep/o56asktom.html
|
||||
$sql = 'SELECT * FROM (SELECT t.*, ROWNUM AS "__rnum" FROM (' . $sql . ') t '
|
||||
. ($limit !== null ? 'WHERE ROWNUM <= ' . ((int) $offset + (int) $limit) : '')
|
||||
. ') WHERE "__rnum" > ' . (int) $offset;
|
||||
. ') WHERE "__rnum" > ' . $offset;
|
||||
|
||||
} elseif ($limit !== null) {
|
||||
$sql = 'SELECT * FROM (' . $sql . ') WHERE ROWNUM <= ' . (int) $limit;
|
||||
$sql = 'SELECT * FROM (' . $sql . ') WHERE ROWNUM <= ' . Dibi\Helpers::intVal($limit);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -480,7 +480,7 @@ class PdoDriver implements Dibi\Driver, Dibi\ResultDriver
|
||||
throw new Dibi\NotSupportedException('Offset is not supported by this database.');
|
||||
|
||||
} elseif ($limit !== null) {
|
||||
$sql = 'SELECT TOP ' . (int) $limit . ' * FROM (' . $sql . ') t';
|
||||
$sql = 'SELECT TOP ' . Dibi\Helpers::intVal($limit) . ' * FROM (' . $sql . ') t';
|
||||
break;
|
||||
}
|
||||
// break omitted
|
||||
|
@@ -412,10 +412,10 @@ class PostgreDriver implements Dibi\Driver, Dibi\ResultDriver, Dibi\Reflector
|
||||
throw new Dibi\NotSupportedException('Negative offset or limit.');
|
||||
}
|
||||
if ($limit !== null) {
|
||||
$sql .= ' LIMIT ' . (int) $limit;
|
||||
$sql .= ' LIMIT ' . Dibi\Helpers::intVal($limit);
|
||||
}
|
||||
if ($offset) {
|
||||
$sql .= ' OFFSET ' . (int) $offset;
|
||||
$sql .= ' OFFSET ' . Dibi\Helpers::intVal($offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -358,8 +358,8 @@ class Sqlite3Driver implements Dibi\Driver, Dibi\ResultDriver
|
||||
throw new Dibi\NotSupportedException('Negative offset or limit.');
|
||||
|
||||
} elseif ($limit !== null || $offset) {
|
||||
$sql .= ' LIMIT ' . ($limit === null ? '-1' : (int) $limit)
|
||||
. ($offset ? ' OFFSET ' . (int) $offset : '');
|
||||
$sql .= ' LIMIT ' . ($limit === null ? '-1' : Dibi\Helpers::intVal($limit))
|
||||
. ($offset ? ' OFFSET ' . Dibi\Helpers::intVal($offset) : '');
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -408,9 +408,9 @@ class Fluent implements IDataSource
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return (int) $this->query([
|
||||
return Helpers::intVal($this->query([
|
||||
'SELECT COUNT(*) FROM (%ex', $this->_export(), ') [data]',
|
||||
])->fetchSingle();
|
||||
])->fetchSingle());
|
||||
}
|
||||
|
||||
|
||||
|
@@ -282,4 +282,21 @@ class Helpers
|
||||
fclose($handle);
|
||||
return $count;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @return string|int
|
||||
*/
|
||||
public static function intVal($value)
|
||||
{
|
||||
if (is_int($value)) {
|
||||
return $value;
|
||||
} elseif (is_string($value) && preg_match('#-?\d++\z#A', $value)) {
|
||||
// support for long numbers - keep them unchanged
|
||||
return is_float($number = $value * 1) ? $value : $number;
|
||||
} else {
|
||||
throw new Exception("Expected number, '$value' given.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -111,7 +111,9 @@ class Result implements IDataSource
|
||||
*/
|
||||
final public function seek($row)
|
||||
{
|
||||
return ($row !== 0 || $this->fetched) ? (bool) $this->getResultDriver()->seek($row) : true;
|
||||
return ($row != 0 || $this->fetched) // intentionally ==
|
||||
? (bool) $this->getResultDriver()->seek($row)
|
||||
: true;
|
||||
}
|
||||
|
||||
|
||||
@@ -227,8 +229,8 @@ class Result implements IDataSource
|
||||
*/
|
||||
final public function fetchAll($offset = null, $limit = null)
|
||||
{
|
||||
$limit = $limit === null ? -1 : (int) $limit;
|
||||
$this->seek((int) $offset);
|
||||
$limit = $limit === null ? -1 : Helpers::intVal($limit);
|
||||
$this->seek($offset);
|
||||
$row = $this->fetch();
|
||||
if (!$row) {
|
||||
return []; // empty result set
|
||||
|
@@ -538,7 +538,7 @@ final class Translator
|
||||
} elseif ($this->comment) {
|
||||
return "(limit $arg)";
|
||||
} else {
|
||||
$this->limit = (int) $arg;
|
||||
$this->limit = Helpers::intVal($arg);
|
||||
}
|
||||
return '';
|
||||
|
||||
@@ -548,7 +548,7 @@ final class Translator
|
||||
} elseif ($this->comment) {
|
||||
return "(offset $arg)";
|
||||
} else {
|
||||
$this->offset = (int) $arg;
|
||||
$this->offset = Helpers::intVal($arg);
|
||||
}
|
||||
return '';
|
||||
|
||||
|
@@ -142,10 +142,9 @@ if ($config['system'] === 'mysql') {
|
||||
->limit(' 1; DROP TABLE users')
|
||||
->offset(' 1; DROP TABLE users');
|
||||
|
||||
Assert::same(
|
||||
reformat(' SELECT * LIMIT 1 OFFSET 1'),
|
||||
(string) $fluent
|
||||
);
|
||||
Assert::error(function () use ($fluent) {
|
||||
(string) $fluent;
|
||||
}, E_USER_ERROR, "Expected number, ' 1; DROP TABLE users' given.");
|
||||
}
|
||||
|
||||
|
||||
|
25
tests/dibi/Helpers.intVal().phpt
Normal file
25
tests/dibi/Helpers.intVal().phpt
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
use Dibi\Helpers;
|
||||
use Tester\Assert;
|
||||
|
||||
require __DIR__ . '/bootstrap.php';
|
||||
|
||||
|
||||
Assert::same(0, Helpers::intVal(0));
|
||||
Assert::same(0, Helpers::intVal('0'));
|
||||
Assert::same(-10, Helpers::intVal('-10'));
|
||||
Assert::same('12345678901234567890123456879', Helpers::intVal('12345678901234567890123456879'));
|
||||
Assert::same('-12345678901234567890123456879', Helpers::intVal('-12345678901234567890123456879'));
|
||||
|
||||
Assert::exception(function () {
|
||||
Helpers::intVal('');
|
||||
}, 'Dibi\Exception', "Expected number, '' given.");
|
||||
|
||||
Assert::exception(function () {
|
||||
Helpers::intVal('not number');
|
||||
}, 'Dibi\Exception', "Expected number, 'not number' given.");
|
||||
|
||||
Assert::exception(function () {
|
||||
Helpers::intVal(null);
|
||||
}, 'Dibi\Exception', "Expected number, '' given.");
|
Reference in New Issue
Block a user