Documentation TYPO3 par Ameos

class.ux_t3lib_db.php

00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 2004 Kasper Skaarhoj (kasper@typo3.com)
00006 *  All rights reserved
00007 *
00008 *  This script is part of the TYPO3 project. The TYPO3 project is
00009 *  free software; you can redistribute it and/or modify
00010 *  it under the terms of the GNU General Public License as published by
00011 *  the Free Software Foundation; either version 2 of the License, or
00012 *  (at your option) any later version.
00013 *
00014 *  The GNU General Public License can be found at
00015 *  http://www.gnu.org/copyleft/gpl.html.
00016 *  A copy is found in the textfile GPL.txt and important notices to the license
00017 *  from the author is found in LICENSE.txt distributed with these scripts.
00018 *
00019 *
00020 *  This script is distributed in the hope that it will be useful,
00021 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023 *  GNU General Public License for more details.
00024 *
00025 *  This copyright notice MUST APPEAR in all copies of the script!
00026 ***************************************************************/
00115 require_once(PATH_t3lib.'class.t3lib_sqlengine.php');
00116 require_once(PATH_t3lib.'class.t3lib_install.php');
00117 //require_once(t3lib_extMgm::extPath('install').'mod/class.tx_install.php');
00118 
00127 class ux_t3lib_DB extends t3lib_DB {
00128 
00129         // Internal, static:
00130         var $printErrors = FALSE;                       // Enable output of SQL errors after query executions. Set through TYPO3_CONF_VARS, see init()
00131         var $debug = FALSE;                                     // Enable debug mode. Set through TYPO3_CONF_VARS, see init()
00132         var $conf = array();                            // Configuration array, copied from TYPO3_CONF_VARS in constructor.
00133 
00134         var $mapping = array();                         // See manual.
00135         var $table2handlerKeys = array();       // See manual.
00136         var $handlerCfg = array (                       // See manual.
00137         '_DEFAULT' => array (
00138         'type' => 'native',
00139         'config' => array(
00140         'username' => '',               // Set by default (overridden)
00141         'password' => '',               // Set by default (overridden)
00142         'host' => '',                   // Set by default (overridden)
00143         'database' => '',               // Set by default (overridden)
00144         'driver' => '',                 // ONLY "adodb" type; eg. "mysql"
00145         )
00146         ),
00147         );
00148 
00149 
00150         // Internal, dynamic:
00151         var $handlerInstance = array();                         // Contains instance of the handler objects as they are created. Exception is the native mySQL calls which are registered as an array with keys "handlerType" = "native" and "link" pointing to the link resource for the connection.
00152         var $lastHandlerKey = '';                                       // Storage of the handler key of last ( SELECT) query - used for subsequent fetch-row calls etc.
00153         var $lastQuery = '';                                            // Storage of last SELECT query
00154         var $lastParsedAndMappedQueryArray=array();     // Query array, the last one parsed
00155 
00156         var $resourceIdToTableNameMap = array();        // Mapping of resource ids to table names.
00157 
00158         // Internal, caching:
00159         var $cache_handlerKeyFromTableList = array();                   // Caching handlerKeys for table lists
00160         var $cache_mappingFromTableList = array();                      // Caching mapping information for table lists
00161         var $cache_autoIncFields = array(); // parsed SQL from standard DB dump file
00162         var $cache_fieldType = array(); // field types for tables/fields
00163         var $cache_primaryKeys = array(); // primary keys
00164 
00165 
00166 
00167 
00168 
00175         function ux_t3lib_DB()  {
00176 
00177                 // Set SQL parser object for internal use:
00178                 $this->SQLparser = t3lib_div::makeInstance('t3lib_sqlengine');
00179                 $this->Installer = t3lib_div::makeInstance('t3lib_install');
00180 
00181                 // Set internal variables with configuration:
00182                 $this->conf = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['dbal'];
00183                 $this->initInternalVariables();
00184         }
00185 
00191         function initInternalVariables()        {
00192 
00193                 // Set outside configuration:
00194                 if (isset($this->conf['mapping']))                              $this->mapping = $this->conf['mapping'];
00195                 if (isset($this->conf['table2handlerKeys']))    $this->table2handlerKeys = $this->conf['table2handlerKeys'];
00196                 if (isset($this->conf['handlerCfg']))                   $this->handlerCfg = $this->conf['handlerCfg'];
00197 
00198                 $this->cacheFieldInfo();
00199                 // Debugging settings:
00200                 $this->printErrors = $this->conf['debugOptions']['printErrors'] ? TRUE : FALSE;
00201                 $this->debug = $this->conf['debugOptions']['enabled'] ? TRUE : FALSE;
00202         }
00203 
00204         function clearCachedFieldInfo() {
00205                 if(file_exists(PATH_typo3conf.'temp_fieldInfo.php'))
00206                 unlink(PATH_typo3conf.'temp_fieldInfo.php');
00207         }
00208 
00209         function cacheFieldInfo() {
00210                 global $TYPO3_LOADED_EXT;
00211                 $extSQL = '';
00212                 $parsedExtSQL = array();
00213 
00214                 // try to fetch cached file first
00215                 // file is removed when admin_query() is called
00216                 if(file_exists(PATH_typo3conf.'temp_fieldInfo.php')) {
00217                         $fdata = unserialize(t3lib_div::getUrl(PATH_typo3conf.'temp_fieldInfo.php'));
00218                         $this->cache_autoIncFields = $fdata['incFields'];
00219                         $this->cache_fieldType = $fdata['fieldTypes'];
00220                         $this->cache_primaryKeys = $fdata['primaryKeys'];
00221                 }
00222                 else {
00223                                 // handle stddb.sql, parse and analyze
00224                         $extSQL = t3lib_div::getUrl(PATH_site.'t3lib/stddb/tables.sql');
00225                         $parsedExtSQL = $this->Installer->getFieldDefinitions_sqlContent($extSQL);
00226                         $this->analyzeFields($parsedExtSQL);
00227 
00228                                 // loop over all installed extensions
00229                         foreach($TYPO3_LOADED_EXT as $ext => $v)        {
00230                                 if(!is_array($v) || !isset($v['ext_tables.sql']))
00231                                 continue;
00232 
00233                                         // fetch db dump (if any) and parse it, then analyze
00234                                 $extSQL = t3lib_div::getUrl($v['ext_tables.sql']);
00235                                 $parsedExtSQL = $this->Installer->getFieldDefinitions_sqlContent($extSQL);
00236                                 $this->analyzeFields($parsedExtSQL);
00237                         }
00238 
00239                         $cachedFieldInfo = array('incFields' => $this->cache_autoIncFields, 'fieldTypes' => $this->cache_fieldType, 'primaryKeys' => $this->cache_primaryKeys);
00240                         $cachedFieldInfo = serialize($this->mapCachedFieldInfo($cachedFieldInfo));
00241 
00242                                 // write serialized content to file
00243                         t3lib_div::writeFile(PATH_typo3conf."temp_fieldInfo.php", $cachedFieldInfo);
00244 
00245                         if (strcmp(t3lib_div::getUrl(PATH_typo3conf."temp_fieldInfo.php"), $cachedFieldInfo))   {
00246                                 die('typo3temp/temp_incfields.php was NOT updated properly (written content didn\'t match file content) - maybe write access problem?');
00247                         }
00248                 }
00249         }
00250 
00258         function analyzeFields($parsedExtSQL) {
00259                 foreach($parsedExtSQL as $table => $tdef) {
00260                         foreach($tdef['fields'] as $field => $fdef) {
00261                                 $fdef = $this->SQLparser->parseFieldDef($fdef);
00262                                 $this->cache_fieldType[$table][$field]['type'] = $fdef['fieldType'];
00263                                 $this->cache_fieldType[$table][$field]['metaType'] = $this->MySQLMetaType($fdef['fieldType']);
00264                                 $this->cache_fieldType[$table][$field]['notnull'] = (isset($fdef['featureIndex']['NOTNULL']) && !$this->SQLparser->checkEmptyDefaultValue($fdef['featureIndex'])) ? 1 : 0;
00265                                 if(isset($fdef['featureIndex']['AUTO_INCREMENT'])) {
00266                                         $this->cache_autoIncFields[$table] = $field;
00267                                 }
00268                                 if(isset($tdef['keys']['PRIMARY'])) {
00269                                         $this->cache_primaryKeys[$table] = substr($tdef['keys']['PRIMARY'], 13, -1);
00270                                 }
00271                         }
00272                 }
00273         }
00274 
00279         function mapCachedFieldInfo($fieldInfo){
00280                 global $TYPO3_CONF_VARS;
00281 
00282                 if(is_array($TYPO3_CONF_VARS['EXTCONF']['dbal']['mapping'])) {
00283                         foreach($TYPO3_CONF_VARS['EXTCONF']['dbal']['mapping'] as $mappedTable => $mappedConf){
00284                                 if(array_key_exists($mappedTable, $fieldInfo['incFields'])) {
00285                                         $mappedTableAlias = $mappedConf['mapTableName'];
00286                                         $fieldInfo['incFields'][$mappedTableAlias] = isset($mappedConf['mapFieldNames'][$fieldInfo['incFields'][$mappedTable]]) ? $mappedConf['mapFieldNames'][$fieldInfo['incFields'][$mappedTable]] : $fieldInfo['incFields'][$mappedTable];
00287                                 }
00288 
00289                                 if(array_key_exists($mappedTable, $fieldInfo['fieldTypes'])) {
00290                                         foreach($fieldInfo['fieldTypes'][$mappedTable] as $field => $fieldConf){
00291                                                 $tempMappedFieldConf[$mappedConf['mapFieldNames'][$field]] = $fieldConf;
00292                                         }
00293 
00294                                         $fieldInfo['fieldTypes'][$mappedConf['mapTableName']] = $tempMappedFieldConf;
00295                                 }
00296 
00297                                 if(array_key_exists($mappedTable, $fieldInfo['primaryKeys'])) {
00298                                         $mappedTableAlias = $mappedConf['mapTableName'];
00299                                         $fieldInfo['primaryKeys'][$mappedTableAlias] = isset($mappedConf['mapFieldNames'][$fieldInfo['primaryKeys'][$mappedTable]]) ? $mappedConf['mapFieldNames'][$fieldInfo['primaryKeys'][$mappedTable]] : $fieldInfo['primaryKeys'][$mappedTable];
00300                                 }
00301 
00302                         }
00303                 }
00304 
00305                 return $fieldInfo;
00306         }
00307 
00308 
00309         /************************************
00310         *
00311         * Query Building (Overriding parent methods)
00312         * These functions are extending counterparts in the parent class.
00313         *
00314         **************************************/
00315 
00316         /* From the ADOdb documentation, this is what we do (_Execute for SELECT, _query for the other actions)
00317 
00318         Execute() is the default way to run queries. You can use the low-level functions _Execute() and _query() to reduce query overhead.
00319         Both these functions share the same parameters as Execute().
00320 
00321         If you do not have any bind parameters or your database supports binding (without emulation), then you can call _Execute() directly.
00322         Calling this function bypasses bind emulation. Debugging is still supported in _Execute().
00323 
00324         If you do not require debugging facilities nor emulated binding, and do not require a recordset to be returned, then you can call _query.
00325         This is great for inserts, updates and deletes. Calling this function bypasses emulated binding, debugging, and recordset handling. Either
00326         the resultid, true or false are returned by _query().
00327         */
00328 
00337         function exec_INSERTquery($table,$fields_values,$no_quote_fields='')    {
00338 
00339                 if ($this->debug)       $pt = t3lib_div::milliseconds();
00340 
00341                 // Do field mapping if needed:
00342                 $ORIG_tableName = $table;
00343                 if ($tableArray = $this->map_needMapping($table))       {
00344 
00345                         // Field mapping of array:
00346                         $fields_values = $this->map_assocArray($fields_values,$tableArray);
00347 
00348                         // Table name:
00349                         if ($this->mapping[$table]['mapTableName'])     {
00350                                 $table = $this->mapping[$table]['mapTableName'];
00351                         }
00352                 }
00353                 // Select API:
00354                 $this->lastHandlerKey = $this->handler_getFromTableList($ORIG_tableName);
00355                 switch((string)$this->handlerCfg[$this->lastHandlerKey]['type'])        {
00356                         case 'native':
00357                                 $this->lastQuery = $this->INSERTquery($table,$fields_values,$no_quote_fields);
00358                                 if(is_string($this->lastQuery)) {
00359                                         $sqlResult = mysql_query($this->lastQuery, $this->handlerInstance[$this->lastHandlerKey]['link']);
00360                                 }
00361                                 else {
00362                                         $sqlResult = mysql_query($this->lastQuery[0], $this->handlerInstance[$this->lastHandlerKey]['link']);
00363                                         foreach($this->lastQuery[1] as $field => $content) {
00364                                                 mysql_query('UPDATE '.$this->quoteFromTables($table).' SET '.$this->quoteFromTables($field).'='.$this->fullQuoteStr($content,$table).' WHERE '.$this->quoteWhereClause($where), $this->handlerInstance[$this->lastHandlerKey]['link']);
00365                                         }
00366                                 }
00367                                 break;
00368                         case 'adodb':
00369                                 // auto generate ID for auto_increment fields if not present (static import needs this!)
00370                                 // should we check the table name here (static_*)?
00371                                 if(isset($this->cache_autoIncFields[$table])) {
00372                                         if(isset($fields_values[$this->cache_autoIncFields[$table]])) {
00373                                                 $new_id = $fields_values[$this->cache_autoIncFields[$table]];
00374                                                 if($table !== 'tx_dbal_debuglog') {
00375                                                         $this->handlerInstance[$this->lastHandlerKey]->last_insert_id = $new_id;
00376                                                 }
00377                                         } else {
00378                                                 $new_id = $this->handlerInstance[$this->lastHandlerKey]->GenID($table.'_'.$this->cache_autoIncFields[$table]);
00379                                                 $fields_values[$this->cache_autoIncFields[$table]] = $new_id;
00380                                                 if($table !== 'tx_dbal_debuglog') {
00381                                                         $this->handlerInstance[$this->lastHandlerKey]->last_insert_id = $new_id;
00382                                                 }
00383                                         }
00384                                 }
00385 
00386                                 $this->lastQuery = $this->INSERTquery($table,$fields_values,$no_quote_fields);
00387                                 if(is_string($this->lastQuery)) {
00388                                         $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->_query($this->lastQuery,false);
00389                                 } else {
00390                                         $this->handlerInstance[$this->lastHandlerKey]->StartTrans();
00391                                         $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->_query($this->lastQuery[0],false);
00392                                         foreach($this->lastQuery[1] as $field => $content) {
00393                                                 if(empty($content)) continue;
00394 
00395                                                 if(isset($this->cache_autoIncFields[$table]) && isset($new_id)) {
00396                                                         $this->handlerInstance[$this->lastHandlerKey]->UpdateBlob($this->quoteFromTables($table),$field,$content,$this->quoteWhereClause($this->cache_autoIncFields[$table].'='.$new_id));
00397                                                 } elseif(isset($this->cache_primaryKeys[$table])) {
00398                                                         $pks = explode(',', $this->cache_primaryKeys[$table]);
00399                                                         foreach ($pks as $pk) {
00400                                                                 if(isset($fields_values[$pk]))
00401                                                                 $where .= $pk.'='.$this->fullQuoteStr($fields_values[$pk], $table).' AND ';
00402                                                         }
00403                                                         $where = $this->quoteWhereClause($where.'1=1');
00404                                                         $this->handlerInstance[$this->lastHandlerKey]->UpdateBlob($this->quoteFromTables($table),$field,$content,$where);
00405                                                 } else {
00406                                                         $this->handlerInstance[$this->lastHandlerKey]->CompleteTrans(false);
00407                                                         die('Could not update BLOB >>>> no WHERE clause found!'); // should never ever happen
00408                                                 }
00409                                         }
00410                                         $this->handlerInstance[$this->lastHandlerKey]->CompleteTrans();
00411                                 }
00412                                 break;
00413                         case 'userdefined':
00414                                 $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->exec_INSERTquery($table,$fields_values,$no_quote_fields);
00415                                 break;
00416                 }
00417 
00418                 if ($this->printErrors && $this->sql_error())   {
00419                         debug(array($this->lastQuery, $this->sql_error()));
00420                 }
00421 
00422                 if ($this->debug)       {
00423                         $this->debugHandler(
00424                         'exec_INSERTquery',
00425                         t3lib_div::milliseconds()-$pt,
00426                         array(
00427                         'handlerType' => $hType,
00428                         'args' => array($table,$fields_values),
00429                         'ORIG_tablename' => $ORIG_tableName
00430                         )
00431                         );
00432                 }
00433                 // Return output:
00434                 return $sqlResult;
00435         }
00436 
00446         function exec_UPDATEquery($table,$where,$fields_values,$no_quote_fields='')     {
00447 
00448                 if ($this->debug)       $pt = t3lib_div::milliseconds();
00449 
00450                 // Do table/field mapping:
00451                 $ORIG_tableName = $table;
00452                 if ($tableArray = $this->map_needMapping($table))       {
00453 
00454                         // Field mapping of array:
00455                         $fields_values = $this->map_assocArray($fields_values,$tableArray);
00456 
00457                         // Where clause table and field mapping:
00458                         $whereParts = $this->SQLparser->parseWhereClause($where);
00459                         $this->map_sqlParts($whereParts,$tableArray[0]['table']);
00460                         $where = $this->SQLparser->compileWhereClause($whereParts);
00461 
00462                         // Table name:
00463                         if ($this->mapping[$table]['mapTableName'])     {
00464                                 $table = $this->mapping[$table]['mapTableName'];
00465                         }
00466                 }
00467 
00468                 // Select API
00469                 $this->lastHandlerKey = $this->handler_getFromTableList($ORIG_tableName);
00470                 switch((string)$this->handlerCfg[$this->lastHandlerKey]['type'])        {
00471                         case 'native':
00472                                 $this->lastQuery = $this->UPDATEquery($table,$where,$fields_values,$no_quote_fields);
00473                                 if(is_string($this->lastQuery)) {
00474                                         $sqlResult = mysql_query($this->lastQuery, $this->handlerInstance[$this->lastHandlerKey]['link']);
00475                                 }
00476                                 else {
00477                                         $sqlResult = mysql_query($this->lastQuery[0], $this->handlerInstance[$this->lastHandlerKey]['link']);
00478                                         foreach($this->lastQuery[1] as $field => $content) {
00479                                                 mysql_query('UPDATE '.$this->quoteFromTables($table).' SET '.$this->quoteFromTables($field).'='.$this->fullQuoteStr($content,$table).' WHERE '.$this->quoteWhereClause($where), $this->handlerInstance[$this->lastHandlerKey]['link']);
00480                                         }
00481                                 }
00482                         break;
00483                         case 'adodb':
00484                                 $this->lastQuery = $this->UPDATEquery($table,$where,$fields_values,$no_quote_fields);
00485                                 if(is_string($this->lastQuery)) {
00486                                         $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->_query($this->lastQuery,false);
00487                                 } else {
00488                                         $this->handlerInstance[$this->lastHandlerKey]->StartTrans();
00489                                         $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->_query($this->lastQuery[0],false);
00490                                         foreach($this->lastQuery[1] as $field => $content) {
00491                                                 $this->handlerInstance[$this->lastHandlerKey]->UpdateBlob($this->quoteFromTables($table),$field,$content,$this->quoteWhereClause($where));
00492                                         }
00493                                         $this->handlerInstance[$this->lastHandlerKey]->CompleteTrans();
00494                                 }
00495                                 break;
00496                         case 'userdefined':
00497                                 $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->exec_UPDATEquery($table,$where,$fields_values,$no_quote_fields);
00498                                 break;
00499                 }
00500 
00501                 if ($this->printErrors && $this->sql_error())   {
00502                         debug(array($this->lastQuery, $this->sql_error()));
00503                 }
00504 
00505                 if ($this->debug)       {
00506                         $this->debugHandler(
00507                         'exec_UPDATEquery',
00508                         t3lib_div::milliseconds()-$pt,
00509                         array(
00510                         'handlerType' => $hType,
00511                         'args' => array($table,$where, $fields_values),
00512                         'ORIG_from_table' => $ORIG_tableName
00513                         )
00514                         );
00515                 }
00516 
00517                 // Return result:
00518                 return $sqlResult;
00519         }
00520 
00528         function exec_DELETEquery($table,$where)        {
00529 
00530                 if ($this->debug)       $pt = t3lib_div::milliseconds();
00531 
00532                 // Do table/field mapping:
00533                 $ORIG_tableName = $table;
00534                 if ($tableArray = $this->map_needMapping($table))       {
00535 
00536                         // Where clause:
00537                         $whereParts = $this->SQLparser->parseWhereClause($where);
00538                         $this->map_sqlParts($whereParts,$tableArray[0]['table']);
00539                         $where = $this->SQLparser->compileWhereClause($whereParts);
00540 
00541                         // Table name:
00542                         if ($this->mapping[$table]['mapTableName'])     {
00543                                 $table = $this->mapping[$table]['mapTableName'];
00544                         }
00545                 }
00546 
00547                 // Select API
00548                 $this->lastHandlerKey = $this->handler_getFromTableList($ORIG_tableName);
00549                 switch((string)$this->handlerCfg[$this->lastHandlerKey]['type'])        {
00550                         case 'native':
00551                                 $this->lastQuery = $this->DELETEquery($table,$where);
00552                                 $sqlResult = mysql_query($this->lastQuery, $this->handlerInstance[$this->lastHandlerKey]['link']);
00553                                 break;
00554                         case 'adodb':
00555                                 $this->lastQuery = $this->DELETEquery($table,$where);
00556                                 $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->_query($this->lastQuery,false);
00557                                 break;
00558                         case 'userdefined':
00559                                 $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->exec_DELETEquery($table,$where);
00560                                 break;
00561                 }
00562 
00563                 if ($this->printErrors && $this->sql_error())   {
00564                         debug(array($this->lastQuery, $this->sql_error()));
00565                 }
00566 
00567                 if ($this->debug)       {
00568                         $this->debugHandler(
00569                         'exec_DELETEquery',
00570                         t3lib_div::milliseconds()-$pt,
00571                         array(
00572                         'handlerType' => $hType,
00573                         'args' => array($table,$where),
00574                         'ORIG_from_table' => $ORIG_tableName
00575                         )
00576                         );
00577                 }
00578 
00579                 // Return result:
00580                 return $sqlResult;
00581         }
00582 
00594         function exec_SELECTquery($select_fields,$from_table,$where_clause,$groupBy='',$orderBy='',$limit='')   {
00595 
00596                 if ($this->debug)       $pt = t3lib_div::milliseconds();
00597 
00598                 // Map table / field names if needed:
00599                 $ORIG_tableName = $from_table;  // Saving table names in $ORIG_from_table since $from_table is transformed beneath:
00600                 if ($tableArray = $this->map_needMapping($ORIG_tableName))      {
00601                         $this->map_remapSELECTQueryParts($select_fields,$from_table,$where_clause,$groupBy,$orderBy);   // Variables passed by reference!
00602                 }
00603 
00604                 // Get handler key and select API:
00605                 $this->lastHandlerKey = $this->handler_getFromTableList($ORIG_tableName);
00606                 $hType = (string)$this->handlerCfg[$this->lastHandlerKey]['type'];
00607                 switch($hType)  {
00608                         case 'native':
00609                                 $this->lastQuery = $this->SELECTquery($select_fields,$from_table,$where_clause,$groupBy,$orderBy,$limit);
00610                                 $sqlResult = mysql_query($this->lastQuery, $this->handlerInstance[$this->lastHandlerKey]['link']);
00611                                 $this->resourceIdToTableNameMap[(string)$sqlResult] = $ORIG_tableName;
00612                                 break;
00613                         case 'adodb':
00614                                 if ($limit!='') {
00615                                         $splitLimit = t3lib_div::intExplode(',',$limit);                // Splitting the limit values:
00616                                         if ($splitLimit[1])     {       // If there are two parameters, do mapping differently than otherwise:
00617                                                 $numrows = $splitLimit[1];
00618                                                 $offset = $splitLimit[0];
00619                                         } else {
00620                                                 $numrows = $splitLimit[0];
00621                                                 $offset = 0;
00622                                         }
00623 
00624                                         $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->SelectLimit($this->SELECTquery($select_fields,$from_table,$where_clause,$groupBy,$orderBy), $numrows, $offset);
00625                                         $this->lastQuery = $sqlResult->sql;
00626                                 } else {
00627                                         $this->lastQuery = $this->SELECTquery($select_fields,$from_table,$where_clause,$groupBy,$orderBy);
00628                                         $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->_Execute($this->lastQuery);
00629                                 }
00630                                 $sqlResult->TYPO3_DBAL_handlerType = 'adodb';   // Setting handler type in result object (for later recognition!)
00631                                 $sqlResult->TYPO3_DBAL_tableList = $ORIG_tableName;
00632                                 break;
00633                         case 'userdefined':
00634                                 $sqlResult = $this->handlerInstance[$this->lastHandlerKey]->exec_SELECTquery($select_fields,$from_table,$where_clause,$groupBy,$orderBy,$limit);
00635                                 if (is_object($sqlResult))      {
00636                                         $sqlResult->TYPO3_DBAL_handlerType = 'userdefined';     // Setting handler type in result object (for later recognition!)
00637                                         $sqlResult->TYPO3_DBAL_tableList = $ORIG_tableName;
00638                                 }
00639                                 break;
00640                 }
00641 
00642                 if ($this->printErrors && $this->sql_error())   {
00643                         debug(array($this->lastQuery, $this->sql_error()));
00644                 }
00645 
00646                 if ($this->debug)       {
00647                         $this->debugHandler(
00648                         'exec_SELECTquery',
00649                         t3lib_div::milliseconds()-$pt,
00650                         array(
00651                         'handlerType' => $hType,
00652                         'args' => array($from_table,$select_fields,$where_clause,$groupBy,$orderBy,$limit),
00653                         'ORIG_from_table' => $ORIG_tableName
00654                         )
00655                         );
00656                 }
00657 
00658                 // Return result handler.
00659                 return $sqlResult;
00660         }
00661 
00662 
00663 
00664         /**************************************
00665         *
00666         * Query building
00667         *
00668         **************************************/
00669 
00680         function INSERTquery($table,$fields_values,$no_quote_fields='') {
00681                 // Table and fieldnames should be "SQL-injection-safe" when supplied to this function (contrary to values in the arrays which may be insecure).
00682                 if (is_array($fields_values) && count($fields_values))  {
00683 
00684                         if (is_string($no_quote_fields))        {
00685                                 $no_quote_fields = explode(',',$no_quote_fields);
00686                         } elseif (!is_array($no_quote_fields))  {
00687                                 $no_quote_fields = array();
00688                         }
00689 
00690                         $blobfields = array();
00691                         $nArr = array();
00692                         foreach($fields_values as $k => $v)     {
00693                                 if($this->sql_field_metatype($table,$k) == 'B') {
00694                                         /* // is this really needed for Oracle?
00695                                         if($this->handlerInstance[$this->lastHandlerKey]->databaseType == 'oci8')
00696                                         $nArr[$this->quoteFieldNames($k)] = 'empty_blob()';
00697                                         else
00698                                         $nArr[$this->quoteFieldNames($k)] = 'null';
00699                                         */
00700                                         $nArr[$this->quoteFieldNames($k)] = 'null';
00701                                         $blobfields[$this->quoteFieldNames($k)] = $v;
00702                                 }
00703                                 else {
00704                                         // Add slashes old-school:
00705                                         // cast numerical values
00706                                         $mt = $this->sql_field_metatype($table,$k);
00707                                         $v = (($mt{0}=='I')||($mt{0}=='F')) ? (int)$v : $v;
00708 
00709                                         $nArr[$this->quoteFieldNames($k)] = (!in_array($k,$no_quote_fields)) ? $this->fullQuoteStr($v, $table) : $v;
00710                                 }
00711                         }
00712                         if(((string)$this->handlerCfg[$this->lastHandlerKey]['type']!=='native') && count($blobfields)) {
00713                                 $query[0] = 'INSERT INTO '.$this->quoteFromTables($table).'
00714                                 (
00715                                         '.implode(',
00716                                         ',array_keys($nArr)).'
00717                                 ) VALUES (
00718                                         '.implode(',
00719                                         ',$nArr).'
00720                                 )';
00721                                 $query[1] = $blobfields;
00722                                 if ($this->debugOutput) $this->debug_lastBuiltQuery = $query[0];
00723                         }
00724                         else {
00725                                 $query = 'INSERT INTO '.$this->quoteFromTables($table).'
00726                                 (
00727                                         '.implode(',
00728                                         ',array_keys($nArr)).'
00729                                 ) VALUES (
00730                                         '.implode(',
00731                                         ',$nArr).'
00732                                 )';
00733 
00734                                 if ($this->debugOutput) $this->debug_lastBuiltQuery = $query;
00735                         }
00736 
00737                         return $query;
00738                 }
00739         }
00740 
00752         function UPDATEquery($table,$where,$fields_values,$no_quote_fields='')  {
00753                 // Table and fieldnames should be "SQL-injection-safe" when supplied to this function (contrary to values in the arrays which may be insecure).
00754                 if (is_string($where))  {
00755                         if (is_array($fields_values) && count($fields_values))  {
00756 
00757                                 if (is_string($no_quote_fields))        {
00758                                         $no_quote_fields = explode(',',$no_quote_fields);
00759                                 } elseif (!is_array($no_quote_fields))  {
00760                                         $no_quote_fields = array();
00761                                 }
00762 
00763                                 $blobfields = array();
00764                                 $nArr = array();
00765                                 foreach($fields_values as $k => $v)     {
00766                                         if($this->sql_field_metatype($table,$k) == 'B') {
00767                                                 // do we need empty_blob() for Oracle? see also INSERTquery()
00768                                                 $nArr[] = $this->quoteFieldNames($k).'=NULL';
00769                                                 $blobfields[$this->quoteFieldNames($k)] = $v;
00770                                         }
00771                                         else {
00772                                                 // Add slashes old-school:
00773                                                 // cast numeric values
00774                                                 $mt = $this->sql_field_metatype($table,$k);
00775                                                 $v = (($mt{0}=='I')||($mt{0}=='F')) ? (int)$v : $v;
00776                                                 $nArr[] = $this->quoteFieldNames($k).'='.((!in_array($k,$no_quote_fields)) ? $this->fullQuoteStr($v, $table) : $v);
00777                                         }
00778                                 }
00779 
00780                                 if(count($blobfields)) {
00781                                         $query[0] = 'UPDATE '.$this->quoteFromTables($table).'
00782                                         SET
00783                                                 '.implode(',
00784                                                 ',$nArr).
00785                                                 (strlen($where)>0 ? '
00786                                         WHERE
00787                                                 '.$this->quoteWhereClause($where) : '');
00788                                                 $query[1] = $blobfields;
00789                                                 if ($this->debugOutput) $this->debug_lastBuiltQuery = $query[0];
00790                                 }
00791                                 else {
00792                                         $query = 'UPDATE '.$this->quoteFromTables($table).'
00793                                         SET
00794                                                 '.implode(',
00795                                                 ',$nArr).
00796                                                 (strlen($where)>0 ? '
00797                                         WHERE
00798                                                 '.$this->quoteWhereClause($where) : '');
00799 
00800                                                 if ($this->debugOutput) $this->debug_lastBuiltQuery = $query;
00801                                 }
00802 
00803                                 return $query;
00804                         }
00805                 }
00806                 else {
00807                         die('<strong>TYPO3 Fatal Error:</strong> "Where" clause argument for UPDATE query was not a string in $this->UPDATEquery() !');
00808                 }
00809         }
00810 
00820         function DELETEquery($table,$where)     {
00821                 if (is_string($where))  {
00822                         $table = $this->quoteFromTables($table);
00823                         $where = $this->quoteWhereClause($where);
00824 
00825                         $query = parent::DELETEquery($table, $where);
00826 
00827                         if ($this->debugOutput) $this->debug_lastBuiltQuery = $query;
00828                         return $query;
00829                 } else {
00830                         die('<strong>TYPO3 Fatal Error:</strong> "Where" clause argument for DELETE query was not a string in $this->DELETEquery() !');
00831                 }
00832         }
00833 
00847         function SELECTquery($select_fields,$from_table,$where_clause,$groupBy='',$orderBy='',$limit='')        {
00848 
00849                 $select_fields = $this->quoteFieldNames($select_fields);
00850                 $from_table = $this->quoteFromTables($from_table);
00851                 $where_clause = $this->quoteWhereClause($where_clause);
00852                 $groupBy = $this->quoteGroupBy($groupBy);
00853                 $orderBy = $this->quoteOrderBy($orderBy);
00854 
00855                 // call parent method to build actual query
00856                 $query = parent::SELECTquery($select_fields,$from_table,$where_clause,$groupBy,$orderBy,$limit);
00857 
00858                 if ($this->debugOutput) $this->debug_lastBuiltQuery = $query;
00859 
00860                 return $query;
00861         }
00862 
00863 
00864         /**************************************
00865         *
00866         * Functions for quoting table/field names
00867         *
00868         **************************************/
00869 
00878         function quoteSelectFields($select_fields) {
00879                 $this->quoteFieldNames($select_fields);
00880         }
00881 
00888         function quoteFieldNames($select_fields) {
00889                 if($select_fields == '') return '';
00890 
00891                 $select_fields = $this->SQLparser->parseFieldList($select_fields);
00892                 foreach($select_fields as $k => $v)     {
00893                         if($select_fields[$k]['field'] != '' && $select_fields[$k]['field'] != '*') {
00894                                 $select_fields[$k]['field'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$select_fields[$k]['field'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
00895                         }
00896                         if($select_fields[$k]['table'] != '') {
00897                                 $select_fields[$k]['table'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$select_fields[$k]['table'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
00898                         }
00899                         if($select_fields[$k]['as'] != '') {
00900                                 $select_fields[$k]['as'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$select_fields[$k]['as'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
00901                         }
00902                         if(isset($select_fields[$k]['func_content.']) && $select_fields[$k]['func_content.'][0]['func_content'] != '*'){
00903                                 if(strstr($select_fields[$k]['func_content.'][0]['func_content'],'.')) {
00904                                         $select_fields[$k]['func_content.'][0]['func_content'] = $this->quoteFieldNames($select_fields[$k]['func_content.'][0]['func_content']);
00905                                         $select_fields[$k]['func_content'] = $this->quoteFieldNames($select_fields[$k]['func_content']);
00906                                 }
00907                                 else {
00908                                         $select_fields[$k]['func_content.'][0]['func_content'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$select_fields[$k]['func_content.'][0]['func_content'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
00909                                         $select_fields[$k]['func_content'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$select_fields[$k]['func_content'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
00910                                 }
00911                         }
00912                 }
00913 
00914                 return $this->SQLparser->compileFieldList($select_fields);
00915         }
00916 
00923         function quoteFromTables($from_table) {
00924                 if($from_table == '') return '';
00925 
00926                 $from_table = $this->SQLparser->parseFromTables($from_table);
00927                 foreach($from_table as $k => $v)        {
00928                         $from_table[$k]['table'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$from_table[$k]['table'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
00929                         if($from_table[$k]['as'] != '') {
00930                                 $from_table[$k]['as'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$from_table[$k]['as'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
00931                         }
00932                         if (is_array($v['JOIN']))       {
00933                                 $from_table[$k]['JOIN']['withTable'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$from_table[$k]['JOIN']['withTable'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
00934                                 $from_table[$k]['JOIN']['ON'][0]['table'] = ($from_table[$k]['JOIN']['ON'][0]['table']) ? $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$from_table[$k]['JOIN']['ON'][0]['table'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote : '';
00935                                 $from_table[$k]['JOIN']['ON'][0]['field'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$from_table[$k]['JOIN']['ON'][0]['field'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
00936                                 $from_table[$k]['JOIN']['ON'][1]['table'] = ($from_table[$k]['JOIN']['ON'][1]['table']) ? $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$from_table[$k]['JOIN']['ON'][1]['table'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote : '';
00937                                 $from_table[$k]['JOIN']['ON'][1]['field'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$from_table[$k]['JOIN']['ON'][1]['field'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
00938                         }
00939                 }
00940                 return $this->SQLparser->compileFromTables($from_table);
00941         }
00942 
00949         function quoteWhereClause($where_clause) {
00950                 if($where_clause == '') return '';
00951 
00952                 $where_clause = $this->SQLparser->parseWhereClause($where_clause);
00953                 $where_clause = $this->_quoteWhereClause($where_clause);
00954                 $where_clause = $this->SQLparser->compileWhereClause($where_clause);
00955 
00956                 return $where_clause;
00957         }
00958 
00965         function _quoteWhereClause($where_clause) {
00966                 foreach($where_clause as $k => $v)      {
00967                         // Look for sublevel:
00968                         if (is_array($where_clause[$k]['sub'])) {
00969                                 $where_clause[$k]['sub'] = $this->_quoteWhereClause($where_clause[$k]['sub']);
00970                         } else {
00971                                 if($where_clause[$k]['table'] != '') {
00972                                         $where_clause[$k]['table'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$where_clause[$k]['table'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
00973                                 }
00974                                 if(!is_numeric($where_clause[$k]['field'])) {
00975                                         $where_clause[$k]['field'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$where_clause[$k]['field'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
00976                                 }
00977                         }
00978                         if ($where_clause[$k]['comparator'])    {
00979                                 // Detecting value type; list or plain:
00980                                 if ((!isset($where_clause[$k]['value'][1]) || $where_clause[$k]['value'][1] == '') && is_string($where_clause[$k]['value'][0]) && strstr($where_clause[$k]['value'][0], '.') && !t3lib_div::inList('NOTIN,IN',strtoupper(str_replace(array(" ","\n","\r","\t"),'',$where_clause[$k]['comparator']))))   {
00981                                         $where_clause[$k]['value'][0] = $this->quoteFieldNames($where_clause[$k]['value'][0]);
00982                                 }
00983                         }
00984                 }
00985 
00986                 return $where_clause;
00987         }
00988 
00995         function quoteGroupBy($groupBy) {
00996                 if($groupBy == '') return '';
00997 
00998                 $groupBy = $this->SQLparser->parseFieldList($groupBy);
00999                 foreach($groupBy as $k => $v)   {
01000                         $groupBy[$k]['field'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$groupBy[$k]['field'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
01001                         if($groupBy[$k]['table'] != '') {
01002                                 $groupBy[$k]['table'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$groupBy[$k]['table'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
01003                         }
01004                 }
01005                 return $this->SQLparser->compileFieldList($groupBy);
01006         }
01007 
01014         function quoteOrderBy($orderBy) {
01015                 if($orderBy == '') return '';
01016 
01017                 $orderBy = $this->SQLparser->parseFieldList($orderBy);
01018                 foreach($orderBy as $k => $v)   {
01019                         $orderBy[$k]['field'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$orderBy[$k]['field'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
01020                         if($orderBy[$k]['table'] != '') {
01021                                 $orderBy[$k]['table'] = $this->handlerInstance[$this->lastHandlerKey]->nameQuote.$orderBy[$k]['table'].$this->handlerInstance[$this->lastHandlerKey]->nameQuote;
01022                         }
01023                 }
01024                 return $this->SQLparser->compileFieldList($orderBy);
01025         }
01026 
01027 
01028 
01029         /**************************************
01030         *
01031         * Various helper functions
01032         *
01033         **************************************/
01034 
01043         function fullQuoteStr($str,$table) {
01044                 return '\''.$this->quoteStr($str, $table).'\'';
01045         }
01046 
01056         function quoteStr($str, $table) {
01057                 $this->lastHandlerKey = $this->handler_getFromTableList($table);
01058                 switch((string)$this->handlerCfg[$this->lastHandlerKey]['type'])        {
01059                         case 'native':
01060                                 $str = mysql_real_escape_string($str, $this->handlerInstance[$this->lastHandlerKey]['link']);
01061                                 break;
01062                         case 'adodb':
01063                                 $str = substr($this->handlerInstance[$this->lastHandlerKey]->qstr($str),1,-1);
01064                                 break;
01065                         case 'userdefined':
01066                                 $str = $this->handlerInstance[$this->lastHandlerKey]->quoteStr($str);
01067                                 break;
01068                         default:
01069                                 die('No handler found!!!');
01070                                 break;
01071                 }
01072 
01073                 return $str;
01074         }
01075 
01076 
01084         function MetaType($type,$table,$max_length=-1)  {
01085                 $this->lastHandlerKey = $this->handler_getFromTableList($table);
01086                 switch((string)$this->handlerCfg[$this->lastHandlerKey]['type'])        {
01087                         case 'adodb':
01088                         $rs = $this->handlerInstance[$this->lastHandlerKey]->SelectLimit('SELECT * FROM '.$this->quoteFromTables($table),1);
01089                         $str = $rs->MetaType($type, $max_length);
01090                         break;
01091                         default:
01092                         die('No handler found!!!');
01093                         break;
01094                 }
01095 
01096                 return $str;
01097         }
01098 
01099 
01106         function MySQLMetaType($t) {
01107 
01108                 switch (strtoupper($t)) {
01109                         case 'STRING':
01110                         case 'CHAR':
01111                         case 'VARCHAR':
01112                         case 'TINYBLOB':
01113                         case 'TINYTEXT':
01114                         case 'ENUM':
01115                         case 'SET':
01116                         return 'C';
01117 
01118                         case 'TEXT':
01119                         case 'LONGTEXT':
01120                         case 'MEDIUMTEXT':
01121                         return 'X';
01122 
01123                         // php_mysql extension always returns 'blob' even if 'text'
01124                         // so we have to check whether binary...
01125                         case 'IMAGE':
01126                         case 'LONGBLOB':
01127                         case 'BLOB':
01128                         case 'MEDIUMBLOB':
01129                         return 'B';
01130 
01131                         case 'YEAR':
01132                         case 'DATE': return 'D';
01133 
01134                         case 'TIME':
01135                         case 'DATETIME':
01136                         case 'TIMESTAMP': return 'T';
01137 
01138                         case 'FLOAT':
01139                         case 'DOUBLE':
01140                         return 'F';
01141 
01142                         case 'INT':
01143                         case 'INTEGER': return 'I';
01144                         case 'TINYINT': // MS SQL Server allows only 0..255 for tinyint, so we do not map to I1
01145                         case 'SMALLINT': return 'I2';
01146                         case 'MEDIUMINT': return 'I4';
01147                         case 'BIGINT': return 'I8';
01148 
01149                         default: return 'N';
01150                 }
01151         }
01152 
01159         function MySQLActualType($meta) {
01160                 switch(strtoupper($meta)) {
01161                         case 'C': return 'VARCHAR';
01162                         case 'XL':
01163                         case 'X': return 'LONGTEXT';
01164 
01165                         case 'C2': return 'VARCHAR';
01166                         case 'X2': return 'LONGTEXT';
01167 
01168                         case 'B': return 'LONGBLOB';
01169 
01170                         case 'D': return 'DATE';
01171                         case 'T': return 'DATETIME';
01172                         case 'L': return 'TINYINT';
01173 
01174                         case 'I': return 'INT';
01175                         case 'I1': // MS SQL Server allows only 0..255 for tinyint, so we do not map to TINYINT
01176                         case 'I2': return 'SMALLINT';
01177                         case 'I4': return 'MEDIUMINT';
01178                         case 'I8': return 'BIGINT';
01179 
01180                         case 'F': return 'DOUBLE';
01181                         case 'N': return 'NUMERIC';
01182                         default:
01183                         return $meta;
01184                 }
01185         }
01186 
01187 
01188 
01189 
01190         /**************************************
01191         *
01192         * SQL wrapper functions (Overriding parent methods)
01193         * (For use in your applications)
01194         *
01195         **************************************/
01196 
01202         function sql_error()    {
01203 
01204                 switch($this->handlerCfg[$this->lastHandlerKey]['type'])        {
01205                         case 'native':
01206                                 $output = mysql_error($this->handlerInstance[$this->lastHandlerKey]['link']);
01207                                 break;
01208                         case 'adodb':
01209                                 $output = $this->handlerInstance[$this->lastHandlerKey]->ErrorMsg();
01210                                 break;
01211                         case 'userdefined':
01212                                 $output = $this->handlerInstance[$this->lastHandlerKey]->sql_error();
01213                                 break;
01214                 }
01215                 return $output;
01216         }
01217 
01224         function sql_num_rows(&$res)    {
01225 
01226                 $handlerType = is_object($res) ? $res->TYPO3_DBAL_handlerType : 'native';
01227                 switch($handlerType)    {
01228                         case 'native':
01229                                 $output = mysql_num_rows($res);
01230                                 break;
01231                         case 'adodb':
01232                                 $output = method_exists($res, 'RecordCount') ? $res->RecordCount() : 0;
01233                                 break;
01234                         case 'userdefined':
01235                                 $output = $res->sql_num_rows();
01236                                 break;
01237                 }
01238                 return $output;
01239         }
01240 
01247         function sql_fetch_assoc(&$res) {
01248                 $output = array();
01249 
01250                 $handlerType = is_object($res) ? $res->TYPO3_DBAL_handlerType : (is_resource($res) ? 'native' : false);
01251                 switch($handlerType)    {
01252                         case 'native':
01253                                 $output = mysql_fetch_assoc($res);
01254                                 $tableList = $this->resourceIdToTableNameMap[(string)$res];     // Reading list of tables from SELECT query:
01255                                 break;
01256                         case 'adodb':
01257                                         // Check if method exists for the current $res object.
01258                                         // If a table exists in TCA but not in the db, a error
01259                                         // occured because $res is not a valid object.
01260                                 if(method_exists($res, 'FetchRow')) {
01261                                         $output = $res->FetchRow();
01262                                         $tableList = $res->TYPO3_DBAL_tableList;        // Reading list of tables from SELECT query:
01263 
01264                                                 // Removing all numeric/integer keys.
01265                                                 // A workaround because in ADOdb we would need to know what we want before executing the query...
01266                                         if (is_array($output))  {
01267                                                 foreach($output as $key => $value)      {
01268                                                         if (is_integer($key))   unset($output[$key]);
01269                                                         elseif($value===' ' && strstr($GLOBALS['TYPO3_DB']->handlerCfg[$GLOBALS['TYPO3_DB']->lastHandlerKey]['config']['driver'],'mssql')) $output[$key]=''; // MSSQL does not know such thing as an empty string. So it returns one space instead, which we must fix.
01270                                                 }
01271                                         }
01272                                 }
01273                                 break;
01274                         case 'userdefined':
01275                                 $output = $res->sql_fetch_assoc();
01276                                 $tableList = $res->TYPO3_DBAL_tableList;        // Reading list of tables from SELECT query:
01277                                 break;
01278                 }
01279 
01280                 // Table/Fieldname mapping:
01281                 if (is_array($output))  {
01282                         if ($tables = $this->map_needMapping($tableList,TRUE))  {
01283                                 $output = $this->map_assocArray($output,$tables,1);
01284                         }
01285                 }
01286 
01287                 // Return result:
01288                 return $output;
01289         }
01290 
01298         function sql_fetch_row(&$res)   {
01299                 $handlerType = is_object($res) ? $res->TYPO3_DBAL_handlerType :  'native';
01300                 switch($handlerType)    {
01301                         case 'native':
01302                                 $output = mysql_fetch_row($res);
01303                                 break;
01304                         case 'adodb':
01305                                         // Check if method exists for the current $res object.
01306                                         // If a table exists in TCA but not in the db, a error
01307                                         // occured because $res is not a valid object.
01308                                 if(method_exists($res, 'FetchRow')) {
01309                                         $output = $res->FetchRow();
01310 
01311                                                 // Removing all assoc. keys.
01312                                                 // A workaround because in ADOdb we would need to know what we want before executing the query...
01313                                         if (is_array($output))  {
01314                                                 foreach($output as $key => $value)      {
01315                                                         if (!is_integer($key))  unset($output[$key]);
01316                                                         elseif($value===' ' && strstr($GLOBALS['TYPO3_DB']->handlerCfg[$GLOBALS['TYPO3_DB']->lastHandlerKey]['config']['driver'],'mssql')) $output[$key]=''; // MSSQL does not know such thing as an empty string. So it returns one space instead, which we must fix.
01317                                                 }
01318                                         }
01319                                 }
01320                                 break;
01321                         case 'userdefined':
01322                                 $output = $res->sql_fetch_row();
01323                                 break;
01324                 }
01325                 return $output;
01326         }
01327 
01334         function sql_free_result(&$res) {
01335 
01336                 $handlerType = is_object($res) ? $res->TYPO3_DBAL_handlerType :  'native';
01337                 switch($handlerType)    {
01338                         case 'native':
01339                                 $output = mysql_free_result($res);
01340                                 break;
01341                         case 'adodb':
01342                                 if(method_exists($res, 'Close')) {
01343                                         $res->Close();
01344                                         unset($res);
01345                                         $output = true;
01346                                 } else {
01347                                         $output = false;
01348                                 }
01349                                 break;
01350                         case 'userdefined':
01351                                 unset($res);
01352                                 break;
01353                 }
01354                 return $output;
01355         }
01356 
01362         function sql_insert_id()        {
01363 
01364                 switch($this->handlerCfg[$this->lastHandlerKey]['type'])        {
01365                         case 'native':
01366                                 $output = mysql_insert_id($this->handlerInstance[$this->lastHandlerKey]['link']);
01367                                 break;
01368                         case 'adodb':
01369                                 $output = $this->handlerInstance[$this->lastHandlerKey]->last_insert_id;
01370                                 break;
01371                         case 'userdefined':
01372                                 $output = $this->handlerInstance[$this->lastHandlerKey]->sql_insert_id();
01373                                 break;
01374                 }
01375                 return $output;
01376         }
01377 
01383         function sql_affected_rows()    {
01384 
01385                 switch($this->handlerCfg[$this->lastHandlerKey]['type'])        {
01386                         case 'native':
01387                                 $output = mysql_affected_rows();
01388                                 break;
01389                         case 'adodb':
01390                                 $output = $this->handlerInstance[$this->lastHandlerKey]->Affected_Rows();
01391                                 break;
01392                         case 'userdefined':
01393                                 $output = $this->handlerInstance[$this->lastHandlerKey]->sql_affected_rows();
01394                                 break;
01395                 }
01396                 return $output;
01397         }
01398 
01406         function sql_data_seek(&$res,$seek)     {
01407 
01408                 $handlerType = is_object($res) ? $res->TYPO3_DBAL_handlerType :  'native';
01409                 switch($handlerType)    {
01410                         case 'native':
01411                                 $output = mysql_data_seek($res,$seek);
01412                                 break;
01413                         case 'adodb':
01414                                 $output = $res->Move($seek);
01415                                 break;
01416                         case 'userdefined':
01417                                 $output = $res->sql_data_seek($seek);
01418                                 break;
01419                 }
01420                 return $output;
01421         }
01422 
01432         function sql_field_metatype($table,$field)      {
01433                 return $this->cache_fieldType[$table][$field]['metaType'];
01434         }
01435 
01445         function sql_field_type(&$res,$pointer) {
01446                 if($res === null) {
01447                         debug(array('no res in sql_field_type!'));
01448                         return 'text';
01449                 }
01450                 else if(is_string($res)){
01451                         if($res == 'tx_dbal_debuglog') return 'text';
01452                         $handlerType = 'adodb';
01453                 }
01454                 else {
01455                         $handlerType = is_object($res) ? $res->TYPO3_DBAL_handlerType :  'native';
01456                 }
01457 
01458                 switch($handlerType)    {
01459                         case 'native':
01460                                 $output = mysql_field_type($res,$pointer);
01461                                 break;
01462                         case 'adodb':
01463                                 if(is_string($pointer)){
01464                                         $output = $this->cache_fieldType[$res][$pointer]['type'];
01465                                 }
01466 
01467                                 break;
01468                         case 'userdefined':
01469                                 $output = $res->sql_field_type($pointer);
01470                                 break;
01471                 }
01472 
01473                 return $output;
01474         }
01475 
01476 
01477 
01478 
01479 
01480 
01481 
01482 
01483         /**********
01484         *
01485         * Legacy functions, bound to _DEFAULT handler. (Overriding parent methods)
01486         * Depreciated.
01487         *
01488         **********/
01489 
01499         function sql($db,$query)        {
01500                 return $this->sql_query($query);
01501         }
01502 
01511         function sql_query($query)      {
01512 
01513                 switch($this->handlerCfg['_DEFAULT']['type'])   {
01514                         case 'native':
01515                                 $sqlResult = mysql_query($query, $this->handlerInstance['_DEFAULT']['link']);
01516                                 break;
01517                         case 'adodb':
01518                                 $sqlResult = $this->handlerInstance['_DEFAULT']->Execute($query);
01519                                 $sqlResult->TYPO3_DBAL_handlerType = 'adodb';
01520                                 break;
01521                         case 'userdefined':
01522                                 $sqlResult = $this->handlerInstance['_DEFAULT']->sql_query($query);
01523                                 $sqlResult->TYPO3_DBAL_handlerType = 'userdefined';
01524                                 break;
01525                 }
01526 
01527                 if ($this->printErrors && $this->sql_error())   {
01528                         debug(array($this->lastQuery, $this->sql_error()));
01529                 }
01530 
01531                 return $sqlResult;
01532         }
01533 
01546         function sql_pconnect($TYPO3_db_host, $TYPO3_db_username, $TYPO3_db_password)   {
01547                 // Overriding the _DEFAULT handler configuration of username, password, localhost and database name:
01548                 $this->handlerCfg['_DEFAULT']['config']['username'] = $TYPO3_db_username;
01549                 $this->handlerCfg['_DEFAULT']['config']['password'] = $TYPO3_db_password;
01550                 $this->handlerCfg['_DEFAULT']['config']['host'] = $TYPO3_db_host;
01551                 $this->handlerCfg['_DEFAULT']['config']['database'] = TYPO3_db;
01552 
01553                 // Initializing and output value:
01554                 $sqlResult = $this->handler_init('_DEFAULT');
01555                 return $sqlResult;
01556         }
01557 
01565         function sql_select_db($TYPO3_db)       {
01566                 return TRUE;
01567         }
01568 
01569 
01570 
01571 
01572 
01573 
01574 
01575 
01576 
01577 
01578 
01579 
01580 
01581 
01582 
01583         /**************************************
01584         *
01585         * SQL admin functions
01586         * (For use in the Install Tool and Extension Manager)
01587         *
01588         **************************************/
01589 
01597         function admin_get_dbs()        {
01598                 $dbArr = array();
01599                 switch($this->handlerCfg['_DEFAULT']['type'])   {
01600                         case 'native':
01601                                 $db_list = mysql_list_dbs($this->link);
01602                                 while ($row = mysql_fetch_object($db_list)) {
01603                                         if ($this->sql_select_db($row->Database))       {
01604                                                 $dbArr[] = $row->Database;
01605                                         }
01606                                 }
01607                                 break;
01608                         case 'adodb':
01609                                         // check needed for install tool - otherwise it will just die because the call to
01610                                         // MetaDatabases is done on a stdClass instance
01611                                 if(method_exists($this->handlerInstance['_DEFAULT'],'MetaDatabases')) {
01612                                         $sqlDBs = $this->handlerInstance['_DEFAULT']->MetaDatabases();
01613                                         if(is_array($sqlDBs)) {
01614                                                 foreach($sqlDBs as $k => $theDB) {
01615                                                         $dbArr[] = $theDB;
01616                                                 }
01617                                         }
01618                                 }
01619                                 break;
01620                         case 'userdefined':
01621                                 $dbArr = $this->handlerInstance['_DEFAULT']->admin_get_tables();
01622                                 break;
01623                 }
01624 
01625                 return $dbArr;
01626         }
01627 
01634         function admin_get_tables()     {
01635                 $whichTables = array();
01636 
01637                 // Getting real list of tables:
01638                 switch($this->handlerCfg['_DEFAULT']['type'])   {
01639                         case 'native':
01640                                 $tables_result = mysql_list_tables(TYPO3_db, $this->handlerInstance['_DEFAULT']['link']);
01641                                 if (!$this->sql_error())        {
01642                                         while ($theTable = $this->sql_fetch_assoc($tables_result)) {
01643                                                 $whichTables[current($theTable)] = current($theTable);
01644                                         }
01645                                 }
01646                                 break;
01647                         case 'adodb':
01648                                 $sqlTables = $this->handlerInstance['_DEFAULT']->MetaTables('TABLES');
01649                                 while (list($k, $theTable) = each($sqlTables)) {
01650                                         $whichTables[$theTable] = $theTable;
01651                                 }
01652                                 break;
01653                         case 'userdefined':
01654                                 $whichTables = $this->handlerInstance['_DEFAULT']->admin_get_tables();
01655                                 break;
01656                 }
01657 
01658                 // Check mapping:
01659                 if (is_array($this->mapping))   {
01660 
01661                         // Mapping table names in reverse, first getting list of real table names:
01662                         $tMap = array();
01663                         foreach($this->mapping as $tN => $tMapInfo)     {
01664                                 if (isset($tMapInfo['mapTableName']))   $tMap[$tMapInfo['mapTableName']]=$tN;
01665                         }
01666 
01667                         // Do mapping:
01668                         $newList=array();
01669                         foreach($whichTables as $tN)    {
01670                                 if (isset($tMap[$tN]))  $tN = $tMap[$tN];
01671                                 $newList[$tN] = $tN;
01672                         }
01673 
01674                         $whichTables = $newList;
01675                 }
01676 
01677                 // Adding tables configured to reside in other DBMS (handler by other handlers than the default):
01678                 if (is_array($this->table2handlerKeys)) {
01679                         foreach($this->table2handlerKeys as $key => $handlerKey)        {
01680                                 $whichTables[$key] = $key;
01681                         }
01682                 }
01683 
01684                 return $whichTables;
01685         }
01686 
01695         function admin_get_fields($tableName)   {
01696                 $output = array();
01697 
01698                 // Do field mapping if needed:
01699                 $ORIG_tableName = $tableName;
01700                 if ($tableArray = $this->map_needMapping($tableName))   {
01701 
01702                         // Table name:
01703                         if ($this->mapping[$tableName]['mapTableName']) {
01704                                 $tableName = $this->mapping[$tableName]['mapTableName'];
01705                         }
01706                 }
01707 
01708                 // Find columns
01709                 $this->lastHandlerKey = $this->handler_getFromTableList($ORIG_tableName);
01710                 switch((string)$this->handlerCfg[$this->lastHandlerKey]['type'])        {
01711                         case 'native':
01712                                 $columns_res = mysql_query('SHOW columns FROM '.$tableName, $this->handlerInstance[$this->lastHandlerKey]['link']);
01713                                 while($fieldRow = mysql_fetch_assoc($columns_res))      {
01714                                         $output[$fieldRow['Field']] = $fieldRow;
01715                                 }
01716                                 break;
01717                         case 'adodb':
01718                                 $fieldRows = $this->handlerInstance[$this->lastHandlerKey]->MetaColumns($tableName, false);
01719                                 foreach($fieldRows as $k => $fieldRow) {
01720                                         settype($fieldRow, 'array');
01721                                         $fieldRow['Field'] = $fieldRow['name'];
01722                                         $ntype = $this->MySQLActualType($this->MetaType($fieldRow['type'],$tableName));
01723                                         $ntype .= (($fieldRow['max_length'] != -1) ? (($ntype == 'INT') ? '(11)' :'('.$fieldRow['max_length'].')') : '');
01724                                         $fieldRow['Type'] = strtolower($ntype);
01725                                         $fieldRow['Null'] = '';
01726                                         $fieldRow['Key'] = '';
01727                                         $fieldRow['Default'] = $fieldRow['default_value'];
01728                                         $fieldRow['Extra'] = '';
01729                                         $output[$fieldRow['name']] = $fieldRow;
01730                                 }
01731                                 break;
01732                         case 'userdefined':
01733                                 $output = $this->handlerInstance[$this->lastHandlerKey]->admin_get_fields($tableName);
01734                                 break;
01735                 }
01736 
01737                 // mapping should be done:
01738                 if (is_array($tableArray) && is_array($this->mapping[$ORIG_tableName]['mapFieldNames']))        {
01739                         $revFields = array_flip($this->mapping[$ORIG_tableName]['mapFieldNames']);
01740 
01741                         $newOutput = array();
01742                         foreach($output as $fN => $fInfo)       {
01743                                 if (isset($revFields[$fN]))     {
01744                                         $fN = $revFields[$fN];
01745                                         $fInfo['Field'] = $fN;
01746                                 }
01747                                 $newOutput[$fN] = $fInfo;
01748                         }
01749                         $output = $newOutput;
01750                 }
01751 
01752                 return $output;
01753         }
01754 
01762         function admin_get_keys($tableName)     {
01763                 $output = array();
01764 
01765                 // Do field mapping if needed:
01766                 $ORIG_tableName = $tableName;
01767                 if ($tableArray = $this->map_needMapping($tableName))   {
01768 
01769                         // Table name:
01770                         if ($this->mapping[$tableName]['mapTableName']) {
01771                                 $tableName = $this->mapping[$tableName]['mapTableName'];
01772                         }
01773                 }
01774 
01775                 // Find columns
01776                 $this->lastHandlerKey = $this->handler_getFromTableList($ORIG_tableName);
01777                 switch((string)$this->handlerCfg[$this->lastHandlerKey]['type'])        {
01778                         case 'native':
01779                         $keyRes = mysql_query('SHOW keys FROM '.$tableName, $this->handlerInstance[$this->lastHandlerKey]['link']);
01780                         while($keyRow = mysql_fetch_assoc($keyRes))     {
01781                                 $output[] = $keyRow;
01782                         }
01783                         break;
01784                         case 'adodb':
01785                         $keyRows = $this->handlerInstance[$this->lastHandlerKey]->MetaIndexes($tableName);
01786                         if($keyRows !== false) {
01787                                 while (list($k, $theKey) = each($keyRows)) {
01788                                         $theKey['Table'] = $tableName;
01789                                         $theKey['Non_unique'] = (int) !$theKey['unique'];
01790                                         $theKey['Key_name'] = str_replace($tableName.'_','',$k);
01791 
01792                                         // the following are probably not needed anyway...
01793                                         $theKey['Collation'] = '';
01794                                         $theKey['Cardinality'] = '';
01795                                         $theKey['Sub_part'] = '';
01796                                         $theKey['Packed'] = '';
01797                                         $theKey['Null'] = '';
01798                                         $theKey['Index_type'] = '';
01799                                         $theKey['Comment'] = '';
01800 
01801                                         // now map multiple fields into multiple rows (we mimic MySQL, remember...)
01802                                         $keycols = $theKey['columns'];
01803                                         while (list($c, $theCol) = each($keycols)) {
01804                                                 $theKey['Seq_in_index'] = $c+1;
01805                                                 $theKey['Column_name'] = $theCol;
01806                                                 $output[] = $theKey;
01807                                         }
01808                                 }
01809                         }
01810                         $priKeyRow = $this->handlerInstance[$this->lastHandlerKey]->MetaPrimaryKeys($tableName);
01811                         $theKey = array();
01812                         $theKey['Table'] = $tableName;
01813                         $theKey['Non_unique'] = 0;
01814                         $theKey['Key_name'] = 'PRIMARY';
01815 
01816                         // the following are probably not needed anyway...
01817                         $theKey['Collation'] = '';
01818                         $theKey['Cardinality'] = '';
01819                         $theKey['Sub_part'] = '';
01820                         $theKey['Packed'] = '';
01821                         $theKey['Null'] = '';
01822                         $theKey['Index_type'] = '';
01823                         $theKey['Comment'] = '';
01824 
01825                         // now map multiple fields into multiple rows (we mimic MySQL, remember...)
01826                         if($priKeyRow !== false) {
01827                                 while (list($c, $theCol) = each($priKeyRow)) {
01828                                         $theKey['Seq_in_index'] = $c+1;
01829                                         $theKey['Column_name'] = $theCol;
01830                                         $output[] = $theKey;
01831                                 }
01832                         }
01833                         break;
01834                         case 'userdefined':
01835                         $output = $this->handlerInstance[$this->lastHandlerKey]->admin_get_keys($tableName);
01836                         break;
01837                 }
01838 
01839                 // mapping should be done:
01840                 if (is_array($tableArray) && is_array($this->mapping[$ORIG_tableName]['mapFieldNames']))        {
01841                         $revFields = array_flip($this->mapping[$ORIG_tableName]['mapFieldNames']);
01842 
01843                         $newOutput = array();
01844                         foreach($output as $kN => $kInfo)       {
01845                                 // Table:
01846                                 $kInfo['Table'] = $ORIG_tableName;
01847 
01848                                 // Column
01849                                 if (isset($revFields[$kInfo['Column_name']]))   {
01850                                         $kInfo['Column_name'] = $revFields[$kInfo['Column_name']];
01851                                 }
01852 
01853                                 // Write it back:
01854                                 $newOutput[$kN] = $kInfo;
01855                         }
01856                         $output = $newOutput;
01857                 }
01858 
01859                 return $output;
01860         }
01861 
01868         function admin_query($query)    {
01869                 $parsedQuery = $this->SQLparser->parseSQL($query);
01870                 $ORIG_table = $parsedQuery['TABLE'];
01871 
01872                 if (is_array($parsedQuery))     {
01873 
01874                         // Process query based on type:
01875                         switch($parsedQuery['type'])    {
01876                                 case 'CREATETABLE':
01877                                 case 'ALTERTABLE':
01878                                 case 'DROPTABLE':
01879                                         if(file_exists(PATH_typo3conf.'temp_fieldInfo.php')) unlink(PATH_typo3conf.'temp_fieldInfo.php');
01880                                         $this->map_genericQueryParsed($parsedQuery);
01881                                         break;
01882                                 case 'INSERT':
01883                                         $this->map_genericQueryParsed($parsedQuery);
01884                                         break;
01885                                 case 'CREATEDATABASE':
01886                                         die('Creating a database with DBAL is not supported. Did you really read the manual?');
01887                                         break;
01888                                 default:
01889                                         die('ERROR: Invalid Query type ('.$parsedQuery['type'].') for ->admin_query() function!: "'.htmlspecialchars($query).'"');
01890                                         break;
01891                         }
01892 
01893                         // Setting query array (for other applications to access if needed)
01894                         $this->lastParsedAndMappedQueryArray = $parsedQuery;
01895 
01896                         // Execute query (based on handler derived from the TABLE name which we actually know for once!)
01897                         $this->lastHandlerKey = $this->handler_getFromTableList($ORIG_table);
01898                         switch((string)$this->handlerCfg[$this->lastHandlerKey]['type'])        {
01899                                 case 'native':
01900                                         // Compiling query:
01901                                         $compiledQuery =  $this->SQLparser->compileSQL($this->lastParsedAndMappedQueryArray);
01902 
01903                                         return mysql_query($compiledQuery[0], $this->link);
01904                                         break;
01905                                 case 'adodb':
01906                                         // Compiling query:
01907                                         $compiledQuery =  $this->SQLparser->compileSQL($this->lastParsedAndMappedQueryArray);
01908                                         if($this->lastParsedAndMappedQueryArray['type']=='INSERT') {
01909                                                 return $this->exec_INSERTquery($this->lastParsedAndMappedQueryArray['TABLE'],$compiledQuery);
01910                                         }
01911                                         return $this->handlerInstance[$this->lastHandlerKey]->DataDictionary->ExecuteSQLArray($compiledQuery);
01912                                         break;
01913                                 case 'userdefined':
01914                                         // Compiling query:
01915                                         $compiledQuery =  $this->SQLparser->compileSQL($this->lastParsedAndMappedQueryArray);
01916 
01917                                         return $this->handlerInstance[$this->lastHandlerKey]->admin_query($compiledQuery);
01918                                         break;
01919                         }
01920                 } else die('ERROR: Query could not be parsed: "'.htmlspecialchars($parsedQuery).'". Query: "'.htmlspecialchars($query).'"');
01921         }
01922 
01923 
01924 
01925 
01926 
01927 
01928 
01929 
01930 
01931 
01932         /************************************
01933         *
01934         * Handler management
01935         *
01936         **************************************/
01937 
01945         function handler_getFromTableList($tableList)   {
01946 
01947                 $key = $tableList;
01948 
01949                 if (!isset($this->cache_handlerKeyFromTableList[$key])) {
01950 
01951                         // Get tables separated:
01952                         $_tableList = $tableList;
01953                         $tableArray = $this->SQLparser->parseFromTables($_tableList);
01954 
01955                         // If success, traverse the tables:
01956                         if (is_array($tableArray) && count($tableArray))        {
01957                                 foreach($tableArray as $vArray) {
01958 
01959                                         // Find handler key, select "_DEFAULT" if none is specifically configured:
01960                                         $handlerKey = $this->table2handlerKeys[$vArray['table']] ? $this->table2handlerKeys[$vArray['table']] : '_DEFAULT';
01961 
01962                                         // In case of separate handler keys for joined tables:
01963                                         if ($outputHandlerKey && $handlerKey != $outputHandlerKey)      {
01964                                                 die('DBAL fatal error: Tables in this list "'.$tableList.'" didn\'t use the same DB handler!');
01965                                         }
01966 
01967                                         $outputHandlerKey = $handlerKey;
01968                                 }
01969 
01970                                 // Check initialized state; if handler is NOT initialized (connected) then we will connect it!
01971                                 if (!isset($this->handlerInstance[$outputHandlerKey]))  {
01972                                         $this->handler_init($outputHandlerKey);
01973                                 }
01974 
01975                                 // Return handler key:
01976                                 $this->cache_handlerKeyFromTableList[$key] = $outputHandlerKey;
01977                         } else {
01978                                 die('DBAL fatal error: No tables found: "'.$tableList.'"');
01979                         }
01980                 }
01981 
01982                 return $this->cache_handlerKeyFromTableList[$key];
01983         }
01984 
01992         function handler_init($handlerKey)      {
01993 
01994                 // Find handler configuration:
01995                 $cfgArray = $this->handlerCfg[$handlerKey];
01996                 $handlerType = (string)$cfgArray['type'];
01997                 $output = FALSE;
01998 
01999                 if (is_array($cfgArray))        {
02000                         switch($handlerType)    {
02001                                 case 'native':
02002                                 $link = mysql_pconnect($cfgArray['config']['host'].(isset($cfgArray['config']['port']) ? ':'.$cfgArray['config']['port'] : ''), $cfgArray['config']['username'], $cfgArray['config']['password']);
02003 
02004                                 // Set handler instance:
02005                                 $this->handlerInstance[$handlerKey] = array('handlerType' => 'native', 'link' => $link);
02006 
02007                                 // If link succeeded:
02008                                 if ($link)      {
02009                                         // For default, set ->link (see t3lib_DB)
02010                                         if ($handlerKey == '_DEFAULT') {
02011                                                 $this->link = $link;
02012                                         }
02013 
02014                                         // Select database as well:
02015                                         if (mysql_select_db($cfgArray['config']['database'], $link))    {
02016                                                 $output = TRUE;
02017                                         }
02018                                         $setDBinit = t3lib_div::trimExplode(chr(10), $GLOBALS['TYPO3_CONF_VARS']['SYS']['setDBinit']);
02019                                         foreach ($setDBinit as $v)      {
02020                                                 if (mysql_query($v, $this->link) === FALSE)     {
02021                                                         t3lib_div::sysLog('Could not initialize DB connection with query "'.$v.'".','Core',3);
02022                                                 }
02023                                         }
02024                                 }
02025                                 break;
02026                                 case 'adodb':
02027                                 $output = true;
02028                                 require_once(t3lib_extMgm::extPath('adodb').'adodb/adodb.inc.php');
02029                                 if(!defined('ADODB_FORCE_NULLS')) define('ADODB_FORCE_NULLS', 1);
02030                                 $GLOBALS['ADODB_FORCE_TYPE'] = ADODB_FORCE_VALUE;
02031                                 $GLOBALS['ADODB_FETCH_MODE'] = ADODB_FETCH_BOTH;
02032 
02033                                 $this->handlerInstance[$handlerKey] = &ADONewConnection($cfgArray['config']['driver']);
02034                                 if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['no_pconnect'])  {
02035                                         $this->handlerInstance[$handlerKey]->Connect($cfgArray['config']['host'].(isset($cfgArray['config']['port']) ? ':'.$cfgArray['config']['port'] : ''),$cfgArray['config']['username'],$cfgArray['config']['password'],$cfgArray['config']['database']);
02036                                 } else {
02037                                         $this->handlerInstance[$handlerKey]->PConnect($cfgArray['config']['host'].(isset($cfgArray['config']['port']) ? ':'.$cfgArray['config']['port'] : ''),$cfgArray['config']['username'],$cfgArray['config']['password'],$cfgArray['config']['database']);
02038                                 }
02039                                 if(!$this->handlerInstance[$handlerKey]->isConnected()) {
02040                                         $dsn = $cfgArray['config']['driver'].'://'.$cfgArray['config']['username'].
02041                                                 (strlen($cfgArray['config']['password']) ? ':XXXX@' : '').
02042                                                 $cfgArray['config']['host'].(isset($cfgArray['config']['port']) ? ':'.$cfgArray['config']['port'] : '').'/'.$cfgArray['config']['database'].
02043                                                 ($GLOBALS['TYPO3_CONF_VARS']['SYS']['no_pconnect'] ? '' : '?persistent=1');
02044                                         error_log('DBAL error: Connection to '.$dsn.' failed. Maybe PHP doesn\'t support the database?');
02045                                         $output = false;
02046                                 } else {
02047                                         $this->handlerInstance[$handlerKey]->DataDictionary  = NewDataDictionary($this->handlerInstance[$handlerKey]);
02048                                         $this->handlerInstance[$handlerKey]->last_insert_id = 0;
02049                                 }
02050                                 break;
02051                                 case 'userdefined':
02052                                 // Find class file:
02053                                 $fileName = t3lib_div::getFileAbsFileName($cfgArray['config']['classFile']);
02054                                 if (@is_file($fileName))        {
02055                                         require_once($fileName);
02056                                 } else die('DBAL error: "'.$fileName.'" was not a file to include.');
02057 
02058                                 // Initialize:
02059                                 $this->handlerInstance[$handlerKey] = t3lib_div::makeInstance($cfgArray['config']['class']);
02060                                 $this->handlerInstance[$handlerKey]->init($cfgArray,$this);
02061 
02062                                 if (is_object($this->handlerInstance[$handlerKey]))             {
02063                                         $output = TRUE;
02064                                 }
02065                                 break;
02066                                 default:
02067                                 die('ERROR: Invalid handler type: "'.$cfgArray['type'].'"');
02068                                 break;
02069                         }
02070 
02071                         return $output;
02072                 } else die('ERROR: No handler for key "'.$handlerKey.'"');
02073         }
02074 
02075 
02076 
02077 
02078 
02079 
02080 
02081 
02082 
02083 
02084 
02085 
02086 
02087 
02088         /************************************
02089         *
02090         * Table/Field mapping
02091         *
02092         **************************************/
02093 
02101         function map_needMapping($tableList,$fieldMappingOnly=FALSE)    {
02102 
02103                 $key = $tableList.'|'.$fieldMappingOnly;
02104                 if (!isset($this->cache_mappingFromTableList[$key]))    {
02105                         $this->cache_mappingFromTableList[$key] = FALSE;        // Default:
02106 
02107                         $tables = $this->SQLparser->parseFromTables($tableList);
02108                         if (is_array($tables))  {
02109                                 foreach($tables as $tableCfg)   {
02110                                         if ($fieldMappingOnly)  {
02111                                                 if (is_array($this->mapping[$tableCfg['table']]['mapFieldNames']))      {
02112                                                         $this->cache_mappingFromTableList[$key] = $tables;
02113                                                 }
02114                                         } else {
02115                                                 if (is_array($this->mapping[$tableCfg['table']]))       {
02116                                                         $this->cache_mappingFromTableList[$key] = $tables;
02117                                                 }
02118                                         }
02119                                 }
02120                         }
02121                 }
02122 
02123                 return $this->cache_mappingFromTableList[$key];
02124         }
02125 
02137         function map_assocArray($input,$tables,$rev=FALSE)      {
02138 
02139                 // Traverse tables from query (hopefully only one table):
02140                 foreach($tables as $tableCfg)   {
02141                         if (is_array($this->mapping[$tableCfg['table']]['mapFieldNames']))      {
02142 
02143                                 // Get the map (reversed if needed):
02144                                 if ($rev)       {
02145                                         $theMap = array_flip($this->mapping[$tableCfg['table']]['mapFieldNames']);
02146                                 } else {
02147                                         $theMap = $this->mapping[$tableCfg['table']]['mapFieldNames'];
02148                                 }
02149 
02150                                 // Traverse selected record, map fieldnames:
02151                                 $output = array();
02152                                 foreach($input as $fN => $value)        {
02153 
02154                                         // Set the field name, change it if found in mapping array:
02155                                         if ($theMap[$fN])       {
02156                                                 $newKey = $theMap[$fN];
02157                                         } else {
02158                                                 $newKey = $fN;
02159                                         }
02160 
02161                                         // Set value to fieldname:
02162                                         $output[$newKey] = $value;
02163                                 }
02164 
02165                                 // When done, override the $input array with the result:
02166                                 $input = $output;
02167                         }
02168                 }
02169 
02170                 // Return input array (which might have been altered in the mean time)
02171                 return $input;
02172         }
02173 
02186         function map_remapSELECTQueryParts(&$select_fields,&$from_table,&$where_clause,&$groupBy,&$orderBy)     {
02187 
02188                 // Tables:
02189                 $tables = $this->SQLparser->parseFromTables($from_table);
02190                 $defaultTable = $tables[0]['table'];
02191                 foreach($tables as $k => $v)    {
02192                         if ($this->mapping[$v['table']]['mapTableName'])        {
02193                                 $tables[$k]['table'] = $this->mapping[$v['table']]['mapTableName'];
02194                         }
02195                 }
02196                 $from_table = $this->SQLparser->compileFromTables($tables);
02197 
02198                 // Where clause:
02199                 $whereParts = $this->SQLparser->parseWhereClause($where_clause);
02200                 $this->map_sqlParts($whereParts,$defaultTable);
02201                 $where_clause = $this->SQLparser->compileWhereClause($whereParts);
02202 
02203                 // Select fields:
02204                 $expFields = $this->SQLparser->parseFieldList($select_fields);
02205                 $this->map_sqlParts($expFields,$defaultTable);
02206                 $select_fields = $this->SQLparser->compileFieldList($expFields);
02207 
02208                 // Group By fields
02209                 $expFields = $this->SQLparser->parseFieldList($groupBy);
02210                 $this->map_sqlParts($expFields,$defaultTable);
02211                 $groupBy = $this->SQLparser->compileFieldList($expFields);
02212 
02213                 // Order By fields
02214                 $expFields = $this->SQLparser->parseFieldList($orderBy);
02215                 $this->map_sqlParts($expFields,$defaultTable);
02216                 $orderBy = $this->SQLparser->compileFieldList($expFields);
02217         }
02218 
02228         function map_sqlParts(&$sqlPartArray, $defaultTable)    {
02229 
02230                 // Traverse sql Part array:
02231                 if (is_array($sqlPartArray))    {
02232                         foreach($sqlPartArray as $k => $v)      {
02233 
02234                                 // Look for sublevel (WHERE parts only)
02235                                 if (is_array($sqlPartArray[$k]['sub'])) {
02236                                         $this->map_sqlParts($sqlPartArray[$k]['sub'], $defaultTable);   // Call recursively!
02237                                 } else {
02238                                         // For the field, look for table mapping (generic):
02239                                         $t = $sqlPartArray[$k]['table'] ? $sqlPartArray[$k]['table'] : $defaultTable;
02240 
02241                                         // Mapping field name, if set:
02242                                         if (is_array($this->mapping[$t]['mapFieldNames']) && $this->mapping[$t]['mapFieldNames'][$sqlPartArray[$k]['field']])   {
02243                                                 $sqlPartArray[$k]['field'] = $this->mapping[$t]['mapFieldNames'][$sqlPartArray[$k]['field']];
02244                                         }
02245 
02246                                         // Map table?
02247                                         if ($sqlPartArray[$k]['table'] && $this->mapping[$sqlPartArray[$k]['table']]['mapTableName'])   {
02248                                                 $sqlPartArray[$k]['table'] = $this->mapping[$sqlPartArray[$k]['table']]['mapTableName'];
02249                                         }
02250                                 }
02251                         }
02252                 }
02253         }
02254 
02263         function map_genericQueryParsed(&$parsedQuery)  {
02264 
02265                 // Getting table - same for all:
02266                 $table = $parsedQuery['TABLE'];
02267                 if ($table)     {
02268                         // Do field mapping if needed:
02269                         if ($tableArray = $this->map_needMapping($table))       {
02270 
02271                                 // Table name:
02272                                 if ($this->mapping[$table]['mapTableName'])     {
02273                                         $parsedQuery['TABLE'] = $this->mapping[$table]['mapTableName'];
02274                                 }
02275 
02276                                 // Based on type, do additional changes:
02277                                 switch($parsedQuery['type'])    {
02278                                         case 'ALTERTABLE':
02279 
02280                                         // Changing field name:
02281                                         $newFieldName = $this->mapping[$table]['mapFieldNames'][$parsedQuery['FIELD']];
02282                                         if ($newFieldName)      {
02283                                                 if ($parsedQuery['FIELD'] == $parsedQuery['newField'])  {
02284                                                         $parsedQuery['FIELD'] = $parsedQuery['newField'] = $newFieldName;
02285                                                 } else $parsedQuery['FIELD'] = $newFieldName;
02286                                         }
02287 
02288                                         // Changing key field names:
02289                                         if (is_array($parsedQuery['fields']))   {
02290                                                 $this->map_fieldNamesInArray($table,$parsedQuery['fields']);
02291                                         }
02292                                         break;
02293                                         case 'CREATETABLE':
02294                                         // Remapping fields:
02295                                         if (is_array($parsedQuery['FIELDS']))   {
02296                                                 $newFieldsArray = array();
02297                                                 foreach($parsedQuery['FIELDS'] as $fN => $fInfo)        {
02298                                                         if ($this->mapping[$table]['mapFieldNames'][$fN])       {
02299                                                                 $fN = $this->mapping[$table]['mapFieldNames'][$fN];
02300                                                         }
02301                                                         $newFieldsArray[$fN] = $fInfo;
02302                                                 }
02303                                                 $parsedQuery['FIELDS'] = $newFieldsArray;
02304                                         }
02305 
02306                                         // Remapping keys:
02307                                         if (is_array($parsedQuery['KEYS']))     {
02308                                                 foreach($parsedQuery['KEYS'] as $kN => $kInfo)  {
02309                                                         $this->map_fieldNamesInArray($table,$parsedQuery['KEYS'][$kN]);
02310                                                 }
02311                                         }
02312                                         break;
02313 
02314 
02316 
02317 
02318                                 }
02319                         }
02320                 } else die('ERROR, mapping: No table found in parsed Query array...');
02321         }
02322 
02330         function map_fieldNamesInArray($table,&$fieldArray)     {
02331                 if (is_array($this->mapping[$table]['mapFieldNames']))  {
02332                         foreach($fieldArray as $k => $v)        {
02333                                 if ($this->mapping[$table]['mapFieldNames'][$v])        {
02334                                         $fieldArray[$k] = $this->mapping[$table]['mapFieldNames'][$v];
02335                                 }
02336                         }
02337                 }
02338         }
02339 
02340 
02341 
02342 
02343 
02344 
02345 
02346 
02347 
02348 
02349 
02350 
02351 
02352 
02353 
02354 
02355 
02356         /**************************************
02357         *
02358         * Debugging
02359         *
02360         **************************************/
02361 
02371         function debugHandler($function,$execTime,$inData)      {
02372                 // we don't want to log our own log/debug SQL
02373                 $script = substr(PATH_thisScript,strlen(PATH_site));
02374 
02375                 if (substr($script,-strlen('dbal/mod1/index.php'))!='dbal/mod1/index.php' &&
02376                 !strstr($inData['args'][0], 'tx_dbal_debuglog'))        {
02377                         $data = array();
02378                         $errorFlag = 0;
02379                         $joinTable = '';
02380 
02381                         if ($this->sql_error()) {
02382                                 $data['sqlError'] = $this->sql_error();
02383                                 $errorFlag|=1;
02384                         }
02385 
02386                         // if lastQuery is empty (for whatever reason) at least log inData.args
02387                         if(empty($this->lastQuery))
02388                         $query = implode(' ',$inData['args']);
02389                         else
02390                         $query = $this->lastQuery;
02391 
02392                         switch($function)       {
02393                                 case 'exec_INSERTquery':
02394                                 case 'exec_UPDATEquery':
02395                                 case 'exec_DELETEquery':
02396                                 $this->debug_log($query,$execTime,$data,$joinTable,$errorFlag, $script);
02397                                 break;
02398 
02399                                 case 'exec_SELECTquery':
02400                                 // Get explain data:
02401                                 if ($this->conf['debugOptions']['EXPLAIN'] && t3lib_div::inList('adodb,native',$inData['handlerType'])) {
02402                                         $data['EXPLAIN'] = $this->debug_explain($this->lastQuery);
02403                                 }
02404 
02405                                 // Check parsing of Query:
02406                                 if ($this->conf['debugOptions']['parseQuery'])  {
02407                                         $parseResults = array();
02408                                         $parseResults['SELECT'] = $this->SQLparser->debug_parseSQLpart('SELECT',$inData['args'][1]);
02409                                         $parseResults['FROM'] = $this->SQLparser->debug_parseSQLpart('FROM',$inData['args'][0]);
02410                                         $parseResults['WHERE'] = $this->SQLparser->debug_parseSQLpart('WHERE',$inData['args'][2]);
02411                                         $parseResults['GROUPBY'] = $this->SQLparser->debug_parseSQLpart('SELECT',$inData['args'][3]);   // Using select field list syntax
02412                                         $parseResults['ORDERBY'] = $this->SQLparser->debug_parseSQLpart('SELECT',$inData['args'][4]);   // Using select field list syntax
02413 
02414                                         foreach($parseResults as $k => $v)      {
02415                                                 if (!strlen($parseResults[$k])) unset($parseResults[$k]);
02416                                         }
02417                                         if (count($parseResults))       {
02418                                                 $data['parseError'] = $parseResults;
02419                                                 $errorFlag|=2;
02420                                         }
02421                                 }
02422 
02423                                 // Checking joinTables:
02424                                 if ($this->conf['debugOptions']['joinTables'])  {
02425                                         if (count(explode(',', $inData['ORIG_from_table']))>1)          {
02426                                                 $joinTable = $inData['args'][0];
02427                                         }
02428                                 }
02429 
02430                                 // Logging it:
02431                                 $this->debug_log($query,$execTime,$data,$joinTable,$errorFlag, $script);
02432                                 if(!empty($inData['args'][2]))
02433                                 $this->debug_WHERE($inData['args'][0], $inData['args'][2], $script);
02434                                 break;
02435                         }
02436                 }
02437         }
02438 
02445         function debug_WHERE($table,$where, $script='') {
02446                 $insertArray = array (
02447                 'tstamp' => $GLOBALS['EXEC_TIME'],
02448                 'beuser_id' => intval($GLOBALS['BE_USER']->user['uid']),
02449                 'script' => $script,
02450                 'tablename' => $table,
02451                 'whereclause' => $where
02452                 );
02453 
02454                 $this->exec_INSERTquery('tx_dbal_debuglog_where', $insertArray);
02455         }
02456 
02467         function debug_log($query,$ms,$data,$join,$errorFlag, $script='')       {
02468                 $insertArray = array (
02469                 'tstamp' => $GLOBALS['EXEC_TIME'],
02470                 'beuser_id' => intval($GLOBALS['BE_USER']->user['uid']),
02471                 'script' => $script,
02472                 'exec_time' => $ms,
02473                 'table_join' => $join,
02474                 'serdata' => serialize($data),
02475                 'query' => (is_array($query) ? $query[0].' WITH '.count($query[1]).' BLOB FIELDS: '.implode(', ',array_keys($query[1])) : $query),
02476                 'errorFlag' => $errorFlag
02477                 );
02478 
02479                 $this->exec_INSERTquery('tx_dbal_debuglog', $insertArray);
02480         }
02481 
02489         function debug_explain($query)  {
02490                 $res = $this->sql_query('EXPLAIN '.$query);
02491 
02492                 $output = array();
02493                 while($row = $this->sql_fetch_assoc($res))      {
02494                         $output[] = $row;
02495                 }
02496                 return $output;
02497         }
02498 }
02499 
02500 
02501 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dbal/class.ux_t3lib_db.php'])  {
02502         include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dbal/class.ux_t3lib_db.php']);
02503 }
02504 ?>


Généré par Les experts TYPO3 avec  doxygen 1.4.6