DCL 3.7.4
Loading...
Searching...
No Matches
SQLDriver.cpp
Go to the documentation of this file.
1#include <dcl/Config.h>
2
3#ifdef __WINNT__
4 #include <windows.h>
5#else
6 #include <dlfcn.h>
7#endif
8
9#include <dcl/_stdlib.h> // getenv
10
11#include <dcl/Object.h>
12
13#if __DCL_HAVE_ALLOC_DEBUG
14#undef __DCL_ALLOC_LEVEL
15#define __DCL_ALLOC_LEVEL __DCL_ALLOC_INTERNAL
16#endif
17
18#include <dcl/String.h>
19#include <dcl/Array.h>
20#include <dcl/Thread.h>
21#include <dcl/SQLCore.h>
22#include <dcl/SQLDriver.h>
23#include "LibState.h"
24
25#if __DCL_HAVE_THIS_FILE__
26#undef __THIS_FILE__
27static const char_t __THIS_FILE__[] = __T("dcl/SQLDriver.cpp");
28#endif
29
30__DCL_BEGIN_NAMESPACE
31
34
35SQLDriverException::SQLDriverException(const String& _name, Exception* _cause)
36 : Exception(_cause), __name(_name)
37{
38}
39
40SQLDriverException::SQLDriverException(const String& _name, ErrorCode _errorCode)
41 : __name(_name), __errorCode(_errorCode)
42{
43}
44
45SQLDriverException::SQLDriverException(const String& _name, ErrorCode _errorCode,
46 const String& _driverSummary)
47 : __name(_name), __errorCode(_errorCode), __driverSummary(_driverSummary)
48{
49}
50
52{
53 StringBuilder r = __name;
54
55 r += __T(": ");
56
57 if (Exception::cause() != NULL) {
59 }
60 else {
61 switch (__errorCode) {
62 case eInvalidDriverModule:
63 r += __T("Invalid Driver Module");
64 break;
65 case eInvalidVersion:
66 r += __T("Invalid DCL_SQL_VERSION");
67 break;
68 case eInitializeFail:
69 r += __T("Initialize callback fail!");
70 break;
71 case eCleanupFail:
72 r += __T("cleanup callback falil");
73 break;
74 default:
75 __DCL_ASSERT(false);
76 }
77
78 if (!__driverSummary.isEmpty())
79 r += __T(" :") + __driverSummary;
80 }
81
82 return r;
83}
84
88{
89 long n = Thread::incrementAndGet(__refCount);
90 return n;
91}
92
94{
95 __DCL_ASSERT(__refCount > 0); // __DCL_ASSERT_VALID(this);
96 long n = Thread::decrementAndGet(__refCount);
97 return n;
98}
99
100SQLDriver::SQLDriver(const String& _name)
102{
103 __refCount = 0;
105 open(_name);
106}
107
109{
111 try {
112 close();
113 }
114 catch (SQLDriverException* e) {
115 __DCL_TRACE1(L"Warning SQLDriver::close fail! %ls\n",
116 e->toString().data());
117 e->destroy();
118 }
119 }
120}
121
122void SQLDriver::open(const String& _name)
124{
126
127 StringBuilder filename = _name
128#ifdef __DCL_DEBUG
129 + __T("D")
130#elif defined(_DEBUG)
131 + __T("Dd")
132#endif
133 ;
134
135 filename +=
136#ifdef __WINNT__
137 __T(".dll")
138#elif defined(__APPLE__)
139 __T(".dylib")
140#else
141 __T(".so")
142#endif
143 ;
144
145 int flags = Dll::DEFAULT
146 #ifdef RTLD_LAZY
147 | RTLD_LAZY
148 #endif
149 ;
150
151 try {
152 Dll::open(filename.toString(), flags);
153 }
154 catch (Exception* _cause) {
155 throw new SQLDriverException(_name, _cause);
156 }
157
158 try {
159 SQL::DRIVER_MODULE* entryPoint = NULL;
160 try {
161 entryPoint = (SQL::DRIVER_MODULE*)getAddress(
163 }
164 catch (Exception* _cause) {
165 throw new SQLDriverException(_name, _cause);
166 }
167
168 if (entryPoint->uSize != sizeof(SQL::DRIVER_MODULE)) {
169 throw new SQLDriverException(_name,
170 SQLDriverException::eInvalidDriverModule);
171 }
172
173 if (__VERSION_MAJOR_MINOR(entryPoint->uVersion)
175 throw new SQLDriverException(_name,
176 SQLDriverException::eInvalidVersion);
177 }
178
179 if (entryPoint->pfnInitialize == NULL
180 || entryPoint->pfnCleanup == NULL
181 || entryPoint->pfnCreateConnectionInstance == NULL) {
182 throw new SQLDriverException(_name,
183 SQLDriverException::eInvalidDriverModule);
184 }
185
186 if (!entryPoint->pfnInitialize()) {
187 throw new SQLDriverException(_name,
188 SQLDriverException::eInitializeFail
189 );
190 }
191
192 __pModuleEntryPoint = entryPoint;
193 __driverName = _name;
194
195 __DCL_TRACE3(__T("Open SQLDriver: %ls (%ls, %ls)\n"),
196 _name.data(),
197 filename.data(),
198 getDriverSummary().data()
199 );
200 }
201 catch (Exception* e) {
202 try {
203 Dll::close();
204 }
205 catch (Exception* _nt) {
206 _nt->destroy();
207 }
208 throw e;
209 }
210}
211
214{
215 Exception* e = NULL;
216 try {
217 __DCL_ASSERT(refCount() == 0);
219
222
223 if (!pEntryPoint->pfnCleanup()) {
225 SQLDriverException::eCleanupFail,
227 );
228 }
229 }
230 catch (Exception* _e) {
231 e = _e;
232 }
233
234 try {
235 Dll::close();
236 }
237 catch (Exception* _e) {
238 if (e != NULL) {
239 __DCL_TRACE1(L"%ls", _e->toString().data());
240 throw e;
241 }
242 else {
243 throw new SQLDriverException(__driverName, _e);
244 }
245 }
246}
247
249{
251 SQL::Connection* pNewConnection =
252 __pModuleEntryPoint->pfnCreateConnectionInstance();
253 addRef();
254 return pNewConnection;
255}
256
258{
259 pConnection->destroy();
260 release();
261}
262
264{
266
267 StringBuilder r = __T("DriverName:") + __driverName;
268 r += __T(", FileName:") + Dll::__filename;
269
270 r += __T(", DCLCVersion:");
271 r.format(L"%u.%u",
274 );
275
276 r += __T(", SQLVersion:");
277 r.format(L"%u.%u",
280 );
281
282 r += L", Build:";
283 r += __pModuleEntryPoint->uBuildFlag ? L"Debug" : L"Release";
284 if (__pModuleEntryPoint->pszBuildTimeStamp) {
285 r += L" ";
286 r += __pModuleEntryPoint->pszBuildTimeStamp;
287 }
288
289 if (__pModuleEntryPoint->pfnInitialize == NULL)
290 r += L", pfnInitialize: (null)";
291 if (__pModuleEntryPoint->pfnInitialize == NULL)
292 r += L", pfnCleanup: (null)";
293 if (__pModuleEntryPoint->pfnCreateConnectionInstance == NULL)
294 r += L", pfnCreateConnectionInstance: (null)";
295
296 if (__pModuleEntryPoint->pszFileVersion) {
297 r += L", FileVersion:";
298 r += __pModuleEntryPoint->pszFileVersion;
299 }
300
301 if (__pModuleEntryPoint->pszServerTitle) {
302 r += L", ServerTitle:";
303 r += __pModuleEntryPoint->pszServerTitle;
304 }
305
306 if (__pModuleEntryPoint->pszDescription) {
307 r += L", Description:";
308 r += __pModuleEntryPoint->pszDescription;
309 }
310 return r;
311}
312
314{
316protected:
317 PointerArray __drivers;
318public:
319 SQLDriver* getDriver(const String& _name)
321
322 void clearAll();
323 void clear(SQLDriver* pDriver)
325
326 bool isEmpty() const { return __drivers.isEmpty(); }
327};
328
330
331SQLDriver* SQLDriverPool::getDriver(const String& _name)
333{
334 String name = _name.trim();
335
336 SQLDriver* driver = NULL;
337 // find previous loaded module
338 for (PointerArray::Iterator it = __drivers.begin();
339 it != __drivers.end(); it++) {
340 if (!((SQLDriver*)(*it))->driverName().compareNoCase(name)) {
341 driver = (SQLDriver*)(*it);
342 break;
343 }
344 }
345
346 if (!driver) {
347 // not found. load new driver
349 __T("Open New SQLDriver: %ls, Prev-Count: %d\n"),
350 name.data(),
351 __drivers.size()
352 );
353
354 driver = new SQLDriver(_name);
355 __drivers.add(driver);
356 }
357
358 return driver;
359}
360
362{
363 // unload all drivers
364 SQLDriver* driver = NULL;
365 for(PointerArray::Iterator it = __drivers.begin();
366 it != __drivers.end(); it++) {
367 driver = (SQLDriver*)(*it);
368 __DCL_ASSERT(driver->refCount() == 0);
369
370 try {
371 driver->close();
372 __DCL_TRACE3(__T("Close SQLDriver:%p, %ls (%ls)\n"),
373 driver,
374 driver->driverName().data(),
375 driver->fileName().data()
376 );
377 }
378 catch (Exception* e) {
379 __DCL_TRACE2(__T("Wrining!! SQLDriver Close Fail! :%p, %ls\n"),
380 driver,
381 e->toString().data()
382 );
383 e->destroy();
384 }
385
386 delete driver;
387 }
388
389 __drivers.clear();
390}
391
394{
395 PointerArray::Iterator it = __drivers.find(driver);
396 __DCL_ASSERT(__drivers.end() != it);
397 __drivers.erase(it);
398
399 Exception* e = NULL;
400 try {
401 driver->close();
402 __DCL_TRACE3(__T("Close SQLDriver:%p, %ls (%ls)\n"),
403 driver,
404 driver->driverName().data(),
405 driver->fileName().data()
406 );
407 }
408 catch (Exception* _e) {
409 e = _e;
410 }
411
412 delete driver;
413
414 if (e != NULL) {
415 throw e;
416 }
417}
418
419// SQLDriver's static members
420extern LibState* __LibState__;
421static SQLDriverPool* __DriverPool__ = NULL;
422
423static void cleanupDriverContext()
424{
425 if (__DriverPool__ == NULL)
426 return;
427
428 __LibState__->lockSQLDriverPool.lock();
429
430 __DriverPool__->clearAll();
431 delete __DriverPool__;
432 __DriverPool__ = NULL;
433
434 __LibState__->lockSQLDriverPool.unlock();
435}
436
437SQLDriver* SQLDriver::getDriver(const String& _name)
439{
440 SQLDriver* r = NULL;
441 Exception* e = NULL;
442
443 __LibState__->lockSQLDriverPool.lock();
444 try {
445 if (__DriverPool__ == NULL) {
446 __DriverPool__ = new SQLDriverPool();
447 __LibState__->pfnSQLCleanup = cleanupDriverContext;
448 }
449 __DCL_ASSERT(__DriverPool__ != NULL);
450
451 r = __DriverPool__->getDriver(_name);
452 }
453 catch (Exception* _e) {
454 e = _e;
455 }
456 __LibState__->lockSQLDriverPool.unlock();
457
458 if (e != NULL) {
459 throw e;
460 }
461
462 return r;
463}
464
467{
468 __DCL_ASSERT(_driver);
469 __DCL_ASSERT(_driver->refCount() == 0);
470 __DCL_ASSERT(__DriverPool__ != NULL);
471
472 Exception* e = NULL;
473
474 __LibState__->lockSQLDriverPool.lock();
475 try {
476 __DriverPool__->clear(_driver);
477 }
478 catch (Exception* _e) {
479 e = _e;
480 }
481 __LibState__->lockSQLDriverPool.unlock();
482
483 if (e != NULL) {
484 throw e;
485 }
486}
487
488__DCL_END_NAMESPACE
#define __THIS_FILE__
Definition _trace.h:14
#define NULL
Definition Config.h:312
#define DCLCAPI
Definition Config.h:95
#define DCL_DSO_ENTRY_POINT_STRING
Definition Config.h:357
wchar_t char_t
Definition Config.h:247
#define __DCL_THROWS1(e)
Definition Config.h:152
__DCL_BEGIN_NAMESPACE LibState * __LibState__
Definition LibMain.cpp:64
IOException *size_t r
Definition MediaInfo.cpp:82
#define __DCL_TRACE1(fmt, arg1)
Definition Object.h:399
#define __DCL_TRACE3(fmt, arg1, arg2, arg3)
Definition Object.h:401
#define DECLARE_CLASSINFO(class_name)
Definition Object.h:227
#define __DCL_ASSERT(expr)
Definition Object.h:394
#define IMPLEMENT_CLASSINFO(class_name, base_class_name)
Definition Object.h:245
#define __T(str)
Definition Object.h:60
#define __DCL_TRACE2(fmt, arg1, arg2)
Definition Object.h:400
Definition Dll.h:28
String __filename
Definition Dll.h:57
virtual String toString() const
Definition Exception.cpp:40
virtual void destroy()
Definition Exception.cpp:74
const Exception * cause() const
Definition Exception.h:50
Object()
Definition Object.cpp:183
virtual void destroy()=0
virtual String toString() const
Definition SQLDriver.cpp:51
SQLDriverException(const String &_name, Exception *_cause)
static SQLDriver * getDriver(const String &_name) __DCL_THROWS1(SQLDriverException *)
SQL::Connection * createConnection()
long addRef()
static void closeDriver(SQLDriver *_pSQLDriver) __DCL_THROWS1(SQLDriverException *)
void close() __DCL_THROWS1(SQLDriverException *)
String getDriverSummary() const
String __driverName
Definition SQLDriver.h:80
SQLDriver(const String &_name) __DCL_THROWS1(SQLDriverException *)
SQL::DRIVER_MODULE * __pModuleEntryPoint
Definition SQLDriver.h:79
const String & driverName() const
Definition SQLDriver.h:72
void destroyConnection(SQL::Connection *pConnection)
long release()
Definition SQLDriver.cpp:93
void open(const String &_name) __DCL_THROWS1(SQLDriverException *)
long refCount() const
Definition SQLDriver.h:56
virtual ~SQLDriver()
SQLDriver * getDriver(const String &_name) __DCL_THROWS1(SQLDriverException *)
void clear(SQLDriver *pDriver) __DCL_THROWS1(SQLDriverException *)
bool isEmpty() const
static long incrementAndGet(volatile long &_n)
static long decrementAndGet(volatile long &_n)
#define DCL_SQL_VERSION
#define __VERSION_MINOR(_x)
#define __VERSION_MAJOR(_x)
#define __VERSION_MAJOR_MINOR(_x)
bool(* pfnCleanup)()
Definition SQLCore.h:474
uint32_t uVersion
Definition SQLCore.h:470
Connection *(* pfnCreateConnectionInstance)()
Definition SQLCore.h:475
bool(* pfnInitialize)()
Definition SQLCore.h:473