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

#include <IBQuery.h>

Inheritance diagram for IBQuery:
SQL::Query Object

Public Member Functions

 IBQuery (IBConnection *_connHandle)
virtual ~IBQuery ()
virtual void __destroy ()
virtual bool __prepare (const char *_sql, size_t _sqllen, size_t _paramCount)
virtual bool __execute ()
virtual bool __fetch ()
virtual bool __getField (size_t _index, SQL::Field **_fieldHandleOut)
virtual bool __getParam (size_t _index, SQL::Param **_paramHandleOut)
Public Member Functions inherited from Object
virtual String toString () const
virtual void destroy ()
String className () const
bool isInstanceOf (const std::type_info &typeinfo) const
virtual const std::type_info & typeInfo () const

Protected Member Functions

bool reset ()
bool initFields ()
bool initParams (size_t _paramCount)
Protected Member Functions inherited from SQL::Query
 Query (Connection *_connHandle)
virtual ~Query ()
virtual bool __moreResults (bool *_moreResults)
Protected Member Functions inherited from Object
virtual ~Object ()
 Object ()

Protected Attributes

isc_stmt_handle __stmtHandle
int __stmtType
XSQLDA * __inSQLDA
XSQLDA * __outSQLDA
IBParam__params
IBField__fields
int __fetchCounter
Protected Attributes inherited from SQL::Query
Connection__connHandle
bool __eof
int64_t __affectedRows
size_t __fieldCount
size_t __paramCount
wchar_t __placeholder
unsigned int __states

Additional Inherited Members

Public Types inherited from SQL::Query
enum  State { stStandBy = (unsigned int) 0x0001 , stPrepared = 0x0002 , stExecuted = 0x0004 , stFetched = 0x0008 }

Detailed Description

Definition at line 11 of file IBQuery.h.

Constructor & Destructor Documentation

◆ IBQuery()

IBQuery::IBQuery ( IBConnection * _connHandle)

◆ ~IBQuery()

IBQuery::~IBQuery ( )
virtual

Definition at line 65 of file IBQuery.cpp.

66{
67#ifdef __DCL_DEBUG
68 if (!reset()) {
69 char buf[256];
70 size_t buflen = sizeof(buf) - 1;
71 bool b = conn()->__getErrorMessage(buf, &buflen);
72 buf[b ? buflen : 0] = '\0';
73 __DCL_TRACE1(L"Warning! Query reset error! %hs\n", buf);
74 }
75#else
76 (void)reset();
77#endif
78}
#define __DCL_TRACE1(fmt, arg1)
Definition Object.h:399
bool reset()
Definition IBQuery.cpp:85

Member Function Documentation

◆ __destroy()

void IBQuery::__destroy ( )
virtual

Implements SQL::Query.

Definition at line 80 of file IBQuery.cpp.

81{
82 delete this;
83}

◆ __execute()

bool IBQuery::__execute ( )
virtual

Implements SQL::Query.

Definition at line 428 of file IBQuery.cpp.

429{
430 if (__stmtType == isc_info_sql_stmt_exec_procedure) {
431 // 2025-07-10
432 // EXECUTE PROCEDURE에 대하여 커서를 만들지 않는다.
433 // 따라서, __fetch()에서 isc_dsql_fetch는 사용할 수 없다.
434 if (isc_dsql_execute2(
435 conn()->statusVector(),
436 conn()->trHandlePtr(),
438 conn()->dialect(),
439 __inSQLDA,
441 )) {
443 return false;
444 }
445 }
446 else {
447 if (isc_dsql_execute(
448 conn()->statusVector(),
449 conn()->trHandlePtr(),
451 conn()->dialect(),
453 )) {
455 return false;
456 }
457 }
458
459 for (size_t i = 0; i < Query::__paramCount; i++) {
460 __params[i].onAfterExecute();
461 }
462
463 // INSERT, DELETE, UPDATE statement의 실행 후
464 // affected records를 구한다.
465
466 unsigned char count_type = 0;
467 switch(__stmtType) {
468 case isc_info_sql_stmt_update: {
469 count_type = isc_info_req_update_count;
470 break;
471 }
472 case isc_info_sql_stmt_delete: {
473 count_type = isc_info_req_delete_count;
474 break;
475 }
476 case isc_info_sql_stmt_insert: {
477 count_type = isc_info_req_insert_count;
478 break;
479 }
480 case isc_info_sql_stmt_select:
481 case isc_info_sql_stmt_select_for_upd: {
482 Query::__eof = false;
483 break;
484 }
485 case isc_info_sql_stmt_exec_procedure: {
486 Query::__eof = false;
487 for (size_t i = 0; i < Query::__fieldCount; i++) {
488 if (!__fields[i].onAfterFetch())
489 return false;
490 }
491 break;
492 }
493 }
494
495 if (count_type) {
496 unsigned char count_is = 0;
497 char count_buffer[33];
498 unsigned short length;
499
500 if (isc_dsql_sql_info(
501 conn()->statusVector(),
502 &__stmtHandle,
503 sizeof(count_info_item),
504 count_info_item,
505 sizeof(count_buffer),
506 count_buffer
507 )) {
509 return false;
510 }
511
512 for(char* p = count_buffer + 3; *p != isc_info_end; ) {
513 count_is = *p++;
514 length = (unsigned short)isc_vax_integer(p, 2);
515 p += 2;
516 Query::__affectedRows = isc_vax_integer(p, length);
517 p += length;
518 if (count_is == count_type)
519 break;
520 }
521 }
522
523 return true;
524}
#define __SET_ERROR(_errorCode)
Definition SQLCore.cpp:149
IBParam * __params
Definition IBQuery.h:25
int __stmtType
Definition IBQuery.h:21
IBField * __fields
Definition IBQuery.h:26
XSQLDA * __inSQLDA
Definition IBQuery.h:22
XSQLDA * __outSQLDA
Definition IBQuery.h:23
isc_stmt_handle __stmtHandle
Definition IBQuery.h:20
@ eServerError
Definition SQLCore.h:21

