コード例 #1
0
ファイル: DescribeExecutor.php プロジェクト: addiks/phpsql
 public function executeJob(StatementJob $statement, array $parameters = array())
 {
     /* @var $statement DescribeStatement */
     $result = new TemporaryResult(['Field', 'Type', 'Null', 'Key', 'Default', 'Extra']);
     $schemaId = $this->schemaManager->getCurrentlyUsedDatabaseId();
     /* @var $tableSchema TableSchema */
     $tableSchema = $this->schemaManager->getTableSchema($statement->getTable()->getTable(), $statement->getTable()->getDatabase());
     if (is_null($tableSchema)) {
         throw new InvalidArgumentException("Table '{$statement->getTable()}' not found!");
     }
     foreach ($tableSchema->getColumnIterator() as $columnId => $columnPage) {
         /* @var $columnPage ColumnSchema */
         $fieldName = $columnPage->getName();
         $dataType = $columnPage->getDataType();
         $length = $columnPage->getLength();
         $hasIndex = !is_null($tableSchema->getIndexIdByColumns([$columnId]));
         $typeString = strtolower($dataType->getName());
         if ($dataType->hasLength()) {
             if ($columnPage->getSecondLength() > 0) {
                 $length = "{$length},{$columnPage->getSecondLength()}";
             }
             $typeString .= "({$length})";
         }
         $null = $columnPage->isNotNull() ? 'NO' : 'YES';
         $key = '';
         if ($hasIndex) {
             $key = 'MUL';
             if ($columnPage->isUniqueKey()) {
                 $key = 'UNI';
             }
             if ($columnPage->isPrimaryKey()) {
                 $key = 'PRI';
             }
         }
         $default = "";
         if ($columnPage->hasDefaultValue()) {
             if ($columnPage->isDefaultValueInFile()) {
                 $defaultValueFilepath = sprintf(FilePathes::FILEPATH_DEFAULT_VALUE, $schemaId, $statement->getTable(), $columnId);
                 $this->schemaManager->getFilesystem()->getFileContents($defaultValueFilepath);
             } else {
                 $default = $columnPage->getDefaultValue();
             }
             if (!$dataType->mustResolveDefaultValue()) {
                 $default = $this->dataConverter->convertBinaryToString($default, $dataType);
             }
         }
         $extraArray = array();
         if ($columnPage->isAutoIncrement()) {
             $extraArray[] = "auto_increment";
         }
         $result->addRow([$fieldName, $typeString, $null, $key, $default, implode(" ", $extraArray)]);
     }
     return $result;
 }
コード例 #2
0
ファイル: CreateIndexExecutor.php プロジェクト: addiks/phpsql
 public function executeJob(StatementJob $statement, array $parameters = array())
 {
     /* @var $statement CreateIndexStatement */
     /* @var $tableSpecifier TableSpecifier */
     $tableSpecifier = $statement->getTable();
     ### WRITE INDEX PAGE
     /* @var $tableResource TableInterface */
     $tableResource = $this->tableManager->getTable($tableSpecifier->getTable(), $tableSpecifier->getDatabase());
     /* @var $tableSchema TableSchema */
     $tableSchema = $tableResource->getTableSchema();
     $indexPage = new Index();
     $indexPage->setName($statement->getName());
     $indexPage->setEngine(IndexEngine::factory($statement->getIndexType()->getName()));
     $columnIds = array();
     $keyLength = 0;
     foreach ($statement->getColumns() as $columnDataset) {
         $columnSpecifier = $columnDataset['column'];
         /* @var $columnSpecifier Column */
         $columnId = $tableSchema->getColumnIndex($columnSpecifier->getColumn());
         if (is_null($columnId)) {
             throw new InvalidArgumentException("Cannot create index for unknown column '{$columnSpecifier->getColumn()}'!");
         }
         if (!is_null($columnDataset['length'])) {
             $keyLength += (int) $columnDataset['length'];
         } else {
             $keyLength += $tableSchema->getColumn($columnId)->getLength();
         }
         $columnIds[] = $columnId;
     }
     $indexPage->setColumns($columnIds);
     $indexPage->setKeyLength($keyLength);
     if ($statement->getIsPrimary()) {
         $indexPage->setType(Type::PRIMARY());
     } elseif ($statement->getIsUnique()) {
         $indexPage->setType(Type::UNIQUE());
     } else {
         $indexPage->setType(Type::INDEX());
     }
     $tableSchema->addIndexSchema($indexPage);
     ### PHSICALLY BUILD INDEX
     /* @var $tableResource TableInterface */
     $tableResource = $this->tableManager->getIndex($indexPage->getName(), $tableSpecifier->getTable(), $tableSpecifier->getDatabase());
     foreach ($tableResource->getIterator() as $rowId => $row) {
         $indexResource->insert($row, $rowId);
     }
     foreach ($this->tableManager->getTableFactories() as $tableFactory) {
         /* @var $tableFactory TableFactoryInterface */
         if ($tableFactory instanceof InformationSchemaTableFactory) {
             $tableFactory->clearCache();
         }
     }
 }
