public function convertSqlToJob(SQLTokenIterator $tokens) { $tableJoin = new TableJoin(); $tableJoin->setDataSource($this->parseTableSource($tokens)); $joinJob = new Join(); $joinJob->addTable(clone $tableJoin); while (!is_null($joinData = $this->parseJoinOperator($tokens))) { $tableJoin->setDataSource($this->parseTableSource($tokens)); $tableJoin->setIsInner((bool) $joinData['isInner']); $tableJoin->setIsRight((bool) $joinData['isRight']); if ($tokens->seekTokenNum(SqlToken::T_ON())) { if (!$this->valueParser->canParseTokens($tokens)) { throw new MalformedSqlException("Missing valid condition after ON for JOIN!", $tokens); } $tableJoin->setCondition($this->valueParser->convertSqlToJob($tokens)); } elseif ($tokens->seekTokenNum(SqlToken::T_USING())) { if ($tokens->seekTokenText('(')) { throw new MalformedSqlException("Missing begin parenthesis after USING for JOIN!", $tokens); } if (!$this->columnParser->canParseTokens($tokens)) { throw new MalformedSqlException("Missing valid column specifier after USING for JOIN!", $tokens); } $tableJoin->setUsingColumnCondition($this->columnParser->convertSqlToJob($tokens)); if ($tokens->seekTokenText(')')) { throw new MalformedSqlException("Missing ending parenthesis after USING for JOIN!", $tokens); } } $joinJob->addTable(clone $tableJoin); } return $joinJob; }
public function convertSqlToJob(SQLTokenIterator $tokens) { $tokens->seekTokenNum(SqlToken::T_DELETE()); if ($tokens->getCurrentTokenNumber() !== SqlToken::T_DELETE()) { throw new ErrorException("Tried to parse DELETE statement when token iterator is not at T_DELETE!"); } $deleteJob = new DeleteStatement(); if ($tokens->seekTokenNum(SqlToken::T_LOW_PRIORITY())) { $deleteJob->setIsLowPriority(true); } if ($tokens->seekTokenNum(SqlToken::T_QUICK())) { $deleteJob->setIsQuick(true); } if ($tokens->seekTokenNum(SqlToken::T_IGNORE())) { $deleteJob->setIsIgnore(true); } if ($tokens->seekTokenNum(SqlToken::T_FROM())) { do { if (!$this->tableParser->canParseTokens($tokens)) { throw new MalformedSqlException("Missing valid table specifier in DELETE statement!", $tokens); } $deleteJob->addDeleteTable($this->tableParser->convertSqlToJob($tokens)); if ($tokens->seekTokenText('.')) { if (!$tokens->seekTokenText('*')) { throw new MalformedSqlException("Only '*' allowed for column specification in DELETE statement!", $tokens); } } } while ($tokens->seekTokenText(',')); if ($tokens->seekTokenNum(SqlToken::T_USING())) { if (!$this->joinParser->canParseTokens($tokens)) { throw new MalformedSqlException("Missing valid JOIN definition after USING in DELETE statement!", $tokens); } $deleteJob->setJoinDefinition($this->joinParser->convertSqlToJob($tokens)); } } else { do { if (!$this->tableParser->canParseTokens($tokens)) { throw new MalformedSqlException("Missing valid table specifier in DELETE statement!", $tokens); } $deleteJob->addDeleteTable($this->tableParser->convertSqlToJob($tokens)); if ($tokens->seekTokenText('.')) { if (!$tokens->seekTokenText('*')) { throw new MalformedSqlException("Only '*' allowed for column specification in DELETE statement!", $tokens); } } } while ($tokens->seekTokenText(',')); if ($tokens->seekTokenNum(SqlToken::T_FROM())) { if (!$this->joinParser->canParseTokens($tokens)) { throw new MalformedSqlException("Missing valid JOIN definition after FROM in DELETE statement!", $tokens); } $deleteJob->setJoinDefinition($this->joinParser->convertSqlToJob($tokens)); } } if ($tokens->seekTokenNum(SqlToken::T_WHERE())) { if (!$this->valueParser->canParseTokens($tokens)) { throw new MalformedSqlException("Missing condition for WHERE clause in UPDATE statement!", $tokens); } $deleteJob->setCondition($this->valueParser->convertSqlToJob($tokens)); } if ($tokens->seekTokenNum(SqlToken::T_ORDER())) { if (!$tokens->seekTokenNum(SqlToken::T_BY())) { throw new MalformedSqlException("Missing BY after ORDER on DELETE statement!", $tokens); } if (!$columnParser->canParseTokens($tokens)) { throw new MalformedSqlException("Missing column specifier for ORDER BY part on DELETE statement!", $tokens); } $deleteJob->setOrderColumn($columnParser->convertSqlToJob($tokens)); if ($tokens->seekTokenNum(SqlToken::T_DESC())) { $deleteJob->setOrderDirection(SqlToken::T_DESC()); } elseif ($tokens->seekTokenNum(SqlToken::T_ASC())) { $deleteJob->setOrderDirection(SqlToken::T_ASC()); } } if ($tokens->seekTokenNum(SqlToken::T_LIMIT())) { if (!$tokens->seekTokenNum(T_NUM_STRING)) { throw new MalformedSqlException("Missing offset number for LIMIT part in DELETE statement!", $tokens); } $deleteJob->setLimitOffset((int) $tokens->getCurrentTokenString()); if ($tokens->seekTokenText(',')) { if (!$tokens->seekTokenNum(T_NUM_STRING)) { throw new MalformedSqlException("Missing length number for LIMIT part in DELETE statement!", $tokens); } $deleteJob->setLimitRowCount((int) $tokens->getCurrentTokenString()); } } return $deleteJob; }
/** * This parses a CREATE INDEX statement. */ protected function parseCreateIndex(SQLTokenIterator $tokens) { /* @var $entity CreateIndexStatement */ $entity = new CreateIndexStatement(); ### FLAGS if ($tokens->isToken(SqlToken::T_UNIQUE(), TokenIterator::PREVIOUS, [SqlToken::T_PRIMARY()])) { $entity->setIsUnique(true); } if ($tokens->isToken(SqlToken::T_PRIMARY(), TokenIterator::PREVIOUS, [SqlToken::T_UNIQUE()])) { $entity->setIsPrimary(true); } ### NAME if (!$tokens->seekTokenNum(T_STRING)) { throw new MalformedSqlException("Missing valid index-name!", $tokens); } $entity->setName($tokens->getCurrentTokenString()); ### USING if ($tokens->seekTokenNum(SqlToken::T_USING())) { switch (true) { // TODO: R-TREE index not implemented yet! case $tokens->seekTokenNum(SqlToken::T_RTREE()): case $tokens->seekTokenNum(SqlToken::T_BTREE()): $entity->setIndexType(IndexType::BTREE()); break; case $tokens->seekTokenNum(SqlToken::T_HASH()): $entity->setIndexType(IndexType::HASH()); break; default: throw new MalformedSqlException("Invalid index-type specified!", $tokens); } } ### TABLE if (!$tokens->seekTokenNum(SqlToken::T_ON())) { throw new MalformedSqlException("Missing T_ON for CREATE INDEX statement!", $tokens); } if (!$this->tableParser->canParseTokens($tokens)) { throw new MalformedSqlException("Missing valid table-specifier for CREATE INDEX statement!", $tokens); } $entity->setTable($this->tableParser->convertSqlToJob($tokens)); ### COLUMNS if (!$tokens->seekTokenText('(')) { throw new MalformedSqlException("Missing beginning parenthesis holding columns in CREATE INDEX statement!", $tokens); } do { if (!$this->columnParser->canParseTokens($tokens)) { throw new MalformedSqlException("Missing valid column-specifier in CREATE INDEX statement!", $tokens); } $column = $this->columnParser->convertSqlToJob($tokens); $length = null; if ($tokens->seekTokenText('(')) { if (!$this->valueParser->canParseTokens($tokens)) { throw new MalformedSqlException("Missing valid column-length in CREATE INDEX statement!", $tokens); } $length = $this->valueParser->convertSqlToJob($tokens); if (!$tokens->seekTokenText(')')) { throw new MalformedSqlException("Missing closing parenthesis holding column-length in CREATE INDEX statement!", $tokens); } } $direction = null; if ($tokens->seekTokenNum(SqlToken::T_ASC())) { $direction = SqlToken::T_ASC(); } elseif ($tokens->seekTokenNum(SqlToken::T_DESC())) { $direction = SqlToken::T_DESC(); } $entity->addColumn($column, $length, $direction); } while ($tokens->seekTokenText(',')); if (!$tokens->seekTokenText(')')) { throw new MalformedSqlException("Missing closing parenthesis holding columns in CREATE INDEX statement!", $tokens); } ### WITH PARSER if ($tokens->seekTokenNum(SqlToken::T_WITH())) { if (!$tokens->seekTokenNum(SqlToken::T_PARSER())) { throw new MalformedSqlException("Missing T_PARSER after T_WITH in CREATE INDEX statement!", $tokens); } if (!$tokens->seekTokenNum(T_STRING)) { throw new MalformedSqlException("Missing valid parser name after WITH PARSER in CREATE INDEX statement!", $tokens); } $entity->setParser($tokens->getCurrentTokenString()); } return $entity; }