public function convertSqlToJob(SQLTokenIterator $tokens) { $tokens->seekTokenNum(SqlToken::T_USE()); if ($tokens->getCurrentTokenNumber() !== SqlToken::T_USE()) { throw new MalformedSqlException("Tried to parse USE statement when token-iterator does not point to T_USE!", $tokens); } if ($tokens->seekTokenNum(T_VARIABLE)) { $databaseName = Variable::factory($tokens->getCurrentTokenString()); } elseif ($tokens->seekTokenNum(T_STRING)) { $databaseName = $tokens->getCurrentTokenString(); } elseif ($tokens->seekTokenNum(T_CONSTANT_ENCAPSED_STRING)) { $databaseName = $tokens->getCurrentTokenString(); if (($databaseName[0] === '"' || $databaseName[0] === "'") && $databaseName[0] === $databaseName[strlen($databaseName) - 1]) { // remove quotes if needed $databaseName = substr($databaseName, 1, strlen($databaseName) - 2); } } else { throw new MalformedSqlException("Missing database-specifier for USE statement!", $tokens); } $databaseNameValue = new ValuePart(); $databaseNameValue->addChainValue($databaseName); $useJob = new UseStatement(); $useJob->setDatabase($databaseNameValue); return $useJob; }
public function convertSqlToJob(SQLTokenIterator $tokens) { $parts = array(); do { $tokens->seekIndex($tokens->getExclusiveTokenIndex()); $part = $tokens->getCurrentTokenString(); if ($part[0] === '`' && $part[strlen($part) - 1] === '`') { $part = substr($part, 1, strlen($part) - 2); } $parts[] = $part; } while ($tokens->seekTokenText(".") && !$tokens->isTokenText('*')); return TableSpecifier::factory(implode(".", $parts)); }
public function convertSqlToJob(SQLTokenIterator $tokens) { $parts = array(); do { if ($tokens->seekTokenNum(T_VARIABLE)) { $part = Variable::factory($tokens->getCurrentTokenString()); } elseif ($tokens->seekTokens([T_STRING, T_CONSTANT_ENCAPSED_STRING])) { $part = $tokens->getCurrentTokenString(); if ($part[0] === '`' && $part[strlen($part) - 1] === '`') { $part = substr($part, 1, strlen($part) - 2); } elseif ($part[0] === '"' && $part[strlen($part) - 1] === '"') { $part = substr($part, 1, strlen($part) - 2); } elseif ($part[0] === "'" && $part[strlen($part) - 1] === "'") { $part = substr($part, 1, strlen($part) - 2); } } else { throw new ErrorException("Tried to convert sql-column-specifier when token-iterator does not point to T_STRING!"); } $parts[] = $part; } while ($tokens->seekTokenText(".")); $specifier = ColumnSpecifier::factory(implode(".", $parts)); return $specifier; }
public function convertSqlToJob(SQLTokenIterator $tokens) { $parts = array(); do { if (!$tokens->seekTokenNum(T_STRING)) { throw new ErrorException("Tried to convert sql-database-specifier when token-iterator does not point to T_STRING!"); } $part = $tokens->getCurrentTokenString(); if ($part[0] === '`' && $part[strlen($part) - 1] === '`') { $part = substr($part, 1, strlen($part) - 2); } $parts[] = $part; } while ($tokens->seekTokenText(".")); $specifier = DatabaseSpecifier::factory(implode(".", $parts)); return $specifier; }
public function convertSqlToJob(SQLTokenIterator $tokens) { $tokens->seekTokenNum(SqlToken::T_SET()); if ($tokens->getCurrentTokenNumber() !== SqlToken::T_SET()) { throw new ErrorException("Tried to parse SET statement when token-iterator is not at T_SET!"); } $setJob = new SetStatement(); if (!$tokens->seekTokenNum(T_STRING)) { throw new MalformedSqlException("Missing configuration name for SET statement!", $tokens); } $setJob->setKey($tokens->getCurrentTokenString()); $tokens->seekTokenText('='); if (!$this->valueParser->canParseTokens($tokens)) { throw new MalformedSqlException("Missing valid value definition for SET statement!", $tokens); } $setJob->setValue($this->valueParser->convertSqlToJob($tokens)); return $setJob; }
public function convertSqlToJob(SQLTokenIterator $tokens) { /* @var $valueParser ValueParser */ $valueParser = $this->valueParser; $tokens->seekTokenNum(SqlToken::T_SHOW()); if ($tokens->getCurrentTokenNumber() !== SqlToken::T_SHOW()) { throw new ErrorException("Tried to convert sql-show to job-entity when tokeniterator does not point to T_SHOW!"); } $showJob = new ShowStatement(); if ($tokens->seekTokenNum(SqlToken::T_FULL())) { $showJob->setIsFull(true); } switch (true) { case $tokens->seekTokenNum(SqlToken::T_DATABASES()): $showJob->setType(ShowType::DATABASES()); break; case $tokens->seekTokenNum(SqlToken::T_TABLES()): $showJob->setType(ShowType::TABLES()); break; case $tokens->seekTokenNum(SqlToken::T_VIEWS()): $showJob->setType(ShowType::VIEWS()); break; default: throw new MalformedSqlException("Invalid parameter for show-statement!", $tokens); } if ($tokens->seekTokenNum(SqlToken::T_FROM())) { if (!$tokens->seekTokenNum(T_STRING)) { throw new MalformedSqlException("Missing database name after FROM in SHOW statement!"); } $showJob->setDatabase($tokens->getCurrentTokenString()); } if ($tokens->seekTokenNum(SqlToken::T_WHERE())) { if (!$valueParser->canParseTokens($tokens)) { throw new MalformedSqlException("Missing valid condition-value after WHERE in SHOW statement!"); } /* @var $conditionValue ValuePart */ $conditionValue = $valueParser->convertSqlToJob($tokens); $showJob->setConditionValue($conditionValue); } return $showJob; }
public function convertSqlToJob(SQLTokenIterator $tokens) { $columnDefinition = new ColumnDefinitionJob(); $tokens->seekTokens([T_STRING, T_CONSTANT_ENCAPSED_STRING]); if (!$tokens->isTokens([T_STRING, T_CONSTANT_ENCAPSED_STRING], TokenIterator::CURRENT)) { throw new MalformedSqlException("Missing name for column!", $tokens); } $name = $tokens->getCurrentTokenString(); if ($name[0] === '`' && $name[strlen($name) - 1] === '`') { $name = substr($name, 1, strlen($name) - 2); } if ($name[0] === '"' && $name[strlen($name) - 1] === '"') { $name = substr($name, 1, strlen($name) - 2); } if ($name[0] === "'" && $name[strlen($name) - 1] === "'") { $name = substr($name, 1, strlen($name) - 2); } $columnDefinition->setName($name); # this makes sure that the next token is valid data-type $dataTypeString = strtoupper($tokens->getExclusiveTokenString()); $dataType = DataType::factory($dataTypeString); $columnDefinition->setDataType($dataType); $tokens->seekIndex($tokens->getExclusiveTokenIndex()); # data-type-length if ($tokens->seekTokenText('(')) { if ($dataType === DataType::ENUM() || $dataType === DataType::SET()) { do { if (!$this->valueParser->canParseTokens($tokens)) { throw new MalformedSqlException("Invalid value in ENUM!", $tokens); } $columnDefinition->addEnumValue($this->valueParser->convertSqlToJob($tokens)); } while ($tokens->seekTokenText(',')); } else { if (!$tokens->seekTokenNum(T_NUM_STRING)) { throw new MalformedSqlException("Missing number for length of data-type!", $tokens); } $columnDefinition->setDataTypeLength((int) $tokens->getCurrentTokenString()); if ($tokens->seekTokenText(',')) { if (!$tokens->seekTokenNum(T_NUM_STRING)) { throw new MalformedSqlException("Missing second number for length of data-type!", $tokens); } $columnDefinition->setDataTypeSecondLength((int) $tokens->getCurrentTokenString()); } } if (!$tokens->seekTokenText(')')) { throw new MalformedSqlException("Missing end-parenthesis for length of data-type!", $tokens); } } while (true) { switch (true) { case $tokens->seekTokenNum(SqlToken::T_NOT()): if (!$tokens->seekTokenNum(SqlToken::T_NULL())) { throw new MalformedSqlException("Missing T_NULL after T_NOT in column-definition!", $tokens); } $columnDefinition->setIsNullable(false); break; case $tokens->seekTokenNum(SqlToken::T_NULL()): $columnDefinition->setIsNullable(true); break; case $tokens->seekTokenNum(SqlToken::T_DEFAULT()): if (!$this->valueParser->canParseTokens($tokens)) { throw new MalformedSqlException("Missing valid default value for column definition!", $tokens); } $beforeIndex = $tokens->getIndex(); $defaultValue = $this->valueParser->convertSqlToJob($tokens); $afterIndex = $tokens->getIndex(); $defaultSqlRepresentation = ""; for ($index = $beforeIndex + 1; $index <= $afterIndex; $index++) { $defaultSqlRepresentation .= $tokens->getTokenArray()[$index][1]; } $columnDefinition->setDefaultValue($defaultValue); break; case $tokens->seekTokenNum(SqlToken::T_UNIQUE()): $tokens->seekTokenNum(SqlToken::T_KEY()); $columnDefinition->setIsUnique(true); break; case $tokens->seekTokenNum(SqlToken::T_PRIMARY()): $tokens->seekTokenNum(SqlToken::T_KEY()); $columnDefinition->setIsPrimaryKey(true); break; case $tokens->seekTokenNum(SqlToken::T_UNSIGNED()): $columnDefinition->setIsUnsigned(true); break; case $tokens->seekTokenNum(SqlToken::T_COMMENT()): if (!$tokens->seekTokenNum(T_CONSTANT_ENCAPSED_STRING)) { throw new MalformedSqlException("Missing encapsed string for comment-declaration column-definition!", $tokens); } $columnDefinition->setComment($tokens->getCurrentTokenString()); break; case $tokens->seekTokenNum(SqlToken::T_AUTO_INCREMENT()): $columnDefinition->setAutoIncrement(true); break; case $tokens->seekTokenNum(SqlToken::T_CHARACTER(), TokenIterator::NEXT, [SqlToken::T_DEFAULT()]): if (!$tokens->seekTokenNum(SqlToken::T_SET())) { throw new MalformedSqlException("MIssing SET after CHARACTER keyword!", $tokens); } case $tokens->seekTokenNum(SqlToken::T_CHARSET(), TokenIterator::NEXT, [SqlToken::T_DEFAULT()]): $tokens->seekTokenText('='); if (!$tokens->seekTokenNum(T_CONSTANT_ENCAPSED_STRING) && !$tokens->seekTokenNum(T_STRING)) { throw new MalformedSqlException("Missing string for CHARACTER SET!", $tokens); } $columnDefinition->setCharacterSet($tokens->getCurrentTokenString()); break; case $tokens->seekTokenNum(SqlToken::T_COLLATE()): $tokens->seekTokenText('='); if (!$tokens->seekTokenNum(T_CONSTANT_ENCAPSED_STRING) && !$tokens->seekTokenNum(T_STRING)) { throw new MalformedSqlException("Missing string for COLLATE!", $tokens); } $columnDefinition->setCollate($tokens->getCurrentTokenString()); break; case $tokens->seekTokenNum(SqlToken::T_ON()): switch (true) { case $tokens->seekTokenNum(SqlToken::T_UPDATE()): switch (true) { case $this->valueParser->canParseTokens($tokens): $columnDefinition->setOnUpdate($this->valueParser->convertSqlToJob($tokens)); break; default: throw new MalformedSqlException("Invalid value for ON UPDATE!", $tokens); } break; case $tokens->seekTokenNum(SqlToken::T_DELETE()): switch (true) { case $this->valueParser->canParseTokens($tokens): $columnDefinition->setOnDelete($this->valueParser->convertSqlToJob($tokens)); break; default: throw new MalformedSqlException("Invalid value for ON UPDATE!", $tokens); } break; default: throw new MalformedSqlException("Only UPDATE and DELETE allowed for ON trigger!", $tokens); } break; case is_int($tokens->isTokenText(')')): case is_int($tokens->isTokenText(',')): break 2; default: break 2; } } return $columnDefinition; }
public function parsePlainValue(SQLTokenIterator $tokens, ValueJob $valueJob) { switch (true) { case $tokens->seekTokenNum(T_NUM_STRING): $valueJob->addChainValue((double) $tokens->getCurrentTokenString()); break; case $tokens->seekTokenNum(T_CONSTANT_ENCAPSED_STRING): $string = $tokens->getCurrentTokenString(); if (($string[0] === '"' || $string[0] === "'") && $string[0] === $string[strlen($string) - 1]) { // remove quotes if needed $string = substr($string, 1, strlen($string) - 2); } $valueJob->addChainValue($string); break; case $tokens->seekTokenNum(T_VARIABLE): $variableString = $tokens->getCurrentTokenString(); $variable = Variable::factory($variableString); if ($variableString === '?') { $variable->setIndex($tokens->countTokenOccourences(T_VARIABLE, 0, $tokens->getIndex() - 1)); } $valueJob->addChainValue($variable); break; case $this->parenthesisParser->canParseTokens($tokens): $valueJob->addChainValue($this->parenthesisParser->convertSqlToJob($tokens)); break; case $this->functionParser->canParseTokens($tokens): $valueJob->addChainValue($this->functionParser->convertSqlToJob($tokens)); break; case $this->columnParser->canParseTokens($tokens): $valueJob->addChainValue($this->columnParser->convertSqlToJob($tokens)); break; case $this->caseParser->canParseTokens($tokens): $valueJob->addChainValue($this->caseParser->convertSqlToJob($tokens)); break; case $tokens->seekTokenNum(SqlToken::T_DEFAULT()): case $tokens->seekTokenNum(SqlToken::T_NULL()): case $tokens->seekTokenNum(SqlToken::T_FALSE()): case $tokens->seekTokenNum(SqlToken::T_TRUE()): case $tokens->seekTokenNum(SqlToken::T_CURRENT_TIMESTAMP()): case $tokens->seekTokenNum(SqlToken::T_CURRENT_DATE()): case $tokens->seekTokenNum(SqlToken::T_CURRENT_TIME()): case $tokens->seekTokenNum(SqlToken::T_CURRENT_USER()): $valueJob->addChainValue($tokens->getCurrentTokenNumber()); break; default: return false; } return true; }
/** * 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; }