protected function formatColumnNameImpl($uiMetaDataName) {
        $columnName = NULL;

        $formattedUIMetaDataName = parent::formatColumnNameImpl($uiMetaDataName);

        list($elementNameSpace, $elementName) = AbstractDatasetUIMetaDataGenerator::splitElementUIMetaDataName($formattedUIMetaDataName);
        switch ($elementNameSpace) {
            case AbstractAttributeUIMetaData::NAME_SPACE:
                list($dimensionName, $dimensionColumnName) = ParameterNameHelper::split($elementName);
                // TODO do we need to check for resource?
                list(, $columnName) = ReferencePathHelper::splitReference($dimensionName);

                $column = $this->dataset->getColumn($dimensionName);
                if ($column->type->getReferencedDatasetName() != NULL) {
                    // this column should not be used
                    if (isset($dimensionColumnName) && $column->type->getReferencedColumnName() != $dimensionColumnName) {
                        $columnName = NULL;
                    }
                }

                break;
            case AbstractMeasureUIMetaData::NAME_SPACE:
                throw new IllegalArgumentException(t('Measures are not supported by this result formatter'));
        }

        return $columnName;
    }
    public function generate(array $possiblyLinkableDatasetNames = NULL) {
        $adjustedPossiblyLinkableDatasetNames = NULL;
        if (isset($possiblyLinkableDatasetNames)) {
            foreach ($possiblyLinkableDatasetNames as $possiblyLinkableDatasetName) {
                $adjustedPossiblyLinkableDatasetName = $this->adjustDatasetName($possiblyLinkableDatasetName);
                // we should not try to link with itself
                if ($adjustedPossiblyLinkableDatasetName == $this->primaryDatasetName) {
                    continue;
                }

                ArrayHelper::addUniqueValue($adjustedPossiblyLinkableDatasetNames, $adjustedPossiblyLinkableDatasetName);
            }
        }

        // preparing reference paths for all datasets which we need to test for possible linkage
        $referencePaths = NULL;
        if (isset($adjustedPossiblyLinkableDatasetNames)) {
            foreach ($adjustedPossiblyLinkableDatasetNames as $adjustedPossiblyLinkableDatasetName) {
                // column name should not be provided because we just try to link with the dataset
                $referencePath = ReferencePathHelper::assembleReference($adjustedPossiblyLinkableDatasetName, NULL);

                $referencePaths[$referencePath] = FALSE; // FALSE - if we cannot find link it is ok. Not everything could be connected
            }
        }

        $linkBuilder = new ReferenceLinkBuilder();
        $link = $linkBuilder->prepareReferenceBranches($this->primaryDatasetName, $referencePaths);

        return $link;
    }
    public function findHandler($datatype) {
        // checking internal cache
        if (isset($this->handlers[$datatype])) {
            return $this->handlers[$datatype];
        }

        // looking for configuration for the type
        $handlerConfiguration = isset($this->handlerConfigurations[$datatype]) ? $this->handlerConfigurations[$datatype] : NULL;
        if (!isset($handlerConfiguration)) {
            // checking if data type is a reference to lookup dataset column
            list($datasetName) = ReferencePathHelper::splitReference($datatype);
            if (isset($datasetName)) {
                $handlerConfiguration = $this->prepareHandlerConfiguration($datatype, 'LookupDatasetColumnDimensionLookupHandler');
            }
        }

        if (isset($handlerConfiguration)) {
            // initializing handler based on configuration
            $classname = $handlerConfiguration['classname'];
            $handler = new $classname($datatype);
        }
        else {
            $handler = new SimpleDimensionLookupHandler($datatype);
        }

        $this->handlers[$datatype] = $handler;

        return $handler;
    }
    final public function format(DataControllerCallContext $callcontext, AbstractRequest $request, $datasetName, $columnName, $columnDataType = NULL) {
        if (!isset($columnDataType)) {
            $metamodel = data_controller_get_metamodel();

            // trying to detect data type for the value
            list($referencedDatasetName, $referencedColumnName) = ReferencePathHelper::splitReference($columnName);
            $selectedDatasetName = isset($referencedDatasetName) ? $referencedDatasetName : $datasetName;
            $selectedColumnName = isset($referencedColumnName) ? $referencedColumnName : $columnName;
            $dataset = $metamodel->getDataset($selectedDatasetName);

            $column = $dataset->findColumn($selectedColumnName);
            // could be formula
            if (!isset($column)) {
                $column = $request->findFormula($selectedColumnName);
            }

            $columnDataType = isset($column) ? $column->type->applicationType : NULL;

            // preparing column data type based on operator parameter data type
            if (!isset($columnDataType) && ($this->operatorHandler instanceof ParameterBasedOperatorHandler)) {
                $columnDataType = $this->operatorHandler->getParameterDataType();
            }
        }

        return $this->prepareExpression($callcontext, $request, $datasetName, $columnName, $columnDataType);
    }
    protected static function prepareReferencedElementName($referencePath, $datasetName, $elementName) {
        $referencedElementName = $elementName;
        if (isset($referencePath)) {
            $nestedReference = ReferencePathHelper::assembleReference($datasetName, $elementName);
            $referencedElementName = ReferencePathHelper::assembleReferencePath(array($nestedReference, $referencePath));
        }

        return $referencedElementName;
    }
    protected function detectParameterKind(AbstractCubeQueryRequest $request, CubeMetaData $cube, $parameterName) {
        $metamodel = data_controller_get_metamodel();

        list($rootName, $leafName) = ParameterNameHelper::split($parameterName);

        list($referencedDatasetName, $referencedRootName) = ReferencePathHelper::splitReference($rootName);
        // checking that referenced cube exists
        $referencedCube = isset($referencedDatasetName)
            ? $metamodel->getCubeByDatasetName($referencedDatasetName)
            : NULL;

        $selectedCube = isset($referencedCube) ? $referencedCube : $cube;
        $selectedRequest = isset($referencedCube) ? $request->registerReferencedRequest($referencedCube->name) : $request;

        // detecting type of the parameter: dimension or measure
        $isDimension = $isMeasure = FALSE;
        if (isset($leafName)) {
            // if dimension column exists - dimension exists too :)
            $isDimension = TRUE;
        }
        else {
            // trying to find a measure
            $measure = $selectedCube->findMeasure($referencedRootName);
            if (isset($measure)) {
                $isMeasure = TRUE;
            }
            else {
                $formula = $request->findFormula($referencedRootName);
                if (isset($formula)) {
                    if (isset($formula->isMeasure) && $formula->isMeasure) {
                        $isMeasure = TRUE;
                    }
                    else {
                        $isDimension = TRUE;
                    }
                }
            }
            // trying to find a dimension
            $dimension = $selectedCube->findDimension($referencedRootName);
            if (isset($dimension)) {
                $isDimension = TRUE;
            }
        }
        if ($isDimension && $isMeasure) {
            throw new IllegalArgumentException(t(
                'The parameter refers to both a dimension and a measure: %parameterName',
                array('%parameterName' => $parameterName)));
        }

        if ($isDimension) {
            if (isset($referencedCube)) {
                throw new IllegalArgumentException(t('Referenced dimensions are not supported yet'));
            }
        }

        return array($selectedRequest, $isDimension, $isMeasure, $referencedRootName, $leafName);
    }
