protected function permitNonLookupDatasetStorageChanges(DataControllerCallContext $callcontext, DatasetMetaData $originalLogicalDataset, DatasetMetaData $modifiedLogicalDataset) {
        // it needs to be update dataset structure operation
        if (!isset($callcontext->changeAction)) {
            return;
        }

        // checking if we try to exclude some columns
        if (!isset($callcontext->changeAction->excludedColumns)) {
            return;
        }

        // checking if we try to exclude reference column
        // If we do we need to delete persistence storage
        // That would delete reference to lookup dataset and in the future the system will not generate unexpected errors related to incorrect data in excluded column
        foreach ($callcontext->changeAction->excludedColumns as $excludedColumn) {
            $originalLogicalColumn = $originalLogicalDataset->getColumn($excludedColumn->name);
            if ($originalLogicalColumn->type->getReferencedDatasetName() == NULL) {
                continue;
            }

            if (!isset($callcontext->changeAction->updatedDataTypeExcludedColumns[$excludedColumn->name])) {
                $callcontext->changeAction->updatedDataTypeExcludedColumns[$excludedColumn->name] = $excludedColumn;
            }
        }
    }
    protected function revertIneligibleColumnPropertyValues(DatasetMetaData $dataset) {
        // excluded columns cannot be part of primary key
        foreach ($dataset->getColumns(FALSE) as $column) {
            if ($column->isUsed()) {
                continue;
            }

            if ($column->isKey()) {
                $column->key = FALSE;
            }
        }
    }
 public function prepareDimension(MetaModel $metamodel, DatasetMetaData $dataset, $columnName, CubeMetaData $cube)
 {
     $column = $dataset->getColumn($columnName);
     $sourceDatasetColumn = $cube->sourceDataset->getColumn($columnName);
     $dimension = $cube->getDimension($columnName);
     $this->prepareYearLevel($dimension, $column);
     // cube source dataset column contains a reference to year identifier
     $sourceDatasetColumn->initializeTypeFrom(Sequence::getSequenceColumnType());
     // adding a reference to date dataset
     $referenceName = DateDimensionDatasetNames::LEVEL_YEARS;
     $metamodel->registerSimpleReferencePoint($referenceName, DateDimensionDatasetNames::LEVEL_YEARS, 'year_id');
     $metamodel->registerSimpleReferencePoint($referenceName, $cube->sourceDatasetName, $columnName);
 }
    public function prepareDimension(MetaModel $metamodel, DatasetMetaData $dataset, $columnName, CubeMetaData $cube) {
        $logicalColumn = $dataset->getColumn($columnName);
        $column = $cube->factsDataset->getColumn($columnName);
        $dimension = $cube->getDimension($columnName);

        // preparing the dimension properties
        $dimension->attributeColumnName = $columnName;
        $dimension->setDatasetName(StarSchemaNamingConvention::getAttributeRelatedName($dataset->name, $columnName));

        // preparing dimension dataset
        $dimension->dataset = new DatasetMetaData();
        $dimension->dataset->name = $dimension->datasetName;
        $dimension->dataset->publicName = $dataset->publicName . " [$logicalColumn->publicName]";
        $dimension->dataset->description = t("Lookup table to store unique values from '@columnName' column", array('@columnName' => $logicalColumn->publicName));
        $dimension->dataset->datasourceName = $dataset->datasourceName;
        $dimension->dataset->source = StarSchemaNamingConvention::getAttributeRelatedName($dataset->source, $columnName);
        $dimension->dataset->markAsPrivate();
        // adding dimension dataset aliases
        if (isset($dataset->aliases)) {
            foreach ($dataset->aliases as $alias) {
                $dimension->dataset->aliases[] = StarSchemaNamingConvention::getAttributeRelatedName($alias, $columnName);
            }
        }

        // adding key column
        $keyColumn = $dimension->dataset->registerColumn($columnName);
        $keyColumn->publicName = $logicalColumn->publicName;
        $keyColumn->description = t("System generated ID to identify each unique value from '@columnName' column", array('@columnName' => $logicalColumn->publicName));
        $keyColumn->initializeTypeFrom(Sequence::getSequenceColumnType());
        $keyColumn->key = TRUE;
        $keyColumn->visible = FALSE;
        
        // adding 'value' column
        $valueColumn = $dimension->dataset->registerColumn('value');
        $valueColumn->publicName = $logicalColumn->publicName;
        $valueColumn->description = t("Actual value from '@columnName' column", array('@columnName' => $logicalColumn->publicName));
        $valueColumn->initializeTypeFrom($logicalColumn->type);

        // facts dataset column contains a reference to lookup
        $column->initializeTypeFrom(Sequence::getSequenceColumnType());
        $column->type->logicalApplicationType = StringDataTypeHandler::DATA_TYPE;

        // marking that the dimension dataset object contains complete meta data & registering it in meta model
        $dimension->dataset->markAsComplete();
        $metamodel->registerDataset($dimension->dataset);

        // adding a reference to the dimension dataset
        $referenceName = $dimension->datasetName;
        $metamodel->registerSimpleReferencePoint($referenceName, $dimension->datasetName, $columnName);
        $metamodel->registerSimpleReferencePoint($referenceName, $cube->factsDatasetName, $columnName);
    }
 protected function isDependent(DatasetMetaData $dataset, DatasetMetaData $datasetB)
 {
     $referenceCount = 0;
     foreach ($dataset->getColumns() as $column) {
         list($referencedDatasetName) = ReferencePathHelper::splitReference($column->type->applicationType);
         if (isset($referencedDatasetName)) {
             $referenceCount++;
         } else {
             continue;
         }
         if ($referencedDatasetName == $datasetB->name) {
             return array(TRUE, NULL);
         }
     }
     return array(FALSE, $referenceCount);
 }
    public function dropColumnStorage(DataControllerCallContext $callcontext, DataSourceStructureHandler $datasourceStructureHandler, DatasetMetaData $dataset, $columnName, $stage) {
        if ($stage == DatasetStorageObserver::STAGE__AFTER) {
            $environment_metamodel = data_controller_get_environment_metamodel();

            $originalLogicalColumn = $this->originalLogicalDataset->getColumn($columnName);
            $originalColumn = $dataset->getColumn($columnName);

            $datasource = $environment_metamodel->getDataSource($dataset->datasourceName);
            $datasourceQueryHandler = DataSourceQueryFactory::getInstance()->getHandler($datasource->type);

            $generator = new FunctionDateDimensionMetaDataGenerator($datasourceQueryHandler);
            $generator->clean($originalColumn);
            $generator->clean($originalLogicalColumn);
        }

        parent::dropColumnStorage($callcontext, $datasourceStructureHandler, $dataset, $columnName, $stage);
    }
 public function initializeFactsDatasetFrom($sourceFactsDataset) {
     if (isset($sourceFactsDataset)) {
         if (!isset($this->factsDataset)) {
             $this->initiateFactsDataset();
         }
         $this->factsDataset->initializeFrom($sourceFactsDataset);
     }
 }
    protected function prepareColumnUIMetaData(array $datasetStack, $referencePath, DatasetMetaData $dataset, $columnName) {
        $column = $dataset->getColumn($columnName);

        $columnUIMetaData = new AttributeUIMetaData();
        $columnUIMetaData->name = self::prepareColumnUIMetaDataName($referencePath, $dataset->name, $column->name);
        $columnUIMetaData->publicName = $column->publicName;
        $columnUIMetaData->description = $column->description;
        $columnUIMetaData->columnIndex = $column->columnIndex;
        $columnUIMetaData->type = clone $column->type;

        list($referencedDatasetName) = ReferencePathHelper::splitReference($column->type->getLogicalApplicationType());
        if (isset($referencedDatasetName)) {
            $metamodel = data_controller_get_metamodel();
            $referencedDataset = $metamodel->getDataset($referencedDatasetName);

            if (!isset($datasetStack[$referencedDataset->name])) {
                $datasetStack[$referencedDataset->name] = TRUE;

                $branchReferencePath = isset($referencePath)
                    ? self::prepareReferencedElementName($referencePath, $dataset->name, $column->name)
                    : ReferencePathHelper::assembleReference($dataset->name, $column->name);

                foreach ($referencedDataset->getColumns() as $referencedColumn) {
                    if (!$referencedColumn->isVisible()) {
                        continue;
                    }

                    $referencedColumnMetaData = $this->prepareColumnUIMetaData($datasetStack, $branchReferencePath, $referencedDataset, $referencedColumn->name);
                    if ($referencedColumn->isKey()) {
                        if (count($referencedColumnMetaData->elements) == 0) {
                            continue;
                        }

                        $referencedColumnMetaData->publicName = $referencedDataset->publicName;
                        $referencedColumnMetaData->description = $referencedDataset->description;
                        $referencedColumnMetaData->isSelectable = FALSE;
                    }

                    $columnUIMetaData->registerElement($referencedColumnMetaData);
                }
            }
        }

        return $columnUIMetaData;
    }
    /**
     * @param DataControllerCallContext $callcontext
     * @param DatasetMetaData $dataset
     * @param DatasetStorageObserver[] $observers
     * @throws Exception
     */
    protected function dropColumnStorage(DataControllerCallContext $callcontext, DatasetMetaData $dataset, array $observers = NULL) {
        if (isset($observers)) {
            // dropping physical storage of the dataset columns
            foreach ($dataset->getColumns(FALSE) as $column) {
                if ($column->persistence != ColumnMetaData::PERSISTENCE__STORAGE_CREATED) {
                    continue;
                }

                MetaModelFactory::getInstance()->startGlobalModification();
                try {
                    $transaction = db_transaction();
                    try {
                        if (isset($observers)) {
                            foreach ($observers as $observer) {
                                $observer->dropColumnStorage(
                                    $callcontext, $this->datasourceStructureHandler,
                                    $dataset, $column->name, DatasetStorageObserver::STAGE__BEFORE);
                            }
                        }

                        $column->persistence = ColumnMetaData::PERSISTENCE__NO_STORAGE;
                        $column->used = FALSE;

                        if (isset($observers)) {
                            foreach ($observers as $observer) {
                                $observer->dropColumnStorage(
                                    $callcontext, $this->datasourceStructureHandler,
                                    $dataset, $column->name, DatasetStorageObserver::STAGE__AFTER);
                            }
                        }
                    }
                    catch (Exception $e) {
                        $transaction->rollback();
                        throw $e;
                    }
                }
                catch (Exception $e) {
                    MetaModelFactory::getInstance()->finishGlobalModification(FALSE);
                    throw $e;
                }
                MetaModelFactory::getInstance()->finishGlobalModification(TRUE);
            }
        }
    }
    public function getDatasetMetaData(DataControllerCallContext $callcontext, DatasetMetaData $dataset) {
        // TODO Change implementation of the method and work with provided $dataset
        list($metadataDatasetName, $schemaDocumentId) = $this->getMetaDataStorageProperties($callcontext, $dataset->name);

        // loading schema for the dataset
        $schemaLoadRequest = new DatasetQueryRequest($metadataDatasetName);
        $schemaLoadRequest->addQueryValue(0, '_id', $schemaDocumentId);
        $schema = $this->queryDataset($callcontext, $schemaLoadRequest, NULL);

        $metadata = new DatasetMetaData();
        if (isset($schema)) {
            foreach ($schema[0]->properties as $propertyName => $property) {
                $column = $metadata->registerColumn($propertyName);
                // TODO support other properties of ColumnType class
                $column->type->applicationType = $property->type;
                $column->key = $property->key;
            }
        }
    }
