Annotation of parser3/src/include/pa_sql_connection.h, revision 1.37
1.1 paf 1: /** @file
1.9 parser 2: Parser: sql fconnection decl.
1.1 paf 3:
1.31 paf 4: Copyright (c) 2001-2003 ArtLebedev Group (http://www.artlebedev.com)
1.23 paf 5: Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
1.1 paf 6: */
7:
8: #ifndef PA_SQL_CONNECTION_H
9: #define PA_SQL_CONNECTION_H
1.25 paf 10:
1.37 ! paf 11: static const char * const IDENT_SQL_CONNECTION_H="$Date: 2003/12/11 09:25:50 $";
1.31 paf 12:
1.1 paf 13:
14: #include "pa_sql_driver.h"
1.4 paf 15: #include "pa_sql_driver_manager.h"
1.1 paf 16:
1.15 paf 17: // defines
18:
19: /// @see SQL_Driver_services_impl::_throw
1.28 paf 20: #ifdef PA_WITH_SJLJ_EXCEPTIONS
1.35 paf 21: #define SQL_CONNECTION_SERVICED_FUNC_GUARDED(actions) \
22: use(); \
23: actions
1.28 paf 24: #else
25: #define SQL_CONNECTION_SERVICED_FUNC_GUARDED(actions) \
1.35 paf 26: use(); \
1.31 paf 27: if(!setjmp(fservices.mark)) { \
1.28 paf 28: actions; \
29: } else \
1.31 paf 30: fservices.propagate_exception();
31: #endif
32:
33: /// SQL_Driver_services Pooled implementation
34: class SQL_Driver_services_impl: public SQL_Driver_services {
35: const String* furl;
36: Exception fexception;
1.37 ! paf 37: const char* frequest_charset;
1.31 paf 38: public:
1.37 ! paf 39: SQL_Driver_services_impl(const char* arequest_charset): furl(0), frequest_charset(arequest_charset) {}
1.31 paf 40: void set_url(const String& aurl) { furl=&aurl;}
1.34 paf 41: const String& url_without_login() const;
1.31 paf 42:
1.37 ! paf 43: override void* malloc(size_t size) { return pa_malloc(size); }
! 44: override void* malloc_atomic(size_t size) { return pa_malloc_atomic(size); }
! 45: override void* realloc(void *ptr, size_t size) { return pa_realloc(ptr, size); }
! 46:
! 47: override const char* request_charset() { return frequest_charset; }
! 48: override void transcode(const char* src, size_t src_length,
! 49: const char*& dst, size_t& dst_length,
! 50: const char* charset_from_name,
! 51: const char* charset_to_name
! 52: );
1.31 paf 53:
54: /**
55: normally we can't 'throw' from dynamic library, so
56: the idea is to #1 jump to C++ some function to main body, where
57: every function stack frame has exception unwind information
58: and from there... #2 propagate_exception()
59:
60: but when parser configured --with-sjlj-exceptions
61: one can simply 'throw' from dynamic library.
62: [sad story: one can not longjump/throw due to some bug in gcc as of 3.2.1 version]
63: */
64: override void _throw(const SQL_Error& aexception) {
65: // converting SQL_exception to parser Exception
66: // hiding passwords and addresses from accidental show [imagine user forgot @exception]
67: #ifdef PA_WITH_SJLJ_EXCEPTIONS
68: throw
69: #else
70: fexception=
1.28 paf 71: #endif
1.31 paf 72: Exception(aexception.type(),
73: &url_without_login(),
74: aexception.comment());
75:
76: #ifndef PA_WITH_SJLJ_EXCEPTIONS
77: longjmp(mark, 1);
78: #endif
79: }
80: virtual void propagate_exception() {
81: #ifndef PA_WITH_SJLJ_EXCEPTIONS
82: throw fexception;
83: #endif
84: }
85: };
1.15 paf 86:
1.14 parser 87: /// SQL connection. handy wrapper around low level SQL_Driver
1.31 paf 88: class SQL_Connection: public PA_Object {
89: const String& furl;
90: SQL_Driver& fdriver;
91: SQL_Driver_services_impl fservices;
92: void *fconnection;
93: time_t time_used;
1.21 paf 94:
1.1 paf 95: public:
96:
1.37 ! paf 97: SQL_Connection(const String& aurl, SQL_Driver& adriver, const char* arequest_charset):
1.1 paf 98: furl(aurl),
1.10 parser 99: fdriver(adriver),
1.37 ! paf 100: fservices(arequest_charset),
1.10 parser 101: fconnection(0),
1.37 ! paf 102: time_used(0) {
1.9 parser 103: }
1.34 paf 104:
105: SQL_Driver_services_impl& services() { return fservices; }
1.12 parser 106:
1.18 paf 107: const String& get_url() { return furl; }
1.12 parser 108:
1.31 paf 109: void set_url() {
110: fservices.set_url(furl);
111: }
112: void use() {
113: time_used=time(0); // they started to use at this time
1.1 paf 114: }
1.10 parser 115: bool expired(time_t older_dies) {
1.35 paf 116: return time_used<older_dies;
1.1 paf 117: }
1.21 paf 118: time_t get_time_used() { return time_used; }
1.1 paf 119:
1.10 parser 120: bool connected() { return fconnection!=0; }
1.9 parser 121: void connect(char *used_only_in_connect_url_cstr) {
1.17 paf 122: SQL_CONNECTION_SERVICED_FUNC_GUARDED(
1.31 paf 123: fdriver.connect(used_only_in_connect_url_cstr, fservices, &fconnection)
1.15 paf 124: );
125: }
126: void disconnect() {
1.16 paf 127: fdriver.disconnect(fconnection); fconnection=0;
1.15 paf 128: }
129: bool ping() {
1.17 paf 130: SQL_CONNECTION_SERVICED_FUNC_GUARDED(
1.37 ! paf 131: return fdriver.ping(fconnection)
1.15 paf 132: );
1.9 parser 133: }
1.31 paf 134: const char* quote(const char* str, unsigned int length) {
1.17 paf 135: SQL_CONNECTION_SERVICED_FUNC_GUARDED(
1.37 ! paf 136: return fdriver.quote(fconnection, str, length)
1.15 paf 137: );
1.4 paf 138: }
139:
1.2 paf 140: void query(
1.31 paf 141: const char* statement, unsigned long offset, unsigned long limit,
1.27 paf 142: SQL_Driver_query_event_handlers& handlers,
143: const String& source) {
144: try {
145: SQL_CONNECTION_SERVICED_FUNC_GUARDED(
1.37 ! paf 146: fdriver.query(fconnection,
1.27 paf 147: statement, offset, limit,
148: handlers)
149: );
150: } catch(const Exception& e) { // query problem
1.29 paf 151: if(strcmp(e.type(), "sql.connect")==0) { // if it is _throw exception,
152: // give more specific source [were url]
153: throw Exception("sql.execute",
154: &source,
155: "%s", e.comment());
156: } else
1.31 paf 157: rethrow;
1.27 paf 158: }
1.2 paf 159: }
160:
1.21 paf 161: void commit() {
162: SQL_CONNECTION_SERVICED_FUNC_GUARDED(
1.37 ! paf 163: fdriver.commit(fconnection)
1.21 paf 164: );
165: }
166: void rollback() {
167: SQL_CONNECTION_SERVICED_FUNC_GUARDED(
1.37 ! paf 168: fdriver.rollback(fconnection)
1.21 paf 169: );
170: }
171:
172: /// return to cache
173: void close() {
1.36 paf 174: SQL_driver_manager->close_connection(furl, this);
1.21 paf 175: }
176:
1.1 paf 177: };
178:
179: #endif
E-mail: