Documentation TYPO3 par Ameos |
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 ***************************************************************/ 00074 class tx_dbal_handler_xmldb extends t3lib_sqlengine { 00075 00076 var $config = array(); 00077 var $pObj; // Set from DBAL class. 00078 00079 // Database Storage directory: 00080 var $DBdir = ''; 00081 var $DBstructure = array( 00082 'tables' => array() 00083 ); 00084 00092 function init($config, &$pObj) { 00093 $this->config = $config['config']; 00094 00095 $dbStorage = t3lib_div::getFileAbsFileName($this->config['DBstorageDir']); 00096 if ($dbStorage && @is_dir($dbStorage) && ($dbStorage{strlen($dbStorage)-1} == '/')) { //ereg('/$',$dbStorage)) { 00097 $this->DBdir = $dbStorage; 00098 00099 // Read structure file: 00100 if (@is_file($this->DBdir.'_STRUCTURE.xml')) { 00101 $this->xmlDB_readStructure(); 00102 if (is_array($this->DBstructure)) { 00103 return TRUE; 00104 } else { 00105 $this->errorStatus = 'The database structure array could not be loaded correctly. "_STRUCTURE.xml" may be corrupt'; 00106 } 00107 } else { 00108 $this->xmlDB_writeStructure(); 00109 if (@is_file($this->DBdir.'_STRUCTURE.xml')) { 00110 return TRUE; 00111 } else { 00112 $this->errorStatus = 'The database structure file could not be created in dir "'.$dbStorage.'"'; 00113 } 00114 } 00115 00116 00117 } else $this->errorStatus = 'The database storage dir "'.$dbStorage.'" did not exist!'; 00118 00119 debug($this->errorStatus,'XMLDB connect ERROR:'); 00120 return FALSE; 00121 } 00122 00129 function readDataSource($table) { 00130 00131 if (!$this->DBdir) { 00132 $this->errorStatus = 'XMLdatabase not connected'; 00133 return FALSE; 00134 } 00135 00136 // Reading table: 00137 if (is_array($this->DBstructure['tables'][$table])) { 00138 if (!isset($this->data[$table])) { // Checking if it has already been read 00139 $newTableFile = 'TABLE_'.$table.'.xml'; 00140 if (@is_file($this->DBdir.$newTableFile)) { 00141 $this->data[$table] = t3lib_div::xml2array(t3lib_div::getUrl($this->DBdir.$newTableFile)); 00142 if (!is_array($this->data[$table])) $this->data[$table] = array(); 00143 return TRUE; 00144 } else { 00145 $this->data[$table] = array(); 00146 $this->errorStatus = 'Tablefile for "'.$table.'" not found'; 00147 } 00148 } 00149 } else $this->errorStatus = 'Table "'.$table.'" not found'; 00150 } 00151 00158 function saveDataSource($table) { 00159 00160 if (!$this->DBdir) { 00161 $this->errorStatus = 'XMLdatabase not connected'; 00162 return FALSE; 00163 } 00164 00165 // Writing table: 00166 if (is_array($this->DBstructure['tables'][$table])) { 00167 $newTableFile = 'TABLE_'.$table.'.xml'; 00168 if (t3lib_div::getFileAbsFileName($this->DBdir.$newTableFile) && @is_file($this->DBdir.$newTableFile)) { 00169 00170 $storeInCharset = $GLOBALS['LANG']->charSet; 00171 $xmlValue = t3lib_div::array2xml($this->data[$table],'',0,'T3xmlDB',0,array('useIndexTagForNum'=>'rec')); 00172 $content = '<?xml version="1.0" encoding="'.$storeInCharset.'" standalone="yes" ?>'.chr(10).$xmlValue; 00173 t3lib_div::writeFile($this->DBdir.$newTableFile,$content); 00174 00175 return TRUE; 00176 } else $this->errorStatus = 'Tablefile for "'.$table.'" not found'; 00177 } else $this->errorStatus = 'Table "'.$table.'" not found'; 00178 } 00179 00185 function xmlDB_writeStructure() { 00186 t3lib_div::writeFile($this->DBdir.'_STRUCTURE.xml', t3lib_div::array2xml($this->DBstructure,'',0,'T3xmlDBStructure',0,array('useIndexTagForNum'=>'item'))); 00187 } 00188 00194 function xmlDB_readStructure() { 00195 $this->DBstructure = t3lib_div::xml2array(t3lib_div::getUrl($this->DBdir.'_STRUCTURE.xml')); 00196 } 00197 00198 00199 00200 00201 00202 00203 00204 00205 00206 /************************************** 00207 * 00208 * SQL admin functions 00209 * (For use in the Install Tool and Extension Manager) 00210 * 00211 **************************************/ 00212 00218 function admin_get_tables() { 00219 00220 if (!$this->DBdir) { 00221 $this->errorStatus = 'XMLdatabase not connected'; 00222 return FALSE; 00223 } 00224 00225 $whichTables = array(); 00226 00227 // Traverse tables: 00228 if (is_array($this->DBstructure['tables'])) { 00229 foreach($this->DBstructure['tables'] as $tableName => $tableInfo) { 00230 $whichTables[$tableName] = $tableName; 00231 } 00232 } 00233 00234 return $whichTables; 00235 } 00236 00243 function admin_get_fields($tableName) { 00244 00245 if (!$this->DBdir) { 00246 $this->errorStatus = 'XMLdatabase not connected'; 00247 return FALSE; 00248 } 00249 00250 $output = array(); 00251 00252 // Traverse fields in table: 00253 if (is_array($this->DBstructure['tables'][$tableName]) && is_array($this->DBstructure['tables'][$tableName]['FIELDS'])) { 00254 foreach($this->DBstructure['tables'][$tableName]['FIELDS'] as $fieldName => $fieldInfo) { 00255 $output[$fieldName] = array( 00256 'Field' => $fieldName, 00257 'Type' => $fieldInfo['definition']['fieldType']. 00258 ($fieldInfo['definition']['value']?'('.$fieldInfo['definition']['value'].')':''). 00259 (isset($fieldInfo['definition']['featureIndex']['UNSIGNED']) ? ' '.$fieldInfo['definition']['featureIndex']['UNSIGNED']['keyword'] : ''), 00260 'Null' => isset($fieldInfo['definition']['featureIndex']['NOTNULL']) ? '' : 'Yes', 00261 'Key' => '', 00262 'Default' => $fieldInfo['definition']['featureIndex']['DEFAULT']['value'][0], 00263 'Extra' => isset($fieldInfo['definition']['featureIndex']['AUTO_INCREMENT']) ? 'auto_increment' : '', 00264 ); 00265 } 00266 } 00267 00268 return $output; 00269 } 00270 00277 function admin_get_keys($tableName) { 00278 00279 if (!$this->DBdir) { 00280 $this->errorStatus = 'XMLdatabase not connected'; 00281 return FALSE; 00282 } 00283 00284 $output = array(); 00285 00286 // Traverse fields in table: 00287 if (is_array($this->DBstructure['tables'][$tableName]) && is_array($this->DBstructure['tables'][$tableName]['KEYS'])) { 00288 foreach($this->DBstructure['tables'][$tableName]['KEYS'] as $keyName => $keyInfo) { 00289 foreach($keyInfo as $seq => $keyField) { 00290 $output[] = array( 00291 'Table' => $tableName, 00292 'Non_unique' => ($keyName=='PRIMARYKEY' ? 0 : 1), 00293 'Key_name' => ($keyName=='PRIMARYKEY' ? 'PRIMARY' : $keyName), 00294 'Seq_in_index' => $seq+1, 00295 'Column_name' => $keyField, 00296 'Collation' => 'A', 00297 'Cardinality' => '', 00298 'Sub_part' => '', 00299 'Packed' => '', 00300 'Comment' => '', 00301 ); 00302 } 00303 } 00304 } 00305 00306 return $output; 00307 } 00308 00315 function admin_query($query) { 00316 00317 if (!$this->DBdir) { 00318 $this->errorStatus = 'XMLdatabase not connected'; 00319 return FALSE; 00320 } 00321 00322 $parsedQuery = $this->parseSQL($query); 00323 $table = $parsedQuery['TABLE']; 00324 00325 if (is_array($parsedQuery)) { 00326 // Process query based on type: 00327 switch($parsedQuery['type']) { 00328 case 'CREATETABLE': 00329 if (!is_array($this->DBstructure['tables'][$table])) { 00330 $newTableFile = 'TABLE_'.$table.'.xml'; 00331 if (!@is_file($this->DBdir.$newTableFile)) { 00332 00333 // Write table file: 00334 t3lib_div::writeFile($this->DBdir.$newTableFile, ''); // Create file 00335 if (@is_file($this->DBdir.$newTableFile)) { 00336 00337 // Set and write structure 00338 if (!is_array($this->DBstructure['tables'])) $this->DBstructure['tables']=array(); 00339 $this->DBstructure['tables'][(string)$table] = $parsedQuery; // I have some STRANGE behaviours with this variable - had to do this trick to make it work! 00340 00341 $this->xmlDB_writeStructure(); 00342 return TRUE; 00343 } else $this->errorStatus = 'Table file "'.$this->DBdir.$newTableFile.'" could not be created! Cannot create table!'; 00344 } else $this->errorStatus = 'Table file "'.$this->DBdir.$newTableFile.'" already exists! Cannot create table!'; 00345 } else $this->errorStatus = 'Table "'.$table.'" already exists!'; 00346 break; 00347 case 'ALTERTABLE': 00348 if (is_array($this->DBstructure['tables'][$table])) { 00349 switch($parsedQuery['action']) { 00350 case 'ADD': 00351 if (!is_array($this->DBstructure['tables'][$table]['FIELDS'][$parsedQuery['FIELD']])) { 00352 $this->DBstructure['tables'][$table]['FIELDS'][$parsedQuery['FIELD']]['definition'] = $parsedQuery['definition']; // Adding field in the end of list. 00353 $this->xmlDB_writeStructure(); 00354 return TRUE; 00355 00356 // TODO: Should traverse all data an add that field in arrays! 00357 } else $this->errorStatus = 'Field "'.$parsedQuery['FIELD'].'" already exists!'; 00358 break; 00359 case 'CHANGE': 00360 if (is_array($this->DBstructure['tables'][$table]['FIELDS'])) { 00361 if (is_array($this->DBstructure['tables'][$table]['FIELDS'][$parsedQuery['FIELD']])) { 00362 $newFieldInfo = array(); 00363 foreach($this->DBstructure['tables'][$table]['FIELDS'] as $fieldName => $fieldDefinition) { 00364 if (!strcmp($fieldName,$parsedQuery['FIELD'])) { 00365 00366 // New fieldname? 00367 if ($parsedQuery['newField']) { 00368 if (!is_array($this->DBstructure['tables'][$table]['FIELDS'][$parsedQuery['newField']])) { 00369 $fieldName = $parsedQuery['newField']; 00370 } else { 00371 $this->errorStatus = 'A field in the table was already named "'.$parsedQuery['newField'].'"'; 00372 return FALSE; 00373 } 00374 } 00375 // Set new field definition: 00376 $fieldDefinition['definition'] = $parsedQuery['definition']; 00377 } 00378 00379 // Set the whole thing in new var: 00380 $newFieldInfo[$fieldName] = $fieldDefinition; 00381 } 00382 $this->DBstructure['tables'][$table]['FIELDS'] = $newFieldInfo; 00383 $this->xmlDB_writeStructure(); 00384 return TRUE; 00385 00386 // TODO: Should traverse all data an remove that field in arrays! 00387 } else $this->errorStatus = 'Field "'.$parsedQuery['FIELD'].'" does not exist!'; 00388 } else $this->errorStatus = 'There are not fields in the table - strange!'; 00389 break; 00390 case 'DROP': 00391 if (is_array($this->DBstructure['tables'][$table]['FIELDS'][$parsedQuery['FIELD']])) { 00392 unset($this->DBstructure['tables'][$table]['FIELDS'][$parsedQuery['FIELD']]); // Removing it... 00393 $this->xmlDB_writeStructure(); 00394 return TRUE; 00395 00396 // TODO: Should traverse all data an remove that field in arrays! 00397 } else $this->errorStatus = 'Field "'.$parsedQuery['FIELD'].'" does not exist!'; 00398 break; 00399 } 00400 } else $this->errorStatus = 'Table "'.$table.'" does not exist!'; 00401 break; 00402 case 'DROPTABLE': 00403 00404 // TODO: 00405 debug($parsedQuery); 00406 00407 00408 break; 00409 default: 00410 $this->errorStatus = 'Query type "'.$parsedQuery['type'].'" was not supported!'; 00411 break; 00412 } 00413 00414 } else $this->errorStatus = 'SQL parse error: '.$parsedQuery; 00415 00416 return FALSE; 00417 } 00418 } 00419 00420 00421 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dbal/handlers/class.tx_dbal_handler_xmldb.php']) { 00422 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dbal/handlers/class.tx_dbal_handler_xmldb.php']); 00423 } 00424 ?>