Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members  

abstract_connection_manager.hh

00001 /*
00002 *  Name:      abstract_connection_manager.hh
00003 *  Author:    Rafael Jesus Alcantara Perez
00004 *  Summary:   Class for handling connections in C++.
00005 *  Date:      $Date: 2003/10/06 13:21:35 $
00006 *  Revision:  $Revision: 1.1 $
00007 *
00008 *  Copyright (C) 1999-2003  Rafael Jesus Alcantara Perez <rafa@dedalo-ing.com>
00009 *
00010 *  This program is free software; you can redistribute it and/or modify
00011 *  it under the terms of the GNU General Public License as published by
00012 *  the Free Software Foundation; either version 2 of the License, or
00013 *  (at your option) any later version.
00014 *
00015 *  This program is distributed in the hope that it will be useful,
00016 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 *  GNU General Public License for more details.
00019 *
00020 *  You should have received a copy of the GNU General Public License
00021 *  along with this program; if not, write to the Free Software
00022 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00023 *  MA 02111-1307, USA.
00024 */
00025 
00026 #ifndef _UESQL_ABSTRACT_CONNECTION_MANAGER__
00027 #define _UESQL_ABSTRACT_CONNECTION_MANAGER__
00028 
00029 #include <algorithm>
00030 #include <mpcl/exceptions.hh>
00031 #include <mpcl/text/string.hh>
00032 #include <mpcl/util/collection/map.hh>
00033 #ifdef _UESQL_DEBUG__
00034 #include <mpcl/util/logging/log.hh>
00035 #endif  // not _UESQL_DEBUG__
00036 #include <queue>
00037 #include <vector>
00038 #include "defs.hh"
00039 
00040 
00042 namespace uesqlc
00043 {
00044 
00046   template <typename TItem>
00047   struct MUpdateFromBuffer : public std::unary_function<TItem, void>
00048   {
00049 
00050       void operator () (TItem* ptITEM) const
00051       {
00052         ptITEM->updateFromBuffer();
00053       }
00054 
00055   };  // struct MUpdateFromBuffer
00056 
00058   template <typename TItem>
00059   struct MWriteDebugInfo : public std::unary_function<TItem, void>
00060   {
00061 
00062       void operator () (TItem* ptITEM) const
00063       {
00064 #       ifdef _UESQL_DEBUG__
00065         mpcl::util::logging::tLog << ", " << ptITEM->get();
00066 #       endif  // not _UESQL_DEBUG__
00067       }
00068 
00069   };  // struct MWriteDebugInfo
00070 
00077   template <typename TConnectionData, typename TResult>
00078   class TAbstractConnectionManager : protected TSqlstateDescriptor
00079   {
00080 
00081     protected:
00082 
00084       typedef
00085         mpcl::util::collection::TMap<mpcl::text::TString, TConnectionData>
00086         TConnectionDataMap;
00087 
00089       mutable int   iUniqueOrdinal;
00090 
00092       TConnectionDataMap   tConnectionDataMap;
00093 
00095       TConnectionData*   ptCurrentConnection;
00096 
00098       std::queue<mpcl::text::TString>   tInputEmbeddedVariableQueue;
00099 
00101       std::vector<IType*>   tOutputEmbeddedVariableVector;
00102 
00104       mpcl::text::TString   yCurrentConnection;
00105 
00106 
00107     public:
00108 
00109       //
00110       //  C O N S T R U C T O R S
00111       //
00112 
00114       TAbstractConnectionManager (void)      :
00115         TSqlstateDescriptor           ()     ,
00116         iUniqueOrdinal                (0)    ,
00117         tConnectionDataMap            ()     ,
00118         ptCurrentConnection           (NULL) ,
00119         tInputEmbeddedVariableQueue   ()     ,
00120         tOutputEmbeddedVariableVector ()     ,
00121         yCurrentConnection            ()
00122       {
00123         initialize();
00124       }
00125 
00127       virtual ~TAbstractConnectionManager (void)
00128       {
00129         finish();
00130       }
00131 
00138       void bindConnection ( const mpcl::text::TString& rkyCONNECTION_NAME ,
00139                             TConnectionData&           rtCONNECTION       )
00140       {
00141         tConnectionDataMap.bind (rkyCONNECTION_NAME, rtCONNECTION);
00142       }
00143 
00150       virtual void diagnose (TResult tRESULT) = 0;
00151 
00158       void unbindConnection (const mpcl::text::TString kyCONNECTION_NAME)
00159       {
00160 
00161         bool                                    gIsCurrentConnection;
00162         typename TConnectionDataMap::iterator   I = tConnectionDataMap.find (kyCONNECTION_NAME);
00163 
00164         if ( I == tConnectionDataMap.end() )
00165         {
00166           throw mpcl::TConstraintException ("there is no such connection", __FILE__, __LINE__);
00167         }
00168         else
00169         {
00170           gIsCurrentConnection = ( ptCurrentConnection == &(I->second) );
00171           I->second.close();
00172           tConnectionDataMap.erase (I);
00173           if ( gIsCurrentConnection )
00174           {
00175             yCurrentConnection.erase();
00176             ptCurrentConnection = NULL;
00177           }
00178         }
00179 
00180       }  // unbindConnection()
00181 
00183       void unbindCurrentConnection (void)
00184       {
00185         if ( existsDefaultConnection() )
00186         {
00187           unbindConnection (yCurrentConnection);
00188         }
00189       }
00190 
00192       void unbindAllConnections (void)
00193       {
00194         while ( !tConnectionDataMap.empty() )
00195         {
00196           unbindConnection (tConnectionDataMap.begin()->first);
00197         }
00198       }
00199 
00204       virtual void clearQueues (void)
00205       {
00206         while ( !tInputEmbeddedVariableQueue.empty() )
00207         {
00208           tInputEmbeddedVariableQueue.pop();
00209         }
00210         tOutputEmbeddedVariableVector.clear();
00211       }
00212 
00218       virtual void clearResult (TResult tRESULT) = 0;
00219 
00225       virtual TResult execute (const mpcl::text::TString& rkySTATEMENT)
00226       {
00227         return execute (rkySTATEMENT.c_str());
00228       }
00229 
00237       virtual TResult execute ( const mpcl::text::TString& rkySTATEMENT       ,
00238                                 const mpcl::text::TString& rkyCONNECTION_NAME )
00239       {
00240         return execute (rkySTATEMENT.c_str(), rkyCONNECTION_NAME.c_str());
00241       }
00242 
00248       virtual TResult execute (const char* pkcSTATEMENT) = 0;
00249 
00257       virtual TResult execute ( const char* pkcSTATEMENT       ,
00258                                 const char* pkyCONNECTION_NAME ) = 0;
00259 
00266       virtual void executeClean (const char* pkcSTATEMENT)
00267       {
00268         clearResult (execute (pkcSTATEMENT));
00269       }
00270 
00272       virtual void finish (void)
00273       {
00274         unbindAllConnections();
00275         clearQueues();
00276         tConnectionDataMap.clear();
00277         yCurrentConnection.erase();
00278       }
00279 
00287       virtual IType* getFromOutputQueue (const size_t zINDEX) const
00288       {
00289         if ( zINDEX >= tOutputEmbeddedVariableVector.size() )
00290         {
00291           throw mpcl::TConstraintException ("out of range", __FILE__, __LINE__);
00292         }
00293         return tOutputEmbeddedVariableVector [zINDEX];
00294       }
00295 
00297       virtual void initialize (void) {}
00298 
00305       mpcl::text::TString instantiate (const char* pkcSTATEMENT);
00306 
00313       mpcl::text::TString instantiate (const mpcl::text::TString& rkySTATEMENT)
00314       {
00315         return instantiate (rkySTATEMENT.c_str());
00316       }
00317 
00322       virtual void pushOnInputQueue (const IType& rktEMBEDDED_VALUE)
00323       {
00324         tInputEmbeddedVariableQueue.push (rktEMBEDDED_VALUE.get());
00325       }
00326 
00331       virtual IType* popFromOutputQueue (void)
00332       {
00333         IType*   ptBaseType = tOutputEmbeddedVariableVector.back();
00334 
00335         tOutputEmbeddedVariableVector.pop_back();
00336         return ptBaseType;
00337       }
00338 
00344       virtual void pushOnOutputQueue (IType* ptSQL_DATA_TYPE)
00345       {
00346         tOutputEmbeddedVariableVector.push_back (ptSQL_DATA_TYPE);
00347       }
00348 
00350       void resetStatus (void)
00351       {
00352         //
00353         //  Condition:  successful completion
00354         //
00355         SQLCODE    = 0;
00356         SQLMESSAGE = "";
00357         SQLSTATE   = "00000";
00358       }
00359 
00364       void setCurrentConnection (const mpcl::text::TString& rkyCONNECTION_NAME);
00365 
00370       virtual void updateOutputVariables (void);
00371 
00372 
00373     public:
00374 
00375       //
00376       //  S E L E C T O R S
00377       //
00378 
00383       TConnectionData& getCurrentConnectionData (void)
00384       {
00385         if ( ptCurrentConnection == NULL )
00386         {
00387           throw mpcl::TConstraintException ("there is no current connection", __FILE__, __LINE__);
00388         }
00389         return *ptCurrentConnection;
00390       }
00391 
00396       const mpcl::text::TString& currentConnectionName (void) const
00397       {
00398         return yCurrentConnection;
00399       }
00400 
00405       virtual bool existsDefaultConnection (void) const
00406       {
00407         return ( ptCurrentConnection != NULL );
00408       }
00409 
00415       bool isConnected (const mpcl::text::TString& rkyCONNECTION_NAME) const
00416       {
00417         return tConnectionDataMap.isBound (rkyCONNECTION_NAME);
00418       }
00419 
00424       bool isNotFoundCondition (void) const
00425       {
00426         return ( SQLSTATE == no_data::pkcNO_SUBCLASS );
00427       }
00428 
00433       bool isSqlerrorCondition (void) const
00434       {
00435         return ( SQLCODE < 0 );
00436       }
00437 
00438   };  // class TAbstractConnectionManager
00439 
00440 }  // namespace uesqlc
00441 
00442 
00443 //
00444 //  C O N S T R U C T O R S
00445 //
00446 
00447 template <typename TConnectionData, typename TResult>
00448 inline mpcl::text::TString uesqlc::TAbstractConnectionManager<TConnectionData, TResult>::
00449 instantiate (const char* pkcSTATEMENT)
00450 {
00451 
00452   using mpcl::text::TString;
00453 
00454   register TString::size_type   zPatternOffset;
00455   TString                       yStatementInstance (pkcSTATEMENT);
00456 
00457   while ( !tInputEmbeddedVariableQueue.empty() )
00458   {
00459     if ( TString::npos == (zPatternOffset = yStatementInstance.find ("$z")) )
00460     {
00461       break;
00462     }
00463     else
00464     {
00465       yStatementInstance.replace (zPatternOffset, 2, tInputEmbeddedVariableQueue.front());
00466       tInputEmbeddedVariableQueue.pop();
00467     }
00468   }
00469   return yStatementInstance;
00470 
00471 }  // instantiate()
00472 
00473 
00474 template <typename TConnectionData, typename TResult>
00475 inline void uesqlc::TAbstractConnectionManager<TConnectionData, TResult>::
00476 setCurrentConnection (const mpcl::text::TString& rkyCONNECTION_NAME)
00477 {
00478 
00479   if ( tConnectionDataMap.isBound (rkyCONNECTION_NAME) )
00480   {
00481     yCurrentConnection  = rkyCONNECTION_NAME;
00482     ptCurrentConnection = &(tConnectionDataMap [rkyCONNECTION_NAME]);
00483 #   ifdef _UESQL_DEBUG__
00484     mpcl::util::logging::tLog << mpcl::util::logging::header << "SET CONNECTION '" << rkyCONNECTION_NAME << "';\n";
00485 #   endif  // not _UESQL_DEBUG__
00486     resetStatus();
00487   }
00488   else
00489   {
00490     //
00491     //  Condition:           connection exception
00492     //  Class subcondition:  connection does not exist
00493     //
00494     SQLCODE    = -1;
00495     SQLMESSAGE = "";
00496     SQLSTATE   = "08003";
00497   }
00498 
00499 }  // setCurrentConnection()
00500 
00501 
00502 template <typename TConnectionData, typename TResult>
00503 inline void uesqlc::TAbstractConnectionManager<TConnectionData, TResult>::
00504 updateOutputVariables (void)
00505 {
00506 
00507 # ifdef _UESQL_DEBUG__
00508   using mpcl::util::logging::header;
00509   using mpcl::util::logging::tLog;
00510 # endif  // not _UESQL_DEBUG__
00511   using std::for_each;
00512 
00513   for_each ( tOutputEmbeddedVariableVector.begin() ,
00514              tOutputEmbeddedVariableVector.end()   ,
00515              MUpdateFromBuffer<IType>()            );
00516 # ifdef _UESQL_DEBUG__
00517   tLog << header << "FETCHED (";
00518   if ( !tOutputEmbeddedVariableVector.empty() )
00519   {
00520     tLog << tOutputEmbeddedVariableVector.front()->get();
00521     for_each ( tOutputEmbeddedVariableVector.begin() + 1 ,
00522                tOutputEmbeddedVariableVector.end()       ,
00523                MWriteDebugInfo<IType>()                  );
00524   }
00525   tLog << ");\n";
00526 # endif  // not _UESQL_DEBUG__
00527 
00528 }  // updateOutputVariables()
00529 
00530 
00531 #endif  // not _UESQL_ABSTRACT_CONNECTION_MANAGER__

Generated on Mon Oct 13 02:40:10 2003 for UESQLC by doxygen1.2.18