コード例 #1
0
ファイル: UseExecutor.php プロジェクト: addiks/phpsql
 public function executeJob(StatementJob $statement, array $parameters = array())
 {
     /* @var $statement UseStatement */
     $executionContext = new ExecutionContext($this->schemaManager, $statement, $parameters);
     $databaseValue = $statement->getDatabase();
     $databaseName = $this->valueResolver->resolveValue($databaseValue, $executionContext);
     $this->schemaManager->setCurrentlyUsedDatabaseId($databaseName);
     $result = new TemporaryResult();
     $result->setIsSuccess($this->schemaManager->getCurrentlyUsedDatabaseId() === $databaseName);
     return $result;
 }
コード例 #2
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;
 }
コード例 #3
0
ファイル: ShowExecutor.php プロジェクト: addiks/phpsql
 public function executeJob(StatementJob $statement, array $parameters = array())
 {
     /* @var $statement ShowStatement */
     switch ($statement->getType()) {
         case ShowType::DATABASES():
             return $this->executeShowDatabases($statement, $parameters);
         case ShowType::TABLES():
             return $this->executeShowTables($statement, $parameters);
         case ShowType::VIEWS():
             return $this->executeShowViews($statement, $parameters);
         case ShowType::COLUMNS():
             return $this->executeShowColumns($statement, $parameters);
     }
 }
コード例 #4
0
ファイル: UpdateExecutor.php プロジェクト: addiks/phpsql
 public function executeJob(StatementJob $statement, array $parameters = array())
 {
     /* @var $statement UpdateStatement */
     $result = new TemporaryResult();
     // TODO: multiple tables or not?
     $executionContext = new ExecutionContext($this->schemaManager, $statement, $parameters, $this->valueResolver);
     /* @var $tableSpecifier TableSpecifier */
     $tableSpecifier = $statement->getTables()[0];
     /* @var $tableResource Table */
     $tableResource = $this->tableManager->getTable($tableSpecifier->getTable(), $tableSpecifier->getDatabase());
     /* @var $tableSchema TableSchema */
     $tableSchema = $tableResource->getTableSchema();
     $indicies = array();
     foreach ($tableSchema->getIndexIterator() as $indexId => $indexPage) {
         /* @var $indexPage Index */
         /* @var $index Index */
         $index = $tableResource->getIndex($indexPage->getName());
         $indicies[] = $index;
     }
     /* @var $condition Value */
     $condition = $statement->getCondition();
     foreach ($tableResource as $rowId => $row) {
         if ($tableResource instanceof UsesBinaryDataInterface && $tableResource->usesBinaryData()) {
             $row = $tableResource->convertDataRowToStringRow($row);
         }
         $executionContext->setCurrentSourceRow($row);
         $conditionResult = $this->valueResolver->resolveValue($condition, $executionContext);
         if ($conditionResult) {
             $newRow = $row;
             foreach ($statement->getDataChanges() as $dataChange) {
                 /* @var $dataChange DataChange */
                 $columnName = (string) $dataChange->getColumn();
                 $newValue = $dataChange->getValue();
                 $newValue = $this->valueResolver->resolveValue($newValue, $executionContext);
                 $newRow[$columnName] = $newValue;
             }
             $row = $tableResource->convertStringRowToDataRow($row);
             $newRow = $tableResource->convertStringRowToDataRow($newRow);
             foreach ($indicies as $index) {
                 /* @var $index Index */
                 $index->updateRow($row, $newRow, $rowId);
             }
             $tableResource->setRowData($rowId, $newRow);
         }
     }
     return $result;
 }
コード例 #5
0
 public function executeJob(StatementJob $statement, array $parameters = array())
 {
     /* @var $statement CreateDatabaseStatement */
     $executionContext = new ExecutionContext($this->schemaManager, $statement, $parameters);
     $name = $this->valueResolver->resolveValue($statement->getName(), $executionContext);
     $this->schemaManager->createSchema($name);
     foreach ($this->tableManager->getTableFactories() as $tableFactory) {
         /* @var $tableFactory TableFactoryInterface */
         if ($tableFactory instanceof InformationSchemaTableFactory) {
             $tableFactory->clearCache();
         }
     }
     ### CREATE RESULTSET
     $result = new TemporaryResult();
     $result->setIsSuccess($this->schemaManager->schemaExists($name));
     return $result;
 }
