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