protected function prepareDatasets4Update(SystemTableMetaModelLoaderCallContext $callcontext, AbstractMetaModel $metamodel, DataSourceMetaData $datasource) {
        foreach ($metamodel->datasets as $dataset) {
            // the dataset should belong to the selected data source
            if ($dataset->datasourceName !== $datasource->name) {
                continue;
            }

            // the dataset has to be of type table
            if (DatasetSourceTypeFactory::getInstance()->detectSourceType($dataset) !== TableDatasetSourceTypeHandler::SOURCE_TYPE) {
                continue;
            }

            // whole dataset meta data was prepared using different method. There is nothing else needs to be done
            if ($dataset->isComplete()) {
                continue;
            }

            // for now supporting datasets without table owner
            if (TableReferenceHelper::findTableOwner($dataset->source) != NULL) {
                continue;
            }

            // there could be several datasets for one table
            $tableAccessKey = $this->adjustTableName($dataset->source);
            $callcontext->datasets[$tableAccessKey][] = $dataset;
        }
    }
    public function __construct() {
        parent::__construct();

        $this->handlerConfigurations = module_invoke_all('dp_dataset_source_type');
    }
    public function dropDatasetStorage(DataControllerCallContext $callcontext, DatasetStorageRequest $request) {
        $environment_metamodel = data_controller_get_environment_metamodel();

        $dataset = DatasetSourceTypeFactory::getInstance()->getTableDataset($request->datasetName);
        $datasource = $environment_metamodel->getDataSource($dataset->datasourceName);

        $sql = $this->getExtension('dropTable')->generate($this, $dataset);
        LogHelper::log_info(new StatementLogMessage('table.drop', $sql));
        $this->executeStatement($datasource, $sql);
    }
    protected function prepareDeleteDatasetRecordStatements(DataControllerCallContext $callcontext, AbstractDatasetManipulationRequest $request) {
        $environment_metamodel = data_controller_get_environment_metamodel();

        $dataset = DatasetSourceTypeFactory::getInstance()->getTableDataset($request->datasetName);
        $datasource = $environment_metamodel->getDataSource($dataset->datasourceName);

        $tableName = $dataset->source;

        $isRecordIndexed = $request->recordsHolder instanceof IndexedRecordsHolder;

        $recordMetaData = isset($request->recordsHolder->recordMetaData) ? $request->recordsHolder->recordMetaData : $dataset;
        $keyColumns = $recordMetaData->getKeyColumns();

        // a request can be more efficient for single column key
        $deleteKeys = NULL;
        if (count($keyColumns) == 1) {
            list($keyColumnIndex, $keyColumn) = each($keyColumns);
            $keyColumnIdentifier = $isRecordIndexed ? $keyColumnIndex : $keyColumn->name;

            $keyValues = NULL;
            foreach ($request->recordsHolder->records as $record) {
                $keyValues[] = $this->formatValue($keyColumn->type->applicationType, $record->getColumnValue($keyColumnIdentifier, TRUE));
            }

            $deleteKeys[] = array($keyColumn->name => $keyValues);
        }
        else {
            foreach ($request->recordsHolder->records as $record) {
                $deleteKey = NULL;
                foreach ($keyColumns as $keyColumnIndex => $keyColumn) {
                    $keyColumnIdentifier = $isRecordIndexed ? $keyColumnIndex : $keyColumn->name;
                    $keyColumnValue = $this->formatValue($keyColumn->type->applicationType, $record->getColumnValue($keyColumnIdentifier, TRUE));

                    $deleteKey[$keyColumn->name] = $keyColumnValue;
                }

                $deleteKeys[] = $deleteKey;
            }
        }

        return $this->getExtension('prepareDeleteStatementBatch')->prepare($this, $datasource, $tableName, $deleteKeys);
    }
    public function assembleDatasetSourceStatement(AbstractQueryRequest $request, DatasetMetaData $dataset, array $columnNames = NULL) {
        $datasetSourceType = DatasetSourceTypeFactory::getInstance()->detectSourceType($dataset);

        $handler = DatasetSourceTypeFactory::getInstance()->getHandler($datasetSourceType);

        $statement = $handler->assemble($this, $request, $dataset, $columnNames);
        if (!isset($statement)) {
            throw new IllegalStateException(t(
            	'Could not prepare source statement for the dataset: %datasetName',
                array('%datasetName' => $dataset->publicName)));
        }

        return $statement;
    }
    protected function prepareTableUpdateOperation(DataSourceHandler $handler, DataControllerCallContext $callcontext, DatasetMetaData $dataset, AbstractDatasetStorageOperation $operation, $indent, &$sql) {
        $classname = get_class($operation);
        switch ($classname) {
            case 'CreateColumnOperation':
                $column = $dataset->getColumn($operation->columnName);
                $sql .= "\n{$indent}ADD " . $this->prepareColumnCreateStatement($handler, $column, FALSE);
                break;
            case 'DropColumnOperation':
                $sql .= "\n{$indent}" . $this->prepareColumnDeleteStatement($handler, $dataset, $operation->columnName);
                break;
            case 'CreateColumnReferenceOperation':
                $referencedDataset = DatasetSourceTypeFactory::getInstance()->getTableDataset($operation->referencedDatasetName);

                $referencedTableName = $referencedDataset->source;
                $referencedColumnName = $referencedDataset->getKeyColumn()->name;

                $sql .= "\n{$indent}ADD " . $this->prepareForeignKeyCreateStatement($handler, $dataset, $operation->columnName, $referencedTableName, $referencedColumnName);
                break;
            case 'DropColumnReferenceOperation':
                $sql .= "\n{$indent}" . $this->prepareForeignKeyDeleteStatement($handler, $dataset, $operation->columnName);
                break;
            case 'CreateDatasetKeyOperation':
                $this->allowPrimaryKeyCreation($handler, $callcontext, $dataset);

                $statement = $this->preparePrimaryKeyCreateStatement4Update($handler, $dataset);
                if (isset($statement)) {
                    $sql .= "\n{$indent}{$statement}";
                }
                break;
            case 'DropDatasetKeyOperation':
                $sql .= "\n{$indent}" . $this->preparePrimaryKeyDeleteStatement($handler, $dataset, $operation->originalKeyColumnNames);
                break;
            default:
                throw new IllegalArgumentException(t('Unsupported dataset update operation: %classname', array('%classname' => $classname)));
        }
    }