DCL 3.7.4
Loading...
Searching...
No Matches
ODBCConnection Class Reference

#include <ODBCConnection.h>

Inheritance diagram for ODBCConnection:
SQL::Connection Object

Public Member Functions

SQLHDBC connHandle () const
bool IS_MS_SS () const
void setErrorHandle (SQLRETURN _rc, SQLSMALLINT _htype, SQLHANDLE _handle, const wchar_t *_filename, int _line)
void setErrorMessage (const ByteString &_message, const wchar_t *_filename, int _line)
 ODBCConnection (const wchar_t *_serverTitle)
virtual void destroy ()
virtual ~ODBCConnection ()
virtual bool __open (const char *_cons, size_t _conslen)
virtual bool __close ()
virtual bool __execute (const char *_sql, size_t _sqllen)
virtual bool __startTrans ()
virtual bool __commitTrans ()
virtual bool __rollbackTrans ()
virtual bool __createQueryInstance (SQL::Query **_queryHandleOut)
virtual bool __getErrorMessage (char *_buf, size_t *_buflen)
virtual bool __getServerInfo (char *_buf, size_t *_buflen)
Public Member Functions inherited from SQL::Connection
long refCount () const
long addRef ()
long release ()
bool open (const char *_conn, size_t _connlen)
bool close ()
bool execute (const char *_sql, size_t _sqllen)
bool startTrans ()
bool commitTrans ()
bool rollbackTrans ()
bool getErrorMessage (char *_buf, size_t *_buflen)
bool getServerInfo (char *_buf, size_t *_buflen)
bool createQueryInstance (Query **_queryHandle)
bool destroyQueryInstance (Query *_queryHandle)
Error errorCode () const
bool canTransact () const
const wchar_t * serverTitle () const
bool inState (unsigned int _state) const
Public Member Functions inherited from Object
virtual String toString () const
String className () const
bool isInstanceOf (const std::type_info &typeinfo) const
virtual const std::type_info & typeInfo () const

Additional Inherited Members