Example #11
0
 protected function mergeWithDataset(AbstractMetaModel $metamodel, array $filters = NULL, $namespace, $sourceDatasetName, $sourceDataset)
 {
     $datasetName = NameSpaceHelper::resolveNameSpace($namespace, $sourceDatasetName);
     // dataset/datasource/name
     if (!isset($sourceDataset->datasourceName)) {
         throw new IllegalStateException(t("'@datasetName' dataset definition does not contain a reference to datasource", array('@datasetName' => isset($sourceDataset->publicName) ? $sourceDataset->publicName : $datasetName)));
     }
     $sourceDataset->datasourceName = NameSpaceHelper::resolveNameSpace($namespace, $sourceDataset->datasourceName);
     // dataset/cache/datasource/name
     if (isset($sourceDataset->cache->datasourceName)) {
         $sourceDataset->cache->datasourceName = NameSpaceHelper::resolveNameSpace($namespace, $sourceDataset->cache->datasourceName);
     }
     $dataset = new DatasetMetaData();
     $dataset->name = $datasetName;
     $dataset->initializeFrom($sourceDataset);
     $isDatasetAcceptable = $this->isMetaDataAcceptable($dataset, $filters);
     if ($isDatasetAcceptable) {
         $metamodel->registerDataset($dataset);
     }
     return $isDatasetAcceptable ? $dataset : NULL;
 }
 protected function assembleForeignKeyConstraints(DataSourceHandler $handler, DatasetMetaData $dataset, $indent, &$sql)
 {
     $metamodel = data_controller_get_metamodel();
     foreach ($dataset->getColumns() as $column) {
         $columnName = $column->name;
         if (!isset($column->type->sourceApplicationType)) {
             continue;
         }
         // the column has to contain a reference to another dataset
         $dimensionLookupHandler = DimensionLookupFactory::getInstance()->getHandler($column->type->sourceApplicationType);
         list($referencedDatasetName) = $dimensionLookupHandler->adjustReferencePointColumn($metamodel, $dataset->name, $column->name);
         if ($dataset->name == $referencedDatasetName) {
             continue;
         }
         $referencedDataset = $metamodel->getDataset($referencedDatasetName);
         // we can create a foreign key constraint referenced to a table only
         $referencedDatasetSourceType = DatasetTypeHelper::detectDatasetSourceType($referencedDataset);
         if ($referencedDatasetSourceType != DatasetTypeHelper::DATASET_SOURCE_TYPE__TABLE) {
             continue;
         }
         $referencedOwner = NULL;
         if ($dataset->datasourceName != $referencedDataset->datasourceName) {
             // if we cannot join datasets we cannot create a foreign key constraint
             $datasourceQueryHandler = DataSourceQueryFactory::getInstance()->getHandler($handler->getDataSourceType());
             if (!$datasourceQueryHandler->isJoinSupported($dataset->datasourceName, $referencedDataset->datasourceName)) {
                 continue;
             }
             $referencedOwner = $handler->getDataSourceOwner($referencedDataset->datasourceName);
         }
         $referencedTableName = $referencedDataset->source;
         $referencedColumnName = $referencedDataset->getKeyColumn()->name;
         $sql .= ",\n{$indent}CONSTRAINT fk_{$dataset->source}_{$columnName} FOREIGN KEY ({$columnName}) REFERENCES " . (isset($referencedOwner) ? $referencedOwner . '.' : '') . "{$referencedTableName} ({$referencedColumnName})";
     }
 }
    public function prepareDimension(MetaModel $metamodel, DatasetMetaData $dataset, $columnName, CubeMetaData $cube) {
        $column = $dataset->getColumn($columnName);
        $dimension = $cube->getDimension($columnName);

        $dimension->attributeColumnName = $column->name;
    }
    protected function mergeWithDataset(AbstractMetaModel $metamodel, array $filters = NULL, $namespace, $sourceDatasetName, $sourceDataset) {
        $datasetName = NameSpaceHelper::resolveNameSpace($namespace, $sourceDatasetName);

        // dataset/datasource/name
        if (isset($sourceDataset->datasourceName)) {
            $sourceDataset->datasourceName = NameSpaceHelper::resolveNameSpace($namespace, $sourceDataset->datasourceName);
        }
        elseif (isset($namespace)) {
            $sourceDataset->datasourceName = $namespace;
        }
        else {
            throw new IllegalStateException(t(
                '%datasetName dataset definition does not contain a reference to datasource',
                array('%datasetName' => (isset($sourceDataset->publicName) ? $sourceDataset->publicName : $datasetName))));
        }

        // datasets defined using .json refer to 'persistent' column
        if (isset($sourceDataset->columns)) {
            foreach ($sourceDataset->columns as $sourceColumn) {
                if (!isset($sourceColumn->persistence)) {
                    $sourceColumn->persistence = ColumnMetaData::PERSISTENCE__STORAGE_CREATED;
                }
            }
        }

        $dataset = new DatasetMetaData();
        $dataset->name = $datasetName;
        $dataset->initializeFrom($sourceDataset);

        $isDatasetAcceptable = $this->isMetaDataAcceptable($dataset, $filters);

        if ($isDatasetAcceptable) {
            $metamodel->registerDataset($dataset);
        }

        return $isDatasetAcceptable ? $dataset : NULL;
    }
    /**
     * @param DataControllerCallContext $callcontext
     * @param DatasetMetaData $originalDataset
     * @param DatasetMetaData $modifiedDataset
     * @param DatasetStorageObserver[] $observers
     * @throws Exception
     */
    protected function updateProperties(DataControllerCallContext $callcontext, DatasetMetaData $originalDataset, DatasetMetaData $modifiedDataset, array $observers = NULL) {
        $justPersistedColumns = NULL;
        ArrayHelper::merge($justPersistedColumns, $callcontext->changeAction->newIncludedColumns);
        ArrayHelper::merge($justPersistedColumns, $callcontext->changeAction->restoredColumns);
        ArrayHelper::merge($justPersistedColumns, $callcontext->changeAction->updatedDataTypeIncludedColumns);

        $columns = $justPersistedColumns;
        ArrayHelper::merge($columns, $callcontext->changeAction->updatedColumns);
        if ($callcontext->changeAction->isDatasetUpdated || isset($columns) || $callcontext->changeAction->isKeyUpdated) {
            MetaModelFactory::getInstance()->startGlobalModification();
            try {
                $transaction = db_transaction();
                try {
                    if (isset($columns)) {
                        foreach ($columns as $column) {
                            if (isset($justPersistedColumns[$column->name])) {
                                $column->used = TRUE;
                            }

                            if (isset($callcontext->changeAction->updatedColumns[$column->name])) {
                                $modifiedColumn = $modifiedDataset->getColumn($column->name);

                                $column->publicName = $modifiedColumn->publicName;
                                $column->description = $modifiedColumn->description;
                                $column->source = $modifiedColumn->source;
                                $column->key = $modifiedColumn->key;
                            }

                            if (isset($observers)) {
                                foreach ($observers as $observer) {
                                    $observer->updateColumn($callcontext, $originalDataset, $column->name);
                                }
                            }
                        }
                    }

                    if ($callcontext->changeAction->isDatasetUpdated) {
                        $originalDataset->publicName = $modifiedDataset->publicName;
                        $originalDataset->description = $modifiedDataset->description;
                        $originalDataset->initializeSourceFrom($modifiedDataset->source, TRUE);
                        $originalDataset->initializeAliasesFrom($modifiedDataset->aliases, TRUE);

                        if (isset($observers)) {
                            foreach ($observers as $observer) {
                                $observer->updateDataset($callcontext, $originalDataset);
                            }
                        }
                    }

                    if ($callcontext->changeAction->isKeyUpdated) {
                        $modifiedDatasetKeyColumnNames = $modifiedDataset->findKeyColumnNames();
                        if (isset($modifiedDatasetKeyColumnNames)) {
                            $this->executeDatasetUpdateOperations(
                                $callcontext,
                                $originalDataset,
                                array(new CreateDatasetKeyOperation()));
                        }
                    }
                }
                catch (Exception $e) {
                    $transaction->rollback();
                    throw $e;
                }
            }
            catch (Exception $e) {
                MetaModelFactory::getInstance()->finishGlobalModification(FALSE);
                throw $e;
            }
            MetaModelFactory::getInstance()->finishGlobalModification(TRUE);
        }
    }
 public function prepareMetaData(DataControllerCallContext $callcontext, $connection, $statement)
 {
     $dataset = new DatasetMetaData();
     for ($i = 0, $columnCount = $this->callback->getColumnCount($connection, $statement); $i < $columnCount; $i++) {
         $column = $this->callback->getColumnMetaData($connection, $statement, $i);
         if ($column === FALSE) {
             throw new IllegalArgumentException(t('The column with the index does not exist: @columnIndex', array('@columnIndex' => $i)));
         }
         $column->name = strtolower($column->name);
         $column->columnIndex = $i;
         $column->type->applicationType = $this->callback->calculateApplicationDataType($column);
         // support for column mapping
         $column->alias = isset($callcontext->columnMapping[$column->name]) ? $callcontext->columnMapping[$column->name] : $column->name;
         // checking if the column is a system column which should be invisible
         if (substr_compare($column->name, DatasetSystemColumnNames::COLUMN_NAME_PREFIX, 0, strlen(DatasetSystemColumnNames::COLUMN_NAME_PREFIX)) === 0) {
             $column->visible = FALSE;
         }
         $dataset->registerColumnInstance($column);
     }
     return $dataset;
 }
 public function load(AbstractMetaModelFactory $factory, AbstractMetaModel $metamodel, array $filters = NULL, $finalAttempt)
 {
     LogHelper::log_notice(t('Creating Meta Model using Drupal Content Types...'));
     $datasetCounter = 0;
     $contentTypes = content_types();
     if (isset($contentTypes)) {
         foreach ($contentTypes as $contentTypeName => $contentType) {
             // preparing list of tables which could be supported by our code
             $supportedTables = NULL;
             foreach ($contentType['fields'] as $field) {
                 $fieldName = $field['field_name'];
                 if ($field['multiple'] > 0) {
                     $message = t('Multiple values are not supported yet: @contentTypeName.@fieldName', array('@contentTypeName' => $contentTypeName, '@fieldName' => $fieldName));
                     LogHelper::log_warn($message);
                     continue;
                     // UnsupportedOperationException
                 }
                 // preparing table name where the field is stored
                 $fieldStorage = $field['db_storage'];
                 switch ($fieldStorage) {
                     case CONTENT_DB_STORAGE_PER_CONTENT_TYPE:
                         $tableName = _content_tablename($field['type_name'], $fieldStorage);
                         break;
                     case CONTENT_DB_STORAGE_PER_FIELD:
                         break;
                         $tableName = _content_tablename($fieldName, $fieldStorage);
                     default:
                         $message = t("Unsupported storage type - '@fieldStorage' for the field: @fieldName", array('@fieldStorage' => $fieldStorage, '@fieldName' => $fieldName));
                         LogHelper::log_warn($message);
                         continue;
                         // UnsupportedOperationException
                 }
                 // calculating number of 'visible' suffixes
                 $visibleSuffixCount = 0;
                 foreach ($field['columns'] as $columnAttributes) {
                     if (isset($columnAttributes['views'])) {
                         if ($columnAttributes['views'] === TRUE) {
                             $visibleSuffixCount++;
                         }
                     } else {
                         $visibleSuffixCount++;
                     }
                 }
                 // generating fields for all 'visible' suffixes
                 foreach ($field['columns'] as $columnSuffix => $columnAttributes) {
                     if (isset($columnAttributes['views']) && $columnAttributes['views'] === FALSE) {
                         continue;
                     }
                     $supportedField = new stdClass();
                     // required flag
                     $supportedField->required = $field->required == 1;
                     // original name of the field
                     $supportedField->original_name = $fieldName;
                     // calculating name of database column
                     $supportedField->column = $fieldName . '_' . $columnSuffix;
                     // field name
                     if ($visibleSuffixCount === 1) {
                         $supportedField->name = $fieldName;
                     } else {
                         $supportedField->name = $supportedField->column;
                     }
                     if (isset($supportedTables[$tableName]->storage)) {
                         $previousStorage = $supportedTables[$tableName]->storage;
                         if ($fieldStorage != $previousStorage) {
                             $message = t("Inconsistent storage for '@tableName' table([@fieldStorage1, @fieldStorage2]) for the field: @fieldName", array('@tableName' => $tableName, '@fieldName' => $fieldName, '@fieldStorage1' => $previousStorage, '@fieldStorage2' => $fieldStorage));
                             LogHelper::log_warn($message);
                             continue;
                             // IllegalStateException
                         }
                     } else {
                         $supportedTables[$tableName]->storage = $fieldStorage;
                     }
                     $supportedTables[$tableName]->supportedFields[$supportedField->name] = $supportedField;
                 }
             }
             // preparing dataset source
             $datasetSource = new stdClass();
             $datasetSource->assembler->type = ContentTypeDatasetSourceAssembler::$DATASET_SOURCE_ASSEMBLER__TYPE;
             $datasetSource->assembler->config->drupal = $contentType;
             if (isset($supportedTables)) {
                 $datasetSource->assembler->config->supportedTables = $supportedTables;
             }
             // preparing & registering dataset
             $dataset = new DatasetMetaData();
             $dataset->name = $this->getDatasetName($contentTypeName);
             $dataset->description = $contentType['description'];
             $dataset->datasourceName = AbstractDrupalDataSourceQueryProxy::$DATASOURCE_NAME__DEFAULT;
             $dataset->source = $datasetSource;
             // FIXME Populate list of columns and mark the dataset as complete
             $dataset->registerColumn('nid')->key = TRUE;
             $metamodel->registerDataset($dataset);
             $datasetCounter++;
         }
     }
     LogHelper::log_info(t('Processed @datasetCount datasets', array('@datasetCount' => $datasetCounter)));
     return self::LOAD_STATE__SUCCESSFUL;
 }
 public static function deinitializeByDataset(MetaModel $metamodel, DatasetMetaData $dataset)
 {
     $cubeName = $dataset->name;
     $cube = $metamodel->unregisterCube($cubeName);
     // de-initializing dimensions
     foreach ($dataset->getColumns() as $column) {
         self::deinitializeByColumn($cube, $dataset, $column->name);
     }
     $metamodel->unregisterDataset($cube->factsDatasetName);
 }
    public function prepareMetaData(DataControllerCallContext $callcontext, $connection, $statement) {
        $dataset = new DatasetMetaData();

        for ($i = 0, $columnCount = $this->callback->getColumnCount($connection, $statement); $i < $columnCount; $i++) {
            $column = $this->callback->getColumnMetaData($connection, $statement, $i);
            if ($column === FALSE) {
                throw new IllegalArgumentException(t('The column with the index does not exist: %columnIndex', array('%columnIndex' => $i)));
            }

            $column->name = strtolower($column->name);
            $column->columnIndex = $i;

            // preparing column type
            if (!isset($column->type->databaseType)) {
                throw new UnsupportedOperationException(t(
                    'Undefined database data type for the column: %columnName',
                    array('%columnName' => $column->name)));
            }
            $this->callback->generateColumnType($column);
            if (!isset($column->type->applicationType)) {
                throw new UnsupportedOperationException(t(
                    'Unsupported data type for %columnName column: %datatype',
                    array('%columnName' => $column->name, '%datatype' => $column->type->databaseType)));
            }

            // support for column mapping
            $column->alias = isset($callcontext->columnMapping[$column->name])
                ? $callcontext->columnMapping[$column->name]
                : $column->name;

            // FIXME eliminate the following block once direct connection is used for uploaded files
            // checking if the column is a system column which should be invisible
            if (substr_compare($column->name, DatasetSystemColumnNames::COLUMN_NAME_PREFIX, 0, strlen(DatasetSystemColumnNames::COLUMN_NAME_PREFIX)) === 0) {
                $column->visible = FALSE;
            }

            $dataset->registerColumnInstance($column);
        }

        return $dataset;

    }
    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)));
        }
    }
    protected function generateLogicalDatasets(SystemTableMetaModelLoaderCallContext $callcontext, AbstractMetaModel $metamodel) {
        $datasetCount = 0;

        foreach ($callcontext->datasets as $tableAccessKey => $dataset) {
            $logicalDataset = new DatasetMetaData();
            $logicalDataset->name = $this->generateLogicalDatasetName($dataset->name);
            $logicalDataset->publicName = $dataset->publicName;
            $logicalDataset->description = $dataset->description;
            $logicalDataset->datasourceName = $dataset->datasourceName;
            $logicalDataset->sourceType = StarSchemaDatasetSourceTypeHandler::SOURCE_TYPE;

            $callcontext->logicalDatasetNameMappings[$logicalDataset->name] = $tableAccessKey;

            foreach ($dataset->columns as $column) {
                $logicalColumn = $logicalDataset->initiateColumn();
                $logicalColumn->name = $column->name;
                $logicalColumn->publicName = $column->publicName;
                $logicalColumn->description = $column->description;
                $logicalColumn->persistence = $column->persistence;
                $logicalColumn->columnIndex = $column->columnIndex;
                $logicalColumn->key = $column->key;
                $logicalColumn->visible = $column->visible;
                $logicalColumn->used = $column->used;

                if (isset($column->type->logicalApplicationType)) {
                    list($refDatasetName, $refColumnName) = ReferencePathHelper::splitReference($column->type->logicalApplicationType);

                    $refDataset = $metamodel->getDataset($refDatasetName);
                    $refColumn = $refDataset->getColumn($refColumnName);

                    $logicalColumn->type->databaseType = $refColumn->type->databaseType;
                    $logicalColumn->type->length = $refColumn->type->length;
                    $logicalColumn->type->precision = $refColumn->type->precision;
                    $logicalColumn->type->scale = $refColumn->type->scale;

                    $logicalColumn->type->applicationType = ReferencePathHelper::assembleReference(
                        $this->generateLogicalDatasetName($refDataset->name), $refColumnName);
                }
                else {
                    $logicalColumn->initializeTypeFrom($column->type);
                }

                $logicalDataset->registerColumnInstance($logicalColumn);
            }

            $callcontext->logicalDatasets[$tableAccessKey] = $logicalDataset;
            $datasetCount++;
        }

        LogHelper::log_info(t('Generated @datasetCount logical datasets', array('@datasetCount' => $datasetCount)));
    }
