Added comment for unknown variable
[Packages/TYPO3.CMS.git] / typo3 / sysext / dbal / lib / class.tx_dbal_sqlengine.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2009-2010 Xavier Perseguers <typo3@perseguers.ch>
6 * (c) 2004-2009 Kasper Skårhøj <kasperYYYY@typo3.com>
7 * All rights reserved
8 *
9 * This script is part of the TYPO3 project. The TYPO3 project is
10 * free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * The GNU General Public License can be found at
16 * http://www.gnu.org/copyleft/gpl.html.
17 * A copy is found in the textfile GPL.txt and important notices to the license
18 * from the author is found in LICENSE.txt distributed with these scripts.
19 *
20 *
21 * This script is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * This copyright notice MUST APPEAR in all copies of the script!
27 ***************************************************************/
28
29
30 /**
31 * PHP SQL engine
32 *
33 * $Id$
34 *
35 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
36 * @author Xavier Perseguers <typo3@perseguers.ch>
37 */
38 /**
39 * [CLASS/FUNCTION INDEX of SCRIPT]
40 *
41 *
42 *
43 * 106: class tx_dbal_sqlengine extends ux_t3lib_sqlparser
44 * 128: public function init($config, $pObj)
45 * 136: public function resetStatusVars()
46 * 152: private function processAccordingToConfig(&$value, $fInfo)
47 *
48 * SECTION: SQL queries
49 * 207: public function exec_INSERTquery($table, $fields_values)
50 * 275: public function exec_UPDATEquery($table, $where, $fields_values)
51 * 334: public function exec_DELETEquery($table, $where)
52 * 385: public function exec_SELECTquery($select_fields, $from_table, $where_clause, $groupBy, $orderBy, $limit)
53 * 428: public function sql_query($query)
54 * 439: public function sql_error()
55 * 448: public function sql_insert_id()
56 * 457: public function sql_affected_rows()
57 * 467: public function quoteStr($str)
58 *
59 * SECTION: SQL admin functions
60 * 493: public function admin_get_tables()
61 * 504: public function admin_get_fields($tableName)
62 * 515: public function admin_get_keys($tableName)
63 * 526: public function admin_query($query)
64 *
65 * SECTION: Data Source I/O
66 * 551: public function readDataSource($table)
67 * 563: public function saveDataSource($table)
68 *
69 * SECTION: SQL engine functions (PHP simulation of SQL) - still experimental
70 * 593: public function selectFromData($table, $where)
71 * 631: public function select_evalSingle($table,$config,&$itemKeys)
72 * 750: public function getResultSet($keys, $table, $fieldList)
73 *
74 * SECTION: Debugging
75 * 793: public function debug_printResultSet($array)
76 *
77 *
78 * 832: class tx_dbal_sqlengine_resultobj
79 * 846: public function sql_num_rows()
80 * 855: public function sql_fetch_assoc()
81 * 866: public function sql_fetch_row()
82 * 884: public function sql_data_seek($pointer)
83 * 897: public function sql_field_type()
84 *
85 * TOTAL FUNCTIONS: 27
86 * (This index is automatically created/updated by the extension "extdeveval")
87 *
88 */
89
90
91
92
93
94
95
96
97 /**
98 * PHP SQL engine / server
99 * Basically this is trying to emulation SQL record selection by PHP, thus allowing SQL queries into alternative data storages managed by PHP.
100 * EXPERIMENTAL!
101 *
102 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
103 * @package TYPO3
104 * @subpackage t3lib
105 */
106 class tx_dbal_sqlengine extends ux_t3lib_sqlparser {
107
108 // array with data records: [table name][num.index] = records
109 var $data = array(); // Data source storage
110
111
112 // Internal, SQL Status vars:
113 var $errorStatus = ''; // Set with error message of last operation
114 var $lastInsertedId = 0; // Set with last inserted unique ID
115 var $lastAffectedRows = 0; // Set with last number of affected rows.
116
117
118
119
120
121 /**
122 * Dummy function for initializing SQL handler. Create you own in derived classes.
123 *
124 * @param array Configuration array from handler
125 * @param object Parent object
126 * @return void
127 */
128 public function init($config, $pObj) {
129 }
130
131 /**
132 * Reset SQL engine status variables (insert id, affected rows, error status)
133 *
134 * @return void
135 */
136 public function resetStatusVars() {
137 $this->errorStatus = '';
138 $this->lastInsertedId = 0;
139 $this->lastAffectedRows = 0;
140 }
141
142 /**
143 * Processing of update/insert values based on field type.
144 *
145 * The input value is typecast and trimmed/shortened according to the field
146 * type and the configuration options from the $fInfo parameter.
147 *
148 * @param mixed $value The input value to process
149 * @param array $fInfo Field configuration data
150 * @return mixed The processed input value
151 */
152 private function processAccordingToConfig(&$value, $fInfo) {
153 $options = $this->parseFieldDef($fInfo['Type']);
154
155 switch(strtolower($options['fieldType'])) {
156 case 'int':
157 case 'smallint':
158 case 'tinyint':
159 case 'mediumint':
160 $value = intval($value);
161 if ($options['featureIndex']['UNSIGNED']) {
162 $value = t3lib_div::intInRange($value,0);
163 }
164 break;
165 case 'double':
166 $value = (double)$value;
167 break;
168 case 'varchar':
169 case 'char':
170 $value = substr($value,0,trim($options['value']));
171 break;
172 case 'text':
173 case 'blob':
174 $value = substr($value,0,65536);
175 break;
176 case 'tinytext':
177 case 'tinyblob':
178 $value = substr($value,0,256);
179 break;
180 case 'mediumtext':
181 case 'mediumblob':
182 // ??
183 break;
184 }
185 }
186
187
188
189
190
191
192
193 /********************************
194 *
195 * SQL queries
196 * This is the SQL access functions used when this class is instantiated as a SQL handler with DBAL. Override these in derived classes.
197 *
198 ********************************/
199
200 /**
201 * Execute an INSERT query
202 *
203 * @param string Table name
204 * @param array Field values as key=>value pairs.
205 * @return boolean TRUE on success and FALSE on failure (error is set internally)
206 */
207 public function exec_INSERTquery($table, $fields_values) {
208
209 // Initialize
210 $this->resetStatusVars();
211
212 // Reading Data Source if not done already.
213 $this->readDataSource($table);
214
215 // If data source is set:
216 if (is_array($this->data[$table])) {
217
218 $fieldInformation = $this->admin_get_fields($table); // Should cache this...!
219
220 // Looking for unique keys:
221 $saveArray = array();
222 foreach($fieldInformation as $fInfo) {
223
224 // Field name:
225 $fN = $fInfo['Field'];
226
227 // Set value:
228 // FIXME $options not defined
229 $saveArray[$fN] = isset($fields_values[$fN]) ? $fields_values[$fN] : $options['Default'];
230
231 // Process value:
232 $this->processAccordingToConfig($saveArray[$fN], $fInfo);
233
234 // If an auto increment field is found, find the largest current uid:
235 if ($fInfo['Extra'] == 'auto_increment') {
236
237 // Get all UIDs:
238 $uidArray = array();
239 foreach($this->data[$table] as $r) {
240 $uidArray[] = $r[$fN];
241 }
242
243 // If current value is blank or already in array, we create a new:
244 if (!$saveArray[$fN] || in_array(intval($saveArray[$fN]), $uidArray)) {
245 if (count($uidArray)) {
246 $saveArray[$fN] = max($uidArray)+1;
247 } else $saveArray[$fN] = 1;
248 }
249
250 // Update "last inserted id":
251 $this->lastInsertedId = $saveArray[$fN];
252 }
253 }
254
255 // Insert row in table:
256 $this->data[$table][] = $saveArray;
257
258 // Save data source
259 $this->saveDataSource($table);
260
261 return TRUE;
262 } else $this->errorStatus = 'No data loaded.';
263
264 return FALSE;
265 }
266
267 /**
268 * Execute UPDATE query on table
269 *
270 * @param string Table name
271 * @param string WHERE clause
272 * @param array Field values as key=>value pairs.
273 * @return boolean TRUE on success and FALSE on failure (error is set internally)
274 */
275 public function exec_UPDATEquery($table, $where, $fields_values) {
276
277 // Initialize:
278 $this->resetStatusVars();
279
280 // Reading Data Source if not done already.
281 $this->readDataSource($table);
282
283 // If anything is there:
284 if (is_array($this->data[$table])) {
285
286 // Parse WHERE clause:
287 $where = $this->parseWhereClause($where);
288
289 if (is_array($where)) {
290
291 // Field information
292 $fieldInformation = $this->admin_get_fields($table); // Should cache this...!
293
294 // Traverse fields to update:
295 foreach($fields_values as $fName => $fValue) {
296 $this->processAccordingToConfig($fields_values[$fName],$fieldInformation[$fName]);
297 }
298
299 // Do query, returns array with keys to the data array of the result:
300 $itemKeys = $this->selectFromData($table,$where);
301
302 // Set "last affected rows":
303 $this->lastAffectedRows = count($itemKeys);
304
305 // Update rows:
306 if ($this->lastAffectedRows) {
307 // Traverse result set here:
308 foreach($itemKeys as $dataArrayKey) {
309
310 // Traverse fields to update:
311 foreach($fields_values as $fName => $fValue) {
312 $this->data[$table][$dataArrayKey][$fName] = $fValue;
313 }
314 }
315
316 // Save data source
317 $this->saveDataSource($table);
318 }
319
320 return TRUE;
321 } else $this->errorStatus = 'WHERE clause contained errors: '.$where;
322 } else $this->errorStatus = 'No data loaded.';
323
324 return FALSE;
325 }
326
327 /**
328 * Execute DELETE query
329 *
330 * @param string Table to delete from
331 * @param string WHERE clause
332 * @return boolean TRUE on success and FALSE on failure (error is set internally)
333 */
334 public function exec_DELETEquery($table, $where) {
335
336 // Initialize:
337 $this->resetStatusVars();
338
339 // Reading Data Source if not done already.
340 $this->readDataSource($table);
341
342 // If anything is there:
343 if (is_array($this->data[$table])) {
344
345 // Parse WHERE clause:
346 $where = $this->parseWhereClause($where);
347
348 if (is_array($where)) {
349
350 // Do query, returns array with keys to the data array of the result:
351 $itemKeys = $this->selectFromData($table,$where);
352
353 // Set "last affected rows":
354 $this->lastAffectedRows = count($itemKeys);
355
356 // Remove rows:
357 if ($this->lastAffectedRows) {
358 // Traverse result set:
359 foreach($itemKeys as $dataArrayKey) {
360 unset($this->data[$table][$dataArrayKey]);
361 }
362
363 // Saving data source
364 $this->saveDataSource($table);
365 }
366
367 return TRUE;
368 } else $this->errorStatus = 'WHERE clause contained errors: '.$where;
369 } else $this->errorStatus = 'No data loaded.';
370
371 return FALSE;
372 }
373
374 /**
375 * Execute SELECT query
376 *
377 * @param string List of fields to select from the table. This is what comes right after "SELECT ...". Required value.
378 * @param string Table(s) from which to select. This is what comes right after "FROM ...". Required value.
379 * @param string Optional additional WHERE clauses put in the end of the query. NOTICE: You must escape values in this argument with $this->fullQuoteStr() yourself! DO NOT PUT IN GROUP BY, ORDER BY or LIMIT!
380 * @param string Optional GROUP BY field(s), if none, supply blank string.
381 * @param string Optional ORDER BY field(s), if none, supply blank string.
382 * @param string Optional LIMIT value ([begin,]max), if none, supply blank string.
383 * @return object Returns result object, but if errors, returns false
384 */
385 public function exec_SELECTquery($select_fields, $from_table, $where_clause, $groupBy, $orderBy, $limit) {
386
387 // Initialize:
388 $this->resetStatusVars();
389
390 // Create result object
391 $sqlObj = t3lib_div::makeInstance('tx_dbal_sqlengine_resultobj');
392 $sqlObj->result = array(); // Empty result as a beginning
393
394 // Get table list:
395 $tableArray = $this->parseFromTables($from_table);
396 $table = $tableArray[0]['table'];
397
398 // Reading Data Source if not done already.
399 $this->readDataSource($table);
400
401 // If anything is there:
402 if (is_array($this->data[$table])) {
403
404 // Parse WHERE clause:
405 $where = $this->parseWhereClause($where_clause);
406 if (is_array($where)) {
407
408 // Do query, returns array with keys to the data array of the result:
409 $itemKeys = $this->selectFromData($table,$where);
410
411 // Finally, read the result rows into this variable:
412 $sqlObj->result = $this->getResultSet($itemKeys,$table,'*');
413 // Reset and return result:
414 reset($sqlObj->result);
415 return $sqlObj;
416 } else $this->errorStatus = 'WHERE clause contained errors: '.$where;
417 } else $this->errorStatus = 'No data loaded: '.$this->errorStatus;
418
419 return FALSE;
420 }
421
422 /**
423 * Performs an SQL query on the "database"
424 *
425 * @param string Query to execute
426 * @return object Result object or false if error
427 */
428 public function sql_query($query) {
429 $res = t3lib_div::makeInstance('tx_dbal_sqlengine_resultobj');
430 $res->result = array();
431 return $res;
432 }
433
434 /**
435 * Returns most recent error
436 *
437 * @return string Error message, if any
438 */
439 public function sql_error() {
440 return $this->errorStatus;
441 }
442
443 /**
444 * Returns most recently create unique ID (of INSERT queries)
445 *
446 * @return integer Last unique id created.
447 */
448 public function sql_insert_id() {
449 return $this->lastInsertedId;
450 }
451
452 /**
453 * Returns affected rows (of UPDATE and DELETE queries)
454 *
455 * @return integer Last amount of affected rows.
456 */
457 public function sql_affected_rows() {
458 return $this->lastAffectedRows;
459 }
460
461 /**
462 * Quoting strings for insertion in SQL queries
463 *
464 * @param string Input String
465 * @return string String, with quotes escaped
466 */
467 public function quoteStr($str) {
468 return addslashes($str);
469 }
470
471
472
473
474
475
476
477
478
479
480 /**************************************
481 *
482 * SQL admin functions
483 * (For use in the Install Tool and Extension Manager)
484 *
485 **************************************/
486
487 /**
488 * (DUMMY) Returns the list of tables from the database
489 *
490 * @return array Tables in an array (tablename is in both key and value)
491 * @todo Should return table details in value! see t3lib_db::admin_get_tables()
492 */
493 public function admin_get_tables() {
494 $whichTables = array();
495 return $whichTables;
496 }
497
498 /**
499 * (DUMMY) Returns information about each field in the $table
500 *
501 * @param string Table name
502 * @return array Field information in an associative array with fieldname => field row
503 */
504 public function admin_get_fields($tableName) {
505 $output = array();
506 return $output;
507 }
508
509 /**
510 * (DUMMY) Returns information about each index key in the $table
511 *
512 * @param string Table name
513 * @return array Key information in a numeric array
514 */
515 public function admin_get_keys($tableName) {
516 $output = array();
517 return $output;
518 }
519
520 /**
521 * (DUMMY) mysql() wrapper function, used by the Install Tool and EM for all queries regarding management of the database!
522 *
523 * @param string Query to execute
524 * @return pointer Result pointer
525 */
526 public function admin_query($query) {
527 return $this->sql_query($query);
528 }
529
530
531
532
533
534
535
536
537 /********************************
538 *
539 * Data Source I/O
540 *
541 ********************************/
542
543 /**
544 * Dummy function for setting table data. Create your own.
545 * NOTICE: Handler to "table-locking" needs to be made probably!
546 *
547 * @param string Table name
548 * @return void
549 * @todo Table locking tools?
550 */
551 public function readDataSource($table) {
552 $this->data[$table] = array();
553 }
554
555 /**
556 * Dummy function for setting table data. Create your own.
557 * NOTICE: Handler to "table-locking" needs to be made probably!
558 *
559 * @param string Table name
560 * @return void
561 * @todo Table locking tools?
562 */
563 public function saveDataSource($table) {
564 debug($this->data[$table]);
565 }
566
567
568
569
570
571
572
573
574
575
576
577
578
579 /********************************
580 *
581 * SQL engine functions (PHP simulation of SQL) - still experimental
582 *
583 ********************************/
584
585 /**
586 * PHP simulation of SQL "SELECT"
587 * Yet EXPERIMENTAL!
588 *
589 * @param string Table name
590 * @param array Where clause parsed into array
591 * @return array Array of keys pointing to result rows in $this->data[$table]
592 */
593 public function selectFromData($table, $where) {
594
595 $output = array();
596 if (is_array($this->data[$table])) {
597
598 // All keys:
599 $OR_index = 0;
600
601 foreach($where as $config) {
602
603 if (strtoupper($config['operator'])=='OR') {
604 $OR_index++;
605 }
606 // FIXME: unknown variable $itemKeys
607 if (!isset($itemKeys[$OR_index])) $itemKeys[$OR_index] = array_keys($this->data[$table]);
608
609 $this->select_evalSingle($table,$config,$itemKeys[$OR_index]);
610 }
611
612 foreach($itemKeys as $uidKeys) {
613 $output = array_merge($output, $uidKeys);
614 }
615 $output = array_unique($output);
616 }
617
618 return $output;
619 }
620
621 /**
622 * Evalutaion of a WHERE-clause-array.
623 * Yet EXPERIMENTAL
624 *
625 * @param string Tablename
626 * @param array WHERE-configuration array
627 * @param array Data array to work on.
628 * @return void Data array passed by reference
629 * @see selectFromData()
630 */
631 public function select_evalSingle($table,$config,&$itemKeys) {
632 $neg = preg_match('/^AND[[:space:]]+NOT$/',trim($config['operator']));
633
634 if (is_array($config['sub'])) {
635 $subSelKeys = $this->selectFromData($table,$config['sub']);
636 if ($neg) {
637 foreach($itemKeys as $kk => $vv) {
638 if (in_array($vv,$subSelKeys)) {
639 unset($itemKeys[$kk]);
640 }
641 }
642 } else {
643 $itemKeys = array_intersect($itemKeys, $subSelKeys);
644 }
645 } else {
646 $comp = strtoupper(str_replace(array(' ',"\t","\r","\n"),'',$config['comparator']));
647 $mod = strtoupper($config['modifier']);
648 switch($comp) {
649 case 'NOTLIKE':
650 case 'LIKE':
651 $like_value = strtolower($config['value'][0]);
652 if (substr($like_value,0,1)=='%') {
653 $wildCard_begin = TRUE;
654 $like_value = substr($like_value,1);
655 }
656 if (substr($like_value,-1)=='%') {
657 $wildCard_end = TRUE;
658 $like_value = substr($like_value,0,-1);
659 }
660 break;
661 case 'NOTIN':
662 case 'IN':
663 $in_valueArray = array();
664 foreach($config['value'] as $vParts) {
665 $in_valueArray[] = (string)$vParts[0];
666 }
667 break;
668 }
669
670 foreach($itemKeys as $kk => $v) {
671 $field_value = $this->data[$table][$v][$config['field']];
672
673 // Calculate it:
674 if ($config['calc']=='&') {
675 $field_value&=intval($config['calc_value']);
676 }
677
678 // Compare it:
679 switch($comp) {
680 case '<=':
681 $bool = $field_value <= $config['value'][0];
682 break;
683 case '>=':
684 $bool = $field_value >= $config['value'][0];
685 break;
686 case '<':
687 $bool = $field_value < $config['value'][0];
688 break;
689 case '>':
690 $bool = $field_value > $config['value'][0];
691 break;
692 case '=':
693 $bool = !strcmp($field_value,$config['value'][0]);
694 break;
695 case '!=':
696 $bool = strcmp($field_value,$config['value'][0]);
697 break;
698 case 'NOTIN':
699 case 'IN':
700 $bool = in_array((string)$field_value, $in_valueArray);
701 if ($comp=='NOTIN') $bool = !$bool;
702 break;
703 case 'NOTLIKE':
704 case 'LIKE':
705 if (!strlen($like_value)) {
706 $bool = TRUE;
707 } elseif ($wildCard_begin && !$wildCard_end) {
708 $bool = !strcmp(substr(strtolower($field_value),-strlen($like_value)),$like_value);
709 } elseif (!$wildCard_begin && $wildCard_end) {
710 $bool = !strcmp(substr(strtolower($field_value),0,strlen($like_value)),$like_value);
711 } elseif ($wildCard_begin && $wildCard_end) {
712 $bool = strstr($field_value,$like_value);
713 } else {
714 $bool = !strcmp(strtolower($field_value),$like_value);
715 }
716 if ($comp=='NOTLIKE') $bool = !$bool;
717 break;
718 default:
719 $bool = $field_value ? TRUE : FALSE;
720 break;
721 }
722
723 // General negation:
724 if ($neg) $bool = !$bool;
725
726 // Modify?
727 switch($mod) {
728 case 'NOT':
729 case '!':
730 $bool = !$bool;
731 break;
732 }
733
734 // Action:
735 if (!$bool) {
736 unset($itemKeys[$kk]);
737 }
738 }
739 }
740 }
741
742 /**
743 * Returning result set based on result keys, table and field list
744 *
745 * @param array Result keys
746 * @param string Tablename
747 * @param string Fieldlist (commaseparated)
748 * @return array Result array with "rows"
749 */
750 public function getResultSet($keys, $table, $fieldList) {
751 $fields = t3lib_div::trimExplode(',',$fieldList);
752
753 $output = array();
754 foreach($keys as $kValue) {
755 if ($fieldList=='*') {
756 $output[$kValue] = $this->data[$table][$kValue];
757 } else {
758 foreach($fields as $fieldName) {
759 $output[$kValue][$fieldName] = $this->data[$table][$kValue][$fieldName];
760 }
761 }
762 }
763
764 return $output;
765 }
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781 /*************************
782 *
783 * Debugging
784 *
785 *************************/
786
787 /**
788 * Returns the result set (in array) as HTML table. For debugging.
789 *
790 * @param array Result set array (array of rows)
791 * @return string HTML table
792 */
793 public function debug_printResultSet($array) {
794
795 if (count($array)) {
796 $tRows=array();
797 $fields = array_keys(current($array));
798 $tCell[]='
799 <td>IDX</td>';
800 foreach($fields as $fieldName) {
801 $tCell[]='
802 <td>'.htmlspecialchars($fieldName).'</td>';
803 }
804 $tRows[]='<tr>'.implode('',$tCell).'</tr>';
805
806
807 foreach($array as $index => $rec) {
808
809 $tCell=array();
810 $tCell[]='
811 <td>'.htmlspecialchars($index).'</td>';
812 foreach($fields as $fieldName) {
813 $tCell[]='
814 <td>'.htmlspecialchars($rec[$fieldName]).'</td>';
815 }
816 $tRows[]='<tr>'.implode('',$tCell).'</tr>';
817 }
818
819 return '<table border="1">'.implode('',$tRows).'</table>';
820 } else 'Empty resultset';
821 }
822 }
823
824
825 /**
826 * PHP SQL engine, result object
827 *
828 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
829 * @package TYPO3
830 * @subpackage dbal
831 */
832 class tx_dbal_sqlengine_resultobj {
833
834 // Result array, must contain the fields in the order they were selected in the SQL statement (for sql_fetch_row())
835 var $result = array();
836
837 var $TYPO3_DBAL_handlerType = '';
838 var $TYPO3_DBAL_tableList = '';
839
840
841 /**
842 * Counting number of rows
843 *
844 * @return integer
845 */
846 public function sql_num_rows() {
847 return count($this->result);
848 }
849
850 /**
851 * Fetching next row in result array
852 *
853 * @return array Associative array
854 */
855 public function sql_fetch_assoc() {
856 $row = current($this->result);
857 next($this->result);
858 return $row;
859 }
860
861 /**
862 * Fetching next row, numerical indices
863 *
864 * @return array Numerical array
865 */
866 public function sql_fetch_row() {
867 $resultRow = $this->sql_fetch_assoc();
868
869 if (is_array($resultRow)) {
870 $numArray = array();
871 foreach($resultRow as $value) {
872 $numArray[]=$value;
873 }
874 return $numArray;
875 }
876 }
877
878 /**
879 * Seeking position in result
880 *
881 * @param integer Position pointer.
882 * @return boolean Returns true on success
883 */
884 public function sql_data_seek($pointer) {
885 reset($this->result);
886 for ($a=0;$a<$pointer;$a++) {
887 next($this->result);
888 }
889 return TRUE;
890 }
891
892 /**
893 * Returning SQL field type
894 *
895 * @return string Blank string, not supported (it seems)
896 */
897 public function sql_field_type() {
898 return '';
899 }
900 }
901
902
903
904 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dbal/lib/class.tx_dbal_sqlengine.php']) {
905 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dbal/lib/class.tx_dbal_sqlengine.php']);
906 }
907
908 ?>