コード例 #6
0
ファイル: DropExecutor.php プロジェクト: addiks/phpsql
 public function executeJob(StatementJob $statement, array $parameters = array())
 {
     /* @var $statement DropStatement */
     $context = new ExecutionContext($this->schemaManager, $statement, $parameters);
     switch ($statement->getType()) {
         case DropStatement::TYPE_DATABASE:
             return $this->executeDropDatabase($statement, $context);
         case DropStatement::TYPE_TABLE:
             return $this->executeDropTable($statement, $context);
         case DropStatement::TYPE_VIEW:
             return $this->executeDropView($statement, $context);
     }
     foreach ($this->tableManager->getTableFactories() as $tableFactory) {
         /* @var $tableFactory TableFactoryInterface */
         if ($tableFactory instanceof InformationSchemaTableFactory) {
             $tableFactory->clearCache();
         }
     }
 }
コード例 #7
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();
         }
     }
 }
コード例 #8
0
ファイル: SelectExecutor.php プロジェクト: addiks/phpsql
 public function executeJob(StatementJob $statement, array $parameters = array())
 {
     /* @var $statement SelectStatement */
     $defaultSchema = $this->schemaManager->getSchema();
     $executionContext = new ExecutionContext($this->schemaManager, $statement, $parameters);
     ### COLLECT SOURCE TABLES
     if (!is_null($statement->getJoinDefinition())) {
         foreach ($statement->getJoinDefinition()->getTables() as $joinTable) {
             /* @var $joinTable TableJoin */
             /* @var $dataSource ParenthesisPart */
             $dataSource = $joinTable->getDataSource();
             $tableResource = null;
             $alias = $dataSource->getAlias();
             $dataSource = $dataSource->getContain();
             if ($dataSource instanceof TableInterface) {
                 $tableResource = $dataSource;
                 if (is_null($alias)) {
                     $alias = $tableResource->getName();
                 }
             }
             if ($dataSource instanceof SelectStatement) {
                 /* @var $subQueryResult TemporaryResult */
                 $tableResource = $this->executeJob($dataSource, $parameters);
             }
             if ($dataSource instanceof TableSpecifier) {
                 if (!is_null($dataSource->getDatabase())) {
                     if (!$this->schemaManager->schemaExists($dataSource->getDatabase())) {
                         throw new InvalidArgumentException("Database '{$dataSource->getDatabase()}' does not exist!");
                     }
                     $schema = $this->schemaManager->getSchema($dataSource->getDatabase());
                 } else {
                     $schema = $defaultSchema;
                 }
                 if (!$schema->tableExists($dataSource->getTable())) {
                     throw new InvalidArgumentException("Table '{$dataSource}' does not exist!");
                 }
                 if (is_null($alias)) {
                     $alias = $dataSource->getTable();
                 }
                 $tableResource = $this->tableManager->getTable($dataSource->getTable(), $dataSource->getDatabase());
             }
             $executionContext->setTable($tableResource, (string) $alias);
         }
     }
     ### INIT RESULTSET
     $resultColumns = array();
     foreach ($statement->getColumns() as $column) {
         if ($column === '*') {
             foreach ($executionContext->getTables() as $alias => $table) {
                 /* @var $table Table */
                 /* @var $tableSchema TableSchema */
                 $tableSchema = $table->getTableSchema();
                 foreach ($tableSchema->getColumnIterator() as $columnPage) {
                     /* @var $columnPage ColumnSchema */
                     $columnName = $columnPage->getName();
                     if (count($executionContext->getTables()) > 1) {
                         $columnName = "{$alias}.{$columnName}";
                     }
                     $resultColumns[] = $columnName;
                 }
             }
         } elseif ($column instanceof ValuePart) {
             $resultColumns[] = $column->getAlias();
         }
     }
     $result = new TemporaryResult($resultColumns);
     $executionContext->setCurrentResultSet(new TemporaryResult($resultColumns));
     $executionContext->setCurrentSourceSet(new TemporaryResult());
     ### PRE-FILTER SOURCE COLUMNS (currently not implemented)
     if (!is_null($statement->getCondition())) {
         /* @var $condition ValuePart */
         $condition = $statement->getCondition();
         $tableConditions = $this->findFixedConditions($condition);
         foreach ($executionContext->getTables() as $alias => $table) {
             /* @var $table TableInterface */
             /* @var $tableSchema TableSchema */
             $tableSchema = $table->getTableSchema();
             $tableIterator = $table;
             $indexes = $this->findIndexesForTableConditions($tableConditions, $table, $alias);
             if (!empty($indexes)) {
                 # TODO: actually choose the best index instead of using the first usable index
                 #       (We probably need table-statistics to do that.)
                 $index = $indexes[0];
                 /* @var $indexSchema IndexSchema */
                 $indexSchema = $index->getIndexSchema();
                 $indexecColumns = array();
                 foreach ($indexSchema->getColumns() as $columnId) {
                     $columnName = $tableSchema->getColumn($columnId)->getName();
                     $indexecColumns[$columnId] = $columnName;
                 }
                 $tableIterator = new FilteredResourceIterator($tableIterator, $condition, $this->valueResolver, $executionContext, $index, $indexecColumns);
             }
             if ($tableIterator !== $table) {
                 $executionContext->setTable($tableIterator, $alias);
             }
         }
     }
     /* @var $joinDefinition Join */
     $joinDefinition = $statement->getJoinDefinition();
     if (!is_null($joinDefinition)) {
         ### BUILD JOIN
         if (count($joinDefinition->getTables()) > 1) {
             $iterator = new JoinIterator($joinDefinition, $executionContext, $this, $this->valueResolver, $statement, null);
         } else {
             /* @var $tableJoin TableJoin */
             $tableJoin = $joinDefinition->getTables()[0];
             $tableSource = $tableJoin->getDataSource();
             $alias = null;
             while ($tableSource instanceof ParenthesisPart) {
                 if (is_null($alias)) {
                     $alias = $tableSource->getAlias();
                 }
                 $tableSource = $tableSource->getContain();
             }
             if ($tableSource instanceof TableSpecifier) {
                 if (is_null($alias)) {
                     $alias = $tableSource->getTable();
                 }
                 $iterator = $executionContext->getTable($alias);
             } elseif ($tableSource instanceof SelectStatement) {
                 $iterator = $this->executeJob($tableSource);
             } else {
                 throw new ErrorException("Unexpected object given as source for join!");
             }
             $iterator = new AliasedResourceIterator($iterator, $alias);
         }
         ### FILTER RESULT
         // WHERE condition
         $condition = $statement->getCondition();
         if (!is_null($condition)) {
             if ($iterator instanceof IteratorAggreagte) {
                 $iterator = $iterator->getIterator();
             }
             $iterator = new FilteredResourceIterator($iterator, $condition, $this->valueResolver, $executionContext);
         }
         // ON/USING conditions from joins
         foreach ($joinDefinition->getTables() as $joinTable) {
             /* @var $joinTable TableJoin */
             $joinCondition = $joinTable->getCondition();
             if (!is_null($joinCondition)) {
                 if ($iterator instanceof IteratorAggreagte) {
                     $iterator = $iterator->getIterator();
                 }
                 $iterator = new FilteredResourceIterator($iterator, $joinCondition, $this->valueResolver, $executionContext);
             }
         }
         ### SET UP SORTING
         $orderColumns = $statement->getOrderColumns();
         if (count($orderColumns) > 0) {
             $innerIterator = $iterator;
             $iterator = new SortedResourceIterator($iterator, $this->valueResolver);
             $iterator->setTemporaryBuildChildIteratorByValue($orderColumns, $innerIterator, $executionContext);
         }
         ### WRITE RESULTSET
         foreach ($iterator as $dataRow) {
             if ($iterator instanceof UsesBinaryDataInterface && $iterator->usesBinaryData()) {
                 $dataRow = $iterator->convertDataRowToStringRow($dataRow);
             }
             $executionContext->getCurrentSourceSet()->addRow($dataRow);
             $executionContext->setCurrentSourceRow($dataRow);
             $resolvedRow = $this->valueResolver->resolveSourceRow($statement->getColumns(), $executionContext);
             $executionContext->getCurrentResultSet()->addRow($resolvedRow);
         }
     } else {
         // no joining (something like "SELECT 5+5 as foo")
         $resolvedRow = $this->valueResolver->resolveSourceRow($statement->getColumns(), $executionContext);
         $executionContext->getCurrentResultSet()->addRow($resolvedRow);
     }
     ### UNLOCK TABLES
     foreach ($executionContext->getTables() as $table) {
         # TODO: unlock tables
     }
     ### APPLY GROUPING
     $groupings = $statement->getGroupings();
     if (count($groupings) > 0) {
         foreach ($groupings as $groupingDefinition) {
             /* @var $groupingDefinition GroupingDefinition */
             /* @var $groupingValue ValuePart */
             $groupingValue = $groupingDefinition->getValue();
             $beforeSourceRow = $executionContext->getCurrentSourceRow();
             $groupedRows = array();
             foreach ($executionContext->getCurrentSourceSet() as $row) {
                 $executionContext->setCurrentSourceRow($row);
                 $groupId = $this->valueResolver->resolveValue($groupingValue, $executionContext);
                 if (!isset($groupedRows[$groupId])) {
                     $groupedRows[$groupId] = array();
                 }
                 $groupedRows[$groupId][] = $row;
             }
             $groupedResultSet = new TemporaryResult($resultColumns);
             foreach ($groupedRows as $groupId => $rows) {
                 if ($groupingDefinition->getDirection() === SqlToken::T_ASC()) {
                     $groupingMainRow = reset($rows);
                 } else {
                     $groupingMainRow = end($rows);
                 }
                 $currentGroupResultSet = new TemporaryResult();
                 foreach ($rows as $row) {
                     $currentGroupResultSet->addRow($row);
                 }
                 $executionContext->setCurrentSourceRow($groupingMainRow);
                 $executionContext->setCurrentSourceSet($currentGroupResultSet);
                 $resolvedRow = $this->valueResolver->resolveSourceRow($statement->getColumns(), $executionContext);
                 $groupedResultSet->addRow($resolvedRow);
             }
             $executionContext->setCurrentSourceRow($beforeSourceRow);
             $executionContext->setCurrentResultSet($groupedResultSet);
         }
     }
     ### APPLY RESULT-FILTER (HAVING)
     /* @var $resultFilter ConditionJob */
     $resultFilter = $statement->getResultFilter();
     if (!is_null($resultFilter)) {
         $filteredResult = new TemporaryResult($resultColumns);
         foreach ($executionContext->getCurrentResultSet() as $row) {
             $executionContext->setCurrentSourceRow($row);
             $passesFilter = (bool) $this->valueResolver->resolveValue($resultFilter, $executionContext);
             if ($passesFilter) {
                 $filteredResult->addRow($row);
             }
         }
         $executionContext->setCurrentResultSet($filteredResult);
     }
     ### APPEND UNIONED SELECT
     $unionSelect = $statement->getUnionSelect();
     if (!is_null($unionSelect)) {
         $unionResult = $this->executeJob($unionSelect, $parameters);
         foreach ($unionResult as $unionRow) {
             $executionContext->getCurrentResultSet()->addRow($unionRow);
         }
     }
     return $executionContext->getCurrentResultSet();
 }
