protected function prepareExpression(DataControllerCallContext $callcontext, AbstractRequest $request, $datasetName, $columnName, $columnDataType) { $boundaryValue = $this->prepareBoundaryValue($callcontext, $request, $datasetName, $columnName, $columnDataType); $operator = OperatorFactory::getInstance()->initiateHandler(EqualOperatorHandler::$OPERATOR__NAME, $boundaryValue); $sqlOperatorHandler = SQLOperatorFactory::getInstance()->getHandler($this->datasourceHandler, $operator); return $sqlOperatorHandler->format($callcontext, $request, $datasetName, $columnName, $columnDataType); }
protected function adjustCompositeParameter($compositeParameter) { $adjustedCompositeParameter = NULL; $parameterIndex = 0; foreach ($compositeParameter as $key => $value) { $adjustedKey = is_string($key) ? StringHelper::trim($key) : $key; $adjustedValues = NULL; if ($value instanceof OperatorHandler) { // we do not need to change anything for the value $adjustedValues[] = $value; } else { // what if the value is a list of operators $operatorFound = FALSE; if (is_array($value)) { foreach ($value as $v) { if ($v instanceof OperatorHandler) { $operatorFound = TRUE; break; } } } // we found at least one operator in the list if ($operatorFound) { foreach ($value as $index => $v) { $adjustedIndex = is_string($index) ? StringHelper::trim($index) : $index; $adjustedValue = ($v instanceof OperatorHandler) ? $v : OperatorFactory::getInstance()->initiateHandler(EqualOperatorHandler::OPERATOR__NAME, array($v)); $adjustedValue->weight = $parameterIndex++; $adjustedValues[$adjustedIndex] = $adjustedValue; } } else { $adjustedValue = OperatorFactory::getInstance()->initiateHandler(EqualOperatorHandler::OPERATOR__NAME, array($value)); $adjustedValue->weight = $parameterIndex++; $adjustedValues[] = $adjustedValue; } } $adjustedCompositeParameter[$adjustedKey] = $adjustedValues; } return $adjustedCompositeParameter; }
protected function getLatestValue(DataControllerCallContext $callcontext, AbstractRequest $request, $datasetName, $columnName) { $latestValue = NULL; if ($this->operatorHandler->wasValueCalculated(self::$OPERATOR_VARIABLE_NAME__LATEST)) { $latestValue = $this->operatorHandler->getCalculatedValue(self::$OPERATOR_VARIABLE_NAME__LATEST); } else { $operator = OperatorFactory::getInstance()->initiateHandler($this->getLatestOperatorName()); $sqlOperatorHandler = SQLOperatorFactory::getInstance()->getHandler($this->datasourceHandler, $operator); $latestValue = $sqlOperatorHandler->prepareBoundaryValue($callcontext, $request, $datasetName, $columnName); // storing into internal cache for further usage $this->operatorHandler->setCalculatedValue(self::$OPERATOR_VARIABLE_NAME__LATEST, $latestValue); } return $latestValue; }
protected function selectBoundary4CubeRequest(DataControllerCallContext $callcontext, AbstractCubeQueryRequest $request, $datasetName, $columnName) { $isSortAscending = $this->isSortAscending(); $resultColumnName = NULL; // preparing new cube meta data $expressionRequest = new CubeQueryRequest($request->getCubeName()); // needs to be called before any additional methods are called $expressionRequest->addOptions($request->options); // copying ONLY some query objects (excluding at least a reference to this operator) // -- dimension queries $dimensionQueries = $request->findDimensionQueries(); if (isset($dimensionQueries)) { foreach ($dimensionQueries as $query) { foreach ($query->columns as $queryColumn) { foreach ($queryColumn->values as $value) { if ($this->shouldValueBeSkipped($value)) { continue; } // updating request configuration for the value supported by this class if ($this->operatorHandler === $value) { $resultColumnName = ParameterNameHelper::assemble($query->name, $queryColumn->name); // returning only observing column of the dimension $expressionRequest->addDimensionColumn(0, $query->name, $queryColumn->name); // ... and excluding NULL values from evaluation $expressionRequest->addDimensionColumnQueryValue( $query->name, $queryColumn->name, OperatorFactory::getInstance()->initiateHandler(NotEqualOperatorHandler::OPERATOR__NAME, NULL)); // sorting data $expressionRequest->addOrderByColumn( ColumnBasedComparator_AbstractSortingConfiguration::assembleDirectionalColumnName($resultColumnName, $isSortAscending)); } else { $expressionRequest->addDimensionColumnQueryValue($query->name, $queryColumn->name, $value); } } } } } // -- facts dataset column queries $factsDatasetColumnQueries = $request->findFactsDatasetColumnQueries(); if (isset($factsDatasetColumnQueries)) { foreach ($factsDatasetColumnQueries as $query) { $values = NULL; foreach ($query->values as $value) { if ($this->shouldValueBeSkipped($value)) { continue; } if ($this->operatorHandler === $value) { $metamodel = data_controller_get_metamodel(); $cube = $metamodel->getCube($expressionRequest->getCubeName()); // finding dimension associated with this fact column $selectedDimension = NULL; if (isset($cube->dimensions)) { foreach ($cube->dimensions as $dimension) { if ($dimension->attributeColumnName == $query->name) { $selectedDimension = $dimension; break; } } } if (!isset($selectedDimension)) { throw new IllegalArgumentException(t( 'Boundary-related operator cannot be applied to the facts dataset column: %columnName', array('%columnName' => $query->name))); } $resultColumnName = ParameterNameHelper::assemble($selectedDimension->name); // returning only observing column from facts dataset $expressionRequest->addDimension(0, $selectedDimension->name); // ... and excluding NULL values from evaluation $expressionRequest->addFactsDatasetColumnQueryValue( $query->name, OperatorFactory::getInstance()->initiateHandler(NotEqualOperatorHandler::OPERATOR__NAME, NULL)); // sorting data $expressionRequest->addOrderByColumn( ColumnBasedComparator_AbstractSortingConfiguration::assembleDirectionalColumnName($resultColumnName, $isSortAscending)); } else { $values[] = $value; } } if (isset($values)) { $expressionRequest->addFactsDatasetColumnQueryValues($query->name, $values); } } } // -- measure queries $measureQueries = $request->findMeasureQueries(); if (isset($measureQueries)) { foreach ($measureQueries as $query) { foreach ($query->values as $value) { if ($this->shouldValueBeSkipped($value)) { throw new IllegalArgumentException(t('Boundary-related operator cannot be applied to measures')); } } $expressionRequest->queries[] = clone $query; } } // limiting response to one record $expressionRequest->setPagination(1, 0); return $this->processCubeExpressionRequest($callcontext, $expressionRequest, $resultColumnName); }
public static function parseParameters(array $parameters = NULL) { if (!isset($parameters)) { return NULL; } $adjustedParameters = NULL; foreach ($parameters as $parameterIndex => $parameterProperties) { if (!is_array($parameterProperties)) { $parameterProperties = array($parameterProperties); } $isParameterPropertyDetected = FALSE; $parameterName = NULL; if (is_int($parameterIndex)) { if (!isset($parameterProperties[self::$QUERY_PARAMETER__COLUMN_NAME])) { throw new IllegalArgumentException(t('Could not find corresponding column name for the parameter: @parameterIndex', array('@parameterIndex' => $parameterIndex))); } $parameterName = $parameterProperties[self::$QUERY_PARAMETER__COLUMN_NAME]; unset($parameterProperties[self::$QUERY_PARAMETER__COLUMN_NAME]); $isParameterPropertyDetected = TRUE; } else { $parameterName = $parameterIndex; } $operatorName = NULL; if (isset($parameterProperties[self::$QUERY_PARAMETER__OPERATOR_NAME])) { $operatorName = $parameterProperties[self::$QUERY_PARAMETER__OPERATOR_NAME]; unset($parameterProperties[self::$QUERY_PARAMETER__OPERATOR_NAME]); $isParameterPropertyDetected = TRUE; } else { $operatorName = EqualOperatorHandler::$OPERATOR__NAME; } $parameterValues = NULL; if (isset($parameterProperties[self::$QUERY_PARAMETER__OPERATOR_VALUE])) { $parameterValues = $parameterProperties[self::$QUERY_PARAMETER__OPERATOR_VALUE]; unset($parameterProperties[self::$QUERY_PARAMETER__OPERATOR_VALUE]); $isParameterPropertyDetected = TRUE; } if (!$isParameterPropertyDetected) { $parameterValues = $parameterProperties; // marking that all properties are processed in the variable $parameterProperties = NULL; } // some properties are left and we do not know what to do with them if (count($parameterProperties) > 0) { throw new IllegalArgumentException(t('Unsupported keys for parameter definition: @unsupportedKeys', array('@unsupportedKeys' => implode(', ', array_keys($parameterProperties))))); } $operatorValues = NULL; if (isset($parameterValues)) { if (ArrayHelper::isIndexedArray($parameterValues)) { $operatorValues = $parameterValues; } else { // named operator value parameters are provided // we need to order the values in the same order as the parameters defined for the operator $operatorMetaData = OperatorFactory::getInstance()->getOperatorMetaData($operatorName); $operatorParameterMetaDatas = $operatorMetaData->getParameters(); if (isset($operatorParameterMetaDatas)) { foreach ($operatorParameterMetaDatas as $operatorParameterMetaData) { $name = $operatorParameterMetaData->name; $value = NULL; if (isset($parameterValues[$name])) { $value = $parameterValues[$name]; unset($parameterValues[$name]); } $operatorValues[] = $value; } } // some named parameters are not recognized if (count($parameterValues) > 0) { throw new IllegalArgumentException(t('Unsupported keys for parameter value definition: @unsupportedKeys', array('@unsupportedKeys' => implode(', ', array_keys($parameterValues))))); } } } $operator = OperatorFactory::getInstance()->initiateHandler($operatorName, $operatorValues); if (isset($adjustedParameters[$parameterName])) { $previousOperator = $adjustedParameters[$parameterName]; if (is_array($previousOperator)) { $adjustedParameters[$parameterName][] = $operator; } else { $adjustedParameters[$parameterName] = array($previousOperator, $operator); } } else { $adjustedParameters[$parameterName] = $operator; } } return $adjustedParameters; }
public function insertOrUpdateOrDeleteDatasetRecords(DataControllerCallContext $callcontext, AbstractDatasetManipulationRequest $request) { $environment_metamodel = data_controller_get_environment_metamodel(); $metamodel = data_controller_get_metamodel(); $datasourceQueryHandler = DataSourceQueryFactory::getInstance()->getHandler($this->getDataSourceType()); $dataset = $metamodel->getDataset($request->datasetName); $datasource = $environment_metamodel->getDataSource($dataset->datasourceName); $recordMetaData = isset($request->recordsHolder->recordMetaData) ? $request->recordsHolder->recordMetaData : $dataset; $isRecordIndexed = $request->recordsHolder instanceof IndexedRecordsHolder; $keyColumnNames = $recordMetaData->getKeyColumnNames(); $nonkeyColumnNames = $recordMetaData->findNonKeyColumnNames(); // preparing a request to find existing records $queryRequest = new DatasetQueryRequest($request->datasetName); // loading only key columns from database $queryRequest->addColumns($keyColumnNames); // a request can be more efficient for single column key if (count($keyColumnNames) == 1) { list($keyColumnIndex, $keyColumnName) = each($keyColumnNames); $keyColumnIdentifier = $isRecordIndexed ? $keyColumnIndex : $keyColumnName; $keyValues = NULL; foreach ($request->recordsHolder->records as $record) { ArrayHelper::addUniqueValue($keyValues, $record->getColumnValue($keyColumnIdentifier, TRUE)); } $queryRequest->addQueryValue( 0, $keyColumnName, OperatorFactory::getInstance()->initiateHandler(EqualOperatorHandler::OPERATOR__NAME, array($keyValues))); } else { for ($i = 0, $count = count($request->recordsHolder->records); $i < $count; $i++) { $record = $request->recordsHolder->records[$i]; foreach ($keyColumnNames as $keyColumnIndex => $keyColumnName) { $keyColumnIdentifier = $isRecordIndexed ? $keyColumnIndex : $keyColumnName; $keyColumnValue = $record->getColumnValue($keyColumnIdentifier, TRUE); $queryRequest->addQueryValue( $i, $keyColumnName, OperatorFactory::getInstance()->initiateHandler(EqualOperatorHandler::OPERATOR__NAME, $keyColumnValue)); } } } // loading existing records ... if any $existingRecordFormatter = new QueryKeyResultFormatter($keyColumnNames); $existingRecords = $existingRecordFormatter->formatRecords($datasourceQueryHandler->queryDataset($callcontext, $queryRequest)); // sorting out records for insert, update and delete operations $keyedRecords = $insertedRecordKeys = $updatedRecordKeys = $deletedRecordKeys = NULL; foreach ($request->recordsHolder->records as $record) { $keyParts = NULL; foreach ($keyColumnNames as $keyColumnIndex => $keyColumnName) { $keyColumnIdentifier = $isRecordIndexed ? $keyColumnIndex : $keyColumnName; $keyParts[] = $record->getColumnValue($keyColumnIdentifier, TRUE); } $key = ArrayHelper::prepareCompositeKey($keyParts); $keyedRecords[$key] = $record; // checking if the record has to be deleted $isDeletable = TRUE; if (isset($nonkeyColumnNames)) { foreach ($nonkeyColumnNames as $columnIndex => $columnName) { $columnIdentifier = $isRecordIndexed ? $columnIndex : $columnName; if ($record->getColumnValue($columnIdentifier) != NULL) { $isDeletable = FALSE; break; } } } else { // the dataset has NO non-key columns. We should not delete these records $isDeletable = FALSE; } if ($isDeletable) { unset($insertedRecordKeys[$key]); unset($updatedRecordKeys[$key]); // the record physically present in database and needs to be deleted if (isset($existingRecords[$key])) { unset($existingRecords[$key]); $deletedRecordKeys[$key] = TRUE; } } elseif (isset($insertedRecordKeys[$key])) { // the key has been already used to insert a record within this batch. This record needs to be part of update operation $updatedRecordKeys[$key] = TRUE; } elseif (isset($existingRecords[$key])) { $updatedRecordKeys[$key] = TRUE; } else { $insertedRecordKeys[$key] = TRUE; } } $sqls = NULL; // deleting existing records $deletedRecordCount = 0; if (isset($deletedRecordKeys)) { $deleteRecordHolder = $this->prepareRecordHolder($request, $keyedRecords, $deletedRecordKeys); // preparing request $deleteRequest = new DatasetDeleteRequest($request->datasetName, $deleteRecordHolder); // preparing statements to delete records from the database ArrayHelper::appendValue($sqls, $this->prepareDeleteDatasetRecordStatements($callcontext, $deleteRequest)); $deletedRecordCount = count($deleteRecordHolder->records); } // inserting new records $insertedRecordCount = 0; if (isset($insertedRecordKeys)) { $insertRecordHolder = $this->prepareRecordHolder($request, $keyedRecords, $insertedRecordKeys); // preparing request $insertRequest = new DatasetInsertRequest($request->datasetName, $insertRecordHolder); // preparing statements to insert records into the database ArrayHelper::appendValue($sqls, $this->prepareInsertDatasetRecordStatements($callcontext, $insertRequest)); $insertedRecordCount = count($insertRecordHolder->records); } // updating existing records $updatedRecordCount = 0; if (isset($updatedRecordKeys)) { $updateRecordHolder = $this->prepareRecordHolder($request, $keyedRecords, $updatedRecordKeys); // preparing request $updateRequest = new DatasetUpdateRequest($request->datasetName, $updateRecordHolder); // preparing statements to update records in the database ArrayHelper::appendValue($sqls, $this->prepareUpdateDatasetRecordStatements($callcontext, $updateRequest)); $updatedRecordCount = count($updateRecordHolder->records); } $affectedRecordCount = isset($sqls) ? $this->executeManipulationStatementBatch($datasource, $sqls) : 0; if (($insertedRecordCount + $updatedRecordCount + $deletedRecordCount) < $affectedRecordCount) { throw new IllegalStateException(t('Number of affected records is greater than expected number of inserted, updated and deleted records')); } return array($insertedRecordCount, $updatedRecordCount, $deletedRecordCount); }
protected function getQueryFilters () { $query_filters = array(); foreach ( $this->filters as $f ) { if ( empty($f->column) || empty($f->name) ) { LogHelper::log_warn('Missing filter name or column.'); continue; } // if a filter is pre-apply, generate an operator for it. if ( !$f->exposed ) { // If there is a value, then format it otherwise leave it as null $value = isset($f->value) ? $this->formatFilterValue($f->value, $this->getColumn($f->column)) : null; $query_filters[$f->column][] = OperatorFactory::getInstance()->initiateHandler($f->operator,$value); } if ( $f->exposed ) { $requestFilter = FALSE; // Check for query filters next if ( !empty($_REQUEST['t']) ) { foreach ( $_REQUEST['t'] as $dashboardId => $requestFilters ) { if ($dashboardId == $this->dashboard) { foreach ($requestFilters as $filterName => $filterParams) { if ( $f->name == $filterName && is_array($filterParams) ) { $requestFilter = TRUE; // If there is a value, then format it otherwise leave it as null $value = isset($filterParams['v']) ? $this->formatFilterValue($filterParams['v'], $this->getColumn($f->column)) : null; $query_filters[$f->column][] = OperatorFactory::getInstance()->initiateHandler($filterParams['o'],$value); } } } } } if ( !empty($f->operator) && !$requestFilter) { // If a filter is exposed and has a default value for it, set it $value = isset($f->value) ? $this->formatFilterValue($f->value, $this->getColumn($f->column)) : null; $query_filters[$f->column][] = OperatorFactory::getInstance()->initiateHandler($f->operator,$value); } } } return $query_filters; }
protected function loadNextRecord(DataControllerCallContext $callcontext) { // checking if the record could be retrieved from cache if (isset($this->requestedRecordCount) && ($this->requestedRecordCount > ($this->processedRecordIndex + 1))) { // the value is possibly in cache. That depends on number of records we were able to load $this->processedRecordIndex++; } else { $this->processedRecordIndex = 0; // loading data from database $this->requestedRecordCount = self::$PRELOADED_RECORD_COUNT; $request = clone $this->request; $request->setPagination($this->requestedRecordCount, 0); // adding condition for the value column if (isset($this->lastOccurenceValue)) { $request->addQueryValue( 0, $this->columnName, OperatorFactory::getInstance()->initiateHandler(LessThanOperatorHandler::OPERATOR__NAME, $this->lastOccurenceValue)); } $this->loadedRecords = $this->datasourceHandler->queryDataset($callcontext, $request); } return isset($this->loadedRecords[$this->processedRecordIndex]) ? $this->loadedRecords[$this->processedRecordIndex] : NULL; }
public function permitDatasetStorageTruncation(DataControllerCallContext $callcontext, DatasetMetaData $logicalDataset) { parent::permitDatasetStorageTruncation($callcontext, $logicalDataset); if (!self::isLookupDataset($logicalDataset)) { return; } $dataQueryController = data_controller_get_instance(); $metamodel = data_controller_get_metamodel(); // checking of the reference datasets have any NOT NULL data in reference columns $populatedReferenceDatasetPublicNames = NULL; foreach ($metamodel->datasets as $dataset) { foreach ($dataset->getColumns(FALSE, TRUE) as $column) { if ($column->persistence != ColumnMetaData::PERSISTENCE__STORAGE_CREATED) { continue; } if ($column->type->getReferencedDatasetName() == $logicalDataset->name) { $recordCount = $dataQueryController->countDatasetRecords( $dataset->name, array($column->name => OperatorFactory::getInstance()->initiateHandler(NotEmptyOperatorHandler::OPERATOR__NAME))); if ($recordCount > 0) { $populatedReferenceDatasetPublicNames[] = $dataset->publicName; break; } } } } // we should not allow to truncate the dataset if there is any data in any reference datasets if (isset($populatedReferenceDatasetPublicNames)) { throw new IllegalArgumentException(t( "%datasetName dataset is referenced by other datasets. The dataset truncation is not permitted unless records in %referenceDatasetNames datasets are deleted first", array( '%datasetName' => $logicalDataset->publicName, '%referenceDatasetNames' => ArrayHelper::serialize($populatedReferenceDatasetPublicNames)))); } }