SQLExecute.hh

00001 //********************************************************************
00002 //*** ResourcePool/oracle/SQLExecute.hh
00003 //*** Copyright (c) 2003-2009 by Markus Winand <mws@fatalmind.com>
00004 //*** $Id: SQLExecute.hh,v 1.39 2009-05-11 14:06:05 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_SQLEXECUTE_HH
00025 #define RESOURCEPOOL_ORACLE_SQLEXECUTE_HH
00026 
00027 #ifndef RESOURCEPOOL_ORACLE_RESOURCEFWD_HH
00028 #include "ResourceFwd.hh"
00029 #endif
00030 
00031 #ifndef RESOURCEPOOL_ORACLE_COMMANDCOMMON_HH
00032 #include "CommandCommon.hh"
00033 #endif
00034 #include "ResourcePool/SQL/SQLStatement.hh"
00035 
00036 #include <string>
00037 #include <deque>
00038 #include <memory>
00039 
00040 #include "mm/RawBuffer.hh"
00041 
00042 
00043 namespace fatalmind {
00044 
00045 // forward decl
00046 class OracleExceptionFactory;
00047 
00048 namespace oracle {
00049 
00050 // forward decl, to be able to be friends
00051 template <class CommandType>
00052 class OptimizedBatchCommand;
00053 
00054 class BatchInfo;
00055 
00056 
00061 template <class TM, template<class>class SLMDC>
00062 class SQLExecute
00063 : public CommandCommon<TM, SLMDC>
00064 {
00065         typedef CommandCommon<TM, SLMDC> super;
00066         typedef SQLExecute<TM, SLMDC> this_t;
00067         using super::_SQL;
00068     public:
00069         SQLExecute(const SQL::SQLStatement& SQL);
00070         SQLExecute(const ResourcePool<ResourceType<TM> >& p, const SQL::SQLStatement& SQL);
00071         virtual ~SQLExecute();
00072 
00073         // TODO: make protected
00074         /*
00075          * attemts to add another command for batch execution.
00076          * batching is only possible for exactly same SQL statements
00077          * where number and types of arguments match exactly.
00078          *
00079          * \return true if the statement was added to the batch.
00080          *         false otherwise.
00081          */
00082         bool addBatch(const SQLExecute<TM, SLMDC>& p);
00083 
00084         // similar to addBatch, BUT
00085         // but returns an empty auto_ptr (auto_ptr.get() == 0) if not batchable 
00086         // OR auot_ptr.get() !=, which is then the already cloneed noop which must be added
00087         // Do i need a specialized noop wrapper, to have access to the bind data?, yes, because tx for example or Batche don't have
00088         std::auto_ptr<Command<oracle::ResourceType<TM, SLMDC> > > addBatch2(const SQLExecute<TM, SLMDC>& p);
00089 
00090         /*
00091          * returns the number of executions currently scheduled.
00092          * usually 1, or bigger in case addBatch was called.
00093          */
00094         int  batchSize() const;
00095 
00096 #ifndef FATALMIND_TEST_SHOW_PROTECTED
00097     protected:
00098 #endif
00099         SQLExecute(const this_t&);
00100         virtual Clone* DoClone() const;
00101         void _execute(fatalmind::oracleResource<TM>&,StatementCache&);
00102         bool push_onto_BatchParamSizes(const typename super::super_bind::_argst& p);
00103         void copySizeIndicator(const typename super::super_bind::_argst& p);
00104 
00105         virtual const std::string& getCommandName() const;
00106         static const std::string _SQLExecuteName;
00107 
00108         /*
00109          * basically the catch() block for batch exceptions.
00110          * in a seperate method, just for better overview in _execute
00111          */
00112         void handleBatchException(int ret, oracleResource<TM>& rhand);
00113         /*
00114          * throws a previously stored exection (which happend
00115          * during a batch execution or returns immediately
00116          * if there is no (further) exception.
00117          */
00118         void throwBatchException() const;
00119         /*
00120          * retruns the offset of the "next" thrown exception.
00121          * or BatchCommand::NO_FURTHER_ERROR if there is none.
00122          */
00123         int  getBatchExceptionOffset() const;
00124 
00125         /*
00126          * perform the OCIBind and OCIBindArrayOfStruct() calls.
00127          */
00128         void real_bind_batch(oracleResource<TM>&);
00129 
00130         virtual void bindoutputoperator(std::ostream& str) const;
00131     private:
00132         StatementCache::handle_t _sth; // TODO, believed to be required for addBatch and similar (across execute() invitations), check again
00133 
00134         // lazy init
00135         gc_ptr<BatchInfo> batchInfo;
00140         void putInsideBatch();
00141 
00142         this_t& operator=(const this_t&);
00143         
00144     friend
00145         class oracle::OptimizedBatchCommand<Command<oracle::ResourceType<TM, SLMDC> > >;
00146 };
00147 
00148 
00149 } // namespace oracle
00150 } // namespace fatalmind
00151 #endif

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