Documentation TYPO3 par Ameos

class.ux_t3lib_db.php

00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 2004 Kasper Skaarhoj (kasper@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 //require_once(t3lib_extMgm::extPath('install').'mod/class.tx_install.php');
00118 
00127 class ux_t3lib_DB extends t3lib_DB {
00128 
00129         // Internal, static:
00130         var $printErrors = FALSE;                       // Enable output of SQL errors after query executions. Set through TYPO3_CONF_VARS, see init()
00131         var $debug = FALSE;                                     // Enable debug mode. Set through TYPO3_CONF_VARS, see init()
00132         var $conf = array();                            // Configuration array, copied from TYPO3_CONF_VARS in constructor.
00133 
00134         var $mapping = array();                         // See manual.
00135         var $table2handlerKeys = array();       // See manual.
00136         var $handlerCfg = array (                       // See manual.
00137         '_DEFAULT' => array (
00138         'type' => 'native',
00139         'config' => array(
00140         'username' => '',               // Set by default (overridden)
00141         'password' => '',               // Set by default (overridden)
00142         'host' => '',                   // Set by default (overridden)
00143         'database' => '',               // Set by default (overridden)
00144         'driver' => '',                 // ONLY "adodb" type; eg. "mysql"
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 
00167 
00168 
00175         function ux_t3lib_DB()  {
00176 
00177                 // Set SQL parser object for internal use:
00178                 $this->SQLparser = t3lib_div::makeInstance('t3lib_sqlengine');
00179                 $this->Installer = t3lib_div::makeInstance('t3lib_install');
00180 
00181                 // Set internal variables with configuration:
00182                 $this->conf = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['dbal'];
00183                 $this->initInternalVariables();
00184         }
00185 
00191         function initInternalVariables()        {
00192 
00193                 // Set outside configuration:
00194                 if (isset($this->conf['mapping']))                              $this->mapping = $this->conf['mapping'];
00195                 if (isset($this->conf['table2handlerKeys']))    $this->table2handlerKeys = $this->conf['table2handlerKeys'];
00196                 if (isset($this->conf['handlerCfg']))                   $this->handlerCfg = $this->conf['handlerCfg'];
00197 
00198                 $this->cacheFieldInfo();
00199                 // Debugging settings:
00200                 $this->printErrors = $this->conf['debugOptions']['printErrors'] ? TRUE : FALSE;
00201                 $this->debug = $this->conf['debugOptions']['enabled'] ? TRUE : FALSE;
00202         }
00203 
00204         function clearCachedFieldInfo() {
00205                 if(file_exists(PATH_typo3conf.'temp_fieldInfo.php'))
00206                 unlink(PATH_typo3conf.'temp_fieldInfo.php');
00207         }
00208 
00209         function cacheFieldInfo() {
00210                 global $TYPO3_LOADED_EXT;
00211                 $extSQL = '';
00212                 $parsedExtSQL = array();
00213 
00214                 // try to fetch cached file first
00215                 // file is removed when admin_query() is called
00216                 if(file_exists(PATH_typo3conf.'temp_fieldInfo.php')) {
00217                         $fdata = unserialize(t3lib_div::getUrl(PATH_typo3conf.'temp_fieldInfo.php'));
00218                         $this->cache_autoIncFields = $fdata['incFields'];
00219                         $this->cache_fieldType = $fdata['fieldTypes'];
00220                         $this->cache_primaryKeys = $fdata['primaryKeys'];
00221                 }
00222                 else {
00223                                 // handle stddb.sql, parse and analyze
00224                         $extSQL = t3lib_div::getUrl(PATH_site.'t3lib/stddb/tables.sql');
00225                         $parsedExtSQL = $this->Installer->getFieldDefinitions_sqlContent($extSQL);
00226                         $this->analyzeFields($parsedExtSQL);
00227 
00228                                 // loop over all installed extensions
00229                         foreach($TYPO3_LOADED_EXT as $ext => $v)        {
00230                                 if(!is_array($v) || !isset($v['ext_tables.sql']))
00231                                 continue;
00232 
00233                                         // fetch db dump (if any) and parse it, then analyze
00234                                 $extSQL = t3lib_div::getUrl($v['ext_tables.sql']);
00235                                 $parsedExtSQL = $this->Installer->getFieldDefinitions_sqlContent($extSQL);
00236                                 $this->analyzeFields($parsedExtSQL);
00237                         }
00238 
00239                         $cachedFieldInfo = array('incFields' => $this->cache_autoIncFields, 'fieldTypes' => $this->cache_fieldType, 'primaryKeys' => $this->cache_primaryKeys);
00240                         $cachedFieldInfo = serialize($this->mapCachedFieldInfo($cachedFieldInfo));
00241 
00242                                 // write serialized content to file
00243                         t3lib_div::writeFile(PATH_typo3conf."temp_fieldInfo.php", $cachedFieldInfo);
00244 
00245                         if (strcmp(t3lib_div::getUrl(PATH_typo3conf."temp_fieldInfo.php"), $cachedFieldInfo))   {
00246                                 die('typo3temp/temp_incfields.php was NOT updated properly (written content didn\'t match file content) - maybe write access problem?');
00247                         }
00248                 }
00249         }
00250 
00258         function analyzeFields($parsedExtSQL) {
00259                 foreach($parsedExtSQL as $table => $tdef) {
00260                         foreach($tdef['fields'] as $field => $fdef) {
00261                                 $fdef = $this->SQLparser->parseFieldDef($fdef);
00262                                 $this->cache_fieldType[$table][$field]['type'] = $fdef['fieldType'];
00263                                 $this->cache_fieldType[$table][$field]['metaType'] = $this->MySQLMetaType($fdef['fieldType']);
00264                                 $this->cache_fieldType[$table][$field]['notnull'] = (isset($fdef['featureIndex']['NOTNULL']) && !$this->SQLparser->checkEmptyDefaultValue($fdef['featureIndex'])) ? 1 : 0;
00265                                 if(isset($fdef['featureIndex']['AUTO_INCREMENT'])) {
00266                                         $this->cache_autoIncFields[$table] = $field;
00267                                 }
00268                                 if(isset($tdef['keys']['PRIMARY'])) {
00269                                         $this->cache_primaryKeys[$table] = substr($tdef['keys']['PRIMARY'], 13, -1);
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]);
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                                         $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->_query($this->lastQuery[0],false);
00392                                         foreach($this->lastQuery[1] as $field => $content) {
00393                                                 if(empty($content)) continue;
00394 
00395                                                 if(isset($this->cache_autoIncFields[$table]) && isset($new_id)) {
00396                                                         $this->handlerInstance[$this->lastHandlerKey]->UpdateBlob($this->quoteFromTables($table),$field,$content,$this->quoteWhereClause($this->cache_autoIncFields[$table].'='.$new_id));
00397                                                 } elseif(isset($this->cache_primaryKeys[$table])) {
00398                                                         $pks = explode(',', $this->cache_primaryKeys[$table]);
00399                                                         foreach ($pks as $pk) {
00400                                                                 if(isset($fields_values[$pk]))
00401                                                                 $where .= $pk.'='.$this->fullQuoteStr($fields_values[$pk], $table).' AND ';
00402                                                         }
00403                                                         $where = $this->quoteWhereClause($where.'1=1');
00404                                                         $this->handlerInstance[$this->lastHandlerKey]->UpdateBlob($this->quoteFromTables($table),$field,$content,$where);
00405                                                 } else {
00406                                                         $this->handlerInstance[$this->lastHandlerKey]->CompleteTrans(false);
00407                                                         die('Could not update BLOB >>>> no WHERE clause found!'); // should never ever happen
00408                                                 }
00409                                         }
00410                                         $this->handlerInstance[$this->lastHandlerKey]->CompleteTrans();
00411                                 }
00412                                 break;
00413                         case 'userdefined':
00414                                 $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->exec_INSERTquery($table,$fields_values,$no_quote_fields);
00415                                 break;
00416                 }
00417 
00418                 if ($this->printErrors && $this->sql_error())   {
00419                         debug(array($this->lastQuery, $this->sql_error()));
00420                 }
00421 
00422                 if ($this->debug)       {
00423                         $this->debugHandler(
00424                         'exec_INSERTquery',
00425                         t3lib_div::milliseconds()-$pt,
00426                         array(
00427                         'handlerType' => $hType,
00428                         'args' => array($table,$fields_values),
00429                         'ORIG_tablename' => $ORIG_tableName
00430                         )
00431                         );
00432                 }
00433                 // Return output:
00434                 return $sqlResult;
00435         }
00436 
00446         function exec_UPDATEquery($table,$where,$fields_values,$no_quote_fields='')     {
00447 
00448                 if ($this->debug)       $pt = t3lib_div::milliseconds();
00449 
00450                 // Do table/field mapping:
00451                 $ORIG_tableName = $table;
00452                 if ($tableArray = $this->map_needMapping($table))       {
00453 
00454                         // Field mapping of array:
00455                         $fields_values = $this->map_assocArray($fields_values,$tableArray);
00456 
00457                         // Where clause table and field mapping:
00458                         $whereParts = $this->SQLparser->parseWhereClause($where);
00459                         $this->map_sqlParts($whereParts,$tableArray[0]['table']);
00460                         $where = $this->SQLparser->compileWhereClause($whereParts);
00461 
00462                         // Table name:
00463                         if ($this->mapping[$table]['mapTableName'])     {
00464                                 $table = $this->mapping[$table]['mapTableName'];
00465                         }
00466                 }
00467 
00468                 // Select API
00469                 $this->lastHandlerKey = $this->handler_getFromTableList($ORIG_tableName);
00470                 switch((string)$this->handlerCfg[$this->lastHandlerKey]['type'])        {
00471                         case 'native':
00472                                 $this->lastQuery = $this->UPDATEquery($table,$where,$fields_values,$no_quote_fields);
00473                                 if(is_string($this->lastQuery)) {
00474                                         $sqlResult = mysql_query($this->lastQuery, $this->handlerInstance[$this->lastHandlerKey]['link']);
00475                                 }
00476                                 else {
00477                                         $sqlResult = mysql_query($this->lastQuery[0], $this->handlerInstance[$this->lastHandlerKey]['link']);
00478                                         foreach($this->lastQuery[1] as $field => $content) {
00479                                                 mysql_query('UPDATE '.$this->quoteFromTables($table).' SET '.$this->quoteFromTables($field).'='.$this->fullQuoteStr($content,$table).' WHERE '.$this->quoteWhereClause($where), $this->handlerInstance[$this->lastHandlerKey]['link']);
00480                                         }
00481                                 }
00482                         break;
00483                         case 'adodb':
00484                                 $this->lastQuery = $this->UPDATEquery($table,$where,$fields_values,$no_quote_fields);
00485                                 if(is_string($this->lastQuery)) {
00486                                         $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->_query($this->lastQuery,false);
00487                                 } else {
00488                                         $this->handlerInstance[$this->lastHandlerKey]->StartTrans();
00489                                         $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->_query($this->lastQuery[0],false);
00490                                         foreach($this->lastQuery[1] as $field => $content) {
00491                                                 $this->handlerInstance[$this->lastHandlerKey]->UpdateBlob($this->quoteFromTables($table),$field,$content,$this->quoteWhereClause($where));
00492                                         }
00493                                         $this->handlerInstance[$this->lastHandlerKey]->CompleteTrans();
00494                                 }
00495                                 break;
00496                         case 'userdefined':
00497                                 $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->exec_UPDATEquery($table,$where,$fields_values,$no_quote_fields);
00498                                 break;
00499                 }
00500 
00501                 if ($this->printErrors && $this->sql_error())   {
00502                         debug(array($this->lastQuery, $this->sql_error()));
00503                 }
00504 
00505                 if ($this->debug)       {
00506                         $this->debugHandler(
00507                         'exec_UPDATEquery',
00508                         t3lib_div::milliseconds()-$pt,
00509                         array(
00510                         'handlerType' => $hType,
00511                         'args' => array($table,$where, $fields_values),
00512                         'ORIG_from_table' => $ORIG_tableName
00513                         )
00514                         );
00515                 }
00516 
00517                 // Return result:
00518                 return $sqlResult;
00519         }
00520 
00528         function exec_DELETEquery($table,$where)        {
00529 
00530                 if ($this->debug)       $pt = t3lib_div::milliseconds();
00531 
00532                 // Do table/field mapping:
00533                 $ORIG_tableName = $table;
00534                 if ($tableArray = $this->map_needMapping($table))       {
00535 
00536                         // Where clause:
00537                         $whereParts = $this->SQLparser->parseWhereClause($where);
00538                         $this->map_sqlParts($whereParts,$tableArray[0]['table']);
00539                         $where = $this->SQLparser->compileWhereClause($whereParts);
00540 
00541                         // Table name:
00542                         if ($this->mapping[$table]['mapTableName'])     {
00543                                 $table = $this->mapping[$table]['mapTableName'];
00544                         }
00545                 }
00546 
00547                 // Select API
00548                 $this->lastHandlerKey = $this->handler_getFromTableList($ORIG_tableName);
00549                 switch((string)$this->handlerCfg[$this->lastHandlerKey]['type'])        {
00550                         case 'native':
00551                                 $this->lastQuery = $this->DELETEquery($table,$where);
00552                                 $sqlResult = mysql_query($this->lastQuery, $this->handlerInstance[$this->lastHandlerKey]['link']);
00553                                 break;
00554                         case 'adodb':
00555                                 $this->lastQuery = $this->DELETEquery($table,$where);
00556                                 $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->_query($this->lastQuery,false);
00557                                 break;
00558                         case 'userdefined':
00559                                 $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->exec_DELETEquery($table,$where);
00560                                 break;
00561                 }
00562 
00563                 if ($this->printErrors && $this->sql_error())   {
00564                         debug(array($this->lastQuery, $this->sql_error()));
00565                 }
00566 
00567                 if ($this->debug)       {
00568                         $this->debugHandler(
00569                         'exec_DELETEquery',
00570                         t3lib_div::milliseconds()-$pt,
00571                         array(
00572                         'handlerType' => $hType,
00573                         'args' => array($table,$where),
00574                         'ORIG_from_table' => $ORIG_tableName
00575                         )
00576                         );
00577                 }
00578 
00579                 // Return result:
00580                 return $sqlResult;
00581         }
00582 
00594         function exec_SELECTquery($select_fields,$from_table,$where_clause,$groupBy='',$orderBy='',$limit='')   {
00595 
00596                 if ($this->debug)       $pt = t3lib_div::milliseconds();
00597 
00598                 // Map table / field names if needed:
00599                 $ORIG_tableName = $from_table;  // Saving table names in $ORIG_from_table since $from_table is transformed beneath:
00600                 if ($tableArray = $this->map_needMapping($ORIG_tableName))      {
00601                         $this->map_remapSELECTQueryParts($select_fields,$from_table,$where_clause,$groupBy,$orderBy);   // Variables passed by reference!
00602                 }
00603 
00604                 // Get handler key and select API:
00605                 $this->lastHandlerKey = $this->handler_getFromTableList($ORIG_tableName);
00606                 $hType = (string)$this->handlerCfg[$this->lastHandlerKey]['type'];
00607                 switch($hType)  {
00608                         case 'native':
00609                                 $this->lastQuery = $this->SELECTquery($select_fields,$from_table,$where_clause,$groupBy,$orderBy,$limit);
00610                                 $sqlResult = mysql_query($this->lastQuery, $this->handlerInstance[$this->lastHandlerKey]['link']);
00611                                 $this->resourceIdToTableNameMap[(string)$sqlResult] = $ORIG_tableName;
00612                                 break;
00613                         case 'adodb':
00614                                 if ($limit!='') {
00615                                         $splitLimit = t3lib_div::intExplode(',',$limit);                // Splitting the limit values:
00616                                         if ($splitLimit[1])     {       // If there are two parameters, do mapping differently than otherwise:
00617                                                 $numrows = $splitLimit[1];
00618                                                 $offset = $splitLimit[0];
00619                                         } else {
00620                                                 $numrows = $splitLimit[0];
00621                                                 $offset = 0;
00622                                         }
00623 
00624                                         $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->SelectLimit($this->SELECTquery($select_fields,$from_table,$where_clause,$groupBy,$orderBy), $numrows, $offset);
00625                                         $this->lastQuery = $sqlResult->sql;
00626                                 } else {
00627                                         $this->lastQuery = $this->SELECTquery($select_fields,$from_table,$where_clause,$groupBy,$orderBy);
00628                                         $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->_Execute($this->lastQuery);
00629                                 }
00630                                 $sqlResult->TYPO3_DBAL_handlerType = 'adodb';   // Setting handler type in result object (for later recognition!)
00631                                 $sqlResult->TYPO3_DBAL_tableList = $ORIG_tableName;
00632                                 break;
00633                         case 'userdefined':
00634                                 $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->exec_SELECTquery($select_fields,$from_table,$where_clause,$groupBy,$orderBy,$limit);
00635                                 if (is_object($sqlResult))      {
00636                                         $sqlResult->TYPO3_DBAL_handlerType = 'userdefined';     // Setting handler type in result object (for later recognition!)
00637                                         $sqlResult->TYPO3_DBAL_tableList = $ORIG_tableName;
00638                                 }
00639                                 break;
00640                 }
00641 
00642                 if ($this->printErrors && $this->sql_error())   {
00643                         debug(array($this->lastQuery, $this->sql_error()));
00644                 }
00645 
00646                 if ($this->debug)       {
00647                         $this->debugHandler(
00648                         'exec_SELECTquery',
00649                         t3lib_div::milliseconds()-$pt,
00650                         array(
00651                         'handlerType' => $hType,
00652                         'args' => array($from_table,$select_fields,$where_clause,$groupBy,$orderBy,$limit),
00653                         'ORIG_from_table' => $ORIG_tableName
00654                         )
00655                         );
00656                 }
00657 
00658                 // Return result handler.
00659                 return $sqlResult;
00660         }
00661 
00662 
00663 
00664         /**************************************
00665         *
00666         * Query building
00667         *
00668         **************************************/
00669 
00680         function INSERTquery($table,$fields_values,$no_quote_fields='') {
00681                 // Table and fieldnames should be "SQL-injection-safe" when supplied to this function (contrary to values in the arrays which may be insecure).
00682                 if (is_array($fields_values) && count($fields_values))  {
00683 
00684                         if (is_string($no_quote_fields))        {
00685                                 $no_quote_fields = explode(',',$no_quote_fields);
00686                         } elseif (!is_array($no_quote_fields))  {
00687                                 $no_quote_fields = array();
00688                         }
00689 
00690                         $blobfields = array();
00691                         $nArr = array();
00692                         foreach($fields_values as $k => $v)     {
00693                                 if($this->sql_field_metatype($table,$k) == 'B') {
00694                                         /* // is this really needed for Oracle?
00695                                         if($this->handlerInstance[$this->lastHandlerKey]->databaseType == 'oci8')
00696                                         $nArr[$this->quoteFieldNames($k)] = 'empty_blob()';
00697                                         else
00698                                         $nArr[$this->quoteFieldNames($k)] = 'null';
00699                                         */
00700                                         $nArr[$this->quoteFieldNames($k)] = 'null';
00701                                         $blobfields[$this->quoteFieldNames($k)] = $v;
00702                                 }
00703                                 else {
00704                                         // Add slashes old-school:
00705                                         // cast numerical values
00706                                         $mt = $this->sql_field_metatype($table,$k);
00707                                         $v = (($mt{0}=='I')||($mt{0}=='F')) ? (int)$v : $v;
00708 
00709                                         $nArr[$this->quoteFieldNames($k)] = (!in_array($k,$no_quote_fields)) ? $this->fullQuoteStr($v, $table) : $v;
00710                                 }
00711                         }
00712                         if(((string)$this->handlerCfg[$this->lastHandlerKey]['type']!=='native') && count($blobfields)) {
00713                                 $query[0] = 'INSERT INTO '.$this->quoteFromTables($table).'
00714                                 (
00715                                         '.implode(',
00716                                         ',array_keys($nArr)).'
00717                                 ) VALUES (
00718                                         '.implode(',
00719                                         ',$nArr).'
00720                                 )';
00721                                 $query[1] = $blobfields;
00722                                 if ($this->debugOutput) $this->debug_lastBuiltQuery = $query[0];
00723                         }
00724                         else {
00725                                 $query = 'INSERT INTO '.$this->quoteFromTables($table).'
00726                                 (
00727                                         '.implode(',
00728                                         ',array_keys($nArr)).'
00729                                 ) VALUES (
00730                                         '.implode(',
00731                                         ',$nArr).'
00732                                 )';
00733 
00734                                 if ($this->debugOutput) $this->debug_lastBuiltQuery = $query;
00735                         }
00736 
00737                         return $query;
00738                 }
00739         }
00740 
00752         function UPDATEquery($table,$where,$fields_values,$no_quote_fields='')  {
00753                 // Table and fieldnames should be "SQL-injection-safe" when supplied to this function (contrary to values in the arrays which may be insecure).
00754                 if (is_string($where))  {
00755                         if (is_array($fields_values) && count($fields_values))  {
00756 
00757                                 if (is_string($no_quote_fields))        {
00758                                         $no_quote_fields = explode(',',$no_quote_fields);
00759                                 } elseif (!is_array($no_quote_fields))  {
00760                                         $no_quote_fields = array();
00761                                 }
00762 
00763                                 $blobfields = array();
00764                                 $nArr = array();
00765                                 foreach($fields_values as $k => $v)     {
00766                                         if($this->sql_field_metatype($table,$k) == 'B') {
00767                                                 // do we need empty_blob() for Oracle? see also INSERTquery()
00768                                                 $nArr[] = $this->quoteFieldNames($k).'=NULL';
00769                                                 $blobfields[$this->quoteFieldNames($k)] = $v;
00770                                         }
00771                                         else {
00772                                                 // Add slashes old-school:
00773                                                 // cast numeric values
00774                                                 $mt = $this->sql_field_metatype($table,$k);
00775                                                 $v = (($mt{0}=='I')||($mt{0}=='F')) ? (int)$v : $v;
00776                                                 $nArr[] = $this->quoteFieldNames($k).'='.((!in_array($k,$no_quote_fields)) ? $this->fullQuoteStr($v, $table) : $v);
00777                                         }
00778                                 }
00779 
00780                                 if(count($blobfields)) {
00781                                         $query[0] = 'UPDATE '.$this->quoteFromTables($table).'
00782                                         SET
00783                                                 '.implode(',
00784                                                 ',$nArr).
00785                                                 (strlen($where)>0 ? '
00786                                         WHERE
00787                                                 '.$this->quoteWhereClause($where) : '');
00788                                                 $query[1] = $blobfields;
00789                                                 if ($this->debugOutput) $this->debug_lastBuiltQuery = $query[0];
00790                                 }
00791                                 else {
00792                                         $query = 'UPDATE '.$this->quoteFromTables($table).'
00793                                         SET
00794                                                 '.implode(',
00795                                                 ',$nArr).
00796                                                 (strlen($where)>0 ? '
00797                                         WHERE
00798                                                 '.$this->quoteWhereClause($where) : '');
00799 
00800                                                 if ($this->debugOutput) $this->debug_lastBuiltQuery = $query;
00801                                 }
00802 
00803                                 return $query;
00804                         }
00805                 }
00806                 else {
00807                         die('<strong>TYPO3 Fatal Error:</strong> "Where" clause argument for UPDATE query was not a string in $this->UPDATEquery() !');
00808                 }
00809         }
00810 
00820         function DELETEquery($table,$where)     {
00821                 if (is_string($where))  {
00822                         $table = $this->quoteFromTables($table);
00823                         $where = $this->quoteWhereClause($where);
00824 
00825                         $query = parent::DELETEquery($table, $where);
00826 
00827                         if ($this->debugOutput) $this->debug_lastBuiltQuery = $query;
00828                         return $query;
00829                 } else {
00830                         die('<strong>TYPO3 Fatal Error:</strong> "Where" clause argument for DELETE query was not a string in $this->DELETEquery() !');
00831                 }
00832         }
00833 
00847         function SELECTquery($select_fields,$from_table,$where_clause,$groupBy='',$orderBy='',$limit='')        {
00848 
00849                 $select_fields = $this->quoteFieldNames($select_fields);
00850                 $from_table = $this->quoteFromTables($from_table);
00851                 $where_clause = $this->quoteWhereClause($where_clause);
00852                 $groupBy = $this->quoteGroupBy($groupBy);
00853                 $orderBy = $this->quoteOrderBy($orderBy);
00854 
00855                 // call parent method to build actual query
00856                 $query = parent::SELECTquery($select_fields,$from_table,$where_clause,$groupBy,$orderBy,$limit);
00857 
00858                 if ($this->debugOutput) $this->debug_lastBuiltQuery = $query;
00859 
00860                 return $query;
00861         }
00862 
00863 
00864         /**************************************
00865         *
00866         * Functions for quoting table/field names
00867         *
00868         **************************************/
00869 
00878         function quoteSelectFields($select_fields) {
00879                 $this->quoteFieldNames($select_fields);
00880         }
00881 
00888         function quoteFieldNames($select_fields) {
00889                 if($select_fields == '') return '';
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 
00926                 $from_table = $this->SQLparser->parseFromTables($from_table);
00927                 foreach($from_table as $k => $v)        {
00928                         $from_table[$k]['table'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$from_table[$k]['table'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
00929                         if($from_table[$k]['as'] != '') {
00930                                 $from_table[$k]['as'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$from_table[$k]['as'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
00931                         }
00932                         if (is_array($v['JOIN']))       {
00933                                 $from_table[$k]['JOIN']['withTable'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$from_table[$k]['JOIN']['withTable'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
00934                                 $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 : '';
00935                                 $from_table[$k]['JOIN']['ON'][0]['field'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$from_table[$k]['JOIN']['ON'][0]['field'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
00936                                 $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 : '';
00937                                 $from_table[$k]['JOIN']['ON'][1]['field'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$from_table[$k]['JOIN']['ON'][1]['field'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
00938                         }
00939                 }
00940                 return $this->SQLparser->compileFromTables($from_table);
00941         }
00942 
00949         function quoteWhereClause($where_clause) {
00950                 if($where_clause == '') return '';
00951 
00952                 $where_clause = $this->SQLparser->parseWhereClause($where_clause);
00953                 $where_clause = $this->_quoteWhereClause($where_clause);
00954                 $where_clause = $this->SQLparser->compileWhereClause($where_clause);
00955 
00956                 return $where_clause;
00957         }
00958 
00965         function _quoteWhereClause($where_clause) {
00966                 foreach($where_clause as $k => $v)      {
00967                         // Look for sublevel:
00968                         if (is_array($where_clause[$k]['sub'])) {
00969                                 $where_clause[$k]['sub'] = $this->_quoteWhereClause($where_clause[$k]['sub']);
00970                         } else {
00971                                 if($where_clause[$k]['table'] != '') {
00972                                         $where_clause[$k]['table'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$where_clause[$k]['table'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
00973                                 }
00974                                 if(!is_numeric($where_clause[$k]['field'])) {
00975                                         $where_clause[$k]['field'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$where_clause[$k]['field'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
00976                                 }
00977                         }
00978                         if ($where_clause[$k]['comparator'])    {
00979                                 // Detecting value type; list or plain:
00980                                 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']))))   {
00981                                         $where_clause[$k]['value'][0] = $this->quoteFieldNames($where_clause[$k]['value'][0]);
00982                                 }
00983                         }
00984                 }
00985 
00986                 return $where_clause;
00987         }
00988 
00995         function quoteGroupBy($groupBy) {
00996                 if($groupBy == '') return '';
00997 
00998                 $groupBy = $this->SQLparser->parseFieldList($groupBy);
00999                 foreach($groupBy as $k => $v)   {
01000                         $groupBy[$k]['field'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$groupBy[$k]['field'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
01001                         if($groupBy[$k]['table'] != '') {
01002                                 $groupBy[$k]['table'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$groupBy[$k]['table'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
01003                         }
01004                 }
01005                 return $this->SQLparser->compileFieldList($groupBy);
01006         }
01007 
01014         function quoteOrderBy($orderBy) {
01015                 if($orderBy == '') return '';
01016 
01017                 $orderBy = $this->SQLparser->parseFieldList($orderBy);
01018                 foreach($orderBy as $k => $v)   {
01019                         $orderBy[$k]['field'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$orderBy[$k]['field'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
01020                         if($orderBy[$k]['table'] != '') {
01021                                 $orderBy[$k]['table'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$orderBy[$k]['table'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
01022                         }
01023                 }
01024                 return $this->SQLparser->compileFieldList($orderBy);
01025         }
01026 
01027 
01028 
01029         /**************************************
01030         *
01031         * Various helper functions
01032         *
01033         **************************************/
01034 
01043         function fullQuoteStr($str,$table) {
01044                 return '\''.$this->quoteStr($str, $table).'\'';
01045         }
01046 
01056         function quoteStr($str, $table) {
01057                 $this->lastHandlerKey = $this->handler_getFromTableList($table);
01058                 switch((string)$this->handlerCfg[$this->lastHandlerKey]['type'])        {
01059                         case 'native':
01060                                 $str = mysql_real_escape_string($str, $this->handlerInstance[$this->lastHandlerKey]['link']);
01061                                 break;
01062                         case 'adodb':
01063                                 $str = substr($this->handlerInstance[$this->lastHandlerKey]->qstr($str),1,-1);
01064                                 break;
01065                         case 'userdefined':
01066                                 $str = $this->handlerInstance[$this->lastHandlerKey]->quoteStr($str);
01067                                 break;
01068                         default:
01069                                 die('No handler found!!!');
01070                                 break;
01071                 }
01072 
01073                 return $str;
01074         }
01075 
01076 
01084         function MetaType($type,$table,$max_length=-1)  {
01085                 $this->lastHandlerKey = $this->handler_getFromTableList($table);
01086                 switch((string)$this->handlerCfg[$this->lastHandlerKey]['type'])        {
01087                         case 'adodb':
01088                         $rs = $this->handlerInstance[$this->lastHandlerKey]->SelectLimit('SELECT * FROM '.$this->quoteFromTables($table),1);
01089                         $str = $rs->MetaType($type, $max_length);
01090                         break;
01091                         default:
01092                         die('No handler found!!!');
01093                         break;
01094                 }
01095 
01096                 return $str;
01097         }
01098 
01099 
01106         function MySQLMetaType($t) {
01107 
01108                 switch (strtoupper($t)) {
01109                         case 'STRING':
01110                         case 'CHAR':
01111                         case 'VARCHAR':
01112                         case 'TINYBLOB':
01113                         case 'TINYTEXT':
01114                         case 'ENUM':
01115                         case 'SET':
01116                         return 'C';
01117 
01118                         case 'TEXT':
01119                         case 'LONGTEXT':
01120                         case 'MEDIUMTEXT':
01121                         return 'X';
01122 
01123                         // php_mysql extension always returns 'blob' even if 'text'
01124                         // so we have to check whether binary...
01125                         case 'IMAGE':
01126                         case 'LONGBLOB':
01127                         case 'BLOB':
01128                         case 'MEDIUMBLOB':
01129                         return 'B';
01130 
01131                         case 'YEAR':
01132                         case 'DATE': return 'D';
01133 
01134                         case 'TIME':
01135                         case 'DATETIME':
01136                         case 'TIMESTAMP': return 'T';
01137 
01138                         case 'FLOAT':
01139                         case 'DOUBLE':
01140                         return 'F';
01141 
01142                         case 'INT':
01143                         case 'INTEGER': return 'I';
01144                         case 'TINYINT': // MS SQL Server allows only 0..255 for tinyint, so we do not map to I1
01145                         case 'SMALLINT': return 'I2';
01146                         case 'MEDIUMINT': return 'I4';
01147                         case 'BIGINT': return 'I8';
01148 
01149                         default: return 'N';
01150                 }
01151         }
01152 
01159         function MySQLActualType($meta) {
01160                 switch(strtoupper($meta)) {
01161                         case 'C': return 'VARCHAR';
01162                         case 'XL':
01163                         case 'X': return 'LONGTEXT';
01164 
01165                         case 'C2': return 'VARCHAR';
01166                         case 'X2': return 'LONGTEXT';
01167 
01168                         case 'B': return 'LONGBLOB';
01169 
01170                         case 'D': return 'DATE';
01171                         case 'T': return 'DATETIME';
01172                         case 'L': return 'TINYINT';
01173 
01174                         case 'I': return 'INT';
01175                         case 'I1': // MS SQL Server allows only 0..255 for tinyint, so we do not map to TINYINT
01176                         case 'I2': return 'SMALLINT';
01177                         case 'I4': return 'MEDIUMINT';
01178                         case 'I8': return 'BIGINT';
01179 
01180                         case 'F': return 'DOUBLE';
01181                         case 'N': return 'NUMERIC';
01182                         default:
01183                         return $meta;
01184                 }
01185         }
01186 
01187 
01188 
01189 
01190         /**************************************
01191         *
01192         * SQL wrapper functions (Overriding parent methods)
01193         * (For use in your applications)
01194         *
01195         **************************************/
01196 
01202         function sql_error()    {
01203 
01204                 switch($this->handlerCfg[$this->lastHandlerKey]['type'])        {
01205                         case 'native':
01206                                 $output = mysql_error($this->handlerInstance[$this->lastHandlerKey]['link']);
01207                                 break;
01208                         case 'adodb':
01209                                 $output = $this->handlerInstance[$this->lastHandlerKey]->ErrorMsg();
01210                                 break;
01211                         case 'userdefined':
01212                                 $output = $this->handlerInstance[$this->lastHandlerKey]->sql_error();
01213                                 break;
01214                 }
01215                 return $output;
01216         }
01217 
01224         function sql_num_rows(&$res)    {
01225 
01226                 $handlerType = is_object($res) ? $res->TYPO3_DBAL_handlerType : 'native';
01227                 switch($handlerType)    {
01228                         case 'native':
01229                                 $output = mysql_num_rows($res);
01230                                 break;
01231                         case 'adodb':
01232                                 $output = method_exists($res, 'RecordCount') ? $res->RecordCount() : 0;
01233                                 break;
01234                         case 'userdefined':
01235                                 $output = $res->sql_num_rows();
01236                                 break;
01237                 }
01238                 return $output;
01239         }
01240 
01247         function sql_fetch_assoc(&$res) {
01248                 $output = array();
01249 
01250                 $handlerType = is_object($res) ? $res->TYPO3_DBAL_handlerType : (is_resource($res) ? 'native' : false);
01251                 switch($handlerType)    {
01252                         case 'native':
01253                                 $output = mysql_fetch_assoc($res);
01254                                 $tableList = $this->resourceIdToTableNameMap[(string)$res];     // Reading list of tables from SELECT query:
01255                                 break;
01256                         case 'adodb':
01257                                         // Check if method exists for the current $res object.
01258                                         // If a table exists in TCA but not in the db, a error
01259                                         // occured because $res is not a valid object.
01260                                 if(method_exists($res, 'FetchRow')) {
01261                                         $output = $res->FetchRow();
01262                                         $tableList = $res->TYPO3_DBAL_tableList;        // Reading list of tables from SELECT query:
01263 
01264                                                 // Removing all numeric/integer keys.
01265                                                 // A workaround because in ADOdb we would need to know what we want before executing the query...
01266                                         if (is_array($output))  {
01267                                                 foreach($output as $key => $value)      {
01268                                                         if (is_integer($key))   unset($output[$key]);
01269                                                         elseif($value===' ' && strstr($GLOBALS['TYPO3_DB']->handlerCfg[$GLOBALS['TYPO3_DB']->lastHandlerKey]['config']['driver'],'mssql')) $output[$key]=''; // MSSQL does not know such thing as an empty string. So it returns one space instead, which we must fix.
01270                                                 }
01271                                         }
01272                                 }
01273                                 break;
01274                         case 'userdefined':
01275                                 $output = $res->sql_fetch_assoc();
01276                                 $tableList = $res->TYPO3_DBAL_tableList;        // Reading list of tables from SELECT query:
01277                                 break;
01278                 }
01279 
01280                 // Table/Fieldname mapping:
01281                 if (is_array($output))  {
01282                         if ($tables = $this->map_needMapping($tableList,TRUE))  {
01283                                 $output = $this->map_assocArray($output,$tables,1);
01284                         }
01285                 }
01286 
01287                 // Return result:
01288                 return $output;
01289         }
01290 
01298         function sql_fetch_row(&$res)   {
01299                 $handlerType = is_object($res) ? $res->TYPO3_DBAL_handlerType :  'native';
01300                 switch($handlerType)    {
01301                         case 'native':
01302                                 $output = mysql_fetch_row($res);
01303                                 break;
01304                         case 'adodb':
01305                                         // Check if method exists for the current $res object.
01306                                         // If a table exists in TCA but not in the db, a error
01307                                         // occured because $res is not a valid object.
01308                                 if(method_exists($res, 'FetchRow')) {
01309                                         $output = $res->FetchRow();
01310 
01311                                                 // Removing all assoc. keys.
01312                                                 // A workaround because in ADOdb we would need to know what we want before executing the query...
01313                                         if (is_array($output))  {
01314                                                 foreach($output as $key => $value)      {
01315                                                         if (!is_integer($key))  unset($output[$key]);
01316                                                         elseif($value===' ' && strstr($GLOBALS['TYPO3_DB']->handlerCfg[$GLOBALS['TYPO3_DB']->lastHandlerKey]['config']['driver'],'mssql')) $output[$key]=''; // MSSQL does not know such thing as an empty string. So it returns one space instead, which we must fix.
01317                                                 }
01318                                         }
01319                                 }
01320                                 break;
01321                         case 'userdefined':
01322                                 $output = $res->sql_fetch_row();
01323                                 break;
01324                 }
01325                 return $output;
01326         }
01327 
01334         function sql_free_result(&$res) {
01335 
01336                 $handlerType = is_object($res) ? $res->TYPO3_DBAL_handlerType :  'native';
01337                 switch($handlerType)    {
01338                         case 'native':
01339                                 $output = mysql_free_result($res);
01340                                 break;
01341                         case 'adodb':
01342                                 if(method_exists($res, 'Close')) {
01343                                         $res->Close();
01344                                         unset($res);
01345                                         $output = true;
01346                                 } else {
01347                                         $output = false;
01348                                 }
01349                                 break;
01350                         case 'userdefined':
01351                                 unset($res);
01352                                 break;
01353                 }
01354                 return $output;
01355         }
01356 
01362         function sql_insert_id()        {
01363 
01364                 switch($this->handlerCfg[$this->lastHandlerKey]['type'])        {
01365                         case 'native':
01366                                 $output = mysql_insert_id($this->handlerInstance[$this->lastHandlerKey]['link']);
01367                                 break;
01368                         case 'adodb':
01369                                 $output = $this->handlerInstance[$this->lastHandlerKey]->last_insert_id;
01370                                 break;
01371                         case 'userdefined':
01372                                 $output = $this->handlerInstance[$this->lastHandlerKey]->sql_insert_id();
01373                                 break;
01374                 }
01375                 return $output;
01376         }
01377 
01383         function sql_affected_rows()    {
01384 
01385                 switch($this->handlerCfg[$this->lastHandlerKey]['type'])        {
01386                         case 'native':
01387                                 $output = mysql_affected_rows();
01388                                 break;
01389                         case 'adodb':
01390                                 $output = $this->handlerInstance[$this->lastHandlerKey]->Affected_Rows();
01391                                 break;
01392                         case 'userdefined':
01393                                 $output = $this->handlerInstance[$this->lastHandlerKey]->sql_affected_rows();
01394                                 break;
01395                 }
01396                 return $output;
01397         }
01398 
01406         function sql_data_seek(&$res,$seek)     {
01407 
01408                 $handlerType = is_object($res) ? $res->TYPO3_DBAL_handlerType :  'native';
01409                 switch($handlerType)