/* * 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; } }; }; };