Public Types inherited from SQL::Connection
enum  State { stClosed = 0x0001 , stOpenned = 0x0002 , stInTransaction = 0x0004 }
Static Public Member Functions inherited from SQL::Connection
static size_t splitConnStr (const char *_connstr, size_t _strlen, ListedByteStringToByteStringMap &_results)
Public Attributes inherited from SQL::Connection
_PROTECTED : void setErrorStatus( Error _errorCode
_PROTECTED const wchar_t * _filename
_PROTECTED const wchar_t int _line
Protected Member Functions inherited from SQL::Connection
 Connection (const wchar_t *_serverTitle)
virtual ~Connection ()
Protected Member Functions inherited from Object
virtual ~Object ()
 Object ()
Protected Attributes inherited from SQL::Connection
bool __canTransact
const wchar_t * __serverTitle
Error __errorCode
const wchar_t * __errorFileName
int __errorLine
unsigned int __states

Detailed Description

Definition at line 8 of file ODBCConnection.h.

Constructor & Destructor Documentation

◆ ODBCConnection()

ODBCConnection::ODBCConnection ( const wchar_t * _serverTitle)

◆ ~ODBCConnection()

ODBCConnection::~ODBCConnection ( )
virtual

Definition at line 67 of file ODBCConnection.cpp.

68{
69 if (__hdbc) {
70 __DCL_TRACE0_N(L"Warning!! The connection was not closed\n");
71 close();
72 }
73
74 if (__henv) {
75 SQLRETURN rc_ = SQLFreeHandle(SQL_HANDLE_ENV, __henv);
76 if (rc_ != SQL_SUCCESS) {
77 __DCL_TRACE1_N(L"SQLFreeHandle(ENV) Fail! [%d]\n", rc_);
78 }
79 __henv = NULL;
80 }
81}
#define NULL
Definition Config.h:312
#define __DCL_TRACE1_N(fmt, arg)
#define __DCL_TRACE0_N(fmt)

Member Function Documentation

◆ __close()

bool ODBCConnection::__close ( )
virtual

Implements SQL::Connection.

Definition at line 174 of file ODBCConnection.cpp.

175{
176 if (!__hdbc) {
178 return false;
179 }
180
181 SQLRETURN rc = SQL_SUCCESS;
182 rc = SQLDisconnect(__hdbc);
183 if (rc != SQL_SUCCESS) {
184 __SET_ERROR_HANDLE(rc, SQL_HANDLE_DBC, __hdbc);
185 }
186
187 SQLRETURN rc_ = SQLFreeHandle(SQL_HANDLE_DBC, __hdbc);
188 if (rc_ != SQL_SUCCESS) {
189 __DCL_TRACE1_N(L"SQLFreeHandle(DBC) Fail! [%d]\n", rc_);
190 }
191 __hdbc = NULL;
192
193 return rc == SQL_SUCCESS;
194}
#define __SET_ERROR_HANDLE(_SQLCODE)
#define __SET_ERROR(_errorCode)
Definition SQLCore.cpp:149
@ eNotConnected
Definition SQLCore.h:33

◆ __commitTrans()

bool ODBCConnection::__commitTrans ( )
virtual

Implements SQL::Connection.

Definition at line 231 of file ODBCConnection.cpp.

232{
233 __UNSET_STATE(Connection::stInTransaction);
234 SQLRETURN rc = SQLEndTran(SQL_HANDLE_DBC, __hdbc, SQL_COMMIT);
235 if (rc != SQL_SUCCESS) {
236 __SET_ERROR_HANDLE(rc, SQL_HANDLE_DBC, __hdbc);
237 return false;
238 }
239
240 return true;
241}
#define __UNSET_STATE(state)
Definition SQLCore.h:483

◆ __createQueryInstance()

bool ODBCConnection::__createQueryInstance ( SQL::Query ** _queryHandleOut)
virtual

Implements SQL::Connection.

Definition at line 255 of file ODBCConnection.cpp.

256{
257 __DCL_ASSERT(_ppQuery != NULL);
258
259 ODBCQuery* pNewQuery = new ODBCQuery(this);
260 if (!pNewQuery) {
262 return false;
263 }
264
265 *_ppQuery = pNewQuery;
266 return true;
267}
#define __DCL_ASSERT(expr)
Definition Object.h:394
@ eOutOfMemory
Definition SQLCore.h:24

◆ __execute()

bool ODBCConnection::__execute ( const char * _sql,
size_t _sqllen )
virtual

Implements SQL::Connection.

Definition at line 196 of file ODBCConnection.cpp.

197{
198 SQLHSTMT hstmt = NULL;
199 SQLRETURN rc = SQLAllocHandle(SQL_HANDLE_STMT, __hdbc, &hstmt);
200 if (rc != SQL_SUCCESS) {
201 __SET_ERROR_HANDLE(rc, SQL_HANDLE_DBC, __hdbc);
202 return false;
203 }
204
205 rc = SQLExecDirectA(hstmt, (SQLCHAR*) _sql, (SQLINTEGER)_sqllen);
206 if (!SQL_SUCCEEDED(rc)) {
207 __SET_ERROR_HANDLE(rc, SQL_HANDLE_STMT, hstmt);
208 }
209 __SET_INFO_HANDLE(rc, SQL_HANDLE_STMT, hstmt);
210
211 SQLRETURN rc_ = SQLFreeStmt(hstmt, SQL_CLOSE);
212 if (rc_ != SQL_SUCCESS) {
213 __DCL_TRACE1_N(L"SQLFreeStmt(STMT) Fail! [%d]\n", rc_);
214 }
215
216 rc_ = SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
217 if (rc_ != SQL_SUCCESS) {
218 __DCL_TRACE1_N(L"SQLFreeHandle(STMT) Fail! [%d]\n", rc_);
219 }
220 hstmt = NULL;
221
222 return rc == SQL_SUCCESS;
223}
#define __SET_INFO_HANDLE(_rc, _htype, _handle)

◆ __getErrorMessage()

bool ODBCConnection::__getErrorMessage ( char * _buf,
size_t * _buflen )
virtual

Implements SQL::Connection.

Definition at line 269 of file ODBCConnection.cpp.

270{
271 if (__lastErrorMessage.length() < *_buflen) {
272 *_buflen = __lastErrorMessage.length();
273 *(_buf + *_buflen) = '\0';
274 }
275 strncpy(_buf, __lastErrorMessage.data(), *_buflen);
276 __lastErrorMessage.clear();
277 return true;
278}

◆ __getServerInfo()

bool ODBCConnection::__getServerInfo ( char * _buf,
size_t * _buflen )
virtual

Implements SQL::Connection.

Definition at line 280 of file ODBCConnection.cpp.

281{
282#if 0 && defined(__WINNT__)
283 StringBuilder sb;
284 WCHAR buf[1024];
285 SQLSMALLINT length;
286
287 SQLRETURN rc = SQLGetInfoW(__hdbc, SQL_DBMS_NAME, buf, __countof(buf, WCHAR) , &length);
288 if (rc != SQL_SUCCESS) {
289 __SET_ERROR_HANDLE(rc, SQL_HANDLE_DBC, __hdbc);
290 return false;
291 }
292 sb.append(buf, length / sizeof(WCHAR));
293
294 rc = SQLGetInfoW(__hdbc, SQL_DBMS_VER, buf, __countof(buf, WCHAR) , &length);
295 if (rc != SQL_SUCCESS) {
296 __SET_ERROR_HANDLE(rc, SQL_HANDLE_DBC, __hdbc);
297 return false;
298 }
299 sb.append(L' ');
300 sb.append(buf, length / sizeof(WCHAR));
301
302 ByteString s = UTF8Encoder::encode(sb.toString());
303 if (s.length() < *_buflen) {
304 *_buflen = s.length();
305 }
306 strncpy(_buf, s.data(), *_buflen);
307 return true;
308#else
309 SQLSMALLINT size = (SQLSMALLINT) __MIN(*_buflen, SHRT_MAX);
310 SQLSMALLINT offset = 0;
311 SQLSMALLINT length;
312 SQLRETURN rc = SQL_SUCCESS;
313
314 rc = SQLGetInfoA(__hdbc, SQL_DBMS_NAME,
315 _buf + offset, size - offset, &length);
316 if (rc != SQL_SUCCESS) {
317 __SET_ERROR_HANDLE(rc, SQL_HANDLE_DBC, __hdbc);
318 return false;
319 }
320
321 if ((offset + length) >= size) {
322 *_buflen = size;
323 return true;
324 }
325
326 offset += length;
327 *(_buf + offset) = ' ';
328 offset++;
329
330 rc = SQLGetInfoA(__hdbc, SQL_DBMS_VER,
331 _buf + offset, size - offset, &length);
332 if (rc != SQL_SUCCESS) {
333 __SET_ERROR_HANDLE(rc, SQL_HANDLE_DBC, __hdbc);
334 return false;
335 }
336
337 if ((offset + length) >= size) {
338 *_buflen = size;
339 return true;
340 }
341
342 *_buflen = offset + length;
343 return true;
344#endif
345}
#define __countof(array, type)
Definition Config.h:336
size_t __MIN(size_t x, size_t y)
Definition size_t.h:27

◆ __open()

bool ODBCConnection::__open ( const char * _cons,
size_t _conslen )
virtual

Implements SQL::Connection.

Definition at line 88 of file ODBCConnection.cpp.

89{
90 SQLRETURN rc = SQL_SUCCESS;
91 if (!__henv) {
92 rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &__henv);
93 if (rc != SQL_SUCCESS) {
95 ByteString::format("Unable to allocate an environment handle [%d]",
96 rc));
97 return false;
98 }
99
100 rc = SQLSetEnvAttr(__henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0);
101 if (rc != SQL_SUCCESS) {
102 __SET_ERROR_HANDLE(rc, SQL_HANDLE_ENV, __henv);
103 return false;
104 }
105 }
106
107 __DCL_ASSERT_HANDLE(__hdbc == NULL);
108 rc = SQLAllocHandle(SQL_HANDLE_DBC, __henv, &__hdbc);
109 if (rc != SQL_SUCCESS) {
110 __SET_ERROR_HANDLE(rc, SQL_HANDLE_ENV, __henv);
111 return false;
112 }
113
114 for ( ; ; ) {
115 SQLSMALLINT length2 = 0;
116 rc = SQLDriverConnectA(__hdbc, NULL,
117 (SQLCHAR*)_cons, (SQLSMALLINT)_conslen,
118 NULL, 0, &length2, SQL_DRIVER_NOPROMPT
119 );
120 if (!SQL_SUCCEEDED(rc)) {
121 __SET_ERROR_HANDLE(rc, SQL_HANDLE_DBC, __hdbc);
122 break;
123 }
124 __SET_INFO_HANDLE(rc, SQL_HANDLE_DBC, __hdbc);
125
126#if defined(__WINNT__) && !defined(strncasecmp)
127#define strncasecmp(s1,s2,n) _strnicmp(s1,s2,n)
128#endif
129 char buf[128];
130 SQLSMALLINT len = sizeof(buf);
131 rc = SQLGetInfoA(__hdbc, SQL_DBMS_NAME, buf, len, &len);
132 if (rc != SQL_SUCCESS) {
133 __SET_ERROR_HANDLE(rc, SQL_HANDLE_DBC, __hdbc);
134 return false;
135 }
136 __IS_MS_SS = strncasecmp(buf, "Microsoft SQL Server", __MIN(9, len)) == 0;
137 __DCL_TRACE3_N(L"[%hs][%d] [%d]\n", buf, len, __IS_MS_SS);
138
139 rc = SQLSetConnectAttrA(__hdbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_OFF, 0);
140 if (rc != SQL_SUCCESS) {
141 __SET_ERROR_HANDLE(rc, SQL_HANDLE_DBC, __hdbc);
142 break;
143 }
144
145 #if __TRACE_THIS
146 SQLUINTEGER GetDataSupport = 0;
147 SQLSMALLINT length;
148
149 rc = SQLGetInfoA(__hdbc, SQL_GETDATA_EXTENSIONS,
150 &GetDataSupport, sizeof(GetDataSupport), &length);
151 __DCL_TRACE3_N(L"[%04x] AC[%04x] AO[%04x]\n",
152 GetDataSupport,
153 GetDataSupport & SQL_GD_ANY_COLUMN,
154 GetDataSupport & SQL_GD_ANY_ORDER
155 );
156 __DCL_TRACE3_N(L"BL[%04x] BO[%04x] OP[%04x]\n",
157 GetDataSupport & SQL_GD_BLOCK,
158 GetDataSupport & SQL_GD_BOUND,
159 GetDataSupport & SQL_GD_OUTPUT_PARAMS
160 );
161 #endif
162 return true;
163 }
164
165 // Connect Failed
166 SQLRETURN rc_ = SQLFreeHandle(SQL_HANDLE_DBC, __hdbc);
167 if (rc_ != SQL_SUCCESS) {
168 __DCL_TRACE1_N(L"SQLFreeHandle(DBC) Fail! [%d]\n", rc_);
169 }
170 __hdbc = NULL;
171 return false;
172}
#define __DCL_TRACE3_N(fmt, arg1, arg2, arg3)
#define __SET_ERROR_MSG(_message)
#define __DCL_ASSERT_HANDLE(expr)
Definition Object.h:408

