Author: Dan Ungureanu (udan1107@gmail.com)
 /**
  * @param Parser     $parser The instance that requests parsing.
  * @param TokensList $list   The list of tokens to be parsed.
  *
  * @return void
  */
 public function parse(Parser $parser, TokensList $list)
 {
     parent::parse($parser, $list);
     // Checks the type of this query.
     if ($this->options->has('START TRANSACTION') || $this->options->has('BEGIN')) {
         $this->type = TransactionStatement::TYPE_BEGIN;
     } elseif ($this->options->has('COMMIT') || $this->options->has('ROLLBACK')) {
         $this->type = TransactionStatement::TYPE_END;
     }
 }
 /**
  * @return string
  */
 public function build()
 {
     // Building the parsed part of the query (if any).
     $query = parent::build() . ' ';
     // Rebuilding the unknown part from tokens.
     foreach ($this->unknown as $token) {
         $query .= $token->token;
     }
     return $query;
 }
 /**
  * Gets a specific clause.
  *
  * @param Statement  $statement The parsed query that has to be modified.
  * @param TokensList $list      The list of tokens.
  * @param string     $clause    The clause to be returned.
  * @param int|string $type      The type of the search.
  *                              If int,
  *                                -1 for everything that was before
  *                                 0 only for the clause
  *                                 1 for everything after
  *                              If string, the name of the first clause that
  *                              should not be included.
  * @param bool       $skipFirst Whether to skip the first keyword in clause.
  *
  * @return string
  */
 public static function getClause($statement, $list, $clause, $type = 0, $skipFirst = true)
 {
     /**
      * The index of the current clause.
      *
      * @var int $currIdx
      */
     $currIdx = 0;
     /**
      * The count of brackets.
      * We keep track of them so we won't insert the clause in a subquery.
      *
      * @var int $brackets
      */
     $brackets = 0;
     /**
      * The string to be returned.
      *
      * @var string $ret
      */
     $ret = '';
     /**
      * The clauses of this type of statement and their index.
      *
      * @var array $clauses
      */
     $clauses = array_flip(array_keys($statement->getClauses()));
     /**
      * Lexer used for lexing the clause.
      *
      * @var Lexer $lexer
      */
     $lexer = new Lexer($clause);
     /**
      * The type of this clause.
      *
      * @var string $clauseType
      */
     $clauseType = $lexer->list->getNextOfType(Token::TYPE_KEYWORD)->value;
     /**
      * The index of this clause.
      *
      * @var int $clauseIdx
      */
     $clauseIdx = $clauses[$clauseType];
     $firstClauseIdx = $clauseIdx;
     $lastClauseIdx = $clauseIdx + 1;
     // Determining the behavior of this function.
     if ($type === -1) {
         $firstClauseIdx = -1;
         // Something small enough.
         $lastClauseIdx = $clauseIdx - 1;
     } elseif ($type === 1) {
         $firstClauseIdx = $clauseIdx + 1;
         $lastClauseIdx = 10000;
         // Something big enough.
     } elseif (is_string($type)) {
         if ($clauses[$type] > $clauseIdx) {
             $firstClauseIdx = $clauseIdx + 1;
             $lastClauseIdx = $clauses[$type] - 1;
         } else {
             $firstClauseIdx = $clauses[$type] + 1;
             $lastClauseIdx = $clauseIdx - 1;
         }
     }
     // This option is unavailable for multiple clauses.
     if ($type !== 0) {
         $skipFirst = false;
     }
     for ($i = $statement->first; $i <= $statement->last; ++$i) {
         $token = $list->tokens[$i];
         if ($token->type === Token::TYPE_COMMENT) {
             continue;
         }
         if ($token->type === Token::TYPE_OPERATOR) {
             if ($token->value === '(') {
                 ++$brackets;
             } elseif ($token->value === ')') {
                 --$brackets;
             }
         }
         if ($brackets == 0) {
             // Checking if the section was changed.
             if ($token->type === Token::TYPE_KEYWORD && isset($clauses[$token->value]) && $clauses[$token->value] >= $currIdx) {
                 $currIdx = $clauses[$token->value];
                 if ($skipFirst && $currIdx == $clauseIdx) {
                     // This token is skipped (not added to the old
                     // clause) because it will be replaced.
                     continue;
                 }
             }
         }
         if ($firstClauseIdx <= $currIdx && $currIdx <= $lastClauseIdx) {
             $ret .= $token->token;
         }
     }
     return trim($ret);
 }
Beispiel #4
0
 /**
  * Gets a starting offset of a specific clause.
  *
  * @param Statement  $statement The parsed query that has to be modified.
  * @param TokensList $list      The list of tokens.
  * @param string     $clause    The clause to be returned.
  *
  * @return int
  */
 public static function getClauseStartOffset($statement, $list, $clause)
 {
     /**
      * The count of brackets.
      * We keep track of them so we won't insert the clause in a subquery.
      *
      * @var int $brackets
      */
     $brackets = 0;
     /**
      * The clauses of this type of statement and their index.
      *
      * @var array $clauses
      */
     $clauses = array_flip(array_keys($statement->getClauses()));
     for ($i = $statement->first; $i <= $statement->last; ++$i) {
         $token = $list->tokens[$i];
         if ($token->type === Token::TYPE_COMMENT) {
             continue;
         }
         if ($token->type === Token::TYPE_OPERATOR) {
             if ($token->value === '(') {
                 ++$brackets;
             } elseif ($token->value === ')') {
                 --$brackets;
             }
         }
         if ($brackets == 0) {
             if ($token->type === Token::TYPE_KEYWORD && isset($clauses[$token->value]) && $clause === $token->value) {
                 return $i;
             }
         }
     }
     return -1;
 }