コード例 #3
0
ファイル: InsertExecutor.php プロジェクト: addiks/phpsql
 public function executeJob(StatementJob $statement, array $parameters = array())
 {
     /* @var $statement InsertStatement */
     $result = new TemporaryResult();
     $context = new ExecutionContext($this->schemaManager, $statement, $parameters);
     $tableName = (string) $statement->getTable();
     /* @var $table TableInterface */
     $table = $this->tableManager->getTable($tableName);
     /* @var $tableSchema TableSchema */
     $tableSchema = $table->getTableSchema();
     ### BUILD COLUMN MAP
     $columnNameToIdMap = array();
     foreach ($tableSchema->getColumnIterator() as $columnId => $columnPage) {
         /* @var $columnPage Column */
         $columnName = $columnPage->getName();
         $columnNameToIdMap[$columnName] = $columnId;
     }
     ### GET INDICES
     $indices = array();
     foreach ($tableSchema->getIndexIterator() as $indexId => $indexPage) {
         /* @var $indexPage Index */
         /* @var $index Index */
         $index = $table->getIndex($indexId);
         $indices[$indexId] = $index;
     }
     ### BUILD ROW DATA
     $rowDatas = array();
     switch (true) {
         case $statement->getDataSource() instanceof Select:
             $subResult = $this->selectExecutor->executeJob($statement->getDataSource(), $parameters);
             foreach ($subResult as $subResultRow) {
                 $rowData = array();
                 foreach ($subResultRow as $columnName => $value) {
                     $columnId = $columnNameToIdMap[$columnName];
                     $rowData[$columnId] = $value;
                 }
                 $rowDatas[] = $rowData;
             }
             break;
         case is_array($statement->getDataSource()):
             foreach ($statement->getDataSource() as $row) {
                 $sourceRow = array();
                 foreach ($statement->getColumns() as $sourceColumnId => $sourceColumn) {
                     /* @var $sourceColumn Column */
                     $sourceColumnName = (string) $sourceColumn;
                     $sourceRow[$sourceColumnName] = $row[$sourceColumnId];
                 }
                 $rowData = array();
                 foreach ($statement->getColumns() as $sourceColumnId => $sourceColumn) {
                     /* @var $sourceColumn Column */
                     $columnName = (string) $sourceColumn;
                     if (!isset($columnNameToIdMap[$columnName])) {
                         throw new ErrorException("Unknown column '{$columnName}' in statement!");
                     }
                     $columnId = $columnNameToIdMap[$columnName];
                     if (isset($sourceRow[$columnName])) {
                         $value = $sourceRow[$columnName];
                         $value = $this->valueResolver->resolveValue($value, $context);
                     } else {
                         $value = null;
                     }
                     /* @var $columnPage Column */
                     $columnPage = $tableSchema->getColumn($columnId);
                     if (is_null($value) && $columnPage->isAutoIncrement()) {
                         $value = $table->getAutoIncrementId();
                         $table->incrementAutoIncrementId();
                     }
                     if ($columnPage->isNotNull() && is_null($value)) {
                         $columnName = $tableSchema->getColumn($columnId)->getName();
                         throw new ErrorException("Column '{$columnName}' cannot be NULL!");
                     }
                     $rowData[$columnId] = $value;
                 }
                 $primaryKey = array();
                 // fill up missing columns
                 foreach ($columnNameToIdMap as $columnName => $columnId) {
                     /* @var $columnPage Column */
                     $columnPage = $tableSchema->getColumn($columnId);
                     if (!isset($rowData[$columnId])) {
                         if ($columnPage->isNotNull()) {
                             if ($columnPage->isAutoIncrement()) {
                                 $rowData[$columnId] = $table->getAutoIncrementId();
                                 $table->incrementAutoIncrementId();
                             } elseif ($columnPage->hasDefaultValue()) {
                                 if ($columnPage->isDefaultValueInFile()) {
                                     $defaultValueReference = $columnPage->getDefaultValue();
                                     $defaultValueFilePath = sprintf(FilePathes::FILEPATH_DEFAULT_VALUE, $schemaId, $tableName, $columnId);
                                 } else {
                                     $rowData[$columnId] = $columnPage->getDefaultValue();
                                 }
                             } else {
                                 throw new ErrorException("Column '{$columnName}' cannot be NULL!");
                             }
                         }
                     }
                     if ($columnPage->isPrimaryKey()) {
                         $primaryKey[$columnName] = $rowData[$columnId];
                     }
                 }
                 $result->setLastInsertId($primaryKey);
                 $rowData = $table->convertStringRowToDataRow($rowData);
                 foreach ($indices as $indexId => $index) {
                     /* @var $index Index */
                     if (!$index->getIndexSchema()->isUnique()) {
                         continue;
                     }
                     if (count($index->searchRow($rowData)) > 0) {
                         $rowDataString = implode(", ", $rowData);
                         throw new ErrorException("Cannot insert because row '{$rowDataString}' collides " . "with unique key '{$index->getIndexSchema()->getName()}'!");
                     }
                 }
                 $rowDatas[] = $rowData;
             }
             break;
     }
     ### INSERT DATA
     $insertedRowIds = array();
     $success = false;
     try {
         foreach ($rowDatas as $rowData) {
             // check unique keys
             foreach ($indices as $indexId => $index) {
                 if (!$index->getIndexSchema()->isUnique()) {
                     continue;
                 }
                 if (count($index->searchRow($rowData)) > 0) {
                     throw new ErrorException("Cannot insert because of unique key '{$index->getIndexSchema()->getName()}'!");
                 }
             }
             $rowId = $table->addRowData($rowData);
             $insertedRowIds[] = $rowId;
             // insert into indicies
             foreach ($indices as $indexId => $index) {
                 $index->insertRow($rowData, $this->decstr($rowId));
             }
         }
         $success = true;
     } catch (Exception $exception) {
         ### ROLLBACK
         foreach ($insertedRowIds as $rowId) {
             $table->removeRow($rowId);
             // remove from indicies
             foreach ($indices as $indexId => $index) {
                 $index->removeRow($row, $this->decstr($rowId));
             }
         }
         throw new ErrorException("Exception in INSERT statement, rollback executed.", null, null, null, 0, $exception);
     }
     ### RESULT
     $result->setIsSuccess((bool) $success);
     return $result;
 }
