From b8e518f44b9640c2b9db2d7d81135db74d7e53ee Mon Sep 17 00:00:00 2001 From: David Grudl Date: Wed, 25 Aug 2010 18:45:48 +0200 Subject: [PATCH] implemented escapeLike() and modifiers %~like, %like~, %~like~ --- dibi/drivers/firebird.php | 13 +++++++++++++ dibi/drivers/mssql.php | 14 ++++++++++++++ dibi/drivers/mssql2005.php | 14 ++++++++++++++ dibi/drivers/mysql.php | 14 ++++++++++++++ dibi/drivers/mysqli.php | 14 ++++++++++++++ dibi/drivers/odbc.php | 14 ++++++++++++++ dibi/drivers/oracle.php | 13 +++++++++++++ dibi/drivers/pdo.php | 13 +++++++++++++ dibi/drivers/postgre.php | 13 +++++++++++++ dibi/drivers/sqlite.php | 13 +++++++++++++ dibi/drivers/sqlite3.php | 14 ++++++++++++++ dibi/libs/DibiTranslator.php | 13 +++++++++++-- dibi/libs/interfaces.php | 8 ++++++++ 13 files changed, 168 insertions(+), 2 deletions(-) diff --git a/dibi/drivers/firebird.php b/dibi/drivers/firebird.php index 3c7303d4..51ecdabf 100644 --- a/dibi/drivers/firebird.php +++ b/dibi/drivers/firebird.php @@ -278,6 +278,19 @@ class DibiFirebirdDriver extends DibiObject implements IDibiDriver, IDibiResultD + /** + * Encodes string for use in a LIKE statement. + * @param string + * @param int + * @return string + */ + public function escapeLike($value, $pos) + { + throw new NotImplementedException; + } + + + /** * Decodes data from result set. * @param string value diff --git a/dibi/drivers/mssql.php b/dibi/drivers/mssql.php index df69e057..f00a1109 100644 --- a/dibi/drivers/mssql.php +++ b/dibi/drivers/mssql.php @@ -230,6 +230,20 @@ class DibiMsSqlDriver extends DibiObject implements IDibiDriver, IDibiResultDriv + /** + * Encodes string for use in a LIKE statement. + * @param string + * @param int + * @return string + */ + public function escapeLike($value, $pos) + { + $value = strtr($value, array("'" => "''", '%' => '[%]', '_' => '[_]', '[' => '[[]')); + return ($pos <= 0 ? "'%" : "'") . $value . ($pos >= 0 ? "%'" : "'"); + } + + + /** * Decodes data from result set. * @param string value diff --git a/dibi/drivers/mssql2005.php b/dibi/drivers/mssql2005.php index d9be7a14..d3439c4f 100644 --- a/dibi/drivers/mssql2005.php +++ b/dibi/drivers/mssql2005.php @@ -232,6 +232,20 @@ class DibiMsSql2005Driver extends DibiObject implements IDibiDriver, IDibiResult + /** + * Encodes string for use in a LIKE statement. + * @param string + * @param int + * @return string + */ + public function escapeLike($value, $pos) + { + $value = strtr($value, array("'" => "''", '%' => '[%]', '_' => '[_]', '[' => '[[]')); + return ($pos <= 0 ? "'%" : "'") . $value . ($pos >= 0 ? "%'" : "'"); + } + + + /** * Decodes data from result set. * @param string value diff --git a/dibi/drivers/mysql.php b/dibi/drivers/mysql.php index 86bc8b12..312e6153 100644 --- a/dibi/drivers/mysql.php +++ b/dibi/drivers/mysql.php @@ -311,6 +311,20 @@ class DibiMySqlDriver extends DibiObject implements IDibiDriver, IDibiResultDriv + /** + * Encodes string for use in a LIKE statement. + * @param string + * @param int + * @return string + */ + public function escapeLike($value, $pos) + { + $value = addcslashes(str_replace('\\', '\\\\', $value), "\x00\n\r\\'%_"); + return ($pos <= 0 ? "'%" : "'") . $value . ($pos >= 0 ? "%'" : "'"); + } + + + /** * Decodes data from result set. * @param string value diff --git a/dibi/drivers/mysqli.php b/dibi/drivers/mysqli.php index c38a15c2..099f45f0 100644 --- a/dibi/drivers/mysqli.php +++ b/dibi/drivers/mysqli.php @@ -307,6 +307,20 @@ class DibiMySqliDriver extends DibiObject implements IDibiDriver, IDibiResultDri + /** + * Encodes string for use in a LIKE statement. + * @param string + * @param int + * @return string + */ + public function escapeLike($value, $pos) + { + $value = addcslashes(str_replace('\\', '\\\\', $value), "\x00\n\r\\'%_"); + return ($pos <= 0 ? "'%" : "'") . $value . ($pos >= 0 ? "%'" : "'"); + } + + + /** * Decodes data from result set. * @param string value diff --git a/dibi/drivers/odbc.php b/dibi/drivers/odbc.php index 941bef92..c093e47d 100644 --- a/dibi/drivers/odbc.php +++ b/dibi/drivers/odbc.php @@ -248,6 +248,20 @@ class DibiOdbcDriver extends DibiObject implements IDibiDriver, IDibiResultDrive + /** + * Encodes string for use in a LIKE statement. + * @param string + * @param int + * @return string + */ + public function escapeLike($value, $pos) + { + $value = strtr($value, array("'" => "''", '%' => '[%]', '_' => '[_]', '[' => '[[]')); + return ($pos <= 0 ? "'%" : "'") . $value . ($pos >= 0 ? "%'" : "'"); + } + + + /** * Decodes data from result set. * @param string value diff --git a/dibi/drivers/oracle.php b/dibi/drivers/oracle.php index 83f0a936..6b495c92 100644 --- a/dibi/drivers/oracle.php +++ b/dibi/drivers/oracle.php @@ -246,6 +246,19 @@ class DibiOracleDriver extends DibiObject implements IDibiDriver, IDibiResultDri + /** + * Encodes string for use in a LIKE statement. + * @param string + * @param int + * @return string + */ + public function escapeLike($value, $pos) + { + throw new NotImplementedException; + } + + + /** * Decodes data from result set. * @param string value diff --git a/dibi/drivers/pdo.php b/dibi/drivers/pdo.php index a54500d4..891d9d1f 100644 --- a/dibi/drivers/pdo.php +++ b/dibi/drivers/pdo.php @@ -281,6 +281,19 @@ class DibiPdoDriver extends DibiObject implements IDibiDriver, IDibiResultDriver + /** + * Encodes string for use in a LIKE statement. + * @param string + * @param int + * @return string + */ + public function escapeLike($value, $pos) + { + throw new NotImplementedException; + } + + + /** * Decodes data from result set. * @param string value diff --git a/dibi/drivers/postgre.php b/dibi/drivers/postgre.php index a5224677..e9344a74 100644 --- a/dibi/drivers/postgre.php +++ b/dibi/drivers/postgre.php @@ -289,6 +289,19 @@ class DibiPostgreDriver extends DibiObject implements IDibiDriver, IDibiResultDr + /** + * Encodes string for use in a LIKE statement. + * @param string + * @param int + * @return string + */ + public function escapeLike($value, $pos) + { + throw new NotImplementedException; + } + + + /** * Decodes data from result set. * @param string value diff --git a/dibi/drivers/sqlite.php b/dibi/drivers/sqlite.php index 683a3e30..fa33d232 100644 --- a/dibi/drivers/sqlite.php +++ b/dibi/drivers/sqlite.php @@ -255,6 +255,19 @@ class DibiSqliteDriver extends DibiObject implements IDibiDriver, IDibiResultDri + /** + * Encodes string for use in a LIKE statement. + * @param string + * @param int + * @return string + */ + public function escapeLike($value, $pos) + { + throw new NotSupportedException; + } + + + /** * Decodes data from result set. * @param string value diff --git a/dibi/drivers/sqlite3.php b/dibi/drivers/sqlite3.php index 31a656de..8598f81a 100644 --- a/dibi/drivers/sqlite3.php +++ b/dibi/drivers/sqlite3.php @@ -247,6 +247,20 @@ class DibiSqlite3Driver extends DibiObject implements IDibiDriver, IDibiResultDr + /** + * Encodes string for use in a LIKE statement. + * @param string + * @param int + * @return string + */ + public function escapeLike($value, $pos) + { + $value = addcslashes($this->connection->escapeString($value), '%_\\'); + return ($pos <= 0 ? "'%" : "'") . $value . ($pos >= 0 ? "%'" : "'") . " ESCAPE '\\'"; + } + + + /** * Decodes data from result set. * @param string value diff --git a/dibi/libs/DibiTranslator.php b/dibi/libs/DibiTranslator.php index 0eaf92ae..eafbc0c4 100644 --- a/dibi/libs/DibiTranslator.php +++ b/dibi/libs/DibiTranslator.php @@ -114,11 +114,11 @@ final class DibiTranslator extends DibiObject (")((?:""|[^"])*)"| ## 5,6) "string" (\'|")| ## 7) lone quote :(\S*?:)([a-zA-Z0-9._]?)| ## 8,9) :substitution: - %([a-zA-Z]{1,4})(?![a-zA-Z])|## 10) modifier + %([a-zA-Z~][a-zA-Z0-9~]{0,5})|## 10) modifier (\?) ## 11) placeholder )/xs', */ // note: this can change $this->args & $this->cursor & ... - . preg_replace_callback('/(?=[`[\'":%?])(?:`(.+?)`|\[(.+?)\]|(\')((?:\'\'|[^\'])*)\'|(")((?:""|[^"])*)"|(\'|")|:(\S*?:)([a-zA-Z0-9._]?)|%([a-zA-Z]{1,4})(?![a-zA-Z])|(\?))/s', + . preg_replace_callback('/(?=[`[\'":%?])(?:`(.+?)`|\[(.+?)\]|(\')((?:\'\'|[^\'])*)\'|(")((?:""|[^"])*)"|(\'|")|:(\S*?:)([a-zA-Z0-9._]?)|%([a-zA-Z~][a-zA-Z0-9~]{0,5})|(\?))/s', array($this, 'cb'), substr($arg, $toSkip) ); @@ -387,6 +387,15 @@ final class DibiTranslator extends DibiObject case 'SQL': // preserve as real SQL (TODO: rename to %sql) return (string) $value; + case 'like~': // LIKE string% + return $this->driver->escapeLike($value, 1); + + case '~like': // LIKE %string + return $this->driver->escapeLike($value, -1); + + case '~like~': // LIKE %string% + return $this->driver->escapeLike($value, 0); + case 'and': case 'or': case 'a': diff --git a/dibi/libs/interfaces.php b/dibi/libs/interfaces.php index ecfb32cc..5a7c051d 100644 --- a/dibi/libs/interfaces.php +++ b/dibi/libs/interfaces.php @@ -166,6 +166,14 @@ interface IDibiDriver */ function escape($value, $type); + /** + * Encodes string for use in a LIKE statement. + * @param string + * @param int + * @return string + */ + function escapeLike($value, $pos); + /** * Injects LIMIT/OFFSET to the SQL query. * @param string &$sql The SQL query that will be modified.