コード例 #9
0
ファイル: CreateTableExecutor.php プロジェクト: addiks/phpsql
 public function executeJob(StatementJob $statement, array $parameters = array())
 {
     /* @var $statement CreateTableStatement */
     $context = new ExecutionContext($this->schemaManager, $statement, $parameters);
     /* @var $databaseSchema Schema */
     $databaseSchema = $this->schemaManager->getSchema();
     $schemaId = $this->schemaManager->getCurrentlyUsedDatabaseId();
     $tableName = $this->valueResolver->resolveValue($statement->getName(), $context);
     $schemaPage = new DatabaseSchemaPage();
     $schemaPage->setName($tableName);
     $schemaPage->setType(Type::TABLE());
     $schemaPage->setEngine(Engine::factory($statement->getEngine()->getName()));
     $schemaPage->setCollation(strtoupper($statement->getCollate()));
     $schemaPage->setUseChecksum($statement->getUseChecksum());
     $schemaPage->setMaxRows($statement->getMaximumRows());
     $schemaPage->setMinRows($statement->getMinimumRows());
     $schemaPage->setPackKeys($statement->getPackKeys());
     $schemaPage->setDelayKeyWrite($statement->getDelayKeyWrite());
     $schemaPage->setRowFormat(RowFormat::factory($statement->getRowFormat()));
     $schemaPage->setInsertMethod(InsertMethod::factory($statement->getInsertMethod()));
     $databaseSchema->registerTableSchema($schemaPage);
     /* @var $tableSchema TableSchema */
     $tableSchema = $this->schemaManager->getTableSchema($tableName);
     assert($tableSchema instanceof TableSchema);
     ### WRITE COLUMNS
     switch (true) {
         case is_array($statement->getColumnDefinition()):
             foreach ($statement->getColumnDefinition() as $name => $column) {
                 /* @var $column ColumnDefinition */
                 $columnPage = new ColumnSchema();
                 $columnPage->setName($name);
                 $columnPage->setDataType(DataType::factory($column->getDataType()->getName()));
                 /* @var $dataType DataType */
                 $dataType = $columnPage->getDataType();
                 $flags = 0;
                 if ($column->getIsPrimaryKey()) {
                     $flags = $flags ^ ColumnSchema::EXTRA_PRIMARY_KEY;
                 }
                 if ($column->getIsUnique()) {
                     $flags = $flags ^ ColumnSchema::EXTRA_UNIQUE_KEY;
                 }
                 if (!$column->getIsNullable()) {
                     $flags = $flags ^ ColumnSchema::EXTRA_NOT_NULL;
                 }
                 if ($column->getIsAutoIncrement()) {
                     $flags = $flags ^ ColumnSchema::EXTRA_AUTO_INCREMENT;
                 }
                 $columnPage->setExtraFlags($flags);
                 /* @var $dataType DataType */
                 $dataType = $column->getDataType();
                 $columnPage->setLength($dataType->getByteLength());
                 $columnPage->setSecondLength($dataType->getSecondByteLength());
                 if (!is_null($column->getDataTypeLength())) {
                     $columnPage->setLength($column->getDataTypeLength());
                 }
                 if (!is_null($column->getDataTypeSecondLength())) {
                     $columnPage->setSecondLength($column->getDataTypeSecondLength());
                 }
                 if (!is_null($column->getDefaultValue()) && !$columnPage->isDefaultValueInFile()) {
                     $columnPage->setDefaultValue($column->getDefaultValue());
                 }
                 $columnIndex = $tableSchema->addColumnSchema($columnPage);
                 if (!is_null($column->getDefaultValue()) && $columnPage->isDefaultValueInFile()) {
                     $defaultValueFilepath = sprintf(FilePathes::FILEPATH_DEFAULT_VALUE, $schemaId, $tableName, $columnIndex);
                     $this->tableManager->getFilesystem()->putFileContents($defaultValueFilepath, $column->getDefaultValue());
                 }
             }
             break;
         case $statement->getColumnDefinition() instanceof Select:
             break;
         case $statement->getColumnDefinition() instanceof TableInterface:
             break;
     }
     foreach ($statement->getIndexes() as $indexName => $index) {
         /* @var $index Index */
         $indexSchemaPage = new IndexSchema();
         $indexSchemaPage->setName($indexName);
         $indexSchemaPage->setEngine(IndexEngine::BTREE());
         switch (true) {
             case $index->getIsPrimary():
                 $indexSchemaPage->setType(IndexType::PRIMARY());
                 break;
             case $index->getIsUnique():
                 $indexSchemaPage->setType(IndexType::UNIQUE());
                 break;
             default:
                 $indexSchemaPage->setType(IndexType::INDEX());
                 break;
         }
         $method = ForeignKeyMethod::factory($index->getForeignKeyOnDeleteReferenceOption()->getName());
         $indexSchemaPage->setForeignKeyOnDeleteMethod($method);
         $method = ForeignKeyMethod::factory($index->getForeignKeyOnUpdateReferenceOption()->getName());
         $indexSchemaPage->setForeignKeyOnUpdateMethod($method);
         $keyLength = 0;
         $columns = array();
         foreach ($index->getColumns() as $indexColumnName) {
             $indexColumnId = $tableSchema->getColumnIndex((string) $indexColumnName);
             if (strlen($indexColumnId) <= 0) {
                 throw new ErrorException("Could not find index column '{$indexColumnName}' in table-schema!");
             }
             $columns[] = $indexColumnId;
             $keyLength += $statement->getColumnDefinition()[(string) $indexColumnName]->getDataSize();
         }
         $indexSchemaPage->setColumns($columns);
         $indexSchemaPage->setKeyLength($keyLength);
         $tableSchema->addIndexSchema($indexSchemaPage);
     }
     foreach ($this->tableManager->getTableFactories() as $tableFactory) {
         /* @var $tableFactory TableFactoryInterface */
         if ($tableFactory instanceof InformationSchemaTableFactory) {
             $tableFactory->clearCache();
         }
     }
     ### RESULT
     $result = new TemporaryResult();
     $result->setIsSuccess(true);
     return $result;
 }
