Annotation of parser3/src/include/pa_sql_connection.h, revision 1.30.2.3
1.1 paf 1: /** @file
1.9 parser 2: Parser: sql fconnection decl.
1.1 paf 3:
1.30 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.30.2.3! paf 11: static const char* IDENT_SQL_CONNECTION_H="$Date: 2003/01/27 16:19:11 $";
1.1 paf 12:
13: #include "pa_pool.h"
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
21: #define SQL_CONNECTION_SERVICED_FUNC_GUARDED(actions) actions
22: #else
23: #define SQL_CONNECTION_SERVICED_FUNC_GUARDED(actions) \
1.30.2.3! paf 24: if(!setjmp(fservices.mark)) { \
1.28 paf 25: actions; \
26: } else \
1.30.2.3! paf 27: fservices.propagate_exception();
1.28 paf 28: #endif
1.15 paf 29:
1.30.2.3! paf 30: /// SQL_Driver_services Pooled implementation
! 31: class SQL_Driver_services_impl: public SQL_Driver_services {
! 32: Pool *fpool;
! 33: ConstStringPtr furl;
! 34: Exception fexception;
! 35: public:
! 36: SQL_Driver_services_impl(): fpool(0), furl(0) {}
! 37: void set_pool_and_url(Pool *apool, ConstStringPtr aurl) { fpool=apool; furl=aurl;}
! 38:
! 39: override void *malloc(size_t size) { return fpool->malloc(size); }
! 40: override void *calloc(size_t size) { return fpool->calloc(size); }
! 41: override void *realloc(void *ptr, size_t size) { return fpool->realloc(ptr, size); }
! 42:
! 43: /**
! 44: normally we can't 'throw' from dynamic library, so
! 45: the idea is to #1 jump to C++ some function to main body, where
! 46: every function stack frame has exception unwind information
! 47: and from there... #2 propagate_exception()
! 48:
! 49: but when parser configured --with-sjlj-exceptions
! 50: one can simply 'throw' from dynamic library.
! 51: [sad story: one can not longjump/throw due to some bug in gcc as of 3.2.1 version]
! 52: */
! 53: override void _throw(const SQL_Error& aexception) {
! 54: // converting SQL_exception to parser Exception
! 55: // hiding passwords and addresses from accidental show [imagine user forgot @exception]
! 56: #ifdef PA_WITH_SJLJ_EXCEPTIONS
! 57: throw
! 58: #else
! 59: fexception=
! 60: #endif
! 61: Exception(aexception.type(),
! 62: url_without_login(),
! 63: aexception.comment());
! 64:
! 65: #ifndef PA_WITH_SJLJ_EXCEPTIONS
! 66: longjmp(mark, 1);
! 67: #endif
! 68: }
! 69: virtual void propagate_exception() {
! 70: #ifndef PA_WITH_SJLJ_EXCEPTIONS
! 71: throw fexception;
! 72: #endif
! 73: }
! 74:
! 75: private:
! 76: ConstStringPtr url_without_login() const;
! 77: };
! 78:
1.14 parser 79: /// SQL connection. handy wrapper around low level SQL_Driver
1.30.2.1 paf 80: class SQL_Connection: public PA_Object {
1.30.2.3! paf 81: ConstStringPtr furl;
! 82: SQL_Driver& fdriver;
! 83: SQL_Driver_services_impl fservices;
! 84: void *fconnection;
! 85: time_t time_used;
! 86: bool marked_to_rollback;
1.21 paf 87:
1.1 paf 88: public:
89:
1.30.2.2 paf 90: SQL_Connection(ConstStringPtr aurl, SQL_Driver& adriver):
1.1 paf 91: furl(aurl),
1.10 parser 92: fdriver(adriver),
93: fconnection(0),
1.30.2.2 paf 94: time_used(0),
1.21 paf 95: marked_to_rollback(false) {
1.9 parser 96: }
1.12 parser 97:
1.30.2.2 paf 98: ConstStringPtr get_url() { return furl; }
1.12 parser 99:
1.30.2.3! paf 100: void set_pool(Pool *pool) {
! 101: fservices.set_pool_and_url(pool, pool?furl:ConstStringPtrZero);
1.1 paf 102: }
1.10 parser 103: bool expired(time_t older_dies) {
1.30.2.2 paf 104: return /*!freferences && */time_used<older_dies;
1.1 paf 105: }
1.21 paf 106: time_t get_time_used() { return time_used; }
1.1 paf 107:
1.10 parser 108: bool connected() { return fconnection!=0; }
1.9 parser 109: void connect(char *used_only_in_connect_url_cstr) {
1.17 paf 110: SQL_CONNECTION_SERVICED_FUNC_GUARDED(
1.15 paf 111: fdriver.connect(used_only_in_connect_url_cstr, *fservices, &fconnection)
112: );
113: }
114: void disconnect() {
1.16 paf 115: fdriver.disconnect(fconnection); fconnection=0;
1.15 paf 116: }
117: bool ping() {
1.17 paf 118: SQL_CONNECTION_SERVICED_FUNC_GUARDED(
1.15 paf 119: return fdriver.ping(*fservices, fconnection)
120: );
121: return 0; // never reached
1.9 parser 122: }
1.4 paf 123: uint quote(char *to, const char *from, unsigned int length) {
1.17 paf 124: SQL_CONNECTION_SERVICED_FUNC_GUARDED(
1.15 paf 125: return fdriver.quote(*fservices, fconnection, to, from, length)
126: );
127: return 0; // never reached
1.4 paf 128: }
129:
1.2 paf 130: void query(
1.3 paf 131: const char *statement, unsigned long offset, unsigned long limit,
1.27 paf 132: SQL_Driver_query_event_handlers& handlers,
1.30.2.2 paf 133: ConstStringPtr source) {
1.27 paf 134: try {
135: SQL_CONNECTION_SERVICED_FUNC_GUARDED(
136: fdriver.query(*fservices, fconnection,
137: statement, offset, limit,
138: handlers)
139: );
140: } catch(const Exception& e) { // query problem
1.29 paf 141: if(strcmp(e.type(), "sql.connect")==0) { // if it is _throw exception,
142: // give more specific source [were url]
143: throw Exception("sql.execute",
1.30.2.2 paf 144: source,
1.29 paf 145: "%s", e.comment());
146: } else
147: /*re*/throw;
1.27 paf 148: }
1.2 paf 149: }
150:
1.21 paf 151: void mark_to_rollback() {
152: marked_to_rollback=true;
153: }
154:
155: private: // closing process
156:
157: void commit() {
158: SQL_CONNECTION_SERVICED_FUNC_GUARDED(
159: fdriver.commit(*fservices, fconnection)
160: );
161: }
162: void rollback() {
163: SQL_CONNECTION_SERVICED_FUNC_GUARDED(
164: fdriver.rollback(*fservices, fconnection)
165: );
166: }
167:
168: /// return to cache
169: void close() {
1.24 paf 170: if(marked_to_rollback) {
1.21 paf 171: rollback();
1.24 paf 172: marked_to_rollback=false;
173: } else
1.21 paf 174: commit();
175:
1.30.2.2 paf 176: SQL_driver_manager.close_connection(furl, *this);
1.21 paf 177: }
178:
1.1 paf 179: };
180:
181: #endif
E-mail: