Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

dbstreamerfactory.cpp

Go to the documentation of this file.
00001 //============================================================================= 
00002 //
00003 // XDFLengine library
00004 //
00005 //----------------------------------------------------------------------------- 
00006 //  DBStreamerFactory.CPP
00007 //----------------------------------------------------------------------------- 
00013 //_____________________________________________________________________________
00014 //
00015 //  Copyright (C) 2003 Guillaume Baurand. All Rights Reserved.
00016 //
00017 //  This file is part of the XDFLengine project.
00018 //
00019 //  The XDFLengine is free software; you can redistribute it and/or modify
00020 //  it under the terms of the GNU General Public License as published by
00021 //  the Free Software Foundation; either version 2 of the License, or
00022 //  (at your option) any later version.
00023 //
00024 //  This program is distributed in the hope that it will be useful,
00025 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00026 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00027 //  GNU General Public License for more details.
00028 //
00029 //  You should have received a copy of the GNU General Public License
00030 //  along with this program; if not, write to the Free Software
00031 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
00032 //  USA.
00033 //
00034 //  For more information, 
00035 //      contact  : guillaume@baurand.net 
00036 //      or visit : http://xdflengine.sourceforge.net
00037 //
00038 //=============================================================================
00039 
00040 #include "dbstreamerfactory.hpp"
00041 #include "processor/xmlprocessor.hpp"
00042 
00043 
00044 BEGIN_XDFLENGINE_NS
00045 
00046 //============================================================================= 
00047 //  CLASS DBStreamerFactory
00048 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00049 
00050 
00051     //_________________________________________________________________________
00052     //  SETCONNECTIONLIFETIME
00053     //-------------------------------------------------------------------------
00054     void DBStreamerFactory::setSQLSyntax(const char* p_pszSQLSyntax)
00055     {
00056 
00057         if(p_pszSQLSyntax)
00058         {
00059             if      ( strcmp(p_pszSQLSyntax,DB_ORA)==0)     g_uiSQLSyntax = SQL_SYNTAX_ORA;
00060             else if ( strcmp(p_pszSQLSyntax,DB_MSSQL)==0)   g_uiSQLSyntax = SQL_SYNTAX_MSSQL;
00061             else if ( strcmp(p_pszSQLSyntax,DB_DB2)==0)     g_uiSQLSyntax = SQL_SYNTAX_DB2;
00062         }
00063     }
00064 
00065     //_________________________________________________________________________
00066     //  GETCONNECTIONLIFETIME
00067     //-------------------------------------------------------------------------
00068     unsigned int DBStreamerFactory::getSQLSyntax()
00069     {
00070         return g_uiSQLSyntax;
00071     }
00072 
00073     //_________________________________________________________________________
00074     //  DBStreamerFactory
00075     //-------------------------------------------------------------------------
00076     DBStreamerFactory::DBStreamerFactory()
00077     {
00078         //---------------------------------------------------------------------
00079         unsigned int i;
00080         //---------------------------------------------------------------------
00081 
00082         logout.display_version( "OTL", "Oracle, ODBC and DB2/CLI Template Library", OTL_VERSION_NUMBER, "Copyright (C) Sergei Kuchin, 1996,2002");  
00083         
00084         // init connection pool
00085         if(! g_boolConnectionPoolsReady)
00086         {
00087             DEBUG_ECHO << "Init connection pool for " << XMLProcessor::getThreadCount() << " threads \n";
00088 
00089             // initialize OCI/ODBC environment
00090             otl_connect::otl_initialize(1); 
00091 
00092             // allocate pools pointers index
00093             g_ppConnectionPools=(DBConnectionPool**) malloc( sizeof(DBConnectionPool*) * XMLProcessor::getThreadCount());
00094 
00095             // fills connection pool map with one pool per thread
00096             for(i=0; i < XMLProcessor::getThreadCount(); i++)
00097             {
00098                 DEBUG_ECHO << "init connection pool for thread #" << i << "\n";
00099                 g_ppConnectionPools[i]=new DBConnectionPool();          
00100             }
00101 
00102             g_boolConnectionPoolsReady=true;
00103 
00104         }
00105         
00106         DEBUG_CREATE(DBStreamerFactory) 
00107     }
00108 
00109     //_________________________________________________________________________
00110     //  ~DBStreamerFactory
00111     //-------------------------------------------------------------------------
00112     DBStreamerFactory::~DBStreamerFactory()
00113     {
00114         //---------------------------------------------------------------------
00115         DBConnectionPool*   l_pDBConnectionPool;
00116         unsigned int        i;
00117         //---------------------------------------------------------------------
00118 
00119         DEBUG_DEL(DBStreamerFactory)
00120 
00121         if( g_boolConnectionPoolsReady)
00122         {
00123             // release connection pools
00124             for(i=0; i<XMLProcessor::getThreadCount(); i++)
00125             {
00126                 l_pDBConnectionPool = g_ppConnectionPools[i];           
00127                 delete( l_pDBConnectionPool);
00128             }
00129 
00130             // desallocate shared pool array
00131             free( g_ppConnectionPools);
00132 
00133             // terminate OCI environment
00134 #ifndef OTL_ODBC
00135             otl_connect::otl_terminate(); 
00136 #endif
00137             g_boolConnectionPoolsReady=false;
00138         }
00139 
00140     }
00141 
00142     //_____________________________________________________________________
00143     // GETCONNECTION
00144     //---------------------------------------------------------------------
00145     otl_connect* DBStreamerFactory::getConnection(const char* p_pszConnectionString,unsigned int p_uiThreadId  )
00146     {
00147         DEBUG_FUNC(DBStreamerFactory::getConnection)
00148         logout << "\t" << "DB POOL" << "   :   " << "Get connection '"<< p_pszConnectionString << "' for thread #" << p_uiThreadId   << "\n";
00149         return (g_ppConnectionPools[p_uiThreadId  ])->getConnection( p_pszConnectionString);
00150     }
00151 
00152 
00153     //_____________________________________________________________________
00154     // RELEASECONNECTION
00155     //---------------------------------------------------------------------
00156     void DBStreamerFactory::releaseConnection(const char* p_pszConnectionString,unsigned int p_uiThreadId  )
00157     {
00158         DEBUG_FUNC(DBStreamerFactory::releaseConnection) 
00159         logout << "\t" << "DB POOL" << "   :   " << "Release connection '"<< p_pszConnectionString << "' for thread #" << p_uiThreadId   << "\n";
00160         g_ppConnectionPools[p_uiThreadId  ]->releaseConnection( p_pszConnectionString);
00161     }
00162 
00163 
00164     //_____________________________________________________________________
00165     //  TICK
00166     //---------------------------------------------------------------------
00167     void DBStreamerFactory::tick(unsigned long  p_ulClock)
00168     {
00169         DEBUG_FUNC(DBStreamerFactory::tick)
00170         //---------------------------------------------------------------------
00171         unsigned int            i;
00172         static unsigned long    l_sulLastClock=0;
00173         //---------------------------------------------------------------------
00174 
00175         if( p_ulClock > l_sulLastClock)
00176         {
00177             l_sulLastClock = p_ulClock;
00178             for(i=0; i<XMLProcessor::getThreadCount(); i++)
00179             {
00180                 logout << "\t" << "DB POOL" << "   :   " <<  " Ticking pool #" << i <<"\n";
00181                 g_ppConnectionPools[i]->tick( p_ulClock);   
00182             }
00183         }
00184     }
00185 
00186 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00187 //=============================================================================
00188 
00189 
00190 
00191 
00192 //============================================================================= 
00193 //  CLASS DBCONNECTIONPOOL
00194 //----------------------------------------------------------------------------- 
00195 
00196 
00197 
00198     //_________________________________________________________________________
00199     //  SETCONNECTIONLIFETIME
00200     //-------------------------------------------------------------------------
00201     void DBConnectionPool::setConnectionLifeTime(unsigned long  p_ulConnectionLifeTime)
00202     {
00203         DEBUG_FUNC(DBConnectionPool::setConnectionLifeTime)
00204         g_ulPooledConnectionLifeTime=p_ulConnectionLifeTime;
00205     }
00206 
00207     //_________________________________________________________________________
00208     //  DBStreamerFactory
00209     //-------------------------------------------------------------------------
00210     DBConnectionPool::DBConnectionPool()
00211     {
00212         DEBUG_CREATE(DBConnectionPool)
00213             m_ulLastTick=0;
00214     }
00215 
00216     //_________________________________________________________________________
00217     //  DBStreamerFactory
00218     //-------------------------------------------------------------------------
00219     DBConnectionPool::~DBConnectionPool()
00220     {
00221 
00222         // Empty handlers map;
00223         while( !m_vaActiveConnections.empty()) deletePooledConnection( m_vaActiveConnections.pop());
00224 
00225         DEBUG_DEL(DBConnectionPool)
00226 
00227     }
00228 
00229 
00230     //_________________________________________________________________________
00231     // GETCONNECTION
00232     //-------------------------------------------------------------------------
00233     otl_connect* DBConnectionPool::getConnection(const char* p_pszConnectionString)
00234     {
00235         //---------------------------------------------------------------------
00236         DBPooledConnection* l_DBPooledConnection=0;
00237         //---------------------------------------------------------------------
00238 
00239         DEBUG_FUNC(DBConnectionPool::getConnection)
00240 
00241         
00242 
00243         l_DBPooledConnection = m_vaActiveConnections.get( p_pszConnectionString);
00244         if(! l_DBPooledConnection)
00245         {
00246             // insert connection in pool
00247             l_DBPooledConnection = poolConnection( p_pszConnectionString);
00248             DEBUG_ECHO << "Connection not found : insert in pool" <<"\n";
00249                         logout << "Getting connection " << p_pszConnectionString << "(" << l_DBPooledConnection->m_uiUsage << ")\n";
00250         }
00251 
00252         // get connection from pool
00253         l_DBPooledConnection->m_uiUsage = l_DBPooledConnection->m_uiUsage+1;
00254 
00255         return l_DBPooledConnection->m_pOTLConnection;
00256     }
00257 
00258 
00259 
00260     //_________________________________________________________________________
00261     // RELEASECONNECTION
00262     //-------------------------------------------------------------------------
00263     void DBConnectionPool::releaseConnection(const char* p_pszConnectionString)
00264     {
00265         //---------------------------------------------------------------------
00266         DBPooledConnection* l_DBPooledConnection;
00267         //---------------------------------------------------------------------
00268 
00269         DEBUG_FUNC(DBConnectionPool::releaseConnection)
00270 
00271 
00272         
00273 
00274         l_DBPooledConnection = m_vaActiveConnections.get( p_pszConnectionString);
00275         if( l_DBPooledConnection)
00276         {
00277             l_DBPooledConnection->m_uiUsage=l_DBPooledConnection->m_uiUsage-1;
00278                         logout << "Releasing connection " << p_pszConnectionString << "(" << l_DBPooledConnection->m_uiUsage << ")\n";
00279             if( g_ulPooledConnectionLifeTime == 0) 
00280                         /*&& ( l_DBPooledConnection->m_uiUsage==0 ) &&
00281                 (   ( g_ulPooledConnectionLifeTime == 0 ) || 
00282                     ( m_ulLastTick - l_DBPooledConnection->m_ulTimeCreated  > g_ulPooledConnectionLifeTime ) ||
00283                     ( m_ulLastTick < l_DBPooledConnection->m_ulTimeCreated )
00284               ) )*/
00285             {
00286                 unPoolConnection( l_DBPooledConnection);
00287             }
00288         }
00289     }
00290 
00291     //_________________________________________________________________________
00292     //  tick
00293     //-------------------------------------------------------------------------
00294     void DBConnectionPool::tick(unsigned long p_ulClock)
00295     {       
00296         //---------------------------------------------------------------------
00297         unsigned int i;
00298         DBPooledConnection* l_DBPooledConnection=0;
00299         //---------------------------------------------------------------------
00300 
00301         DEBUG_FUNC(DBConnectionPool::tick)
00302 
00303         //logout << "\t" << "DB POOL" << "   :   " << "Pool cleanup..." << "\n";
00304 
00305         m_ulLastTick = p_ulClock;
00306 
00307         // check for outdated connections
00308         for(i=0 ; i<m_vaActiveConnections.size() ; i++)
00309         {
00310             l_DBPooledConnection=m_vaActiveConnections.get(i);
00311             logout << l_DBPooledConnection->m_uiUsage << "/";
00312             logout << l_DBPooledConnection->m_ulTimeCreated << "\n";
00313 
00314             if( (   ( g_ulPooledConnectionLifeTime!=-1 ) && 
00315                     ( l_DBPooledConnection->m_uiUsage == 0 )
00316                 )
00317                 &&
00318                 (   
00319                     ( m_ulLastTick - l_DBPooledConnection->m_ulTimeCreated  > g_ulPooledConnectionLifeTime ) ||
00320                     ( m_ulLastTick < l_DBPooledConnection->m_ulTimeCreated )
00321               ) )
00322             {
00323                 unPoolConnection( l_DBPooledConnection);    
00324             }
00325 
00326         }
00327 
00328     }
00329 
00330 // PRIVATES 
00331 
00332     //_________________________________________________________________________
00333     // POOLCONNECTION
00334     //-------------------------------------------------------------------------
00335     DBPooledConnection* DBConnectionPool::poolConnection(const char* p_pszConnectionString)
00336     {
00337         //---------------------------------------------------------------------
00338         DBPooledConnection* l_DBPooledConnection=0;
00339         otl_connect*        l_pOTLConnection=0;
00340         //--------------------------------------------------------------------- 
00341 
00342         DEBUG_FUNC(DBConnectionPool::poolConnection)
00343 
00344         logout << "\t" << "DB POOL" << "   :   " << "Pool connection " << p_pszConnectionString << "\n";
00345 
00346         PREP_CATCH_XML_FLOW_ERROR;
00347         
00348         l_pOTLConnection= new otl_connect;
00349 
00350         // Connect !
00351         try { l_pOTLConnection->rlogon(  p_pszConnectionString); }
00352         catch(otl_exception& p)
00353         { 
00354             MAKE_XMLFLOW_EXCEPTION ( ERRCODE_LOC_DBCONNPOOL + ERRCODE_CAUSE_DATAACCESS , "Unable to connect to DB." , (char*)(&(p.msg)), "DBConnectionPool::poolConnection", "", false);
00355             p.~otl_tmpl_exception();
00356             goto RELEASE_AND_RETURN;
00357         }
00358 
00359         l_DBPooledConnection=new DBPooledConnection;
00360         l_DBPooledConnection->m_ulTimeCreated = m_ulLastTick;
00361         l_DBPooledConnection->m_pOTLConnection = l_pOTLConnection;
00362         l_DBPooledConnection->m_uiUsage=0;
00363         l_DBPooledConnection->m_pszConnectionString =importCharBuffer( 0, p_pszConnectionString);
00364 
00365         m_vaActiveConnections.add( l_DBPooledConnection, p_pszConnectionString);
00366 
00367         DEBUG_ECHO << "Pooled connection '" << p_pszConnectionString << "'\n";
00368 
00369     RELEASE_AND_RETURN:
00370     
00371         // release 
00372         ON_XML_FLOW_ERROR_DO
00373         {
00374             if( l_DBPooledConnection)
00375             {
00376                 releaseCharBuffer( l_DBPooledConnection->m_pszConnectionString);
00377                 delete l_DBPooledConnection;
00378             }
00379             if( l_pOTLConnection)
00380             {
00381                 l_pOTLConnection->logoff();
00382                 delete l_pOTLConnection;
00383             }
00384         }
00385             
00386         ON_XML_FLOW_ERROR_THROW;    
00387         return l_DBPooledConnection;
00388     }
00389 
00390     //_________________________________________________________________________
00391     // UNPOOLCONNECTION
00392     //-------------------------------------------------------------------------
00393     void DBConnectionPool::unPoolConnection(DBPooledConnection* p_pDBPooledConnection)
00394     {
00395         //---------------------------------------------------------------------
00396         DBPooledConnection* l_DBPooledConnection=0;
00397         //---------------------------------------------------------------------
00398 
00399         DEBUG_FUNC(DBConnectionPool::unPoolConnection)
00400 
00401         // insert connection in pool
00402         deletePooledConnection( m_vaActiveConnections.remove( p_pDBPooledConnection->m_pszConnectionString));   
00403     }
00404 
00405     //_________________________________________________________________________
00406     // DELETEPOOLEDCONNECTION
00407     //-------------------------------------------------------------------------
00408     void DBConnectionPool::deletePooledConnection(DBPooledConnection*   p_pDBPooledConnection)
00409     {
00410         //---------------------------------------------------------------------
00411         otl_connect*        l_pOTLConnection;
00412         //---------------------------------------------------------------------
00413 
00414         DEBUG_FUNC(DBConnectionPool::deletePooledConnection)
00415 
00416         logout << "\t" << "DB POOL" << "   :   " << "Unpool connection " << p_pDBPooledConnection->m_pszConnectionString  << "(" << p_pDBPooledConnection->m_uiUsage << ")\n";
00417 
00418         releaseCharBuffer( p_pDBPooledConnection->m_pszConnectionString);
00419 
00420         l_pOTLConnection = p_pDBPooledConnection->m_pOTLConnection;
00421 
00422         // release connection
00423         l_pOTLConnection->logoff();
00424         delete l_pOTLConnection;
00425 
00426         // release pooled connection
00427         delete p_pDBPooledConnection;
00428     }
00429 
00430 
00431 
00432 //=============================================================================
00433 
00434 END_XDFLENGINE_NS
00435 

Generated on Sat Oct 4 13:19:58 2003 for XDFLengine by doxygen1.3-rc2