DCL 3.7.4
Loading...
Searching...
No Matches
IFXConnection.cpp
Go to the documentation of this file.
1#line 1 "ifxconnection.ec"
2#include <dcl/Config.h>
3
4#include <sqlhdr.h>
5#include <sqliapi.h>
6
7#include <sqlstype.h>
8
9#include <ctype.h> // isspace
10#include <string.h> // strlen, strncpy
11
12#include <dcl/Object.h>
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/Numeric.h>
19#include <dcl/Regex.h>
20#include <dcl/SQLCore.h>
21
22#include "IFXConnection.h"
23#include "IFXQuery.h"
24#include "IFXField.h" // for _getServerInfo
25
26#define __TRACE_THIS 0
27#if __TRACE_THIS
28#define __DCL_TRACE0_N __DCL_TRACE0
29#define __DCL_TRACE1_N __DCL_TRACE1
30#define __DCL_TRACE2_N __DCL_TRACE2
31#define __DCL_TRACE3_N __DCL_TRACE3
32#define __DCL_TRACE4_N __DCL_TRACE4
33#else
34#define __DCL_TRACE0_N(fmt)
35#define __DCL_TRACE1_N(fmt, arg)
36#define __DCL_TRACE2_N(fmt, arg1, arg2)
37#define __DCL_TRACE3_N(fmt, arg1, arg2, arg3)
38#define __DCL_TRACE4_N(fmt, arg1, arg2, arg3, arg4)
39#endif
40
41#undef __THIS_FILE__
42static const char_t __THIS_FILE__[] = __T("dcl/sql/IFXConnection.ec");
43
44__DCL_BEGIN_NAMESPACE
45
46#define __SET_ERROR(_error) \
47 setErrorHandle(_error, 0L, __THIS_FILE__, __LINE__)
48#define __SET_ERROR_HANDLE(_SQLCODE) \
49 setErrorHandle(SQL::eServerError, _SQLCODE, __THIS_FILE__, __LINE__)
50#define __SET_ERROR_MSG(_message) \
51 setErrorMessage(_message, __THIS_FILE__, __LINE__)
52
54
55IFXConnection::IFXConnection(const wchar_t* _serverTitle)
56 : Connection(_serverTitle)
57{
58}
59
61{
62 if (!__connectionID.isEmpty()) {
63 __DCL_TRACE0_N(L"Warning!! The connection was not closed\n");
64 close();
65 }
66}
67
69{
70 delete this;
71}
72
73/*
74_conns에 가능한 프로퍼티
75 USER,
76 PASSWORD,
77 SERVER, -- host name
78 DATABASE
79*/
80
81void IFXConnection::reset()
82{
83/*
84 * EXEC SQL BEGIN DECLARE SECTION;
85 */
86#line 79 "ifxconnection.ec"
87#line 80 "ifxconnection.ec"
88 char *connID = (_CONST char*) __connectionID.data();
89/*
90 * EXEC SQL END DECLARE SECTION;
91 */
92#line 81 "ifxconnection.ec"
93
94
95/*
96 * EXEC SQL SET CONNECTION :connID;
97 */
98#line 83 "ifxconnection.ec"
99 {
100#line 83 "ifxconnection.ec"
101 sqli_connect_set(0, connID, 0);
102#line 83 "ifxconnection.ec"
103 }
104
105/*
106 * EXEC SQL BEGIN WORK;
107 */
108#line 85 "ifxconnection.ec"
109 {
110#line 85 "ifxconnection.ec"
111 sqli_trans_begin2((mint)1);
112#line 85 "ifxconnection.ec"
113 }
114 if (SQLCODE == 0) {
115 Connection::__canTransact = true;
116/*
117 * EXEC SQL ROLLBACK WORK;
118 */
119#line 88 "ifxconnection.ec"
120 {
121#line 88 "ifxconnection.ec"
122 sqli_trans_rollback();
123#line 88 "ifxconnection.ec"
124 }
125 }
126 else {
127 Connection::__canTransact = false;
128 }
129
131}
132
133bool IFXConnection::__open(const char* _conns, size_t _connlen)
134{
135 ListedByteStringToByteStringMap map;
136 Connection::splitConnStr(_conns, _connlen, map);
137
138 ByteString _SERVER = map["SERVER"];
139 ByteString _USER = map["USER"];
140 ByteString _PASSWORD = map["PASSWORD"];
141 ByteString _DATABASE = map["DATABASE"];
142 ByteString _TARGET;
143
144 {
145 ByteStringBuilder sb = _DATABASE;
146 if (!_SERVER.isEmpty()) {
147 sb.append("@").append(_SERVER);
148 }
149 _TARGET = sb.toByteString();
150 __DCL_TRACE1_N(L"TARGET [%hs]\n", _TARGET.data());
151 }
152
153 ByteString connectionID = ByteString::format("conn_%zx", (size_t)this);
154
155/*
156 * EXEC SQL BEGIN DECLARE SECTION;
157 */
158#line 119 "ifxconnection.ec"
159#line 120 "ifxconnection.ec"
160 char *user = (_CONST char*) _USER.data();
161 char *pass = (_CONST char*) _PASSWORD.data();
162 char *target = (_CONST char*) _TARGET.data();
163 char *connID = (_CONST char*) connectionID.data();
164/*
165 * EXEC SQL END DECLARE SECTION;
166 */
167#line 124 "ifxconnection.ec"
168
169
170/*
171 * EXEC SQL CONNECT TO :target AS :connID
172 * USER :user USING :pass
173 * WITH CONCURRENT TRANSACTION;
174 */
175#line 126 "ifxconnection.ec"
176 {
177#line 128 "ifxconnection.ec"
178 ifx_conn_t *_sqiconn;
179 _sqiconn = (ifx_conn_t *)ifx_alloc_conn_user(user, pass);
180 sqli_connect_open(ESQLINTVERSION, 0, target, connID, _sqiconn, 1);
181 ifx_free_conn_user(&_sqiconn);
182#line 128 "ifxconnection.ec"
183 }
184
185 if (SQLCODE < 0) {
186 __SET_ERROR_HANDLE(SQLCODE);
187 return false;
188 }
189 __connectionID = connectionID;
190
191 if (!_DATABASE.isEmpty()) {
192 reset();
193 }
194 return true;
195}
196
198{
199 if (__connectionID.isEmpty()) {
201 return false;
202 }
203
204/*
205 * EXEC SQL BEGIN DECLARE SECTION;
206 */
207#line 149 "ifxconnection.ec"
208#line 150 "ifxconnection.ec"
209 char *connID = (_CONST char*) __connectionID.data();
210/*
211 * EXEC SQL END DECLARE SECTION;
212 */
213#line 151 "ifxconnection.ec"
214
215
216/*
217 * EXEC SQL DISCONNECT :connID;
218 */
219#line 153 "ifxconnection.ec"
220 {
221#line 153 "ifxconnection.ec"
222 sqli_connect_close(0, connID, 0, 0);
223#line 153 "ifxconnection.ec"
224 }
225 if (SQLCODE < 0) {
226 __SET_ERROR_HANDLE(SQLCODE);
227 return false;
228 }
229
230 __connectionID.clear();
231 return true;
232}
233
240
241typedef struct {
243 const char* pattern;
245
246static STMT_PATTERN sp[] = {
247 { StmtTransBegin, "BEGIN" },
248 { StmtTransEnd, "COMMIT|ROLLBACK" },
249 { StmtDatabase, "DATABASE" },
250 { StmtOther, NULL }
251};
252
253static StmtType __GetStmtType(const char* _sql)
254{
255 for(size_t i = 0; sp[i].type != StmtOther; i++) {
256 try {
257 if (Regex::test(sp[i].pattern, _sql, true))
258 return sp[i].type;
259 }
260 catch(Exception* e) {
261 e->destroy();
262 }
263 }
264 return StmtOther;
265}
266
267bool IFXConnection::__execute(const char* _sql, size_t _sqllen)
268{
269/*
270 * EXEC SQL BEGIN DECLARE SECTION;
271 */
272#line 198 "ifxconnection.ec"
273#line 199 "ifxconnection.ec"
274 char *connID = (_CONST char*) __connectionID.data();
275 char *pszSqlStatement = (_CONST char*) _sql;
276/*
277 * EXEC SQL END DECLARE SECTION;
278 */
279#line 201 "ifxconnection.ec"
280
281
282/*
283 * EXEC SQL SET CONNECTION :connID;
284 */
285#line 203 "ifxconnection.ec"
286 {
287#line 203 "ifxconnection.ec"
288 sqli_connect_set(0, connID, 0);
289#line 203 "ifxconnection.ec"
290 }
291 if (SQLCODE < 0) {
292 __SET_ERROR_HANDLE(SQLCODE);
293 return false;
294 }
295
296/*
297 * EXEC SQL EXECUTE IMMEDIATE :pszSqlStatement;
298 */
299#line 209 "ifxconnection.ec"
300 {
301#line 209 "ifxconnection.ec"
302 sqli_exec_immed(pszSqlStatement);
303#line 209 "ifxconnection.ec"
304 }
305 if (SQLCODE < 0) {
306 __SET_ERROR_HANDLE(SQLCODE);
307 return false;
308 }
309
310 switch(__GetStmtType(_sql)) {
311 case StmtTransBegin :
313 break;
314 case StmtTransEnd :
316 break;
317 case StmtDatabase :
318 reset();
319 break;
320 case StmtOther :
321 default :
322 ;
323 }
324
325 return true;
326}
327
329{
330/*
331 * EXEC SQL BEGIN DECLARE SECTION;
332 */
333#line 235 "ifxconnection.ec"
334#line 236 "ifxconnection.ec"
335 char *connID = (_CONST char*) __connectionID.data();
336/*
337 * EXEC SQL END DECLARE SECTION;
338 */
339#line 237 "ifxconnection.ec"
340
341
342/*
343 * EXEC SQL SET CONNECTION :connID;
344 */
345#line 239 "ifxconnection.ec"
346 {
347#line 239 "ifxconnection.ec"
348 sqli_connect_set(0, connID, 0);
349#line 239 "ifxconnection.ec"
350 }
351 if (SQLCODE < 0) {
352 __SET_ERROR_HANDLE(SQLCODE);
353 return false;
354 }
355
356/*
357 * EXEC SQL BEGIN WORK;
358 */
359#line 245 "ifxconnection.ec"
360 {
361#line 245 "ifxconnection.ec"
362 sqli_trans_begin2((mint)1);
363#line 245 "ifxconnection.ec"
364 }
365 if (SQLCODE < 0) {
366 __SET_ERROR_HANDLE(SQLCODE);
367 return false;
368 }
369
371 return true;
372}
373
375{
376/*
377 * EXEC SQL BEGIN DECLARE SECTION;
378 */
379#line 257 "ifxconnection.ec"
380#line 258 "ifxconnection.ec"
381 char *connID = (_CONST char*) __connectionID.data();
382/*
383 * EXEC SQL END DECLARE SECTION;
384 */
385#line 259 "ifxconnection.ec"
386
387
388/*
389 * EXEC SQL SET CONNECTION :connID;
390 */
391#line 261 "ifxconnection.ec"
392 {
393#line 261 "ifxconnection.ec"
394 sqli_connect_set(0, connID, 0);
395#line 261 "ifxconnection.ec"
396 }
397 if (SQLCODE < 0) {
398 __SET_ERROR_HANDLE(SQLCODE);
399 return false;
400 }
401
402/*
403 * EXEC SQL COMMIT WORK;
404 */
405#line 267 "ifxconnection.ec"
406 {
407#line 267 "ifxconnection.ec"
408 sqli_trans_commit();
409#line 267 "ifxconnection.ec"
410 }
411 if (SQLCODE < 0) {
412 __SET_ERROR_HANDLE(SQLCODE);
413 return false;
414 }
415
417 return true;
418}
419
421{
422/*
423 * EXEC SQL BEGIN DECLARE SECTION;
424 */
425#line 279 "ifxconnection.ec"
426#line 280 "ifxconnection.ec"
427 char *connID = (_CONST char*) __connectionID.data();
428/*
429 * EXEC SQL END DECLARE SECTION;
430 */
431#line 281 "ifxconnection.ec"
432
433
434/*
435 * EXEC SQL SET CONNECTION :connID;
436 */
437#line 283 "ifxconnection.ec"
438 {
439#line 283 "ifxconnection.ec"
440 sqli_connect_set(0, connID, 0);
441#line 283 "ifxconnection.ec"
442 }
443 if (SQLCODE < 0) {
444 __SET_ERROR_HANDLE(SQLCODE);
445 return false;
446 }
447
448/*
449 * EXEC SQL ROLLBACK WORK;
450 */
451#line 289 "ifxconnection.ec"
452 {
453#line 289 "ifxconnection.ec"
454 sqli_trans_rollback();
455#line 289 "ifxconnection.ec"
456 }
457 if (SQLCODE < 0) {
458 __SET_ERROR_HANDLE(SQLCODE);
459 return false;
460 }
461
463 return true;
464}
465
467{
468 __DCL_ASSERT(_queryHandleOut != NULL);
469
470 SQL::Query* pNewQuery = new IFXQuery(this);
471 if (!pNewQuery) {
473 return false;
474 }
475
476 *_queryHandleOut = pNewQuery;
477 return true;
478}
479
481 SQL::Error _error, long _SQLCODE,
482 const wchar_t* _filename, int _line
483)
484{
485 Connection::setErrorStatus(_error, _filename, _line);
486 if (_SQLCODE == 0) {
487 __lastErrorMessage.clear();
488 return;
489 }
490
491 __DCL_ASSERT(_SQLCODE == sqlca.sqlcode);
492
493 ByteStringBuilder sb;
494 sb.format("SQLCODE(%d) ", _SQLCODE);
495
496 char buf[1024];
497 mint actual = 0;
498 mint r = rgetlmsg(_SQLCODE, buf, sizeof(buf), &actual);
499 if (!r) {
500 while (actual > 0) {
501 if (!isspace(buf[actual - 1]))
502 break;
503 actual--;
504 }
505 buf[actual] = '\0';
506 sb.format(buf, sqlca.sqlerrm);
507 }
508 else {
509 sb.format("(%d)", r);
510 switch (r) {
511 case -1227:
512 sb.append("Message file not found");
513 break;
514 case -1228:
515 sb.append("Message number not found in message file");
516 break;
517 case -1231:
518 sb.append("Cannot seek within messge file");
519 break;
520 case -1232:
521 sb.append("Message buffer too small");
522 break;
523 default:
524 sb.append("Unkndown");
525 }
526 }
527 __lastErrorMessage = sb.toByteString();
528}
529
530bool IFXConnection::__getErrorMessage(char* _buf, size_t* _buflen)
531{
532 __DCL_ASSERT(Connection::__errorCode == SQL::eServerError);
533 if (__lastErrorMessage.length() < *_buflen) {
534 *_buflen = __lastErrorMessage.length();
535 *(_buf + *_buflen) = '\0';
536 }
537 strncpy(_buf, __lastErrorMessage.data(), *_buflen);
538 return true;
539}
540
541bool IFXConnection::__getServerInfo(char* _buf, size_t* _buflen)
542{
543 IFXQuery* query = new IFXQuery(this);
544 if (query == NULL) {
546 return false;
547 }
548
549 bool localTrans = false;
551 __startTrans();
552 localTrans = true;
553 }
554
555 const char* _sql =
556 "SELECT DBINFO('version', 'full')"
557 "\n FROM systables WHERE tabid = 1";
558 for ( ; ; ) {
559 if (!query->prepare(_sql, ByteString::length(_sql), 0))
560 break;
561
562 if (!query->execute())
563 break;
564
565 if (!query->fetch())
566 break;
567
568 if (query->eof()) {
570 break;
571 }
572
573 IFXField* field = NULL;
574 if (!query->__getField(0, (SQL::Field**)&field))
575 break;
576
577 size_t size = (size_t)-1;
578 if (!field->__getDataSize(&size, false) || size == (size_t)-1) {
580 break;
581 }
582
583 if (!field->__getData(_buf, _buflen, SQL::typeText))
584 break;
585
586 // *_buflen에 '\0'이 포함되어 있다.
587 *_buflen = ByteString::length(_buf, *_buflen);
588
589 query->__destroy();
590 query = NULL;
591
592 if (localTrans) {
594 }
595 return true;
596 }
597
598 if (query) {
599 query->__destroy();
600 }
601
602 if (localTrans) {
604 }
605 return false;
606}
607
608__DCL_END_NAMESPACE
609
610#line 441 "ifxconnection.ec"
#define __THIS_FILE__
Definition _trace.h:14
#define NULL
Definition Config.h:312
wchar_t char_t
Definition Config.h:247
#define _CONST
Definition Config.h:325
#define __DCL_TRACE1_N(fmt, arg)
@ StmtTransEnd
@ StmtOther
@ StmtTransBegin
@ StmtDatabase
#define __DCL_TRACE0_N(fmt)
#define __SET_ERROR_HANDLE(_SQLCODE)
int mint
Definition IFXParam.cpp:11
IOException *size_t r
Definition MediaInfo.cpp:82
#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 __SET_ERROR(_errorCode)
Definition SQLCore.cpp:149
#define __UNSET_STATE(state)
Definition SQLCore.h:483
#define __SET_STATE(state)
Definition SQLCore.h:482
StmtType
virtual void destroy()
Definition Exception.cpp:74
virtual ~IFXConnection()
_CONST char * connectionID() const
virtual bool __startTrans()
virtual bool __open(const char *_conns, size_t _connlen)
virtual bool __commitTrans()
virtual bool __rollbackTrans()
void setErrorHandle(SQL::Error _error, long _SQLCODE, const wchar_t *_filename, int _line)
virtual bool __createQueryInstance(SQL::Query **_queryHandleOut)
virtual void destroy()
virtual bool __close()
virtual bool __execute(const char *_sql, size_t _sqllen)
virtual bool __getServerInfo(char *_buf, size_t *_buflen)
IFXConnection(const wchar_t *_serverTitle)
virtual bool __getErrorMessage(char *_buf, size_t *_buflen)
virtual bool __getDataSize(size_t *_size, bool _maxsize)
Definition IFXField.cpp:350
virtual bool __getData(void *_buf, size_t *_size, SQL::DataType _bufType)
Definition IFXField.cpp:384
virtual bool __getField(size_t _index, SQL::Field **_fieldHandleOut)
Definition IFXQuery.cpp:737
virtual void __destroy()
Definition IFXQuery.cpp:110
static bool test(const wchar_t *_regex, const wchar_t *_string, bool _icase=false) __DCL_THROWS1(RegexException *)
Definition Regex.cpp:250
_PROTECTED const wchar_t * _filename
Definition SQLCore.h:439
_PROTECTED const wchar_t int _line
Definition SQLCore.h:441
bool inState(unsigned int _state) const
Definition SQLCore.inl:99
@ typeText
Definition SQLCore.h:73
Error
Definition SQLCore.h:19
@ eOutOfMemory
Definition SQLCore.h:24
@ eServerError
Definition SQLCore.h:21
@ eNotConnected
Definition SQLCore.h:33
@ eNotAvailable
Definition SQLCore.h:38
const char * pattern