2010-08-23 Xavier Perseguers <typo3@perseguers.ch>
+ * Raised DBAL to version 1.2.0alpha1
* Fixed bug #15528: Add unit tests for t3lib_db_PreparedStatement (thanks to Helmut Hummel)
* Fixed bug #15527: Enhance t3lib_db_PreparedStatement (thanks to Helmut Hummel)
+2010-08-23 Xavier Perseguers <typo3@perseguers.ch>
+
+ * Set version to 1.2.0alpha1
+
+2010-08-19 Xavier Perseguers <typo3@perseguers.ch>
+
+ * Added unit test for feature #15457
+ * Added feature #15457: Add support for prepared queries
+
+2010-08-14 Xavier Perseguers <typo3@perseguers.ch>
+
+ * Code cleanup with useless blank spaces at end of line
+
+2010-08-08 Xavier Perseguers <typo3@perseguers.ch>
+
+ * Added unit test for bug #15253: NOT LIKE is not remapped using dbms_lob.instr with Oracle
+ * Fixed bug #12535: DAM-related: Element browser crashes as where-clause cannot be parsed
+
+2010-07-27 Xavier Perseguers <typo3@perseguers.ch>
+
+ * Fixed bug #15160: Queries should only be parsed once
+
+2010-07-17 Xavier Perseguers <typo3@perseguers.ch>
+
+ * Updated PHP documentation
+
+2010-07-16 Xavier Perseguers <typo3@perseguers.ch>
+
+ * Added unit test for bug #14818: t3lib_db->listQuery() performance
+ * Fixed bug #14985: FIND_IN_SET should be used isntead of complicated LIKE where clause
+
+2010-07-11 Xavier Perseguers <typo3@perseguers.ch>
+
+ * Fixed bug #15045: Trailing newlines after php closing tag
+
+2010-06-27 Xavier Perseguers <typo3@perseguers.ch>
+
+ * Synchronized @deprecated annotations with Core
+
2010-06-22 Jeff Segars <jeff@webempoweredchurch.org>
- * Fixed bug #14814: Improve install tool texts.
+ * Fixed bug #14814: Improve install tool texts
-2010-06-13 Xavier Perseguers <typo3@perseguers.ch>
+2010-06-19 Xavier Perseguers <typo3@perseguers.ch>
- * Set version to 1.1.7 (TYPO3 4.4i RC1)
+ * Fixed bug #3855: Log number of returned or affected rows
+ * Updated copyright year in manual
2010-06-12 Xavier Perseguers <typo3@perseguers.ch>
* Fixed bug #7015: t3lib_DB displays wrong SQL in error case
-2010-05-28 Xavier Perseguers <typo3@perseguers.ch>
-
- * Set version to 1.1.6 (TYPO3 4.4 beta3)
-
2010-05-27 Xavier Perseguers <typo3@perseguers.ch>
* Fixed bug #14496: SQL parser does not handle ALTER TABLE with character set operation
2010-05-03 Xavier Perseguers <typo3@perseguers.ch>
- * Set version to 1.1.5 (TYPO3 4.4 beta2)
* Fixed 1-2-3 installer crash when having only mysql available
-2010-05-02 Xavier Perseguers <typo3@perseguers.ch>
-
- * Set version to 1.1.4 (TYPO3 4.4 beta2)
-
2010-05-01 Xavier Perseguers <typo3@perseguers.ch>
* Fixed bug #14274: Some exception are not caught when trying to install DBAL in 1-2-3 Install Tool process
* Fixed bug #2186: Error installing static_info_tables
* Fixed bug #14265: Driver dropdown in install tool should be hidden when only MySQL is available
-2010-04-30 Xavier Perseguers <typo3@perseguers.ch>
-
- * Set version to 1.1.3
-
2010-04-29 Xavier Perseguers <typo3@perseguers.ch>
* Added autoloader for Install Tool
/***************************************************************
* Copyright notice
*
-* (c) 1999-2010 Kasper Skaarhoj (kasperYYYY@typo3.com)
-* (c) 2006-2010 Karsten Dambekalns <karsten@typo3.org>
+* (c) 1999-2009 Kasper Skaarhoj (kasperYYYY@typo3.com)
+* (c) 2006-2009 Karsten Dambekalns <karsten@typo3.org>
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
/**
* Include file extending localRecordList for DBAL compatibility
*
- * $Id: class.ux_db_list_extra.php 25913 2009-10-27 14:20:41Z xperseguers $
+ * $Id: class.ux_db_list_extra.php 30032 2010-02-14 23:14:56Z xperseguers $
*
* @author Kasper Skaarhoj <kasperYYYY@typo3.com>
* @author Karsten Dambekalns <k.dambekalns@fishfarm.de>
/***************************************************************
* Copyright notice
*
-* (c) 2004-2010 Kasper Skaarhoj (kasperYYYY@typo3.com)
-* (c) 2004-2010 Karsten Dambekalns <karsten@typo3.org>
+* (c) 2004-2009 Kasper Skaarhoj (kasperYYYY@typo3.com)
+* (c) 2004-2009 Karsten Dambekalns <karsten@typo3.org>
* (c) 2009-2010 Xavier Perseguers <typo3@perseguers.ch>
* All rights reserved
*
/**
* Contains a database abstraction layer class for TYPO3
*
- * $Id: class.ux_t3lib_db.php 29977 2010-02-13 13:18:32Z xperseguers $
+ * $Id: class.ux_t3lib_db.php 37006 2010-08-19 16:40:34Z xperseguers $
*
* @author Kasper Skaarhoj <kasper@typo3.com>
* @author Karsten Dambekalns <k.dambekalns@fishfarm.de>
// Map table / field names if needed:
$ORIG_tableName = $from_table; // Saving table names in $ORIG_from_table since $from_table is transformed beneath:
- if ($tableArray = $this->map_needMapping($ORIG_tableName)) {
- $this->map_remapSELECTQueryParts($select_fields,$from_table,$where_clause,$groupBy,$orderBy); // Variables passed by reference!
+ $parsedFromTable = array();
+ $remappedParameters = array();
+ if ($tableArray = $this->map_needMapping($ORIG_tableName, FALSE, $parsedFromTable)) {
+ $from = $parsedFromTable ? $parsedFromTable : $from_table;
+ $remappedParameters = $this->map_remapSELECTQueryParts($select_fields, $from, $where_clause, $groupBy, $orderBy);
}
// Get handler key and select API:
$hType = (string)$this->handlerCfg[$this->lastHandlerKey]['type'];
switch ($hType) {
case 'native':
- $this->lastQuery = $this->SELECTquery($select_fields,$from_table,$where_clause,$groupBy,$orderBy,$limit);
+ if (count($remappedParameters) > 0) {
+ list($select_fields, $from_table, $where_clause, $groupBy, $orderBy) = $this->compileSelectParameters($remappedParameters);
+ }
+ $this->lastQuery = $this->SELECTquery($select_fields, $from_table, $where_clause, $groupBy, $orderBy, $limit);
$sqlResult = mysql_query($this->lastQuery, $this->handlerInstance[$this->lastHandlerKey]['link']);
$this->resourceIdToTableNameMap[(string)$sqlResult] = $ORIG_tableName;
break;
$offset = 0;
}
- $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->SelectLimit($this->SELECTquery($select_fields,$from_table,$where_clause,$groupBy,$orderBy), $numrows, $offset);
+ if (count($remappedParameters) > 0) {
+ $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->SelectLimit($this->SELECTqueryFromArray($remappedParameters), $numrows, $offset);
+ } else {
+ $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->SelectLimit($this->SELECTquery($select_fields, $from_table, $where_clause, $groupBy, $orderBy), $numrows, $offset);
+ }
$this->lastQuery = $sqlResult->sql;
} else {
- $this->lastQuery = $this->SELECTquery($select_fields,$from_table,$where_clause,$groupBy,$orderBy);
+ if (count($remappedParameters) > 0) {
+ $this->lastQuery = $this->SELECTqueryFromArray($remappedParameters);
+ } else {
+ $this->lastQuery = $this->SELECTquery($select_fields, $from_table, $where_clause, $groupBy, $orderBy);
+ }
$sqlResult = $this->handlerInstance[$this->lastHandlerKey]->_Execute($this->lastQuery);
}
$sqlResult->TYPO3_DBAL_tableList = $ORIG_tableName;
break;
case 'userdefined':
- $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->exec_SELECTquery($select_fields,$from_table,$where_clause,$groupBy,$orderBy,$limit);
+ if (count($remappedParameters) > 0) {
+ list($select_fields, $from_table, $where_clause, $groupBy, $orderBy) = $this->compileSelectParameters($remappedParameters);
+ }
+ $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->exec_SELECTquery($select_fields, $from_table, $where_clause, $groupBy, $orderBy, $limit);
if (is_object($sqlResult)) {
$sqlResult->TYPO3_DBAL_handlerType = 'userdefined'; // Setting handler type in result object (for later recognition!)
$sqlResult->TYPO3_DBAL_tableList = $ORIG_tableName;
}
if ($this->debug) {
+ $data = array(
+ 'handlerType' => $hType,
+ 'args' => array($from_table, $select_fields, $where_clause, $groupBy, $orderBy, $limit),
+ 'ORIG_from_table' => $ORIG_tableName,
+ );
+ if ($this->conf['debugOptions']['numberRows']) {
+ $data['numberRows'] = $this->sql_num_rows($sqlResult);
+ }
$this->debugHandler(
'exec_SELECTquery',
t3lib_div::milliseconds()-$pt,
- array(
- 'handlerType' => $hType,
- 'args' => array($from_table,$select_fields,$where_clause,$groupBy,$orderBy,$limit),
- 'ORIG_from_table' => $ORIG_tableName
- )
+ $data
);
}
return $query;
}
+ /**
+ * Creates a SELECT SQL-statement to be used with an ADOdb backend.
+ *
+ * @param array parsed parameters: array($select_fields, $from_table, $where_clause, $groupBy, $orderBy)
+ * @return string Full SQL query for SELECT
+ */
+ protected function SELECTqueryFromArray(array $params) {
+ // $select_fields
+ $params[0] = $this->_quoteFieldNames($params[0]);
+ // $from_table
+ $params[1] = $this->_quoteFromTables($params[1]);
+ // $where_clause
+ if (count($params[2]) > 0) {
+ $params[2] = $this->_quoteWhereClause($params[2]);
+ }
+ // $group_by
+ if (count($params[3]) > 0) {
+ $params[3] = $this->_quoteGroupBy($params[3]);
+ }
+ // $order_by
+ if (count($params[4]) > 0) {
+ $params[4] = $this->_quoteOrderBy($params[4]);
+ }
+
+ // Compile the SELECT parameters
+ list($select_fields, $from_table, $where_clause, $groupBy, $orderBy) = $this->compileSelectParameters($params);
+
+ // Call parent method to build actual query
+ $query = parent::SELECTquery($select_fields, $from_table, $where_clause, $groupBy, $orderBy);
+
+ if ($this->debugOutput || $this->store_lastBuiltQuery) {
+ $this->debug_lastBuiltQuery = $query;
+ }
+
+ return $query;
+ }
+
+ /**
+ * Compiles and returns an array of SELECTquery parameters (without $limit) to
+ * be used with SELECTquery() or exec_SELECTquery().
+ *
+ * @param array $params
+ * @return array array($select_fields, $from_table, $where_clause, $groupBy, $orderBy)
+ */
+ protected function compileSelectParameters(array $params) {
+ $select_fields = $this->SQLparser->compileFieldList($params[0]);
+ $from_table = $this->SQLparser->compileFromTables($params[1]);
+ $where_clause = (count($params[2]) > 0) ? $this->SQLparser->compileWhereClause($params[2]) : '';
+ $groupBy = (count($params[3]) > 0) ? $this->SQLparser->compileFieldList($params[3]) : '';
+ $orderBy = (count($params[4]) > 0) ? $this->SQLparser->compileFieldList($params[4]) : '';
+
+ return array($select_fields, $from_table, $where_clause, $groupBy, $orderBy);
+ }
+
/**
* Creates a TRUNCATE TABLE SQL-statement
*
return $query;
}
+ /**************************************
+ *
+ * Prepared Query Support
+ *
+ **************************************/
+
+ /**
+ * Creates a SELECT prepared SQL statement.
+ *
+ * @param string See exec_SELECTquery()
+ * @param string See exec_SELECTquery()
+ * @param string See exec_SELECTquery()
+ * @param string See exec_SELECTquery()
+ * @param string See exec_SELECTquery()
+ * @param string See exec_SELECTquery()
+ * @param array $input_parameters An array of values with as many elements as there are bound parameters in the SQL statement being executed. All values are treated as t3lib_db_PreparedStatement::PARAM_AUTOTYPE.
+ * @return t3lib_db_PreparedStatement Prepared statement
+ */
+ public function prepare_SELECTquery($select_fields, $from_table, $where_clause, $groupBy = '', $orderBy = '', $limit = '', array $input_parameters = array()) {
+ if ($this->debug) {
+ $pt = t3lib_div::milliseconds();
+ }
+
+ // Map table / field names if needed:
+ $ORIG_tableName = $from_table; // Saving table names in $ORIG_from_table since $from_table is transformed beneath:
+ $parsedFromTable = array();
+ $queryComponents = array();
+ if ($tableArray = $this->map_needMapping($ORIG_tableName, FALSE, $parsedFromTable)) {
+ $from = $parsedFromTable ? $parsedFromTable : $from_table;
+ $components = $this->map_remapSELECTQueryParts($select_fields, $from, $where_clause, $groupBy, $orderBy);
+ $queryComponents['SELECT'] = $components[0];
+ $queryComponents['FROM'] = $components[1];
+ $queryComponents['WHERE'] = $components[2];
+ $queryComponents['GROUPBY'] = $components[3];
+ $queryComponents['ORDERBY'] = $components[4];
+ $queryComponents['parameters'] = $components[5];
+ } else {
+ $queryComponents = $this->getQueryComponents($select_fields, $from_table, $where_clause, $groupBy, $orderBy, $limit);
+ }
+
+ $queryComponents['ORIG_tableName'] = $ORIG_tableName;
+
+ if (!$this->runningNative()) {
+ // Quotes all fields
+ $queryComponents['SELECT'] = $this->_quoteFieldNames($queryComponents['SELECT']);
+ $queryComponents['FROM'] = $this->_quoteFromTables($queryComponents['FROM']);
+ $queryComponents['WHERE'] = $this->_quoteWhereClause($queryComponents['WHERE']);
+ $queryComponents['GROUPBY'] = $this->_quoteGroupBy($queryComponents['GROUPBY']);
+ $queryComponents['ORDERBY'] = $this->_quoteOrderBy($queryComponents['ORDERBY']);
+ }
+
+ $precompiledParts = $this->precompileSELECTquery($queryComponents);
+
+ $preparedStatement = t3lib_div::makeInstance('t3lib_db_PreparedStatement', '', $from_table, $precompiledParts);
+ /* @var $preparedStatement t3lib_db_PreparedStatement */
+
+ // Bind values to parameters
+ foreach ($input_parameters as $key => $value) {
+ $preparedStatement->bindValue($key, $value, t3lib_db_PreparedStatement::PARAM_AUTOTYPE);
+ }
+
+ if ($this->debug) {
+ $data = array(
+ 'args' => array($from_table, $select_fields, $where_clause, $groupBy, $orderBy, $limit, $input_parameters),
+ 'ORIG_from_table' => $ORIG_tableName,
+ );
+ $this->debugHandler(
+ 'prepare_SELECTquery',
+ t3lib_div::milliseconds() - $pt,
+ $data
+ );
+ }
+
+ // Return prepared statement
+ return $preparedStatement;
+ }
+
+ /**
+ * Returns the parsed query components.
+ *
+ * @param string $select_fields
+ * @param string $from_table
+ * @param string $where_clause
+ * @param string $groupBy
+ * @param string $orderBy
+ * @param string $limit
+ * @return array
+ */
+ protected function getQueryComponents($select_fields, $from_table, $where_clause, $groupBy, $orderBy, $limit) {
+ $queryComponents = array(
+ 'SELECT' => '',
+ 'FROM' => '',
+ 'WHERE' => '',
+ 'GROUPBY' => '',
+ 'ORDERBY' => '',
+ 'LIMIT' => '',
+ 'parameters' => array(),
+ );
+
+ $this->lastHandlerKey = $this->handler_getFromTableList($from_table);
+ $hType = (string)$this->handlerCfg[$this->lastHandlerKey]['type'];
+ if ($hType === 'adodb' && $this->runningADOdbDriver('postgres')) {
+ // Possibly rewrite the LIMIT to be PostgreSQL-compatible
+ $splitLimit = t3lib_div::intExplode(',', $limit); // Splitting the limit values:
+ if ($splitLimit[1]) { // If there are two parameters, do mapping differently than otherwise:
+ $numrows = $splitLimit[1];
+ $offset = $splitLimit[0];
+ $limit = $numrows . ' OFFSET ' . $offset;
+ }
+ }
+ $queryComponents['LIMIT'] = $limit;
+
+ $queryComponents['SELECT'] = $this->SQLparser->parseFieldList($select_fields);
+ if ($this->SQLparser->parse_error) {
+ die($this->SQLparser->parse_error . ' in ' . __FILE__ . ' : ' . __LINE__);
+ }
+
+ $queryComponents['FROM'] = $this->SQLparser->parseFromTables($from_table);
+
+ $queryComponents['WHERE'] = $this->SQLparser->parseWhereClause($where_clause, '', $queryComponents['parameters']);
+ if (!is_array($queryComponents['WHERE'])) {
+ die('Could not parse where clause in ' . __FILE__ . ' : ' . __LINE__);
+ }
+
+ $queryComponents['GROUPBY'] = $this->SQLparser->parseFieldList($groupBy);
+ $queryComponents['ORDERBY'] = $this->SQLparser->parseFieldList($orderBy);
+
+ // Return the query components
+ return $queryComponents;
+ }
+
+ /**
+ * Precompiles a SELECT prepared SQL statement.
+ *
+ * @param array $components
+ * @return array Precompiled SQL statement
+ */
+ protected function precompileSELECTquery(array $components) {
+ $parameterWrap = '__' . dechex(time()) . '__';
+ foreach ($components['parameters'] as $key => $params) {
+ if ($key === '?') {
+ foreach ($params as $index => $param) {
+ $components['parameters'][$key][$index][0] = $parameterWrap . $param[0] . $parameterWrap;
+ }
+ } else {
+ $components['parameters'][$key][0] = $parameterWrap . $params[0] . $parameterWrap;
+ }
+ }
+
+ $select_fields = $this->SQLparser->compileFieldList($components['SELECT']);
+ $from_table = $this->SQLparser->compileFromTables($components['FROM']);
+ $where_clause = $this->SQLparser->compileWhereClause($components['WHERE']);
+ $groupBy = $this->SQLparser->compileFieldList($components['GROUPBY']);
+ $orderBy = $this->SQLparser->compileFieldList($components['ORDERBY']);
+ $limit = $components['LIMIT'];
+ $precompiledParts = array();
+
+ $this->lastHandlerKey = $this->handler_getFromTableList($components['ORIG_tableName']);
+ $hType = (string)$this->handlerCfg[$this->lastHandlerKey]['type'];
+ $precompiledParts['handler'] = $hType;
+ $precompiledParts['ORIG_tableName'] = $components['ORIG_tableName'];
+
+ switch ($hType) {
+ case 'native':
+ $query = parent::SELECTquery($select_fields, $from_table, $where_clause, $groupBy, $orderBy, $limit);
+ $precompiledParts['queryParts'] = explode($parameterWrap, $query);
+ break;
+ case 'adodb':
+ $query = parent::SELECTquery($select_fields, $from_table, $where_clause, $groupBy, $orderBy);
+ $precompiledParts['queryParts'] = explode($parameterWrap, $query);
+ $precompiledParts['LIMIT'] = $limit;
+ break;
+ case 'userdefined':
+ $precompiledParts['queryParts'] = array(
+ 'SELECT' => $select_fields,
+ 'FROM' => $from_table,
+ 'WHERE' => $where_clause,
+ 'GROUPBY' => $groupBy,
+ 'ORDERBY' => $orderBy,
+ 'LIMIT' => $limit,
+ );
+ break;
+ }
+
+ return $precompiledParts;
+ }
+
+ /**
+ * Executes a prepared query.
+ *
+ * @param string $query The query to execute
+ * @param array $queryComponents The components of the query to execute
+ * @return pointer MySQL result pointer / DBAL object
+ * @access protected This method may only be called by t3lib_db_PreparedStatement
+ */
+ public function exec_PREPAREDquery($query, array $precompiledParts) {
+ if ($this->debug) {
+ $pt = t3lib_div::milliseconds();
+ }
+
+ // Get handler key and select API:
+ switch ($precompiledParts['handler']) {
+ case 'native':
+ $this->lastQuery = $query;
+ $sqlResult = mysql_query($this->lastQuery, $this->handlerInstance[$this->lastHandlerKey]['link']);
+ $this->resourceIdToTableNameMap[(string)$sqlResult] = $precompiledParts['ORIG_tableName'];
+ break;
+ case 'adodb':
+ $limit = $precompiledParts['LIMIT'];
+ if ($this->runningADOdbDriver('postgres')) {
+ // Possibly rewrite the LIMIT to be PostgreSQL-compatible
+ $splitLimit = t3lib_div::intExplode(',', $limit); // Splitting the limit values:
+ if ($splitLimit[1]) { // If there are two parameters, do mapping differently than otherwise:
+ $numrows = $splitLimit[1];
+ $offset = $splitLimit[0];
+ $limit = $numrows . ' OFFSET ' . $offset;
+ }
+ }
+ if ($limit != '') {
+ $splitLimit = t3lib_div::intExplode(',', $limit); // Splitting the limit values:
+ if ($splitLimit[1]) { // If there are two parameters, do mapping differently than otherwise:
+ $numrows = $splitLimit[1];
+ $offset = $splitLimit[0];
+ } else {
+ $numrows = $splitLimit[0];
+ $offset = 0;
+ }
+
+ $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->SelectLimit($query, $numrows, $offset);
+ $this->lastQuery = $sqlResult->sql;
+ } else {
+ $this->lastQuery = $query;
+ $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->_Execute($this->lastQuery);
+ }
+
+ $sqlResult->TYPO3_DBAL_handlerType = 'adodb'; // Setting handler type in result object (for later recognition!)
+ $sqlResult->TYPO3_DBAL_tableList = $precompiledParts['ORIG_tableName'];
+ break;
+ case 'userdefined':
+ $queryParts = $precompiledParts['queryParts'];
+ $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->exec_SELECTquery(
+ $queryParts['SELECT'],
+ $queryParts['FROM'],
+ $queryParts['WHERE'],
+ $queryParts['GROUPBY'],
+ $queryParts['ORDERBY'],
+ $queryParts['LIMIT']
+ );
+ if (is_object($sqlResult)) {
+ $sqlResult->TYPO3_DBAL_handlerType = 'userdefined'; // Setting handler type in result object (for later recognition!)
+ $sqlResult->TYPO3_DBAL_tableList = $precompiledParts['ORIG_tableName'];
+ }
+ break;
+ }
+
+ if ($this->printErrors && $this->sql_error()) {
+ debug(array($this->lastQuery, $this->sql_error()));
+ }
+
+ if ($this->debug) {
+ $data = array(
+ 'handlerType' => $precompiledParts['handler'],
+ 'args' => $precompiledParts,
+ 'ORIG_from_table' => $precompiledParts['ORIG_tableName'],
+ );
+ if ($this->conf['debugOptions']['numberRows']) {
+ $data['numberRows'] = $this->sql_num_rows($sqlResult);
+ }
+ $this->debugHandler(
+ 'exec_PREPAREDquery',
+ t3lib_div::milliseconds() - $pt,
+ $data
+ );
+ }
+
+ // Return result handler.
+ return $sqlResult;
+ }
/**************************************
*
/**
* Quotes the field (and table) names within a where clause with the quote character suitable for the DB being used
*
- * @param string A where clause that can e parsed by parseWhereClause
+ * @param string A where clause that can be parsed by parseWhereClause
* @return string Usable where clause with quoted field/table names
*/
public function quoteWhereClause($where_clause) {
case 'EXISTS':
$where_clause[$k]['func']['subquery'] = $this->quoteSELECTsubquery($v['func']['subquery']);
break;
+ case 'FIND_IN_SET':
+ // quoteStr that will be used for Oracle
+ $pattern = str_replace($where_clause[$k]['func']['str'][1], '\\' . $where_clause[$k]['func']['str'][1], $where_clause[$k]['func']['str'][0]);
+ // table is not really needed and may in fact be empty in real statements
+ // but it's not overriden from t3lib_db at the moment...
+ $patternForLike = $this->escapeStrForLike($pattern, $where_clause[$k]['func']['table']);
+ $where_clause[$k]['func']['str_like'] = $patternForLike;
+
+ // BEWARE: no break here to have next statements too
case 'IFNULL':
case 'LOCATE':
if ($where_clause[$k]['func']['table'] != '') {
if ($where_clause[$k]['func']['field'] != '') {
$where_clause[$k]['func']['field'] = $this->quoteName($v['func']['field']);
}
- break;
+ break;
}
} else {
if ($where_clause[$k]['table'] != '') {
}
/**
- * [Describe function...]
+ * Quotes the field (and table) names within a group by clause with the quote
+ * character suitable for the DB being used
*
- * @param [type] $$groupBy: ...
- * @return [type] ...
+ * @param string A group by clause that can by parsed by parseFieldList
+ * @return string Usable group by clause with quoted field/table names
*/
protected function quoteGroupBy($groupBy) {
if ($groupBy === '') return '';
if ($this->runningNative()) return $groupBy;
$groupBy = $this->SQLparser->parseFieldList($groupBy);
+ $groupBy = $this->_quoteGroupBy($groupBy);
+
+ return $this->SQLparser->compileFieldList($groupBy);
+ }
+
+ /**
+ * Quotes field names in a SQL GROUP BY clause acccording to DB rules
+ *
+ * @param array $groupBy The parsed GROUP BY clause to quote
+ * @return array
+ * @see quoteGroupBy()
+ */
+ protected function _quoteGroupBy(array $groupBy) {
foreach ($groupBy as $k => $v) {
$groupBy[$k]['field'] = $this->quoteName($groupBy[$k]['field']);
if ($groupBy[$k]['table'] != '') {
$groupBy[$k]['table'] = $this->quoteName($groupBy[$k]['table']);
}
}
- return $this->SQLparser->compileFieldList($groupBy);
+ return $groupBy;
}
/**
- * [Describe function...]
+ * Quotes the field (and table) names within an order by clause with the quote
+ * character suitable for the DB being used
*
- * @param [type] $$orderBy: ...
- * @return [type] ...
+ * @param string An order by clause that can by parsed by parseFieldList
+ * @return string Usable order by clause with quoted field/table names
*/
protected function quoteOrderBy($orderBy) {
if ($orderBy === '') return '';
if ($this->runningNative()) return $orderBy;
$orderBy = $this->SQLparser->parseFieldList($orderBy);
+ $orderBy = $this->_quoteOrderBy($orderBy);
+
+ return $this->SQLparser->compileFieldList($orderBy);
+ }
+
+ /**
+ * Quotes field names in a SQL ORDER BY clause acccording to DB rules
+ *
+ * @param array $orderBy The parsed ORDER BY clause to quote
+ * @return array
+ * @see quoteOrderBy()
+ */
+ protected function _quoteOrderBy(array $orderBy) {
foreach ($orderBy as $k => $v) {
$orderBy[$k]['field'] = $this->quoteName($orderBy[$k]['field']);
if ($orderBy[$k]['table'] != '') {
$orderBy[$k]['table'] = $this->quoteName($orderBy[$k]['table']);
}
}
- return $this->SQLparser->compileFieldList($orderBy);
+ return $orderBy;
}
-
/**************************************
*
* Various helper functions
* @param string Username to connect with.
* @param string Password to connect with.
* @return mixed Returns handler connection value
- * @deprecated since TYPO3 4.1
* @see handler_init()
*/
public function sql_pconnect($TYPO3_db_host, $TYPO3_db_username, $TYPO3_db_password) {
*
* @param string Database to connect to.
* @return boolean Always returns TRUE; function is obsolete, database selection is made in handler_init() function!
- * @deprecated since TYPO3 4.1
*/
public function sql_select_db($TYPO3_db) {
return TRUE;
*
* @param string List of tables in query
* @param boolean If TRUE, it will check only if FIELDs are configured and ignore the mapped table name if any.
+ * @param array Parsed list of tables, should be passed as reference to be reused and prevent double parsing
* @return mixed Returns an array of table names (parsed version of input table) if mapping is needed, otherwise just FALSE.
*/
- protected function map_needMapping($tableList, $fieldMappingOnly = FALSE) {
+ protected function map_needMapping($tableList, $fieldMappingOnly = FALSE, array &$parsedTableList = array()) {
$key = $tableList.'|'.$fieldMappingOnly;
if (!isset($this->cache_mappingFromTableList[$key])) {
$this->cache_mappingFromTableList[$key] = FALSE; // Default:
$tables = $this->SQLparser->parseFromTables($tableList);
if (is_array($tables)) {
+ $parsedTableList = $tables;
foreach ($tables as $tableCfg) {
if ($fieldMappingOnly) {
if (is_array($this->mapping[$tableCfg['table']]['mapFieldNames'])) {
/**
* Remaps table/field names in a SELECT query's parts
- * Notice: All arguments are passed by reference!
*
- * @param string List of fields to select from the table. This is what comes right after "SELECT ...". Required value.
+ * @param mixed Either parsed list of tables (SQLparser->parseFromTables()) or list of fields to select from the table. This is what comes right after "SELECT ...". Required value.
* @param string Table(s) from which to select. This is what comes right after "FROM ...". Require value.
* @param string Where clause. This is what comes right after "WHERE ...". Can be blank.
* @param string Group by field(s)
* @return void
* @see exec_SELECTquery()
*/
- protected function map_remapSELECTQueryParts(&$select_fields, &$from_table, &$where_clause, &$groupBy, &$orderBy) {
+ protected function map_remapSELECTQueryParts($select_fields, $from_table, $where_clause, $groupBy, $orderBy) {
// Backup current mapping as it may be altered if aliases on mapped tables are found
$backupMapping = $this->mapping;
// Tables:
- $tables = $this->SQLparser->parseFromTables($from_table);
+ $tables = is_array($from_table) ? $from_table : $this->SQLparser->parseFromTables($from_table);
$defaultTable = $tables[0]['table'];
// Prepare mapping for aliased tables. This will copy the definition of the original table name.
// The alias is prefixed with a database-incompatible character to prevent naming clash with real table name
}
}
}
- $from_table = $this->SQLparser->compileFromTables($tables);
+ $fromParts = $tables;
// Where clause:
- $whereParts = $this->SQLparser->parseWhereClause($where_clause);
- $this->map_sqlParts($whereParts,$defaultTable);
- $where_clause = $this->SQLparser->compileWhereClause($whereParts, FALSE);
+ $parameterReferences = array();
+ $whereParts = $this->SQLparser->parseWhereClause($where_clause, '', $parameterReferences);
+ $this->map_sqlParts($whereParts, $defaultTable);
// Select fields:
- $expFields = $this->SQLparser->parseFieldList($select_fields);
- $this->map_sqlParts($expFields,$defaultTable);
- $select_fields = $this->SQLparser->compileFieldList($expFields, FALSE, FALSE);
+ $selectParts = $this->SQLparser->parseFieldList($select_fields);
+ $this->map_sqlParts($selectParts, $defaultTable);
// Group By fields
- $expFields = $this->SQLparser->parseFieldList($groupBy);
- $this->map_sqlParts($expFields,$defaultTable);
- $groupBy = $this->SQLparser->compileFieldList($expFields);
+ $groupByParts = $this->SQLparser->parseFieldList($groupBy);
+ $this->map_sqlParts($groupByParts, $defaultTable);
// Order By fields
- $expFields = $this->SQLparser->parseFieldList($orderBy);
- $this->map_sqlParts($expFields,$defaultTable);
- $orderBy = $this->SQLparser->compileFieldList($expFields);
+ $orderByParts = $this->SQLparser->parseFieldList($orderBy);
+ $this->map_sqlParts($orderByParts, $defaultTable);
// Restore the original mapping
$this->mapping = $backupMapping;
+
+ return array($selectParts, $fromParts, $whereParts, $groupByParts, $orderByParts, $parameterReferences);
}
/**
case 'EXISTS':
$this->map_subquery($sqlPartArray[$k]['func']['subquery']);
break;
+ case 'FIND_IN_SET':
case 'IFNULL':
case 'LOCATE':
// For the field, look for table mapping (generic):
}
// if lastQuery is empty (for whatever reason) at least log inData.args
- if (empty($this->lastQuery))
- $query = implode(' ',$inData['args']);
- else
+ if (empty($this->lastQuery)) {
+ $query = implode(' ', $inData['args']);
+ } else {
$query = $this->lastQuery;
+ }
+
+ if ($this->conf['debugOptions']['numberRows']) {
+ switch ($function) {
+ case 'exec_INSERTquery':
+ case 'exec_UPDATEquery':
+ case 'exec_DELETEquery':
+ $data['numberRows'] = $this->sql_affected_rows();
+ break;
+ case 'exec_SELECTquery':
+ $data['numberRows'] = $inData['numberRows'];
+ break;
+ }
+ }
if ($this->conf['debugOptions']['backtrace']) {
$backtrace = debug_backtrace();
/***************************************************************
* Copyright notice
*
-* (c) 2004-2010 Kasper Skaarhoj (kasperYYYY@typo3.com)
-* (c) 2004-2010 Karsten Dambekalns <karsten@typo3.org>
+* (c) 2004-2009 Kasper Skaarhoj (kasperYYYY@typo3.com)
+* (c) 2004-2009 Karsten Dambekalns <karsten@typo3.org>
* (c) 2009-2010 Xavier Perseguers <typo3@perseguers.ch>
* All rights reserved
*
/**
* PHP SQL engine
*
- * $Id: class.ux_t3lib_sqlparser.php 29977 2010-02-13 13:18:32Z xperseguers $
+ * $Id: class.ux_t3lib_sqlparser.php 36759 2010-08-14 15:55:24Z xperseguers $
*
* @author Kasper Skaarhoj <kasperYYYY@typo3.com>
* @author Karsten Dambekalns <k.dambekalns@fishfarm.de>
$output .= ($v['func']['table'] ? $v['func']['table'] . '.' : '') . $v['func']['field'];
$output .= ', ' . $v['func']['default'][1] . $this->compileAddslashes($v['func']['default'][0]) . $v['func']['default'][1];
$output .= ')';
+ } elseif (isset($v['func']) && $v['func']['type'] === 'FIND_IN_SET') {
+ $output = ' ' . trim($v['modifier']) . ' ';
+ if ($functionMapping) {
+ switch (TRUE) {
+ case ($GLOBALS['TYPO3_DB']->runningADOdbDriver('mssql')):
+ $field = ($v['func']['table'] ? $v['func']['table'] . '.' : '') . $v['func']['field'];
+ if (!isset($v['func']['str_like'])) {
+ $v['func']['str_like'] = $v['func']['str'][0];
+ }
+ $output .= '\',\'+' . $field . '+\',\' LIKE \'%,' . $v['func']['str_like'] . ',%\'';
+ break;
+ case ($GLOBALS['TYPO3_DB']->runningADOdbDriver('oci8')):
+ $field = ($v['func']['table'] ? $v['func']['table'] . '.' : '') . $v['func']['field'];
+ if (!isset($v['func']['str_like'])) {
+ $v['func']['str_like'] = $v['func']['str'][0];
+ }
+ $output .= '\',\'||' . $field . '||\',\' LIKE \'%,' . $v['func']['str_like'] . ',%\'';
+ break;
+ case ($GLOBALS['TYPO3_DB']->runningADOdbDriver('postgres')):
+ $output .= ' FIND_IN_SET(';
+ $output .= $v['func']['str'][1] . $v['func']['str'][0] . $v['func']['str'][1];
+ $output .= ', ' . ($v['func']['table'] ? $v['func']['table'] . '.' : '') . $v['func']['field'];
+ $output .= ') != 0';
+ break;
+ default:
+ $field = ($v['func']['table'] ? $v['func']['table'] . '.' : '') . $v['func']['field'];
+ if (!isset($v['func']['str_like'])) {
+ $v['func']['str_like'] = $v['func']['str'][0];
+ }
+ $output .= '('
+ . $field . ' LIKE \'%,' . $v['func']['str_like'] . ',%\''
+ . ' OR ' . $field . ' LIKE \'' . $v['func']['str_like'] . ',%\''
+ . ' OR ' . $field . ' LIKE \'%,' . $v['func']['str_like'] . '\''
+ . ' OR ' . $field . '= ' . $v['func']['str'][1] . $v['func']['str'][0] . $v['func']['str'][1]
+ . ')';
+ break;
+ }
+ } else /* !$functionMapping */ {
+ switch (TRUE) {
+ case ($GLOBALS['TYPO3_DB']->runningADOdbDriver('mssql')):
+ case ($GLOBALS['TYPO3_DB']->runningADOdbDriver('oci8')):
+ case ($GLOBALS['TYPO3_DB']->runningADOdbDriver('postgres')):
+ $output .= ' FIND_IN_SET(';
+ $output .= $v['func']['str'][1] . $v['func']['str'][0] . $v['func']['str'][1];
+ $output .= ', ' . ($v['func']['table'] ? $v['func']['table'] . '.' : '') . $v['func']['field'];
+ $output .= ')';
+ break;
+ default:
+ $field = ($v['func']['table'] ? $v['func']['table'] . '.' : '') . $v['func']['field'];
+ if (!isset($v['func']['str_like'])) {
+ $v['func']['str_like'] = $v['func']['str'][0];
+ }
+ $output .= '('
+ . $field . ' LIKE \'%,' . $v['func']['str_like'] . ',%\''
+ . ' OR ' . $field . ' LIKE \'' . $v['func']['str_like'] . ',%\''
+ . ' OR ' . $field . ' LIKE \'%,' . $v['func']['str_like'] . '\''
+ . ' OR ' . $field . '= ' . $v['func']['str'][1] . $v['func']['str'][0] . $v['func']['str'][1]
+ . ')';
+ break;
+ }
+ }
} else {
// Set field/table with modifying prefix if any:
} else {
$output .= $v['calc_value'][1] . $this->compileAddslashes($v['calc_value'][0]) . $v['calc_value'][1];
}
- } elseif (!($GLOBALS['TYPO3_DB']->runningADOdbDriver('oci8') && $v['comparator'] === 'LIKE' && $functionMapping)) {
+ } elseif (!($GLOBALS['TYPO3_DB']->runningADOdbDriver('oci8') && preg_match('/(NOT )?LIKE( BINARY)?/', $v['comparator']) && $functionMapping)) {
$output .= trim(($v['table'] ? $v['table'] . '.' : '') . $v['field']);
}
}
// Set comparator:
if ($v['comparator']) {
+ $isLikeOperator = preg_match('/(NOT )?LIKE( BINARY)?/', $v['comparator']);
switch (TRUE) {
- case ($GLOBALS['TYPO3_DB']->runningADOdbDriver('oci8') && $v['comparator'] === 'LIKE' && $functionMapping):
+ case ($GLOBALS['TYPO3_DB']->runningADOdbDriver('oci8') && $isLikeOperator && $functionMapping):
// Oracle cannot handle LIKE on CLOB fields - sigh
if (isset($v['value']['operator'])) {
$values = array();
$compareValue = ' ' . $v['value']['operator'] . '(' . implode(',', $values) . ')';
} else {
$compareValue = $v['value'][1] . $this->compileAddslashes(trim($v['value'][0], '%')) . $v['value'][1];
+ }
+ if (t3lib_div::isFirstPartOfStr($v['comparator'], 'NOT')) {
+ $output .= 'NOT ';
}
// To be on the safe side
$isLob = TRUE;
}
break;
default:
+ if ($isLikeOperator && $functionMapping) {
+ if ($GLOBALS['TYPO3_DB']->runningADOdbDriver('postgres') ||
+ $GLOBALS['TYPO3_DB']->runningADOdbDriver('postgres64') ||
+ $GLOBALS['TYPO3_DB']->runningADOdbDriver('postgres7') ||
+ $GLOBALS['TYPO3_DB']->runningADOdbDriver('postgres8')) {
+
+ // Remap (NOT)? LIKE to (NOT)? ILIKE
+ // and (NOT)? LIKE BINARY to (NOT)? LIKE
+ switch ($v['comparator']) {
+ // Remap (NOT)? LIKE to (NOT)? ILIKE
+ case 'LIKE':
+ $v['comparator'] = 'ILIKE';
+ break;
+ case 'NOT LIKE':
+ $v['comparator'] = 'NOT ILIKE';
+ break;
+ default:
+ $v['comparator'] = str_replace(' BINARY', '', $v['comparator']);
+ break;
+ }
+ } else {
+ // No more BINARY operator
+ $v['comparator'] = str_replace(' BINARY', '', $v['comparator']);
+ }
+ }
+
$output .= ' ' . $v['comparator'];
// Detecting value type; list or plain:
########################################################################
# Extension Manager/Repository config file for ext "dbal".
#
-# Auto generated 22-06-2010 17:18
+# Auto generated 23-08-2010 15:51
#
# Manual updates:
# Only the data in the array - everything else is removed by next
'author_company' => '',
'CGLcompliance' => '',
'CGLcompliance_note' => '',
- 'version' => '1.1.7',
- '_md5_values_when_last_written' => 'a:43:{s:9:"ChangeLog";s:4:"ba81";s:28:"class.tx_dbal_autoloader.php";s:4:"4781";s:29:"class.tx_dbal_installtool.php";s:4:"ffb8";s:26:"class.ux_db_list_extra.php";s:4:"7af1";s:21:"class.ux_t3lib_db.php";s:4:"5d57";s:28:"class.ux_t3lib_sqlparser.php";s:4:"4b4e";s:16:"ext_autoload.php";s:4:"821a";s:21:"ext_conf_template.txt";s:4:"f5cf";s:12:"ext_icon.gif";s:4:"c9ba";s:17:"ext_localconf.php";s:4:"afdd";s:14:"ext_tables.php";s:4:"8414";s:14:"ext_tables.sql";s:4:"1f95";s:19:"last_synched_target";s:4:"5d1b";s:27:"doc/class.tslib_fe.php.diff";s:4:"0083";s:14:"doc/manual.sxw";s:4:"b022";s:45:"handlers/class.tx_dbal_handler_openoffice.php";s:4:"8b11";s:43:"handlers/class.tx_dbal_handler_rawmysql.php";s:4:"c024";s:40:"handlers/class.tx_dbal_handler_xmldb.php";s:4:"a9bb";s:31:"lib/class.tx_dbal_sqlengine.php";s:4:"2ed1";s:33:"lib/class.tx_dbal_tsparserext.php";s:4:"862d";s:14:"mod1/clear.gif";s:4:"cc11";s:13:"mod1/conf.php";s:4:"6e63";s:14:"mod1/index.php";s:4:"0bd5";s:18:"mod1/locallang.xml";s:4:"0b57";s:22:"mod1/locallang_mod.xml";s:4:"86ef";s:19:"mod1/moduleicon.gif";s:4:"2b8f";s:10:"res/README";s:4:"be19";s:26:"res/Templates/install.html";s:4:"62c9";s:30:"res/oracle/indexed_search.diff";s:4:"ec81";s:23:"res/oracle/realurl.diff";s:4:"86da";s:25:"res/oracle/scheduler.diff";s:4:"7c06";s:27:"res/oracle/templavoila.diff";s:4:"1fd5";s:43:"res/postgresql/postgresql-compatibility.sql";s:4:"034c";s:22:"tests/BaseTestCase.php";s:4:"9e07";s:26:"tests/FakeDbConnection.php";s:4:"35f0";s:23:"tests/dbGeneralTest.php";s:4:"9bfc";s:21:"tests/dbMssqlTest.php";s:4:"4cbc";s:22:"tests/dbOracleTest.php";s:4:"16b6";s:26:"tests/dbPostgresqlTest.php";s:4:"27cd";s:30:"tests/sqlParserGeneralTest.php";s:4:"5953";s:31:"tests/fixtures/mssql.config.php";s:4:"0ec8";s:30:"tests/fixtures/oci8.config.php";s:4:"4a1a";s:36:"tests/fixtures/postgresql.config.php";s:4:"2296";}',
+ 'version' => '1.2.0alpha1',
+ '_md5_values_when_last_written' => 'a:42:{s:9:"ChangeLog";s:4:"0ba7";s:28:"class.tx_dbal_autoloader.php";s:4:"8cd0";s:29:"class.tx_dbal_installtool.php";s:4:"29b5";s:26:"class.ux_db_list_extra.php";s:4:"60d9";s:21:"class.ux_t3lib_db.php";s:4:"6801";s:28:"class.ux_t3lib_sqlparser.php";s:4:"586b";s:16:"ext_autoload.php";s:4:"bd13";s:21:"ext_conf_template.txt";s:4:"f5cf";s:12:"ext_icon.gif";s:4:"c9ba";s:17:"ext_localconf.php";s:4:"5ece";s:14:"ext_tables.php";s:4:"b187";s:14:"ext_tables.sql";s:4:"1f95";s:27:"doc/class.tslib_fe.php.diff";s:4:"0083";s:14:"doc/manual.sxw";s:4:"57b6";s:45:"handlers/class.tx_dbal_handler_openoffice.php";s:4:"8556";s:43:"handlers/class.tx_dbal_handler_rawmysql.php";s:4:"ef52";s:40:"handlers/class.tx_dbal_handler_xmldb.php";s:4:"3ec1";s:31:"lib/class.tx_dbal_sqlengine.php";s:4:"75be";s:33:"lib/class.tx_dbal_tsparserext.php";s:4:"df12";s:14:"mod1/clear.gif";s:4:"cc11";s:13:"mod1/conf.php";s:4:"6e63";s:14:"mod1/index.php";s:4:"4a5e";s:18:"mod1/locallang.xml";s:4:"0b57";s:22:"mod1/locallang_mod.xml";s:4:"86ef";s:19:"mod1/moduleicon.gif";s:4:"2b8f";s:10:"res/README";s:4:"be19";s:26:"res/Templates/install.html";s:4:"62c9";s:30:"res/oracle/indexed_search.diff";s:4:"ec81";s:23:"res/oracle/realurl.diff";s:4:"86da";s:25:"res/oracle/scheduler.diff";s:4:"7c06";s:27:"res/oracle/templavoila.diff";s:4:"1fd5";s:43:"res/postgresql/postgresql-compatibility.sql";s:4:"bbff";s:22:"tests/BaseTestCase.php";s:4:"33db";s:26:"tests/FakeDbConnection.php";s:4:"cf49";s:23:"tests/dbGeneralTest.php";s:4:"dba5";s:21:"tests/dbMssqlTest.php";s:4:"a0f3";s:22:"tests/dbOracleTest.php";s:4:"2ff5";s:26:"tests/dbPostgresqlTest.php";s:4:"2f3f";s:30:"tests/sqlParserGeneralTest.php";s:4:"74b4";s:31:"tests/fixtures/mssql.config.php";s:4:"0e31";s:30:"tests/fixtures/oci8.config.php";s:4:"6c8a";s:36:"tests/fixtures/postgresql.config.php";s:4:"f13a";}',
'constraints' => array(
'depends' => array(
'adodb' => '5.10.0-',
'php' => '5.2.0-0.0.0',
- 'typo3' => '4.4.0-4.4.99',
+ 'typo3' => '4.4.0beta1-0.0.0',
),
'conflicts' => array(
),
/***************************************************************
* Copyright notice
*
-* (c) 2004-2010 Kasper Skaarhoj (kasper@typo3.com)
+* (c) 2004-2009 Kasper Skaarhoj (kasper@typo3.com)
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
/**
* Contains an example DBAL handler class
*
- * $Id: class.tx_dbal_handler_openoffice.php 28898 2010-01-16 14:32:35Z xperseguers $
+ * $Id: class.tx_dbal_handler_openoffice.php 35523 2010-07-11 14:04:44Z xperseguers $
*
* @author Kasper Skaarhoj <kasper@typo3.com>
*/
/***************************************************************
* Copyright notice
*
-* (c) 2004-2010 Kasper Skaarhoj (kasper@typo3.com)
+* (c) 2004-2009 Kasper Skaarhoj (kasper@typo3.com)
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
/**
* Contains an example DBAL handler class
*
- * $Id: class.tx_dbal_handler_rawmysql.php 25889 2009-10-27 10:09:11Z xperseguers $
+ * $Id: class.tx_dbal_handler_rawmysql.php 35523 2010-07-11 14:04:44Z xperseguers $
*
* @author Kasper Skaarhoj <kasper@typo3.com>
*/
/***************************************************************
* Copyright notice
*
-* (c) 2004-2010 Kasper Skaarhoj (kasper@typo3.com)
+* (c) 2004-2009 Kasper Skaarhoj (kasper@typo3.com)
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
/**
* Contains an example DBAL handler class
*
- * $Id: class.tx_dbal_handler_xmldb.php 25889 2009-10-27 10:09:11Z xperseguers $
+ * $Id: class.tx_dbal_handler_xmldb.php 35523 2010-07-11 14:04:44Z xperseguers $
*
* @author Kasper Skaarhoj <kasper@typo3.com>
*/
-https://svn.typo3.org/TYPO3v4/Extensions/dbal/tags/1.1.7/
+https://svn.typo3.org/TYPO3v4/Extensions/dbal/tags/1.2.0alpha1/
* Copyright notice
*
* (c) 2009-2010 Xavier Perseguers <typo3@perseguers.ch>
-* (c) 2004-2010 Kasper Skaarhoj <kasperYYYY@typo3.com>
+* (c) 2004-2009 Kasper Skaarhoj <kasperYYYY@typo3.com>
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
/**
* PHP SQL engine
*
- * $Id: class.tx_dbal_sqlengine.php 28572 2010-01-08 17:13:29Z xperseguers $
+ * $Id: class.tx_dbal_sqlengine.php 35523 2010-07-11 14:04:44Z xperseguers $
*
* @author Kasper Skaarhoj <kasperYYYY@typo3.com>
* @author Xavier Perseguers <typo3@perseguers.ch>
/**
* Class that renders fields for the Extension Manager configuration.
*
- * $Id: class.tx_dbal_tsparserext.php 28572 2010-01-08 17:13:29Z xperseguers $
+ * $Id: class.tx_dbal_tsparserext.php 36759 2010-08-14 15:55:24Z xperseguers $
* @author Xavier Perseguers <typo3@perseguers.ch>
*
* @package TYPO3
/***************************************************************
* Copyright notice
*
-* (c) 2004-2010 Kasper Skaarhoj (kasperYYYY@typo3.com)
-* (c) 2004-2010 Karsten Dambekalns (karsten@typo3.org)
+* (c) 2004-2009 Kasper Skaarhoj (kasperYYYY@typo3.com)
+* (c) 2004-2009 Karsten Dambekalns (karsten@typo3.org)
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
-- Note: You may consider having a look at project mysqlcompat on http://pgfoundry.org/projects/mysqlcompat
-- and report in DBAL bugtracker if you need another compatibility operator added.
--
--- $Id: postgresql-compatibility.sql 29977 2010-02-13 13:18:32Z xperseguers $
+-- $Id: postgresql-compatibility.sql 35742 2010-07-16 13:22:56Z xperseguers $
-- R. van Twisk <typo3@rvt.dds.nl>
SELECT COALESCE($1, $2)
$$ IMMUTABLE STRICT LANGUAGE SQL;
+-- FIND_IN_SET
+-- FIND_IN_SET()
+CREATE OR REPLACE FUNCTION find_in_set(text, text)
+RETURNS integer AS $$
+DECLARE
+ list text[];
+ len integer;
+BEGIN
+ IF $2 = '' THEN
+ RETURN 0;
+ END IF;
+ list := pg_catalog.string_to_array($2, ',');
+ len := pg_catalog.array_upper(list, 1);
+ FOR i IN 1..len LOOP
+ IF list[i] = $1 THEN
+ RETURN i;
+ END IF;
+ END LOOP;
+ RETURN 0;
+END;
+$$ STRICT IMMUTABLE LANGUAGE PLPGSQL;
+
-- Remove Compatibility operators
--
--DROP OPERATOR ~~ (integer,text);
/***************************************************************
* Copyright notice
*
-* (c) 2009-2010 Robert Lemke <robert@typo3.org>
+* (c) 2009 Robert Lemke <robert@typo3.org>
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* Subclass this base class if you want to take advantage of the framework
* capabilities.
*
- * $Id: BaseTestCase.php 27006 2009-11-25 22:08:07Z xperseguers $
+ * $Id: BaseTestCase.php 36760 2010-08-14 15:58:41Z xperseguers $
*
* @author Robert Lemke <robert@typo3.org>
*
/***************************************************************
* Copyright notice
*
-* (c) 2009-2010 Xavier Perseguers <typo3@perseguers.ch>
+* (c) 2009 Xavier Perseguers <typo3@perseguers.ch>
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
/**
* Fake ADOdb connection factory.
*
- * $Id: FakeDbConnection.php 27006 2009-11-25 22:08:07Z xperseguers $
+ * $Id: FakeDbConnection.php 36760 2010-08-14 15:58:41Z xperseguers $
*
* @author Xavier Perseguers <typo3@perseguers.ch>
*
$this->db = $GLOBALS['TYPO3_DB'];
$this->temporaryFiles = array();
- $className = self::buildAccessibleProxy('ux_t3lib_db');
+ $className = self::buildAccessibleProxy('ux_t3lib_db');
$GLOBALS['TYPO3_DB'] = new $className;
$GLOBALS['TYPO3_DB']->lastHandlerKey = '_DEFAULT';
}
$expected = 'SELECT * FROM pages WHERE MAX(uid) IN (1,2,3,4)';
$this->assertEquals($expected, $query);
}
+
+ /**
+ * @test
+ * @see http://bugs.typo3.org/view.php?id=12535
+ */
+ public function likeBinaryOperatorIsKept() {
+ $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery(
+ '*',
+ 'tt_content',
+ 'bodytext LIKE BINARY \'test\''
+ ));
+ $expected = 'SELECT * FROM tt_content WHERE bodytext LIKE BINARY \'test\'';
+ $this->assertEquals($expected, $query);
+ }
+
+ /**
+ * @test
+ * @see http://bugs.typo3.org/view.php?id=12535
+ */
+ public function notLikeBinaryOperatorIsKept() {
+ $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery(
+ '*',
+ 'tt_content',
+ 'bodytext NOT LIKE BINARY \'test\''
+ ));
+ $expected = 'SELECT * FROM tt_content WHERE bodytext NOT LIKE BINARY \'test\'';
+ $this->assertEquals($expected, $query);
+ }
+
+ ///////////////////////////////////////
+ // Tests concerning prepared queries
+ ///////////////////////////////////////
+
+ /**
+ * @test
+ * @see http://bugs.typo3.org/view.php?id=15457
+ */
+ public function similarNamedParametersAreProperlyReplaced() {
+ $sql = 'SELECT * FROM cache WHERE tag = :tag1 OR tag = :tag10 OR tag = :tag100';
+ $parameterValues = array(
+ ':tag1' => 'tag-one',
+ ':tag10' => 'tag-two',
+ ':tag100' => 'tag-three',
+ );
+
+ $className = self::buildAccessibleProxy('t3lib_db_PreparedStatement');
+ $query = $sql;
+ $precompiledQueryParts = array();
+ $statement = new $className($sql, 'cache');
+ $statement->bindValues($parameterValues);
+ $parameters = $statement->_get('parameters');
+
+ $statement->_callRef('replaceValuesInQuery', $query, $precompiledQueryParts, $parameters);
+ $expected = 'SELECT * FROM cache WHERE tag = \'tag-one\' OR tag = \'tag-two\' OR tag = \'tag-three\'';
+ $this->assertEquals($expected, $query);
+ }
}
?>
\ No newline at end of file
}
}
+ /**
+ * @test
+ * @see http://bugs.typo3.org/view.php?id=14985
+ */
+ public function findInSetIsProperlyRemapped() {
+ $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery(
+ '*',
+ 'fe_users',
+ 'FIND_IN_SET(10, usergroup)'
+ ));
+ $expected = 'SELECT * FROM "fe_users" WHERE \',\'+"usergroup"+\',\' LIKE \'%,10,%\'';
+ $this->assertEquals($expected, $query);
+ }
+
///////////////////////////////////////
// Tests concerning remapping with
// external (non-TYPO3) databases
$groupBy = '';
$orderBy = '';
- $GLOBALS['TYPO3_DB']->_callRef('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
- $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery($selectFields, $fromTables, $whereClause, $groupBy, $orderBy));
+ $remappedParameters = $GLOBALS['TYPO3_DB']->_call('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
+ $query = $this->cleanSql($GLOBALS['TYPO3_DB']->_call('SELECTqueryFromArray', $remappedParameters));
$expected = 'SELECT "MemberID", "FirstName", "LastName" FROM "Members" WHERE 0 = 0 AND 1 = 1';
$this->assertEquals($expected, $query);
$groupBy = '';
$orderBy = '';
- $GLOBALS['TYPO3_DB']->_callRef('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
- $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery($selectFields, $fromTables, $whereClause, $groupBy, $orderBy));
+ $remappedParameters = $GLOBALS['TYPO3_DB']->_call('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
+ $query = $this->cleanSql($GLOBALS['TYPO3_DB']->_call('SELECTqueryFromArray', $remappedParameters));
$expected = 'SELECT *, CASE WHEN CHARINDEX(\'(fce)\', "ds", 4) > 0 THEN 2 ELSE 1 END AS "scope" FROM "tx_templavoila_tmplobj" WHERE 1 = 1';
$this->assertEquals($expected, $query);
$groupBy = '';
$orderBy = '';
- $GLOBALS['TYPO3_DB']->_callRef('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
- $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery($selectFields, $fromTables, $whereClause, $groupBy, $orderBy));
+ $remappedParameters = $GLOBALS['TYPO3_DB']->_call('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
+ $query = $this->cleanSql($GLOBALS['TYPO3_DB']->_call('SELECTqueryFromArray', $remappedParameters));
$expected = 'SELECT *, CASE WHEN CHARINDEX(\'(fce)\', "tx_templavoila_tmplobj"."ds", 4) > 0 THEN 2 ELSE 1 END AS "scope" FROM "tx_templavoila_tmplobj" WHERE 1 = 1';
$this->assertEquals($expected, $query);
$groupBy = '';
$orderBy = '';
- $GLOBALS['TYPO3_DB']->_callRef('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
- $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery($selectFields, $fromTables, $whereClause, $groupBy, $orderBy));
+ $remappedParameters = $GLOBALS['TYPO3_DB']->_call('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
+ $query = $this->cleanSql($GLOBALS['TYPO3_DB']->_call('SELECTqueryFromArray', $remappedParameters));
$expected = 'SELECT * FROM "ext_tt_news_cat"';
$expected .= ' INNER JOIN "ext_tt_news_cat_mm" ON "ext_tt_news_cat"."cat_uid"="ext_tt_news_cat_mm"."uid_foreign"';
$groupBy = '';
$orderBy = '';
- $GLOBALS['TYPO3_DB']->_callRef('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
- $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery($selectFields, $fromTables, $whereClause, $groupBy, $orderBy));
+ $remappedParameters = $GLOBALS['TYPO3_DB']->_call('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
+ $query = $this->cleanSql($GLOBALS['TYPO3_DB']->_call('SELECTqueryFromArray', $remappedParameters));
$expected = 'SELECT "tstamp", "script", SUM("exec_time") AS "calc_sum", COUNT(*) AS "qrycount", MAX("errorflag") AS "error" FROM "tx_dbal_debuglog" WHERE 1 = 1';
$this->assertEquals($expected, $query);
$groupBy = '';
$orderBy = '';
- $GLOBALS['TYPO3_DB']->_callRef('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
- $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery($selectFields, $fromTables, $whereClause, $groupBy, $orderBy));
+ $remappedParameters = $GLOBALS['TYPO3_DB']->_call('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
+ $query = $this->cleanSql($GLOBALS['TYPO3_DB']->_call('SELECTqueryFromArray', $remappedParameters));
$expected = 'SELECT MAX("ext_tt_news_cat"."cat_uid") AS "biggest_id" FROM "ext_tt_news_cat"';
$expected .= ' INNER JOIN "ext_tt_news_cat_mm" ON "ext_tt_news_cat"."cat_uid"="ext_tt_news_cat_mm"."uid_foreign"';
$groupBy = '';
$orderBy = '';
- $GLOBALS['TYPO3_DB']->_callRef('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
- $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery($selectFields, $fromTables, $whereClause, $groupBy, $orderBy));
+ $remappedParameters = $GLOBALS['TYPO3_DB']->_call('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
+ $query = $this->cleanSql($GLOBALS['TYPO3_DB']->_call('SELECTqueryFromArray', $remappedParameters));
$expected = 'SELECT * FROM "sys_refindex", "tx_dam_file_tracking" WHERE "sys_refindex"."tablename" = \'tx_dam_file_tracking\'';
$expected .= ' AND (instr("sys_refindex"."ref_string", CONCAT("tx_dam_file_tracking"."path","tx_dam_file_tracking"."filename"),1,1) > 0)';
$groupBy = '';
$orderBy = 'cpg_categories.pos';
- $GLOBALS['TYPO3_DB']->_callRef('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
- $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery($selectFields, $fromTables, $whereClause, $groupBy, $orderBy));
+ $remappedParameters = $GLOBALS['TYPO3_DB']->_call('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
+ $query = $this->cleanSql($GLOBALS['TYPO3_DB']->_call('SELECTqueryFromArray', $remappedParameters));
$expected = 'SELECT "cpg_categories"."uid", "cpg_categories"."name" FROM "cpg_categories", "my_pages" WHERE "my_pages"."page_uid" = "cpg_categories"."page_id"';
$expected .= ' AND "my_pages"."deleted" = 0 AND 1 = 1 ORDER BY "cpg_categories"."pos"';
$groupBy = '';
$orderBy = '';
- $GLOBALS['TYPO3_DB']->_callRef('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
- $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery($selectFields, $fromTables, $whereClause, $groupBy, $orderBy));
+ $remappedParameters = $GLOBALS['TYPO3_DB']->_call('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
+ $query = $this->cleanSql($GLOBALS['TYPO3_DB']->_call('SELECTqueryFromArray', $remappedParameters));
$expected = 'SELECT "news"."news_uid" FROM "ext_tt_news" AS "news" WHERE "news"."news_uid" = 1';
$this->assertEquals($expected, $query);
$groupBy = '';
$orderBy = '';
- $GLOBALS['TYPO3_DB']->_callRef('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
- $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery($selectFields, $fromTables, $whereClause, $groupBy, $orderBy));
+ $remappedParameters = $GLOBALS['TYPO3_DB']->_call('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
+ $query = $this->cleanSql($GLOBALS['TYPO3_DB']->_call('SELECTqueryFromArray', $remappedParameters));
$expected = 'SELECT "tt_news_cat"."news_uid" FROM "ext_tt_news" AS "tt_news_cat" WHERE "tt_news_cat"."news_uid" = 1';
$this->assertEquals($expected, $query);
$orderBy = '';
// First call to possibly alter (in memory) the mapping from localconf.php
- $GLOBALS['TYPO3_DB']->_callRef('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
+ $remappedParameters = $GLOBALS['TYPO3_DB']->_call('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
$selectFields = 'uid';
$fromTables = 'foo';
$groupBy = '';
$orderBy = '';
- $GLOBALS['TYPO3_DB']->_callRef('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
- $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery($selectFields, $fromTables, $whereClause, $groupBy, $orderBy));
+ $remappedParameters = $GLOBALS['TYPO3_DB']->_call('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
+ $query = $this->cleanSql($GLOBALS['TYPO3_DB']->_call('SELECTqueryFromArray', $remappedParameters));
$expected = 'SELECT "uid" FROM "foo" WHERE "uid" = 1';
$this->assertEquals($expected, $query);
$groupBy = '';
$orderBy = '';
- $GLOBALS['TYPO3_DB']->_callRef('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
- $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery($selectFields, $fromTables, $whereClause, $groupBy, $orderBy));
+ $remappedParameters = $GLOBALS['TYPO3_DB']->_call('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
+ $query = $this->cleanSql($GLOBALS['TYPO3_DB']->_call('SELECTqueryFromArray', $remappedParameters));
$expected = 'SELECT "cat"."cat_uid", "cat_mm"."local_uid", "news"."news_uid"';
$expected .= ' FROM "ext_tt_news_cat" AS "cat"';
$groupBy = '';
$orderBy = 'foo.uid';
- $GLOBALS['TYPO3_DB']->_callRef('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
- $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery($selectFields, $fromTables, $whereClause, $groupBy, $orderBy));
+ $remappedParameters = $GLOBALS['TYPO3_DB']->_call('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
+ $query = $this->cleanSql($GLOBALS['TYPO3_DB']->_call('SELECTqueryFromArray', $remappedParameters));
$expected = 'SELECT "foo"."news_uid" FROM "ext_tt_news" AS "foo"';
$expected .= ' INNER JOIN "ext_tt_news_cat_mm" ON "ext_tt_news_cat_mm"."local_uid"="foo"."news_uid"';
$groupBy = '';
$orderBy = 'foo.uid';
- $GLOBALS['TYPO3_DB']->_callRef('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
- $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery($selectFields, $fromTables, $whereClause, $groupBy, $orderBy));
+ $remappedParameters = $GLOBALS['TYPO3_DB']->_call('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
+ $query = $this->cleanSql($GLOBALS['TYPO3_DB']->_call('SELECTqueryFromArray', $remappedParameters));
$expected = 'SELECT "foo"."news_uid" FROM "ext_tt_news" AS "foo"';
$expected .= ' INNER JOIN "ext_tt_news_cat_mm" ON "ext_tt_news_cat_mm"."local_uid"="foo"."news_uid"';
$groupBy = '';
$orderBy = '';
- $GLOBALS['TYPO3_DB']->_callRef('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
- $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery($selectFields, $fromTables, $whereClause, $groupBy, $orderBy));
+ $remappedParameters = $GLOBALS['TYPO3_DB']->_call('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
+ $query = $this->cleanSql($GLOBALS['TYPO3_DB']->_call('SELECTqueryFromArray', $remappedParameters));
$expected = 'SELECT "foo"."news_uid" FROM "ext_tt_news" AS "foo"';
$expected .= ' WHERE "news_uid" IN (';
$groupBy = '';
$orderBy = 'pages.uid';
- $GLOBALS['TYPO3_DB']->_callRef('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
- $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery($selectFields, $fromTables, $whereClause, $groupBy, $orderBy));
+ $remappedParameters = $GLOBALS['TYPO3_DB']->_call('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
+ $query = $this->cleanSql($GLOBALS['TYPO3_DB']->_call('SELECTqueryFromArray', $remappedParameters));
$expected = 'SELECT "pages"."news_uid" FROM "ext_tt_news" AS "pages"';
$expected .= ' INNER JOIN "ext_tt_news_cat_mm" AS "cat_mm" ON "cat_mm"."local_uid"="pages"."news_uid"';
$this->assertEquals($expected, $select);
}
+ /**
+ * @test
+ * @see http://bugs.typo3.org/view.php?id=15253
+ */
+ public function notLikeIsRemappedAccordingToFieldType() {
+ $select = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery(
+ '*',
+ 'tt_content',
+ 'tt_content.bodytext NOT LIKE \'foo%\''
+ ));
+ $expected = 'SELECT * FROM "tt_content" WHERE NOT (dbms_lob.instr("tt_content"."bodytext", \'foo\',1,1) > 0)';
+ $this->assertEquals($expected, $select);
+
+ $select = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery(
+ '*',
+ 'fe_users',
+ 'fe_users.usergroup NOT LIKE \'2\''
+ ));
+ $expected = 'SELECT * FROM "fe_users" WHERE NOT (instr("fe_users"."usergroup", \'2\',1,1) > 0)';
+ $this->assertEquals($expected, $select);
+ }
+
/**
* @test
* @see http://bugs.typo3.org/view.php?id=14479
$groupBy = '';
$orderBy = '';
- $GLOBALS['TYPO3_DB']->_callRef('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
- $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery($selectFields, $fromTables, $whereClause, $groupBy, $orderBy));
+ $remappedParameters = $GLOBALS['TYPO3_DB']->_call('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
+ $query = $this->cleanSql($GLOBALS['TYPO3_DB']->_call('SELECTqueryFromArray', $remappedParameters));
$expected = 'SELECT * FROM "tx_crawler_queue" WHERE "process_id" IN (SELECT "ps_id" FROM "tx_crawler_ps" WHERE "is_active" = 0 AND "deleted" = 0)';
$this->assertEquals($expected, $query);
$groupBy = '';
$orderBy = '';
- $GLOBALS['TYPO3_DB']->_callRef('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
- $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery($selectFields, $fromTables, $whereClause, $groupBy, $orderBy));
+ $remappedParameters = $GLOBALS['TYPO3_DB']->_call('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
+ $query = $this->cleanSql($GLOBALS['TYPO3_DB']->_call('SELECTqueryFromArray', $remappedParameters));
$expected = 'SELECT * FROM "tx_crawler_ps" WHERE "is_active" = 0 AND NOT EXISTS (';
$expected .= 'SELECT * FROM "tx_crawler_queue" WHERE "tx_crawler_queue"."process_id" = "tx_crawler_ps"."ps_id" AND "tx_crawler_queue"."exec_time" = 0';
$groupBy = '';
$orderBy = '';
- $GLOBALS['TYPO3_DB']->_callRef('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
- $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery($selectFields, $fromTables, $whereClause, $groupBy, $orderBy));
+ $remappedParameters = $GLOBALS['TYPO3_DB']->_call('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
+ $query = $this->cleanSql($GLOBALS['TYPO3_DB']->_call('SELECTqueryFromArray', $remappedParameters));
$expected = 'SELECT "ps_id", CASE "is_active" WHEN 1 THEN \'one\' WHEN 2 THEN \'two\' ELSE \'out of range\' END AS "number" ';
$expected .= 'FROM "tx_crawler_ps" WHERE 1 = 1';
$groupBy = '';
$orderBy = '';
- $GLOBALS['TYPO3_DB']->_callRef('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
- $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery($selectFields, $fromTables, $whereClause, $groupBy, $orderBy));
+ $remappedParameters = $GLOBALS['TYPO3_DB']->_call('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
+ $query = $this->cleanSql($GLOBALS['TYPO3_DB']->_call('SELECTqueryFromArray', $remappedParameters));
$expected = 'SELECT "ps_id", CASE "ext_tt_news"."news_uid" WHEN 1 THEN \'one\' WHEN 2 THEN \'two\' ELSE \'out of range\' END AS "number" ';
$expected .= 'FROM "tx_crawler_ps", "ext_tt_news" WHERE 1 = 1';
$expected = 'SELECT * FROM "tt_news_cat_mm" WHERE NVL("tt_news_cat_mm"."uid_foreign", 0) IN (21,22)';
$this->assertEquals($expected, $query);
}
+
+ /**
+ * @test
+ * @see http://bugs.typo3.org/view.php?id=14985
+ */
+ public function findInSetIsProperlyRemapped() {
+ $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery(
+ '*',
+ 'fe_users',
+ 'FIND_IN_SET(10, usergroup)'
+ ));
+ $expected = 'SELECT * FROM "fe_users" WHERE \',\'||"usergroup"||\',\' LIKE \'%,10,%\'';
+ $this->assertEquals($expected, $query);
+ }
+
+ /**
+ * @test
+ * @see http://bugs.typo3.org/view.php?id=14985
+ */
+ public function findInSetFieldIsProperlyRemapped() {
+ $selectFields = 'fe_group';
+ $fromTables = 'tt_news';
+ $whereClause = 'FIND_IN_SET(10, fe_group)';
+ $groupBy = '';
+ $orderBy = '';
+
+ $remappedParameters = $GLOBALS['TYPO3_DB']->_call('map_remapSELECTQueryParts', $selectFields, $fromTables, $whereClause, $groupBy, $orderBy);
+ $query = $this->cleanSql($GLOBALS['TYPO3_DB']->_call('SELECTqueryFromArray', $remappedParameters));
+
+ $expected = 'SELECT "usergroup" FROM "ext_tt_news" WHERE \',\'||"ext_tt_news"."usergroup"||\',\' LIKE \'%,10,%\'';
+ $this->assertEquals($expected, $query);
+ }
+
+ /**
+ * @test
+ * @see http://bugs.typo3.org/view.php?id=14818
+ */
+ public function listQueryIsProperlyRemapped() {
+ $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery(
+ '*',
+ 'fe_users',
+ $GLOBALS['TYPO3_DB']->listQuery('usergroup', 10, 'fe_users')
+ ));
+ $expected = 'SELECT * FROM "fe_users" WHERE \',\'||"usergroup"||\',\' LIKE \'%,10,%\'';
+ $this->assertEquals($expected, $query);
+ }
+
+ /**
+ * @test
+ * @see http://bugs.typo3.org/view.php?id=12535
+ */
+ public function likeBinaryOperatorIsRemoved() {
+ $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery(
+ '*',
+ 'tt_content',
+ 'bodytext LIKE BINARY \'test\''
+ ));
+ $expected = 'SELECT * FROM "tt_content" WHERE (dbms_lob.instr("bodytext", \'test\',1,1) > 0)';
+ $this->assertEquals($expected, $query);
+ }
}
?>
\ No newline at end of file
$expected = 'SELECT * FROM "be_users" WHERE 1 = 1 LIMIT 40 OFFSET 20';
$this->assertEquals($expected, $query);
}
+
+ /**
+ * @test
+ * @see http://bugs.typo3.org/view.php?id=14985
+ */
+ public function findInSetIsProperlyRemapped() {
+ $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery(
+ '*',
+ 'fe_users',
+ 'FIND_IN_SET(10, usergroup)'
+ ));
+ $expected = 'SELECT * FROM "fe_users" WHERE FIND_IN_SET(10, "usergroup") != 0';
+ $this->assertEquals($expected, $query);
+ }
+
+ /**
+ * @test
+ * @see http://bugs.typo3.org/view.php?id=12535
+ */
+ public function likeBinaryOperatorIsRemappedToLike() {
+ $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery(
+ '*',
+ 'tt_content',
+ 'bodytext LIKE BINARY \'test\''
+ ));
+ $expected = 'SELECT * FROM "tt_content" WHERE "bodytext" LIKE \'test\'';
+ $this->assertEquals($expected, $query);
+ }
+
+ /**
+ * @test
+ * @see http://bugs.typo3.org/view.php?id=12535
+ */
+ public function notLikeBinaryOperatorIsRemappedToNotLike() {
+ $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery(
+ '*',
+ 'tt_content',
+ 'bodytext NOT LIKE BINARY \'test\''
+ ));
+ $expected = 'SELECT * FROM "tt_content" WHERE "bodytext" NOT LIKE \'test\'';
+ $this->assertEquals($expected, $query);
+ }
+
+ /**
+ * @test
+ * @see http://bugs.typo3.org/view.php?id=12535
+ */
+ public function likeOperatorIsRemappedToIlike() {
+ $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery(
+ '*',
+ 'tt_content',
+ 'bodytext LIKE \'test\''
+ ));
+ $expected = 'SELECT * FROM "tt_content" WHERE "bodytext" ILIKE \'test\'';
+ $this->assertEquals($expected, $query);
+ }
+
+ /**
+ * @test
+ * @see http://bugs.typo3.org/view.php?id=12535
+ */
+ public function notLikeOperatorIsRemappedToNotIlike() {
+ $query = $this->cleanSql($GLOBALS['TYPO3_DB']->SELECTquery(
+ '*',
+ 'tt_content',
+ 'bodytext NOT LIKE \'test\''
+ ));
+ $expected = 'SELECT * FROM "tt_content" WHERE "bodytext" NOT ILIKE \'test\'';
+ $this->assertEquals($expected, $query);
+ }
}
?>
\ No newline at end of file
/**
* MS SQL configuration
*
- * $Id: mssql.config.php 29886 2010-02-09 21:39:29Z xperseguers $
+ * $Id: mssql.config.php 36760 2010-08-14 15:58:41Z xperseguers $
*
* @author Xavier Perseguers <typo3@perseguers.ch>
*
/**
* Oracle configuration
*
- * $Id: oci8.config.php 27125 2009-11-29 17:21:28Z xperseguers $
+ * $Id: oci8.config.php 36760 2010-08-14 15:58:41Z xperseguers $
*
* @author Xavier Perseguers <typo3@perseguers.ch>
*
'tt_news' => array(
'mapTableName' => 'ext_tt_news',
'mapFieldNames' => array(
- 'uid' => 'news_uid',
+ 'uid' => 'news_uid',
+ 'fe_group' => 'usergroup',
),
),
'tt_news_cat' => array(
$this->assertEquals($expected, $alterTable[0]);
}
+ /**
+ * @test
+ * @see http://bugs.typo3.org/view.php?id=14985
+ */
+ public function canParseFindInSetStatement() {
+ $parseString = 'SELECT * FROM fe_users WHERE FIND_IN_SET(10, usergroup)';
+ $components = $this->fixture->_callRef('parseSELECT', $parseString);
+
+ $this->assertTrue(is_array($components), $components);
+ $selectTable = $this->cleanSql($this->fixture->_callRef('compileSELECT', $components));
+ $expected = 'SELECT * FROM fe_users WHERE FIND_IN_SET(10, usergroup)';
+ $this->assertEquals($expected, $selectTable);
+ }
+
///////////////////////////////////////
// Tests concerning JOINs
///////////////////////////////////////
$this->assertEquals($expected, $actual);
}
+
+ ///////////////////////////////////////
+ // Tests concerning prepared queries
+ ///////////////////////////////////////
+
+ /**
+ * @test
+ * @see http://bugs.typo3.org/view.php?id=15457
+ */
+ public function namedPlaceholderIsSupported() {
+ $sql = 'SELECT * FROM pages WHERE pid = :pid ORDER BY title';
+ $expected = 'SELECT * FROM pages WHERE pid = :pid ORDER BY title';
+ $actual = $this->cleanSql($this->fixture->debug_testSQL($sql));
+
+ $this->assertEquals($expected, $actual);
+ }
+
+ /**
+ * @test
+ * @see http://bugs.typo3.org/view.php?id=15457
+ */
+ public function questionMarkPlaceholderIsSupported() {
+ $sql = 'SELECT * FROM pages WHERE pid = ? ORDER BY title';
+ $expected = 'SELECT * FROM pages WHERE pid = ? ORDER BY title';
+ $actual = $this->cleanSql($this->fixture->debug_testSQL($sql));
+
+ $this->assertEquals($expected, $actual);
+ }
+
+ /**
+ * @test
+ * @see http://bugs.typo3.org/view.php?id=15457
+ */
+ public function parametersAreReferenced() {
+ $sql = 'SELECT * FROM pages WHERE pid = :pid1 OR pid = :pid2';
+ $components = $this->fixture->_callRef('parseSELECT', $sql);
+
+ $this->assertTrue(is_array($components['parameters']), 'References to parameters not found');
+ $this->assertEquals(2, count($components['parameters']));
+ $this->assertTrue(is_array($components['parameters']), 'References to parameters not found');
+ $this->assertTrue(isset($components['parameters'][':pid1']));
+ $this->assertTrue(isset($components['parameters'][':pid2']));
+ }
+
+ /**
+ * @test
+ * @see http://bugs.typo3.org/view.php?id=15457
+ */
+ public function sameParameterIsReferencedInSubquery() {
+ $sql = 'SELECT * FROM pages WHERE uid = :pageId OR uid IN (SELECT uid FROM pages WHERE pid = :pageId)';
+ $pageId = 12;
+
+ $components = $this->fixture->_callRef('parseSELECT', $sql);
+ $components['parameters'][':pageId'][0] = $pageId;
+ $query = $this->cleanSql($this->fixture->_callRef('compileSELECT', $components));
+ $expected = 'SELECT * FROM pages WHERE uid = 12 OR uid IN (SELECT uid FROM pages WHERE pid = 12)';
+
+ $this->assertEquals($expected, $query);
+ }
+
+ /**
+ * @test
+ * @see http://bugs.typo3.org/view.php?id=15457
+ */
+ public function namedParametersMayBeSafelyReplaced() {
+ $sql = 'SELECT * FROM pages WHERE pid = :pid AND title NOT LIKE \':pid\'';
+ $pid = 12;
+
+ $components = $this->fixture->_callRef('parseSELECT', $sql);
+ $components['parameters'][':pid'][0] = $pid;
+ $query = $this->cleanSql($this->fixture->_callRef('compileSELECT', $components));
+ $expected = 'SELECT * FROM pages WHERE pid = ' . $pid . ' AND title NOT LIKE \':pid\'';
+
+ $this->assertEquals($expected, $query);
+ }
+
+ /**
+ * @test
+ * @see http://bugs.typo3.org/view.php?id=15457
+ */
+ public function questionMarkParametersMayBeSafelyReplaced() {
+ $sql = 'SELECT * FROM pages WHERE pid = ? AND timestamp < ? AND title != \'How to test?\'';
+ $parameterValues = array(12, 1281782690);
+
+ $components = $this->fixture->_callRef('parseSELECT', $sql);
+ for ($i = 0; $i < count($components['parameters']['?']); $i++) {
+ $components['parameters']['?'][$i][0] = $parameterValues[$i];
+ }
+ $query = $this->cleanSql($this->fixture->_callRef('compileSELECT', $components));
+ $expected = 'SELECT * FROM pages WHERE pid = 12 AND timestamp < 1281782690 AND title != \'How to test?\'';
+
+ $this->assertEquals($expected, $query);
+ }
}
?>
\ No newline at end of file