◆ __fetch()

bool IBQuery::__fetch ( )
virtual

Implements SQL::Query.

Definition at line 526 of file IBQuery.cpp.

527{
528 __DCL_ASSERT(!eof());
529 if (__stmtType == isc_info_sql_stmt_exec_procedure) {
530 // 2025-07-10
531 // SQLDA 구조를 따르는 Informix, PostgreSQL과 MariaDB 모두
532 // PROCEDURE 실행의 결과를 필드 접근으로 구현되었다.
533 // fetch 후 필드 접근 패턴으로 맞춘다.
535 if (__fetchCounter > 1) {
536 Query::__eof = true;
537 }
538 return true;
539 }
540
541 __DCL_ASSERT(__stmtType == isc_info_sql_stmt_select
542 || __stmtType == isc_info_sql_stmt_select_for_upd);
543 ISC_STATUS rs = isc_dsql_fetch(
544 conn()->statusVector(),
545 &__stmtHandle,
548 );
549 if (rs == 0) {
550 for(size_t i = 0; i < Query::__fieldCount; i++) {
551 if (!__fields[i].onAfterFetch())
552 return false;
553 }
554 return true;
555 }
556 else if (rs == 100) {
557 Query::__eof = true;
558 return true;
559 }
560
561 __DCL_TRACE1(L"[%zd]\n", (int64_t)rs);
563 return false;
564}
#define SQLDA_CURRENT_VERSION
Definition IBQuery.cpp:23
#define __DCL_ASSERT(expr)
Definition Object.h:394
int __fetchCounter
Definition IBQuery.h:29

◆ __getField()

bool IBQuery::__getField ( size_t _index,
SQL::Field ** _fieldHandleOut )
virtual

Implements SQL::Query.

Definition at line 566 of file IBQuery.cpp.

567{
568 __DCL_ASSERT(Query::__fieldCount > 0);
569 __DCL_ASSERT((0 <= _index) && (_index < Query::__fieldCount));
570 *_fieldHandleOut = &__fields[_index];
571 return true;
572}

◆ __getParam()

bool IBQuery::__getParam ( size_t _index,
SQL::Param ** _paramHandleOut )
virtual

Implements SQL::Query.

Definition at line 574 of file IBQuery.cpp.

575{
576 __DCL_ASSERT(Query::__paramCount > 0);
577 __DCL_ASSERT((0 <= _index) && (_index < Query::__paramCount));
578 *_paramHandleOut = &__params[_index];
579 return true;
580}

◆ __prepare()

bool IBQuery::__prepare ( const char * _sql,
size_t _sqllen,
size_t _paramCount )
virtual

Implements SQL::Query.

Definition at line 355 of file IBQuery.cpp.

