Main Page | Directories | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages | Examples

t3lib_sqlparser Class Reference

Inherited by t3lib_sqlengine.

List of all members.

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 = ''


Member Function Documentation

t3lib_sqlparser::getValue &$  parseString,
comparator = ''
 

Finds value in beginning of $parseString, returns result and strips it of parseString.

Parameters:
string The parseString, eg. "(0,1,2,3) ..." or "('asdf','qwer') ..." or "1234 ..." or "'My string value here' ..."
string The comparator used before. If "NOT IN" or "IN" then the value is expected to be a list of values. Otherwise just an integer (un-quoted) or string (quoted)
Returns:
string The value (string/integer). Otherwise an array with error message in first key (0)

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

Parameters:
string Input string
Returns:
string Output string

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

Parameters:
string Input string
Returns:
string Output string

Setting the internal error message value, $this->parse_error and returns that value.

Parameters:
string Input error message
string Remaining query to parse.
Returns:
string Error message.

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

Parameters:
string Input string
Returns:
string Output string

Compiles an SQL query from components

Parameters:
array Array of SQL query components
Returns:
string SQL query
See also:
parseSQL()

Compiles a SELECT statement from components array

Parameters:
array Array of SQL query components
Returns:
string SQL SELECT query
See also:
parseSELECT()

Compiles an UPDATE statement from components array

Parameters:
array Array of SQL query components
Returns:
string SQL UPDATE query
See also:
parseUPDATE()

Compiles an INSERT statement from components array

Parameters:
array Array of SQL query components
Returns:
string SQL INSERT query
See also:
parseINSERT()

Compiles an DELETE statement from components array

Parameters:
array Array of SQL query components
Returns:
string SQL DELETE query
See also:
parseDELETE()

Compiles a CREATE TABLE statement from components array

Parameters:
array Array of SQL query components
Returns:
string SQL CREATE TABLE query
See also:
parseCREATETABLE()

Compiles an ALTER TABLE statement from components array

Parameters:
array Array of SQL query components
Returns:
string SQL ALTER TABLE query
See also:
parseALTERTABLE()

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.

Parameters:
array Array of select fields, (made with ->parseFieldList())
Returns:
string Select field string
See also:
parseFieldList()

Compiles a "FROM [output] WHERE..:" table list based on input array (made with ->parseFromTables())

Parameters:
array Array of table names, (made with ->parseFromTables())
Returns:
string Table name string
See also:
parseFromTables()

Implodes an array of WHERE clause configuration into a WHERE clause. NOTICE: MIGHT BY A TEMPORARY FUNCTION. Use for debugging only!

Parameters:
array WHERE clause configuration
Returns:
string WHERE clause as string.
See also:
explodeWhereClause()

Compile field definition

Parameters:
array Field definition parts
Returns:
string Field definition string

Check parsability of input SQL part string; Will parse and re-compile after which it is compared

Parameters:
string Part definition of string; "SELECT" = fieldlist (also ORDER BY and GROUP BY), "FROM" = table list, "WHERE" = Where clause.
string SQL string to verify parsability of
Returns:
mixed Returns array with string 1 and 2 if error, otherwise false

Compare two query strins by stripping away whitespace.

Parameters:
string SQL String 1
string SQL string 2
boolean If true, the strings are compared insensitive to case
Returns:
mixed Returns array with string 1 and 2 if error, otherwise false

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

Parameters:
string SQL query
Returns:
string Query if all is well, otherwise exit.

Definition at line 999 of file class.t3lib_sqlparser.php.

t3lib_sqlparser::nextPart &$  parseString,
regex,
trimAll = FALSE
 

Strips of a part of the parseString and returns the matching part.

Helper function for the parsing methods.

Parameters:
string Parse string; if $regex finds anything the value of the first () level will be stripped of the string in the beginning. Further $parseString is left-trimmed (on success). Notice; parsestring is passed by reference.
string Regex to find a matching part in the beginning of the string. Rules: You MUST start the regex with "^" (finding stuff in the beginning of string) and the result of the first parenthesis is what will be returned to you (and stripped of the string). Eg. '^(AND|OR|&&)[[:space:]]+' will return AND, OR or && if found and having one of more whitespaces after it, plus shorten $parseString with that match and any space after (by ltrim())
boolean If set the full match of the regex is stripped of the beginning of the string!
Returns:
string The value of the first parenthesis level of the REGEX.

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    }

t3lib_sqlparser::parseALTERTABLE parseString  ) 
 

Parsing ALTER TABLE query.

