예제 #1
0
// ------------------------------------------------------------------------------------------------
std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, bool is_src, 
	const ConnectionMap& conns, 
	const char* const* classnames, 
	size_t count) const

{
	ai_assert(classnames);
	ai_assert(count != 0 && count <= MAX_CLASSNAMES);

	size_t lenghts[MAX_CLASSNAMES];

	const size_t c = count;
	for (size_t i = 0; i < c; ++i) {
		lenghts[i] = strlen(classnames[i]);
	}

	std::vector<const Connection*> temp;

	const std::pair<ConnectionMap::const_iterator,ConnectionMap::const_iterator> range = 
		conns.equal_range(id);

	temp.reserve(std::distance(range.first,range.second));
	for (ConnectionMap::const_iterator it = range.first; it != range.second; ++it) {
		const Token& key = (is_src 
			? (*it).second->LazyDestinationObject()
			: (*it).second->LazySourceObject()
		).GetElement().KeyToken();

		const char* obtype = key.begin();

		for (size_t i = 0; i < c; ++i) {
			ai_assert(classnames[i]);
			if(static_cast<size_t>(std::distance(key.begin(),key.end())) == lenghts[i] && !strncmp(classnames[i],obtype,lenghts[i])) {
				obtype = NULL;
				break;
			}
		}

		if(obtype) {
			continue;
		}

		temp.push_back((*it).second);
	}

	std::sort(temp.begin(), temp.end(), std::mem_fun(&Connection::Compare));
	return temp; // NRVO should handle this
}
예제 #2
0
// ------------------------------------------------------------------------------------------------
std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, 
	const ConnectionMap& conns) const
{
	std::vector<const Connection*> temp;

	const std::pair<ConnectionMap::const_iterator,ConnectionMap::const_iterator> range = 
		conns.equal_range(id);

	temp.reserve(std::distance(range.first,range.second));
	for (ConnectionMap::const_iterator it = range.first; it != range.second; ++it) {
		temp.push_back((*it).second);
	}

	std::sort(temp.begin(), temp.end(), std::mem_fun(&Connection::Compare));

	return temp; // NRVO should handle this
}
예제 #3
0
    IDatabase* DatabaseFactory::getDatabase(EDataTypes dataType, EDataActions dataAction)
    {
        FUNCTION_ENTRY("getDatabase");
        // Set up a local variable to point to the database that is either created or found
        IDatabase* theDatabase = NULL;

        ThreadGuard guard( m_getDatabaseLock );

        // get the connection string for this datatype/action
        std::string dbConnection;
        
        // forever loop will exit by exception or when a good db is found
        while(1)
        {
            // If this call fails it will throw something.
            try
            {
                DbConnection::getInstance().getConnectionString(dataType, dataAction, dbConnection);
            }
            catch(DbConnectionFailed&)
            {
                // we exit the forever loop with this throw
                TA_THROW(DatabaseException("Unable to find a working database"));
            }

            // Get the ID of this thread - we want one database connection per thread
            int threadId = Thread::getCurrentThreadId();

            // Look to see if there is already a database connection for this thread
			//<ThreadID: Map<ConnectionString, SimpleDBDatabase>>
            ThreadMap::iterator threadIter ( m_databaseMap.find( threadId ));
            if ( threadIter == m_databaseMap.end() )
            {
                // add new ConnectionMap. Set db* to null untill it's defined
                ConnectionMap cmap;
                cmap.insert( ConnectionMap::value_type( dbConnection, 0 ) );
                threadIter = m_databaseMap.insert(ThreadMap::value_type(threadId, cmap) ).first;
            }

            ConnectionMap::iterator connIter ( threadIter->second.find( dbConnection ) );
            if (connIter == threadIter->second.end())
            {
                connIter = threadIter->second.insert(ConnectionMap::value_type( dbConnection, 0 )).first;
            }
            if (connIter->second != 0 )
            {
                // Then the connection already exists.
	            theDatabase = connIter->second; //TODO: need to set dataType and DataAction
				theDatabase->setDataTypeAction(dataType, dataAction);
            }
            else // Database doesn't exist for this thread, so need to create it.
            {
			    LOG(SourceInfo, DebugUtil::GenericLog, DebugUtil::DebugInfo, "New SimpleDbDatabase object created for thread %lu", threadId);
            
	            theDatabase = new TA_Base_Core::SimpleDbDatabase(dataType, dataAction);

                // add to map
                connIter->second = theDatabase;
            }


            // Now that we have a database object, we need to connect it - do this everytime
            // 'cause if the database is alerady connected, nothing will happen, but if it has
            // been inadvertandtly disconnected, then it will be reconnected
            try // The connect line can generate a DatabaseException
            {
                theDatabase->connect( dbConnection );

                // we can also exit the forever loop this (preferred) way
 
                FUNCTION_EXIT;
   		        return theDatabase;
            }
            catch (DatabaseException&) 
            {
                // A DatabaseException was generated. Need to delete the database object for now.
                delete theDatabase;
                threadIter->second.erase(connIter);
                TA_Base_Core::Thread::sleep(100);
                // do not rethrow, just sleep for a while
                // there may be another database we can talk to.
            }
        } // end forever loop
	}