357{
358 if(!reset())
359 return false;
360
361 if (isc_dsql_allocate_statement(
362 conn()->statusVector(),
363 conn()->dbHandlePtr(),
365 )) {
367 return false;
368 }
369
370#ifdef FIREBIRD_IBASE_H
371 #undef _CONST
372 #define _CONST const
373#endif
374
375 ISC_STATUS rs = isc_dsql_prepare(
376 conn()->statusVector(),
377 conn()->trHandlePtr(),
378 &__stmtHandle,
379 0,
380 (_CONST char*)_sql,
381 conn()->dialect(),
382 NULL
383 );
384 if (rs) {
386 return false;
387 }
388
389 char res_buffer[8];
390 if (isc_dsql_sql_info(
391 conn()->statusVector(),
393 sizeof(stmt_info_item),
394 stmt_info_item,
395 sizeof(res_buffer),
396 res_buffer
397 )) {
399 return false;
400 }
401
402 if (res_buffer[0] != isc_info_sql_stmt_type) {
404 return false;
405 }
406
407 int len = isc_vax_integer(&res_buffer[1], 2);
408 __stmtType = isc_vax_integer(&res_buffer[3], len);
409
410 // SELECT, EXECUTE PROCEDURE 는 Row Sets을 반환한다.
411 if ((__stmtType == isc_info_sql_stmt_select)
412 || (__stmtType == isc_info_sql_stmt_select_for_upd)
413 || (__stmtType == isc_info_sql_stmt_exec_procedure)
414 ) {
415 if (!initFields())
416 return false;
417 }
418
419 if (_paramCount > 0) {
420 if (!initParams(_paramCount))
421 return false;
422 }
423
424 return true;
425// rs = isc_dsql_set_cursor_name(statusVector, &__stmtHandle, "CURSOR1", 0);
426}
#define NULL
Definition Config.h:312
#define _CONST
Definition Config.h:325
bool initParams(size_t _paramCount)
Definition IBQuery.cpp:306
bool initFields()
Definition IBQuery.cpp:192

◆ initFields()

bool IBQuery::initFields ( )
protected

Definition at line 192 of file IBQuery.cpp.

193{
195 && (Query::__fieldCount == 0)
196 && (__fields == NULL)
197 && (__outSQLDA == NULL)
198 );
199
200 ISC_STATUS* statusVector = conn()->statusVector();
201 __outSQLDA = (XSQLDA*)malloc(XSQLDA_LENGTH(1));
202 if (__outSQLDA == NULL) {
204 return false;
205 }
207 __outSQLDA->sqln = 1;
208
209 if(isc_dsql_describe(
210 statusVector,
211 &__stmtHandle,
214 )) {
216 return false;
217 }
218
219 if (__outSQLDA->sqld == 0) {
220 // 필드가 없다.
221 return true;
222 }
223
224 if (__outSQLDA->sqln < __outSQLDA->sqld) {
225 __outSQLDA = (XSQLDA*)realloc(__outSQLDA, XSQLDA_LENGTH(__outSQLDA->sqld));
226 if (__outSQLDA == NULL) {
228 return false;
229 }
231 __outSQLDA->sqln = __outSQLDA->sqld;
232
233 if (isc_dsql_describe(
234 statusVector,
235 &__stmtHandle,
238 )) {
240 return false;
241 }
242 }
243
244 // __outSQLDA에 적용할, 레코드 버퍼 크기를 계산한다.
245 size_t offset = 0;
246 XSQLVAR* sqlvar = __outSQLDA->sqlvar;
247 for(short i = 0; i < __outSQLDA->sqld; i++, sqlvar++) {
248 offset = __TYPE_ALIGN(offset, sqlvar->sqltype);
249 switch(sqlvar->sqltype & ~1) {
250 case SQL_TEXT :
251 offset += sqlvar->sqllen + 1;
252 break;
253 case SQL_VARYING :
254 offset += sqlvar->sqllen + sizeof(short) + 1;
255 break;
256 default :
257 offset += sqlvar->sqllen;
258 }
259 }
260
261 __DCL_TRACE1_N(L"outBuffer [%zd]\n", offset);
262 if (offset > 0) {
263 __outSQLDA = (XSQLDA*)realloc(__outSQLDA,
264 XSQLDA_LENGTH(__outSQLDA->sqld) + offset);
265 if (__outSQLDA == NULL) {
267 return false;
268 }
269 }
270
271 char* outBuffer = (char*)__outSQLDA + XSQLDA_LENGTH(__outSQLDA->sqld);
272 __DCL_TRACE2_N(L"__outSQLDA[%p] outBuffer[%p]\n", __outSQLDA, outBuffer);
273 sqlvar = __outSQLDA->sqlvar;
274 offset = 0;
275 for(short i = 0; i < __outSQLDA->sqld; i++, sqlvar++) {
276 offset = __TYPE_ALIGN(offset, sqlvar->sqltype);
277 sqlvar->sqldata = outBuffer + offset;
278 switch(sqlvar->sqltype & ~1) {
279 case SQL_TEXT :
280 offset += sqlvar->sqllen + 1;
281 break;
282 case SQL_VARYING :
283 offset += sqlvar->sqllen + sizeof(short) + 1;
284 break;
285 default :
286 offset += sqlvar->sqllen;
287 }
288 }
289
290 Query::__fieldCount = __outSQLDA->sqld;
291 __fields = new IBField[Query::__fieldCount];
292 if (__fields == NULL) {
294 return false;
295 }
296
297 sqlvar = __outSQLDA->sqlvar;
298 for (size_t i = 0; i < Query::__fieldCount; i++, sqlvar++) {
299 if (!__fields[i].init(this, sqlvar))
300 return false;
301 }
302
303 return true;
304}
#define __DCL_TRACE1_N(fmt, arg)
#define __DCL_TRACE2_N(fmt, arg1, arg2)
#define NULL_HANDLE
@ eOutOfMemory
Definition SQLCore.h:24

