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