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; }