00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00091 require_once(PATH_t3lib.'class.t3lib_sqlparser.php');
00092
00093
00102 class t3lib_sqlengine extends t3lib_sqlparser {
00103
00104
00105 var $data = array();
00106
00107
00108
00109 var $errorStatus = '';
00110 var $lastInsertedId = 0;
00111 var $lastAffectedRows = 0;
00112
00113
00114
00115
00116
00124 function init($config, &$pObj) {
00125 }
00126
00132 function resetStatusVars() {
00133 $this->errorStatus = '';
00134 $this->lastInsertedId = 0;
00135 $this->lastAffectedRows = 0;
00136 }
00137
00145 function processAccordingToConfig(&$value,$fInfo) {
00146 $options = $this->parseFieldDef($fInfo['Type']);
00147
00148 switch(strtolower($options['fieldType'])) {
00149 case 'int':
00150 case 'smallint':
00151 case 'tinyint':
00152 case 'mediumint':
00153 $value = intval($value);
00154 if ($options['featureIndex']['UNSIGNED']) {
00155 $value = t3lib_div::intInRange($value,0);
00156 }
00157 break;
00158 case 'double':
00159 $value = (double)$value;
00160 break;
00161 case 'varchar':
00162 case 'char':
00163 $value = substr($value,0,trim($options['value']));
00164 break;
00165 case 'text':
00166 case 'blob':
00167 $value = substr($value,0,65536);
00168 break;
00169 case 'tinytext':
00170 case 'tinyblob':
00171 $value = substr($value,0,256);
00172 break;
00173 case 'mediumtext':
00174 case 'mediumblob':
00175
00176 break;
00177 }
00178 }
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00200 function exec_INSERTquery($table,$fields_values) {
00201
00202
00203 $this->resetStatusVars();
00204
00205
00206 $this->readDataSource($table);
00207
00208
00209 if (is_array($this->data[$table])) {
00210
00211 $fieldInformation = $this->admin_get_fields($table);
00212
00213
00214 $saveArray = array();
00215 foreach($fieldInformation as $fInfo) {
00216
00217
00218 $fN = $fInfo['Field'];
00219
00220
00221 $saveArray[$fN] = isset($fields_values[$fN]) ? $fields_values[$fN] : $options['Default'];
00222
00223
00224 $this->processAccordingToConfig($saveArray[$fN], $fInfo);
00225
00226
00227 if ($fInfo['Extra'] == 'auto_increment') {
00228
00229
00230 $uidArray = array();
00231 foreach($this->data[$table] as $r) {
00232 $uidArray[] = $r[$fN];
00233 }
00234
00235
00236 if (!$saveArray[$fN] || in_array(intval($saveArray[$fN]), $uidArray)) {
00237 if (count($uidArray)) {
00238 $saveArray[$fN] = max($uidArray)+1;
00239 } else $saveArray[$fN] = 1;
00240 }
00241
00242
00243 $this->lastInsertedId = $saveArray[$fN];
00244 }
00245 }
00246 #debug(array($fields_values,$saveArray));
00247
00248 $this->data[$table][] = $saveArray;
00249
00250
00251 $this->saveDataSource($table);
00252
00253 return TRUE;
00254 } else $this->errorStatus = 'No data loaded.';
00255
00256 return FALSE;
00257 }
00258
00267 function exec_UPDATEquery($table,$where,$fields_values) {
00268
00269
00270 $this->resetStatusVars();
00271
00272
00273 $this->readDataSource($table);
00274
00275
00276 if (is_array($this->data[$table])) {
00277
00278
00279 $where = $this->parseWhereClause($where);
00280
00281 if (is_array($where)) {
00282
00283
00284 $fieldInformation = $this->admin_get_fields($table);
00285
00286
00287 foreach($fields_values as $fName => $fValue) {
00288 $this->processAccordingToConfig($fields_values[$fName],$fieldInformation[$fName]);
00289 }
00290 #debug($fields_values);
00291
00292 $itemKeys = $this->selectFromData($table,$where);
00293
00294
00295 $this->lastAffectedRows = count($itemKeys);
00296
00297
00298 if ($this->lastAffectedRows) {
00299
00300 foreach($itemKeys as $dataArrayKey) {
00301
00302
00303 foreach($fields_values as $fName => $fValue) {
00304 $this->data[$table][$dataArrayKey][$fName] = $fValue;
00305 }
00306 }
00307
00308
00309 $this->saveDataSource($table);
00310 }
00311
00312 return TRUE;
00313 } else $this->errorStatus = 'WHERE clause contained errors: '.$where;
00314 } else $this->errorStatus = 'No data loaded.';
00315
00316 return FALSE;
00317 }
00318
00326 function exec_DELETEquery($table,$where) {
00327
00328
00329 $this->resetStatusVars();
00330
00331
00332 $this->readDataSource($table);
00333
00334
00335 if (is_array($this->data[$table])) {
00336
00337
00338 $where = $this->parseWhereClause($where);
00339
00340 if (is_array($where)) {
00341
00342
00343 $itemKeys = $this->selectFromData($table,$where);
00344
00345
00346 $this->lastAffectedRows = count($itemKeys);
00347
00348
00349 if ($this->lastAffectedRows) {
00350
00351 foreach($itemKeys as $dataArrayKey) {
00352 unset($this->data[$table][$dataArrayKey]);
00353 }
00354
00355
00356 $this->saveDataSource($table);
00357 }
00358
00359 return TRUE;
00360 } else $this->errorStatus = 'WHERE clause contained errors: '.$where;
00361 } else $this->errorStatus = 'No data loaded.';
00362
00363 return FALSE;
00364 }
00365
00377 function exec_SELECTquery($select_fields,$from_table,$where_clause,$groupBy,$orderBy,$limit) {
00378
00379
00380 $this->resetStatusVars();
00381
00382
00383 $sqlObj = t3lib_div::makeInstance('t3lib_sqlengine_resultobj');
00384 $sqlObj->result = array();
00385
00386
00387 $tableArray = $this->parseFromTables($from_table);
00388 $table = $tableArray[0]['table'];
00389
00390
00391 $this->readDataSource($table);
00392
00393
00394 if (is_array($this->data[$table])) {
00395
00396
00397 $where = $this->parseWhereClause($where_clause);
00398 if (is_array($where)) {
00399
00400
00401 $itemKeys = $this->selectFromData($table,$where);
00402
00403
00404 $sqlObj->result = $this->getResultSet($itemKeys,$table,'*');
00405
00406 reset($sqlObj->result);
00407 return $sqlObj;
00408 } else $this->errorStatus = 'WHERE clause contained errors: '.$where;
00409 } else $this->errorStatus = 'No data loaded: '.$this->errorStatus;
00410
00411 return FALSE;
00412 }
00413
00420 function sql_query($query) {
00421 $res = t3lib_div::makeInstance('t3lib_sqlengine_resultobj');
00422 $res->result = array();
00423 return $res;
00424 }
00425
00431 function sql_error() {
00432 return $this->errorStatus;
00433 }
00434
00440 function sql_insert_id() {
00441 return $this->lastInsertedId;
00442 }
00443
00449 function sql_affected_rows() {
00450 return $this->lastAffectedRows;
00451 }
00452
00459 function quoteStr($str) {
00460 return addslashes($str);
00461 }
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00484 function admin_get_tables() {
00485 $whichTables = array();
00486 return $whichTables;
00487 }
00488
00495 function admin_get_fields($tableName) {
00496 $output = array();
00497 return $output;
00498 }
00499
00506 function admin_get_keys($tableName) {
00507 $output = array();
00508 return $output;
00509 }
00510
00517 function admin_query($query) {
00518 return $this->sql_query($query);
00519 }
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00542 function readDataSource($table) {
00543 $this->data[$table] = array();
00544 }
00545
00554 function saveDataSource($table) {
00555 debug($this->data[$table]);
00556 }
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00583 function selectFromData($table,$where) {
00584
00585 $output = array();
00586 if (is_array($this->data[$table])) {
00587
00588
00589 $OR_index = 0;
00590
00591 foreach($where as $config) {
00592
00593 if (strtoupper($config['operator'])=='OR') {
00594 $OR_index++;
00595 }
00596
00597 if (!isset($itemKeys[$OR_index])) $itemKeys[$OR_index] = array_keys($this->data[$table]);
00598
00599 $this->select_evalSingle($table,$config,$itemKeys[$OR_index]);
00600 }
00601
00602 foreach($itemKeys as $uidKeys) {
00603 $output = array_merge($output, $uidKeys);
00604 }
00605 $output = array_unique($output);
00606 }
00607
00608 return $output;
00609 }
00610
00619 function select_evalSingle($table,$config,&$itemKeys) {
00620 $neg = ereg('^AND[[:space:]]+NOT$',trim($config['operator']));
00621
00622 if (is_array($config['sub'])) {
00623 $subSelKeys = $this->selectFromData($table,$config['sub']);
00624 if ($neg) {
00625 foreach($itemKeys as $kk => $vv) {
00626 if (in_array($vv,$subSelKeys)) {
00627 unset($itemKeys[$kk]);
00628 }
00629 }
00630 } else {
00631 $itemKeys = array_intersect($itemKeys, $subSelKeys);
00632 }
00633 } else {
00634 $comp = strtoupper(ereg_replace('[[:space:]]','',$config['comparator']));
00635 $mod = strtoupper($config['modifier']);
00636 switch($comp) {
00637 case 'NOTLIKE':
00638 case 'LIKE':
00639 $like_value = strtolower($config['value'][0]);
00640 if (substr($like_value,0,1)=='%') {
00641 $wildCard_begin = TRUE;
00642 $like_value = substr($like_value,1);
00643 }
00644 if (substr($like_value,-1)=='%') {
00645 $wildCard_end = TRUE;
00646 $like_value = substr($like_value,0,-1);
00647 }
00648 break;
00649 case 'NOTIN':
00650 case 'IN':
00651 $in_valueArray = array();
00652 foreach($config['value'] as $vParts) {
00653 $in_valueArray[] = (string)$vParts[0];
00654 }
00655 break;
00656 }
00657
00658 foreach($itemKeys as $kk => $v) {
00659 $field_value = $this->data[$table][$v][$config['field']];
00660
00661
00662 if ($config['calc']=='&') {
00663 $field_value&=intval($config['calc_value']);
00664 }
00665
00666
00667 switch($comp) {
00668 case '<=':
00669 $bool = $field_value <= $config['value'][0];
00670 break;
00671 case '>=':
00672 $bool = $field_value >= $config['value'][0];
00673 break;
00674 case '<':
00675 $bool = $field_value < $config['value'][0];
00676 break;
00677 case '>':
00678 $bool = $field_value > $config['value'][0];
00679 break;
00680 case '=':
00681 $bool = !strcmp($field_value,$config['value'][0]);
00682 break;
00683 case '!=':
00684 $bool = strcmp($field_value,$config['value'][0]);
00685 break;
00686 case 'NOTIN':
00687 case 'IN':
00688 $bool = in_array((string)$field_value, $in_valueArray);
00689 if ($comp=='NOTIN') $bool = !$bool;
00690 break;
00691 case 'NOTLIKE':
00692 case 'LIKE':
00693 if (!strlen($like_value)) {
00694 $bool = TRUE;
00695 } elseif ($wildCard_begin && !$wildCard_end) {
00696 $bool = !strcmp(substr(strtolower($field_value),-strlen($like_value)),$like_value);
00697 } elseif (!$wildCard_begin && $wildCard_end) {
00698 $bool = !strcmp(substr(strtolower($field_value),0,strlen($like_value)),$like_value);
00699 } elseif ($wildCard_begin && $wildCard_end) {
00700 $bool = strstr($field_value,$like_value);
00701 } else {
00702 $bool = !strcmp(strtolower($field_value),$like_value);
00703 }
00704 if ($comp=='NOTLIKE') $bool = !$bool;
00705 break;
00706 default:
00707 $bool = $field_value ? TRUE : FALSE;
00708 break;
00709 }
00710
00711
00712 if ($neg) $bool = !$bool;
00713
00714
00715 switch($mod) {
00716 case 'NOT':
00717 case '!':
00718 $bool = !$bool;
00719 break;
00720 }
00721
00722
00723 if (!$bool) {
00724 unset($itemKeys[$kk]);
00725 }
00726 }
00727
00728 # echo $this->debug_printResultSet($this->getResultSet($itemKeys,$table,'uid,tstamp'));
00729 }
00730 }
00731
00740 function getResultSet($keys, $table, $fieldList) {
00741 $fields = t3lib_div::trimExplode(',',$fieldList);
00742
00743 $output = array();
00744 foreach($keys as $kValue) {
00745 if ($fieldList=='*') {
00746 $output[$kValue] = $this->data[$table][$kValue];
00747 } else {
00748 foreach($fields as $fieldName) {
00749 $output[$kValue][$fieldName] = $this->data[$table][$kValue][$fieldName];
00750 }
00751 }
00752 }
00753
00754 return $output;
00755 }
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00785 function debug_printResultSet($array) {
00786
00787 if (count($array)) {
00788 $tRows=array();
00789 $fields = array_keys(current($array));
00790 $tCell[]='
00791 <td>IDX</td>';
00792 foreach($fields as $fieldName) {
00793 $tCell[]='
00794 <td>'.htmlspecialchars($fieldName).'</td>';
00795 }
00796 $tRows[]='<tr>'.implode('',$tCell).'</tr>';
00797
00798
00799 foreach($array as $index => $rec) {
00800
00801 $tCell=array();
00802 $tCell[]='
00803 <td>'.htmlspecialchars($index).'</td>';
00804 foreach($fields as $fieldName) {
00805 $tCell[]='
00806 <td>'.htmlspecialchars($rec[$fieldName]).'</td>';
00807 }
00808 $tRows[]='<tr>'.implode('',$tCell).'</tr>';
00809 }
00810
00811 return '<table border="1">'.implode('',$tRows).'</table>';
00812 } else 'Empty resultset';
00813 }
00814 }
00815
00816
00824 class t3lib_sqlengine_resultobj {
00825
00826
00827 var $result = array();
00828
00829 var $TYPO3_DBAL_handlerType = '';
00830 var $TYPO3_DBAL_tableList = '';
00831
00832
00838 function sql_num_rows() {
00839 return count($this->result);
00840 }
00841
00847 function sql_fetch_assoc() {
00848 $row = current($this->result);
00849 next($this->result);
00850 return $row;
00851 }
00852
00858 function sql_fetch_row() {
00859 $resultRow = $this->sql_fetch_assoc();
00860
00861 if (is_array($resultRow)) {
00862 $numArray = array();
00863 foreach($resultRow as $value) {
00864 $numArray[]=$value;
00865 }
00866 return $numArray;
00867 }
00868 }
00869
00876 function sql_data_seek($pointer) {
00877 reset($this->result);
00878 for ($a=0;$a<$pointer;$a++) {
00879 next($this->result);
00880 }
00881 return TRUE;
00882 }
00883
00889 function sql_field_type() {
00890 return '';
00891 }
00892 }
00893
00894
00895
00896 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_sqlengine.php']) {
00897 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_sqlengine.php']);
00898 }
00899 ?>