-2006-06-16 Karsten Dambekalns <karsten@typo3.org>
+2006-06-30 Karsten Dambekalns <karsten@typo3.org>
- * Implemented support for t3lib_div::sysLog() on connection failure
+ * this update closes bugs #3638, #2106, #2866, #3754 (for Firefox, broken in MSIE) and maybe a few more
+ * Implemented support for sysLog() on connection failure
* DBAL now honours the no_pconnect setting
- * XCLASSed t3lib_pageSelect to fix fe_group check on Oracle, using IS NULL
* For handlers in native mode the setDBinit queries are executed upon connection
+ * The initial value for generated sequences can be configured per handler, to avoid duplicate key errors after having imported data
+ * BLOB fields are handled correctly now during INSERT and UPDATE
+ * Setting $store_lastBuiltQuery acts like in t3lib_db now (fill $debug_lastBuiltQuery)
+ * For the native handler quoting methods directly return the input for speedup, as no quoting is needed in that case
+ * Added support for native and userdefined handler to MetaType()
+ * Changed mapping of types to always use the largest possible integer, map tinytext to varchar instead of text
+ * admin_get_tables() skips tables whose names match /BIN\$/ (coming from the recycle bin on Oracle)
+ * Importing dumps using the install tool now works, see manual for tips
+ * Changed the way NOT NULL and DEFAULT are handled when setting up tables, see manual for the rules that now apply
+ * Code cleanup (indentation, documentation)
+ * Updated the manual and added new content
2006-01-19 Karsten Dambekalns <karsten@typo3.org>
if (is_array($parsedQuery)) {
- // Process query based on type:
+ // Process query based on type:
switch($parsedQuery['type']) {
case 'CREATETABLE':
case 'ALTERTABLE':
break;
}
- // Setting query array (for other applications to access if needed)
+ // Setting query array (for other applications to access if needed)
$this->lastParsedAndMappedQueryArray = $parsedQuery;
- // Execute query (based on handler derived from the TABLE name which we actually know for once!)
+ // Execute query (based on handler derived from the TABLE name which we actually know for once!)
$this->lastHandlerKey = $this->handler_getFromTableList($ORIG_table);
switch((string)$this->handlerCfg[$this->lastHandlerKey]['type']) {
case 'native':
// Compiling query:
$compiledQuery = $this->SQLparser->compileSQL($this->lastParsedAndMappedQueryArray);
+ if($this->lastParsedAndMappedQueryArray['type']=='INSERT') {
+ return mysql_query($compiledQuery, $this->link);
+ }
return mysql_query($compiledQuery[0], $this->link);
break;
case 'adodb':
} else {
$this->handlerInstance[$handlerKey]->DataDictionary = NewDataDictionary($this->handlerInstance[$handlerKey]);
$this->handlerInstance[$handlerKey]->last_insert_id = 0;
- $this->handlerInstance[$handlerKey]->sequenceStart = $cfgArray['config']['sequenceStart'];
+ if(isset($cfgArray['config']['sequenceStart'])) {
+ $this->handlerInstance[$handlerKey]->sequenceStart = $cfgArray['config']['sequenceStart'];
+ } else {
+ $this->handlerInstance[$handlerKey]->sequenceStart = 1;
+ }
}
break;
case 'userdefined':
function compileINSERT($components) {
switch((string)$GLOBALS['TYPO3_DB']->handlerCfg[$GLOBALS['TYPO3_DB']->lastHandlerKey]['type']) {
case 'native':
- parent::compileINSERT($components);
+ $query = parent::compileINSERT($components);
break;
case 'adodb':
if(isset($components['VALUES_ONLY']) && is_array($components['VALUES_ONLY'])) {
break;
case 'adodb':
// Set type:
- $cfg = $GLOBALS['TYPO3_DB']->MySQLMetaType($fieldCfg['fieldType']);
+ $type = $GLOBALS['TYPO3_DB']->MySQLMetaType($fieldCfg['fieldType']);
+ $cfg = $type;
// Add value, if any:
- if (strlen($fieldCfg['value']) && (in_array($cfg, array('C','C2')))) {
+ if (strlen($fieldCfg['value']) && (in_array($type, array('C','C2')))) {
$cfg .= ' '.$fieldCfg['value'];
- } elseif (!isset($fieldCfg['value']) && (in_array($cfg, array('C','C2')))) {
+ } elseif (!isset($fieldCfg['value']) && (in_array($type, array('C','C2')))) {
$cfg .= ' 255'; // add 255 as length for varchar without specified length (e.g. coming from tinytext, tinyblob)
}
// MySQL assigns DEFAULT value automatically if NOT NULL, fake this here
// numeric fields get 0 as default, other fields an empty string
if(isset($fieldCfg['featureIndex']['NOTNULL']) && !isset($fieldCfg['featureIndex']['DEFAULT']) && !isset($fieldCfg['featureIndex']['AUTO_INCREMENT'])) {
- switch(true) {
+ switch($type) {
case 'I8':
case 'F':
case 'N':
// auto_increment is removed, it is handled by (emulated) sequences
case ($feature == 'AUTO_INCREMENT') :
// never add NOT NULL if running on Oracle and we have an empty string as default
- case ($feature == 'NOTNULL' && !$GLOBALS['TYPO3_DB']->runningADOdbDriver('oci8') && $fieldCfg['featureIndex']['DEFAULT']['value'][0]==='') :
- continue;
+ case ($feature == 'NOTNULL' && $GLOBALS['TYPO3_DB']->runningADOdbDriver('oci8')) :
+ continue;
+ case ($feature == 'NOTNULL') :
+ $cfg.=' NOTNULL';
+ break;
+ default :
+ $cfg.=' '.$featureDef['keyword'];
}
- $cfg.=' '.$featureDef['keyword'];
-
// Add value if found:
if (is_array($featureDef['value'])) {
if($featureDef['value'][0]==='') {
break;
case 'adodb':
// Set type:
- $cfg = $GLOBALS['TYPO3_DB']->MySQLMetaType($fieldCfg['fieldType']);
+ $type = $GLOBALS['TYPO3_DB']->MySQLMetaType($fieldCfg['fieldType']);
+ $cfg = $type;
// Add value, if any:
- if (strlen($fieldCfg['value']) && (in_array($cfg, array('C','C2')))) {
+ if (strlen($fieldCfg['value']) && (in_array($type, array('C','C2')))) {
$cfg .= ' '.$fieldCfg['value'];
- } elseif (!isset($fieldCfg['value']) && (in_array($cfg, array('C','C2')))) {
+ } elseif (!isset($fieldCfg['value']) && (in_array($type, array('C','C2')))) {
$cfg .= ' 255'; // add 255 as length for varchar without specified length (e.g. coming from tinytext, tinyblob)
}
if (is_array($fieldCfg['featureIndex'])) {
// MySQL assigns DEFAULT value automatically if NOT NULL, fake this here
+ // numeric fields get 0 as default, other fields an empty string
if(isset($fieldCfg['featureIndex']['NOTNULL']) && !isset($fieldCfg['featureIndex']['DEFAULT']) && !isset($fieldCfg['featureIndex']['AUTO_INCREMENT'])) {
- $fieldCfg['featureIndex']['DEFAULT'] = array('keyword' => 'DEFAULT', 'value' => array('','\''));
+ switch($type) {
+ case 'I8':
+ case 'F':
+ case 'N':
+ $fieldCfg['featureIndex']['DEFAULT'] = array('keyword' => 'DEFAULT', 'value' => array('0',''));
+ break;
+ default:
+ $fieldCfg['featureIndex']['DEFAULT'] = array('keyword' => 'DEFAULT', 'value' => array('','\''));
+ }
}
foreach($fieldCfg['featureIndex'] as $feature => $featureDef) {
switch(true) {
// unsigned only for mysql, as it is mysql specific
- case ($feature == 'UNSIGNED' && !$GLOBALS['TYPO3_DB']->runningNative()) :
+ case ($feature == 'UNSIGNED' && !$GLOBALS['TYPO3_DB']->runningADOdbDriver('mysql')) :
// auto_increment is removed, it is handled by (emulated) sequences
case ($feature == 'AUTO_INCREMENT') :
- // never add NOT NULL as it is useless in TYPO3 and breaks most databases other than MySQL
+ // never add NOT NULL if running on Oracle and we have an empty string as default
+ case ($feature == 'NOTNULL' && $GLOBALS['TYPO3_DB']->runningADOdbDriver('oci8')) :
+ continue;
case ($feature == 'NOTNULL') :
- continue;
+ $cfg.=' NOTNULL';
+ break;
+ default :
+ $cfg.=' '.$featureDef['keyword'];
}
- $cfg.=' '.$featureDef['keyword'];
-
// Add value if found:
if (is_array($featureDef['value'])) {
- if(!is_numeric($featureDef['value'][0]) && empty($featureDef['value'][0])) {
+ if($featureDef['value'][0]==='') {
$cfg .= ' "\'\'"';
} else {
$cfg.=' '.$featureDef['value'][1].$this->compileAddslashes($featureDef['value'][0]).$featureDef['value'][1];
--- /dev/null
+Index: typo3/sysext/cms/tslib/class.tslib_fe.php
+===================================================================
+RCS file: /cvsroot/typo3/TYPO3core/typo3/sysext/cms/tslib/class.tslib_fe.php,v
+retrieving revision 1.104.2.25
+diff -u -w -r1.104.2.25 class.tslib_fe.php
+--- typo3/sysext/cms/tslib/class.tslib_fe.php 7 Jun 2006 10:02:10 -0000 1.104.2.25
++++ typo3/sysext/cms/tslib/class.tslib_fe.php 27 Jun 2006 19:36:14 -0000
+@@ -1579,16 +1579,22 @@
+
+ $GLOBALS['TT']->push('Cache Query','');
+ $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
+- 'S.*',
+- 'cache_pages S,pages P',
+- 'S.hash='.$GLOBALS['TYPO3_DB']->fullQuoteStr($this->newHash, 'cache_pages').'
+- AND S.page_id=P.uid
+- AND S.expires > '.intval($GLOBALS['EXEC_TIME']).'
+- AND P.deleted=0
+- AND P.hidden=0
+- AND P.starttime<='.intval($GLOBALS['EXEC_TIME']).'
+- AND (P.endtime=0 OR P.endtime>'.intval($GLOBALS['EXEC_TIME']).')'
++ '*',
++ 'cache_pages',
++ 'hash='.$GLOBALS['TYPO3_DB']->fullQuoteStr($this->newHash, 'cache_pages').'
++ AND expires > '.intval($GLOBALS['EXEC_TIME'])
+ );
++ if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
++ $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
++ 'uid',
++ 'pages',
++ 'uid='.$row['page_id'].'
++ AND deleted=0
++ AND hidden=0
++ AND starttime<='.intval($GLOBALS['EXEC_TIME']).'
++ AND (endtime=0 OR endtime>'.intval($GLOBALS['EXEC_TIME']).')'
++ );
++ }
+ $GLOBALS['TT']->pull();
+
+ if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
$TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_db.php'] = t3lib_extMgm::extPath('dbal').'class.ux_t3lib_db.php';
$TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_sqlengine.php'] = t3lib_extMgm::extPath('dbal').'class.ux_t3lib_sqlengine.php';
$TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_sqlparser.php'] = t3lib_extMgm::extPath('dbal').'class.ux_t3lib_sqlparser.php';
-$TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_page.php'] = t3lib_extMgm::extPath('dbal').'class.ux_t3lib_page.php';
?>
document.getElementById(\'tx-dbal-result\').style.display = \'none\';
switch(s) {
case \'SELECT\':
+ document.getElementById(\'tx-dbal-qryupdate\').style.display = \'none\';
document.getElementById(\'tx-dbal-qryfields\').style.display = \'table-row\';
document.getElementById(\'tx-dbal-qryinsertvalues\').style.display = \'none\';
document.getElementById(\'tx-dbal-qryupdatevalues\').style.display = \'none\';
document.getElementById(\'tx-dbal-qrylimit\').style.display = \'table-row\';
break;
case \'INSERT\':
+ document.getElementById(\'tx-dbal-qryupdate\').style.display = \'none\';
document.getElementById(\'tx-dbal-qryfields\').style.display = \'none\';
document.getElementById(\'tx-dbal-qryinsertvalues\').style.display = \'table-row\';
document.getElementById(\'tx-dbal-qryupdatevalues\').style.display = \'none\';
document.getElementById(\'tx-dbal-qrylimit\').style.display = \'table-row\';
break;
case \'UPDATE\':
+ document.getElementById(\'tx-dbal-qryupdate\').style.display = \'table-row\';
document.getElementById(\'tx-dbal-qryfields\').style.display = \'none\';
document.getElementById(\'tx-dbal-qryinsertvalues\').style.display = \'none\';
document.getElementById(\'tx-dbal-qryupdatevalues\').style.display = \'table-row\';
document.getElementById(\'tx-dbal-qrylimit\').style.display = \'none\';
break;
case \'DELETE\':
+ document.getElementById(\'tx-dbal-qryupdate\').style.display = \'none\';
document.getElementById(\'tx-dbal-qryfields\').style.display = \'none\';
document.getElementById(\'tx-dbal-qryinsertvalues\').style.display = \'none\';
document.getElementById(\'tx-dbal-qryupdatevalues\').style.display = \'none\';
<option value="SELECT" '.($input['QUERY']=='SELECT'? 'selected="selected"' : '').'>SELECT</option>
<option value="INSERT" '.($input['QUERY']=='INSERT'? 'selected="selected"' : '').'>INSERT</option>
<option value="UPDATE" '.($input['QUERY']=='UPDATE'? 'selected="selected"' : '').'>UPDATE</option>
- <option value="DELETE" '.($input['QUERY']=='DELETE' ? 'selected="selected"' : '').'">DELETE</option>
+ <option value="DELETE" '.($input['QUERY']=='DELETE' ? 'selected="selected"' : '').'>DELETE</option>
</select>
</td></tr>
<tr id="tx-dbal-qryupdate" style="display:none;"><td></td><td><input name="tx_dbal[UPDATE]" value="'.$input['UPDATE'].'" type="text" size="30" maxsize="100" /></td></tr>