Project

General

Profile

Bug #23103 » 15001_dbal_v4.diff

Administrator Admin, 2010-07-20 07:57

View differences:

class.ux_t3lib_sqlparser.php (working copy)
// Set comparator:
if ($v['comparator']) {
switch (TRUE) {
case ($GLOBALS['TYPO3_DB']->runningADOdbDriver('oci8') && $v['comparator'] === 'LIKE' && $functionMapping):
// Oracle cannot handle LIKE on CLOB fields - sigh
if (isset($v['value']['operator'])) {
$values = array();
foreach ($v['value']['args'] as $fieldDef) {
$values[] = ($fieldDef['table'] ? $fieldDef['table'] . '.' : '') . $fieldDef['field'];
}
$compareValue = ' ' . $v['value']['operator'] . '(' . implode(',', $values) . ')';
} else {
$compareValue = $v['value'][1] . $this->compileAddslashes(trim($v['value'][0], '%')) . $v['value'][1];
if ($v['comparator'] === 'LIKE') {
if ($GLOBALS['TYPO3_DB']->runningADOdbDriver('oci8') && $functionMapping) {
// Oracle cannot handle LIKE on CLOB fields - sigh
if (isset($v['value']['operator'])) {
$values = array();
foreach ($v['value']['args'] as $fieldDef) {
$values[] = ($fieldDef['table'] ? $fieldDef['table'] . '.' : '') . $fieldDef['field'];
}
// To be on the safe side
$isLob = TRUE;
if ($v['table']) {
// Table and field names are quoted:
$tableName = substr($v['table'], 1, strlen($v['table']) - 2);
$fieldName = substr($v['field'], 1, strlen($v['field']) - 2);
$fieldType = $GLOBALS['TYPO3_DB']->sql_field_metatype($tableName, $fieldName);
$isLob = ($fieldType === 'B' || $fieldType === 'XL');
$compareValue = ' ' . $v['value']['operator'] . '(' . implode(',', $values) . ')';
} else {
// Remove %'s at the beginning and at the end
$value = trim($v['value'][0], '%');
// But keep it within the search string if it is escaped => literal
if (substr($value, -1) === '\\') {
$value .= '%';
}
if ($isLob) {
$output .= '(dbms_lob.instr(' . trim(($v['table'] ? $v['table'] . '.' : '') . $v['field']) . ', ' . $compareValue . ',1,1) > 0)';
} else {
$output .= '(instr(' . trim(($v['table'] ? $v['table'] . '.' : '') . $v['field']) . ', ' . $compareValue . ',1,1) > 0)';
}
break;
default:
$output .= ' ' . $v['comparator'];
// Detecting value type; list or plain:
if (t3lib_div::inList('NOTIN,IN', strtoupper(str_replace(array(' ', "\t", "\r", "\n"), '', $v['comparator'])))) {
if (isset($v['subquery'])) {
$output .= ' (' . $this->compileSELECT($v['subquery']) . ')';
} else {
$valueBuffer = array();
foreach ($v['value'] as $realValue) {
$valueBuffer[] = $realValue[1] . $this->compileAddslashes($realValue[0]) . $realValue[1];
}
$output .= ' (' . trim(implode(',', $valueBuffer)) . ')';
}
} else if (isset($v['value']['operator'])) {
// As we are going to use the instr method, wildcards should not be escaped anymore
$value = preg_replace('/\\\\([%_])/', '$1', $value);
$compareValue = $v['value'][1] . $this->compileAddslashes($value) . $v['value'][1];
}
// To be on the safe side
$isLob = TRUE;
if ($v['table']) {
// Table and field names are quoted:
$tableName = substr($v['table'], 1, strlen($v['table']) - 2);
$fieldName = substr($v['field'], 1, strlen($v['field']) - 2);
$fieldType = $GLOBALS['TYPO3_DB']->sql_field_metatype($tableName, $fieldName);
$isLob = ($fieldType === 'B' || $fieldType === 'XL');
}
if ($isLob) {
$output .= '(dbms_lob.instr(' . trim(($v['table'] ? $v['table'] . '.' : '') . $v['field']) . ', ' . $compareValue . ',1,1) > 0)';
} else {
$output .= '(instr(' . trim(($v['table'] ? $v['table'] . '.' : '') . $v['field']) . ', ' . $compareValue . ',1,1) > 0)';
}
} else {
$output .= ' LIKE ';
if (isset($v['value']['operator'])) {
$values = array();
foreach ($v['value']['args'] as $fieldDef) {
$values[] = ($fieldDef['table'] ? $fieldDef['table'] . '.' : '') . $fieldDef['field'];
}
$output .= ' ' . $v['value']['operator'] . '(' . implode(',', $values) . ')';
$output .= $v['value']['operator'] . '(' . implode(',', $values) . ')';
} else {
$output .= ' ' . $v['value'][1] . $this->compileAddslashes($v['value'][0]) . $v['value'][1];
$output .= $v['value'][1] . $this->compileAddslashes($v['value'][0]) . $v['value'][1];
}
break;
if ($GLOBALS['TYPO3_DB']->runningADOdbDriver('mssql') && $functionMapping && preg_match('/\\\\[%_]/', $v['value'][0])) {
// Escaped wilcards need special handling with MSSQL
$output .= ' ESCAPE \'\\\'';
}
}
} else /* $v['comparator'] !== 'LIKE' */ {
$output .= ' ' . $v['comparator'];
// Detecting value type; list or plain:
if (t3lib_div::inList('NOTIN,IN', strtoupper(str_replace(array(' ', "\t", "\r", "\n"), '', $v['comparator'])))) {
if (isset($v['subquery'])) {
$output .= ' (' . $this->compileSELECT($v['subquery']) . ')';
} else {
$valueBuffer = array();
foreach ($v['value'] as $realValue) {
$valueBuffer[] = $realValue[1] . $this->compileAddslashes($realValue[0]) . $realValue[1];
}
$output .= ' (' . trim(implode(',', $valueBuffer)) . ')';
}
} else if (isset($v['value']['operator'])) {
$values = array();
foreach ($v['value']['args'] as $fieldDef) {
$values[] = ($fieldDef['table'] ? $fieldDef['table'] . '.' : '') . $fieldDef['field'];
}
$output .= ' ' . $v['value']['operator'] . '(' . implode(',', $values) . ')';
} else {
$output .= ' ' . $v['value'][1] . $this->compileAddslashes($v['value'][0]) . $v['value'][1];
}
}
}
}
class.ux_t3lib_db.php (working copy)
$table = $queryParts['TABLE'];
$values = array();
if (isset($queryParts['VALUES_ONLY']) && is_array($queryParts['VALUES_ONLY'])) {
$fields = $GLOBALS['TYPO3_DB']->cache_fieldType[$table];
$fields = $this->cache_fieldType[$table];
$fc = 0;
foreach ($fields as $fn => $fd) {
$values[$fn] = $queryParts['VALUES_ONLY'][$fc++][0];
......
return $query;
}
/**
* Returns a WHERE clause which will make an AND search for the words in the $searchWords array
* in any of the fields in array $fields.
*
* @param array Array of search words
* @param array Array of fields
* @param string Table in which we are searching (for DBAL detection of quoteStr() method)
* @return string WHERE clause for search
* @see removeUnsupportedFieldsForLike()
*/
public function searchQuery($searchWords, $fields, $table) {
$queryPart = $this->removeUnsupportedFieldsForLike($searchWords, $fields, $table);
if (strlen($queryPart) > 0) {
$queryPart .= ' OR ';
}
if (count($fields) > 0) {
$queryPart .= parent::searchQuery($searchWords, $fields, $table);
}
return $queryPart;
}
/**************************************
*
* Functions for quoting table/field names
......
}
}
/**
* Returns a where clause part or an empty string, deletes all unsupported fields from referenced fields-array.
*
* DBAL specific: Oracle: no LIKE for numeric fields, use exact search instead
* Oracle: no LIKE for BLOB fields
*
* @param array Array of search words
* @param array Array of fields, passed by reference!
* @param string Table in which we are searching (for DBAL detection of quoteStr() method)
* @return string WHERE clause for search
*/
protected function removeUnsupportedFieldsForLike($searchWords, &$fields, $table) {
$queryPart = '';
if ($this->runningADOdbDriver('oci8')) {
$numericQueryParts = array();
$numericSearchWords = array_filter($searchWords, 'is_numeric');
foreach ($fields as $key => $fieldName) {
switch ($this->cache_fieldType[$table][$fieldName]['metaType']) {
case 'I':
case 'I1':
case 'I2':
case 'I4':
case 'I8':
case 'F':
// Looking within numeric fields with an exact search
foreach ($numericSearchWords as $word) {
$numericQueryParts[] = $fields[$key] . '=' . intval($word);
}
unset($fields[$key]);
break;
case 'B':
// Remove all BLOB columns, as LIKE is not supported on them...
unset($fields[$key]);
break;
default:
// Do nothing
}
}
reset($fields);
$queryPart .= implode(' OR ', $numericQueryParts);
}
return $queryPart;
}
/**************************************
*
* SQL wrapper functions (Overriding parent methods)
tests/dbOracleTest.php (working copy)
$this->assertEquals($expected, $select);
}
/**
* @test
* @see http://bugs.typo3.org/view.php?id=15001
*/
public function wildcardCharacterCanBeUsedWithLike() {
$select = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery(
'*',
'pages',
'title LIKE \'%\\%%\''
));
$expected = 'SELECT * FROM "pages" WHERE (dbms_lob.instr("title", \'%\',1,1) > 0)';
$this->assertEquals($expected, $select);
$select = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery(
'*',
'pages',
'title LIKE \'%Some\\%thing\\_Else\\_%\''
));
$expected = 'SELECT * FROM "pages" WHERE (dbms_lob.instr("title", \'Some%thing_Else_\',1,1) > 0)';
$this->assertEquals($expected, $select);
}
///////////////////////////////////////
// Tests concerning DB management
///////////////////////////////////////
tests/dbMssqlTest.php (working copy)
}
///////////////////////////////////////
// Tests concerning remapping
///////////////////////////////////////
/**
* @test
* @see http://bugs.typo3.org/view.php?id=15001
*/
public function wildcardCharacterCanBeUsedWithLike() {
$select = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery(
'*',
'pages',
'title LIKE \'%\\%%\''
));
$expected = 'SELECT * FROM "pages" WHERE "title" LIKE \'%\\%%\' ESCAPE \'\\\'';
$this->assertEquals($expected, $select);
$select = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery(
'*',
'pages',
'title LIKE \'%Some\\%thing\\_Else\\_%\''
));
$expected = 'SELECT * FROM "pages" WHERE "title" LIKE \'%Some\\%thing\\_Else\\_%\' ESCAPE \'\\\'';
$this->assertEquals($expected, $select);
}
///////////////////////////////////////
// Tests concerning advanced operators
///////////////////////////////////////
ext_localconf.php (working copy)
$TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_db.php'] = t3lib_extMgm::extPath('dbal') . 'class.ux_t3lib_db.php';
$TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_sqlparser.php'] = t3lib_extMgm::extPath('dbal') . 'class.ux_t3lib_sqlparser.php';
$TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/class.db_list_extra.inc'] = t3lib_extMgm::extPath('dbal') . 'class.ux_db_list_extra.php';
// Register a hook for the installer
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install/mod/class.tx_install.php']['stepOutput'][] = 'EXT:dbal/class.tx_dbal_installtool.php:tx_dbal_installtool';
(3-3/4)