diff --git a/Database/APR/RelationalCollection/CMakeLists.txt b/Database/APR/RelationalCollection/CMakeLists.txt deleted file mode 100644 index 9fb2b465e63a0e025e75cdda16825637c8619c73..0000000000000000000000000000000000000000 --- a/Database/APR/RelationalCollection/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration - -# Declare the package name: -atlas_subdir( RelationalCollection ) - -# External dependencies: -find_package( CORAL COMPONENTS CoralBase RelationalAccess ) - -# Component(s) in the package: -atlas_add_library( RelationalCollection - src/*.cpp - NO_PUBLIC_HEADERS - PRIVATE_INCLUDE_DIRS ${CORAL_INCLUDE_DIRS} - PRIVATE_LINK_LIBRARIES ${CORAL_LIBRARIES} CollectionBase POOLCore PersistentDataModel ) - -# Component list generation: -atlas_generate_componentslist( RelationalCollection ) diff --git a/Database/APR/RelationalCollection/src/DBLock.cpp b/Database/APR/RelationalCollection/src/DBLock.cpp deleted file mode 100644 index d81d12c6bb3f3a1657acc4d4528dd2cd1e7dd0fa..0000000000000000000000000000000000000000 --- a/Database/APR/RelationalCollection/src/DBLock.cpp +++ /dev/null @@ -1,260 +0,0 @@ -/* - Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration -*/ - -#include "DBLock.h" - -#include "POOLCore/Exception.h" - -#include "RelationalCollectionNames.h" -#include "RelationalCollectionBindVariables.h" - -#include "RelationalAccess/TableDescription.h" -#include "RelationalAccess/IQuery.h" -#include "RelationalAccess/ICursor.h" -#include "RelationalAccess/ITable.h" -#include "RelationalAccess/ISchema.h" -#include "RelationalAccess/ITablePrivilegeManager.h" -#include "RelationalAccess/ITransaction.h" -#include "RelationalAccess/ITableDataEditor.h" - -#include "CoralBase/MessageStream.h" -#include "CoralBase/AttributeSpecification.h" -#include "CoralBase/Attribute.h" -#include "CoralBase/AttributeList.h" -#include "CoralBase/TimeStamp.h" - - -#ifdef WIN32 -# include <windows.h> -# define sleep(x) Sleep((x)*1000) -std::string userinfo() { - return "Windows"; -} -#elif defined __APPLE__ -std::string userinfo() { - return "Apple"; -} -#else -// hopefully UNIX -# include <unistd.h> -# include <limits.h> -# include <pwd.h> -std::string userinfo() { - static char hostname[HOST_NAME_MAX+1]; - if( gethostname( hostname, HOST_NAME_MAX ) ) { - *hostname = 0; //error - } - hostname[HOST_NAME_MAX] = 0; - struct passwd *pwdent = getpwuid(geteuid()); - const char *username_p = (pwdent? pwdent->pw_name : 0); - std::string username; - if( username_p ) - username = username_p; - return std::string(hostname) + "/" + username; -} - -#endif - - -using namespace pool; -using namespace std; -using namespace pool::RelationalCollection; - - - -DBLock::DBLock( coral::ISessionProxy& session, const std::string& collName ) - : m_session( session ), - m_name( collName ), - m_locked( false ), - m_autorelease( true ), - m_lockIngoreAge( 4000 ), - m_maxWait( 300 ) -{ - const char* env = getenv("POOL_RCOLL_LOCKAGELIMIT"); - if( env ) { - int age = atoi(env); - if( age < 60 && age != 0 ) { - // 0 means infinity - m_lockIngoreAge = 60; - } else { - m_lockIngoreAge = age; - } - } - env = getenv("POOL_RCOLL_LOCKTIMEOUT"); - if( env ) { - int to = atoi(env); - if( to < 10 && to != 0 ) { - // 0 means infinity - m_maxWait = 10; - } else { - m_maxWait = to; - } - } -} - - -DBLock::~DBLock() -{ - if( m_locked && m_autorelease ) { - unlock(); - m_session.transaction().commit(); - } -} - - -void -DBLock::setAutorelease( bool ar ) -{ - m_autorelease = ar; -} - - -void -DBLock::lock( bool XTrans ) -{ - using namespace pool::RelationalCollection; - coral::MessageStream log( "pool::RelationalCollection::DBLock" ); - - coral::ISchema& nominalSchema = m_session.nominalSchema(); - if( !nominalSchema.existsTable( RelationalCollectionNames::nameOfCollectionLockTable() ) ) { - // create the table where the locking is done - coral::TableDescription description( RelationalCollectionNames::nameOfCollectionLockTable() ); - description.setName( RelationalCollectionNames::nameOfCollectionLockTable() ); - description.insertColumn( - RelationalCollectionNames::entryIDVarInCollectionLockTable(), - coral::AttributeSpecification::typeNameForType<std::string>(), 50, false ); - description.insertColumn( - RelationalCollectionNames::collectionNameVarInCollectionLockTable(), - coral::AttributeSpecification::typeNameForType<std::string>(), 500, false ); - description.insertColumn( - RelationalCollectionNames::clientInfoVarInCollectionLockTable(), - coral::AttributeSpecification::typeNameForType<std::string>(), 500, false ); - description.insertColumn( - RelationalCollectionNames::lockTypeVarInCollectionLockTable(), - coral::AttributeSpecification::typeNameForType<std::string>(), 20, false ); - description.insertColumn( - RelationalCollectionNames::timestampVarInCollectionLockTable(), - coral::AttributeSpecification::typeNameForType<coral::TimeStamp>(), 2, false ); - - description.setPrimaryKey( RelationalCollectionNames::entryIDVarInCollectionLockTable() ); - log << coral::Debug << " Creating lock TABLE:" << RelationalCollectionNames::nameOfCollectionLockTable() << coral::MessageStream::endmsg; - nominalSchema.createTable( description ); //.privilegeManager().grantToPublic( coral::ITablePrivilegeManager::Select ); - } - - int total_wait = 0; - do { - coral::ITable& lockTable = m_session.nominalSchema().tableHandle( - RelationalCollectionNames::nameOfCollectionLockTable() ); - coral::IQuery* query = lockTable.newQuery(); - query->addToOutputList( RelationalCollectionNames::entryIDVarInCollectionLockTable() ); - query->addToOutputList( RelationalCollectionNames::collectionNameVarInCollectionLockTable() ); - query->addToOutputList( RelationalCollectionNames::lockTypeVarInCollectionLockTable() ); - query->addToOutputList( RelationalCollectionNames::timestampVarInCollectionLockTable() ); - query->addToOutputList( RelationalCollectionNames::clientInfoVarInCollectionLockTable() ); - - coral::AttributeList whereDataForLock; - whereDataForLock.extend<std::string>( - RelationalCollectionNames::entryIDVarInCollectionLockTable() ); - whereDataForLock.begin()->data<std::string>() = "LOCK"; - string whereClauseForLock = RelationalCollectionNames::entryIDVarInCollectionLockTable() + " = :" + RelationalCollectionNames::entryIDVarInCollectionLockTable(); - query->setCondition( whereClauseForLock, whereDataForLock ); - query->limitReturnedRows( 1, 0 ); - query->setForUpdate(); - log << coral::Debug << " Checking the LOCK table:" << RelationalCollectionNames::nameOfCollectionLockTable() << coral::MessageStream::endmsg; - coral::ICursor& cursor = query->execute(); - - if( !cursor.next() ) { - log << coral::Debug << " Creating lock ROW in " << RelationalCollectionNames::nameOfCollectionLockTable() << coral::MessageStream::endmsg; - // no entry - new table or row removed by hand. Add the row - coral::AttributeList rowBuffer; - rowBuffer.extend< std::string >( RelationalCollectionNames::entryIDVarInCollectionLockTable() ); - rowBuffer.extend< std::string >( RelationalCollectionNames::collectionNameVarInCollectionLockTable() ); - rowBuffer.extend< std::string >( RelationalCollectionNames::clientInfoVarInCollectionLockTable() ); - rowBuffer.extend< std::string >( RelationalCollectionNames::lockTypeVarInCollectionLockTable() ); - rowBuffer.extend< coral::TimeStamp >( RelationalCollectionNames::timestampVarInCollectionLockTable() ); - - rowBuffer[0].data< std::string >() = "LOCK"; - rowBuffer[1].data< std::string >() = m_name; - rowBuffer[2].data< std::string >() = userinfo(); - rowBuffer[3].data< std::string >() = XTrans? "PERM" : "TEMP"; - rowBuffer[4].data< coral::TimeStamp >() = coral::TimeStamp::now(); - lockTable.dataEditor().insertRow( rowBuffer ); - - } else { - string lockType = cursor.currentRow()[RelationalCollectionNames::lockTypeVarInCollectionLockTable()].data< std::string >(); - long long lockTime = cursor.currentRow()[RelationalCollectionNames::timestampVarInCollectionLockTable()].data< coral::TimeStamp >().total_nanoseconds() / 1000000000; - long long nowTime = coral::TimeStamp::now().total_nanoseconds() / 1000000000; - long long lock_age = nowTime - lockTime; - log << coral::Debug << " Current lock type is " << lockType << coral::MessageStream::endmsg; - if( lockType == "PERM" ) { - string lock_creator = cursor.currentRow()[RelationalCollectionNames::clientInfoVarInCollectionLockTable()].data< std::string >(); - string locked_collection = cursor.currentRow()[RelationalCollectionNames::collectionNameVarInCollectionLockTable()].data< std::string >(); - log << coral::Warning << " Permanent collection database lock detected (" << lock_age << " sec old) made by " << lock_creator << " on collection " << locked_collection << coral::MessageStream::endmsg; - if( m_lockIngoreAge==0 || lock_age < m_lockIngoreAge ) { - delete query; query = 0; - // release locks and wait some - m_session.transaction().commit(); - - if( total_wait >= m_maxWait ) { - log << coral::Warning << " Wait time exceeded: maximum specified wait time: " << m_maxWait << " sec - giving up" << coral::MessageStream::endmsg; - throw pool::Exception("Lock wait time exceeded", - "RelationalCollection::open::DBLock::lock", - "RelationalCollection" ); - } - log << coral::Warning << " Sleeping for 10s" << coral::MessageStream::endmsg; - sleep(10); - total_wait += 10; - bool forUpdate(false); - m_session.transaction().start( forUpdate ); - continue; - - } else { - log << coral::Warning << " Ignoring database lock: greater than " << m_lockIngoreAge << coral::MessageStream::endmsg; - } - } - - log << coral::Debug << " Setting database lock to " << ( XTrans? "'PERM'" : "'TEMP'" ) << coral::MessageStream::endmsg; - // update the row in the LOCK table to set databse lock and store lock type - string setClause = - RelationalCollectionNames::collectionNameVarInCollectionLockTable() - + " = '" + m_name + "'" - + ", " + RelationalCollectionNames::clientInfoVarInCollectionLockTable() - + " = '" + userinfo() + "'" - + ", " + RelationalCollectionNames::timestampVarInCollectionLockTable() - + " = :newtime " - + ", " + RelationalCollectionNames::lockTypeVarInCollectionLockTable() - + " = " + ( XTrans? "'PERM'" : "'TEMP'" ); - whereDataForLock.extend< coral::TimeStamp >( "newtime" ); - whereDataForLock[1].data< coral::TimeStamp >() = coral::TimeStamp::now(); - lockTable.dataEditor().updateRows( setClause, whereClauseForLock, whereDataForLock ); - } - delete query; - m_locked = true; - return; - }while( true ); -} - - -void -DBLock::unlock() -{ - using namespace pool::RelationalCollection; - - coral::ISchema& nominalSchema = m_session.nominalSchema(); - coral::ITable& lockTable = nominalSchema.tableHandle( - RelationalCollectionNames::nameOfCollectionLockTable() ); - - string setClause = - RelationalCollectionNames::lockTypeVarInCollectionLockTable() + " = 'NONE'"; - - coral::AttributeList whereDataForLock; - whereDataForLock.extend<std::string>( - RelationalCollectionNames::entryIDVarInCollectionLockTable() ); - whereDataForLock.begin()->data<std::string>() = "LOCK"; - string whereClauseForLock = RelationalCollectionNames::entryIDVarInCollectionLockTable() + " = :" + RelationalCollectionNames::entryIDVarInCollectionLockTable(); - - lockTable.dataEditor().updateRows( setClause, whereClauseForLock, whereDataForLock ); - m_locked = false; -} - diff --git a/Database/APR/RelationalCollection/src/DBLock.h b/Database/APR/RelationalCollection/src/DBLock.h deleted file mode 100644 index 1923fd0d97cba89ba623d95ff7df786ac6bb7c2e..0000000000000000000000000000000000000000 --- a/Database/APR/RelationalCollection/src/DBLock.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration -*/ - -#ifndef RELATIONALCOLLECTION_DBLOCK_H -#define RELATIONALCOLLECTION_DBLOCK_H - - -#include "RelationalAccess/ISessionProxy.h" - -namespace pool { - namespace RelationalCollection { - - class DBLock - { - public: - DBLock( coral::ISessionProxy& session, const std::string& collName ); - ~DBLock(); - - /// set a global lock to serialize collection operations (creation etc) - /// if XTrans is flase, the lock will be gone when transaction is committed - /// if XTrans is true, the lock will be permanent - void lock( bool Xtrans ); - - /// remove global lock - void unlock(); - - /// set lock release behavior in the destructor - void setAutorelease( bool ar ); - - private: - - /// Reference to current database access session. - coral::ISessionProxy& m_session; - - std::string m_name; - - /// true if this object holds a database lock - bool m_locked; - - /// if true (default) try to remove the lock in the destructor - bool m_autorelease; - - /// ignore database lock if older than this limit (in sec) - long long m_lockIngoreAge; - - /// give up waiting for database access after this time (in sec) - int m_maxWait; - }; - - - } -} - -#endif - - diff --git a/Database/APR/RelationalCollection/src/GUIDQuery.cpp b/Database/APR/RelationalCollection/src/GUIDQuery.cpp deleted file mode 100755 index fe084149a032c0bcd9e69038822fd5041c46debb..0000000000000000000000000000000000000000 --- a/Database/APR/RelationalCollection/src/GUIDQuery.cpp +++ /dev/null @@ -1,240 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - - -#include "GUIDQuery.h" -#include "RelationalCollectionNames.h" - -#include "PersistentDataModel/Token.h" - -#include "RelationalAccess/IQuery.h" -#include "RelationalAccess/ICursor.h" -#include "RelationalAccess/ISessionProxy.h" -#include "RelationalAccess/ISessionProperties.h" - -#include "CoralBase/Attribute.h" -#include "CoralBase/AttributeList.h" -#include "CoralBase/MessageStream.h" - -#include "POOLCore/Exception.h" - -#include "CollectionBase/ICollectionDescription.h" - -#include <iostream> -using namespace std; - - -namespace pool { - namespace RelationalCollection { - - // convert empty Tokens into zeroes - string guidFromToken( const Token& token ) { - return token.dbID().toString(); - } - - - void GUIDQuery::readGUIDs() - { - m_guids.clear(); - coral::MessageStream log( "pool::RelationalCollection::readGUIDs()" ); - - if( m_session.properties().flavorName() != "Oracle" || m_selectedTokenColumnNames.size() <= 1 ) { - // simple version for a single token, or non-oracle database - for( std::set<std::string>::const_iterator - tokenNameI = m_selectedTokenColumnNames.begin(), - end = m_selectedTokenColumnNames.end(); - tokenNameI != end; ++tokenNameI ) { - log << coral::Debug - << "Querying GUIDs for token " << *tokenNameI << coral::MessageStream::endmsg; - readGUIDs( *tokenNameI ); - } - return; - } - - // Oracle version - single query for all tokens, using CASE syntax - - prepareQueryCondition(); - prepareQuery(); - - // Create a subquery that produces a sequence (1,2,.., <number of tokens>) - // used in the main query to iterate over the tokens in a single row - string tokenSubQueryName = "token_seq"; - string tokenNumName = "token_num"; - coral::IQueryDefinition& subquery = m_query->defineSubQuery(tokenSubQueryName); - subquery.addToTableList( RelationalCollectionNames::nameOfCollectionDescriptionsTable() ); - coral::AttributeList bindings; - bindings.extend(tokenNumName, typeid(unsigned)); - bindings[tokenNumName].data<unsigned>() = m_selectedTokenColumnNames.size(); - log << coral::Debug << "Selecting " << bindings[tokenNumName].data<unsigned>() << " tokens" << coral::MessageStream::endmsg; - subquery.setCondition("rownum<= :"+tokenNumName, bindings); - subquery.addToOutputList("rownum", tokenNumName); - - m_query->addToTableList( tokenSubQueryName ); - - // create the case statements for the main query - one switch per token - // it will extract the token link reference and token name - std::ostringstream sqlTokID; - std::ostringstream sqlTokName; - sqlTokID << "case"; - sqlTokName << "case"; - int tokenN = 1; - for( std::set<std::string>::const_iterator - tokenNameI = m_selectedTokenColumnNames.begin(), - end = m_selectedTokenColumnNames.end(); - tokenNameI != end; ++tokenNameI ) - { - string oid1ColumnName = m_tableTokenColumnPrefixForCollectionTokenColumnName.find( *tokenNameI )->second + RelationalCollectionNames::oid_1_variableInCollectionDataTable(); - sqlTokID << " when " << tokenSubQueryName << "." << tokenNumName << "=" <<tokenN - << " then " << oid1ColumnName; - sqlTokName << " when " << tokenSubQueryName << "." << tokenNumName << "=" <<tokenN - << " then " << "'" << *tokenNameI << "'"; - tokenN++; - } - sqlTokID << " end "; - sqlTokName << " end "; - m_query->addToOutputList( sqlTokID.str(), "TokenLink" ); - m_outputDataBuffer->extend( "TokenLink", typeid(unsigned) ); - - m_query->addToOutputList( sqlTokName.str(), "TokenName" ); - m_outputDataBuffer->extend( "TokenName", typeid(string) ); - - // Execute query and retrieve cursor for navigation over result. - m_query->defineOutput( *m_outputDataBuffer ); - m_query->setDistinct(); - - coral::ICursor& cursor = m_query->execute(); - - // map token link IDs into GUIDs using the link tables retrieved when opening the collection - Token token; - while( cursor.next() ) { - unsigned linkId = cursor.currentRow()[0].data< unsigned >(); - const string& tokenName = cursor.currentRow()[1].data< string >(); - const string& fragmentName = m_description.collectionFragmentName( tokenName ); - std::map< unsigned, std::string >* tokenKeyForLinkId = m_mapOfTokenKeyForLinkIdMaps.find( fragmentName )->second; - token.fromString( tokenKeyForLinkId->find( linkId )->second ); - m_guids.insert( make_pair(guidFromToken(token), tokenName) ); - //cout << token.dbID() << " " << tokenName << endl; - } - } - - - - void GUIDQuery::readGUIDs( const std::string& tokenName ) - { - prepareQueryCondition(); - prepareQuery(); - - // Form the OID_1 column name of the Token. - std::string oid1ColumnName = m_tableTokenColumnPrefixForCollectionTokenColumnName.find( tokenName ) ->second - + RelationalCollectionNames::oid_1_variableInCollectionDataTable(); - - m_query->addToOutputList( oid1ColumnName ); - m_outputDataBuffer->extend( oid1ColumnName, typeid(unsigned) ); - - // Execute query and retrieve cursor for navigation over result. - m_query->defineOutput( *m_outputDataBuffer ); - m_query->setDistinct(); - coral::ICursor& cursor = m_query->execute(); - - // map token link IDs into GUIDs using the link tables retrieved when opening the collection - string fragmentName = m_description.collectionFragmentName( tokenName ); - std::map< unsigned, std::string >* tokenKeyForLinkId = m_mapOfTokenKeyForLinkIdMaps.find( fragmentName )->second; - Token token; - while( cursor.next() ) { - unsigned linkId = cursor.currentRow()[0].data< unsigned >(); - token.fromString( tokenKeyForLinkId->find( linkId )->second ); - m_guids.insert( make_pair(guidFromToken(token),tokenName) ); - } - - } - - - - void GUIDQuery::addToAttributeOutputList( const std::string& columnName ) - { - std::string errorMsg( "Attribute `" + columnName + "' is not a Token" ); - throw pool::Exception( errorMsg, - "RelationalCollectionGUIDQuery::addToOutputList", - "RelationalCollection" ); - } - - - const GUIDQuery::CountedGroupedGUIDs& - GUIDQuery::getGroupedGUIDs() - { - m_groupedGUIDs.clear(); - coral::MessageStream log( "pool::RelationalCollection::getGroupedGUIDs()" ); - - prepareQueryCondition(); - prepareQuery(); - - /* create query in the form: - SELECT COUNT(*), tokens GROUP BY tokens - it will extract the token link references */ - m_query->addToOutputList( "count(*)", "count" ); - m_outputDataBuffer->extend( "count", typeid(unsigned) ); - string sep, groupby; - for( std::set<std::string>::const_iterator - tokenNameI = m_selectedTokenColumnNames.begin(), - end = m_selectedTokenColumnNames.end(); - tokenNameI != end; ++tokenNameI ) - { - string oid1ColumnName = m_tableTokenColumnPrefixForCollectionTokenColumnName.find( *tokenNameI )->second + RelationalCollectionNames::oid_1_variableInCollectionDataTable(); - m_query->addToOutputList( oid1ColumnName, *tokenNameI ); - m_outputDataBuffer->extend( *tokenNameI, typeid(unsigned) ); - groupby += sep + oid1ColumnName; - sep = ","; - m_groupedGUIDs.tokenNames.push_back( *tokenNameI ); - } - m_query->groupBy( groupby ); - - // Execute query and retrieve cursor for navigation over result. - m_query->defineOutput( *m_outputDataBuffer ); - coral::ICursor& cursor = m_query->execute(); - - // map token link IDs into GUIDs using the link tables retrieved when opening the collection - Token token; - while( cursor.next() ) { - countedGUIDGroup_t row; - row.first = cursor.currentRow()[0].data< unsigned >(); - for( std::set<std::string>::const_iterator - tokenNameI = m_selectedTokenColumnNames.begin(), - end = m_selectedTokenColumnNames.end(); - tokenNameI != end; ++tokenNameI ) - { - unsigned linkId = cursor.currentRow()[*tokenNameI].data< unsigned >(); - const string& fragmentName = m_description.collectionFragmentName( *tokenNameI ); - std::map< unsigned, std::string >* tokenKeyForLinkId = m_mapOfTokenKeyForLinkIdMaps.find( fragmentName )->second; - token.fromString( tokenKeyForLinkId->find( linkId )->second ); - row.second.push_back( guidFromToken(token) ); - } - // check for duplicated rows - result of an old linktable insert bug - // if found, just sum up the count - bool found(false); - for( vector< countedGUIDGroup_t >::iterator rowi = m_groupedGUIDs.groupedGUIDRows.begin(), - end = m_groupedGUIDs.groupedGUIDRows.end(); rowi != end; ++rowi ) { - bool match(true); - for( unsigned t = 0; t < rowi->second.size(); t++ ) { - if( row.second[t] != rowi->second[t] ) { - match = false; break; - } - } - if( match ) { - rowi->first += row.first; - found = true; - break; - } - } - if( !found ) - m_groupedGUIDs.groupedGUIDRows.push_back( row ); - } - return m_groupedGUIDs; - } - - - } -} - - - diff --git a/Database/APR/RelationalCollection/src/GUIDQuery.h b/Database/APR/RelationalCollection/src/GUIDQuery.h deleted file mode 100755 index 075f0c6ee956ba5bf9c4a2f34d3d76cb9b4f9c8a..0000000000000000000000000000000000000000 --- a/Database/APR/RelationalCollection/src/GUIDQuery.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#ifndef RELATIONALCOLLECTION_RELATIONALCOLLECTIONGUIDQUERY_H -#define RELATIONALCOLLECTION_RELATIONALCOLLECTIONGUIDQUERY_H - -// Disable warning C4250 on Windows (inheritance via dominance) -#ifdef WIN32 -#pragma warning ( disable : 4250 ) -#endif - -/* - * @author Marcin.Nowak@cern.ch - */ - - -#include "RelationalCollectionQuery.h" -#include "CollectionBase/ICollectionRelationalExtensions.h" - -#include <set> - - -namespace pool { - namespace RelationalCollection { - - - class GUIDQuery : public RelationalCollectionQuery, - virtual public ICollectionGUIDQuery - { - public: - GUIDQuery( coral::ISessionProxy& session, - const pool::ICollectionDescription& description, - const std::map< std::string, std::string >& dataTableNameForCollectionFragmentName, - const std::map< std::string, std::string >& linksTableNameForCollectionFragmentName, - const std::map< std::string, std::string >& tableTokenColumnPrefixForCollectionTokenColumnName, - const std::map< std::string, std::string >& tableAttributeColumnNameForCollectionAttributeColumnName, - const coral::AttributeList& tableAttributeList, - const std::map< std::string, std::map< std::string, unsigned >* >& mapOfLinkIdForTokenKeyMaps, - const std::map< std::string, std::map< unsigned, std::string >* >& mapOfTokenKeyForLinkIdMaps ) - : RelationalCollectionQuery( - session, description, - dataTableNameForCollectionFragmentName, - linksTableNameForCollectionFragmentName, - tableTokenColumnPrefixForCollectionTokenColumnName, - tableAttributeColumnNameForCollectionAttributeColumnName, - tableAttributeList, - mapOfLinkIdForTokenKeyMaps, - mapOfTokenKeyForLinkIdMaps, - false /* do not add primary key */ ) - { } - - /// Query all GUIDs that were requested using AddToOutputList() - void readGUIDs(); - - /// Query GUIDs for a specific Token. Results are accumulated in the GUID Set - void readGUIDs( const std::string& tokenName ); - - /// Provide access to the GUID set. - virtual const GUIDSet& getGUIDs() { return m_guids; } - - virtual const CountedGroupedGUIDs& getGroupedGUIDs(); - - protected: - GUIDSet m_guids; - CountedGroupedGUIDs m_groupedGUIDs; - - // hide methods not supposed to be called - protected: - /// this method does not make sense in a GUID query - void addToAttributeOutputList( const std::string& columnName ); - - /// not useable since there is no special Cursor (yet?) for this type of query - ICollectionCursor& execute() { return RelationalCollectionQuery::execute(); } - }; - - } -} -#endif diff --git a/Database/APR/RelationalCollection/src/RelationalCollection.cpp b/Database/APR/RelationalCollection/src/RelationalCollection.cpp deleted file mode 100644 index ecc1eeec38d30aa3844a42ccd0730928f3a4ee74..0000000000000000000000000000000000000000 --- a/Database/APR/RelationalCollection/src/RelationalCollection.cpp +++ /dev/null @@ -1,2267 +0,0 @@ -/* - Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration -*/ - -#include "RelationalCollection.h" -#include "RelationalCollectionNames.h" -#include "RelationalCollectionBindVariables.h" -#include "RelationalCollectionSchemaEditor.h" -#include "RelationalCollectionDataEditor.h" -#include "RelationalCollectionQuery.h" -#include "RelationalCollectionMetadata.h" -#include "DBLock.h" -#include "GUIDQuery.h" - -#include "PersistentDataModel/Token.h" - -#include "CollectionBase/ICollectionFragment.h" -#include "CollectionBase/ICollectionIndex.h" -#include "CollectionBase/ICollectionColumn.h" -#include "CollectionBase/ICollectionUniqueConstraint.h" -#include "CollectionBase/CollectionRowBuffer.h" -#include "CollectionBase/CollectionBaseNames.h" -#include "CollectionBase/ICollectionMetadata.h" - -#include "POOLCore/Exception.h" - -#include "RelationalAccess/ISessionProxy.h" -#include "RelationalAccess/ISessionProperties.h" -#include "RelationalAccess/ConnectionService.h" -#include "RelationalAccess/ITransaction.h" -#include "RelationalAccess/ISchema.h" -#include "RelationalAccess/IQuery.h" -#include "RelationalAccess/ICursor.h" -#include "RelationalAccess/TableDescription.h" -#include "RelationalAccess/ITable.h" -#include "RelationalAccess/IView.h" -#include "RelationalAccess/ITablePrivilegeManager.h" -#include "RelationalAccess/IConnectionServiceConfiguration.h" -#include "RelationalAccess/ITableDataEditor.h" - -#include "CoralBase/AttributeList.h" -#include "CoralBase/Attribute.h" -#include "CoralBase/AttributeSpecification.h" - -#include <memory> -#include <iostream> -#include <cstdio> // For sprintf (bug #69271) -using namespace std; -using namespace pool; - - -pool::RelationalCollection::RelationalCollection:: -RelationalCollection( const pool::ICollectionDescription* description, - pool::ICollection::OpenMode mode, - pool::ISession* ) - : m_description( *description ), - m_mode( mode ), - m_session( 0 ), - m_name( description->name() ), - m_schemaEditor( 0 ), - m_dataEditor( 0 ), - m_metadata( 0 ), - m_whereClauseForCollectionNameInHeadersTable( RelationalCollectionBindVariables::whereClauseForCollectionNameInHeadersTable() ), - m_whereClauseForChildCollectionNameInHeadersTable( RelationalCollectionBindVariables::whereClauseForChildCollectionNameInHeadersTable() ), - m_whereClauseForCollectionNameInDescriptionsTable( RelationalCollectionBindVariables::whereClauseForCollectionNameInDescriptionsTable() ), - m_whereClauseForCollectionNameInIndexDescriptionsTable( RelationalCollectionBindVariables::whereClauseForCollectionNameInIndexDescriptionsTable() ), - m_whereClauseForIndexNameInIndexDescriptionsTable( RelationalCollectionBindVariables::whereClauseForIndexNameInIndexDescriptionsTable() ), - m_whereDataForCollectionNameInHeadersTable( new coral::AttributeList ), - m_whereDataForChildCollectionNameInHeadersTable( new coral::AttributeList ), - m_whereDataForCollectionNameInDescriptionsTable( new coral::AttributeList ), - m_whereDataForCollectionNameInIndexDescriptionsTable( new coral::AttributeList ), - m_whereDataForIndexNameInIndexDescriptionsTable( new coral::AttributeList ), - m_dataTableNameForCollectionFragmentName(), - m_linksTableNameForCollectionFragmentName(), - m_tableTokenColumnPrefixForCollectionTokenColumnName(), - m_tableAttributeColumnNameForCollectionAttributeColumnName(), - m_tableColumnNameForCollectionColumnName(), - m_collectionColumnNameForTableColumnPosition(), - m_tableAttributeList( new coral::AttributeList ), - m_collectionRowBuffer(), - m_dataTableRowBufferForCollectionFragmentName(), - m_linksTableRowBuffer( new coral::AttributeList ), - m_mapOfLinkIdForTokenKeyMaps(), - m_mapOfTokenKeyForLinkIdMaps(), - m_mapOfWhereClausesForOID1InDataTable(), - m_mapOfWhereDataForOID1InDataTable(), - m_initialized( false ) - //, m_poolOut( "RelationalCollection", coral::Debug ) - -{ - // Define bind variable type used in where clause to find collection fragment name in collection headers table. - m_whereDataForCollectionNameInHeadersTable->extend<std::string>( RelationalCollectionNames::collectionNameVariableInCollectionHeadersTable() ); - - // Define bind variable type used in where clause to find child collection fragment name in collection headers table. - m_whereDataForChildCollectionNameInHeadersTable->extend<std::string>( RelationalCollectionNames::childCollectionNameVariableInCollectionHeadersTable() ); - - // Define bind variable type used in where clause to find collection fragment name in collection descriptions table. - m_whereDataForCollectionNameInDescriptionsTable->extend<std::string>( RelationalCollectionNames::collectionNameVariableInCollectionDescriptionsTable() ); - - // Define bind variable type used in where clause to find collection fragment name in collection index descriptions table. - m_whereDataForCollectionNameInIndexDescriptionsTable->extend<std::string>( RelationalCollectionNames::collectionNameVariableInCollectionIndexDescriptionsTable() ); - - // Define bind variable types used in where clause to find index name in collection index descriptions table. - m_whereDataForIndexNameInIndexDescriptionsTable->extend<std::string>( RelationalCollectionNames::indexNameVariableInCollectionIndexDescriptionsTable() ); - m_whereDataForIndexNameInIndexDescriptionsTable->extend<std::string>( RelationalCollectionNames::collectionNameVariableInCollectionIndexDescriptionsTable() ); - - // Initialize and open collection. - open(); -} - - -pool::RelationalCollection::RelationalCollection::~RelationalCollection() -{ - if( isOpen() ) close(); - - delete m_schemaEditor; m_schemaEditor = 0; - delete m_dataEditor; m_dataEditor = 0; - delete m_metadata; m_metadata = 0; - - delete m_whereDataForCollectionNameInHeadersTable; - delete m_whereDataForChildCollectionNameInHeadersTable; - delete m_whereDataForCollectionNameInDescriptionsTable; - delete m_whereDataForCollectionNameInIndexDescriptionsTable; - delete m_whereDataForIndexNameInIndexDescriptionsTable; - delete m_tableAttributeList; - delete m_linksTableRowBuffer; - - for ( std::map< std::string, coral::AttributeList* >::iterator iBuffer = - m_dataTableRowBufferForCollectionFragmentName.begin(); iBuffer != - m_dataTableRowBufferForCollectionFragmentName.end(); ++iBuffer ) - { - delete iBuffer->second; - } - - for ( std::map< std::string, std::map< std::string, unsigned >* >::iterator iMap = - m_mapOfLinkIdForTokenKeyMaps.begin(); iMap != m_mapOfLinkIdForTokenKeyMaps.end(); ++iMap ) - { - delete iMap->second; - } - - for ( std::map< std::string, std::map< unsigned, std::string >* >::iterator iMap = - m_mapOfTokenKeyForLinkIdMaps.begin(); iMap != m_mapOfTokenKeyForLinkIdMaps.end(); ++iMap ) - { - delete iMap->second; - } - - for ( std::map< std::string, coral::AttributeList* >::iterator iList = - m_mapOfWhereDataForOID1InDataTable.begin(); iList != - m_mapOfWhereDataForOID1InDataTable.end(); ++iList ) - { - delete iList->second; - } - -// m_poolOut << "Collection destructor finished" << coral::MessageStream::endmsg; -} - - -pool::ICollection::OpenMode -pool::RelationalCollection::RelationalCollection::openMode() const -{ - return m_mode; -} - - -void -pool::RelationalCollection::RelationalCollection::open() -{ - if( isOpen() ) return; - - // Get connection service. - unique_ptr<coral::ConnectionService> connectionService( new coral::ConnectionService() ); - coral::MessageStream log( "pool::RelationalCollection::open" ); - // Retrieve a connection handle. - bool readOnly = ( m_mode == pool::ICollection::READ ); - log << coral::Info << " Opening relational collection " << (readOnly? "in READ mode" : "") << coral::MessageStream::endmsg; - try { - coral::IConnectionServiceConfiguration& coralConf( connectionService->configuration() ); - - const char *env = getenv("POOL_RCOLL_CONN_RETRY"); - int retry = env? atoi(env) : 0; - env = getenv("POOL_RCOLL_CONN_TIMEOUT"); - int timeout = env? atoi(env) : 0; - - if( retry > 0 || timeout > 0 ) { - if( retry > 0 ) { - log << coral::Info - << "Setting Coral DB connection retry period to " << retry << " seconds" << coral::MessageStream::endmsg; - coralConf.setConnectionRetrialPeriod( retry ); - } - if( timeout > 0 ) { - log << coral::Info - << "Setting Coral DB connection timeout " << timeout << " seconds" << coral::MessageStream::endmsg; - coralConf.setConnectionRetrialTimeOut( timeout ); - } - } - - - m_session = connectionService->connect( m_description.connection(), - (readOnly? coral::ReadOnly : coral::Update) ); - - // Start a transaction. - coral::ITransaction& transaction = m_session->transaction(); - if ( !transaction.isActive() ) { - transaction.start( readOnly ); - } - - // Initialize collection if necessary. - if( !m_initialized ) try { - initialize(); - } catch( pool::Exception& ) { - if( m_session->transaction().isActive() ) - m_session->transaction().rollback(); - delete m_session; m_session = 0; - throw; - } - else { - // reinitialize the pointer to the database schema - m_dataEditor->m_schema = &m_session->nominalSchema(); - } - - } catch( coral::Exception &e ) { - log << coral::Error << " ***** Exception " << e.what() - << coral::MessageStream::endmsg; - throw pool::Exception( e.what(), - "RelationalCollection::open", - "RelationalCollection" ); - } -} - - -bool -pool::RelationalCollection::RelationalCollection::isOpen() const -{ - return ( m_session != 0 ); -} - - -void -pool::RelationalCollection::RelationalCollection::commit( bool restartTransaction ) -{ - coral::ITransaction& transaction = m_session->transaction(); - if( !transaction.isActive() ) - return; - if( m_dataEditor ) - m_dataEditor->flushCachedRows(); - transaction.commit(); - if( restartTransaction ) { - bool readOnly = ( m_mode == pool::ICollection::READ ); - transaction.start( readOnly ); - if( m_metadata ) { - m_metadata->reinitialize( m_session ); - } - } -} - - -void -pool::RelationalCollection::RelationalCollection::rollback() -{ - coral::ITransaction& transaction = m_session->transaction(); - if( !transaction.isActive() ) - return; - m_dataEditor->deleteRowCache(); - transaction.rollback(); - - bool readOnly = ( m_mode == pool::ICollection::READ ); - transaction.start( readOnly ); - m_dataEditor->createRowCache(); -} - - -void -pool::RelationalCollection::RelationalCollection::close() -{ - if( m_session ) { - coral::ITransaction& transaction = m_session->transaction(); - if( transaction.isActive() ) { - m_dataEditor->deleteRowCache(); - transaction.rollback(); - } - delete m_session; m_session = 0; - } - delete m_metadata; m_metadata = 0; -} - - -bool -pool::RelationalCollection::RelationalCollection:: -exists( const std::string& fragmentName, - bool setForUpdate, - bool checkChildFragments ) const -{ - coral::ISchema& nominalSchema = m_session->nominalSchema(); - - // Check top level collection fragment by default. - int minId = m_description.collectionFragment( fragmentName.size()? fragmentName : m_name ).id(); - int maxId = minId; - if ( checkChildFragments ) { - maxId = m_description.numberOfCollectionFragments() - 1; - } - - for( int i = minId; i <= maxId; ++i ) { - coral::IQuery* query = nominalSchema.tableHandle( RelationalCollectionNames::nameOfCollectionHeadersTable() ).newQuery(); - - // Get collection fragment name. - std::string fname = m_description.collectionFragment( i ).name(); - - // Lock existing row in collection headers table for this collection fragment for duration of transaction. - if( setForUpdate ) { - query->setForUpdate(); - } - - // Set predicates and execute query. - m_whereDataForCollectionNameInHeadersTable->begin()->data<std::string>() = fname; - query->setCondition( m_whereClauseForCollectionNameInHeadersTable, *m_whereDataForCollectionNameInHeadersTable ); - query->limitReturnedRows( 1, 0 ); - coral::ICursor& cursor = query->execute(); - bool exists = cursor.next(); - delete query; - - if ( ! exists ) { - coral::MessageStream log( "pool::RelationalCollection::RelationalCollection::exists()" ); - log << coral::Debug - << "Collection fragment `" + fname + "' does not exist." << coral::MessageStream::endmsg; - return false; - } - } - - return true; -} - - -bool -pool::RelationalCollection::RelationalCollection:: -drop( const std::string& _fragmentName, - bool dropChildFragments, - bool ignoreExternalDependencies ) -{ - bool docommit( true ); - return drop_impl( _fragmentName, dropChildFragments, ignoreExternalDependencies, docommit ); -} - - -bool -pool::RelationalCollection::RelationalCollection:: -drop_impl( const std::string& _fragmentName, - bool dropChildFragments, - bool ignoreExternalDependencies, - bool do_commit ) - -{ - coral::ISchema& nominalSchema = m_session->nominalSchema(); - coral::MessageStream log( "pool::RelationalCollection::RelationalCollection::drop()" ); - - // Drop top level collection fragment by default. - string fragmentName = ( _fragmentName.size()? _fragmentName : m_name ); - int minId = m_description.collectionFragment( fragmentName ).id(); - int maxId = minId; - if( dropChildFragments ) { - maxId = m_description.numberOfCollectionFragments() - 1; - } - - for ( int i = minId; i <= maxId; ++i ) { - std::string fname = m_description.collectionFragment( i ).name(); - - // Continue if collection fragment does not exist. - if( !exists( fname, true ) ) { - log << coral::Warning - << "Collection fragment `" + fname + "' does not exist." - << coral::MessageStream::endmsg; - continue; - } - - // Drop foreign key constraint from child collection fragment if such constraint exists. - dropChildForeignKeyConstraint( fname ); - - // Find any dependencies on parent fragments not defined in the collection description. - std::vector< std::string > parentFragmentNames; - coral::ITable& headersTable = nominalSchema.tableHandle( RelationalCollectionNames::nameOfCollectionHeadersTable() ); - coral::IQuery* query = headersTable.newQuery(); - m_whereDataForChildCollectionNameInHeadersTable->begin()->data<std::string>() = fname; - query->addToOutputList( RelationalCollectionNames::collectionNameVariableInCollectionHeadersTable() ); - query->setCondition( m_whereClauseForChildCollectionNameInHeadersTable, - *m_whereDataForChildCollectionNameInHeadersTable ); - coral::ICursor& cursor = query->execute(); - while ( cursor.next() ) { - const coral::AttributeList& row = cursor.currentRow(); - parentFragmentNames.push_back( row[0].data<std::string>() ); - } - delete query; - - // If external dependencies are not be ignored stop dropping fragments after first one is found. - if( parentFragmentNames.size() && !ignoreExternalDependencies ) { - return false; - } - - // If collection fragment is referenced by a foreign key, drop the foreign key. - std::string foreignKeyName = m_description.collectionFragment( i ).foreignKeyName(); - if( foreignKeyName.size() ) { - std::string childFragmentName = m_description.collectionFragment( i ).childCollectionFragmentName(); - std::string childDataTableName = ( m_dataTableNameForCollectionFragmentName.find( childFragmentName ) )->second; - nominalSchema.tableHandle( childFragmentName ).schemaEditor().dropForeignKey( foreignKeyName ); - } - - // If collection fragment has parent fragments, update parent fragment rows in collection headers table. - for (const std::string& name : parentFragmentNames ) - { - m_whereDataForCollectionNameInHeadersTable->begin()->data<std::string>() = name; - std::string setClause = RelationalCollectionNames::childCollectionNameVariableInCollectionHeadersTable() + " = " + "\'\'" + " , " + RelationalCollectionNames::foreignKeyNameVariableInCollectionHeadersTable() + " = " + "\'\'"; - nominalSchema.tableHandle( RelationalCollectionNames::nameOfCollectionHeadersTable() ).dataEditor().updateRows( - setClause, - m_whereClauseForCollectionNameInHeadersTable, - *m_whereDataForCollectionNameInHeadersTable ); - } - - // Drop data and links tables of collection. - string &tableName = m_dataTableNameForCollectionFragmentName[ fname ]; - if( nominalSchema.existsTable( tableName) ) - nominalSchema.dropTable( tableName); - tableName = m_linksTableNameForCollectionFragmentName[ fname ]; - if( nominalSchema.existsTable( tableName) ) - nominalSchema.dropTable( tableName ); - - // Delete corresponding rows in collection descriptions table. - m_whereDataForCollectionNameInDescriptionsTable->begin()->data<std::string>() = fname; - nominalSchema.tableHandle( RelationalCollectionNames::nameOfCollectionDescriptionsTable() ).dataEditor().deleteRows( - m_whereClauseForCollectionNameInDescriptionsTable, *m_whereDataForCollectionNameInDescriptionsTable ); - - // Delete corresponding row in collection headers table. - m_whereDataForCollectionNameInHeadersTable->begin()->data<std::string>() = fname; - nominalSchema.tableHandle( RelationalCollectionNames::nameOfCollectionHeadersTable() ).dataEditor().deleteRows( - m_whereClauseForCollectionNameInHeadersTable, *m_whereDataForCollectionNameInHeadersTable ); - - // Drop collection fragment from collection description. - if( m_schemaEditor ) { - if( fragmentName != m_name ) { - // do not call for the main fragment - it will not work - // assume that we want to delete everything in such case and do not even touch the description - m_schemaEditor->dropCollectionFragment( fname ); - } - } - } - - // Delete metadata - metadata(); // force metadata initialization //hack around no delete in IMetadata. MN - int metadata_deleted = m_metadata->deleteCollectionMetadata(); - log << coral::Debug - << "Deleted " << metadata_deleted << " metadata entries for collection `" + fragmentName + "'." - << coral::MessageStream::endmsg; - - if( do_commit ) commit( true ); - return true; -} - - -bool -pool::RelationalCollection::RelationalCollection::rename( const std::string& oldName, - const std::string& newName ) -{ - if ( oldName == m_name ) { - m_name = newName; - } - - m_schemaEditor->renameCollectionFragment( oldName, newName ); - - return true; -} - - -bool -pool::RelationalCollection::RelationalCollection::grantToUser( const std::string& userName, - pool::ICollection::Privilege privilege, - const std::string& fragmentName, - bool grantForChildFragments ) -{ - coral::ISchema& nominalSchema = m_session->nominalSchema(); - - // Get data table privilege. Default is to grant select privilege. - coral::ITablePrivilegeManager::Privilege dataTablePrivilege; - switch ( privilege ) - { - case UPDATE_ACCESS: - dataTablePrivilege = coral::ITablePrivilegeManager::Update; - break; - case WRITE_ACCESS: - dataTablePrivilege = coral::ITablePrivilegeManager::Insert; - break; - case DELETE_ACCESS: - dataTablePrivilege = coral::ITablePrivilegeManager::Delete; - break; - default: - dataTablePrivilege = coral::ITablePrivilegeManager::Select; - } - - // Grant privilege for top level collection fragment by default. - int minId = m_description.collectionFragment( fragmentName.size()? fragmentName : m_name ).id(); - int maxId = minId; - if ( grantForChildFragments ) { - maxId = m_description.numberOfCollectionFragments() - 1; - } - - // Loop over requested collection fragments. - for ( int i = minId; i <= maxId; ++i ) { - // Get name of data table for this collection fragment. - std::string dataTableName = ( m_dataTableNameForCollectionFragmentName.find( - m_description.collectionFragment( i ).name() ) )->second; - - // Grant privilege for this collection fragment. - nominalSchema.tableHandle( dataTableName ).privilegeManager().grantToUser( userName, dataTablePrivilege ); - } - - return true; -} - - -bool -pool::RelationalCollection::RelationalCollection::revokeFromUser( const std::string& userName, - pool::ICollection::Privilege privilege, - const std::string& fragmentName, - bool revokeForChildFragments ) -{ - coral::ISchema& nominalSchema = m_session->nominalSchema(); - - // Get data table privilege. Default is to revoke delete privilege. - coral::ITablePrivilegeManager::Privilege dataTablePrivilege; - switch ( privilege) - { - case READ_ACCESS: - dataTablePrivilege = coral::ITablePrivilegeManager::Select; - break; - case UPDATE_ACCESS: - dataTablePrivilege = coral::ITablePrivilegeManager::Update; - break; - case WRITE_ACCESS: - dataTablePrivilege = coral::ITablePrivilegeManager::Insert; - break; - default: - dataTablePrivilege = coral::ITablePrivilegeManager::Delete; - } - - // Revoke privilege for top level collection fragment by default. - int minId = m_description.collectionFragment( fragmentName.size()? fragmentName : m_name ).id(); - int maxId = minId; - if ( revokeForChildFragments ) - { - maxId = m_description.numberOfCollectionFragments() - 1; - } - - // Loop over requested collection fragments. - for ( int i = minId; i <= maxId; ++i ) - { - // Get name of data table for this collection fragment. - std::string dataTableName = ( m_dataTableNameForCollectionFragmentName.find( - m_description.collectionFragment( i ).name() ) )->second; - - // Revoke privilege for this collection fragment. - nominalSchema.tableHandle( dataTableName ).privilegeManager().revokeFromUser( userName, dataTablePrivilege ); - } - - return true; -} - - -bool -pool::RelationalCollection::RelationalCollection::grantToPublic( const std::string& fragmentName, bool grantForChildFragments ) -{ - coral::ISchema& nominalSchema = m_session->nominalSchema(); - - // Grant privilege for top level collection fragment by default. - int minId = m_description.collectionFragment( fragmentName.size()? fragmentName : m_name ).id(); - int maxId = minId; - if ( grantForChildFragments ) - { - maxId = m_description.numberOfCollectionFragments() - 1; - } - - // Loop over requested collection fragments. - for ( int i = minId; i <= maxId; ++i ) - { - // Get name of data table for this collection fragment. - std::string dataTableName = ( m_dataTableNameForCollectionFragmentName.find( - m_description.collectionFragment( i ).name() ) )->second; - - // Grant privilege for this collection fragment. - nominalSchema.tableHandle( dataTableName ).privilegeManager().grantToPublic( coral::ITablePrivilegeManager::Select ); - } - - return true; -} - - -bool -pool::RelationalCollection::RelationalCollection::revokeFromPublic( const std::string& fragmentName, bool revokeForChildFragments ) -{ - coral::ISchema& nominalSchema = m_session->nominalSchema(); - - // Revoke privilege for top level collection fragment by default. - int minId = m_description.collectionFragment( fragmentName.size()? fragmentName : m_name ).id(); - int maxId = minId; - if ( revokeForChildFragments ) - { - maxId = m_description.numberOfCollectionFragments() - 1; - } - - // Loop over requested collection fragments. - for ( int i = minId; i <= maxId; ++i ) - { - // Get name of data table for this collection fragment. - std::string dataTableName = ( m_dataTableNameForCollectionFragmentName.find( - m_description.collectionFragment( i ).name() ) )->second; - - // Revoke privilege for this collection fragment. - nominalSchema.tableHandle( dataTableName ).privilegeManager().revokeFromPublic( coral::ITablePrivilegeManager::Select ); - } - - return true; -} - - -const pool::ICollectionDescription& -pool::RelationalCollection::RelationalCollection::description() const -{ - return m_description; -} - - -pool::ICollectionSchemaEditor& -pool::RelationalCollection::RelationalCollection::schemaEditor() -{ - if ( m_mode == pool::ICollection::READ ) { - std::string errorMsg = "Cannot modify the schema of a collection in READ open mode."; - throw pool::Exception( errorMsg, - "RelationalCollection::schemaEditor", - "RelationalCollection" ); - } - - return ( *m_schemaEditor ); -} - - -pool::ICollectionDataEditor& -pool::RelationalCollection::RelationalCollection::dataEditor() -{ - if ( m_mode == pool::ICollection::READ ) - { - std::string errorMsg = "Cannot modify the data of a collection in READ open mode."; - throw pool::Exception( errorMsg, - "RelationalCollection::dataEditor", - "RelationalCollection" ); - } - - return ( *m_dataEditor ); -} - - -pool::ICollectionQuery* -pool::RelationalCollection::RelationalCollection::newQuery() const -{ - return new RelationalCollectionQuery( - *m_session, - m_description, - m_dataTableNameForCollectionFragmentName, - m_linksTableNameForCollectionFragmentName, - m_tableTokenColumnPrefixForCollectionTokenColumnName, - m_tableAttributeColumnNameForCollectionAttributeColumnName, - *m_tableAttributeList, - m_mapOfLinkIdForTokenKeyMaps, - m_mapOfTokenKeyForLinkIdMaps ); -} - - -pool::ICollectionMetadata& -pool::RelationalCollection::RelationalCollection::metadata() -{ - { - if( !m_metadata ) { - m_metadata = new RelationalCollectionMetadata(); - m_metadata->initialize( m_description.name(), *m_session, m_mode ); - } - return *m_metadata; - } -} - - -void -pool::RelationalCollection::RelationalCollection:: -initialize() -{ - // debug stuff to clean up later - std::string OpenModeNames[10]; - OpenModeNames[pool::ICollection::READ] = "read"; - OpenModeNames[pool::ICollection::UPDATE] = "update"; - OpenModeNames[pool::ICollection::CREATE] = "create"; - OpenModeNames[pool::ICollection::CREATE_AND_OVERWRITE] = "create-and-overwrite"; - OpenModeNames[pool::ICollection::CREATE_MISSING_FRAGMENTS] = "create-missing-fragments"; - - coral::MessageStream log( "pool::RelationalCollection::init" ); - log << coral::Info << "Opening collection `" << m_name << "' in " << OpenModeNames[m_mode] << " mode " << coral::MessageStream::endmsg; - bool inCreateMode = - m_mode == pool::ICollection::CREATE || - m_mode == pool::ICollection::CREATE_MISSING_FRAGMENTS || - m_mode == pool::ICollection::CREATE_AND_OVERWRITE; - - DBLock dbLock( *m_session, m_description.name() ); - if( m_mode != pool::ICollection::READ ) { - bool XTransaction(true); //doing PERM lock, TEMP did not work... MN - dbLock.lock(XTransaction); - } - - coral::ISchema& nominalSchema = m_session->nominalSchema(); - - bool headerTableExists = - nominalSchema.existsTable( RelationalCollectionNames::nameOfCollectionHeadersTable() ) - || nominalSchema.existsView( RelationalCollectionNames::nameOfCollectionHeadersTable() ); - bool descriptionTableExists = - nominalSchema.existsTable( RelationalCollectionNames::nameOfCollectionDescriptionsTable() ) - || nominalSchema.existsView( RelationalCollectionNames::nameOfCollectionDescriptionsTable() ); - bool indexDescTableExists = - nominalSchema.existsTable( RelationalCollectionNames::nameOfCollectionIndexDescriptionsTable() ) - || nominalSchema.existsView( RelationalCollectionNames::nameOfCollectionIndexDescriptionsTable() ); - - string missingTables; - if( !headerTableExists ) - missingTables += RelationalCollectionNames::nameOfCollectionHeadersTable() + " "; - if( !descriptionTableExists ) - missingTables += RelationalCollectionNames::nameOfCollectionDescriptionsTable() + " "; - if( !indexDescTableExists ) - missingTables += RelationalCollectionNames::nameOfCollectionIndexDescriptionsTable() + " "; - - if( !inCreateMode - && (!headerTableExists || !descriptionTableExists || !indexDescTableExists) ) { - std::string errorMsg = "Table(s): " + missingTables + " not existing. Cannot open collection `" + m_name + "' in UPDATE or READ mode."; - throw pool::Exception( errorMsg, - "RelationalCollection::initialize", - "RelationalCollection" ); - } - - if( !(headerTableExists && descriptionTableExists && indexDescTableExists) ) { - if( headerTableExists || descriptionTableExists || indexDescTableExists ) { - // some talbes are missing - do not try to create them so to not mess up some older schema - std::string errorMsg = "Inconsistent database schema: tables: " + missingTables + " are missing. Cannot open collection `" + m_name + "'"; - throw pool::Exception( errorMsg, - "RelationalCollection::initialize", - "RelationalCollection" ); - } - - log << coral::Info << "Creating new database schema for collection `" - << m_name << "'" << coral::MessageStream::endmsg; - createHeadersTable(); - createDescriptionsTable(); - createIndexDescriptionsTable(); - } - - - // delete old collection fragments if requested - if( m_mode == pool::ICollection::CREATE_AND_OVERWRITE ) { - for( int i = 0; i < m_description.numberOfCollectionFragments(); i++ ) { - std::string fragmentName = m_description.collectionFragment( i ).name(); - if( exists( fragmentName, false ) ) { - retrieveFragmentTableNames( fragmentName ); - bool dont_commit(false); - drop_impl( fragmentName, false, true, dont_commit ); - } - } - } - - // For READ or UPDATE open mode retrieve descriptions of collection fragments. - if( m_mode == pool::ICollection::UPDATE || m_mode == pool::ICollection::READ ) { - retrieveCollectionFragmentDescriptions(); - - for( int i = 0; i < m_description.numberOfCollectionFragments(); i++ ) { - std::string fragmentName = m_description.collectionFragment( i ).name(); - if( exists( fragmentName, false ) ) { - // something is wrong with the data model if I need to dyn_cast //MN. - retrieveColumnDescriptions( fragmentName, - dynamic_cast<CollectionDescription*>(&m_description) ); - retrieveFragmentTableNames( fragmentName ); - } else { - std::string errorMsg = "Collection fragment `" + fragmentName + - "' does not exist. Cannot open collection `" + m_name + "' in UPDATE or READ mode."; - throw pool::Exception( errorMsg, - "RelationalCollection::initialize", - "RelationalCollection" ); - } - } - } - - // Create new schema editor object for collection. - m_schemaEditor = new pool::RelationalCollection::RelationalCollectionSchemaEditor( - *m_session, - m_description, - m_dataTableNameForCollectionFragmentName, - m_linksTableNameForCollectionFragmentName, - m_tableTokenColumnPrefixForCollectionTokenColumnName, - m_tableAttributeColumnNameForCollectionAttributeColumnName, - m_tableColumnNameForCollectionColumnName, - m_collectionColumnNameForTableColumnPosition, - *m_tableAttributeList, - m_collectionRowBuffer, - m_dataTableRowBufferForCollectionFragmentName, - m_mapOfWhereClausesForOID1InDataTable, - m_mapOfWhereDataForOID1InDataTable ); - - // Initialize private maps and data row buffers for all collection fragments. - for( int i = 0; i < m_description.numberOfCollectionFragments(); i++ ) { - initializeMapsAndDataRowBuffers( m_description.collectionFragment( i ).name() ); - } - - // Create tables - if( inCreateMode ) { - // Loop over all collection fragments and create new tables - for( int i = 0; i < m_description.numberOfCollectionFragments(); i++ ) { - std::string fragmentName = m_description.collectionFragment( i ).name(); - - // If the fragment does not exist create it - if( !exists( fragmentName, true ) ) { - createDataAndLinksTables( fragmentName ); - } else { - if( m_mode == pool::ICollection::CREATE_MISSING_FRAGMENTS ) { - if( this->newSchemaEqualsExistingSchema( fragmentName ) ) { - retrieveFragmentTableNames( fragmentName ); - // Update row for parent collection fragment in collection headers table. - if( fragmentName != m_name ) { - m_whereDataForCollectionNameInHeadersTable->begin()->data<std::string>() - = m_description.collectionFragment( fragmentName ).parentCollectionFragmentName(); - std::string setClause = RelationalCollectionNames::childCollectionNameVariableInCollectionHeadersTable() + " = " + fragmentName; - nominalSchema.tableHandle( RelationalCollectionNames::nameOfCollectionHeadersTable() ).dataEditor().updateRows( - setClause, - m_whereClauseForCollectionNameInHeadersTable, - *m_whereDataForCollectionNameInHeadersTable ); - } - - // Drop all foreign keys applied by collection fragment except that defined in collection description. - this->dropParentForeignKeyConstraints( fragmentName, true ); - } else { - std::string errorMsg = "Schema of existing collection fragment `" + fragmentName + "' differs from new one. " + "Cannot open collection `" + m_name + "' in open mode CREATE_MISSING_FRAGMENTS."; - throw pool::Exception( errorMsg, - "RelationalCollection::initialize", - "RelationalCollection" ); - } - } else { - std::string errorMsg = "Cannot overwrite existing collection fragment `" + fragmentName + "' of collection `" + m_name + "' in CREATE open mode."; - throw pool::Exception( errorMsg, - "RelationalCollection::initialize", - "RelationalCollection" ); - } - } - } - } - - for( int i = 0; i < m_description.numberOfCollectionFragments(); i++ ) { - createLinkIdToTokenKeyMaps( m_description.collectionFragment( i ).name() ); - } - - // Create row buffer for links table schema. - createLinksTableRowBuffer(); - - // Create any indices, unique constraints or foreign key constraints defined by collection description. - if( inCreateMode ) { - for( int i = 0; i < m_description.numberOfIndices(); i++ ) { - this->createIndex( m_description.index( i ).name(), - m_description.index( i ).columnNames(), - m_description.index( i ).isUnique() ); - } - for( int i = 0; i < m_description.numberOfUniqueConstraints(); i++ ) { - this->setUniqueConstraint( m_description.uniqueConstraint( i ).name(), - m_description.uniqueConstraint( i ).columnNames() ); - } - for( int i = 0; i < m_description.numberOfCollectionFragments(); i++ ) { - this->setForeignKeyConstraint( m_description.collectionFragment( i ).name() ); - } - } - else { - for( int i = 0; i < m_description.numberOfCollectionFragments(); i++ ) { - std::string fragmentName = m_description.collectionFragment( i ).name(); - this->retrieveIndexDescriptions( fragmentName ); - this->retrieveUniqueConstraintDescriptions( fragmentName ); - } - } - - // For UPDATE mode, drop all foreign key constraints on parent collection fragments not defined in collection description. - if( m_mode == pool::ICollection::UPDATE ) { - for( int i = 0; i < m_description.numberOfCollectionFragments(); i++ ) { - dropParentForeignKeyConstraints( m_description.collectionFragment( i ).name(), true ); - } - } - - if( inCreateMode ) { - if( m_session->properties().flavorName() == "Oracle" ) { - const string init_procedure = "POOL_COLLECTION_INIT"; - bool procedureExists( false ); - try { - std::unique_ptr<coral::IQuery> query( m_session->schema("SYS").newQuery() ); - coral::AttributeList output; - output.extend( "count(*)", "int"); - query->addToOutputList("count(*)"); - query->defineOutput( output ); - query->addToTableList("USER_OBJECTS"); - coral::AttributeList variables; - variables.extend( "OBJECT_NAME", "string" ); - variables[0].data<string>() = init_procedure; - variables.extend( "OBJECT_TYPE", "string" ); - variables[1].data<string>() = "PROCEDURE"; - string query_conditions = "OBJECT_NAME = :" + variables[0].specification().name() - + " AND OBJECT_TYPE = :" + variables[1].specification().name(); - query->setCondition( query_conditions, variables ); - - coral::ICursor& result = query->execute(); - if( result.next() ) { - if( result.currentRow()[0].data<int>() > 0 ) { - procedureExists = true; - } - } - if( !procedureExists) { - log << coral::Debug - << "Database procedure " << init_procedure << " not found." << coral::MessageStream::endmsg; - } - } catch( std::exception &e ) { - log << coral::Warning - << "Lookup for database procedure " << init_procedure - << " returned error: " << e.what() << coral::MessageStream::endmsg; - } - if( procedureExists ) { - // commit all schema tables for a new collection before insertion - bool restartTrans( true ); - commit( restartTrans ); - - log << coral::Info - << "Executing database procedure " << init_procedure << "(" << m_name << ") " - << coral::MessageStream::endmsg; - try { - coral::AttributeList params; - params.extend( "CollName", "string" ); - params.begin()->data<string>() = m_name; - nominalSchema.callProcedure( init_procedure, params ); - log << coral::Debug - << "Database procedure " << init_procedure - << "(" << m_name << ") executed." << coral::MessageStream::endmsg; - } - catch( std::exception &e ) { - std::string errorMsg = "Error executing database procedure " + init_procedure + "(" + m_name + ") : " + e.what(); - log << coral::Error << errorMsg << coral::MessageStream::endmsg; - if( getenv("POOL_RCOLL_LOCKONERROR") ) { - dbLock.setAutorelease( false ); // leave the database locked - log << coral::Warning << "LOCKING database - all collection creation tasks will wait!" << coral::MessageStream::endmsg; - } - log << coral::Info << "Removing collection " << m_name << coral::MessageStream::endmsg; - drop( m_name, true, true ); - throw pool::Exception( errorMsg, - "RelationalCollection::initialize", - "RelationalCollection" ); - } - } - } - } - - if( m_mode != pool::ICollection::READ ) { - dbLock.unlock(); - // commit away central locks before insertion - commit(); - } - - // Create new data editor object for collection. - m_dataEditor = new RelationalCollectionDataEditor( - *m_session, - m_description, - m_dataTableNameForCollectionFragmentName, - m_linksTableNameForCollectionFragmentName, - m_fragmentDataMap, - m_tableTokenColumnPrefixForCollectionTokenColumnName, - m_tableAttributeColumnNameForCollectionAttributeColumnName, - *m_tableAttributeList, - m_collectionRowBuffer, - m_dataTableRowBufferForCollectionFragmentName, - *m_linksTableRowBuffer, - m_mapOfLinkIdForTokenKeyMaps, - m_mapOfTokenKeyForLinkIdMaps, - m_mapOfWhereClausesForOID1InDataTable, - m_mapOfWhereDataForOID1InDataTable ); - - m_initialized = true; -} - - - - - -void -pool::RelationalCollection::RelationalCollection::createHeadersTable() -{ - coral::ISchema& nominalSchema = m_session->nominalSchema(); - - coral::TableDescription description( RelationalCollectionNames::collectionTypeName() ); - description.setName( RelationalCollectionNames::nameOfCollectionHeadersTable() ); - - bool fixedSize = true; - int columnSize = 400; - description.insertColumn( - RelationalCollectionNames::collectionNameVariableInCollectionHeadersTable(), - coral::AttributeSpecification::typeNameForType<std::string>(), columnSize, !fixedSize ); - description.insertColumn( - RelationalCollectionNames::dataTableNameVariableInCollectionHeadersTable(), - coral::AttributeSpecification::typeNameForType<std::string>(), columnSize, !fixedSize ); - description.insertColumn( - RelationalCollectionNames::linksTableNameVariableInCollectionHeadersTable(), - coral::AttributeSpecification::typeNameForType<std::string>(), columnSize, !fixedSize ); - description.insertColumn( - RelationalCollectionNames::writtenRecordsVariableInCollectionHeadersTable(), - coral::AttributeSpecification::typeNameForType<int>() ); - description.insertColumn( - RelationalCollectionNames::deletedRecordsVariableInCollectionHeadersTable(), - coral::AttributeSpecification::typeNameForType<int>() ); - description.insertColumn( - RelationalCollectionNames::childCollectionNameVariableInCollectionHeadersTable(), - coral::AttributeSpecification::typeNameForType<std::string>(), columnSize, !fixedSize ); - description.insertColumn( - RelationalCollectionNames::foreignKeyNameVariableInCollectionHeadersTable(), - coral::AttributeSpecification::typeNameForType<std::string>(), columnSize, !fixedSize ); - - description.setPrimaryKey( - RelationalCollectionNames::collectionNameVariableInCollectionHeadersTable() ); - - nominalSchema.createTable( description ); //.privilegeManager().grantToPublic( coral::ITablePrivilegeManager::Select ); -} - - -void -pool::RelationalCollection::RelationalCollection::createDescriptionsTable() -{ - coral::ISchema& nominalSchema = m_session->nominalSchema(); - - coral::TableDescription description( RelationalCollectionNames::collectionTypeName() ); - description.setName( RelationalCollectionNames::nameOfCollectionDescriptionsTable() ); - - bool fixedSize = true; - int columnSize = 400; - description.insertColumn( - RelationalCollectionNames::collectionNameVariableInCollectionDescriptionsTable(), - coral::AttributeSpecification::typeNameForType<std::string>(), columnSize, !fixedSize ); - description.insertColumn( - RelationalCollectionNames::collectionVariableNameVariableInCollectionDescriptionsTable(), - coral::AttributeSpecification::typeNameForType<std::string>(), columnSize, !fixedSize ); - description.insertColumn( - RelationalCollectionNames::collectionVariableTypeVariableInCollectionDescriptionsTable(), - coral::AttributeSpecification::typeNameForType<std::string>(), columnSize, !fixedSize ); - description.insertColumn( - RelationalCollectionNames::collectionVariableMaxSizeVariableInCollectionDescriptionsTable(), - coral::AttributeSpecification::typeNameForType<int>() ); - description.insertColumn( - RelationalCollectionNames::collectionVariableSizeIsFixedVariableInCollectionDescriptionsTable(), - coral::AttributeSpecification::typeNameForType<std::string>(), 5, !fixedSize ); - description.insertColumn( - RelationalCollectionNames::collectionVariablePositionVariableInCollectionDescriptionsTable(), - coral::AttributeSpecification::typeNameForType<int>() ); - description.insertColumn( - RelationalCollectionNames::collectionVariableAnnotationVariableInCollectionDescriptionsTable(), - coral::AttributeSpecification::typeNameForType<std::string>() ); -// description.insertColumn( -// pool::RelationalCollection::RelationalCollectionNames::collectionVariableUniqueConstraintNameVariableInCollectionDescriptionsTable(), -// coral::AttributeSpecification::typeNameForType<std::string>() ); - - nominalSchema.createTable( description ); //.privilegeManager().grantToPublic( coral::ITablePrivilegeManager::Select ); -} - - -void -pool::RelationalCollection::RelationalCollection::createIndexDescriptionsTable() -{ - coral::ISchema& nominalSchema = m_session->nominalSchema(); - - coral::TableDescription description( pool::RelationalCollection::RelationalCollectionNames::collectionTypeName() ); - description.setName( pool::RelationalCollection::RelationalCollectionNames::nameOfCollectionIndexDescriptionsTable() ); - - description.insertColumn( RelationalCollectionNames::indexNameVariableInCollectionIndexDescriptionsTable(), - coral::AttributeSpecification::typeNameForType<std::string>() ); - description.insertColumn( RelationalCollectionNames::uniqueConstraintNameVariableInCollectionIndexDescriptionsTable(), - coral::AttributeSpecification::typeNameForType<std::string>() ); - description.insertColumn( RelationalCollectionNames::collectionVariableNameVariableInCollectionIndexDescriptionsTable(), - coral::AttributeSpecification::typeNameForType<std::string>() ); - description.insertColumn( RelationalCollectionNames::collectionNameVariableInCollectionIndexDescriptionsTable(), - coral::AttributeSpecification::typeNameForType<std::string>() ); - - nominalSchema.createTable( description ); //.privilegeManager().grantToPublic( coral::ITablePrivilegeManager::Select ); -} - - -bool -pool::RelationalCollection::RelationalCollection::newSchemaEqualsExistingSchema( const std::string& fragmentName ) -{ - CollectionDescription existingDesc( fragmentName, m_description.type() ); - retrieveColumnDescriptions( fragmentName, &existingDesc ); - - return existingDesc.equals( m_description ); -} - - -void -pool::RelationalCollection::RelationalCollection:: -createDataAndLinksTables( const std::string& fragmentName ) -{ - coral::ISchema& nominalSchema = m_session->nominalSchema(); - - // Find next available names for data and links tables of new collection fragment and update private maps. - std::string dataTableName, linksTableName; - for( int i = 0; ; ++i ) { - dataTableName = RelationalCollectionNames::nameOfCollectionDataTable( i ); - linksTableName = RelationalCollectionNames::nameOfCollectionLinksTable( i ); - if( ! ( nominalSchema.existsTable( dataTableName ) || - nominalSchema.existsView( dataTableName ) || - nominalSchema.existsTable( linksTableName ) || - nominalSchema.existsView( linksTableName ) ) ) - break; - } - m_dataTableNameForCollectionFragmentName[fragmentName] = dataTableName; - m_linksTableNameForCollectionFragmentName[fragmentName] = linksTableName; - m_fragmentDataMap[fragmentName].setCurrentRowId( 0 ); - - // Create table description for data table of new collection fragment. - coral::TableDescription dataTableDescription( RelationalCollectionNames::collectionTypeName() ); - dataTableDescription.setName( dataTableName ); - - // Add primary key column. - dataTableDescription.insertColumn( - RelationalCollectionNames::recordIdVariableInCollectionDataTable(), - coral::AttributeSpecification::typeNameForType<int>() ); - - // Add columns for event reference if this is the top level collection fragment and an event reference was specified. - int addedEventRefColumn = 0; - if( fragmentName == m_name && m_description.hasEventReferenceColumn() ) { - addedEventRefColumn = 1; - dataTableDescription.insertColumn( - RelationalCollectionNames::oid_1_variableInCollectionDataTable(), - coral::AttributeSpecification::typeNameForType<int>() ); - dataTableDescription.insertColumn( - RelationalCollectionNames::oid_2_variableInCollectionDataTable(), - coral::AttributeSpecification::typeNameForType<int>() ); - } - - // Add Token columns to data table schema. - for( int i = addedEventRefColumn; i < m_description.numberOfTokenColumns( fragmentName ); i++ ) { - std::string tableColumnPrefix = m_tableColumnNameForCollectionColumnName[ m_description.tokenColumn( i, fragmentName ).name() ]; - std::string oid1ColumnName = tableColumnPrefix + RelationalCollectionNames::oid_1_variableInCollectionDataTable(); - std::string oid2ColumnName = tableColumnPrefix + RelationalCollectionNames::oid_2_variableInCollectionDataTable(); - dataTableDescription.insertColumn( oid1ColumnName, coral::AttributeSpecification::typeNameForType<int>() ); - dataTableDescription.insertColumn( oid2ColumnName, coral::AttributeSpecification::typeNameForType<int>() ); - } - - // Add Attribute columns to data table schema. - for( int i = 0; i < m_description.numberOfAttributeColumns( fragmentName ); i++ ) { - const ICollectionColumn &column = m_description.attributeColumn( i, fragmentName ); - std::string tableColumnName = m_tableColumnNameForCollectionColumnName[ column.name() ]; - dataTableDescription.insertColumn( tableColumnName, column.type() ); - } - - // Set primary key for data table. - dataTableDescription.setPrimaryKey( RelationalCollectionNames::recordIdVariableInCollectionDataTable() ); - - // Create data table and define user privileges. - nominalSchema.createTable( dataTableDescription ); //.privilegeManager().grantToPublic( coral::ITablePrivilegeManager::Select ); - - // Create description object for links table of new collection fragment. - coral::TableDescription linksTableDescription( RelationalCollectionNames::collectionTypeName() ); - linksTableDescription.setName( linksTableName ); - - // Add link table ID and Token key information to links table schema: - linksTableDescription.insertColumn( - RelationalCollectionNames::linkIdVariableInCollectionLinksTable(), - coral::AttributeSpecification::typeNameForType<int>() ); - linksTableDescription.insertColumn( - RelationalCollectionNames::databaseIdVariableInCollectionLinksTable(), - coral::AttributeSpecification::typeNameForType<std::string>() ); - linksTableDescription.insertColumn( - RelationalCollectionNames::containerIdVariableInCollectionLinksTable(), - coral::AttributeSpecification::typeNameForType<std::string>() ); - linksTableDescription.insertColumn( - RelationalCollectionNames::classIdVariableInCollectionLinksTable(), - coral::AttributeSpecification::typeNameForType<std::string>() ); - linksTableDescription.insertColumn( - RelationalCollectionNames::technologyIdVariableInCollectionLinksTable(), - coral::AttributeSpecification::typeNameForType<int>() ); - - // Set primary key for links table of new collection fragment. - linksTableDescription.setPrimaryKey( RelationalCollectionNames::linkIdVariableInCollectionLinksTable() ); - - // Create links table for new collection fragment and define user privileges. - nominalSchema.createTable( linksTableDescription ); //.privilegeManager().grantToPublic( coral::ITablePrivilegeManager::Select ); - - // Add rows for new collection fragment to headers table. - initializeHeadersTable( fragmentName, dataTableName, linksTableName ); - - // Add rows for new collection fragment to descriptions table. - initializeDescriptionsTable( fragmentName ); -} - - - -void -pool::RelationalCollection::RelationalCollection:: -initializeHeadersTable( const std::string& fragmentName, - const std::string& dataTableName, - const std::string& linksTableName ) -{ - coral::ISchema& nominalSchema = m_session->nominalSchema(); - - // Add row for new collection fragment into collection headers table. - coral::AttributeList rowBuffer; - rowBuffer.extend<std::string>( - RelationalCollectionNames::collectionNameVariableInCollectionHeadersTable() ); - rowBuffer.extend<std::string>( - RelationalCollectionNames::dataTableNameVariableInCollectionHeadersTable() ); - rowBuffer.extend<std::string>( - RelationalCollectionNames::linksTableNameVariableInCollectionHeadersTable() ); - rowBuffer.extend<unsigned>( - RelationalCollectionNames::writtenRecordsVariableInCollectionHeadersTable() ); - rowBuffer.extend<unsigned>( - RelationalCollectionNames::deletedRecordsVariableInCollectionHeadersTable() ); - rowBuffer.extend<std::string>( - RelationalCollectionNames::childCollectionNameVariableInCollectionHeadersTable() ); - rowBuffer.extend<std::string>( - RelationalCollectionNames::foreignKeyNameVariableInCollectionHeadersTable() ); - const ICollectionFragment& fragment = m_description.collectionFragment( fragmentName ); - coral::AttributeList::iterator iAttribute = rowBuffer.begin(); - iAttribute->data< std::string >() = fragmentName; - ++iAttribute; - iAttribute->data< std::string >() = dataTableName; - ++iAttribute; - iAttribute->data< std::string >() = linksTableName; - ++iAttribute; - iAttribute->data< unsigned >() = 0; - ++iAttribute; - iAttribute->data< unsigned >() = 0; - ++iAttribute; - iAttribute->data< std::string >() = fragment.childCollectionFragmentName(); - ++iAttribute; - iAttribute->data< std::string >() = fragment.foreignKeyName(); - nominalSchema.tableHandle( RelationalCollectionNames::nameOfCollectionHeadersTable() ).dataEditor().insertRow( rowBuffer ); - - // Lock row in collection headers table for this collection fragment for duration of transaction. - exists( fragmentName, true ); -} - - -void -pool::RelationalCollection::RelationalCollection:: -initializeDescriptionsTable( const std::string& fragmentName ) -{ - // Add rows for new collection fragment into collection descriptions table. - coral::AttributeList rowBuffer; - - rowBuffer.extend< std::string >( - RelationalCollectionNames::collectionNameVariableInCollectionDescriptionsTable() ); - rowBuffer.extend< std::string >( - RelationalCollectionNames::collectionVariableNameVariableInCollectionDescriptionsTable() ); - rowBuffer.extend< std::string >( - RelationalCollectionNames::collectionVariableTypeVariableInCollectionDescriptionsTable() ); - rowBuffer.extend< int >( - RelationalCollectionNames::collectionVariableMaxSizeVariableInCollectionDescriptionsTable() ); - rowBuffer.extend< std::string >( - RelationalCollectionNames::collectionVariableSizeIsFixedVariableInCollectionDescriptionsTable() ); - rowBuffer.extend< int >( - RelationalCollectionNames::collectionVariablePositionVariableInCollectionDescriptionsTable() ); - rowBuffer.extend< std::string >( - RelationalCollectionNames::collectionVariableAnnotationVariableInCollectionDescriptionsTable() ); - - // Get handle to collection descriptions table. - coral::ITable& descriptionsTable = - m_session->nominalSchema().tableHandle( RelationalCollectionNames::nameOfCollectionDescriptionsTable() ); - - // Set collection fragment name to be the same for all rows to be added here. - rowBuffer[0].data< std::string >() = fragmentName; - - // Add rows for Token column descriptions. - for( int i = 0; i < m_description.numberOfTokenColumns( fragmentName ); i++ ) { - const pool::ICollectionColumn& column = m_description.tokenColumn( i , fragmentName ); - if( column.name() == CollectionBaseNames::defaultEventReferenceColumnName() - && column.name() == m_description.eventReferenceColumnName() - && column.annotation().empty() ) { - // don't store event reference column if it had default name and no annotation - continue; - } - rowBuffer[1].data< std::string >() = column.name(); - rowBuffer[2].data< std::string >() = CollectionBaseNames::tokenTypeName(); - rowBuffer[3].data< int >() = 0; - rowBuffer[4].data< std::string >() = "true"; - rowBuffer[5].data< int >() = column.id(); - rowBuffer[6].data< std::string >() = column.annotation(); - //cout << " -->>> Adding Token column " << column.name() << ", ID=" << column.id() <<", annotated:" << column.annotation() << endl; - // Insert new row: - descriptionsTable.dataEditor().insertRow( rowBuffer ); - } - - // Add rows for Attribute descriptions. - for( int i = 0; i < m_description.numberOfAttributeColumns( fragmentName ); i++ ) { - const pool::ICollectionColumn& column = m_description.attributeColumn( i , fragmentName ); - - rowBuffer[1].data< std::string >() = column.name(); - rowBuffer[2].data< std::string >() = column.type(); - rowBuffer[3].data< int >() = column.maxSize(); - rowBuffer[4].data< std::string >() = column.sizeIsFixed()? "true" : "false"; - rowBuffer[5].data< int >() = column.id(); - rowBuffer[6].data< std::string >() = column.annotation(); - // Insert new row. - descriptionsTable.dataEditor().insertRow( rowBuffer ); - } -} - - -void -pool::RelationalCollection::RelationalCollection:: -retrieveCollectionFragmentDescriptions() -{ - coral::ISchema& nominalSchema = m_session->nominalSchema(); - - coral::ITable& headersTable = nominalSchema.tableHandle( - RelationalCollectionNames::nameOfCollectionHeadersTable() ); - - // Get all collection fragments and add to fragment list in correct order. (Note: Top level collection fragment already - // added in collection description constructor). - std::string fragmentName = m_name; - while ( fragmentName.size() > 0 ) { - coral::IQuery* query = headersTable.newQuery(); - - query->addToOutputList( - RelationalCollectionNames::childCollectionNameVariableInCollectionHeadersTable() ); - query->addToOutputList( - RelationalCollectionNames::foreignKeyNameVariableInCollectionHeadersTable() ); - m_whereDataForCollectionNameInHeadersTable->begin()->data<std::string>() = fragmentName; - query->setCondition( m_whereClauseForCollectionNameInHeadersTable, *m_whereDataForCollectionNameInHeadersTable ); - query->limitReturnedRows( 1, 0 ); - - coral::ICursor& cursor = query->execute(); - - if( cursor.next() ) { - const coral::AttributeList& row = cursor.currentRow(); - std::string childFragmentName; - if( !row[0].isNull() ) - childFragmentName = row[0].data<std::string>(); - std::string foreignKeyName; - if( !row[1].isNull() ) - foreignKeyName = row[1].data<std::string>(); - - if( childFragmentName.size() > 0 ) { - if (!m_schemaEditor) { - throw pool::Exception( "No schema editor", - "RelationalCollection::retrieveCollectionFragmentDescriptions", - "RelationalCollection" ); - } - if( foreignKeyName.size() > 0 ) { - //m_description.addCollectionFragment( childFragmentName, fragmentName, true ); - // MN: FIX guess - check functionality! - m_schemaEditor->addCollectionFragment( childFragmentName, fragmentName, true ); - } - else { - // m_description.addCollectionFragment( childFragmentName, fragmentName, false ); - // MN: FIX guess - check functionality! - m_schemaEditor->addCollectionFragment( childFragmentName, fragmentName, false ); - } - } - fragmentName = childFragmentName; - } - else { - delete query; - std::string errorMsg = "Collection fragment `" + fragmentName + "' does not exist."; - throw pool::Exception( errorMsg, - "RelationalCollection::retrieveCollectionFragmentDescriptions", - "RelationalCollection" ); - } - delete query; - } -} - - -void -pool::RelationalCollection::RelationalCollection:: -retrieveColumnDescriptions( const std::string& fragmentName, - CollectionDescription *collDesc ) const -{ - coral::ISchema& nominalSchema = m_session->nominalSchema(); - - // Retrieve column names and types for this fragment and insert into collection description object. - coral::ITable& descriptionsTable = nominalSchema.tableHandle( RelationalCollectionNames::nameOfCollectionDescriptionsTable() ); - std::unique_ptr<coral::IQuery> descQuery( descriptionsTable.newQuery() ); - descQuery->addToOutputList( RelationalCollectionNames::collectionVariableNameVariableInCollectionDescriptionsTable() ); - descQuery->addToOutputList( RelationalCollectionNames::collectionVariableTypeVariableInCollectionDescriptionsTable() ); - descQuery->addToOutputList( RelationalCollectionNames::collectionVariableMaxSizeVariableInCollectionDescriptionsTable() ); - descQuery->defineOutputType(RelationalCollectionNames::collectionVariableMaxSizeVariableInCollectionDescriptionsTable(), "int" ); - descQuery->addToOutputList( RelationalCollectionNames::collectionVariableSizeIsFixedVariableInCollectionDescriptionsTable() ); - descQuery->addToOutputList( RelationalCollectionNames::collectionVariablePositionVariableInCollectionDescriptionsTable() ); - descQuery->defineOutputType(RelationalCollectionNames::collectionVariablePositionVariableInCollectionDescriptionsTable(), "int" ); - descQuery->addToOutputList( RelationalCollectionNames::collectionVariableAnnotationVariableInCollectionDescriptionsTable() ); - m_whereDataForCollectionNameInDescriptionsTable->begin()->data<std::string>() = fragmentName; - descQuery->setCondition( m_whereClauseForCollectionNameInDescriptionsTable, - *m_whereDataForCollectionNameInDescriptionsTable ); - descQuery->addToOrderList( RelationalCollectionNames::collectionVariablePositionVariableInCollectionDescriptionsTable() ); - descQuery->setRowCacheSize( 100 ); - coral::ICursor& descCursor = descQuery->execute(); - - while( descCursor.next() ) { - const coral::AttributeList& row = descCursor.currentRow(); - - std::string collectionColumnName = row[0].data<std::string>(); - std::string columnType = row[1].data<std::string>(); - int maxSize = row[2].data<int>(); - bool sizeIsFixed = ( row[3].data<std::string>() == "true" ); - int variablePosition = row[4].data<int>(); - std::string annotation; - if( !row[5].isNull() ) annotation = row[5].data<std::string>(); - //cout << " -->>> Got Description for column " << collectionColumnName << " annotated:" << annotation << ", isFixed='" << row[3].data<std::string>() << "' (" << sizeIsFixed << ")" <<endl; - - if( variablePosition == 0 ) { - // this is the EvRef token column - collDesc->setEventReferenceColumnName( collectionColumnName ); - } - collDesc->insertColumn( collectionColumnName, columnType, annotation, fragmentName, maxSize, sizeIsFixed ); - collDesc->setColumnId( collectionColumnName, variablePosition, "retrieveColumnDescriptions" ); - } -} - - -// Initialize all maps for retrieving table column names -// and all internal row buffers for this collection fragment. -void -pool::RelationalCollection::RelationalCollection:: -initializeMapsAndDataRowBuffers( const std::string& fragmentName ) -{ - coral::AttributeList* dataTableRowBuffer = new coral::AttributeList; - - // Add primary key column - only temporary fix? MN - dataTableRowBuffer->extend( RelationalCollectionNames::recordIdVariableInCollectionDataTable(), typeid( unsigned ) ); - - for( int i = 0; i < m_description.numberOfTokenColumns( fragmentName ); i++ ) { - const pool::ICollectionColumn& column = m_description.tokenColumn( i , fragmentName ); - const std::string& columnName = column.name(); - int variablePosition = column.id(); - std::string variableName; - if( columnName != m_description.eventReferenceColumnName() ) { - variableName = RelationalCollectionNames::variableDataVariableInCollectionDataTable( variablePosition ) + "_"; - } -// m_poolOut << "RelColl - adding token column " << columnName << ", ID=" << variablePosition << ", variable name=" << variableName << coral::MessageStream::endmsg; - m_schemaEditor->addTokenColumnToMaps( variableName, columnName, variablePosition ); - m_schemaEditor->addTokenColumnToRowBuffer( dataTableRowBuffer, variableName ); - } - - for( int i = 0; i < m_description.numberOfAttributeColumns( fragmentName ); i++ ) { - const pool::ICollectionColumn& column = m_description.attributeColumn( i , fragmentName ); - const std::string& columnName = column.name(); - const std::string& columnType = column.type(); - int variablePosition = column.id(); - std::string tableColumnName = RelationalCollectionNames::variableDataVariableInCollectionDataTable( variablePosition ); - -// m_poolOut << "RelColl - adding attrib column " << columnName << ", ID=" << variablePosition << ", table column name=" << tableColumnName << coral::MessageStream::endmsg; - m_schemaEditor->addColumnToMaps( columnName, tableColumnName, columnType, variablePosition ); - dataTableRowBuffer->extend( tableColumnName, columnType ); - } - - // Add data table row buffer object for this collection fragment to private map. - m_dataTableRowBufferForCollectionFragmentName[fragmentName] = dataTableRowBuffer; -} - - -void -pool::RelationalCollection::RelationalCollection::createLinksTableRowBuffer() -{ - m_linksTableRowBuffer->extend( - RelationalCollectionNames::linkIdVariableInCollectionLinksTable(), typeid(unsigned) ); - - m_linksTableRowBuffer->extend( - RelationalCollectionNames::databaseIdVariableInCollectionLinksTable(), typeid(std::string) ); - - m_linksTableRowBuffer->extend( - RelationalCollectionNames::containerIdVariableInCollectionLinksTable(), typeid(std::string) ); - - m_linksTableRowBuffer->extend( - RelationalCollectionNames::classIdVariableInCollectionLinksTable(), typeid(std::string) ); - - m_linksTableRowBuffer->extend( - RelationalCollectionNames::technologyIdVariableInCollectionLinksTable(), typeid(unsigned) ); -} - - -void -pool::RelationalCollection::RelationalCollection:: -createLinkIdToTokenKeyMaps( const std::string& fragmentName ) -{ - // Query the links table. - unique_ptr<coral::IQuery> query( m_session->nominalSchema().newQuery() ); - query->addToTableList( m_linksTableNameForCollectionFragmentName[fragmentName] ); - - // Select all columns from links table and order by link ID. - coral::AttributeList outputDataBuffer; - std::string linkIdColumnName = RelationalCollectionNames::linkIdVariableInCollectionLinksTable(); - query->addToOutputList( linkIdColumnName ); - query->addToOrderList( linkIdColumnName ); - outputDataBuffer.extend< unsigned >( linkIdColumnName ); - std::string databaseIdColumnName = RelationalCollectionNames::databaseIdVariableInCollectionLinksTable(); - query->addToOutputList( databaseIdColumnName ); - outputDataBuffer.extend< std::string >( databaseIdColumnName ); - std::string containerIdColumnName = RelationalCollectionNames::containerIdVariableInCollectionLinksTable(); - query->addToOutputList( containerIdColumnName ); - outputDataBuffer.extend< std::string >( containerIdColumnName ); - std::string classIdColumnName = RelationalCollectionNames::classIdVariableInCollectionLinksTable(); - query->addToOutputList( classIdColumnName ); - outputDataBuffer.extend< std::string >( classIdColumnName ); - std::string technologyIdColumnName = RelationalCollectionNames::technologyIdVariableInCollectionLinksTable(); - query->addToOutputList( technologyIdColumnName ); - outputDataBuffer.extend< unsigned >( technologyIdColumnName ); - - // Execute query. - query->defineOutput( outputDataBuffer ); - query->setRowCacheSize( 5000 ); - coral::ICursor& cursor = query->execute(); - - // Create map for retrieving Token key (link ID) using link ID (Token key) as key. - std::map< unsigned, std::string > *tokenKeyForLinkId = new std::map< unsigned, std::string >(); - std::map< std::string, unsigned > *linkIdForTokenKey = new std::map< std::string, unsigned >(); - - // Get all link ID's and Token keys for collection fragment and add to maps. - while( cursor.next() ) { - unsigned linkId = outputDataBuffer[0].data< unsigned >(); - std::string databaseId = outputDataBuffer[1].data< std::string >(); - std::string containerId = outputDataBuffer[2].data< std::string >(); - std::string classId = outputDataBuffer[3].data< std::string >(); - unsigned technologyId = outputDataBuffer[4].data< unsigned >(); - /* - Token token; - token.setDb( databaseId ); - token.setCont( containerId ); - pool::Guid guid; - token.setClassID( guid.fromString( classId ) ); - token.setTechnology( technologyId ); - const std::string tokenKey = token.key(); - */ - // MN:this is a hack to build the string representation by hand, - // but it preserves the technology ID unlike the Token::key() method - char text[128]; - ::sprintf(text, "][TECH=%08X]", technologyId); - std::string tokenKey = "[DB="+databaseId+"][CNT="+containerId+"][CLID="+classId+text; - - tokenKeyForLinkId->insert( std::make_pair( linkId, tokenKey ) ); - linkIdForTokenKey->insert( std::make_pair( tokenKey, linkId ) ); - } - - m_mapOfTokenKeyForLinkIdMaps[ fragmentName ] = tokenKeyForLinkId; - m_mapOfLinkIdForTokenKeyMaps[ fragmentName ] = linkIdForTokenKey; -} - - -void -pool::RelationalCollection::RelationalCollection::createIndex( const std::string& indexName, - const std::vector< std::string >& columnNames, - bool isUnique ) -{ - coral::ISchema& nominalSchema = m_session->nominalSchema(); - - // Get name of collection fragment to contain index. - std::string fragmentName = m_description.collectionFragmentName( *( columnNames.begin() ) ); - - // Get data table name to contain index. - std::string dataTableName = m_dataTableNameForCollectionFragmentName[ fragmentName ]; - - // Check if an index already exists for these columns. - std::map< std::string, std::vector< std::string >* > collectionColumnNamesForIndexName; - std::map< std::string, bool > isUniqueFlagForIndexName; - coral::IQuery* query = nominalSchema.tableHandle( RelationalCollectionNames::nameOfCollectionIndexDescriptionsTable() ).newQuery(); - query->addToOutputList( - RelationalCollectionNames::indexNameVariableInCollectionIndexDescriptionsTable() ); - query->addToOutputList( - RelationalCollectionNames::uniqueConstraintNameVariableInCollectionIndexDescriptionsTable() ); - query->addToOutputList( - RelationalCollectionNames::collectionVariableNameVariableInCollectionIndexDescriptionsTable() ); - m_whereDataForCollectionNameInIndexDescriptionsTable->begin()->data<std::string>() = fragmentName; - query->setCondition( m_whereClauseForCollectionNameInIndexDescriptionsTable, - *m_whereDataForCollectionNameInIndexDescriptionsTable ); - query->setRowCacheSize( 100 ); - coral::ICursor& cursor = query->execute(); - while ( cursor.next() ) - { - const coral::AttributeList& row = cursor.currentRow(); - - std::string existingIndexName = row[0].data<std::string>(); - std::string existingUniqueConstraintName = row[1].data<std::string>(); - std::string collectionColumnName = row[2].data<std::string>(); - - if( existingIndexName.size() > 0 ) { - if( existingUniqueConstraintName == existingIndexName ) { - isUniqueFlagForIndexName.insert( std::make_pair( existingIndexName, true ) ); - } - else { - isUniqueFlagForIndexName.insert( std::make_pair( existingIndexName, false ) ); - } - - std::map< std::string, std::vector< std::string >* >::iterator iNames = - collectionColumnNamesForIndexName.find( existingIndexName ); - if ( iNames != collectionColumnNamesForIndexName.end() ) { - iNames->second->push_back( collectionColumnName ); - } - else { - std::vector< std::string >* existingColumnNames = new std::vector< std::string >(); - existingColumnNames->push_back( collectionColumnName ); - collectionColumnNamesForIndexName.insert( std::make_pair( existingIndexName, existingColumnNames ) ); - } - } - } - delete query; - bool indexFound = false; - for( std::map< std::string, std::vector< std::string >* >::const_iterator iData = - collectionColumnNamesForIndexName.begin(); iData != collectionColumnNamesForIndexName.end(); ++iData ) - { - std::string existingIndexName = iData->first; - std::vector< std::string >* existingColumnNames = iData->second; - - if ( existingColumnNames->size() == columnNames.size() && - std::equal( existingColumnNames->begin(), - existingColumnNames->end(), - columnNames.begin() ) ) - { - bool existingIsUnique = ( isUniqueFlagForIndexName.find( existingIndexName ) )->second; - if ( existingIsUnique == isUnique ) - { - indexFound = true; - } - else - { - nominalSchema.tableHandle( dataTableName ).schemaEditor().dropIndex( existingIndexName ); - - (*m_whereDataForIndexNameInIndexDescriptionsTable)[0].data<std::string>() = existingIndexName; - (*m_whereDataForIndexNameInIndexDescriptionsTable)[1].data<std::string>() = fragmentName; - nominalSchema.tableHandle( RelationalCollectionNames::nameOfCollectionIndexDescriptionsTable() ) - .dataEditor().deleteRows( m_whereClauseForIndexNameInIndexDescriptionsTable, - *m_whereDataForIndexNameInIndexDescriptionsTable ); - } - break; - } - } - for ( std::map< std::string, std::vector< std::string >* >::iterator iNames = collectionColumnNamesForIndexName.begin(); - iNames != collectionColumnNamesForIndexName.end(); ++iNames ) - { - delete iNames->second; - } - - if ( ! indexFound ) - { - // Get table column names for columns used by this index. - std::vector< std::string > tableColumnNames; - for ( std::vector< std::string >::const_iterator iName = columnNames.begin(); iName != columnNames.end(); ++iName ) - { - std::string collectionColumnName = *iName; - std::string tableColumnName = ( m_tableColumnNameForCollectionColumnName.find( collectionColumnName ) )->second; - - if ( m_description.column( collectionColumnName ).type() == pool::CollectionBaseNames::tokenTypeName() ) - { - std::string oid1ColumnName = tableColumnName + - RelationalCollectionNames::oid_1_variableInCollectionDataTable(); - tableColumnNames.push_back( oid1ColumnName ); - std::string oid2ColumnName = tableColumnName + - RelationalCollectionNames::oid_2_variableInCollectionDataTable(); - tableColumnNames.push_back( oid2ColumnName ); - } - else - { - tableColumnNames.push_back( tableColumnName ); - } - } - - // Create index in database. - nominalSchema.tableHandle( dataTableName ).schemaEditor().createIndex( indexName, - tableColumnNames, - isUnique ); - - // Insert rows for new index into collection index descriptions table. - for ( std::vector< std::string >::const_iterator iName = columnNames.begin(); iName != columnNames.end(); ++iName ) - { - coral::AttributeList rowBuffer; - rowBuffer.extend<std::string>( RelationalCollectionNames::indexNameVariableInCollectionIndexDescriptionsTable() ); - rowBuffer.extend<std::string>( RelationalCollectionNames::uniqueConstraintNameVariableInCollectionIndexDescriptionsTable() ); - rowBuffer.extend<std::string>( RelationalCollectionNames::collectionVariableNameVariableInCollectionIndexDescriptionsTable() ); - rowBuffer.extend<std::string>( - RelationalCollectionNames::collectionNameVariableInCollectionIndexDescriptionsTable() ); - coral::AttributeList::iterator iAttribute = rowBuffer.begin(); - iAttribute->data< std::string >() = indexName; - ++iAttribute; - iAttribute->data< std::string >() = (isUnique? indexName : ""); - ++iAttribute; - iAttribute->data< std::string >() = *iName; - ++iAttribute; - iAttribute->data< std::string >() = fragmentName; - nominalSchema.tableHandle( RelationalCollectionNames::nameOfCollectionIndexDescriptionsTable() ).dataEditor().insertRow( rowBuffer ); - } - } -} - - -void -pool::RelationalCollection::RelationalCollection:: -setUniqueConstraint( const std::string& constraintName, const std::vector< std::string >& columnNames ) -{ - coral::ISchema& nominalSchema = m_session->nominalSchema(); - - // Get name of collection fragment to contain unique constraint. - std::string fragmentName = m_description.collectionFragmentName( *( columnNames.begin() ) ); - - // Get data table name to contain unique constraint. - std::string dataTableName = m_dataTableNameForCollectionFragmentName[fragmentName]; - - // Check if a unique constraint already exists for these columns. - std::map< std::string, std::vector< std::string >* > collectionColumnNamesForUniqueConstraintName; - std::map< std::string, bool > isUniqueFlagForUniqueConstraintName; - coral::IQuery* query = nominalSchema.tableHandle( pool::RelationalCollection::RelationalCollectionNames::nameOfCollectionIndexDescriptionsTable() ).newQuery(); - query->addToOutputList( - pool::RelationalCollection::RelationalCollectionNames::indexNameVariableInCollectionIndexDescriptionsTable() ); - query->addToOutputList( - pool::RelationalCollection::RelationalCollectionNames::uniqueConstraintNameVariableInCollectionIndexDescriptionsTable() ); - query->addToOutputList( - pool::RelationalCollection::RelationalCollectionNames::collectionVariableNameVariableInCollectionIndexDescriptionsTable() ); - m_whereDataForCollectionNameInIndexDescriptionsTable->begin()->data<std::string>() = fragmentName; - query->setCondition( m_whereClauseForCollectionNameInIndexDescriptionsTable, - *m_whereDataForCollectionNameInIndexDescriptionsTable ); - query->setRowCacheSize( 100 ); - coral::ICursor& cursor = query->execute(); - while ( cursor.next() ) - { - const coral::AttributeList& row = cursor.currentRow(); - - std::string existingIndexName = row[0].data<std::string>(); - std::string existingUniqueConstraintName = row[1].data<std::string>(); - std::string collectionColumnName = row[2].data<std::string>(); - - if( existingUniqueConstraintName.size() > 0 && existingUniqueConstraintName != existingIndexName ) - { - std::map< std::string, std::vector< std::string >* >::iterator iNames = - collectionColumnNamesForUniqueConstraintName.find( existingUniqueConstraintName ); - if ( iNames != collectionColumnNamesForUniqueConstraintName.end() ) - { - iNames->second->push_back( collectionColumnName ); - } - else - { - std::vector< std::string >* existingColumnNames = new std::vector< std::string >(); - existingColumnNames->push_back( collectionColumnName ); - collectionColumnNamesForUniqueConstraintName.insert( std::make_pair( existingUniqueConstraintName, - existingColumnNames ) ); - } - } - } - delete query; - bool uniqueConstraintFound = false; - for( std::map< std::string, std::vector< std::string >* >::const_iterator iData = - collectionColumnNamesForUniqueConstraintName.begin(); - iData != collectionColumnNamesForUniqueConstraintName.end(); - ++iData ) - { - std::string existingUniqueConstraintName = iData->first; - std::vector< std::string >* existingColumnNames = iData->second; - - if ( existingColumnNames->size() == columnNames.size() && - std::equal( existingColumnNames->begin(), - existingColumnNames->end(), - columnNames.begin() ) ) - { - uniqueConstraintFound = true; - break; - } - } - for ( std::map< std::string, std::vector< std::string >* >::iterator iNames = - collectionColumnNamesForUniqueConstraintName.begin(); - iNames != collectionColumnNamesForUniqueConstraintName.end(); - ++iNames ) - { - delete iNames->second; - } - - if ( ! uniqueConstraintFound ) - { - // Get table column names for columns used by this unique constraint. - std::vector< std::string > tableColumnNames; - for ( std::vector< std::string >::const_iterator iName = columnNames.begin(); iName != columnNames.end(); ++iName ) - { - std::string collectionColumnName = *iName; - std::string tableColumnName = ( m_tableColumnNameForCollectionColumnName.find( collectionColumnName ) )->second; - - if ( m_description.column( collectionColumnName ).type() == pool::CollectionBaseNames::tokenTypeName() ) - { - std::string oid1ColumnName = tableColumnName + - pool::RelationalCollection::RelationalCollectionNames::oid_1_variableInCollectionDataTable(); - tableColumnNames.push_back( oid1ColumnName ); - std::string oid2ColumnName = tableColumnName + - pool::RelationalCollection::RelationalCollectionNames::oid_2_variableInCollectionDataTable(); - tableColumnNames.push_back( oid2ColumnName ); - } - else - { - tableColumnNames.push_back( tableColumnName ); - } - } - - // set unique constraint in database. - nominalSchema.tableHandle( dataTableName ).schemaEditor().createIndex( constraintName, - tableColumnNames, - true ); - - // Insert rows for new unique constraint into collection index descriptions table. - for ( std::vector< std::string >::const_iterator iName = columnNames.begin(); iName != columnNames.end(); ++iName ) - { - coral::AttributeList rowBuffer; - rowBuffer.extend<std::string>( - pool::RelationalCollection::RelationalCollectionNames::indexNameVariableInCollectionIndexDescriptionsTable() ); - rowBuffer.extend<std::string>( - pool::RelationalCollection::RelationalCollectionNames::uniqueConstraintNameVariableInCollectionIndexDescriptionsTable() ); - rowBuffer.extend<std::string>( - pool::RelationalCollection::RelationalCollectionNames::collectionVariableNameVariableInCollectionIndexDescriptionsTable() ); - rowBuffer.extend<std::string>( - pool::RelationalCollection::RelationalCollectionNames::collectionNameVariableInCollectionIndexDescriptionsTable() ); - coral::AttributeList::iterator iAttribute = rowBuffer.begin(); - iAttribute->data< std::string >() = ""; - ++iAttribute; - iAttribute->data< std::string >() = constraintName; - ++iAttribute; - iAttribute->data< std::string >() = *iName; - ++iAttribute; - iAttribute->data< std::string >() = fragmentName; - nominalSchema.tableHandle( pool::RelationalCollection::RelationalCollectionNames::nameOfCollectionIndexDescriptionsTable() ).dataEditor().insertRow( rowBuffer ); - } - } -} - - -void -pool::RelationalCollection::RelationalCollection::retrieveIndexDescriptions( const std::string& fragmentName ) -{ - coral::ISchema& nominalSchema = m_session->nominalSchema(); - - std::map< std::string, std::vector< std::string >* > collectionColumnNamesForIndexName; - std::map< std::string, bool > isUniqueFlagForIndexName; - - // Find indices for this collection fragment. - coral::IQuery* query = nominalSchema.tableHandle( pool::RelationalCollection::RelationalCollectionNames::nameOfCollectionIndexDescriptionsTable() ).newQuery(); - query->addToOutputList( - pool::RelationalCollection::RelationalCollectionNames::indexNameVariableInCollectionIndexDescriptionsTable() ); - query->addToOutputList( - pool::RelationalCollection::RelationalCollectionNames::uniqueConstraintNameVariableInCollectionIndexDescriptionsTable() ); - query->addToOutputList( - pool::RelationalCollection::RelationalCollectionNames::collectionVariableNameVariableInCollectionIndexDescriptionsTable() ); - m_whereDataForCollectionNameInIndexDescriptionsTable->begin()->data<std::string>() = fragmentName; - query->setCondition( m_whereClauseForCollectionNameInIndexDescriptionsTable, - *m_whereDataForCollectionNameInIndexDescriptionsTable ); - query->setRowCacheSize( 100 ); - coral::ICursor& cursor = query->execute(); - while ( cursor.next() ) - { - const coral::AttributeList& row = cursor.currentRow(); - - std::string indexName = row[0].data<std::string>(); - std::string uniqueConstraintName = row[1].data<std::string>(); - std::string collectionColumnName = row[2].data<std::string>(); - - if( indexName.size() > 0 ) - { - if ( uniqueConstraintName == indexName ) - { - isUniqueFlagForIndexName.insert( std::make_pair( indexName, true ) ); - } - else - { - isUniqueFlagForIndexName.insert( std::make_pair( indexName, false ) ); - } - - std::map< std::string, std::vector< std::string >* >::iterator iNames = - collectionColumnNamesForIndexName.find( indexName ); - if ( iNames != collectionColumnNamesForIndexName.end() ) - { - iNames->second->push_back( collectionColumnName ); - } - else - { - std::vector< std::string >* columnNames = new std::vector< std::string >(); - columnNames->push_back( collectionColumnName ); - collectionColumnNamesForIndexName.insert( std::make_pair( indexName, columnNames ) ); - } - } - } - delete query; - - // Add indices to collection description. - for( std::map< std::string, std::vector< std::string >* >::const_iterator iIndex = - collectionColumnNamesForIndexName.begin(); - iIndex != collectionColumnNamesForIndexName.end(); - ++iIndex ) - { - std::string indexName = iIndex->first; - - std::map< std::string, bool >::const_iterator isUnique = isUniqueFlagForIndexName.find( indexName ); - if ( isUnique != isUniqueFlagForIndexName.end() ) - { - // MN: FIX guess - check functionality! - //m_description.createIndex( indexName, *iIndex->second, isUnique->second ); - m_schemaEditor->createIndex( indexName, *iIndex->second, isUnique->second ); - } - else - { - std::string errorMsg = "Uniqueness flag cannot be found for index with name `" - + indexName + "'."; - throw pool::Exception( errorMsg, - "RelationalCollection::retrieveIndexDescriptions", - "RelationalCollection" ); - } - } - - // Delete column names from private map. - for ( std::map< std::string, std::vector< std::string >* >::iterator iNames = - collectionColumnNamesForIndexName.begin(); iNames != - collectionColumnNamesForIndexName.end(); ++iNames ) - { - delete iNames->second; - } -} - - -void -pool::RelationalCollection::RelationalCollection::retrieveUniqueConstraintDescriptions( const std::string& fragmentName ) -{ - coral::ISchema& nominalSchema = m_session->nominalSchema(); - - std::map< std::string, std::vector< std::string >* > collectionColumnNamesForUniqueConstraintName; - - // Find unique constraints for this collection fragment. - coral::IQuery* query = nominalSchema.tableHandle( pool::RelationalCollection::RelationalCollectionNames::nameOfCollectionIndexDescriptionsTable() ).newQuery(); - query->addToOutputList( - pool::RelationalCollection::RelationalCollectionNames::indexNameVariableInCollectionIndexDescriptionsTable() ); - query->addToOutputList( - pool::RelationalCollection::RelationalCollectionNames::uniqueConstraintNameVariableInCollectionIndexDescriptionsTable() ); - query->addToOutputList( - pool::RelationalCollection::RelationalCollectionNames::collectionVariableNameVariableInCollectionIndexDescriptionsTable() ); - m_whereDataForCollectionNameInIndexDescriptionsTable->begin()->data<std::string>() = fragmentName; - query->setCondition( m_whereClauseForCollectionNameInIndexDescriptionsTable, - *m_whereDataForCollectionNameInIndexDescriptionsTable ); - query->setRowCacheSize( 100 ); - coral::ICursor& cursor = query->execute(); - while ( cursor.next() ) - { - const coral::AttributeList& row = cursor.currentRow(); - - std::string indexName = row[0].data<std::string>(); - std::string uniqueConstraintName = row[1].data<std::string>(); - std::string collectionColumnName = row[2].data<std::string>(); - - if( uniqueConstraintName.size() > 0 && uniqueConstraintName != indexName ) - { - std::map< std::string, std::vector< std::string >* >::iterator iNames = - collectionColumnNamesForUniqueConstraintName.find( uniqueConstraintName ); - if ( iNames != collectionColumnNamesForUniqueConstraintName.end() ) - { - iNames->second->push_back( collectionColumnName ); - } - else - { - std::vector< std::string >* columnNames = new std::vector< std::string >(); - columnNames->push_back( collectionColumnName ); - collectionColumnNamesForUniqueConstraintName.insert( std::make_pair( uniqueConstraintName, columnNames ) ); - } - } - } - delete query; - - // Add unique constraints to collection description. - for( std::map< std::string, std::vector< std::string >* >::const_iterator iConstraint = - collectionColumnNamesForUniqueConstraintName.begin(); iConstraint != - collectionColumnNamesForUniqueConstraintName.end(); ++iConstraint ) - { - // MN: FIX guess - check functionality! - // m_description.setUniqueConstraint( iConstraint->first, *iConstraint->second ); - m_schemaEditor->setUniqueConstraint( iConstraint->first, *iConstraint->second ); - } - - // Delete column names from private map. - for ( std::map< std::string, std::vector< std::string >* >::iterator iNames = - collectionColumnNamesForUniqueConstraintName.begin(); iNames != - collectionColumnNamesForUniqueConstraintName.end(); ++iNames ) - { - delete iNames->second; - } -} - - -void -pool::RelationalCollection::RelationalCollection:: -dropParentForeignKeyConstraints( const std::string& fragmentName, bool keepDefinedConstraint ) -{ - coral::ISchema& nominalSchema = m_session->nominalSchema(); - - // Get collection fragment description object. - const pool::ICollectionFragment& fragment = m_description.collectionFragment( fragmentName ); - - // Get name of parent collection fragment in collection description. - std::string parentFragmentName = fragment.parentCollectionFragmentName(); - - // Get data table name of collection fragment. - std::string dataTableName = m_dataTableNameForCollectionFragmentName[ fragmentName ]; - - // Drop foreign key constraints used to reference parent collection fragments of this collection fragment. - coral::IQuery* query = nominalSchema.tableHandle( pool::RelationalCollection::RelationalCollectionNames::nameOfCollectionHeadersTable() ).newQuery(); - query->addToOutputList( - pool::RelationalCollection::RelationalCollectionNames::collectionNameVariableInCollectionHeadersTable() ); - query->addToOutputList( - pool::RelationalCollection::RelationalCollectionNames::foreignKeyNameVariableInCollectionHeadersTable() ); - m_whereDataForChildCollectionNameInHeadersTable->begin()->data<std::string>() = fragmentName; - query->setCondition( m_whereClauseForChildCollectionNameInHeadersTable, *m_whereDataForChildCollectionNameInHeadersTable ); - query->limitReturnedRows( 1, 0 ); - coral::ICursor& cursor = query->execute(); - while ( cursor.next() ) - { - const coral::AttributeList& row = cursor.currentRow(); - - std::string externalParentFragmentName = row[0].data<std::string>(); - std::string externalForeignKeyName = row[1].data<std::string>(); - - if ( keepDefinedConstraint && ( externalParentFragmentName == parentFragmentName ) ) - { - continue; - } - else - { - if( externalForeignKeyName.size() ) { - // Drop the foreign key - nominalSchema.tableHandle( dataTableName ).schemaEditor().dropForeignKey( externalForeignKeyName ); - - // Update the collection descriptions table. - m_whereDataForCollectionNameInHeadersTable->begin()->data<std::string>() = externalParentFragmentName; - std::string setClause = pool::RelationalCollection::RelationalCollectionNames::foreignKeyNameVariableInCollectionHeadersTable() + " = " + "\'\'"; - nominalSchema.tableHandle( pool::RelationalCollection::RelationalCollectionNames::nameOfCollectionHeadersTable() ).dataEditor().updateRows( - setClause, - m_whereClauseForCollectionNameInHeadersTable, - *m_whereDataForCollectionNameInHeadersTable ); - } - } - } - delete query; -} - - -void -pool::RelationalCollection::RelationalCollection:: -dropChildForeignKeyConstraint( const std::string& fragmentName ) -{ - coral::ISchema& nominalSchema = m_session->nominalSchema(); - - // Get collection fragment description object. - const pool::ICollectionFragment& fragment = m_description.collectionFragment( fragmentName ); - - // Get name of child collection fragment in collection description. - std::string childFragmentName = fragment.childCollectionFragmentName(); - - // Get data table name of collection fragment. - std::string dataTableName = m_dataTableNameForCollectionFragmentName.find( fragmentName )->second; - - // Drop foreign key constraint on this collection fragment if such a constrait exists. - coral::IQuery* query = nominalSchema.tableHandle( pool::RelationalCollection::RelationalCollectionNames::nameOfCollectionHeadersTable() ).newQuery(); - query->addToOutputList( - RelationalCollectionNames::childCollectionNameVariableInCollectionHeadersTable() ); - query->addToOutputList( - RelationalCollectionNames::foreignKeyNameVariableInCollectionHeadersTable() ); - m_whereDataForCollectionNameInHeadersTable->begin()->data<std::string>() = fragmentName; - query->setCondition( m_whereClauseForCollectionNameInHeadersTable, - *m_whereDataForCollectionNameInHeadersTable ); - query->limitReturnedRows( 1, 0 ); - coral::ICursor& cursor = query->execute(); - while( cursor.next() ) { - const coral::AttributeList& row = cursor.currentRow(); - - std::string externalChildFragmentName; - if( !row[0].isNull() ) - externalChildFragmentName = row[0].data<std::string>(); - std::string externalForeignKeyName; - if( !row[1].isNull() ) - externalForeignKeyName = row[1].data<std::string>(); - - if( externalChildFragmentName == childFragmentName ) { - if( externalForeignKeyName.size() > 0 ) { - coral::IQuery* childQuery = nominalSchema.tableHandle( pool::RelationalCollection::RelationalCollectionNames::nameOfCollectionHeadersTable() ).newQuery(); - childQuery->addToOutputList( pool::RelationalCollection::RelationalCollectionNames::dataTableNameVariableInCollectionHeadersTable() ); - m_whereDataForCollectionNameInHeadersTable->begin()->data<std::string>() = externalChildFragmentName; - childQuery->setCondition( m_whereClauseForCollectionNameInHeadersTable, - *m_whereDataForCollectionNameInHeadersTable ); - childQuery->limitReturnedRows( 1, 0 ); - coral::ICursor& childCursor = childQuery->execute(); - while ( childCursor.next() ) { - // Drop the foreign key - const coral::AttributeList& childRow = childCursor.currentRow(); - nominalSchema.tableHandle( childRow[0].data<std::string>() ).schemaEditor().dropForeignKey( externalForeignKeyName ); - - // Update the collection headers table. - m_whereDataForCollectionNameInHeadersTable->begin()->data<std::string>() = fragmentName; - std::string setClause = RelationalCollectionNames::foreignKeyNameVariableInCollectionHeadersTable() + " = " + "\'\'"; - nominalSchema.tableHandle( - RelationalCollectionNames::nameOfCollectionHeadersTable() ).dataEditor().updateRows( - setClause, - m_whereClauseForCollectionNameInHeadersTable, - *m_whereDataForCollectionNameInHeadersTable ); - } - } - } - else - { - delete query; - - std::string errorMsg = "Found more than one entry for collection fragment `" + fragmentName + - "' in collection headers table."; - throw pool::Exception( errorMsg, - "RelationalCollection::dropChildForeignKeyConstraint", - "RelationalCollection" ); - } - } - delete query; -} - - -void -pool::RelationalCollection::RelationalCollection::setForeignKeyConstraint( const std::string& fragmentName ) -{ - coral::ISchema& nominalSchema = m_session->nominalSchema(); - - // Get names of child collection fragment and foreign key constraints. - const pool::ICollectionFragment& fragment = m_description.collectionFragment( fragmentName ); - std::string childFragmentName = fragment.childCollectionFragmentName(); - bool usesForeignKey = fragment.usesForeignKey(); - std::string foreignKeyName = fragment.foreignKeyName(); - - // Check if foreign key constraints already exist for this collection fragment and drop those for collection - // fragments not defined in the collection description. - bool foreignKeyFound = false; - coral::IQuery* query = nominalSchema.tableHandle( RelationalCollectionNames::nameOfCollectionHeadersTable() ).newQuery(); - query->addToOutputList( - RelationalCollectionNames::childCollectionNameVariableInCollectionHeadersTable() ); - query->addToOutputList( - RelationalCollectionNames::foreignKeyNameVariableInCollectionHeadersTable() ); - m_whereDataForCollectionNameInHeadersTable->begin()->data<std::string>() = fragmentName; - query->setCondition( m_whereClauseForCollectionNameInHeadersTable, - *m_whereDataForCollectionNameInHeadersTable ); - query->limitReturnedRows( 1, 0 ); - coral::ICursor& cursor = query->execute(); - if ( cursor.next() ) - { - const coral::AttributeList& row = cursor.currentRow(); - - std::string existingChildFragmentName; - if( !row[0].isNull() ) - existingChildFragmentName = row[0].data<std::string>(); - std::string existingForeignKeyName; - if( !row[1].isNull() ) - existingForeignKeyName = row[1].data<std::string>(); - - if( existingForeignKeyName.size() > 0 ) { - if( existingChildFragmentName == childFragmentName ) { - foreignKeyFound = true; - if( ! usesForeignKey ) { - std::string childDataTableName = ( m_dataTableNameForCollectionFragmentName.find( childFragmentName ) )->second; - nominalSchema.tableHandle( childDataTableName ).schemaEditor().dropForeignKey( foreignKeyName ); - } - } - else { - coral::IQuery* childQuery = nominalSchema.tableHandle( pool::RelationalCollection::RelationalCollectionNames::nameOfCollectionHeadersTable() ).newQuery(); - childQuery->addToOutputList( RelationalCollectionNames::dataTableNameVariableInCollectionHeadersTable() ); - m_whereDataForCollectionNameInHeadersTable->begin()->data<std::string>() = existingChildFragmentName; - childQuery->setCondition( m_whereClauseForCollectionNameInHeadersTable, - *m_whereDataForCollectionNameInHeadersTable ); - childQuery->limitReturnedRows( 1, 0 ); - coral::ICursor& childCursor = childQuery->execute(); - if( childCursor.next() ) { - // Drop foreign keys not defined by collection description. - std::string existingChildDataTableName = ( childCursor.currentRow() )[0].data<std::string>(); - nominalSchema.tableHandle( existingChildDataTableName ).schemaEditor().dropForeignKey( existingForeignKeyName ); - } - else { - delete childQuery; - - std::string errorMsg = "Cannot find child collection fragment of fragment `" + fragmentName + - "' with name `" + childFragmentName + "'."; - throw pool::Exception( errorMsg, - "RelationalCollection::setForeignKeyConstraint", - "RelationalCollection" ); - } - delete childQuery; - } - } - } - else { - std::string errorMsg = "Collection headers table row for collection fragment `" + fragmentName + "' does not exist."; - delete query; - throw pool::Exception( errorMsg, - "RelationalCollection::setForeignKeyConstraint", - "RelationalCollection" ); - } - delete query; - - // Create foreign key constraint if specified in collection fragment description object and it does not exist yet. - if ( fragment.usesForeignKey() && ( ! foreignKeyFound ) ) - { - std::string childDataTableName = ( m_dataTableNameForCollectionFragmentName.find( childFragmentName ) )->second; - nominalSchema.tableHandle( childDataTableName ).schemaEditor().createForeignKey( - foreignKeyName, - RelationalCollectionNames::recordIdVariableInCollectionDataTable(), - ( m_dataTableNameForCollectionFragmentName.find( fragmentName ) )->second, - RelationalCollectionNames::recordIdVariableInCollectionDataTable() ); - - // Update collection headers table. - m_whereDataForCollectionNameInHeadersTable->begin()->data<std::string>() = fragmentName; - std::string setClause = RelationalCollectionNames::childCollectionNameVariableInCollectionHeadersTable() + " = " + childFragmentName + " , " + RelationalCollectionNames::foreignKeyNameVariableInCollectionHeadersTable() + " = " + foreignKeyName; - nominalSchema.tableHandle( RelationalCollectionNames::nameOfCollectionHeadersTable() ).dataEditor().updateRows( - setClause, - m_whereClauseForCollectionNameInHeadersTable, - *m_whereDataForCollectionNameInHeadersTable ); - } -} - - - - - -void -pool::RelationalCollection::RelationalCollection:: -retrieveFragmentTableNames( const std::string& fragmentName ) -{ - // Retrieve data and links table names for this collection fragment and insert in private maps. - std::unique_ptr<coral::IQuery> query( - m_session->nominalSchema().tableHandle( RelationalCollectionNames::nameOfCollectionHeadersTable() ).newQuery() ); - - query->addToOutputList( RelationalCollectionNames::dataTableNameVariableInCollectionHeadersTable() ); - query->addToOutputList( RelationalCollectionNames::linksTableNameVariableInCollectionHeadersTable() ); - query->addToOutputList( RelationalCollectionNames::writtenRecordsVariableInCollectionHeadersTable() ); - query->defineOutputType( RelationalCollectionNames::writtenRecordsVariableInCollectionHeadersTable(), "int" ); - m_whereDataForCollectionNameInHeadersTable->begin()->data<std::string>() = fragmentName; - query->setCondition( m_whereClauseForCollectionNameInHeadersTable, *m_whereDataForCollectionNameInHeadersTable ); - query->limitReturnedRows( 1, 0 ); - - coral::ICursor& cursor = query->execute(); - if( cursor.next() ) { - const coral::AttributeList& row = cursor.currentRow(); - m_dataTableNameForCollectionFragmentName[fragmentName] = row[0].data<std::string>(); - m_linksTableNameForCollectionFragmentName[fragmentName] = row[1].data<std::string>(); - m_fragmentDataMap[fragmentName].setCurrentRowId( row[2].data<int>() ); - } - else { - std::string errorMsg = "No data and links tables found for collection fragment `" - + fragmentName + "'."; - throw pool::Exception( errorMsg, - "RelationalCollection::initialize", - "RelationalCollection" ); - } -} - - - - -pool::ICollectionGUIDQuery* -pool::RelationalCollection::RelationalCollection::newGUIDQuery() const -{ - return new GUIDQuery( - *m_session, - m_description, - m_dataTableNameForCollectionFragmentName, - m_linksTableNameForCollectionFragmentName, - m_tableTokenColumnPrefixForCollectionTokenColumnName, - m_tableAttributeColumnNameForCollectionAttributeColumnName, - *m_tableAttributeList, - m_mapOfLinkIdForTokenKeyMaps, - m_mapOfTokenKeyForLinkIdMaps ); -} - diff --git a/Database/APR/RelationalCollection/src/RelationalCollection.h b/Database/APR/RelationalCollection/src/RelationalCollection.h deleted file mode 100755 index 128d5990018203597cb58a51bf9e860a1273b7d7..0000000000000000000000000000000000000000 --- a/Database/APR/RelationalCollection/src/RelationalCollection.h +++ /dev/null @@ -1,433 +0,0 @@ -/* - Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration -*/ - -#ifndef RELATIONALCOLLECTION_RELATIONALCOLLECTION_H -#define RELATIONALCOLLECTION_RELATIONALCOLLECTION_H - -#include "CollectionBase/ICollection.h" -#include "CollectionBase/CollectionRowBuffer.h" -#include "CollectionBase/CollectionDescription.h" -#include "CollectionBase/ICollectionRelationalExtensions.h" - -#include "RelationalCollectionFragmentData.h" - -#include "Gaudi/PluginService.h" - -#include <map> - - -namespace coral { - class ISessionProxy; - class ISchema; - class AttributeList; -} - - -namespace pool { - - class ISession; - - namespace RelationalCollection { - - class RelationalCollectionSchemaEditor; - class RelationalCollectionDataEditor; - class RelationalCollectionMetadata; - - /** - * @class RelationalCollection RelationalCollection.h src/RelationalCollection.h - * - * Implementation of the ICollection interface to a collection of event references - * and their associated metadata. This class may also be used as an interface to a - * "collection fragment" which, by definition, contains a subset of the event level - * metadata, does not contain the event reference and which can reference an existing - * collection or collection fragment and/or be referenced by a chain of collection - * fragments to form a collection or collection fragment with extended schema. - */ - class RelationalCollection : virtual public ICollection, public ICollectionRelationalExtensions - { - public: - typedef Gaudi::PluginService::Factory<ICollection*( const ICollectionDescription*, ICollection::OpenMode, ISession*)> Factory; - - /** - * Constructor. - * - * @param description Specication of collection properties. - * @param mode Open mode of collection (CREATE, CREATE_MISSING_FRAGMENTS, CREATE_AND_OVERWRITE, READ or UPDATE). - * @param session Reference to POOL database session (place holder for implicit collections). - */ - RelationalCollection( const pool::ICollectionDescription* description, - pool::ICollection::OpenMode mode, - pool::ISession* session ); - - /// Default destructor. - ~RelationalCollection(); - - RelationalCollection (const RelationalCollection&) = delete; - RelationalCollection& operator= (const RelationalCollection&) = delete; - - /// Returns the open mode of the collection for the present transaction. - virtual ICollection::OpenMode openMode() const; - - /// Opens the collection and initializes it if necessary. - virtual void open(); - - /// Checks if the collection is open. - virtual bool isOpen() const; - - /// Commits the latest changes made to the collection. - virtual void commit( bool restartTransaction = true ); - - /// Aborts the latest changes made to the collection. - virtual void rollback(); - - /// Closes the collection and terminates any database connections. - virtual void close(); - - /** - * Checks for the existence of one or more fragments of the collection. - * - * @param fragmentName Name of collection fragment. - * @param setForUpdate Flag indicating whether to lock the collection for update if it exists. - * @param checkChildFragments Flag to check for existence of all child fragments of given fragment. - */ - virtual bool exists( const std::string& fragmentName, - bool setForUpdate = false, - bool checkChildFragments = false ) const; - - /** - * Drops one or more fragments of the collection and returns false if a fragment to be dropped cannot be found. - * - * @param fragmentName Name of collection fragment to drop. - * @param dropChildFragments Flag indicating whether to drop all child fragments of given fragment. - * @param ignoreExternalDependencies Flag indicating whether to check for dependencies on fragment by external fragments. - */ - virtual bool drop( const std::string& fragmentName, - bool dropChildFragments = false, - bool ignoreExternalDependencies = false ); - - - /// Actuall implementation of drop method, with additional parameter for commit at the end - bool drop_impl( const std::string& fragmentName, - bool dropChildFragments = false, - bool ignoreExternalDependencies = false, - bool commit = true ); - - - /** - * Renames a fragment of the collection. - * - * @param oldName Old name of collection fragment. - * @param newName New name of collection fragment. - */ - virtual bool rename( const std::string& oldName, - const std::string& newName ); - - /* - * Grants an access privilege to a user for one or more collection fragments. - * - * @param userName Name of user to which to grant the privilege. - * @param privilege Type of privilege to grant. - * @param fragmentName Name of collection fragment to which to grant access. - * @param grantForChildFragments Flag indicating whether to grant same access for all child fragments of specified collection fragment. - */ - virtual bool grantToUser( const std::string& userName, - pool::ICollection::Privilege privilege, - const std::string& fragmentName = "", - bool grantForChildFragments = false ); - - /* - * Revokes an access privilege from a user for one or more collection fragments. - * - * @param userName Name of user from which to revoke the privilege. - * @param privilege Type of privilege to revoke. - * @param fragmentName Name of collection fragment from which to revoke access. - * @param revokeForChildFragments Flag indicating whether to revoke same access for all child fragments of specified collection fragment. - */ - virtual bool revokeFromUser( const std::string& userName, - pool::ICollection::Privilege privilege, - const std::string& fragmentName = "", - bool revokeForChildFragments = false ); - - /* - * Grants SELECT access to the public for one or more collection fragments. - * - * @param fragmentName Name of collection fragment for which to grant access. - * @param grantForChildFragments Flag indicating whether to grant same access for all child fragments of specified collection fragment. - */ - virtual bool grantToPublic( const std::string& fragmentName = "", - bool grantForChildFragments = false ); - - /* - * Revokes SELECT access from the public for one or more collection fragments. - * - * @param fragmentName Name of collection fragment for which to revoke access. - * @param revokeForChildFragments Flag indicating whether to revoke same access for all child fragments of specified collection fragment. - */ - virtual bool revokeFromPublic( const std::string& fragmentName = "", - bool revokeForChildFragments = false ); - - /// Returns an object used to describe the collection properties. - virtual const ICollectionDescription& description() const; - - /// Returns an object used to modify the collection schema. - virtual ICollectionSchemaEditor& schemaEditor(); - - /// Returns an object used to add, update or delete rows of the collection. - virtual ICollectionDataEditor& dataEditor(); - - /// Returns an object used to query the collection. - virtual ICollectionQuery* newQuery() const; - - /// Returns an object used to access collection metadata - virtual ICollectionMetadata& metadata(); - - /// Returns an object used to query the collection for GUIDs directly on the server - virtual ICollectionGUIDQuery* newGUIDQuery() const; - - private: - /// Initializes the collection. - void initialize(); - - /// Creates the collection headers table. - void createHeadersTable(); - - /// Creates the collection descriptions table. - void createDescriptionsTable(); - - /// Creates the collection index and unique constraint descriptions table. - void createIndexDescriptionsTable(); - - /** - * Checks whether the schema of a collection fragment defined by the collection description - * object matches the schema of an existing collection fragment of the same name. - * - * @param fragmentName Name of the collection fragments. - */ - bool newSchemaEqualsExistingSchema( const std::string& fragmentName ); - - /** - * Creates the data and links tables for a fragment of a collection being created. - * - * @param fragmentName Name of collection fragment for which to create tables. - */ - void createDataAndLinksTables( const std::string& fragmentName ); - - /** - * Initializes the collection headers table for a fragment of a collection being created. - * - * @param fragmentName Name of collection fragment for which to initialize collection headers table. - */ - void initializeHeadersTable( const std::string& fragmentName, - const std::string& dataTableName, - const std::string& linksTableName); - - /** - * Initializes the collection descriptions table for a fragment of a collection being created. - * - * @param fragmentName Name of collection fragment for which to initialize collection descriptions table. - */ - void initializeDescriptionsTable( const std::string& fragmentName ); - - /// Retrieves descriptions of all collection fragments of an existing collection. - void retrieveCollectionFragmentDescriptions(); - - /** - * Retrieves descriptions of all columns of a collection fragment of an existing collection. - * - * @param fragmentName Name of collection fragment for which to retrieve column descriptions. - * @param collDesc Description object which is filled with the information. - */ - void retrieveColumnDescriptions( const std::string& fragmentName, - CollectionDescription *collDesc ) const; - - void retrieveFragmentTableNames( const std::string& fragmentName ); - - /** - * Initializes all private maps and data row buffers used by the collection to add, update or query data. - * - * @param fragmentName Name of collection fragment for which to initialize maps and row buffers. - */ - void initializeMapsAndDataRowBuffers( const std::string& fragmentName ); - - /// Creates a row buffer that uses the schema of the Token links tables. - void createLinksTableRowBuffer(); - - /** - * Creates the maps of link ID's to Token keys for a given fragment of the collection. - * - * @param fragmentName Name of collection fragment for which to create maps. - */ - void createLinkIdToTokenKeyMaps( const std::string& fragmentName ); - - /** - * Creates an index one or more columns of a collection being created. - * - * @param indexName Name assigned to index. - * @param columnNames Names of columns for which index is created. - * @param isUnique Flag to indicates whether combination of indexed column values must be unique. - */ - void createIndex( const std::string& indexName, - const std::vector< std::string >& columnNames, - bool isUnique ); - - /** - * Sets a unique constraint on one or more columns of a collection being created. - * - * @param constraintName Name of constraint. - * @param columnNames Names of columns for which constraint is applied. - */ - void setUniqueConstraint( const std::string& constraintName, - const std::vector< std::string >& columnNames ); - - /** - * Retrieves descriptions of all indices in a collection fragment of the collection. - * - * @param fragmentName Name of collection fragment that contains the indices. - */ - void retrieveIndexDescriptions( const std::string& fragmentName ); - - /** - * Retrieves a description of a unique constraint in a collection fragment of the collection. - * - * @param fragmentName Name of collection fragment that contains the unique constraints. - */ - void retrieveUniqueConstraintDescriptions( const std::string& fragmentName ); - - /** - * Drops all foreign key constraints applied by a collection fragment except the constraint - * (if it exists) that is defined in the collection description. An input flag is provided to - * allow the defined constraint to also be dropped. - * - * @param fragmentName Name of collection fragment for which to drop applied foreign key constraints. - * @param dropDefinedConstraint Flag indicating whether to drop applied constraint defined in collection description. - */ - void dropParentForeignKeyConstraints( const std::string& fragmentName, - bool dropDefinedConstraint = false ); - - /** - * Drops the foreign key constraint on the collection fragment by its child collection fragment if such - * a constraint exists. - * - * @param fragmentName Name of collection fragment for which to drop the foreign key constraint. - */ - void dropChildForeignKeyConstraint( const std::string& fragmentName ); - - /** - * Sets a foreign key constraint on the parent collection fragment of the collection fragment specified as input. - * - * @param fragmentName Name of collection fragment for which to set constraint. - */ - void setForeignKeyConstraint( const std::string& fragmentName ); - - private: - /// Specification of collection properties. - CollectionDescription m_description; - - /// Open mode of collection for present transaction. - ICollection::OpenMode m_mode; - - /// Reference to current database access session. - coral::ISessionProxy *m_session; - - /// Name of top level collection fragment. - std::string m_name; - - /// Schema editor for collection. - RelationalCollectionSchemaEditor *m_schemaEditor; - - /// Data editor for collection. - RelationalCollectionDataEditor *m_dataEditor; - - RelationalCollectionMetadata *m_metadata; - - - /// Where clause for finding collection fragment name in collection headers table. - std::string m_whereClauseForCollectionNameInHeadersTable; - - /// Where clause for finding child collection fragment name in collection headers table. - std::string m_whereClauseForChildCollectionNameInHeadersTable; - - /// Where clause for finding collection fragment name in collection descriptions table. - std::string m_whereClauseForCollectionNameInDescriptionsTable; - - /// Where clause for finding collection fragment name in index and unique constraints descriptions table. - std::string m_whereClauseForCollectionNameInIndexDescriptionsTable; - - // Where clause for finding index name in index and unique constraint descriptions table. - std::string m_whereClauseForIndexNameInIndexDescriptionsTable; - - /// Bind data for collection headers table collection fragment name where clause. - coral::AttributeList* m_whereDataForCollectionNameInHeadersTable; - - /// Bind data for collection headers table child collection fragment name where clause. - coral::AttributeList* m_whereDataForChildCollectionNameInHeadersTable; - - /// Bind data for collection descriptions table collection fragment name where clause. - coral::AttributeList* m_whereDataForCollectionNameInDescriptionsTable; - - /// Bind data for collection index descriptions table collection fragment name where clause. - coral::AttributeList* m_whereDataForCollectionNameInIndexDescriptionsTable; - - /// Bind data for collection index descriptions table index name where clause. - coral::AttributeList* m_whereDataForIndexNameInIndexDescriptionsTable; - - /// Map of data table names using names of corresponding collection fragment names as keys. - std::map< std::string, std::string > m_dataTableNameForCollectionFragmentName; - - /// Map of links table names using names of corresponding collection fragment names as keys. - std::map< std::string, std::string > m_linksTableNameForCollectionFragmentName; - - /// Map holding the number of records written for a collection fragment name - //std::map< std::string, unsigned > m_recordsWrittenForCollectionFragmentName; - - /// Information related to fragments, map keyed by fragment name - FragmentDataMap m_fragmentDataMap; - - /// Map of table column prefixes for Tokens using names of corresponding collection columns as keys. - std::map< std::string, std::string > m_tableTokenColumnPrefixForCollectionTokenColumnName; - - /// Map of table column names for Attributes using names of corresponding collection columns as keys. - std::map< std::string, std::string > m_tableAttributeColumnNameForCollectionAttributeColumnName; - - /// Map of table column names or prefixes using names of corresponding collection columns as keys. - std::map< std::string, std::string > m_tableColumnNameForCollectionColumnName; - - /// Map of collection column names using positions of corresponding table columns as keys. - std::map< int, std::string > m_collectionColumnNameForTableColumnPosition; - - /// List of all Attributes defined by collection but using table column names. - coral::AttributeList* m_tableAttributeList; - - /// Collection row buffer containing all Tokens and Attributes defined by collection. - pool::CollectionRowBuffer m_collectionRowBuffer; - - /// Map of data table row buffers using names of corresponding collection fragments as keys. - std::map< std::string, coral::AttributeList* > m_dataTableRowBufferForCollectionFragmentName; - - /// Row buffer using schema of collection links tables. - coral::AttributeList* m_linksTableRowBuffer; - - /// Map of maps of link table ID's that use corresponding Token prefixes as keys, using collection fragment names as keys. - std::map< std::string, std::map< std::string, unsigned >* > m_mapOfLinkIdForTokenKeyMaps; - - /// Map of maps of Token prefixes that use corresponding link table ID's as keys, using collection fragment names as keys. - std::map< std::string, std::map< unsigned, std::string >* > m_mapOfTokenKeyForLinkIdMaps; - - /// Map of where clauses for finding Token OID_1 values in data tables, using Token collection column names as keys. - std::map< std::string, std::string > m_mapOfWhereClausesForOID1InDataTable; - - /// Map of where data for finding Token OID_1 values in data tables, using Token collection column names as keys. - std::map< std::string, coral::AttributeList* > m_mapOfWhereDataForOID1InDataTable; - - /// Flag indicating whether collection has been initialized. - bool m_initialized; - - /// output stream - // mutable coral::MessageStream m_poolOut; - }; - - } -} - -#endif diff --git a/Database/APR/RelationalCollection/src/RelationalCollectionBindVariables.cpp b/Database/APR/RelationalCollection/src/RelationalCollectionBindVariables.cpp deleted file mode 100755 index 2f5e12c4b17e95f782208248bea2e9013b14e0cb..0000000000000000000000000000000000000000 --- a/Database/APR/RelationalCollection/src/RelationalCollectionBindVariables.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#include "RelationalCollectionBindVariables.h" -#include "RelationalCollectionNames.h" - -#include <sstream> - - -std::string -pool::RelationalCollection::RelationalCollectionBindVariables::whereClauseForCollectionNameInHeadersTable() -{ - return ( pool::RelationalCollection::RelationalCollectionNames::collectionNameVariableInCollectionHeadersTable() + " = :" + pool::RelationalCollection::RelationalCollectionNames::collectionNameVariableInCollectionHeadersTable() ); -} - - -std::string -pool::RelationalCollection::RelationalCollectionBindVariables::whereClauseForChildCollectionNameInHeadersTable() -{ - return ( pool::RelationalCollection::RelationalCollectionNames::childCollectionNameVariableInCollectionHeadersTable() + " = :" + pool::RelationalCollection::RelationalCollectionNames::childCollectionNameVariableInCollectionHeadersTable() ); -} - - -std::string -pool::RelationalCollection::RelationalCollectionBindVariables::whereClauseForCollectionNameInDescriptionsTable() -{ - return ( pool::RelationalCollection::RelationalCollectionNames::collectionNameVariableInCollectionDescriptionsTable() + " = :" + pool::RelationalCollection::RelationalCollectionNames::collectionNameVariableInCollectionDescriptionsTable() ); -} - - -std::string -pool::RelationalCollection::RelationalCollectionBindVariables::whereClauseForColumnNameInDescriptionsTable() -{ - return ( RelationalCollectionNames::collectionVariableNameVariableInCollectionDescriptionsTable() + " = :" + RelationalCollectionNames::collectionVariableNameVariableInCollectionDescriptionsTable() + " AND " + RelationalCollectionNames::collectionNameVariableInCollectionDescriptionsTable() + " = :" + RelationalCollectionNames::collectionNameVariableInCollectionDescriptionsTable() ); -} - - -std::string -pool::RelationalCollection::RelationalCollectionBindVariables::whereClauseForCollectionNameInIndexDescriptionsTable() -{ - return ( pool::RelationalCollection::RelationalCollectionNames::collectionNameVariableInCollectionIndexDescriptionsTable() + " =:" +pool::RelationalCollection::RelationalCollectionNames::collectionNameVariableInCollectionIndexDescriptionsTable() ); -} - - -std::string -pool::RelationalCollection::RelationalCollectionBindVariables::whereClauseForIndexNameInIndexDescriptionsTable() -{ - return ( pool::RelationalCollection::RelationalCollectionNames::indexNameVariableInCollectionIndexDescriptionsTable() + " = :" + pool::RelationalCollection::RelationalCollectionNames::indexNameVariableInCollectionIndexDescriptionsTable() + " AND " + pool::RelationalCollection::RelationalCollectionNames::collectionNameVariableInCollectionDescriptionsTable() + " = :" + pool::RelationalCollection::RelationalCollectionNames::collectionNameVariableInCollectionDescriptionsTable() ); -} - - -std::string -pool::RelationalCollection::RelationalCollectionBindVariables::whereClauseForUniqueConstraintNameInIndexDescriptionsTable() -{ - return ( RelationalCollectionNames::uniqueConstraintNameVariableInCollectionIndexDescriptionsTable() + " = :" + RelationalCollectionNames::uniqueConstraintNameVariableInCollectionIndexDescriptionsTable() + " AND " + RelationalCollectionNames::collectionNameVariableInCollectionDescriptionsTable() + " = :" + RelationalCollectionNames::collectionNameVariableInCollectionDescriptionsTable() ); -} - - -std::string -pool::RelationalCollection::RelationalCollectionBindVariables::whereClauseForPrimaryKeyInDataTable() -{ - return ( pool::RelationalCollection::RelationalCollectionNames::recordIdVariableInCollectionDataTable() + " = :" + pool::RelationalCollection::RelationalCollectionNames::recordIdVariableInCollectionDataTable() ); -} - - -std::string -pool::RelationalCollection::RelationalCollectionBindVariables::whereClauseForLinkIdInLinksTable() -{ - return ( pool::RelationalCollection::RelationalCollectionNames::linkIdVariableInCollectionLinksTable() + " = :" + pool::RelationalCollection::RelationalCollectionNames::linkIdVariableInCollectionLinksTable() ); -} - - - -std::string -pool::RelationalCollection::RelationalCollectionBindVariables:: -whereClauseForMetadata() -{ - return RelationalCollectionNames::collectionNameColumn() + " = :" + RelationalCollectionNames::collectionNameColumn(); -} - - -std::string -pool::RelationalCollection::RelationalCollectionBindVariables:: -whereClauseForMetadataKey() -{ - return whereClauseForMetadata() + " AND " + RelationalCollectionNames::metadataKeyColumn() + " = :" + RelationalCollectionNames::metadataKeyColumn(); -} diff --git a/Database/APR/RelationalCollection/src/RelationalCollectionBindVariables.h b/Database/APR/RelationalCollection/src/RelationalCollectionBindVariables.h deleted file mode 100755 index 9a7518f1946ae53d7c8f1b1c46a89b973081c68e..0000000000000000000000000000000000000000 --- a/Database/APR/RelationalCollection/src/RelationalCollectionBindVariables.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#ifndef RELATIONALCOLLECTION_RELATIONALCOLLECTIONBINDVARIABLES_H -#define RELATIONALCOLLECTION_RELATIONALCOLLECTIONBINDVARIABLES_H - -#include <string> - -namespace pool { - - namespace RelationalCollection { - - /// Utility class holding frequently used bind variables in the RelationalCollection package. - class RelationalCollectionBindVariables - { - public: - // Collection headers table. - - // Returns a where clause for finding a collection fragment name in the collection headers table. - static std::string whereClauseForCollectionNameInHeadersTable(); - // Returns a where clause for finding a child collection fragment name in the collection headers table. - static std::string whereClauseForChildCollectionNameInHeadersTable(); - - // Collection descriptions table. - - /// Returns a where clause for finding a collection fragment name in the collection descriptions table. - static std::string whereClauseForCollectionNameInDescriptionsTable(); - /// Returns a where clause for finding a column name in the collection descriptions table. - static std::string whereClauseForColumnNameInDescriptionsTable(); - - // Collection indices and unique constraints table. - - /// Returns a where clause for finding a collection fragment name in the index and unique constraints descriptions table. - static std::string whereClauseForCollectionNameInIndexDescriptionsTable(); - /// Returns a where clause for finding an index name in the index and unique constraint descriptions table. - static std::string whereClauseForIndexNameInIndexDescriptionsTable(); - /// Returns a where clause for finding a unique constrant name in the index and unique constraint descriptions table. - static std::string whereClauseForUniqueConstraintNameInIndexDescriptionsTable(); - - // Collection data table. - - /// Returns a where clause for finding a primary key in the data table of a collection. - static std::string whereClauseForPrimaryKeyInDataTable(); - - // Collection links table. - - /// Returns a where clause for finding a link ID in the links table of a collection. - static std::string whereClauseForLinkIdInLinksTable(); - - - // Metadata table - static std::string whereClauseForMetadata(); - static std::string whereClauseForMetadataKey(); - - }; - } -} - -#endif diff --git a/Database/APR/RelationalCollection/src/RelationalCollectionCursor.cpp b/Database/APR/RelationalCollection/src/RelationalCollectionCursor.cpp deleted file mode 100755 index 4575078549de81c87e4f4382d04a0b22d2f870a0..0000000000000000000000000000000000000000 --- a/Database/APR/RelationalCollection/src/RelationalCollectionCursor.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#include "RelationalCollectionCursor.h" - -#include "PersistentDataModel/Token.h" - -#include "CollectionBase/ICollectionDescription.h" -#include "CollectionBase/CollectionRowBuffer.h" - -#include "RelationalAccess/ICursor.h" - -#include "CoralBase/Attribute.h" - -//#include <iostream> -using namespace std; - -pool::RelationalCollection::RelationalCollectionCursor::RelationalCollectionCursor( - coral::ICursor& cursor, - const pool::ICollectionDescription& description, - const std::map< std::string, std::map< unsigned, std::string >* >& mapOfTokenKeyForLinkIdMaps, - const pool::CollectionRowBuffer& collectionRowBuffer ) - : m_cursor( cursor ), - m_description( description ), - m_mapOfTokenKeyForLinkIdMaps( mapOfTokenKeyForLinkIdMaps ), - m_collectionRowBuffer( new pool::CollectionRowBuffer( collectionRowBuffer ) ), - m_primaryKey( 0 ) -{} - - -pool::RelationalCollection::RelationalCollectionCursor::~RelationalCollectionCursor() -{ - this->close(); - delete m_collectionRowBuffer; //? MN -} - - -bool -pool::RelationalCollection::RelationalCollectionCursor::next() -{ - if( !m_cursor.next() ) { - return false; - } - - // Get iterator over current row. - coral::AttributeList::const_iterator iData = m_cursor.currentRow().begin(); -/* - cout << " * Cursor next(), values: " << endl; - for( ; iData != m_cursor.currentRow().end(); ++iData ) { - std::cout << "["; - iData->toOutputStream( std::cout ); - std::cout << "] "; - } - cout << endl; - iData = m_cursor.currentRow().begin(); -*/ - // Get primary key for current row. - m_primaryKey = iData->data< unsigned >(); - ++iData; - - const Token empty_token; - // Get Tokens for current row and add them to row buffer. - for( pool::TokenList::iterator iToken = m_collectionRowBuffer->tokenList().begin(); - iToken != m_collectionRowBuffer->tokenList().end(); ++iToken, ++iData ) - { - // clear target Token before filling (this does not affect tokenName!) - empty_token.setData(&*iToken); - const std::string& tokenName = iToken.tokenName(); - const std::string fragmentName = m_description.collectionFragmentName( tokenName ); - std::map< unsigned, std::string >* tokenKeyForLinkId = m_mapOfTokenKeyForLinkIdMaps.find( fragmentName )->second; - unsigned linkId = iData->data< unsigned >(); - iToken->fromString( ( tokenKeyForLinkId->find( linkId ) )->second ); - iToken->oid().first = static_cast<int>( linkId ); - ++iData; - unsigned oid2 = iData->data< unsigned >(); - iToken->oid().second = static_cast<int>( oid2 ); - } - return true; -} - - -const pool::CollectionRowBuffer& -pool::RelationalCollection::RelationalCollectionCursor::currentRow() const -{ - return *m_collectionRowBuffer; -} - - -const Token& -pool::RelationalCollection::RelationalCollectionCursor::eventRef() const -{ - return ( m_collectionRowBuffer->tokenList()[ m_description.eventReferenceColumnName() ] ); -} - - -unsigned -pool::RelationalCollection::RelationalCollectionCursor::primaryKey() const -{ - return m_primaryKey; -} - - -void -pool::RelationalCollection::RelationalCollectionCursor::close() -{} - diff --git a/Database/APR/RelationalCollection/src/RelationalCollectionCursor.h b/Database/APR/RelationalCollection/src/RelationalCollectionCursor.h deleted file mode 100755 index 79ced8890b6e064e6c8e32bceb6aff13e42439a0..0000000000000000000000000000000000000000 --- a/Database/APR/RelationalCollection/src/RelationalCollectionCursor.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#ifndef RELATIONALCOLLECTION_RELATIONALCOLLECTIONCURSOR_H -#define RELATIONALCOLLECTION_RELATIONALCOLLECTIONCURSOR_H - -#include "CollectionBase/ICollectionCursor.h" - -#include <string> -#include <map> - - -namespace coral { - class ICursor; -} - -namespace pool { - - class ICollectionDescription; - - namespace RelationalCollection { - - /** - * @class RelationalCollectionCursor RelationalCollectionCursor.h src/RelationalCollectionCursor.h - * - * Implementation of the ICollectionCursor interface used to navigate the result of a query on a collection. - */ - class RelationalCollectionCursor : virtual public pool::ICollectionCursor - { - public: - /** - * Constructor. - * - * @param cursor Cursor for navigation over rows that pass query. - * @param description Specification of collection properties. - * @param mapOfTokenKeyForLinkIdMaps Map of maps of Token prefixes that use corresponding link table ID's as keys, using collection fragment names as keys. - * @param collectionRowBuffer Row buffer containing Tokens and Attributes selected by query. - */ - RelationalCollectionCursor( - coral::ICursor& cursor, - const ICollectionDescription& description, - const std::map< std::string, std::map< unsigned, std::string >* >& mapOfTokenKeyForLinkIdMaps, - const CollectionRowBuffer& collectionRowBuffer ); - - /// Destructor. - ~RelationalCollectionCursor(); - - RelationalCollectionCursor (const RelationalCollectionCursor&) = delete; - RelationalCollectionCursor& operator= (const RelationalCollectionCursor&) = delete; - - /// Advances the cursor to the next row of the query result set. - virtual bool next(); - - /// Returns the selected Tokens and Attributes for the current row of the query result set. - virtual const pool::CollectionRowBuffer& currentRow() const; - - /// Returns the event reference Token for the current row. - virtual const Token& eventRef() const; - - /// Returns the primary key for the current row. - virtual unsigned primaryKey() const; - - /// Cleanup. - virtual void close(); - - private: - /// Cursor for navigation over rows that pass query. - coral::ICursor& m_cursor; - - /// Specification of collection properities. - const ICollectionDescription& m_description; - - /// Map of maps of Token prefixes that use corresponding link table ID's as keys, using collection fragment names as keys. - const std::map< std::string, std::map< unsigned, std::string >* >& m_mapOfTokenKeyForLinkIdMaps; - - /// Row buffer containing Tokens and Attributes selected by query. - pool::CollectionRowBuffer *m_collectionRowBuffer; - - /// Primary key for current row. - unsigned m_primaryKey; - }; - } -} - -#endif - - diff --git a/Database/APR/RelationalCollection/src/RelationalCollectionDataEditor.cpp b/Database/APR/RelationalCollection/src/RelationalCollectionDataEditor.cpp deleted file mode 100755 index 7ebe75a7f8b05a34d1396fcb0af7716f0ecbb0dd..0000000000000000000000000000000000000000 --- a/Database/APR/RelationalCollection/src/RelationalCollectionDataEditor.cpp +++ /dev/null @@ -1,818 +0,0 @@ -/* - Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration -*/ - -#include "RelationalCollectionDataEditor.h" -#include "RelationalCollectionNames.h" -#include "RelationalCollectionBindVariables.h" -#include "RelationalCollectionQuery.h" -#include "RelationalCollectionCursor.h" - -#include "PersistentDataModel/Token.h" - -#include "CollectionBase/ICollectionDescription.h" -#include "CollectionBase/CollectionRowBuffer.h" -#include "CollectionBase/TokenList.h" -#include "CollectionBase/ICollectionCursor.h" -#include "CollectionBase/ICollectionFragment.h" -#include "CollectionBase/ICollectionColumn.h" - -#include "CoralBase/MessageStream.h" -#include "POOLCore/Exception.h" - -#include "RelationalAccess/ISessionProxy.h" -#include "RelationalAccess/ISchema.h" - -#include "RelationalAccess/ConnectionService.h" -#include "RelationalAccess/ITransaction.h" -#include "RelationalAccess/ITable.h" -#include "RelationalAccess/IQuery.h" -#include "RelationalAccess/ICursor.h" -#include "RelationalAccess/ITableDataEditor.h" -#include "RelationalAccess/IBulkOperation.h" -#include "RelationalAccess/IConnectionServiceConfiguration.h" - -#include "CoralBase/Attribute.h" -#include "CoralBase/AttributeList.h" - -#include <sstream> -#include <cstdio> // For sprintf (bug #69271) -//#include <iostream> -#include <memory> -using namespace std; - - - -template< typename T > -inline void -extendAttributeList( coral::AttributeList& list, const std::string& attribute, const T& value ) -{ - list.extend<T>( attribute ); - list[ attribute ].data<T>() = value; -} - - -pool::RelationalCollection::RelationalCollectionDataEditor::RelationalCollectionDataEditor( - coral::ISessionProxy& session, - const pool::ICollectionDescription& description, - const std::map< std::string, std::string >& dataTableNameForCollectionFragmentName, - const std::map< std::string, std::string >& linksTableNameForCollectionFragmentName, - FragmentDataMap& fragmentDataMap, - const std::map< std::string, std::string >& tableTokenColumnPrefixForCollectionTokenColumnName, - const std::map< std::string, std::string >& tableAttributeColumnNameForCollectionAttributeColumnName, - const coral::AttributeList& tableAttributeList, - pool::CollectionRowBuffer& collectionRowBuffer, - std::map< std::string, coral::AttributeList* >& dataTableRowBufferForCollectionFragmentName, - coral::AttributeList& linksTableRowBuffer, - std::map< std::string, std::map< std::string, unsigned >* >& mapOfLinkIdForTokenKeyMaps, - std::map< std::string, std::map< unsigned, std::string >* >& mapOfTokenKeyForLinkIdMaps, - const std::map< std::string, std::string >& mapOfWhereClausesForOID1InDataTable, - const std::map< std::string, coral::AttributeList* >& mapOfWhereDataForOID1InDataTable ) - : m_rowCacheSize( 0 ), - m_rowIDAllocationStep( 100 ), - m_session( session ), - m_schema( &m_session.nominalSchema() ), - m_description( description ), - m_dataTableNameForCollectionFragmentName( dataTableNameForCollectionFragmentName ), - m_linksTableNameForCollectionFragmentName( linksTableNameForCollectionFragmentName ), - m_fragmentDataMap( fragmentDataMap ), - m_tableTokenColumnPrefixForCollectionTokenColumnName( tableTokenColumnPrefixForCollectionTokenColumnName ), - m_tableAttributeColumnNameForCollectionAttributeColumnName( tableAttributeColumnNameForCollectionAttributeColumnName ), - m_tableAttributeList( tableAttributeList ), - m_collectionRowBuffer( collectionRowBuffer ), - m_dataTableRowBufferForCollectionFragmentName( dataTableRowBufferForCollectionFragmentName ), - m_linksTableRowBuffer( linksTableRowBuffer ), - m_mapOfLinkIdForTokenKeyMaps( mapOfLinkIdForTokenKeyMaps ), - m_mapOfTokenKeyForLinkIdMaps( mapOfTokenKeyForLinkIdMaps ), - m_mapOfWhereClausesForOID1InDataTable( mapOfWhereClausesForOID1InDataTable ), - m_mapOfWhereDataForOID1InDataTable( mapOfWhereDataForOID1InDataTable ), - m_whereClauseForCollectionNameInHeadersTable( RelationalCollectionBindVariables::whereClauseForCollectionNameInHeadersTable() ), - m_whereDataForCollectionNameInHeadersTable( new coral::AttributeList ), - m_whereClauseForPrimaryKeyInDataTable( RelationalCollectionBindVariables::whereClauseForPrimaryKeyInDataTable() ), - m_whereDataForPrimaryKeyInDataTable( new coral::AttributeList ), - m_whereClauseForLinkIdInLinksTable( RelationalCollectionBindVariables::whereClauseForLinkIdInLinksTable() ), - m_whereDataForLinkIdInLinksTable( new coral::AttributeList ), - m_bulkRowOperationForCollectionFragmentName(), - m_rowIDSession( 0 ) -{ - // Define bind variable type used in where clause to find collection fragment name in collection headers table. - m_whereDataForCollectionNameInHeadersTable->extend<std::string>( - RelationalCollectionNames::collectionNameVariableInCollectionHeadersTable() ); - - // Define bind variable type used in where clause to find primary key in data table of collection. - m_whereDataForPrimaryKeyInDataTable->extend<unsigned>( - pool::RelationalCollection::RelationalCollectionNames::recordIdVariableInCollectionDataTable() ); - - // Define bind variable type used in where clause to find link ID in links table of collection. - m_whereDataForLinkIdInLinksTable->extend<unsigned>( - pool::RelationalCollection::RelationalCollectionNames::linkIdVariableInCollectionLinksTable() ); -} - - - -pool::RelationalCollection::RelationalCollectionDataEditor::~RelationalCollectionDataEditor() -{ - delete m_whereDataForCollectionNameInHeadersTable; - delete m_whereDataForPrimaryKeyInDataTable; - delete m_whereDataForLinkIdInLinksTable; - delete m_rowIDSession; -} - - -void -pool::RelationalCollection::RelationalCollectionDataEditor::setRowCacheSize( int rowCacheSize ) -{ - if( rowCacheSize <= 0 ) - return; - - flushCachedRows(); - deleteRowCache(); - - m_rowCacheSize = rowCacheSize; - createRowCache(); - - setRowIDAllocationStep( rowCacheSize ); -} - - -void -pool::RelationalCollection::RelationalCollectionDataEditor::createRowCache() -{ - if( m_rowCacheSize <= 0 ) - return; - - for( std::map< std::string, coral::AttributeList* >::const_iterator iData = - m_dataTableRowBufferForCollectionFragmentName.begin(); iData != - m_dataTableRowBufferForCollectionFragmentName.end(); ++iData ) - { - // Get collection fragment name. - std::string fragmentName = iData->first; - - // Get data table name. - std::string dataTableName = m_dataTableNameForCollectionFragmentName.find( fragmentName )->second; - - // Get reference to data table row buffer. - coral::AttributeList* dataTableRowBuffer = iData->second; - - // Create new bulk operation object for this collection fragment and cache size. - coral::ITable& dataTable = m_schema->tableHandle( dataTableName ); - coral::IBulkOperation* bulkOperation = dataTable.dataEditor().bulkInsert( *dataTableRowBuffer, m_rowCacheSize ); - - // Store bulk operation object for this collection fragment. - m_bulkRowOperationForCollectionFragmentName[ fragmentName ] = bulkOperation; - } -} - - -void -pool::RelationalCollection::RelationalCollectionDataEditor::flushCachedRows() -{ - if( m_rowCacheSize <= 0 ) - return; - - for( std::map< std::string, coral::IBulkOperation* >::const_iterator iOper = - m_bulkRowOperationForCollectionFragmentName.begin(); - iOper != m_bulkRowOperationForCollectionFragmentName.end(); - ++iOper ) { - iOper->second->flush(); - } -} - - - -void -pool::RelationalCollection::RelationalCollectionDataEditor::deleteRowCache() -{ - if( m_rowCacheSize <= 0 ) - return; - - for( std::map< std::string, coral::IBulkOperation* >::const_iterator iOper = - m_bulkRowOperationForCollectionFragmentName.begin(); - iOper != m_bulkRowOperationForCollectionFragmentName.end(); - ++iOper ) { - delete iOper->second; - } - m_bulkRowOperationForCollectionFragmentName.clear(); -} - - - -void -pool::RelationalCollection::RelationalCollectionDataEditor:: -setRowIDAllocationStep( int step ) -{ - - if( step < 100 ) m_rowIDAllocationStep = 100; - else if( step > 1000 ) m_rowIDAllocationStep = 1000; - else m_rowIDAllocationStep = step; -} - - - -pool::CollectionRowBuffer& -pool::RelationalCollection::RelationalCollectionDataEditor::rowBuffer() -{ - return m_collectionRowBuffer; -} - - -pool::CollectionRowBuffer& -pool::RelationalCollection::RelationalCollectionDataEditor::emptyRowBuffer() -{ - clearRowBuffers(); - return m_collectionRowBuffer; -} - - -void -pool::RelationalCollection::RelationalCollectionDataEditor::clearRowBuffers() -{ - // NOTE - similar code is in main collection.cpp and schema editor - keep in synch - - // Create empty collection and data table row buffers and reset private map. - pool::TokenList tokenList; - coral::AttributeList attributeList; - for( int i = 0; i < m_description.numberOfCollectionFragments(); i++ ) - { - coral::AttributeList *dataTableRowBuffer = new coral::AttributeList; - std::string fragmentName = m_description.collectionFragment( i ).name(); - // Add primary key column - only temporary fix? MN - dataTableRowBuffer->extend( RelationalCollectionNames::recordIdVariableInCollectionDataTable(), - coral::AttributeSpecification::typeNameForType<unsigned>() ); - for( int j = 0; j < m_description.numberOfTokenColumns( fragmentName ); j++ ) - { - const std::string& collectionColumnName = m_description.tokenColumn( j, fragmentName ).name(); - tokenList.extend( collectionColumnName ); - std::string tableColumnPrefix = - ( m_tableTokenColumnPrefixForCollectionTokenColumnName.find( collectionColumnName ) )->second; - std::string oid1ColumnName = tableColumnPrefix + - RelationalCollectionNames::oid_1_variableInCollectionDataTable(); - std::string oid2ColumnName = tableColumnPrefix + - RelationalCollectionNames::oid_2_variableInCollectionDataTable(); - dataTableRowBuffer->extend( oid1ColumnName, typeid(unsigned) ); - dataTableRowBuffer->extend( oid2ColumnName, typeid(unsigned) ); - } - for( int j = 0; j < m_description.numberOfAttributeColumns( fragmentName ); j++ ) - { - const std::string& collectionColumnName = m_description.attributeColumn( j, fragmentName ).name(); - const std::string& columnType = m_description.attributeColumn( j, fragmentName ).type(); - attributeList.extend( collectionColumnName, columnType ); - std::string tableColumnName = - ( m_tableAttributeColumnNameForCollectionAttributeColumnName.find( collectionColumnName ) )->second; - dataTableRowBuffer->extend( tableColumnName, columnType ); - } - // maybe a check for existance is needed // MN - delete m_dataTableRowBufferForCollectionFragmentName[fragmentName]; - m_dataTableRowBufferForCollectionFragmentName[fragmentName] = dataTableRowBuffer; - } - m_collectionRowBuffer.setTokenList( tokenList ); - m_collectionRowBuffer.setAttributeList( attributeList ); - - setRowCacheSize( m_rowCacheSize ); // Needed to take into account the new row buffer? -} - - - -int -pool::RelationalCollection::RelationalCollectionDataEditor:: -getUniqueRowID( ) -{ - // Obtain unique RowID number - // ============================== - std::string fragmentName = m_description.name(); // this is the main fragment - FragmentData &fragmentData = m_fragmentDataMap[ fragmentName ]; - if( !fragmentData.hasAllocatedIds() ) { - - if( !m_rowIDSession ) { - unique_ptr<coral::ConnectionService> connectionService( new coral::ConnectionService() ); - //cout << ">>>>>>> Timeout=" << connectionService->configuration().connectionTimeOut() << endl; - m_rowIDSession = connectionService->connect( m_description.connection(), coral::Update ); - } - - // Start a transaction. - m_rowIDSession->transaction().start(); - - m_whereDataForCollectionNameInHeadersTable->begin()->data<std::string>() = fragmentName; - coral::ITable& headersTable = m_rowIDSession->nominalSchema().tableHandle( RelationalCollectionNames::nameOfCollectionHeadersTable() ); - - std::unique_ptr<coral::IQuery> query( headersTable.newQuery() ); - query->addToOutputList( RelationalCollectionNames::writtenRecordsVariableInCollectionHeadersTable() ); - query->defineOutputType( RelationalCollectionNames::writtenRecordsVariableInCollectionHeadersTable(), "unsigned int" ); - query->setCondition( m_whereClauseForCollectionNameInHeadersTable, *m_whereDataForCollectionNameInHeadersTable ); - query->limitReturnedRows( 1, 0 ); - query->setForUpdate(); - - coral::ICursor& cursor = query->execute(); - if( !cursor.next() ) { - std::string errorMsg = "Failed to query number of records written for collection `" - + m_description.name() + "'."; - throw pool::Exception( errorMsg, "RelationalCollectionDataEditor::insertRow", - "RelationalCollection" ); - } - int currentID = cursor.currentRow()[0].data<unsigned>(); - delete query.release(); - - fragmentData.allocateIDs( currentID, m_rowIDAllocationStep ); - - coral::MessageStream log( "pool::RelationalCollection::insertRow()" ); - log << coral::Debug - << " Allocated new range of rowIDs: " << currentID << " - " - << currentID + m_rowIDAllocationStep << coral::MessageStream::endmsg; - - std::ostringstream setClause; - const string recwrittenBVName = "RECORDS_WRITTEN"; - setClause << RelationalCollectionNames::writtenRecordsVariableInCollectionHeadersTable() << " = :" << recwrittenBVName; - coral::AttributeList bindVariables; - extendAttributeList<int>( bindVariables, recwrittenBVName, currentID + m_rowIDAllocationStep ); - - extendAttributeList<string>( bindVariables, RelationalCollectionNames::collectionNameVariableInCollectionHeadersTable(), fragmentName ); - headersTable.dataEditor().updateRows( setClause.str(), m_whereClauseForCollectionNameInHeadersTable, bindVariables ); - - m_rowIDSession->transaction().commit(); - } - - return fragmentData.getNextRowId(); -} - - - -void -pool::RelationalCollection::RelationalCollectionDataEditor:: -insertRow( const pool::CollectionRowBuffer& inputRowBuffer, bool /* updateRecordsCounter */ ) -{ - int rowID = -1; // no rowID generated yet - - // Add input Token data to data and links table row buffers. - for( pool::TokenList::const_iterator iToken = inputRowBuffer.tokenList().begin(); - iToken != inputRowBuffer.tokenList().end(); ++iToken ) - { - // Get collection column name and table column name prefix. - std::string collectionColumnName = iToken.tokenName(); - // cout << " ---------- ColumnName = " << collectionColumnName << endl; - std::string tableColumnNamePrefix = m_tableTokenColumnPrefixForCollectionTokenColumnName.find(collectionColumnName)->second; - - // Get data table column names for Token. - std::string oid1ColumnName = tableColumnNamePrefix + RelationalCollectionNames::oid_1_variableInCollectionDataTable(); - std::string oid2ColumnName = tableColumnNamePrefix + RelationalCollectionNames::oid_2_variableInCollectionDataTable(); - - // Get name of collection fragment that contains Token. - std::string fragmentName = m_description.collectionFragmentName( collectionColumnName ); - - // Get data table row buffer for collection fragment. - coral::AttributeList& dataTableRowBuffer = *m_dataTableRowBufferForCollectionFragmentName[fragmentName]; - - // Get mappings of link ID's to Token keys for this collection fragment. - std::map< std::string, unsigned > - *linkIdForTokenKey = m_mapOfLinkIdForTokenKeyMaps[ fragmentName ]; - std::map< unsigned, std::string > - *tokenKeyForLinkId = m_mapOfTokenKeyForLinkIdMaps[ fragmentName ]; - - // Look for this Token key in map. - //const std::string tokenKey = iToken->key(); - // MN:this is a hack to build the string representation by hand, - // but it preserves the technology ID unlike the Token::key() method - char text[128]; - ::sprintf(text, "][TECH=%08X]", iToken->technology()); - const std::string tokenKey = "[DB=" + iToken->dbID().toString() + "][CNT=" + iToken->contID() - + "][CLID=" + iToken->classID().toString() + text; - //cout << " --- Checking Token key: " << tokenKey << endl; - map< string, unsigned >::const_iterator linkIdIter = linkIdForTokenKey->find( tokenKey ); - if( linkIdIter == linkIdForTokenKey->end() ) { - // Create new link ID. - //cout << " --- Adding new Token key " << tokenKey << endl; - unsigned linkId = getUniqueRowID(); - if( rowID < 0 ) { - rowID = linkId; // reuse the unique rowID for data row - } - - // Store new link ID in maps. - linkIdForTokenKey->insert( std::make_pair( tokenKey, linkId ) ); - tokenKeyForLinkId->insert( std::make_pair( linkId, tokenKey ) ); - - // Get name of links table name for this collection fragment. - std::string linksTableName = m_linksTableNameForCollectionFragmentName.find( fragmentName )->second; - - // Store new token key information in links table row buffer. - m_linksTableRowBuffer[RelationalCollectionNames::linkIdVariableInCollectionLinksTable()].data<unsigned>() = linkId; - m_linksTableRowBuffer[RelationalCollectionNames::databaseIdVariableInCollectionLinksTable()].data<std::string>() = iToken->dbID().toString(); - m_linksTableRowBuffer[RelationalCollectionNames::containerIdVariableInCollectionLinksTable()].data<std::string>() = iToken->contID(); - m_linksTableRowBuffer[RelationalCollectionNames::classIdVariableInCollectionLinksTable()].data<std::string>() = iToken->classID().toString(); - m_linksTableRowBuffer[RelationalCollectionNames::technologyIdVariableInCollectionLinksTable()].data<unsigned>() = iToken->technology(); - - // Insert new row into links table. - //cout << " Insert new row into links table " << tokenKey << ", ROW ID = " << linkId; - m_schema->tableHandle( linksTableName ).dataEditor().insertRow( m_linksTableRowBuffer ); - // Set OID_1 of Token to new link ID. - dataTableRowBuffer[oid1ColumnName].data<unsigned>() = linkId; - //cout << " Inserting token, ROW ID = " << linkId<< endl; - } - else { - //cout << " Inserting token, ROW ID = " << linkIdIter->second << endl; - // Set OID_1 of Token to existing link ID. - dataTableRowBuffer[oid1ColumnName].data<unsigned>() = linkIdIter->second; - } - //cout << " Token, OID2= " << iToken->oid().second << endl; - // Set OID_2 of Token. - dataTableRowBuffer[oid2ColumnName].data<unsigned>() = iToken->oid().second; - } - - // Bind input Attribute data to data table row buffers. - // ================== Attribute part ================ - for( coral::AttributeList::const_iterator iAttribute = inputRowBuffer.attributeList().begin(); - iAttribute != inputRowBuffer.attributeList().end(); ++iAttribute ) - { - // Get collection Attribute column name. - std::string collectionColumnName = iAttribute->specification().name(); - - // Get name of collection fragment that contains this Attribute. - std::string fragmentName = m_description.collectionFragmentName( collectionColumnName ); - - // Get reference to data table row buffer for collection fragment. - coral::AttributeList& dataTableRowBuffer = *m_dataTableRowBufferForCollectionFragmentName[fragmentName]; - - // Bind collection Attribute column values to corresponding Attribute column values in data table row buffer. - const std::string& tableColumnName = m_tableAttributeColumnNameForCollectionAttributeColumnName.find(collectionColumnName)->second; - - dataTableRowBuffer[tableColumnName].bindUnsafely( iAttribute->addressOfData() ); - } - - // generate rowID if it was not done earlier - if( rowID < 0 ) rowID = getUniqueRowID(); - - // Insert new row into data table of each corresponding collection fragment. - // ========================= Inserting Rows for each Fragment ============= - for( std::map< std::string, coral::AttributeList* >::const_iterator iData = - m_dataTableRowBufferForCollectionFragmentName.begin(); - iData != m_dataTableRowBufferForCollectionFragmentName.end(); ++iData ) - { - // Get collection fragment name and the corresponding row buffer - const std::string &fragmentName = iData->first; - coral::AttributeList &dataTableRowBuffer = *(iData->second); - - dataTableRowBuffer[RelationalCollectionNames::recordIdVariableInCollectionDataTable()].data<unsigned>() = rowID; - // Insert row or cache it for bulk row insertion. - if( m_rowCacheSize == 0 ) { - const std::string& dataTableName = m_dataTableNameForCollectionFragmentName.find(fragmentName)->second; - m_schema->tableHandle( dataTableName ).dataEditor().insertRow( dataTableRowBuffer ); - } else { - m_bulkRowOperationForCollectionFragmentName[ fragmentName ]->processNextIteration(); - } - } - -} - - -int -pool::RelationalCollection::RelationalCollectionDataEditor:: -updateRows( coral::AttributeList* attributeSetList, - pool::TokenList* tokenSetList, - const std::string& whereClause, - coral::AttributeList* attributeBindData, - pool::TokenList* tokenBindData ) -{ - // Check that a list of Attribute and/or Token names to be updated was provided as input. - if ( ( ! attributeSetList ) && ( ! tokenSetList ) ) - { - std::string errorMsg = "No list of Attribute and/or Token names and associated new values were provided as input. Nothing to update."; - throw pool::Exception( errorMsg, - "RelationalCollectionDataEditor::updateRows", - "RelationalCollection" ); - } - - // Create a new query object. - RelationalCollectionQuery *query = new RelationalCollectionQuery( - m_session, - m_description, - m_dataTableNameForCollectionFragmentName, - m_linksTableNameForCollectionFragmentName, - m_tableTokenColumnPrefixForCollectionTokenColumnName, - m_tableAttributeColumnNameForCollectionAttributeColumnName, - m_tableAttributeList, - m_mapOfLinkIdForTokenKeyMaps, - m_mapOfTokenKeyForLinkIdMaps ); - - // Add Tokens to update to query output list. - if (tokenSetList) { - for( pool::TokenList::const_iterator iToken = tokenSetList->begin(); iToken != tokenSetList->end(); ++iToken ) - { - query->addToOutputList( iToken.tokenName() ); - } - } - - // Set query condition. - query->setCondition( whereClause, attributeBindData, tokenBindData ); - - // Execute query and get cursor over rows that pass query. Primary key added to output list by default. - RelationalCollectionCursor& cursor = *dynamic_cast<RelationalCollectionCursor*>(&query->execute()); - - long rowCounter = 0; - while( ! cursor.next() ) { - // Get primary key for this row and use it as where clause data. - m_whereDataForPrimaryKeyInDataTable->begin()->data<unsigned>() = cursor.primaryKey(); - - // Make requested updates to Attribute columns for this row. - if (attributeSetList) { - for ( coral::AttributeList::const_iterator iAttribute = attributeSetList->begin(); iAttribute != - attributeSetList->end(); ++iAttribute ) - { - // Get names of Attribute column and associated data table. - std::string collectionColumnName = iAttribute->specification().name(); - std::string tableColumnName = - ( m_tableAttributeColumnNameForCollectionAttributeColumnName.find( collectionColumnName ) )->second; - std::string fragmentName = m_description.collectionFragmentName( collectionColumnName ); - std::string dataTableName = ( m_dataTableNameForCollectionFragmentName.find( fragmentName ) )->second; - - // Define set clause. - std::ostringstream setClauseStream; - //setClauseStream << tableColumnName << " = " << **iAttribute; - // This is my interpretation of what should happen, check?? FIXME - setClauseStream << tableColumnName << " = "; - bool valueOnly(true); - iAttribute->toOutputStream( setClauseStream, valueOnly ); - - // Update row. - m_schema->tableHandle( dataTableName ).dataEditor().updateRows( - setClauseStream.str(), - m_whereClauseForPrimaryKeyInDataTable, - *m_whereDataForPrimaryKeyInDataTable ); - } - } - - // Make requested updates to Token columns for this row. - if (tokenSetList) { - for( pool::TokenList::const_iterator iToken = tokenSetList->begin(); iToken != tokenSetList->end(); ++iToken ) - { - // Get names of Token OID columns and associated data and links tables. - std::string collectionColumnName = iToken.tokenName(); - std::string tableColumnPrefix = m_tableTokenColumnPrefixForCollectionTokenColumnName.find( collectionColumnName )->second; - std::string oid1ColumnName = tableColumnPrefix + RelationalCollectionNames::oid_1_variableInCollectionDataTable(); - std::string oid2ColumnName = tableColumnPrefix + RelationalCollectionNames::oid_2_variableInCollectionDataTable(); - std::string fragmentName = m_description.collectionFragmentName( collectionColumnName ); - std::string dataTableName = m_dataTableNameForCollectionFragmentName.find( fragmentName )->second; - std::string linksTableName = m_linksTableNameForCollectionFragmentName.find( fragmentName )->second; - - // Get mappings of link ID's to Token keys for this collection fragment. - std::map< std::string, unsigned >* linkIdForTokenKey = - ( m_mapOfLinkIdForTokenKeyMaps.find( fragmentName ) )->second; - std::map< unsigned, std::string >* tokenKeyForLinkId = - ( m_mapOfTokenKeyForLinkIdMaps.find( fragmentName ) )->second; - - // Look for Token key in map and add new entry to links table if it does not exist. - unsigned newOID1ColumnValue = 0; - unsigned newOID2ColumnValue = 0; - std::string tokenKey = iToken->key(); - if ( linkIdForTokenKey->find( tokenKey ) == linkIdForTokenKey->end() ) - { - // Create new link ID. - unsigned linkId = 0; - while( tokenKeyForLinkId->find(linkId) != tokenKeyForLinkId->end() ) { - linkId++; - } - - // Store link ID in maps. - linkIdForTokenKey->insert( std::make_pair( tokenKey, linkId ) ); - tokenKeyForLinkId->insert( std::make_pair( linkId, tokenKey ) ); - - // Get links table column names. - std::string linkIdColumnName = linksTableName + "." + - RelationalCollectionNames::linkIdVariableInCollectionLinksTable(); - std::string dbIdColumnName = linksTableName + "." + - RelationalCollectionNames::databaseIdVariableInCollectionLinksTable(); - std::string contIdColumnName = linksTableName + "." + - RelationalCollectionNames::containerIdVariableInCollectionLinksTable(); - std::string classIdColumnName = linksTableName + "." + - RelationalCollectionNames::classIdVariableInCollectionLinksTable(); - std::string technologyIdColumnName = linksTableName + "." + - RelationalCollectionNames::technologyIdVariableInCollectionLinksTable(); - - // Store new token key information in links table row buffer. - Token token; - token.fromString( tokenKey ); - m_linksTableRowBuffer[linkIdColumnName].data<unsigned>() = linkId; - m_linksTableRowBuffer[dbIdColumnName].data<std::string>() = token.dbID().toString(); - m_linksTableRowBuffer[contIdColumnName].data<std::string>() = token.contID(); - m_linksTableRowBuffer[classIdColumnName].data<std::string>() = token.classID().toString(); - m_linksTableRowBuffer[technologyIdColumnName].data<unsigned>() = token.technology(); - - // Insert new row into links table. - m_schema->tableHandle( linksTableName ).dataEditor().insertRow( m_linksTableRowBuffer ); - - // Set OID_1 of Token to new link ID. - newOID1ColumnValue = linkId; - } - else { - // Set OID_1 of Token to existing link ID. - newOID1ColumnValue = ( linkIdForTokenKey->find( tokenKey ) )->second; - } - - // Get OID_2 of Token. - newOID2ColumnValue = iToken->oid().second; - - // Define set clause. - std::ostringstream setClauseStream; - setClauseStream << oid1ColumnName << " = " << newOID1ColumnValue << " , " - << oid2ColumnName << " = " << newOID2ColumnValue; - - // Update row. - m_schema->tableHandle( dataTableName ).dataEditor().updateRows( setClauseStream.str(), - m_whereClauseForPrimaryKeyInDataTable, - *m_whereDataForPrimaryKeyInDataTable ); - - // Get old OID_1 column value. - // int oldOID1ColumnValue = cursor.currentRow().getToken( collectionColumnName ).oid()->first; - // another guess, FIXME?? - unsigned oldOID1ColumnValue = cursor.currentRow().tokenList()[collectionColumnName].oid().first; - - // Look for other Tokens with old OID_1 value in data table. - if ( newOID1ColumnValue != oldOID1ColumnValue ) - { - bool oldOID1ColumnValueFound = false; - //for ( int i = 0; i < m_description.numberOfTokens( i, fragmentName ); i++ ) - // another guess, FIXME?? - for( int i = 0; i < m_description.numberOfTokenColumns(fragmentName); i++ ) - { - std::string tokenName = m_description.tokenColumn( i, fragmentName ).name(); - coral::IQuery* oid1Query = m_schema->tableHandle( dataTableName ).newQuery(); - coral::AttributeList* whereDataForOID1InDataTable = - ( m_mapOfWhereDataForOID1InDataTable.find( tokenName ) )->second; - // FIXME?? assume that the attribute list has only 1 attribute - whereDataForOID1InDataTable->begin()->data<unsigned>() = oldOID1ColumnValue; - oid1Query->setCondition( ( m_mapOfWhereClausesForOID1InDataTable.find( tokenName ) )->second, - *whereDataForOID1InDataTable ); - oid1Query->setRowCacheSize( 1000 ); - coral::ICursor& oid1Cursor = oid1Query->execute(); - if ( oid1Cursor.next() ) - { - oldOID1ColumnValueFound = true; - delete oid1Query; - break; - } - - delete oid1Query; - } - - // Delete row for this link ID if it is no longer needed in the links table and update private maps. - if( ! oldOID1ColumnValueFound ) { - m_whereDataForLinkIdInLinksTable->begin()->data<unsigned>() = oldOID1ColumnValue; - m_schema->tableHandle( linksTableName ).dataEditor().deleteRows( m_whereClauseForLinkIdInLinksTable, - *m_whereDataForLinkIdInLinksTable ); - linkIdForTokenKey->erase( tokenKey ); - tokenKeyForLinkId->erase( oldOID1ColumnValue ); - } - } - } - } - - // Increment counter of number of rows updated. - rowCounter++; - } - - // Cleanup. - delete query; - - return rowCounter; -} - - -int -pool::RelationalCollection::RelationalCollectionDataEditor:: -deleteRows( const std::string& whereClause, coral::AttributeList* attributeBindData, pool::TokenList* tokenBindData, bool updateRecordsCounter ) -{ - // Check that a condition for deletion has been provided. - if( whereClause.empty() ) { - std::string errorMsg = "Must provide a condition for row deletion. If all rows are to be deleted use method `ICollectionService::drop' to drop collection `" + m_description.name() + "'."; - throw pool::Exception( errorMsg, - "RelationalCollectionDataEditor::deleteRows", - "RelationalCollection" ); - } - - // Create new collection query object, select all Tokens columns and set where clause. - pool::ICollectionQuery* query = new pool::RelationalCollection::RelationalCollectionQuery( - m_session, - m_description, - m_dataTableNameForCollectionFragmentName, - m_linksTableNameForCollectionFragmentName, - m_tableTokenColumnPrefixForCollectionTokenColumnName, - m_tableAttributeColumnNameForCollectionAttributeColumnName, - m_tableAttributeList, - m_mapOfLinkIdForTokenKeyMaps, - m_mapOfTokenKeyForLinkIdMaps ); - query->selectAllTokens(); - query->setRowCacheSize( 1000 ); - query->setCondition( whereClause, attributeBindData, tokenBindData ); - - // Execute query and get cursor over rows that pass query. Primary key added to output list by default. - RelationalCollectionCursor& cursor = *dynamic_cast<RelationalCollectionCursor*>(&query->execute()); - - long rowCounter = 0; - while( ! cursor.next() ) - { - // Get primary key for this row and add it to where clause data. - m_whereDataForPrimaryKeyInDataTable->begin()->data<unsigned>() = cursor.primaryKey(); - - // Loop over all collection fragments. - for ( std::map< std::string, std::string >::const_iterator iName = m_dataTableNameForCollectionFragmentName.begin(); - iName != m_dataTableNameForCollectionFragmentName.end(); ++iName ) - { - // Get names of collection fragment, data table and links table. - std::string fragmentName = iName->first; - std::string dataTableName = iName->second; - std::string linksTableName = ( m_linksTableNameForCollectionFragmentName.find( fragmentName ) )->second; - - // Delete row in data table of collection fragment that contains this primary key. - m_schema->tableHandle( dataTableName ).dataEditor().deleteRows( m_whereClauseForPrimaryKeyInDataTable, - *m_whereDataForPrimaryKeyInDataTable ); - - if( updateRecordsCounter ) { - // Set where data for this collection fragment in collection headers table. - m_whereDataForCollectionNameInHeadersTable->begin()->data<std::string>() = fragmentName; - - /* - // Decrement number of records written into collection fragment in collection headers table. - std::string setClause = pool::RelationalCollection::RelationalCollectionNames::writtenRecordsVariableInCollectionHeadersTable() + " = " + pool::RelationalCollection::RelationalCollectionNames::writtenRecordsVariableInCollectionHeadersTable() + " - 1"; - nominalSchema.tableHandle( pool::RelationalCollection::RelationalCollectionNames::nameOfCollectionHeadersTable() ).dataEditor().updateRows( - setClause, - m_whereClauseForCollectionNameInHeadersTable, - *m_whereDataForCollectionNameInHeadersTable ); - */ - // Increment number of records deleted from collection fragment in collection headers table. - std::string setClause2 = RelationalCollectionNames::deletedRecordsVariableInCollectionHeadersTable() + " = " + RelationalCollectionNames::deletedRecordsVariableInCollectionHeadersTable() + " + 1"; - m_schema->tableHandle( RelationalCollectionNames::nameOfCollectionHeadersTable() ).dataEditor().updateRows( - setClause2, - m_whereClauseForCollectionNameInHeadersTable, - *m_whereDataForCollectionNameInHeadersTable ); - } - - // Get link Id to Token key maps for possible updates. - std::map< std::string, unsigned >* linkIdForTokenKey = - ( m_mapOfLinkIdForTokenKeyMaps.find( fragmentName ) )->second; - std::map< unsigned, std::string >* tokenKeyForLinkId = - ( m_mapOfTokenKeyForLinkIdMaps.find( fragmentName ) )->second; - - // Get values of all Tokens in deleted row and check if corresponding rows in links table are still needed. - for ( pool::TokenList::const_iterator iToken = cursor.currentRow().tokenList().begin(); iToken != - cursor.currentRow().tokenList().end(); ++iToken ) - { - // Get OID_1 column name. - std::string collectionColumnName = iToken.tokenName(); - std::string tableColumnPrefix = - ( m_tableTokenColumnPrefixForCollectionTokenColumnName.find( collectionColumnName ) )->second; - std::string oid1ColumnName = tableColumnPrefix + - RelationalCollectionNames::oid_1_variableInCollectionDataTable(); - - // Get OID_1 column value. - unsigned oid1ColumnValue = iToken->oid().first; - - // Look for OID_1 value in data table. - bool oid1ColumnFound = false; - // FIXME - changed here - for( int i = 0; i < m_description.numberOfTokenColumns( fragmentName ); i++ ) - { - // Get collection column name. - std::string collectionColumnName = m_description.tokenColumn( i, fragmentName ).name(); - - // Get OID_1 column name. - std::string prefix = ( m_tableTokenColumnPrefixForCollectionTokenColumnName.find( collectionColumnName ) )->second; - std::string oid1Name = prefix + RelationalCollectionNames::oid_1_variableInCollectionDataTable(); - - // Look for other Tokens in data table with this OID_1 column value. - coral::IQuery* oid1Query = m_schema->tableHandle( dataTableName ).newQuery(); - coral::AttributeList* whereDataForOID1InDataTable = ( - m_mapOfWhereDataForOID1InDataTable.find( collectionColumnName ) )->second; - whereDataForOID1InDataTable->begin()->data<unsigned>() = oid1ColumnValue; - oid1Query->setCondition( ( m_mapOfWhereClausesForOID1InDataTable.find( collectionColumnName ) )->second, - *whereDataForOID1InDataTable ); - oid1Query->setRowCacheSize( 1000 ); - coral::ICursor& oid1Cursor = oid1Query->execute(); - if ( oid1Cursor.next() ) { - oid1ColumnFound = true; - delete oid1Query; - break; - } - - // Cleanup. - delete oid1Query; - } - - // If this OID_1 (i.e. link ID) is no longer used delete row from links table and update private maps. - if( ! oid1ColumnFound ) { - m_whereDataForLinkIdInLinksTable->begin()->data<unsigned>() = oid1ColumnValue; - m_schema->tableHandle( linksTableName ).dataEditor().deleteRows( m_whereClauseForLinkIdInLinksTable, *m_whereDataForLinkIdInLinksTable ); - std::string tokenKey = iToken->key(); - linkIdForTokenKey->erase( tokenKey ); - tokenKeyForLinkId->erase( oid1ColumnValue ); - } - } - } - -// Increment counter of number of rows deleted. - rowCounter++; - } - -// Cleanup. - delete query; - - return rowCounter; -} - - diff --git a/Database/APR/RelationalCollection/src/RelationalCollectionDataEditor.h b/Database/APR/RelationalCollection/src/RelationalCollectionDataEditor.h deleted file mode 100755 index 5704df0d0f02ab54b4c2a4ad4ef562248e1b6d9f..0000000000000000000000000000000000000000 --- a/Database/APR/RelationalCollection/src/RelationalCollectionDataEditor.h +++ /dev/null @@ -1,248 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#ifndef RELATIONALCOLLECTION_RELATIONALCOLLECTIONDATAEDITOR_H -#define RELATIONALCOLLECTION_RELATIONALCOLLECTIONDATAEDITOR_H - -#include "CollectionBase/ICollectionDataEditor.h" - -#include "RelationalCollectionFragmentData.h" - - -namespace coral { - class ISessionProxy; - class IBulkOperation; - class ISchema; -} - -namespace pool { - - class ICollectionDescription; - - namespace RelationalCollection { - - /** - * @class RelationalCollectionDataEditor RelationalCollectionDataEditor.h src/RelationalCollectionDataEditor.h - * - * Implementation of the ICollectionDataEditor interface used to add, update or delete data in a collection. - */ - class RelationalCollectionDataEditor : virtual public pool::ICollectionDataEditor - { - - friend class RelationalCollection; - public: - /** - * Constructor. - - * @param session Reference to current database access session. - * @param description Specification of collection properties. - * @param dataTableNameForCollectionFragmentName Map of data table names using names of corresponding collection fragment names as keys. - * @param linksTableNameForCollectionFragmentName Map of links table names using names of corresponding collection fragment names as keys. - * @param tableTokenColumnPrefixForCollectionTokenColumnName Map of table column prefixes for Tokens using names of corresponding collection columns as keys. - * @param tableAttributeColumnNameForCollectionAttributeColumnName Map of table column names for Attributes using names of corresponding collection columns as keys. - * @param tableAttributeList List of all Attributes defined by collection but using table column names. - * @param collectionRowBuffer Collection row buffer containing all Tokens and Attributes defined by collection. - * @param dataTableRowBufferForCollectionFragmentName Map of data table row buffers using names of corresponding collection fragments as keys. - * @param linksTableRowBuffer Row buffer using schema of collection links tables. - * @param mapOfLinkIdForTokenKeyMaps Map of maps of link table ID's that use corresponding Token prefixes as keys, using collection fragment names as keys. - * @param mapOfTokenKeyForLinkIdMaps Map of maps of Token prefixes that use corresponding link table ID's as keys, using collection fragment names as keys. - * @param mapOfWhereClausesForOID1InDataTable Map of where clauses for finding Token OID_1 values in data tables, using Token names as keys. - * @param mapOfWhereDataForOID1InDataTable Map of where data for finding Token OID_1 values in data tables, using Token names as keys. - */ - RelationalCollectionDataEditor( - coral::ISessionProxy& session, - const pool::ICollectionDescription& description, - const std::map< std::string, std::string >& dataTableNameForCollectionFragmentName, - const std::map< std::string, std::string >& linksTableNameForCollectionFragmentName, - FragmentDataMap& fragmentDataMap, - const std::map< std::string, std::string >& tableTokenColumnPrefixForCollectionTokenColumnName, - const std::map< std::string, std::string >& tableAttributeColumnNameForCollectionAttributeColumnName, - const coral::AttributeList& tableAttributeList, - CollectionRowBuffer& collectionRowBuffer, - std::map< std::string, coral::AttributeList* >& dataTableRowBufferForCollectionFragmentName, - coral::AttributeList& linksTableRowBuffer, - std::map< std::string, std::map< std::string, unsigned >* >& mapOfLinkIdForTokenKeyMaps, - std::map< std::string, std::map< unsigned, std::string >* >& mapOfTokenKeyForLinkIdMaps, - const std::map< std::string, std::string >& mapOfWhereClausesForOID1InDataTable, - const std::map< std::string, coral::AttributeList* >& mapOfWhereDataForOID1InDataTable ); - - /** - * Destructor. - */ - ~RelationalCollectionDataEditor(); - - RelationalCollectionDataEditor (const RelationalCollectionDataEditor&) = delete; - RelationalCollectionDataEditor& operator= (const RelationalCollectionDataEditor&) = delete; - - /** - * Sets the number of rows to cache before insertion into the collection. If the input - * argument is 0 (the default) bulk row insertion will not be applied. - * - * @param rowCacheSize Number of rows to cache before insertion into collection. - */ - virtual void setRowCacheSize( int rowCacheSize = 0 ); - - /// Allocate "step" row primary keys every time more is needed - void setRowIDAllocationStep( int step ); - - /** - * Returns a reference to a collection row buffer for adding rows of data to the collection. - * If data for one or more columns will not be provided use the method `emptyRowBuffer' instead. - */ - virtual CollectionRowBuffer& rowBuffer(); - - /** - * Returns a reference to an empty collection row buffer for adding rows of data to the collection. - * If data will be provided for all columns use the method `rowBuffer' instead since buffers do - * not need to be cleared in this case. - */ - virtual CollectionRowBuffer& emptyRowBuffer(); - - /** - * Clears all row buffers. Should be applied before inserting rows for which some columns are - * expected to have null values. - */ - virtual void clearRowBuffers(); - - /** - * Adds a new row of data to the collection. An option is provided to turn off the - * written records counter to improve performance. - * - * @param inputRowBuffer Buffer containing data for row to be added. - * @param updateRecordsCounter Flag indicating whether to increment written records counter. - */ - virtual void insertRow( const pool::CollectionRowBuffer& inputRowBuffer, bool updateRecordsCounter = true ); - - /** - * Updates the rows of the collection that satisfy a query. Returns the number of rows updated. - * Throws an exception if both the Attribute and Token set lists provided as input are empty. - * - * @param tokenSetList List of Tokens to set with associated values. - * @param attributeSetList List of Attributes to set with associated values. - * @param whereClause Predicates of query. - * @param attributeBindData Attribute bind data for where clause. - * @param tokenBindData Token bind data for where clause. - */ - virtual int updateRows( coral::AttributeList* attributeSetList = 0, - TokenList* tokenSetList = 0, - const std::string& whereClause = "", - coral::AttributeList* attributeBindData = 0, - pool::TokenList* tokenBindData = 0 ); - - /** - * Deletes the rows of the collection that satisfy a query. Returns the number of rows deleted. - * Throws an exception if no where clause is provided as input. An option is provided to turn - * off the written and deleted records counters if the written records counter was turned off - * during record insertion to improve performance. - * - * @param whereClause Predicates of query. - * @param attributeBindData Attribute bind data for where clause. - * @param tokenBindData Token bind data for where clause. - * @param updateRecordsCounter Flag indicating whether to decrement written records counter and increment deleted records counter. - */ - virtual int deleteRows( const std::string& whereClause, - coral::AttributeList* attributeBindData = 0, - pool::TokenList* tokenBindData = 0, - bool updateRecordsCounter = true ); - - protected: - /// Create Coral bulk insert structures - virtual void createRowCache(); - - /// Flush all cached rows in case of bulk operations - virtual void flushCachedRows(); - - /// Cleanup Coral structures used for bulk operations - virtual void deleteRowCache(); - - /// Generate unique rowID to be used as PK in data and link tables - virtual int getUniqueRowID(); - - private: - /// If greater than 0, do bulk inserts grouping m_rowCacheSize rows - int m_rowCacheSize; - - /// Allocate m_rowIDAllocationStep primary keys every time - int m_rowIDAllocationStep; - - /// Reference to the current database access session. - coral::ISessionProxy& m_session; - - /// Current database schema - coral::ISchema* m_schema; - - /// Specification of collection properties. - const ICollectionDescription& m_description; - - /// Map of data table names using names of corresponding collection fragment names as keys. - const std::map< std::string, std::string >& m_dataTableNameForCollectionFragmentName; - - /// Map of links table names using names of corresponding collection fragment names as keys. - const std::map< std::string, std::string >& m_linksTableNameForCollectionFragmentName; - - /// Information related to fragments, map keyed by fragment name - FragmentDataMap& m_fragmentDataMap; - - /// Map of table column prefixes for Tokens using names of corresponding collection columns as keys. - const std::map< std::string, std::string >& m_tableTokenColumnPrefixForCollectionTokenColumnName; - - /// Map of table column names for Attributes using names of corresponding collection columns as keys. - const std::map< std::string, std::string >& m_tableAttributeColumnNameForCollectionAttributeColumnName; - - /// List of all Attributes defined by collection but using table column names. - const coral::AttributeList& m_tableAttributeList; - - /// Collection row buffer containing all Tokens and Attributes defined by collection. - CollectionRowBuffer& m_collectionRowBuffer; - - /// Map of data table row buffers using names of corresponding collection fragments as keys. - std::map< std::string, coral::AttributeList* >& m_dataTableRowBufferForCollectionFragmentName; - - /// Row buffer using schema of collection links tables. - coral::AttributeList& m_linksTableRowBuffer; - - /// Map of maps of link table ID's that use corresponding Token prefixes as keys, using collection fragment names as keys. - std::map< std::string, std::map< std::string, unsigned >* >& m_mapOfLinkIdForTokenKeyMaps; - - /// Map of maps of Token prefixes that use corresponding link table ID's as keys, using collection fragment names as keys. - std::map< std::string, std::map< unsigned, std::string >* >& m_mapOfTokenKeyForLinkIdMaps; - - /// Map of where clauses for finding Token OID_1 values in data tables, using Token names as keys. - const std::map< std::string, std::string >& m_mapOfWhereClausesForOID1InDataTable; - - /// Map of where data for finding Token OID_1 values in data tables, using Token names as keys. - const std::map< std::string, coral::AttributeList* >& m_mapOfWhereDataForOID1InDataTable; - - /// Where clause for finding collection fragment name in collection headers table. - std::string m_whereClauseForCollectionNameInHeadersTable; - - /// Bind data for collection headers table collection fragment name where clause. - coral::AttributeList* m_whereDataForCollectionNameInHeadersTable; - - /// Where clause for finding primary key in collection data table. - std::string m_whereClauseForPrimaryKeyInDataTable; - - /// Bind data for collection data table primary key where clause. - coral::AttributeList* m_whereDataForPrimaryKeyInDataTable; - - /// Where clause for finding link ID in collection links table. - std::string m_whereClauseForLinkIdInLinksTable; - - /// Bind data for collection links table link ID where clause. - coral::AttributeList* m_whereDataForLinkIdInLinksTable; - - /// Map of bulk row insertion operation objects using names of corresponding collection fragments as keys. - std::map< std::string, coral::IBulkOperation* > m_bulkRowOperationForCollectionFragmentName; - - // ---------------- variables for the rowID allocation session - - /// An secondary session with the same database, to allocate row IDs - coral::ISessionProxy* m_rowIDSession; - - }; - } -} - -#endif - diff --git a/Database/APR/RelationalCollection/src/RelationalCollectionExpressionParser.cpp b/Database/APR/RelationalCollection/src/RelationalCollectionExpressionParser.cpp deleted file mode 100755 index e6bbee27d41d5dcca9553c6830c459264822df19..0000000000000000000000000000000000000000 --- a/Database/APR/RelationalCollection/src/RelationalCollectionExpressionParser.cpp +++ /dev/null @@ -1,453 +0,0 @@ -/* - Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration -*/ - -#include "RelationalCollectionExpressionParser.h" -#include "RelationalCollectionNames.h" - -#include "PersistentDataModel/Token.h" - -#include "CollectionBase/ICollectionDescription.h" -#include "CollectionBase/TokenList.h" - -#include "POOLCore/Exception.h" - -#include "CoralBase/AttributeList.h" -#include "CoralBase/Attribute.h" - -#include "CoralBase/MessageStream.h" - -#include <sstream> -#include <iostream> -using namespace std; - - -// conversion from C++ to relational operators -// small test version -const string operatorMap[][2] = { - { "==", "=" }, - { "&&", " and " }, - { "||", " or " }, - { "", "" } -}; - -// replace C++ operators -// note - this will reduce any length of "====" into "=" -bool replaceOperators( string& str ) -{ - const size_t s = str.length(); - for( int i=0; !operatorMap[i][0].empty(); i++ ) { - const string& patt = operatorMap[i][0]; - const size_t patsize = patt.length(); - if( s >= patsize && str.substr( s - patsize ) == patt ) { - str = str.substr( 0, s - patsize ) + operatorMap[i][1]; - return true; - } - } - return false; -} - - -std::string -pool::RelationalCollection::RelationalCollectionExpressionParser::parse( - const std::string& whereClause, - const pool::ICollectionDescription& description, - const std::map< std::string, std::string >& dataTableNameForCollectionFragmentName, - const std::map< std::string, std::string >& linksTableNameForCollectionFragmentName, - const std::map< std::string, std::string >& tableTokenColumnPrefixForCollectionTokenColumnName, - const std::map< std::string, std::string >& tableAttributeColumnNameForCollectionAttributeColumnName, - const std::map< std::string, std::map< std::string, unsigned >* >& mapOfLinkIdForTokenKeyMaps, - std::vector< std::string >& collectionFragmentNames, - std::vector< std::string >& linksTableNames, - std::vector< std::string >& linkIDToOID1MatchingConditions, - coral::AttributeList* attributeBindData, - pool::TokenList* tokenBindData, - coral::AttributeList* whereClauseBindData ) -{ - std::ostringstream parsingOutput; - - std::vector< std::string > whereClauseFragments; - std::string lastWord = ""; - std::string lastNonWord = ""; - bool withinQuotes = false; - - // Parse where clause into variables, values, key words and symbol sequences and store sequentially in a local vector. - for( std::string::size_type i = 0; i < whereClause.size(); ++i ) { - char c = whereClause[i]; - if( c == '\'' ) { - if( withinQuotes ) { - withinQuotes = false; - } - else { - if( !lastWord.empty() ) { - whereClauseFragments.push_back( lastWord ); - lastWord = ""; - } - withinQuotes = true; - } - lastNonWord += c; - continue; - } - - if( withinQuotes ) { - lastNonWord += c; - continue; - } - - if ( c == ' ' || c == '\t' || c == '\n' || c == '\r' || - c == '`' || c == '~' || c == '!' || c == '@' || c == '%' || - c == '^' || c == '&' || c == '*' || c == '(' || c == ')' || - c == '-' || c == '+' || c == '=' || c == '[' || c == ']' || - c == '{' || c == '}' || c == ';' || c == ':' || c == '"' || - c == '\\' || c == '|' || c == '<' || c == '>' || c == ',' || - c == '.' || c == '?' || c == '/' ) - { - if( !lastWord.empty() ) { - whereClauseFragments.push_back( lastWord ); - lastWord = ""; - } - - lastNonWord += c; - replaceOperators( lastNonWord ); - } - else { - if( lastNonWord.size() ) { - if( lastNonWord.size() > 2 && lastNonWord.find( " :" ) == ( lastNonWord.size() - 2 ) ) { - lastWord = ":"; - whereClauseFragments.push_back( lastNonWord.substr(0, lastNonWord.size() - 1 ) ); - } - else { - whereClauseFragments.push_back( lastNonWord ); - } - lastNonWord = ""; - } - - lastWord += c; - } - } - - // Add whatever is left over. - if( !lastWord.empty() ) { - whereClauseFragments.push_back( lastWord ); - } - else if( !lastNonWord.empty() ) { - whereClauseFragments.push_back( lastNonWord ); - } - - // Create new vector of where clause fragments that use table column names instead of collection column names. - std::vector< std::string > newWhereClauseFragments; - unsigned pos = 0; - for( std::vector< std::string >::const_iterator iWord = whereClauseFragments.begin(); - iWord != whereClauseFragments.end(); ++iWord, ++pos ) - { - // cout << "Parsing: cond: " << *iWord << endl; - bool isAttribute(false), isToken(false); - // Look for where clause fragment in list of Attribute names. - std::map< std::string, std::string >::const_iterator it = - tableAttributeColumnNameForCollectionAttributeColumnName.find( *iWord ); - if( it != tableAttributeColumnNameForCollectionAttributeColumnName.end() ) { - isAttribute = true; - } else { - // Look for where clause fragment in list of Token names. - it = tableTokenColumnPrefixForCollectionTokenColumnName.find( *iWord ); - if( it != tableTokenColumnPrefixForCollectionTokenColumnName.end() ) { - isToken = true; - } - } - // Get name of collection fragment that contains Attribute and add to output vector. - std::string fragmentName; - std::string columnName; - if( isAttribute || isToken ) { - fragmentName = description.collectionFragmentName( *iWord ); - columnName = it->second; - for (const std::string& name : collectionFragmentNames ) - { - if( name == fragmentName ) { - // cppcheck-suppress invalidContainerLoop; ok: we break after this - collectionFragmentNames.push_back( fragmentName ); - break; - } - } - } - - if( isAttribute ) { - newWhereClauseFragments.push_back( columnName ); - } - else if( isToken ) { - // Get names of data and links tables that contain columns for Token. - std::string dataTableName = ( dataTableNameForCollectionFragmentName.find( fragmentName ) )->second; - std::string linksTableName = ( linksTableNameForCollectionFragmentName.find( fragmentName ) )->second; - - // Find names of columns for Token in data table. - std::string tokenColumnPrefix = columnName; - std::string oid1ColumnName = tokenColumnPrefix + RelationalCollectionNames::oid_1_variableInCollectionDataTable(); - std::string oid2ColumnName = tokenColumnPrefix + RelationalCollectionNames::oid_2_variableInCollectionDataTable(); - - // Find the next where clause fragment. - std::string nextWord; - if( whereClauseFragments.size() > pos+1 ) { - nextWord = whereClauseFragments[pos+1]; - } - - // Check if where clause fragment is part of a Token column condition. - if( !nextWord.empty() && nextWord[0] == '.' ) { - // Is Token column condition. Increment iterator and position and get Token column name. - ++iWord; ++pos; - - // Find name of Token column used for condition. - std::string columnName; - if( whereClauseFragments.size() > pos+1 ) { - // Column name found. Increment iterator and position. - columnName = whereClauseFragments[pos+1]; - ++iWord; ++pos; - - bool isOIDColumn = - ( columnName == RelationalCollectionNames::oid_1_variableInCollectionDataTable() || - columnName == RelationalCollectionNames::oid_2_variableInCollectionDataTable() ); - // Check that column name belongs to the data or links table schema for Tokens. - if ( isOIDColumn || - columnName == RelationalCollectionNames::linkIdVariableInCollectionLinksTable() || - columnName == RelationalCollectionNames::databaseIdVariableInCollectionLinksTable() || - columnName == RelationalCollectionNames::classIdVariableInCollectionLinksTable() || - columnName == RelationalCollectionNames::containerIdVariableInCollectionLinksTable() || - columnName == RelationalCollectionNames::classIdVariableInCollectionLinksTable() || - columnName == RelationalCollectionNames::technologyIdVariableInCollectionLinksTable() ) - { - // Add table name and column name for Token column to new where clause fragment list. - newWhereClauseFragments.push_back( isOIDColumn? dataTableName : linksTableName ); - newWhereClauseFragments.push_back( "." ); - newWhereClauseFragments.push_back( columnName ); - - // Add additional query conditions if Token column of condition is in links table. - if( !isOIDColumn ) { - // Add links table name to list of table names to add to query. - if( std::find(linksTableNames.begin(), linksTableNames.end(), linksTableName) - == linksTableNames.end() ) { - linksTableNames.push_back( linksTableName ); - } - // Add condition to match Link ID column of links table with OID_1 column of data table. - std::string linkIdColumnName = linksTableName + "." + RelationalCollectionNames::linkIdVariableInCollectionLinksTable(); - std::string condition = " " + oid1ColumnName + " = " + linkIdColumnName + " "; - bool foundCondition = false; - for( std::vector< std::string >::const_iterator iCondition = linkIDToOID1MatchingConditions.begin(); - iCondition != linkIDToOID1MatchingConditions.end(); ++iCondition ) - { - if ( *iCondition == condition ) { - foundCondition = true; - break; - } - } - if ( ! foundCondition ) { - linkIDToOID1MatchingConditions.push_back( condition ); - } - } - } else { - std::string errorMsg = "Badly formed Token column condition. Name `" + columnName + - "' is an unrecognized Token column name."; - throw pool::Exception( errorMsg, - "RelationalCollectionExpressionParser::parse", - "RelationalCollection" ); - } - } else { - std::string errorMsg = "Badly formed Token column condition. No Token column name specified after string `" + - whereClauseFragments[pos] + "."; - throw pool::Exception( errorMsg, - "RelationalCollectionExpressionParser::parse", - "RelationalCollection" ); - } - } - // Check if where clause fragment is part of a Token condition. - else { - std::string comparator; - std::string valueAsString; - - // Check if next where clause fragment to the right contains a comparison operator. - if ( whereClauseFragments.size() > pos+1 ) { - comparator = whereClauseFragments[pos+1]; - } - if ( ( comparator.find( "=" ) < comparator.find( "(" ) && - comparator.find_first_not_of( " =(" ) == comparator.npos ) || - ( comparator.find( "<" ) < comparator.find( "(" ) && - comparator.find_first_not_of( " <(" ) == comparator.npos ) || - ( comparator.find( ">" ) < comparator.find( "(" ) && - comparator.find_first_not_of( " >(" ) == comparator.npos ) ) - { - // Comparison operator found. Increment iterator and position. - ++iWord; - ++pos; - - // Look for the Token value in the next where clause fragment to the right. - if ( whereClauseFragments.size() > pos+1 ) { - // Token value found. Increment iterator and position. - valueAsString = whereClauseFragments[pos+1]; - ++iWord; - ++pos; - } - else { - std::string errorMsg = "Badly formed Token condition. No value found for Token '" + *iWord + "'."; - throw pool::Exception( errorMsg, - "RelationalCollectionExpressionParser::parse", - "RelationalCollection" ); - } - } - else { - // Check if next where clause fragment to the left contains a Token comparison operator. - if( pos > 0 ) { - comparator = whereClauseFragments[pos-1]; - } - if( ( comparator.find( "=" ) > comparator.find( ")" ) && - comparator.find_first_not_of( " =)" ) == comparator.npos ) || - ( comparator.find( "<" ) > comparator.find( ")" ) && - comparator.find_first_not_of( " <)" ) == comparator.npos ) || - ( comparator.find( ">" ) > comparator.find( ")" ) && - comparator.find_first_not_of( " >)" ) == comparator.npos ) ) - { - // Comparison operator found. Temporarily remove from new where clause fragment vector. - newWhereClauseFragments.pop_back(); - - // Look for Token value. - if( pos > 1 ) { - // Look for the Token value in the next where clause fragment to the left. - valueAsString = whereClauseFragments[pos-2]; - newWhereClauseFragments.pop_back(); - } - else { - std::string errorMsg = "Badly formed Token condition. No value found for Token '" + *iWord + "'."; - throw pool::Exception( errorMsg, - "RelationalCollectionExpressionParser::parse", - "RelationalCollection" ); - } - } - else { - std::string errorMsg = "Badly formed Token condition. No valid comparison operator found for Token '" + *iWord + "'."; - throw pool::Exception( errorMsg, - "RelationalCollectionExpressionParser::parse", - "RelationalCollection" ); - } - } - - // Get Token column values and bind them if necessary. - unsigned oid1ColumnValue = 0; - unsigned oid2ColumnValue = 0; - std::map< std::string, unsigned >* linkIdForTokenKey = - ( mapOfLinkIdForTokenKeyMaps.find( fragmentName ) )->second; - if ( !valueAsString.empty() && valueAsString[0] == ':' ) - { - // Get bind variable for Token. - std::string bindVariable = valueAsString.substr( 1 ); - - // Check if Token bind variable defined in input Token bind data buffer. - bool foundBindVariable = false; - for ( pool::TokenList::const_iterator iToken = tokenBindData->begin(); iToken != tokenBindData->end(); ++iToken ) - { - if ( iToken.tokenName() == bindVariable ) { - foundBindVariable = true; - } - } - if( !foundBindVariable ) { - std::string errorMsg = "Badly formed Token condition. Could not find bind data variable `" + - bindVariable + "' in input Token bind data buffer."; - throw pool::Exception( errorMsg, - "RelationalCollectionExpressionParser::parse", - "RelationalCollection" ); - } - - // Get Token column values from input bind data. - oid1ColumnValue = ( linkIdForTokenKey->find( (*tokenBindData)[ bindVariable ].key() ) )->second; - oid2ColumnValue = static_cast<unsigned>( (*tokenBindData)[ bindVariable ].oid().second ); - - // Add Token column values to where clause bind data buffer. - whereClauseBindData->extend( oid1ColumnName, typeid(unsigned) ); - whereClauseBindData->extend( oid2ColumnName, typeid(unsigned) ); - (*whereClauseBindData)[ oid1ColumnName ].data<unsigned>() = oid1ColumnValue; - (*whereClauseBindData)[ oid2ColumnName ].data<unsigned>() = oid2ColumnValue; - } - else - { - // Get Token column values from where clause fragment. - Token token; - token.fromString( valueAsString ); - oid1ColumnValue = ( linkIdForTokenKey->find( token.key() ) )->second; - oid2ColumnValue = static_cast<unsigned>( token.oid().second ); - } - - // Get string representations of Token column values. - std::string oid1ColumnValueAsString = ""; - std::ostringstream oid1Stream; - oid1Stream << oid1ColumnValue; - oid1ColumnValueAsString = oid1Stream.str(); - std::string oid2ColumnValueAsString = ""; - std::ostringstream oid2Stream; - oid2Stream << oid2ColumnValue; - oid2ColumnValueAsString = oid2Stream.str(); - - // Add Token column condition to new where clause fragment vector. - newWhereClauseFragments.push_back( oid1ColumnName ); - newWhereClauseFragments.push_back( comparator ); - newWhereClauseFragments.push_back( oid1ColumnValueAsString ); - newWhereClauseFragments.push_back( " AND " ); - newWhereClauseFragments.push_back( oid2ColumnName ); - newWhereClauseFragments.push_back( comparator ); - newWhereClauseFragments.push_back( oid2ColumnValueAsString ); - } - } - // Check if where clause fragment is a bind variable. - else if( iWord->find( ":" ) == 0 ) { - // Get bind variable for Attribute. - std::string bindVariable = iWord->substr( 1 ); - - // Look for bind variable in input Attribute bind data buffer - // and add to output Attribute bind data buffer if found. - bool foundBindVariable = false; - for( coral::AttributeList::const_iterator iAttribute = attributeBindData->begin(); - iAttribute != attributeBindData->end(); ++iAttribute ) - { - if ( iAttribute->specification().name() == bindVariable ) - { - foundBindVariable = true; - whereClauseBindData->extend( bindVariable, - (*attributeBindData)[ bindVariable ].specification().type() ); - (*whereClauseBindData)[ bindVariable ] = (*attributeBindData)[ bindVariable ]; - break; - } - } - // If bind variable not found in input Attribute bind data buffer verify that it is in input Token data buffer. - if ( ! foundBindVariable ) { - for( pool::TokenList::const_iterator iToken = tokenBindData->begin(); iToken != tokenBindData->end(); ++iToken ) - { - if( iToken.tokenName() == bindVariable ) { - foundBindVariable = true; - } - } - if ( ! foundBindVariable ) { - std::string errorMsg = "Badly formed bind variable expression. Could not find bind data variable `" + - bindVariable + "' in input Attribute or Token data buffers."; - throw pool::Exception( errorMsg, - "RelationalCollectionExpressionParser::parse", - "RelationalCollection" ); - } - } - - // Add ":" and bind data variable to new where clause fragments vector unchanged. - newWhereClauseFragments.push_back( *iWord ); - } - // Add all other types of where clause fragments to new where clause fragments vector unchanged. - else { - // cout << " Query parse: adding word '" << *iWord << "'" << endl; - newWhereClauseFragments.push_back( *iWord ); - } - } - - // Add all new where clause fragments to the output string sequentially. - for (const std::string& fragment : newWhereClauseFragments ) - { - parsingOutput << fragment; - } - - coral::MessageStream log( "pool::RelationalCollectionExpressionParser::parse()" ); - log << coral::Debug - << "Parsed query: " << parsingOutput.str() << coral::MessageStream::endmsg; - - return parsingOutput.str(); -} - diff --git a/Database/APR/RelationalCollection/src/RelationalCollectionExpressionParser.h b/Database/APR/RelationalCollection/src/RelationalCollectionExpressionParser.h deleted file mode 100755 index 916434756f1dbd7fbd784fd640ccc27eedbea64e..0000000000000000000000000000000000000000 --- a/Database/APR/RelationalCollection/src/RelationalCollectionExpressionParser.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#ifndef RELATIONALCOLLECTION_RELATIONALCOLLECTIONEXPRESSIONPARSER_H -#define RELATIONALCOLLECTION_RELATIONALCOLLECTIONEXPRESSIONPARSER_H - -#include <string> -#include <vector> -#include <map> - - -namespace coral { - class AttributeList; -} - -namespace pool { - - class ICollectionDescription; - class TokenList; - - namespace RelationalCollection { - - /** - * @class RelationalCollectionExpressionParser RelationalCollectionExpressionParser.h src/RelationalCollectionExpressionParser.h - * - * A utility class for parsing a user submitted where clause. - * - */ - - class RelationalCollectionExpressionParser - { - public: - /** - * Parses a user provided where clause by converting Attribute and Token names of a collection - * to their corresponding data table column names. The where clause may also contain conditions - * on the individual columns used to form a Token in the data and links tables. In that case the - * user should provide the column name in the form "<Token name>.<column name>" where "<column name>" - * refers to the actual name of the column in the data or links table of the Token in this case. - * If bind data is provided in an Attribute or Token input data buffer then the same names should - * be used in the where clause but preceded by the ":" symbol. Token column condition bind data should - * be included in the Attribute input data buffer. - * - * @param whereClause Where clause provided by user. - * @param description Specification of collection properties. - * @param dataTableNameForCollectionFragmentName Map of data table names using names of corresponding collection fragment names as keys. - * @param linksTableNameForCollectionFragmentName Map of links table names using names of corresponding collection fragment names as keys. - * @param tableTokenColumnPrefixForCollectionTokenColumnName Map of table column prefixes for Tokens using names of corresponding collection columns as keys. - * @param tableAttributeColumnNameForCollectionAttributeColumnName Map of table column names for Attributes using names of corresponding collection columns as keys. - * @param mapOfLinkIdForTokenKeyMaps Map of maps of link table ID's that use corresponding Token prefixes as keys, using collection fragment names as keys. - * @param collectionFragmentNames Names of collection fragments needed by query. Returned by reference. - * @param linksTableNames Names of links tables needed by query. Returned by reference. - * @param linkIDToOID1MatchingConditions Links table to data table matching conditions needed by query. Returned by reference. - * @param attributeBindData Attribute input bind data. - * @param tokenBindData Token input bind data. - * @param whereClauseBindData Data buffer containing all bind data needed by query. Returned by reference. - */ - static std::string parse( - const std::string& whereClause, - const pool::ICollectionDescription& description, - const std::map< std::string, std::string >& dataTableNameForCollectionFragmentName, - const std::map< std::string, std::string >& linksTableNameForCollectionFragmentName, - const std::map< std::string, std::string >& tableTokenColumnPrefixForCollectionTokenColumnName, - const std::map< std::string, std::string >& tableAttributeColumnNameForCollectionAttributeColumnName, - const std::map< std::string, std::map< std::string, unsigned >* >& mapOfLinkIdForTokenKeyMaps, - std::vector< std::string >& collectionFragmentNames, - std::vector< std::string >& linksTableNames, - std::vector< std::string >& linkIDToOID1MatchingConditions, - coral::AttributeList* attributeBindData, - pool::TokenList* tokenBindData, - coral::AttributeList* whereClauseBindData ); - }; - - } - -} - -#endif diff --git a/Database/APR/RelationalCollection/src/RelationalCollectionFragmentData.h b/Database/APR/RelationalCollection/src/RelationalCollectionFragmentData.h deleted file mode 100644 index dc5c737fcb963bdca22d21133268819a4e590969..0000000000000000000000000000000000000000 --- a/Database/APR/RelationalCollection/src/RelationalCollectionFragmentData.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#ifndef RELATIONALCOLLECTION_RELATIONALCOLLECTIONFRAGMENTDATA_H -#define RELATIONALCOLLECTION_RELATIONALCOLLECTIONFRAGMENTDATA_H - -#include <string> -#include <map> - -namespace pool { - - namespace RelationalCollection { - - class FragmentData - { - public: - FragmentData() : m_currentRowId(0), m_remainingIds(0) {} - - int getCurrentRowId() { return m_currentRowId; } - int getNextRowId(); - bool hasAllocatedIds() { return m_remainingIds > 0; } - - const std::string& getDataTableName() const { return m_dataTableName; } - const std::string& getLinksTableName() const { return m_linksTableName; } - - std::string& dataTableName() { return m_dataTableName; } - std::string& linksTableName() { return m_linksTableName; } - - void setCurrentRowId(int id) { m_currentRowId = id; } - void allocateIDs(int first, int range ) { m_currentRowId = first; m_remainingIds = range; } - - protected: - int m_currentRowId; - int m_remainingIds; - std::string m_dataTableName; - std::string m_linksTableName; - }; - - - - class FragmentDataMap : public std::map< std::string, FragmentData > - { - public: - const FragmentData& fragmentData(const std::string& fragmentName) const { - return this->find( fragmentName )->second; - } - }; - - } -} - -inline -int pool::RelationalCollection::FragmentData::getNextRowId() -{ - if( hasAllocatedIds() ) { - m_remainingIds--; - return m_currentRowId++; - } - - return -1; // replace with exception -} - - -#endif - - diff --git a/Database/APR/RelationalCollection/src/RelationalCollectionMetadata.cpp b/Database/APR/RelationalCollection/src/RelationalCollectionMetadata.cpp deleted file mode 100644 index 488bdbd32a166b5477f76862a68b0a575e02facd..0000000000000000000000000000000000000000 --- a/Database/APR/RelationalCollection/src/RelationalCollectionMetadata.cpp +++ /dev/null @@ -1,352 +0,0 @@ -/* - Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration -*/ - -#include "RelationalCollectionMetadata.h" -#include "RelationalCollectionNames.h" -#include "RelationalCollectionBindVariables.h" - -#include "POOLCore/Exception.h" - -#include "RelationalAccess/ISessionProxy.h" -#include "RelationalAccess/ISessionProperties.h" -#include "RelationalAccess/ISchema.h" -#include "RelationalAccess/IQuery.h" -#include "RelationalAccess/ICursor.h" -#include "RelationalAccess/ITable.h" -#include "RelationalAccess/ITableDataEditor.h" -#include "RelationalAccess/ITableSchemaEditor.h" -#include "RelationalAccess/ITablePrivilegeManager.h" -#include "RelationalAccess/TableDescription.h" -#include "CoralBase/AttributeSpecification.h" -#include "CoralBase/Attribute.h" - -#include "CoralBase/MessageStream.h" - -#include <memory> -#include <iostream> -using namespace std; - - -namespace pool { - namespace RelationalCollection { - - RelationalCollectionMetadata::RelationalCollectionMetadata() - : m_mode(ICollection::READ), m_isOracle(true), m_metadataTable(0) - { - } - - - RelationalCollectionMetadata::~RelationalCollectionMetadata() - { } - - void - RelationalCollectionMetadata::initialize( const std::string& collectionName, - coral::ISessionProxy& session, - pool::ICollection::OpenMode mode ) - { - m_mode = mode; - m_collectionName = collectionName; - m_isOracle = ( session.properties().flavorName() == "Oracle" ); - coral::ISchema& nominalSchema = session.nominalSchema(); - bool metadataTableExists = nominalSchema.existsTable( RelationalCollectionNames::metadataTable() ); - - if( !metadataTableExists ) { - coral::MessageStream log( "pool::RelationalCollectionMetadata::init()" ); - log << coral::Warning - << " ****** no metadata table found" << coral::MessageStream::endmsg; - - if( mode == ICollection::READ ) { - m_metadataTable = 0; - return; - } else { - // create the metadata table - coral::TableDescription description( RelationalCollectionNames::collectionTypeName() ); - description.setName( RelationalCollectionNames::metadataTable() ); - description.insertColumn( RelationalCollectionNames::collectionNameColumn(), - coral::AttributeSpecification::typeNameForType<std::string>(), - 2000, false); - description.insertColumn( RelationalCollectionNames::metadataKeyColumn(), - coral::AttributeSpecification::typeNameForType<std::string>() ); - description.insertColumn( RelationalCollectionNames::metadataValueColumn(), - coral::AttributeSpecification::typeNameForType<std::string>() ); - - std::vector<std::string> primaryKeyColumns; - primaryKeyColumns.push_back( RelationalCollectionNames::collectionNameColumn() ); - primaryKeyColumns.push_back( RelationalCollectionNames::metadataKeyColumn() ); - description.setPrimaryKey( primaryKeyColumns ); - - nominalSchema.createTable( description ); //.privilegeManager().grantToPublic( coral::ITablePrivilegeManager::Select ); - - log << coral::Info - << " ****** created the metadata table" << coral::MessageStream::endmsg; - } - } - - m_metadataTable = &nominalSchema.tableHandle( RelationalCollectionNames::metadataTable() ); - - // Define bind variables value holder for querying metadata table - m_whereDataForMetadata.extend<std::string>( RelationalCollectionNames::collectionNameColumn() ); - m_whereDataForMetadata[0].data<std::string>() = m_collectionName; - - m_whereDataForMetadataKey.extend<std::string>( RelationalCollectionNames::collectionNameColumn() ); - m_whereDataForMetadataKey[0].data<std::string>() = m_collectionName; - m_whereDataForMetadataKey.extend<std::string>( RelationalCollectionNames::metadataKeyColumn() ); - } - - - void - RelationalCollectionMetadata::reinitialize( coral::ISessionProxy* session ) - { - if( m_metadataTable ) - m_metadataTable = & session->nominalSchema().tableHandle( RelationalCollectionNames::metadataTable() ); - } - - - unsigned long long - RelationalCollectionMetadata::entries() const - { - if( !m_metadataTable ) - return 0; - std::unique_ptr<coral::IQuery> query( m_metadataTable->newQuery() ); - query->setCondition( RelationalCollectionBindVariables::whereClauseForMetadata(), m_whereDataForMetadata ); - query->limitReturnedRows( 1, 0 ); - query->addToOutputList( "count(*)"); - query->defineOutputType( "count(*)", "unsigned long long"); - coral::ICursor& cursor = query->execute(); - if( !cursor.next() ) - return 0; - return cursor.currentRow()[0].data<unsigned long long>(); - } - - - - bool - RelationalCollectionMetadata::existsKey( const std::string& key ) const - { - if( !m_metadataTable ) - return false; - map<string,bool>::iterator ki= m_keyInfo.find( key ); - if( ki != m_keyInfo.end() ) - return ki->second; - std::unique_ptr<coral::IQuery> query( m_metadataTable->newQuery() ); - m_whereDataForMetadataKey[1].data<std::string>() = key; - query->addToOutputList( RelationalCollectionNames::collectionNameColumn() ); - query->setCondition( RelationalCollectionBindVariables::whereClauseForMetadataKey(), m_whereDataForMetadataKey ); - query->limitReturnedRows( 1, 0 ); - coral::ICursor& cursor = query->execute(); - bool exists = cursor.next(); - m_keyInfo[ key ] = exists; - return exists; - } - - - const char* - RelationalCollectionMetadata::getValueForKey( const std::string& key ) const - { - if( !m_metadataTable ) - return 0; - std::unique_ptr<coral::IQuery> query( m_metadataTable->newQuery() ); - m_whereDataForMetadataKey[1].data<std::string>() = key; - query->setCondition( RelationalCollectionBindVariables::whereClauseForMetadataKey(), m_whereDataForMetadataKey ); - query->limitReturnedRows( 1, 0 ); - coral::ICursor& cursor = query->execute(); - bool exists = cursor.next(); - m_keyInfo[ key ] = exists; - if( !exists ) return 0; - // cache the query result, as I am afraid it can go away when the query is deleted - m_lastValue = cursor.currentRow()[2].data<std::string>(); - return m_lastValue.c_str(); - } - - - void - RelationalCollectionMetadata::setValueForKey( const std::string& key, - const std::string& value ) - { - if( m_mode == ICollection::READ ) { - throw pool::Exception( "Metadata update not allowed in Read-only mode", - "RelationalCollectionMetadata::setValueForKey", - "RelationalCollection"); - } - if( key.empty() ) { - throw pool::Exception( "Attempt to set metadata with an empty Key", - "RelationalCollectionMetadata::setValueForKey", - "RelationalCollection"); - } - coral::MessageStream log( "pool::RelationalCollectionMetadata::setValueForKey()" ); - - if( existsKey(key) ) { - //update - std::string setClause = RelationalCollectionNames::metadataValueColumn() + " = '" + value + "'"; - m_whereDataForMetadataKey[1].data<std::string>() = key; - m_metadataTable->dataEditor().updateRows( - setClause, - RelationalCollectionBindVariables::whereClauseForMetadataKey(), - m_whereDataForMetadataKey ); - log << coral::Debug - << " Updated metadata entry: (" << key <<", " << value << ") " << coral::MessageStream::endmsg; - } else { - // instert - coral::AttributeList rowBuffer; - rowBuffer.extend<std::string>( RelationalCollectionNames::collectionNameColumn() ); - rowBuffer.extend<std::string>( RelationalCollectionNames::metadataKeyColumn() ); - rowBuffer.extend<std::string>( RelationalCollectionNames::metadataValueColumn() ); - coral::AttributeList::iterator iAttribute = rowBuffer.begin(); - iAttribute->data< std::string >() = m_collectionName; - ++iAttribute; - iAttribute->data< std::string >() = key; - ++iAttribute; - iAttribute->data< std::string >() = value; - m_metadataTable->dataEditor().insertRow( rowBuffer ); - log << coral::Debug - << " Inserted new metadata entry: (" << key <<", " << value << ") " << coral::MessageStream::endmsg; - } - m_keyInfo[ key ] = true; - } - - - int - RelationalCollectionMetadata::deleteCollectionMetadata() - { - if( m_mode == ICollection::READ ) { - throw pool::Exception( "Metadata deletion not possible in Read-only mode", - "RelationalCollectionMetadata::deleteCollectionMetadata", - "RelationalCollection"); - } - if( !m_metadataTable ) - return 0; - return m_metadataTable->dataEditor().deleteRows( RelationalCollectionBindVariables::whereClauseForMetadata(), m_whereDataForMetadata ); - } - - - - - - // ------- RelationalCollectionMetadataIterator - - RelationalCollectionMetadata::RelationalCollectionMetadataIterator:: - RelationalCollectionMetadataIterator( const RelationalCollectionMetadata* meta, - coral::IQuery *query, - std::map<std::string,bool> *keymap ) - : m_metadata( meta ), - m_query( query ), - m_cursor( 0 ), - m_keyInfo( keymap ), - m_valid( false ) - { - if( query ) { - m_cursor = &query->execute(); - ++*this; - } - } - - - RelationalCollectionMetadata::RelationalCollectionMetadataIterator:: - ~RelationalCollectionMetadataIterator( ) - { - delete m_query; - } - - - bool - RelationalCollectionMetadata::RelationalCollectionMetadataIterator:: - operator==( const ICollectionMetadataIterator& _rhs ) const - { - const RelationalCollectionMetadataIterator* rhs - = dynamic_cast<const RelationalCollectionMetadataIterator*>( &_rhs ); - if( !rhs ) - throw pool::Exception( "Incompatible iterator comparison", - "RelationalCollectionMetadataItorator::operator==", - "RelationalCollection"); - return key() == rhs->key(); - } - - - void - RelationalCollectionMetadata::RelationalCollectionMetadataIterator:: - operator++() - { - if( m_cursor && m_cursor->next() ) { - m_valid = true; - if( m_keyInfo ) (*m_keyInfo)[ key() ] = true; - } else { - m_valid = false; - } - } - - - const std::string& - RelationalCollectionMetadata::RelationalCollectionMetadataIterator:: - key() const - { - static std::string emptyKey; - return ( m_valid? m_cursor->currentRow()["key"].data<std::string>() : emptyKey ); - } - - - const char * - RelationalCollectionMetadata::RelationalCollectionMetadataIterator:: - value() const - { - if( !m_valid ) return 0; - const coral::Attribute &attr = m_cursor->currentRow()["value"]; - const string& value = attr.data<std::string>(); - if( !m_metadata->m_isOracle || value.length() != 4000 ) { - // cppcheck-suppress stlcstr - return value.c_str(); - } - - // most likely a truncated CLOB entry - read the full value - const char * val = m_metadata->getValueForKey( key() ); - if( !val ) { - throw pool::Exception( string("Failed to retrieve the full value for large metadata entry: ") + key(), - "RelationalCollectionMetadataIterator::value()", - "RelationalCollection"); - } - const_cast<coral::Attribute&>(attr).setValue( string(val) ); //cache it - return val; - } - - - - - ICollectionMetadata::const_iterator - RelationalCollectionMetadata::begin() const - { - if( !m_metadataTable ) - return end(); - std::unique_ptr<coral::IQuery> query( m_metadataTable->newQuery() ); - - coral::AttributeList output; - output.extend( "key", "string"); - query->addToOutputList( RelationalCollectionNames::metadataKeyColumn() ); - output.extend( "value", "string"); - if( m_isOracle ) { - // CLOB -> string conversion to enable bulk reads - query->addToOutputList(" TO_CHAR( SUBSTR( " + RelationalCollectionNames::metadataValueColumn() + ", 0, 4000 ) )" ); - } else { - query->addToOutputList( RelationalCollectionNames::metadataValueColumn() ); - } - query->defineOutput( output ); - - query->setRowCacheSize( 5000 ); - query->setCondition( RelationalCollectionBindVariables::whereClauseForMetadata(), - m_whereDataForMetadata ); - return ICollectionMetadata::const_iterator( - std::make_unique<RelationalCollectionMetadataIterator>( this, query.release(), - entries() < 10000? &m_keyInfo : 0 ) ); - } - - - ICollectionMetadata::const_iterator - RelationalCollectionMetadata::end() const - { - return ICollectionMetadata::const_iterator( - std::make_unique<RelationalCollectionMetadataIterator>( nullptr, nullptr, nullptr ) ); - } - - - } // end namespace -} - diff --git a/Database/APR/RelationalCollection/src/RelationalCollectionMetadata.h b/Database/APR/RelationalCollection/src/RelationalCollectionMetadata.h deleted file mode 100644 index 6aa064fa6e8859dbb16d6e7dc40869b347e48572..0000000000000000000000000000000000000000 --- a/Database/APR/RelationalCollection/src/RelationalCollectionMetadata.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration -*/ - -#ifndef RelationalCollectionMetadata_h -#define RelationalCollectionMetadata_h - -#include "CollectionBase/ICollection.h" -#include "CollectionBase/ICollectionMetadata.h" - -#include "CoralBase/AttributeList.h" - -#include <string> -#include <map> - - -namespace coral { - class ISessionProxy; - class IQuery; - class ICursor; - class ITable; -} - - -namespace pool { - namespace RelationalCollection { - - class RelationalCollectionMetadata : public ICollectionMetadata - { - public: - - RelationalCollectionMetadata(); - virtual ~RelationalCollectionMetadata(); - - void initialize( const std::string& collectionName, - coral::ISessionProxy& session, - pool::ICollection::OpenMode mode ); - - /// refresh table pointers after commit - void reinitialize( coral::ISessionProxy* session ); - - // void readKeys() const; - - /// count metadata entries for this collection - unsigned long long entries() const; - - bool existsKey( const std::string& key ) const; - - /// returns a pointer to an internal cache - next call will erase previous value - const char* getValueForKey( const std::string& key ) const; - - void setValueForKey( const std::string& key, - const std::string& val ); - - int deleteCollectionMetadata(); - - - class RelationalCollectionMetadataIterator - : public ICollectionMetadata::ICollectionMetadataIterator - { - public: - friend class RelationalCollectionMetadata; - - RelationalCollectionMetadataIterator( const RelationalCollectionMetadata* meta, - coral::IQuery *query, - std::map<std::string,bool> *keymap ); - virtual ~RelationalCollectionMetadataIterator( ); - - bool operator==( const ICollectionMetadataIterator& _rhs ) const; - bool operator!=( const ICollectionMetadataIterator& rhs ) const { - return !operator==( rhs ); - } - void operator++(); - - const std::string& key() const; - const char * value() const; - - protected: - const RelationalCollectionMetadata* m_metadata; - coral::IQuery* m_query; - coral::ICursor* m_cursor; - std::map<std::string,bool> *m_keyInfo; - bool m_valid; - }; - - - - ICollectionMetadata::const_iterator begin() const; - ICollectionMetadata::const_iterator end() const; - - private: - ICollection::OpenMode m_mode; - - std::string m_collectionName; - /// true if the collection is in Oracle - bool m_isOracle; - - mutable std::map<std::string, bool> m_keyInfo; - - /// Reference to the metadata table (do not delete) - coral::ITable* m_metadataTable; - - mutable coral::AttributeList m_whereDataForMetadata; - mutable coral::AttributeList m_whereDataForMetadataKey; - - /// cache for the last value retrieved by getValue() - mutable std::string m_lastValue; - }; // end RelationalCollectionMetadata - - } // end namespace -} - -#endif - - - - - - diff --git a/Database/APR/RelationalCollection/src/RelationalCollectionNames.cpp b/Database/APR/RelationalCollection/src/RelationalCollectionNames.cpp deleted file mode 100644 index d79d14f6c852c2baa030a2086b382af09a8cc4ce..0000000000000000000000000000000000000000 --- a/Database/APR/RelationalCollection/src/RelationalCollectionNames.cpp +++ /dev/null @@ -1,318 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#include "RelationalCollectionNames.h" -#include <sstream> - -std::string -pool::RelationalCollection::RelationalCollectionNames::collectionTypeName() -{ - return "RelationalCollection"; -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::nameOfCollectionHeadersTable() -{ - return "POOL_COLLECTIONS"; -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::collectionNameVariableInCollectionHeadersTable() -{ - return "COLLECTION_NAME"; -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::dataTableNameVariableInCollectionHeadersTable() -{ - return "DATA_TABLE_NAME"; -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::linksTableNameVariableInCollectionHeadersTable() -{ - return "LINKS_TABLE_NAME"; -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::writtenRecordsVariableInCollectionHeadersTable() -{ - return "RECORDS_WRITTEN"; -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::deletedRecordsVariableInCollectionHeadersTable() -{ - return "RECORDS_DELETED"; -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::childCollectionNameVariableInCollectionHeadersTable() -{ - return "CHILD_COLLECTION_NAME"; -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::foreignKeyNameVariableInCollectionHeadersTable() -{ - return "FOREIGN_KEY_NAME"; -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::nameOfCollectionDescriptionsTable() -{ - return "POOL_COLLECTIONS_DESC"; -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::collectionNameVariableInCollectionDescriptionsTable() -{ - return "COLLECTION_NAME"; -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::collectionVariableNameVariableInCollectionDescriptionsTable() -{ - return "VARIABLE_NAME"; -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::collectionVariableTypeVariableInCollectionDescriptionsTable() -{ - return "VARIABLE_TYPE"; -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::collectionVariableMaxSizeVariableInCollectionDescriptionsTable() -{ - return "VARIABLE_MAXIMUM_SIZE"; -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::collectionVariableSizeIsFixedVariableInCollectionDescriptionsTable() -{ - return "VARIABLE_SIZE_IS_FIXED"; -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::collectionVariablePositionVariableInCollectionDescriptionsTable() -{ - return "VARIABLE_POSITION"; -} - - - -std::string -pool::RelationalCollection::RelationalCollectionNames::collectionVariableAnnotationVariableInCollectionDescriptionsTable() -{ - return "VARIABLE_ANNOTATION"; -} - -std::string -pool::RelationalCollection::RelationalCollectionNames::nameOfCollectionDataTable( int iteration ) -{ - if ( iteration == 0 ) return "POOL_COLLECTION_DATA"; - std::ostringstream os; - os << "POOL_COLLECTION_DATA_" << iteration; - return os.str(); -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::recordIdVariableInCollectionDataTable() -{ - return "ID"; -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::oid_1_variableInCollectionDataTable() -{ - return "OID_1"; -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::oid_2_variableInCollectionDataTable() -{ - return "OID_2"; -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::variableDataVariableInCollectionDataTable( int position ) -{ - std::ostringstream os; - os << "VAR_" << position; - return os.str(); -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::nameOfCollectionLinksTable( int iteration ) -{ - if ( iteration == 0 ) return "POOL_COLLECTION_LINKS"; - std::ostringstream os; - os << "POOL_COLLECTION_LINKS_" << iteration; - return os.str(); -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::linkIdVariableInCollectionLinksTable() -{ - return "LINK_ID"; -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::databaseIdVariableInCollectionLinksTable() -{ - return "DATABASE_ID"; -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::containerIdVariableInCollectionLinksTable() -{ - return "CONTAINER_ID"; -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::classIdVariableInCollectionLinksTable() -{ - return "CLASS_ID"; -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::technologyIdVariableInCollectionLinksTable() -{ - return "TECHNOLOGY_ID"; -} - - - -// The name of the table holding the collection index and unique constraint descriptions. -//MN: added this implementation, guess -std::string -pool::RelationalCollection::RelationalCollectionNames:: -nameOfCollectionIndexDescriptionsTable() -{ - return "POOL_COLL_INDX_DESC"; -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::indexNameVariableInCollectionIndexDescriptionsTable() -{ - return "INDEX_NAME"; -} - -std::string -pool::RelationalCollection::RelationalCollectionNames::uniqueConstraintNameVariableInCollectionIndexDescriptionsTable() -{ - return "UNIQUE_CONSTRAINT_NAME"; -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::collectionVariableNameVariableInCollectionIndexDescriptionsTable() -{ - return "VARIABLE_NAME"; -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::collectionNameVariableInCollectionIndexDescriptionsTable() -{ - return "COLLECTION_NAME"; -} - - - -std::string -pool::RelationalCollection::RelationalCollectionNames::metadataTable() -{ - return "POOL_COLL_METADATA"; -} - - - -std::string -pool::RelationalCollection::RelationalCollectionNames::collectionNameColumn() -{ - return "COLLECTION_NAME"; -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::metadataKeyColumn() -{ - return "MD_KEY"; -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::metadataValueColumn() -{ - return "MD_VALUE"; -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::nameOfCollectionLockTable() -{ - return "POOL_COLL_LOCK"; -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::entryIDVarInCollectionLockTable() -{ - return "ID"; -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::collectionNameVarInCollectionLockTable() -{ - return "COLLECTION"; -} - -std::string -pool::RelationalCollection::RelationalCollectionNames::clientInfoVarInCollectionLockTable() -{ - return "CLIENT_INFO"; -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::lockTypeVarInCollectionLockTable() -{ - return "LOCKTYPE"; -} - - -std::string -pool::RelationalCollection::RelationalCollectionNames::timestampVarInCollectionLockTable() -{ - return "TIMESTAMP"; -} diff --git a/Database/APR/RelationalCollection/src/RelationalCollectionNames.h b/Database/APR/RelationalCollection/src/RelationalCollectionNames.h deleted file mode 100644 index 8678342bd1b4857926d7873f7b59fee0665ca2de..0000000000000000000000000000000000000000 --- a/Database/APR/RelationalCollection/src/RelationalCollectionNames.h +++ /dev/null @@ -1,120 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#ifndef RELATIONALCOLLECTION_RELATIONALCOLLECTIONNAMES_H -#define RELATIONALCOLLECTION_RELATIONALCOLLECTIONNAMES_H - -#include <string> - -namespace pool { - - namespace RelationalCollection { - - /// Utility class holding the string literals used in the RelationalCollection package. - class RelationalCollectionNames { - public: - /// The type name of these collections. - static std::string collectionTypeName(); - - // The collection headers table. - - /// The name of the table holding the collection headers. - static std::string nameOfCollectionHeadersTable(); - /// The variable name holding the collection name in the table holding the collection headers. - static std::string collectionNameVariableInCollectionHeadersTable(); - /// The variable name holding the data table name in the table holding the collection headers. - static std::string dataTableNameVariableInCollectionHeadersTable(); - /// The variable name holding the links table name in the table holding the collection headers. - static std::string linksTableNameVariableInCollectionHeadersTable(); - /// The variable name holding the number of records written in the table holding the collection headers. - static std::string writtenRecordsVariableInCollectionHeadersTable(); - /// The variable name holding the number of records deleted in the table holding the collection headers. - static std::string deletedRecordsVariableInCollectionHeadersTable(); - /// The variable name holding the child collection fragment name in the table holding the collection headers. - static std::string childCollectionNameVariableInCollectionHeadersTable(); - /// The variable name holding the foreign key name in the table holding the collection headers. - static std::string foreignKeyNameVariableInCollectionHeadersTable(); - - // The collection descriptions table. - - /// The name of the table holding the collection descriptions. - static std::string nameOfCollectionDescriptionsTable(); - /// The variable name holding the collection name in the table holding the collection descriptions. - static std::string collectionNameVariableInCollectionDescriptionsTable(); - /// The variable name holding the collection variable name in the table holding the collection descriptions. - static std::string collectionVariableNameVariableInCollectionDescriptionsTable(); - /// The variable name holding the collection variable type in the table holding the collection descriptions. - static std::string collectionVariableTypeVariableInCollectionDescriptionsTable(); - /// The variable name holding the collection variable type's maximum size in the table holding the collection descriptions. - static std::string collectionVariableMaxSizeVariableInCollectionDescriptionsTable(); - /// The variable name holding the collection variable's fixed size flag in the table holding the collection descriptions. - static std::string collectionVariableSizeIsFixedVariableInCollectionDescriptionsTable(); - /// The variable name holding the position of a collection variable in the table holding the collection descriptions. - static std::string collectionVariablePositionVariableInCollectionDescriptionsTable(); - - /// Variable name holding collection attribute annotations in the collection descriptions - static std::string collectionVariableAnnotationVariableInCollectionDescriptionsTable(); - - // The collection data table. - - /// The name of the table holding the collection data. - static std::string nameOfCollectionDataTable( int iteration ); - /// The record id variable name in the table holding the collection data. - static std::string recordIdVariableInCollectionDataTable(); - /// The variable name holding the first part of the OID in the table holding the collection data. - static std::string oid_1_variableInCollectionDataTable(); - /// The variable name holding the second part of the OID in the table holding the collection data. - static std::string oid_2_variableInCollectionDataTable(); - /// The variable name the data of a variable in the table holding the collection data. - static std::string variableDataVariableInCollectionDataTable( int position ); - - // The collection links table. - - /// The name of the table holding the collection links. - static std::string nameOfCollectionLinksTable( int iteration ); - /// The link ID variable in the table holding the collection links. - static std::string linkIdVariableInCollectionLinksTable(); - /// The database ID variable in the table holding the collection links. - static std::string databaseIdVariableInCollectionLinksTable(); - /// The container ID variable in the table holding the collection links. - static std::string containerIdVariableInCollectionLinksTable(); - /// The class ID variable in the table holding the collection links. - static std::string classIdVariableInCollectionLinksTable(); - /// The technology ID variable in the table holding the collection links. - static std::string technologyIdVariableInCollectionLinksTable(); - - // The collection index and unique constraint descriptions table. - - /// The name of the table holding the collection index and unique constraint descriptions. - static std::string nameOfCollectionIndexDescriptionsTable(); - /// The variable name holding the index name in the table holding the collection index descriptions. - static std::string indexNameVariableInCollectionIndexDescriptionsTable(); - /// The variable name holding the collection unique constraint name in the table holding the collection index descriptions. - static std::string uniqueConstraintNameVariableInCollectionIndexDescriptionsTable(); - /// The variable name holding the collection variable name in the table holding the collection index descriptions. - static std::string collectionVariableNameVariableInCollectionIndexDescriptionsTable(); - /// The variable name holding the collection name in the table holding the collection index descriptions. - static std::string collectionNameVariableInCollectionIndexDescriptionsTable(); - - - // metadata table - static std::string metadataTable(); - static std::string collectionNameColumn(); - static std::string metadataKeyColumn(); - static std::string metadataValueColumn(); - - // LOCK table - static std::string nameOfCollectionLockTable(); - static std::string entryIDVarInCollectionLockTable(); - static std::string collectionNameVarInCollectionLockTable(); - static std::string clientInfoVarInCollectionLockTable(); - static std::string lockTypeVarInCollectionLockTable(); - static std::string timestampVarInCollectionLockTable(); - - - }; - } -} - -#endif diff --git a/Database/APR/RelationalCollection/src/RelationalCollectionQuery.cpp b/Database/APR/RelationalCollection/src/RelationalCollectionQuery.cpp deleted file mode 100755 index 083145ac89f4e944c01ce47401d874827a89d485..0000000000000000000000000000000000000000 --- a/Database/APR/RelationalCollection/src/RelationalCollectionQuery.cpp +++ /dev/null @@ -1,415 +0,0 @@ -/* - Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration -*/ - -#include "RelationalCollectionQuery.h" -#include "RelationalCollectionNames.h" -#include "RelationalCollectionExpressionParser.h" -#include "RelationalCollectionCursor.h" - -#include "CollectionBase/ICollectionDescription.h" -#include "CollectionBase/TokenList.h" -#include "CollectionBase/CollectionRowBuffer.h" -#include "CollectionBase/ICollectionCursor.h" -#include "CollectionBase/ICollectionColumn.h" -#include "CollectionBase/ICollectionFragment.h" -#include "CollectionBase/CollectionBaseNames.h" -#include "CollectionBase/boost_tokenizer_headers.h" - -#include "POOLCore/Exception.h" - -#include "CoralBase/Attribute.h" -#include "CoralBase/AttributeList.h" - -#include "RelationalAccess/ISessionProxy.h" -#include "RelationalAccess/IQuery.h" -#include "RelationalAccess/ICursor.h" -#include "RelationalAccess/ISchema.h" - -#include <iostream> -using namespace std; - -pool::RelationalCollection::RelationalCollectionQuery::RelationalCollectionQuery( - coral::ISessionProxy& session, - const pool::ICollectionDescription& description, - const std::map< std::string, std::string >& dataTableNameForCollectionFragmentName, - const std::map< std::string, std::string >& linksTableNameForCollectionFragmentName, - const std::map< std::string, std::string >& tableTokenColumnPrefixForCollectionTokenColumnName, - const std::map< std::string, std::string >& tableAttributeColumnNameForCollectionAttributeColumnName, - const coral::AttributeList& tableAttributeList, - const std::map< std::string, std::map< std::string, unsigned >* >& mapOfLinkIdForTokenKeyMaps, - const std::map< std::string, std::map< unsigned, std::string >* >& mapOfTokenKeyForLinkIdMaps, - bool readPrimaryKey ) - : m_description( description ), - m_dataTableNameForCollectionFragmentName( dataTableNameForCollectionFragmentName ), - m_linksTableNameForCollectionFragmentName( linksTableNameForCollectionFragmentName ), - m_tableTokenColumnPrefixForCollectionTokenColumnName( tableTokenColumnPrefixForCollectionTokenColumnName ), - m_tableAttributeColumnNameForCollectionAttributeColumnName( tableAttributeColumnNameForCollectionAttributeColumnName ), - m_tableAttributeList( tableAttributeList ), - m_mapOfLinkIdForTokenKeyMaps( mapOfLinkIdForTokenKeyMaps ), - m_mapOfTokenKeyForLinkIdMaps( mapOfTokenKeyForLinkIdMaps ), - m_query( 0 ), - m_outputDataBuffer( 0 ), - m_whereClauseBindData( new coral::AttributeList ), - m_outputTokenList( new pool::TokenList ), - m_outputAttributeList( new coral::AttributeList ), - m_cursor( 0 ), - m_session( session ), - m_rowCacheSize( 0 ), - m_readPrimaryKey( readPrimaryKey ) -{ - // by default always include primary Event Ref in the query - m_skipEventRef = false; - // Get name of data table for top level collection fragment. - m_dataTableName = m_dataTableNameForCollectionFragmentName.find( m_description.name() )->second; -} - - -pool::RelationalCollection::RelationalCollectionQuery::~RelationalCollectionQuery() -{ - delete m_query; - delete m_outputDataBuffer; - delete m_whereClauseBindData; - delete m_outputTokenList; - delete m_outputAttributeList; - delete m_cursor; -} - - - -void -pool::RelationalCollection::RelationalCollectionQuery::addToOutputList( const std::string& columnNames ) -{ - typedef boost::tokenizer<boost::char_separator<char> > Tizer; - boost::char_separator<char> sep(" ,"); - Tizer tizer( columnNames, sep ); - - for( Tizer::iterator token = tizer.begin(); token != tizer.end(); ++token ) { - if( *token == "*" ) { - selectAll(); - return; - } - // Check if is a Token column. - if( m_description.column( *token ).type() == pool::CollectionBaseNames::tokenTypeName() ) { - addToTokenOutputList( *token ); - } else { - addToAttributeOutputList( *token ); - } - } -} - - -void -pool::RelationalCollection::RelationalCollectionQuery::addToOutputList( const std::vector<std::string>& columnNames ) -{ - for ( std::vector< std::string >::const_iterator - iName = columnNames.begin(); iName != columnNames.end(); ++iName ) - { - addToOutputList( *iName ); - } -} - - -void -pool::RelationalCollection::RelationalCollectionQuery::selectAllAttributes() -{ - for( int i = 0; i < m_description.numberOfCollectionFragments(); i++ ) { - for( int j = 0; j < m_description.numberOfAttributeColumns( i ); j++ ) { - addToAttributeOutputList( m_description.attributeColumn( j, i ).name() ); - } - } -} - - -void -pool::RelationalCollection::RelationalCollectionQuery::selectAllTokens() -{ - for( int i = 0; i < m_description.numberOfCollectionFragments(); i++ ) { - for( int j = 0; j < m_description.numberOfTokenColumns( i ); j++ ) { - addToTokenOutputList( m_description.tokenColumn( j, i ).name() ); - } - } -} - - -void -pool::RelationalCollection::RelationalCollectionQuery::selectAll() -{ - this->selectAllAttributes(); - this->selectAllTokens(); -} - - -void -pool::RelationalCollection::RelationalCollectionQuery::addToCollectionFragmentList( const std::string& fragmentName ) -{ - m_collectionFragmentNames.insert( fragmentName ); -} - - -void -pool::RelationalCollection::RelationalCollectionQuery::addToCollectionFragmentList( - const std::vector< std::string >& fragmentNames ) -{ - for( vector< string >::const_iterator iName = fragmentNames.begin(); iName != fragmentNames.end(); ++iName ) { - addToCollectionFragmentList( *iName ); - } -} - - -void -pool::RelationalCollection::RelationalCollectionQuery::addAllCollectionFragments() -{ - for ( int i = 0; i < m_description.numberOfCollectionFragments(); i++ ) { - addToCollectionFragmentList( m_description.collectionFragment( i ).name() ); - } -} - - -void -pool::RelationalCollection::RelationalCollectionQuery:: -setCondition( const std::string& whereClause, - coral::AttributeList* attributeBindData, - pool::TokenList* tokenBindData ) -{ - // Names of collection fragments containing metadata used in where clause. Value will be returned by reference. - std::vector< std::string > collectionFragmentNames; - - // Parse where clause. - m_whereClause += RelationalCollectionExpressionParser::parse( whereClause, - m_description, - m_dataTableNameForCollectionFragmentName, - m_linksTableNameForCollectionFragmentName, - m_tableTokenColumnPrefixForCollectionTokenColumnName, - m_tableAttributeColumnNameForCollectionAttributeColumnName, - m_mapOfLinkIdForTokenKeyMaps, - collectionFragmentNames, - m_linksTableNames, - m_linkIDToOID1MatchingConditions, - attributeBindData, - tokenBindData, - m_whereClauseBindData ); - - // Add names of collection fragments containing metadata used in where clause to query table list. - for ( std::vector< std::string >::const_iterator iName = collectionFragmentNames.begin(); - iName != collectionFragmentNames.end(); ++iName ) - { - addToCollectionFragmentList( *iName ); - } -} - - -const std::string& -pool::RelationalCollection::RelationalCollectionQuery::whereClause() const -{ - return m_whereClause; -} - - -void -pool::RelationalCollection::RelationalCollectionQuery::setRowCacheSize( int rowCacheSize ) -{ - m_rowCacheSize = rowCacheSize; -} - - - - -void -pool::RelationalCollection::RelationalCollectionQuery::prepareQueryCondition() -{ - // has to query at least 1 table - if( m_collectionFragmentNames.empty() ) { - addToCollectionFragmentList( m_description.collectionFragmentName( m_description.eventReferenceColumnName() ) ); - } - - // Add primary key matching conditions to where clause. - for( set<string>::const_iterator - fragmentI = m_collectionFragmentNames.begin(), end = m_collectionFragmentNames.end(); - fragmentI != end; ++fragmentI ) - { - string dataTableName = m_dataTableNameForCollectionFragmentName.find( *fragmentI )->second; - if( dataTableName != m_dataTableName ) { - // Add condition to match primary key of data table with that of top level collection fragment data table. - string condition = " " + dataTableName + "." + RelationalCollectionNames::recordIdVariableInCollectionDataTable() + " = " + m_dataTableName + "." + RelationalCollectionNames::recordIdVariableInCollectionDataTable() + " "; - m_whereClause += ( (m_whereClause.size() > 0)? " AND " : "" ) + condition; - } - } - - // Add links table ID to data table OID_1 matching conditions to where clause. - for( std::vector< std::string >::const_iterator iCondition = - m_linkIDToOID1MatchingConditions.begin(); iCondition != - m_linkIDToOID1MatchingConditions.end(); ++iCondition ) - { - m_whereClause += ( (m_whereClause.size() > 0)? " AND " : "" ) + *iCondition; - } - -} - - -void -pool::RelationalCollection::RelationalCollectionQuery::prepareQuery( ) -{ - delete m_query; - delete m_outputDataBuffer; - m_query = m_session.nominalSchema().newQuery(); - m_outputDataBuffer = new coral::AttributeList ; - - // set the default to avoid row by row reading if the user forgets to set this - m_query->setRowCacheSize( m_rowCacheSize ? m_rowCacheSize : 1000 ); - - if( m_readPrimaryKey ) addPrimaryKeyToSelect(); - - // Add names of links tables used for Token column conditions to query table list. - for (const std::string& name : m_linksTableNames) { - m_query->addToTableList( name ); - } - - // Add data table associated with collection fragment to query table list. - for( set<string>::const_iterator - fragmentI = m_collectionFragmentNames.begin(), end = m_collectionFragmentNames.end(); - fragmentI != end; ++fragmentI ) - { - m_query->addToTableList( m_dataTableNameForCollectionFragmentName.find( *fragmentI )->second ); - } - - m_query->setCondition( m_whereClause, *m_whereClauseBindData ); -} - - - -// Add primary key of the top level collection fragment to the query select list -// Should be first on the list (assumed so in cursor::next() -void -pool::RelationalCollection::RelationalCollectionQuery::addPrimaryKeyToSelect() -{ - std::string primaryKeyColumnName = m_dataTableName + "." + - RelationalCollectionNames::recordIdVariableInCollectionDataTable(); - m_query->addToOutputList( primaryKeyColumnName ); - m_outputDataBuffer->extend<unsigned>( primaryKeyColumnName ); -} - - - - -pool::ICollectionCursor& -pool::RelationalCollection::RelationalCollectionQuery::execute() -{ - // Add event reference Token column to query select list - // if one is defined in the collection description - // and exclusion was not requested - if( !m_skipEventRef && m_description.hasEventReferenceColumn() ) { - addToTokenOutputList( m_description.eventReferenceColumnName() ); - } - - prepareQueryCondition(); - prepareQuery(); - - // Bind the selected Tokens. - for( TokenList::iterator iToken = m_outputTokenList->begin(); - iToken != m_outputTokenList->end(); ++iToken ) - { - // Form the OID_1 and OID_2 column names of Token. - std::string tableColumnPrefix = m_tableTokenColumnPrefixForCollectionTokenColumnName.find( iToken.tokenName() )->second; - std::string oid1ColumnName = tableColumnPrefix + RelationalCollectionNames::oid_1_variableInCollectionDataTable(); - std::string oid2ColumnName = tableColumnPrefix + RelationalCollectionNames::oid_2_variableInCollectionDataTable(); - - // cout << "-->>>*** Adding Token column to query: " << iToken.tokenName() - //<< ", odi2 DBcolumn name is " << oid2ColumnName << endl; - - // Add column names for this Token to query selection list. - m_query->addToOutputList( oid1ColumnName ); - m_query->addToOutputList( oid2ColumnName ); - - // Add columns for this Token to query output data. - m_outputDataBuffer->extend( oid1ColumnName, typeid(unsigned) ); - m_outputDataBuffer->extend( oid2ColumnName, typeid(unsigned) ); - } - - // Bind the selected Attributes. - for( std::vector< std::string >::const_iterator iName = m_selectedAttributeColumnNames.begin(); - iName != m_selectedAttributeColumnNames.end(); ++iName ) - { - // select column name of Attribute and add Attribute to query bind data. - const coral::Attribute& tableAttribute = m_tableAttributeList[ m_tableAttributeColumnNameForCollectionAttributeColumnName.find( *iName )->second ]; - std::string tableColumnName = tableAttribute.specification().name(); - m_query->addToOutputList( tableColumnName ); - m_outputDataBuffer->extend( tableColumnName, tableAttribute.specification().type() ); - - // Bind Attributes selected by query to Attribute list accessed by user. - // MN: do we want unsafe bind here? or something different -// (*m_outputDataBuffer)[tableColumnName].bindUnsafely( m_tableAttributeList[*iName].addressOfData() ); -// (*m_outputDataBuffer)[tableColumnName].bindUnsafely( (*m_outputAttributeList)[*iName].addressOfData() ); - (*m_outputAttributeList)[*iName].shareData( (*m_outputDataBuffer)[tableColumnName] ); - } - - // Execute query and retrieve cursor for navigation over result. - m_query->defineOutput( *m_outputDataBuffer ); - coral::ICursor& cursor = m_query->execute(); - - // Create collection row buffer to contain query output. - pool::CollectionRowBuffer collectionRowBuffer( *m_outputTokenList, *m_outputAttributeList ); - m_cursor = new RelationalCollectionCursor( cursor, - m_description, - m_mapOfTokenKeyForLinkIdMaps, - collectionRowBuffer ); - return *m_cursor; -} - - - - -void -pool::RelationalCollection::RelationalCollectionQuery::addToTokenOutputList( const std::string& columnName ) -{ - if ( m_tableTokenColumnPrefixForCollectionTokenColumnName.find( columnName ) == - m_tableTokenColumnPrefixForCollectionTokenColumnName.end() ) - { - std::string errorMsg( "Token column with name `" + columnName + "' does not exist." ); - throw pool::Exception( errorMsg, - "RelationalCollectionQuery::addToTokenOutputList", - "RelationalCollection" ); - } - - if (m_selectedTokenColumnNames.insert(columnName).second) { - // cout << "Adding token column to query output list:" << columnName << endl; - m_outputTokenList->extend( columnName ); - addToCollectionFragmentList( m_description.collectionFragmentName( columnName ) ); - } -} - - - - -void -pool::RelationalCollection::RelationalCollectionQuery::addToAttributeOutputList( const std::string& columnName ) -{ - // Check for column existence. - if ( m_tableAttributeColumnNameForCollectionAttributeColumnName.find( columnName ) == - m_tableAttributeColumnNameForCollectionAttributeColumnName.end() ) - { - std::string errorMsg( "Attribute column with name `" + columnName + "' does not exist." ); - throw pool::Exception( errorMsg, - "RelationalCollectionQuery::addToAttributeOutputList", - "RelationalCollection" ); - } - - // Add to select list. - if( find( m_selectedAttributeColumnNames.begin(), m_selectedAttributeColumnNames.end(), columnName ) == m_selectedAttributeColumnNames.end() ) - { - m_selectedAttributeColumnNames.push_back( columnName ); - const coral::Attribute& tableAttribute = m_tableAttributeList[ m_tableAttributeColumnNameForCollectionAttributeColumnName.find( columnName )->second ]; - m_outputAttributeList->extend( columnName, tableAttribute.specification().type() ); - addToCollectionFragmentList( m_description.collectionFragmentName( columnName ) ); - // cout << "Adding attribute column to query output list:" << columnName << endl; - } -} - - - -void -pool::RelationalCollection::RelationalCollectionQuery:: -skipEventReference( bool skip ) -{ - m_skipEventRef = skip; -} diff --git a/Database/APR/RelationalCollection/src/RelationalCollectionQuery.h b/Database/APR/RelationalCollection/src/RelationalCollectionQuery.h deleted file mode 100755 index bf4a11de714e7d5b6d7a8a1e20f13c5376593ea2..0000000000000000000000000000000000000000 --- a/Database/APR/RelationalCollection/src/RelationalCollectionQuery.h +++ /dev/null @@ -1,258 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#ifndef RELATIONALCOLLECTION_RELATIONALCOLLECTIONQUERY_H -#define RELATIONALCOLLECTION_RELATIONALCOLLECTIONQUERY_H - -#include "CollectionBase/ICollectionQuery.h" - -#include <map> -#include <set> -#include <vector> - - -namespace coral { - class ISessionProxy; - class IQuery; -} - -namespace pool { - - class ICollectionDescription; - - namespace RelationalCollection { - - /** - * @class RelationalCollectionQuery RelationalCollectionQuery.h src/RelationalCollectionQuery.h - * - * Implementation of the ICollectionQuery interface used to query a collection. - */ - class RelationalCollectionQuery : virtual public pool::ICollectionQuery - { - public: - /** - * Constructor: Selects the primary key and the event reference Token (if one exists for the top - * level collection fragment) and adds the data table of the top level collection fragment to - * the query table list. - * - * @param session Reference to current database access session. - * @param description Specification of collection properties. - * @param dataTableNameForCollectionFragmentName Map of data table names using names of corresponding collection fragment names as keys. - * @param linksTableNameForCollectionFragmentName Map of links table names using names of corresponding collection fragment names as keys. - * @param tableTokenColumnPrefixForCollectionTokenColumnName Map of table column prefixes for Tokens using names of corresponding collection columns as keys. - * @param tableAttributeColumnNameForCollectionAttributeColumnName Map of table column names for Attributes using names of corresponding collection columns as keys. - * @param tableAttributeList List of all Attributes defined by collection but using table column names. - * @param mapOfLinkIdForTokenKeyMaps Map of maps of link table ID's that use corresponding Token prefixes as keys, using collection fragment names as keys. - * @param mapOfTokenKeyForLinkIdMaps Map of maps of Token prefixes that use corresponding link table ID's as keys, using collection fragment names as keys. - * @param readPrimaryKey - if true (the default) add primary key to the query select list - don't change - */ - RelationalCollectionQuery( - coral::ISessionProxy& session, - const pool::ICollectionDescription& description, - const std::map< std::string, std::string >& dataTableNameForCollectionFragmentName, - const std::map< std::string, std::string >& linksTableNameForCollectionFragmentName, - const std::map< std::string, std::string >& tableTokenColumnPrefixForCollectionTokenColumnName, - const std::map< std::string, std::string >& tableAttributeColumnNameForCollectionAttributeColumnName, - const coral::AttributeList& tableAttributeList, - const std::map< std::string, std::map< std::string, unsigned >* >& mapOfLinkIdForTokenKeyMaps, - const std::map< std::string, std::map< unsigned, std::string >* >& mapOfTokenKeyForLinkIdMaps, - bool readPrimaryKey = true - ); - - /// Default destructor. - virtual ~RelationalCollectionQuery(); - - RelationalCollectionQuery (const RelationalCollectionQuery&) = delete; - RelationalCollectionQuery& operator= (const RelationalCollectionQuery&) = delete; - - /** - * Adds a column to the query select list. - * - * @param columnName Name of column to select. - */ - virtual void addToOutputList( const std::string& columnName ); - - /** - * Adds one or more columns to the query select list. - * - * @param columnNames Names of columns to select. - */ - virtual void addToOutputList( const std::vector<std::string>& columnNames ); - - /// Adds all Attribute columns to the query select list. - virtual void selectAllAttributes(); - - /// Adds all Token columns to the query select list. - virtual void selectAllTokens(); - - /// Adds all Token and Attribute columns to the query select list. - virtual void selectAll(); - - /** - * Adds the data table associated with a collection fragment to the query table list. - * - * @param fragmentName Name of collection fragment to add. - */ - virtual void addToCollectionFragmentList( const std::string& fragmentName ); - - /** - * Adds the data tables associated with one or more collection fragments to the query - * table list. - * - * @param fragmentNames Names of collection fragments to add. - */ - virtual void addToCollectionFragmentList( const std::vector< std::string >& fragmentNames ); - - /// Adds all collection fragments to the query table list. - virtual void addAllCollectionFragments(); - - /** - * Sets the predicates of the query. The predicates may involve conditions on Attributes, - * Tokens or individual columns of a Token in a data or links table. In the case of - * Token column conditions the name of the column should be provided by the user in - * form "<Token name>.<column name>" where "<column name>" is the actual name of the - * column in the associated data or links table. If bind variables are used they should - * be preceded by the symbol ":" in the where clause and the bind data should be - * provided as Attribute or Token lists that use the bind variables as their names. - * For Token column conditions the input Attribute list should be used for this purpose, - * using "<column name>" as the Attribute name. If desired, the where clause can be - * constructed in fragments by repeated calls to `setCondition'. All necessary table names, - * primary key matching conditions and links table ID to data table ID matching conditions - * are added to the final query string internally before the query is executed. - * - * @param whereClause The predicates of the query. - * @param attributeBindData Attribute and Token column condition data to bind if bind variables are used in query. - * @param tokenBindData Token condition data to bind if bind variables are used in query. - */ - virtual void setCondition( const std::string& whereClause, - coral::AttributeList* attributeBindData = 0, - pool::TokenList* tokenBindData = 0 ); - - /// Returns the where clause of the query. - virtual const std::string& whereClause() const; - - /** - * Sets the cache size used to store the query result. - * - * @param Number of rows stored in cache before cache is flushed. - */ - virtual void setRowCacheSize( int rowCacheSize ); - - /// Processes the query and returns a cursor over the query result. - virtual pool::ICollectionCursor& execute(); - - /** - * Tell the query to not include the primary event reference - * in the result by default (it can still beselected manually) - * - * @param skip if true (the default) then skip the primary event reference - */ - - virtual void skipEventReference( bool = true ); - - - protected: - /** - * Adds a Token column to the query select list. - * - * @param columnName Name of Token column to select. - */ - virtual void addToTokenOutputList( const std::string& columnName ); - - /** - * Adds an Attribute to the query select list. - */ - virtual void addToAttributeOutputList( const std::string& columnName ); - - /// Construct the WHERE part of the query - virtual void prepareQueryCondition(); - - /// create underlying query object. set WHERE and FROM query parts - virtual void prepareQuery(); - - /// Add primary key of the top level collection fragment to the query select list - virtual void addPrimaryKeyToSelect(); - - protected: - /// Specification of collection properties. - const pool::ICollectionDescription& m_description; - - /// Map of data table names using names of corresponding collection fragment names as keys. - const std::map< std::string, std::string >& m_dataTableNameForCollectionFragmentName; - - /// Map of links table names using names of corresponding collection fragment names as keys. - const std::map< std::string, std::string >& m_linksTableNameForCollectionFragmentName; - - /// Map of table column prefixes for Tokens using names of corresponding collection columns as keys. - const std::map< std::string, std::string >& m_tableTokenColumnPrefixForCollectionTokenColumnName; - - /// Map of table column names for Attributes using names of corresponding collection columns as keys. - const std::map< std::string, std::string >& m_tableAttributeColumnNameForCollectionAttributeColumnName; - - /// List of all Attributes defined by collection but using table column names. - const coral::AttributeList& m_tableAttributeList; - - /// Map of maps of link table ID's that use corresponding Token prefixes as keys, using collection fragment names as keys. - const std::map< std::string, std::map< std::string, unsigned >* >& m_mapOfLinkIdForTokenKeyMaps; - - /// Map of maps of Token prefixes that use corresponding link table ID's as keys, using collection fragment names as keys. - const std::map< std::string, std::map< unsigned, std::string >* >& m_mapOfTokenKeyForLinkIdMaps; - - /// Reference to table query processing object. - coral::IQuery* m_query; - - /// Name of data table of top level collection fragment. - std::string m_dataTableName; - - /// Row buffer to contain the results of the query. - coral::AttributeList* m_outputDataBuffer; - - /// Names of Token columns selected by query. - std::set< std::string > m_selectedTokenColumnNames; - - /// Names of Attribute columns selected by query. - std::vector< std::string > m_selectedAttributeColumnNames; - - /// Collection fragments for which to include associated data tables in query. - std::set< std::string > m_collectionFragmentNames; - - /// Link tables for which where clause contains explicit conditions on links table columns. - std::vector< std::string > m_linksTableNames; - - /// Where clause fragments to match links table link ID's with OID_1's of associated data tables. - std::vector< std::string > m_linkIDToOID1MatchingConditions; - - /// Where clause of query. - std::string m_whereClause; - - /// Data provided to query if bind variables are used in where clause. - coral::AttributeList* m_whereClauseBindData; - - /// Row buffer to contain Tokens selected by query. - pool::TokenList* m_outputTokenList; - - /// Row buffer to contain Attributes selected by query. - coral::AttributeList* m_outputAttributeList; - - /// Cursor to navigate over results of query. - pool::ICollectionCursor* m_cursor; - - /// the session - coral::ISessionProxy& m_session; - - /// query returned rows bundling - unsigned m_rowCacheSize; - - /// If true add primary table key to the query selection list - bool m_readPrimaryKey; - - /// If false, the primary event reference is added always to the query result - bool m_skipEventRef; - }; - } -} - -#endif - - diff --git a/Database/APR/RelationalCollection/src/RelationalCollectionSchemaEditor.cpp b/Database/APR/RelationalCollection/src/RelationalCollectionSchemaEditor.cpp deleted file mode 100755 index dc32d1a93ff08773c3ce73a8201bf25c7a3fbfd6..0000000000000000000000000000000000000000 --- a/Database/APR/RelationalCollection/src/RelationalCollectionSchemaEditor.cpp +++ /dev/null @@ -1,1344 +0,0 @@ -/* - Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration -*/ - -#include "RelationalCollectionSchemaEditor.h" -#include "RelationalCollectionNames.h" -#include "RelationalCollectionBindVariables.h" - -#include "CollectionBase/ICollectionDescription.h" -#include "CollectionBase/CollectionDescription.h" -#include "CollectionBase/ICollectionIndex.h" -#include "CollectionBase/ICollectionUniqueConstraint.h" -#include "CollectionBase/ICollectionFragment.h" -#include "CollectionBase/CollectionColumn.h" -#include "CollectionBase/TokenList.h" -#include "CollectionBase/CollectionRowBuffer.h" -#include "CollectionBase/CollectionBaseNames.h" - -#include "POOLCore/Exception.h" - -#include "RelationalAccess/ISessionProxy.h" -#include "RelationalAccess/ISchema.h" -#include "RelationalAccess/IQuery.h" -#include "RelationalAccess/ICursor.h" -#include "RelationalAccess/ITable.h" -#include "RelationalAccess/ITableDataEditor.h" -#include "RelationalAccess/ITableSchemaEditor.h" -#include "RelationalAccess/ITablePrivilegeManager.h" -#include "RelationalAccess/TableDescription.h" - -#include "CoralBase/Attribute.h" -#include "CoralBase/AttributeList.h" -#include "CoralBase/AttributeSpecification.h" - -#include <iostream> -using namespace std; - -pool::RelationalCollection::RelationalCollectionSchemaEditor::RelationalCollectionSchemaEditor( - coral::ISessionProxy& session, - pool::ICollectionDescription& description, - std::map< std::string, std::string >& dataTableNameForCollectionFragmentName, - std::map< std::string, std::string >& linksTableNameForCollectionFragmentName, - std::map< std::string, std::string >& tableTokenColumnPrefixForCollectionTokenColumnName, - std::map< std::string, std::string >& tableAttributeColumnNameForCollectionAttributeColumnName, - std::map< std::string, std::string >& tableColumnNameForCollectionColumnName, - std::map< int, std::string >& collectionColumnNameForTableColumnPosition, - coral::AttributeList& tableAttributeList, - pool::CollectionRowBuffer& collectionRowBuffer, - std::map< std::string, coral::AttributeList* >& dataTableRowBufferForCollectionFragmentName, - std::map< std::string, std::string >& mapOfWhereClausesForOID1InDataTable, - std::map< std::string, coral::AttributeList* >& mapOfWhereDataForOID1InDataTable ) - : m_session( &session ), - m_description( dynamic_cast<CollectionDescription*>(&description) ), - m_dataTableNameForCollectionFragmentName( dataTableNameForCollectionFragmentName ), - m_linksTableNameForCollectionFragmentName( linksTableNameForCollectionFragmentName ), - m_tableTokenColumnPrefixForCollectionTokenColumnName( tableTokenColumnPrefixForCollectionTokenColumnName ), - m_tableAttributeColumnNameForCollectionAttributeColumnName( tableAttributeColumnNameForCollectionAttributeColumnName ), - m_tableColumnNameForCollectionColumnName( tableColumnNameForCollectionColumnName ), - m_collectionColumnNameForTableColumnPosition( collectionColumnNameForTableColumnPosition ), - m_tableAttributeList( tableAttributeList ), - m_collectionRowBuffer( collectionRowBuffer ), - m_dataTableRowBufferForCollectionFragmentName( dataTableRowBufferForCollectionFragmentName ), - m_mapOfWhereClausesForOID1InDataTable( mapOfWhereClausesForOID1InDataTable ), - m_mapOfWhereDataForOID1InDataTable( mapOfWhereDataForOID1InDataTable ), - m_whereClauseForCollectionNameInHeadersTable( - RelationalCollectionBindVariables::whereClauseForCollectionNameInHeadersTable() ), - m_whereClauseForChildCollectionNameInHeadersTable( - RelationalCollectionBindVariables::whereClauseForChildCollectionNameInHeadersTable() ), - m_whereClauseForCollectionNameInDescriptionsTable( - RelationalCollectionBindVariables::whereClauseForCollectionNameInDescriptionsTable() ), - m_whereClauseForColumnNameInDescriptionsTable( - RelationalCollectionBindVariables::whereClauseForColumnNameInDescriptionsTable() ), - m_whereClauseForCollectionNameInIndexDescriptionsTable( - RelationalCollectionBindVariables::whereClauseForCollectionNameInIndexDescriptionsTable() ), - m_whereClauseForIndexNameInIndexDescriptionsTable( - RelationalCollectionBindVariables::whereClauseForIndexNameInIndexDescriptionsTable() ), - m_whereClauseForUniqueConstraintNameInIndexDescriptionsTable( - RelationalCollectionBindVariables::whereClauseForUniqueConstraintNameInIndexDescriptionsTable() ), - m_whereDataForCollectionNameInHeadersTable( new coral::AttributeList ), - m_whereDataForChildCollectionNameInHeadersTable( new coral::AttributeList ), - m_whereDataForCollectionNameInDescriptionsTable( new coral::AttributeList ), - m_whereDataForColumnNameInDescriptionsTable( new coral::AttributeList ), - m_whereDataForCollectionNameInIndexDescriptionsTable( new coral::AttributeList ), - m_whereDataForIndexNameInIndexDescriptionsTable( new coral::AttributeList ), - m_whereDataForUniqueConstraintNameInIndexDescriptionsTable( new coral::AttributeList ) -{ - // Define bind variable type used in where clause to find collection fragment name in collection headers table. - m_whereDataForCollectionNameInHeadersTable->extend<std::string>( - RelationalCollectionNames::collectionNameVariableInCollectionHeadersTable() ); - - // Define bind variable type used in where clause to find child collection fragment name in collection headers table. - m_whereDataForChildCollectionNameInHeadersTable->extend<std::string>( - RelationalCollectionNames::childCollectionNameVariableInCollectionHeadersTable() ); - - // Define bind variable type used in where clause to find collection fragment name in collection descriptions table. - m_whereDataForCollectionNameInDescriptionsTable->extend<std::string>( - RelationalCollectionNames::collectionNameVariableInCollectionDescriptionsTable() ); - - // Define bind variable type used in where clause to find column name in collection descriptions table. - m_whereDataForColumnNameInDescriptionsTable->extend<std::string>( - RelationalCollectionNames::collectionVariableNameVariableInCollectionDescriptionsTable() ); - m_whereDataForColumnNameInDescriptionsTable->extend<std::string>( - RelationalCollectionNames::collectionNameVariableInCollectionDescriptionsTable() ); - - // Define bind variable type used in where clause to find collection fragment name in collection index descriptions table. - m_whereDataForCollectionNameInIndexDescriptionsTable->extend<std::string>( - RelationalCollectionNames::collectionNameVariableInCollectionIndexDescriptionsTable() ); - - // Define bind variable types used in where clause to find index name in collection index descriptions table. - m_whereDataForIndexNameInIndexDescriptionsTable->extend<std::string>( - RelationalCollectionNames::indexNameVariableInCollectionIndexDescriptionsTable() ); - m_whereDataForIndexNameInIndexDescriptionsTable->extend<std::string>( - RelationalCollectionNames::collectionNameVariableInCollectionIndexDescriptionsTable() ); - - // Define bind variable types used in where clause to find unique constraint name in collection index descriptions table. - m_whereDataForUniqueConstraintNameInIndexDescriptionsTable->extend<std::string>( - RelationalCollectionNames::uniqueConstraintNameVariableInCollectionIndexDescriptionsTable() ); - m_whereDataForUniqueConstraintNameInIndexDescriptionsTable->extend<std::string>( - RelationalCollectionNames::collectionNameVariableInCollectionIndexDescriptionsTable() ); -} - - -pool::RelationalCollection::RelationalCollectionSchemaEditor:: -~RelationalCollectionSchemaEditor() -{ - delete m_whereDataForCollectionNameInHeadersTable; - delete m_whereDataForChildCollectionNameInHeadersTable; - delete m_whereDataForCollectionNameInDescriptionsTable; - delete m_whereDataForColumnNameInDescriptionsTable; - delete m_whereDataForCollectionNameInIndexDescriptionsTable; - delete m_whereDataForIndexNameInIndexDescriptionsTable; - delete m_whereDataForUniqueConstraintNameInIndexDescriptionsTable; -} - - -void -pool::RelationalCollection::RelationalCollectionSchemaEditor:: -setEventReferenceColumnName( const std::string& columnName ) -{ - renameColumn( m_description->eventReferenceColumnName(), columnName ); -} - - - -const pool::ICollectionColumn& -pool::RelationalCollection::RelationalCollectionSchemaEditor:: -insertColumn( const std::string& columnName, - const std::type_info& columnType, - const std::string& annotation, - std::string fragmentName, - int maxSize, - bool sizeIsFixed ) -{ - return insertColumn( columnName, coral::AttributeSpecification::typeNameForId( columnType ), - annotation, fragmentName, maxSize, sizeIsFixed ); -} - - - -const pool::ICollectionColumn& -pool::RelationalCollection::RelationalCollectionSchemaEditor:: -insertColumn( const std::string& columnName, const std::string& columnType, - const std::string& annotation, - std::string fragmentName, int maxSize, bool sizeIsFixed ) -{ - // Check if a Token column is being inserted. - if( columnType == pool::CollectionBaseNames::tokenTypeName() ) { - return insertTokenColumn( columnName, annotation, fragmentName ); - } - - // If no collection fragment name provided, use top level collection fragment. - if( fragmentName.size() == 0 ) { - fragmentName = m_description->name(); - } - // Insert column into collection description object. - const ICollectionColumn& column = m_description->insertColumn( columnName, columnType, - annotation, fragmentName, - maxSize, sizeIsFixed ); - int newPos = m_description->column( columnName ).id(); - - // Get name of data table to contain new column. - std::string dataTableName = dataTableNameForCollectionFragmentName( fragmentName, "insertColumn" ); - - // Create new table column name. - std::string tableColumnName = RelationalCollectionNames::variableDataVariableInCollectionDataTable( newPos ); - - // Insert column into data table. - m_session->nominalSchema().tableHandle( dataTableName ).schemaEditor().insertColumn( tableColumnName, columnType, maxSize, sizeIsFixed ); - - addRowToDescriptionsTable( fragmentName, columnName, annotation, columnType, maxSize, - (sizeIsFixed? "true" : "false"), newPos ); - - addColumnToMaps( columnName, tableColumnName, columnType, newPos ); - - recreateDataTableRowBuffer( fragmentName ); - return column; -} - - - -const pool::ICollectionColumn& -pool::RelationalCollection::RelationalCollectionSchemaEditor:: -insertTokenColumn( const std::string& columnName, const std::string& annotation, std::string fragmentName ) -{ - const std::string methodName("insertTokenColumn"); - coral::ISchema& nominalSchema = m_session->nominalSchema(); - - // If no collection fragment name provided use top level collection fragment. - if( fragmentName.size() == 0 ) { - fragmentName = m_description->name(); - } - - int newPos = 0; - const ICollectionColumn* column; - // Insert column into collection description object. - if( columnName != m_description->eventReferenceColumnName() ) { - // event reference column is in the description by default - column = &m_description->insertTokenColumn( columnName, annotation, fragmentName ); - // Get new table column position number - newPos = m_description->column( columnName ).id(); - } else { - column = &m_description->column( m_description->eventReferenceColumnName() ); - } - - // Get name of data table to contain column. - const std::string& dataTableName = dataTableNameForCollectionFragmentName( fragmentName, methodName ); - - // Create new table Token column names. - std::string variableName = RelationalCollectionNames::variableDataVariableInCollectionDataTable( newPos ) + "_"; - std::string oid1ColumnName = variableName + RelationalCollectionNames::oid_1_variableInCollectionDataTable(); - std::string oid2ColumnName = variableName + RelationalCollectionNames::oid_2_variableInCollectionDataTable(); - - // Insert column into data table. - nominalSchema.tableHandle( dataTableName ).schemaEditor().insertColumn( - oid1ColumnName, coral::AttributeSpecification::typeNameForType<int>() ); - nominalSchema.tableHandle( dataTableName ).schemaEditor().insertColumn( - oid2ColumnName, coral::AttributeSpecification::typeNameForType<int>() ); - - addRowToDescriptionsTable( fragmentName, columnName, annotation, - CollectionBaseNames::tokenTypeName(), 0, "true", newPos ); - addTokenColumnToMaps( variableName, columnName, newPos ); - recreateDataTableRowBuffer( fragmentName ); - return *column; -} - - - -const pool::ICollectionColumn& -pool::RelationalCollection::RelationalCollectionSchemaEditor:: -annotateColumn( const std::string& columnName, const std::string& annotation ) -{ - const ICollectionColumn& column = m_description->annotateColumn( columnName, annotation ); - - // Update corresponding row in collection descriptions table. - (*m_whereDataForColumnNameInDescriptionsTable)[0].data<std::string>() = columnName; - (*m_whereDataForColumnNameInDescriptionsTable)[1].data<std::string>() = m_description->collectionFragmentName( columnName ); - - std::string setClause = RelationalCollectionNames::collectionVariableAnnotationVariableInCollectionDescriptionsTable() + " = \'" + annotation + "\'"; - m_session->nominalSchema().tableHandle( RelationalCollectionNames::nameOfCollectionDescriptionsTable() ) - .dataEditor().updateRows( setClause, - m_whereClauseForColumnNameInDescriptionsTable, - *m_whereDataForColumnNameInDescriptionsTable ); - - return column; -} - - - -const std::string& -pool::RelationalCollection::RelationalCollectionSchemaEditor:: -dataTableNameForCollectionFragmentName( const std::string& fragmentName, const std::string& method ) const -{ - std::map< std::string, std::string >::const_iterator iName - = m_dataTableNameForCollectionFragmentName.find( fragmentName ); - if( iName == m_dataTableNameForCollectionFragmentName.end() ) { - std::string errorMsg = "Cannot not find data table name for collection fragment `" + fragmentName + "'."; - throw pool::Exception( errorMsg, - "RelationalCollectionSchemaEditor::" + method , - "RelationalCollection" ); - } - return iName->second; -} - - -void -pool::RelationalCollection::RelationalCollectionSchemaEditor:: -recreateDataTableRowBuffer( const std::string& fragmentName ) -{ - coral::AttributeList* dataTableRowBuffer = new coral::AttributeList; - - // Add primary key column - only temporary fix? MN - dataTableRowBuffer->extend( RelationalCollectionNames::recordIdVariableInCollectionDataTable(), coral::AttributeSpecification::typeNameForType<unsigned>() ); - - for( int i = 0; i < m_description->numberOfTokenColumns( fragmentName ); i++ ) { - const std::string& tableColumnPrefix = m_tableTokenColumnPrefixForCollectionTokenColumnName[m_description->tokenColumn( i, fragmentName ).name()]; - addTokenColumnToRowBuffer( dataTableRowBuffer, tableColumnPrefix ); - } - - for( int i = 0; i < m_description->numberOfAttributeColumns( fragmentName ); i++ ) { - const std::string& tableColumnName = m_tableAttributeColumnNameForCollectionAttributeColumnName[m_description->attributeColumn( i, fragmentName ).name()]; - dataTableRowBuffer->extend( tableColumnName, m_description->attributeColumn( i, fragmentName ).type() ); - } - - delete m_dataTableRowBufferForCollectionFragmentName[ fragmentName ]; - m_dataTableRowBufferForCollectionFragmentName[ fragmentName ] = dataTableRowBuffer; -} - - - -// Add row for new column into collection descriptions table. -void -pool::RelationalCollection::RelationalCollectionSchemaEditor:: -addRowToDescriptionsTable(const std::string& fragmentName, const std::string& columnName, - const std::string& annotation, - const std::string& colType, unsigned maxSize, - const std::string& isFixed, unsigned newPos ) -{ - coral::AttributeList rowBuffer; - rowBuffer.extend< std::string >( RelationalCollectionNames::collectionNameVariableInCollectionDescriptionsTable() ); - rowBuffer.extend< std::string >( RelationalCollectionNames::collectionVariableNameVariableInCollectionDescriptionsTable() ); - rowBuffer.extend< std::string >( RelationalCollectionNames::collectionVariableTypeVariableInCollectionDescriptionsTable() ); - rowBuffer.extend< int >( RelationalCollectionNames::collectionVariableMaxSizeVariableInCollectionDescriptionsTable() ); - rowBuffer.extend< std::string >( RelationalCollectionNames::collectionVariableSizeIsFixedVariableInCollectionDescriptionsTable() ); - rowBuffer.extend< int >( RelationalCollectionNames::collectionVariablePositionVariableInCollectionDescriptionsTable() ); - rowBuffer[0].data< std::string >() = fragmentName; - rowBuffer[1].data< std::string >() = columnName; - rowBuffer[2].data< std::string >() = colType; - rowBuffer[3].data< int >() = maxSize; - rowBuffer[4].data< std::string >() = isFixed; - rowBuffer[5].data< int >() = newPos; - - rowBuffer.extend< std::string >( RelationalCollectionNames::collectionVariableAnnotationVariableInCollectionDescriptionsTable() ); - rowBuffer[6].data< std::string >() = annotation; - - m_session->nominalSchema().tableHandle( RelationalCollectionNames::nameOfCollectionDescriptionsTable() ).dataEditor().insertRow( rowBuffer ); -} - - - - -// Update private maps and row buffers. -void -pool::RelationalCollection::RelationalCollectionSchemaEditor:: -addColumnToMaps( const std::string& columnName, const std::string& tableColumnName, - const std::string& columnType, int columnPos ) -{ - m_tableAttributeColumnNameForCollectionAttributeColumnName[ columnName ] = tableColumnName; - m_tableColumnNameForCollectionColumnName[ columnName ] = tableColumnName; - m_collectionRowBuffer.attributeList().extend( columnName, columnType ); - m_tableAttributeList.extend( tableColumnName, columnType ); - m_collectionColumnNameForTableColumnPosition[ columnPos ] = columnName; -} - - - - -void -pool::RelationalCollection::RelationalCollectionSchemaEditor:: -addTokenColumnToRowBuffer( coral::AttributeList* rowBuffer, const std::string& variableName) -{ - std::string oid1ColumnName = variableName + RelationalCollectionNames::oid_1_variableInCollectionDataTable(); - std::string oid2ColumnName = variableName + RelationalCollectionNames::oid_2_variableInCollectionDataTable(); - - rowBuffer->extend( oid1ColumnName, typeid( unsigned ) ); - rowBuffer->extend( oid2ColumnName, typeid( unsigned ) ); -} - - - -void -pool::RelationalCollection::RelationalCollectionSchemaEditor:: -addTokenColumnToMaps( std::string variableName, const std::string& columnName, int columnPos ) -{ - // Update private maps and row buffers. - m_tableTokenColumnPrefixForCollectionTokenColumnName[ columnName ] = variableName; - m_tableColumnNameForCollectionColumnName[ columnName ] = variableName; - m_collectionRowBuffer.tokenList().extend( columnName ); - m_collectionColumnNameForTableColumnPosition[ columnPos ] = columnName; - - - std::string oid1VariableName = variableName + RelationalCollectionNames::oid_1_variableInCollectionDataTable(); - std::string whereClause = oid1VariableName + " =:" + oid1VariableName; - m_mapOfWhereClausesForOID1InDataTable[ columnName ] = whereClause; - - coral::AttributeList* whereData = new coral::AttributeList; - whereData->extend<unsigned>( oid1VariableName ); - m_mapOfWhereDataForOID1InDataTable[ columnName ] = whereData; -} - - -void -pool::RelationalCollection::RelationalCollectionSchemaEditor:: -dropColumn( const std::string& columnName ) -{ - coral::ISchema& nominalSchema = m_session->nominalSchema(); - - // Get column type. - std::string columnType = m_description->column( columnName ).type(); - - // Get name of collection fragment that contains column. - std::string fragmentName = m_description->column( columnName ).collectionFragmentName(); - - // Drop column from collection description object. - m_description->dropColumn( columnName ); - - // Get handle to data table that contains column. - coral::ITable& table = nominalSchema.tableHandle( dataTableNameForCollectionFragmentName( fragmentName, "dropColumn" ) ); - - // Drop column from data table and update private maps and row buffers. - if( columnType == CollectionBaseNames::tokenTypeName() ) { - std::string tableColumnPrefix = m_tableTokenColumnPrefixForCollectionTokenColumnName[columnName]; - std::string oid1ColumnName = tableColumnPrefix + RelationalCollectionNames::oid_1_variableInCollectionDataTable(); - std::string oid2ColumnName = tableColumnPrefix + RelationalCollectionNames::oid_2_variableInCollectionDataTable(); - - table.schemaEditor().dropColumn( oid1ColumnName ); - table.schemaEditor().dropColumn( oid2ColumnName ); - - m_tableTokenColumnPrefixForCollectionTokenColumnName.erase( columnName ); - - m_mapOfWhereClausesForOID1InDataTable.erase( columnName ); - delete m_mapOfWhereDataForOID1InDataTable[ columnName ]; - m_mapOfWhereDataForOID1InDataTable.erase( columnName ); - } - else { - std::string tableColumnName = m_tableAttributeColumnNameForCollectionAttributeColumnName[columnName]; - table.schemaEditor().dropColumn( tableColumnName ); - - m_tableAttributeColumnNameForCollectionAttributeColumnName.erase( columnName ); - } - - m_tableColumnNameForCollectionColumnName.erase( columnName ); - recreateDataTableRowBuffer( fragmentName ); - rebuildAttributeLists(); - - - for( std::map< int, std::string >::iterator iData = m_collectionColumnNameForTableColumnPosition.begin(); - iData != m_collectionColumnNameForTableColumnPosition.end(); ++iData ) - { - if( iData->second == columnName ) { - m_collectionColumnNameForTableColumnPosition.erase( iData ); - break; - } - } - - // Delete corresponding row in collection descriptions table. - (*m_whereDataForColumnNameInDescriptionsTable)[0].data<std::string>() = columnName; - (*m_whereDataForColumnNameInDescriptionsTable)[1].data<std::string>() = fragmentName; - nominalSchema.tableHandle( RelationalCollectionNames::nameOfCollectionDescriptionsTable() ).dataEditor().deleteRows( - m_whereClauseForColumnNameInDescriptionsTable, *m_whereDataForColumnNameInDescriptionsTable ); -} - - -void -pool::RelationalCollection::RelationalCollectionSchemaEditor::renameColumn( const std::string& oldName, - const std::string& newName ) -{ - coral::ISchema& nominalSchema = m_session->nominalSchema(); - - // Get column type. - std::string columnType = m_description->column( oldName ).type(); - - // Rename column in collection description object. - m_description->renameColumn( oldName, newName ); - - // Update corresponding row in collection descriptions table. - if ( newName != m_description->eventReferenceColumnName() ) { - (*m_whereDataForColumnNameInDescriptionsTable)[0].data<std::string>() = oldName; - // MN: made a fix here which is just a guess!! (newName) - (*m_whereDataForColumnNameInDescriptionsTable)[1].data<std::string>() = newName; - std::string setClause = RelationalCollectionNames::collectionVariableNameVariableInCollectionDescriptionsTable() + " = " + newName; - nominalSchema.tableHandle( - RelationalCollectionNames::nameOfCollectionDescriptionsTable() ).dataEditor().updateRows( - setClause, - m_whereClauseForColumnNameInDescriptionsTable, - *m_whereDataForColumnNameInDescriptionsTable ); - } - - // Update private maps and row buffers. - if ( columnType == pool::CollectionBaseNames::tokenTypeName() ) { - // Corresponding data table column name stays the same. - std::string tableColumnPrefix = ( m_tableTokenColumnPrefixForCollectionTokenColumnName.find( oldName ) )->second; - m_tableTokenColumnPrefixForCollectionTokenColumnName.erase( oldName ); - m_tableTokenColumnPrefixForCollectionTokenColumnName.insert( std::make_pair( newName, tableColumnPrefix ) ); - m_tableColumnNameForCollectionColumnName.erase( oldName ); - m_tableColumnNameForCollectionColumnName.insert( std::make_pair( newName, tableColumnPrefix ) ); - - pool::TokenList tokenList; - for( int i = 0; i < m_description->numberOfCollectionFragments(); i++ ) { - std::string fname = m_description->collectionFragment( i ).name(); - for( int j = 0; j < m_description->numberOfTokenColumns( fname ); j++ ) { - tokenList.extend( m_description->tokenColumn( j, fname ).name() ); - } - } - m_collectionRowBuffer.setTokenList( tokenList ); - - // OID1 column name stays the same. - std::string whereClause = ( m_mapOfWhereClausesForOID1InDataTable.find( oldName ) )->second; - m_mapOfWhereClausesForOID1InDataTable.erase( oldName ); - m_mapOfWhereClausesForOID1InDataTable.insert( std::make_pair( newName, whereClause ) ); - - // MN: guessing how this should work... FIX? validate? - //delete m_mapOfWhereDataForOID1InDataTable.find( oldName )->second; - //m_mapOfWhereDataForOID1InDataTable.find( oldName )->second = 0; - coral::AttributeList *whereData = m_mapOfWhereDataForOID1InDataTable.find( oldName )->second; - m_mapOfWhereDataForOID1InDataTable.erase( oldName ); - m_mapOfWhereDataForOID1InDataTable.insert( std::make_pair( newName, whereData ) ); - } - else - { - // Corresponding data table column name stays the same. - std::string tableColumnName = ( m_tableAttributeColumnNameForCollectionAttributeColumnName.find( oldName ) )->second; - - m_tableAttributeColumnNameForCollectionAttributeColumnName.erase( oldName ); - m_tableAttributeColumnNameForCollectionAttributeColumnName.insert( std::make_pair( newName, tableColumnName ) ); - - m_tableColumnNameForCollectionColumnName.erase( oldName ); - m_tableColumnNameForCollectionColumnName.insert( std::make_pair( newName, tableColumnName ) ); - - coral::AttributeList attributeList; - for( int i = 0; i < m_description->numberOfCollectionFragments(); i++ ) - { - std::string fname = m_description->collectionFragment( i ).name(); - for( int j = 0; j < m_description->numberOfAttributeColumns( fname ); j++ ) - { - attributeList.extend( m_description->attributeColumn( j, fname ).name(), - m_description->attributeColumn( j, fname ).type() ); - } - } - m_collectionRowBuffer.setAttributeList( attributeList ); - } - for ( std::map< int, std::string >::iterator iData = m_collectionColumnNameForTableColumnPosition.begin(); - iData != m_collectionColumnNameForTableColumnPosition.end(); ++iData ) - { - int pos = iData->first; - if ( iData->second == oldName ) - { - m_collectionColumnNameForTableColumnPosition.erase( pos ); - m_collectionColumnNameForTableColumnPosition.insert( std::make_pair( pos, newName ) ); - break; - } - } -} - - -void -pool::RelationalCollection::RelationalCollectionSchemaEditor::changeColumnType( const std::string& columnName, - const std::string& newType, - int maxSize, - bool sizeIsFixed ) -{ - coral::ISchema& nominalSchema = m_session->nominalSchema(); - - // Get old column type. - std::string oldType = m_description->column( columnName ).type(); - const std::string& annotation = m_description->column( columnName ).annotation(); - - // Get name of collection fragment that contains column. - std::string fragmentName = m_description->column( columnName ).collectionFragmentName(); - - // Change column type in collection description object and data table. - if ( oldType == pool::CollectionBaseNames::tokenTypeName() ) { - // Drop existing Token column. - dropColumn( columnName ); - // Insert Attribute column with new type. - insertColumn( columnName, newType, annotation, fragmentName, maxSize, sizeIsFixed ); - } - else { - if ( newType == pool::CollectionBaseNames::tokenTypeName() ) { - // Drop existing Attribute column. - dropColumn( columnName ); - // Insert new Token column. - insertTokenColumn( columnName, annotation, fragmentName ); - } - else { - // Change column type in collection description object. - m_description->changeColumnType( columnName, newType, maxSize, sizeIsFixed ); - // Get name of data table that contains column. - std::string dataTableName = ""; - std::map< std::string, std::string >::const_iterator iName = - m_dataTableNameForCollectionFragmentName.find( fragmentName ); - if ( iName != m_dataTableNameForCollectionFragmentName.end() ) { - dataTableName = iName->second; - } - else { - std::string errorMsg = "Cannot not find data table name for collection fragment `" + fragmentName + "'."; - throw pool::Exception( errorMsg, - "RelationalCollectionSchemaEditor::insertTokenColumn", - "RelationalCollection" ); - } - - // Change column type in data table. - nominalSchema.tableHandle( dataTableName ).schemaEditor(). - changeColumnType( columnName, newType, maxSize,sizeIsFixed ); - - // Update corresponding row in collection descriptions table. - (*m_whereDataForColumnNameInDescriptionsTable)[0].data<std::string>() = columnName; - (*m_whereDataForColumnNameInDescriptionsTable)[1].data<std::string>() = fragmentName; - std::string setClause = RelationalCollectionNames::collectionVariableTypeVariableInCollectionDescriptionsTable() + " = " + newType; - nominalSchema.tableHandle( - RelationalCollectionNames::nameOfCollectionDescriptionsTable() ).dataEditor().updateRows( - setClause, - m_whereClauseForColumnNameInDescriptionsTable, - *m_whereDataForColumnNameInDescriptionsTable ); - - // Update private maps and row buffers. - coral::AttributeList* dataTableRowBuffer = new coral::AttributeList; - for( int i = 0; i < m_description->numberOfTokenColumns( fragmentName ); i++ ) { - std::string tableColumnPrefix = m_tableTokenColumnPrefixForCollectionTokenColumnName.find( m_description->tokenColumn( i, fragmentName ).name() )->second; - - addTokenColumnToRowBuffer( dataTableRowBuffer, tableColumnPrefix ); - } - for( int i = 0; i < m_description->numberOfAttributeColumns( fragmentName ); i++ ) { - std::string tableColumnName = ( m_tableAttributeColumnNameForCollectionAttributeColumnName.find( m_description->attributeColumn( i, fragmentName ).name() ) )->second; - dataTableRowBuffer->extend( tableColumnName, m_description->attributeColumn( i, fragmentName ).type() ); - } - delete m_dataTableRowBufferForCollectionFragmentName.find( fragmentName )->second; - m_dataTableRowBufferForCollectionFragmentName.find( fragmentName )->second = 0; - m_dataTableRowBufferForCollectionFragmentName.insert( std::make_pair( fragmentName, dataTableRowBuffer ) ); - - coral::AttributeList attributeList; - coral::AttributeList tableAttributeList; - for( int i = 0; i < m_description->numberOfCollectionFragments(); i++ ) { - std::string fname = m_description->collectionFragment( i ).name(); - - for( int j = 0; j < m_description->numberOfAttributeColumns( fname ); j++ ) { - std::string cname = m_description->attributeColumn( j, fname ).name(); - std::string ctype = m_description->attributeColumn( j, fname ).type(); - - attributeList.extend( cname, ctype ); - tableAttributeList.extend( - m_tableAttributeColumnNameForCollectionAttributeColumnName.find( cname )->second, ctype ); - } - } - m_collectionRowBuffer.setAttributeList( attributeList ); - m_tableAttributeList = tableAttributeList; - } - } -} - - - -void -pool::RelationalCollection::RelationalCollectionSchemaEditor:: -changeColumnType( const std::string& columnName, const std::type_info& newType, - int maxSize, bool sizeIsFixed ) -{ - changeColumnType( columnName, coral::AttributeSpecification::typeNameForId( newType ), - maxSize, sizeIsFixed ); -} - - - -void -pool::RelationalCollection::RelationalCollectionSchemaEditor:: -createIndex( std::string indexName, const std::string& columnName, bool isUnique ) -{ - this->createIndex( indexName, std::vector<std::string>( 1, columnName ), isUnique ); -} - - - -void -pool::RelationalCollection::RelationalCollectionSchemaEditor:: -createIndex( std::string indexName, const std::vector<std::string>& columnNames, bool isUnique ) -{ - coral::ISchema& nominalSchema = m_session->nominalSchema(); - - // Create index in collection description object. - m_description->createIndex( indexName, columnNames, isUnique ); - - // Get newly generated name for index. - indexName = m_description->index( columnNames ).name(); - - // Get data table column names for columns used by this index. - std::vector< std::string > tableColumnNames; - for ( std::vector< std::string >::const_iterator iName = columnNames.begin(); iName != columnNames.end(); ++iName ) - { - std::string collectionColumnName = *iName; - std::string tableColumnName = ( m_tableColumnNameForCollectionColumnName.find( collectionColumnName ) )->second; - - if ( m_description->column( collectionColumnName ).type() == pool::CollectionBaseNames::tokenTypeName() ) - { - std::string oid1ColumnName = tableColumnName - + RelationalCollectionNames::oid_1_variableInCollectionDataTable(); - tableColumnNames.push_back( oid1ColumnName ); - std::string oid2ColumnName = tableColumnName - + RelationalCollectionNames::oid_2_variableInCollectionDataTable(); - tableColumnNames.push_back( oid2ColumnName ); - } - else { - tableColumnNames.push_back( tableColumnName ); - } - } - - // Add index to data table. - std::string fragmentName = m_description->collectionFragmentName( *( columnNames.begin() ) ); - std::string dataTableName = ( m_dataTableNameForCollectionFragmentName.find( fragmentName ) )->second; - nominalSchema.tableHandle( dataTableName ).schemaEditor().createIndex( indexName, - tableColumnNames, - isUnique ); - - // Insert rows for new index into collection index descriptions table. - for ( std::vector< std::string >::const_iterator iName = columnNames.begin(); iName != columnNames.end(); ++iName ) - { - coral::AttributeList rowBuffer; - rowBuffer.extend<std::string>( RelationalCollectionNames::indexNameVariableInCollectionIndexDescriptionsTable() ); - rowBuffer.extend<std::string>( RelationalCollectionNames::uniqueConstraintNameVariableInCollectionIndexDescriptionsTable() ); - rowBuffer.extend<std::string>( RelationalCollectionNames::collectionVariableNameVariableInCollectionIndexDescriptionsTable() ); - rowBuffer.extend<std::string>( RelationalCollectionNames::collectionNameVariableInCollectionIndexDescriptionsTable() ); - coral::AttributeList::iterator iAttribute = rowBuffer.begin(); - iAttribute->data< std::string >() = indexName; - ++iAttribute; - if ( isUnique ) - { - iAttribute->data< std::string >() = indexName; - } - else - { - iAttribute->data< std::string >() = ""; - } - ++iAttribute; - iAttribute->data< std::string >() = *iName; - ++iAttribute; - iAttribute->data< std::string >() = fragmentName; - nominalSchema.tableHandle( RelationalCollectionNames::nameOfCollectionIndexDescriptionsTable() ).dataEditor().insertRow( rowBuffer ); - } -} - - -void -pool::RelationalCollection::RelationalCollectionSchemaEditor::dropIndex( const std::string& columnName ) -{ - this->dropIndex( std::vector<std::string>( 1, columnName ) ); -} - - -void -pool::RelationalCollection::RelationalCollectionSchemaEditor::dropIndex( const std::vector< std::string >& columnNames ) -{ - coral::ISchema& nominalSchema = m_session->nominalSchema(); - - // Get name of index. - std::string indexName = m_description->index( columnNames ).name(); - - // Get name of collection fragment that contains index. - std::string fragmentName = m_description->collectionFragmentName( *( columnNames.begin() ) ); - - // Get name of data table that contains index. - std::string dataTableName = ( m_dataTableNameForCollectionFragmentName.find( fragmentName ) )->second; - - // Drop index from collection description object. - m_description->dropIndex( columnNames ); - - // Drop index from data table. - nominalSchema.tableHandle( dataTableName ).schemaEditor().dropIndex( indexName ); - - // Delete corresponding rows in collection index descriptions table. - (*m_whereDataForIndexNameInIndexDescriptionsTable)[0].data<std::string>() = indexName; - (*m_whereDataForIndexNameInIndexDescriptionsTable)[1].data<std::string>() = fragmentName; - nominalSchema.tableHandle( - pool::RelationalCollection::RelationalCollectionNames::nameOfCollectionIndexDescriptionsTable() ).dataEditor().deleteRows( m_whereClauseForIndexNameInIndexDescriptionsTable, *m_whereDataForIndexNameInIndexDescriptionsTable ); -} - - -void -pool::RelationalCollection::RelationalCollectionSchemaEditor:: -setUniqueConstraint( const std::string& constraintName, const std::string& columnName ) -{ - setUniqueConstraint( constraintName, std::vector<std::string>( 1, columnName ) ); -} - - -void -pool::RelationalCollection::RelationalCollectionSchemaEditor:: -setUniqueConstraint( const std::string& constraintNameIn, const std::vector< std::string >& columnNames ) -{ - coral::ISchema& nominalSchema = m_session->nominalSchema(); - - // Set unique constraint in collection description object. - m_description->setUniqueConstraint( constraintNameIn, columnNames ); - - // Get newly generated name for unique constraint. - std::string constraintName = m_description->uniqueConstraint( columnNames ).name(); - - // Get data table column names for columns used by this unique constraint. - std::vector< std::string > tableColumnNames; - for ( std::vector< std::string >::const_iterator iName = columnNames.begin(); iName != columnNames.end(); ++iName ) - { - std::string collectionColumnName = *iName; - std::string tableColumnName = ( m_tableColumnNameForCollectionColumnName.find( collectionColumnName ) )->second; - - if ( m_description->column( collectionColumnName ).type() == pool::CollectionBaseNames::tokenTypeName() ) - { - std::string oid1ColumnName = tableColumnName + - RelationalCollectionNames::oid_1_variableInCollectionDataTable(); - tableColumnNames.push_back( oid1ColumnName ); - std::string oid2ColumnName = tableColumnName + - RelationalCollectionNames::oid_2_variableInCollectionDataTable(); - tableColumnNames.push_back( oid2ColumnName ); - } - else - { - tableColumnNames.push_back( tableColumnName ); - } - } - - // Set unique constraint in data table. - std::string fragmentName = m_description->collectionFragmentName( *( columnNames.begin() ) ); - std::string dataTableName = ( m_dataTableNameForCollectionFragmentName.find( fragmentName ) )->second; - nominalSchema.tableHandle( dataTableName ).schemaEditor().setUniqueConstraint( tableColumnNames, - constraintName, - true ); - - // Insert rows for new index into collection index and unique constraint descriptions table. - for ( std::vector< std::string >::const_iterator iName = columnNames.begin(); iName != columnNames.end(); ++iName ) - { - coral::AttributeList rowBuffer; - rowBuffer.extend<std::string>( - pool::RelationalCollection::RelationalCollectionNames::indexNameVariableInCollectionIndexDescriptionsTable() ); - rowBuffer.extend<std::string>( - pool::RelationalCollection::RelationalCollectionNames::uniqueConstraintNameVariableInCollectionIndexDescriptionsTable() ); - rowBuffer.extend<std::string>( - pool::RelationalCollection::RelationalCollectionNames::collectionVariableNameVariableInCollectionIndexDescriptionsTable() ); - rowBuffer.extend<std::string>( - pool::RelationalCollection::RelationalCollectionNames::collectionNameVariableInCollectionIndexDescriptionsTable() ); - coral::AttributeList::iterator iAttribute = rowBuffer.begin(); - iAttribute->data< std::string >() = ""; - ++iAttribute; - iAttribute->data< std::string >() = constraintName; - ++iAttribute; - iAttribute->data< std::string >() = *iName; - ++iAttribute; - iAttribute->data< std::string >() = fragmentName; - nominalSchema.tableHandle( pool::RelationalCollection::RelationalCollectionNames::nameOfCollectionIndexDescriptionsTable() ).dataEditor().insertRow( rowBuffer ); - } -} - - -void -pool::RelationalCollection::RelationalCollectionSchemaEditor::unsetUniqueConstraint( const std::string& columnName ) -{ - this->unsetUniqueConstraint( std::vector<std::string>( 1, columnName ) ); -} - - -void -pool::RelationalCollection::RelationalCollectionSchemaEditor::unsetUniqueConstraint( - const std::vector< std::string >& columnNames ) -{ - coral::ISchema& nominalSchema = m_session->nominalSchema(); - - // Get name of unique constraint. - std::string constraintName = m_description->uniqueConstraint( columnNames ).name(); - - // Get name of collection fragment that contains unique constraint. - std::string fragmentName = m_description->collectionFragmentName( *columnNames.begin() ); - - // Get name of data table that contains unique constraint. - std::string dataTableName = ( m_dataTableNameForCollectionFragmentName.find( fragmentName ) )->second; - - // Drop unique constraint from collection description object. - m_description->unsetUniqueConstraint( columnNames ); - - // Drop unique constraint from data table. - nominalSchema.tableHandle( dataTableName ).schemaEditor(). - setUniqueConstraint( columnNames, constraintName, false ); - - // Delete corresponding rows in collection index and unique constraint descriptions table. - (*m_whereDataForUniqueConstraintNameInIndexDescriptionsTable)[0].data<std::string>() = constraintName; - (*m_whereDataForUniqueConstraintNameInIndexDescriptionsTable)[1].data<std::string>() = fragmentName; - nominalSchema.tableHandle( pool::RelationalCollection::RelationalCollectionNames::nameOfCollectionIndexDescriptionsTable() ).dataEditor().deleteRows( m_whereClauseForUniqueConstraintNameInIndexDescriptionsTable, *m_whereDataForUniqueConstraintNameInIndexDescriptionsTable ); -} - - - -void -pool::RelationalCollection::RelationalCollectionSchemaEditor:: -addCollectionFragment( const std::string& fragmentName, - std::string parentFragmentName, - bool usesForeignKey ) -{ - cout << " *DEBUG* RelationalCollectionSchemaEditor::addCollectionFragment() called" << endl; - - coral::ISchema& nominalSchema = m_session->nominalSchema(); - - // Check if parent collection fragment is defined in the collection description. - if ( m_dataTableNameForCollectionFragmentName.find( parentFragmentName ) == - m_dataTableNameForCollectionFragmentName.end() ) - { - std::string errorMsg = "Collection fragment with name `" + parentFragmentName + - "' is not defined in the collection description."; - throw pool::Exception( errorMsg, - "RelationalCollectionSchemaEditor::addCollectionFragment", - "RelationalCollection" ); - } - - // Drop foreign key constraint on parent collection fragment if constraint exists. - std::string oldForeignKeyName = m_description->collectionFragment( parentFragmentName ).foreignKeyName(); - if ( oldForeignKeyName.size() > 0 ) - { - std::string oldParentChildFragmentName = - m_description->collectionFragment( parentFragmentName ).childCollectionFragmentName(); - std::string oldParentChildDataTableName = - //MN: FIXed here, again a guess - m_dataTableNameForCollectionFragmentName.find( oldParentChildFragmentName )->second; - nominalSchema.tableHandle( oldParentChildDataTableName ).schemaEditor().dropForeignKey( oldForeignKeyName ); - } - - // Add collection fragment to collection description object. - m_description->addCollectionFragment( fragmentName, parentFragmentName, usesForeignKey ); - - // Get updated collection fragment properties. - std::string childFragmentName = m_description->collectionFragment( fragmentName ).childCollectionFragmentName(); - std::string foreignKeyName = m_description->collectionFragment( fragmentName ).foreignKeyName(); - std::string parentForeignKeyName = m_description->collectionFragment( parentFragmentName ).foreignKeyName(); - - // Update parent collection fragment row in collection headers table. - if( parentFragmentName.size() > 0 ) { - m_whereDataForCollectionNameInHeadersTable->begin()->data<std::string>() = parentFragmentName; - std::string setClause = RelationalCollectionNames::childCollectionNameVariableInCollectionHeadersTable() + " = " + fragmentName + " , " + RelationalCollectionNames::foreignKeyNameVariableInCollectionHeadersTable() + " = " + parentForeignKeyName; - nominalSchema.tableHandle( - RelationalCollectionNames::nameOfCollectionHeadersTable() ).dataEditor().updateRows( - setClause, - m_whereClauseForCollectionNameInHeadersTable, - *m_whereDataForCollectionNameInHeadersTable ); - } - - // Check if collection fragment already exists in database. - coral::IQuery* query = nominalSchema.tableHandle( - RelationalCollectionNames::nameOfCollectionHeadersTable() ).newQuery(); - m_whereDataForCollectionNameInHeadersTable->begin()->data<std::string>() = fragmentName; - query->setCondition( m_whereClauseForCollectionNameInHeadersTable, *m_whereDataForCollectionNameInHeadersTable ); - query->limitReturnedRows( 1, 0 ); - coral::ICursor& cursor = query->execute(); - bool exists = cursor.next(); - delete query; - - // If collection fragment does not exist create new data and links tables and update headers table. - std::string dataTableName = ""; - std::string linksTableName = ""; - if ( ! exists ) - { - // Find next available names for data and links tables of collection fragment. - for ( int i = 0; ; ++i ) - { - dataTableName = pool::RelationalCollection::RelationalCollectionNames::nameOfCollectionDataTable( i ); - linksTableName = pool::RelationalCollection::RelationalCollectionNames::nameOfCollectionLinksTable( i ); - if ( ! ( nominalSchema.existsTable( dataTableName ) || - nominalSchema.existsTable( linksTableName ) ) ) break; - } - - // Insert new data and links table names in private maps. - m_dataTableNameForCollectionFragmentName.insert( std::make_pair( fragmentName, dataTableName ) ); - m_linksTableNameForCollectionFragmentName.insert( std::make_pair( fragmentName, linksTableName ) ); - - // Create table description for data table. - coral::TableDescription dataTableDescription( - pool::RelationalCollection::RelationalCollectionNames::collectionTypeName() ); - dataTableDescription.setName( dataTableName ); - - // Add primary key column to data table. - dataTableDescription.insertColumn( - pool::RelationalCollection::RelationalCollectionNames::recordIdVariableInCollectionDataTable(), - coral::AttributeSpecification::typeNameForType<unsigned>() ); - - // Set primary key of data table. - dataTableDescription.setPrimaryKey( - pool::RelationalCollection::RelationalCollectionNames::recordIdVariableInCollectionDataTable() ); - - // Create data table of collection fragment and define user privileges. - nominalSchema.createTable( dataTableDescription ); //.privilegeManager().grantToPublic( coral::ITablePrivilegeManager::Select ); - - // Create description object for links table of collection fragment. - coral::TableDescription linksTableDescription( - pool::RelationalCollection::RelationalCollectionNames::collectionTypeName() ); - linksTableDescription.setName( linksTableName ); - - // Add link table ID and Token key information to links table schema: - linksTableDescription.insertColumn( - pool::RelationalCollection::RelationalCollectionNames::linkIdVariableInCollectionLinksTable(), - coral::AttributeSpecification::typeNameForType<unsigned>() ); - linksTableDescription.insertColumn( - pool::RelationalCollection::RelationalCollectionNames::databaseIdVariableInCollectionLinksTable(), - coral::AttributeSpecification::typeNameForType<std::string>() ); - linksTableDescription.insertColumn( - pool::RelationalCollection::RelationalCollectionNames::containerIdVariableInCollectionLinksTable(), - coral::AttributeSpecification::typeNameForType<std::string>() ); - linksTableDescription.insertColumn( - pool::RelationalCollection::RelationalCollectionNames::classIdVariableInCollectionLinksTable(), - coral::AttributeSpecification::typeNameForType<std::string>() ); - linksTableDescription.insertColumn( - pool::RelationalCollection::RelationalCollectionNames::technologyIdVariableInCollectionLinksTable(), - coral::AttributeSpecification::typeNameForType<unsigned>() ); - - // Set primary key for links table. - linksTableDescription.setPrimaryKey( - pool::RelationalCollection::RelationalCollectionNames::linkIdVariableInCollectionLinksTable() ); - - // Create links table for new collection fragment and define user privileges. - nominalSchema.createTable( linksTableDescription ); //.privilegeManager().grantToPublic( coral::ITablePrivilegeManager::Select ); - - // Add row for new collection fragment into collection headers table. - coral::AttributeList headersRowBuffer; - headersRowBuffer.extend<std::string>( - RelationalCollectionNames::collectionNameVariableInCollectionHeadersTable() ); - headersRowBuffer.extend<std::string>( - RelationalCollectionNames::dataTableNameVariableInCollectionHeadersTable() ); - headersRowBuffer.extend<std::string>( - RelationalCollectionNames::linksTableNameVariableInCollectionHeadersTable() ); - headersRowBuffer.extend<unsigned>( - RelationalCollectionNames::writtenRecordsVariableInCollectionHeadersTable() ); - headersRowBuffer.extend<unsigned>( - RelationalCollectionNames::deletedRecordsVariableInCollectionHeadersTable() ); - headersRowBuffer.extend<std::string>( - RelationalCollectionNames::childCollectionNameVariableInCollectionHeadersTable() ); - headersRowBuffer.extend<std::string>( - RelationalCollectionNames::foreignKeyNameVariableInCollectionHeadersTable() ); - coral::AttributeList::iterator iAttribute = headersRowBuffer.begin(); - iAttribute->data< std::string >() = fragmentName; - ++iAttribute; - iAttribute->data< std::string >() = dataTableName; - ++iAttribute; - iAttribute->data< std::string >() = linksTableName; - ++iAttribute; - iAttribute->data< unsigned >() = 0; - ++iAttribute; - iAttribute->data< unsigned >() = 0; - ++iAttribute; - iAttribute->data< std::string >() = childFragmentName; - ++iAttribute; - iAttribute->data< std::string >() = foreignKeyName; - nominalSchema.tableHandle( RelationalCollectionNames::nameOfCollectionHeadersTable() ).dataEditor().insertRow( headersRowBuffer ); - - // Lock new row of collection headers table. - coral::IQuery* query = nominalSchema.tableHandle( - RelationalCollectionNames::nameOfCollectionHeadersTable() ).newQuery(); - m_whereDataForCollectionNameInHeadersTable->begin()->data<std::string>() = fragmentName; - query->setForUpdate(); - query->setCondition( m_whereClauseForCollectionNameInHeadersTable, *m_whereDataForCollectionNameInHeadersTable ); - query->limitReturnedRows( 1, 0 ); - query->execute(); - delete query; - } - else { - // Get name of data table for existing collection fragment. - dataTableName = m_dataTableNameForCollectionFragmentName.find( fragmentName )->second; - - // Update child collection fragment and foreign key names of existing collection fragment. - m_whereDataForCollectionNameInHeadersTable->begin()->data<std::string>() = fragmentName; - std::string setClause = RelationalCollectionNames::childCollectionNameVariableInCollectionHeadersTable() + " = " + childFragmentName + " , " + RelationalCollectionNames::foreignKeyNameVariableInCollectionHeadersTable() + " = " + foreignKeyName; - nominalSchema.tableHandle( RelationalCollectionNames::nameOfCollectionHeadersTable() ).dataEditor().updateRows( - setClause, - m_whereClauseForCollectionNameInHeadersTable, - *m_whereDataForCollectionNameInHeadersTable ); - } - - // Create foreign key constraint on parent collection fragment if specified in new collection description. - if( parentForeignKeyName.size() > 0 ) { - std::string parentDataTableName = ( m_dataTableNameForCollectionFragmentName.find( parentFragmentName ) )->second; - nominalSchema.tableHandle( dataTableName ).schemaEditor().createForeignKey( - parentForeignKeyName, - RelationalCollectionNames::recordIdVariableInCollectionDataTable(), - parentDataTableName, - RelationalCollectionNames::recordIdVariableInCollectionDataTable() ); - } - - // Create foreign key constraint on new collection fragment if specified in new collection description. - if ( foreignKeyName.size() > 0 ) { - std::string childDataTableName = ( m_dataTableNameForCollectionFragmentName.find( childFragmentName ) )->second; - nominalSchema.tableHandle( childDataTableName ).schemaEditor().createForeignKey( - foreignKeyName, RelationalCollectionNames::recordIdVariableInCollectionDataTable(), - dataTableName, RelationalCollectionNames::recordIdVariableInCollectionDataTable() ); - } - - // Update private maps in case collection fragment is associated with a pre-existing data table. - const pool::ICollectionFragment& fragment = m_description->collectionFragment( fragmentName ); - coral::AttributeList* dataTableRowBuffer = new coral::AttributeList; - int tokPos = 0; - for (pool::CollectionColumn* column : fragment.tokenColumns()) - { - std::string collectionColumnName = column->name(); - std::string variableName = RelationalCollectionNames::variableDataVariableInCollectionDataTable( tokPos ); - std::string tableColumnPrefix = dataTableName + "." + variableName + "_"; - //std::cout << " >>>> Adding Token Column prefix: " << collectionColumnName - // << ", " << tableColumnPrefix << std::endl; - m_tableTokenColumnPrefixForCollectionTokenColumnName.insert( std::make_pair( collectionColumnName, tableColumnPrefix ) ); - m_tableColumnNameForCollectionColumnName.insert( std::make_pair( collectionColumnName, tableColumnPrefix ) ); - m_collectionColumnNameForTableColumnPosition[ tokPos ] = collectionColumnName; - addTokenColumnToRowBuffer( dataTableRowBuffer, tableColumnPrefix ); - - std::string oid1VariableName = variableName + "_" + RelationalCollectionNames::oid_1_variableInCollectionDataTable(); - std::string whereClause = oid1VariableName + " =:" + oid1VariableName; - m_mapOfWhereClausesForOID1InDataTable.insert( std::make_pair( collectionColumnName, whereClause ) ); - coral::AttributeList* whereData = new coral::AttributeList; - whereData->extend<unsigned>( oid1VariableName ); - m_mapOfWhereDataForOID1InDataTable.insert( std::make_pair( collectionColumnName, whereData ) ); - tokPos++; - } - int attrPos = 0; - for (pool::CollectionColumn* column : fragment.attributeColumns()) - { - std::string collectionColumnName = column->name(); - std::string columnType = column->type(); - std::string tableColumnName = dataTableName + "." + RelationalCollectionNames::variableDataVariableInCollectionDataTable( attrPos ); - m_tableAttributeColumnNameForCollectionAttributeColumnName.insert( std::make_pair( collectionColumnName, - tableColumnName ) ); - m_tableColumnNameForCollectionColumnName.insert( std::make_pair( collectionColumnName, tableColumnName ) ); - m_collectionColumnNameForTableColumnPosition[ attrPos ] = collectionColumnName; - dataTableRowBuffer->extend( tableColumnName, columnType ); - attrPos++; - } - m_dataTableRowBufferForCollectionFragmentName.insert( std::make_pair( fragmentName, dataTableRowBuffer ) ); - - rebuildAttributeLists(); -} - - - -void -pool::RelationalCollection::RelationalCollectionSchemaEditor:: -rebuildAttributeLists( ) -{ - // Rebuild private row buffers. - pool::TokenList tokenList; - coral::AttributeList attributeList; - coral::AttributeList tableAttributeList; - for( int i = 0; i < m_description->numberOfCollectionFragments(); i++ ) - { - std::string fname = m_description->collectionFragment( i ).name(); - for( int j = 0; j < m_description->numberOfTokenColumns( fname ); j++ ) { - tokenList.extend( m_description->tokenColumn( j, fname ).name() ); - } - for( int j = 0; j < m_description->numberOfAttributeColumns( fname ); j++ ) - { - std::string collectionColumnName = m_description->attributeColumn( j, fname ).name(); - // MN: adding columnType - FIX? validate? - std::string columnType = m_description->attributeColumn( j, fname ).type(); - attributeList.extend( collectionColumnName, columnType ); - std::string tableColumnName = m_tableAttributeColumnNameForCollectionAttributeColumnName.find( collectionColumnName )->second; - tableAttributeList.extend( tableColumnName, columnType); - } - } - - m_collectionRowBuffer.setTokenList( tokenList ); - m_collectionRowBuffer.setAttributeList( attributeList ); - m_tableAttributeList = tableAttributeList; -} - - -void -pool::RelationalCollection::RelationalCollectionSchemaEditor:: -dropCollectionFragment( const std::string& fragmentName ) -{ - - // MN: This method was not tested and will for sure crash - - coral::ISchema& nominalSchema = m_session->nominalSchema(); - - // Get names of parent and child collection fragments and child fragment data table. - std::string parentFragmentName = m_description->collectionFragment( fragmentName ).parentCollectionFragmentName(); - std::string childFragmentName = m_description->collectionFragment( fragmentName ).childCollectionFragmentName(); - std::string childDataTableName; - - // Drop foreign key constraint on parent collection fragment if constraint exists. - if( parentFragmentName.size() ) { - std::string oldParentForeignKeyName = m_description->collectionFragment( parentFragmentName ).foreignKeyName(); - if ( oldParentForeignKeyName.size() > 0 ) { - std::string dataTableName = m_dataTableNameForCollectionFragmentName.find( fragmentName )->second; - nominalSchema.tableHandle( dataTableName ).schemaEditor().dropForeignKey( oldParentForeignKeyName ); - } - } - - // Drop foreign key constraint on collection fragment if constraint exists. - if( childFragmentName.size() ) { - childDataTableName = m_dataTableNameForCollectionFragmentName.find( childFragmentName )->second; - string foreignKeyName = m_description->collectionFragment( fragmentName ).foreignKeyName(); - if( foreignKeyName.size() ) { - nominalSchema.tableHandle( childDataTableName ).schemaEditor().dropForeignKey( foreignKeyName ); - } - } - - // Drop collection fragment from collection description object. - m_description->dropCollectionFragment( fragmentName ); - - // Create new foreign key constraint on parent collection fragment from child collection fragment if constraint specified. - std::string parentForeignKeyName = m_description->collectionFragment( parentFragmentName ).foreignKeyName(); - if ( parentForeignKeyName.size() > 0 ) - { - std::string parentDataTableName = ( m_dataTableNameForCollectionFragmentName.find( parentFragmentName ) )->second; - nominalSchema.tableHandle( childDataTableName ).schemaEditor().createForeignKey( - parentForeignKeyName, - pool::RelationalCollection::RelationalCollectionNames::recordIdVariableInCollectionDataTable(), - parentDataTableName, - pool::RelationalCollection::RelationalCollectionNames::recordIdVariableInCollectionDataTable() ); - } - - // Update parent collection fragment row in collection headers table. - if( parentFragmentName.size() > 0 ) { - m_whereDataForCollectionNameInHeadersTable->begin()->data<std::string>() = parentFragmentName; - std::string setClause = RelationalCollectionNames::childCollectionNameVariableInCollectionHeadersTable() + " = " + childFragmentName + " , " + RelationalCollectionNames::foreignKeyNameVariableInCollectionHeadersTable() + " = " + parentForeignKeyName; - nominalSchema.tableHandle( - RelationalCollectionNames::nameOfCollectionHeadersTable() ).dataEditor().updateRows( - setClause, - m_whereClauseForCollectionNameInHeadersTable, - *m_whereDataForCollectionNameInHeadersTable ); - } - - // Update collection fragment row in collection headers table. - if( parentFragmentName.size() > 0 ) { - m_whereDataForCollectionNameInHeadersTable->begin()->data<std::string>() = fragmentName; - std::string setClause = RelationalCollectionNames::childCollectionNameVariableInCollectionHeadersTable() + " = " + "\'\'" + " , " + RelationalCollectionNames::foreignKeyNameVariableInCollectionHeadersTable() + " = " + "\'\'"; - nominalSchema.tableHandle( - RelationalCollectionNames::nameOfCollectionDescriptionsTable() ).dataEditor().updateRows( - setClause, - m_whereClauseForCollectionNameInHeadersTable, - *m_whereDataForCollectionNameInHeadersTable ); - } - - // Drop collection collection fragment from private maps. - m_dataTableNameForCollectionFragmentName.erase( fragmentName ); - m_linksTableNameForCollectionFragmentName.erase( fragmentName ); - delete ( m_dataTableRowBufferForCollectionFragmentName.find( fragmentName ) )->second; - ( m_dataTableRowBufferForCollectionFragmentName.find( fragmentName ) )->second = 0; - m_dataTableRowBufferForCollectionFragmentName.erase( fragmentName ); - for( int i = 0; i < m_description->numberOfTokenColumns( fragmentName ); i++ ) - { - std::string collectionColumnName = m_description->tokenColumn( i, fragmentName ).name(); - m_tableTokenColumnPrefixForCollectionTokenColumnName.erase( collectionColumnName ); - m_tableColumnNameForCollectionColumnName.erase( collectionColumnName ); - for ( std::map< int, std::string >::iterator iData = m_collectionColumnNameForTableColumnPosition.begin(); - iData != m_collectionColumnNameForTableColumnPosition.end(); ++iData ) - { - if ( iData->second == collectionColumnName ) { - m_collectionColumnNameForTableColumnPosition.erase( iData->first ); - break; - } - } - m_mapOfWhereClausesForOID1InDataTable.erase( collectionColumnName ); - delete ( m_mapOfWhereDataForOID1InDataTable.find( collectionColumnName ) )->second; - ( m_mapOfWhereDataForOID1InDataTable.find( collectionColumnName ) )->second = 0; - m_mapOfWhereDataForOID1InDataTable.erase( collectionColumnName ); - } - for( int i = 0; i < m_description->numberOfAttributeColumns( fragmentName ); i++ ) { - std::string collectionColumnName = m_description->attributeColumn( i, fragmentName ).name(); - m_tableAttributeColumnNameForCollectionAttributeColumnName.erase( collectionColumnName ); - m_tableColumnNameForCollectionColumnName.erase( collectionColumnName ); - for ( std::map< int, std::string >::iterator iData = m_collectionColumnNameForTableColumnPosition.begin(); - iData != m_collectionColumnNameForTableColumnPosition.end(); ++iData ) - { - if ( iData->second == collectionColumnName ) { - m_collectionColumnNameForTableColumnPosition.erase( iData->first ); - break; - } - } - } - - rebuildAttributeLists(); -} - - -void -pool::RelationalCollection::RelationalCollectionSchemaEditor:: -renameCollectionFragment( const std::string& oldName, const std::string& newName ) -{ - // Rename collection fragment in collection description object. - m_description->renameCollectionFragment( oldName, newName ); - coral::ISchema& nominalSchema = m_session->nominalSchema(); - - // Change collection fragment name in collection headers table. - m_whereDataForCollectionNameInHeadersTable->begin()->data<std::string>() = oldName; - std::string setClause = RelationalCollectionNames::collectionNameVariableInCollectionHeadersTable() + " = " + newName; - nominalSchema.tableHandle( - RelationalCollectionNames::nameOfCollectionHeadersTable() ).dataEditor().updateRows( - setClause, - m_whereClauseForCollectionNameInHeadersTable, - *m_whereDataForCollectionNameInHeadersTable ); - - // Change child collection fragment name in collection headers table. - m_whereDataForChildCollectionNameInHeadersTable->begin()->data<std::string>() = oldName; - setClause = RelationalCollectionNames::childCollectionNameVariableInCollectionHeadersTable() + " = " + newName; - nominalSchema.tableHandle( - RelationalCollectionNames::nameOfCollectionHeadersTable() ).dataEditor().updateRows( - setClause, - m_whereClauseForChildCollectionNameInHeadersTable, - *m_whereDataForChildCollectionNameInHeadersTable ); - - // Change collection fragment name in collection descriptions table. - m_whereDataForCollectionNameInDescriptionsTable->begin()->data<std::string>() = oldName; - setClause = RelationalCollectionNames::collectionNameVariableInCollectionDescriptionsTable() + " = " + newName; - nominalSchema.tableHandle( - RelationalCollectionNames::nameOfCollectionDescriptionsTable() ).dataEditor().updateRows( - setClause, - m_whereClauseForCollectionNameInDescriptionsTable, - *m_whereDataForCollectionNameInDescriptionsTable ); - - // Change collection fragment name and associated index in index and unique constraint descriptions table. - m_whereDataForCollectionNameInIndexDescriptionsTable->begin()->data<std::string>() = oldName; - for( int i = 0; i < m_description->numberOfIndices(); i++ ) - { - const pool::ICollectionIndex& index = m_description->index( i ); - std::vector< std::string > columnNames = index.columnNames(); - if ( m_description->collectionFragmentName( *( columnNames.begin() ) ) == newName ) - { - // Note: Index and unique constraint names need to be reset because they were changed by collection description update. - std::string indexName = index.name(); - std::string uniqueConstraintName = "\'\'"; - if ( index.isUnique() ) - { - uniqueConstraintName = indexName; - } - std::string setClause = RelationalCollectionNames::indexNameVariableInCollectionIndexDescriptionsTable() + " = " + indexName + " , " + RelationalCollectionNames::uniqueConstraintNameVariableInCollectionIndexDescriptionsTable() + " = " + uniqueConstraintName + " , " + RelationalCollectionNames::collectionNameVariableInCollectionIndexDescriptionsTable() + " = " + newName; - nominalSchema.tableHandle( RelationalCollectionNames::nameOfCollectionIndexDescriptionsTable() ).dataEditor().updateRows( - setClause, - m_whereClauseForCollectionNameInIndexDescriptionsTable, - *m_whereDataForCollectionNameInIndexDescriptionsTable ); - } - } - - // Change collection fragment name and associated unique constraint in index and unique constraint descriptions table. - m_whereDataForCollectionNameInIndexDescriptionsTable->begin()->data<std::string>() = oldName; - for( int i = 0; i < m_description->numberOfUniqueConstraints(); i++ ) - { - const pool::ICollectionUniqueConstraint& constraint = m_description->uniqueConstraint( i ); - std::vector< std::string > columnNames = constraint.columnNames(); - if ( m_description->collectionFragmentName( *( columnNames.begin() ) ) == newName ) - { - // Note: Unique constraint names need to be reset because they were changed by collection description update. - std::string constraintName = constraint.name(); - std::string setClause = RelationalCollectionNames::uniqueConstraintNameVariableInCollectionIndexDescriptionsTable() + " = " + constraintName + " , " + RelationalCollectionNames::collectionNameVariableInCollectionIndexDescriptionsTable() + " = " + newName; - nominalSchema.tableHandle( RelationalCollectionNames::nameOfCollectionIndexDescriptionsTable() ).dataEditor().updateRows( - setClause, - m_whereClauseForCollectionNameInIndexDescriptionsTable, - *m_whereDataForCollectionNameInIndexDescriptionsTable ); - } - } - - // Update private maps. - std::string dataTableName = ( m_dataTableNameForCollectionFragmentName.find( oldName ) )->second; - m_dataTableNameForCollectionFragmentName.erase( oldName ); - m_dataTableNameForCollectionFragmentName.insert( std::make_pair( newName, dataTableName ) ); - std::string linksTableName = ( m_linksTableNameForCollectionFragmentName.find( oldName ) )->second; - m_linksTableNameForCollectionFragmentName.erase( oldName ); - m_linksTableNameForCollectionFragmentName.insert( std::make_pair( newName, linksTableName ) ); -} diff --git a/Database/APR/RelationalCollection/src/RelationalCollectionSchemaEditor.h b/Database/APR/RelationalCollection/src/RelationalCollectionSchemaEditor.h deleted file mode 100755 index 6af41c931117c6657a105865373487d10309c742..0000000000000000000000000000000000000000 --- a/Database/APR/RelationalCollection/src/RelationalCollectionSchemaEditor.h +++ /dev/null @@ -1,394 +0,0 @@ -/* - Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration -*/ - -#ifndef RELATIONALCOLLECTION_RELATIONALCOLLECTIONSCHEMAEDITOR_H -#define RELATIONALCOLLECTION_RELATIONALCOLLECTIONSCHEMAEDITOR_H - -#include "CollectionBase/ICollectionSchemaEditor.h" - -#include <map> - - -namespace coral { - class ISessionProxy; - class AttributeList; -} - -namespace pool { - - class ICollectionDescription; - class CollectionDescription; - class CollectionRowBuffer; - - namespace RelationalCollection { - - /** - * @class RelationalCollectionSchemaEditor RelationalCollectionSchemaEditor.h src/RelationalCollectionSchemaEditor.h - * - * An implementation of the ICollectionSchemaEditor interface used to define the schema of a collection. - */ - class RelationalCollectionSchemaEditor : virtual public ICollectionSchemaEditor - { - public: - /** - * Constructor. - * - * @param session Reference to current database access session. - * @param description Specification of collection properties. - * @param dataTableNameForCollectionFragmentName Map of data table names using names of corresponding collection fragment names as keys. - * @param linksTableNameForCollectionFragmentName Map of links table names using names of corresponding collection fragment names as keys. - * @param tableTokenColumnPrefixForCollectionTokenColumnName Map of table column prefixes for Tokens using names of corresponding collection columns as keys. - * @param tableAttributeColumnNameForCollectionAttributeColumnName Map of table column names for Attributes using names of corresponding collection columns as keys. - * @param tableColumnNameForCollectionColumnName Map of table column names or prefixes using names of corresponding collection columns as keys. - * @param collectionColumnNameForTableColumnPosition Map of collection column names using positions of corresponding table columns as keys. - * @param tableAttributeList List of all Attributes defined by collection but using table column names. - * @param collectionRowBuffer Collection row buffer containing all Tokens and Attributes defined by collection. - * @param dataTableRowBufferForCollectionFragmentName Map of data table row buffers using names of corresponding collection fragments as keys. - * @param mapOfWhereClausesForOID1InDataTable Map of where clauses for finding Token OID_1 values in data tables, using Token names as keys. - * @param mapOfWhereDataForOID1InDataTable Map of where data for finding Token OID_1 values in data tables, using Token names as keys. - */ - RelationalCollectionSchemaEditor( - coral::ISessionProxy& session, - pool::ICollectionDescription& description, - std::map< std::string, std::string >& dataTableNameForCollectionFragmentName, - std::map< std::string, std::string >& linksTableNameForCollectionFragmentName, - std::map< std::string, std::string >& tableTokenColumnPrefixForCollectionTokenColumnName, - std::map< std::string, std::string >& tableAttributeColumnNameForCollectionAttributeColumnName, - std::map< std::string, std::string >& tablColumnNameForCollectionColumnName, - std::map< int, std::string >& collectionColumnNameForTableColumnPosition, - coral::AttributeList& tableAttributeList, - pool::CollectionRowBuffer& collectionRowBuffer, - std::map< std::string, coral::AttributeList* >& dataTableRowBufferForCollectionFragmentName, - std::map< std::string, std::string >& mapOfWhereClausesForOID1InDataTable, - std::map< std::string, coral::AttributeList* >& mapOfWhereDataForOID1InDataTable ); - - /// Default constructor. - ~RelationalCollectionSchemaEditor(); - - RelationalCollectionSchemaEditor (const RelationalCollectionSchemaEditor&) = delete; - RelationalCollectionSchemaEditor& operator= (const RelationalCollectionSchemaEditor&) = delete; - - /** - * Sets the name of the event reference Token column. Otherwise a default name is used. - * - * @param columnName Name of event reference Token column. - */ - virtual void setEventReferenceColumnName( const std::string& columnName ); - - /** - * Adds a new column to the collection fragment specified as input. If no collection - * fragment is specified the column is added to the top level collection fragment. - * Throws an exception if the specified collection fragment has not been declared - * to be part of the collection via a call to the method `addCollectionFragment'. - * - * @param columnName Name of new column. - * @param columnType Data type of new column. - * @param fragmentName Name of collection fragment to contain new column. - * @param maxSize Maximum size of column data type (useful for string or blob data types). - * @param sizeIsFixed Flag indicating whether size of column data type is fixed (useful for string or blob data types). - */ - virtual const ICollectionColumn& insertColumn( const std::string& columnName, - const std::string& columnType, - const std::string& annotation = "", - std::string fragmentName = "", - int maxSize = 0, - bool sizeIsFixed = true ); - - /** - * Adds a new column to the collection fragment specified as input. If no collection - * fragment is specified the column is added to the top level collection fragment. - * Throws an exception if the specified collection fragment has not been declared to be - * part of the collection via a call to the method `addCollectionFragment'. - * - * @param columnName Name of new column. - * @param columnType Data type of new column. - * @param fragmentName Name of collection fragment to contain new column. - * @param maxSize Maximum size of column data type (useful for string or blob data types). - * @param sizeIsFixed Flag indicating whether size of column data type is fixed (useful for string or blob data types). - */ - virtual const ICollectionColumn& insertColumn( const std::string& columnName, - const std::type_info& columnType, - const std::string& annotation = "", - std::string fragmentName = "", - int maxSize = 0, - bool sizeIsFixed = true ); - - /** - * Adds a new column of type pool::Token to the collection fragment specified as input. - * If no collection fragment is specified the column is added to the top level collection - * fragment. Throws an exception if the specified collection fragment has not been declared to be - * part of the collection via a call to the method `addCollectionFragment'. Throws an exception if - * an attempt is made to add the event reference Token column to any other collection fragment - * than the top level fragment. - * - * @param columnName Name of new column. - * @param fragmentName Name of collection fragment to contain new column. - */ - virtual const ICollectionColumn& insertTokenColumn( const std::string& columnName, - const std::string& annotation = "", - std::string fragmentName = "" ); - - - /// add annotation to column - virtual const ICollectionColumn& annotateColumn( const std::string& columnName, - const std::string& annotation ); - - - - // Add row for new column into collection descriptions table. - virtual void addRowToDescriptionsTable(const std::string& fragmentName, - const std::string& columnName, - const std::string& annotation, - const std::string& colType, unsigned maxSize, - const std::string& isFixed, unsigned newPos ); - - // update all the maps (in RelationalCollection) when adding a new token column - virtual void addTokenColumnToMaps( std::string variableName, - const std::string& columnName, int columnPos ); - - virtual void addTokenColumnToRowBuffer( coral::AttributeList* rowBuffer, - const std::string& tableColumnPrefix ); - - virtual void addColumnToMaps( const std::string& columnName, - const std::string& tableColumnName, - const std::string& columntype, int columnPos ); - - virtual void recreateDataTableRowBuffer( const std::string& fragmentName ); - - /** - * Removes a column from the collection. - * - * @param columnName Name of column to be removed. - */ - virtual void dropColumn( const std::string& columnName ); - - /** - * Renames a column of the collection. - * - * @param oldName Old name of column. - * @param newName New name of column. - */ - virtual void renameColumn( const std::string& oldName, const std::string& newName ); - - /** - * Changes the data type of a column in the collection. Throws an exception if an attempt is - * made to change the data type of the event reference Token column. - * - * @param columnName Name of column whose type is to be changed. - * @param newType New data type assigned to column. - * @param maxSize Maximum size of new data type (useful for string and blob types). - * @param sizeIsFixed Flag indicating whether size of new data type is fixed (useful for string and blob types). - */ - virtual void changeColumnType( const std::string& columnName, - const std::string& newType, - int maxSize = 0, - bool sizeIsFixed = true ); - - /** - * Changes the data type of a column in the collection. Throws an exception if an attempt is - * made to change the data type of the event reference Token column. - * - * @param columnName Name of column whose type is to be changed. - * @param newType New data type assigned to column. - * @param maxSize Maximum size of new data type (useful for string and blob types). - * @param sizeIsFixed Flag indicating whether size of new data type is fixed (useful for string and blob types). - */ - virtual void changeColumnType( const std::string& columnName, - const std::type_info& newType, - int maxSize = 0, - bool sizeIsFixed = true ); - - /** - * Creates an index on a column of the collection. Automatically generates a unique name for the index. - * - * @param columnName Name of column for which index is created. - * @param isUnique Flag to indicate whether indexed column values must be unique. - */ - virtual void createIndex( std::string indexName, - const std::string& columnName, - bool isUnique = false ); - - /** - * Creates an index on one or more columns of the collection. Automatically generates a unique name - * for the index - * - * @param columnNames Names of columns for which index is to be created. - * @param isUnique Flag to indicates whether combination of indexed column values must be unique. - */ - virtual void createIndex( std::string indexName, - const std::vector< std::string >& columnNames, - bool isUnique = false ); - - /** - * Removes an index from the collection, given the name of the column on - * which the index to be removed is applied. - * - * @param columnName Name of column on which index to be removed is applied. - */ - virtual void dropIndex( const std::string& columnName ); - - /** - * Removes an index from a column of the collection, given the names of the columns on - * which the index to be removed is applied. - * - * @param columnNames Names of columns on which index to be removed is applied. - */ - virtual void dropIndex( const std::vector<std::string>& columnNames ); - - /** - * Sets a unique constraint on a column of the collection. Automatically generates a unique name - * for the unique constraint. - * - * @param columnName Name of column for which constraint is applied. - */ - void setUniqueConstraint( const std::string& constraintName, const std::string& columnName ); - - /** - * Sets a unique constraint on one or more columns of the collection. Automatically generates a - * unique name for the unique constraint. - * - * @param columnNames Names of columns for which constraint is applied. - */ - void setUniqueConstraint( const std::string& constraintName, const std::vector<std::string>& columnNames ); - - /** - * Unsets an existing unique constraint on a single column of the collection, - * given the name of the column. - * - * @param columnName Name of column used by unique constraint to be unset. - */ - void unsetUniqueConstraint( const std::string& columnName ); - - /** - * Unsets an existing unique constraint on one or more columns of the colleciton, - * given the names of the columns. - * - * @param columnNames Names of columns used by unique constraint to be unset. - */ - void unsetUniqueConstraint( const std::vector<std::string>& columnNames ); - - /** - * Adds a collection fragment to the collection. If no parent collection fragment name is provided - * as input the last collection fragment in the fragment chain is assigned as the parent collection fragment of - * the new collection fragment. - * - * @param fragmentName Name of collection fragment to add to collection. - * @param parentFragmentName Name of collection fragment to assign as parent of new collection fragment. - * @param usesForeignKey Flag indicating whether new fragment is to reference its parent fragment via a foreign key. - */ - virtual void addCollectionFragment( const std::string& fragmentName, - std::string parentFragmentName = "", - bool usesForeignKey = true ); - - /** - * Drops a collection fragment from the collection. After the fragment is dropped its parent - * collection fragment is assigned as the new parent of its child collection fragment. - * - * @param fragmentName Name of collection fragment to drop from collection description. - */ - virtual void dropCollectionFragment( const std::string& fragmentName ); - - /** - * Renames a collection fragment in the collection. Regenerates unique names for all indices, - * unique constraints and foreign key constraints defined for the fragment. - * - * @param oldName Old name of collection fragment. - * @param newName New name of collection fragment. - */ - virtual void renameCollectionFragment( const std::string& oldName, const std::string& newName ); - - virtual const std::string& dataTableNameForCollectionFragmentName( const std::string& fragmentName, const std::string& methodName ) const; - - protected: - - // refresh the attribute lists after adding or removing collection fragments - void rebuildAttributeLists(); - - private: - /// Reference to current database access session. - coral::ISessionProxy *m_session; - - /// Specification of collection properties. - CollectionDescription *m_description; - - /// Map of data table names using names of corresponding collection fragment names as keys. - std::map< std::string, std::string >& m_dataTableNameForCollectionFragmentName; - - /// Map of links table names using names of corresponding collection fragment names as keys. - std::map< std::string, std::string >& m_linksTableNameForCollectionFragmentName; - - /// Map of table column prefixes for Tokens using names of corresponding collection columns as keys. - std::map< std::string, std::string >& m_tableTokenColumnPrefixForCollectionTokenColumnName; - - /// Map of table column names for Attributes using names of corresponding collection columns as keys. - std::map< std::string, std::string >& m_tableAttributeColumnNameForCollectionAttributeColumnName; - - /// Map of table column names or prefixes using names of corresponding collection columns as keys. - std::map< std::string, std::string >& m_tableColumnNameForCollectionColumnName; - - /// Map of collection column names using positions of corresponding table columns as keys. - std::map< int, std::string >& m_collectionColumnNameForTableColumnPosition; - - /// List of all Attributes defined by collection but using table column names. - coral::AttributeList& m_tableAttributeList; - - /// Collection row buffer containing all Tokens and Attributes defined by collection. - CollectionRowBuffer& m_collectionRowBuffer; - - /// Map of data table row buffers using names of corresponding collection fragments as keys. - std::map< std::string, coral::AttributeList* >& m_dataTableRowBufferForCollectionFragmentName; - - /// Map of where clauses for finding Token OID_1 values in data tables, using Token names as keys. - std::map< std::string, std::string >& m_mapOfWhereClausesForOID1InDataTable; - - /// Map of where data for finding Token OID_1 values in data tables, using Token names as keys. - std::map< std::string, coral::AttributeList* >& m_mapOfWhereDataForOID1InDataTable; - - /// Where clause for finding collection fragment name in collection headers table. - std::string m_whereClauseForCollectionNameInHeadersTable; - - /// Where clause for finding child collection fragment name in collection headers table. - std::string m_whereClauseForChildCollectionNameInHeadersTable; - - /// Where clause for finding collection fragment name in collection descriptions table. - std::string m_whereClauseForCollectionNameInDescriptionsTable; - - /// Where clause for finding column name in collection descriptions table. - std::string m_whereClauseForColumnNameInDescriptionsTable; - - /// Where clause for finding collection fragment name in index and unique constraints descriptions table. - std::string m_whereClauseForCollectionNameInIndexDescriptionsTable; - - // Where clause for finding index name in index and unique constraint descriptions table. - std::string m_whereClauseForIndexNameInIndexDescriptionsTable; - - // Where clause for finding unique constraint name in index and unique constraint descriptions table. - std::string m_whereClauseForUniqueConstraintNameInIndexDescriptionsTable; - - /// Bind data for collection headers table collection fragment name where clause. - coral::AttributeList* m_whereDataForCollectionNameInHeadersTable; - - /// Bind data for collection headers table child collection fragment name where clause. - coral::AttributeList* m_whereDataForChildCollectionNameInHeadersTable; - - /// Bind data for collection descriptions table collection fragment name where clause. - coral::AttributeList* m_whereDataForCollectionNameInDescriptionsTable; - - /// Bind data for collection descriptions table column name where clause. - coral::AttributeList* m_whereDataForColumnNameInDescriptionsTable; - - /// Bind data for collection index descriptions table collection fragment name where clause. - coral::AttributeList* m_whereDataForCollectionNameInIndexDescriptionsTable; - - /// Bind data for collection index descriptions table index name where clause. - coral::AttributeList* m_whereDataForIndexNameInIndexDescriptionsTable; - - /// Bind data for collection index descriptions table unique constraint name where clause. - coral::AttributeList* m_whereDataForUniqueConstraintNameInIndexDescriptionsTable; - }; - } -} - -#endif - diff --git a/Database/APR/RelationalCollection/src/modules.cpp b/Database/APR/RelationalCollection/src/modules.cpp deleted file mode 100755 index 763935e8de4cd98dcfbe73e918b09aa1b4e42184..0000000000000000000000000000000000000000 --- a/Database/APR/RelationalCollection/src/modules.cpp +++ /dev/null @@ -1,9 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#include "RelationalCollection.h" - -using pool::RelationalCollection::RelationalCollection; - -DECLARE_COMPONENT_WITH_ID(RelationalCollection, "RelationalCollection") diff --git a/Database/APR/RelationalCollection/tests/WriteRead/TestDriver.cpp b/Database/APR/RelationalCollection/tests/WriteRead/TestDriver.cpp deleted file mode 100644 index cc62e2f831333f5086430dc0885b3bbaa2b182f3..0000000000000000000000000000000000000000 --- a/Database/APR/RelationalCollection/tests/WriteRead/TestDriver.cpp +++ /dev/null @@ -1,254 +0,0 @@ -/* - Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration -*/ - -#include "TestDriver.h" -#include <iostream> -#include <stdexcept> -#include <sstream> -#include <memory> - -#include "PersistentDataModel/Guid.h" -#include "PersistentDataModel/Token.h" - -#include "CollectionBase/ICollectionService.h" -#include "CollectionBase/CollectionService.h" -#include "CollectionBase/CollectionDescription.h" -#include "CollectionBase/ICollection.h" -#include "CollectionBase/CollectionRowBuffer.h" -#include "CollectionBase/TokenList.h" -#include "CollectionBase/ICollectionQuery.h" -#include "CollectionBase/ICollectionCursor.h" -#include "CollectionBase/ICollectionColumn.h" -#include "CollectionBase/ICollectionDataEditor.h" -#include "CollectionBase/ICollectionMetadata.h" - -#include "CoralBase/Attribute.h" -#include "CoralBase/AttributeList.h" - -int numTokenInstances(); - -using namespace std; -using namespace pool; - -TestDriver::TestDriver( const std::string& name, - const std::string& connection ) - : m_name( name ), m_connection( connection ) -{ -} - - -TestDriver::~TestDriver() -{ - std::cout << "Number of floating tokens : " << numTokenInstances() << std::endl; -} - - -void -TestDriver::write() -{ - cout << "Creationg CollectionService" << endl; - auto serviceHandle = std::unique_ptr<pool::CollectionService>(new pool::CollectionService); - - cout << "Creating a collection description object" << endl; - pool::CollectionDescription description( m_name, "RelationalCollection", m_connection, "MainEventRef" ); - - cout << "Creating new collection" << endl; - pool::ICollection* collection = serviceHandle->create( description, true ); - if ( ! collection ) { - throw std::runtime_error( "Could not create a relational collection object" ); - } - - cout << "Adding columns to the collection schema" << endl; - // (Event reference Token column was added by default upon collection creation). - collection->schemaEditor().insertColumn( "RowId", "int" ); - collection->schemaEditor().insertColumn( "Xx", "double", "This is user annotation for XX" ); - collection->schemaEditor().insertColumn( "Yy", "float" ); - collection->schemaEditor().insertColumn( "Empty", "string" ); - - collection->schemaEditor().annotateColumn( "Yy", "annotation for YY" ); - collection->schemaEditor().annotateColumn( "MainEventRef", "This is the main Event reference Token" ); - - cout << "Adding token columns..." << endl; - collection->schemaEditor().insertTokenColumn( "Ref", "This is a secondary Token attribute" ); - - // Get row buffer for adding data to collection. - pool::CollectionRowBuffer rowBuffer = collection->dataEditor().rowBuffer(); - - cout << "Adding rows to collection " << endl; - for ( unsigned i = 0; i < 10; ++i ) - { - // Add event reference Token to data buffer (this is always the first column in the row). - Token token; - token.setTechnology( 1 ); - token.setDb( "myDb" ); - std::ostringstream os; - os << "Container_" << i / 4; - token.setCont( os.str() ); - pool::TokenList::iterator iToken = rowBuffer.tokenList().begin(); - int tok_n = 1; - while( iToken != rowBuffer.tokenList().end() ) { - token.oid().first = i%4; - token.oid().second = 100000*tok_n + i; - if( iToken.tokenName() == "Ref" ) - token.oid().second += 1u<<31U; - token.setData( &*iToken ); - cout << "Storing token:" << iToken->toString() << endl; - tok_n++; ++iToken; - } - - // Add Attribute meta data to data buffer. - coral::AttributeList::iterator iAttribute = rowBuffer.attributeList().begin(); - iAttribute->data<int>() = i; - ++iAttribute; - iAttribute->data< double >() = i + 0.11; - ++iAttribute; - iAttribute->data< float >() = float(i + 0.22); - - // Add new row to collection. - collection->dataEditor().insertRow( rowBuffer ); - } - - - // Metadata test - ICollectionMetadata& metadata( collection->metadata() ); - metadata.setValueForKey("Author", "This collection has been created by WriteRead test from RelationalCollection package"); - - const char *author = metadata.getValueForKey("Author"); - if( !author ) { - throw std::runtime_error("The collection has no Author key in the metadata"); - } else { - cout << "Collection author metadata inserted: " << author << endl; - } - - metadata.setValueForKey("random1", "random metadata 1"); - metadata.setValueForKey("random5", "random metadata 5"); - metadata.setValueForKey("random1", "overwritten random metadata 1"); - - - cout << "Committing..." << endl; - collection->commit(); - - // Close collection. - collection->close(); - delete collection; -} - - -void -TestDriver::read() -{ - cout << " Retrieve handle to loaded collection service" << endl; - auto_ptr<pool::CollectionService> serviceHandle( new CollectionService ); - - cout << "Getting handle to existing collection ( opened for read-only transactions by default )" << endl; - pool::ICollection* collection = serviceHandle->handle( m_name, "RelationalCollection" , m_connection ); - - if( ! collection ) { - throw std::runtime_error( "Could not create a relational collection object" ); - } - - cout << "Executing query that only selects event reference column (the default)" << endl; - pool::ICollectionQuery* query1 = collection->newQuery(); - query1->setCondition( "Xx * Yy < 20 AND Xx > 2" ); - pool::ICollectionCursor& cursor1 = query1->execute(); - int counter = 0; - while ( cursor1.next() ) - { -//MN: std::cout << "Token : " << cursor1.currentRow().eventRef().toString() << std::endl; - std::cout << "Token : " << cursor1.eventRef().toString() << std::endl; - coral::AttributeList attributeList = cursor1.currentRow().attributeList(); - std::cout << "Meta data : "; - for( coral::AttributeList::const_iterator iAttribute = attributeList.begin(); - iAttribute != attributeList.end(); ++iAttribute ) - { - if ( iAttribute != attributeList.begin() ) std::cout << ", "; - std::cout << "["; - iAttribute->toOutputStream( std::cout ); - std::cout << "]"; - } - cout << endl; - counter++; - } - std::cout << counter << " records read back" << std::endl; - delete query1; - - // Execute query that selects 2 meta data columns. - pool::ICollectionQuery* query2 = collection->newQuery(); - query2->setCondition( "Xx * Yy < 20 AND Xx > 2" ); - query2->addToOutputList( "Xx" ); - query2->addToOutputList( "Yy" ); - pool::ICollectionCursor& cursor2 = query2->execute(); - counter = 0; - while ( cursor2.next() ) - { - //MN: std::cout << "Token : " << cursor2.currentRow().eventRef().toString() << std::endl; - std::cout << "Token : " << cursor2.eventRef().toString() << std::endl; - coral::AttributeList attributeList = cursor2.currentRow().attributeList(); - std::cout << "Meta data : "; - for ( coral::AttributeList::const_iterator iAttribute = attributeList.begin(); - iAttribute != attributeList.end(); ++iAttribute ) - { - if ( iAttribute != attributeList.begin() ) std::cout << ", "; - std::cout << "["; - iAttribute->toOutputStream( std::cout ); - std::cout << "]"; - } - cout << endl; - counter++; - } - std::cout << counter << " records read back" << std::endl; - delete query2; - - // Execute query that selects all meta data. - pool::ICollectionQuery* query3 = collection->newQuery(); - query3->setCondition( "Xx * Yy < 20 AND Xx > 2" ); - query3->selectAll(); - pool::ICollectionCursor& cursor3 = query3->execute(); - counter = 0; - while( cursor3.next() ) { - //MN: std::cout << "Token : " << cursor3.currentRow().eventRef().toString() << std::endl; - std::cout << "Token : " << cursor3.eventRef().toString() << std::endl; - coral::AttributeList attributeList = cursor3.currentRow().attributeList(); - std::cout << "Meta data : "; - for ( coral::AttributeList::const_iterator iAttribute = attributeList.begin(); - iAttribute != attributeList.end(); ++iAttribute ) - { - if ( iAttribute != attributeList.begin() ) std::cout << ", "; - std::cout << "["; - iAttribute->toOutputStream( std::cout ); - std::cout << "]"; - } - const pool::TokenList tokens = cursor3.currentRow().tokenList(); - std::cout << endl; - cout << "Token 2: " << tokens["Ref"].toString() << std::endl; - - cout << "-------- " << endl; - - counter++; - } - std::cout << counter << " records read back" << std::endl; - delete query3; - - - // Metadata test - const char *author = collection->metadata().getValueForKey("Author"); - if( !author ) { - cout << "The collection has no Author key in the metadata" << endl; - } else { - cout << "Collection author metadata: " << author << endl; - } - - std::cout << endl << "Dumping all metadata" << std::endl; - ICollectionMetadata::const_iterator mdIter - = collection->metadata().begin(); - while( mdIter != collection->metadata().end() ) { - cout << " Metadata Key=" << mdIter.key(); - cout << ", Value=" << mdIter.value() << endl; - ++mdIter; - } - - // Close collection. - collection->close(); - delete collection; -} diff --git a/Database/APR/RelationalCollection/tests/WriteRead/TestDriver.h b/Database/APR/RelationalCollection/tests/WriteRead/TestDriver.h deleted file mode 100644 index 461bccdee627ef7f6cec130e631b7032c9aa5328..0000000000000000000000000000000000000000 --- a/Database/APR/RelationalCollection/tests/WriteRead/TestDriver.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#ifndef TESTDRIVER_H -#define TESTDRIVER_H - -#include <string> - - -class TestDriver { -public: - TestDriver( const std::string& name, - const std::string& connection ); - - ~TestDriver(); - - void write(); - - void read(); - - -private: - std::string m_name; - std::string m_connection; -}; - -#endif diff --git a/Database/APR/RelationalCollection/tests/WriteRead/main.cpp b/Database/APR/RelationalCollection/tests/WriteRead/main.cpp deleted file mode 100644 index 332fdf0576076a11c44303cceca69d7b4b8fa593..0000000000000000000000000000000000000000 --- a/Database/APR/RelationalCollection/tests/WriteRead/main.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#include <iostream> -#include <cstdlib> -#include <exception> - -#ifdef WIN32 -# include <windows.h> -# define sleep(x) Sleep((x)*1000) /* Windows version */ -#else -# include <unistd.h> -#endif - -#include "TestDriver.h" - - -int main( int, char** ) -{ - try { - // const std::string userNameEnv = "CORAL_AUTH_USER=ral_writer"; -// ::putenv( const_cast<char*>( userNameEnv.c_str() ) ); -// const std::string passwdEnv = "CORAL_AUTH_PASSWORD=ral"; -// ::putenv( const_cast<char*>( passwdEnv.c_str() ) ); - -// const std::string connection = "write_test"; - const std::string connection = "POOL-Collection-Oracle-lcgnight"; - //const std::string connection = "sqlite://pool.db"; - //const std::string connection = "mysql://pcitdb59/IOANNISDB"; - - std::string name = "/My/First/Collection"; - std::cout << "ReadWrite test starting..." << std::endl; - - for ( int i = 0; i < 2; ++i ) { - TestDriver driver( name, connection ); - - std::cout << std::endl << "************************************" << std::endl; - std::cout << "Writing the collection" << std::endl; - driver.write(); - - ::sleep( 2 ); - - std::cout << std::endl << "************************************" << std::endl; - std::cout << "Reading the collection" << std::endl; - driver.read(); - - name = "/My/Second/Collection"; - } - - std::cout << "Exiting..." << std::endl; - } - catch ( std::exception& e ) { - std::cerr << "---> Exception:" << std::endl; - std::cerr << e.what() << std::endl; - return 1; - } - catch (...) { - std::cerr << "Unhandled exception..." << std::endl; - return 1; - } - return 0; -} diff --git a/Database/APR/RelationalCollection/tests/WriteUpdate/TestDriver.cpp b/Database/APR/RelationalCollection/tests/WriteUpdate/TestDriver.cpp deleted file mode 100644 index fc134b92363c827f0239f8b86536f803c235eb13..0000000000000000000000000000000000000000 --- a/Database/APR/RelationalCollection/tests/WriteUpdate/TestDriver.cpp +++ /dev/null @@ -1,175 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#include "TestDriver.h" -#include <iostream> -#include <stdexcept> -#include <sstream> -#include <memory> - -#include "PersistentDataModel/Guid.h" -#include "PersistentDataModel/Token.h" - -#include "CollectionBase/CollectionService.h" -#include "CollectionBase/CollectionDescription.h" -#include "CollectionBase/ICollection.h" -#include "CollectionBase/CollectionRowBuffer.h" -#include "CollectionBase/TokenList.h" -#include "CollectionBase/ICollectionQuery.h" -#include "CollectionBase/ICollectionCursor.h" -#include "CollectionBase/ICollectionColumn.h" -#include "CollectionBase/ICollectionDataEditor.h" - -#include "CoralBase/Attribute.h" -#include "CoralBase/AttributeList.h" - -#include <vector> -using namespace std; - -int numTokenInstances(); - -TestDriver::TestDriver( const std::string& name, - const std::string& connection ) - :m_name( name ), m_connection( connection ) -{ - // pool::POOLContext::loadComponent( "POOL/Services/EnvironmentAuthenticationService" ); -} - - -TestDriver::~TestDriver() -{ - std::cout << "Number of floating tokens : " << numTokenInstances() << std::endl; -} - - - -void -TestDriver::write() -{ - cout << "Creationg CollectionService" << endl; - unique_ptr<pool::CollectionService> serviceHandle( new pool::CollectionService() ); - - cout << "Creating a collection description object" << endl; - - // Create a collection description object. - pool::CollectionDescription description( m_name, "RelationalCollection", m_connection ); - - // Create new collection. - cout << "Creating new collection" << endl; - pool::ICollection* collection = serviceHandle->create( description, true ); - - if ( ! collection ) - { - throw std::runtime_error( "Could not create a relational collection object" ); - } - - // Add columns to the collection schema ( Event reference Token column was added by default upon collection creation ). - cout << "Adding columns to the collection schema" << endl; - collection->schemaEditor().insertColumn( "RowId", "int" ); - collection->schemaEditor().insertColumn( "Xx", "double" ); - collection->schemaEditor().insertColumn( "Yy", "float" ); - - collection->schemaEditor().insertTokenColumn( "Ref" ); - - // Get row buffer for adding data to collection. - pool::CollectionRowBuffer rowBuffer = collection->dataEditor().rowBuffer(); - - // Add rows to collection. - for ( unsigned long i = 0; i < 10; ++i ) - { - // Add event reference Token to data buffer (this is always the first column in the row). - Token token; - token.setTechnology( 1 ); - token.setDb( "myDb" ); - std::ostringstream os; - os << "Container_" << i / 4; - token.setCont( os.str() ); - pool::TokenList::iterator iToken = rowBuffer.tokenList().begin(); - int tok_n = 1; - while( iToken != rowBuffer.tokenList().end() ) { - token.oid().first = i%4; - token.oid().second = 1000*tok_n + i; - token.setData( &*iToken ); - cout << "Storing token:" << iToken->toString() << endl; - tok_n++; ++iToken; - } - - // Add Attribute meta data to data buffer. - coral::AttributeList::iterator iAttribute = rowBuffer.attributeList().begin(); - iAttribute->data<int>() = i; - ++iAttribute; - iAttribute->data< double >() = i + 0.11; - ++iAttribute; - iAttribute->data< float >() = float(i + 0.22); - - // Add new row to collection. - collection->dataEditor().insertRow( rowBuffer ); - } - - // Commit the new rows. - collection->commit(); - - // Close collection. - collection->close(); -} - - -void -TestDriver::update() -{ - unique_ptr<pool::CollectionService> serviceHandle( new pool::CollectionService ); - - // Create a collection description object. - cout << "Getting handle to existing collection" << endl; - pool::ICollection* collection = serviceHandle->handle( m_name, "RelationalCollection" , m_connection, false ); - - if( !collection ) { - throw std::runtime_error( "Could not create a relational collection object" ); - } - - // Get row buffer for adding data to collection. - pool::CollectionRowBuffer rowBuffer = collection->dataEditor().rowBuffer(); - - // Add rows to collection. - for ( unsigned long i = 0; i < 10; ++i ) - { - // Add event reference Token to data buffer (this is always the first column in the row). - Token token; - token.setTechnology( 1 ); - token.setDb( "myDb" ); - std::ostringstream os; - os << "Container_" << i / 4; - token.setCont( os.str() ); - token.oid().first = i%4; - token.oid().second = 1000 + i; - pool::TokenList::iterator iToken = rowBuffer.tokenList().begin(); - token.setData( &*iToken ); - cout << "Storing token:" << iToken->toString() << endl; - - // Add Attribute meta data to data buffer. - coral::AttributeList::iterator iAttribute = rowBuffer.attributeList().begin(); - iAttribute->data<int>() = i; - ++iAttribute; - iAttribute->data< double >() = i + 0.11; - ++iAttribute; - iAttribute->data< float >() = float(i + 0.22); - - cout << " > Add new row to collection" << endl; - for( iAttribute = rowBuffer.attributeList().begin(); iAttribute != rowBuffer.attributeList().end(); ++iAttribute ) { - if( iAttribute != rowBuffer.attributeList().begin() ) std::cout << ", "; - std::cout << "["; - iAttribute->toOutputStream( std::cout ); - std::cout << "]"; - } - cout << endl; - - collection->dataEditor().insertRow( rowBuffer ); - } - - // Commit the new rows. - collection->commit(); - - // Close collection. - collection->close(); -} diff --git a/Database/APR/RelationalCollection/tests/WriteUpdate/TestDriver.h b/Database/APR/RelationalCollection/tests/WriteUpdate/TestDriver.h deleted file mode 100644 index db14ba8bcf47874786887798c188d97637dab609..0000000000000000000000000000000000000000 --- a/Database/APR/RelationalCollection/tests/WriteUpdate/TestDriver.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#ifndef TESTDRIVER_H -#define TESTDRIVER_H - -#include <string> - - -class TestDriver { -public: - TestDriver( const std::string& name, - const std::string& connection ); - - ~TestDriver(); - - void write(); - - void update(); - - -private: - std::string m_name; - std::string m_connection; -}; - -#endif diff --git a/Database/APR/RelationalCollection/tests/WriteUpdate/main.cpp b/Database/APR/RelationalCollection/tests/WriteUpdate/main.cpp deleted file mode 100644 index c638382a58d6dabe75f3bd13a6f1adfcb7d2ae2d..0000000000000000000000000000000000000000 --- a/Database/APR/RelationalCollection/tests/WriteUpdate/main.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* - Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration -*/ - -#include <iostream> -#include <cstdlib> -#include <exception> - -#ifdef WIN32 -# include <windows.h> -# define sleep(x) Sleep((x)*1000) /* Windows version */ -#else -# include <unistd.h> -#endif - -#include "TestDriver.h" - -int main( int, char** ) -{ - try { - const std::string userNameEnv = "CORAL_AUTH_USER=ral_writer"; - const std::string passwdEnv = "CORAL_AUTH_PASSWORD=ral"; -#ifndef _WIN32 - ::putenv( const_cast<char*>( userNameEnv.c_str() ) ); - ::putenv( const_cast<char*>( passwdEnv.c_str() ) ); -#else - ::_putenv( const_cast<char*>( userNameEnv.c_str() ) ); - ::_putenv( const_cast<char*>( passwdEnv.c_str() ) ); -#endif - const std::string connection = "POOL-Collection-Oracle-lcgnight"; - //const std::string connection = "sqlite://pool.db"; - //const std::string connection = "mysql://pcitdb59/IOANNISDB"; - - std::string name = "/My/First/Collection"; - - std::cout << "ReadUpdate test starting..." << std::endl; - - for ( int i = 0; i < 2; ++i ) { - TestDriver driver( name, connection ); - - std::cout << "Writing the collection" << std::endl; - driver.write(); - - ::sleep( 2 ); - - std::cout << "Updating the collection" << std::endl; - driver.update(); - - name = "/My/Second/Collection"; - } - - std::cout << "Exiting..." << std::endl; - } - catch ( std::exception& e ) { - std::cerr << "---> Exception:" << std::endl; - std::cerr << e.what() << std::endl; - return 1; - } - catch (...) { - std::cerr << "Unhandled exception..." << std::endl; - return 1; - } - return 0; -} diff --git a/Projects/AthSimulation/package_filters.txt b/Projects/AthSimulation/package_filters.txt index 06a72953ca096d270053700ffd2975ad578b3712..2c899dad1495e398197c5233e5c74ac5332e4d9f 100644 --- a/Projects/AthSimulation/package_filters.txt +++ b/Projects/AthSimulation/package_filters.txt @@ -65,7 +65,6 @@ + Database/APR/ImplicitCollection + Database/APR/POOLCore + Database/APR/PersistencySvc -+ Database/APR/RelationalCollection + Database/APR/RootCollection + Database/APR/RootStorageSvc + Database/APR/StorageSvc