◆ __rollbackTrans()

bool ODBCConnection::__rollbackTrans ( )
virtual

Implements SQL::Connection.

Definition at line 243 of file ODBCConnection.cpp.

244{
245 __UNSET_STATE(Connection::stInTransaction);
246 SQLRETURN rc = SQLEndTran(SQL_HANDLE_DBC, __hdbc, SQL_ROLLBACK);
247 if (rc != SQL_SUCCESS) {
248 __SET_ERROR_HANDLE(rc, SQL_HANDLE_DBC, __hdbc);
249 return false;
250 }
251
252 return true;
253}

◆ __startTrans()

bool ODBCConnection::__startTrans ( )
virtual

Implements SQL::Connection.

Definition at line 225 of file ODBCConnection.cpp.

226{
227 __SET_STATE(Connection::stInTransaction);
228 return true;
229}
#define __SET_STATE(state)
Definition SQLCore.h:482

◆ connHandle()

SQLHDBC ODBCConnection::connHandle ( ) const
inline

Definition at line 50 of file ODBCConnection.h.

51{
52 return __hdbc;
53}

◆ destroy()

void ODBCConnection::destroy ( )
virtual

파생클래스에서 new 연산자를 override했거나, 추가적인 행위가 필요하다면 이것도 override하라

Implements SQL::Connection.

