/src/typo3_src-4.1.2/typo3/sysext/dbal/class.ux_t3lib_db.php

00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 2004-2006 Kasper Skaarhoj (kasperYYYY@typo3.com)
00006 *  All rights reserved
00007 *
00008 *  This script is part of the TYPO3 project. The TYPO3 project is
00009 *  free software; you can redistribute it and/or modify
00010 *  it under the terms of the GNU General Public License as published by
00011 *  the Free Software Foundation; either version 2 of the License, or
00012 *  (at your option) any later version.
00013 *
00014 *  The GNU General Public License can be found at
00015 *  http://www.gnu.org/copyleft/gpl.html.
00016 *  A copy is found in the textfile GPL.txt and important notices to the license
00017 *  from the author is found in LICENSE.txt distributed with these scripts.
00018 *
00019 *
00020 *  This script is distributed in the hope that it will be useful,
00021 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023 *  GNU General Public License for more details.
00024 *
00025 *  This copyright notice MUST APPEAR in all copies of the script!
00026 ***************************************************************/
00115 require_once(PATH_t3lib.'class.t3lib_sqlengine.php');
00116 require_once(PATH_t3lib.'class.t3lib_install.php');
00117 
00126 class ux_t3lib_DB extends t3lib_DB {
00127 
00128         // Internal, static:
00129         var $printErrors = false;               // Enable output of SQL errors after query executions. Set through TYPO3_CONF_VARS, see init()
00130         var $debug = false;                     // Enable debug mode. Set through TYPO3_CONF_VARS, see init()
00131         var $conf = array();                    // Configuration array, copied from TYPO3_CONF_VARS in constructor.
00132 
00133         var $mapping = array();                 // See manual.
00134         var $table2handlerKeys = array();       // See manual.
00135         var $handlerCfg = array (               // See manual.
00136             '_DEFAULT' => array (
00137                                 'type' => 'native',
00138                                 'config' => array(
00139                                     'username' => '',           // Set by default (overridden)
00140                                     'password' => '',           // Set by default (overridden)
00141                                     'host' => '',               // Set by default (overridden)
00142                                     'database' => '',           // Set by default (overridden)
00143                                     'driver' => '',             // ONLY "adodb" type; eg. "mysql"
00144                                     'sequenceStart' => 1 // ONLY "adodb", first number in sequences/serials/...
00145                                 )
00146             ),
00147         );
00148 
00149 
00150         // Internal, dynamic:
00151         var $handlerInstance = array();                         // Contains instance of the handler objects as they are created. Exception is the native mySQL calls which are registered as an array with keys "handlerType" = "native" and "link" pointing to the link resource for the connection.
00152         var $lastHandlerKey = '';                                       // Storage of the handler key of last ( SELECT) query - used for subsequent fetch-row calls etc.
00153         var $lastQuery = '';                                            // Storage of last SELECT query
00154         var $lastParsedAndMappedQueryArray = array();   // Query array, the last one parsed
00155 
00156         var $resourceIdToTableNameMap = array();        // Mapping of resource ids to table names.
00157 
00158         // Internal, caching:
00159         var $cache_handlerKeyFromTableList = array();                   // Caching handlerKeys for table lists
00160         var $cache_mappingFromTableList = array();                      // Caching mapping information for table lists
00161         var $cache_autoIncFields = array(); // parsed SQL from standard DB dump file
00162         var $cache_fieldType = array(); // field types for tables/fields
00163         var $cache_primaryKeys = array(); // primary keys
00164 
00165 
00166 
00173         function ux_t3lib_DB()  {
00174 
00175                 // Set SQL parser object for internal use:
00176                 $this->SQLparser = t3lib_div::makeInstance('t3lib_sqlengine');
00177                 $this->Installer = t3lib_div::makeInstance('t3lib_install');
00178 
00179                 // Set internal variables with configuration:
00180                 $this->conf = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['dbal'];
00181                 $this->initInternalVariables();
00182         }
00183 
00189         function initInternalVariables()        {
00190 
00191                 // Set outside configuration:
00192                 if (isset($this->conf['mapping']))                              $this->mapping = $this->conf['mapping'];
00193                 if (isset($this->conf['table2handlerKeys']))    $this->table2handlerKeys = $this->conf['table2handlerKeys'];
00194                 if (isset($this->conf['handlerCfg']))                   $this->handlerCfg = $this->conf['handlerCfg'];
00195 
00196                 $this->cacheFieldInfo();
00197                 // Debugging settings:
00198                 $this->printErrors = $this->conf['debugOptions']['printErrors'] ? TRUE : FALSE;
00199                 $this->debug = $this->conf['debugOptions']['enabled'] ? TRUE : FALSE;
00200         }
00201 
00202         function clearCachedFieldInfo() {
00203                 if(file_exists(PATH_typo3conf.'temp_fieldInfo.php'))
00204                 unlink(PATH_typo3conf.'temp_fieldInfo.php');
00205         }
00206 
00207         function cacheFieldInfo() {
00208                 global $TYPO3_LOADED_EXT;
00209                 $extSQL = '';
00210                 $parsedExtSQL = array();
00211 
00212                 // try to fetch cached file first
00213                 // file is removed when admin_query() is called
00214                 if(file_exists(PATH_typo3conf.'temp_fieldInfo.php')) {
00215                         $fdata = unserialize(t3lib_div::getUrl(PATH_typo3conf.'temp_fieldInfo.php'));
00216                         $this->cache_autoIncFields = $fdata['incFields'];
00217                         $this->cache_fieldType = $fdata['fieldTypes'];
00218                         $this->cache_primaryKeys = $fdata['primaryKeys'];
00219                 }
00220                 else {
00221                                 // handle stddb.sql, parse and analyze
00222                         $extSQL = t3lib_div::getUrl(PATH_site.'t3lib/stddb/tables.sql');
00223                         $parsedExtSQL = $this->Installer->getFieldDefinitions_sqlContent($extSQL);
00224                         $this->analyzeFields($parsedExtSQL);
00225 
00226                                 // loop over all installed extensions
00227                         foreach($TYPO3_LOADED_EXT as $ext => $v)        {
00228                                 if(!is_array($v) || !isset($v['ext_tables.sql']))
00229                                 continue;
00230 
00231                                         // fetch db dump (if any) and parse it, then analyze
00232                                 $extSQL = t3lib_div::getUrl($v['ext_tables.sql']);
00233                                 $parsedExtSQL = $this->Installer->getFieldDefinitions_sqlContent($extSQL);
00234                                 $this->analyzeFields($parsedExtSQL);
00235                         }
00236 
00237                         $cachedFieldInfo = array('incFields' => $this->cache_autoIncFields, 'fieldTypes' => $this->cache_fieldType, 'primaryKeys' => $this->cache_primaryKeys);
00238                         $cachedFieldInfo = serialize($this->mapCachedFieldInfo($cachedFieldInfo));
00239 
00240                                 // write serialized content to file
00241                         t3lib_div::writeFile(PATH_typo3conf."temp_fieldInfo.php", $cachedFieldInfo);
00242 
00243                         if (strcmp(t3lib_div::getUrl(PATH_typo3conf."temp_fieldInfo.php"), $cachedFieldInfo))   {
00244                                 die('typo3temp/temp_incfields.php was NOT updated properly (written content didn\'t match file content) - maybe write access problem?');
00245                         }
00246                 }
00247         }
00248 
00256         function analyzeFields($parsedExtSQL) {
00257                 foreach($parsedExtSQL as $table => $tdef) {
00258                         if (is_array($tdef['fields'])) {
00259                                 foreach($tdef['fields'] as $field => $fdef) {
00260                                         $fdef = $this->SQLparser->parseFieldDef($fdef);
00261                                         $this->cache_fieldType[$table][$field]['type'] = $fdef['fieldType'];
00262                                         $this->cache_fieldType[$table][$field]['metaType'] = $this->MySQLMetaType($fdef['fieldType']);
00263                                         $this->cache_fieldType[$table][$field]['notnull'] = (isset($fdef['featureIndex']['NOTNULL']) && !$this->SQLparser->checkEmptyDefaultValue($fdef['featureIndex'])) ? 1 : 0;
00264                                         if(isset($fdef['featureIndex']['AUTO_INCREMENT'])) {
00265                                                 $this->cache_autoIncFields[$table] = $field;
00266                                         }
00267                                         if(isset($tdef['keys']['PRIMARY'])) {
00268                                                 $this->cache_primaryKeys[$table] = substr($tdef['keys']['PRIMARY'], 13, -1);
00269                                         }
00270                                 }
00271                         }
00272                 }
00273         }
00274 
00279         function mapCachedFieldInfo($fieldInfo){
00280                 global $TYPO3_CONF_VARS;
00281 
00282                 if(is_array($TYPO3_CONF_VARS['EXTCONF']['dbal']['mapping'])) {
00283                         foreach($TYPO3_CONF_VARS['EXTCONF']['dbal']['mapping'] as $mappedTable => $mappedConf){
00284                                 if(array_key_exists($mappedTable, $fieldInfo['incFields'])) {
00285                                         $mappedTableAlias = $mappedConf['mapTableName'];
00286                                         $fieldInfo['incFields'][$mappedTableAlias] = isset($mappedConf['mapFieldNames'][$fieldInfo['incFields'][$mappedTable]]) ? $mappedConf['mapFieldNames'][$fieldInfo['incFields'][$mappedTable]] : $fieldInfo['incFields'][$mappedTable];
00287                                 }
00288 
00289                                 if(array_key_exists($mappedTable, $fieldInfo['fieldTypes'])) {
00290                                         foreach($fieldInfo['fieldTypes'][$mappedTable] as $field => $fieldConf){
00291                                                 $tempMappedFieldConf[$mappedConf['mapFieldNames'][$field]] = $fieldConf;
00292                                         }
00293 
00294                                         $fieldInfo['fieldTypes'][$mappedConf['mapTableName']] = $tempMappedFieldConf;
00295                                 }
00296 
00297                                 if(array_key_exists($mappedTable, $fieldInfo['primaryKeys'])) {
00298                                         $mappedTableAlias = $mappedConf['mapTableName'];
00299                                         $fieldInfo['primaryKeys'][$mappedTableAlias] = isset($mappedConf['mapFieldNames'][$fieldInfo['primaryKeys'][$mappedTable]]) ? $mappedConf['mapFieldNames'][$fieldInfo['primaryKeys'][$mappedTable]] : $fieldInfo['primaryKeys'][$mappedTable];
00300                                 }
00301 
00302                         }
00303                 }
00304 
00305                 return $fieldInfo;
00306         }
00307 
00308 
00309         /************************************
00310         *
00311         * Query Building (Overriding parent methods)
00312         * These functions are extending counterparts in the parent class.
00313         *
00314         **************************************/
00315 
00316         /* From the ADOdb documentation, this is what we do (_Execute for SELECT, _query for the other actions)
00317 
00318         Execute() is the default way to run queries. You can use the low-level functions _Execute() and _query() to reduce query overhead.
00319         Both these functions share the same parameters as Execute().
00320 
00321         If you do not have any bind parameters or your database supports binding (without emulation), then you can call _Execute() directly.
00322         Calling this function bypasses bind emulation. Debugging is still supported in _Execute().
00323 
00324         If you do not require debugging facilities nor emulated binding, and do not require a recordset to be returned, then you can call _query.
00325         This is great for inserts, updates and deletes. Calling this function bypasses emulated binding, debugging, and recordset handling. Either
00326         the resultid, true or false are returned by _query().
00327         */
00328 
00337         function exec_INSERTquery($table,$fields_values,$no_quote_fields='')    {
00338 
00339                 if ($this->debug)       $pt = t3lib_div::milliseconds();
00340 
00341                 // Do field mapping if needed:
00342                 $ORIG_tableName = $table;
00343                 if ($tableArray = $this->map_needMapping($table))       {
00344 
00345                         // Field mapping of array:
00346                         $fields_values = $this->map_assocArray($fields_values,$tableArray);
00347 
00348                         // Table name:
00349                         if ($this->mapping[$table]['mapTableName'])     {
00350                                 $table = $this->mapping[$table]['mapTableName'];
00351                         }
00352                 }
00353                 // Select API:
00354                 $this->lastHandlerKey = $this->handler_getFromTableList($ORIG_tableName);
00355                 switch((string)$this->handlerCfg[$this->lastHandlerKey]['type'])        {
00356                         case 'native':
00357                                 $this->lastQuery = $this->INSERTquery($table,$fields_values,$no_quote_fields);
00358                                 if(is_string($this->lastQuery)) {
00359                                         $sqlResult = mysql_query($this->lastQuery, $this->handlerInstance[$this->lastHandlerKey]['link']);
00360                                 }
00361                                 else {
00362                                         $sqlResult = mysql_query($this->lastQuery[0], $this->handlerInstance[$this->lastHandlerKey]['link']);
00363                                         foreach($this->lastQuery[1] as $field => $content) {
00364                                                 mysql_query('UPDATE '.$this->quoteFromTables($table).' SET '.$this->quoteFromTables($field).'='.$this->fullQuoteStr($content,$table).' WHERE '.$this->quoteWhereClause($where), $this->handlerInstance[$this->lastHandlerKey]['link']);
00365                                         }
00366                                 }
00367                                 break;
00368                         case 'adodb':
00369                                         // auto generate ID for auto_increment fields if not present (static import needs this!)
00370                                         // should we check the table name here (static_*)?
00371                                 if(isset($this->cache_autoIncFields[$table])) {
00372                                         if(isset($fields_values[$this->cache_autoIncFields[$table]])) {
00373                                                 $new_id = $fields_values[$this->cache_autoIncFields[$table]];
00374                                                 if($table !== 'tx_dbal_debuglog') {
00375                                                         $this->handlerInstance[$this->lastHandlerKey]->last_insert_id = $new_id;
00376                                                 }
00377                                         } else {
00378                                                 $new_id = $this->handlerInstance[$this->lastHandlerKey]->GenID($table.'_'.$this->cache_autoIncFields[$table], $this->handlerInstance[$this->lastHandlerKey]->sequenceStart);
00379                                                 $fields_values[$this->cache_autoIncFields[$table]] = $new_id;
00380                                                 if($table !== 'tx_dbal_debuglog') {
00381                                                         $this->handlerInstance[$this->lastHandlerKey]->last_insert_id = $new_id;
00382                                                 }
00383                                         }
00384                                 }
00385 
00386                                 $this->lastQuery = $this->INSERTquery($table,$fields_values,$no_quote_fields);
00387                                 if(is_string($this->lastQuery)) {
00388                                         $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->_query($this->lastQuery,false);
00389                                 } else {
00390                                         $this->handlerInstance[$this->lastHandlerKey]->StartTrans();
00391                                         if(strlen($this->lastQuery[0]))
00392                                                 $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->_query($this->lastQuery[0],false);
00393                                         foreach($this->lastQuery[1] as $field => $content) {
00394                                                 if(empty($content)) continue;
00395 
00396                                                 if(isset($this->cache_autoIncFields[$table]) && isset($new_id)) {
00397                                                         $this->handlerInstance[$this->lastHandlerKey]->UpdateBlob($this->quoteFromTables($table),$field,$content,$this->quoteWhereClause($this->cache_autoIncFields[$table].'='.$new_id));
00398                                                 } elseif(isset($this->cache_primaryKeys[$table])) {
00399                                                         $pks = explode(',', $this->cache_primaryKeys[$table]);
00400                                                         foreach ($pks as $pk) {
00401                                                                 if(isset($fields_values[$pk]))
00402                                                                 $where .= $pk.'='.$this->fullQuoteStr($fields_values[$pk], $table).' AND ';
00403                                                         }
00404                                                         $where = $this->quoteWhereClause($where.'1=1');
00405                                                         $this->handlerInstance[$this->lastHandlerKey]->UpdateBlob($this->quoteFromTables($table),$field,$content,$where);
00406                                                 } else {
00407                                                         $this->handlerInstance[$this->lastHandlerKey]->CompleteTrans(false);
00408                                                         die('Could not update BLOB >>>> no WHERE clause found!'); // should never ever happen
00409                                                 }
00410                                         }
00411                                         $this->handlerInstance[$this->lastHandlerKey]->CompleteTrans();
00412                                 }
00413                                 break;
00414                         case 'userdefined':
00415                                 $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->exec_INSERTquery($table,$fields_values,$no_quote_fields);
00416                                 break;
00417                 }
00418 
00419                 if ($this->printErrors && $this->sql_error())   {
00420                         debug(array($this->lastQuery, $this->sql_error()));
00421                 }
00422 
00423                 if ($this->debug)       {
00424                         $this->debugHandler(
00425                                 'exec_INSERTquery',
00426                                 t3lib_div::milliseconds()-$pt,
00427                                 array(
00428                                         'handlerType' => $hType,
00429                                         'args' => array($table,$fields_values),
00430                                         'ORIG_tablename' => $ORIG_tableName
00431                                 )
00432                         );
00433                 }
00434                         // Return output:
00435                 return $sqlResult;
00436         }
00437 
00447         function exec_UPDATEquery($table,$where,$fields_values,$no_quote_fields='')     {
00448 
00449                 if ($this->debug)       $pt = t3lib_div::milliseconds();
00450 
00451                 // Do table/field mapping:
00452                 $ORIG_tableName = $table;
00453                 if ($tableArray = $this->map_needMapping($table))       {
00454 
00455                         // Field mapping of array:
00456                         $fields_values = $this->map_assocArray($fields_values,$tableArray);
00457 
00458                         // Where clause table and field mapping:
00459                         $whereParts = $this->SQLparser->parseWhereClause($where);
00460                         $this->map_sqlParts($whereParts,$tableArray[0]['table']);
00461                         $where = $this->SQLparser->compileWhereClause($whereParts);
00462 
00463                         // Table name:
00464                         if ($this->mapping[$table]['mapTableName'])     {
00465                                 $table = $this->mapping[$table]['mapTableName'];
00466                         }
00467                 }
00468 
00469                 // Select API
00470                 $this->lastHandlerKey = $this->handler_getFromTableList($ORIG_tableName);
00471                 switch((string)$this->handlerCfg[$this->lastHandlerKey]['type'])        {
00472                         case 'native':
00473                                 $this->lastQuery = $this->UPDATEquery($table,$where,$fields_values,$no_quote_fields);
00474                                 if(is_string($this->lastQuery)) {
00475                                         $sqlResult = mysql_query($this->lastQuery, $this->handlerInstance[$this->lastHandlerKey]['link']);
00476                                 }
00477                                 else {
00478                                         $sqlResult = mysql_query($this->lastQuery[0], $this->handlerInstance[$this->lastHandlerKey]['link']);
00479                                         foreach($this->lastQuery[1] as $field => $content) {
00480                                                 mysql_query('UPDATE '.$this->quoteFromTables($table).' SET '.$this->quoteFromTables($field).'='.$this->fullQuoteStr($content,$table).' WHERE '.$this->quoteWhereClause($where), $this->handlerInstance[$this->lastHandlerKey]['link']);
00481                                         }
00482                                 }
00483                         break;
00484                         case 'adodb':
00485                                 $this->lastQuery = $this->UPDATEquery($table,$where,$fields_values,$no_quote_fields);
00486                                 if(is_string($this->lastQuery)) {
00487                                         $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->_query($this->lastQuery,false);
00488                                 } else {
00489                                         $this->handlerInstance[$this->lastHandlerKey]->StartTrans();
00490                                         if(strlen($this->lastQuery[0]))
00491                                                 $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->_query($this->lastQuery[0],false);
00492                                         foreach($this->lastQuery[1] as $field => $content) {
00493                                                 $this->handlerInstance[$this->lastHandlerKey]->UpdateBlob($this->quoteFromTables($table),$field,$content,$this->quoteWhereClause($where));
00494                                         }
00495                                         $this->handlerInstance[$this->lastHandlerKey]->CompleteTrans();
00496                                 }
00497                                 break;
00498                         case 'userdefined':
00499                                 $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->exec_UPDATEquery($table,$where,$fields_values,$no_quote_fields);
00500                                 break;
00501                 }
00502 
00503                 if ($this->printErrors && $this->sql_error())   {
00504                         debug(array($this->lastQuery, $this->sql_error()));
00505                 }
00506 
00507                 if ($this->debug)       {
00508                         $this->debugHandler(
00509                                 'exec_UPDATEquery',
00510                                 t3lib_div::milliseconds()-$pt,
00511                                 array(
00512                                         'handlerType' => $hType,
00513                                         'args' => array($table,$where, $fields_values),
00514                                         'ORIG_from_table' => $ORIG_tableName
00515                                 )
00516                         );
00517                 }
00518 
00519                         // Return result:
00520                 return $sqlResult;
00521         }
00522 
00530         function exec_DELETEquery($table,$where)        {
00531 
00532                 if ($this->debug)       $pt = t3lib_div::milliseconds();
00533 
00534                         // Do table/field mapping:
00535                 $ORIG_tableName = $table;
00536                 if ($tableArray = $this->map_needMapping($table))       {
00537 
00538                                 // Where clause:
00539                         $whereParts = $this->SQLparser->parseWhereClause($where);
00540                         $this->map_sqlParts($whereParts,$tableArray[0]['table']);
00541                         $where = $this->SQLparser->compileWhereClause($whereParts);
00542 
00543                                 // Table name:
00544                         if ($this->mapping[$table]['mapTableName'])     {
00545                                 $table = $this->mapping[$table]['mapTableName'];
00546                         }
00547                 }
00548 
00549                         // Select API
00550                 $this->lastHandlerKey = $this->handler_getFromTableList($ORIG_tableName);
00551                 switch((string)$this->handlerCfg[$this->lastHandlerKey]['type'])        {
00552                         case 'native':
00553                                 $this->lastQuery = $this->DELETEquery($table,$where);
00554                                 $sqlResult = mysql_query($this->lastQuery, $this->handlerInstance[$this->lastHandlerKey]['link']);
00555                                 break;
00556                         case 'adodb':
00557                                 $this->lastQuery = $this->DELETEquery($table,$where);
00558                                 $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->_query($this->lastQuery,false);
00559                                 break;
00560                         case 'userdefined':
00561                                 $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->exec_DELETEquery($table,$where);
00562                                 break;
00563                 }
00564 
00565                 if ($this->printErrors && $this->sql_error())   {
00566                         debug(array($this->lastQuery, $this->sql_error()));
00567                 }
00568 
00569                 if ($this->debug)       {
00570                         $this->debugHandler(
00571                                 'exec_DELETEquery',
00572                                 t3lib_div::milliseconds()-$pt,
00573                                 array(
00574                                         'handlerType' => $hType,
00575                                         'args' => array($table,$where),
00576                                         'ORIG_from_table' => $ORIG_tableName
00577                                 )
00578                         );
00579                 }
00580 
00581                         // Return result:
00582                 return $sqlResult;
00583         }
00584 
00596         function exec_SELECTquery($select_fields,$from_table,$where_clause,$groupBy='',$orderBy='',$limit='')   {
00597 
00598                 if ($this->debug)       $pt = t3lib_div::milliseconds();
00599 
00600                         // Map table / field names if needed:
00601                 $ORIG_tableName = $from_table;  // Saving table names in $ORIG_from_table since $from_table is transformed beneath:
00602                 if ($tableArray = $this->map_needMapping($ORIG_tableName))      {
00603                         $this->map_remapSELECTQueryParts($select_fields,$from_table,$where_clause,$groupBy,$orderBy);   // Variables passed by reference!
00604                 }
00605 
00606                         // Get handler key and select API:
00607                 $this->lastHandlerKey = $this->handler_getFromTableList($ORIG_tableName);
00608                 $hType = (string)$this->handlerCfg[$this->lastHandlerKey]['type'];
00609                 switch($hType)  {
00610                         case 'native':
00611                                 $this->lastQuery = $this->SELECTquery($select_fields,$from_table,$where_clause,$groupBy,$orderBy,$limit);
00612                                 $sqlResult = mysql_query($this->lastQuery, $this->handlerInstance[$this->lastHandlerKey]['link']);
00613                                 $this->resourceIdToTableNameMap[(string)$sqlResult] = $ORIG_tableName;
00614                                 break;
00615                         case 'adodb':
00616                                 if ($limit!='') {
00617                                         $splitLimit = t3lib_div::intExplode(',',$limit);                // Splitting the limit values:
00618                                         if ($splitLimit[1])     {       // If there are two parameters, do mapping differently than otherwise:
00619                                                 $numrows = $splitLimit[1];
00620                                                 $offset = $splitLimit[0];
00621                                         } else {
00622                                                 $numrows = $splitLimit[0];
00623                                                 $offset = 0;
00624                                         }
00625 
00626                                         $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->SelectLimit($this->SELECTquery($select_fields,$from_table,$where_clause,$groupBy,$orderBy), $numrows, $offset);
00627                                         $this->lastQuery = $sqlResult->sql;
00628                                 } else {
00629                                         $this->lastQuery = $this->SELECTquery($select_fields,$from_table,$where_clause,$groupBy,$orderBy);
00630                                         $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->_Execute($this->lastQuery);
00631                                 }
00632                                 $sqlResult->TYPO3_DBAL_handlerType = 'adodb';   // Setting handler type in result object (for later recognition!)
00633                                 $sqlResult->TYPO3_DBAL_tableList = $ORIG_tableName;
00634                                 break;
00635                         case 'userdefined':
00636                                 $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->exec_SELECTquery($select_fields,$from_table,$where_clause,$groupBy,$orderBy,$limit);
00637                                 if (is_object($sqlResult))      {
00638                                         $sqlResult->TYPO3_DBAL_handlerType = 'userdefined';     // Setting handler type in result object (for later recognition!)
00639                                         $sqlResult->TYPO3_DBAL_tableList = $ORIG_tableName;
00640                                 }
00641                                 break;
00642                 }
00643 
00644                 if ($this->printErrors && $this->sql_error())   {
00645                         debug(array($this->lastQuery, $this->sql_error()));
00646                 }
00647 
00648                 if ($this->debug)       {
00649                         $this->debugHandler(
00650                                 'exec_SELECTquery',
00651                                 t3lib_div::milliseconds()-$pt,
00652                                 array(
00653                                         'handlerType' => $hType,
00654                                         'args' => array($from_table,$select_fields,$where_clause,$groupBy,$orderBy,$limit),
00655                                         'ORIG_from_table' => $ORIG_tableName
00656                                 )
00657                         );
00658                 }
00659 
00660                         // Return result handler.
00661                 return $sqlResult;
00662         }
00663 
00664 
00665 
00666         /**************************************
00667         *
00668         * Query building
00669         *
00670         **************************************/
00671 
00682         function INSERTquery($table,$fields_values,$no_quote_fields='') {
00683                 // Table and fieldnames should be "SQL-injection-safe" when supplied to this function (contrary to values in the arrays which may be insecure).
00684                 if (is_array($fields_values) && count($fields_values))  {
00685 
00686                         if (is_string($no_quote_fields))        {
00687                                 $no_quote_fields = explode(',',$no_quote_fields);
00688                         } elseif (!is_array($no_quote_fields))  {
00689                                 $no_quote_fields = array();
00690                         }
00691 
00692                         $blobfields = array();
00693                         $nArr = array();
00694                         foreach($fields_values as $k => $v)     {
00695                                 if(!$this->runningNative() && $this->sql_field_metatype($table,$k) == 'B') {
00696                                                 // we skip the field in the regular INSERT statement, it is only in blobfields
00697                                         $blobfields[$this->quoteFieldNames($k)] = $v;
00698                                 }
00699                                 else {
00700                                         // Add slashes old-school:
00701                                         // cast numerical values
00702                                         $mt = $this->sql_field_metatype($table,$k);
00703                                         $v = (($mt{0}=='I')||($mt{0}=='F')) ? (int)$v : $v;
00704 
00705                                         $nArr[$this->quoteFieldNames($k)] = (!in_array($k,$no_quote_fields)) ? $this->fullQuoteStr($v, $table) : $v;
00706                                 }
00707                         }
00708                         if(count($blobfields)) {
00709                                 if(count($nArr)) {
00710                                         $query[0] = 'INSERT INTO '.$this->quoteFromTables($table).'
00711                                         (
00712                                                 '.implode(',
00713                                                 ',array_keys($nArr)).'
00714                                         ) VALUES (
00715                                                 '.implode(',
00716                                                 ',$nArr).'
00717                                         )';
00718                                 }
00719                                 $query[1] = $blobfields;
00720                                 if ($this->debugOutput || $this->store_lastBuiltQuery) $this->debug_lastBuiltQuery = $query[0];
00721                         }
00722                         else {
00723                                 $query = 'INSERT INTO '.$this->quoteFromTables($table).'
00724                                 (
00725                                         '.implode(',
00726                                         ',array_keys($nArr)).'
00727                                 ) VALUES (
00728                                         '.implode(',
00729                                         ',$nArr).'
00730                                 )';
00731 
00732                                 if ($this->debugOutput || $this->store_lastBuiltQuery) $this->debug_lastBuiltQuery = $query;
00733                         }
00734 
00735                         return $query;
00736                 }
00737         }
00738 
00750         function UPDATEquery($table,$where,$fields_values,$no_quote_fields='')  {
00751                 // Table and fieldnames should be "SQL-injection-safe" when supplied to this function (contrary to values in the arrays which may be insecure).
00752                 if (is_string($where))  {
00753                         if (is_array($fields_values) && count($fields_values))  {
00754 
00755                                 if (is_string($no_quote_fields))        {
00756                                         $no_quote_fields = explode(',',$no_quote_fields);
00757                                 } elseif (!is_array($no_quote_fields))  {
00758                                         $no_quote_fields = array();
00759                                 }
00760 
00761                                 $blobfields = array();
00762                                 $nArr = array();
00763                                 foreach($fields_values as $k => $v)     {
00764                                         if(!$this->runningNative() && $this->sql_field_metatype($table,$k) == 'B') {
00765                                                         // we skip the field in the regular UPDATE statement, it is only in blobfields
00766                                                 $blobfields[$this->quoteFieldNames($k)] = $v;
00767                                         }
00768                                         else {
00769                                                         // Add slashes old-school:
00770                                                         // cast numeric values
00771                                                 $mt = $this->sql_field_metatype($table,$k);
00772                                                 $v = (($mt{0}=='I')||($mt{0}=='F')) ? (int)$v : $v;
00773                                                 $nArr[] = $this->quoteFieldNames($k).'='.((!in_array($k,$no_quote_fields)) ? $this->fullQuoteStr($v, $table) : $v);
00774                                         }
00775                                 }
00776 
00777                                 if(count($blobfields)) {
00778                                         if(count($nArr)) {
00779                                                 $query[0] = 'UPDATE '.$this->quoteFromTables($table).'
00780                                                 SET
00781                                                         '.implode(',
00782                                                         ',$nArr).
00783                                                         (strlen($where)>0 ? '
00784                                                 WHERE
00785                                                         '.$this->quoteWhereClause($where) : '');
00786                                         }
00787                                         $query[1] = $blobfields;
00788                                         if ($this->debugOutput || $this->store_lastBuiltQuery) $this->debug_lastBuiltQuery = $query[0];
00789                                 }
00790                                 else {
00791                                         $query = 'UPDATE '.$this->quoteFromTables($table).'
00792                                         SET
00793                                                 '.implode(',
00794                                                 ',$nArr).
00795                                                 (strlen($where)>0 ? '
00796                                         WHERE
00797                                                 '.$this->quoteWhereClause($where) : '');
00798 
00799                                                 if ($this->debugOutput || $this->store_lastBuiltQuery) $this->debug_lastBuiltQuery = $query;
00800                                 }
00801 
00802                                 return $query;
00803                         }
00804                 }
00805                 else {
00806                         die('<strong>TYPO3 Fatal Error:</strong> "Where" clause argument for UPDATE query was not a string in $this->UPDATEquery() !');
00807                 }
00808         }
00809 
00819         function DELETEquery($table,$where)     {
00820                 if (is_string($where))  {
00821                         $table = $this->quoteFromTables($table);
00822                         $where = $this->quoteWhereClause($where);
00823 
00824                         $query = parent::DELETEquery($table, $where);
00825 
00826                         if ($this->debugOutput || $this->store_lastBuiltQuery) $this->debug_lastBuiltQuery = $query;
00827                         return $query;
00828                 } else {
00829                         die('<strong>TYPO3 Fatal Error:</strong> "Where" clause argument for DELETE query was not a string in $this->DELETEquery() !');
00830                 }
00831         }
00832 
00846         function SELECTquery($select_fields,$from_table,$where_clause,$groupBy='',$orderBy='',$limit='')        {
00847 
00848                 $select_fields = $this->quoteFieldNames($select_fields);
00849                 $from_table = $this->quoteFromTables($from_table);
00850                 $where_clause = $this->quoteWhereClause($where_clause);
00851                 $groupBy = $this->quoteGroupBy($groupBy);
00852                 $orderBy = $this->quoteOrderBy($orderBy);
00853 
00854                 // call parent method to build actual query
00855                 $query = parent::SELECTquery($select_fields,$from_table,$where_clause,$groupBy,$orderBy,$limit);
00856 
00857                 if ($this->debugOutput || $this->store_lastBuiltQuery) $this->debug_lastBuiltQuery = $query;
00858 
00859                 return $query;
00860         }
00861 
00862 
00863         /**************************************
00864         *
00865         * Functions for quoting table/field names
00866         *
00867         **************************************/
00868 
00877         function quoteSelectFields($select_fields) {
00878                 $this->quoteFieldNames($select_fields);
00879         }
00880 
00887         function quoteFieldNames($select_fields) {
00888                 if($select_fields == '') return '';
00889                 if($this->runningNative()) return $select_fields;
00890 
00891                 $select_fields = $this->SQLparser->parseFieldList($select_fields);
00892                 foreach($select_fields as $k => $v)     {
00893                         if($select_fields[$k]['field'] != '' && $select_fields[$k]['field'] != '*') {
00894                                 $select_fields[$k]['field'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$select_fields[$k]['field'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
00895                         }
00896                         if($select_fields[$k]['table'] != '') {
00897                                 $select_fields[$k]['table'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$select_fields[$k]['table'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
00898                         }
00899                         if($select_fields[$k]['as'] != '') {
00900                                 $select_fields[$k]['as'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$select_fields[$k]['as'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
00901                         }
00902                         if(isset($select_fields[$k]['func_content.']) && $select_fields[$k]['func_content.'][0]['func_content'] != '*'){
00903                                 if(strstr($select_fields[$k]['func_content.'][0]['func_content'],'.')) {
00904                                         $select_fields[$k]['func_content.'][0]['func_content'] = $this->quoteFieldNames($select_fields[$k]['func_content.'][0]['func_content']);
00905                                         $select_fields[$k]['func_content'] = $this->quoteFieldNames($select_fields[$k]['func_content']);
00906                                 }
00907                                 else {
00908                                         $select_fields[$k]['func_content.'][0]['func_content'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$select_fields[$k]['func_content.'][0]['func_content'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
00909                                         $select_fields[$k]['func_content'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$select_fields[$k]['func_content'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
00910                                 }
00911                         }
00912                 }
00913 
00914                 return $this->SQLparser->compileFieldList($select_fields);
00915         }
00916 
00923         function quoteFromTables($from_table) {
00924                 if($from_table == '') return '';
00925                 if($this->runningNative()) return $from_table;
00926 
00927                 $from_table = $this->SQLparser->parseFromTables($from_table);
00928                 foreach($from_table as $k => $v)        {
00929                         $from_table[$k]['table'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$from_table[$k]['table'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
00930                         if($from_table[$k]['as'] != '') {
00931                                 $from_table[$k]['as'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$from_table[$k]['as'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
00932                         }
00933                         if (is_array($v['JOIN']))       {
00934                                 $from_table[$k]['JOIN']['withTable'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$from_table[$k]['JOIN']['withTable'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
00935                                 $from_table[$k]['JOIN']['ON'][0]['table'] = ($from_table[$k]['JOIN']['ON'][0]['table']) ? $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$from_table[$k]['JOIN']['ON'][0]['table'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote : '';
00936                                 $from_table[$k]['JOIN']['ON'][0]['field'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$from_table[$k]['JOIN']['ON'][0]['field'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
00937                                 $from_table[$k]['JOIN']['ON'][1]['table'] = ($from_table[$k]['JOIN']['ON'][1]['table']) ? $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$from_table[$k]['JOIN']['ON'][1]['table'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote : '';
00938                                 $from_table[$k]['JOIN']['ON'][1]['field'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$from_table[$k]['JOIN']['ON'][1]['field'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
00939                         }
00940                 }
00941                 return $this->SQLparser->compileFromTables($from_table);
00942         }
00943 
00950         function quoteWhereClause($where_clause) {
00951                 if($where_clause == '') return '';
00952                 if($this->runningNative()) return $where_clause;
00953 
00954                 $where_clause = $this->SQLparser->parseWhereClause($where_clause);
00955                 $where_clause = $this->_quoteWhereClause($where_clause);
00956                 $where_clause = $this->SQLparser->compileWhereClause($where_clause);
00957 
00958                 return $where_clause;
00959         }
00960 
00967         function _quoteWhereClause($where_clause) {
00968                 foreach($where_clause as $k => $v)      {
00969                         // Look for sublevel:
00970                         if (is_array($where_clause[$k]['sub'])) {
00971                                 $where_clause[$k]['sub'] = $this->_quoteWhereClause($where_clause[$k]['sub']);
00972                         } else {
00973                                 if($where_clause[$k]['table'] != '') {
00974                                         $where_clause[$k]['table'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$where_clause[$k]['table'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
00975                                 }
00976                                 if(!is_numeric($where_clause[$k]['field'])) {
00977                                         $where_clause[$k]['field'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$where_clause[$k]['field'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
00978                                 }
00979                         }
00980                         if ($where_clause[$k]['comparator'])    {
00981                                 // Detecting value type; list or plain:
00982                                 if ((!isset($where_clause[$k]['value'][1]) || $where_clause[$k]['value'][1] == '') && is_string($where_clause[$k]['value'][0]) && strstr($where_clause[$k]['value'][0], '.') && !t3lib_div::inList('NOTIN,IN',strtoupper(str_replace(array(" ","\n","\r","\t"),'',$where_clause[$k]['comparator']))))   {
00983                                         $where_clause[$k]['value'][0] = $this->quoteFieldNames($where_clause[$k]['value'][0]);
00984                                 }
00985                         }
00986                 }
00987 
00988                 return $where_clause;
00989         }
00990 
00997         function quoteGroupBy($groupBy) {
00998                 if($groupBy == '') return '';
00999                 if($this->runningNative()) return $groupBy;
01000 
01001                 $groupBy = $this->SQLparser->parseFieldList($groupBy);
01002                 foreach($groupBy as $k => $v)   {
01003                         $groupBy[$k]['field'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$groupBy[$k]['field'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
01004                         if($groupBy[$k]['table'] != '') {
01005                                 $groupBy[$k]['table'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$groupBy[$k]['table'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
01006                         }
01007                 }
01008                 return $this->SQLparser->compileFieldList($groupBy);
01009         }
01010 
01017         function quoteOrderBy($orderBy) {
01018                 if($orderBy == '') return '';
01019                 if($this->runningNative()) return $orderBy;
01020 
01021                 $orderBy = $this->SQLparser->parseFieldList($orderBy);
01022                 foreach($orderBy as $k => $v)   {
01023                         $orderBy[$k]['field'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$orderBy[$k]['field'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
01024                         if($orderBy[$k]['table'] != '') {
01025                                 $orderBy[$k]['table'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$orderBy[$k]['table'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
01026                         }
01027                 }
01028                 return $this->SQLparser->compileFieldList($orderBy);
01029         }
01030 
01031 
01032 
01033         /**************************************
01034         *
01035         * Various helper functions
01036         *
01037         **************************************/
01038 
01047         function fullQuoteStr($str,$table) {
01048                 return '\''.$this->quoteStr($str, $table).'\'';
01049         }
01050 
01060         function quoteStr($str, $table) {
01061                 $this->lastHandlerKey = $this->handler_getFromTableList($table);
01062                 switch((string)$this->handlerCfg[$this->lastHandlerKey]['type'])        {
01063                         case 'native':
01064                                 $str = mysql_real_escape_string($str, $this->handlerInstance[$this->lastHandlerKey]['link']);
01065                                 break;
01066                         case 'adodb':
01067                                 $str = substr($this->handlerInstance[$this->lastHandlerKey]->qstr($str),1,-1);
01068                                 break;
01069                         case 'userdefined':
01070                                 $str = $this->handlerInstance[$this->lastHandlerKey]->quoteStr($str);
01071                                 break;
01072                         default:
01073                                 die('No handler found!!!');
01074                                 break;
01075                 }
01076 
01077                 return $str;
01078         }
01079 
01080 
01088         function MetaType($type,$table,$max_length=-1)  {
01089                 $this->lastHandlerKey = $this->handler_getFromTableList($table);
01090                 switch((string)$this->handlerCfg[$this->lastHandlerKey]['type'])        {
01091                         case 'native':
01092                                 $str = $type;
01093                                 break;
01094                         case 'adodb':
01095                                 $rs = $this->handlerInstance[$this->lastHandlerKey]->SelectLimit('SELECT * FROM '.$this->quoteFromTables($table),1);
01096                                 $str = $rs->MetaType($type, $max_length);
01097                                 break;
01098                         case 'userdefined':
01099                                 $str = $this->handlerInstance[$this->lastHandlerKey]->MetaType($str,$table,$max_length);
01100                                 break;
01101                         default:
01102                                 die('No handler found!!!');
01103                                 break;
01104                 }
01105 
01106                 return $str;
01107         }
01108 
01109 
01116         function MySQLMetaType($t) {
01117 
01118                 switch (strtoupper($t)) {
01119                         case 'STRING':
01120                         case 'CHAR':
01121                         case 'VARCHAR':
01122                         case 'TINYBLOB':
01123                         case 'TINYTEXT':
01124                         case 'ENUM':
01125                         case 'SET': return 'C';
01126 
01127                         case 'TEXT':
01128                         case 'LONGTEXT':
01129                         case 'MEDIUMTEXT': return 'X';
01130 
01131                         case 'IMAGE':
01132                         case 'LONGBLOB':
01133                         case 'BLOB':
01134                         case 'MEDIUMBLOB': return 'B';
01135 
01136                         case 'YEAR':
01137                         case 'DATE': return 'D';
01138 
01139                         case 'TIME':
01140                         case 'DATETIME':
01141                         case 'TIMESTAMP': return 'T';
01142 
01143                         case 'FLOAT':
01144                         case 'DOUBLE': return 'F';
01145 
01146                         case 'INT':
01147                         case 'INTEGER':
01148                         case 'TINYINT':
01149                         case 'SMALLINT':
01150                         case 'MEDIUMINT':
01151                         case 'BIGINT': return 'I8'; // we always return I8 to be on the safe side. Under some circumstances the fields are to small otherwise...
01152 
01153                         default: return 'N';
01154                 }
01155         }
01156 
01163         function MySQLActualType($meta) {
01164                 switch(strtoupper($meta)) {
01165                         case 'C': return 'VARCHAR';
01166                         case 'XL':
01167                         case 'X': return 'LONGTEXT';
01168 
01169                         case 'C2': return 'VARCHAR';
01170                         case 'X2': return 'LONGTEXT';
01171 
01172                         case 'B': return 'LONGBLOB';
01173 
01174                         case 'D': return 'DATE';
01175                         case 'T': return 'DATETIME';
01176                         case 'L': return 'TINYINT';
01177 
01178                         case 'I':
01179                         case 'I1':
01180                         case 'I2':
01181                         case 'I4':
01182                         case 'I8': return 'BIGINT'; // we only have I8 in DBAL, see MySQLMetaType()
01183 
01184                         case 'F': return 'DOUBLE';
01185                         case 'N': return 'NUMERIC';
01186 
01187                         default: return $meta;
01188                 }
01189         }
01190 
01191 
01192 
01193 
01194         /**************************************
01195         *
01196         * SQL wrapper functions (Overriding parent methods)
01197         * (For use in your applications)
01198         *
01199         **************************************/
01200 
01206         function sql_error()    {
01207 
01208                 switch($this->handlerCfg[$this->lastHandlerKey]['type'])        {
01209                         case 'native':
01210                                 $output = mysql_error($this->handlerInstance[$this->lastHandlerKey]['link']);
01211                                 break;
01212                         case 'adodb':
01213                                 $output = $this->handlerInstance[$this->lastHandlerKey]->ErrorMsg();
01214                                 break;
01215                         case 'userdefined':
01216                                 $output = $this->handlerInstance[$this->lastHandlerKey]->sql_error();
01217                                 break;
01218                 }
01219                 return $output;
01220         }
01221 
01228         function sql_num_rows(&$res)    {
01229                 if($res === false) return 0;
01230 
01231                 $handlerType = is_object($res) ? $res->TYPO3_DBAL_handlerType : 'native';
01232                 switch($handlerType)    {
01233                         case 'native':
01234                                 $output = mysql_num_rows($res);
01235                                 break;
01236                         case 'adodb':
01237                                 $output = method_exists($res, 'RecordCount') ? $res->RecordCount() : 0;
01238                                 break;
01239                         case 'userdefined':
01240                                 $output = $res->sql_num_rows();
01241                                 break;
01242                 }
01243                 return $output;
01244         }
01245 
01252         function sql_fetch_assoc(&$res) {
01253                 $output = array();
01254 
01255                 $handlerType = is_object($res) ? $res->TYPO3_DBAL_handlerType : (is_resource($res) ? 'native' : false);
01256                 switch($handlerType)    {
01257                         case 'native':
01258                                 $output = mysql_fetch_assoc($res);
01259                                 $tableList = $this->resourceIdToTableNameMap[(string)$res];     // Reading list of tables from SELECT query:
01260                                 break;
01261                         case 'adodb':
01262                                         // Check if method exists for the current $res object.
01263                                         // If a table exists in TCA but not in the db, a error
01264                                         // occured because $res is not a valid object.
01265                                 if(method_exists($res, 'FetchRow')) {
01266                                         $output = $res->FetchRow();
01267                                         $tableList = $res->TYPO3_DBAL_tableList;        // Reading list of tables from SELECT query:
01268 
01269                                                 // Removing all numeric/integer keys.
01270                                                 // A workaround because in ADOdb we would need to know what we want before executing the query...
01271                                         if (is_array($output))  {
01272                                                 foreach($output as $key => $value)      {
01273                                                         if (is_integer($key))   unset($output[$key]);
01274                                                         elseif($value===' ' && $this->runningADOdbDriver('mssql')) $output[$key]=''; // MSSQL does not know such thing as an empty string. So it returns one space instead, which we must fix.
01275                                                 }
01276                                         }
01277                                 }
01278                                 break;
01279                         case 'userdefined':
01280                                 $output = $res->sql_fetch_assoc();
01281                                 $tableList = $res->TYPO3_DBAL_tableList;        // Reading list of tables from SELECT query:
01282                                 break;
01283                 }
01284 
01285                 // Table/Fieldname mapping:
01286                 if (is_array($output))  {
01287                         if ($tables = $this->map_needMapping($tableList,TRUE))  {
01288                                 $output = $this->map_assocArray($output,$tables,1);
01289                         }
01290                 }
01291 
01292                 // Return result:
01293                 return $output;
01294         }
01295 
01303         function sql_fetch_row(&$res)   {
01304                 $handlerType = is_object($res) ? $res->TYPO3_DBAL_handlerType :  'native';
01305                 switch($handlerType)    {
01306                         case 'native':
01307                                 $output = mysql_fetch_row($res);
01308                                 break;
01309                         case 'adodb':
01310                                         // Check if method exists for the current $res object.
01311                                         // If a table exists in TCA but not in the db, a error
01312                                         // occured because $res is not a valid object.
01313                                 if(method_exists($res, 'FetchRow')) {
01314                                         $output = $res->FetchRow();
01315 
01316                                                 // Removing all assoc. keys.
01317                                                 // A workaround because in ADOdb we would need to know what we want before executing the query...
01318                                         if (is_array($output))  {
01319                                                 foreach($output as $key => $value)      {
01320                                                         if (!is_integer($key))  unset($output[$key]);
01321                                                         elseif($value===' ' && $this->runningADOdbDriver('mssql')) $output[$key]=''; // MSSQL does not know such thing as an empty string. So it returns one space instead, which we must fix.
01322                                                 }
01323                                         }
01324                                 }
01325                                 break;
01326                         case 'userdefined':
01327                                 $output = $res->sql_fetch_row();
01328                                 break;
01329                 }
01330                 return $output;
01331         }
01332 
01339         function sql_free_result(&$res) {
01340                 if($res===false) return false;
01341 
01342                 $handlerType = is_object($res) ? $res->TYPO3_DBAL_handlerType :  'native';
01343                 switch($handlerType)    {
01344                         case 'native':
01345                                 $output = mysql_free_result($res);
01346                                 break;
01347                         case 'adodb':
01348                                 if(method_exists($res, 'Close')) {
01349                                         $res->Close();
01350                                         unset($res);
01351                                         $output = true;
01352                                 } else {
01353                                         $output = false;
01354                                 }
01355                                 break;
01356                         case 'userdefined':
01357                                 unset($res);
01358                                 break;
01359                 }
01360                 return $output;
01361         }
01362 
01368         function sql_insert_id()        {
01369 
01370                 switch($this->handlerCfg[$this->lastHandlerKey]['type'])        {
01371                         case 'native':
01372                                 $output = mysql_insert_id($this->handlerInstance[$this->lastHandlerKey]['link']);
01373