--- parser3/src/include/pa_sql_connection.h 2001/05/17 13:23:28 1.9 +++ parser3/src/include/pa_sql_connection.h 2024/11/04 03:53:25 1.49 @@ -1,66 +1,181 @@ /** @file Parser: sql fconnection decl. - Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com) - - Author: Alexander Petrosyan (http://design.ru/paf) - - $Id: pa_sql_connection.h,v 1.9 2001/05/17 13:23:28 parser Exp $ + Copyright (c) 2001-2024 Art. Lebedev Studio (http://www.artlebedev.com) + Authors: Konstantin Morshnev , Alexandr Petrosian */ #ifndef PA_SQL_CONNECTION_H #define PA_SQL_CONNECTION_H -#include "pa_config_includes.h" -#include "pa_pool.h" +#define IDENT_PA_SQL_CONNECTION_H "$Id: pa_sql_connection.h,v 1.49 2024/11/04 03:53:25 moko Exp $" + + #include "pa_sql_driver.h" #include "pa_sql_driver_manager.h" -/// SQL fconnection. handy wrapper around low level SQL_Driver -class SQL_Connection : public Pooled { +// defines +/// @see SQL_Driver_services_impl::_throw +#ifdef PA_WITH_SJLJ_EXCEPTIONS + #define SQL_CONNECTION_SERVICED_FUNC_GUARDED(actions) \ + use(); \ + actions +#else + #define SQL_CONNECTION_SERVICED_FUNC_GUARDED(actions) \ + use(); \ + if(!setjmp(fservices.mark)) { \ + actions; \ + } else \ + fservices.propagate_exception(); +#endif + +/// SQL_Driver_services Pooled implementation +class SQL_Driver_services_impl: public SQL_Driver_services { + const String* furl; + Exception fexception; + const char* frequest_charset; + const char* fdocument_root; public: + SQL_Driver_services_impl(const char* arequest_charset, const char* adocument_root): furl(0), frequest_charset(arequest_charset), fdocument_root(adocument_root) {} + void set_url(const String& aurl) { furl=&aurl;} + const String& url_without_login() const; + + override void* malloc(size_t size) { return pa_malloc(size); } + override void* malloc_atomic(size_t size) { return pa_malloc_atomic(size); } + override void* realloc(void *ptr, size_t size) { return pa_realloc(ptr, size); } + + override const char* request_charset() { return frequest_charset; } + override const char* request_document_root() { return fdocument_root; } + + override void transcode(const char* src, size_t src_length, + const char*& dst, size_t& dst_length, + const char* charset_from_name, + const char* charset_to_name + ); + + /** + 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() ? aexception.type() : "sql.connect", &url_without_login(), aexception.comment()); - SQL_Connection(Pool& pool, const String& aurl, SQL_Driver& adriver) : Pooled(pool), - furl(aurl), - fdriver(adriver) { +#ifndef PA_WITH_SJLJ_EXCEPTIONS + longjmp(mark, 1); +#endif } - void set_services(SQL_Driver_services *aservices) { - fservices=aservices; + + virtual void propagate_exception() { +#ifndef PA_WITH_SJLJ_EXCEPTIONS + throw fexception; +#endif } +}; - void close() { - SQL_driver_manager->close_connection(furl, *this); +/// SQL connection. handy wrapper around low level SQL_Driver +class SQL_Connection: public PA_Object { + const String& furl; + SQL_Driver& fdriver; + SQL_Driver_services_impl fservices; + void *fconnection; + time_t time_used; + +public: + + SQL_Connection(const String& aurl, SQL_Driver& adriver, const char* arequest_charset, const char* adocument_root): + furl(aurl), + fdriver(adriver), + fservices(arequest_charset, adocument_root), + fconnection(0), + time_used(0) { } - void connect(char *used_only_in_connect_url_cstr) { - fdriver.connect(used_only_in_connect_url_cstr, *fservices, &fconnection); + SQL_Driver_services_impl& services() { return fservices; } + + const String& get_url() { return furl; } + + void set_url() { + fservices.set_url(furl); } - void disconnect() { fdriver.disconnect(*fservices, fconnection); } - void commit() { fdriver.commit(*fservices, fconnection); } - void rollback() { fdriver.rollback(*fservices, fconnection); } - bool ping() { return fdriver.ping(*fservices, fconnection); } - uint quote(char *to, const char *from, unsigned int length) { - return fdriver.quote(*fservices, fconnection, to, from, length); + void use() { + time_used=time(0); // they started to use at this time } + bool expired(time_t older_dies) { + return time_usedclose_connection(furl, this); + } - const String& furl; - SQL_Driver& fdriver; - SQL_Driver_services *fservices; - void *fconnection; }; #endif