Parameters:
string SQL string starting with ALTER TABLE
Returns:
mixed Returns array with components of ALTER TABLE query on success, otherwise an error message string.
See also:
compileALTERTABLE()

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    }

t3lib_sqlparser::parseCREATETABLE parseString  ) 
 

Parsing CREATE TABLE query.

Parameters:
string SQL string starting with CREATE TABLE
Returns:
mixed Returns array with components of CREATE TABLE query on success, otherwise an error message string.
See also:
compileCREATETABLE()

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    }

t3lib_sqlparser::parseDELETE parseString  ) 
 

Parsing DELETE query.

Parameters:
string SQL string with DELETE query to parse
Returns:
mixed Returns array with components of DELETE query on success, otherwise an error message string.
See also:
compileDELETE()

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    }

t3lib_sqlparser::parseDROPTABLE parseString  ) 
 

Parsing DROP TABLE query.

Parameters:
string SQL string starting with DROP TABLE
Returns:
mixed Returns array with components of DROP TABLE query on success, otherwise an error message string.

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    }

t3lib_sqlparser::parseEXPLAIN parseString  ) 
 

Parsing EXPLAIN query.

Parameters:
string SQL string with EXPLAIN query to parse
Returns:
mixed Returns array with components of EXPLAIN query on success, otherwise an error message string.
See also:
parseSELECT()

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    }

t3lib_sqlparser::parseFieldDef &$  parseString,
stopRegex = ''
 

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.

Parameters:
string WHERE clause to parse. NOTICE: passed by reference!
string Regular expressing to STOP parsing, eg. '^(GROUP BY|ORDER BY|LIMIT)([[:space:]]*)'
Returns:
mixed If successful parsing, returns an array, otherwise an error string.

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    }

t3lib_sqlparser::parseFieldList &$  parseString,
stopRegex = ''
 

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!

Parameters:
string The string with fieldnames, eg. "title, uid AS myUid, max(tstamp), count(*)" etc. NOTICE: passed by reference!
string Regular expressing to STOP parsing, eg. '^(FROM)([[:space:]]*)'
Returns:
array If successful parsing, returns an array, otherwise an error string.
See also:
compileFieldList()

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    }

t3lib_sqlparser::parseFromTables &$  parseString,
stopRegex = ''
 

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.

Parameters:
string list of tables, eg. "pages, tt_content" or "pages A, pages B". NOTICE: passed by reference!
string Regular expressing to STOP parsing, eg. '^(WHERE)([[:space:]]*)'
Returns:
array If successful parsing, returns an array, otherwise an error string.
See also:
compileFromTables()

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    }

t3lib_sqlparser::parseINSERT parseString  ) 
 

Parsing INSERT query.

Parameters:
string SQL string with INSERT query to parse
Returns:
mixed Returns array with components of INSERT query on success, otherwise an error message string.
See also:
compileINSERT()

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    }

t3lib_sqlparser::parseSELECT parseString  ) 
 

Parsing SELECT query.

Parameters:
string SQL string with SELECT query to parse
Returns:
mixed Returns array with components of SELECT query on success, otherwise an error message string.
See also:
compileSELECT()

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    }

t3lib_sqlparser::parseSQL parseString  ) 
 

Parses any single SQL query.

Parameters:
string SQL query
Returns:
array Result array with all the parts in - or error message string
See also:
compileSQL(), debug_testSQL()

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    }

t3lib_sqlparser::parseUPDATE parseString  ) 
 

Parsing UPDATE query.

Parameters:
string SQL string with UPDATE query to parse
Returns:
mixed Returns array with components of UPDATE query on success, otherwise an error message string.
See also:
compileUPDATE()

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    }

t3lib_sqlparser::parseWhereClause &$  parseString,
stopRegex = ''
 

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.

Parameters:
string WHERE clause to parse. NOTICE: passed by reference!
string Regular expressing to STOP parsing, eg. '^(GROUP BY|ORDER BY|LIMIT)([[:space:]]*)'
Returns:
mixed If successful parsing, returns an array, otherwise an error string.

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    }


Member Data Documentation

t3lib_sqlparser::$lastStopKeyWord = ''
 

Definition at line 110 of file class.t3lib_sqlparser.php.

t3lib_sqlparser::$parse_error = ''
 

Definition at line 109 of file class.t3lib_sqlparser.php.


The documentation for this class was generated from the following file:
Generated on Sun Oct 3 01:07:13 2004 for TYPO3core 3.7.0 dev by  doxygen 1.3.8-20040913