Example #22
0
 public function __construct()
 {
     parent::__construct();
     $this->system = TRUE;
 }
    protected function update(Import\ImportStream $stream, Import\ImportContext $context) {
        $datasets = $stream->get('datasets');
        if (empty($datasets)) {
            return;
        }

        gd_datasource_set_active($context->get('datasourceName'));
        $metamodel = data_controller_get_metamodel();

        $environment_metamodel = data_controller_get_environment_metamodel();
        $datasource = $environment_metamodel->getDataSource($context->get('datasourceName'));

        foreach ( $datasets as $dataset ) {
            $existingDataset = GD_DatasetMetaModelLoaderHelper::findDatasetByUUID($metamodel->datasets, $dataset->uuid);
            if ( !$existingDataset ) {

                // map for re-linking dependent objects
                $dataset->originalName = $dataset->name;

                // create new name
                $newDatasetName = GD_NamingConvention::generateDatasetName();
                $dataset->name = $newDatasetName;
                $dataset->source = $newDatasetName;
                $dataset->datasourceName = $datasource->name;
            } else {
                // map for re-linking dependent objects
                $dataset->originalName = $dataset->name;

                $dataset->name = $existingDataset->name;
                $dataset->source = $existingDataset->source;
                $dataset->datasourceName = $existingDataset->datasourceName;
            }
        }

        // prepare dataset columns for import
        $this->prepareColumns($datasets);

        // prepares the metadata object, has to be of type RecordMetaData
        foreach ( $datasets as $key => $dataset ) {
            $metadata = new DatasetMetaData();
            $metadata->initializeFrom($dataset);
            $datasets[$key] = $metadata;
        }

        // ensure datasets are created in order to satisfy dependencies
        usort($datasets, array(new ReferencedDatasetComparator(), 'compare'));

        foreach ( $datasets as $dataset ) {
            $existingDataset = GD_DatasetMetaModelLoaderHelper::findDatasetByUUID($metamodel->datasets, $dataset->uuid);
            if ($existingDataset) {
                gd_data_controller_ddl_modify_dataset($dataset);
            } else {
                MetaModelFactory::getInstance()->startGlobalModification();
                try {
                    $transaction = db_transaction();
                    try {
                        gd_data_controller_ddl_create_dataset($dataset);
                    } catch (Exception $e) {
                        $transaction->rollback();
                        throw $e;
                    }
                } catch (Exception $e) {
                    MetaModelFactory::getInstance()->finishGlobalModification(false);
                    throw $e;
                }
                MetaModelFactory::getInstance()->finishGlobalModification(true);
            }
        }

        $stream->set('datasets',$datasets);
    }
    public function dropColumnStorage(DataControllerCallContext $callcontext, DataSourceStructureHandler $datasourceStructureHandler, DatasetMetaData $dataset, $columnName, $stage) {
        if ($stage == DatasetStorageObserver::STAGE__AFTER) {
            $originalLogicalColumn = $this->originalLogicalDataset->getColumn($columnName);
            $originalColumn = $dataset->getColumn($columnName);

            $originalLogicalColumn->persistence = $originalColumn->persistence;
            $originalLogicalColumn->used = $originalColumn->used;

            $handler = DimensionFactory::getInstance()->getHandler($originalLogicalColumn->type->getLogicalApplicationType());
            $handler->dropDimensionStorage($callcontext, $datasourceStructureHandler, $this->originalLogicalDataset, $columnName);
        }

        parent::dropColumnStorage($callcontext, $datasourceStructureHandler, $dataset, $columnName, $stage);
    }
    public function dropColumnStorage(DataControllerCallContext $callcontext, DataSourceStructureHandler $datasourceStructureHandler, DatasetMetaData $dataset, $columnName, $stage) {
        if ($stage == DatasetStorageObserver::STAGE__AFTER) {
            $originalColumn = $dataset->getColumn($columnName);

            $node = node_load($this->getColumn_NID($dataset, $columnName));

            $node->field_column_persistence[$node->language][0]['value'] = $originalColumn->persistence;
            $node->status = $originalColumn->isUsed() ? NODE_PUBLISHED : NODE_NOT_PUBLISHED;

            node_save($node);
        }

        parent::dropColumnStorage($callcontext, $datasourceStructureHandler, $dataset, $columnName, $stage);
    }
    public static function prepareDataset(MetaModel $metamodel, $datasetNode, array $datasetColumnNodes = NULL, DataSourceMetaData $datasource) {
        $dataset = new DatasetMetaData();
        $dataset->name = get_node_field_value($datasetNode, 'field_dataset_sysname', 0, 'value', TRUE);
        $dataset->publicName = $datasetNode->title;

        // preparing the dataset alternative names (aliases)
        $aliasIndex = 0;
        while (($alias = get_node_field_value($datasetNode, 'field_dataset_alias', $aliasIndex)) != NULL) {
            $dataset->aliases[] = $alias;

            $aliasIndex++;
        }

        $dataset->description = get_node_field_value($datasetNode, 'field_dataset_desc');

        $dataset->datasourceName = $datasource->name;

        // preparing source configuration properties
        $dataset->sourceType = get_node_field_value($datasetNode, 'field_dataset_source_type', 0, 'value', TRUE);
        $dataset->source = get_node_field_value($datasetNode, 'field_dataset_source', 0, 'value', TRUE);
        // preparing source properties as an associative array
        $dataset->configuration = get_node_field_object_value($datasetNode, 'field_dataset_source_properties');

        // dataset system properties
        $dataset->uuid = get_node_field_value($datasetNode, 'field_dataset_uuid', 0, 'value', TRUE);
        $dataset->nid = $datasetNode->nid;

        // preparing dataset columns
        if (isset($datasetColumnNodes)) {
            foreach ($datasetColumnNodes as $columnNode) {
                $column = $dataset->initiateColumn();
                $column->used = $columnNode->status == NODE_PUBLISHED;

                $column->name = get_node_field_value($columnNode, 'field_column_sysname', 0, 'value', TRUE);
                $column->publicName = $columnNode->title;
                $column->description = get_node_field_value($columnNode, 'field_column_desc');
                $column->key = get_node_field_boolean_value($columnNode, 'field_column_key');

                // column data type
                $column->type->applicationType = get_node_field_value($columnNode, 'field_column_datatype', 0, 'value', $column->used);
                if (isset($column->type->applicationType) && ($column->type->getReferencedDatasetName() == NULL)) {
                    $column->type->logicalApplicationType = NameSpaceHelper::addNameSpace(NAME_SPACE__STAR_SCHEMA, $column->type->applicationType);
                }
                $format = get_node_field_object_value($columnNode, 'field_column_format');
                if (isset($format->scale)) {
                    $column->type->scale = $format->scale;
                }

                $column->columnIndex = get_node_field_int_value($columnNode, 'field_column_index', 0, 'value', TRUE);
                $column->source = get_node_field_value($columnNode, 'field_column_source');
                $column->persistence = get_node_field_int_value($columnNode, 'field_column_persistence', 0, 'value', TRUE);

                // attribute system properties
                $column->nid = $columnNode->nid;

                $dataset->registerColumnInstance($column);
            }
        }

        // marking that the dataset object contains complete meta data
        $dataset->markAsComplete();

        $metamodel->registerDataset($dataset);

        return $dataset;
    }
 protected function getAssemblerName(DatasetMetaData $dataset) {
     return $dataset->getConfigurationProperty('assembler', TRUE);
 }
 public function isComplete() {
     return parent::isComplete() && (!isset($this->datasetName) || (isset($this->dataset) && $this->dataset->isComplete()));
 }
 protected function fixDropPrimaryKeyColumnProblem(DataSourceHandler $handler, DatasetMetaData $dataset, array $originalKeyColumnNames)
 {
     // when a column is used in primary key MySQL creates 'NOT NULL' constraint automatically
     // when the column is excluded from primary key the constraint is not deleted
     // with the following fix we recreate the column without such constraint
     $sql = '';
     foreach ($originalKeyColumnNames as $columnName) {
         $column = $dataset->getColumn($columnName);
         if ($sql != '') {
             $sql .= ', ';
         }
         $sql .= 'MODIFY COLUMN ' . $this->prepareColumnCreateStatement($handler, $column, FALSE);
     }
     return $sql;
 }
    public function assemble(AbstractSQLDataSourceQueryHandler $datasourceHandler, AbstractQueryRequest $request, DatasetMetaData $dataset, array $columnNames = NULL) {
        $statement = new Statement();

        $TABLE_ALIAS__FACTS = 'dsf';
        $TABLE_ALIAS__COLUMN_JOIN = 'cj';

        $metamodel = data_controller_get_metamodel();

        $cubeName = $dataset->name;
        $cube = $metamodel->getCube($cubeName);

        $factsDataset = $metamodel->getDataset($cube->factsDatasetName);

        self::$TABLE_ALIAS_SUFFIX__SEQUENCE++;
        $factsTable = new DatasetSection($factsDataset, $TABLE_ALIAS__FACTS . self::$TABLE_ALIAS_SUFFIX__SEQUENCE);
        $statement->tables[] = $factsTable;

        foreach ($dataset->getColumns() as $column) {
            $columnName = $column->name;

            $columnDefaultAlias = NULL;
            if (isset($columnNames)) {
                $columnDefaultAlias = array_search($columnName, $columnNames);
                if ($columnDefaultAlias === FALSE) {
                    continue;
                }

                // fixing the alias if the list of columns is not associative array
                if (is_int($columnDefaultAlias)) {
                    $columnDefaultAlias = NULL;
                }
            }

            // FIXME the following code does not work in the following situation:
            //   1) we need to query a dataset which is defined in GovDashboard using file upload
            //   2) column names are not provided
            //   3) for columns which are references to lookup, value from the primary key from lookup table is returned
            //      even if in definition of the dataset we have columns with the following application type: name@lookup, code @lookup and etc

            $isReferenceUsed = FALSE;
            $handler = DimensionLookupFactory::getInstance()->findHandler($column->type->getLogicalApplicationType());
            if (isset($handler)) {
                // FIXME remove this implementation when we implement 'Executable Tree' functionality
                list($connectedDatasetName, $connectedColumnName) = $handler->adjustReferencePointColumn($metamodel, $factsDataset->name, $columnName);
                if (($connectedDatasetName != $factsDataset->name) || ($connectedColumnName != $columnName)) {
                    self::$TABLE_ALIAS_SUFFIX__SEQUENCE++;
                    $columnJoinAliasPrefix = $TABLE_ALIAS__COLUMN_JOIN . self::$TABLE_ALIAS_SUFFIX__SEQUENCE;

                    $connectedDataset = $metamodel->getDataset($connectedDatasetName);
                    $connectedDatasetKeyColumnName = $connectedDataset->getKeyColumn()->name;

                    // preparing list of columns we want to get from connected dataset
                    $connectedDatasetColumnNames = NULL;
                    ArrayHelper::addUniqueValue($connectedDatasetColumnNames, $connectedDatasetKeyColumnName);
                    ArrayHelper::addUniqueValue($connectedDatasetColumnNames, $connectedColumnName);

                    $connectedStatement = $datasourceHandler->assembleDatasetSourceStatement($request, $connectedDataset, $connectedDatasetColumnNames);
                    $connectedStatement->addTableAliasPrefix($columnJoinAliasPrefix);

                    $connectedTable = $connectedStatement->getColumnTable($connectedColumnName);
                    // registering the column for facts table
                    $factsTableColumn = new ColumnSection($columnName, 'fact_' . $columnName);
                    $factsTableColumn->visible = FALSE;
                    $factsTable->columns[] = $factsTableColumn;
                    // adjusting key column from lookup
                    $connectedDatasetKeyColumn = $connectedTable->getColumn($connectedDatasetKeyColumnName);
                    $connectedDatasetKeyColumn->alias = 'lookup_' . $connectedDatasetKeyColumnName;
                    $connectedDatasetKeyColumn->visible = FALSE;
                    // adjusting value column from lookup
                    $connectedDatasetValueColumn = $connectedTable->getColumn($connectedColumnName);
                    $connectedDatasetValueColumn->alias = $columnName;
                    // the key column could be the same as value column
                    $connectedDatasetValueColumn->visible = TRUE;
                    // new value column which uses composite name as column alias
                    if (isset($columnDefaultAlias)) {
                        $connectedDatasetValueColumn2 = new ColumnSection(
                            $connectedColumnName,
                            DataSourceColumnNameHelper::generateFromParameterElements($datasourceHandler->getMaximumEntityNameLength(), $columnDefaultAlias));
                        $connectedDatasetValueColumn2->visible = FALSE;
                        $connectedTable->columns[] = $connectedDatasetValueColumn2;
                    }

                    // linking the lookup table with the facts table
                    $connectedTable->conditions[] = new JoinConditionSection(
                        $connectedDatasetKeyColumn->alias, new TableColumnConditionSectionValue($factsTable->alias, $columnName));

                    $statement->merge($connectedStatement);

                    $isReferenceUsed = TRUE;
                }
            }

            if (!$isReferenceUsed) {
                $factsTable->columns[] = new ColumnSection($columnName);
            }
        }

        return $statement;
    }