コード例 #4
0
ファイル: AlterExecutor.php プロジェクト: addiks/phpsql
 public function executeJob(StatementJob $statement, array $parameters = array())
 {
     /* @var $statement AlterStatement */
     $executionContext = new ExecutionContext($this->schemaManager, $statement, $parameters);
     /* @var $tableSpecifier TableSpecifier */
     $tableSpecifier = $statement->getTable();
     /* @var $table TableInterface */
     $table = $this->tableManager->getTable($tableSpecifier->getTable(), $tableSpecifier->getDatabase());
     $tableId = $this->tableManager->getTableIdByName($tableSpecifier->getTable(), $tableSpecifier->getDatabase());
     /* @var $tableSchema TableSchema */
     $tableSchema = $table->getTableSchema();
     foreach ($statement->getDataChanges() as $dataChange) {
         /* @var $dataChange DataChange */
         switch ($dataChange->getAttribute()) {
             case AlterAttributeType::ADD():
                 /* @var $columnDefinition ColumnDefinition */
                 $columnDefinition = $dataChange->getSubject();
                 /* @var $columnSchema ColumnSchema */
                 $columnSchema = $this->convertColumnDefinitionToColumnSchema($columnDefinition, $executionContext);
                 $columnId = $tableSchema->addColumnSchema($columnSchema);
                 /* @var $tableFactory TableFactoryInterface */
                 $tableFactory = $this->tableManager->getTableFactoryByTable($tableSpecifier->getTable(), $tableSpecifier->getDatabase());
                 $tableFactory->addColumnToTable($tableSpecifier->getDatabase(), $tableId, $columnId, $table, $columnSchema);
                 break;
             case AlterAttributeType::DROP():
                 /* @var $columnSpecifier ColumnSpecifier */
                 $columnSpecifier = $dataChange->getSubject();
                 $columnId = $tableSchema->getColumnIndex($columnSpecifier->getColumn());
                 $tableSchema->removeColumn($columnId);
                 break;
             case AlterAttributeType::SET_AFTER():
             case AlterAttributeType::SET_FIRST():
             case AlterAttributeType::MODIFY():
                 /* @var $columnDefinition ColumnDefinition */
                 $columnDefinition = $dataChange->getSubject();
                 /* @var $columnSchema ColumnSchema */
                 $columnSchema = $this->convertColumnDefinitionToColumnSchema($columnDefinition, $executionContext);
                 $columnId = $tableSchema->getColumnIndex($columnSchema->getName());
                 /* @var $oldColumnSchema ColumnSchema */
                 $oldColumnSchema = $tableSchema->getColumn($columnId);
                 $columnSchema->setIndex($oldColumnSchema->getIndex());
                 $tableSchema->writeColumn($columnId, $columnSchema);
                 /* @var $tableFactory TableFactoryInterface */
                 $tableFactory = $this->tableManager->getTableFactoryByTable($tableSpecifier->getTable(), $tableSpecifier->getDatabase());
                 $tableFactory->modifyColumnOnTable($tableSpecifier->getDatabase(), $tableId, $columnId, $table, $columnSchema);
                 if ($dataChange->getAttribute() === AlterAttributeType::SET_FIRST()) {
                     $subjectColumnIndex = $tableSchema->getColumnIndex($columnDefinition->getName());
                     $subjectColumnSchema = $tableSchema->getColumn($subjectColumnIndex);
                     $oldIndex = $subjectColumnSchema->getIndex();
                     foreach ($tableSchema->getColumnIterator() as $columnIndex => $columnPage) {
                         if ($columnPage->getIndex() < $oldIndex) {
                             $columnPage->setIndex($columnPage->getIndex() + 1);
                             $tableSchema->writeColumn($columnIndex, $columnPage);
                         }
                     }
                     $subjectColumnSchema->setIndex(0);
                     $tableSchema->writeColumn($subjectColumnIndex, $subjectColumnSchema);
                 } elseif ($dataChange->getAttribute() === AlterAttributeType::SET_AFTER()) {
                     /* @var $afterColumn ColumnSpecifier */
                     $afterColumn = $dataChange->getValue();
                     $afterColumnIndex = $tableSchema->getColumnIndex($afterColumn->getColumn());
                     $afterColumnSchema = $tableSchema->getColumn($afterColumnIndex);
                     $subjectColumnIndex = $tableSchema->getColumnIndex($columnDefinition->getName());
                     $subjectColumnSchema = $tableSchema->getColumn($subjectColumnIndex);
                     if ($afterColumnSchema->getIndex() < $subjectColumnSchema->getIndex()) {
                         foreach ($tableSchema->getColumnIterator() as $columnIndex => $columnPage) {
                             if ($columnPage->getIndex() > $afterColumnSchema->getIndex() && $columnPage->getIndex() < $subjectColumnSchema->getIndex()) {
                                 $columnPage->setIndex($columnPage->getIndex() + 1);
                                 $tableSchema->writeColumn($columnIndex, $columnPage);
                             }
                         }
                         $subjectColumnSchema->setIndex($afterColumnSchema->getIndex() + 1);
                         $tableSchema->writeColumn($subjectColumnIndex, $subjectColumnSchema);
                     } else {
                         foreach ($tableSchema->getColumnIterator() as $columnIndex => $columnPage) {
                             if ($columnPage->getIndex() > $afterColumnSchema->getIndex() && $columnPage->getIndex() < $subjectColumnSchema->getIndex()) {
                                 $columnPage->setIndex($columnPage->getIndex() - 1);
                                 $tableSchema->writeColumn($columnIndex, $columnPage);
                             }
                         }
                         $subjectColumnSchema->setIndex($afterColumnSchema->getIndex());
                         $tableSchema->writeColumn($subjectColumnIndex, $subjectColumnSchema);
                         $afterColumnSchema->setIndex($afterColumnSchema->getIndex() - 1);
                         $tableSchema->writeColumn($afterColumnSchema, $afterColumnSchema);
                     }
                 }
                 break;
             case AlterAttributeType::RENAME():
                 $databaseSchema = $this->schemaManager->getSchema($tableSpecifier->getDatabase());
                 /* @var $tablePage SchemaPage */
                 $tableIndex = $databaseSchema->getTableIndex($tableSpecifier->getTable());
                 $tablePage = $databaseSchema->getTablePage($tableIndex);
                 $tablePage->setName($dataChange->getValue());
                 $databaseSchema->registerTableSchema($tablePage, $tableIndex);
                 break;
             case AlterAttributeType::CHARACTER_SET():
                 break;
             case AlterAttributeType::COLLATE():
                 break;
             case AlterAttributeType::CONVERT():
                 break;
             case AlterAttributeType::DEFAULT_VALUE():
                 break;
             case AlterAttributeType::ORDER_BY_ASC():
                 break;
             case AlterAttributeType::ORDER_BY_DESC():
                 break;
         }
     }
     foreach ($this->tableManager->getTableFactories() as $tableFactory) {
         /* @var $tableFactory TableFactoryInterface */
         if ($tableFactory instanceof InformationSchemaTableFactory) {
             $tableFactory->clearCache();
         }
     }
     $result = new TemporaryResult();
     return $result;
 }