From c5846d0e19e3b5fd9d818d714fea2df3f3ef90eb Mon Sep 17 00:00:00 2001 From: jsdelfino Date: Mon, 16 Nov 2009 06:46:29 +0000 Subject: Cleaning up SVN structure, moving das trunk to das-cpp/trunk. git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@880626 13f79535-47bb-0310-9956-ffa450edef68 --- .../core/src/apache/das/rdb/ApplyChanges.cpp | 568 ++++++++++++++ .../runtime/core/src/apache/das/rdb/Column.cpp | 114 +++ .../runtime/core/src/apache/das/rdb/ColumnData.cpp | 849 +++++++++++++++++++++ .../core/src/apache/das/rdb/CommandImpl.cpp | 67 ++ .../runtime/core/src/apache/das/rdb/ConfigImpl.cpp | 334 ++++++++ .../runtime/core/src/apache/das/rdb/Connection.cpp | 214 ++++++ .../core/src/apache/das/rdb/CreatedDataObject.cpp | 107 +++ .../apache/das/rdb/DASColumnNotFoundException.cpp | 32 + .../core/src/apache/das/rdb/DASDataObject.cpp | 259 +++++++ .../core/src/apache/das/rdb/DASFactoryImpl.cpp | 43 ++ .../runtime/core/src/apache/das/rdb/DASImpl.cpp | 161 ++++ .../das/rdb/DASInvalidColumnNameException.cpp | 32 + .../rdb/DASInvalidRelationshipNameException.cpp | 32 + .../apache/das/rdb/DASInvalidSDOTypeException.cpp | 32 + .../apache/das/rdb/DASInvalidSQLTypeException.cpp | 32 + .../das/rdb/DASInvalidTableNameException.cpp | 32 + .../DASOptimisticConcurrencyControlException.cpp | 32 + .../das/rdb/DASPrimaryKeyNotFoundException.cpp | 32 + .../core/src/apache/das/rdb/DeteledDataObject.cpp | 41 + .../core/src/apache/das/rdb/GraphBuilder.cpp | 213 ++++++ .../src/apache/das/rdb/GraphBuilderMetaData.cpp | 302 ++++++++ .../runtime/core/src/apache/das/rdb/KeyPair.cpp | 72 ++ .../core/src/apache/das/rdb/ModifiedDataObject.cpp | 141 ++++ .../core/src/apache/das/rdb/ODBCTypeHelper.cpp | 108 +++ .../runtime/core/src/apache/das/rdb/PKObject.cpp | 168 ++++ .../core/src/apache/das/rdb/PreparedStatement.cpp | 42 + .../core/src/apache/das/rdb/ReadCommandImpl.cpp | 47 ++ .../core/src/apache/das/rdb/Relationship.cpp | 206 +++++ .../src/apache/das/rdb/RelationshipStatement.cpp | 128 ++++ .../src/apache/das/rdb/RelationshipWrapper.cpp | 117 +++ .../runtime/core/src/apache/das/rdb/ResultSet.cpp | 356 +++++++++ .../core/src/apache/das/rdb/ResultSetMetaData.cpp | 216 ++++++ .../core/src/apache/das/rdb/SQLException.cpp | 40 + .../runtime/core/src/apache/das/rdb/Statement.cpp | 107 +++ .../runtime/core/src/apache/das/rdb/Table.cpp | 236 ++++++ .../runtime/core/src/apache/das/rdb/TableData.cpp | 98 +++ 36 files changed, 5610 insertions(+) create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/ApplyChanges.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/Column.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/ColumnData.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/CommandImpl.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/ConfigImpl.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/Connection.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/CreatedDataObject.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/DASColumnNotFoundException.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/DASDataObject.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/DASFactoryImpl.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/DASImpl.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/DASInvalidColumnNameException.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/DASInvalidRelationshipNameException.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/DASInvalidSDOTypeException.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/DASInvalidSQLTypeException.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/DASInvalidTableNameException.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/DASOptimisticConcurrencyControlException.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/DASPrimaryKeyNotFoundException.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/DeteledDataObject.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/GraphBuilder.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/GraphBuilderMetaData.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/KeyPair.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/ModifiedDataObject.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/ODBCTypeHelper.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/PKObject.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/PreparedStatement.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/ReadCommandImpl.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/Relationship.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/RelationshipStatement.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/RelationshipWrapper.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/ResultSet.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/ResultSetMetaData.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/SQLException.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/Statement.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/Table.cpp create mode 100644 das-cpp/trunk/runtime/core/src/apache/das/rdb/TableData.cpp (limited to 'das-cpp/trunk/runtime/core/src/apache/das/rdb') 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::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::iterator relationshipsIterator = relationships.begin() ; + relationshipsIterator != relationships.end() ; relationshipsIterator++) { + + delete relationshipsIterator->second; + + } + + for (std::map::iterator tablesIterator = tables.begin() ; + tablesIterator != tables.end() ; tablesIterator++) { + + delete tablesIterator->second; + + } + + for (std::map*>::iterator dasDataObjectsIterator = dasDataObjects.begin() ; + dasDataObjectsIterator != dasDataObjects.end() ; dasDataObjectsIterator++) { + + std::list* list = dasDataObjectsIterator->second; + + for (std::list::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 createdObjects; + std::list deletedObjects; + std::list 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::iterator deletedIterator; + for (deletedIterator = deletedObjects.begin() ; deletedIterator != deletedObjects.end() ; deletedIterator++) { + processDeletedDataObject(*deletedIterator); + } + + std::list::iterator createdIterator; + for (createdIterator = createdObjects.begin() ; createdIterator != createdObjects.end() ; createdIterator++) { + processCreatedDataObject(*createdIterator); + } + + std::list::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::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* configTableColumns; + std::map* 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(); + pkColumnCount = configTable->getPKColumnCount(); + + for (std::map::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::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::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::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::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*>::const_iterator it = dasDataObjects.find((std::string) dataObject->getType().getName()); + + if (it != dasDataObjects.end()) { + std::list& list = *it->second; + std::list::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*> manyOldValuedProperties; + std::map 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*>::iterator manyIt = + manyOldValuedProperties.find(&prop); + + std::list* list; + + if (manyIt == manyOldValuedProperties.end()) { + list = new std::list(); + 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*>::iterator manyIt = + manyOldValuedProperties.find(&props[i]); + + bool existsOldDO = false; + + if (manyIt != manyOldValuedProperties.end()) { + std::list& list = *manyIt->second; + + for (std::list::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::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*>::iterator manyIt = manyOldValuedProperties.begin() ; + manyIt != manyOldValuedProperties.end() ; manyIt++) { + + std::list* list = manyIt->second; + + for (std::list::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* list; + std::string typeName = dataObject.getDataObject()->getType().getName(); + std::map*>::iterator it = + dasDataObjects.find(typeName); + + if (it == dasDataObjects.end()) { + list = new std::list(); + dasDataObjects.insert(std::make_pair(typeName, list)); + + } else { + list = it->second; + } + + list->push_back(&dataObject); + +} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/Column.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/Column.cpp new file mode 100644 index 0000000000..44b2a5dd99 --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/Column.cpp @@ -0,0 +1,114 @@ +/* + * 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/Column.h" + +namespace apache { + namespace das { + namespace rdb { + +Column::Column(const Column& column) { + this->columnName = column.columnName; + this->propertyName = column.propertyName; + this->sqlType = column.sqlType; + this->containerTable = column.containerTable; + this->pk = column.pk; + managed = column.managed; + collision = column.collision; + +} + +Column::Column(std::string columnName, SQLSMALLINT sqlType) { + StringWrapper columnNameWrapper(columnName); + columnName = columnNameWrapper.toUpper(); + managed = true; + collision = false; + + if (!columnNameWrapper.isValidRDBName()) { + throw DASInvalidColumnNameException("Column name must not contain whitespace characters!"); + } + + this->columnName = columnName; + this->propertyName = columnName; + this->sqlType = sqlType; + containerTable = 0; + pk = false; + +} + +Column::~Column(void) {} + +void Column::setCollision(bool collision) { + this->collision = collision; +} + +void Column::setManaged(bool managed) { + this->managed = managed; +} + +bool Column::isCollision(void) const { + return collision; +} + +bool Column::isManaged(void) const { + return managed; +} + +void Column::setContainerTable(Table* containerTable) { + this->containerTable = containerTable; +} + +Table* Column::getContainerTable(void) const { + return containerTable; +} + +std::string Column::getName(void) const { + return columnName; +} + +SQLSMALLINT Column::getSQLType(void) const { + return sqlType; +} + +void Column::setPropertyName(std::string propertyName) { + StringWrapper propertyNameWrapper(propertyName); + propertyName = propertyNameWrapper.toUpper(); + + if (!propertyNameWrapper.isValidRDBName()) { + throw DASInvalidPropertyNameException("Property name must not contain whitespace characters!"); + } + + this->propertyName = propertyName; + +} + +std::string Column::getPropertyName(void) const { + return propertyName; +} + +void Column::setPK(bool pk) { + this->pk = pk; +} + +bool Column::isPK(void) const { + return pk; +} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/ColumnData.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/ColumnData.cpp new file mode 100644 index 0000000000..653119c367 --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/ColumnData.cpp @@ -0,0 +1,849 @@ +/* + * 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/ColumnData.h" + +namespace apache { + namespace das { + namespace rdb { + +ColumnData::ColumnData(const Column& column, ResultSetPtr resultSet) { + this->column = &column; + + if (column.getContainerTable() == 0) { + throw std::invalid_argument("Column table not set"); + } + + /*if (resultSet->isNull(column.getContainerTable()->getTableName(), column.getName())) { + data = 0; + + } else {*/ + + switch (column.getSQLType()) { + + case SQL_INTEGER : + { + SQLINTEGER sqlInteger = resultSet->getSQLInteger( + column.getContainerTable()->getTableName(), column.getName()); + + data = new SQLINTEGER; + SQLINTEGER* aux = (SQLINTEGER*) data; + *aux = sqlInteger; + + } + + break; + + case SQL_SMALLINT : + { + SQLSMALLINT sqlSmallInt = resultSet->getSQLSmallInt( + column.getContainerTable()->getTableName(), column.getName()); + + data = new SQLSMALLINT; + SQLSMALLINT* aux = (SQLSMALLINT*) data; + *aux = sqlSmallInt; + + } + + break; + + /*case SQL_BIGINT : + { + SQL_BIGINT sqlInteger = resultSet->getSQLInteger( + column.getContainerTable()->getTableName(), column.getName()); + + data = new SQL_BIGINT; + SQL_BIGINT* aux = (SQL_BIGINT*) data; + *aux = sqlInteger; + + } + + break;*/ + + case SQL_CHAR : + { + SQLCHAR sqlChar = resultSet->getSQLChar(column.getContainerTable()->getTableName(), + column.getName()); + + data = new SQLCHAR; + SQLCHAR* aux = (SQLCHAR*) data; + *aux= sqlChar; + } + + break; + + case SQL_WCHAR : + { + SQLWCHAR sqlWChar = resultSet->getSQLWChar(column.getContainerTable()->getTableName(), + column.getName()); + + data = new SQLWCHAR; + SQLWCHAR* aux = (SQLWCHAR*) data; + *aux= sqlWChar; + } + + break; + + case SQL_DOUBLE : + { + SQLDOUBLE sqlDouble = resultSet->getSQLDouble(column.getContainerTable()->getTableName(), + column.getName()); + + data = new SQLDOUBLE; + SQLDOUBLE* aux = (SQLDOUBLE*) data; + *aux = sqlDouble; + } + + break; + + case SQL_FLOAT : + { + SQLFLOAT sqlFloat = resultSet->getSQLFloat(column.getContainerTable()->getTableName(), + column.getName()); + + data = new SQLFLOAT; + SQLFLOAT* aux = (SQLFLOAT*) data; + *aux = sqlFloat; + } + + break; + + case SQL_REAL : + { + SQLREAL sqlReal = resultSet->getSQLReal(column.getContainerTable()->getTableName(), + column.getName()); + + data = new SQLREAL; + SQLREAL* aux = (SQLREAL*) data; + *aux = sqlReal; + } + + break; + + case SQL_VARCHAR : + { + std::string varchar = resultSet->getSQLVarchar(column.getContainerTable()->getTableName(), + column.getName()); + + data = new std::string(varchar.begin(), varchar.end()); + std::string* aux = (std::string*) data; + (*aux).assign(varchar.begin(), varchar.end()); + } + + break; + + case SQL_WVARCHAR : + { + std::wstring wvarchar = resultSet->getSQLWVarchar(column.getContainerTable()->getTableName(), + column.getName()); + + std::wstring* aux = new std::wstring(); + *aux = wvarchar; + data = aux; + + } + + break; + + default : + throw DASInvalidSQLTypeException(); + + } + + //} + +} + +ColumnData::ColumnData(const Column& column, const commonj::sdo::Setting& setting) { + this->column = &column; + + if (column.getContainerTable() == 0) { + throw std::invalid_argument("Column table not set"); + } + + if (!setting.isSet() || setting.isNull()) { + data = 0; + } else { + + switch (column.getSQLType()) { + + case SQL_INTEGER : + { + SQLINTEGER sqlInteger = setting.getIntValue(); + + data = new SQLINTEGER; + SQLINTEGER* aux = (SQLINTEGER*) data; + *aux = sqlInteger; + + } + + break; + + case SQL_SMALLINT : + { + SQLSMALLINT sqlSmallInt = setting.getIntValue(); + + data = new SQLSMALLINT; + SQLSMALLINT* aux = (SQLSMALLINT*) data; + *aux = sqlSmallInt; + + } + + break; + + case SQL_CHAR : + { + SQLCHAR sqlChar = setting.getCharacterValue(); + + data = new SQLCHAR; + SQLCHAR* aux = (SQLCHAR*) data; + *aux= sqlChar; + } + + break; + + case SQL_WCHAR : + { + SQLWCHAR sqlWChar = setting.getCharacterValue(); + + data = new SQLWCHAR; + SQLWCHAR* aux = (SQLWCHAR*) data; + *aux= sqlWChar; + } + + break; + + case SQL_DOUBLE : + { + SQLDOUBLE sqlDouble = setting.getDoubleValue(); + + data = new SQLDOUBLE; + SQLDOUBLE* aux = (SQLDOUBLE*) data; + *aux = sqlDouble; + } + + break; + + case SQL_FLOAT : + { + SQLFLOAT sqlFloat = setting.getDoubleValue(); + + data = new SQLFLOAT; + SQLFLOAT* aux = (SQLFLOAT*) data; + *aux = sqlFloat; + } + + break; + + case SQL_REAL : + { + SQLREAL sqlReal = setting.getFloatValue(); + + data = new SQLREAL; + SQLREAL* aux = (SQLREAL*) data; + *aux = sqlReal; + } + + break; + + case SQL_VARCHAR : + { + unsigned int length = setting.getLength(); + wchar_t* buffer = new wchar_t[length]; + setting.getStringValue(buffer, length); + //buffer[length] = 0; + + std::wstring wstr(buffer, 0, length); + std::string* str = new std::string(wstr.begin(), wstr.end()); + str->assign(wstr.begin(), wstr.end()); + + data = str; + + delete [] buffer; + + } + + break; + + case SQL_WVARCHAR : + { + unsigned int length = setting.getLength(); + wchar_t* buffer = new wchar_t[length]; + setting.getStringValue(buffer, length); + //buffer[length] = 0; + + data = new std::wstring(buffer, 0, length); + + delete [] buffer; + + } + + break; + + default : + throw DASInvalidSQLTypeException(); + + } + + } + +} + +ColumnData::ColumnData(const Column& column, commonj::sdo::DataObjectPtr dataObject) { + this->column = &column; + + if (column.getContainerTable() == 0) { + throw std::invalid_argument("Column table not set"); + } + + if (!dataObject->isSet(column.getPropertyName().c_str()) || dataObject->isNull(column.getPropertyName().c_str())) { + data = 0; + + } else { + + switch (column.getSQLType()) { + + case SQL_INTEGER : + { + SQLINTEGER sqlInteger = dataObject->getInt(column.getPropertyName().c_str()); + + data = new SQLINTEGER; + SQLINTEGER* aux = (SQLINTEGER*) data; + *aux = sqlInteger; + + } + + break; + + case SQL_SMALLINT : + { + SQLSMALLINT sqlSmallInt = dataObject->getInt(column.getPropertyName().c_str()); + + data = new SQLSMALLINT; + SQLSMALLINT* aux = (SQLSMALLINT*) data; + *aux = sqlSmallInt; + + } + + break; + + case SQL_CHAR : + { + SQLCHAR sqlChar = dataObject->getCharacter(column.getPropertyName().c_str()); + + data = new SQLCHAR; + SQLCHAR* aux = (SQLCHAR*) data; + *aux= sqlChar; + } + + break; + + case SQL_WCHAR : + { + SQLWCHAR sqlWChar = dataObject->getCharacter(column.getPropertyName().c_str()); + + data = new SQLWCHAR; + SQLWCHAR* aux = (SQLWCHAR*) data; + *aux= sqlWChar; + } + + break; + + case SQL_DOUBLE : + { + SQLDOUBLE sqlDouble = dataObject->getDouble(column.getPropertyName().c_str()); + + data = new SQLDOUBLE; + SQLDOUBLE* aux = (SQLDOUBLE*) data; + *aux = sqlDouble; + } + + break; + + case SQL_FLOAT : + { + SQLFLOAT sqlFloat = dataObject->getDouble(column.getPropertyName().c_str()); + + data = new SQLFLOAT; + SQLFLOAT* aux = (SQLFLOAT*) data; + *aux = sqlFloat; + } + + break; + + case SQL_REAL : + { + SQLREAL sqlReal = dataObject->getFloat(column.getPropertyName().c_str()); + + data = new SQLREAL; + SQLREAL* aux = (SQLREAL*) data; + *aux = sqlReal; + } + + break; + + case SQL_VARCHAR : + { + unsigned int length = dataObject->getLength(column.getPropertyName().c_str()); + wchar_t* buffer = new wchar_t[length]; + dataObject->getString(column.getPropertyName().c_str(), buffer, length); + + std::wstring wstr(buffer, 0, length); + std::string* str = new std::string(wstr.begin(), wstr.end()); + str->assign(wstr.begin(), wstr.end()); + + data = str; + + delete [] buffer; + + } + + break; + + case SQL_WVARCHAR : + { + unsigned int length = dataObject->getLength(column.getPropertyName().c_str()); + wchar_t* buffer = new wchar_t[length]; + dataObject->getString(column.getPropertyName().c_str(), buffer, length); + + data = new std::wstring(buffer, 0, length); + + delete [] buffer; + + } + + break; + + default : + throw DASInvalidSQLTypeException(); + + } + + } + +} + +ColumnData::~ColumnData(void) { + delete data; +} + +std::string ColumnData::toSQL(void) const { + + if (data == 0) { + return "NULL"; + } else { + + switch (column->getSQLType()) { + + case SQL_INTEGER : + return StringWrapper::toString(*((SQLINTEGER*) data)); + + case SQL_SMALLINT : + return StringWrapper::toString(*((SQLSMALLINT*) data)); + + case SQL_CHAR : + return '\'' + StringWrapper::toString(*((SQLCHAR*) data)) + '\''; + + case SQL_WCHAR : + return '\'' + StringWrapper::toString(*((SQLWCHAR*) data)) + '\''; + + case SQL_DOUBLE : + return StringWrapper::toString(*((SQLDOUBLE*) data)); + + case SQL_FLOAT : + return StringWrapper::toString(*((SQLFLOAT*) data)); + + case SQL_REAL : + return StringWrapper::toString(*((SQLREAL*) data)); + + case SQL_VARCHAR : + { + std::string str = *((std::string*) data); + return '\'' + str + '\''; + + } + + case SQL_WVARCHAR : + { + std::wstring wstr = *((std::wstring*) data); + std::string str(wstr.begin(), wstr.end()); + str.assign(wstr.begin(), wstr.end()); + return '\'' + str + '\''; + + } + + default : + throw DASInvalidSQLTypeException(); + + } + + } + +} + +void ColumnData::populateDataGraph(TableData& tableData) const { + try { + tableData.getGraphObject()->getType().getPropertyIndex(column->getPropertyName().c_str()); + + } catch (commonj::sdo::SDOPropertyNotFoundException&) { + return; + } + + if (data == 0) { + tableData.getGraphObject()->setNull(column->getPropertyName().c_str()); + + } else { + + switch (column->getSQLType()) { + + case SQL_INTEGER : + tableData.getGraphObject()->setInt(column->getPropertyName().c_str(), (long) *((SQLINTEGER*) data)); + + break; + + case SQL_SMALLINT : + tableData.getGraphObject()->setInt(column->getPropertyName().c_str(), (long) *((SQLSMALLINT*) data)); + + break; + + case SQL_CHAR : + tableData.getGraphObject()->setCharacter(column->getPropertyName().c_str(), (wchar_t) *((SQLCHAR*) data)); + + break; + + case SQL_WCHAR : + tableData.getGraphObject()->setCharacter(column->getPropertyName().c_str(), (wchar_t) *((SQLWCHAR*) data)); + + break; + + case SQL_FLOAT : + tableData.getGraphObject()->setDouble(column->getPropertyName().c_str(), (long double) *((SQLFLOAT*) data)); + + case SQL_DOUBLE : + tableData.getGraphObject()->setDouble(column->getPropertyName().c_str(), (long double) *((SQLDOUBLE*) data)); + + break; + + case SQL_REAL : + tableData.getGraphObject()->setFloat(column->getPropertyName().c_str(), (float) *((SQLREAL*) data)); + + break; + + case SQL_VARCHAR : + { + std::string* varchar = (std::string*) data; + std::wstring wstr(varchar->begin(), varchar->end()); + wstr.assign(varchar->begin(), varchar->end()); + + tableData.getGraphObject()->setString(column->getPropertyName().c_str(), + wstr.c_str(), wstr.size()); + } + + break; + + case SQL_WVARCHAR : + { + std::wstring* wvarchar = (std::wstring*) data; + + tableData.getGraphObject()->setString(column->getPropertyName().c_str(), + (*wvarchar).c_str(), (*wvarchar).size()); + } + + break; + + default : + throw DASInvalidSQLTypeException(); + + } + + } + +} + +bool ColumnData::operator==(const ColumnData& columnData) const { + + if (column->getSQLType() != columnData.column->getSQLType()) { + throw DASInvalidSQLTypeException("Different sql types!"); + } + + if (data == 0) { + return false; + } + + switch (column->getSQLType()) { + + case SQL_INTEGER : + + if (*((SQLINTEGER*) columnData.data) == *((SQLINTEGER*) data)) { + return true; + } + + break; + + case SQL_SMALLINT : + + if (*((SQLSMALLINT*) columnData.data) == *((SQLSMALLINT*) data)) { + return true; + } + + break; + + case SQL_CHAR : + + if (*((SQLCHAR*) columnData.data) == *((SQLCHAR*) data)) { + return true; + } + + break; + + case SQL_WCHAR : + + if (*((SQLWCHAR*) columnData.data) == *((SQLWCHAR*) data)) { + return true; + } + + break; + + case SQL_DOUBLE : + if (*((SQLDOUBLE*) columnData.data) == *((SQLDOUBLE*) data)) { + return true; + } + + case SQL_FLOAT : + if (*((SQLFLOAT*) columnData.data) == *((SQLFLOAT*) data)) { + return true; + } + + break; + + case SQL_REAL : + + if (*((SQLREAL*) columnData.data) == *((SQLREAL*) data)) { + return true; + } + + break; + + case SQL_VARCHAR : + if (*((std::string*) columnData.data) == *((std::string*) data)) { + return true; + } + + break; + + case SQL_WVARCHAR : + if (*((std::wstring*) columnData.data) == *((std::wstring*) data)) { + return true; + } + + break; + + default : + throw DASInvalidSQLTypeException(); + + } + + return false; + +} + +bool ColumnData::operator!=(const ColumnData& columnData) const { + return !(*this == columnData); +} + +const Column& ColumnData::getColumn(void) const { + return *column; +} + +bool ColumnData::operator<(const ColumnData& columnData) const { + + if (column->getSQLType() != columnData.column->getSQLType()) { + throw DASInvalidSQLTypeException("Different sql types!"); + } + + if (data == 0) { + return false; + } + + switch (column->getSQLType()) { + + case SQL_SMALLINT : + + if (*((SQLSMALLINT*) columnData.data) > *((SQLSMALLINT*) data)) { + return true; + } + + break; + + case SQL_INTEGER : + + if (*((SQLINTEGER*) columnData.data) > *((SQLINTEGER*) data)) { + return true; + } + + break; + + case SQL_CHAR : + + if (*((SQLCHAR*) columnData.data) > *((SQLCHAR*) data)) { + return true; + } + + break; + + case SQL_WCHAR : + + if (*((SQLWCHAR*) columnData.data) > *((SQLWCHAR*) data)) { + return true; + } + + break; + + case SQL_DOUBLE : + if (*((SQLDOUBLE*) columnData.data) > *((SQLDOUBLE*) data)) { + return true; + } + + case SQL_FLOAT : + if (*((SQLFLOAT*) columnData.data) > *((SQLFLOAT*) data)) { + return true; + } + + break; + + case SQL_REAL : + + if (*((SQLREAL*) columnData.data) > *((SQLREAL*) data)) { + return true; + } + + break; + + case SQL_VARCHAR : + if (*((std::string*) columnData.data) > *((std::string*) data)) { + return true; + } + + break; + + case SQL_WVARCHAR : + if (*((std::wstring*) columnData.data) > *((std::wstring*) data)) { + return true; + } + + break; + + default : + throw DASInvalidSQLTypeException(); + + } + + return false; + +} + +bool ColumnData::operator>(const ColumnData& columnData) const { + + if (column->getSQLType() != columnData.column->getSQLType()) { + throw DASInvalidSQLTypeException("Different sql types!"); + } + + if (data == 0) { + return false; + } + + switch (column->getSQLType()) { + + case SQL_INTEGER : + + if (*((SQLINTEGER*) columnData.data) < *((SQLINTEGER*) data)) { + return true; + } + + break; + + case SQL_SMALLINT : + + if (*((SQLSMALLINT*) columnData.data) < *((SQLSMALLINT*) data)) { + return true; + } + + break; + + case SQL_CHAR : + + if (*((SQLCHAR*) columnData.data) < *((SQLCHAR*) data)) { + return true; + } + + break; + + case SQL_WCHAR : + + if (*((SQLWCHAR*) columnData.data) < *((SQLWCHAR*) data)) { + return true; + } + + break; + + case SQL_DOUBLE : + if (*((SQLDOUBLE*) columnData.data) < *((SQLDOUBLE*) data)) { + return true; + } + + case SQL_FLOAT : + if (*((SQLFLOAT*) columnData.data) < *((SQLFLOAT*) data)) { + return true; + } + + break; + + case SQL_REAL : + + if (*((SQLREAL*) columnData.data) < *((SQLREAL*) data)) { + return true; + } + + break; + + case SQL_VARCHAR : + if (*((std::string*) columnData.data) < *((std::string*) data)) { + return true; + } + + break; + + case SQL_WVARCHAR : + if (*((std::wstring*) columnData.data) < *((std::wstring*) data)) { + return true; + } + + break; + + default : + throw DASInvalidSQLTypeException(); + + } + + return false; + +} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/CommandImpl.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/CommandImpl.cpp new file mode 100644 index 0000000000..193d3e1108 --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/CommandImpl.cpp @@ -0,0 +1,67 @@ +/* + * 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/CommandImpl.h" +#include "apache/das/rdb/DASImpl.h" + +namespace apache { + namespace das { + namespace rdb { + +CommandImpl::CommandImpl(DASImpl& das, std::string sqlString) { + this->das = &das; + statement = das.getConnection()->createStatement(); + sql = sqlString; + + //statement = new Statement(); + + //try { + /*URL url = getClass().getResource("/xml/sdoJava.xsd"); + if (url == null) { + //throw new RuntimeException("Could not find resource: xml/sdoJava.xsd"); + } + + InputStream inputStream = url.openStream(); + XSDHelper.INSTANCE.define(inputStream, url.toString()); + inputStream.close();*/ + //} catch (IOException ex) { + // throw new RuntimeException(ex); + //} + +} + +CommandImpl::~CommandImpl() {} + +DASImpl& CommandImpl::getDAS(void) { + return *das; +} + +commonj::sdo::DataObjectPtr CommandImpl::executeQuery(void) { + statement->executeQuery(sql); + + return commonj::sdo::DataObjectPtr(0); + +} + +void CommandImpl::close(void) { + statement->close(); +} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/ConfigImpl.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/ConfigImpl.cpp new file mode 100644 index 0000000000..20c7871ba4 --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/ConfigImpl.cpp @@ -0,0 +1,334 @@ +/* + * 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/ConfigImpl.h" + +namespace apache { + namespace das { + namespace rdb { + +ConfigImpl::ConfigImpl(void) { + relationships = new std::map(); + tables = new std::map(); + commands = new std::map(); + + convOverConfig = false; + +} + +ConfigImpl::ConfigImpl(const Config& config) : Config(config) { + ConfigImpl& thisConfig = (ConfigImpl&) config; + tables = new std::map(); + relationships = new std::map(); + commands = new std::map(*thisConfig.commands); + + std::map::iterator tableIterator; + std::map::iterator relationshipIterator; + std::map::iterator commandIterator; + + this->convOverConfig = thisConfig.convOverConfig; + + for (tableIterator = thisConfig.tables->begin() ; tableIterator != thisConfig.tables->end() ; + tableIterator++) { + + tables->insert(std::make_pair(tableIterator->first, new Table(*tableIterator->second))); + + } + + for (relationshipIterator = thisConfig.relationships->begin() ; + relationshipIterator != thisConfig.relationships->end() ; relationshipIterator++) { + + relationships->insert(std::make_pair(relationshipIterator->first, + new Relationship(*relationshipIterator->second))); + + } + +} + +ConfigImpl::ConfigImpl(std::string xmlFile) { + relationships = new std::map(); + tables = new std::map(); + commands = new std::map(); + + convOverConfig = false; + + commonj::sdo::DataFactoryPtr dataFactory = commonj::sdo::DataFactory::getDataFactory(); + dataFactory->addType(DAS_NAMESPACE, "RootType"); + dataFactory->addType(DAS_NAMESPACE, "Table"); + dataFactory->addType(DAS_NAMESPACE, "Relationship"); + dataFactory->addType(DAS_NAMESPACE, "KeyPair"); + dataFactory->addType(DAS_NAMESPACE, "Column"); + dataFactory->addType(DAS_NAMESPACE, "Config"); + dataFactory->addType(DAS_NAMESPACE, "Command"); + + const commonj::sdo::Type& rootType = dataFactory->getType(DAS_NAMESPACE, "RootType"); + const commonj::sdo::Type& table = dataFactory->getType(DAS_NAMESPACE, "Table"); + const commonj::sdo::Type& relationship = dataFactory->getType(DAS_NAMESPACE, "Relationship"); + const commonj::sdo::Type& keyPair = dataFactory->getType(DAS_NAMESPACE, "KeyPair"); + const commonj::sdo::Type& column = dataFactory->getType(DAS_NAMESPACE, "Column"); + const commonj::sdo::Type& config = dataFactory->getType(DAS_NAMESPACE, "Config"); + const commonj::sdo::Type& command = dataFactory->getType(DAS_NAMESPACE, "Command"); + + dataFactory->addPropertyToType(rootType, "Config", config); + + dataFactory->addPropertyToType(table, "Column", column, true, false, true); + dataFactory->addPropertyToType(table, "tableName", SDO_NAMESPACE, "String", false, false, true); + dataFactory->addPropertyToType(table, "typeName", SDO_NAMESPACE, "String", false, false, true); + + dataFactory->addPropertyToType(config, "Table", table, true, false, true); + dataFactory->addPropertyToType(config, "Relationship", relationship, true, false, true); + dataFactory->addPropertyToType(config, "Command", command, true, false, true); + dataFactory->addPropertyToType(config, "uri", SDO_NAMESPACE, "String", false, false, true); + dataFactory->setDefault(SDO_NAMESPACE, "String", "uri", ""); + + dataFactory->addPropertyToType(command, "name", SDO_NAMESPACE, "String", false, false, true); + dataFactory->addPropertyToType(command, "SQL", SDO_NAMESPACE, "String", false, false, true); + + dataFactory->addPropertyToType(relationship, "KeyPair", keyPair, true, false, true); + dataFactory->addPropertyToType(relationship, "name", SDO_NAMESPACE, "String", false, false, true); + dataFactory->addPropertyToType(relationship, "primaryKeyTable", SDO_NAMESPACE, "String", false, false, true); + dataFactory->addPropertyToType(relationship, "foreignKeyTable", SDO_NAMESPACE, "String", false, false, true); + dataFactory->addPropertyToType(relationship, "many", SDO_NAMESPACE, "Boolean", false, false, true); + dataFactory->setDefault(relationship, "many", true); + + dataFactory->addPropertyToType(keyPair, "primaryKeyColumn", SDO_NAMESPACE, "String", false, false, true); + dataFactory->addPropertyToType(keyPair, "foreignKeyColumn", SDO_NAMESPACE, "String", false, false, true); + + dataFactory->addPropertyToType(column, "columnName", SDO_NAMESPACE, "String", false, false, true); + dataFactory->addPropertyToType(column, "sqlType", SDO_NAMESPACE, "String", false, false, true); + dataFactory->addPropertyToType(column, "propertyName", SDO_NAMESPACE, "String", false, false, true); + dataFactory->addPropertyToType(column, "primaryKey", SDO_NAMESPACE, "Boolean", false, false, true); + dataFactory->addPropertyToType(column, "primaryKey", SDO_NAMESPACE, "Boolean", false, false, true); + dataFactory->addPropertyToType(column, "collision", SDO_NAMESPACE, "Boolean", false, false, true); + dataFactory->addPropertyToType(column, "managed", SDO_NAMESPACE, "Boolean", false, false, true); + dataFactory->setDefault(column, "primaryKey", false); + dataFactory->setDefault(column, "collision", false); + dataFactory->setDefault(column, "managed", true); + + dataFactory->resolve(); + + commonj::sdo::XMLHelperPtr xmlh = commonj::sdo::HelperProvider::getXMLHelper(dataFactory); + commonj::sdo::XMLDocumentPtr doc = xmlh->loadFile(xmlFile.c_str(), DAS_NAMESPACE); + commonj::sdo::DataObjectPtr root = doc->getRootDataObject(); + + commonj::sdo::DataObjectList& tableList = root->getList("Table"); + + for (unsigned int i = 0 ; i < tableList.size() ; i++) { + std::string tableName = SDODataObjectWrapper(tableList[i]).getString("tableName"); + + if (tableName != "") { + Table& table = addTable(tableName); + std::string typeName = SDODataObjectWrapper(tableList[i]).getString("typeName"); + + if (typeName != "") { + table.setTypeName(typeName); + } + + commonj::sdo::DataObjectList& columnList = tableList[i]->getList("Column"); + + for (unsigned int j = 0 ; j < columnList.size() ; j++) { + std::string columnName = SDODataObjectWrapper(columnList[j]).getString("columnName"); + std::string sqlType = SDODataObjectWrapper(columnList[j]).getString("sqlType"); + + if (columnName != "" && sqlType != "") { + Column& column = table.addColumn(columnName, ODBCTypeHelper::getSQLType(sqlType)); + std::string propertyName = SDODataObjectWrapper(columnList[j]).getString("propertyName"); + + if (propertyName != "") { + column.setPropertyName(propertyName); + } + + column.setPK(columnList[j]->getBoolean("primaryKey")); + column.setManaged(columnList[j]->getBoolean("managed")); + column.setCollision(columnList[j]->getBoolean("collision")); + + } + + + } + + } + + } + + commonj::sdo::DataObjectList& relationshipList = root->getList("Relationship"); + + for (unsigned int i = 0 ; i < relationshipList.size() ; i++) { + std::string primaryKeyTable = SDODataObjectWrapper(relationshipList[i]).getString("primaryKeyTable"); + std::string foreignKeyTable = SDODataObjectWrapper(relationshipList[i]).getString("foreignKeyTable"); + std::string name = SDODataObjectWrapper(relationshipList[i]).getString("name");; + + Relationship& relationship = addRelationship(primaryKeyTable, foreignKeyTable); + relationship.setMany(relationshipList[i]->getBoolean("many")); + + commonj::sdo::DataObjectList& keyPairList = relationshipList[i]->getList("KeyPair"); + + for (unsigned int i = 0 ; i < keyPairList.size() ; i++) { + std::string primaryKeyColumn = SDODataObjectWrapper(keyPairList[i]).getString("primaryKeyColumn"); + std::string foreignKeyColumn = SDODataObjectWrapper(keyPairList[i]).getString("foreignKeyColumn"); + relationship.addKeyPair(primaryKeyColumn, foreignKeyColumn); + + } + + } + + commonj::sdo::DataObjectList& commandList = root->getList("Command"); + + for (unsigned int i = 0 ; i < commandList.size() ; i++) { + std::string name = SDODataObjectWrapper(commandList[i]).getString("name"); + std::string sql = SDODataObjectWrapper(commandList[i]).getString("SQL"); + + commands->insert(std::make_pair(name, sql)); + + } + + setURI(StringWrapper(root, "uri").getString()); + +} + +ConfigImpl::~ConfigImpl(void) { + std::map::const_iterator tableIterator; + std::map::const_iterator relationshipIterator; + + tableIterator = tables->begin(); + for ( ; tableIterator != tables->end() ; + tableIterator++) { + delete tableIterator->second; + } + + for (relationshipIterator = relationships->begin() ; + relationshipIterator != relationships->end() ; relationshipIterator++) { + delete relationshipIterator->second; + } + + delete relationships; + delete tables; + delete commands; + +} + +std::string ConfigImpl::getCommand(std::string commandName) const { + std::map::const_iterator it = commands->find(commandName); + + if (it == commands->end()) { + throw DASCommandNotFoundException(); + } + + return it->second; + +} + +const Table* ConfigImpl::getTableByTypeName(std::string typeName) const { + std::map::const_iterator it; + + for (it = tables->begin() ; + it != tables->end() ; it++) { + + if (it->second->getTypeName() == typeName) { + return it->second; + } + + } + + return 0; + +} + +Table& ConfigImpl::addTable(std::string tableName) { + return newTable(*(new Table(tableName))); +} + +Table& ConfigImpl::addTable(const Table& table) { + return newTable(*(new Table(table))); +} + +Table& ConfigImpl::newTable(Table& table) { + std::string tableName = table.getTableName(); + std::map::iterator tableIterator = tables->find(tableName); + + if (tableIterator == tables->end()) { + tables->insert(std::make_pair(tableName, &table)); + + return table; + + } + + return (Table&) *tableIterator->second; + +} + +const std::map& ConfigImpl::getRelationships(void) const { + return (const std::map&) *relationships; +} + +Relationship& ConfigImpl::addRelationship(std::string pkTableName, std::string fkTableName, std::string name) { + return newRelationship(*(new Relationship(pkTableName, fkTableName, name))); +} + +Relationship& ConfigImpl::addRelationship(const Relationship& relationship) { + return newRelationship(*(new Relationship(relationship))); +} + +Relationship& ConfigImpl::newRelationship(Relationship& relationship) { + std::string pkXfk = relationship.getPKTableName() + "." + relationship.getFKTableName(); + std::map::iterator it = relationships->find(pkXfk); + + if (it == relationships->end()) { + relationships->insert(std::make_pair(pkXfk, &relationship)); + + return relationship; + + } + + return (Relationship&) *it->second; + +} + +const Relationship* ConfigImpl::getRelationship(std::string pkTableName, std::string fkTableName) const { + std::map::iterator it = relationships->find(pkTableName + "." + fkTableName); + + if (it == relationships->end()) { + return 0; + } + + return it->second; + +} + +const std::map& ConfigImpl::getTables(void) const { + return (const std::map&) *tables; +} + +bool ConfigImpl::isConvOverConfig(void) const { + return convOverConfig; +} + +const Table* ConfigImpl::getTable(std::string tableName) const { + std::map::iterator tableIterator = tables->find(tableName); + + if (tableIterator == tables->end()) { + return 0; + } + + return tableIterator->second; + +} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/Connection.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/Connection.cpp new file mode 100644 index 0000000000..752f70f528 --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/Connection.cpp @@ -0,0 +1,214 @@ +/* + * 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/Connection.h" + +namespace apache { + namespace das { + namespace rdb { + +Connection::Connection(string dsn, string user, string password) { + SQLRETURN result; + + SQLINTEGER error; + SQLCHAR sqlStat; + SQLCHAR * message = 0; + SQLSMALLINT messageLength; + + //Alloc environment handle + result = SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&environment); + + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + throw SQLException(result, "Error to alloc the environment handle - SQLHENV"); + + //Set the environment + result = SQLSetEnvAttr(environment, SQL_ATTR_ODBC_VERSION,(void*)SQL_OV_ODBC3, 0); + + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)){ + SQLFreeHandle(SQL_HANDLE_ENV, environment); + throw SQLException(result, "Error to set the environment handle - SQLHENV"); + } + + //Allocate connection handle + result = SQLAllocHandle(SQL_HANDLE_DBC, environment, &connection); + + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)){ + SQLFreeHandle(SQL_HANDLE_ENV, environment); + throw SQLException(result, "Error to alloc the connection handle - SQLHDBC"); + } + + setAutoCommit(false); + + //Connect to the datasource + result = SQLConnect(connection, reinterpret_cast(const_cast (dsn.c_str())), SQL_NTS, + reinterpret_cast(const_cast (user.c_str())), SQL_NTS, + reinterpret_cast(const_cast (password.c_str())), SQL_NTS); + + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)){ + + SQLGetDiagRec(SQL_HANDLE_DBC, connection,1, + &sqlStat, &error,message,100,&messageLength); + + SQLFreeHandle(SQL_HANDLE_DBC, connection); + SQLFreeHandle(SQL_HANDLE_ENV, environment); + + string error("Error to establish the connection.\nSQLSTATE: "); + error += reinterpret_cast(&sqlStat); + throw SQLException(result, error); + } + +} + +Connection::Connection(string connectString) { + SQLRETURN result; + + SQLINTEGER error; + SQLCHAR sqlStat; + SQLCHAR * message = 0; + SQLSMALLINT messageLength; + SQLCHAR outConnectString[1024]; + + //Alloc environment handle + result = SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&environment); + + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + throw SQLException(result, "Error to alloc the environment handle - SQLHENV"); + + //Set the environment + result = SQLSetEnvAttr(environment, SQL_ATTR_ODBC_VERSION,(void*)SQL_OV_ODBC3, 0); + + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)){ + SQLFreeHandle(SQL_HANDLE_ENV, environment); + throw SQLException(result, "Error to set the environment handle - SQLHENV"); + } + + //Allocate connection handle + result = SQLAllocHandle(SQL_HANDLE_DBC, environment, &connection); + + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)){ + SQLFreeHandle(SQL_HANDLE_ENV, environment); + throw SQLException(result, "Error to alloc the connection handle - SQLHDBC"); + } + + setAutoCommit(false); + + //Connect to the datasource + result = SQLDriverConnect( connection, 0, (SQLCHAR*) (char*) connectString.c_str(), SQL_NTS, + (SQLCHAR*)outConnectString, sizeof(outConnectString), + &messageLength, SQL_DRIVER_COMPLETE ); + + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)){ + + SQLGetDiagRec(SQL_HANDLE_DBC, connection,1, + &sqlStat, &error,message,100,&messageLength); + + SQLFreeHandle(SQL_HANDLE_DBC, connection); + SQLFreeHandle(SQL_HANDLE_ENV, environment); + + string outC = (char*) outConnectString; + + string error("Error to establish the connection.\nSQLSTATE: "); + error += reinterpret_cast(&sqlStat); + throw SQLException(result, error); + } + +} + +Connection::~Connection(void){ + std::list::iterator it; + + for (it = statements.begin() ; it != statements.end() ; it++) { + + if (**it) { + delete **it; + delete *it; + + } + + } + + SQLDisconnect(connection); + SQLFreeHandle(SQL_HANDLE_DBC,connection); + SQLFreeHandle(SQL_HANDLE_ENV, environment); + +} + +SQLHDBC Connection::getODBCConnection(void) const{ + return connection; +} + +void Connection::commit(void){ + SQLRETURN result = SQLEndTran(SQL_HANDLE_DBC, connection, SQL_COMMIT); + + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)){ + throw SQLException(result, "Commit error"); + } + +} + +void Connection::rollback(void){ + SQLRETURN result = SQLEndTran(SQL_HANDLE_DBC, connection, SQL_ROLLBACK); + + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)){ + throw SQLException(result, "Rollback error"); + } + +} + +void Connection::setAutoCommit(bool autoCommit){ + if(autoCommit) + SQLSetConnectAttr(connection,SQL_ATTR_AUTOCOMMIT,reinterpret_cast(SQL_AUTOCOMMIT_ON), SQL_IS_INTEGER ); + else + SQLSetConnectAttr(connection,SQL_ATTR_AUTOCOMMIT,SQL_AUTOCOMMIT_OFF, SQL_IS_INTEGER ); +} + +StatementPtr Connection::createStatement(void) { + SQLHSTMT statementHandle; + SQLRETURN result = SQLAllocHandle(SQL_HANDLE_STMT, connection, &statementHandle); + + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)){ + throw SQLException(result, "Error to alloc the statement handle - SQLSTMT"); + } + + std::list::iterator it; + + for (it = statements.begin() ; it != statements.end() ; ) { + + if (**it) { + it++; + + } else { + std::list::iterator aux = it; + it++; + statements.erase(aux); + + } + + } + + Statement* stmt = new Statement(*this, statementHandle); + StatementPtr ret(stmt); + statements.push_back(new StatementPtr(stmt, false)); + + return ret; + +} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/CreatedDataObject.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/CreatedDataObject.cpp new file mode 100644 index 0000000000..de24d356d4 --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/CreatedDataObject.cpp @@ -0,0 +1,107 @@ +/* + * 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/CreatedDataObject.h" + +namespace apache { + namespace das { + namespace rdb { + +CreatedDataObject::CreatedDataObject(const Table& table, commonj::sdo::DataObjectPtr dataObject, + commonj::sdo::ChangeSummaryPtr changeSummary) + : DASDataObject(table, dataObject, changeSummary) { + + + commonj::sdo::PropertyList properties = dataObject->getInstanceProperties(); + statement.append("insert into ").append(table.getTableName()).append("("); + bool containsDataType = false; + std::string columns; + std::string values; + + for (unsigned int i = 0 ; i < properties.size() ; i++) { + + if (properties[i].getType().isDataType()) { + + if (containsDataType) { + columns.append(","); + values.append(","); + + } + + containsDataType = true; + const Column* column = table.getColumnByProperty(properties[i].getName()); + ColumnData columnData(*column, dataObject); + + columns.append(column->getName()); + values.append(columnData.toSQL()); + + } + + } + + statement.append(columns).append(") values(").append(values).append(");"); + +} + +CreatedDataObject::~CreatedDataObject(void) {} + +std::string CreatedDataObject::getStatement(void) const { + return statement; +} + +//void CreatedDataObject::execute(StatementPtr stmt) const { +// DASDataObject::execute(stmt); +// +// std::string statement; +// statement = statement.append("insert into ").append(getDataObject()->getType().getName()).append("("); +// +// stmt->executeQuery(statement); +// +// +//} +// +//void CreatedDataObject::execute(StatementPtr stmt) const { +// +// for (std::list::const_iterator it = dependencies.begin() ; +// it != dependencies.end() ; it++) { +// +// (*it)->execute(stmt); +// +// } +// +// std::cout << statement << std::endl; +// +// if (statement != "") { +// stmt->executeQuery(statement); +// } +// +//} + +void CreatedDataObject::printStmt(void) { + /*DASDataObject::printStmt(); + + std::string statement; + statement = statement.append("insert into ").append(getDataObject()->getType().getName()).append("(").append(columns).append(") values(").append(values).append(");"); + + std::cout << statement << std::endl;*/ + +} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/DASColumnNotFoundException.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/DASColumnNotFoundException.cpp new file mode 100644 index 0000000000..be40dd89f0 --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/DASColumnNotFoundException.cpp @@ -0,0 +1,32 @@ +/* + * 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/DASColumnNotFoundException.h" + +namespace apache { + namespace das { + namespace rdb { + +DASColumnNotFoundException::DASColumnNotFoundException(std::string message) : std::exception(message.c_str()) {} + +DASColumnNotFoundException::~DASColumnNotFoundException(void) {} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/DASDataObject.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/DASDataObject.cpp new file mode 100644 index 0000000000..f04d9dd7a5 --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/DASDataObject.cpp @@ -0,0 +1,259 @@ +/* + * 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/ModifiedDataObject.h" + +namespace apache { + namespace das { + namespace rdb { + +DASDataObject::DASDataObject(const Table& table, commonj::sdo::DataObjectPtr dataObject, + commonj::sdo::ChangeSummaryPtr changeSummary) : PKObject(table) { + + commonj::sdo::SettingList* settingList = 0; + this->changeSummary = changeSummary; + occChecked = false; + this->dataObject = dataObject; + bool modifiedOnGraph = changeSummary->isDeleted(dataObject) || changeSummary->isModified(dataObject); + + if (modifiedOnGraph) { + settingList = &changeSummary->getOldValues(dataObject); + } + + std::map settingMap; + const std::map columns = table.getColumns(); + std::string statement; + unsigned int pkColumnCount = table.getPKColumnCount(); + unsigned int pkCount = 0; + + if (modifiedOnGraph) { + + for (int i = 0 ; i < settingList->size() ; i++) { + settingMap.insert(std::make_pair((*settingList)[i].getProperty().getName(), &(*settingList)[i])); + } + + } + + for (std::map::const_iterator columnsIterator = columns.begin() ; + columnsIterator != columns.end() && pkColumnCount > pkCount ; columnsIterator++) { + const Column& column = *columnsIterator->second; + + if (column.isPK()) { + + if (modifiedOnGraph) { + + std::map::const_iterator settingIterator = + settingMap.find(column.getPropertyName()); + + if (settingIterator != settingMap.end()) { + + if (settingIterator->second->isNull() || !settingIterator->second->isSet()) { + //throw exception + } + + ColumnData* oldPKData = new ColumnData(column, *settingIterator->second); + addPrimaryKey(column.getPropertyName(), + *(oldPKData)); + + continue; + + } + + } + + if (dataObject->isNull(column.getPropertyName()) || !dataObject->isSet(column.getPropertyName())) { + //throw exception + } + + addPrimaryKey(column.getPropertyName(), *(new ColumnData(column, dataObject))); + + } + + } + +} + +bool DASDataObject::isOCCChecked(void) const { + return occChecked; +} + +void DASDataObject::setOCCChecked(bool occChecked) { + this->occChecked = occChecked; +} + +long DASDataObject::getOldOCC(void) const { + const Column* occCol = getTable().getOCCColumn(); + + if (occCol != 0) { + + try { + const commonj::sdo::Setting& setting = changeSummary->getOldValue(dataObject, *dataObject->getInstanceProperty(occCol->getPropertyName())); + + if (!setting.isNull() && setting.isSet()) { + return setting.getIntValue(); + } + + } catch (commonj::sdo::SDOIndexOutOfRangeException&) { + return getNewOCC(); + } + + } + + return 0; + +} + +long DASDataObject::getNewOCC(void) const { + const Column* occCol = getTable().getOCCColumn(); + + if (occCol != 0) { + + if (dataObject->isSet(occCol->getPropertyName()) && !dataObject->isNull(occCol->getPropertyName())) { + return dataObject->getInt(occCol->getName()); + } + + } + + return 0; + +} + +void DASDataObject::printStmt() { + std::cout << "[" << getTable().getTableName() << "]" << std::endl; + + for (std::list::iterator it = updateStatements.begin() ; it != updateStatements.end() ; it++) { + std::cout << *it << std::endl; + } + + std::cout << std::endl; + +} + +DASDataObject::~DASDataObject(void) { + + for (std::map::iterator it = fks.begin() ; it != fks.end() ; it++) { + delete it->second; + } + +} + +const commonj::sdo::DataObjectPtr DASDataObject::getDataObject(void) const { + return dataObject; +} + +std::string DASDataObject::getWhereStmt(void) const { + std::string stmt = "where "; + const KeyDataList& pks = getPrimaryKeys(); + unsigned int i = 1; + + for (KeyDataList::const_iterator it = pks.begin() ; it != pks.end() ; it++) { + stmt.append(getTable().getTableName() + "." + it->second->getColumn().getName()).append("=").append(/*"2"*/it->second->toSQL()); + + if (i != pks.size()) { + stmt.append(" and "); + } + + i++; + + } + + if (!isOCCChecked()) { + const Column* occCol = getTable().getOCCColumn(); + + if (occCol != 0) { + stmt.append(" and ").append(occCol->getName()).append("=").append(StringWrapper::toString(getOldOCC())); + } + + } + + return stmt; + +} + +std::string DASDataObject::getStatement(void) const { + return ""; +} + +RelationshipStatement& DASDataObject::addFK(const Relationship& relationship, const KeyDataList* keyDataList) { + std::map::iterator it = fks.find(relationship.getName()); + RelationshipStatement* relatStmt; + + if (it == fks.end()) { + relatStmt = new RelationshipStatement(relationship, keyDataList); + relatStmt->setDASDataObject(*this); + fks.insert(std::make_pair(relationship.getName(), relatStmt)); + + } else if (keyDataList != 0) { + relatStmt = it->second; + relatStmt->setFKList(keyDataList); + + } + + return *relatStmt; + +} + +void DASDataObject::execute(StatementPtr stmt) { + std::string statement = getStatement(); + + if (statement != "") { + const Column* occColumn = getTable().getOCCColumn(); + bool noData = false; + ResultSetPtr rs; + + try { + rs = stmt->executeQuery(statement); + + } catch (SQLException& ex) { + + if (ex.getODBCReturnCode() == SQL_NO_DATA) { + noData = true; + } else { + throw; + } + + } + + if (occColumn != 0 && !isOCCChecked()) { + + if (noData || rs->getRowCount() == 0) { + throw DASOptimisticConcurrencyControlException(); + } else { + setOCCChecked(true); + } + + } + + } + + for (std::list::const_iterator it = dependencies.begin() ; + it != dependencies.end() ; it++) { + + (*it)->execute(stmt); + + } + +} + +void DASDataObject::addDependency(RelationshipStatement& relationshipStatement) { + dependencies.push_back(&relationshipStatement); +} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/DASFactoryImpl.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/DASFactoryImpl.cpp new file mode 100644 index 0000000000..e28f5e6d3a --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/DASFactoryImpl.cpp @@ -0,0 +1,43 @@ +/* + * 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/DASFactoryImpl.h" + +namespace apache { + namespace das { + namespace rdb { + +DASFactoryImpl::DASFactoryImpl(void) {} + +DASFactoryImpl::~DASFactoryImpl(void) {} + +DAS* DASFactoryImpl::createDAS(Connection& connection) { + return new DASImpl(connection); +} + +DAS* DASFactoryImpl::createDAS(const Config& config, Connection& connection) { + return new DASImpl(config, connection); +} + +DAS* DASFactoryImpl::createDAS(const Config& config) { + return new DASImpl(config); +} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/DASImpl.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/DASImpl.cpp new file mode 100644 index 0000000000..eab18ab980 --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/DASImpl.cpp @@ -0,0 +1,161 @@ +/* + * 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/DASImpl.h" + +namespace apache { + namespace das { + namespace rdb { + +DASFactory* DASImpl::FACTORY = new DASFactoryImpl(); + +DASImpl::DASImpl(Connection& inConnection) { + /*if (FACTORY == 0) { + FACTORY = new DASFactoryImpl(); + }*/ + + createdCommands = new std::list(); + config = new ConfigImpl(); + setConnection(&inConnection); + +} + +DASImpl::DASImpl(const Config& config, Connection& inConnection) { + /*if (FACTORY == 0) { + FACTORY = new DASFactoryImpl(); + }*/ + + createdCommands = new std::list(); + this->config = new ConfigImpl(config); + setConnection(&inConnection); + +} + +DASImpl::DASImpl(const Config& config) { + /*if (FACTORY == 0) { + FACTORY = new DASFactoryImpl(); + }*/ + + createdCommands = new std::list(); + this->config = new ConfigImpl((ConfigImpl&) config); + +} + +DASImpl::~DASImpl() { + std::list::iterator it; + + for (it = createdCommands->begin() ; it != createdCommands->end() ; it++) { + delete **it; + delete *it; + + } + + delete createdCommands; + delete config; + +} + +DASFactory& DASImpl::getFACTORY(void) { + return *FACTORY; +} + +void DASImpl::setConnection(Connection* aConnection) { + connection = aConnection; +} + +Connection* DASImpl::getConnection(void) { + return connection; +} + +void DASImpl::releaseResources(void) { + closeConnection(); +} + +CommandPtr DASImpl::getCommand(std::string commandName) { + std::string commandSQL = config->getCommand(commandName); + + return createCommand(commandSQL); + +} + +CommandPtr DASImpl::createCommand(std::string sql) { + CommandPtr command = 0; + //trim(inSql); + char firstChar = toupper(sql[0]); + + switch (firstChar) { + case 'S': + command = new ReadCommandImpl(*this, sql); + break; + + default : + command = new CommandImpl(*this, sql); + + } + + std::list::iterator it; + + for (it = createdCommands->begin() ; it != createdCommands->end() ; ) { + + if (**it) { + it++; + + } else { + std::list::iterator aux = it; + it++; + createdCommands->erase(aux); + + } + + } + + createdCommands->push_back(new CommandPtr(command, false)); + return command; + +} + +void DASImpl::closeConnection(void) { + + if (connection != 0) { + + //try { + delete connection; + connection = 0; + //} catch (SQLException e) { + // throw new RuntimeException(e); + //} + + } + +} + +const ::apache::das::Config& DASImpl::getConfig(void) const { + return *((Config*) config); +} + +void DASImpl::applyChanges(commonj::sdo::DataObjectPtr root) { + ApplyChanges(*this, root); + commonj::sdo::ChangeSummaryPtr csummary = root->getChangeSummary(); + csummary->endLogging(); + csummary->beginLogging(); + +} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/DASInvalidColumnNameException.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/DASInvalidColumnNameException.cpp new file mode 100644 index 0000000000..a199a7f0d5 --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/DASInvalidColumnNameException.cpp @@ -0,0 +1,32 @@ +/* + * 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/DASInvalidColumnNameException.h" + +namespace apache { + namespace das { + namespace rdb { + +DASInvalidColumnNameException::DASInvalidColumnNameException(std::string message) : std::exception(message.c_str()) {} + +DASInvalidColumnNameException::~DASInvalidColumnNameException(void) {} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/DASInvalidRelationshipNameException.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/DASInvalidRelationshipNameException.cpp new file mode 100644 index 0000000000..9db5b4665a --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/DASInvalidRelationshipNameException.cpp @@ -0,0 +1,32 @@ +/* + * 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/DASInvalidRelationshipNameException.h" + +namespace apache { + namespace das { + namespace rdb { + +DASInvalidRelationshipNameException::DASInvalidRelationshipNameException(std::string message) : std::exception(message.c_str()) {} + +DASInvalidRelationshipNameException::~DASInvalidRelationshipNameException(void) {} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/DASInvalidSDOTypeException.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/DASInvalidSDOTypeException.cpp new file mode 100644 index 0000000000..e924dd9cdf --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/DASInvalidSDOTypeException.cpp @@ -0,0 +1,32 @@ +/* + * 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/DASInvalidSDOTypeException.h" + +namespace apache { + namespace das { + namespace rdb { + +DASInvalidSDOTypeException::DASInvalidSDOTypeException(std::string message) : std::exception(message.c_str()) {} + +DASInvalidSDOTypeException::~DASInvalidSDOTypeException(void) {} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/DASInvalidSQLTypeException.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/DASInvalidSQLTypeException.cpp new file mode 100644 index 0000000000..d7b16547df --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/DASInvalidSQLTypeException.cpp @@ -0,0 +1,32 @@ +/* + * 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/DASInvalidSQLTypeException.h" + +namespace apache { + namespace das { + namespace rdb { + +DASInvalidSQLTypeException::DASInvalidSQLTypeException(std::string message) : std::exception(message.c_str()) {} + +DASInvalidSQLTypeException::~DASInvalidSQLTypeException(void) {} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/DASInvalidTableNameException.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/DASInvalidTableNameException.cpp new file mode 100644 index 0000000000..5f578d2130 --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/DASInvalidTableNameException.cpp @@ -0,0 +1,32 @@ +/* + * 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/DASInvalidTableNameException.h" + +namespace apache { + namespace das { + namespace rdb { + + DASInvalidTableNameException::DASInvalidTableNameException(std::string message) : std::exception(message.c_str()) {} + +DASInvalidTableNameException::~DASInvalidTableNameException(void) {} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/DASOptimisticConcurrencyControlException.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/DASOptimisticConcurrencyControlException.cpp new file mode 100644 index 0000000000..983a1b0def --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/DASOptimisticConcurrencyControlException.cpp @@ -0,0 +1,32 @@ +/* + * 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/DASOptimisticConcurrencyControlException.h" + +namespace apache { + namespace das { + namespace rdb { + +DASOptimisticConcurrencyControlException::DASOptimisticConcurrencyControlException(std::string message) : std::exception(message.c_str()) {} + +DASOptimisticConcurrencyControlException::~DASOptimisticConcurrencyControlException(void) {} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/DASPrimaryKeyNotFoundException.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/DASPrimaryKeyNotFoundException.cpp new file mode 100644 index 0000000000..15464c742a --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/DASPrimaryKeyNotFoundException.cpp @@ -0,0 +1,32 @@ +/* + * 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/DASPrimaryKeyNotFoundException.h" + +namespace apache { + namespace das { + namespace rdb { + +DASPrimaryKeyNotFoundException::DASPrimaryKeyNotFoundException(std::string message) : std::exception(message.c_str()) {} + +DASPrimaryKeyNotFoundException::~DASPrimaryKeyNotFoundException(void) {} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/DeteledDataObject.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/DeteledDataObject.cpp new file mode 100644 index 0000000000..f39d4136bb --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/DeteledDataObject.cpp @@ -0,0 +1,41 @@ +/* + * 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/DeletedDataObject.h" + +namespace apache { + namespace das { + namespace rdb { + +DeletedDataObject::DeletedDataObject(const Table& table, commonj::sdo::DataObjectPtr dataObject, + commonj::sdo::ChangeSummaryPtr changeSummary) + : DASDataObject(table, dataObject, changeSummary) {} + +DeletedDataObject::~DeletedDataObject(void) {} + +std::string DeletedDataObject::getStatement(void) const { + std::string ret = "delete from "; + ret.append(getTable().getTableName()).append(" ").append(getWhereStmt()).append(";"); + + return ret; + +} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/GraphBuilder.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/GraphBuilder.cpp new file mode 100644 index 0000000000..7676df0291 --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/GraphBuilder.cpp @@ -0,0 +1,213 @@ +/* + * 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/GraphBuilder.h" + +namespace apache { + namespace das { + namespace rdb { + +GraphBuilder::GraphBuilder(const ConfigImpl& config, ResultSetPtr resultSet) { + graphBuilderMetaData = new GraphBuilderMetaData(config, resultSet->getResultSetMetaData()) ; + commonj::sdo::DataFactoryPtr dataFactory = graphBuilderMetaData->createGraph(); + + this->resultSet = resultSet; + const std::map& tables = graphBuilderMetaData->getTables(); + + while (resultSet->next()) { + + std::map::const_iterator it; + for (it = tables.begin() ; it != tables.end() ; it++) { + Table* table = it->second; + + std::list* tableList; + TableData* tableData = new TableData(*table, resultSet); + + if (!tableData->hasPK()) { + delete tableData; + continue; + + } + + std::map*>::iterator it2 = + tablesData.find(table->getTableName()); + + if (it2 == tablesData.end()) { + tableList = new std::list(); + tablesData.insert(std::make_pair(table->getTableName(), tableList)); + + } else { + tableList = it2->second; + } + + std::list::const_iterator it3; + bool duplicated = false; + + for (it3 = tableList->begin() ; it3 != tableList->end() ; it3++) { + + if (*tableData == **it3) { + delete tableData; + duplicated = true; + break; + + } + + } + + if (!duplicated) { + tableList->push_back(tableData); + } + + } + + } + + int a = resultSet->getRowCount(); + + root = dataFactory->create(config.getURI(), DAS_ROOT_NAME); + std::map*>::iterator it; + + if (tablesData.size() > 0) { + + for (it = tablesData.begin() ; it != tablesData.end() ; it++) { + std::list& tableList = *it->second; + std::list::iterator it2; + + for (it2 = tableList.begin() ; it2 != tableList.end() ; it2++) { + (*it2)->populateDataGraph(*this); + } + + } + + std::map::const_iterator it2; + std::map& relationships = graphBuilderMetaData->getRelationships(); + std::map*> tablesDataByPK; + std::map*>::iterator it3; + for (it3 = tablesData.begin() ; it3 != tablesData.end() ; it3++) { + std::map* tableList = new std::map(); + std::list::iterator it4; + + for (it4 = it3->second->begin() ; it4 != it3->second->end() ; it4++) { + TableData* tableData = *it4; + tableList->insert(std::make_pair(&tableData->getPrimaryKeys(), tableData)); + + } + + tablesDataByPK.insert(std::make_pair(it3->first, tableList)); + + } + + for (it2 = tables.begin() ; it2 != tables.end() ; it2++) { + RelationshipWrapper relationshipWrapper; + std::list& fkTableRelationships = relationshipWrapper.getRelationshipsByTableName(relationships, it2->first, false); + + std::list::iterator relationshipIterator; + for (relationshipIterator = fkTableRelationships.begin() ; + relationshipIterator != fkTableRelationships.end() ; relationshipIterator++) { + + std::list& fkTablesList = + *((std::map*>::iterator) tablesData.find( + (*relationshipIterator)->getFKTableName()))->second; + + std::map& pkTablesData = + *((std::map*>::iterator) + tablesDataByPK.find((*relationshipIterator)->getPKTableName()))->second; + + std::list::iterator tableDataIterator; + for (tableDataIterator = fkTablesList.begin() ; tableDataIterator != + fkTablesList.end() ; tableDataIterator++) { + + TableData& fkTableData = **tableDataIterator; + const std::map& keyPairs = (*relationshipIterator)->getKeyPairs(); + std::map::const_iterator keyPairIterator; + KeyDataList fksColumnList; + + for (keyPairIterator = keyPairs.begin() ; keyPairIterator != keyPairs.end() ; + keyPairIterator++) { + + const KeyPair& keyPair = *keyPairIterator->second; + ColumnData* columnData = fkTableData. + getColumnData(keyPair.getFKColumnName()); + + fksColumnList.insert(std::make_pair(keyPair.getPKColumnName(), + columnData)); + + } + + std::map::iterator pkTablaDataIterator = + pkTablesData.find(&fksColumnList); + + if (pkTablaDataIterator != pkTablesData.end()) { + TableData& pkTableData = *pkTablaDataIterator->second; + + if ((*relationshipIterator)->isMany()) { + pkTableData.getGraphObject()->getList((*relationshipIterator)->getName().c_str()). + append(fkTableData.getGraphObject()); + + } else { + pkTableData.getGraphObject()->setDataObject((*relationshipIterator)->getName().c_str(), + fkTableData.getGraphObject()); + + } + + } + + } + + } + + } + + std::map*>::iterator tablesDataByPKIterator; + for (tablesDataByPKIterator = tablesDataByPK.begin() ; tablesDataByPKIterator != + tablesDataByPK.end() ; tablesDataByPKIterator++) { + + delete tablesDataByPKIterator->second; + + } + + } + +} + +GraphBuilder::~GraphBuilder(void) { + std::map*>::iterator it; + std::list::iterator it2; + + for (it = tablesData.begin() ; it != tablesData.end() ; it++) { + std::list* tableList = it->second; + + for (it2 = tableList->begin() ; it2 != tableList->end() ; it2++) { + delete *it2; + } + + delete tableList; + + } + + delete graphBuilderMetaData; + +} + +commonj::sdo::DataObjectPtr GraphBuilder::getRoot(void) const { + return root; +} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/GraphBuilderMetaData.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/GraphBuilderMetaData.cpp new file mode 100644 index 0000000000..81d3962998 --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/GraphBuilderMetaData.cpp @@ -0,0 +1,302 @@ +/* + * 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/GraphBuilderMetaData.h" + +namespace apache { + namespace das { + namespace rdb { + +GraphBuilderMetaData::GraphBuilderMetaData(const ConfigImpl& config, const ResultSetMetaData& resultSetMetaData) { + this->resultSetMetaData = &resultSetMetaData; + this->config = &config; + graphTables = new std::map(); + const std::map& configRelationships = config.getRelationships(); + relationships = new std::map(); + std::map::const_iterator relationshipIterator; + + unsigned int colCount = resultSetMetaData.getColumnCount(); + std::map*> tablesColumns; + + for (unsigned int i = 0 ; i < colCount ; i++) { + std::string columnName = resultSetMetaData.getColumnName(i); + SQLSMALLINT columnSQLType = resultSetMetaData.getSQLType(i); + std::string columnTableName = resultSetMetaData.getTableName(i); + std::map::iterator tableIterator = graphTables-> + find(columnTableName); + + Table* table = 0; + const Table* configTable = config.getTable(columnTableName); + + if (tableIterator == graphTables->end()) { + table = new Table(columnTableName); + + if (configTable != 0) { + table->setTypeName(configTable->getTypeName()); + } + + graphTables->insert(std::make_pair(table->getTableName(), table)); + + } else { + table = tableIterator->second; + } + + if (configTable == 0) { + table->addColumn(columnName, columnSQLType); + } else { + Column* column = (Column*) configTable->getColumn(columnName); + + if (column != 0) { + table->addColumn(Column(*column)); + } else { + table->addColumn(columnName, columnSQLType); + } + + } + + } + + std::map::iterator tableIterator; + for (tableIterator = graphTables->begin() ; tableIterator != graphTables->end() ; + tableIterator++) { + + Table& table = *tableIterator->second; + const Table* configTable = config.getTable(table.getTableName()); + bool hasPK = false; + + if (configTable != 0 && configTable->getPKColumnCount() == + table.getPKColumnCount() && configTable->getPKColumnCount() != 0) { + hasPK = true; + + } + + const std::map& tableColumns = table.getColumns(); + std::map::const_iterator columnIterator; + + if (!hasPK) { + Column* column = table.getColumn("ID"); + + if (column != 0) { + column->setPK(true); + hasPK = true; + + } + + + } + + if (!hasPK) { + + if (configTable == 0 || configTable->getColumns().size() == 0) { + + for (columnIterator = tableColumns.begin() ; + columnIterator != tableColumns.end() ; columnIterator++) { + ((Column*) columnIterator->second)->setPK(true); + } + + } + + } + + } + + for (relationshipIterator = configRelationships.begin() ; + relationshipIterator != configRelationships.end() ; relationshipIterator++) { + + Relationship& relationship = *relationshipIterator->second; + bool contains = true; + const std::map& keyPairs = relationship.getKeyPairs(); + std::map::const_iterator keyPairIterator; + std::map::iterator pkTableIterator = + graphTables->find(relationship.getPKTableName()); + + std::map::iterator fkTableIterator = + graphTables->find(relationship.getFKTableName()); + + if (pkTableIterator == graphTables->end() || + fkTableIterator == graphTables->end()) { + continue; + } + + Table& pkTable = *pkTableIterator->second; + Table& fkTable = *fkTableIterator->second; + + for (keyPairIterator = keyPairs.begin() ; keyPairIterator != keyPairs.end() ; + keyPairIterator++) { + + const KeyPair& keyPair = *keyPairIterator->second; + Column* pkColumn = pkTable.getColumn(keyPair.getPKColumnName()); + Column* fkColumn = fkTable.getColumn(keyPair.getFKColumnName()); + + if (fkColumn == 0 || pkColumn == 0 || !pkColumn->isPK() || + fkColumn->getSQLType() != pkColumn->getSQLType()) { + + contains = false; + break; + + } + + } + + if (contains) { + relationships->insert(std::make_pair( + relationship.getPKTableName() + "." + relationship.getFKTableName(), + new Relationship(relationship))); + + } + + } + + for (tableIterator = graphTables->begin() ; tableIterator != graphTables->end() ; + tableIterator++) { + + Table& table = *tableIterator->second; + const std::map& tableColumns = table.getColumns(); + std::map::const_iterator columnIterator; + + for (columnIterator = tableColumns.begin() ; + columnIterator != tableColumns.end() ; columnIterator++) { + + std::string columnName = columnIterator->second->getName(); + + if (columnName.size() > 3 && + columnName.substr(columnName.size() - 3, 3) == "_ID") { + + std::string pkTableName = columnName.substr(0, columnName.size() - 3); + std::string pkXfk = pkTableName + "." + table.getTableName(); + + std::map::iterator pkTableIterator = + graphTables->find(pkTableName); + + if (pkTableIterator == graphTables->end()) { + continue; + } + + Column* pkColumn = pkTableIterator->second->getColumn("ID"); + if (pkColumn == 0 || + columnIterator->second->getSQLType() != pkColumn->getSQLType()) { + continue; + } + + std::map::iterator relationshipIterator = + relationships->find(pkXfk); + + if (relationshipIterator == relationships->end() && + pkColumn->isPK()) { + + if (pkTableIterator->second->getPKColumnCount() == 1) { + Relationship* relationship = + new Relationship(pkTableName, table.getTableName()); + + relationship->addKeyPair("ID", columnName); + relationships->insert(std::make_pair(relationship->getName(), relationship)); + + } + + } + + } + + } + + } + +} + +GraphBuilderMetaData::~GraphBuilderMetaData(void) { + std::map::iterator itTables; + std::map::iterator itRelationships; + + for (itTables = graphTables->begin() ; itTables != graphTables->end() ; itTables++) { + delete itTables->second; + } + + for (itRelationships = relationships->begin() ; itRelationships != relationships->end() ; itRelationships++) { + delete itRelationships->second; + } + + delete graphTables; + delete relationships; + +} + +commonj::sdo::DataFactoryPtr GraphBuilderMetaData::createGraph(void) const { + commonj::sdo::DataFactoryPtr dataFactory = commonj::sdo::DataFactory::getDataFactory(); + dataFactory->addType(config->getURI(), DAS_ROOT_NAME); + dataFactory->addPropertyToType(config->getURI(), DAS_ROOT_NAME, "ChangeSummary", SDO_NAMESPACE, "ChangeSummary", false, false, true); + + std::map::const_iterator it; + std::map::const_iterator it2; + + for (it = graphTables->begin() ; it != graphTables->end() ; it++) { + Table& table = *(it->second); + std::string tableName = table.getTypeName(); + + dataFactory->addType(config->getURI(), tableName.c_str()); + dataFactory->addPropertyToType(config->getURI(), DAS_ROOT_NAME, + tableName.c_str(), config->getURI(), tableName.c_str(), true, false, true); + + } + + for (it = graphTables->begin() ; it != graphTables->end() ; it++) { + it->second->createGraph(*this, dataFactory); + } + + for (it2 = relationships->begin() ; it2 != relationships->end() ; it2++) { + const Relationship& relationship = *it2->second; + + dataFactory->addPropertyToType(config->getURI(), relationship.getPKTableName().c_str(), + relationship.getName().c_str(), config->getURI(), + relationship.getFKTableName().c_str(), relationship.isMany(), false, false); + + } + + return dataFactory; + +} + +const ResultSetMetaData& GraphBuilderMetaData::getResultSetMetaData(void) const { + return *resultSetMetaData; +} + +const ConfigImpl& GraphBuilderMetaData::getConfig(void) const { + return *config; +} + +std::map& GraphBuilderMetaData::getTables(void) const { + return *graphTables; +} + +Table* GraphBuilderMetaData::getTable(std::string tableName) const { + std::map::iterator it = graphTables->find(tableName); + + if (it == graphTables->end()) { + return 0; + } + + return it->second; + +} + +std::map& GraphBuilderMetaData::getRelationships(void) const { + return *relationships; +} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/KeyPair.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/KeyPair.cpp new file mode 100644 index 0000000000..30a895a82f --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/KeyPair.cpp @@ -0,0 +1,72 @@ +/* + * 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/KeyPair.h" + +namespace apache { + namespace das { + namespace rdb { + +KeyPair::KeyPair(const KeyPair& keyPair) { + pkColumnName = keyPair.pkColumnName; + fkColumnName = keyPair.fkColumnName; + relationship = keyPair.relationship; + +} + +KeyPair::KeyPair(std::string pkColumnName, std::string fkColumnName) { + StringWrapper pkColumnNameWrapper(pkColumnName); + pkColumnName = pkColumnNameWrapper.toUpper(); + StringWrapper fkColumnNameWrapper(fkColumnName); + fkColumnName = fkColumnNameWrapper.toUpper(); + + if (!pkColumnNameWrapper.isValidRDBName()) { + throw DASInvalidColumnNameException("PK column name must not contain whitespace characters!"); + } + + if (!fkColumnNameWrapper.isValidRDBName()) { + throw DASInvalidColumnNameException("FK column name must not contain whitespace characters!"); + } + + this->pkColumnName = pkColumnName; + this->fkColumnName = fkColumnName; + relationship = 0; + +} + +KeyPair::~KeyPair(void) {} + +std::string KeyPair::getPKColumnName(void) const { + return pkColumnName; +} + +std::string KeyPair::getFKColumnName(void) const { + return fkColumnName; +} + +void KeyPair::setRelationship(Relationship* relationship) { + this->relationship = relationship; +} + +Relationship* KeyPair::getRelationship(void) const { + return relationship; +} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/ModifiedDataObject.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/ModifiedDataObject.cpp new file mode 100644 index 0000000000..560684a25b --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/ModifiedDataObject.cpp @@ -0,0 +1,141 @@ +/* + * 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/ModifiedDataObject.h" + +namespace apache { + namespace das { + namespace rdb { + +ModifiedDataObject::ModifiedDataObject(const Table& table, commonj::sdo::DataObjectPtr dataObject, + commonj::sdo::ChangeSummaryPtr changeSummary) : DASDataObject(table, dataObject, changeSummary) { + + bool modifiedOnGraph = changeSummary->isCreated(dataObject) || changeSummary->isDeleted(dataObject) || changeSummary->isModified(dataObject); + const KeyDataList& columnDataList = getPrimaryKeys(); + unsigned int pkCount = 0; + unsigned int pkColumnCount = columnDataList.size(); + bool dataTypeModified = false; + //pkModified = false; + + if (modifiedOnGraph) { + sets.append("update ").append(table.getTableName()).append(" set"); + commonj::sdo::SettingList& settings = changeSummary->getOldValues(dataObject); + /*const KeyDataList& keyDataList = getPrimaryKeys(); + + for (KeyDataList::const_iterator pkIt = keyDataList.begin() ; pkIt != keyDataList.end() ; pkIt++) { + ColumnData actualColumnData(pkIt->second->getColumn(), dataObject); + + if (actualColumnData != *pkIt->second) { + pkModified = true; + break; + + } + + }*/ + + for (int i = 0 ; i < settings.size() ; i++) { + + if (settings[i].getType().isDataType()) { + + if (dataTypeModified) { + sets.append(","); + } + + std::string propName = settings[i].getProperty().getName(); + const Column* column = table.getColumnByProperty(propName); + + if (!column->isCollision() || !column->isManaged()) { + dataTypeModified = true; + sets.append(" ").append(column->getName()).append("=").append(ColumnData(*column, dataObject).toSQL()); + + } + + } + + } + + if (!dataTypeModified) { + sets = ""; + } + + } + +} + +ModifiedDataObject::~ModifiedDataObject(void) {} + +std::string ModifiedDataObject::getStatement(void) const { + + if (sets != "") { + std::string ret = sets; + const Column* occCol = getTable().getOCCColumn(); + + if (occCol != 0 && !isOCCChecked() && occCol->isManaged()) { + ret.append(",").append(occCol->getName()).append("=").append(StringWrapper::toString(getNewOCC() + 1)); + } + + ret.append(" ").append(getWhereStmt()).append(";"); + + return ret; + + } else { + return ""; + } + +} + +//bool ModifiedDataObject::isPKModified(void) const { +// return pkModified; +//} + + +// +//void ModifiedDataObject::printStmt() { +// DASDataObject::printStmt(); +// +// if (sets.size() != 0 || fks.size() != 0) { +// std::string statement; +// statement.append("update ").append(getTable().getTableName()).append(" set").append(sets); +// +// for (std::map::const_iterator it = fks.begin() ; it != fks.end() ; it++) { +// +// statement.append(" ").append(it->first).append("="); +// +// if (it->second == 0) { +// statement.append(SQL_NULL_VALUE); +// } else { +// statement.append(it->second->toSQL()); +// } +// +// } +// +// statement.append(" ").append(whereStmt).append(";"); +// +// std::cout << statement << std::endl; +// +// } +// +//} + + + + + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/ODBCTypeHelper.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/ODBCTypeHelper.cpp new file mode 100644 index 0000000000..aad3c49ad5 --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/ODBCTypeHelper.cpp @@ -0,0 +1,108 @@ +/* + * 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/ODBCTypeHelper.h" + +namespace apache { + namespace das { + namespace rdb { + +const std::string ODBCTypeHelper::getSDOType(SQLSMALLINT sqlType) { + + switch (sqlType) { + + case SQL_CHAR : + case SQL_WCHAR : + return "Character"; + + case SQL_INTEGER : + case SQL_SMALLINT : + return "Int"; + + case SQL_REAL : + return "Float"; + + case SQL_FLOAT : + case SQL_DOUBLE : + return "Double"; + + case SQL_VARCHAR : + case SQL_WVARCHAR : + return "String"; + + default : + throw DASInvalidSQLTypeException("Invalid sql type: " + sqlType + (std::string) ""); + + } + +} + +const SQLSMALLINT ODBCTypeHelper::getSQLType(const commonj::sdo::Type& type) { + std::string typeName = type.getName(); + + if ("String" == typeName) { + return SQL_WVARCHAR; + + } else if ("Double" == typeName) { + return SQL_DOUBLE; + + } else if ("Float" == typeName) { + return SQL_REAL; + + } else if ("Int" == typeName) { + return SQL_INTEGER; + + } else if ("Character" == typeName) { + return SQL_WCHAR; + + } else { + throw DASInvalidSDOTypeException((std::string) "Invalid sdo data type: " + type.getURI() + "." + type.getName() + ""); + } + +} + +const SQLSMALLINT ODBCTypeHelper::getSQLType(std::string sqlTypeName) { + sqlTypeName = StringWrapper(sqlTypeName).toLower(); + + if ("varchar" == sqlTypeName) { + return SQL_VARCHAR; + } else if ("wvarchar" == sqlTypeName) { + return SQL_WVARCHAR; + } else if ("integer" == sqlTypeName) { + return SQL_INTEGER; + } else if ("float" == sqlTypeName) { + return SQL_FLOAT; + } else if ("real" == sqlTypeName) { + return SQL_REAL; + } else if ("double" == sqlTypeName) { + return SQL_DOUBLE; + } else if ("char" == sqlTypeName) { + return SQL_CHAR; + } else if ("wchar" == sqlTypeName) { + return SQL_WCHAR; + } else if ("smallint" == sqlTypeName) { + return SQL_SMALLINT; + } else { + throw DASInvalidSQLTypeException("sql type does not exist: " + sqlTypeName); + } + +} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/PKObject.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/PKObject.cpp new file mode 100644 index 0000000000..84133b0980 --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/PKObject.cpp @@ -0,0 +1,168 @@ +/* + * 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/PKObject.h" +#include "apache/das/rdb/ColumnData.h" + +namespace apache { + namespace das { + namespace rdb { + +PKObject::PKObject(const Table& table) { + this->table = &table; + primaryKeys = new KeyDataList(); + +} + +PKObject::~PKObject(void) { + KeyDataList::const_iterator it; + + for (it = primaryKeys->begin() ; it != primaryKeys->end() ; it++) { + delete it->second; + } + + delete primaryKeys; + +} + +void PKObject::addPrimaryKey(std::string columnName, ColumnData& columnData) { + primaryKeys->insert(std::make_pair(columnName, &columnData)); +} + +const Table& PKObject::getTable(void) const { + return *table; +} + +bool PKObject::isPK(std::string columnName) const { + KeyDataList::const_iterator it = primaryKeys->find(columnName); + + return it != primaryKeys->end(); + +} + +bool PKObject::operator==(const KeyDataList* primaryKeyList) const { + + if (primaryKeys->size() != primaryKeyList->size()) { + return false; + } + + KeyDataList::const_iterator it, primaryKeyIterator; + + for (it = primaryKeyList->begin() ; it != primaryKeyList->end() ; it++) { + primaryKeyIterator = primaryKeys->find(it->first); + + if (primaryKeyIterator == primaryKeys->end()) { + return false; + + } else if (*it->second != *primaryKeyIterator->second) { + return false; + + } + + } + + return true; + +} + +bool PKObject::operator==(const PKObject& pkObject) const { + return (*this == pkObject.primaryKeys); +} + +bool PKObject::operator!=(const PKObject& pkObject) const { + return !(*this == pkObject); +} + +bool PKObject::operator!=(const KeyDataList* primaryKeyList) const { + return !(*this == primaryKeyList); +} + +const KeyDataList& PKObject::getPrimaryKeys(void) const { + return *primaryKeys; +} + +bool PKObject::operator<(const PKObject& pkObject) const { + return (*this < pkObject.primaryKeys); +} + +bool PKObject::operator<(const KeyDataList* primaryKeyList) const { + + if (primaryKeys->size() < primaryKeyList->size()) { + return true; + } else if (primaryKeys->size() > primaryKeyList->size()) { + return false; + } + + KeyDataList::const_iterator it; + + for (it = primaryKeyList->begin() ; it != primaryKeyList->end() ; it++) { + KeyDataList::const_iterator primaryKeyIterator = + primaryKeys->find(it->first); + + if (primaryKeyIterator != primaryKeys->end()) { + + if (*it->second < *primaryKeyIterator->second) { + return true; + } else if (*it->second > *primaryKeyIterator->second) { + return false; + } + + } + + } + + return false; + +} + +bool KeyDataCmp::operator() ( const KeyDataList* keyDataList1, const KeyDataList* keyDataList2 ) const { + if (keyDataList1->size() < keyDataList2->size()) { + return true; + } else if (keyDataList1->size() > keyDataList2->size()) { + return false; + } + + KeyDataList::const_iterator it; + + for (it = keyDataList2->begin() ; it != keyDataList2->end() ; it++) { + KeyDataList::const_iterator primaryKeyIterator = + keyDataList1->find(it->first); + + if (primaryKeyIterator != keyDataList1->end()) { + + if (it->second->getColumn().getSQLType() != primaryKeyIterator->second->getColumn().getSQLType()) { + return false; + } + + if (*it->second < *primaryKeyIterator->second) { + return true; + } else if (*it->second > *primaryKeyIterator->second) { + return false; + } + + } + + } + + return false; + +} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/PreparedStatement.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/PreparedStatement.cpp new file mode 100644 index 0000000000..271e340030 --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/PreparedStatement.cpp @@ -0,0 +1,42 @@ +/* + * 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/PreparedStatement.h" + +namespace apache { + namespace das { + namespace rdb { + +PreparedStatement::PreparedStatement(Connection& connection, SQLHSTMT statementHandle, string sql) + : Statement(connection, statementHandle){ + this->sql = sql; + + for(unsigned int i = 0; i < sql.size(); i++){ + if(sql.at(i) == '?') + positions.push_back(i); + } +} + + +PreparedStatement::~PreparedStatement(){ + Statement::~Statement(); +} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/ReadCommandImpl.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/ReadCommandImpl.cpp new file mode 100644 index 0000000000..c7df40dd57 --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/ReadCommandImpl.cpp @@ -0,0 +1,47 @@ +/* + * 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/ReadCommandImpl.h" + +namespace apache { + namespace das { + namespace rdb { + +ReadCommandImpl::ReadCommandImpl(DASImpl& das, std::string sqlString) : CommandImpl(das, sqlString) {} + +ReadCommandImpl::~ReadCommandImpl(void) {} + +commonj::sdo::DataObjectPtr ReadCommandImpl::executeQuery(void) { + ResultSetPtr results = statement->executeQuery(sql); + commonj::sdo::DataObjectPtr root = buildGraph(results); + root->getChangeSummary()->beginLogging(); + + return root; + +} + +commonj::sdo::DataObjectPtr ReadCommandImpl::buildGraph(ResultSetPtr resultSet) { + GraphBuilder graphBuilder((ConfigImpl&) ((DASImpl*) das)->getConfig(), resultSet); + + return graphBuilder.getRoot(); + +} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/Relationship.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/Relationship.cpp new file mode 100644 index 0000000000..32c720b49c --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/Relationship.cpp @@ -0,0 +1,206 @@ +/* + * 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/Relationship.h" + +namespace apache { + namespace das { + namespace rdb { + +Relationship::Relationship(const Relationship& relationship) { + many = relationship.many; + relationshipName = relationship.relationshipName; + pkTableName = relationship.pkTableName; + fkTableName = relationship.fkTableName; + this->keyPairs = new std::map(); + + std::map::iterator it; + for (it = relationship.keyPairs->begin() ; it != relationship.keyPairs->end() ; it++) { + KeyPair* newKP = new KeyPair(*it->second); + newKP->setRelationship(this); + this->keyPairs->insert(std::make_pair(it->first, newKP)); + + } + +} + +Relationship::Relationship(std::string pkTableName, std::string fkTableName, + std::string relationshipName) { + + StringWrapper pkTableNameWrapper(pkTableName); + StringWrapper fkTableNameWrapper(fkTableName); + StringWrapper relationshipNameWrapper(relationshipName); + pkTableName = pkTableNameWrapper.toUpper(); + fkTableName = fkTableNameWrapper.toUpper(); + + if (relationshipName == "") { + this->relationshipName = fkTableName; + } else { + + if (!relationshipNameWrapper.isValidRDBName()) { + throw DASInvalidRelationshipNameException("Relationship name must not contain whitespace characters!"); + } + + this->relationshipName = relationshipNameWrapper.toUpper(); + + } + + if (!pkTableNameWrapper.isValidRDBName()) { + throw DASInvalidTableNameException("PK Table name must not contain whitespace characters!"); + } + + if (!fkTableNameWrapper.isValidRDBName()) { + throw DASInvalidTableNameException("FK Table name must not contain whitespace characters!"); + } + + this->pkTableName = pkTableName; + this->fkTableName = fkTableName; + many = true; + keyPairs = new std::map(); + +} + +void Relationship::setMany(bool many) { + this->many = many; +} + +bool Relationship::isMany(void) const { + return many; +} + +KeyPair& Relationship::addKeyPair(std::string pkColumnName, std::string fkColumnName) { + KeyPair& newKP = newKeyPair(*(new KeyPair(pkColumnName, fkColumnName))); + newKP.setRelationship(this); + + return newKP; + +} + +KeyPair& Relationship::addKeyPair(const KeyPair& keyPair) { + KeyPair& newKP = newKeyPair(*(new KeyPair(keyPair))); + newKP.setRelationship(this); + + return newKP; + +} + +KeyPair& Relationship::newKeyPair(KeyPair& keyPair) { + const KeyPair* configKeyPair = getKeyPair(keyPair.getPKColumnName(), keyPair.getFKColumnName()); + + if (configKeyPair == 0) { + keyPairs->insert(std::make_pair(keyPair.getPKColumnName() + "." + keyPair.getFKColumnName(), &keyPair)); + + return keyPair; + + } + + return (KeyPair&) *configKeyPair; + +} + +std::string Relationship::getName(void) const { + return relationshipName; +} + +Relationship::~Relationship(void) { + std::map::iterator it; + + for (it = keyPairs->begin() ; it != keyPairs->end() ; it++) { + delete it->second; + } + + delete keyPairs; + +} + +std::string Relationship::getPKTableName(void) const { + return pkTableName; +} + +std::string Relationship::getFKTableName(void) const { + return fkTableName; +} + +const std::map& Relationship::getKeyPairs(void) const { + return (const std::map&) *keyPairs; +} + +const KeyPair* Relationship::getKeyPair(std::string pkColumnName, std::string fkColumnName) const { + std::map::iterator it = keyPairs-> + find(pkColumnName + "." + fkColumnName); + + if (it == keyPairs->end()) { + return 0; + } + + return it->second; + +} + +std::list* Relationship::getKeyPair(std::string columnName, bool pkColumn) const { + std::map::const_iterator it; + std::list* ret = new std::list(); + + for (it = keyPairs->begin() ; it != keyPairs->end() ; it++) { + std::string actualColumnName; + + if (pkColumn) { + actualColumnName = it->second->getPKColumnName(); + } else { + actualColumnName = it->second->getFKColumnName(); + } + + if (columnName == actualColumnName) { + ret->push_back(it->second); + } + + } + + return ret; + +} + + +bool Relationship::containsColumn(std::string columnName, bool pkColumn) const { + std::map::const_iterator it; + + for (it = keyPairs->begin() ; it != keyPairs->end() ; it++) { + + if (pkColumn) { + + if (it->second->getPKColumnName() == columnName) { + return true; + } + + } else { + + if (it->second->getFKColumnName() == columnName) { + return true; + } + + } + + } + + return false; + +} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/RelationshipStatement.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/RelationshipStatement.cpp new file mode 100644 index 0000000000..a7b23727a9 --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/RelationshipStatement.cpp @@ -0,0 +1,128 @@ +/* + * 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/RelationshipStatement.h" +#include "apache/das/rdb/Relationship.h" + +namespace apache { + namespace das { + namespace rdb { + +RelationshipStatement::RelationshipStatement(const Relationship& relationship, const KeyDataList* keyDataList) { + this->relationship = &relationship; + this->keyDataList = keyDataList; + executed = false; + +} + +void RelationshipStatement::setDASDataObject(DASDataObject& dataObject) { + this->dataObject = &dataObject; +} + +RelationshipStatement::~RelationshipStatement(void) {} + +bool RelationshipStatement::isUnset(void) const { + return keyDataList == 0; +} + +DASDataObject& RelationshipStatement::getDASDataObject(void) const { + return *dataObject; +} + +void RelationshipStatement::setFKList(const KeyDataList* keyDataList) { + this->keyDataList = keyDataList; +} + +void RelationshipStatement::execute(StatementPtr statement) { + + if (!executed) { + const std::map& keyPairs = relationship->getKeyPairs(); + std::string stmt; + stmt.append("update ").append(relationship->getFKTableName()).append(" set"); + unsigned int i = 1; + + for (std::map::const_iterator it = keyPairs.begin() ; it != keyPairs.end() ; it++) { + stmt.append(" ").append(it->second->getFKColumnName()).append("="); + + if (keyDataList == 0) { + stmt.append(SQL_NULL_VALUE); + } else { + KeyDataList::const_iterator pkIt = keyDataList->find(it->second->getPKColumnName()); + + if (pkIt == keyDataList->end()) { + //throw exception + } + + stmt.append(pkIt->second->toSQL()); + + } + + if (i != keyPairs.size()) { + stmt.append(","); + } + + i++; + + } + + const Column* occCol = 0; + if (!dataObject->isOCCChecked()) { + occCol = dataObject->getTable().getOCCColumn(); + + if (occCol != 0 && occCol->isManaged()) { + stmt.append(occCol->getName()).append("=").append(StringWrapper::toString(dataObject->getNewOCC() + 1)); + } + + } + + + stmt.append(" ").append(dataObject->getWhereStmt()).append(";"); + bool noData = false; + ResultSetPtr rs; + + try { + rs = statement->executeQuery(stmt); + } catch (SQLException& ex) { + + if (ex.getODBCReturnCode() == SQL_NO_DATA) { + noData = true; + } else { + throw; + } + + } + + if (!dataObject->isOCCChecked()) { + + if (occCol != 0 && (noData || rs->getRowCount() == 0)) { + throw DASOptimisticConcurrencyControlException(); + } else { + dataObject->setOCCChecked(true); + } + + } + + executed = true; + + } + +} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/RelationshipWrapper.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/RelationshipWrapper.cpp new file mode 100644 index 0000000000..22bc41277a --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/RelationshipWrapper.cpp @@ -0,0 +1,117 @@ +/* + * 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/RelationshipWrapper.h" + +namespace apache { + namespace das { + namespace rdb { + +RelationshipWrapper::RelationshipWrapper(void) {} + +RelationshipWrapper::~RelationshipWrapper(void) { + std::list*>::iterator it; + + for (it = relationshipLists.begin() ; it != relationshipLists.end() ; it++) { + delete *it; + } + +} + +std::list& RelationshipWrapper::getRelationshipsByTableName( + const std::map& relationships, std::string tableName, + bool pkTable) { + + std::list* relationshipList = new std::list(); + std::map::const_iterator it; + + for (it = relationships.begin() ; it != relationships.end() ; it++) { + + if (pkTable) { + + if (it->second->getPKTableName() == tableName) { + relationshipList->push_back(it->second); + } + + } else { + + if (it->second->getFKTableName() == tableName) { + relationshipList->push_back(it->second); + } + + } + + } + + relationshipLists.push_back(relationshipList); + + return *relationshipList; + +} + +std::list& RelationshipWrapper::getRelationshipsByTableName(const std::list< + Relationship*>& relationships, std::string tableName, + bool pkTable) { + + std::list* relationshipList = new std::list(); + std::list::const_iterator it; + + for (it = relationships.begin() ; it != relationships.end() ; it++) { + + if (pkTable) { + + if ((*it)->getPKTableName() == tableName) { + relationshipList->push_back(*it); + } + + } else { + + if ((*it)->getFKTableName() == tableName) { + relationshipList->push_back(*it); + } + + } + + } + + relationshipLists.push_back(relationshipList); + + return *relationshipList; + +} + +void RelationshipWrapper::free(std::list& relationshipList) { + std::list*>::iterator it; + + for (it = relationshipLists.begin() ; it != relationshipLists.end() ; it++) { + + if (*it == &relationshipList) { + delete *it; + relationshipLists.erase(it); + + return; + + } + + } + +} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/ResultSet.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/ResultSet.cpp new file mode 100644 index 0000000000..4870f4fbfa --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/ResultSet.cpp @@ -0,0 +1,356 @@ +/* + * 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/ResultSet.h" + +namespace apache { + namespace das { + namespace rdb { + +ResultSet::ResultSet(StatementPtr aStmt) { + stmt = aStmt; + metaData = new ResultSetMetaData(*this); + +} + +ResultSet::~ResultSet(void) { + ResultSetObject::free(); + delete metaData; + +} + +const ResultSetMetaData& ResultSet::getResultSetMetaData(void) const { + return *metaData; +} + +StatementPtr ResultSet::getStatement(void) const { + return stmt; +} + +SQLINTEGER ResultSet::getSQLInteger(unsigned int columnIndex) const { + SQLINTEGER sqlPtr = 0; + SQLSMALLINT length = 0; + SQLINTEGER aux = 0; + + if (metaData->getSQLType(columnIndex) == SQL_INTEGER) { + SQLRETURN result = SQLGetData(stmt->getODBCStatement(), columnIndex + 1, SQL_C_LONG, &sqlPtr, 0, &aux); +SQLINTEGER error; + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)){ +SQLCHAR sqlStat; + +SQLCHAR * message = new SQLCHAR[100]; + SQLSMALLINT messageLength; + SQLGetDiagRec(SQL_HANDLE_DBC, stmt->getConnection().getODBCConnection(),1, + &sqlStat, &error,message,100,&messageLength); + + + + string error("Error to establish the connection.\nSQLSTATE: "); + error += reinterpret_cast(&sqlStat); + throw SQLException(result, error); + } + + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + throw SQLException(result, "Error on getting database data!"); + + } else { + throw DASInvalidSQLTypeException("Column sql type on index " + columnIndex + (std::string) " is not integer!"); + } + + return sqlPtr; + +} + +SQLINTEGER ResultSet::getSQLInteger(std::string tableName, std::string columnName) const { + return getSQLInteger(metaData->getColumnIndex(tableName, columnName)); +} + +SQLSMALLINT ResultSet::getSQLSmallInt(unsigned int columnIndex) const { + SQLSMALLINT sqlPtr = 0; + SQLSMALLINT length = 0; + SQLINTEGER aux = 0; + + if (metaData->getSQLType(columnIndex) == SQL_SMALLINT) { + SQLRETURN result = SQLGetData(stmt->getODBCStatement(), columnIndex + 1, SQL_C_SHORT, &sqlPtr, 0, &aux); + + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + throw SQLException(result, "Error on getting database data!"); + + } else { + throw DASInvalidSQLTypeException("Column sql type on index " + columnIndex + (std::string) " is not integer!"); + } + + return sqlPtr; + +} + +SQLSMALLINT ResultSet::getSQLSmallInt(std::string tableName, std::string columnName) const { + return getSQLSmallInt(metaData->getColumnIndex(tableName, columnName)); +} + + +SQLWCHAR ResultSet::getSQLWChar(unsigned int columnIndex) const { + SQLWCHAR strAux = 0; + + if (metaData->getSQLType(columnIndex) == SQL_WCHAR) { + SQLINTEGER length = 0; + SQLRETURN result = SQLGetData(stmt->getODBCStatement(), columnIndex + 1, SQL_C_WCHAR, &strAux, 2, &length); + + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + throw SQLException(result, "Error on getting database data!"); + + } else { + throw DASInvalidSQLTypeException("Column sql type on index " + columnIndex + (std::string) " is not char!"); + } + + return strAux; + +} + +SQLWCHAR ResultSet::getSQLWChar(std::string tableName, std::string columnName) const { + return getSQLWChar(metaData->getColumnIndex(tableName, columnName)); +} + +SQLCHAR ResultSet::getSQLChar(unsigned int columnIndex) const { + SQLCHAR strAux = 0; + + if (metaData->getSQLType(columnIndex) == SQL_CHAR) { + SQLINTEGER length = 0; + SQLRETURN result = SQLGetData(stmt->getODBCStatement(), columnIndex + 1, SQL_C_CHAR, &strAux, 2, &length); + + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + throw SQLException(result, "Error on getting database data!"); + + } else { + throw DASInvalidSQLTypeException("Column sql type on index " + columnIndex + (std::string) " is not char!"); + } + + return strAux; + +} + +SQLCHAR ResultSet::getSQLChar(std::string tableName, std::string columnName) const { + return getSQLChar(metaData->getColumnIndex(tableName, columnName)); +} + +SQLREAL ResultSet::getSQLReal(unsigned int columnIndex) const { + SQLREAL ret = 0; + + if (metaData->getSQLType(columnIndex) == SQL_REAL) { + SQLREAL real = 0; + SQLINTEGER length = 0; + SQLRETURN result = SQLGetData(stmt->getODBCStatement(), columnIndex + 1, SQL_C_FLOAT, &real, 1, &length); + + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + throw SQLException(result, "Error on getting database data!"); + + ret = (SQLREAL) real; + + } else { + throw DASInvalidSQLTypeException("Column sql type on index " + columnIndex + (std::string) " is not real!"); + } + + return ret; + +} + +SQLREAL ResultSet::getSQLReal(std::string tableName, std::string columnName) const { + return getSQLReal(metaData->getColumnIndex(tableName, columnName)); +} + +SQLFLOAT ResultSet::getSQLFloat(unsigned int columnIndex) const { + SQLFLOAT ret = 0; + + if (metaData->getSQLType(columnIndex) == SQL_FLOAT) { + SQLDOUBLE data = 0; + SQLINTEGER length = 0; + SQLRETURN result = SQLGetData(stmt->getODBCStatement(), columnIndex + 1, SQL_C_DOUBLE, &data, 1, &length); + + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + throw SQLException(result, "error on getting database data!"); + + ret = (SQLFLOAT) data; + + } else { + throw DASInvalidSQLTypeException("Column sql type on index " + columnIndex + (std::string) " is not float!"); + } + + return ret; + +} + +SQLFLOAT ResultSet::getSQLFloat(std::string tableName, std::string columnName) const { + return getSQLFloat(metaData->getColumnIndex(tableName, columnName)); +} + +SQLDOUBLE ResultSet::getSQLDouble(unsigned int columnIndex) const { + double ret = 0; + + if (metaData->getSQLType(columnIndex) == SQL_DOUBLE) { + SQLDOUBLE data = 0; + SQLINTEGER length = 0; + SQLRETURN result = SQLGetData(stmt->getODBCStatement(), columnIndex + 1, SQL_C_DOUBLE, &data, 1, &length); + + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + throw SQLException(result, "error on getting database data!"); + + ret = (SQLDOUBLE) data; + + } else { + throw DASInvalidSQLTypeException("Column sql type on index " + columnIndex + (std::string) " is not double!"); + } + + return ret; + +} + +SQLDOUBLE ResultSet::getSQLDouble(std::string tableName, std::string columnName) const { + return getSQLDouble(metaData->getColumnIndex(tableName, columnName)); +} + +std::string ResultSet::getSQLDecimal(unsigned int columnIndex) const { + + if (metaData->getSQLType(columnIndex) == SQL_DECIMAL) { + return getSQLString(columnIndex); + } else { + throw DASInvalidSQLTypeException("Column sql type on index " + columnIndex + (std::string) " is not decimal!"); + } + +} + +std::string ResultSet::getSQLDecimal(std::string tableName, std::string columnName) const { + return getSQLDecimal(metaData->getColumnIndex(tableName, columnName)); +} + +bool ResultSet::isNull(unsigned int columnIndex) const { + SQLINTEGER sqlPtr = 0; + SQLSMALLINT length = 0; + SQLINTEGER aux = 0; + + if (metaData->getSQLType(columnIndex) == SQL_INTEGER) { + SQLRETURN result = SQLGetData(stmt->getODBCStatement(), columnIndex + 1, SQL_C_DEFAULT, &sqlPtr, 0, &aux); + + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + throw SQLException(result, "Error on getting database data!"); + + } else { + throw DASInvalidSQLTypeException("Column sql type on index " + columnIndex + (std::string) " is not integer!"); + } + + return aux == SQL_NULL_DATA; + +} + +bool ResultSet::isNull(std::string tableName, std::string columnName) const { + return isNull(metaData->getColumnIndex(tableName, columnName)); +} + +bool ResultSet::next(void) { + return (SQL_SUCCESS == SQLFetch(stmt->getODBCStatement())); +} + +unsigned int ResultSet::getRowCount(void) const { + SQLINTEGER rowCount = 0; + SQLRETURN result = SQLRowCount(stmt->getODBCStatement(), &rowCount); + + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + throw SQLException(result, "error on getting row count!"); + + return (unsigned int) rowCount; + +} + +std::string ResultSet::getSQLString(unsigned int columnIndex) const { + SQLPOINTER sqlPtr = 0; + SQLCHAR strAux[1]; + SQLINTEGER length = 0; + SQLRETURN result = SQLGetData(stmt->getODBCStatement(), columnIndex + 1, SQL_C_CHAR, &strAux, 1, &length); + + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + throw SQLException(result, "error on getting database data!"); + + length++; + sqlPtr = new SQLCHAR[length]; + SQLINTEGER aux = 0; + result = SQLGetData(stmt->getODBCStatement(), columnIndex + 1, SQL_C_CHAR, sqlPtr, length, &aux); + + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + throw SQLException(result, "error on getting database data!"); + + std::string ret = (char*) sqlPtr; + delete [] ((SQLCHAR*) sqlPtr); + + return ret; + +} + +std::wstring ResultSet::getSQLWString(unsigned int columnIndex) const { + SQLPOINTER sqlPtr = 0; + SQLWCHAR strAux[1]; + SQLINTEGER length = 0; + SQLRETURN result = SQLGetData(stmt->getODBCStatement(), columnIndex + 1, SQL_C_WCHAR, &strAux, 1, &length); + + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + throw SQLException(result, "error on getting database data!"); + + length++; + sqlPtr = new SQLWCHAR[length]; + SQLINTEGER aux = 0; + result = SQLGetData(stmt->getODBCStatement(), columnIndex + 1, SQL_C_WCHAR, sqlPtr, length, &aux); + + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) + throw SQLException(result, "error on getting database data!"); + + std::wstring ret = (wchar_t*) sqlPtr; + delete [] ((SQLWCHAR*) sqlPtr); + + return ret; + +} + +std::string ResultSet::getSQLVarchar(unsigned int columnIndex) const { + + if (metaData->getSQLType(columnIndex) == SQL_VARCHAR) { + return getSQLString(columnIndex); + } else { + throw DASInvalidSQLTypeException("Column sql type on index " + columnIndex + (std::string) " is not varchar!"); + } + +} + +std::string ResultSet::getSQLVarchar(std::string tableName, std::string columnName) const { + return getSQLVarchar(metaData->getColumnIndex(tableName, columnName)); +} + +std::wstring ResultSet::getSQLWVarchar(unsigned int columnIndex) const { + + if (metaData->getSQLType(columnIndex) == SQL_WVARCHAR) { + return getSQLWString(columnIndex); + } else { + throw DASInvalidSQLTypeException("Column sql type on index " + columnIndex + (std::string) " is not varchar!"); + } + +} + +std::wstring ResultSet::getSQLWVarchar(std::string tableName, std::string columnName) const { + return getSQLWVarchar(metaData->getColumnIndex(tableName, columnName)); +} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/ResultSetMetaData.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/ResultSetMetaData.cpp new file mode 100644 index 0000000000..e17295560e --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/ResultSetMetaData.cpp @@ -0,0 +1,216 @@ +/* + * 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/ResultSetMetaData.h" + +namespace apache { + namespace das { + namespace rdb { + +ResultSetMetaData::ResultSetMetaData(const ResultSet& aResultSet) { + resultSet = &aResultSet; + unsigned int columnCount = getColumnCount(); + + for (unsigned int i = 0 ; i < columnCount ; i++) { + std::string columnName = StringWrapper(getColumnName(i)).toUpper(); + std::string tableName = StringWrapper(getTableName(i)).toUpper(); + columnsIndexes.insert(std::make_pair(tableName + "." + columnName, i)); + + } + +} + +ResultSetMetaData::~ResultSetMetaData(void) {} + +SQLSMALLINT ResultSetMetaData::getSQLCType(SQLSMALLINT sqlType) { + + switch (sqlType) { + + case SQL_CHAR : + return SQL_C_CHAR; + + case SQL_BINARY : + return SQL_C_BINARY; + + case SQL_TYPE_DATE : + return SQL_C_TYPE_DATE; + + case SQL_DECIMAL : + return SQL_C_CHAR; + + case SQL_DOUBLE : + return SQL_C_DOUBLE; + + case SQL_FLOAT : + return SQL_C_DOUBLE; + + case SQL_INTEGER : + return SQL_C_LONG; + + case SQL_LONGVARCHAR : + return SQL_C_CHAR; + + case SQL_LONGVARBINARY : + return SQL_C_BINARY; + + case SQL_NUMERIC : + return SQL_C_CHAR; + + case SQL_REAL : + return SQL_C_FLOAT; + + case SQL_SMALLINT : + return SQL_C_SHORT; + + case SQL_TYPE_TIME : + return SQL_C_TYPE_TIME; + + case SQL_TYPE_TIMESTAMP : + return SQL_C_TYPE_TIMESTAMP; + + case SQL_VARCHAR : + return SQL_C_CHAR; + + case SQL_VARBINARY : + return SQL_C_BINARY; + + default : + throw DASInvalidSQLTypeException(); + + } + +} + +SQLSMALLINT ResultSetMetaData::getSQLType(unsigned int columnIndex) const { + SQLSMALLINT sqlType = 0; + SQLColAttribute(resultSet->getStatement()->getODBCStatement(), columnIndex + 1, SQL_DESC_TYPE, NULL, NULL, NULL, &sqlType); + + return sqlType; + +} + +SQLSMALLINT ResultSetMetaData::getSQLType(std::string tableName, std::string columnName) const { + return getSQLType(getColumnIndex(tableName, columnName)); +} + +std::string ResultSetMetaData::getSQLTypeName(unsigned int columnIndex) const { + SQLCHAR* sqlPtr = 0; + char strAux[1]; + SQLSMALLINT length = 0; + SQLColAttribute(resultSet->getStatement()->getODBCStatement(), columnIndex + 1, SQL_DESC_TYPE_NAME, &strAux, 1, (SQLSMALLINT*) &length, NULL); + length++; + sqlPtr = (SQLCHAR*) new SQLCHAR[length]; + SQLColAttributeA(resultSet->getStatement()->getODBCStatement(), columnIndex + 1, SQL_DESC_TYPE_NAME, sqlPtr, length, (SQLSMALLINT*) &length, NULL); + + std::string ret((char*) sqlPtr); + delete [] sqlPtr; + + return StringWrapper(ret).toUpper(); + +} + +std::string ResultSetMetaData::getSQLTypeName(std::string tableName, std::string columnName) const { + return getSQLTypeName(getColumnIndex(tableName, columnName)); +} + + +std::string ResultSetMetaData::getColumnName(unsigned int columnIndex) const { + SQLCHAR* sqlPtr = 0; + char strAux[1]; + SQLSMALLINT length = 0; + SQLColAttribute(resultSet->getStatement()->getODBCStatement(), columnIndex + 1, SQL_DESC_BASE_COLUMN_NAME, &strAux, 1, (SQLSMALLINT*) &length, NULL); + length++; + sqlPtr = (SQLCHAR*) new SQLCHAR[length]; + SQLColAttributeA(resultSet->getStatement()->getODBCStatement(), columnIndex + 1, SQL_DESC_BASE_COLUMN_NAME, sqlPtr, length, (SQLSMALLINT*) &length, NULL); + + std::string ret((char*) sqlPtr); + delete [] sqlPtr; + + return StringWrapper(ret).toUpper(); + +} + +unsigned int ResultSetMetaData::getColumnIndex(std::string tableName, std::string columnName) const { + tableName = StringWrapper(tableName).toUpper(); + columnName = StringWrapper(columnName).toUpper(); + std::map::const_iterator it = columnsIndexes.find(tableName + "." + columnName); + + if (it == columnsIndexes.end()) { + throw DASColumnNotFoundException("No such column on table " + tableName + ": " + columnName); + } + + return it->second; + +} + + +std::string ResultSetMetaData::getTableName(unsigned int columnIndex) const { + SQLCHAR* sqlPtr = 0; + char strAux[1]; + SQLSMALLINT length = 0; + SQLColAttribute(resultSet->getStatement()->getODBCStatement(), columnIndex + 1, SQL_DESC_TABLE_NAME, &strAux, 1, (SQLSMALLINT*) &length, NULL); + length++; + sqlPtr = (SQLCHAR*) new SQLCHAR[length]; + SQLColAttributeA(resultSet->getStatement()->getODBCStatement(), columnIndex + 1, SQL_DESC_TABLE_NAME, sqlPtr, length, (SQLSMALLINT*) &length, NULL); + + std::string ret((char*) sqlPtr); + delete [] sqlPtr; + + return StringWrapper(ret).toUpper(); + +} + +std::string ResultSetMetaData::getTableName(std::string tableName, std::string columnName) const { + return getTableName(getColumnIndex(tableName, columnName)); +} + + +SQLSMALLINT ResultSetMetaData::getSQLCType(unsigned int columnIndex) const { + return getSQLCType(getSQLType(columnIndex)); +} + +SQLSMALLINT ResultSetMetaData::getSQLCType(std::string tableName, std::string columnName) const { + return getSQLCType(getSQLType(getColumnIndex(tableName, columnName))); +} + +unsigned int ResultSetMetaData::getColumnCount(void) const { + SQLUINTEGER columnCount = 0; + SQLRETURN ret = SQLColAttribute(resultSet->getStatement()->getODBCStatement(), NULL, SQL_DESC_COUNT, NULL, NULL, NULL, &columnCount); + + return (unsigned int) columnCount; + +} + +bool ResultSetMetaData::containsColumn(std::string tableName, std::string columnName) const { + std::map::const_iterator it = columnsIndexes.find(tableName + "." + columnName); + + if (it == columnsIndexes.end()) { + return false; + } + + return true; + +} + +const ResultSet& ResultSetMetaData::getResultSet(void) const { + return *resultSet; +} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/SQLException.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/SQLException.cpp new file mode 100644 index 0000000000..3de09819bd --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/SQLException.cpp @@ -0,0 +1,40 @@ +/* + * 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/SQLException.h" + +namespace apache { + namespace das { + namespace rdb { + +SQLException::SQLException(SQLRETURN returnCode, string errorText) + :exception(errorText.c_str()) { + this->returnCode = returnCode; + +} + +SQLException::~SQLException(){} + +SQLRETURN SQLException::getODBCReturnCode(void) const { + return returnCode; +} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/Statement.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/Statement.cpp new file mode 100644 index 0000000000..62e92cda67 --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/Statement.cpp @@ -0,0 +1,107 @@ +/* + * 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/Statement.h" + +namespace apache { + namespace das { + namespace rdb { + +Statement::Statement(Connection& connection, SQLHSTMT statementHandle) : resultSet(0, false) { + this->statementHandle = statementHandle; + this->connection = &connection; + +} + +Statement::~Statement(void) { + if (!resultSet) { + delete resultSet; + } + + SQLFreeHandle(SQL_HANDLE_STMT, statementHandle); + StatementObject::free(); + +} + +std::string Statement::getError(void) const { + SQLCHAR state[5]; + SQLCHAR message[1000]; + SQLINTEGER nativeError = 0; + SQLSMALLINT messageLength = 0; + + SQLRETURN result = SQLGetDiagRec(SQL_HANDLE_STMT, statementHandle, 1, + state, &nativeError, message, 1000, &messageLength); + + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { + return ""; + } + + if (messageLength < 1000) { + message[messageLength + 1] = 0; + } + + std::string ret = (std::string) (char*) state; + ret += ": "; + ret += StringWrapper::toString((long) nativeError); + ret += " - "; + ret += (char*) message; + + return ret; + +} + +Connection& Statement::getConnection(void) const { + return *connection; +} + +ResultSetPtr Statement::executeQuery(std::string sql) { + queryString = sql; + SQLCloseCursor(statementHandle); + SQLRETURN result = SQLExecDirect(statementHandle, (SQLCHAR*) (char*) sql.c_str(), SQL_NTS); + + if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { + throw SQLException(result, getError()); + } + + return createResultSet(); + +} + +ResultSetPtr Statement::createResultSet(void) { + if (resultSet) { + delete resultSet; + } + + ResultSetPtr ret = new ResultSet((StatementPtr) *this); + resultSet = ret; + + return ret; + +} + +void Statement::close(void) { + delete this; +} + +HSTMT Statement::getODBCStatement(void) const { + return statementHandle; +} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/Table.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/Table.cpp new file mode 100644 index 0000000000..66f905dafd --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/Table.cpp @@ -0,0 +1,236 @@ +/* + * 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/Table.h" + +namespace apache { + namespace das { + namespace rdb { + +Table::Table(std::string tableName) { + tableName = StringWrapper(tableName).toUpper(); + + if (tableName.find(' ') != -1 || tableName.find('\t') != -1 || tableName.find('\n') != -1 || tableName.find('\r') != -1) { + throw DASInvalidTableNameException("Table name must not contain whitespace characters!"); + } + + this->tableName = tableName; + this->typeName = tableName; + this->columns = new std::map(); + +} + +Table::Table(std::string tableName, std::string typeName) { + tableName = StringWrapper(tableName).toUpper(); + + if (tableName.find(' ') != -1 || tableName.find('\t') != -1 || tableName.find('\n') != -1 || tableName.find('\r') != -1) { + throw DASInvalidTableNameException("Table name must not contain whitespace characters!"); + } + + this->tableName = tableName; + this->typeName = typeName; + this->columns = new std::map(); + +} + +Table::Table(const Table& table) { + tableName = table.tableName; + typeName = table.typeName; + this->columns = new std::map(); + + std::map::iterator it; + for (it = table.columns->begin() ; it != table.columns->end() ; it++) { + Column* newColumn = new Column(*it->second); + newColumn->setContainerTable(this); + columns->insert(std::make_pair(it->first, newColumn)); + + } + +} + +Table::~Table(void) { + std::map::iterator it; + + for (it = columns->begin() ; it != columns->end() ; it++) { + delete it->second; + } + + delete columns; + +} + +const Column* Table::getColumnByProperty(std::string propertyName) const { + + for (std::map::const_iterator it = columns->begin() ; + it != columns->end() ; it++) { + + if (it->second->getPropertyName() == propertyName) { + return it->second; + } + + } + + return 0; + +} + +std::string Table::getTableName(void) const { + return tableName; +} + +Column& Table::addColumn(std::string columnName, SQLSMALLINT sqlType) { + Column* column = new Column(columnName, sqlType); + return newColumn(*column); +} + +Column& Table::addColumn(const Column& column) { + return newColumn(*(new Column(column))); +} + +Column& Table::newColumn(Column& column) { + std::string columnName = column.getName(); + Column* tableColumn = getColumn(columnName); + + if (tableColumn == 0) { + columns->insert(std::make_pair(columnName, &column)); + column.setContainerTable(this); + + return column; + + } + + return *tableColumn; + +} + +void Table::createGraph(const GraphBuilderMetaData& graphBuilderMetaData, commonj::sdo::DataFactoryPtr dataFactory) const { + std::map::const_iterator it; + std::map& relationships = graphBuilderMetaData.getRelationships(); + std::map::const_iterator relationshipIterator; + std::list tablePKRelationships; + std::list tableFKRelationships; + std::list relationshipColumns; + + for (relationshipIterator = relationships.begin() ; relationshipIterator != + relationships.end() ; relationshipIterator++) { + + if (relationshipIterator->second->getFKTableName() == tableName) { + const std::map& keyPairs = relationshipIterator->second->getKeyPairs(); + std::map::const_iterator keyPairIterator; + + for (keyPairIterator = keyPairs.begin() ; keyPairIterator != + keyPairs.end() ; keyPairIterator++) { + + relationshipColumns.push_back(keyPairIterator->second-> + getFKColumnName()); + + } + + } + + } + + for (it = columns->begin() ; it != columns->end() ; it++) { + const Column& column = *(it->second); + + if (graphBuilderMetaData.getResultSetMetaData().containsColumn(tableName, column.getName())) { + + std::list::const_iterator it2 = std::find(relationshipColumns.begin(), + relationshipColumns.end(), column.getName()); + + if (it2 == relationshipColumns.end()) { + dataFactory->addPropertyToType(graphBuilderMetaData.getConfig().getURI(), typeName.c_str(), + column.getPropertyName().c_str(), SDO_NAMESPACE, + ODBCTypeHelper::getSDOType(column.getSQLType()).c_str() , false, + false, true); + + } + + } + + } + +} + +const Column* Table::getOCCColumn(void) const { + + for (std::map::const_iterator it = columns->begin() ; it != columns->end() ; it++) { + + if (it->second->isCollision()) { + return it->second; + } + + } + + return 0; + +} + +void Table::setTypeName(std::string typeName) { + typeName = StringWrapper(typeName).toUpper(); + + if (typeName.find(' ') != -1 || typeName.find('\t') != -1 || typeName.find('\n') != -1 || typeName.find('\r') != -1) { + throw DASInvalidTypeNameException("Type must not contain whitespace characters!"); + } + + this->typeName = typeName; + +} + +Column* Table::getColumn(std::string columnName) { + std::map::const_iterator it = columns->find(columnName); + + if (it == columns->end()) { + return 0; + } + + return (Column*) it->second; + +} + +const Column* Table::getColumn(std::string columnName) const { + return ((Table*) this)->getColumn(columnName); +} + +std::string Table::getTypeName(void) const { + return typeName; +} + +const std::map& Table::getColumns(void) const { + return *columns; +} + +unsigned int Table::getPKColumnCount(void) const { + unsigned int count = 0; + std::map::const_iterator it; + + for (it = columns->begin() ; it != columns->end() ; it++) { + + if (it->second->isPK()) { + count++; + } + + } + + return count; + +} + + }; + }; +}; diff --git a/das-cpp/trunk/runtime/core/src/apache/das/rdb/TableData.cpp b/das-cpp/trunk/runtime/core/src/apache/das/rdb/TableData.cpp new file mode 100644 index 0000000000..3f6fd68828 --- /dev/null +++ b/das-cpp/trunk/runtime/core/src/apache/das/rdb/TableData.cpp @@ -0,0 +1,98 @@ +/* + * 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/TableData.h" + +namespace apache { + namespace das { + namespace rdb { + +TableData::TableData(const Table& table, ResultSetPtr resultSet) : PKObject(table) { + dataObject = 0; + const std::map& columns = table.getColumns(); + std::map::const_iterator columnIterator; + const ResultSetMetaData& metaData = resultSet->getResultSetMetaData(); + const KeyDataList& primaryKeys = getPrimaryKeys(); + + for (columnIterator = columns.begin() ; columnIterator != columns.end() ; + columnIterator++) { + + const Column& column = *columnIterator->second; + std::string columnName = column.getName(); + + if (metaData.containsColumn(table.getTableName(), columnName)) { + ColumnData* columnData = new ColumnData(column, resultSet); + + columnsData.insert(std::make_pair(columnName, columnData)); + + if (column.isPK()) { + addPrimaryKey(columnName, *columnData); + } + + } + + } + +} + +TableData::~TableData(void) { + std::map::iterator it; + + for (it = columnsData.begin() ; it != columnsData.end() ; it++) { + + if (!(it->second->getColumn().isPK())) { + delete it->second; + } + + } + +} + +bool TableData::hasPK(void) const { + const KeyDataList& primaryKeys = getPrimaryKeys(); + return (primaryKeys.size() == getTable().getPKColumnCount() && primaryKeys.size() > 0); +} + +commonj::sdo::DataObjectPtr TableData::getGraphObject(void) const { + return dataObject; +} + +void TableData::populateDataGraph(GraphBuilder& graphBuilder) { + dataObject = graphBuilder.getRoot()->createDataObject(getTable().getTableName().c_str()); + std::map::iterator it; + + for (it = columnsData.begin() ; it != columnsData.end() ; it++) { + it->second->populateDataGraph(*this); + } + +} + +ColumnData* TableData::getColumnData(std::string columnName) const { + std::map::const_iterator it = columnsData.find(columnName); + + if (it == columnsData.end()) { + return 0; + } + + return it->second; + +} + + }; + }; +}; -- cgit v1.2.3