Resource.hh

00001 //********************************************************************
00002 //*** ResourcePool/oracle/Resource.hh
00003 //*** Copyright (c) 2003-2009 by Markus Winand <mws@fatalmind.com>
00004 //*** $Id: Resource.hh,v 1.40 2009-05-11 14:54:36 mws Exp $
00005 //********************************************************************
00006 /*
00007 This file is part of ResourcePool.
00008 
00009 ResourcePool is free software; you can redistribute it
00010 and/or modify it under the terms of the GNU General Public License
00011 as published by the Free Software Foundation; either version 2 of 
00012 the License, or (at your option) any later version.
00013 
00014 ResourcePool is distributed in the hope that it will be
00015 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
00016 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 GNU General Public License for more details.
00018 
00019 You should have received a copy of the GNU General Public License
00020 along with ResourcePool; if not, write to the Free Software
00021 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00022 02111-1307  USA */
00023 
00024 #ifndef RESOURCEPOOL_ORACLE_RESOURCE_HH
00025 #define RESOURCEPOOL_ORACLE_RESOURCE_HH
00026 
00027 
00028 void TEST_oracle_resource_two(); // fwd decl
00029 
00030 #ifndef RESOURCEPOOL_CREATEEXCEPTION_HH
00031 #include "ResourcePool/CreateException.hh"
00032 #endif
00033 
00034 #include "ResourcePool/ResourcePoolEventObserver.hh"
00035 #include "ResourceFwd.hh"
00036 
00037 #ifndef RESOURCEPOOL_ORACLE_ORACLEEXCEPTION_HH
00038 #include "OracleException.hh"
00039 #endif
00040 
00041 #ifndef RESOURCEPOOL_ORACLE_OCIHANDLE_HH
00042 #include "OCIHandle.hh"
00043 #endif
00044 
00045 #ifndef RESOURCEPOOL_ORACLE_OCIENVHANDLEFWD_HH
00046 #include "OCIEnvHandleFwd.hh"
00047 #endif
00048 
00049 #ifndef RESOURCEPOOL_ORACLE_STATEMENTCACHE_HH
00050 #include "StatementCache.hh"
00051 #endif
00052 
00053 #include "Transaction.hh"
00054 
00055 #ifndef OCI_ORACLE
00056 #include <oci.h>
00057 #endif
00058 
00059 #include <string>
00060 
00061 namespace fatalmind {
00062 
00063 namespace oracle {
00064 // TODO, use a more generic approach
00065 template<class TM>
00066 class FinallyTxDepth {
00067     public:
00068         FinallyTxDepth(oracleHandlesWithCache<TM>& a_hand)
00069         : hand(a_hand)
00070         {
00071             hand.incTxDepth();
00072         }
00073 
00074         ~FinallyTxDepth() {
00075             hand.decTxDepth();
00076         }
00077     private:
00078         oracleHandlesWithCache<TM>& hand;
00079 };
00080 
00081 }
00082 
00083 class oracleHandles {
00084     public:
00085         oracleHandles(const oracle::OCIEnvHandle& env
00086         ):_env(env) 
00087         , _err(_env)
00088         , _srv(_env)
00089         , _svc(_env)
00090         , _ses(_env)
00091         , _txDepth(0)
00092         {
00093         }
00094 
00095         virtual ~oracleHandles() {
00096         }
00097 
00098         inline OCIEnv* getEnv() const {
00099             return _env.get();
00100         }
00101 
00102         inline OCIError* getError() const {
00103             return _err.get();
00104         }
00105 
00106         inline OCIServer* getServer() const {
00107             return _srv.get();
00108         }
00109 
00110         inline OCISvcCtx* getSvcCtx() const {
00111             return _svc.get();
00112         }
00113 
00114         inline OCISession* getSession() const {
00115             return _ses.get();
00116         }
00117 
00118         inline int getTxDepth() const {
00119             return _txDepth;
00120         }
00121 
00122         // constant versions of stuff which would otherwise
00123         // be constructed on demand.
00124         // it might be hard not not clash with already defined symbols
00125         static struct LogConstants {
00126             static const std::string OCIHandleAlloc;
00127             static const std::string OCIStmtPrepare;
00128             static const std::string OCIAttrGet;
00129             static const std::string OCIAttrGetType;
00130             static const std::string OCIAttrGetSize;
00131             static const std::string OCIStmtExecute;
00132             static const std::string OCIBindByPos;
00133             static const std::string OCIBindArrayOfStruct;
00134             static const std::string OCITransCommit;
00135             static const std::string OCITransRollback;
00136             static const std::string OCI_NODATA;
00137             static const std::string NODATA; // incl. semikolon
00138             static const std::string MOREDATA; // incl. semikolon
00139             static const std::string ORA01422MSG;
00140             static const std::string ORA01422;
00141             static const std::string ORA99999;
00142 
00143             static const std::string EXACT;
00144             static const std::string IMPLICIT;
00145             static const std::string SLMDC;
00146 
00147             static const std::string EMPTY;
00148             static const std::string SEMICOLON;
00149         } LogConstant;
00150 
00151     protected:
00152         const oracle::OCIEnvHandle&     _env;
00153         const oracle::OCIErrorHandle    _err;
00154         const oracle::OCIServerHandle   _srv;
00155         const oracle::OCISvcCtxHandle   _svc;
00156         const oracle::OCISessionHandle  _ses;
00157     private:
00158     // hidden stuff
00159         oracleHandles(const oracleHandles&);
00160         oracleHandles& operator=(const oracleHandles&);
00161 
00162     // transaction managment helper function
00163         int _txDepth;
00164 
00165         inline int incTxDepth() {
00166             return _txDepth++;
00167         }
00168         inline void decTxDepth() {
00169             --_txDepth;
00170         }
00171 
00172     friend class oracle::FinallyTxDepth<DefaultThreadedModel>;
00173     friend void ::TEST_oracle_resource_two();
00174 };
00175 
00176 template<class TM = DefaultThreadedModel >
00177 class oracleHandlesWithCache: public oracleHandles {
00178     public:
00179         oracleHandlesWithCache(const oracle::OCIEnvHandle& env
00180             , gc_ptr<typename oracle::SelectListMetaDataCacheInterface<TM>::type > slmdc
00181         ):oracleHandles(env)
00182         , _slmdc(slmdc)
00183         {
00184         }
00185         virtual ~oracleHandlesWithCache()
00186         {
00187         }
00188 
00189         virtual typename oracle::SelectListMetaDataCacheInterface<TM>::type& getSelectListMetaDataCache() {
00190             return *_slmdc;
00191         }
00192 
00193 //      typedef typename SLMDC::value_t slmdc_value_t;
00194     protected:
00195         gc_ptr<typename oracle::SelectListMetaDataCacheInterface<TM>::type, TM> _slmdc;
00196     private:
00197     // hidden stuff
00198         oracleHandlesWithCache(const oracleHandlesWithCache<TM>&);
00199         oracleHandlesWithCache& operator=(const oracleHandlesWithCache<TM>&);
00200 };
00201 
00202 
00203 template<class TM>
00204 class oracleResource: public  oracleHandlesWithCache<TM> {
00205     public:
00206         typedef oracleHandlesWithCache<TM> super;
00207         using super::_srv;
00208         using super::_svc;
00209         using super::_ses;
00210         using super::_err;
00211         typedef typename oracle::SelectListMetaDataCacheInterface<TM>::type _slmdci_t;
00212 
00213         oracleResource<TM>(const std::string& service_name
00214             , const std::string& user
00215             , const std::string& pass
00216             , const oracle::OCIEnvHandle& env
00217             , gc_ptr<_slmdci_t, TM> slmdc
00218             , gc_ptr<ResourcePoolEventObserver, TM> o
00219         );
00220         ~oracleResource();
00221         bool precheck();
00222         bool postcheck();
00223         void close();
00224         void fail_close();
00225 
00231         std::string getSID() const {
00232             return sid_;
00233         };
00234 
00240         std::string getSerialNo() const {
00241             return serial_;
00242         };
00251         std::string getAudSID() const {
00252             return audsid_;
00253         };
00254 
00255         /*
00256          * Returns a string describing the identiy of the database session.
00257          * Intended for human usage to perform administrative actions upon the session.
00258          *
00259          * All database types support such a functionality, althout the content is strongly
00260          * depending on the database type.
00261          */
00262         const std::string& getSessionID() const {
00263             return sessionid_;
00264         }
00265         const 
00266         inline
00267         std::string& getResourceID() const {
00268             return sessionid_;
00269         }
00270 
00271         struct Events {
00272             ResourcePoolEventObserver::event_t PREPARE;
00273             ResourcePoolEventObserver::event_t EXECUTE;
00274             ResourcePoolEventObserver::event_t EXECUTE_FAIL;
00275             ResourcePoolEventObserver::event_t FETCH;
00276             ResourcePoolEventObserver::event_t COMMIT;
00277             ResourcePoolEventObserver::event_t ROLLBACK;
00278         } Event;
00279 
00280         void event(const ResourcePoolEventObserver::event_t eventid, const std::string& status = "") {
00281             observer->event(eventid, getResourceID(), status);
00282         }
00283         
00284         gc_ptr<EventReader> getReader(const ResourcePoolEventObserver::event_t eventid) {
00285             return observer->getReader(eventid, getResourceID());
00286         }
00287 
00288         oracle::StatementCache& getStatementCache() {
00289             return sthcache;
00290         }
00291 
00292     private:
00293 
00294         void fetchSessionID();
00295 
00296         std::string sid_; 
00297         std::string serial_; 
00298         std::string audsid_; 
00299         std::string sessionid_;
00300         gc_ptr<ResourcePoolEventObserver> observer;
00301         oracle::StatementCache sthcache;
00302 };
00303 
00304 } // namespace fatalmind
00305 #endif
00306 

Generated on Mon Nov 9 16:21:24 2009 for ResourcePool by  doxygen 1.5.3