Ejemplo n.º 7
0
 public static function assembleDatabaseColumnName($maximumLength, $elementName, $subElementName = NULL, $elementPropertyName = NULL)
 {
     $databaseColumnName = ReferencePathHelper::generateDatabaseColumnName($elementName);
     if (isset($subElementName)) {
         $databaseColumnName .= self::$COLUMN_NAME_DELIMITER__DATABASE . strtolower($subElementName);
     }
     if (isset($elementPropertyName)) {
         $databaseColumnName .= self::$COLUMN_NAME_DELIMITER__DATABASE . strtolower($elementPropertyName);
     }
     return ParameterNameTruncater::truncateParameterName($databaseColumnName, $maximumLength);
 }
Ejemplo n.º 8
0
 protected function prepareDataType4Casting($datatype)
 {
     if (isset($datatype)) {
         list($datasetName, $columnName) = ReferencePathHelper::splitReference($datatype);
         if (isset($datasetName)) {
             $adjustedDataType = isset($this->originalDataType4ReferencedDataTypes[$datatype]) ? $this->originalDataType4ReferencedDataTypes[$datatype] : NULL;
             if (!isset($adjustedDataType)) {
                 $adjustedDataType = $this->adjustReferencedDataType4Casting($datasetName, $columnName);
                 $this->originalDataType4ReferencedDataTypes[$datatype] = $adjustedDataType;
             }
             return $adjustedDataType;
         }
     }
     return $datatype;
 }
 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 static function getExportColumnName ( $uiMetaDataName, MetaModel $metamodel ) {

        if ( trim($uiMetaDataName) == '' ) {
            $message = t('Empty columnName discovered');
            drupal_set_message($message, 'warning');
            LogHelper::log_warn($message);

            return $uiMetaDataName;
        }


        list($elementNameSpace, $name) = AbstractDatasetUIMetaDataGenerator::splitElementUIMetaDataName($uiMetaDataName);
        switch ( $elementNameSpace ) {

            case AbstractAttributeUIMetaData::NAME_SPACE:
                list($referencedDimensionName, $dimensionColumnName) = ParameterNameHelper::split($name);
                list($datasetName, $dimensionName) = ReferencePathHelper::splitReference($referencedDimensionName);
                if (isset($datasetName)) {
                    $adjustedReferencedDimensionName = ReferencePathHelper::assembleReference(self::getExportDatasetName($datasetName,$metamodel), $dimensionName);
                    $name = ParameterNameHelper::assemble($adjustedReferencedDimensionName, $dimensionColumnName);
                }
                break;

            case AbstractMeasureUIMetaData::NAME_SPACE:
                list($datasetName, $measureName) = ReferencePathHelper::splitReference($name);
                if (isset($datasetName)) {
                    $name = ReferencePathHelper::assembleReference(self::getExportDatasetName($datasetName,$metamodel), $measureName);
                }
                break;

            case FormulaUIMetaData::NAME_SPACE:
                list($datasetName, $formulaName) = ReferencePathHelper::splitReference($name);
                if (isset($datasetName)) {
                    $name = ReferencePathHelper::assembleReference(self::getExportDatasetName($datasetName,$metamodel), $formulaName);
                }
                break;

            default:
                $message = t('Unsupported UI Meta Data name space: @uiMetaDataName', array('@uiMetaDataName' => $uiMetaDataName));
                LogHelper::log_error($message);
                throw new UnsupportedOperationException($message);
        }

        return AbstractDatasetUIMetaDataGenerator::prepareElementUIMetaDataName($elementNameSpace, $name);
    }
    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;
    }
    protected static function generateFromReference($reference) {
        if (!isset($reference)) {
            return NULL;
        }

        $parts = ReferencePathHelper::splitReference($reference);

        $databaseColumnName = NULL;
        for ($i = 0, $count = count($parts); $i < $count; $i += 2) {
            $resource = $parts[$i];
            $name = $parts[$i + 1];

            $columnNameSegment = $name;
            if (isset($resource)) {
                list($namespace, $resourceName) = NameSpaceHelper::splitAlias($resource);

                $columnNameSegment .= '_';
                if (isset($namespace)) {
                    $columnNameSegment .= $namespace . '_';
                }
                $columnNameSegment .= $resourceName;
            }

            if (isset($databaseColumnName)) {
                $databaseColumnName .= '_';
            }
            $databaseColumnName .= $columnNameSegment;
        }

        // replacing non-word characters with '_'
        $databaseColumnName = preg_replace('#\W+#', '_', $databaseColumnName);
        // removing several subsequent instances of '_'
        $databaseColumnName = preg_replace('#_{2,}#', '_', $databaseColumnName);
        // fixing possibility for leading digits
        if ((strlen($databaseColumnName) > 0) && is_numeric(substr($databaseColumnName, 0, 1))) {
            $databaseColumnName = 'fix_' . $databaseColumnName;
        }

        $databaseColumnName = strtolower($databaseColumnName);

        return $databaseColumnName;
    }
 public static function containsCategory(ColumnMetaData $column, $category)
 {
     if (!isset($column->type->applicationType)) {
         return FALSE;
     }
     $type = $column->type->applicationType;
     if ($type == NumberDataTypeHandler::DATA_TYPE || $type == CurrencyDataTypeHandler::DATA_TYPE || $type == PercentDataTypeHandler::DATA_TYPE) {
         return $category == self::FACT;
     } elseif ($type == IntegerDataTypeHandler::DATA_TYPE) {
         $calculatedCategory = $column->isKey() ? self::ATTRIBUTE : self::FACT;
         // if logical application type is a reference this column is an attribute
         if ($calculatedCategory != self::ATTRIBUTE && isset($column->type->logicalApplicationType)) {
             list($referencedDatasetName) = ReferencePathHelper::splitReference($column->type->logicalApplicationType);
             if (isset($referencedDatasetName)) {
                 $calculatedCategory = self::ATTRIBUTE;
             }
         }
         return $category == $calculatedCategory;
     } else {
         return $category == self::ATTRIBUTE;
     }
 }
    public function initiateSortingConfiguration($columnName, $isSortAscending = TRUE) {
        list($rootName, $leafName) = ParameterNameHelper::split($columnName);

        $isFormula = $this->findFormula($rootName) != NULL;
        if (!$isFormula) {
            StringDataTypeHandler::checkValueAsWord($rootName);
            ReferencePathHelper::checkReference($leafName);
        }

        return new __AbstractCubeQueryRequest_SortingConfiguration($rootName, $leafName, $isSortAscending);
    }
