"TYPO3 4.0.1: typo3_src-4.0.1/typo3/sysext/dbal/class.ux_t3lib_db.php Source File", "datetime" => "Sat Dec 2 19:22:30 2006", "date" => "2 Dec 2006", "doxygenversion" => "1.4.6", "projectname" => "TYPO3 4.0.1", "projectnumber" => "4.0.1" ); get_header($doxygen_vars); ?>

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                                 break;
01374                         case 'adodb':
01375                                 $output = $this->handlerInstance[$this->lastHandlerKey]->last_insert_id;
01376                                 break;
01377                         case 'userdefined':
01378                                 $output = $this->handlerInstance[$this->lastHandlerKey]->sql_insert_id();
01379                                 break;
01380                 }
01381                 return $output;
01382         }
01383 
01389         function sql_affected_rows()    {
01390 
01391                 switch($this->handlerCfg[$this->lastHandlerKey]['type'])        {
01392                         case 'native':
01393                                 $output = mysql_affected_rows();
01394                                 break;
01395                         case 'adodb':
01396                                 $output = $this->handlerInstance[$this->lastHandlerKey]->Affected_Rows();
01397                                 break;
01398                         case 'userdefined':
01399                                 $output = $this->handlerInstance[$this->lastHandlerKey]->sql_affected_rows();
01400                                 break;
01401                 }
01402                 return $output;
01403         }
01404 
01412         function sql_data_seek(&$res,$seek)     {
01413 
01414                 $handlerType = is_object($res) ? $res->TYPO3_DBAL_handlerType :  'native';
01415                 switch($handlerType)    {
01416                         case 'native':
01417                                 $output = mysql_data_seek($res,$seek);
01418                                 break;
01419                         case 'adodb':
01420                                 $output = $res->Move($seek);
01421                                 break;
01422                         case 'userdefined':
01423                                 $output = $res->sql_data_seek($seek);
01424                                 break;
01425                 }
01426                 return $output;
01427         }
01428 
01438         function sql_field_metatype($table,$field)      {
01439                 return $this->cache_fieldType[$table][$field]['metaType'];
01440         }
01441 
01451         function sql_field_type(&$res,$pointer) {
01452                 if($res === null) {
01453                         debug(array('no res in sql_field_type!'));
01454                         return 'text';
01455                 }
01456                 else if(is_string($res)){
01457                         if($res == 'tx_dbal_debuglog') return 'text';
01458                         $handlerType = 'adodb';
01459                 }
01460                 else {
01461                         $handlerType = is_object($res) ? $res->TYPO3_DBAL_handlerType :  'native';
01462                 }
01463 
01464                 switch($handlerType)    {
01465                         case 'native':
01466                                 $output = mysql_field_type($res,$pointer);
01467                                 break;
01468                         case 'adodb':
01469                                 if(is_string($pointer)){
01470                                         $output = $this->cache_fieldType[$res][$pointer]['type'];
01471                                 }
01472 
01473                                 break;
01474                         case 'userdefined':
01475                                 $output = $res->sql_field_type($pointer);
01476                                 break;
01477                 }
01478 
01479                 return $output;
01480         }
01481 
01482 
01483 
01484 
01485 
01486 
01487 
01488 
01489         /**********
01490         *
01491         * Legacy functions, bound to _DEFAULT handler. (Overriding parent methods)
01492         * Depreciated.
01493         *
01494         **********/
01495 
01505         function sql($db,$query)        {
01506                 return $this->sql_query($query);
01507         }
01508 
01519         function sql_query($query)      {
01520 
01521                 switch($this->handlerCfg['_DEFAULT']['type'])   {
01522                         case 'native':
01523                                 $sqlResult = mysql_query($query, $this->handlerInstance['_DEFAULT']['link']);
01524                                 break;
01525                         case 'adodb':
01526                                 $sqlResult = $this->handlerInstance['_DEFAULT']->Execute($query);
01527                                 $sqlResult->TYPO3_DBAL_handlerType = 'adodb';
01528                                 break;
01529                         case 'userdefined':
01530                                 $sqlResult = $this->handlerInstance['_DEFAULT']->sql_query($query);
01531                                 $sqlResult->TYPO3_DBAL_handlerType = 'userdefined';
01532                                 break;
01533                 }
01534 
01535                 if ($this->printErrors && $this->sql_error())   {
01536                         debug(array($this->lastQuery, $this->sql_error()));
01537                 }
01538 
01539                 return $sqlResult;
01540         }
01541 
01554         function sql_pconnect($TYPO3_db_host, $TYPO3_db_username, $TYPO3_db_password)   {
01555                 // Overriding the _DEFAULT handler configuration of username, password, localhost and database name:
01556                 $this->handlerCfg['_DEFAULT']['config']['username'] = $TYPO3_db_username;
01557                 $this->handlerCfg['_DEFAULT']['config']['password'] = $TYPO3_db_password;
01558                 $this->handlerCfg['_DEFAULT']['config']['host'] = $TYPO3_db_host;
01559                 $this->handlerCfg['_DEFAULT']['config']['database'] = TYPO3_db;
01560 
01561                 // Initializing and output value:
01562                 $sqlResult = $this->handler_init('_DEFAULT');
01563                 return $sqlResult;
01564         }
01565 
01573         function sql_select_db($TYPO3_db)       {
01574                 return TRUE;
01575         }
01576 
01577 
01578 
01579 
01580 
01581 
01582 
01583 
01584 
01585 
01586 
01587 
01588 
01589 
01590 
01591         /**************************************
01592         *
01593         * SQL admin functions
01594         * (For use in the Install Tool and Extension Manager)
01595         *
01596         **************************************/
01597 
01605         function admin_get_dbs()        {
01606                 $dbArr = array();
01607                 switch($this->handlerCfg['_DEFAULT']['type'])   {
01608                         case 'native':
01609                                 $db_list = mysql_list_dbs($this->link);
01610                                 while ($row = mysql_fetch_object($db_list)) {
01611                                         if ($this->sql_select_db($row->Database))       {
01612                                                 $dbArr[] = $row->Database;
01613                                         }
01614                                 }
01615                                 break;
01616                         case 'adodb':
01617                                         // check needed for install tool - otherwise it will just die because the call to
01618                                         // MetaDatabases is done on a stdClass instance
01619                                 if(method_exists($this->handlerInstance['_DEFAULT'],'MetaDatabases')) {
01620                                         $sqlDBs = $this->handlerInstance['_DEFAULT']->MetaDatabases();
01621                                         if(is_array($sqlDBs)) {
01622                                                 foreach($sqlDBs as $k => $theDB) {
01623                                                         $dbArr[] = $theDB;
01624                                                 }
01625                                         }
01626                                 }
01627                                 break;
01628                         case 'userdefined':
01629                                 $dbArr = $this->handlerInstance['_DEFAULT']->admin_get_tables();
01630                                 break;
01631                 }
01632 
01633                 return $dbArr;
01634         }
01635 
01645         function admin_get_tables()     {
01646                 $whichTables = array();
01647 
01648                 // Getting real list of tables:
01649                 switch($this->handlerCfg['_DEFAULT']['type'])   {
01650                         case 'native':
01651                                 $tables_result = mysql_list_tables(TYPO3_db, $this->handlerInstance['_DEFAULT']['link']);
01652                                 if (!$this->sql_error())        {
01653                                         while ($theTable = $this->sql_fetch_assoc($tables_result)) {
01654                                                 $whichTables[current($theTable)] = current($theTable);
01655                                         }
01656                                 }
01657                                 break;
01658                         case 'adodb':
01659                                 $sqlTables = $this->handlerInstance['_DEFAULT']->MetaTables('TABLES');
01660                                 while (list($k, $theTable) = each($sqlTables)) {
01661                                         if(preg_match('/BIN\$/', $theTable)) continue; // skip tables from the Oracle 10 Recycle Bin
01662                                         $whichTables[$theTable] = $theTable;
01663                                 }
01664                                 break;
01665                         case 'userdefined':
01666                                 $whichTables = $this->handlerInstance['_DEFAULT']->admin_get_tables();
01667                                 break;
01668                 }
01669 
01670                 // Check mapping:
01671                 if (is_array($this->mapping) && count($this->mapping))  {
01672 
01673                         // Mapping table names in reverse, first getting list of real table names:
01674                         $tMap = array();
01675                         foreach($this->mapping as $tN => $tMapInfo)     {
01676                                 if (isset($tMapInfo['mapTableName']))   $tMap[$tMapInfo['mapTableName']]=$tN;
01677                         }
01678 
01679                         // Do mapping:
01680                         $newList=array();
01681                         foreach($whichTables as $tN)    {
01682                                 if (isset($tMap[$tN]))  $tN = $tMap[$tN];
01683                                 $newList[$tN] = $tN;
01684                         }
01685 
01686                         $whichTables = $newList;
01687                 }
01688 
01689                 // Adding tables configured to reside in other DBMS (handler by other handlers than the default):
01690                 if (is_array($this->table2handlerKeys)) {
01691                         foreach($this->table2handlerKeys as $key => $handlerKey)        {
01692                                 $whichTables[$key] = $key;
01693                         }
01694                 }
01695 
01696                 return $whichTables;
01697         }
01698 
01707         function admin_get_fields($tableName)   {
01708                 $output = array();
01709 
01710                 // Do field mapping if needed:
01711                 $ORIG_tableName = $tableName;
01712                 if ($tableArray = $this->map_needMapping($tableName))   {
01713 
01714                         // Table name:
01715                         if ($this->mapping[$tableName]['mapTableName']) {
01716                                 $tableName = $this->mapping[$tableName]['mapTableName'];
01717                         }
01718                 }
01719 
01720                 // Find columns
01721                 $this->lastHandlerKey = $this->handler_getFromTableList($ORIG_tableName);
01722                 switch((string)$this->handlerCfg[$this->lastHandlerKey]['type'])        {
01723                         case 'native':
01724                                 $columns_res = mysql_query('SHOW columns FROM '.$tableName, $this->handlerInstance[$this->lastHandlerKey]['link']);
01725                                 while($fieldRow = mysql_fetch_assoc($columns_res))      {
01726                                         $output[$fieldRow['Field']] = $fieldRow;
01727                                 }
01728                                 break;
01729                         case 'adodb':
01730                                 $fieldRows = $this->handlerInstance[$this->lastHandlerKey]->MetaColumns($tableName, false);
01731                                 foreach($fieldRows as $k => $fieldRow) {
01732                                         settype($fieldRow, 'array');
01733                                         $fieldRow['Field'] = $fieldRow['name'];
01734                                         $ntype = $this->MySQLActualType($this->MetaType($fieldRow['type'],$tableName));
01735                                         $ntype .= (($fieldRow['max_length'] != -1) ? (($ntype == 'INT') ? '(11)' :'('.$fieldRow['max_length'].')') : '');
01736                                         $fieldRow['Type'] = strtolower($ntype);
01737                                         $fieldRow['Null'] = '';
01738                                         $fieldRow['Key'] = '';
01739                                         $fieldRow['Default'] = $fieldRow['default_value'];
01740                                         $fieldRow['Extra'] = '';
01741                                         $output[$fieldRow['name']] = $fieldRow;
01742                                 }
01743                                 break;
01744                         case 'userdefined':
01745                                 $output = $this->handlerInstance[$this->lastHandlerKey]->admin_get_fields($tableName);
01746                                 break;
01747                 }
01748 
01749                 // mapping should be done:
01750                 if (is_array($tableArray) && is_array($this->mapping[$ORIG_tableName]['mapFieldNames']))        {
01751                         $revFields = array_flip($this->mapping[$ORIG_tableName]['mapFieldNames']);
01752 
01753                         $newOutput = array();
01754                         foreach($output as $fN => $fInfo)       {
01755                                 if (isset($revFields[$fN]))     {
01756                                         $fN = $revFields[$fN];
01757                                         $fInfo['Field'] = $fN;
01758                                 }
01759                                 $newOutput[$fN] = $fInfo;
01760                         }
01761                         $output = $newOutput;
01762                 }
01763 
01764                 return $output;
01765         }
01766 
01774         function admin_get_keys($tableName)     {
01775                 $output = array();
01776 
01777                 // Do field mapping if needed:
01778                 $ORIG_tableName = $tableName;
01779                 if ($tableArray = $this->map_needMapping($tableName))   {
01780 
01781                         // Table name:
01782                         if ($this->mapping[$tableName]['mapTableName']) {
01783                                 $tableName = $this->mapping[$tableName]['mapTableName'];
01784                         }
01785                 }
01786 
01787                 // Find columns
01788                 $this->lastHandlerKey = $this->handler_getFromTableList($ORIG_tableName);
01789                 switch((string)$this->handlerCfg[$this->lastHandlerKey]['type'])        {
01790                         case 'native':
01791                         $keyRes = mysql_query('SHOW keys FROM '.$tableName, $this->handlerInstance[$this->lastHandlerKey]['link']);
01792                         while($keyRow = mysql_fetch_assoc($keyRes))     {
01793                                 $output[] = $keyRow;
01794                         }
01795                         break;
01796                         case 'adodb':
01797                         $keyRows = $this->handlerInstance[$this->lastHandlerKey]->MetaIndexes($tableName);
01798                         if($keyRows !== false) {
01799                                 while (list($k, $theKey) = each($keyRows)) {
01800                                         $theKey['Table'] = $tableName;
01801                                         $theKey['Non_unique'] = (int) !$theKey['unique'];
01802                                         $theKey['Key_name'] = str_replace($tableName.'_','',$k);
01803 
01804                                         // the following are probably not needed anyway...
01805                                         $theKey['Collation'] = '';
01806                                         $theKey['Cardinality'] = '';
01807                                         $theKey['Sub_part'] = '';
01808                                         $theKey['Packed'] = '';
01809                                         $theKey['Null'] = '';
01810                                         $theKey['Index_type'] = '';
01811                                         $theKey['Comment'] = '';
01812 
01813                                         // now map multiple fields into multiple rows (we mimic MySQL, remember...)
01814                                         $keycols = $theKey['columns'];
01815                                         while (list($c, $theCol) = each($keycols)) {
01816                                                 $theKey['Seq_in_index'] = $c+1;
01817                                                 $theKey['Column_name'] = $theCol;
01818                                                 $output[] = $theKey;
01819                                         }
01820                                 }
01821                         }
01822                         $priKeyRow = $this->handlerInstance[$this->lastHandlerKey]->MetaPrimaryKeys($tableName);
01823                         $theKey = array();
01824                         $theKey['Table'] = $tableName;
01825                         $theKey['Non_unique'] = 0;
01826                         $theKey['Key_name'] = 'PRIMARY';
01827 
01828                         // the following are probably not needed anyway...
01829                         $theKey['Collation'] = '';
01830                         $theKey['Cardinality'] = '';
01831                         $theKey['Sub_part'] = '';
01832                         $theKey['Packed'] = '';
01833                         $theKey['Null'] = '';
01834                         $theKey['Index_type'] = '';
01835                         $theKey['Comment'] = '';
01836 
01837                         // now map multiple fields into multiple rows (we mimic MySQL, remember...)
01838                         if($priKeyRow !== false) {
01839                                 while (list($c, $theCol) = each($priKeyRow)) {
01840                                         $theKey['Seq_in_index'] = $c+1;
01841                                         $theKey['Column_name'] = $theCol;
01842                                         $output[] = $theKey;
01843                                 }
01844                         }
01845                         break;
01846                         case 'userdefined':
01847                         $output = $this->handlerInstance[$this->lastHandlerKey]->admin_get_keys($tableName);
01848                         break;
01849                 }
01850 
01851                 // mapping should be done:
01852                 if (is_array($tableArray) && is_array($this->mapping[$ORIG_tableName]['mapFieldNames']))        {
01853                         $revFields = array_flip($this->mapping[$ORIG_tableName]['mapFieldNames']);
01854 
01855                         $newOutput = array();
01856                         foreach($output as $kN => $kInfo)       {
01857                                 // Table:
01858                                 $kInfo['Table'] = $ORIG_tableName;
01859 
01860                                 // Column
01861                                 if (isset($revFields[$kInfo['Column_name']]))   {
01862                                         $kInfo['Column_name'] = $revFields[$kInfo['Column_name']];
01863                                 }
01864 
01865                                 // Write it back:
01866                                 $newOutput[$kN] = $kInfo;
01867                         }
01868                         $output = $newOutput;
01869                 }
01870 
01871                 return $output;
01872         }
01873 
01880         function admin_query($query)    {
01881                 $parsedQuery = $this->SQLparser->parseSQL($query);
01882                 $ORIG_table = $parsedQuery['TABLE'];
01883 
01884                 if (is_array($parsedQuery))     {
01885 
01886                                 // Process query based on type:
01887                         switch($parsedQuery['type'])    {
01888                                 case 'CREATETABLE':
01889                                 case 'ALTERTABLE':
01890                                 case 'DROPTABLE':
01891                                         if(file_exists(PATH_typo3conf.'temp_fieldInfo.php')) unlink(PATH_typo3conf.'temp_fieldInfo.php');
01892                                         $this->map_genericQueryParsed($parsedQuery);
01893                                         break;
01894                                 case 'INSERT':
01895                                         $this->map_genericQueryParsed($parsedQuery);
01896                                         break;
01897                                 case 'CREATEDATABASE':
01898                                         die('Creating a database with DBAL is not supported. Did you really read the manual?');
01899                                         break;
01900                                 default:
01901                                         die('ERROR: Invalid Query type ('.$parsedQuery['type'].') for ->admin_query() function!: "'.htmlspecialchars($query).'"');
01902                                         break;
01903                         }
01904 
01905                                 // Setting query array (for other applications to access if needed)
01906                         $this->lastParsedAndMappedQueryArray = $parsedQuery;
01907 
01908                                 // Execute query (based on handler derived from the TABLE name which we actually know for once!)
01909                         $this->lastHandlerKey = $this->handler_getFromTableList($ORIG_table);
01910                         switch((string)$this->handlerCfg[$this->lastHandlerKey]['type'])        {
01911                                 case 'native':
01912                                                 // Compiling query:
01913                                         $compiledQuery =  $this->SQLparser->compileSQL($this->lastParsedAndMappedQueryArray);
01914 
01915                                         if($this->lastParsedAndMappedQueryArray['type']=='INSERT') {
01916                                                 return mysql_query($compiledQuery, $this->link);
01917                                         }
01918                                         return mysql_query($compiledQuery[0], $this->link);
01919                                         break;
01920                                 case 'adodb':
01921                                                 // Compiling query:
01922                                         $compiledQuery =  $this->SQLparser->compileSQL($this->lastParsedAndMappedQueryArray);
01923                                         if($this->lastParsedAndMappedQueryArray['type']=='INSERT') {
01924                                                 return $this->exec_INSERTquery($this->lastParsedAndMappedQueryArray['TABLE'],$compiledQuery);
01925                                         }
01926                                         return $this->handlerInstance[$this->lastHandlerKey]->DataDictionary->ExecuteSQLArray($compiledQuery);
01927                                         break;
01928                                 case 'userdefined':
01929                                                 // Compiling query:
01930                                         $compiledQuery =  $this->SQLparser->compileSQL($this->lastParsedAndMappedQueryArray);
01931 
01932                                         return $this->handlerInstance[$this->lastHandlerKey]->admin_query($compiledQuery);
01933                                         break;
01934                         }
01935                 } else die('ERROR: Query could not be parsed: "'.htmlspecialchars($parsedQuery).'". Query: "'.htmlspecialchars($query).'"');
01936         }
01937 
01938 
01939 
01940 
01941 
01942 
01943 
01944 
01945 
01946 
01947         /************************************
01948         *
01949         * Handler management
01950         *
01951         **************************************/
01952 
01960         function handler_getFromTableList($tableList)   {
01961 
01962                 $key = $tableList;
01963 
01964                 if (!isset($this->cache_handlerKeyFromTableList[$key])) {
01965 
01966                                 // Get tables separated:
01967                         $_tableList = $tableList;
01968                         $tableArray = $this->SQLparser->parseFromTables($_tableList);
01969 
01970                                 // If success, traverse the tables:
01971                         if (is_array($tableArray) && count($tableArray))        {
01972                                 foreach($tableArray as $vArray) {
01973 
01974                                                 // Find handler key, select "_DEFAULT" if none is specifically configured:
01975                                         $handlerKey = $this->table2handlerKeys[$vArray['table']] ? $this->table2handlerKeys[$vArray['table']] : '_DEFAULT';
01976 
01977                                                 // In case of separate handler keys for joined tables:
01978                                         if ($outputHandlerKey && $handlerKey != $outputHandlerKey)      {
01979                                                 die('DBAL fatal error: Tables in this list "'.$tableList.'" didn\'t use the same DB handler!');
01980                                         }
01981 
01982                                         $outputHandlerKey = $handlerKey;
01983                                 }
01984 
01985                                         // Check initialized state; if handler is NOT initialized (connected) then we will connect it!
01986                                 if (!isset($this->handlerInstance[$outputHandlerKey]))  {
01987                                         $this->handler_init($outputHandlerKey);
01988                                 }
01989 
01990                                         // Return handler key:
01991                                 $this->cache_handlerKeyFromTableList[$key] = $outputHandlerKey;
01992                         } else {
01993                                 die('DBAL fatal error: No handler found in handler_getFromTableList() for: "'.$tableList.'" ('.$tableArray.')');
01994                         }
01995                 }
01996 
01997                 return $this->cache_handlerKeyFromTableList[$key];
01998         }
01999 
02007         function handler_init($handlerKey)      {
02008 
02009                         // Find handler configuration:
02010                 $cfgArray = $this->handlerCfg[$handlerKey];
02011                 $handlerType = (string)$cfgArray['type'];
02012                 $output = FALSE;
02013 
02014                 if (is_array($cfgArray))        {
02015                         switch($handlerType)    {
02016                                 case 'native':
02017                                         if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['no_pconnect'])  {
02018                                                 $link = mysql_connect($cfgArray['config']['host'].(isset($cfgArray['config']['port']) ? ':'.$cfgArray['config']['port'] : ''), $cfgArray['config']['username'], $cfgArray['config']['password'], true);
02019                                         } else {
02020                                                 $link = mysql_pconnect($cfgArray['config']['host'].(isset($cfgArray['config']['port']) ? ':'.$cfgArray['config']['port'] : ''), $cfgArray['config']['username'], $cfgArray['config']['password']);
02021                                         }
02022 
02023                                                 // Set handler instance:
02024                                         $this->handlerInstance[$handlerKey] = array('handlerType' => 'native', 'link' => $link);
02025 
02026                                                 // If link succeeded:
02027                                         if ($link)      {
02028                                                         // For default, set ->link (see t3lib_DB)
02029                                                 if ($handlerKey == '_DEFAULT') {
02030                                                         $this->link = $link;
02031                                                 }
02032 
02033                                                         // Select database as well:
02034                                                 if (mysql_select_db($cfgArray['config']['database'], $link))    {
02035                                                         $output = TRUE;
02036                                                 }
02037                                                 $setDBinit = t3lib_div::trimExplode(chr(10), $GLOBALS['TYPO3_CONF_VARS']['SYS']['setDBinit'], 1);
02038                                                 foreach ($setDBinit as $v)      {
02039                                                         if (mysql_query($v, $this->link) === FALSE)     {
02040                                                                 t3lib_div::sysLog('Could not initialize DB connection with query "'.$v.'".','Core',3);
02041                                                         }
02042                                                 }
02043                                         } else {
02044                                                 t3lib_div::sysLog('Could not connect to MySQL server '.$cfgArray['config']['host'].' with user '.$cfgArray['config']['username'].'.','Core',4);
02045                                         }
02046                                         break;
02047                                 case 'adodb':
02048                                         $output = true;
02049                                         require_once(t3lib_extMgm::extPath('adodb').'adodb/adodb.inc.php');
02050                                         if(!defined('ADODB_FORCE_NULLS')) define('ADODB_FORCE_NULLS', 1);
02051                                         $GLOBALS['ADODB_FORCE_TYPE'] = ADODB_FORCE_VALUE;
02052                                         $GLOBALS['ADODB_FETCH_MODE'] = ADODB_FETCH_BOTH;
02053 
02054                                         $this->handlerInstance[$handlerKey] = &ADONewConnection($cfgArray['config']['driver']);
02055                                         if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['no_pconnect'])  {
02056                                                 $this->handlerInstance[$handlerKey]->Connect($cfgArray['config']['host'].(isset($cfgArray['config']['port']) ? ':'.$cfgArray['config']['port'] : ''),$cfgArray['config']['username'],$cfgArray['config']['password'],$cfgArray['config']['database']);
02057                                         } else {
02058                                                 $this->handlerInstance[$handlerKey]->PConnect($cfgArray['config']['host'].(isset($cfgArray['config']['port']) ? ':'.$cfgArray['config']['port'] : ''),$cfgArray['config']['username'],$cfgArray['config']['password'],$cfgArray['config']['database']);
02059                                         }
02060                                         if(!$this->handlerInstance[$handlerKey]->isConnected()) {
02061                                                 $dsn = $cfgArray['config']['driver'].'://'.$cfgArray['config']['username'].
02062                                                         (strlen($cfgArray['config']['password']) ? ':XXXX@' : '').
02063                                                         $cfgArray['config']['host'].(isset($cfgArray['config']['port']) ? ':'.$cfgArray['config']['port'] : '').'/'.$cfgArray['config']['database'].
02064                                                         ($GLOBALS['TYPO3_CONF_VARS']['SYS']['no_pconnect'] ? '' : '?persistent=1');
02065                                                 t3lib_div::sysLog('Could not connect to DB server using ADOdb on '.$cfgArray['config']['host'].' with user '.$cfgArray['config']['username'].'.','Core',4);
02066                                                 error_log('DBAL error: Connection to '.$dsn.' failed. Maybe PHP doesn\'t support the database?');
02067                                                 $output = false;
02068                                         } else {
02069                                                 $this->handlerInstance[$handlerKey]->DataDictionary  = NewDataDictionary($this->handlerInstance[$handlerKey]);
02070                                                 $this->handlerInstance[$handlerKey]->last_insert_id = 0;
02071                                                 if(isset($cfgArray['config']['sequenceStart'])) {
02072                                                         $this->handlerInstance[$handlerKey]->sequenceStart = $cfgArray['config']['sequenceStart'];
02073                                                 } else {
02074                                                         $this->handlerInstance[$handlerKey]->sequenceStart = 1;
02075                                                 }
02076                                         }
02077                                         break;
02078                                 case 'userdefined':
02079                                         // Find class file:
02080                                         $fileName = t3lib_div::getFileAbsFileName($cfgArray['config']['classFile']);
02081                                         if (@is_file($fileName))        {
02082                                                 require_once($fileName);
02083                                         } else die('DBAL error: "'.$fileName.'" was not a file to include.');
02084 
02085                                         // Initialize:
02086                                         $this->handlerInstance[$handlerKey] = t3lib_div::makeInstance($cfgArray['config']['class']);
02087                                         $this->handlerInstance[$handlerKey]->init($cfgArray,$this);
02088 
02089                                         if (is_object($this->handlerInstance[$handlerKey]))             {
02090                                                 $output = TRUE;
02091                                         }
02092                                         break;
02093                                 default:
02094                                         die('ERROR: Invalid handler type: "'.$cfgArray['type'].'"');
02095                                         break;
02096                         }
02097 
02098                         return $output;
02099                 } else die('ERROR: No handler for key "'.$handlerKey.'"');
02100         }
02101 
02102 
02108         function runningNative() {
02109                 return ((string)$this->handlerCfg[$this->lastHandlerKey]['type']==='native');
02110         }
02111 
02112 
02119         function runningADOdbDriver($driver) {
02120                 return strstr($this->handlerCfg[$this->lastHandlerKey]['config']['driver'], $driver);
02121         }
02122 
02123 
02124 
02125 
02126 
02127 
02128 
02129 
02130 
02131 
02132         /************************************
02133         *
02134         * Table/Field mapping
02135         *
02136         **************************************/
02137 
02145         function map_needMapping($tableList,$fieldMappingOnly=FALSE)    {
02146 
02147                 $key = $tableList.'|'.$fieldMappingOnly;
02148                 if (!isset($this->cache_mappingFromTableList[$key]))    {
02149                         $this->cache_mappingFromTableList[$key] = FALSE;        // Default:
02150 
02151                         $tables = $this->SQLparser->parseFromTables($tableList);
02152                         if (is_array($tables))  {
02153                                 foreach($tables as $tableCfg)   {
02154                                         if ($fieldMappingOnly)  {
02155                                                 if (is_array($this->mapping[$tableCfg['table']]['mapFieldNames']))      {
02156                                                         $this->cache_mappingFromTableList[$key] = $tables;
02157                                                 }
02158                                         } else {
02159                                                 if (is_array($this->mapping[$tableCfg['table']]))       {
02160                                                         $this->cache_mappingFromTableList[$key] = $tables;
02161                                                 }
02162                                         }
02163                                 }
02164                         }
02165                 }
02166 
02167                 return $this->cache_mappingFromTableList[$key];
02168         }
02169 
02181         function map_assocArray($input,$tables,$rev=FALSE)      {
02182 
02183                         // Traverse tables from query (hopefully only one table):
02184                 foreach($tables as $tableCfg)   {
02185                         if (is_array($this->mapping[$tableCfg['table']]['mapFieldNames']))      {
02186 
02187                                         // Get the map (reversed if needed):
02188                                 if ($rev)       {
02189                                         $theMap = array_flip($this->mapping[$tableCfg['table']]['mapFieldNames']);
02190                                 } else {
02191                                         $theMap = $this->mapping[$tableCfg['table']]['mapFieldNames'];
02192                                 }
02193 
02194                                         // Traverse selected record, map fieldnames:
02195                                 $output = array();
02196                                 foreach($input as $fN => $value)        {
02197 
02198                                                 // Set the field name, change it if found in mapping array:
02199                                         if ($theMap[$fN])       {
02200                                                 $newKey = $theMap[$fN];
02201                                         } else {
02202                                                 $newKey = $fN;
02203                                         }
02204 
02205                                                 // Set value to fieldname:
02206                                         $output[$newKey] = $value;
02207                                 }
02208 
02209                                         // When done, override the $input array with the result:
02210                                 $input = $output;
02211                         }
02212                 }
02213 
02214                         // Return input array (which might have been altered in the mean time)
02215                 return $input;
02216         }
02217 
02230         function map_remapSELECTQueryParts(&$select_fields,&$from_table,&$where_clause,&$groupBy,&$orderBy)     {
02231 
02232                         // Tables:
02233                 $tables = $this->SQLparser->parseFromTables($from_table);
02234                 $defaultTable = $tables[0]['table'];
02235                 foreach($tables as $k => $v)    {
02236                         if ($this->mapping[$v['table']]['mapTableName'])        {
02237                                 $tables[$k]['table'] = $this->mapping[$v['table']]['mapTableName'];
02238                         }
02239                 }
02240                 $from_table = $this->SQLparser->compileFromTables($tables);
02241 
02242                         // Where clause:
02243                 $whereParts = $this->SQLparser->parseWhereClause($where_clause);
02244                 $this->map_sqlParts($whereParts,$defaultTable);
02245                 $where_clause = $this->SQLparser->compileWhereClause($whereParts);
02246 
02247                         // Select fields:
02248                 $expFields = $this->SQLparser->parseFieldList($select_fields);
02249                 $this->map_sqlParts($expFields,$defaultTable);
02250                 $select_fields = $this->SQLparser->compileFieldList($expFields);
02251 
02252                         // Group By fields
02253                 $expFields = $this->SQLparser->parseFieldList($groupBy);
02254                 $this->map_sqlParts($expFields,$defaultTable);
02255                 $groupBy = $this->SQLparser->compileFieldList($expFields);
02256 
02257                         // Order By fields
02258                 $expFields = $this->SQLparser->parseFieldList($orderBy);
02259                 $this->map_sqlParts($expFields,$defaultTable);
02260                 $orderBy = $this->SQLparser->compileFieldList($expFields);
02261         }
02262 
02272         function map_sqlParts(&$sqlPartArray, $defaultTable)    {
02273 
02274                         // Traverse sql Part array:
02275                 if (is_array($sqlPartArray))    {
02276                         foreach($sqlPartArray as $k => $v)      {
02277 
02278                                         // Look for sublevel (WHERE parts only)
02279                                 if (is_array($sqlPartArray[$k]['sub'])) {
02280                                         $this->map_sqlParts($sqlPartArray[$k]['sub'], $defaultTable);   // Call recursively!
02281                                 } else {
02282                                                 // For the field, look for table mapping (generic):
02283                                         $t = $sqlPartArray[$k]['table'] ? $sqlPartArray[$k]['table'] : $defaultTable;
02284 
02285                                                 // Mapping field name, if set:
02286                                         if (is_array($this->mapping[$t]['mapFieldNames']) && $this->mapping[$t]['mapFieldNames'][$sqlPartArray[$k]['field']])   {
02287                                                 $sqlPartArray[$k]['field'] = $this->mapping[$t]['mapFieldNames'][$sqlPartArray[$k]['field']];
02288                                         }
02289 
02290                                                 // Map table?
02291                                         if ($sqlPartArray[$k]['table'] && $this->mapping[$sqlPartArray[$k]['table']]['mapTableName'])   {
02292                                                 $sqlPartArray[$k]['table'] = $this->mapping[$sqlPartArray[$k]['table']]['mapTableName'];
02293                                         }
02294                                 }
02295                         }
02296                 }
02297         }
02298 
02307         function map_genericQueryParsed(&$parsedQuery)  {
02308 
02309                         // Getting table - same for all:
02310                 $table = $parsedQuery['TABLE'];
02311                 if ($table)     {
02312                                 // Do field mapping if needed:
02313                         if ($tableArray = $this->map_needMapping($table))       {
02314 
02315                                         // Table name:
02316                                 if ($this->mapping[$table]['mapTableName'])     {
02317                                         $parsedQuery['TABLE'] = $this->mapping[$table]['mapTableName'];
02318                                 }
02319 
02320                                         // Based on type, do additional changes:
02321                                 switch($parsedQuery['type'])    {
02322                                         case 'ALTERTABLE':
02323 
02324                                                 // Changing field name:
02325                                         $newFieldName = $this->mapping[$table]['mapFieldNames'][$parsedQuery['FIELD']];
02326                                         if ($newFieldName)      {
02327                                                 if ($parsedQuery['FIELD'] == $parsedQuery['newField'])  {
02328                                                         $parsedQuery['FIELD'] = $parsedQuery['newField'] = $newFieldName;
02329                                                 } else $parsedQuery['FIELD'] = $newFieldName;
02330                                         }
02331 
02332                                                 // Changing key field names:
02333                                         if (is_array($parsedQuery['fields']))   {
02334                                                 $this->map_fieldNamesInArray($table,$parsedQuery['fields']);
02335                                         }
02336                                         break;
02337                                         case 'CREATETABLE':
02338                                                 // Remapping fields:
02339                                         if (is_array($parsedQuery['FIELDS']))   {
02340                                                 $newFieldsArray = array();
02341                                                 foreach($parsedQuery['FIELDS'] as $fN => $fInfo)        {
02342                                                         if ($this->mapping[$table]['mapFieldNames'][$fN])       {
02343                                                                 $fN = $this->mapping[$table]['mapFieldNames'][$fN];
02344                                                         }
02345                                                         $newFieldsArray[$fN] = $fInfo;
02346                                                 }
02347                                                 $parsedQuery['FIELDS'] = $newFieldsArray;
02348                                         }
02349 
02350                                                 // Remapping keys:
02351                                         if (is_array($parsedQuery['KEYS']))     {
02352                                                 foreach($parsedQuery['KEYS'] as $kN => $kInfo)  {
02353                                                         $this->map_fieldNamesInArray($table,$parsedQuery['KEYS'][$kN]);
02354                                                 }
02355                                         }
02356                                         break;
02357 
02359 
02360                                 }
02361                         }
02362                 } else die('ERROR, mapping: No table found in parsed Query array...');
02363         }
02364 
02372         function map_fieldNamesInArray($table,&$fieldArray)     {
02373                 if (is_array($this->mapping[$table]['mapFieldNames']))  {
02374                         foreach($fieldArray as $k => $v)        {
02375                                 if ($this->mapping[$table]['mapFieldNames'][$v])        {
02376                                         $fieldArray[$k] = $this->mapping[$table]['mapFieldNames'][$v];
02377                                 }
02378                         }
02379                 }
02380         }
02381 
02382 
02383 
02384 
02385 
02386 
02387 
02388 
02389 
02390 
02391 
02392 
02393 
02394 
02395 
02396 
02397 
02398         /**************************************
02399         *
02400         * Debugging
02401         *
02402         **************************************/
02403 
02413         function debugHandler($function,$execTime,$inData)      {
02414                         // we don't want to log our own log/debug SQL
02415                 $script = substr(PATH_thisScript,strlen(PATH_site));
02416 
02417                 if (substr($script,-strlen('dbal/mod1/index.php'))!='dbal/mod1/index.php' &&
02418                 !strstr($inData['args'][0], 'tx_dbal_debuglog'))        {
02419                         $data = array();
02420                         $errorFlag = 0;
02421                         $joinTable = '';
02422 
02423                         if ($this->sql_error()) {
02424                                 $data['sqlError'] = $this->sql_error();
02425                                 $errorFlag|=1;
02426                         }
02427 
02428                                 // if lastQuery is empty (for whatever reason) at least log inData.args
02429                         if(empty($this->lastQuery))
02430                                 $query = implode(' ',$inData['args']);
02431                         else
02432                                 $query = $this->lastQuery;
02433 
02434                         switch($function)       {
02435                                 case 'exec_INSERTquery':
02436                                 case 'exec_UPDATEquery':
02437                                 case 'exec_DELETEquery':
02438                                         $this->debug_log($query,$execTime,$data,$joinTable,$errorFlag, $script);
02439                                         break;
02440 
02441                                 case 'exec_SELECTquery':
02442                                                 // Get explain data:
02443                                         if ($this->conf['debugOptions']['EXPLAIN'] && t3lib_div::inList('adodb,native',$inData['handlerType'])) {
02444                                                 $data['EXPLAIN'] = $this->debug_explain($this->lastQuery);
02445                                         }
02446 
02447                                                 // Check parsing of Query:
02448                                         if ($this->conf['debugOptions']['parseQuery'])  {
02449                                                 $parseResults = array();
02450                                                 $parseResults['SELECT'] = $this->SQLparser->debug_parseSQLpart('SELECT',$inData['args'][1]);
02451                                                 $parseResults['FROM'] = $this->SQLparser->debug_parseSQLpart('FROM',$inData['args'][0]);
02452                                                 $parseResults['WHERE'] = $this->SQLparser->debug_parseSQLpart('WHERE',$inData['args'][2]);
02453                                                 $parseResults['GROUPBY'] = $this->SQLparser->debug_parseSQLpart('SELECT',$inData['args'][3]);   // Using select field list syntax
02454                                                 $parseResults['ORDERBY'] = $this->SQLparser->debug_parseSQLpart('SELECT',$inData['args'][4]);   // Using select field list syntax
02455 
02456                                                 foreach($parseResults as $k => $v)      {
02457                                                         if (!strlen($parseResults[$k])) unset($parseResults[$k]);
02458                                                 }
02459                                                 if (count($parseResults))       {
02460                                                         $data['parseError'] = $parseResults;
02461                                                         $errorFlag|=2;
02462                                                 }
02463                                         }
02464 
02465                                                 // Checking joinTables:
02466                                         if ($this->conf['debugOptions']['joinTables'])  {
02467                                                 if (count(explode(',', $inData['ORIG_from_table']))>1)          {
02468                                                         $joinTable = $inData['args'][0];
02469                                                 }
02470                                         }
02471 
02472                                                 // Logging it:
02473                                         $this->debug_log($query,$execTime,$data,$joinTable,$errorFlag, $script);
02474                                         if(!empty($inData['args'][2]))
02475                                         $this->debug_WHERE($inData['args'][0], $inData['args'][2], $script);
02476                                         break;
02477                         }
02478                 }
02479         }
02480 
02489         function debug_WHERE($table,$where, $script='') {
02490                 $insertArray = array (
02491                 'tstamp' => $GLOBALS['EXEC_TIME'],
02492                 'beuser_id' => intval($GLOBALS['BE_USER']->user['uid']),
02493                 'script' => $script,
02494                 'tablename' => $table,
02495                 'whereclause' => $where
02496                 );
02497 
02498                 $this->exec_INSERTquery('tx_dbal_debuglog_where', $insertArray);
02499         }
02500 
02512         function debug_log($query,$ms,$data,$join,$errorFlag, $script='')       {
02513                 $insertArray = array (
02514                 'tstamp' => $GLOBALS['EXEC_TIME'],
02515                 'beuser_id' => intval($GLOBALS['BE_USER']->user['uid']),
02516                 'script' => $script,
02517                 'exec_time' => $ms,
02518                 'table_join' => $join,
02519                 'serdata' => serialize($data),
02520                 'query' => (is_array($query) ? $query[0].' WITH '.count($query[1]).' BLOB FIELDS: '.implode(', ',array_keys($query[1])) : $query),
02521                 'errorFlag' => $errorFlag
02522                 );
02523 
02524                 $this->exec_INSERTquery('tx_dbal_debuglog', $insertArray);
02525         }
02526 
02534         function debug_explain($query)  {
02535                 $res = $this->sql_query('EXPLAIN '.$query);
02536 
02537                 $output = array();
02538                 while($row = $this->sql_fetch_assoc($res))      {
02539                         $output[] = $row;
02540                 }
02541                 return $output;
02542         }
02543 }
02544 
02545 
02546 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dbal/class.ux_t3lib_db.php'])  {
02547         include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dbal/class.ux_t3lib_db.php']);
02548 }
02549 ?>