protected function permitLookupDatasetStorageChanges(DataControllerCallContext $callcontext, DatasetMetaData $originalLogicalDataset, DatasetMetaData $modifiedLogicalDataset) { $metamodel = data_controller_get_metamodel(); $originalPrimaryKeyColumnName = $originalLogicalDataset->getKeyColumn()->name; // checking if the primary key changed $doesPrimaryKeyMatch = FALSE; $modifiedPrimaryKeyColumnNames = $modifiedLogicalDataset->findKeyColumnNames(); if (count($modifiedPrimaryKeyColumnNames) == 1) { $modifiedPrimaryKeyColumnName = reset($modifiedPrimaryKeyColumnNames); $doesPrimaryKeyMatch = $originalPrimaryKeyColumnName == $modifiedPrimaryKeyColumnName; } if ($doesPrimaryKeyMatch) { return; } // checking if this dataset was used as lookup somewhere foreach ($metamodel->datasets as $dataset) { foreach ($dataset->getColumns(FALSE, TRUE) as $column) { if ($column->type->getReferencedDatasetName() == $originalLogicalDataset->name) { throw new IllegalArgumentException(t( '%datasetName dataset is referenced by other datasets. Changes to the primary key is not permitted unless the references are removed first', array('%datasetName' => $modifiedLogicalDataset->publicName))); } } } }
/** * @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); } }
protected function allowPrimaryKeyCreation(DataSourceHandler $handler, DataControllerCallContext $callcontext, DatasetMetaData $dataset) { $primaryKeyColumnNames = $dataset->findKeyColumnNames(); if (isset($primaryKeyColumnNames)) { $environment_metamodel = data_controller_get_environment_metamodel(); $datasource = $environment_metamodel->getDataSource($dataset->datasourceName); $assembledTableName = assemble_database_entity_name($handler, $datasource->name, $dataset->source); $datasourceQueryHandler = DataSourceQueryFactory::getInstance()->getHandler($datasource->type); // checking if there are any records with NULL values $nullValueConditions = array(); foreach ($primaryKeyColumnNames as $columnName) { $nullValueConditions[] = "$columnName IS NULL"; } $nullValueSQL = 'SELECT ' . implode(', ', $primaryKeyColumnNames) . " FROM $assembledTableName WHERE " . implode(' OR ', $nullValueConditions); $datasourceQueryHandler->getExtension('applyPagination')->apply($datasourceQueryHandler, $nullValueSQL, 0, 1); LogHelper::log_info(new StatementLogMessage('dataset.update.primaryKey.data.check.null', $nullValueSQL)); $nullColumnRecords = $datasourceQueryHandler->executeQuery($callcontext, $datasource, $nullValueSQL); $isTruncateRequired = isset($nullColumnRecords); // checking for non-unique values if (!$isTruncateRequired) { $nonUniqueValueSQL = 'SELECT ' . implode(', ', $primaryKeyColumnNames) . " FROM $assembledTableName GROUP BY " . implode(', ', $primaryKeyColumnNames) . ' HAVING COUNT(*) > 1'; $datasourceQueryHandler->getExtension('applyPagination')->apply($datasourceQueryHandler, $nonUniqueValueSQL, 0, 1); LogHelper::log_info(new StatementLogMessage('dataset.update.primaryKey.data.check', $nonUniqueValueSQL)); $nonUniqueColumnRecords = $datasourceQueryHandler->executeQuery($callcontext, $datasource, $nonUniqueValueSQL); $isTruncateRequired = isset($nonUniqueColumnRecords); } if ($isTruncateRequired) { $truncateDatasetSQL = $handler->getExtension('truncateTable')->generate($handler, $dataset); LogHelper::log_info(new StatementLogMessage('dataset.update.primaryKey.data.truncate', $truncateDatasetSQL)); $handler->executeStatement($datasource, $truncateDatasetSQL); } } }