--- parser3/src/include/pa_sql_connection.h 2003/01/27 16:19:11 1.30.2.2 +++ parser3/src/include/pa_sql_connection.h 2003/01/28 09:48:16 1.30.2.4 @@ -8,7 +8,7 @@ #ifndef PA_SQL_CONNECTION_H #define PA_SQL_CONNECTION_H -static const char* IDENT_SQL_CONNECTION_H="$Date: 2003/01/27 16:19:11 $"; +static const char* IDENT_SQL_CONNECTION_H="$Date: 2003/01/28 09:48:16 $"; #include "pa_pool.h" #include "pa_sql_driver.h" @@ -21,14 +21,69 @@ static const char* IDENT_SQL_CONNECTION_ #define SQL_CONNECTION_SERVICED_FUNC_GUARDED(actions) actions #else #define SQL_CONNECTION_SERVICED_FUNC_GUARDED(actions) \ - if(!fservices || !setjmp(fservices->mark)) { \ + if(!setjmp(fservices.mark)) { \ actions; \ } else \ - fservices->propagate_exception(); + fservices.propagate_exception(); #endif +/// SQL_Driver_services Pooled implementation +class SQL_Driver_services_impl: public SQL_Driver_services { + Pool *fpool; + ConstStringPtr furl; + Exception fexception; +public: + SQL_Driver_services_impl(): fpool(0), furl(0) {} + void set_pool_and_url(Pool *apool, ConstStringPtr aurl) { fpool=apool; furl=aurl;} + + override void *malloc(size_t size) { return fpool->malloc(size); } + override void *calloc(size_t size) { return fpool->calloc(size); } + override void *realloc(void *ptr, size_t size) { return fpool->realloc(ptr, size); } + + /** + normally we can't 'throw' from dynamic library, so + the idea is to #1 jump to C++ some function to main body, where + every function stack frame has exception unwind information + and from there... #2 propagate_exception() + + but when parser configured --with-sjlj-exceptions + one can simply 'throw' from dynamic library. + [sad story: one can not longjump/throw due to some bug in gcc as of 3.2.1 version] + */ + override void _throw(const SQL_Error& aexception) { + // converting SQL_exception to parser Exception + // hiding passwords and addresses from accidental show [imagine user forgot @exception] +#ifdef PA_WITH_SJLJ_EXCEPTIONS + throw +#else + fexception= +#endif + Exception(aexception.type(), + url_without_login(), + aexception.comment()); + +#ifndef PA_WITH_SJLJ_EXCEPTIONS + longjmp(mark, 1); +#endif + } + virtual void propagate_exception() { +#ifndef PA_WITH_SJLJ_EXCEPTIONS + throw fexception; +#endif + } + +private: + ConstStringPtr url_without_login() const; +}; + /// SQL connection. handy wrapper around low level SQL_Driver class SQL_Connection: public PA_Object { + ConstStringPtr furl; + SQL_Driver& fdriver; + SQL_Driver_services_impl fservices; + void *fconnection; + time_t time_used; + bool marked_to_rollback; public: @@ -42,8 +97,8 @@ public: ConstStringPtr get_url() { return furl; } - void set_services(SQL_Driver_services *aservices) { - fservices=aservices; + void set_pool(Pool *pool) { + fservices.set_pool_and_url(pool, pool?furl:ConstStringPtrZero); } bool expired(time_t older_dies) { return /*!freferences && */time_used