コード例 #10
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;
 }
コード例 #11
0
ファイル: InsertStatement.php プロジェクト: addiks/phpsql
 /**
  * @see Addiks\PHPSQL.Statement::getIsValid()
  */
 public function validate()
 {
     if (is_array($this->getDataSource())) {
         $columnCount = count($this->getColumns());
         foreach ($this->getDataSource() as $rowIndex => $row) {
             $rowIndex++;
             if (count($row) !== $columnCount) {
                 throw new InvalidArgument("Column-count in row #{$rowIndex} does not match column-count in column-specifier!");
             }
         }
     }
     parent::validate();
 }
コード例 #12
0
ファイル: DeleteExecutor.php プロジェクト: addiks/phpsql
 public function executeJob(StatementJob $statement, array $parameters = array())
 {
     /* @var $statement DeleteStatement */
     $result = new TemporaryResult();
     $executionContext = new ExecutionContext($this->schemaManager, $statement, $parameters);
     /* @var $conditionValue Value */
     $conditionValue = $statement->getCondition();
     $rowCount = 0;
     $rowSkip = 0;
     $limitOffset = $statement->getLimitOffset();
     $limitCount = $statement->getLimitRowCount();
     foreach ($statement->getDeleteTables() as $tableSpecifier) {
         /* @var $tableSpecifier TableSpecifier */
         /* @var $tableResource Table */
         $tableResource = $this->tableManager->getTable($tableSpecifier->getTable(), $tableSpecifier->getDatabase());
         $sortedIterator = new SortedResourceIterator($tableResource, $this->valueResolver);
         /* @var $tableSchema TableSchema */
         $tableSchema = $tableResource->getTableSchema();
         if (!is_null($statement->getOrderColumn())) {
             $orderColumns = $statement->getOrderColumn();
             $sortedIterator->setTemporaryBuildChildIteratorByValue($orderColumns, $tableResource);
         } else {
             $primaryKeyColumns = $tableSchema->getPrimaryKeyColumns();
             $primaryIndexId = $tableSchema->getIndexIdByColumns(array_keys($primaryKeyColumns));
             if (!is_null($primaryIndexId)) {
                 /* @var $index Index */
                 $index = $tableResource->getIndex($primaryIndexId);
                 // TODO: try to extract begin/end values from conditions
                 $beginValue = null;
                 $endValue = null;
                 $iterator = $index->getIterator($beginValue, $endValue);
                 $sortedIterator->setChildIterator($iterator);
             } else {
                 /* @var $sortIndex Quicksort */
                 $sortIndex = $sortedIterator->getSortIndexByColumns($primaryKeyColumns);
                 foreach ($tableResource as $rowId => $row) {
                     $sortIndex->addRow($rowId, $row);
                 }
                 $sortIndex->sort();
                 $sortedIterator->setChildIterator($sortIndex);
             }
         }
         foreach ($sortedIterator as $rowId => $row) {
             $executionContext->setCurrentSourceRow($row);
             $isConditionMatch = true;
             if (!is_null($conditionValue)) {
                 $isConditionMatch = $this->valueResolver->resolveValue($conditionValue, $executionContext);
             }
             if ($isConditionMatch) {
                 if (!is_null($limitOffset) && $rowSkip < $limitOffset) {
                     $rowSkip++;
                     continue;
                 }
                 if (!is_null($limitCount) && $rowCount > $limitCount) {
                     continue;
                 }
                 $rowCount++;
                 foreach ($tableResource->getTableSchema()->getIndexIterator() as $indexId => $indexPage) {
                     /* @var $indexPage Index */
                     /* @var $indexResource Index */
                     $indexResource = $tableResource->getIndex($indexId);
                     $originalRow = $tableResource->getRowData($rowId);
                     $rowIdStr = $this->decstr($rowId);
                     $indexResource->removeRow($originalRow, $rowIdStr);
                 }
                 $tableResource->removeRow($rowId);
             }
         }
     }
     return $result;
 }
コード例 #13
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;
 }