Public Member Functions | |
parseSQL ($parseString) | |
Parses any single SQL query. | |
parseSELECT ($parseString) | |
Parsing SELECT query. | |
parseUPDATE ($parseString) | |
Parsing UPDATE query. | |
parseINSERT ($parseString) | |
Parsing INSERT query. | |
parseDELETE ($parseString) | |
Parsing DELETE query. | |
parseEXPLAIN ($parseString) | |
Parsing EXPLAIN query. | |
parseCREATETABLE ($parseString) | |
Parsing CREATE TABLE query. | |
parseALTERTABLE ($parseString) | |
Parsing ALTER TABLE query. | |
parseDROPTABLE ($parseString) | |
Parsing DROP TABLE query. | |
parseFieldList (&$parseString, $stopRegex='') | |
Parsing the fields in the "SELECT [$selectFields] FROM" part of a query into an array. | |
parseFromTables (&$parseString, $stopRegex='') | |
Parsing the tablenames in the "FROM [$parseString] WHERE" part of a query into an array. | |
parseWhereClause (&$parseString, $stopRegex='') | |
Parsing the WHERE clause fields in the "WHERE [$parseString] ..." part of a query into a multidimensional array. | |
parseFieldDef (&$parseString, $stopRegex='') | |
Parsing the WHERE clause fields in the "WHERE [$parseString] ..." part of a query into a multidimensional array. | |
nextPart (&$parseString, $regex, $trimAll=FALSE) | |
Strips of a part of the parseString and returns the matching part. | |
getValue (&$parseString, $comparator='') | |
Finds value in beginning of $parseString, returns result and strips it of parseString. | |
Public Attributes | |
$parse_error = '' | |
$lastStopKeyWord = '' |
|
Finds value in beginning of $parseString, returns result and strips it of parseString.
Strip slashes function used for parsing NOTICE: If a query being parsed was prepared for another database than MySQL this function should probably be changed
Add slashes function used for compiling queries NOTICE: If a query being parsed was prepared for another database than MySQL this function should probably be changed
Setting the internal error message value, $this->parse_error and returns that value.
Trimming SQL as preparation for parsing. ";" in the end is stripped of. White space is trimmed away around the value A single space-char is added in the end
Compiles an SQL query from components
Compiles a SELECT statement from components array
Compiles an UPDATE statement from components array
Compiles an INSERT statement from components array
Compiles an DELETE statement from components array
Compiles a CREATE TABLE statement from components array
Compiles an ALTER TABLE statement from components array
Compiles a "SELECT [output] FROM..:" field list based on input array (made with ->parseFieldList()) Can also compile field lists for ORDER BY and GROUP BY.
Compiles a "FROM [output] WHERE..:" table list based on input array (made with ->parseFromTables())
Implodes an array of WHERE clause configuration into a WHERE clause. NOTICE: MIGHT BY A TEMPORARY FUNCTION. Use for debugging only!
Compile field definition
Check parsability of input SQL part string; Will parse and re-compile after which it is compared
Compare two query strins by stripping away whitespace.
Performs the ultimate test of the parser: Direct a SQL query in; You will get it back (through the parsed and re-compiled) if no problems, otherwise the script will print the error and exit
Definition at line 999 of file class.t3lib_sqlparser.php. |
|
Strips of a part of the parseString and returns the matching part. Helper function for the parsing methods.
Definition at line 985 of file class.t3lib_sqlparser.php. Referenced by parseSQL(). 00985 { 00986 if (eregi($regex,$parseString.' ', $reg)) { // Adding space char because [[:space:]]+ is often a requirement in regex's 00987 $parseString = ltrim(substr($parseString,strlen($reg[$trimAll?0:1]))); 00988 return $reg[1]; 00989 } 00990 }
|
|
Parsing ALTER TABLE query.
Definition at line 503 of file class.t3lib_sqlparser.php. Referenced by parseSQL(). 00503 { 00504 00505 // Removing ALTER TABLE 00506 $parseString = $this->trimSQL($parseString); 00507 $parseString = eregi_replace('^ALTER[[:space:]]+TABLE[[:space:]]+','',$parseString); 00508 00509 // Init output variable: 00510 $result = array(); 00511 $result['type'] = 'ALTERTABLE'; 00512 00513 // Get table: 00514 $result['TABLE'] = $this->nextPart($parseString, '^([[:alnum:]_]+)[[:space:]]+'); 00515 00516 if ($result['TABLE']) { 00517 if ($result['action'] = $this->nextPart($parseString, '^(CHANGE|DROP[[:space:]]+KEY|DROP[[:space:]]+PRIMARY[[:space:]]+KEY|ADD[[:space:]]+KEY|ADD[[:space:]]+PRIMARY[[:space:]]+KEY|DROP|ADD|RENAME)([[:space:]]+|\()')) { 00518 $actionKey = strtoupper(ereg_replace('[[:space:]]','',$result['action'])); 00519 00520 // Getting field: 00521 if (t3lib_div::inList('ADDPRIMARYKEY,DROPPRIMARYKEY',$actionKey) || $fieldKey = $this->nextPart($parseString, '^([[:alnum:]_]+)[[:space:]]+')) { 00522 00523 switch($actionKey) { 00524 case 'ADD': 00525 $result['FIELD'] = $fieldKey; 00526 $result['definition'] = $this->parseFieldDef($parseString); 00527 if ($this->parse_error) { return $this->parse_error; } 00528 break; 00529 case 'DROP': 00530 case 'RENAME': 00531 $result['FIELD'] = $fieldKey; 00532 break; 00533 case 'CHANGE': 00534 $result['FIELD'] = $fieldKey; 00535 if ($result['newField'] = $this->nextPart($parseString, '^([[:alnum:]_]+)[[:space:]]+')) { 00536 $result['definition'] = $this->parseFieldDef($parseString); 00537 if ($this->parse_error) { return $this->parse_error; } 00538 } else return $this->parseError('No NEW field name found',$parseString); 00539 break; 00540 00541 case 'ADDKEY': 00542 case 'ADDPRIMARYKEY': 00543 $result['KEY'] = $fieldKey; 00544 $result['fields'] = $this->getValue($parseString,'_LIST'); 00545 if ($this->parse_error) { return $this->parse_error; } 00546 break; 00547 case 'DROPKEY': 00548 $result['KEY'] = $fieldKey; 00549 break; 00550 case 'DROPPRIMARYKEY': 00551 // ??? todo! 00552 break; 00553 } 00554 } else return $this->parseError('No field name found',$parseString); 00555 } else return $this->parseError('No action CHANGE, DROP or ADD found!',$parseString); 00556 } else return $this->parseError('No table found!',$parseString); 00557 00558 // Should be no more content now: 00559 if ($parseString) { 00560 return $this->parseError('Still content in clause after parsing!',$parseString); 00561 } 00562 00563 return $result; 00564 }
|
|
Parsing CREATE TABLE query.
Definition at line 431 of file class.t3lib_sqlparser.php. Referenced by parseSQL(). 00431 { 00432 00433 // Removing CREATE TABLE 00434 $parseString = $this->trimSQL($parseString); 00435 $parseString = eregi_replace('^CREATE[[:space:]]+TABLE[[:space:]]+','',$parseString); 00436 00437 // Init output variable: 00438 $result = array(); 00439 $result['type'] = 'CREATETABLE'; 00440 00441 // Get table: 00442 $result['TABLE'] = $this->nextPart($parseString, '^([[:alnum:]_]+)[[:space:]]*\(',TRUE); 00443 00444 if ($result['TABLE']) { 00445 00446 // While the parseString is not yet empty: 00447 while(strlen($parseString)>0) { 00448 if ($key = $this->nextPart($parseString, '^(KEY|PRIMARY KEY)([[:space:]]+|\()')) { // Getting key 00449 $key = strtoupper(ereg_replace('[[:space:]]','',$key)); 00450 00451 switch($key) { 00452 case 'PRIMARYKEY': 00453 $result['KEYS'][$key] = $this->getValue($parseString,'_LIST'); 00454 if ($this->parse_error) { return $this->parse_error; } 00455 break; 00456 case 'KEY': 00457 if ($keyName = $this->nextPart($parseString, '^([[:alnum:]_]+)([[:space:]]+|\()')) { 00458 $result['KEYS'][$keyName] = $this->getValue($parseString,'_LIST'); 00459 if ($this->parse_error) { return $this->parse_error; } 00460 } else return $this->parseError('No keyname found',$parseString); 00461 break; 00462 } 00463 } elseif ($fieldName = $this->nextPart($parseString, '^([[:alnum:]_]+)[[:space:]]+')) { // Getting field: 00464 $result['FIELDS'][$fieldName]['definition'] = $this->parseFieldDef($parseString); 00465 if ($this->parse_error) { return $this->parse_error; } 00466 } 00467 00468 // Finding delimiter: 00469 $delim = $this->nextPart($parseString, '^(,|\))'); 00470 if (!$delim) { 00471 return $this->parseError('No delimiter found',$parseString); 00472 } elseif ($delim==')') { 00473 break; 00474 } 00475 } 00476 00477 // Finding what is after the table definition - table type in MySQL 00478 if ($delim==')') { 00479 if ($this->nextPart($parseString, '^(TYPE[[:space:]]*=)')) { 00480 $result['tableType'] = $parseString; 00481 $parseString = ''; 00482 } 00483 } else return $this->parseError('No fieldname found!',$parseString); 00484 00485 // Getting table type 00486 } else return $this->parseError('No table found!',$parseString); 00487 00488 // Should be no more content now: 00489 if ($parseString) { 00490 return $this->parseError('Still content in clause after parsing!',$parseString); 00491 } 00492 00493 return $result; 00494 }
|
|
Parsing DELETE query.
Definition at line 371 of file class.t3lib_sqlparser.php. Referenced by parseSQL(). 00371 { 00372 00373 // Removing DELETE 00374 $parseString = $this->trimSQL($parseString); 00375 $parseString = eregi_replace('^DELETE[[:space:]]+FROM[[:space:]]+','',$parseString); 00376 00377 // Init output variable: 00378 $result = array(); 00379 $result['type'] = 'DELETE'; 00380 00381 // Get table: 00382 $result['TABLE'] = $this->nextPart($parseString, '^([[:alnum:]_]+)[[:space:]]+'); 00383 00384 if ($result['TABLE']) { 00385 00386 // WHERE 00387 if ($this->nextPart($parseString,'^(WHERE)')) { 00388 $result['WHERE'] = $this->parseWhereClause($parseString); 00389 if ($this->parse_error) { return $this->parse_error; } 00390 } 00391 } else return $this->parseError('No table found!',$parseString); 00392 00393 // Should be no more content now: 00394 if ($parseString) { 00395 return $this->parseError('Still content in clause after parsing!',$parseString); 00396 } 00397 00398 // Return result: 00399 return $result; 00400 }
|
|
Parsing DROP TABLE query.
Definition at line 572 of file class.t3lib_sqlparser.php. Referenced by parseSQL(). 00572 { 00573 00574 // Removing DROP TABLE 00575 $parseString = $this->trimSQL($parseString); 00576 $parseString = eregi_replace('^DROP[[:space:]]+TABLE[[:space:]]+','',$parseString); 00577 00578 // Init output variable: 00579 $result = array(); 00580 $result['type'] = 'DROPTABLE'; 00581 00582 // IF EXISTS 00583 $result['ifExists'] = $this->nextPart($parseString, '^(IF[[:space:]]+EXISTS[[:space:]]+)'); 00584 00585 // Get table: 00586 $result['TABLE'] = $this->nextPart($parseString, '^([[:alnum:]_]+)[[:space:]]+'); 00587 00588 if ($result['TABLE']) { 00589 00590 // Should be no more content now: 00591 if ($parseString) { 00592 return $this->parseError('Still content in clause after parsing!',$parseString); 00593 } 00594 00595 return $result; 00596 } else return $this->parseError('No table found!',$parseString); 00597 }
|
|
Parsing EXPLAIN query.
Definition at line 409 of file class.t3lib_sqlparser.php. Referenced by parseSQL(). 00409 { 00410 00411 // Removing EXPLAIN 00412 $parseString = $this->trimSQL($parseString); 00413 $parseString = eregi_replace('^EXPLAIN[[:space:]]+','',$parseString); 00414 00415 // Init output variable: 00416 $result = $this->parseSELECT($parseString); 00417 if (is_array($result)) { 00418 $result['type'] = 'EXPLAIN'; 00419 } 00420 00421 return $result; 00422 }
|
|
Parsing the WHERE clause fields in the "WHERE [$parseString] ..." part of a query into a multidimensional array. The success of this parsing determines if that part of the query is supported by TYPO3.
Definition at line 924 of file class.t3lib_sqlparser.php. Referenced by t3lib_sqlengine::processAccordingToConfig(). 00924 { 00925 // Prepare variables: 00926 $parseString = $this->trimSQL($parseString); 00927 $this->lastStopKeyWord = ''; 00928 $this->parse_error = ''; 00929 00930 $result = array(); 00931 00932 // Field type: 00933 if ($result['fieldType'] = $this->nextPart($parseString,'^(int|smallint|tinyint|mediumint|double|varchar|char|text|tinytext|mediumtext|blob|tinyblob|mediumblob|longblob)([[:space:]]+|\()')) { 00934 00935 // Looking for value: 00936 if (substr($parseString,0,1)=='(') { 00937 $parseString = substr($parseString,1); 00938 if ($result['value'] = $this->nextPart($parseString,'^([^)]*)')) { 00939 $parseString = ltrim(substr($parseString,1)); 00940 } else return $this->parseError('No end-parenthesis for value found!',$parseString); 00941 } 00942 00943 // Looking for keywords 00944 while($keyword = $this->nextPart($parseString,'^(DEFAULT|NOT[[:space:]]+NULL|AUTO_INCREMENT|UNSIGNED)([[:space:]]+|,|\))')) { 00945 $keywordCmp = strtoupper(ereg_replace('[[:space:]]*','',$keyword)); 00946 00947 $result['featureIndex'][$keywordCmp]['keyword'] = $keyword; 00948 00949 switch($keywordCmp) { 00950 case 'DEFAULT': 00951 $result['featureIndex'][$keywordCmp]['value'] = $this->getValue($parseString); 00952 break; 00953 } 00954 } 00955 } else return $this->parseError('Field type unknown!',$parseString); 00956 00957 return $result; 00958 }
|
|
Parsing the fields in the "SELECT [$selectFields] FROM" part of a query into an array. The output from this function can be compiled back into a field list with ->compileFieldList() Will detect the keywords "DESC" and "ASC" after the table name; thus is can be used for parsing the more simply ORDER BY and GROUP BY field lists as well!
Definition at line 631 of file class.t3lib_sqlparser.php. 00631 { 00632 00633 // Prepare variables: 00634 $parseString = $this->trimSQL($parseString); 00635 $this->lastStopKeyWord = ''; 00636 $this->parse_error = ''; 00637 00638 00639 $stack = array(); // Contains the parsed content 00640 $pnt = 0; // Pointer to positions in $stack 00641 $level = 0; // Indicates the parenthesis level we are at. 00642 $loopExit = 0; // Recursivity brake. 00643 00644 // $parseString is continously shortend by the process and we keep parsing it till it is zero: 00645 while (strlen($parseString)) { 00646 00647 // Checking if we are inside / outside parenthesis (in case of a function like count(), max(), min() etc...): 00648 if ($level>0) { // Inside parenthesis here (does NOT detect if values in quotes are used, the only token is ")" or "("): 00649 00650 // Accumulate function content until next () parenthesis: 00651 $funcContent = $this->nextPart($parseString,'^([^()]*.)'); 00652 $stack[$pnt]['func_content.'][] = array( 00653 'level' => $level, 00654 'func_content' => substr($funcContent,0,-1) 00655 ); 00656 $stack[$pnt]['func_content'].= $funcContent; 00657 00658 // Detecting ( or ) 00659 switch(substr($stack[$pnt]['func_content'],-1)) { 00660 case '(': 00661 $level++; 00662 break; 00663 case ')': 00664 $level--; 00665 if (!$level) { // If this was the last parenthesis: 00666 $stack[$pnt]['func_content'] = substr($stack[$pnt]['func_content'],0,-1); 00667 $parseString = ltrim($parseString); // Remove any whitespace after the parenthesis. 00668 } 00669 break; 00670 } 00671 } else { // Outside parenthesis, looking for next field: 00672 00673 // Looking for a known function (only known functions supported) 00674 $func = $this->nextPart($parseString,'^(count|max|min|floor|sum|avg)[[:space:]]*\('); 00675 if ($func) { 00676 $parseString = trim(substr($parseString,1)); // Strip of "(" 00677 $stack[$pnt]['type'] = 'function'; 00678 $stack[$pnt]['function'] = $func; 00679 $level++; // increse parenthesis level counter. 00680 } else { 00681 // Otherwise, look for regular fieldname: 00682 if ($fieldName = $this->nextPart($parseString,'^([[:alnum:]\*._]+)(,|[[:space:]]+)')) { 00683 $stack[$pnt]['type'] = 'field'; 00684 00685 // Explode fieldname into field and table: 00686 $tableField = explode('.',$fieldName,2); 00687 if (count($tableField)==2) { 00688 $stack[$pnt]['table'] = $tableField[0]; 00689 $stack[$pnt]['field'] = $tableField[1]; 00690 } else { 00691 $stack[$pnt]['table'] = ''; 00692 $stack[$pnt]['field'] = $tableField[0]; 00693 } 00694 } else { 00695 return $this->parseError('No field name found as expected',$parseString); 00696 } 00697 } 00698 } 00699 00700 // After a function or field we look for "AS" alias and a comma to separate to the next field in the list: 00701 if (!$level) { 00702 00703 // Looking for "AS" alias: 00704 if ($as = $this->nextPart($parseString,'^(AS)[[:space:]]+')) { 00705 $stack[$pnt]['as'] = $this->nextPart($parseString,'^([[:alnum:]_]+)(,|[[:space:]]+)'); 00706 $stack[$pnt]['as_keyword'] = $as; 00707 } 00708 00709 // Looking for "ASC" or "DESC" keywords (for ORDER BY) 00710 if ($sDir = $this->nextPart($parseString,'^(ASC|DESC)([[:space:]]+|,)')) { 00711 $stack[$pnt]['sortDir'] = $sDir; 00712 } 00713 00714 // Looking for stop-keywords: 00715 if ($stopRegex && $this->lastStopKeyWord = $this->nextPart($parseString, $stopRegex)) { 00716 $this->lastStopKeyWord = strtoupper(ereg_replace('[[:space:]]*','',$this->lastStopKeyWord)); 00717 return $stack; 00718 } 00719 00720 // Looking for comma (since the stop-keyword did not trigger a return...) 00721 if (strlen($parseString) && !$this->nextPart($parseString,'^(,)')) { 00722 return $this->parseError('No comma found as expected',$parseString); 00723 } 00724 00725 // Increasing pointer: 00726 $pnt++; 00727 } 00728 00729 // Check recursivity brake: 00730 $loopExit++; 00731 if ($loopExit>500) { 00732 return $this->parseError('More than 500 loops, exiting prematurely...',$parseString); 00733 } 00734 } 00735 00736 // Return result array: 00737 return $stack; 00738 }
|
|
Parsing the tablenames in the "FROM [$parseString] WHERE" part of a query into an array. The success of this parsing determines if that part of the query is supported by TYPO3.
Definition at line 749 of file class.t3lib_sqlparser.php. Referenced by t3lib_sqlengine::exec_SELECTquery(). 00749 { 00750 00751 // Prepare variables: 00752 $parseString = $this->trimSQL($parseString); 00753 $this->lastStopKeyWord = ''; 00754 $this->parse_error = ''; 00755 00756 $stack = array(); // Contains the parsed content 00757 $pnt = 0; // Pointer to positions in $stack 00758 $loopExit = 0; // Recursivity brake. 00759 00760 // $parseString is continously shortend by the process and we keep parsing it till it is zero: 00761 while (strlen($parseString)) { 00762 00763 // Looking for the table: 00764 if ($stack[$pnt]['table'] = $this->nextPart($parseString,'^([[:alnum:]_]+)(,|[[:space:]]+)')) { 00765 if ($as = $this->nextPart($parseString,'^(AS)[[:space:]]+')) { 00766 $stack[$pnt]['as'] = $this->nextPart($parseString,'^([[:alnum:]_]+)(,|[[:space:]]+)'); 00767 $stack[$pnt]['as_keyword'] = $as; 00768 } 00769 } else return $this->parseError('No table name found as expected!',$parseString); 00770 00771 // Looking for JOIN 00772 if ($join = $this->nextPart($parseString,'^(JOIN|LEFT[[:space:]]+JOIN)[[:space:]]+')) { 00773 $stack[$pnt]['JOIN']['type'] = $join; 00774 if ($stack[$pnt]['JOIN']['withTable'] = $this->nextPart($parseString,'^([[:alnum:]_]+)[[:space:]]+ON[[:space:]]+',1)) { 00775 $field1 = $this->nextPart($parseString,'^([[:alnum:]_.]+)[[:space:]]*=[[:space:]]*',1); 00776 $field2 = $this->nextPart($parseString,'^([[:alnum:]_.]+)[[:space:]]+'); 00777 if ($field1 && $field2) { 00778 $stack[$pnt]['JOIN']['ON'] = array($field1,$field2); 00779 } else return $this->parseError('No join fields found!',$parseString); 00780 } else return $this->parseError('No join table found!',$parseString); 00781 } 00782 00783 // Looking for stop-keywords: 00784 if ($stopRegex && $this->lastStopKeyWord = $this->nextPart($parseString, $stopRegex)) { 00785 $this->lastStopKeyWord = strtoupper(ereg_replace('[[:space:]]*','',$this->lastStopKeyWord)); 00786 return $stack; 00787 } 00788 00789 // Looking for comma: 00790 if (strlen($parseString) && !$this->nextPart($parseString,'^(,)')) { 00791 return $this->parseError('No comma found as expected',$parseString); 00792 } 00793 00794 // Increasing pointer: 00795 $pnt++; 00796 00797 // Check recursivity brake: 00798 $loopExit++; 00799 if ($loopExit>500) { 00800 return $this->parseError('More than 500 loops, exiting prematurely...',$parseString); 00801 } 00802 } 00803 00804 // Return result array: 00805 return $stack; 00806 }
|
|
Parsing INSERT query.
Definition at line 311 of file class.t3lib_sqlparser.php. Referenced by parseSQL(). 00311 { 00312 00313 // Removing INSERT 00314 $parseString = $this->trimSQL($parseString); 00315 $parseString = eregi_replace('^INSERT[[:space:]]+INTO[[:space:]]+','',$parseString); 00316 00317 // Init output variable: 00318 $result = array(); 00319 $result['type'] = 'INSERT'; 00320 00321 // Get table: 00322 $result['TABLE'] = $this->nextPart($parseString, '^([[:alnum:]_]+)([[:space:]]+|\()'); 00323 00324 if ($result['TABLE']) { 00325 00326 if ($this->nextPart($parseString,'^(VALUES)[[:space:]]+')) { // In this case there are no field names mentioned in the SQL! 00327 // Get values/fieldnames (depending...) 00328 $result['VALUES_ONLY'] = $this->getValue($parseString,'IN'); 00329 if ($this->parse_error) { return $this->parse_error; } 00330 } else { // There are apparently fieldnames listed: 00331 $fieldNames = $this->getValue($parseString,'_LIST'); 00332 if ($this->parse_error) { return $this->parse_error; } 00333 00334 if ($this->nextPart($parseString,'^(VALUES)[[:space:]]+')) { // "VALUES" keyword binds the fieldnames to values: 00335 00336 $values = $this->getValue($parseString,'IN'); // Using the "getValue" function to get the field list... 00337 if ($this->parse_error) { return $this->parse_error; } 00338 00339 foreach($fieldNames as $k => $fN) { 00340 if (ereg('^[[:alnum:]_]+$',$fN)) { 00341 if (isset($values[$k])) { 00342 if (!isset($result['FIELDS'][$fN])) { 00343 $result['FIELDS'][$fN] = $values[$k]; 00344 } else return $this->parseError('Fieldname ("'.$fN.'") already found in list!',$parseString); 00345 } else return $this->parseError('No value set!',$parseString); 00346 } else return $this->parseError('Invalid fieldname ("'.$fN.'")',$parseString); 00347 } 00348 if (isset($values[$k+1])) { 00349 return $this->parseError('Too many values in list!',$parseString); 00350 } 00351 } else return $this->parseError('VALUES keyword expected',$parseString); 00352 } 00353 } else return $this->parseError('No table found!',$parseString); 00354 00355 // Should be no more content now: 00356 if ($parseString) { 00357 return $this->parseError('Still content after parsing!',$parseString); 00358 } 00359 00360 // Return result 00361 return $result; 00362 }
|
|
Parsing SELECT query.
Definition at line 188 of file class.t3lib_sqlparser.php. Referenced by parseSQL(). 00188 { 00189 00190 // Removing SELECT: 00191 $parseString = $this->trimSQL($parseString); 00192 $parseString = eregi_replace('^SELECT[[:space:]]+','',$parseString); 00193 00194 // Init output variable: 00195 $result = array(); 00196 $result['type'] = 'SELECT'; 00197 00198 // Looking for STRAIGHT_JOIN keyword: 00199 $result['STRAIGHT_JOIN'] = $this->nextPart($parseString, '^(STRAIGHT_JOIN)[[:space:]]+'); 00200 00201 // Select fields: 00202 $result['SELECT'] = $this->parseFieldList($parseString, '^(FROM)[[:space:]]+'); 00203 if ($this->parse_error) { return $this->parse_error; } 00204 00205 // Continue if string is not ended: 00206 if ($parseString) { 00207 00208 // Get table list: 00209 $result['FROM'] = $this->parseFromTables($parseString, '^(WHERE)[[:space:]]+'); 00210 if ($this->parse_error) { return $this->parse_error; } 00211 00212 // If there are more than just the tables (a WHERE clause that would be...) 00213 if ($parseString) { 00214 00215 // Get WHERE clause: 00216 $result['WHERE'] = $this->parseWhereClause($parseString, '^(GROUP[[:space:]]+BY|ORDER[[:space:]]+BY|LIMIT)[[:space:]]+'); 00217 if ($this->parse_error) { return $this->parse_error; } 00218 00219 // If the WHERE clause parsing was stopped by GROUP BY, ORDER BY or LIMIT, then proceed with parsing: 00220 if ($this->lastStopKeyWord) { 00221 00222 // GROUP BY parsing: 00223 if ($this->lastStopKeyWord == 'GROUPBY') { 00224 $result['GROUPBY'] = $this->parseFieldList($parseString, '^(ORDER[[:space:]]+BY|LIMIT)[[:space:]]+'); 00225 if ($this->parse_error) { return $this->parse_error; } 00226 } 00227 00228 // ORDER BY parsing: 00229 if ($this->lastStopKeyWord == 'ORDERBY') { 00230 $result['ORDERBY'] = $this->parseFieldList($parseString, '^(LIMIT)[[:space:]]+'); 00231 if ($this->parse_error) { return $this->parse_error; } 00232 } 00233 00234 // LIMIT parsing: 00235 if ($this->lastStopKeyWord == 'LIMIT') { 00236 if (ereg('^([0-9]+|[0-9]+[[:space:]]*,[[:space:]]*[0-9]+)$',trim($parseString))) { 00237 $result['LIMIT'] = $parseString; 00238 } else { 00239 return $this->parseError('No value for limit!',$parseString); 00240 } 00241 } 00242 } 00243 } 00244 } else return $this->parseError('No table to select from!',$parseString); 00245 00246 // Return result: 00247 return $result; 00248 }
|
|
Parses any single SQL query.
Definition at line 128 of file class.t3lib_sqlparser.php. References nextPart(), parseALTERTABLE(), parseCREATETABLE(), parseDELETE(), parseDROPTABLE(), parseEXPLAIN(), parseINSERT(), parseSELECT(), and parseUPDATE(). 00128 { 00129 00130 // Prepare variables: 00131 $parseString = $this->trimSQL($parseString); 00132 $this->parse_error = ''; 00133 $result = array(); 00134 00135 // Finding starting keyword of string: 00136 $_parseString = $parseString; // Protecting original string... 00137 $keyword = $this->nextPart($_parseString, '^(SELECT|UPDATE|INSERT[[:space:]]+INTO|DELETE[[:space:]]+FROM|EXPLAIN|DROP[[:space:]]+TABLE|CREATE[[:space:]]+TABLE|ALTER[[:space:]]+TABLE)[[:space:]]+'); 00138 $keyword = strtoupper(ereg_replace('[[:space:]]*','',$keyword)); 00139 00140 switch($keyword) { 00141 case 'SELECT': 00142 // Parsing SELECT query: 00143 $result = $this->parseSELECT($parseString); 00144 break; 00145 case 'UPDATE': 00146 // Parsing UPDATE query: 00147 $result = $this->parseUPDATE($parseString); 00148 break; 00149 case 'INSERTINTO': 00150 // Parsing INSERT query: 00151 $result = $this->parseINSERT($parseString); 00152 break; 00153 case 'DELETEFROM': 00154 // Parsing DELETE query: 00155 $result = $this->parseDELETE($parseString); 00156 break; 00157 case 'EXPLAIN': 00158 // Parsing EXPLAIN SELECT query: 00159 $result = $this->parseEXPLAIN($parseString); 00160 break; 00161 case 'DROPTABLE': 00162 // Parsing DROP TABLE query: 00163 $result = $this->parseDROPTABLE($parseString); 00164 break; 00165 case 'ALTERTABLE': 00166 // Parsing ALTER TABLE query: 00167 $result = $this->parseALTERTABLE($parseString); 00168 break; 00169 case 'CREATETABLE': 00170 // Parsing CREATE TABLE query: 00171 $result = $this->parseCREATETABLE($parseString); 00172 break; 00173 default: 00174 return $this->parseError('"'.$keyword.'" is not a keyword',$parseString); 00175 break; 00176 } 00177 00178 return $result; 00179 }
|
|
Parsing UPDATE query.
Definition at line 257 of file class.t3lib_sqlparser.php. Referenced by parseSQL(). 00257 { 00258 00259 // Removing UPDATE 00260 $parseString = $this->trimSQL($parseString); 00261 $parseString = eregi_replace('^UPDATE[[:space:]]+','',$parseString); 00262 00263 // Init output variable: 00264 $result = array(); 00265 $result['type'] = 'UPDATE'; 00266 00267 // Get table: 00268 $result['TABLE'] = $this->nextPart($parseString, '^([[:alnum:]_]+)[[:space:]]+'); 00269 00270 // Continue if string is not ended: 00271 if ($result['TABLE']) { 00272 if ($parseString && $this->nextPart($parseString, '^(SET)[[:space:]]+')) { 00273 00274 $comma = TRUE; 00275 00276 // Get field/value pairs: 00277 while($comma) { 00278 if ($fieldName = $this->nextPart($parseString,'^([[:alnum:]_]+)[[:space:]]*=')) { 00279 $this->nextPart($parseString,'^(=)'); // Strip of "=" sign. 00280 $value = $this->getValue($parseString); 00281 $result['FIELDS'][$fieldName] = $value; 00282 } else return $this->parseError('No fieldname found',$parseString); 00283 00284 $comma = $this->nextPart($parseString,'^(,)'); 00285 } 00286 00287 // WHERE 00288 if ($this->nextPart($parseString,'^(WHERE)')) { 00289 $result['WHERE'] = $this->parseWhereClause($parseString); 00290 if ($this->parse_error) { return $this->parse_error; } 00291 } 00292 } else return $this->parseError('Query missing SET...',$parseString); 00293 } else return $this->parseError('No table found!',$parseString); 00294 00295 // Should be no more content now: 00296 if ($parseString) { 00297 return $this->parseError('Still content in clause after parsing!',$parseString); 00298 } 00299 00300 // Return result: 00301 return $result; 00302 }
|
|
Parsing the WHERE clause fields in the "WHERE [$parseString] ..." part of a query into a multidimensional array. The success of this parsing determines if that part of the query is supported by TYPO3.
Definition at line 816 of file class.t3lib_sqlparser.php. Referenced by t3lib_sqlengine::exec_DELETEquery(), t3lib_sqlengine::exec_SELECTquery(), and t3lib_sqlengine::exec_UPDATEquery(). 00816 { 00817 00818 // Prepare variables: 00819 $parseString = $this->trimSQL($parseString); 00820 $this->lastStopKeyWord = ''; 00821 $this->parse_error = ''; 00822 00823 $stack = array(0 => array()); // Contains the parsed content 00824 $pnt = array(0 => 0); // Pointer to positions in $stack 00825 $level = 0; // Determines parenthesis level 00826 $loopExit = 0; // Recursivity brake. 00827 00828 // $parseString is continously shortend by the process and we keep parsing it till it is zero: 00829 while (strlen($parseString)) { 00830 00831 // Look for next parenthesis level: 00832 $newLevel = $this->nextPart($parseString,'^([(])'); 00833 if ($newLevel=='(') { // If new level is started, manage stack/pointers: 00834 $level++; // Increase level 00835 $pnt[$level] = 0; // Reset pointer for this level 00836 $stack[$level] = array(); // Reset stack for this level 00837 } else { // If no new level is started, just parse the current level: 00838 00839 // Find "modifyer", eg. "NOT or !" 00840 $stack[$level][$pnt[$level]]['modifier'] = trim($this->nextPart($parseString,'^(!|NOT[[:space:]]+)')); 00841 00842 // Fieldname: 00843 if ($fieldName = $this->nextPart($parseString,'^([[:alnum:]._]+)([[:space:]]+|&|<=|>=|<|>|=|!=|IS)')) { 00844 00845 // Parse field name into field and table: 00846 $tableField = explode('.',$fieldName,2); 00847 if (count($tableField)==2) { 00848 $stack[$level][$pnt[$level]]['table'] = $tableField[0]; 00849 $stack[$level][$pnt[$level]]['field'] = $tableField[1]; 00850 } else { 00851 $stack[$level][$pnt[$level]]['table'] = ''; 00852 $stack[$level][$pnt[$level]]['field'] = $tableField[0]; 00853 } 00854 } else { 00855 return $this->parseError('No field name found as expected',$parseString); 00856 } 00857 00858 // See if the value is calculated. Support only for "&" (boolean AND) at the moment: 00859 $stack[$level][$pnt[$level]]['calc'] = $this->nextPart($parseString,'^(&)'); 00860 if (strlen($stack[$level][$pnt[$level]]['calc'])) { 00861 // Finding value for calculation: 00862 $stack[$level][$pnt[$level]]['calc_value'] = $this->getValue($parseString); 00863 } 00864 00865 // Find "comparator": 00866 $stack[$level][$pnt[$level]]['comparator'] = $this->nextPart($parseString,'^(<=|>=|<|>|=|!=|NOT[[:space:]]+IN|IN|NOT[[:space:]]+LIKE|LIKE|IS)'); 00867 if (strlen($stack[$level][$pnt[$level]]['comparator'])) { 00868 // Finding value for comparator: 00869 $stack[$level][$pnt[$level]]['value'] = $this->getValue($parseString,$stack[$level][$pnt[$level]]['comparator']); 00870 if ($this->parse_error) { return $this->parse_error; } 00871 } 00872 00873 // Finished, increase pointer: 00874 $pnt[$level]++; 00875 00876 // Checking if the current level is ended, in that case do stack management: 00877 while ($this->nextPart($parseString,'^([)])')) { 00878 $level--; // Decrease level: 00879 $stack[$level][$pnt[$level]]['sub'] = $stack[$level+1]; // Copy stack 00880 $pnt[$level]++; // Increase pointer of the new level 00881 00882 // Make recursivity check: 00883 $loopExit++; 00884 if ($loopExit>500) { 00885 return $this->parseError('More than 500 loops (in search for exit parenthesis), exiting prematurely...',$parseString); 00886 } 00887 } 00888 00889 // Detecting the operator for the next level; support for AND, OR and &&): 00890 $op = $this->nextPart($parseString,'^(AND|OR|AND[[:space:]]+NOT)(\(|[[:space:]]+)'); 00891 if ($op) { 00892 $stack[$level][$pnt[$level]]['operator'] = $op; 00893 } elseif (strlen($parseString)) { 00894 00895 // Looking for stop-keywords: 00896 if ($stopRegex && $this->lastStopKeyWord = $this->nextPart($parseString, $stopRegex)) { 00897 $this->lastStopKeyWord = strtoupper(ereg_replace('[[:space:]]*','',$this->lastStopKeyWord)); 00898 return $stack[0]; 00899 } else { 00900 return $this->parseError('No operator, but parsing not finished.',$parseString); 00901 } 00902 } 00903 } 00904 00905 // Make recursivity check: 00906 $loopExit++; 00907 if ($loopExit>500) { 00908 return $this->parseError('More than 500 loops, exiting prematurely...',$parseString); 00909 } 00910 } 00911 00912 // Return the stacks lowest level: 00913 return $stack[0]; 00914 }
|
|
Definition at line 110 of file class.t3lib_sqlparser.php. |
|
Definition at line 109 of file class.t3lib_sqlparser.php. |