Ejemplo n.º 15
0
 public function registerDataset(DatasetMetaData $dataset)
 {
     $this->checkAssemblingStarted();
     if (!isset($dataset->name)) {
         LogHelper::log_error($dataset);
         throw new IllegalArgumentException(t('Dataset name has not been defined'));
     }
     $datasetName = $dataset->name;
     NameSpaceHelper::checkAlias($datasetName);
     if (isset($this->datasets[$datasetName])) {
         if ($dataset->temporary) {
             unset($this->datasets[$datasetName]);
         } else {
             throw new IllegalArgumentException(t('Dataset with name @datasetName has already been defined', array('@datasetName' => $dataset->publicName)));
         }
     }
     // registering references to lookups based on column type
     foreach ($dataset->getColumns() as $column) {
         list($lookupDatasetName) = ReferencePathHelper::splitReference($column->type->applicationType);
         if (isset($lookupDatasetName)) {
             $referenceName = $lookupDatasetName;
             // FIXME it would be better if we provide the primary key (check findReferencesByDatasetName where we fix this issue)
             $this->registerSimpleReferencePoint($referenceName, $lookupDatasetName, NULL);
             $this->registerSimpleReferencePoint($referenceName, $dataset->name, $column->name);
         }
     }
     $this->datasets[$datasetName] = $dataset;
 }
    protected function prepareAttributeColumnUIMetaData(array $datasetStack, $referencePath, CubeMetaData $cube, $dimensionName, $dimensionReferencePath, DatasetMetaData $dataset = NULL, ColumnMetaData $column) {
        $dimensionColumnName = isset($dimensionReferencePath)
            ? self::prepareReferencedElementName($dimensionReferencePath, $dataset->name, $column->name)
            : $column->name;

        $attributeUIMetaData = new AttributeColumnUIMetaData();
        $attributeUIMetaData->name = self::prepareAttributeUIMetaDataName($referencePath, $cube->factsDatasetName, $dimensionName, $dimensionColumnName);
        $attributeUIMetaData->publicName = $column->publicName;
        $attributeUIMetaData->description = $column->description;
        $attributeUIMetaData->columnIndex = $column->columnIndex;
        $attributeUIMetaData->type = clone $column->type;
        $attributeUIMetaData->datasetName = $cube->factsDatasetName;

        if ($column->isKey()) {
            $attributeUIMetaData->isSelectable = FALSE;
        }

        if (!$column->isUsed()) {
            $attributeUIMetaData->isSelectable = FALSE;
        }

        if (!$column->isKey()) {
            $this->prepareAttributeColumnUIMetaData4ColumnBranch($datasetStack, $attributeUIMetaData, $referencePath, $cube, $dimensionName, $dimensionReferencePath, $dataset, $column);
        }

        list($referencedDatasetName) = ReferencePathHelper::splitReference($column->type->getLogicalApplicationType());
        if (isset($referencedDatasetName)) {
            $branchReferencePath = NULL;
            if (isset($dataset)) {
                $branchReferencePath = isset($dimensionReferencePath)
                    ? self::prepareReferencedElementName($dimensionReferencePath, $dataset->name, $column->name)
                    : ReferencePathHelper::assembleReference($dataset->name, $column->name);
            }
            $this->generateColumnUIMetaData4DimensionDataset(
                $datasetStack, $attributeUIMetaData, $referencePath, $cube, $dimensionName, $branchReferencePath, $referencedDatasetName);
        }

        return $attributeUIMetaData;
    }
    protected function findColumnTableByReferencePath($referencePath) {
        $tableCount = count($this->tables);

        $references = ReferencePathHelper::splitReferencePath($referencePath);
        $references = array_reverse($references);

        $tableIndex = NULL;
        for ($i = 0, $refcount = count($references); $i < $refcount - 1; $i++) {
            $reference = $references[$i];
            list($referencedDatasetName, $referencedColumnName) = ReferencePathHelper::splitReference($reference);
            if (!isset($referencedDatasetName)) {
                continue;
            }

            $nextReference = $references[$i + 1];
            list($nextReferencedDatasetName, $nextReferencedColumnName) = ReferencePathHelper::splitReference($nextReference);
            if (!isset($nextReferencedDatasetName)) {
                continue;
            }

            $branchIndex = NULL;
            for ($j = (isset($tableIndex) ? $tableIndex : 0); $j < $tableCount; $j++) {
                $table = $this->tables[$j];
                if ($table->dataset->name == $referencedDatasetName) {
                    for ($k = $j + 1; $k < $tableCount; $k++) {
                        $nextTable = $this->tables[$k];
                        if (($nextTable->dataset->name == $nextReferencedDatasetName)
                                && ($nextTable->conditions[0]->joinValue->tableAlias == $table->alias)
                                && ($nextTable->conditions[0]->joinValue->columnName == $referencedColumnName)) {
                            $branchIndex = $k;
                            break 2;
                        }
                    }
                }
            }
            if (!isset($branchIndex)) {
                return NULL;
            }
            $tableIndex = $branchIndex;
        }

        return isset($tableIndex) ? $this->tables[$tableIndex] : NULL;
    }
    public function addColumn($column) {
        $isFormula = $this->findFormula($column) != NULL;
        ReferencePathHelper::checkReference($column, TRUE, !$isFormula);

        ArrayHelper::addUniqueValue($this->columns, $column);
    }
    public function initiateSortingConfiguration($columnName, $isSortAscending = TRUE) {
        $isFormula = $this->findFormula($columnName) != NULL;
        ReferencePathHelper::checkReference($columnName, TRUE, !$isFormula);

        return new ColumnBasedComparator_DefaultSortingConfiguration($columnName, $isSortAscending);
    }
    public function registerDataset(DatasetMetaData $dataset) {
        $this->checkAssemblingStarted();

        if (!isset($dataset->name)) {
            LogHelper::log_debug($dataset);
            throw new IllegalArgumentException(t('Dataset name has not been defined'));
        }
        $datasetName = $dataset->name;
        NameSpaceHelper::checkAlias($datasetName);

        $existingDataset = $this->findDataset($datasetName, TRUE);
        if (isset($existingDataset)) {
            if ($dataset->isTemporary()) {
                $this->unregisterDataset($datasetName);
            }
            else {
                LogHelper::log_debug($existingDataset);
                LogHelper::log_debug($dataset);
                throw new IllegalArgumentException(t(
                    'Dataset with name %datasetName has already been defined',
                    array('%datasetName' => $dataset->publicName)));
            }
        }

        // registering references to lookups based on column type
        foreach ($dataset->getColumns() as $column) {
            $lookupDatasetName = $column->type->getReferencedDatasetName();
            if (isset($lookupDatasetName)) {
                $referenceName = $lookupDatasetName;
                // FIXME it would be better if we provide the primary key (check findReferencesByDatasetName where we fix this issue)
                $this->registerSimpleReferencePoint($referenceName, $lookupDatasetName, /* Primary Key */ NULL);
                $this->registerSimpleReferencePoint($referenceName, $dataset->name, $column->name);
            }

            if (isset($column->type->logicalApplicationType)) {
                list($refDatasetName, $refColumnName) = ReferencePathHelper::splitReference($column->type->logicalApplicationType);
                if (isset($refDatasetName)) {
                    $referenceName = $refDatasetName;
                    // FIXME it would be better if we provide the primary key (check findReferencesByDatasetName where we fix this issue)
                    $this->registerSimpleReferencePoint($referenceName, $refDatasetName, /* Primary Key */ NULL);
                    $this->registerSimpleReferencePoint($referenceName, $dataset->name, $column->name);
                }
            }
        }

        $this->datasets[$datasetName] = $dataset;
    }