◆ initParams()

bool IBQuery::initParams ( size_t _paramCount)
protected

Definition at line 306 of file IBQuery.cpp.

307{
309 && (Query::__paramCount == 0)
310 && (__params == NULL)
311 && (__inSQLDA == NULL)
312 );
313
314 short paramCount = (short)_paramCount;
315 ISC_STATUS* statusVector = conn()->statusVector();
316 __inSQLDA = (XSQLDA*)malloc(XSQLDA_LENGTH(paramCount));
317 if (__inSQLDA == NULL) {
319 return false;
320 }
322 __inSQLDA->sqln = paramCount;
323
324 if (isc_dsql_describe_bind(
325 statusVector,
326 &__stmtHandle,
329 )) {
331 return false;
332 }
333 __DCL_ASSERT(__inSQLDA->sqld == paramCount);
334
335 Query::__paramCount = __inSQLDA->sqld;
336 __params = new IBParam[Query::__paramCount];
337 if (__params == NULL) {
339 return false;
340 }
341
342 XSQLVAR* sqlvar = __inSQLDA->sqlvar;
343 for(size_t i = 0; i < Query::__paramCount; i++, sqlvar++) {
344 if (!__params[i].init(this, sqlvar)) {
345 return false;
346 }
347 }
348
349 return true;
350}

◆ reset()

bool IBQuery::reset ( )
protected

Definition at line 85 of file IBQuery.cpp.

86{
87 Query::__eof = true;
88 Query::__affectedRows = -1;
91
92 // clear fields
93 if (__fields) {
94 __DCL_ASSERT(Query::__fieldCount > 0);
95 delete[] __fields;
96 __fields = NULL;
97 Query::__fieldCount = 0;
98 }
99
100 // clear binds
101 if (__params) {
102 __DCL_ASSERT(Query::__paramCount > 0);
103 delete[] __params;
104 __params = NULL;
105 Query::__paramCount = 0;
106 }
107
108 if (__outSQLDA) {
109 free(__outSQLDA);
111 }
112
113 if (__inSQLDA) {
114 free(__inSQLDA);
115 __inSQLDA = NULL;
116 }
117
118 ISC_STATUS* statusVector = conn()->statusVector();
119 bool r = true;
120 if (__stmtHandle) {
121 if (isc_dsql_free_statement(
122 statusVector,
123 &__stmtHandle,
124 DSQL_drop
125 )) {
127 r = false;
128 }
130 }
131 return r;
132}
#define _IB_STMT_TYPE_UNKNOWN
Definition IBQuery.h:6
IOException *size_t r
Definition MediaInfo.cpp:82

Member Data Documentation

◆ __fetchCounter

int IBQuery::__fetchCounter
protected

Definition at line 29 of file IBQuery.h.

◆ __fields

IBField* IBQuery::__fields
protected

Definition at line 26 of file IBQuery.h.

◆ __inSQLDA

XSQLDA* IBQuery::__inSQLDA
protected

Definition at line 22 of file IBQuery.h.

◆ __outSQLDA

XSQLDA* IBQuery::__outSQLDA
protected

Definition at line 23 of file IBQuery.h.

◆ __params

IBParam* IBQuery::__params
protected

Definition at line 25 of file IBQuery.h.

◆ __stmtHandle

isc_stmt_handle IBQuery::__stmtHandle
protected

Definition at line 20 of file IBQuery.h.

◆ __stmtType

int IBQuery::__stmtType
protected

Definition at line 21 of file IBQuery.h.


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