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