public function addColumnDefinition(ColumnDefinition $column) { if (!is_array($this->columnDefinition)) { $this->columnDefinition = array(); } if (isset($this->columnDefinition[$column->getName()])) { throw new MalformedSqlException("Column '{$column->getName()}' already defined!"); } $this->columnDefinition[$column->getName()] = $column; if ($column->getIsPrimaryKey()) { $index = new Index(); $index->setIsPrimary(true); $index->setName("PRIMARY"); $index->addColumn(ColumnSpecifier::factory($column->getName())); $this->addIndex($index); } elseif ($column->getIsUnique()) { $index = new Index(); $index->setIsUnique(true); $index->setName($column->getName()); $index->addColumn(ColumnSpecifier::factory($column->getName())); $this->addIndex($index); } }
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; }
protected function convertColumnDefinitionToColumnSchema(ColumnDefinition $columnDefinition, ExecutionContext $executionContext) { $columnPage = new ColumnSchema(); $columnPage->setName($columnDefinition->getName()); /* @var $dataType DataType */ $dataType = $columnDefinition->getDataType(); $columnPage->setDataType($dataType); if (!is_null($columnDefinition->getDataTypeLength())) { $columnPage->setLength($columnDefinition->getDataTypeLength()); } if (!is_null($columnDefinition->getDataTypeSecondLength())) { $columnPage->setSecondLength($columnDefinition->getDataTypeSecondLength()); } $flags = 0; if ($columnDefinition->getIsAutoIncrement()) { $flags = $flags ^ ColumnSchema::EXTRA_AUTO_INCREMENT; } if (!$columnDefinition->getIsNullable()) { $flags = $flags ^ ColumnSchema::EXTRA_NOT_NULL; } if ($columnDefinition->getIsPrimaryKey()) { $flags = $flags ^ ColumnSchema::EXTRA_PRIMARY_KEY; } if ($columnDefinition->getIsUnique()) { $flags = $flags ^ ColumnSchema::EXTRA_UNIQUE_KEY; } if ($columnDefinition->getIsUnsigned()) { $flags = $flags ^ ColumnSchema::EXTRA_UNSIGNED; } if (false) { $flags = $flags ^ ColumnSchema::EXTRA_ZEROFILL; } $columnPage->setExtraFlags($flags); #$columnPage->setFKColumnIndex($index); #$columnPage->setFKTableIndex($index); /* @var $defaultValue Value */ $defaultValue = $columnDefinition->getDefaultValue(); if (!is_null($defaultValue)) { if (!$dataType->mustResolveDefaultValue()) { # default value must be resolved at insertion-time => save unresolved $defaultValueData = $this->valueResolver->resolveValue($defaultValue, $executionContext); $defaultValueData = $this->dataConverter->convertStringToBinary($defaultValueData, $columnPage->getDataType()); } else { $defaultValueData = (string) $defaultValue; } } else { $defaultValueData = null; } $columnPage->setDefaultValue($defaultValueData); $comment = $columnDefinition->getComment(); # TODO: save column comment return $columnPage; }