summaryrefslogtreecommitdiffstats
path: root/das-cpp/trunk/runtime/core/src/apache/das/rdb/ApplyChanges.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'das-cpp/trunk/runtime/core/src/apache/das/rdb/ApplyChanges.cpp')
-rw-r--r--das-cpp/trunk/runtime/core/src/apache/das/rdb/ApplyChanges.cpp568
1 files changed, 568 insertions, 0 deletions
diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/ApplyChanges.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/ApplyChanges.cpp
new file mode 100644
index 0000000000..eea9d81e35
--- /dev/null
+++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/ApplyChanges.cpp
@@ -0,0 +1,568 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+#include "apache/das/rdb/ApplyChanges.h"
+
+namespace apache {
+ namespace das {
+ namespace rdb {
+
+ApplyChanges::ApplyChanges(DASImpl& das, commonj::sdo::DataObjectPtr root) : summary(root->getChangeSummary()) {
+ this->config = (const ConfigImpl*) &das.getConfig();
+ this->root = root;
+ processRootDataObject(root);
+ StatementPtr stmt = *das.getConnection()->createStatement();
+
+ try {
+
+ for (std::list<DASDataObject*>::iterator it = updateOrderList.begin() ;
+ it != updateOrderList.end() ; it++) {
+
+ (*it)->execute(stmt);
+
+ }
+
+ stmt->executeQuery("commit");
+
+ } catch (...) {
+ stmt->executeQuery("rollback");
+ throw;
+
+ }
+
+}
+
+ApplyChanges::~ApplyChanges(void) {
+
+ for (std::map<std::string, const Relationship*>::iterator relationshipsIterator = relationships.begin() ;
+ relationshipsIterator != relationships.end() ; relationshipsIterator++) {
+
+ delete relationshipsIterator->second;
+
+ }
+
+ for (std::map<std::string, const Table*>::iterator tablesIterator = tables.begin() ;
+ tablesIterator != tables.end() ; tablesIterator++) {
+
+ delete tablesIterator->second;
+
+ }
+
+ for (std::map<std::string, std::list<DASDataObject*>*>::iterator dasDataObjectsIterator = dasDataObjects.begin() ;
+ dasDataObjectsIterator != dasDataObjects.end() ; dasDataObjectsIterator++) {
+
+ std::list<DASDataObject*>* list = dasDataObjectsIterator->second;
+
+ for (std::list<DASDataObject*>::iterator listIterator = list->begin() ;
+ listIterator != list->end() ; listIterator++) {
+
+ delete *listIterator;
+
+ }
+
+ delete list;
+
+ }
+
+}
+
+void ApplyChanges::processRootDataObject(commonj::sdo::DataObjectPtr dataObject) {
+ commonj::sdo::ChangedDataObjectList& changedObjects = summary->getChangedDataObjects();
+ std::list<commonj::sdo::DataObjectPtr> createdObjects;
+ std::list<commonj::sdo::DataObjectPtr> deletedObjects;
+ std::list<commonj::sdo::DataObjectPtr> modifiedObjects;
+
+ for (unsigned int i = 0 ; i < changedObjects.size() ; i++) {
+
+ if (changedObjects[i] == root) {
+ continue;
+ }
+
+ processMetadata(changedObjects[i]);
+
+ if (summary->isCreated(changedObjects[i])) {
+ createdObjects.push_back(changedObjects[i]);
+
+ } else if (summary->isDeleted(changedObjects[i])) {
+ deletedObjects.push_back(changedObjects[i]);
+
+ } else {
+ modifiedObjects.push_back(changedObjects[i]);
+ }
+
+ //const commonj::sdo::SettingList& setting = summary->getOldValues(changedObjects[i]);
+
+ }
+
+ std::list<commonj::sdo::DataObjectPtr>::iterator deletedIterator;
+ for (deletedIterator = deletedObjects.begin() ; deletedIterator != deletedObjects.end() ; deletedIterator++) {
+ processDeletedDataObject(*deletedIterator);
+ }
+
+ std::list<commonj::sdo::DataObjectPtr>::iterator createdIterator;
+ for (createdIterator = createdObjects.begin() ; createdIterator != createdObjects.end() ; createdIterator++) {
+ processCreatedDataObject(*createdIterator);
+ }
+
+ std::list<commonj::sdo::DataObjectPtr>::iterator modifiedIterator;
+ for (modifiedIterator = modifiedObjects.begin() ; modifiedIterator != modifiedObjects.end() ; modifiedIterator++) {
+ processModifiedDataObject(*modifiedIterator);
+ }
+
+}
+
+DASDataObject& ApplyChanges::processDataObject(commonj::sdo::DataObjectPtr dataObject) {
+
+ if (summary->isCreated(dataObject)) {
+ return processCreatedDataObject(dataObject);
+ } else if (summary->isDeleted(dataObject)) {
+ return processDeletedDataObject(dataObject);
+ } else {
+ return processModifiedDataObject(dataObject);
+ }
+
+}
+
+void ApplyChanges::processMetadata(commonj::sdo::DataObjectPtr dataObject) {
+ const commonj::sdo::Type& type = dataObject->getType();
+ std::map<std::string, const Table*>::iterator it = tables.find((std::string) type.getName());
+
+ if (it != tables.end()) {
+ return;
+ }
+
+ const Table* configTable = config->getTableByTypeName((std::string) type.getName());
+ commonj::sdo::PropertyList properties = type.getProperties();
+ const std::map<std::string, const Column*>* configTableColumns;
+ std::map<std::string, const Column*>* configTableColumnsByPropertyName = 0;
+ Table* table;
+ unsigned int pkColumnCount = 0;
+ unsigned int pkFoundCount = 0;
+
+ if (configTable != 0) {
+ table = new Table(configTable->getTableName(), configTable->getTypeName());
+ configTableColumns = &configTable->getColumns();
+ configTableColumnsByPropertyName = new std::map<std::string, const Column*>();
+ pkColumnCount = configTable->getPKColumnCount();
+
+ for (std::map<std::string, const Column*>::const_iterator configTableColumnsIterator = configTableColumns->begin() ;
+ configTableColumnsIterator != configTableColumns->end() ; configTableColumnsIterator++) {
+
+ configTableColumnsByPropertyName->insert(
+ std::make_pair(configTableColumnsIterator->second->getPropertyName(),
+ configTableColumnsIterator->second));
+
+ }
+
+ } else {
+ table = new Table((std::string) type.getName());
+ }
+
+ for (unsigned int j = 0 ; j < properties.size() ; j++) {
+
+ if (properties[j].getType().isDataType()) {
+
+ if (configTable != 0) {
+ std::map<std::string, const Column*>::const_iterator configTableColumnsIterator =
+ configTableColumnsByPropertyName->find(properties[j].getName());
+
+ if (configTableColumnsIterator != configTableColumnsByPropertyName->end()) {
+ const Column& column = *configTableColumnsIterator->second;
+
+ if (column.isPK()) {
+ pkFoundCount++;
+ }
+
+ table->addColumn(column);
+
+ } else {
+ table->addColumn(properties[j].getName(), ODBCTypeHelper::getSQLType(properties[j].getType()));
+ }
+
+ } else {
+ table->addColumn(properties[j].getName(), ODBCTypeHelper::getSQLType(properties[j].getType()));
+ }
+
+ } else {
+ const Table* fkTable = config->getTableByTypeName(properties[j].getType().getName());
+ std::string fkTableName;
+
+ if (fkTable == 0) {
+ fkTableName = properties[j].getType().getName();
+ } else {
+ fkTableName = fkTable->getTableName();
+ }
+
+ const Relationship* relationship = config->getRelationship(table->getTableName(), fkTableName);
+
+ if (relationship == 0) {
+ Relationship* aux = new Relationship(table->getTableName(), fkTableName);
+ aux->addKeyPair("ID", table->getTableName() + "_ID");
+ relationships.insert(std::make_pair(table->getTableName() + "." + fkTableName, aux));
+
+ } else {
+ relationships.insert(std::make_pair(table->getTableName() + "." + fkTableName, new Relationship(*relationship)));
+ }
+
+ }
+
+ }
+
+ if (pkColumnCount == 0 || pkColumnCount > pkFoundCount) {
+ Column* column = table->getColumn("ID");
+
+ if (column == 0) {
+ throw DASPrimaryKeyNotFoundException((std::string) "No PK found on Type " + type.getURI() + "." + type.getName());
+ }
+
+ column->setPK(true);
+
+ }
+
+ if (configTableColumnsByPropertyName != 0) {
+ delete configTableColumnsByPropertyName;
+ }
+
+ tables.insert(std::make_pair(type.getName(), table));
+
+}
+
+bool ApplyChanges::isInStack(const DASDataObject& dasDataObject) {
+
+ for (std::list<DASDataObject*>::const_iterator it = stack.begin() ; stack.end() != it ; it++) {
+
+ if ((*it)->getDataObject() == dasDataObject.getDataObject()) {
+ return true;
+ }
+
+ }
+
+ return false;
+
+}
+
+const Table& ApplyChanges::getTable(commonj::sdo::DataObjectPtr dataObject) {
+ std::string typeName = dataObject->getType().getName();
+ std::map<std::string, const Table*>::const_iterator it = tables.find(typeName);
+
+ if (it == tables.end()) {
+ processMetadata(dataObject);
+ }
+
+ it = tables.find(typeName);
+
+ return *it->second;
+
+}
+
+CreatedDataObject& ApplyChanges::processCreatedDataObject(commonj::sdo::DataObjectPtr dataObject) {
+ DASDataObject* dasDB = getDASDataObject(dataObject);
+ //dataObject->printSelf(std::cout);
+
+ if (dasDB != 0) {
+ return (CreatedDataObject&) *dasDB;
+ }
+
+ CreatedDataObject* createdDataObject = new CreatedDataObject(
+ getTable(dataObject), dataObject, summary);
+
+ updateOrderList.push_back(createdDataObject);
+ addDataObject(*createdDataObject);
+ commonj::sdo::PropertyList properties = dataObject->getInstanceProperties();
+
+ for (unsigned int i = 0 ; i < properties.size() ; i++) {
+
+ if (properties[i].getType().isDataObjectType()) {
+
+ if (properties[i].isMany()) {
+ commonj::sdo::DataObjectList& dataObjectList = dataObject->getList(properties[i]);
+
+ for (unsigned int j = 0 ; j < dataObjectList.size() ; j++) {
+ DASDataObject& dob = processDataObject(dataObjectList[j]);
+ RelationshipStatement& rs = dob.addFK(getRelationship(*createdDataObject, dob), &createdDataObject->getPrimaryKeys());
+ dob.addDependency(rs);
+
+ }
+
+ } else {
+ commonj::sdo::DataObjectPtr dao = dataObject->getDataObject(properties[i]);
+ DASDataObject& dob = processDataObject(dao);
+ dob.addFK(getRelationship(*createdDataObject, dob), &createdDataObject->getPrimaryKeys());
+ RelationshipStatement& rs = dob.addFK(getRelationship(*createdDataObject, dob), &createdDataObject->getPrimaryKeys());
+ dob.addDependency(rs);
+
+ }
+
+ }
+
+ }
+
+ return *createdDataObject;
+
+}
+
+const Relationship& ApplyChanges::getRelationship(DASDataObject& parentDataObject, DASDataObject& dataObject) const {
+ std::map<std::string, const Relationship*>::const_iterator relatIt = relationships.
+ find(parentDataObject.getTable().getTableName() + "." + dataObject.getTable().getTableName());
+
+ return *relatIt->second;
+
+}
+
+DeletedDataObject& ApplyChanges::processDeletedDataObject(commonj::sdo::DataObjectPtr dataObject) {
+ DASDataObject* dasDB = getDASDataObject(dataObject);
+ //dataObject->printSelf(std::cout);
+
+ if (dasDB != 0) {
+ return (DeletedDataObject&) *dasDB;
+ }
+
+ DeletedDataObject* deletedDataObject = new DeletedDataObject(
+ getTable(dataObject), dataObject, summary);
+
+ const commonj::sdo::SettingList& setting = summary->getOldValues(dataObject);
+
+ for (int i = 0 ; i < setting.size() ; i++) {
+
+ if (setting[i].isSet() && setting[i].getProperty().getType().isDataObjectType()) {
+ commonj::sdo::DataObjectPtr containedDataObject = setting[i].getDataObjectValue();
+
+ if (!summary->isDeleted(containedDataObject)) {
+ DASDataObject& modDO = processDataObject(containedDataObject);
+ RelationshipStatement& rs = modDO.addFK(getRelationship(*deletedDataObject, modDO), 0);
+ deletedDataObject->addDependency(rs);
+
+ }
+
+ }
+
+ }
+
+ addDataObject(*deletedDataObject);
+ updateOrderList.push_back(deletedDataObject);
+
+ return *deletedDataObject;
+
+}
+
+DASDataObject* ApplyChanges::getDASDataObject(commonj::sdo::DataObjectPtr dataObject) const {
+ std::map<std::string, std::list<DASDataObject*>*>::const_iterator it = dasDataObjects.find((std::string) dataObject->getType().getName());
+
+ if (it != dasDataObjects.end()) {
+ std::list<DASDataObject*>& list = *it->second;
+ std::list<DASDataObject*>::iterator it2;
+
+ for (it2 = list.begin() ; it2 != list.end() ; it2++) {
+
+ if ((*it2)->getDataObject() == dataObject) {
+ return *it2;
+ }
+
+ }
+
+ }
+
+ return 0;
+
+}
+
+ModifiedDataObject& ApplyChanges::processModifiedDataObject(commonj::sdo::DataObjectPtr dataObject) {
+ DASDataObject* dasDB = getDASDataObject(dataObject);
+ //dataObject->printSelf(std::cout);
+
+ if (dasDB != 0) {
+ return (ModifiedDataObject&) *dasDB;
+ }
+
+ ModifiedDataObject* modifiedDataObject = new ModifiedDataObject(
+ getTable(dataObject), dataObject, summary);
+
+ updateOrderList.push_back(modifiedDataObject);
+ addDataObject(*modifiedDataObject);
+
+ if (summary->isModified(dataObject)) {
+ std::map<const commonj::sdo::Property*, std::list<commonj::sdo::DataObjectPtr>*> manyOldValuedProperties;
+ std::map<const commonj::sdo::Property*, commonj::sdo::DataObjectPtr> singleOldValuedProperties;
+ commonj::sdo::PropertyList props = dataObject->getInstanceProperties();
+ const commonj::sdo::SettingList& setting = summary->getOldValues(dataObject);
+
+ for (int i = 0 ; i < setting.size() ; i++) {
+ const commonj::sdo::Property& prop = setting[i].getProperty();
+
+ if (prop.getType().isDataObjectType()) {
+
+ if (!setting[i].isNull() && setting[i].isSet()) {
+ commonj::sdo::DataObjectPtr oldDO = setting[i].getDataObjectValue();
+ //oldDO->printSelf(std::cout);
+ //std::cout << std::endl;
+
+ if (prop.isMany()) {
+ std::map<const commonj::sdo::Property*, std::list<commonj::sdo::DataObjectPtr>*>::iterator manyIt =
+ manyOldValuedProperties.find(&prop);
+
+ std::list<commonj::sdo::DataObjectPtr>* list;
+
+ if (manyIt == manyOldValuedProperties.end()) {
+ list = new std::list<commonj::sdo::DataObjectPtr>();
+ manyOldValuedProperties.insert(std::make_pair(&prop, list));
+
+ } else {
+ list = manyIt->second;
+ }
+
+ list->push_back(oldDO);
+
+ } else {
+ singleOldValuedProperties.insert(std::make_pair(&prop, oldDO));
+ }
+
+ }
+
+ }
+ }
+
+ for (unsigned int i = 0 ; i < props.size() ; i++) {
+
+ if (props[i].getType().isDataObjectType()) {
+
+ if (props[i].isMany()) {
+
+ if (!dataObject->isSet(props[i]) || !dataObject->isNull(props[i])) {
+ commonj::sdo::DataObjectList& doList = dataObject->getList(props[i]);
+
+ for (unsigned int j = 0 ; j < doList.size() ; j++) {
+ commonj::sdo::DataObjectPtr dob = doList[j];
+
+ if (summary->isCreated(dob)) {
+ CreatedDataObject& createdDO = processCreatedDataObject(dob);
+ RelationshipStatement& rs = createdDO.addFK(getRelationship(*modifiedDataObject, createdDO), &modifiedDataObject->getPrimaryKeys());
+ modifiedDataObject->addDependency(rs);
+
+ } else {
+ std::map<const commonj::sdo::Property*, std::list<commonj::sdo::DataObjectPtr>*>::iterator manyIt =
+ manyOldValuedProperties.find(&props[i]);
+
+ bool existsOldDO = false;
+
+ if (manyIt != manyOldValuedProperties.end()) {
+ std::list<commonj::sdo::DataObjectPtr>& list = *manyIt->second;
+
+ for (std::list<commonj::sdo::DataObjectPtr>::iterator listIt = list.begin() ;
+ listIt != list.end() ; listIt++) {
+
+ if (*listIt == dob) {
+ existsOldDO = true;
+ list.erase(listIt);
+ break;
+
+ }
+
+ }
+
+ }
+
+ if (!existsOldDO) {
+ ModifiedDataObject& modDO = processModifiedDataObject(dob);
+ RelationshipStatement& rs = modDO.addFK(getRelationship(*modifiedDataObject, modDO), &modifiedDataObject->getPrimaryKeys());
+ modifiedDataObject->addDependency(rs);
+
+ }
+
+ }
+
+ }
+
+ }
+
+ } else {
+
+ if (!dataObject->isSet(props[i]) || !dataObject->isNull(props[i])) {
+ commonj::sdo::DataObjectPtr dob = dataObject->getDataObject(props[i]);
+
+ if (summary->isCreated(dob)) {
+ CreatedDataObject& createdDO = processCreatedDataObject(dob);
+ RelationshipStatement& rs = createdDO.addFK(getRelationship(*modifiedDataObject, createdDO), &modifiedDataObject->getPrimaryKeys());
+ modifiedDataObject->addDependency(rs);
+
+ } else {
+ std::map<const commonj::sdo::Property*, commonj::sdo::DataObjectPtr>::iterator singleIt =
+ singleOldValuedProperties.find(&props[i]);
+
+ if (singleIt == singleOldValuedProperties.end() || singleIt->second != dob) {
+ ModifiedDataObject& modDO = processModifiedDataObject(dob);
+ RelationshipStatement& rs = modDO.addFK(getRelationship(*modifiedDataObject, modDO), &modifiedDataObject->getPrimaryKeys());
+ modifiedDataObject->addDependency(rs);
+
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ for (std::map<const commonj::sdo::Property*, std::list<commonj::sdo::DataObjectPtr>*>::iterator manyIt = manyOldValuedProperties.begin() ;
+ manyIt != manyOldValuedProperties.end() ; manyIt++) {
+
+ std::list<commonj::sdo::DataObjectPtr>* list = manyIt->second;
+
+ for (std::list<commonj::sdo::DataObjectPtr>::const_iterator listIt = list->begin() ;
+ listIt != list->end() ; listIt++) {
+
+ ModifiedDataObject& modDO = processModifiedDataObject(*listIt);
+ RelationshipStatement& rs = modDO.addFK(getRelationship(*modifiedDataObject, modDO), 0);
+ modDO.addDependency(rs);
+
+ }
+
+ delete list;
+
+ }
+
+ }
+
+ return *modifiedDataObject;
+
+}
+
+void ApplyChanges::addDataObject(DASDataObject& dataObject) {
+ std::list<DASDataObject*>* list;
+ std::string typeName = dataObject.getDataObject()->getType().getName();
+ std::map<std::string, std::list<DASDataObject*>*>::iterator it =
+ dasDataObjects.find(typeName);
+
+ if (it == dasDataObjects.end()) {
+ list = new std::list<DASDataObject*>();
+ dasDataObjects.insert(std::make_pair(typeName, list));
+
+ } else {
+ list = it->second;
+ }
+
+ list->push_back(&dataObject);
+
+}
+
+ };
+ };
+};