public static function initializeDimensionFromColumn(MetaModel $metamodel, CubeMetaData $cube, DatasetMetaData $dataset, $columnName)
 {
     $logicalColumn = $dataset->getColumn($columnName);
     if ($logicalColumn->isVisible()) {
         // preparing dimension
         $dimension = $cube->registerDimension($logicalColumn->name);
         $dimension->publicName = $logicalColumn->publicName;
         $dimension->description = $logicalColumn->description;
         $handler = DimensionLookupFactory::getInstance()->getHandler($logicalColumn->type->getLogicalApplicationType());
         $handler->prepareDimension($metamodel, $dataset, $logicalColumn->name, $cube);
         $dimension->used = $logicalColumn->used;
         // ********** adding measure which counts unique values
         $attributeName = ParameterNameHelper::assemble($dimension->name);
         // adding measure
         $measureName = StarSchemaNamingConvention::getAttributeRelatedMeasureName($attributeName, StarSchemaNamingConvention::$MEASURE_NAME_SUFFIX__DISTINCT_COUNT);
         $measure = $cube->registerMeasure($measureName);
         $measure->publicName = t("Distinct count for '@columnName' column", array('@columnName' => $logicalColumn->publicName));
         $measure->description = t("System generated measure for '@columnName' column to count distinct values", array('@columnName' => $logicalColumn->publicName));
         $measure->additivity = MeasureAdditivity::NON_ADDITIVE;
         $measure->type->applicationType = IntegerDataTypeHandler::DATA_TYPE;
         $measure->used = $logicalColumn->used;
         // preparing expression
         $formulaExpressionParser = new FormulaExpressionParser(SQLFormulaExpressionHandler::LANGUAGE__SQL);
         $measure->function = 'COUNT(DISTINCT ' . $formulaExpressionParser->assemble($logicalColumn->name) . ')';
     }
 }
 protected function useApplicableCubeRegions(CubeQueryRequest $request, CubeMetaData $cube)
 {
     $metamodel = data_controller_get_metamodel();
     if (!isset($cube->regions)) {
         return;
     }
     // FIXME add support for measures in query list. Selected region needs to suport not only returning measures but also querying onces
     $isExactMatchRequired = FALSE;
     if (isset($request->measures)) {
         foreach ($request->measures as $requestMeasure) {
             $measureName = $requestMeasure->measureName;
             $cubeMeasure = $cube->findMeasure($measureName);
             if (isset($cubeMeasure) && isset($cubeMeasure->aggregationType)) {
                 switch ($cubeMeasure->aggregationType) {
                     case MeasureTypes::ADDITIVE:
                         break;
                     case MeasureTypes::SEMI_ADDITIVE:
                     case MeasureTypes::NON_ADDITIVE:
                         $isExactMatchRequired = TRUE;
                         break;
                     default:
                         throw new UnsupportedOperationException(t('Unsupported measure aggregation type: @measureAggregationType', array('@measureAggregationType' => $cubeMeasure->aggregationType)));
                 }
             }
         }
     }
     // collecting possible eligible regions
     $eligibleRegionNames = NULL;
     foreach ($cube->regions as $regionName => $region) {
         // checking if the region supports all requested measures
         if (isset($request->measures)) {
             foreach ($request->measures as $requestMeasure) {
                 if (!isset($region->measures[$requestMeasure->measureName])) {
                     continue 2;
                 }
             }
         }
         $eligibleRegionNames[] = $regionName;
     }
     if (!isset($eligibleRegionNames)) {
         return;
     }
     // filtering eligible regions based on requested or queried dimensions
     if (isset($request->dimensions)) {
         $this->excludeIneligibleRegions($cube, $eligibleRegionNames, $request->dimensions, $isExactMatchRequired);
     }
     if (isset($request->queries)) {
         $this->excludeIneligibleRegions($cube, $eligibleRegionNames, $request->queries, $isExactMatchRequired);
     }
     // do we still have any regions which could be used for the request
     if (count($eligibleRegionNames) === 0) {
         return;
     }
     // we select first region suitable for the request
     $selectedRegionName = reset($eligibleRegionNames);
     $selectedRegion = $cube->regions->{$selectedRegionName};
     // preparing new cube configuration
     $regionCube = new CubeMetaData();
     $regionCube->name = "{$cube->name}_using_{$selectedRegionName}_region";
     // source dataset
     $regionCube->sourceDatasetName = $selectedRegion->datasetName;
     // dimensions
     if (isset($cube->dimensions)) {
         foreach ($cube->dimensions as $dimension) {
             $dimensionName = $dimension->name;
             if (!isset($selectedRegion->dimensions->{$dimensionName})) {
                 continue;
             }
             $regionCubeDimension = $regionCube->registerDimension($dimensionName);
             $selectedRegionDimension = $selectedRegion->dimensions->{$dimensionName};
             if (isset($selectedRegionDimension->levels)) {
                 // we need to prepare new dimension which contains levels which are supported by this region
                 $sourceLevel = NULL;
                 $isSelectedLevelFound = FALSE;
                 foreach ($dimension->levels as $level) {
                     $levelName = $level->name;
                     if (!$isSelectedLevelFound && isset($level->sourceColumnName)) {
                         $sourceLevel = $level;
                     }
                     $isLevelPresent = isset($selectedRegionDimension->levels->{$levelName});
                     if ($isLevelPresent) {
                         if ($isSelectedLevelFound) {
                             throw new UnsupportedOperationException(t("Only one level is supported yet for each dimension in '@selectedRegionName' region of '@cubeName' cube", array('@selectedRegionName' => $selectedRegionName, '@cubeName' => $cube->publicName)));
                         }
                         $isSelectedLevelFound = TRUE;
                     }
                     if ($isSelectedLevelFound) {
                         $regionLevel = $regionCubeDimension->registerLevel($levelName);
                         $regionLevel->initializeFrom($level);
                         if ($isLevelPresent) {
                             $regionLevel->sourceColumnName = $sourceLevel->sourceColumnName;
                         } elseif (isset($regionLevel->sourceColumnName)) {
                             // we cannot support source key on consecutive levels. It is only supported for 'virtual' cubes
                             unset($regionLevel->sourceColumnName);
                         }
                     }
                 }
             } else {
                 $regionCubeDimension->initializeFrom($dimension);
             }
         }
     }
     // measures
     if (isset($request->measures)) {
         foreach ($request->measures as $requestMeasure) {
             $measureName = $requestMeasure->measureName;
             $cubeMeasure = $cube->getMeasure($measureName);
             $regionMeasure = $regionCube->registerMeasure($measureName);
             $regionMeasure->initializeFrom($cubeMeasure);
         }
     }
     // FIXME the following code will throw an exception if we try to reuse the same region during execution of a PHP script
     // registering the cube in meta model
     $regionCube->temporary = TRUE;
     // FIXME when loading meta model automatically create cubes for all regions
     $metamodel->registerCube($regionCube);
     // updating the request to use new cube
     LogHelper::log_notice(t("Using '@selectedRegionName' region of '@cubeName' cube", array('@selectedRegionName' => $selectedRegionName, '@cubeName' => $cube->name)));
     LogHelper::log_info(t('Creating temporary cube to satisfy this request: @regionCubeName', array('@regionCubeName' => $regionCube->name)));
     // FIXME create new request and delete the following method in request class
     $request->setCubeName($regionCube->name);
 }