1
0
mirror of https://github.com/dg/dibi.git synced 2025-08-05 13:47:33 +02:00

IDibiDriver: escape() & unescape() replaced with escape*() & unescapeBinary() (BC break!)

This commit is contained in:
David Grudl
2015-10-08 01:36:44 +02:00
parent 7f76a8b2f4
commit cbebcba37d
20 changed files with 594 additions and 397 deletions

View File

@@ -51,7 +51,7 @@ class DibiDataSource extends DibiObject implements IDataSource
public function __construct($sql, DibiConnection $connection)
{
if (strpbrk($sql, " \t\r\n") === FALSE) {
$this->sql = $connection->getDriver()->escape($sql, dibi::IDENTIFIER); // table name
$this->sql = $connection->getDriver()->escapeIdentifier($sql); // table name
} else {
$this->sql = '(' . $sql . ') t'; // SQL command
}

View File

@@ -256,34 +256,48 @@ class DibiFirebirdDriver extends DibiObject implements IDibiDriver, IDibiResultD
/**
* Encodes data for use in a SQL statement.
* @param mixed value
* @param string type (dibi::TEXT, dibi::BOOL, ...)
* @return string encoded value
* @throws InvalidArgumentException
* @param string
* @return string
*/
public function escape($value, $type)
public function escapeText($value)
{
switch ($type) {
case dibi::TEXT:
case dibi::BINARY:
return "'" . str_replace("'", "''", $value) . "'";
return "'" . str_replace("'", "''", $value) . "'";
}
case dibi::IDENTIFIER:
return $value;
case dibi::BOOL:
return $value ? 1 : 0;
public function escapeBinary($value)
{
return "'" . str_replace("'", "''", $value) . "'";
}
case dibi::DATE:
case dibi::DATETIME:
if (!$value instanceof DateTime && !$value instanceof DateTimeInterface) {
$value = new DibiDateTime($value);
}
return $value->format($type === dibi::DATETIME ? "'Y-m-d H:i:s'" : "'Y-m-d'");
default:
throw new InvalidArgumentException('Unsupported type.');
public function escapeIdentifier($value)
{
return $value;
}
public function escapeBool($value)
{
return $value ? 1 : 0;
}
public function escapeDate($value)
{
if (!$value instanceof DateTime && !$value instanceof DateTimeInterface) {
$value = new DibiDateTime($value);
}
return $value->format("'Y-m-d'");
}
public function escapeDateTime($value)
{
if (!$value instanceof DateTime && !$value instanceof DateTimeInterface) {
$value = new DibiDateTime($value);
}
return $value->format("'Y-m-d H:i:s'");
}
@@ -301,17 +315,19 @@ class DibiFirebirdDriver extends DibiObject implements IDibiDriver, IDibiResultD
/**
* Decodes data from result set.
* @param string value
* @param string type (dibi::BINARY)
* @return string decoded value
* @throws InvalidArgumentException
* @param string
* @return string
*/
public function unescape($value, $type)
public function unescapeBinary($value)
{
if ($type === dibi::BINARY) {
return $value;
}
throw new InvalidArgumentException('Unsupported type.');
return $value;
}
/** @deprecated */
public function escape($value, $type)
{
return DibiHelpers::escape($this, $value, $type);
}

View File

@@ -213,37 +213,52 @@ class DibiMsSql2005Driver extends DibiObject implements IDibiDriver, IDibiResult
/**
* Encodes data for use in a SQL statement.
* @param mixed value
* @param string type (dibi::TEXT, dibi::BOOL, ...)
* @return string encoded value
* @throws InvalidArgumentException
*/
public function escape($value, $type)
public function escapeText($value)
{
switch ($type) {
case dibi::TEXT:
case dibi::BINARY:
return "'" . str_replace("'", "''", $value) . "'";
case dibi::IDENTIFIER:
// @see https://msdn.microsoft.com/en-us/library/ms176027.aspx
return '[' . str_replace(']', ']]', $value) . ']';
case dibi::BOOL:
return $value ? 1 : 0;
case dibi::DATE:
case dibi::DATETIME:
if (!$value instanceof DateTime && !$value instanceof DateTimeInterface) {
$value = new DibiDateTime($value);
}
return $value->format($type === dibi::DATETIME ? "'Y-m-d H:i:s'" : "'Y-m-d'");
default:
throw new InvalidArgumentException('Unsupported type.');
}
return "'" . str_replace("'", "''", $value) . "'";
}
public function escapeBinary($value)
{
return "'" . str_replace("'", "''", $value) . "'";
}
public function escapeIdentifier($value)
{
// @see https://msdn.microsoft.com/en-us/library/ms176027.aspx
return '[' . str_replace(']', ']]', $value) . ']';
}
public function escapeBool($value)
{
return $value ? 1 : 0;
}
public function escapeDate($value)
{
if (!$value instanceof DateTime && !$value instanceof DateTimeInterface) {
$value = new DibiDateTime($value);
}
return $value->format("'Y-m-d'");
}
public function escapeDateTime($value)
{
if (!$value instanceof DateTime && !$value instanceof DateTimeInterface) {
$value = new DibiDateTime($value);
}
return $value->format("'Y-m-d H:i:s'");
}
/**
* Encodes string for use in a LIKE statement.
* @param string
@@ -259,17 +274,19 @@ class DibiMsSql2005Driver extends DibiObject implements IDibiDriver, IDibiResult
/**
* Decodes data from result set.
* @param string value
* @param string type (dibi::BINARY)
* @return string decoded value
* @throws InvalidArgumentException
* @param string
* @return string
*/
public function unescape($value, $type)
public function unescapeBinary($value)
{
if ($type === dibi::BINARY) {
return $value;
}
throw new InvalidArgumentException('Unsupported type.');
return $value;
}
/** @deprecated */
public function escape($value, $type)
{
return DibiHelpers::escape($this, $value, $type);
}

View File

@@ -53,7 +53,7 @@ class DibiMsSql2005Reflector extends DibiObject implements IDibiReflector
SELECT c.name as COLUMN_NAME, c.is_identity AS AUTO_INCREMENT
FROM sys.columns c
INNER JOIN sys.tables t ON c.object_id = t.object_id
WHERE t.name = {$this->driver->escape($table, dibi::TEXT)}
WHERE t.name = {$this->driver->escapeText($table)}
");
$autoIncrements = array();
@@ -74,7 +74,7 @@ class DibiMsSql2005Reflector extends DibiObject implements IDibiReflector
And TC.CONSTRAINT_TYPE = 'PRIMARY KEY'
And CCU.COLUMN_NAME = C.COLUMN_NAME
) As Z
WHERE C.TABLE_NAME = {$this->driver->escape($table, dibi::TEXT)}
WHERE C.TABLE_NAME = {$this->driver->escapeText($table)}
");
$columns = array();
while ($row = $res->fetch(TRUE)) {
@@ -101,13 +101,13 @@ class DibiMsSql2005Reflector extends DibiObject implements IDibiReflector
*/
public function getIndexes($table)
{
$keyUsagesRes = $this->driver->query("SELECT * FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_NAME = {$this->driver->escape($table, dibi::TEXT)}");
$keyUsagesRes = $this->driver->query("SELECT * FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_NAME = {$this->driver->escapeText($table)}");
$keyUsages = array();
while ($row = $keyUsagesRes->fetch(TRUE)) {
$keyUsages[$row['CONSTRAINT_NAME']][(int) $row['ORDINAL_POSITION'] - 1] = $row['COLUMN_NAME'];
}
$res = $this->driver->query("SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME = {$this->driver->escape($table, dibi::TEXT)}");
$res = $this->driver->query("SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME = {$this->driver->escapeText($table)}");
$indexes = array();
while ($row = $res->fetch(TRUE)) {
$indexes[$row['CONSTRAINT_NAME']]['name'] = $row['CONSTRAINT_NAME'];

View File

@@ -63,7 +63,7 @@ class DibiMsSqlDriver extends DibiObject implements IDibiDriver, IDibiResultDriv
throw new DibiDriverException("Can't connect to DB.");
}
if (isset($config['database']) && !@mssql_select_db($this->escape($config['database'], dibi::IDENTIFIER), $this->connection)) { // intentionally @
if (isset($config['database']) && !@mssql_select_db($this->escapeIdentifier($config['database']), $this->connection)) { // intentionally @
throw new DibiDriverException("Can't select DB '$config[database]'.");
}
}
@@ -198,34 +198,48 @@ class DibiMsSqlDriver extends DibiObject implements IDibiDriver, IDibiResultDriv
/**
* Encodes data for use in a SQL statement.
* @param mixed value
* @param string type (dibi::TEXT, dibi::BOOL, ...)
* @return string encoded value
* @throws InvalidArgumentException
*/
public function escape($value, $type)
public function escapeText($value)
{
switch ($type) {
case dibi::TEXT:
case dibi::BINARY:
return "'" . str_replace("'", "''", $value) . "'";
return "'" . str_replace("'", "''", $value) . "'";
}
case dibi::IDENTIFIER:
// @see https://msdn.microsoft.com/en-us/library/ms176027.aspx
return '[' . str_replace(array('[', ']'), array('[[', ']]'), $value) . ']';
case dibi::BOOL:
return $value ? 1 : 0;
public function escapeBinary($value)
{
return "'" . str_replace("'", "''", $value) . "'";
}
case dibi::DATE:
case dibi::DATETIME:
if (!$value instanceof DateTime && !$value instanceof DateTimeInterface) {
$value = new DibiDateTime($value);
}
return $value->format($type === dibi::DATETIME ? "'Y-m-d H:i:s'" : "'Y-m-d'");
default:
throw new InvalidArgumentException('Unsupported type.');
public function escapeIdentifier($value)
{
// @see https://msdn.microsoft.com/en-us/library/ms176027.aspx
return '[' . str_replace(array('[', ']'), array('[[', ']]'), $value) . ']';
}
public function escapeBool($value)
{
return $value ? 1 : 0;
}
public function escapeDate($value)
{
if (!$value instanceof DateTime && !$value instanceof DateTimeInterface) {
$value = new DibiDateTime($value);
}
return $value->format("'Y-m-d'");
}
public function escapeDateTime($value)
{
if (!$value instanceof DateTime && !$value instanceof DateTimeInterface) {
$value = new DibiDateTime($value);
}
return $value->format("'Y-m-d H:i:s'");
}
@@ -244,17 +258,19 @@ class DibiMsSqlDriver extends DibiObject implements IDibiDriver, IDibiResultDriv
/**
* Decodes data from result set.
* @param string value
* @param string type (dibi::BINARY)
* @return string decoded value
* @throws InvalidArgumentException
* @param string
* @return string
*/
public function unescape($value, $type)
public function unescapeBinary($value)
{
if ($type === dibi::BINARY) {
return $value;
}
throw new InvalidArgumentException('Unsupported type.');
return $value;
}
/** @deprecated */
public function escape($value, $type)
{
return DibiHelpers::escape($this, $value, $type);
}

View File

@@ -58,13 +58,13 @@ class DibiMsSqlReflector extends DibiObject implements IDibiReflector
$result = $this->driver->query("
SELECT MAX(rowcnt)
FROM sys.sysindexes
WHERE id=OBJECT_ID({$this->driver->escape($table, dibi::IDENTIFIER)})
WHERE id=OBJECT_ID({$this->driver->escapeIdentifier($table)})
");
$row = $result->fetch(FALSE);
if (!is_array($row) || count($row) < 1) {
if ($fallback) {
$row = $this->driver->query("SELECT COUNT(*) FROM {$this->driver->escape($table, dibi::IDENTIFIER)}")->fetch(FALSE);
$row = $this->driver->query("SELECT COUNT(*) FROM {$this->driver->escapeIdentifier($table)}")->fetch(FALSE);
$count = intval($row[0]);
} else {
$count = FALSE;
@@ -87,7 +87,7 @@ class DibiMsSqlReflector extends DibiObject implements IDibiReflector
$res = $this->driver->query("
SELECT * FROM
INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = {$this->driver->escape($table, dibi::TEXT)}
WHERE TABLE_NAME = {$this->driver->escapeText($table)}
ORDER BY TABLE_NAME, ORDINAL_POSITION
");
$columns = array();
@@ -144,7 +144,7 @@ class DibiMsSqlReflector extends DibiObject implements IDibiReflector
(ic.object_id = col.object_id and ic.column_id = col.column_id)
INNER JOIN sys.tables t ON
(ind.object_id = t.object_id)
WHERE t.name = {$this->driver->escape($table, dibi::TEXT)}
WHERE t.name = {$this->driver->escapeText($table)}
AND t.is_ms_shipped = 0
ORDER BY
t.name, ind.name, ind.index_id, ic.index_column_id
@@ -187,7 +187,7 @@ class DibiMsSqlReflector extends DibiObject implements IDibiReflector
FROM sys.foreign_keys AS f
INNER JOIN sys.foreign_key_columns AS fc
ON f.OBJECT_ID = fc.constraint_object_id
WHERE OBJECT_NAME(f.parent_object_id) = {$this->driver->escape($table, dibi::TEXT)}
WHERE OBJECT_NAME(f.parent_object_id) = {$this->driver->escapeText($table)}
");
$keys = array();

View File

@@ -284,42 +284,54 @@ class DibiMySqlDriver extends DibiObject implements IDibiDriver, IDibiResultDriv
/**
* Encodes data for use in a SQL statement.
* @param mixed value
* @param string type (dibi::TEXT, dibi::BOOL, ...)
* @return string encoded value
* @throws InvalidArgumentException
*/
public function escape($value, $type)
public function escapeText($value)
{
switch ($type) {
case dibi::TEXT:
if (!is_resource($this->connection)) {
throw new DibiException('Lost connection to server.');
}
return "'" . mysql_real_escape_string($value, $this->connection) . "'";
case dibi::BINARY:
if (!is_resource($this->connection)) {
throw new DibiException('Lost connection to server.');
}
return "_binary'" . mysql_real_escape_string($value, $this->connection) . "'";
case dibi::IDENTIFIER:
// @see http://dev.mysql.com/doc/refman/5.0/en/identifiers.html
return '`' . str_replace('`', '``', $value) . '`';
case dibi::BOOL:
return $value ? 1 : 0;
case dibi::DATE:
case dibi::DATETIME:
if (!$value instanceof DateTime && !$value instanceof DateTimeInterface) {
$value = new DibiDateTime($value);
}
return $value->format($type === dibi::DATETIME ? "'Y-m-d H:i:s'" : "'Y-m-d'");
default:
throw new InvalidArgumentException('Unsupported type.');
if (!is_resource($this->connection)) {
throw new DibiException('Lost connection to server.');
}
return "'" . mysql_real_escape_string($value, $this->connection) . "'";
}
public function escapeBinary($value)
{
if (!is_resource($this->connection)) {
throw new DibiException('Lost connection to server.');
}
return "_binary'" . mysql_real_escape_string($value, $this->connection) . "'";
}
public function escapeIdentifier($value)
{
// @see http://dev.mysql.com/doc/refman/5.0/en/identifiers.html
return '`' . str_replace('`', '``', $value) . '`';
}
public function escapeBool($value)
{
return $value ? 1 : 0;
}
public function escapeDate($value)
{
if (!$value instanceof DateTime && !$value instanceof DateTimeInterface) {
$value = new DibiDateTime($value);
}
return $value->format("'Y-m-d'");
}
public function escapeDateTime($value)
{
if (!$value instanceof DateTime && !$value instanceof DateTimeInterface) {
$value = new DibiDateTime($value);
}
return $value->format("'Y-m-d H:i:s'");
}
@@ -338,17 +350,19 @@ class DibiMySqlDriver extends DibiObject implements IDibiDriver, IDibiResultDriv
/**
* Decodes data from result set.
* @param string value
* @param string type (dibi::BINARY)
* @return string decoded value
* @throws InvalidArgumentException
* @param string
* @return string
*/
public function unescape($value, $type)
public function unescapeBinary($value)
{
if ($type === dibi::BINARY) {
return $value;
}
throw new InvalidArgumentException('Unsupported type.');
return $value;
}
/** @deprecated */
public function escape($value, $type)
{
return DibiHelpers::escape($this, $value, $type);
}

View File

@@ -54,13 +54,13 @@ class DibiMySqlReflector extends DibiObject implements IDibiReflector
*/
public function getColumns($table)
{
/*$table = $this->escape($table, dibi::TEXT);
/*$table = $this->escapeText($table);
$this->query("
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = $table AND TABLE_SCHEMA = DATABASE()
");*/
$res = $this->driver->query("SHOW FULL COLUMNS FROM {$this->driver->escape($table, dibi::IDENTIFIER)}");
$res = $this->driver->query("SHOW FULL COLUMNS FROM {$this->driver->escapeIdentifier($table)}");
$columns = array();
while ($row = $res->fetch(TRUE)) {
$type = explode('(', $row['Type']);
@@ -87,14 +87,14 @@ class DibiMySqlReflector extends DibiObject implements IDibiReflector
*/
public function getIndexes($table)
{
/*$table = $this->escape($table, dibi::TEXT);
/*$table = $this->escapeText($table);
$this->query("
SELECT *
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE TABLE_NAME = $table AND TABLE_SCHEMA = DATABASE()
AND REFERENCED_COLUMN_NAME IS NULL
");*/
$res = $this->driver->query("SHOW INDEX FROM {$this->driver->escape($table, dibi::IDENTIFIER)}");
$res = $this->driver->query("SHOW INDEX FROM {$this->driver->escapeIdentifier($table)}");
$indexes = array();
while ($row = $res->fetch(TRUE)) {
$indexes[$row['Key_name']]['name'] = $row['Key_name'];
@@ -114,7 +114,7 @@ class DibiMySqlReflector extends DibiObject implements IDibiReflector
*/
public function getForeignKeys($table)
{
$data = $this->driver->query("SELECT `ENGINE` FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = {$this->driver->escape($table, dibi::TEXT)}")->fetch(TRUE);
$data = $this->driver->query("SELECT `ENGINE` FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = {$this->driver->escapeText($table)}")->fetch(TRUE);
if ($data['ENGINE'] !== 'InnoDB') {
throw new DibiNotSupportedException("Foreign keys are not supported in {$data['ENGINE']} tables.");
}
@@ -128,7 +128,7 @@ class DibiMySqlReflector extends DibiObject implements IDibiReflector
kcu.CONSTRAINT_NAME = rc.CONSTRAINT_NAME
AND kcu.CONSTRAINT_SCHEMA = rc.CONSTRAINT_SCHEMA
WHERE rc.CONSTRAINT_SCHEMA = DATABASE()
AND rc.TABLE_NAME = {$this->driver->escape($table, dibi::TEXT)}
AND rc.TABLE_NAME = {$this->driver->escapeText($table)}
GROUP BY rc.CONSTRAINT_NAME
");

View File

@@ -274,35 +274,47 @@ class DibiMySqliDriver extends DibiObject implements IDibiDriver, IDibiResultDri
/**
* Encodes data for use in a SQL statement.
* @param mixed value
* @param string type (dibi::TEXT, dibi::BOOL, ...)
* @return string encoded value
* @throws InvalidArgumentException
*/
public function escape($value, $type)
public function escapeText($value)
{
switch ($type) {
case dibi::TEXT:
return "'" . mysqli_real_escape_string($this->connection, $value) . "'";
return "'" . mysqli_real_escape_string($this->connection, $value) . "'";
}
case dibi::BINARY:
return "_binary'" . mysqli_real_escape_string($this->connection, $value) . "'";
case dibi::IDENTIFIER:
return '`' . str_replace('`', '``', $value) . '`';
public function escapeBinary($value)
{
return "_binary'" . mysqli_real_escape_string($this->connection, $value) . "'";
}
case dibi::BOOL:
return $value ? 1 : 0;
case dibi::DATE:
case dibi::DATETIME:
if (!$value instanceof DateTime && !$value instanceof DateTimeInterface) {
$value = new DibiDateTime($value);
}
return $value->format($type === dibi::DATETIME ? "'Y-m-d H:i:s'" : "'Y-m-d'");
public function escapeIdentifier($value)
{
return '`' . str_replace('`', '``', $value) . '`';
}
default:
throw new InvalidArgumentException('Unsupported type.');
public function escapeBool($value)
{
return $value ? 1 : 0;
}
public function escapeDate($value)
{
if (!$value instanceof DateTime && !$value instanceof DateTimeInterface) {
$value = new DibiDateTime($value);
}
return $value->format("'Y-m-d'");
}
public function escapeDateTime($value)
{
if (!$value instanceof DateTime && !$value instanceof DateTimeInterface) {
$value = new DibiDateTime($value);
}
return $value->format("'Y-m-d H:i:s'");
}
@@ -321,17 +333,19 @@ class DibiMySqliDriver extends DibiObject implements IDibiDriver, IDibiResultDri
/**
* Decodes data from result set.
* @param string value
* @param string type (dibi::BINARY)
* @return string decoded value
* @throws InvalidArgumentException
* @param string
* @return string
*/
public function unescape($value, $type)
public function unescapeBinary($value)
{
if ($type === dibi::BINARY) {
return $value;
}
throw new InvalidArgumentException('Unsupported type.');
return $value;
}
/** @deprecated */
public function escape($value, $type)
{
return DibiHelpers::escape($this, $value, $type);
}

View File

@@ -222,33 +222,47 @@ class DibiOdbcDriver extends DibiObject implements IDibiDriver, IDibiResultDrive
/**
* Encodes data for use in a SQL statement.
* @param mixed value
* @param string type (dibi::TEXT, dibi::BOOL, ...)
* @return string encoded value
* @throws InvalidArgumentException
*/
public function escape($value, $type)
public function escapeText($value)
{
switch ($type) {
case dibi::TEXT:
case dibi::BINARY:
return "'" . str_replace("'", "''", $value) . "'";
return "'" . str_replace("'", "''", $value) . "'";
}
case dibi::IDENTIFIER:
return '[' . str_replace(array('[', ']'), array('[[', ']]'), $value) . ']';
case dibi::BOOL:
return $value ? 1 : 0;
public function escapeBinary($value)
{
return "'" . str_replace("'", "''", $value) . "'";
}
case dibi::DATE:
case dibi::DATETIME:
if (!$value instanceof DateTime && !$value instanceof DateTimeInterface) {
$value = new DibiDateTime($value);
}
return $value->format($type === dibi::DATETIME ? "#m/d/Y H:i:s#" : "#m/d/Y#");
default:
throw new InvalidArgumentException('Unsupported type.');
public function escapeIdentifier($value)
{
return '[' . str_replace(array('[', ']'), array('[[', ']]'), $value) . ']';
}
public function escapeBool($value)
{
return $value ? 1 : 0;
}
public function escapeDate($value)
{
if (!$value instanceof DateTime && !$value instanceof DateTimeInterface) {
$value = new DibiDateTime($value);
}
return $value->format("#m/d/Y#");
}
public function escapeDateTime($value)
{
if (!$value instanceof DateTime && !$value instanceof DateTimeInterface) {
$value = new DibiDateTime($value);
}
return $value->format("#m/d/Y H:i:s#");
}
@@ -267,17 +281,19 @@ class DibiOdbcDriver extends DibiObject implements IDibiDriver, IDibiResultDrive
/**
* Decodes data from result set.
* @param string value
* @param string type (dibi::BINARY)
* @return string decoded value
* @throws InvalidArgumentException
* @param string
* @return string
*/
public function unescape($value, $type)
public function unescapeBinary($value)
{
if ($type === dibi::BINARY) {
return $value;
}
throw new InvalidArgumentException('Unsupported type.');
return $value;
}
/** @deprecated */
public function escape($value, $type)
{
return DibiHelpers::escape($this, $value, $type);
}

View File

@@ -220,34 +220,48 @@ class DibiOracleDriver extends DibiObject implements IDibiDriver, IDibiResultDri
/**
* Encodes data for use in a SQL statement.
* @param mixed value
* @param string type (dibi::TEXT, dibi::BOOL, ...)
* @return string encoded value
* @throws InvalidArgumentException
*/
public function escape($value, $type)
public function escapeText($value)
{
switch ($type) {
case dibi::TEXT:
case dibi::BINARY:
return "'" . str_replace("'", "''", $value) . "'"; // TODO: not tested
return "'" . str_replace("'", "''", $value) . "'"; // TODO: not tested
}
case dibi::IDENTIFIER:
// @see http://download.oracle.com/docs/cd/B10500_01/server.920/a96540/sql_elements9a.htm
return '"' . str_replace('"', '""', $value) . '"';
case dibi::BOOL:
return $value ? 1 : 0;
public function escapeBinary($value)
{
return "'" . str_replace("'", "''", $value) . "'"; // TODO: not tested
}
case dibi::DATE:
case dibi::DATETIME:
if (!$value instanceof DateTime && !$value instanceof DateTimeInterface) {
$value = new DibiDateTime($value);
}
return $value->format($type === dibi::DATETIME ? $this->fmtDateTime : $this->fmtDate);
default:
throw new InvalidArgumentException('Unsupported type.');
public function escapeIdentifier($value)
{
// @see http://download.oracle.com/docs/cd/B10500_01/server.920/a96540/sql_elements9a.htm
return '"' . str_replace('"', '""', $value) . '"';
}
public function escapeBool($value)
{
return $value ? 1 : 0;
}
public function escapeDate($value)
{
if (!$value instanceof DateTime && !$value instanceof DateTimeInterface) {
$value = new DibiDateTime($value);
}
return $value->format($this->fmtDate);
}
public function escapeDateTime($value)
{
if (!$value instanceof DateTime && !$value instanceof DateTimeInterface) {
$value = new DibiDateTime($value);
}
return $value->format($this->fmtDateTime);
}
@@ -267,17 +281,19 @@ class DibiOracleDriver extends DibiObject implements IDibiDriver, IDibiResultDri
/**
* Decodes data from result set.
* @param string value
* @param string type (dibi::BINARY)
* @return string decoded value
* @throws InvalidArgumentException
* @param string
* @return string
*/
public function unescape($value, $type)
public function unescapeBinary($value)
{
if ($type === dibi::BINARY) {
return $value;
}
throw new InvalidArgumentException('Unsupported type.');
return $value;
}
/** @deprecated */
public function escape($value, $type)
{
return DibiHelpers::escape($this, $value, $type);
}

View File

@@ -243,70 +243,84 @@ class DibiPdoDriver extends DibiObject implements IDibiDriver, IDibiResultDriver
/**
* Encodes data for use in a SQL statement.
* @param mixed value
* @param string type (dibi::TEXT, dibi::BOOL, ...)
* @return string encoded value
* @throws InvalidArgumentException
*/
public function escape($value, $type)
public function escapeText($value)
{
switch ($type) {
case dibi::TEXT:
case dibi::BINARY:
if ($this->driverName === 'odbc') {
return "'" . str_replace("'", "''", $value) . "'";
} else {
return $this->connection->quote($value, $type === dibi::TEXT ? PDO::PARAM_STR : PDO::PARAM_LOB);
}
if ($this->driverName === 'odbc') {
return "'" . str_replace("'", "''", $value) . "'";
} else {
return $this->connection->quote($value, PDO::PARAM_STR);
}
}
case dibi::IDENTIFIER:
switch ($this->driverName) {
case 'mysql':
return '`' . str_replace('`', '``', $value) . '`';
case 'oci':
case 'pgsql':
return '"' . str_replace('"', '""', $value) . '"';
public function escapeBinary($value)
{
if ($this->driverName === 'odbc') {
return "'" . str_replace("'", "''", $value) . "'";
} else {
return $this->connection->quote($value, PDO::PARAM_LOB);
}
}
case 'sqlite':
case 'sqlite2':
return '[' . strtr($value, '[]', ' ') . ']';
case 'odbc':
case 'mssql':
return '[' . str_replace(array('[', ']'), array('[[', ']]'), $value) . ']';
public function escapeIdentifier($value)
{
switch ($this->driverName) {
case 'mysql':
return '`' . str_replace('`', '``', $value) . '`';
case 'dblib':
case 'sqlsrv':
return '[' . str_replace(']', ']]', $value) . ']';
case 'oci':
case 'pgsql':
return '"' . str_replace('"', '""', $value) . '"';
default:
return $value;
}
case 'sqlite':
case 'sqlite2':
return '[' . strtr($value, '[]', ' ') . ']';
case dibi::BOOL:
if ($this->driverName === 'pgsql') {
return $value ? 'TRUE' : 'FALSE';
} else {
return $value ? 1 : 0;
}
case 'odbc':
case 'mssql':
return '[' . str_replace(array('[', ']'), array('[[', ']]'), $value) . ']';
case dibi::DATE:
case dibi::DATETIME:
if (!$value instanceof DateTime && !$value instanceof DateTimeInterface) {
$value = new DibiDateTime($value);
}
if ($this->driverName === 'odbc') {
return $value->format($type === dibi::DATETIME ? '#m/d/Y H:i:s#' : '#m/d/Y#');
} else {
return $value->format($type === dibi::DATETIME ? "'Y-m-d H:i:s'" : "'Y-m-d'");
}
case 'dblib':
case 'sqlsrv':
return '[' . str_replace(']', ']]', $value) . ']';
default:
throw new InvalidArgumentException('Unsupported type.');
return $value;
}
}
public function escapeBool($value)
{
if ($this->driverName === 'pgsql') {
return $value ? 'TRUE' : 'FALSE';
} else {
return $value ? 1 : 0;
}
}
public function escapeDate($value)
{
if (!$value instanceof DateTime && !$value instanceof DateTimeInterface) {
$value = new DibiDateTime($value);
}
return $value->format($this->driverName === 'odbc' ? '#m/d/Y#' : "'Y-m-d'");
}
public function escapeDateTime($value)
{
if (!$value instanceof DateTime && !$value instanceof DateTimeInterface) {
$value = new DibiDateTime($value);
}
return $value->format($this->driverName === 'odbc' ? "#m/d/Y H:i:s#" : "'Y-m-d H:i:s'");
}
/**
* Encodes string for use in a LIKE statement.
* @param string
@@ -351,17 +365,19 @@ class DibiPdoDriver extends DibiObject implements IDibiDriver, IDibiResultDriver
/**
* Decodes data from result set.
* @param string value
* @param string type (dibi::BINARY)
* @return string decoded value
* @throws InvalidArgumentException
* @param string
* @return string
*/
public function unescape($value, $type)
public function unescapeBinary($value)
{
if ($type === dibi::BINARY) {
return $value;
}
throw new InvalidArgumentException('Unsupported type.');
return $value;
}
/** @deprecated */
public function escape($value, $type)
{
return DibiHelpers::escape($this, $value, $type);
}

View File

@@ -262,42 +262,54 @@ class DibiPostgreDriver extends DibiObject implements IDibiDriver, IDibiResultDr
/**
* Encodes data for use in a SQL statement.
* @param mixed value
* @param string type (dibi::TEXT, dibi::BOOL, ...)
* @return string encoded value
* @throws InvalidArgumentException
*/
public function escape($value, $type)
public function escapeText($value)
{
switch ($type) {
case dibi::TEXT:
if (!is_resource($this->connection)) {
throw new DibiException('Lost connection to server.');
}
return "'" . pg_escape_string($this->connection, $value) . "'";
case dibi::BINARY:
if (!is_resource($this->connection)) {
throw new DibiException('Lost connection to server.');
}
return "'" . pg_escape_bytea($this->connection, $value) . "'";
case dibi::IDENTIFIER:
// @see http://www.postgresql.org/docs/8.2/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS
return '"' . str_replace('"', '""', $value) . '"';
case dibi::BOOL:
return $value ? 'TRUE' : 'FALSE';
case dibi::DATE:
case dibi::DATETIME:
if (!$value instanceof DateTime && !$value instanceof DateTimeInterface) {
$value = new DibiDateTime($value);
}
return $value->format($type === dibi::DATETIME ? "'Y-m-d H:i:s'" : "'Y-m-d'");
default:
throw new InvalidArgumentException('Unsupported type.');
if (!is_resource($this->connection)) {
throw new DibiException('Lost connection to server.');
}
return "'" . pg_escape_string($this->connection, $value) . "'";
}
public function escapeBinary($value)
{
if (!is_resource($this->connection)) {
throw new DibiException('Lost connection to server.');
}
return "'" . pg_escape_bytea($this->connection, $value) . "'";
}
public function escapeIdentifier($value)
{
// @see http://www.postgresql.org/docs/8.2/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS
return '"' . str_replace('"', '""', $value) . '"';
}
public function escapeBool($value)
{
return $value ? 'TRUE' : 'FALSE';
}
public function escapeDate($value)
{
if (!$value instanceof DateTime && !$value instanceof DateTimeInterface) {
$value = new DibiDateTime($value);
}
return $value->format("'Y-m-d'");
}
public function escapeDateTime($value)
{
if (!$value instanceof DateTime && !$value instanceof DateTimeInterface) {
$value = new DibiDateTime($value);
}
return $value->format("'Y-m-d H:i:s'");
}
@@ -318,17 +330,19 @@ class DibiPostgreDriver extends DibiObject implements IDibiDriver, IDibiResultDr
/**
* Decodes data from result set.
* @param string value
* @param string type (dibi::BINARY)
* @return string decoded value
* @throws InvalidArgumentException
* @param string
* @return string
*/
public function unescape($value, $type)
public function unescapeBinary($value)
{
if ($type === dibi::BINARY) {
return pg_unescape_bytea($value);
}
throw new InvalidArgumentException('Unsupported type.');
return pg_unescape_bytea($value);
}
/** @deprecated */
public function escape($value, $type)
{
return DibiHelpers::escape($this, $value, $type);
}
@@ -486,7 +500,7 @@ class DibiPostgreDriver extends DibiObject implements IDibiDriver, IDibiResultDr
*/
public function getColumns($table)
{
$_table = $this->escape($this->escape($table, dibi::IDENTIFIER), dibi::TEXT);
$_table = $this->escapeText($this->escapeIdentifier($table));
$res = $this->query("
SELECT indkey
FROM pg_class
@@ -553,7 +567,7 @@ class DibiPostgreDriver extends DibiObject implements IDibiDriver, IDibiResultDr
*/
public function getIndexes($table)
{
$_table = $this->escape($this->escape($table, dibi::IDENTIFIER), dibi::TEXT);
$_table = $this->escapeText($this->escapeIdentifier($table));
$res = $this->query("
SELECT
a.attnum AS ordinal_position,
@@ -601,7 +615,7 @@ class DibiPostgreDriver extends DibiObject implements IDibiDriver, IDibiResultDr
*/
public function getForeignKeys($table)
{
$_table = $this->escape($this->escape($table, dibi::IDENTIFIER), dibi::TEXT);
$_table = $this->escapeText($this->escapeIdentifier($table));
$res = $this->query("
SELECT

View File

@@ -214,35 +214,47 @@ class DibiSqlite3Driver extends DibiObject implements IDibiDriver, IDibiResultDr
/**
* Encodes data for use in a SQL statement.
* @param mixed value
* @param string type (dibi::TEXT, dibi::BOOL, ...)
* @return string encoded value
* @throws InvalidArgumentException
*/
public function escape($value, $type)
public function escapeText($value)
{
switch ($type) {
case dibi::TEXT:
return "'" . $this->connection->escapeString($value) . "'";
return "'" . $this->connection->escapeString($value) . "'";
}
case dibi::BINARY:
return "X'" . bin2hex((string) $value) . "'";
case dibi::IDENTIFIER:
return '[' . strtr($value, '[]', ' ') . ']';
public function escapeBinary($value)
{
return "X'" . bin2hex((string) $value) . "'";
}
case dibi::BOOL:
return $value ? 1 : 0;
case dibi::DATE:
case dibi::DATETIME:
if (!$value instanceof DateTime && !$value instanceof DateTimeInterface) {
$value = new DibiDateTime($value);
}
return $value->format($type === dibi::DATETIME ? $this->fmtDateTime : $this->fmtDate);
public function escapeIdentifier($value)
{
return '[' . strtr($value, '[]', ' ') . ']';
}
default:
throw new InvalidArgumentException('Unsupported type.');
public function escapeBool($value)
{
return $value ? 1 : 0;
}
public function escapeDate($value)
{
if (!$value instanceof DateTime && !$value instanceof DateTimeInterface) {
$value = new DibiDateTime($value);
}
return $value->format($this->fmtDate);
}
public function escapeDateTime($value)
{
if (!$value instanceof DateTime && !$value instanceof DateTimeInterface) {
$value = new DibiDateTime($value);
}
return $value->format($this->fmtDateTime);
}
@@ -261,17 +273,19 @@ class DibiSqlite3Driver extends DibiObject implements IDibiDriver, IDibiResultDr
/**
* Decodes data from result set.
* @param string value
* @param string type (dibi::BINARY)
* @return string decoded value
* @throws InvalidArgumentException
* @param string
* @return string
*/
public function unescape($value, $type)
public function unescapeBinary($value)
{
if ($type === dibi::BINARY) {
return $value;
}
throw new InvalidArgumentException('Unsupported type.');
return $value;
}
/** @deprecated */
public function escape($value, $type)
{
return DibiHelpers::escape($this, $value, $type);
}

View File

@@ -279,6 +279,13 @@ class DibiSqliteDriver extends DibiObject implements IDibiDriver, IDibiResultDri
}
/** @deprecated */
public function escape($value, $type)
{
return DibiHelpers::escape($this, $value, $type);
}
/**
* Injects LIMIT/OFFSET to the SQL query.
* @return void

View File

@@ -52,12 +52,12 @@ class DibiSqliteReflector extends DibiObject implements IDibiReflector
public function getColumns($table)
{
$meta = $this->driver->query("
SELECT sql FROM sqlite_master WHERE type = 'table' AND name = {$this->driver->escape($table, dibi::TEXT)}
SELECT sql FROM sqlite_master WHERE type = 'table' AND name = {$this->driver->escapeText($table)}
UNION ALL
SELECT sql FROM sqlite_temp_master WHERE type = 'table' AND name = {$this->driver->escape($table, dibi::TEXT)}
SELECT sql FROM sqlite_temp_master WHERE type = 'table' AND name = {$this->driver->escapeText($table)}
")->fetch(TRUE);
$res = $this->driver->query("PRAGMA table_info({$this->driver->escape($table, dibi::IDENTIFIER)})");
$res = $this->driver->query("PRAGMA table_info({$this->driver->escapeIdentifier($table)})");
$columns = array();
while ($row = $res->fetch(TRUE)) {
$column = $row['name'];
@@ -85,7 +85,7 @@ class DibiSqliteReflector extends DibiObject implements IDibiReflector
*/
public function getIndexes($table)
{
$res = $this->driver->query("PRAGMA index_list({$this->driver->escape($table, dibi::IDENTIFIER)})");
$res = $this->driver->query("PRAGMA index_list({$this->driver->escapeIdentifier($table)})");
$indexes = array();
while ($row = $res->fetch(TRUE)) {
$indexes[$row['name']]['name'] = $row['name'];
@@ -93,7 +93,7 @@ class DibiSqliteReflector extends DibiObject implements IDibiReflector
}
foreach ($indexes as $index => $values) {
$res = $this->driver->query("PRAGMA index_info({$this->driver->escape($index, dibi::IDENTIFIER)})");
$res = $this->driver->query("PRAGMA index_info({$this->driver->escapeIdentifier($index)})");
while ($row = $res->fetch(TRUE)) {
$indexes[$index]['columns'][$row['seqno']] = $row['name'];
}
@@ -139,7 +139,7 @@ class DibiSqliteReflector extends DibiObject implements IDibiReflector
if (!($this->driver instanceof DibiSqlite3Driver)) {
// throw new DibiNotSupportedException; // @see http://www.sqlite.org/foreignkeys.html
}
$res = $this->driver->query("PRAGMA foreign_key_list({$this->driver->escape($table, dibi::IDENTIFIER)})");
$res = $this->driver->query("PRAGMA foreign_key_list({$this->driver->escapeIdentifier($table)})");
$keys = array();
while ($row = $res->fetch(TRUE)) {
$keys[$row['id']]['name'] = $row['id']; // foreign key name

33
src/Dibi/Helpers.php Normal file
View File

@@ -0,0 +1,33 @@
<?php
/**
* This file is part of the "dibi" - smart database abstraction layer.
* Copyright (c) 2005 David Grudl (https://davidgrudl.com)
*/
/**
* @package dibi
*/
class DibiHelpers
{
/** @internal */
public static function escape($driver, $value, $type)
{
static $types = array(
dibi::TEXT => 'text',
dibi::BINARY => 'binary',
dibi::BOOL => 'bool',
dibi::DATE => 'date',
dibi::DATETIME => 'datetime',
dibi::IDENTIFIER => 'identifier',
);
if (isset($types[$type])) {
return $driver->{'escape' . $types[$type]}($value);
} else {
throw new InvalidArgumentException('Unsupported type.');
}
}
}

View File

@@ -506,7 +506,7 @@ class DibiResult extends DibiObject implements IDataSource
}
} elseif ($type === dibi::BINARY) {
$row[$key] = $this->getResultDriver()->unescape($value, $type);
$row[$key] = $this->getResultDriver()->unescapeBinary($value);
}
}
}

View File

@@ -339,13 +339,17 @@ final class DibiTranslator extends DibiObject
switch ($modifier) {
case 's': // string
return $value === NULL ? 'NULL' : $this->driver->escapeText($value);
case 'bin':// binary
return $value === NULL ? 'NULL' : $this->driver->escapeBinary($value);
case 'b': // boolean
return $value === NULL ? 'NULL' : $this->driver->escape($value, $modifier);
return $value === NULL ? 'NULL' : $this->driver->escapeBool($value);
case 'sN': // string or NULL
case 'sn':
return $value == '' ? 'NULL' : $this->driver->escape($value, dibi::TEXT); // notice two equal signs
return $value == '' ? 'NULL' : $this->driver->escapeText($value); // notice two equal signs
case 'iN': // signed int or NULL
case 'in': // deprecated
@@ -381,13 +385,7 @@ final class DibiTranslator extends DibiObject
if ($value === NULL) {
return 'NULL';
} else {
if (is_numeric($value)) {
$value = (int) $value; // timestamp
} elseif (is_string($value)) {
$value = new DateTime($value);
}
return $this->driver->escape($value, $modifier);
return $modifier === 'd' ? $this->driver->escapeDate($value) : $this->driver->escapeDateTime($value);
}
case 'by':
@@ -441,7 +439,7 @@ final class DibiTranslator extends DibiObject
// without modifier procession
if (is_string($value)) {
return $this->driver->escape($value, dibi::TEXT);
return $this->driver->escapeText($value);
} elseif (is_int($value)) {
return (string) $value;
@@ -450,13 +448,13 @@ final class DibiTranslator extends DibiObject
return rtrim(rtrim(number_format($value, 10, '.', ''), '0'), '.');
} elseif (is_bool($value)) {
return $this->driver->escape($value, dibi::BOOL);
return $this->driver->escapeBool($value);
} elseif ($value === NULL) {
return 'NULL';
} elseif ($value instanceof DateTime || $value instanceof DateTimeInterface) {
return $this->driver->escape($value, dibi::DATETIME);
return $this->driver->escapeDateTime($value);
} elseif ($value instanceof DibiLiteral) {
return (string) $value;
@@ -582,10 +580,10 @@ final class DibiTranslator extends DibiObject
return $this->identifiers->{$matches[2]};
} elseif ($matches[3]) { // SQL strings: '...'
return $this->driver->escape(str_replace("''", "'", $matches[4]), dibi::TEXT);
return $this->driver->escapeText(str_replace("''", "'", $matches[4]));
} elseif ($matches[5]) { // SQL strings: "..."
return $this->driver->escape(str_replace('""', '"', $matches[6]), dibi::TEXT);
return $this->driver->escapeText(str_replace('""', '"', $matches[6]));
} elseif ($matches[7]) { // string quote
$this->hasError = TRUE;
@@ -614,7 +612,7 @@ final class DibiTranslator extends DibiObject
$parts = explode('.', $value);
foreach ($parts as & $v) {
if ($v !== '*') {
$v = $this->driver->escape($v, dibi::IDENTIFIER);
$v = $this->driver->escapeIdentifier($v);
}
}
return implode('.', $parts);

View File

@@ -97,12 +97,20 @@ interface IDibiDriver
/**
* Encodes data for use in a SQL statement.
* @param string value
* @param string type (dibi::TEXT, dibi::BOOL, ...)
* @param mixed value
* @return string encoded value
* @throws InvalidArgumentException
*/
function escape($value, $type);
function escapeText($value);
function escapeBinary($value);
function escapeIdentifier($value);
function escapeBool($value);
function escapeDate($value);
function escapeDateTime($value);
/**
* Encodes string for use in a LIKE statement.
@@ -171,12 +179,10 @@ interface IDibiResultDriver
/**
* Decodes data from result set.
* @param string value
* @param string type (dibi::BINARY)
* @return string decoded value
* @throws InvalidArgumentException
* @param string
* @return string
*/
function unescape($value, $type);
function unescapeBinary($value);
}