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
00092 require_once(PATH_t3lib.'class.t3lib_sqlparser.php');
00093
00094
00104 class t3lib_sqlengine extends t3lib_sqlparser {
00105
00106
00107 var $data = array();
00108
00109
00110
00111 var $errorStatus = '';
00112 var $lastInsertedId = 0;
00113 var $lastAffectedRows = 0;
00114
00115
00116
00117
00118
00126 function init($config, &$pObj) {
00127 }
00128
00134 function resetStatusVars() {
00135 $this->errorStatus = '';
00136 $this->lastInsertedId = 0;
00137 $this->lastAffectedRows = 0;
00138 }
00139
00150 function processAccordingToConfig(&$value,$fInfo) {
00151 $options = $this->parseFieldDef($fInfo['Type']);
00152
00153 switch(strtolower($options['fieldType'])) {
00154 case 'int':
00155 case 'smallint':
00156 case 'tinyint':
00157 case 'mediumint':
00158 $value = intval($value);
00159 if ($options['featureIndex']['UNSIGNED']) {
00160 $value = t3lib_div::intInRange($value,0);
00161 }
00162 break;
00163 case 'double':
00164 $value = (double)$value;
00165 break;
00166 case 'varchar':
00167 case 'char':
00168 $value = substr($value,0,trim($options['value']));
00169 break;
00170 case 'text':
00171 case 'blob':
00172 $value = substr($value,0,65536);
00173 break;
00174 case 'tinytext':
00175 case 'tinyblob':
00176 $value = substr($value,0,256);
00177 break;
00178 case 'mediumtext':
00179 case 'mediumblob':
00180
00181 break;
00182 }
00183 }
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00205 function exec_INSERTquery($table,$fields_values) {
00206
00207
00208 $this->resetStatusVars();
00209
00210
00211 $this->readDataSource($table);
00212
00213
00214 if (is_array($this->data[$table])) {
00215
00216 $fieldInformation = $this->admin_get_fields($table);
00217
00218
00219 $saveArray = array();
00220 foreach($fieldInformation as $fInfo) {
00221
00222
00223 $fN = $fInfo['Field'];
00224
00225
00226 $saveArray[$fN] = isset($fields_values[$fN]) ? $fields_values[$fN] : $options['Default'];
00227
00228
00229 $this->processAccordingToConfig($saveArray[$fN], $fInfo);
00230
00231
00232 if ($fInfo['Extra'] == 'auto_increment') {
00233
00234
00235 $uidArray = array();
00236 foreach($this->data[$table] as $r) {
00237 $uidArray[] = $r[$fN];
00238 }
00239
00240
00241 if (!$saveArray[$fN] || in_array(intval($saveArray[$fN]), $uidArray)) {
00242 if (count($uidArray)) {
00243 $saveArray[$fN] = max($uidArray)+1;
00244 } else $saveArray[$fN] = 1;
00245 }
00246
00247
00248 $this->lastInsertedId = $saveArray[$fN];
00249 }
00250 }
00251 #debug(array($fields_values,$saveArray));
00252
00253 $this->data[$table][] = $saveArray;
00254
00255
00256 $this->saveDataSource($table);
00257
00258 return TRUE;
00259 } else $this->errorStatus = 'No data loaded.';
00260
00261 return FALSE;
00262 }
00263
00272 function exec_UPDATEquery($table,$where,$fields_values) {
00273
00274
00275 $this->resetStatusVars();
00276
00277
00278 $this->readDataSource($table);
00279
00280
00281 if (is_array($this->data[$table])) {
00282
00283
00284 $where = $this->parseWhereClause($where);
00285
00286 if (is_array($where)) {
00287
00288
00289 $fieldInformation = $this->admin_get_fields($table);
00290
00291
00292 foreach($fields_values as $fName => $fValue) {
00293 $this->processAccordingToConfig($fields_values[$fName],$fieldInformation[$fName]);
00294 }
00295 #debug($fields_values);
00296
00297 $itemKeys = $this->selectFromData($table,$where);
00298
00299
00300 $this->lastAffectedRows = count($itemKeys);
00301
00302
00303 if ($this->lastAffectedRows) {
00304
00305 foreach($itemKeys as $dataArrayKey) {
00306
00307
00308 foreach($fields_values as $fName => $fValue) {
00309 $this->data[$table][$dataArrayKey][$fName] = $fValue;
00310 }
00311 }
00312
00313
00314 $this->saveDataSource($table);
00315 }
00316
00317 return TRUE;
00318 } else $this->errorStatus = 'WHERE clause contained errors: '.$where;
00319 } else $this->errorStatus = 'No data loaded.';
00320
00321 return FALSE;
00322 }
00323
00331 function exec_DELETEquery($table,$where) {
00332
00333
00334 $this->resetStatusVars();
00335
00336
00337 $this->readDataSource($table);
00338
00339
00340 if (is_array($this->data[$table])) {
00341
00342
00343 $where = $this->parseWhereClause($where);
00344
00345 if (is_array($where)) {
00346
00347
00348 $itemKeys = $this->selectFromData($table,$where);
00349
00350
00351 $this->lastAffectedRows = count($itemKeys);
00352
00353
00354 if ($this->lastAffectedRows) {
00355
00356 foreach($itemKeys as $dataArrayKey) {
00357 unset($this->data[$table][$dataArrayKey]);
00358 }
00359
00360
00361 $this->saveDataSource($table);
00362 }
00363
00364 return TRUE;
00365 } else $this->errorStatus = 'WHERE clause contained errors: '.$where;
00366 } else $this->errorStatus = 'No data loaded.';
00367
00368 return FALSE;
00369 }
00370
00382 function exec_SELECTquery($select_fields,$from_table,$where_clause,$groupBy,$orderBy,$limit) {
00383
00384
00385 $this->resetStatusVars();
00386
00387
00388 $sqlObj = t3lib_div::makeInstance('t3lib_sqlengine_resultobj');
00389 $sqlObj->result = array();
00390
00391
00392 $tableArray = $this->parseFromTables($from_table);
00393 $table = $tableArray[0]['table'];
00394
00395
00396 $this->readDataSource($table);
00397
00398
00399 if (is_array($this->data[$table])) {
00400
00401
00402 $where = $this->parseWhereClause($where_clause);
00403 if (is_array($where)) {
00404
00405
00406 $itemKeys = $this->selectFromData($table,$where);
00407
00408
00409 $sqlObj->result = $this->getResultSet($itemKeys,$table,'*');
00410
00411 reset($sqlObj->result);
00412 return $sqlObj;
00413 } else $this->errorStatus = 'WHERE clause contained errors: '.$where;
00414 } else $this->errorStatus = 'No data loaded: '.$this->errorStatus;
00415
00416 return FALSE;
00417 }
00418
00425 function sql_query($query) {
00426 $res = t3lib_div::makeInstance('t3lib_sqlengine_resultobj');
00427 $res->result = array();
00428 return $res;
00429 }
00430
00436 function sql_error() {
00437 return $this->errorStatus;
00438 }
00439
00445 function sql_insert_id() {
00446 return $this->lastInsertedId;
00447 }
00448
00454 function sql_affected_rows() {
00455 return $this->lastAffectedRows;
00456 }
00457
00464 function quoteStr($str) {
00465 return addslashes($str);
00466 }
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00489 function admin_get_tables() {
00490 $whichTables = array();
00491 return $whichTables;
00492 }
00493
00500 function admin_get_fields($tableName) {
00501 $output = array();
00502 return $output;
00503 }
00504
00511 function admin_get_keys($tableName) {
00512 $output = array();
00513 return $output;
00514 }
00515
00522 function admin_query($query) {
00523 return $this->sql_query($query);
00524 }
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00547 function readDataSource($table) {
00548 $this->data[$table] = array();
00549 }
00550
00559 function saveDataSource($table) {
00560 debug($this->data[$table]);
00561 }
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00589 function selectFromData($table,$where) {
00590
00591 $output = array();
00592 if (is_array($this->data[$table])) {
00593
00594
00595 $OR_index = 0;
00596
00597 foreach($where as $config) {
00598
00599 if (strtoupper($config['operator'])=='OR') {
00600 $OR_index++;
00601 }
00602
00603 if (!isset($itemKeys[$OR_index])) $itemKeys[$OR_index] = array_keys($this->data[$table]);
00604
00605 $this->select_evalSingle($table,$config,$itemKeys[$OR_index]);
00606 }
00607
00608 foreach($itemKeys as $uidKeys) {
00609 $output = array_merge($output, $uidKeys);
00610 }
00611 $output = array_unique($output);
00612 }
00613
00614 return $output;
00615 }
00616
00627 function select_evalSingle($table,$config,&$itemKeys) {
00628 $neg = preg_match('/^AND[[:space:]]+NOT$/',trim($config['operator']));
00629
00630 if (is_array($config['sub'])) {
00631 $subSelKeys = $this->selectFromData($table,$config['sub']);
00632 if ($neg) {
00633 foreach($itemKeys as $kk => $vv) {
00634 if (in_array($vv,$subSelKeys)) {
00635 unset($itemKeys[$kk]);
00636 }
00637 }
00638 } else {
00639 $itemKeys = array_intersect($itemKeys, $subSelKeys);
00640 }
00641 } else {
00642 $comp = strtoupper(str_replace(array(' ',"\t","\r","\n"),'',$config['comparator']));
00643 $mod = strtoupper($config['modifier']);
00644 switch($comp) {
00645 case 'NOTLIKE':
00646 case 'LIKE':
00647 $like_value = strtolower($config['value'][0]);
00648 if (substr($like_value,0,1)=='%') {
00649 $wildCard_begin = TRUE;
00650 $like_value = substr($like_value,1);
00651 }
00652 if (substr($like_value,-1)=='%') {
00653 $wildCard_end = TRUE;
00654 $like_value = substr($like_value,0,-1);
00655 }
00656 break;
00657 case 'NOTIN':
00658 case 'IN':
00659 $in_valueArray = array();
00660 foreach($config['value'] as $vParts) {
00661 $in_valueArray[] = (string)$vParts[0];
00662 }
00663 break;
00664 }
00665
00666 foreach($itemKeys as $kk => $v) {
00667 $field_value = $this->data[$table][$v][$config['field']];
00668
00669
00670 if ($config['calc']=='&') {
00671 $field_value&=intval($config['calc_value']);
00672 }
00673
00674
00675 switch($comp) {
00676 case '<=':
00677 $bool = $field_value <= $config['value'][0];
00678 break;
00679 case '>=':
00680 $bool = $field_value >= $config['value'][0];
00681 break;
00682 case '<':
00683 $bool = $field_value < $config['value'][0];
00684 break;
00685 case '>':
00686 $bool = $field_value > $config['value'][0];
00687 break;
00688 case '=':
00689 $bool = !strcmp($field_value,$config['value'][0]);
00690 break;
00691 case '!=':
00692 $bool = strcmp($field_value,$config['value'][0]);
00693 break;
00694 case 'NOTIN':
00695 case 'IN':
00696 $bool = in_array((string)$field_value, $in_valueArray);
00697 if ($comp=='NOTIN') $bool = !$bool;
00698 break;
00699 case 'NOTLIKE':
00700 case 'LIKE':
00701 if (!strlen($like_value)) {
00702 $bool = TRUE;
00703 } elseif ($wildCard_begin && !$wildCard_end) {
00704 $bool = !strcmp(substr(strtolower($field_value),-strlen($like_value)),$like_value);
00705 } elseif (!$wildCard_begin && $wildCard_end) {
00706 $bool = !strcmp(substr(strtolower($field_value),0,strlen($like_value)),$like_value);
00707 } elseif ($wildCard_begin && $wildCard_end) {
00708 $bool = strstr($field_value,$like_value);
00709 } else {
00710 $bool = !strcmp(strtolower($field_value),$like_value);
00711 }
00712 if ($comp=='NOTLIKE') $bool = !$bool;
00713 break;
00714 default:
00715 $bool = $field_value ? TRUE : FALSE;
00716 break;
00717 }
00718
00719
00720 if ($neg) $bool = !$bool;
00721
00722
00723 switch($mod) {
00724 case 'NOT':
00725 case '!':
00726 $bool = !$bool;
00727 break;
00728 }
00729
00730
00731 if (!$bool) {
00732 unset($itemKeys[$kk]);
00733 }
00734 }
00735
00736 # echo $this->debug_printResultSet($this->getResultSet($itemKeys,$table,'uid,tstamp'));
00737 }
00738 }
00739
00748 function getResultSet($keys, $table, $fieldList) {
00749 $fields = t3lib_div::trimExplode(',',$fieldList);
00750
00751 $output = array();
00752 foreach($keys as $kValue) {
00753 if ($fieldList=='*') {
00754 $output[$kValue] = $this->data[$table][$kValue];
00755 } else {
00756 foreach($fields as $fieldName) {
00757 $output[$kValue][$fieldName] = $this->data[$table][$kValue][$fieldName];
00758 }
00759 }
00760 }
00761
00762 return $output;
00763 }
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00791 function debug_printResultSet($array) {
00792
00793 if (count($array)) {
00794 $tRows=array();
00795 $fields = array_keys(current($array));
00796 $tCell[]='
00797 <td>IDX</td>';
00798 foreach($fields as $fieldName) {
00799 $tCell[]='
00800 <td>'.htmlspecialchars($fieldName).'</td>';
00801 }
00802 $tRows[]='<tr>'.implode('',$tCell).'</tr>';
00803
00804
00805 foreach($array as $index => $rec) {
00806
00807 $tCell=array();
00808 $tCell[]='
00809 <td>'.htmlspecialchars($index).'</td>';
00810 foreach($fields as $fieldName) {
00811 $tCell[]='
00812 <td>'.htmlspecialchars($rec[$fieldName]).'</td>';
00813 }
00814 $tRows[]='<tr>'.implode('',$tCell).'</tr>';
00815 }
00816
00817 return '<table border="1">'.implode('',$tRows).'</table>';
00818 } else 'Empty resultset';
00819 }
00820 }
00821
00822
00830 class t3lib_sqlengine_resultobj {
00831
00832
00833 var $result = array();
00834
00835 var $TYPO3_DBAL_handlerType = '';
00836 var $TYPO3_DBAL_tableList = '';
00837
00838
00844 function sql_num_rows() {
00845 return count($this->result);
00846 }
00847
00853 function sql_fetch_assoc() {
00854 $row = current($this->result);
00855 next($this->result);
00856 return $row;
00857 }
00858
00864 function sql_fetch_row() {
00865 $resultRow = $this->sql_fetch_assoc();
00866
00867 if (is_array($resultRow)) {
00868 $numArray = array();
00869 foreach($resultRow as $value) {
00870 $numArray[]=$value;
00871 }
00872 return $numArray;
00873 }
00874 }
00875
00882 function sql_data_seek($pointer) {
00883 reset($this->result);
00884 for ($a=0;$a<$pointer;$a++) {
00885 next($this->result);
00886 }
00887 return TRUE;
00888 }
00889
00895 function sql_field_type() {
00896 return '';
00897 }
00898 }
00899
00900
00901
00902 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_sqlengine.php']) {
00903 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_sqlengine.php']);
00904 }
00905 ?>