Ejemplo n.º 21
0
 public function addColumn($column)
 {
     ReferencePathHelper::checkReference($column);
     ArrayHelper::addUniqueValue($this->columns, $column);
 }
    public function generateStatement(AbstractSQLDataSourceQueryHandler $datasourceHandler, DataControllerCallContext $callcontext, AbstractCubeQueryRequest $request) {
        $statement = $this->prepareSelectedCubeQueryStatement($datasourceHandler, $callcontext, $request);
        if (!isset($request->referencedRequests)) {
            return $statement;
        }

        $combinedStatement = new Statement();

        $metamodel = data_controller_get_metamodel();

        $cubeName = $request->getCubeName();
        $cube = $metamodel->getCube($cubeName);

        $datasetMappedCubeRequests = array($cube->factsDatasetName => $request);

        // preparing list of reference paths
        $referencePaths = NULL;
        foreach ($request->referencedRequests as $referencedRequest) {
            $referencedCubeName = $referencedRequest->getCubeName();
            $referencedCube = $metamodel->getCube($referencedCubeName);
            $referencedDatasetName = $referencedCube->factsDatasetName;

            $referencePath = ReferencePathHelper::assembleReference($referencedDatasetName, NULL);
            $referencePaths[$referencePath] = TRUE; // TRUE - required reference

            $datasetMappedCubeRequests[$referencedDatasetName] = $referencedRequest;
        }

        // finding ways to link the referenced cubes
        $linkBuilder = new ReferenceLinkBuilder();
        $link = $linkBuilder->prepareReferenceBranches($cube->factsDatasetName, $referencePaths);

        // preparing primary cube aggregation statement
        list($isSubqueryRequired, $assembledPrimaryCubeAggregationSections) = $statement->prepareSections(NULL);
        $primaryCubeAggregationTableSection = new SubquerySection(
            Statement::assemble($isSubqueryRequired, NULL, $assembledPrimaryCubeAggregationSections, SelectStatementPrint::INDENT__SUBQUERY, FALSE),
            self::$TABLE_ALIAS__REFERENCED . $link->linkId);

        // adding columns which are returned by primary aggregation
        foreach ($statement->tables as $table) {
            if (!isset($table->columns)) {
                continue;
            }

            foreach ($table->columns as $column) {
                if (!$column->visible) {
                    continue;
                }

                $primaryCubeAggregationTableSection->columns[] = new ColumnSection($column->alias);
            }
        }

        // registering primary cube statement in resulting statement
        $combinedStatement->tables[] = $primaryCubeAggregationTableSection;

        $this->prepareReferencedCubeQueryStatement($datasourceHandler, $callcontext, $combinedStatement, $datasetMappedCubeRequests, $link);

        return $combinedStatement;
    }
    public function assembleColumnName($tableAlias) {
        $selectedTableAlias = $this->tableAlias;

        if (isset($selectedTableAlias)) {
            if (isset($tableAlias) && ($selectedTableAlias != $tableAlias)) {
                throw new UnsupportedOperationException();
            }
        }
        else {
            $this->tableAlias = $tableAlias;
            $selectedTableAlias = $tableAlias;
        }

        list(, $columnName) = ReferencePathHelper::splitReference($this->name);

        return ColumnNameHelper::combineColumnName($selectedTableAlias, $columnName);
    }
    protected function detectRoutes(ReferenceLink $rootLink, array $referencePaths) {
        $routeId = 0;
        foreach ($referencePaths as $referencePath => $required) {
            // preparing possible routes
            $referenceRoutes = $rootLink->prepareRoutes($referencePath);

            // selecting 'the best' route
            $selectedRoute = NULL;
            if (isset($referenceRoutes)) {
                foreach ($referenceRoutes as $directReferenceFlag => $routes) {
                    foreach ($routes as $route) {
                        if (!isset($selectedRoute) || ($selectedRoute->weight > $route->weight)) {
                            $selectedRoute = $route;
                        }
                    }
                }
            }

            if (isset($selectedRoute)) {
                $rootLink->assignRouteId($selectedRoute, $routeId);
                $routeId++;
            }
            elseif ($required) {
                $metamodel = data_controller_get_metamodel();

                LogHelper::log_error(t('Could not execute reference path: @referencePath', array('@referencePath' => $referencePath)));

                list($referencedDatasetName) = ReferencePathHelper::splitReference($referencePath);
                $referencedDataset = $metamodel->getDataset($referencedDatasetName);

                throw new IllegalArgumentException(t(
                    '%datasetNameA and %datasetNameB datasets are not connected',
                    array('%datasetNameA' => $rootLink->dataset->publicName, '%datasetNameB' => $referencedDataset->publicName)));
            }
        }
    }
 protected function prepareColumnDatabaseType(DataSourceHandler $handler, ColumnMetaData $column)
 {
     if (isset($column->type->applicationType)) {
         $storageDataType = NULL;
         list($datasetName) = ReferencePathHelper::splitReference($column->type->applicationType);
         if (isset($datasetName)) {
             $storageDataType = Sequence::getSequenceColumnType()->applicationType;
         } else {
             $datatypeHandler = DataTypeFactory::getInstance()->getHandler($column->type->applicationType);
             $storageDataType = $datatypeHandler->getStorageDataType();
         }
         switch ($storageDataType) {
             case StringDataTypeHandler::$DATA_TYPE:
                 break;
             case IntegerDataTypeHandler::$DATA_TYPE:
                 $this->prepareInteger($column);
                 break;
             case NumberDataTypeHandler::$DATA_TYPE:
             case CurrencyDataTypeHandler::$DATA_TYPE:
             case PercentDataTypeHandler::$DATA_TYPE:
                 $this->prepareNumber($column);
                 break;
             case BooleanDataTypeHandler::$DATA_TYPE:
                 // calculating length of mapping of TRUE and FALSE values
                 $valueTrue = $handler->castValue(BooleanDataTypeHandler::$DATA_TYPE, TRUE);
                 $valueFalse = $handler->castValue(BooleanDataTypeHandler::$DATA_TYPE, FALSE);
                 // length of the field depends on length of the mappings
                 $lengthValueTrue = strlen($valueTrue);
                 $lengthValueFalse = strlen($valueFalse);
                 $length = MathHelper::max($lengthValueTrue, $lengthValueFalse);
                 // detecting type for each value and selecting primary type
                 $datatype = DataTypeFactory::getInstance()->selectDataType(array(DataTypeFactory::getInstance()->autoDetectDataType($valueTrue), DataTypeFactory::getInstance()->autoDetectDataType($valueFalse)));
                 // for numeric values we use integer storage type, for rest - string
                 if ($datatype === IntegerDataTypeHandler::$DATA_TYPE) {
                     $this->prepareInteger($column, $length);
                 } elseif ($lengthValueTrue === $lengthValueFalse) {
                     $this->prepareFixedLengthString($column, $length);
                 } else {
                     $this->prepareVariableLengthString($column, $length);
                 }
                 break;
             case DateTimeDataTypeHandler::$DATA_TYPE:
                 $this->prepareDate($column, TRUE, TRUE);
                 break;
             case DateDataTypeHandler::$DATA_TYPE:
                 $this->prepareDate($column);
                 break;
             case TimeDataTypeHandler::$DATA_TYPE:
                 $this->prepareDate($column, FALSE, TRUE);
                 break;
             default:
                 throw new UnsupportedOperationException(t("Unsupported data type for '@columnName' column: @columnType", array('@columnName' => $column->publicName, '@columnType' => $column->type->applicationType)));
         }
     }
     if (!isset($column->type->databaseType)) {
         $this->prepareVariableLengthString($column);
     }
     return $column->type->databaseType;
 }
    protected static function prepareListColumnMappings(array $cubes = NULL, array $parsedUIMetaDataNames) {
        $columnMappings = NULL;

        foreach ($parsedUIMetaDataNames as $columnName => $parsedUIMetaDataName) {
            $datasetColumnName = NULL;
            if ($parsedUIMetaDataName instanceof AttributeParsedUIMetaDataName) {
                $cube = isset($cubes[$parsedUIMetaDataName->datasetName]) ? $cubes[$parsedUIMetaDataName->datasetName] : NULL;
                if (isset($cube)) {
                    $dimension = $cube->getDimension($parsedUIMetaDataName->name);

                    $references = NULL;
                    if (isset($parsedUIMetaDataName->columnName)) {
                        $column = $cube->factsDataset->getColumn($dimension->attributeColumnName);
                        $branch = $column->findBranch($parsedUIMetaDataName->columnName);
                        // the dimension column can be a branch, not a dimension dataset column
                        if (!isset($branch) && isset($dimension->datasetName)) {
                            list($adjustedDimensionDatasetName) = gd_data_controller_metamodel_adjust_dataset_name($dimension->datasetName);
                            $references[] = ReferencePathHelper::assembleReference($adjustedDimensionDatasetName, $parsedUIMetaDataName->columnName);
                        }
                    }

                    if (isset($references)) {
                        $references[] = ReferencePathHelper::assembleReference($cube->factsDatasetName, $dimension->attributeColumnName);
                        $datasetColumnName = ReferencePathHelper::assembleReferencePath($references);
                    }
                    else {
                        $datasetColumnName = isset($parsedUIMetaDataName->columnName)
                            ? $parsedUIMetaDataName->columnName
                            : $dimension->attributeColumnName;
                    }
                }
                else {
                    $datasetColumnName = $parsedUIMetaDataName->name;
                }
            }
            elseif ($parsedUIMetaDataName instanceof FormulaAttributeParsedUIMetaDataName) {
                $datasetColumnName = $parsedUIMetaDataName->name;
            }
            elseif ($parsedUIMetaDataName instanceof FormulaMeasureParsedUIMetaDataName) {
                $datasetColumnName = $parsedUIMetaDataName->name;
            }

            if (isset($datasetColumnName)) {
                $columnMappings[$columnName] = $datasetColumnName;
            }
        }

        return $columnMappings;
    }
    /**
     * @param $referencePath
     * @param null $parentColumnName
     * @return ReferenceRoute[]
     */
    public function prepareRoutes($referencePath, $parentColumnName = NULL) {
        $routes = NULL;

        $referenceParts = ReferencePathHelper::splitReference($referencePath);

        $columnName = array_pop($referenceParts);
        $datasetName = array_pop($referenceParts);

        // checking that dataset is the same and parent column name is the same
        $isReferenceFound = ($this->dataset->name == $datasetName)
            && (!isset($parentColumnName) || in_array($parentColumnName, $this->parentColumnNames));

        $nestedReferencePath = $isReferenceFound
            ? ReferencePathHelper::assembleReferenceParts($referenceParts)
            : $referencePath; // it is possible that not full execution path is provided

        if (isset($nestedReferencePath)) {
            if (isset($this->nestedLinks)) {
                $nestedRoutes = NULL;
                foreach ($this->nestedLinks as $nestedLink) {
                    $nestedLinkRoutes = $nestedLink->prepareRoutes($nestedReferencePath, ($isReferenceFound ? $columnName : NULL));
                    if (isset($nestedLinkRoutes)) {
                        // current reference could not be found. We mark nested found reference as not direct
                        if (!$isReferenceFound && isset($nestedLinkRoutes[TRUE])) {
                            $adjustedNestedLinkRoutes = NULL;
                            $adjustedNestedLinkRoutes[FALSE] = $nestedLinkRoutes[TRUE];
                            $nestedRoutes[] = $adjustedNestedLinkRoutes;
                        }
                        else {
                            $nestedRoutes[] = $nestedLinkRoutes;
                        }
                    }
                }

                if (isset($nestedRoutes)) {
                    // checking if we found direct route
                    $isNestedReferenceFound = FALSE;
                    foreach ($nestedRoutes as $nestedLinkRoutes) {
                        if (isset($nestedLinkRoutes[TRUE])) {
                            $isNestedReferenceFound = TRUE;
                            break;
                        }
                    }

                    foreach ($nestedRoutes as $nestedLinkRoutes) {
                        if (!isset($nestedLinkRoutes[$isNestedReferenceFound])) {
                            continue;
                        }

                        foreach ($nestedLinkRoutes[$isNestedReferenceFound] as $nestedLinkRoute) {
                            $route = new ReferenceRoute($this->linkId, $this->weight);
                            $route->combineFrom($nestedLinkRoute);

                            $routes[$isNestedReferenceFound][] = $route;
                        }
                    }
                }
            }
        }
        elseif ($isReferenceFound) {
            $routes[$isReferenceFound][] = new ReferenceRoute($this->linkId, $this->weight);
        }

        return $routes;
    }
    public function addQueryValue($index, $name, $value) {
        $isFormula = $this->findFormula($name) != NULL;
        ReferencePathHelper::checkReference($name, TRUE, !$isFormula);

        $this->queries[$index][$name][] = $value;
    }
    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)));
    }
 protected function assembleConnectedDatasetSourceStatement(DataControllerCallContext $callcontext, ReferenceLink $link, array $columnNames, array $linkExecutionStack = NULL)
 {
     $TABLE_ALIAS__LINK = 'l';
     $nestedLinkExecutionStack = $linkExecutionStack;
     $nestedLinkExecutionStack[] = $link;
     $selectedColumnNames = ReferenceLinkBuilder::selectReferencedColumnNames4ReferenceLink($nestedLinkExecutionStack, $columnNames);
     $linkTableAliasPrefix = $TABLE_ALIAS__LINK . $link->linkId;
     $statement = $this->assembleDatasetSourceStatement($callcontext, $link->dataset, $selectedColumnNames);
     $statement->addTableAliasPrefix($linkTableAliasPrefix);
     // adding columns which we use to join with parent dataset
     if (!$link->isRoot()) {
         foreach ($link->columnNames as $columnName) {
             $joinColumnAlias = ReferencePathHelper::assembleDatabaseColumnName($this->getMaximumEntityNameLength(), ReferencePathHelper::assembleReference($link->dataset->name, $columnName));
             $joinTable = $statement->findColumnTable($columnName);
             if (!isset($joinTable)) {
                 $joinTable = $statement->tables[0];
             }
             $joinColumn = $joinTable->findColumnByAlias($joinColumnAlias);
             if (!isset($joinColumn)) {
                 $joinTable->columns[] = new ColumnSection($columnName, $joinColumnAlias);
             }
         }
     }
     // adding columns which we use to join with nested datasets
     if (isset($link->nestedLinks)) {
         foreach ($link->nestedLinks as $nestedLink) {
             foreach ($nestedLink->parentColumnNames as $parentColumnName) {
                 $parentColumnAlias = ReferencePathHelper::assembleDatabaseColumnName($this->getMaximumEntityNameLength(), ReferencePathHelper::assembleReference($link->dataset->name, $parentColumnName));
                 $joinTable = $statement->getColumnTable($parentColumnName);
                 $joinColumn = $joinTable->findColumnByAlias($parentColumnAlias);
                 if (!isset($joinColumn)) {
                     $joinTable->columns[] = new ColumnSection($parentColumnName, $parentColumnAlias);
                 }
             }
         }
     }
     // collecting columns which we need to mark as invisible
     $shouldBeInvisibleColumns = NULL;
     foreach ($statement->tables as $table) {
         if (isset($table->columns)) {
             foreach ($table->columns as $column) {
                 $shouldBeInvisibleColumns[$table->alias][$column->alias] = $column;
             }
         } else {
             $table->columns = array();
             // We do not need any columns
         }
     }
     // adding or making as visible columns which we need to return
     if (isset($selectedColumnNames)) {
         foreach ($selectedColumnNames as $originalColumnName => $selectedColumnName) {
             // we need to show only those columns which are requested.
             // All intermediate columns (which are used to link with nested datasets) will not be shown
             if (array_search($originalColumnName, $columnNames) !== FALSE) {
                 $databaseColumnName = ReferencePathHelper::assembleDatabaseColumnName($this->getMaximumEntityNameLength(), $originalColumnName);
                 $table = $statement->getColumnTable($selectedColumnName, TRUE);
                 $column = $table->findColumnByAlias($databaseColumnName);
                 if (isset($column)) {
                     $column->visible = TRUE;
                     unset($shouldBeInvisibleColumns[$table->alias][$column->alias]);
                 } else {
                     $column = $table->findColumnByAlias($selectedColumnName);
                     if (isset($column)) {
                         // adding clone of the same column with another alias
                         $column = clone $column;
                         $column->visible = TRUE;
                         $column->alias = $databaseColumnName;
                     } else {
                         $column = new ColumnSection($selectedColumnName, $databaseColumnName);
                     }
                     $table->columns[] = $column;
                 }
                 $callcontext->columnMapping[$databaseColumnName] = $originalColumnName;
             }
         }
     }
     if (isset($shouldBeInvisibleColumns)) {
         foreach ($shouldBeInvisibleColumns as $tableColumns) {
             foreach ($tableColumns as $column) {
                 $column->visible = FALSE;
             }
         }
     }
     // supporting nested links
     if (isset($link->nestedLinks)) {
         foreach ($link->nestedLinks as $nestedLink) {
             $nestedStatement = $this->assembleConnectedDatasetSourceStatement($callcontext, $nestedLink, $columnNames, $nestedLinkExecutionStack);
             foreach ($nestedLink->parentColumnNames as $referencePointColumnIndex => $parentColumnName) {
                 // preparing parent table alias
                 $parentColumnAlias = ReferencePathHelper::assembleDatabaseColumnName($this->getMaximumEntityNameLength(), ReferencePathHelper::assembleReference($link->dataset->name, $parentColumnName));
                 $parentTableAlias = $statement->getColumnTable($parentColumnAlias)->alias;
                 // linking with parent
                 $nestedColumnName = $nestedLink->columnNames[$referencePointColumnIndex];
                 $nestedColumnAlias = ReferencePathHelper::assembleDatabaseColumnName($this->getMaximumEntityNameLength(), ReferencePathHelper::assembleReference($nestedLink->dataset->name, $nestedColumnName));
                 $nestedStatement->getColumnTable($nestedColumnAlias)->conditions[] = new JoinConditionSection($nestedColumnName, new TableColumnConditionSectionValue($parentTableAlias, $parentColumnName));
             }
             $statement->merge($nestedStatement);
         }
     }
     return $statement;
 }