Definition at line 83 of file ODBCConnection.cpp.

84{
85 delete this;
86}

◆ IS_MS_SS()

bool ODBCConnection::IS_MS_SS ( ) const
inline

Definition at line 55 of file ODBCConnection.h.

56{
57 return __IS_MS_SS;
58}

◆ setErrorHandle()

void ODBCConnection::setErrorHandle ( SQLRETURN _rc,
SQLSMALLINT _htype,
SQLHANDLE _handle,
const wchar_t * _filename,
int _line )

Definition at line 347 of file ODBCConnection.cpp.

354{
355 Connection::setErrorStatus(SQL::eServerError, _filename, _line);
356
357 if (_rc == SQL_SUCCESS_WITH_INFO || _rc == SQL_ERROR) {
359 _htype == SQL_HANDLE_ENV
360 || _htype == SQL_HANDLE_DBC
361 || _htype == SQL_HANDLE_STMT
362 || _htype == SQL_HANDLE_DESC
363 // || _htype == SQL_HANDLE_DBC_INFO_TOKEN
364 );
365 __DCL_ASSERT(_handle != NULL);
366
367#if 0 && defined(__WINNT__)
368 /*
369 * sizeof(WCHAR) == 2 인 Windows에서만 사용할 수 있다.
370 * Linux에서 WCHAR은 기본적으로 signed short로 wchar_t가 아니다.
371 * 이 코드는 LANG=C.UTF-4 환경변수가 적용되지 않는 Windows에서만 적용한다.
372 */
373 StringBuilder sb;
374 SQLSMALLINT RecNumber = 0;
375 SQLINTEGER NativeError;
376 WCHAR SQLState[SQL_SQLSTATE_SIZE + 1];
377 WCHAR MessageText[1024];
378 SQLSMALLINT MessageTextLength;
379 SQLRETURN rc;
380 while ((rc = SQLGetDiagRecW(
381 _htype, _handle, ++RecNumber, SQLState, &NativeError,
382 MessageText, __countof(MessageText, WCHAR), &MessageTextLength
383 )) == SQL_SUCCESS) {
384 if (sb.length() > 0) {
385 sb.append('\n');
386 }
387 sb.format(L"[%d][%ls]", RecNumber, SQLState);
388 sb.append(MessageText, (size_t) MessageTextLength);
389 }
390 //__DCL_TRACE1_N(L"rc[%d]\n", rc);
391 String s = sb.toString();
392 #if __TRACE_THIS
393 if (_rc == SQL_SUCCESS_WITH_INFO) {
394 __DCL_TRACE1_N(L"SQL_SUCCESS_WITH_INFO:\n %ls\n",
395 s.replace(L"\n", L"\n ").data());
396 }
397 #endif
398 try {
399 __lastErrorMessage = UTF8Encoder::encode(s);
400 }
401 catch (CharsetConvertException* _e) {
402 __DCL_TRACE1(L"Fatal!! [%ls]\n", _e->toString().data());
403 _e->destroy();
404 }
405#else
406 ByteStringBuilder sb;
407 SQLSMALLINT RecNumber = 0;
408 SQLINTEGER NativeError;
409 SQLCHAR SQLState[SQL_SQLSTATE_SIZE + 1];
410 SQLCHAR ErrorMsg[1024];
411 SQLSMALLINT ErrorMsgLen;
412 SQLRETURN rc;
413 while ((rc = SQLGetDiagRecA(
414 _htype, _handle, ++RecNumber, SQLState, &NativeError,
415 ErrorMsg, __countof(ErrorMsg, SQLCHAR), &ErrorMsgLen
416 )) == SQL_SUCCESS) {
417 if (sb.length() > 0) {
418 sb.append('\n');
419 }
420 sb.format("[%d][%hs]", RecNumber, SQLState);
421 sb.append((const char*)ErrorMsg, (size_t)ErrorMsgLen);
422 }
423 __DCL_ASSERT(rc == SQL_NO_DATA);
424 ByteString s;
425#ifdef __WINNT__
426 /*
427 * Windows에서 LANG=C.UTF-4 환경변수가 적용되지 않으므로,
428 * wchar_t로 변환 후 UTF-8로 다시 변환한다.
429 */
430 try {
431 String ws = LocaleDecoder::decode(sb.toByteString());
432 s = UTF8Encoder::encode(ws);
433 #if __TRACE_THIS
434 if (_rc == SQL_SUCCESS_WITH_INFO) {
435 __DCL_TRACE1_N(L"SQL_SUCCESS_WITH_INFO:\n %ls\n",
436 ws.replace(L"\n", L"\n ").data());
437 }
438 #endif
439 }
440 catch (CharsetConvertException* _e) {
441 __DCL_TRACE1(L"Fatal!! [%ls]\n", _e->toString().data());
442 _e->destroy();
443 }
444#else
445 s = sb.toByteString();
446 #if __TRACE_THIS
447 if (_rc == SQL_SUCCESS_WITH_INFO) {
448 __DCL_TRACE1_N(L"SQL_SUCCESS_WITH_INFO:\n %hs\n",
449 s.replace("\n", "\n ").data());
450 }
451 #endif
452#endif
453 __lastErrorMessage = s;
454#endif
455 }
456 else {
457 #define CASE_STR(rc) case rc: __lastErrorMessage = #rc; break;
458 switch (_rc) {
459 CASE_STR(SQL_SUCCESS)
460 CASE_STR(SQL_SUCCESS_WITH_INFO)
462 CASE_STR(SQL_NO_DATA)
463 CASE_STR(SQL_INVALID_HANDLE)
464 default:
465 __DCL_ASSERT(false);
466 __lastErrorMessage = ByteString::format("SQLRETURN[%d] mabe bug!!", _rc);
467 }
468 }
469}
#define CASE_STR(rc)
#define __DCL_TRACE1(fmt, arg1)
Definition Object.h:399
__DCL_BEGIN_NAMESPACE struct __SQL_ERROR SQL_ERROR
virtual void destroy()
Definition Exception.cpp:74
_PROTECTED const wchar_t * _filename
Definition SQLCore.h:439
_PROTECTED const wchar_t int _line
Definition SQLCore.h:441
@ eServerError
Definition SQLCore.h:21

◆ setErrorMessage()

void ODBCConnection::setErrorMessage ( const ByteString & _message,
const wchar_t * _filename,
int _line )
inline

Definition at line 60 of file ODBCConnection.h.

65{
66 Connection::setErrorStatus(SQL::eServerError, _filename, _line);
67 __lastErrorMessage = _message;
68}

The documentation for this class was generated from the following files: