1 /********************************************************************/
2 /* */
3 /* sql_fire.c Database access functions for Firebird/InterBase. */
4 /* Copyright (C) 1989 - 2019 Thomas Mertes */
5 /* */
6 /* This file is part of the Seed7 Runtime Library. */
7 /* */
8 /* The Seed7 Runtime Library is free software; you can */
9 /* redistribute it and/or modify it under the terms of the GNU */
10 /* Lesser General Public License as published by the Free Software */
11 /* Foundation; either version 2.1 of the License, or (at your */
12 /* option) any later version. */
13 /* */
14 /* The Seed7 Runtime Library is distributed in the hope that it */
15 /* will be useful, but WITHOUT ANY WARRANTY; without even the */
16 /* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR */
17 /* PURPOSE. See the GNU Lesser General Public License for more */
18 /* details. */
19 /* */
20 /* You should have received a copy of the GNU Lesser General */
21 /* Public License along with this program; if not, write to the */
22 /* Free Software Foundation, Inc., 51 Franklin Street, */
23 /* Fifth Floor, Boston, MA 02110-1301, USA. */
24 /* */
25 /* Module: Seed7 Runtime Library */
26 /* File: seed7/src/sql_fire.c */
27 /* Changes: 2018, 2019 Thomas Mertes */
28 /* Content: Database access functions for Firebird/InterBase. */
29 /* */
30 /********************************************************************/
31
32 #define LOG_FUNCTIONS 0
33 #define VERBOSE_EXCEPTIONS 0
34
35 #include "version.h"
36
37 #include "stdlib.h"
38 #include "stdio.h"
39 #include "string.h"
40 #include "limits.h"
41 #include "time.h"
42 #ifdef FIRE_INCLUDE
43 #include FIRE_INCLUDE
44 #endif
45
46 #include "common.h"
47 #include "data_rtl.h"
48 #include "striutl.h"
49 #include "heaputl.h"
50 #include "numutl.h"
51 #include "str_rtl.h"
52 #include "flt_rtl.h"
53 #include "tim_rtl.h"
54 #include "cmd_rtl.h"
55 #include "big_drv.h"
56 #include "rtl_err.h"
57 #include "dll_drv.h"
58 #include "sql_base.h"
59 #include "sql_drv.h"
60
61 #ifdef FIRE_INCLUDE
62
63
64 typedef struct {
65 uintType usage_count;
66 sqlFuncType sqlFunc;
67 intType driver;
68 isc_db_handle connection;
69 isc_tr_handle trans_handle;
70 } dbRecord, *dbType;
71
72 typedef struct {
73 boolType bound;
74 } bindDataRecord, *bindDataType;
75
76 typedef struct {
77 uintType usage_count;
78 sqlFuncType sqlFunc;
79 dbType db;
80 isc_stmt_handle ppStmt;
81 XSQLDA *in_sqlda;
82 XSQLDA *out_sqlda;
83 bindDataType param_array;
84 int statement_type;
85 boolType executeSuccessful;
86 boolType fetchOkay;
87 boolType fetchFinished;
88 } preparedStmtRecord, *preparedStmtType;
89
90 typedef struct {
91 memSizeType fileName8Length;
92 cstriType fileName8;
93 memSizeType user8Length;
94 const_cstriType user8;
95 memSizeType password8Length;
96 const_cstriType password8;
97 } loginRecord, *loginType;
98
99 static sqlFuncType sqlFunc = NULL;
100
101 static char isc_tbp[] = {isc_tpb_version3, isc_tpb_write,
102 isc_tpb_concurrency, isc_tpb_wait};
103 static char type_item[] = {isc_info_sql_stmt_type};
104
105 #ifndef SQL_BOOLEAN
106 #define SQL_BOOLEAN 32764
107 #endif
108
109
110 #ifdef FIRE_DLL
111
112 #ifndef STDCALL
113 #if defined(_WIN32) && HAS_STDCALL
114 #define STDCALL __stdcall
115 #else
116 #define STDCALL
117 #endif
118 #endif
119
120 typedef ISC_STATUS (STDCALL *tp_isc_attach_database) (ISC_STATUS *status_vector,
121 short db_name_length,
122 char *db_name,
123 isc_db_handle *db_handle,
124 short parm_buffer_length,
125 char *parm_buffer);
126 typedef ISC_STATUS (STDCALL *tp_isc_blob_info) (ISC_STATUS *status_vector,
127 isc_blob_handle *blob_handle,
128 short item_list_buffer_length,
129 char *item_list_buffer,
130 short result_buffer_length,
131 char *result_buffer);
132 typedef ISC_STATUS (STDCALL *tp_isc_close_blob) (ISC_STATUS *status_vector,
133 isc_blob_handle *blob_handle);
134 typedef ISC_STATUS (STDCALL *tp_isc_commit_transaction) (ISC_STATUS *status_vector,
135 isc_tr_handle *trans_handle);
136 typedef ISC_STATUS (STDCALL *tp_isc_create_blob2) (ISC_STATUS *status_vector,
137 isc_db_handle *db_handle,
138 isc_tr_handle *trans_handle,
139 isc_blob_handle *blob_handle,
140 ISC_QUAD *blob_id,
141 short bpb_length,
142 char *bpb_address);
143 typedef ISC_STATUS (STDCALL *tp_isc_create_database) (ISC_STATUS *status_vector,
144 short db_name_length,
145 char *db_name,
146 isc_db_handle *db_handle,
147 short parm_buffer_length,
148 char *parm_buffer,
149 short db_type);
150 typedef void (STDCALL *tp_isc_decode_sql_date) (ISC_DATE *ib_date,
151 void *tm_date);
152 typedef void (STDCALL *tp_isc_decode_sql_time) (ISC_TIME *ib_time,
153 void *tm_date);
154 typedef void (STDCALL *tp_isc_decode_timestamp) (ISC_TIMESTAMP *ib_date,
155 void *tm_date);
156 typedef ISC_STATUS (STDCALL *tp_isc_detach_database) (ISC_STATUS *status_vector,
157 isc_db_handle *db_handle);
158 typedef ISC_STATUS (STDCALL *tp_isc_dsql_allocate_statement) (ISC_STATUS *status_vector,
159 isc_db_handle *db_handle,
160 isc_stmt_handle *stmt_handle);
161 typedef ISC_STATUS (STDCALL *tp_isc_dsql_describe) (ISC_STATUS *status_vector,
162 isc_stmt_handle *stmt_handle,
163 unsigned short da_version,
164 XSQLDA *xsqlda);
165 typedef ISC_STATUS (STDCALL *tp_isc_dsql_describe_bind) (ISC_STATUS *status_vector,
166 isc_stmt_handle *stmt_handle,
167 unsigned short da_version,
168 XSQLDA *xsqlda);
169 typedef ISC_STATUS (STDCALL *tp_isc_dsql_execute2) (ISC_STATUS *status_vector,
170 isc_tr_handle *trans_handle,
171 isc_stmt_handle *stmt_handle,
172 unsigned short da_version,
173 XSQLDA *in_xsqlda,
174 XSQLDA *out_xsqlda);
175 typedef ISC_STATUS (STDCALL *tp_isc_dsql_fetch) (ISC_STATUS *status_vector,
176 isc_stmt_handle *stmt_handle,
177 unsigned short da_version,
178 XSQLDA *xsqlda);
179 typedef ISC_STATUS (STDCALL *tp_isc_dsql_free_statement) (ISC_STATUS *status_vector,
180 isc_stmt_handle *stmt_handle,
181 unsigned short option);
182 typedef ISC_STATUS (STDCALL *tp_isc_dsql_prepare) (ISC_STATUS *status_vector,
183 isc_tr_handle *trans_handle,
184 isc_stmt_handle *stmt_handle,
185 unsigned short length,
186 char *statement,
187 unsigned short dialect,
188 XSQLDA *xsqlda);
189 typedef ISC_STATUS (STDCALL *tp_isc_dsql_sql_info) (ISC_STATUS *status_vector,
190 isc_stmt_handle *stmt_handle,
191 unsigned short item_length,
192 char *items,
193 unsigned short buffer_length,
194 char *buffer);
195 typedef void (STDCALL *tp_isc_encode_sql_date) (void *tm_date,
196 ISC_DATE *ib_date);
197 typedef void (STDCALL *tp_isc_encode_sql_time) (void *tm_date,
198 ISC_TIME *ib_time);
199 typedef void (STDCALL *tp_isc_encode_timestamp) (void *tm_date,
200 ISC_TIMESTAMP *ib_timestamp);
201 typedef ISC_STATUS (STDCALL *tp_isc_get_segment) (ISC_STATUS *status_vector,
202 isc_blob_handle *blob_handle,
203 unsigned short *actual_seg_length,
204 unsigned short seg_buffer_length,
205 char *seg_buffer);
206 typedef ISC_STATUS (STDCALL *tp_isc_interprete) (char *buffer, ISC_STATUS **status_vector);
207 typedef ISC_STATUS (STDCALL *tp_isc_open_blob2) (ISC_STATUS *status_vector,
208 isc_db_handle *db_handle,
209 isc_tr_handle *trans_handle,
210 isc_blob_handle *blob_handle,
211 ISC_QUAD *blob_id,
212 short bpb_length,
213 char *bpb_address);
214 typedef ISC_INT64 (STDCALL *tp_isc_portable_integer) (char *buffer,
215 short length);
216 typedef ISC_STATUS (STDCALL *tp_isc_print_status) (ISC_STATUS *status_vector);
217 typedef ISC_STATUS (STDCALL *tp_isc_put_segment) (ISC_STATUS *status_vector,
218 isc_blob_handle *blob_handle,
219 unsigned short seg_buffer_length,
220 char *seg_buffer);
221 typedef ISC_STATUS (STDCALL *tp_isc_rollback_transaction) (ISC_STATUS *status_vector,
222 isc_tr_handle *trans_handle);
223 typedef ISC_STATUS (STDCALL *tp_isc_start_transaction) (ISC_STATUS *status_vector,
224 isc_tr_handle *trans_handle,
225 short db_handle_count,
226 isc_db_handle *db_handle,
227 unsigned short tpb_length,
228 char *tpb_address);
229
230 static tp_isc_attach_database ptr_isc_attach_database;
231 static tp_isc_blob_info ptr_isc_blob_info;
232 static tp_isc_close_blob ptr_isc_close_blob;
233 static tp_isc_commit_transaction ptr_isc_commit_transaction;
234 static tp_isc_create_blob2 ptr_isc_create_blob2;
235 static tp_isc_create_database ptr_isc_create_database;
236 static tp_isc_decode_sql_date ptr_isc_decode_sql_date;
237 static tp_isc_decode_sql_time ptr_isc_decode_sql_time;
238 static tp_isc_decode_timestamp ptr_isc_decode_timestamp;
239 static tp_isc_detach_database ptr_isc_detach_database;
240 static tp_isc_dsql_allocate_statement ptr_isc_dsql_allocate_statement;
241 static tp_isc_dsql_describe ptr_isc_dsql_describe;
242 static tp_isc_dsql_describe_bind ptr_isc_dsql_describe_bind;
243 static tp_isc_dsql_execute2 ptr_isc_dsql_execute2;
244 static tp_isc_dsql_fetch ptr_isc_dsql_fetch;
245 static tp_isc_dsql_free_statement ptr_isc_dsql_free_statement;
246 static tp_isc_dsql_prepare ptr_isc_dsql_prepare;
247 static tp_isc_dsql_sql_info ptr_isc_dsql_sql_info;
248 static tp_isc_encode_sql_date ptr_isc_encode_sql_date;
249 static tp_isc_encode_sql_time ptr_isc_encode_sql_time;
250 static tp_isc_encode_timestamp ptr_isc_encode_timestamp;
251 static tp_isc_get_segment ptr_isc_get_segment;
252 static tp_isc_interprete ptr_isc_interprete;
253 static tp_isc_open_blob2 ptr_isc_open_blob2;
254 static tp_isc_portable_integer ptr_isc_portable_integer;
255 static tp_isc_print_status ptr_isc_print_status;
256 static tp_isc_put_segment ptr_isc_put_segment;
257 static tp_isc_rollback_transaction ptr_isc_rollback_transaction;
258 static tp_isc_start_transaction ptr_isc_start_transaction;
259
260 #define isc_attach_database ptr_isc_attach_database
261 #define isc_blob_info ptr_isc_blob_info
262 #define isc_close_blob ptr_isc_close_blob
263 #define isc_commit_transaction ptr_isc_commit_transaction
264 #define isc_create_blob2 ptr_isc_create_blob2
265 #define isc_create_database ptr_isc_create_database
266 #define isc_decode_sql_date ptr_isc_decode_sql_date
267 #define isc_decode_sql_time ptr_isc_decode_sql_time
268 #define isc_decode_timestamp ptr_isc_decode_timestamp
269 #define isc_detach_database ptr_isc_detach_database
270 #define isc_dsql_allocate_statement ptr_isc_dsql_allocate_statement
271 #define isc_dsql_describe ptr_isc_dsql_describe
272 #define isc_dsql_describe_bind ptr_isc_dsql_describe_bind
273 #define isc_dsql_execute2 ptr_isc_dsql_execute2
274 #define isc_dsql_fetch ptr_isc_dsql_fetch
275 #define isc_dsql_free_statement ptr_isc_dsql_free_statement
276 #define isc_dsql_prepare ptr_isc_dsql_prepare
277 #define isc_dsql_sql_info ptr_isc_dsql_sql_info
278 #define isc_encode_sql_date ptr_isc_encode_sql_date
279 #define isc_encode_sql_time ptr_isc_encode_sql_time
280 #define isc_encode_timestamp ptr_isc_encode_timestamp
281 #define isc_get_segment ptr_isc_get_segment
282 #define isc_interprete ptr_isc_interprete
283 #define isc_open_blob2 ptr_isc_open_blob2
284 #define isc_portable_integer ptr_isc_portable_integer
285 #define isc_print_status ptr_isc_print_status
286 #define isc_put_segment ptr_isc_put_segment
287 #define isc_rollback_transaction ptr_isc_rollback_transaction
288 #define isc_start_transaction ptr_isc_start_transaction
289
290
291
setupDll(const char * dllName)292 static boolType setupDll (const char *dllName)
293
294 {
295 static void *dbDll = NULL;
296
297 /* setupDll */
298 logFunction(printf("setupDll(\"%s\")\n", dllName););
299 if (dbDll == NULL) {
300 dbDll = dllOpen(dllName);
301 if (dbDll != NULL) {
302 if ((isc_attach_database = (tp_isc_attach_database) dllFunc(dbDll, "isc_attach_database")) == NULL ||
303 (isc_blob_info = (tp_isc_blob_info) dllFunc(dbDll, "isc_blob_info")) == NULL ||
304 (isc_close_blob = (tp_isc_close_blob) dllFunc(dbDll, "isc_close_blob")) == NULL ||
305 (isc_commit_transaction = (tp_isc_commit_transaction) dllFunc(dbDll, "isc_commit_transaction")) == NULL ||
306 (isc_create_blob2 = (tp_isc_create_blob2) dllFunc(dbDll, "isc_create_blob2")) == NULL ||
307 (isc_create_database = (tp_isc_create_database) dllFunc(dbDll, "isc_create_database")) == NULL ||
308 (isc_decode_sql_date = (tp_isc_decode_sql_date) dllFunc(dbDll, "isc_decode_sql_date")) == NULL ||
309 (isc_decode_sql_time = (tp_isc_decode_sql_time) dllFunc(dbDll, "isc_decode_sql_time")) == NULL ||
310 (isc_decode_timestamp = (tp_isc_decode_timestamp) dllFunc(dbDll, "isc_decode_timestamp")) == NULL ||
311 (isc_detach_database = (tp_isc_detach_database) dllFunc(dbDll, "isc_detach_database")) == NULL ||
312 (isc_dsql_allocate_statement = (tp_isc_dsql_allocate_statement) dllFunc(dbDll, "isc_dsql_allocate_statement")) == NULL ||
313 (isc_dsql_describe = (tp_isc_dsql_describe) dllFunc(dbDll, "isc_dsql_describe")) == NULL ||
314 (isc_dsql_describe_bind = (tp_isc_dsql_describe_bind) dllFunc(dbDll, "isc_dsql_describe_bind")) == NULL ||
315 (isc_dsql_execute2 = (tp_isc_dsql_execute2) dllFunc(dbDll, "isc_dsql_execute2")) == NULL ||
316 (isc_dsql_fetch = (tp_isc_dsql_fetch) dllFunc(dbDll, "isc_dsql_fetch")) == NULL ||
317 (isc_dsql_free_statement = (tp_isc_dsql_free_statement) dllFunc(dbDll, "isc_dsql_free_statement")) == NULL ||
318 (isc_dsql_prepare = (tp_isc_dsql_prepare) dllFunc(dbDll, "isc_dsql_prepare")) == NULL ||
319 (isc_dsql_sql_info = (tp_isc_dsql_sql_info) dllFunc(dbDll, "isc_dsql_sql_info")) == NULL ||
320 (isc_encode_sql_date = (tp_isc_encode_sql_date) dllFunc(dbDll, "isc_encode_sql_date")) == NULL ||
321 (isc_encode_sql_time = (tp_isc_encode_sql_time) dllFunc(dbDll, "isc_encode_sql_time")) == NULL ||
322 (isc_encode_timestamp = (tp_isc_encode_timestamp) dllFunc(dbDll, "isc_encode_timestamp")) == NULL ||
323 (isc_get_segment = (tp_isc_get_segment) dllFunc(dbDll, "isc_get_segment")) == NULL ||
324 (isc_interprete = (tp_isc_interprete) dllFunc(dbDll, "isc_interprete")) == NULL ||
325 (isc_open_blob2 = (tp_isc_open_blob2) dllFunc(dbDll, "isc_open_blob2")) == NULL ||
326 (isc_portable_integer = (tp_isc_portable_integer) dllFunc(dbDll, "isc_portable_integer")) == NULL ||
327 (isc_print_status = (tp_isc_print_status) dllFunc(dbDll, "isc_print_status")) == NULL ||
328 (isc_put_segment = (tp_isc_put_segment) dllFunc(dbDll, "isc_put_segment")) == NULL ||
329 (isc_rollback_transaction = (tp_isc_rollback_transaction) dllFunc(dbDll, "isc_rollback_transaction")) == NULL ||
330 (isc_start_transaction = (tp_isc_start_transaction) dllFunc(dbDll, "isc_start_transaction")) == NULL) {
331 dbDll = NULL;
332 } /* if */
333 } /* if */
334 } /* if */
335 logFunction(printf("setupDll --> %d\n", dbDll != NULL););
336 return dbDll != NULL;
337 } /* setupDll */
338
339
340
findDll(void)341 static boolType findDll (void)
342
343 {
344 const char *dllList[] = { FIRE_DLL };
345 unsigned int pos;
346 boolType found = FALSE;
347
348 /* findDll */
349 for (pos = 0; pos < sizeof(dllList) / sizeof(char *) && !found; pos++) {
350 found = setupDll(dllList[pos]);
351 } /* for */
352 if (!found) {
353 dllErrorMessage("sqlOpenFire", "findDll", dllList,
354 sizeof(dllList) / sizeof(char *));
355 } /* if */
356 return found;
357 } /* findDll */
358
359 #else
360
361 #define findDll() TRUE
362
363 #endif
364
365
366
setDbErrorMsg(const char * funcName,const char * dbFuncName,ISC_STATUS * status_vector)367 static void setDbErrorMsg (const char *funcName, const char *dbFuncName,
368 ISC_STATUS *status_vector)
369
370 {
371 ISC_STATUS *pvector;
372 char messageText[512];
373
374 /* setDbErrorMsg */
375 dbError.funcName = funcName;
376 dbError.dbFuncName = dbFuncName;
377 dbError.errorCode = 0;
378 pvector = status_vector;
379 isc_interprete(messageText, &pvector);
380 strcpy(dbError.message, messageText);
381 messageText[0] = '\n';
382 messageText[1] = '-';
383 while (isc_interprete(&messageText[2], &pvector) != 0) {
384 strcat(dbError.message, messageText);
385 } /* while */
386 } /* setDbErrorMsg */
387
388
389
390 static void sqlClose (databaseType database);
391
392
393
394 /**
395 * Closes a database and frees the memory used by it.
396 */
freeDatabase(databaseType database)397 static void freeDatabase (databaseType database)
398
399 {
400 dbType db;
401
402 /* freeDatabase */
403 logFunction(printf("freeDatabase(" FMT_U_MEM ")\n",
404 (memSizeType) database););
405 sqlClose(database);
406 db = (dbType) database;
407 FREE_RECORD2(db, dbRecord, count.database, count.database_bytes);
408 logFunction(printf("freeDatabase -->\n"););
409 } /* freeDatabase */
410
411
412
413 /**
414 * Closes a prepared statement and frees the memory used by it.
415 */
freePreparedStmt(sqlStmtType sqlStatement)416 static void freePreparedStmt (sqlStmtType sqlStatement)
417
418 {
419 preparedStmtType preparedStmt;
420 ISC_STATUS status_vector[20];
421 int column;
422 int numColumns;
423 XSQLVAR *var;
424
425 /* freePreparedStmt */
426 logFunction(printf("freePreparedStmt(" FMT_U_MEM ")\n",
427 (memSizeType) sqlStatement););
428 preparedStmt = (preparedStmtType) sqlStatement;
429 if (preparedStmt->ppStmt != 0) {
430 if (unlikely((isc_dsql_free_statement(status_vector,
431 &preparedStmt->ppStmt,
432 DSQL_drop),
433 status_vector[0] == 1 && status_vector[1] != 0))) {
434 setDbErrorMsg("freePreparedStmt", "isc_dsql_free_statement",
435 status_vector);
436 logError(printf("freePreparedStmt: isc_dsql_free_statement error:\n%s\n",
437 dbError.message););
438 raise_error(DATABASE_ERROR);
439 } /* if */
440 } /* if */
441 if (preparedStmt->in_sqlda != NULL) {
442 numColumns = preparedStmt->in_sqlda->sqld;
443 for (column = 0, var = preparedStmt->in_sqlda->sqlvar;
444 column < numColumns; column++, var++) {
445 free(var->sqldata);
446 free(var->sqlind);
447 } /* for */
448 free(preparedStmt->in_sqlda);
449 } /* if */
450 if (preparedStmt->out_sqlda != NULL) {
451 numColumns = preparedStmt->out_sqlda->sqld;
452 for (column = 0, var = preparedStmt->out_sqlda->sqlvar;
453 column < numColumns; column++, var++) {
454 free(var->sqldata);
455 free(var->sqlind);
456 } /* for */
457 free(preparedStmt->out_sqlda);
458 } /* if */
459 if (preparedStmt->param_array != NULL) {
460 FREE_TABLE(preparedStmt->param_array, bindDataRecord,
461 (memSizeType) preparedStmt->in_sqlda->sqld);
462 } /* if */
463 FREE_RECORD2(preparedStmt, preparedStmtRecord,
464 count.prepared_stmt, count.prepared_stmt_bytes);
465 logFunction(printf("freePreparedStmt -->\n"););
466 } /* freePreparedStmt */
467
468
469
470 #if LOG_FUNCTIONS_EVERYWHERE || LOG_FUNCTIONS || VERBOSE_EXCEPTIONS_EVERYWHERE || VERBOSE_EXCEPTIONS
nameOfSqlType(int dtype)471 static const char *nameOfSqlType (int dtype)
472
473 {
474 static char buffer[50];
475 const char *typeName;
476
477 /* nameOfSqlType */
478 logFunction(printf("nameOfSqlType(%d)\n", dtype););
479 switch (dtype) {
480 case SQL_TEXT: typeName = "SQL_TEXT"; break;
481 case SQL_VARYING: typeName = "SQL_VARYING"; break;
482 case SQL_SHORT: typeName = "SQL_SHORT"; break;
483 case SQL_LONG: typeName = "SQL_LONG"; break;
484 case SQL_FLOAT: typeName = "SQL_FLOAT"; break;
485 case SQL_DOUBLE: typeName = "SQL_DOUBLE"; break;
486 case SQL_D_FLOAT: typeName = "SQL_D_FLOAT"; break;
487 case SQL_TIMESTAMP: typeName = "SQL_TIMESTAMP"; break;
488 case SQL_BLOB: typeName = "SQL_BLOB"; break;
489 case SQL_ARRAY: typeName = "SQL_ARRAY"; break;
490 case SQL_QUAD: typeName = "SQL_QUAD"; break;
491 case SQL_TYPE_TIME: typeName = "SQL_TYPE_TIME"; break;
492 case SQL_TYPE_DATE: typeName = "SQL_TYPE_DATE"; break;
493 case SQL_INT64: typeName = "SQL_INT64"; break;
494 case SQL_BOOLEAN: typeName = "SQL_BOOLEAN"; break;
495 case SQL_NULL: typeName = "SQL_NULL"; break;
496 default:
497 sprintf(buffer, "%d", dtype);
498 typeName = buffer;
499 break;
500 } /* switch */
501 logFunction(printf("nameOfSqlType --> %s\n", typeName););
502 return typeName;
503 } /* nameOfSqlType */
504 #endif
505
506
507
assign_in_sqlda(preparedStmtType preparedStmt)508 static errInfoType assign_in_sqlda (preparedStmtType preparedStmt)
509
510 {
511 XSQLDA *in_sqlda;
512 ISC_STATUS status_vector[20];
513 errInfoType err_info = OKAY_NO_ERROR;
514
515 /* assign_in_sqlda */
516 in_sqlda = (XSQLDA *) malloc(XSQLDA_LENGTH(1));
517 if (unlikely(in_sqlda == NULL)) {
518 err_info = MEMORY_ERROR;
519 } else {
520 memset(in_sqlda, 0, XSQLDA_LENGTH(1));
521 in_sqlda->version = SQLDA_VERSION1;
522 in_sqlda->sqln = 1;
523 if ((isc_dsql_describe_bind(status_vector,
524 &preparedStmt->ppStmt, 1, in_sqlda),
525 status_vector[0] == 1 && status_vector[1] != 0)) {
526 setDbErrorMsg("sqlPrepare", "isc_dsql_describe_bind",
527 status_vector);
528 logError(printf("sqlPrepare: isc_dsql_describe_bind error:\n%s\n",
529 dbError.message););
530 free(in_sqlda);
531 err_info = DATABASE_ERROR;
532 } else {
533 if (in_sqlda->sqld > in_sqlda->sqln) {
534 short numInVars = in_sqlda->sqld;
535 free(in_sqlda);
536 in_sqlda = (XSQLDA *) malloc(XSQLDA_LENGTH((memSizeType) numInVars));
537 if (unlikely(in_sqlda == NULL)) {
538 err_info = MEMORY_ERROR;
539 } else {
540 memset(in_sqlda, 0, XSQLDA_LENGTH((memSizeType) numInVars));
541 in_sqlda->version = SQLDA_VERSION1;
542 in_sqlda->sqln = numInVars;
543 if ((isc_dsql_describe_bind(status_vector,
544 &preparedStmt->ppStmt, 1, in_sqlda),
545 status_vector[0] == 1 && status_vector[1] != 0)) {
546 setDbErrorMsg("sqlPrepare", "isc_dsql_describe_bind",
547 status_vector);
548 logError(printf("sqlPrepare: isc_dsql_describe_bind error:\n%s\n",
549 dbError.message););
550 free(in_sqlda);
551 err_info = DATABASE_ERROR;
552 } else {
553 preparedStmt->in_sqlda = in_sqlda;
554 } /* if */
555 } /* if */
556 } else {
557 preparedStmt->in_sqlda = in_sqlda;
558 } /* if */
559 } /* if */
560 } /* if */
561 return err_info;
562 } /* assign_in_sqlda */
563
564
565
assign_out_sqlda(preparedStmtType preparedStmt,XSQLDA * out_sqlda)566 static errInfoType assign_out_sqlda (preparedStmtType preparedStmt,
567 XSQLDA *out_sqlda)
568
569 {
570 ISC_STATUS status_vector[20];
571 errInfoType err_info = OKAY_NO_ERROR;
572
573 /* assign_out_sqlda */
574 if (out_sqlda->sqld > out_sqlda->sqln) {
575 short numOutVars = out_sqlda->sqld;
576 free(out_sqlda);
577 out_sqlda = (XSQLDA *) malloc(XSQLDA_LENGTH((memSizeType) numOutVars));
578 if (unlikely(out_sqlda == NULL)) {
579 err_info = MEMORY_ERROR;
580 } else {
581 memset(out_sqlda, 0, XSQLDA_LENGTH((memSizeType) numOutVars));
582 out_sqlda->version = SQLDA_VERSION1;
583 out_sqlda->sqln = numOutVars;
584 if ((isc_dsql_describe(status_vector, &preparedStmt->ppStmt,
585 1, out_sqlda),
586 status_vector[0] == 1 && status_vector[1] != 0)) {
587 setDbErrorMsg("sqlPrepare", "isc_dsql_describe",
588 status_vector);
589 logError(printf("sqlPrepare: isc_dsql_describe error:\n%s\n",
590 dbError.message););
591 free(out_sqlda);
592 err_info = DATABASE_ERROR;
593 } else {
594 preparedStmt->out_sqlda = out_sqlda;
595 } /* if */
596 } /* if */
597 } else {
598 preparedStmt->out_sqlda = out_sqlda;
599 } /* if */
600 return err_info;
601 } /* assign_out_sqlda */
602
603
604
setupParameters(preparedStmtType preparedStmt)605 static errInfoType setupParameters (preparedStmtType preparedStmt)
606
607 {
608 int column;
609 int numColumns;
610 XSQLVAR *sqlvar;
611 int dtype;
612 errInfoType err_info = OKAY_NO_ERROR;
613
614 /* setupParameters */
615 logFunction(printf("setupParameters\n"););
616 err_info = assign_in_sqlda(preparedStmt);
617 if (unlikely(err_info != OKAY_NO_ERROR)) {
618 preparedStmt->param_array = NULL;
619 } else if (preparedStmt->in_sqlda->sqld == 0) {
620 /* malloc(0) may return NULL, which would wrongly trigger a MEMORY_ERROR. */
621 preparedStmt->param_array = NULL;
622 } else if (unlikely(!ALLOC_TABLE(preparedStmt->param_array,
623 bindDataRecord,
624 (memSizeType) preparedStmt->in_sqlda->sqld))) {
625 err_info = MEMORY_ERROR;
626 } else {
627 memset(preparedStmt->param_array, 0,
628 (memSizeType) preparedStmt->in_sqlda->sqld * sizeof(bindDataRecord));
629 } /* if */
630 if (likely(err_info == OKAY_NO_ERROR)) {
631 numColumns = preparedStmt->in_sqlda->sqld;
632 for (column = 0, sqlvar = preparedStmt->in_sqlda->sqlvar;
633 column < numColumns; column++, sqlvar++) {
634 /* printf("sqllen: %hd\n", sqlvar->sqllen); */
635 dtype = sqlvar->sqltype & ~1; /* drop flag bit for now */
636 switch(dtype) {
637 case SQL_TEXT:
638 if (unlikely(sqlvar->sqllen <= 0)) {
639 dbInconsistent("setupParameters", "sqllen");
640 logError(printf("setupParameters: Column %d: "
641 "sqllen %hd of SQL_TEXT is negative or zero.\n",
642 column + 1, sqlvar->sqllen););
643 err_info = DATABASE_ERROR;
644 } else {
645 sqlvar->sqldata = (char *) malloc(sizeof(char) * (memSizeType) sqlvar->sqllen);
646 } /* if */
647 break;
648 case SQL_VARYING:
649 if (unlikely(sqlvar->sqllen <= 0)) {
650 dbInconsistent("setupParameters", "sqllen");
651 logError(printf("setupParameters: Column %d: "
652 "sqllen %hd of SQL_VARYING is negative or zero.\n",
653 column + 1, sqlvar->sqllen););
654 err_info = DATABASE_ERROR;
655 } else {
656 sqlvar->sqldata = (char *) malloc(sizeof(uint16Type) +
657 sizeof(char) * (memSizeType) sqlvar->sqllen);
658 } /* if */
659 break;
660 case SQL_BOOLEAN:
661 case SQL_SHORT:
662 if (unlikely(sqlvar->sqlscale != 0)) {
663 dbInconsistent("setupParameters", "sqlscale");
664 logError(printf("setupParameters: Column %d: "
665 "The scale of an SQL_SHORT field must be 0.\n", column););
666 err_info = DATABASE_ERROR;
667 } else {
668 sqlvar->sqldata = (char *) malloc(sizeof(short));
669 } /* if */
670 break;
671 case SQL_LONG:
672 if (unlikely(sqlvar->sqlscale != 0)) {
673 dbInconsistent("setupParameters", "sqlscale");
674 logError(printf("setupParameters: Column %d: "
675 "The scale of an SQL_LONG field must be 0.\n", column););
676 err_info = DATABASE_ERROR;
677 } else {
678 sqlvar->sqldata = (char *) malloc(sizeof(ISC_LONG));
679 } /* if */
680 break;
681 case SQL_INT64:
682 sqlvar->sqldata = (char *) malloc(sizeof(ISC_INT64));
683 break;
684 case SQL_FLOAT:
685 sqlvar->sqldata = (char *) malloc(sizeof(float));
686 break;
687 case SQL_DOUBLE:
688 sqlvar->sqldata = (char *) malloc(sizeof(double));
689 break;
690 case SQL_BLOB:
691 sqlvar->sqldata = (char *) malloc(sizeof(ISC_QUAD));
692 break;
693 case SQL_TIMESTAMP:
694 sqlvar->sqldata = (char *) malloc(sizeof(ISC_TIMESTAMP));
695 break;
696 case SQL_TYPE_TIME:
697 sqlvar->sqldata = (char *) malloc(sizeof(ISC_TIME));
698 break;
699 case SQL_TYPE_DATE:
700 sqlvar->sqldata = (char *) malloc(sizeof(ISC_DATE));
701 break;
702 default:
703 logError(printf("setupParameters: Column %d has the unknown type %s.\n",
704 column + 1, nameOfSqlType(dtype)););
705 err_info = RANGE_ERROR;
706 break;
707 } /* switch */
708 if (sqlvar->sqltype & 1) {
709 /* allocate variable to hold NULL status */
710 sqlvar->sqlind = (short *) malloc(sizeof(short));
711 } /* if */
712 } /* for */
713 } /* if */
714 logFunction(printf("setupParameters --> %d\n", err_info););
715 return err_info;
716 } /* setupParameters */
717
718
719
setupResult(preparedStmtType preparedStmt,XSQLDA * out_sqlda)720 static errInfoType setupResult (preparedStmtType preparedStmt,
721 XSQLDA *out_sqlda)
722
723 {
724 int column;
725 int numColumns;
726 XSQLVAR *sqlvar;
727 int dtype;
728 errInfoType err_info = OKAY_NO_ERROR;
729
730 /* setupResult */
731 logFunction(printf("setupResult\n"););
732 err_info = assign_out_sqlda(preparedStmt, out_sqlda);
733 if (likely(err_info == OKAY_NO_ERROR)) {
734 numColumns = preparedStmt->out_sqlda->sqld;
735 for (column = 0, sqlvar = preparedStmt->out_sqlda->sqlvar;
736 column < numColumns; column++, sqlvar++) {
737 /* printf("sqllen: %hd\n", sqlvar->sqllen); */
738 dtype = sqlvar->sqltype & ~1; /* drop flag bit for now */
739 switch(dtype) {
740 case SQL_TEXT:
741 if (unlikely(sqlvar->sqllen <= 0)) {
742 dbInconsistent("setupResult", "sqllen");
743 logError(printf("setupResult: Column %d: "
744 "sqllen %hd of SQL_TEXT is negative or zero.\n",
745 column + 1, sqlvar->sqllen););
746 err_info = DATABASE_ERROR;
747 } else {
748 sqlvar->sqldata = (char *) malloc(sizeof(char) * (memSizeType) sqlvar->sqllen);
749 } /* if */
750 break;
751 case SQL_VARYING:
752 if (unlikely(sqlvar->sqllen <= 0)) {
753 dbInconsistent("setupResult", "sqllen");
754 logError(printf("setupResult: Column %d: "
755 "sqllen %hd of SQL_VARYING is negative or zero.\n",
756 column + 1, sqlvar->sqllen););
757 err_info = DATABASE_ERROR;
758 } else {
759 sqlvar->sqldata = (char *) malloc(sizeof(uint16Type) +
760 sizeof(char) * (memSizeType) sqlvar->sqllen);
761 } /* if */
762 break;
763 case SQL_BOOLEAN:
764 case SQL_SHORT:
765 sqlvar->sqldata = (char *) malloc(sizeof(short));
766 break;
767 case SQL_LONG:
768 sqlvar->sqldata = (char *) malloc(sizeof(ISC_LONG));
769 break;
770 case SQL_INT64:
771 sqlvar->sqldata = (char *) malloc(sizeof(ISC_INT64));
772 break;
773 case SQL_FLOAT:
774 sqlvar->sqldata = (char *) malloc(sizeof(float));
775 break;
776 case SQL_DOUBLE:
777 sqlvar->sqldata = (char *) malloc(sizeof(double));
778 break;
779 case SQL_BLOB:
780 sqlvar->sqldata = (char *) malloc(sizeof(ISC_QUAD));
781 break;
782 case SQL_TIMESTAMP:
783 sqlvar->sqldata = (char *) malloc(sizeof(ISC_TIMESTAMP));
784 break;
785 case SQL_TYPE_TIME:
786 sqlvar->sqldata = (char *) malloc(sizeof(ISC_TIME));
787 break;
788 case SQL_TYPE_DATE:
789 sqlvar->sqldata = (char *) malloc(sizeof(ISC_DATE));
790 break;
791 case SQL_ARRAY:
792 sqlvar->sqldata = (char *) malloc(sizeof(ISC_QUAD));
793 break;
794 default:
795 logError(printf("setupResult: Column %d has the unknown type %s.\n",
796 column + 1, nameOfSqlType(dtype)););
797 err_info = RANGE_ERROR;
798 break;
799 } /* switch */
800 if (sqlvar->sqltype & 1) {
801 /* allocate variable to hold NULL status */
802 sqlvar->sqlind = (short *) malloc(sizeof(short));
803 } /* if */
804 } /* for */
805 } /* if */
806 logFunction(printf("setupResult --> %d\n", err_info););
807 return err_info;
808 } /* setupResult */
809
810
811
allParametersBound(preparedStmtType preparedStmt)812 static boolType allParametersBound (preparedStmtType preparedStmt)
813
814 {
815 int column_index;
816 boolType okay = TRUE;
817
818 /* allParametersBound */
819 for (column_index = 0; column_index < preparedStmt->in_sqlda->sqld;
820 column_index++) {
821 if (unlikely(!preparedStmt->param_array[column_index].bound)) {
822 logError(printf("sqlExecute: Unbound parameter %d.\n",
823 column_index + 1););
824 okay = FALSE;
825 } /* if */
826 } /* for */
827 return okay;
828 } /* allParametersBound */
829
830
831
intToScaledInt64(const intType value,int decimalDigits,errInfoType * err_info)832 static int64Type intToScaledInt64 (const intType value,
833 int decimalDigits, errInfoType *err_info)
834
835 {
836 int64Type factor;
837
838 /* intToScaledInt64 */
839 logFunction(printf("intToScaledInt64(" FMT_D ", %d, *)\n",
840 value, decimalDigits););
841 switch (decimalDigits) {
842 case 0: factor = 1; break;
843 case 1: factor = 10; break;
844 case 2: factor = 100; break;
845 case 3: factor = 1000; break;
846 case 4: factor = 10000; break;
847 case 5: factor = 100000; break;
848 case 6: factor = 1000000; break;
849 case 7: factor = 10000000; break;
850 case 8: factor = 100000000; break;
851 case 9: factor = 1000000000; break;
852 case 10: factor = 10000000000; break;
853 case 11: factor = 100000000000; break;
854 case 12: factor = 1000000000000; break;
855 case 13: factor = 10000000000000; break;
856 case 14: factor = 100000000000000; break;
857 case 15: factor = 1000000000000000; break;
858 case 16: factor = 10000000000000000; break;
859 case 17: factor = 100000000000000000; break;
860 case 18: factor = 1000000000000000000; break;
861 default:
862 logError(printf("intToScaledInt64: Wrong number of decimal digits: %d\n",
863 decimalDigits););
864 raise_error(RANGE_ERROR);
865 factor = 1;
866 break;
867 } /* switch */
868 if (value < 0) {
869 if (unlikely(value < INT64TYPE_MIN / factor)) {
870 logError(printf("intToScaledInt64: Value (" FMT_D
871 ") smaller than minimum (" FMT_D ").\n",
872 value, INT64TYPE_MIN / factor));
873 *err_info = RANGE_ERROR;
874 factor = 1;
875 } /* if */
876 } else {
877 if (unlikely(value > INT64TYPE_MAX / factor)) {
878 logError(printf("intToScaledInt64: Value (" FMT_D
879 ") larger than maximum (" FMT_D ").\n",
880 value, INT64TYPE_MAX / factor));
881 *err_info = RANGE_ERROR;
882 factor = 1;
883 } /* if */
884 } /* if */
885 return value * factor;
886 } /* intToScaledInt64 */
887
888
889
bigIntToScaledInt64(const const_bigIntType value,int decimalDigits,errInfoType * err_info)890 static int64Type bigIntToScaledInt64 (const const_bigIntType value,
891 int decimalDigits, errInfoType *err_info)
892
893 {
894 bigIntType number;
895 int64Type int64Value = 0;
896
897 /* bigIntToScaledInt64 */
898 logFunction(printf("bigIntToScaledInt64(%s, %d, *)\n",
899 bigHexCStri(value), decimalDigits););
900 number = bigIPowSignedDigit(10, decimalDigits);
901 if (number != NULL) {
902 bigMultAssign(&number, value);
903 if (number != NULL) {
904 /* printf("mantissaValue: ");
905 prot_bigint(mantissaValue);
906 printf("\n"); */
907 int64Value = bigToInt64(number, err_info);
908 bigDestr(number);
909 } /* if */
910 } /* if */
911 return int64Value;
912 } /* bigIntToScaledInt64 */
913
914
915
bigRatToScaledInt64(const const_bigIntType numerator,const const_bigIntType denominator,int decimalDigits,errInfoType * err_info)916 static int64Type bigRatToScaledInt64 (const const_bigIntType numerator,
917 const const_bigIntType denominator, int decimalDigits,
918 errInfoType *err_info)
919
920 {
921 bigIntType number;
922 bigIntType mantissaValue;
923 int64Type int64Value = 0;
924
925 /* bigRatToScaledInt64 */
926 logFunction(printf("bigRatToScaledInt64(%s, %s, %d, *)\n",
927 bigHexCStri(numerator), bigHexCStri(denominator),
928 decimalDigits););
929 if (unlikely(bigEqSignedDigit(denominator, 0))) {
930 /* Numeric values do not support Infinity and NaN. */
931 logError(printf("bigRatToScaledInt64: Decimal values do not support Infinity and NaN.\n"););
932 *err_info = RANGE_ERROR;
933 } else {
934 number = bigIPowSignedDigit(10, decimalDigits);
935 if (number != NULL) {
936 bigMultAssign(&number, numerator);
937 mantissaValue = bigDiv(number, denominator);
938 bigDestr(number);
939 if (mantissaValue != NULL) {
940 /* printf("mantissaValue: ");
941 prot_bigint(mantissaValue);
942 printf("\n"); */
943 int64Value = bigToInt64(mantissaValue, err_info);
944 bigDestr(mantissaValue);
945 } /* if */
946 } /* if */
947 } /* if */
948 return int64Value;
949 } /* bigRatToScaledInt64 */
950
951
952
getBlobLength(isc_blob_handle blob_handle,errInfoType * err_info)953 static memSizeType getBlobLength (isc_blob_handle blob_handle, errInfoType *err_info)
954
955 {
956 ISC_STATUS status_vector[20];
957 char blob_items[] = {isc_info_blob_total_length};
958 char res_buffer[20];
959 char *ptr;
960 char item;
961 short length;
962 boolType totalLengthAssigned = FALSE;
963 ISC_INT64 totalLength;
964
965 /* getBlobLength */
966 logFunction(printf("getBlobLength(" FMT_U32 ", *)\n", blob_handle););
967 if ((isc_blob_info(status_vector,
968 &blob_handle,
969 sizeof(blob_items),
970 blob_items,
971 sizeof(res_buffer),
972 res_buffer),
973 status_vector[0] == 1 && status_vector[1] != 0)) {
974 setDbErrorMsg("getBlobLength", "isc_blob_info",
975 status_vector);
976 logError(printf("getBlobLength: isc_blob_info() error:\n%s\n",
977 dbError.message););
978 *err_info = DATABASE_ERROR;
979 totalLength = 0;
980 } else {
981 for (ptr = res_buffer; *ptr != isc_info_end;) {
982 item = *ptr++;
983 length = (short) isc_portable_integer(ptr, 2);
984 ptr += 2;
985 switch (item) {
986 case isc_info_blob_total_length:
987 totalLength = isc_portable_integer(ptr, length);
988 totalLengthAssigned = TRUE;
989 break;
990 case isc_info_truncated:
991 /* handle error */
992 break;
993 default:
994 break;
995 } /* switch */
996 ptr += length;
997 } /* for */
998 } /* if */
999 if (unlikely(!totalLengthAssigned)) {
1000 dbInconsistent("getBlobLength", "isc_blob_info");
1001 logError(printf("getBlobLength: Isc_blob_info returns no value "
1002 " for isc_info_blob_total_length.\n"););
1003 *err_info = DATABASE_ERROR;
1004 totalLength = 0;
1005 } else if (unlikely(totalLength < 0)) {
1006 dbInconsistent("getBlobLength", "isc_blob_info");
1007 logError(printf("getBlobLength: Isc_blob_info returns negative "
1008 " value for isc_info_blob_total_length: " FMT_D64 ".\n",
1009 (int64Type) totalLength););
1010 *err_info = DATABASE_ERROR;
1011 totalLength = 0;
1012 } if (unlikely(totalLength > MAX_MEMSIZETYPE)) {
1013 /* It is not possible to cast totalLength to memSizeType. */
1014 /* Memory with this length cannot be allocated. */
1015 *err_info = MEMORY_ERROR;
1016 totalLength = 0;
1017 } /* if */
1018 logFunction(printf("getBlobLength --> " FMT_U_MEM "\n",
1019 (memSizeType) totalLength););
1020 return (memSizeType) totalLength;
1021 } /* getBlobLength */
1022
1023
1024
copyBlobContents(isc_blob_handle blob_handle,memSizeType blobLength,ustriType destination)1025 static memSizeType copyBlobContents (isc_blob_handle blob_handle,
1026 memSizeType blobLength, ustriType destination)
1027
1028 {
1029 memSizeType bytesToGet;
1030 unsigned short segmentLength;
1031 unsigned short actualSegmentLength;
1032 ISC_STATUS status_vector[20];
1033 ISC_STATUS blob_stat;
1034
1035 /* copyBlobContents */
1036 bytesToGet = blobLength;
1037 if (bytesToGet > UINT16TYPE_MAX) {
1038 segmentLength = UINT16TYPE_MAX;
1039 } else {
1040 segmentLength = (unsigned short) bytesToGet;
1041 } /* if */
1042 blob_stat = isc_get_segment(status_vector,
1043 &blob_handle,
1044 &actualSegmentLength,
1045 segmentLength,
1046 (char *) destination);
1047 while (blob_stat == 0 || status_vector[1] == isc_segment) {
1048 /* isc_get_segment returns 0 if a segment was successfully read. */
1049 /* status_vector[1] is set to isc_segment if only part of a */
1050 /* segment was read due to the buffer (blob_segment) not being */
1051 /* large enough. In that case, the following calls to */
1052 /* isc_get_segment() read the rest of the buffer. */
1053 bytesToGet -= (memSizeType) actualSegmentLength;
1054 destination += actualSegmentLength;
1055 if (bytesToGet > UINT16TYPE_MAX) {
1056 segmentLength = UINT16TYPE_MAX;
1057 } else {
1058 segmentLength = (unsigned short) bytesToGet;
1059 } /* if */
1060 blob_stat = isc_get_segment(status_vector,
1061 &blob_handle,
1062 &actualSegmentLength,
1063 segmentLength,
1064 (char *) destination);
1065 } /* while */
1066 return blobLength - bytesToGet;
1067 } /* copyBlobContents */
1068
1069
1070
getBlob(preparedStmtType preparedStmt,ISC_QUAD * blob_id,errInfoType * err_info)1071 static bstriType getBlob (preparedStmtType preparedStmt,
1072 ISC_QUAD *blob_id, errInfoType *err_info)
1073
1074 {
1075 ISC_STATUS status_vector[20];
1076 isc_blob_handle blob_handle = 0;
1077 memSizeType blobLength;
1078 bstriType bstri;
1079
1080 /* getBlob */
1081 logFunction(printf("getBlob(" FMT_U_MEM ", " FMT_X64 ", *)\n",
1082 (memSizeType) preparedStmt, *(uint64Type *) blob_id););
1083 /* Blob_handle must be zero when isc_open_blob2 is called. */
1084 if ((isc_open_blob2(status_vector,
1085 &preparedStmt->db->connection,
1086 &preparedStmt->db->trans_handle,
1087 &blob_handle,
1088 blob_id,
1089 0,
1090 NULL),
1091 status_vector[0] == 1 && status_vector[1] != 0)) {
1092 setDbErrorMsg("getBlob", "isc_open_blob2",
1093 status_vector);
1094 logError(printf("getBlob: isc_open_blob2() error:\n%s\n",
1095 dbError.message););
1096 *err_info = DATABASE_ERROR;
1097 bstri = NULL;
1098 } else {
1099 blobLength = getBlobLength(blob_handle, err_info);
1100 if (likely(*err_info == OKAY_NO_ERROR)) {
1101 if (unlikely(blobLength > MAX_BSTRI_LEN ||
1102 !ALLOC_BSTRI_SIZE_OK(bstri, blobLength))) {
1103 *err_info = MEMORY_ERROR;
1104 bstri = NULL;
1105 } else {
1106 bstri->size = copyBlobContents(blob_handle, blobLength, bstri->mem);
1107 } /* if */
1108 } else {
1109 bstri = NULL;
1110 } /* if */
1111 isc_close_blob(status_vector, &blob_handle);
1112 if (unlikely(status_vector[0] == 1 && status_vector[1] != 0)) {
1113 setDbErrorMsg("getBlob", "isc_close_blob",
1114 status_vector);
1115 logError(printf("getBlob: isc_close_blob() error:\n%s\n",
1116 dbError.message););
1117 *err_info = DATABASE_ERROR;
1118 FREE_BSTRI(bstri, blobLength);
1119 bstri = NULL;
1120 } /* if */
1121 } /* if */
1122 logFunction(printf("getBlob --> \"%s\"\n",
1123 bstriAsUnquotedCStri(bstri)););
1124 return bstri;
1125 } /* getBlob */
1126
1127
1128
getBlobAsStri(preparedStmtType preparedStmt,ISC_QUAD * blob_id,errInfoType * err_info)1129 static striType getBlobAsStri (preparedStmtType preparedStmt,
1130 ISC_QUAD *blob_id, errInfoType *err_info)
1131
1132 {
1133 ISC_STATUS status_vector[20];
1134 isc_blob_handle blob_handle = 0;
1135 memSizeType blobLength;
1136 memSizeType actualBlobLength;
1137 striType stri;
1138
1139 /* getBlobAsStri */
1140 logFunction(printf("getBlobAsStri(" FMT_U_MEM ", " FMT_X64 ", *)\n",
1141 (memSizeType) preparedStmt, *(uint64Type *) blob_id););
1142 /* Blob_handle must be zero when isc_open_blob2 is called. */
1143 if (unlikely((isc_open_blob2(status_vector,
1144 &preparedStmt->db->connection,
1145 &preparedStmt->db->trans_handle,
1146 &blob_handle,
1147 blob_id,
1148 0,
1149 NULL),
1150 status_vector[0] == 1 && status_vector[1] != 0))) {
1151 setDbErrorMsg("getBlobAsStri", "isc_open_blob2",
1152 status_vector);
1153 logError(printf("getBlobAsStri: isc_open_blob2() error:\n%s\n",
1154 dbError.message););
1155 *err_info = DATABASE_ERROR;
1156 stri = NULL;
1157 } else {
1158 blobLength = getBlobLength(blob_handle, err_info);
1159 if (likely(*err_info == OKAY_NO_ERROR)) {
1160 if (unlikely(blobLength > MAX_STRI_LEN ||
1161 !ALLOC_STRI_SIZE_OK(stri, blobLength))) {
1162 *err_info = MEMORY_ERROR;
1163 stri = NULL;
1164 } else {
1165 actualBlobLength = copyBlobContents(blob_handle, blobLength, (ustriType) stri->mem);
1166 memcpy_to_strelem(stri->mem, (ustriType) stri->mem, actualBlobLength);
1167 stri->size = actualBlobLength;
1168 } /* if */
1169 } else {
1170 stri = NULL;
1171 } /* if */
1172 isc_close_blob(status_vector, &blob_handle);
1173 if (unlikely(status_vector[0] == 1 && status_vector[1] != 0)) {
1174 setDbErrorMsg("getBlobAsStri", "isc_close_blob",
1175 status_vector);
1176 logError(printf("getBlobAsStri: isc_close_blob() error:\n%s\n",
1177 dbError.message););
1178 *err_info = DATABASE_ERROR;
1179 FREE_STRI(stri, blobLength);
1180 stri = NULL;
1181 } /* if */
1182 } /* if */
1183 logFunction(printf("getBlobAsStri --> \"%s\"\n",
1184 striAsUnquotedCStri(stri)););
1185 return stri;
1186 } /* getBlobAsStri */
1187
1188
1189
getClob(preparedStmtType preparedStmt,ISC_QUAD * blob_id,errInfoType * err_info)1190 static striType getClob (preparedStmtType preparedStmt,
1191 ISC_QUAD *blob_id, errInfoType *err_info)
1192
1193 {
1194 ISC_STATUS status_vector[20];
1195 isc_blob_handle blob_handle = 0;
1196 memSizeType blobLength;
1197 memSizeType actualBlobLength;
1198 cstriType utf8_stri;
1199 striType stri;
1200
1201 /* getClob */
1202 logFunction(printf("getClob(" FMT_U_MEM ", " FMT_X64 ", *)\n",
1203 (memSizeType) preparedStmt, *(uint64Type *) blob_id););
1204 /* Blob_handle must be zero when isc_open_blob2 is called. */
1205 if (unlikely((isc_open_blob2(status_vector,
1206 &preparedStmt->db->connection,
1207 &preparedStmt->db->trans_handle,
1208 &blob_handle,
1209 blob_id,
1210 0,
1211 NULL),
1212 status_vector[0] == 1 && status_vector[1] != 0))) {
1213 setDbErrorMsg("getClob", "isc_open_blob2",
1214 status_vector);
1215 logError(printf("getClob: isc_open_blob2() error:\n%s\n",
1216 dbError.message););
1217 *err_info = DATABASE_ERROR;
1218 stri = NULL;
1219 } else {
1220 blobLength = getBlobLength(blob_handle, err_info);
1221 if (likely(*err_info == OKAY_NO_ERROR)) {
1222 if (unlikely(blobLength > MAX_MEMSIZETYPE ||
1223 !ALLOC_BYTES(utf8_stri, blobLength))) {
1224 *err_info = MEMORY_ERROR;
1225 stri = NULL;
1226 } else {
1227 actualBlobLength = copyBlobContents(blob_handle, blobLength, (ustriType) utf8_stri);
1228 stri = cstri8_buf_to_stri(utf8_stri, actualBlobLength, err_info);
1229 FREE_BYTES(utf8_stri, blobLength);
1230 } /* if */
1231 } else {
1232 stri = NULL;
1233 } /* if */
1234 isc_close_blob(status_vector, &blob_handle);
1235 if (unlikely(status_vector[0] == 1 && status_vector[1] != 0)) {
1236 setDbErrorMsg("getClob", "isc_close_blob",
1237 status_vector);
1238 logError(printf("getClob: isc_close_blob() error:\n%s\n",
1239 dbError.message););
1240 *err_info = DATABASE_ERROR;
1241 FREE_STRI(stri, blobLength);
1242 stri = NULL;
1243 } /* if */
1244 } /* if */
1245 logFunction(printf("getClob --> \"%s\"\n",
1246 striAsUnquotedCStri(stri)););
1247 return stri;
1248 } /* getClob */
1249
1250
1251
putBlob(preparedStmtType preparedStmt,const const_bstriType bstri,XSQLVAR * sqlvar)1252 static errInfoType putBlob (preparedStmtType preparedStmt,
1253 const const_bstriType bstri, XSQLVAR *sqlvar)
1254
1255 {
1256 ISC_STATUS status_vector[20];
1257 isc_blob_handle blob_handle = 0;
1258 ISC_QUAD blob_id;
1259 memSizeType byteIndex;
1260 memSizeType bytesToWrite;
1261 unsigned short segmentLength;
1262 errInfoType err_info = OKAY_NO_ERROR;
1263
1264 /* putBlob */
1265 logFunction(printf("putBlob(" FMT_U_MEM ", \"%s\")\n",
1266 (memSizeType) preparedStmt, bstriAsUnquotedCStri(bstri)));
1267 /* Blob_handle must be zero when isc_create_blob2() is called. */
1268 if (unlikely((isc_create_blob2(status_vector,
1269 &preparedStmt->db->connection,
1270 &preparedStmt->db->trans_handle,
1271 &blob_handle,
1272 &blob_id,
1273 0,
1274 NULL),
1275 status_vector[0] == 1 && status_vector[1] != 0))) {
1276 setDbErrorMsg("putBlob", "isc_create_blob2",
1277 status_vector);
1278 logError(printf("putBlob: isc_create_blob2() error:\n%s\n",
1279 dbError.message););
1280 err_info = DATABASE_ERROR;
1281 } else {
1282 byteIndex = 0;
1283 bytesToWrite = bstri->size;
1284 while (bytesToWrite > 0 && err_info == OKAY_NO_ERROR) {
1285 if (bytesToWrite > UINT16TYPE_MAX) {
1286 segmentLength = UINT16TYPE_MAX;
1287 } else {
1288 segmentLength = (unsigned short) bytesToWrite;
1289 } /* if */
1290 if (unlikely((isc_put_segment(status_vector,
1291 &blob_handle,
1292 segmentLength,
1293 (char *) &bstri->mem[byteIndex]),
1294 status_vector[0] == 1 && status_vector[1] != 0))) {
1295 setDbErrorMsg("putBlob", "isc_put_segment",
1296 status_vector);
1297 logError(printf("putBlob: isc_put_segment() error:\n%s\n",
1298 dbError.message););
1299 err_info = DATABASE_ERROR;
1300 } else {
1301 byteIndex += segmentLength;
1302 bytesToWrite -= segmentLength;
1303 } /* if */
1304 } /* while */
1305 if (unlikely((isc_close_blob(status_vector,
1306 &blob_handle),
1307 status_vector[0] == 1 && status_vector[1] != 0))) {
1308 setDbErrorMsg("getBlob", "isc_close_blob",
1309 status_vector);
1310 logError(printf("getBlob: isc_close_blob() error:\n%s\n",
1311 dbError.message););
1312 err_info = DATABASE_ERROR;
1313 } else if (likely(err_info == OKAY_NO_ERROR)) {
1314 memcpy(sqlvar->sqldata, &blob_id, sizeof(ISC_QUAD));
1315 } /* if */
1316 } /* if */
1317 logFunction(printf("putBlob --> %d\n", err_info););
1318 return err_info;
1319 } /* putBlob */
1320
1321
1322
sqlBindBigInt(sqlStmtType sqlStatement,intType pos,const const_bigIntType value)1323 static void sqlBindBigInt (sqlStmtType sqlStatement, intType pos,
1324 const const_bigIntType value)
1325
1326 {
1327 preparedStmtType preparedStmt;
1328 ISC_STATUS status_vector[20];
1329 XSQLVAR *sqlvar;
1330 striType decimalNumber;
1331 errInfoType err_info = OKAY_NO_ERROR;
1332
1333 /* sqlBindBigInt */
1334 logFunction(printf("sqlBindBigInt(" FMT_U_MEM ", " FMT_D ", %s)\n",
1335 (memSizeType) sqlStatement, pos, bigHexCStri(value)););
1336 preparedStmt = (preparedStmtType) sqlStatement;
1337 if (unlikely(pos < 1 || pos > preparedStmt->in_sqlda->sqld)) {
1338 logError(printf("sqlBindBigInt: pos: " FMT_D ", max pos: %hd.\n",
1339 pos, preparedStmt->in_sqlda->sqld););
1340 raise_error(RANGE_ERROR);
1341 } else {
1342 if (preparedStmt->executeSuccessful) {
1343 if (unlikely((isc_dsql_free_statement(status_vector,
1344 &preparedStmt->ppStmt,
1345 DSQL_close),
1346 status_vector[0] == 1 && status_vector[1] != 0))) {
1347 setDbErrorMsg("sqlBindBigInt", "isc_dsql_free_statement",
1348 status_vector);
1349 logError(printf("sqlBindBigInt: isc_dsql_free_statement error:\n%s\n",
1350 dbError.message););
1351 err_info = DATABASE_ERROR;
1352 } else {
1353 preparedStmt->executeSuccessful = FALSE;
1354 } /* if */
1355 } /* if */
1356 if (likely(err_info == OKAY_NO_ERROR)) {
1357 sqlvar = &preparedStmt->in_sqlda->sqlvar[pos - 1];
1358 /* printf("paramType: %s\n", nameOfSqlType(sqlvar->sqltype & ~1)); */
1359 switch (sqlvar->sqltype & ~1) {
1360 case SQL_SHORT:
1361 *(int16Type *) sqlvar->sqldata = bigToInt16(value, &err_info);
1362 break;
1363 case SQL_LONG:
1364 *(int32Type *) sqlvar->sqldata = bigToInt32(value, &err_info);
1365 break;
1366 case SQL_INT64:
1367 /* printf("sqlBindBigInt: scale: %hd\n", sqlvar->sqlscale); */
1368 if (sqlvar->sqlscale == 0) {
1369 *(int64Type *) sqlvar->sqldata = bigToInt64(value, &err_info);
1370 } else {
1371 *(int64Type *) sqlvar->sqldata = bigIntToScaledInt64(value,
1372 -sqlvar->sqlscale, &err_info);
1373 } /* if */
1374 break;
1375 case SQL_FLOAT:
1376 *(float *) sqlvar->sqldata = (float) bigIntToDouble(value);
1377 break;
1378 case SQL_DOUBLE:
1379 *(double *) sqlvar->sqldata = bigIntToDouble(value);
1380 break;
1381 case SQL_TEXT:
1382 decimalNumber = bigStr(value);
1383 if (decimalNumber == NULL) {
1384 err_info = MEMORY_ERROR;
1385 } else {
1386 /* setupParameters() has already checked that sqllen > 0 holds */
1387 if (unlikely((memSizeType) sqlvar->sqllen < decimalNumber->size)) {
1388 logError(printf("sqlBindBigInt: Parameter " FMT_D ": "
1389 "Decimal representation of %s longer than allowed (%hd).\n",
1390 pos, striAsUnquotedCStri(decimalNumber),
1391 sqlvar->sqllen););
1392 err_info = RANGE_ERROR;
1393 } else {
1394 memcpy_from_strelem((ustriType) sqlvar->sqldata,
1395 decimalNumber->mem, decimalNumber->size);
1396 memset(&sqlvar->sqldata[decimalNumber->size], ' ',
1397 (memSizeType) sqlvar->sqllen - decimalNumber->size);
1398 } /* if */
1399 FREE_STRI(decimalNumber, decimalNumber->size);
1400 } /* if */
1401 break;
1402 case SQL_VARYING:
1403 decimalNumber = bigStr(value);
1404 if (decimalNumber == NULL) {
1405 err_info = MEMORY_ERROR;
1406 } else {
1407 /* setupParameters() has already checked that sqllen > 0 holds */
1408 if (unlikely((memSizeType) sqlvar->sqllen < decimalNumber->size)) {
1409 logError(printf("sqlBindBigInt: Parameter " FMT_D ": "
1410 "Decimal representation of %s longer than allowed (%hd).\n",
1411 pos, striAsUnquotedCStri(decimalNumber),
1412 sqlvar->sqllen););
1413 err_info = RANGE_ERROR;
1414 } else {
1415 *(int16Type *) sqlvar->sqldata =
1416 (int16Type) decimalNumber->size;
1417 memcpy_from_strelem((ustriType)
1418 &sqlvar->sqldata[sizeof(uint16Type)],
1419 decimalNumber->mem, decimalNumber->size);
1420 memset(&sqlvar->sqldata[sizeof(uint16Type) + decimalNumber->size],
1421 '\0', (memSizeType) sqlvar->sqllen - decimalNumber->size);
1422 } /* if */
1423 FREE_STRI(decimalNumber, decimalNumber->size);
1424 } /* if */
1425 break;
1426 default:
1427 logError(printf("sqlBindBigInt: Parameter " FMT_D " has the unknown type %s.\n",
1428 pos, nameOfSqlType(sqlvar->sqltype & ~1)););
1429 err_info = RANGE_ERROR;
1430 break;
1431 } /* switch */
1432 if (likely(err_info == OKAY_NO_ERROR)) {
1433 if (sqlvar->sqltype & 1) {
1434 *sqlvar->sqlind = 0;
1435 } /* if */
1436 preparedStmt->fetchOkay = FALSE;
1437 preparedStmt->param_array[pos - 1].bound = TRUE;
1438 } /* if */
1439 } /* if */
1440 if (unlikely(err_info != OKAY_NO_ERROR)) {
1441 raise_error(err_info);
1442 } /* if */
1443 } /* if */
1444 } /* sqlBindBigInt */
1445
1446
1447
sqlBindBigRat(sqlStmtType sqlStatement,intType pos,const const_bigIntType numerator,const const_bigIntType denominator)1448 static void sqlBindBigRat (sqlStmtType sqlStatement, intType pos,
1449 const const_bigIntType numerator, const const_bigIntType denominator)
1450
1451 {
1452 preparedStmtType preparedStmt;
1453 ISC_STATUS status_vector[20];
1454 XSQLVAR *sqlvar;
1455 errInfoType err_info = OKAY_NO_ERROR;
1456
1457 /* sqlBindBigRat */
1458 logFunction(printf("sqlBindBigRat(" FMT_U_MEM ", " FMT_D ", %s, %s)\n",
1459 (memSizeType) sqlStatement, pos,
1460 bigHexCStri(numerator), bigHexCStri(denominator)););
1461 preparedStmt = (preparedStmtType) sqlStatement;
1462 if (unlikely(pos < 1 || pos > preparedStmt->in_sqlda->sqld)) {
1463 logError(printf("sqlBindBigRat: pos: " FMT_D ", max pos: %hd.\n",
1464 pos, preparedStmt->in_sqlda->sqld););
1465 raise_error(RANGE_ERROR);
1466 } else {
1467 if (preparedStmt->executeSuccessful) {
1468 if (unlikely((isc_dsql_free_statement(status_vector,
1469 &preparedStmt->ppStmt,
1470 DSQL_close),
1471 status_vector[0] == 1 && status_vector[1] != 0))) {
1472 setDbErrorMsg("sqlBindBigRat", "isc_dsql_free_statement",
1473 status_vector);
1474 logError(printf("sqlBindBigRat: isc_dsql_free_statement error:\n%s\n",
1475 dbError.message););
1476 err_info = DATABASE_ERROR;
1477 } else {
1478 preparedStmt->executeSuccessful = FALSE;
1479 } /* if */
1480 } /* if */
1481 if (likely(err_info == OKAY_NO_ERROR)) {
1482 sqlvar = &preparedStmt->in_sqlda->sqlvar[pos - 1];
1483 /* printf("paramType: %s\n", nameOfSqlType(sqlvar->sqltype & ~1)); */
1484 switch (sqlvar->sqltype & ~1) {
1485 case SQL_INT64:
1486 /* printf("sqlBindBigRat: scale: %hd\n", sqlvar->sqlscale); */
1487 *(int64Type *) sqlvar->sqldata = bigRatToScaledInt64(numerator, denominator,
1488 -sqlvar->sqlscale, &err_info);
1489 break;
1490 case SQL_FLOAT:
1491 *(float *) sqlvar->sqldata =
1492 (float) bigRatToDouble(numerator, denominator);;
1493 break;
1494 case SQL_DOUBLE:
1495 *(double *) sqlvar->sqldata =
1496 bigRatToDouble(numerator, denominator);
1497 break;
1498 default:
1499 logError(printf("sqlBindBigRat: Parameter " FMT_D " has the unknown type %s.\n",
1500 pos, nameOfSqlType(sqlvar->sqltype & ~1)););
1501 err_info = RANGE_ERROR;
1502 break;
1503 } /* switch */
1504 if (likely(err_info == OKAY_NO_ERROR)) {
1505 if (sqlvar->sqltype & 1) {
1506 *sqlvar->sqlind = 0;
1507 } /* if */
1508 preparedStmt->fetchOkay = FALSE;
1509 preparedStmt->param_array[pos - 1].bound = TRUE;
1510 } /* if */
1511 } /* if */
1512 if (unlikely(err_info != OKAY_NO_ERROR)) {
1513 raise_error(err_info);
1514 } /* if */
1515 } /* if */
1516 } /* sqlBindBigRat */
1517
1518
1519
sqlBindBool(sqlStmtType sqlStatement,intType pos,boolType value)1520 static void sqlBindBool (sqlStmtType sqlStatement, intType pos, boolType value)
1521
1522 {
1523 preparedStmtType preparedStmt;
1524 ISC_STATUS status_vector[20];
1525 XSQLVAR *sqlvar;
1526 errInfoType err_info = OKAY_NO_ERROR;
1527
1528 /* sqlBindBool */
1529 logFunction(printf("sqlBindBool(" FMT_U_MEM ", " FMT_D ", %s)\n",
1530 (memSizeType) sqlStatement, pos, value ? "TRUE" : "FALSE"););
1531 preparedStmt = (preparedStmtType) sqlStatement;
1532 if (unlikely(pos < 1 || pos > preparedStmt->in_sqlda->sqld)) {
1533 logError(printf("sqlBindBool: pos: " FMT_D ", max pos: %hd.\n",
1534 pos, preparedStmt->in_sqlda->sqld););
1535 raise_error(RANGE_ERROR);
1536 } else {
1537 if (preparedStmt->executeSuccessful) {
1538 if (unlikely((isc_dsql_free_statement(status_vector,
1539 &preparedStmt->ppStmt,
1540 DSQL_close),
1541 status_vector[0] == 1 && status_vector[1] != 0))) {
1542 setDbErrorMsg("sqlBindBool", "isc_dsql_free_statement",
1543 status_vector);
1544 logError(printf("sqlBindBool: isc_dsql_free_statement error:\n%s\n",
1545 dbError.message););
1546 err_info = DATABASE_ERROR;
1547 } else {
1548 preparedStmt->executeSuccessful = FALSE;
1549 } /* if */
1550 } /* if */
1551 if (likely(err_info == OKAY_NO_ERROR)) {
1552 sqlvar = &preparedStmt->in_sqlda->sqlvar[pos - 1];
1553 /* printf("paramType: %s\n", nameOfSqlType(sqlvar->sqltype & ~1)); */
1554 switch (sqlvar->sqltype & ~1) {
1555 case SQL_BOOLEAN:
1556 case SQL_SHORT:
1557 *(int16Type *) sqlvar->sqldata = (int16Type) value;
1558 break;
1559 case SQL_LONG:
1560 *(int32Type *) sqlvar->sqldata = (int32Type) value;
1561 break;
1562 case SQL_INT64:
1563 /* printf("sqlBindBool: scale: %hd\n", sqlvar->sqlscale); */
1564 if (unlikely(sqlvar->sqlscale != 0)) {
1565 logError(printf("sqlBindBool: Parameter " FMT_D ": "
1566 "The scale of a boolean field must be 0.\n", pos););
1567 err_info = RANGE_ERROR;
1568 } else {
1569 *(int64Type *) sqlvar->sqldata = (int64Type) value;
1570 } /* if */
1571 break;
1572 case SQL_TEXT:
1573 if (unlikely(sqlvar->sqllen != 1)) {
1574 logError(printf("sqlBindBool: Parameter " FMT_D ": "
1575 "The size of a boolean field must be 1.\n", pos););
1576 err_info = RANGE_ERROR;
1577 } else {
1578 ((char *) sqlvar->sqldata)[0] = (char) ('0' + value);
1579 } /* if */
1580 break;
1581 default:
1582 logError(printf("sqlBindBool: Parameter " FMT_D " has the unknown type %s.\n",
1583 pos, nameOfSqlType(sqlvar->sqltype & ~1)););
1584 err_info = RANGE_ERROR;
1585 break;
1586 } /* switch */
1587 if (likely(err_info == OKAY_NO_ERROR)) {
1588 if (sqlvar->sqltype & 1) {
1589 *sqlvar->sqlind = 0;
1590 } /* if */
1591 preparedStmt->fetchOkay = FALSE;
1592 preparedStmt->param_array[pos - 1].bound = TRUE;
1593 } /* if */
1594 } /* if */
1595 if (unlikely(err_info != OKAY_NO_ERROR)) {
1596 raise_error(err_info);
1597 } /* if */
1598 } /* if */
1599 } /* sqlBindBool */
1600
1601
1602
sqlBindBStri(sqlStmtType sqlStatement,intType pos,const const_bstriType bstri)1603 static void sqlBindBStri (sqlStmtType sqlStatement, intType pos,
1604 const const_bstriType bstri)
1605
1606 {
1607 preparedStmtType preparedStmt;
1608 ISC_STATUS status_vector[20];
1609 XSQLVAR *sqlvar;
1610 errInfoType err_info = OKAY_NO_ERROR;
1611
1612 /* sqlBindBStri */
1613 logFunction(printf("sqlBindBStri(" FMT_U_MEM ", " FMT_D ", \"%s\")\n",
1614 (memSizeType) sqlStatement, pos, bstriAsUnquotedCStri(bstri)););
1615 preparedStmt = (preparedStmtType) sqlStatement;
1616 if (unlikely(pos < 1 || pos > preparedStmt->in_sqlda->sqld)) {
1617 logError(printf("sqlBindBStri: pos: " FMT_D ", max pos: %hd.\n",
1618 pos, preparedStmt->in_sqlda->sqld););
1619 raise_error(RANGE_ERROR);
1620 } else {
1621 if (preparedStmt->executeSuccessful) {
1622 if (unlikely((isc_dsql_free_statement(status_vector,
1623 &preparedStmt->ppStmt,
1624 DSQL_close),
1625 status_vector[0] == 1 && status_vector[1] != 0))) {
1626 setDbErrorMsg("sqlBindBStri", "isc_dsql_free_statement",
1627 status_vector);
1628 logError(printf("sqlBindBStri: isc_dsql_free_statement error:\n%s\n",
1629 dbError.message););
1630 err_info = DATABASE_ERROR;
1631 } else {
1632 preparedStmt->executeSuccessful = FALSE;
1633 } /* if */
1634 } /* if */
1635 if (likely(err_info == OKAY_NO_ERROR)) {
1636 sqlvar = &preparedStmt->in_sqlda->sqlvar[pos - 1];
1637 /* printf("paramType: %s\n", nameOfSqlType(sqlvar->sqltype & ~1)); */
1638 switch (sqlvar->sqltype & ~1) {
1639 case SQL_BLOB:
1640 err_info = putBlob(preparedStmt, bstri, sqlvar);
1641 break;
1642 case SQL_TEXT:
1643 /* setupParameters() has already checked that sqllen > 0 holds */
1644 if (unlikely((memSizeType) sqlvar->sqllen < bstri->size)) {
1645 logError(printf("sqlBindBStri(*, " FMT_D ", \"%s\"): "
1646 "Bstring longer than allowed (%hd).\n",
1647 pos, bstriAsUnquotedCStri(bstri),
1648 sqlvar->sqllen););
1649 err_info = RANGE_ERROR;
1650 } else {
1651 memcpy(sqlvar->sqldata, bstri->mem, bstri->size);
1652 memset(&sqlvar->sqldata[bstri->size], ' ',
1653 (memSizeType) sqlvar->sqllen - bstri->size);
1654 } /* if */
1655 break;
1656 case SQL_VARYING:
1657 /* setupParameters() has already checked that sqllen > 0 holds */
1658 if (unlikely((memSizeType) sqlvar->sqllen < bstri->size)) {
1659 logError(printf("sqlBindBStri(*, " FMT_D ", \"%s\"): "
1660 "Bstring longer than allowed (%hd).\n",
1661 pos, bstriAsUnquotedCStri(bstri),
1662 sqlvar->sqllen););
1663 err_info = RANGE_ERROR;
1664 } else {
1665 *(int16Type *) sqlvar->sqldata = (int16Type) bstri->size;
1666 memcpy(&sqlvar->sqldata[sizeof(uint16Type)],
1667 bstri->mem, bstri->size);
1668 memset(&sqlvar->sqldata[sizeof(uint16Type) + bstri->size],
1669 '\0', (memSizeType) sqlvar->sqllen - bstri->size);
1670 } /* if */
1671 break;
1672 default:
1673 logError(printf("sqlBindBStri: Parameter " FMT_D " has the unknown type %s.\n",
1674 pos, nameOfSqlType(sqlvar->sqltype & ~1)););
1675 err_info = RANGE_ERROR;
1676 break;
1677 } /* switch */
1678 if (likely(err_info == OKAY_NO_ERROR)) {
1679 if (sqlvar->sqltype & 1) {
1680 *sqlvar->sqlind = 0;
1681 } /* if */
1682 preparedStmt->fetchOkay = FALSE;
1683 preparedStmt->param_array[pos - 1].bound = TRUE;
1684 } /* if */
1685 } /* if */
1686 if (unlikely(err_info != OKAY_NO_ERROR)) {
1687 raise_error(err_info);
1688 } /* if */
1689 } /* if */
1690 } /* sqlBindBStri */
1691
1692
1693
sqlBindDuration(sqlStmtType sqlStatement,intType pos,intType year,intType month,intType day,intType hour,intType minute,intType second,intType micro_second)1694 static void sqlBindDuration (sqlStmtType sqlStatement, intType pos,
1695 intType year, intType month, intType day, intType hour,
1696 intType minute, intType second, intType micro_second)
1697
1698 {
1699 preparedStmtType preparedStmt;
1700 ISC_STATUS status_vector[20];
1701 XSQLVAR *sqlvar;
1702 struct tm tm_time;
1703 errInfoType err_info = OKAY_NO_ERROR;
1704
1705 /* sqlBindDuration */
1706 logFunction(printf("sqlBindDuration(" FMT_U_MEM ", " FMT_D ", P"
1707 FMT_D "Y" FMT_D "M" FMT_D "DT"
1708 FMT_D "H" FMT_D "M%s" FMT_U "." F_U(06) "S)\n",
1709 (memSizeType) sqlStatement, pos,
1710 year, month, day, hour, minute,
1711 second < 0 || micro_second < 0 ? "-" : "",
1712 intAbs(second), intAbs(micro_second)););
1713 preparedStmt = (preparedStmtType) sqlStatement;
1714 if (unlikely(pos < 1 || pos > preparedStmt->in_sqlda->sqld)) {
1715 logError(printf("sqlBindDuration: pos: " FMT_D ", max pos: %hd.\n",
1716 pos, preparedStmt->in_sqlda->sqld););
1717 raise_error(RANGE_ERROR);
1718 } else if (unlikely(year < -INT_MAX || year > INT_MAX || month < -12 || month > 12 ||
1719 day < -31 || day > 31 || hour <= -24 || hour >= 24 ||
1720 minute <= -60 || minute >= 60 || second <= -60 || second >= 60 ||
1721 micro_second <= -1000000 || micro_second >= 1000000)) {
1722 logError(printf("sqlBindDuration: Duration not in allowed range.\n"););
1723 raise_error(RANGE_ERROR);
1724 } else {
1725 if (preparedStmt->executeSuccessful) {
1726 if (unlikely((isc_dsql_free_statement(status_vector,
1727 &preparedStmt->ppStmt,
1728 DSQL_close),
1729 status_vector[0] == 1 && status_vector[1] != 0))) {
1730 setDbErrorMsg("sqlBindDuration", "isc_dsql_free_statement",
1731 status_vector);
1732 logError(printf("sqlBindDuration: isc_dsql_free_statement error:\n%s\n",
1733 dbError.message););
1734 err_info = DATABASE_ERROR;
1735 } else {
1736 preparedStmt->executeSuccessful = FALSE;
1737 } /* if */
1738 } /* if */
1739 if (likely(err_info == OKAY_NO_ERROR)) {
1740 sqlvar = &preparedStmt->in_sqlda->sqlvar[pos - 1];
1741 /* printf("paramType: %s\n", nameOfSqlType(sqlvar->sqltype & ~1)); */
1742 switch (sqlvar->sqltype & ~1) {
1743 case SQL_TIMESTAMP:
1744 tm_time.tm_year = (int) year;
1745 tm_time.tm_mon = (int) month;
1746 tm_time.tm_mday = (int) day;
1747 tm_time.tm_hour = (int) hour;
1748 tm_time.tm_min = (int) minute;
1749 tm_time.tm_sec = (int) second;
1750 isc_encode_timestamp(&tm_time, (ISC_TIMESTAMP *) sqlvar->sqldata);
1751 break;
1752 case SQL_TYPE_TIME:
1753 tm_time.tm_year = (int) year;
1754 tm_time.tm_mon = (int) month;
1755 tm_time.tm_mday = (int) day;
1756 tm_time.tm_hour = (int) hour;
1757 tm_time.tm_min = (int) minute;
1758 tm_time.tm_sec = (int) second;
1759 isc_encode_sql_time(&tm_time, (ISC_TIME *) sqlvar->sqldata);
1760 break;
1761 case SQL_TYPE_DATE:
1762 tm_time.tm_year = (int) year;
1763 tm_time.tm_mon = (int) month;
1764 tm_time.tm_mday = (int) day;
1765 tm_time.tm_hour = (int) hour;
1766 tm_time.tm_min = (int) minute;
1767 tm_time.tm_sec = (int) second;
1768 isc_encode_sql_date(&tm_time, (ISC_DATE *) sqlvar->sqldata);
1769 break;
1770 default:
1771 logError(printf("sqlBindDuration: Parameter " FMT_D " has the unknown type %s.\n",
1772 pos, nameOfSqlType(sqlvar->sqltype & ~1)););
1773 err_info = RANGE_ERROR;
1774 break;
1775 } /* switch */
1776 if (likely(err_info == OKAY_NO_ERROR)) {
1777 if (sqlvar->sqltype & 1) {
1778 *sqlvar->sqlind = 0;
1779 } /* if */
1780 preparedStmt->fetchOkay = FALSE;
1781 preparedStmt->param_array[pos - 1].bound = TRUE;
1782 } /* if */
1783 } /* if */
1784 if (unlikely(err_info != OKAY_NO_ERROR)) {
1785 raise_error(err_info);
1786 } /* if */
1787 } /* if */
1788 } /* sqlBindDuration */
1789
1790
1791
sqlBindFloat(sqlStmtType sqlStatement,intType pos,floatType value)1792 static void sqlBindFloat (sqlStmtType sqlStatement, intType pos, floatType value)
1793
1794 {
1795 preparedStmtType preparedStmt;
1796 ISC_STATUS status_vector[20];
1797 XSQLVAR *sqlvar;
1798 errInfoType err_info = OKAY_NO_ERROR;
1799
1800 /* sqlBindFloat */
1801 logFunction(printf("sqlBindFloat(" FMT_U_MEM ", " FMT_D ", " FMT_E ")\n",
1802 (memSizeType) sqlStatement, pos, value););
1803 preparedStmt = (preparedStmtType) sqlStatement;
1804 if (unlikely(pos < 1 || pos > preparedStmt->in_sqlda->sqld)) {
1805 logError(printf("sqlBindFloat: pos: " FMT_D ", max pos: %hd.\n",
1806 pos, preparedStmt->in_sqlda->sqld););
1807 raise_error(RANGE_ERROR);
1808 } else {
1809 if (preparedStmt->executeSuccessful) {
1810 if (unlikely((isc_dsql_free_statement(status_vector,
1811 &preparedStmt->ppStmt,
1812 DSQL_close),
1813 status_vector[0] == 1 && status_vector[1] != 0))) {
1814 setDbErrorMsg("sqlBindFloat", "isc_dsql_free_statement",
1815 status_vector);
1816 logError(printf("sqlBindFloat: isc_dsql_free_statement error:\n%s\n",
1817 dbError.message););
1818 err_info = DATABASE_ERROR;
1819 } else {
1820 preparedStmt->executeSuccessful = FALSE;
1821 } /* if */
1822 } /* if */
1823 if (likely(err_info == OKAY_NO_ERROR)) {
1824 sqlvar = &preparedStmt->in_sqlda->sqlvar[pos - 1];
1825 /* printf("paramType: %s\n", nameOfSqlType(sqlvar->sqltype & ~1)); */
1826 switch (sqlvar->sqltype & ~1) {
1827 case SQL_FLOAT:
1828 *(float *) sqlvar->sqldata = (float) value;
1829 break;
1830 case SQL_DOUBLE:
1831 *(double *) sqlvar->sqldata = (double) value;
1832 break;
1833 default:
1834 logError(printf("sqlBindFloat: Parameter " FMT_D " has the unknown type %s.\n",
1835 pos, nameOfSqlType(sqlvar->sqltype & ~1)););
1836 err_info = RANGE_ERROR;
1837 break;
1838 } /* switch */
1839 if (likely(err_info == OKAY_NO_ERROR)) {
1840 if (sqlvar->sqltype & 1) {
1841 *sqlvar->sqlind = 0;
1842 } /* if */
1843 preparedStmt->fetchOkay = FALSE;
1844 preparedStmt->param_array[pos - 1].bound = TRUE;
1845 } /* if */
1846 } /* if */
1847 if (unlikely(err_info != OKAY_NO_ERROR)) {
1848 raise_error(err_info);
1849 } /* if */
1850 } /* if */
1851 } /* sqlBindFloat */
1852
1853
1854
sqlBindInt(sqlStmtType sqlStatement,intType pos,intType value)1855 static void sqlBindInt (sqlStmtType sqlStatement, intType pos, intType value)
1856
1857 {
1858 preparedStmtType preparedStmt;
1859 ISC_STATUS status_vector[20];
1860 XSQLVAR *sqlvar;
1861 char decimalInt[INTTYPE_DECIMAL_SIZE + NULL_TERMINATION_LEN];
1862 int decimalLength;
1863 errInfoType err_info = OKAY_NO_ERROR;
1864
1865 /* sqlBindInt */
1866 logFunction(printf("sqlBindInt(" FMT_U_MEM ", " FMT_D ", " FMT_D ")\n",
1867 (memSizeType) sqlStatement, pos, value););
1868 preparedStmt = (preparedStmtType) sqlStatement;
1869 if (unlikely(pos < 1 || pos > preparedStmt->in_sqlda->sqld)) {
1870 logError(printf("sqlBindInt: pos: " FMT_D ", max pos: %hd.\n",
1871 pos, preparedStmt->in_sqlda->sqld););
1872 raise_error(RANGE_ERROR);
1873 } else {
1874 if (preparedStmt->executeSuccessful) {
1875 if (unlikely((isc_dsql_free_statement(status_vector,
1876 &preparedStmt->ppStmt,
1877 DSQL_close),
1878 status_vector[0] == 1 && status_vector[1] != 0))) {
1879 setDbErrorMsg("sqlBindInt", "isc_dsql_free_statement",
1880 status_vector);
1881 logError(printf("sqlBindInt: isc_dsql_free_statement error:\n%s\n",
1882 dbError.message););
1883 err_info = DATABASE_ERROR;
1884 } else {
1885 preparedStmt->executeSuccessful = FALSE;
1886 } /* if */
1887 } /* if */
1888 if (likely(err_info == OKAY_NO_ERROR)) {
1889 sqlvar = &preparedStmt->in_sqlda->sqlvar[pos - 1];
1890 /* printf("paramType: %s\n", nameOfSqlType(sqlvar->sqltype & ~1)); */
1891 switch (sqlvar->sqltype & ~1) {
1892 case SQL_SHORT:
1893 if (unlikely(value < INT16TYPE_MIN || value > INT16TYPE_MAX)) {
1894 logError(printf("sqlBindInt: Parameter " FMT_D ": "
1895 FMT_D " does not fit into a 16-bit integer.\n",
1896 pos, value));
1897 err_info = RANGE_ERROR;
1898 } else {
1899 *(int16Type *) sqlvar->sqldata = (int16Type) value;
1900 } /* if */
1901 break;
1902 case SQL_LONG:
1903 if (unlikely(value < INT32TYPE_MIN || value > INT32TYPE_MAX)) {
1904 logError(printf("sqlBindInt: Parameter " FMT_D ": "
1905 FMT_D " does not fit into a 32-bit integer.\n",
1906 pos, value));
1907 err_info = RANGE_ERROR;
1908 } else {
1909 *(int32Type *) sqlvar->sqldata = (int32Type) value;
1910 } /* if */
1911 break;
1912 case SQL_INT64:
1913 /* printf("sqlBindInt: scale: %hd\n", sqlvar->sqlscale); */
1914 if (sqlvar->sqlscale == 0) {
1915 *(int64Type *) sqlvar->sqldata = value;
1916 } else {
1917 *(int64Type *) sqlvar->sqldata = intToScaledInt64(value,
1918 -sqlvar->sqlscale, &err_info);
1919 } /* if */
1920 break;
1921 case SQL_FLOAT:
1922 *(float *) sqlvar->sqldata = (float) value;
1923 break;
1924 case SQL_DOUBLE:
1925 *(double *) sqlvar->sqldata = (double) value;
1926 break;
1927 case SQL_TEXT:
1928 decimalLength = sprintf(decimalInt, FMT_D, value);
1929 if (unlikely(sqlvar->sqllen < decimalLength)) {
1930 logError(printf("sqlBindInt: Parameter " FMT_D ": "
1931 "Decimal representation of " FMT_D
1932 " longer than allowed (%hd).\n",
1933 pos, value, sqlvar->sqllen););
1934 err_info = RANGE_ERROR;
1935 } else {
1936 memcpy(sqlvar->sqldata, decimalInt, (memSizeType) decimalLength);
1937 memset(&sqlvar->sqldata[decimalLength], ' ',
1938 (memSizeType) sqlvar->sqllen - (memSizeType) decimalLength);
1939 } /* if */
1940 break;
1941 case SQL_VARYING:
1942 decimalLength = sprintf(decimalInt, FMT_D, value);
1943 if (unlikely(sqlvar->sqllen < decimalLength)) {
1944 logError(printf("sqlBindInt: Parameter " FMT_D ": "
1945 "Decimal representation of " FMT_D
1946 " longer than allowed (%hd).\n",
1947 pos, value, sqlvar->sqllen););
1948 err_info = RANGE_ERROR;
1949 } else {
1950 *(int16Type *) sqlvar->sqldata = (int16Type) decimalLength;
1951 memcpy(&sqlvar->sqldata[sizeof(uint16Type)], decimalInt,
1952 (memSizeType) decimalLength);
1953 memset(&sqlvar->sqldata[sizeof(uint16Type) + (memSizeType) decimalLength],
1954 '\0', (memSizeType) sqlvar->sqllen -
1955 (memSizeType) decimalLength);
1956 } /* if */
1957 break;
1958 default:
1959 logError(printf("sqlBindInt: Parameter " FMT_D " has the unknown type %s.\n",
1960 pos, nameOfSqlType(sqlvar->sqltype & ~1)););
1961 err_info = RANGE_ERROR;
1962 break;
1963 } /* switch */
1964 if (likely(err_info == OKAY_NO_ERROR)) {
1965 if (sqlvar->sqltype & 1) {
1966 *sqlvar->sqlind = 0;
1967 } /* if */
1968 preparedStmt->fetchOkay = FALSE;
1969 preparedStmt->param_array[pos - 1].bound = TRUE;
1970 } /* if */
1971 } /* if */
1972 if (unlikely(err_info != OKAY_NO_ERROR)) {
1973 raise_error(err_info);
1974 } /* if */
1975 } /* if */
1976 } /* sqlBindInt */
1977
1978
1979
sqlBindNull(sqlStmtType sqlStatement,intType pos)1980 static void sqlBindNull (sqlStmtType sqlStatement, intType pos)
1981
1982 {
1983 preparedStmtType preparedStmt;
1984 ISC_STATUS status_vector[20];
1985 XSQLVAR *sqlvar;
1986 errInfoType err_info = OKAY_NO_ERROR;
1987
1988 /* sqlBindNull */
1989 logFunction(printf("sqlBindNull(" FMT_U_MEM ", " FMT_D ")\n",
1990 (memSizeType) sqlStatement, pos););
1991 preparedStmt = (preparedStmtType) sqlStatement;
1992 if (unlikely(pos < 1 || pos > preparedStmt->in_sqlda->sqld)) {
1993 logError(printf("sqlBindNull: pos: " FMT_D ", max pos: %hd.\n",
1994 pos, preparedStmt->in_sqlda->sqld););
1995 raise_error(RANGE_ERROR);
1996 } else {
1997 if (preparedStmt->executeSuccessful) {
1998 if (unlikely((isc_dsql_free_statement(status_vector,
1999 &preparedStmt->ppStmt,
2000 DSQL_close),
2001 status_vector[0] == 1 && status_vector[1] != 0))) {
2002 setDbErrorMsg("sqlBindNull", "isc_dsql_free_statement",
2003 status_vector);
2004 logError(printf("sqlBindNull: isc_dsql_free_statement error:\n%s\n",
2005 dbError.message););
2006 err_info = DATABASE_ERROR;
2007 } else {
2008 preparedStmt->executeSuccessful = FALSE;
2009 } /* if */
2010 } /* if */
2011 if (likely(err_info == OKAY_NO_ERROR)) {
2012 sqlvar = &preparedStmt->in_sqlda->sqlvar[pos - 1];
2013 /* printf("paramType: %s\n", nameOfSqlType(sqlvar->sqltype & ~1)); */
2014 if (sqlvar->sqltype & 1) {
2015 *sqlvar->sqlind = -1;
2016 } /* if */
2017 preparedStmt->fetchOkay = FALSE;
2018 preparedStmt->param_array[pos - 1].bound = TRUE;
2019 } /* if */
2020 } /* if */
2021 } /* sqlBindNull */
2022
2023
2024
sqlBindStri(sqlStmtType sqlStatement,intType pos,const const_striType stri)2025 static void sqlBindStri (sqlStmtType sqlStatement, intType pos,
2026 const const_striType stri)
2027
2028 {
2029 preparedStmtType preparedStmt;
2030 ISC_STATUS status_vector[20];
2031 XSQLVAR *sqlvar;
2032 cstriType stri8;
2033 memSizeType length;
2034 bstriType bstri;
2035 errInfoType err_info = OKAY_NO_ERROR;
2036
2037 /* sqlBindStri */
2038 logFunction(printf("sqlBindStri(" FMT_U_MEM ", " FMT_D ", \"%s\")\n",
2039 (memSizeType) sqlStatement, pos, striAsUnquotedCStri(stri)););
2040 preparedStmt = (preparedStmtType) sqlStatement;
2041 if (unlikely(pos < 1 || pos > preparedStmt->in_sqlda->sqld)) {
2042 logError(printf("sqlBindStri: pos: " FMT_D ", max pos: %hd.\n",
2043 pos, preparedStmt->in_sqlda->sqld););
2044 raise_error(RANGE_ERROR);
2045 } else {
2046 if (preparedStmt->executeSuccessful) {
2047 if (unlikely((isc_dsql_free_statement(status_vector,
2048 &preparedStmt->ppStmt,
2049 DSQL_close),
2050 status_vector[0] == 1 && status_vector[1] != 0))) {
2051 setDbErrorMsg("sqlBindStri", "isc_dsql_free_statement",
2052 status_vector);
2053 logError(printf("sqlBindStri: isc_dsql_free_statement error:\n%s\n",
2054 dbError.message););
2055 err_info = DATABASE_ERROR;
2056 } else {
2057 preparedStmt->executeSuccessful = FALSE;
2058 } /* if */
2059 } /* if */
2060 if (likely(err_info == OKAY_NO_ERROR)) {
2061 sqlvar = &preparedStmt->in_sqlda->sqlvar[pos - 1];
2062 /* printf("paramType: %s\n", nameOfSqlType(sqlvar->sqltype & ~1)); */
2063 switch (sqlvar->sqltype & ~1) {
2064 case SQL_TEXT:
2065 stri8 = stri_to_cstri8_buf(stri, &length);
2066 if (unlikely(stri8 == NULL)) {
2067 err_info = MEMORY_ERROR;
2068 } else {
2069 /* setupParameters() has already checked that sqllen > 0 holds */
2070 if (unlikely((memSizeType) sqlvar->sqllen < length)) {
2071 logError(printf("sqlBindStri(*, " FMT_D ", \"%s\"): "
2072 "UTF-8 length (" FMT_U_MEM ") longer than allowed (%hd).\n",
2073 pos, striAsUnquotedCStri(stri), length, sqlvar->sqllen););
2074 err_info = RANGE_ERROR;
2075 } else {
2076 memcpy(sqlvar->sqldata, stri8, length);
2077 memset(&sqlvar->sqldata[length], ' ',
2078 (memSizeType) sqlvar->sqllen - length);
2079 } /* if */
2080 free(stri8);
2081 } /* if */
2082 break;
2083 case SQL_VARYING:
2084 stri8 = stri_to_cstri8_buf(stri, &length);
2085 if (unlikely(stri8 == NULL)) {
2086 err_info = MEMORY_ERROR;
2087 } else {
2088 /* setupParameters() has already checked that sqllen > 0 holds */
2089 if (unlikely((memSizeType) sqlvar->sqllen < length)) {
2090 logError(printf("sqlBindStri(*, " FMT_D ", \"%s\"): "
2091 "UTF-8 length (" FMT_U_MEM ") longer than allowed (%hd).\n",
2092 pos, striAsUnquotedCStri(stri), length, sqlvar->sqllen););
2093 err_info = RANGE_ERROR;
2094 } else {
2095 *(int16Type *) sqlvar->sqldata = (int16Type) length;
2096 memcpy(&sqlvar->sqldata[sizeof(uint16Type)], stri8, length);
2097 memset(&sqlvar->sqldata[sizeof(uint16Type) + length], '\0',
2098 (memSizeType) sqlvar->sqllen - length);
2099 } /* if */
2100 free(stri8);
2101 } /* if */
2102 break;
2103 case SQL_BLOB:
2104 if (sqlvar->sqlsubtype == 1) {
2105 /* BLOB SUB_TYPE 1 means essentially: textual Blob. */
2106 bstri = stri_to_bstri8(stri);
2107 if (unlikely(bstri == NULL)) {
2108 err_info = MEMORY_ERROR;
2109 } else {
2110 err_info = putBlob(preparedStmt, bstri, sqlvar);
2111 FREE_BSTRI(bstri, bstri->size);
2112 } /* if */
2113 } else {
2114 /* BLOB SUB_TYPE 0 is a binary Blob. */
2115 logError(printf("sqlBindStri: Parameter " FMT_D " is a BLOB column.\n", pos););
2116 err_info = RANGE_ERROR;
2117 } /* if */
2118 break;
2119 default:
2120 logError(printf("sqlBindStri: Parameter " FMT_D " has the unknown type %s.\n",
2121 pos, nameOfSqlType(sqlvar->sqltype & ~1)););
2122 err_info = RANGE_ERROR;
2123 break;
2124 } /* switch */
2125 if (likely(err_info == OKAY_NO_ERROR)) {
2126 if (sqlvar->sqltype & 1) {
2127 *sqlvar->sqlind = 0;
2128 } /* if */
2129 preparedStmt->fetchOkay = FALSE;
2130 preparedStmt->param_array[pos - 1].bound = TRUE;
2131 } /* if */
2132 } /* if */
2133 if (unlikely(err_info != OKAY_NO_ERROR)) {
2134 raise_error(err_info);
2135 } /* if */
2136 } /* if */
2137 } /* sqlBindStri */
2138
2139
2140
sqlBindTime(sqlStmtType sqlStatement,intType pos,intType year,intType month,intType day,intType hour,intType minute,intType second,intType micro_second,intType time_zone)2141 static void sqlBindTime (sqlStmtType sqlStatement, intType pos,
2142 intType year, intType month, intType day, intType hour,
2143 intType minute, intType second, intType micro_second,
2144 intType time_zone)
2145
2146 {
2147 preparedStmtType preparedStmt;
2148 ISC_STATUS status_vector[20];
2149 XSQLVAR *sqlvar;
2150 struct tm tm_time;
2151 errInfoType err_info = OKAY_NO_ERROR;
2152
2153 /* sqlBindTime */
2154 logFunction(printf("sqlBindTime(" FMT_U_MEM ", " FMT_D ", "
2155 F_D(04) "-" F_D(02) "-" F_D(02) " "
2156 F_D(02) ":" F_D(02) ":" F_D(02) "." F_D(06) ", "
2157 FMT_D ")\n",
2158 (memSizeType) sqlStatement, pos,
2159 year, month, day,
2160 hour, minute, second, micro_second,
2161 time_zone););
2162 preparedStmt = (preparedStmtType) sqlStatement;
2163 if (unlikely(pos < 1 || pos > preparedStmt->in_sqlda->sqld)) {
2164 logError(printf("sqlBindTime: pos: " FMT_D ", max pos: %hd.\n",
2165 pos, preparedStmt->in_sqlda->sqld););
2166 raise_error(RANGE_ERROR);
2167 } else if (unlikely(year < INT_MIN + 1900 || year > INT_MAX ||
2168 month < 1 || month > 12 || day < 1 || day > 31 ||
2169 hour < 0 || hour >= 24 || minute < 0 ||
2170 minute >= 60 || second < 0 || second >= 60 ||
2171 micro_second < 0 || micro_second >= 1000000)) {
2172 logError(printf("sqlBindTime: Time not in allowed range.\n"););
2173 raise_error(RANGE_ERROR);
2174 } else {
2175 if (preparedStmt->executeSuccessful) {
2176 if (unlikely((isc_dsql_free_statement(status_vector,
2177 &preparedStmt->ppStmt,
2178 DSQL_close),
2179 status_vector[0] == 1 && status_vector[1] != 0))) {
2180 setDbErrorMsg("sqlBindTime", "isc_dsql_free_statement",
2181 status_vector);
2182 logError(printf("sqlBindTime: isc_dsql_free_statement error:\n%s\n",
2183 dbError.message););
2184 err_info = DATABASE_ERROR;
2185 } else {
2186 preparedStmt->executeSuccessful = FALSE;
2187 } /* if */
2188 } /* if */
2189 if (likely(err_info == OKAY_NO_ERROR)) {
2190 sqlvar = &preparedStmt->in_sqlda->sqlvar[pos - 1];
2191 /* printf("paramType: %s\n", nameOfSqlType(sqlvar->sqltype & ~1)); */
2192 switch (sqlvar->sqltype & ~1) {
2193 case SQL_TIMESTAMP:
2194 tm_time.tm_year = (int) year - 1900;
2195 tm_time.tm_mon = (int) month - 1;
2196 tm_time.tm_mday = (int) day;
2197 tm_time.tm_hour = (int) hour;
2198 tm_time.tm_min = (int) minute;
2199 tm_time.tm_sec = (int) second;
2200 isc_encode_timestamp(&tm_time, (ISC_TIMESTAMP *) sqlvar->sqldata);
2201 ((ISC_TIMESTAMP *) sqlvar->sqldata)->timestamp_time += (ISC_TIME) micro_second / 100;
2202 break;
2203 case SQL_TYPE_TIME:
2204 tm_time.tm_year = (int) year - 1900;
2205 tm_time.tm_mon = (int) month - 1;
2206 tm_time.tm_mday = (int) day;
2207 tm_time.tm_hour = (int) hour;
2208 tm_time.tm_min = (int) minute;
2209 tm_time.tm_sec = (int) second;
2210 isc_encode_sql_time(&tm_time, (ISC_TIME *) sqlvar->sqldata);
2211 *(ISC_TIME *) sqlvar->sqldata += (ISC_TIME) micro_second / 100;
2212 break;
2213 case SQL_TYPE_DATE:
2214 tm_time.tm_year = (int) year - 1900;
2215 tm_time.tm_mon = (int) month - 1;
2216 tm_time.tm_mday = (int) day;
2217 tm_time.tm_hour = (int) hour;
2218 tm_time.tm_min = (int) minute;
2219 tm_time.tm_sec = (int) second;
2220 isc_encode_sql_date(&tm_time, (ISC_DATE *) sqlvar->sqldata);
2221 break;
2222 default:
2223 logError(printf("sqlBindTime: Parameter " FMT_D " has the unknown type %s.\n",
2224 pos, nameOfSqlType(sqlvar->sqltype & ~1)););
2225 err_info = RANGE_ERROR;
2226 break;
2227 } /* switch */
2228 if (likely(err_info == OKAY_NO_ERROR)) {
2229 if (sqlvar->sqltype & 1) {
2230 *sqlvar->sqlind = 0;
2231 } /* if */
2232 preparedStmt->fetchOkay = FALSE;
2233 preparedStmt->param_array[pos - 1].bound = TRUE;
2234 } /* if */
2235 } /* if */
2236 if (unlikely(err_info != OKAY_NO_ERROR)) {
2237 raise_error(err_info);
2238 } /* if */
2239 } /* if */
2240 } /* sqlBindTime */
2241
2242
2243
sqlClose(databaseType database)2244 static void sqlClose (databaseType database)
2245
2246 {
2247 dbType db;
2248 ISC_STATUS status_vector[20];
2249 errInfoType err_info = OKAY_NO_ERROR;
2250
2251 /* sqlClose */
2252 logFunction(printf("sqlClose(" FMT_U_MEM ")\n",
2253 (memSizeType) database););
2254 db = (dbType) database;
2255 if (db->connection != 0) {
2256 if (db->trans_handle != 0) {
2257 isc_commit_transaction(status_vector,
2258 &db->trans_handle);
2259 if (unlikely(status_vector[0] == 1 && status_vector[1] != 0)) {
2260 setDbErrorMsg("sqlClose", "isc_commit_transaction",
2261 status_vector);
2262 logError(printf("sqlClose: isc_commit_transaction error:\n%s\n",
2263 dbError.message););
2264 err_info = DATABASE_ERROR;
2265 } else {
2266 db->trans_handle = 0;
2267 } /* if */
2268 } /* if */
2269 if (likely(err_info == OKAY_NO_ERROR)) {
2270 isc_detach_database(status_vector,
2271 &db->connection);
2272 if (unlikely(status_vector[0] == 1 && status_vector[1] != 0)) {
2273 setDbErrorMsg("sqlClose", "isc_detach_database",
2274 status_vector);
2275 logError(printf("sqlClose: isc_detach_database error:\n%s\n",
2276 dbError.message););
2277 err_info = DATABASE_ERROR;
2278 } else {
2279 db->connection = 0;
2280 } /* if */
2281 } /* if */
2282 if (unlikely(err_info != OKAY_NO_ERROR)) {
2283 raise_error(err_info);
2284 } /* if */
2285 } /* if */
2286 logFunction(printf("sqlClose -->\n"););
2287 } /* sqlClose */
2288
2289
2290
sqlColumnBigInt(sqlStmtType sqlStatement,intType column)2291 static bigIntType sqlColumnBigInt (sqlStmtType sqlStatement, intType column)
2292
2293 {
2294 preparedStmtType preparedStmt;
2295 XSQLVAR *sqlvar;
2296 short *sqlind;
2297 bigIntType columnValue;
2298
2299 /* sqlColumnBigInt */
2300 logFunction(printf("sqlColumnBigInt(" FMT_U_MEM ", " FMT_D ")\n",
2301 (memSizeType) sqlStatement, column););
2302 preparedStmt = (preparedStmtType) sqlStatement;
2303 if (unlikely(!preparedStmt->fetchOkay || column < 1 ||
2304 column > preparedStmt->out_sqlda->sqld)) {
2305 logError(printf("sqlColumnBigInt: Fetch okay: %d, column: " FMT_D
2306 ", max column: %hd.\n",
2307 preparedStmt->fetchOkay, column,
2308 preparedStmt->out_sqlda->sqld););
2309 raise_error(RANGE_ERROR);
2310 columnValue = NULL;
2311 } else {
2312 sqlvar = &preparedStmt->out_sqlda->sqlvar[column - 1];
2313 sqlind = sqlvar->sqlind;
2314 if (sqlind != NULL && *sqlind == -1) {
2315 /* printf("Column is NULL -> Use default value: 0\n"); */
2316 columnValue = bigZero();
2317 } else if (unlikely(sqlind != NULL && *sqlind != 0)) {
2318 dbInconsistent("sqlColumnBigInt", "sqlind");
2319 logError(printf("sqlColumnBigInt: Column " FMT_D ": "
2320 "sqlind has the value %d.\n",
2321 column, *sqlind););
2322 raise_error(DATABASE_ERROR);
2323 columnValue = NULL;
2324 } else {
2325 /* printf("columnType: %s\n", nameOfSqlType(sqlvar->sqltype & ~1)); */
2326 switch (sqlvar->sqltype & ~1) {
2327 case SQL_SHORT:
2328 if (unlikely(sqlvar->sqlscale != 0)) {
2329 logError(printf("sqlColumnBigInt: Column " FMT_D ": "
2330 "The scale of an integer field must be 0.\n", column););
2331 raise_error(RANGE_ERROR);
2332 columnValue = NULL;
2333 } else {
2334 columnValue = bigFromInt32((int32Type) *(int16Type *) sqlvar->sqldata);
2335 } /* if */
2336 break;
2337 case SQL_LONG:
2338 if (unlikely(sqlvar->sqlscale != 0)) {
2339 logError(printf("sqlColumnBigInt: Column " FMT_D ": "
2340 "The scale of an integer field must be 0.\n", column););
2341 raise_error(RANGE_ERROR);
2342 columnValue = NULL;
2343 } else {
2344 columnValue = bigFromInt32(*(int32Type *) sqlvar->sqldata);
2345 } /* if */
2346 break;
2347 case SQL_INT64:
2348 if (unlikely(sqlvar->sqlscale != 0)) {
2349 logError(printf("sqlColumnBigInt: Column " FMT_D ": "
2350 "The scale of an integer field must be 0.\n", column););
2351 raise_error(RANGE_ERROR);
2352 columnValue = NULL;
2353 } else {
2354 columnValue = bigFromInt64(*(int64Type *) sqlvar->sqldata);
2355 } /* if */
2356 break;
2357 default:
2358 logError(printf("sqlColumnBigInt: Column " FMT_D " has the unknown type %s.\n",
2359 column, nameOfSqlType(sqlvar->sqltype & ~1)););
2360 raise_error(RANGE_ERROR);
2361 columnValue = NULL;
2362 break;
2363 } /* switch */
2364 } /* if */
2365 } /* if */
2366 logFunction(printf("sqlColumnBigInt --> %s\n", bigHexCStri(columnValue)););
2367 return columnValue;
2368 } /* sqlColumnBigInt */
2369
2370
2371
sqlColumnBigRat(sqlStmtType sqlStatement,intType column,bigIntType * numerator,bigIntType * denominator)2372 static void sqlColumnBigRat (sqlStmtType sqlStatement, intType column,
2373 bigIntType *numerator, bigIntType *denominator)
2374
2375 {
2376 preparedStmtType preparedStmt;
2377 XSQLVAR *sqlvar;
2378 short *sqlind;
2379 float floatValue;
2380 double doubleValue;
2381
2382 /* sqlColumnBigRat */
2383 logFunction(printf("sqlColumnBigRat(" FMT_U_MEM ", " FMT_D ", *, *)\n",
2384 (memSizeType) sqlStatement, column););
2385 preparedStmt = (preparedStmtType) sqlStatement;
2386 if (unlikely(!preparedStmt->fetchOkay || column < 1 ||
2387 column > preparedStmt->out_sqlda->sqld)) {
2388 logError(printf("sqlColumnBigRat: Fetch okay: %d, column: " FMT_D
2389 ", max column: %hd.\n",
2390 preparedStmt->fetchOkay, column,
2391 preparedStmt->out_sqlda->sqld););
2392 raise_error(RANGE_ERROR);
2393 } else {
2394 sqlvar = &preparedStmt->out_sqlda->sqlvar[column - 1];
2395 sqlind = sqlvar->sqlind;
2396 if (sqlind != NULL && *sqlind == -1) {
2397 /* printf("Column is NULL -> Use default value: 0\n"); */
2398 *numerator = bigZero();
2399 *denominator = bigFromInt32(1);
2400 } else if (unlikely(sqlind != NULL && *sqlind != 0)) {
2401 dbInconsistent("sqlColumnBigRat", "sqlind");
2402 logError(printf("sqlColumnBigRat: Column " FMT_D ": "
2403 "sqlind has the value %d.\n",
2404 column, *sqlind););
2405 raise_error(DATABASE_ERROR);
2406 } else {
2407 /* printf("columnType: %s\n", nameOfSqlType(sqlvar->sqltype & ~1)); */
2408 switch (sqlvar->sqltype & ~1) {
2409 case SQL_SHORT:
2410 *numerator = bigFromInt32((int32Type)
2411 *(int16Type *) sqlvar->sqldata);
2412 if (sqlvar->sqlscale == 0) {
2413 *denominator = bigFromInt32(1);
2414 } else {
2415 *denominator = bigIPowSignedDigit(10, -sqlvar->sqlscale);
2416 } /* if */
2417 break;
2418 case SQL_LONG:
2419 *numerator = bigFromInt32(*(int32Type *) sqlvar->sqldata);
2420 if (sqlvar->sqlscale == 0) {
2421 *denominator = bigFromInt32(1);
2422 } else {
2423 *denominator = bigIPowSignedDigit(10, -sqlvar->sqlscale);
2424 } /* if */
2425 break;
2426 case SQL_INT64:
2427 *numerator = bigFromInt64(*(int64Type *) sqlvar->sqldata);
2428 if (sqlvar->sqlscale == 0) {
2429 *denominator = bigFromInt32(1);
2430 } else {
2431 *denominator = bigIPowSignedDigit(10, -sqlvar->sqlscale);
2432 } /* if */
2433 break;
2434 case SQL_FLOAT:
2435 floatValue = *(float *) sqlvar->sqldata;
2436 /* printf("sqlColumnBigRat: float: %f\n", floatValue); */
2437 *numerator = roundDoubleToBigRat(floatValue, FALSE, denominator);
2438 break;
2439 case SQL_DOUBLE:
2440 doubleValue = *(double *) sqlvar->sqldata;
2441 /* printf("sqlColumnBigRat: double: %f\n", doubleValue); */
2442 *numerator = roundDoubleToBigRat(doubleValue, TRUE, denominator);
2443 break;
2444 default:
2445 logError(printf("sqlColumnBigRat: Column " FMT_D " has the unknown type %s.\n",
2446 column, nameOfSqlType(sqlvar->sqltype & ~1)););
2447 raise_error(RANGE_ERROR);
2448 break;
2449 } /* switch */
2450 } /* if */
2451 } /* if */
2452 logFunction(printf("sqlColumnBigRat(" FMT_U_MEM ", " FMT_D ", %s, %s) -->\n",
2453 (memSizeType) sqlStatement, column,
2454 bigHexCStri(*numerator), bigHexCStri(*denominator)););
2455 } /* sqlColumnBigRat */
2456
2457
2458
sqlColumnBool(sqlStmtType sqlStatement,intType column)2459 static boolType sqlColumnBool (sqlStmtType sqlStatement, intType column)
2460
2461 {
2462 preparedStmtType preparedStmt;
2463 XSQLVAR *sqlvar;
2464 short *sqlind;
2465 intType columnValue;
2466
2467 /* sqlColumnBool */
2468 logFunction(printf("sqlColumnBool(" FMT_U_MEM ", " FMT_D ")\n",
2469 (memSizeType) sqlStatement, column););
2470 preparedStmt = (preparedStmtType) sqlStatement;
2471 if (unlikely(!preparedStmt->fetchOkay || column < 1 ||
2472 column > preparedStmt->out_sqlda->sqld)) {
2473 logError(printf("sqlColumnBool: Fetch okay: %d, column: " FMT_D
2474 ", max column: %hd.\n",
2475 preparedStmt->fetchOkay, column,
2476 preparedStmt->out_sqlda->sqld););
2477 raise_error(RANGE_ERROR);
2478 columnValue = 0;
2479 } else {
2480 sqlvar = &preparedStmt->out_sqlda->sqlvar[column - 1];
2481 sqlind = sqlvar->sqlind;
2482 if (sqlind != NULL && *sqlind == -1) {
2483 /* printf("Column is NULL -> Use default value: FALSE\n"); */
2484 columnValue = 0;
2485 } else if (unlikely(sqlind != NULL && *sqlind != 0)) {
2486 dbInconsistent("sqlColumnBool", "sqlind");
2487 logError(printf("sqlColumnBool: Column " FMT_D ": "
2488 "sqlind has the value %d.\n",
2489 column, *sqlind););
2490 raise_error(DATABASE_ERROR);
2491 columnValue = 0;
2492 } else {
2493 /* printf("columnType: %s\n", nameOfSqlType(sqlvar->sqltype & ~1)); */
2494 switch (sqlvar->sqltype & ~1) {
2495 case SQL_BOOLEAN:
2496 case SQL_SHORT:
2497 if (unlikely(sqlvar->sqlscale != 0)) {
2498 logError(printf("sqlColumnBool: Column " FMT_D ": "
2499 "The scale of a boolean field must be 0.\n", column););
2500 raise_error(RANGE_ERROR);
2501 columnValue = 0;
2502 } else {
2503 columnValue = *(int16Type *) sqlvar->sqldata;
2504 } /* if */
2505 break;
2506 case SQL_LONG:
2507 if (unlikely(sqlvar->sqlscale != 0)) {
2508 logError(printf("sqlColumnBool: Column " FMT_D ": "
2509 "The scale of a boolean field must be 0.\n", column););
2510 raise_error(RANGE_ERROR);
2511 columnValue = 0;
2512 } else {
2513 columnValue = *(int32Type *) sqlvar->sqldata;
2514 } /* if */
2515 break;
2516 case SQL_INT64:
2517 if (unlikely(sqlvar->sqlscale != 0)) {
2518 logError(printf("sqlColumnBool: Column " FMT_D ": "
2519 "The scale of a boolean field must be 0.\n", column););
2520 raise_error(RANGE_ERROR);
2521 columnValue = 0;
2522 } else {
2523 columnValue = *(int64Type *) sqlvar->sqldata;
2524 } /* if */
2525 break;
2526 case SQL_TEXT:
2527 if (unlikely(sqlvar->sqllen != 1)) {
2528 logError(printf("sqlColumnBool: Column " FMT_D ": "
2529 "The size of a boolean field must be 1.\n", column););
2530 raise_error(RANGE_ERROR);
2531 columnValue = 0;
2532 } else {
2533 columnValue = ((char *) sqlvar->sqldata)[0] != '0';
2534 } /* if */
2535 break;
2536 default:
2537 logError(printf("sqlColumnBool: Column " FMT_D " has the unknown type %s.\n",
2538 column, nameOfSqlType(sqlvar->sqltype & ~1)););
2539 raise_error(RANGE_ERROR);
2540 columnValue = 0;
2541 break;
2542 } /* switch */
2543 if (unlikely((uintType) columnValue >= 2)) {
2544 logError(printf("sqlColumnBool: Column " FMT_D ": "
2545 FMT_D " is not an allowed boolean value.\n",
2546 column, columnValue););
2547 raise_error(RANGE_ERROR);
2548 } /* if */
2549 } /* if */
2550 } /* if */
2551 logFunction(printf("sqlColumnBool --> %s\n", columnValue ? "TRUE" : "FALSE"););
2552 return columnValue != 0;
2553 } /* sqlColumnBool */
2554
2555
2556
sqlColumnBStri(sqlStmtType sqlStatement,intType column)2557 static bstriType sqlColumnBStri (sqlStmtType sqlStatement, intType column)
2558
2559 {
2560 preparedStmtType preparedStmt;
2561 XSQLVAR *sqlvar;
2562 short *sqlind;
2563 short length;
2564 uint16Type varyingLength;
2565 errInfoType err_info = OKAY_NO_ERROR;
2566 bstriType columnValue;
2567
2568 /* sqlColumnBStri */
2569 logFunction(printf("sqlColumnBStri(" FMT_U_MEM ", " FMT_D ")\n",
2570 (memSizeType) sqlStatement, column););
2571 preparedStmt = (preparedStmtType) sqlStatement;
2572 if (unlikely(!preparedStmt->fetchOkay || column < 1 ||
2573 column > preparedStmt->out_sqlda->sqld)) {
2574 logError(printf("sqlColumnBStri: Fetch okay: %d, column: " FMT_D
2575 ", max column: %hd.\n",
2576 preparedStmt->fetchOkay, column,
2577 preparedStmt->out_sqlda->sqld););
2578 raise_error(RANGE_ERROR);
2579 columnValue = NULL;
2580 } else {
2581 sqlvar = &preparedStmt->out_sqlda->sqlvar[column - 1];
2582 sqlind = sqlvar->sqlind;
2583 if (sqlind != NULL && *sqlind == -1) {
2584 /* printf("Column is NULL -> Use default value: \"\"\n"); */
2585 if (unlikely(!ALLOC_BSTRI_SIZE_OK(columnValue, 0))) {
2586 raise_error(MEMORY_ERROR);
2587 } else {
2588 columnValue->size = 0;
2589 } /* if */
2590 } else if (unlikely(sqlind != NULL && *sqlind != 0)) {
2591 dbInconsistent("sqlColumnBStri", "sqlind");
2592 logError(printf("sqlColumnBStri: Column " FMT_D ": "
2593 "sqlind has the value %d.\n",
2594 column, *sqlind););
2595 raise_error(DATABASE_ERROR);
2596 columnValue = NULL;
2597 } else {
2598 /* printf("columnType: %s\n", nameOfSqlType(sqlvar->sqltype & ~1)); */
2599 switch (sqlvar->sqltype & ~1) {
2600 case SQL_TEXT:
2601 length = sqlvar->sqllen;
2602 /* printf("length: %hd\n", length); */
2603 while (length > 0 && sqlvar->sqldata[length - 1] == ' ') {
2604 length--;
2605 } /* if */
2606 if (unlikely(!ALLOC_BSTRI_CHECK_SIZE(columnValue, (memSizeType) length))) {
2607 raise_error(MEMORY_ERROR);
2608 } else {
2609 memcpy(columnValue->mem, sqlvar->sqldata, (memSizeType) length);
2610 columnValue->size = (memSizeType) length;
2611 } /* if */
2612 break;
2613 case SQL_VARYING:
2614 length = sqlvar->sqllen;
2615 /* printf("length: %hd\n", length); */
2616 varyingLength = *(uint16Type *) sqlvar->sqldata;
2617 /* printf("varyingLength: " FMT_U16 "\n", varyingLength); */
2618 if (unlikely(varyingLength > length)) {
2619 dbInconsistent("sqlColumnBStri", "sqllen");
2620 logError(printf("sqlColumnBStri: Column " FMT_D ": "
2621 "Length of SQL_VARYING " FMT_U16 " larger than field size %hd.\n",
2622 column, varyingLength, length););
2623 raise_error(DATABASE_ERROR);
2624 columnValue = NULL;
2625 } else if (unlikely(!ALLOC_BSTRI_CHECK_SIZE(columnValue, (memSizeType) varyingLength))) {
2626 raise_error(MEMORY_ERROR);
2627 } else {
2628 memcpy(columnValue->mem,
2629 &sqlvar->sqldata[sizeof(uint16Type)],
2630 (memSizeType) varyingLength);
2631 columnValue->size = (memSizeType) varyingLength;
2632 } /* if */
2633 break;
2634 case SQL_BLOB:
2635 if (sqlvar->sqlsubtype == 1) {
2636 /* BLOB SUB_TYPE 1 means essentially: textual Blob. */
2637 logError(printf("sqlColumnBStri: Column " FMT_D " is a CLOB.\n",
2638 column););
2639 raise_error(RANGE_ERROR);
2640 columnValue = NULL;
2641 } else {
2642 /* BLOB SUB_TYPE 0 is a binary Blob. */
2643 columnValue = getBlob(preparedStmt,
2644 (ISC_QUAD *) sqlvar->sqldata,
2645 &err_info);
2646 if (unlikely(columnValue == NULL)) {
2647 raise_error(err_info);
2648 } /* if */
2649 } /* if */
2650 break;
2651 default:
2652 logError(printf("sqlColumnBStri: Column " FMT_D " has the unknown type %s.\n",
2653 column, nameOfSqlType(sqlvar->sqltype & ~1)););
2654 raise_error(RANGE_ERROR);
2655 columnValue = NULL;
2656 break;
2657 } /* switch */
2658 } /* if */
2659 } /* if */
2660 logFunction(printf("sqlColumnBStri --> \"%s\"\n", bstriAsUnquotedCStri(columnValue)););
2661 return columnValue;
2662 } /* sqlColumnBStri */
2663
2664
2665
sqlColumnDuration(sqlStmtType sqlStatement,intType column,intType * year,intType * month,intType * day,intType * hour,intType * minute,intType * second,intType * micro_second)2666 static void sqlColumnDuration (sqlStmtType sqlStatement, intType column,
2667 intType *year, intType *month, intType *day, intType *hour,
2668 intType *minute, intType *second, intType *micro_second)
2669
2670 {
2671 preparedStmtType preparedStmt;
2672 XSQLVAR *sqlvar;
2673 short *sqlind;
2674 struct tm tm_time;
2675
2676 /* sqlColumnDuration */
2677 logFunction(printf("sqlColumnDuration(" FMT_U_MEM ", " FMT_D ", *)\n",
2678 (memSizeType) sqlStatement, column););
2679 preparedStmt = (preparedStmtType) sqlStatement;
2680 if (unlikely(!preparedStmt->fetchOkay || column < 1 ||
2681 column > preparedStmt->out_sqlda->sqld)) {
2682 logError(printf("sqlColumnDuration: Fetch okay: %d, column: " FMT_D
2683 ", max column: %hd.\n",
2684 preparedStmt->fetchOkay, column,
2685 preparedStmt->out_sqlda->sqld););
2686 raise_error(RANGE_ERROR);
2687 } else {
2688 sqlvar = &preparedStmt->out_sqlda->sqlvar[column - 1];
2689 sqlind = sqlvar->sqlind;
2690 if (sqlind != NULL && *sqlind == -1) {
2691 /* printf("Column is NULL -> Use default value: P0D\n"); */
2692 *year = 0;
2693 *month = 0;
2694 *day = 0;
2695 *hour = 0;
2696 *minute = 0;
2697 *second = 0;
2698 *micro_second = 0;
2699 } else if (unlikely(sqlind != NULL && *sqlind != 0)) {
2700 dbInconsistent("sqlColumnDuration", "sqlind");
2701 logError(printf("sqlColumnDuration: Column " FMT_D ": "
2702 "sqlind has the value %d.\n",
2703 column, *sqlind););
2704 raise_error(DATABASE_ERROR);
2705 } else {
2706 /* printf("columnType: %s\n", nameOfSqlType(sqlvar->sqltype & ~1)); */
2707 switch (sqlvar->sqltype & ~1) {
2708 case SQL_TIMESTAMP:
2709 isc_decode_timestamp((ISC_TIMESTAMP *) sqlvar->sqldata, &tm_time);
2710 *year = tm_time.tm_year;
2711 *month = tm_time.tm_mon - 13;
2712 *day = tm_time.tm_mday;
2713 *hour = tm_time.tm_hour;
2714 *minute = tm_time.tm_min;
2715 *second = tm_time.tm_sec;
2716 *micro_second = 0;
2717 break;
2718 case SQL_TYPE_TIME:
2719 isc_decode_sql_time((ISC_TIME *) sqlvar->sqldata, &tm_time);
2720 *year = tm_time.tm_year;
2721 *month = tm_time.tm_mon;
2722 *day = tm_time.tm_mday;
2723 *hour = tm_time.tm_hour;
2724 *minute = tm_time.tm_min;
2725 *second = tm_time.tm_sec;
2726 *micro_second = 0;
2727 break;
2728 case SQL_TYPE_DATE:
2729 isc_decode_sql_date((ISC_DATE *) sqlvar->sqldata, &tm_time);
2730 *year = tm_time.tm_year;
2731 *month = tm_time.tm_mon;
2732 *day = tm_time.tm_mday;
2733 *hour = tm_time.tm_hour;
2734 *minute = tm_time.tm_min;
2735 *second = tm_time.tm_sec;
2736 *micro_second = 0;
2737 break;
2738 default:
2739 logError(printf("sqlColumnDuration: Column " FMT_D " has the unknown type %s.\n",
2740 column, nameOfSqlType(sqlvar->sqltype & ~1)););
2741 raise_error(RANGE_ERROR);
2742 break;
2743 } /* switch */
2744 } /* if */
2745 } /* if */
2746 logFunction(printf("sqlColumnDuration(" FMT_U_MEM ", " FMT_D ") --> P"
2747 FMT_D "Y" FMT_D "M" FMT_D "DT"
2748 FMT_D "H" FMT_D "M%s" FMT_U "." F_U(06) "S\n",
2749 (memSizeType) sqlStatement, column,
2750 *year, *month, *day, *hour, *minute,
2751 *second < 0 || *micro_second < 0 ? "-" : "",
2752 intAbs(*second), intAbs(*micro_second)););
2753 } /* sqlColumnDuration */
2754
2755
2756
sqlColumnFloat(sqlStmtType sqlStatement,intType column)2757 static floatType sqlColumnFloat (sqlStmtType sqlStatement, intType column)
2758
2759 {
2760 preparedStmtType preparedStmt;
2761 XSQLVAR *sqlvar;
2762 short *sqlind;
2763 floatType columnValue;
2764
2765 /* sqlColumnFloat */
2766 logFunction(printf("sqlColumnFloat(" FMT_U_MEM ", " FMT_D ")\n",
2767 (memSizeType) sqlStatement, column););
2768 preparedStmt = (preparedStmtType) sqlStatement;
2769 if (unlikely(!preparedStmt->fetchOkay || column < 1 ||
2770 column > preparedStmt->out_sqlda->sqld)) {
2771 logError(printf("sqlColumnFloat: Fetch okay: %d, column: " FMT_D
2772 ", max column: %hd.\n",
2773 preparedStmt->fetchOkay, column,
2774 preparedStmt->out_sqlda->sqld););
2775 raise_error(RANGE_ERROR);
2776 columnValue = 0.0;
2777 } else {
2778 sqlvar = &preparedStmt->out_sqlda->sqlvar[column - 1];
2779 sqlind = sqlvar->sqlind;
2780 if (sqlind != NULL && *sqlind == -1) {
2781 /* printf("Column is NULL -> Use default value: 0.0\n"); */
2782 columnValue = 0.0;
2783 } else if (unlikely(sqlind != NULL && *sqlind != 0)) {
2784 dbInconsistent("sqlColumnFloat", "sqlind");
2785 logError(printf("sqlColumnFloat: Column " FMT_D ": "
2786 "sqlind has the value %d.\n",
2787 column, *sqlind););
2788 raise_error(DATABASE_ERROR);
2789 columnValue = 0.0;
2790 } else {
2791 /* printf("columnType: %s\n", nameOfSqlType(sqlvar->sqltype & ~1)); */
2792 switch (sqlvar->sqltype & ~1) {
2793 case SQL_SHORT:
2794 if (sqlvar->sqlscale == 0) {
2795 columnValue = (floatType) *(int16Type *) sqlvar->sqldata;
2796 } else {
2797 columnValue = ((floatType) *(int16Type *) sqlvar->sqldata) /
2798 fltIPow(10.0, -sqlvar->sqlscale);
2799 } /* if */
2800 break;
2801 case SQL_LONG:
2802 if (sqlvar->sqlscale == 0) {
2803 columnValue = (floatType) *(int32Type *) sqlvar->sqldata;
2804 } else {
2805 columnValue = ((floatType) *(int32Type *) sqlvar->sqldata) /
2806 fltIPow(10.0, -sqlvar->sqlscale);
2807 } /* if */
2808 break;
2809 case SQL_INT64:
2810 if (sqlvar->sqlscale == 0) {
2811 columnValue = (floatType) *(int64Type *) sqlvar->sqldata;
2812 } else {
2813 columnValue = ((floatType) *(int64Type *) sqlvar->sqldata) /
2814 fltIPow(10.0, -sqlvar->sqlscale);
2815 } /* if */
2816 break;
2817 case SQL_FLOAT:
2818 columnValue = *(float *) sqlvar->sqldata;
2819 break;
2820 case SQL_DOUBLE:
2821 columnValue = *(double *) sqlvar->sqldata;
2822 break;
2823 default:
2824 logError(printf("sqlColumnFloat: Column " FMT_D " has the unknown type %s.\n",
2825 column, nameOfSqlType(sqlvar->sqltype & ~1)););
2826 raise_error(RANGE_ERROR);
2827 columnValue = 0.0;
2828 break;
2829 } /* switch */
2830 } /* if */
2831 } /* if */
2832 logFunction(printf("sqlColumnFloat --> " FMT_E "\n", columnValue););
2833 return columnValue;
2834 } /* sqlColumnFloat */
2835
2836
2837
sqlColumnInt(sqlStmtType sqlStatement,intType column)2838 static intType sqlColumnInt (sqlStmtType sqlStatement, intType column)
2839
2840 {
2841 preparedStmtType preparedStmt;
2842 XSQLVAR *sqlvar;
2843 short *sqlind;
2844 intType columnValue;
2845
2846 /* sqlColumnInt */
2847 logFunction(printf("sqlColumnInt(" FMT_U_MEM ", " FMT_D ")\n",
2848 (memSizeType) sqlStatement, column););
2849 preparedStmt = (preparedStmtType) sqlStatement;
2850 if (unlikely(!preparedStmt->fetchOkay || column < 1 ||
2851 column > preparedStmt->out_sqlda->sqld)) {
2852 logError(printf("sqlColumnInt: Fetch okay: %d, column: " FMT_D
2853 ", max column: %hd.\n",
2854 preparedStmt->fetchOkay, column,
2855 preparedStmt->out_sqlda->sqld););
2856 raise_error(RANGE_ERROR);
2857 columnValue = 0;
2858 } else {
2859 sqlvar = &preparedStmt->out_sqlda->sqlvar[column - 1];
2860 sqlind = sqlvar->sqlind;
2861 if (sqlind != NULL && *sqlind == -1) {
2862 /* printf("Column is NULL -> Use default value: 0\n"); */
2863 columnValue = 0;
2864 } else if (unlikely(sqlind != NULL && *sqlind != 0)) {
2865 dbInconsistent("sqlColumnInt", "sqlind");
2866 logError(printf("sqlColumnInt: Column " FMT_D ": "
2867 "sqlind has the value %d.\n",
2868 column, *sqlind););
2869 raise_error(DATABASE_ERROR);
2870 columnValue = 0;
2871 } else {
2872 /* printf("columnType: %s\n", nameOfSqlType(sqlvar->sqltype & ~1)); */
2873 switch (sqlvar->sqltype & ~1) {
2874 case SQL_SHORT:
2875 if (unlikely(sqlvar->sqlscale != 0)) {
2876 logError(printf("sqlColumnInt: Column " FMT_D ": "
2877 "The scale of an integer field must be 0.\n", column););
2878 raise_error(RANGE_ERROR);
2879 columnValue = 0;
2880 } else {
2881 columnValue = *(int16Type *) sqlvar->sqldata;
2882 } /* if */
2883 break;
2884 case SQL_LONG:
2885 if (unlikely(sqlvar->sqlscale != 0)) {
2886 logError(printf("sqlColumnInt: Column " FMT_D ": "
2887 "The scale of an integer field must be 0.\n", column););
2888 raise_error(RANGE_ERROR);
2889 columnValue = 0;
2890 } else {
2891 columnValue = *(int32Type *) sqlvar->sqldata;
2892 } /* if */
2893 break;
2894 case SQL_INT64:
2895 if (unlikely(sqlvar->sqlscale != 0)) {
2896 logError(printf("sqlColumnInt: Column " FMT_D ": "
2897 "The scale of an integer field must be 0.\n", column););
2898 raise_error(RANGE_ERROR);
2899 columnValue = 0;
2900 } else {
2901 columnValue = *(int64Type *) sqlvar->sqldata;
2902 } /* if */
2903 break;
2904 default:
2905 logError(printf("sqlColumnInt: Column " FMT_D " has the unknown type %s.\n",
2906 column, nameOfSqlType(sqlvar->sqltype & ~1)););
2907 raise_error(RANGE_ERROR);
2908 columnValue = 0;
2909 break;
2910 } /* switch */
2911 } /* if */
2912 } /* if */
2913 logFunction(printf("sqlColumnInt --> " FMT_D "\n", columnValue););
2914 return columnValue;
2915 } /* sqlColumnInt */
2916
2917
2918
sqlColumnStri(sqlStmtType sqlStatement,intType column)2919 static striType sqlColumnStri (sqlStmtType sqlStatement, intType column)
2920
2921 {
2922 preparedStmtType preparedStmt;
2923 XSQLVAR *sqlvar;
2924 short *sqlind;
2925 short length;
2926 uint16Type varyingLength;
2927 errInfoType err_info = OKAY_NO_ERROR;
2928 striType columnValue;
2929
2930 /* sqlColumnStri */
2931 logFunction(printf("sqlColumnStri(" FMT_U_MEM ", " FMT_D ")\n",
2932 (memSizeType) sqlStatement, column););
2933 preparedStmt = (preparedStmtType) sqlStatement;
2934 if (unlikely(!preparedStmt->fetchOkay || column < 1 ||
2935 column > preparedStmt->out_sqlda->sqld)) {
2936 logError(printf("sqlColumnStri: Fetch okay: %d, column: " FMT_D
2937 ", max column: %hd.\n",
2938 preparedStmt->fetchOkay, column,
2939 preparedStmt->out_sqlda->sqld););
2940 raise_error(RANGE_ERROR);
2941 columnValue = NULL;
2942 } else {
2943 sqlvar = &preparedStmt->out_sqlda->sqlvar[column - 1];
2944 sqlind = sqlvar->sqlind;
2945 if (sqlind != NULL && *sqlind == -1) {
2946 /* printf("Column is NULL -> Use default value: \"\"\n"); */
2947 columnValue = strEmpty();
2948 } else if (unlikely(sqlind != NULL && *sqlind != 0)) {
2949 dbInconsistent("sqlColumnStri", "sqlind");
2950 logError(printf("sqlColumnStri: Column " FMT_D ": "
2951 "sqlind has the value %d.\n",
2952 column, *sqlind););
2953 raise_error(DATABASE_ERROR);
2954 columnValue = NULL;
2955 } else {
2956 /* printf("columnType: %s\n", nameOfSqlType(sqlvar->sqltype & ~1)); */
2957 switch (sqlvar->sqltype & ~1) {
2958 case SQL_TEXT:
2959 length = sqlvar->sqllen;
2960 /* printf("length: %hd\n", length); */
2961 while (length > 0 && sqlvar->sqldata[length - 1] == ' ') {
2962 length--;
2963 } /* if */
2964 columnValue = cstri8_buf_to_stri(sqlvar->sqldata,
2965 (memSizeType) length, &err_info);
2966 if (unlikely(columnValue == NULL)) {
2967 raise_error(err_info);
2968 } /* if */
2969 break;
2970 case SQL_VARYING:
2971 length = sqlvar->sqllen;
2972 /* printf("length: %hd\n", length); */
2973 varyingLength = *(uint16Type *) sqlvar->sqldata;
2974 /* printf("varyingLength: " FMT_U16 "\n", varyingLength); */
2975 if (unlikely(varyingLength > length)) {
2976 dbInconsistent("sqlColumnStri", "sqllen");
2977 logError(printf("sqlColumnStri: Column " FMT_D ": "
2978 "Length of SQL_VARYING " FMT_U16 " larger than field size %hd.\n",
2979 column, varyingLength, length););
2980 raise_error(DATABASE_ERROR);
2981 columnValue = NULL;
2982 } else {
2983 columnValue = cstri8_buf_to_stri(
2984 &sqlvar->sqldata[sizeof(uint16Type)],
2985 (memSizeType) varyingLength, &err_info);
2986 if (unlikely(columnValue == NULL)) {
2987 raise_error(err_info);
2988 } /* if */
2989 } /* if */
2990 break;
2991 case SQL_BLOB:
2992 if (sqlvar->sqlsubtype == 1) {
2993 /* BLOB SUB_TYPE 1 means essentially: textual Blob. */
2994 columnValue = getClob(preparedStmt,
2995 (ISC_QUAD *) sqlvar->sqldata,
2996 &err_info);
2997 } else {
2998 /* BLOB SUB_TYPE 0 is a binary Blob. */
2999 columnValue = getBlobAsStri(preparedStmt,
3000 (ISC_QUAD *) sqlvar->sqldata,
3001 &err_info);
3002 } /* if */
3003 if (unlikely(columnValue == NULL)) {
3004 raise_error(err_info);
3005 } /* if */
3006 break;
3007 #if 0
3008 case SQL_ARRAY:
3009 length = sqlvar->sqllen;
3010 printf("length: %hd\n", length);
3011 printf("data[0]: %d\n", sqlvar->sqldata[0]);
3012 printf("data[1]: %d\n", sqlvar->sqldata[1]);
3013 printf("data[2]: %d\n", sqlvar->sqldata[2]);
3014 printf("data[3]: %d\n", sqlvar->sqldata[3]);
3015 printf("data[4]: %d\n", sqlvar->sqldata[4]);
3016 printf("data[5]: %d\n", sqlvar->sqldata[5]);
3017 printf("data[6]: %d\n", sqlvar->sqldata[6]);
3018 printf("data[7]: %d\n", sqlvar->sqldata[7]);
3019 printf("varyingLength: %u\n",
3020 sqlvar->sqldata[0] +
3021 sqlvar->sqldata[1] * 256);
3022 printf("sqldata: " FMT_U_MEM "\n", (memSizeType) sqlvar->sqldata);
3023 printf("varyingLength: %hu\n",
3024 *(uint16Type *) sqlvar->sqldata);
3025 raise_error(RANGE_ERROR);
3026 columnValue = NULL;
3027 break;
3028 #endif
3029 default:
3030 logError(printf("sqlColumnStri: Column " FMT_D " has the unknown type %s.\n",
3031 column, nameOfSqlType(sqlvar->sqltype & ~1)););
3032 raise_error(RANGE_ERROR);
3033 columnValue = NULL;
3034 break;
3035 } /* switch */
3036 } /* if */
3037 } /* if */
3038 logFunction(printf("sqlColumnStri --> \"%s\"\n", striAsUnquotedCStri(columnValue)););
3039 return columnValue;
3040 } /* sqlColumnStri */
3041
3042
3043
sqlColumnTime(sqlStmtType sqlStatement,intType column,intType * year,intType * month,intType * day,intType * hour,intType * minute,intType * second,intType * micro_second,intType * time_zone,boolType * is_dst)3044 static void sqlColumnTime (sqlStmtType sqlStatement, intType column,
3045 intType *year, intType *month, intType *day, intType *hour,
3046 intType *minute, intType *second, intType *micro_second,
3047 intType *time_zone, boolType *is_dst)
3048
3049 {
3050 preparedStmtType preparedStmt;
3051 XSQLVAR *sqlvar;
3052 short *sqlind;
3053 struct tm tm_time;
3054
3055 /* sqlColumnTime */
3056 logFunction(printf("sqlColumnTime(" FMT_U_MEM ", " FMT_D ")\n",
3057 (memSizeType) sqlStatement, column););
3058 preparedStmt = (preparedStmtType) sqlStatement;
3059 if (unlikely(!preparedStmt->fetchOkay || column < 1 ||
3060 column > preparedStmt->out_sqlda->sqld)) {
3061 logError(printf("sqlColumnTime: Fetch okay: %d, column: " FMT_D
3062 ", max column: %hd.\n",
3063 preparedStmt->fetchOkay, column,
3064 preparedStmt->out_sqlda->sqld););
3065 raise_error(RANGE_ERROR);
3066 } else {
3067 sqlvar = &preparedStmt->out_sqlda->sqlvar[column - 1];
3068 sqlind = sqlvar->sqlind;
3069 if (sqlind != NULL && *sqlind == -1) {
3070 /* printf("Column is NULL -> Use default value: 0-01-01 00:00:00\n"); */
3071 *year = 0;
3072 *month = 1;
3073 *day = 1;
3074 *hour = 0;
3075 *minute = 0;
3076 *second = 0;
3077 *micro_second = 0;
3078 *time_zone = 0;
3079 *is_dst = 0;
3080 } else if (unlikely(sqlind != NULL && *sqlind != 0)) {
3081 dbInconsistent("sqlColumnTime", "sqlind");
3082 logError(printf("sqlColumnTime: Column " FMT_D ": "
3083 "sqlind has the value %d.\n",
3084 column, *sqlind););
3085 raise_error(DATABASE_ERROR);
3086 } else {
3087 /* printf("columnType: %s\n", nameOfSqlType(sqlvar->sqltype & ~1)); */
3088 switch (sqlvar->sqltype & ~1) {
3089 case SQL_TIMESTAMP:
3090 isc_decode_timestamp((ISC_TIMESTAMP *) sqlvar->sqldata, &tm_time);
3091 *year = tm_time.tm_year + 1900;
3092 *month = tm_time.tm_mon + 1;
3093 *day = tm_time.tm_mday;
3094 *hour = tm_time.tm_hour;
3095 *minute = tm_time.tm_min;
3096 *second = tm_time.tm_sec;
3097 *micro_second = (intType) (((ISC_TIMESTAMP *) sqlvar->sqldata)->timestamp_time % 10000) * 100;
3098 timSetLocalTZ(*year, *month, *day, *hour, *minute, *second,
3099 time_zone, is_dst);
3100 break;
3101 case SQL_TYPE_TIME:
3102 isc_decode_sql_time((ISC_TIME *) sqlvar->sqldata, &tm_time);
3103 *year = tm_time.tm_year + 1900;
3104 *month = tm_time.tm_mon + 1;
3105 *day = tm_time.tm_mday;
3106 *hour = tm_time.tm_hour;
3107 *minute = tm_time.tm_min;
3108 *second = tm_time.tm_sec;
3109 *micro_second = (intType) (*(ISC_TIME *) sqlvar->sqldata % 10000) * 100;
3110 timSetLocalTZ(*year, *month, *day, *hour, *minute, *second,
3111 time_zone, is_dst);
3112 break;
3113 case SQL_TYPE_DATE:
3114 isc_decode_sql_date((ISC_DATE *) sqlvar->sqldata, &tm_time);
3115 *year = tm_time.tm_year + 1900;
3116 *month = tm_time.tm_mon + 1;
3117 *day = tm_time.tm_mday;
3118 *hour = tm_time.tm_hour;
3119 *minute = tm_time.tm_min;
3120 *second = tm_time.tm_sec;
3121 *micro_second = 0;
3122 timSetLocalTZ(*year, *month, *day, *hour, *minute, *second,
3123 time_zone, is_dst);
3124 break;
3125 default:
3126 logError(printf("sqlColumnTime: Column " FMT_D " has the unknown type %s.\n",
3127 column, nameOfSqlType(sqlvar->sqltype & ~1)););
3128 raise_error(RANGE_ERROR);
3129 break;
3130 } /* switch */
3131 } /* if */
3132 } /* if */
3133 logFunction(printf("sqlColumnTime(" FMT_U_MEM ", " FMT_D ", "
3134 F_D(04) "-" F_D(02) "-" F_D(02) " "
3135 F_D(02) ":" F_D(02) ":" F_D(02) "."
3136 F_D(06) ", " FMT_D ", %d) -->\n",
3137 (memSizeType) sqlStatement, column,
3138 *year, *month, *day, *hour, *minute, *second,
3139 *micro_second, *time_zone, *is_dst););
3140 } /* sqlColumnTime */
3141
3142
3143
sqlCommit(databaseType database)3144 static void sqlCommit (databaseType database)
3145
3146 {
3147 dbType db;
3148 ISC_STATUS status_vector[20];
3149
3150 /* sqlCommit */
3151 logFunction(printf("sqlCommit(" FMT_U_MEM ")\n",
3152 (memSizeType) database););
3153 db = (dbType) database;
3154 isc_commit_transaction(status_vector,
3155 &db->trans_handle);
3156 if (unlikely(status_vector[0] == 1 && status_vector[1] != 0)) {
3157 setDbErrorMsg("sqlCommit", "isc_commit_transaction",
3158 status_vector);
3159 logError(printf("sqlCommit: isc_commit_transaction error:\n%s\n",
3160 dbError.message););
3161 raise_error(DATABASE_ERROR);
3162 } else {
3163 /* Set transaction handle to zero for isc_start_transaction(). */
3164 db->trans_handle = 0;
3165 isc_start_transaction(status_vector,
3166 &db->trans_handle,
3167 1,
3168 &db->connection,
3169 (unsigned short) sizeof(isc_tbp),
3170 isc_tbp);
3171 if (unlikely(status_vector[0] == 1 && status_vector[1] != 0)) {
3172 setDbErrorMsg("sqlCommit", "isc_start_transaction",
3173 status_vector);
3174 logError(printf("sqlCommit: isc_start_transaction error:\n%s\n",
3175 dbError.message););
3176 raise_error(DATABASE_ERROR);
3177 } /* if */
3178 } /* if */
3179 } /* sqlCommit */
3180
3181
3182
sqlExecute(sqlStmtType sqlStatement)3183 static void sqlExecute (sqlStmtType sqlStatement)
3184
3185 {
3186 preparedStmtType preparedStmt;
3187 ISC_STATUS status_vector[20];
3188 errInfoType err_info = OKAY_NO_ERROR;
3189
3190 /* sqlExecute */
3191 logFunction(printf("sqlExecute(" FMT_U_MEM ")\n",
3192 (memSizeType) sqlStatement););
3193 preparedStmt = (preparedStmtType) sqlStatement;
3194 if (unlikely(!allParametersBound(preparedStmt))) {
3195 dbLibError("sqlExecute", "SQLExecute",
3196 "Unbound statement parameter(s).\n");
3197 raise_error(DATABASE_ERROR);
3198 } else {
3199 /* printf("ppStmt: " FMT_U_MEM "\n", (memSizeType) preparedStmt->ppStmt); */
3200 if (preparedStmt->executeSuccessful) {
3201 if (unlikely((isc_dsql_free_statement(status_vector,
3202 &preparedStmt->ppStmt,
3203 DSQL_close),
3204 status_vector[0] == 1 && status_vector[1] != 0))) {
3205 setDbErrorMsg("sqlExecute", "isc_dsql_free_statement",
3206 status_vector);
3207 logError(printf("sqlExecute: isc_dsql_free_statement error:\n%s\n",
3208 dbError.message););
3209 err_info = DATABASE_ERROR;
3210 } else {
3211 preparedStmt->executeSuccessful = FALSE;
3212 } /* if */
3213 } /* if */
3214 if (unlikely(err_info != OKAY_NO_ERROR)) {
3215 raise_error(err_info);
3216 } else {
3217 preparedStmt->fetchOkay = FALSE;
3218 isc_dsql_execute2(status_vector,
3219 &preparedStmt->db->trans_handle,
3220 &preparedStmt->ppStmt,
3221 1, /* in_sqlda uses an XSQLDA descriptor. */
3222 preparedStmt->in_sqlda,
3223 NULL); /* Multiple rows are accessed with isc_dsql_fetch(). */
3224 if (unlikely(status_vector[0] == 1 && status_vector[1] != 0)) {
3225 setDbErrorMsg("sqlExecute", "isc_dsql_execute2",
3226 status_vector);
3227 logError(printf("sqlExecute: isc_dsql_execute2:\n%s\n",
3228 dbError.message););
3229 preparedStmt->executeSuccessful = FALSE;
3230 raise_error(DATABASE_ERROR);
3231 } else {
3232 if (preparedStmt->statement_type == isc_info_sql_stmt_ddl) {
3233 sqlCommit((databaseType) preparedStmt->db);
3234 } /* if */
3235 preparedStmt->executeSuccessful = TRUE;
3236 preparedStmt->fetchFinished = FALSE;
3237 } /* if */
3238 } /* if */
3239 } /* if */
3240 logFunction(printf("sqlExecute -->\n"););
3241 } /* sqlExecute */
3242
3243
3244
sqlFetch(sqlStmtType sqlStatement)3245 static boolType sqlFetch (sqlStmtType sqlStatement)
3246
3247 {
3248 preparedStmtType preparedStmt;
3249 ISC_STATUS status_vector[20];
3250 ISC_STATUS fetch_result;
3251
3252 /* sqlFetch */
3253 logFunction(printf("sqlFetch(" FMT_U_MEM ")\n",
3254 (memSizeType) sqlStatement););
3255 preparedStmt = (preparedStmtType) sqlStatement;
3256 if (unlikely(!preparedStmt->executeSuccessful)) {
3257 dbLibError("sqlFetch", "SQLExecute",
3258 "Execute was not successful.\n");
3259 logError(printf("sqlFetch: Execute was not successful.\n"););
3260 preparedStmt->fetchOkay = FALSE;
3261 raise_error(DATABASE_ERROR);
3262 } else if (preparedStmt->out_sqlda->sqld == 0) {
3263 preparedStmt->fetchOkay = FALSE;
3264 } else if (!preparedStmt->fetchFinished) {
3265 /* printf("ppStmt: " FMT_U_MEM "\n", (memSizeType) preparedStmt->ppStmt); */
3266 fetch_result = isc_dsql_fetch(status_vector,
3267 &preparedStmt->ppStmt,
3268 1, /* out_sqlda uses an XSQLDA descriptor. */
3269 preparedStmt->out_sqlda);
3270 if (fetch_result == 0) {
3271 /* printf("fetch success\n"); */
3272 preparedStmt->fetchOkay = TRUE;
3273 } else if (fetch_result == 100) {
3274 preparedStmt->fetchOkay = FALSE;
3275 preparedStmt->fetchFinished = TRUE;
3276 } else {
3277 setDbErrorMsg("sqlFetch", "isc_dsql_fetch",
3278 status_vector);
3279 logError(printf("sqlFetch: isc_dsql_fetch fetch_result: " FMT_D_MEM ":\n%s\n",
3280 (memSizeType) fetch_result, dbError.message););
3281 preparedStmt->fetchOkay = FALSE;
3282 preparedStmt->fetchFinished = TRUE;
3283 raise_error(DATABASE_ERROR);
3284 } /* if */
3285 } /* if */
3286 logFunction(printf("sqlFetch --> %d\n", preparedStmt->fetchOkay););
3287 return preparedStmt->fetchOkay;
3288 } /* sqlFetch */
3289
3290
3291
sqlIsNull(sqlStmtType sqlStatement,intType column)3292 static boolType sqlIsNull (sqlStmtType sqlStatement, intType column)
3293
3294 {
3295 preparedStmtType preparedStmt;
3296 XSQLVAR *sqlvar;
3297 short *sqlind;
3298 boolType isNull;
3299
3300 /* sqlIsNull */
3301 logFunction(printf("sqlIsNull(" FMT_U_MEM ", " FMT_D ")\n",
3302 (memSizeType) sqlStatement, column););
3303 preparedStmt = (preparedStmtType) sqlStatement;
3304 if (unlikely(!preparedStmt->fetchOkay || column < 1 ||
3305 column > preparedStmt->out_sqlda->sqld)) {
3306 logError(printf("sqlIsNull: Fetch okay: %d, column: " FMT_D
3307 ", max column: %hd.\n",
3308 preparedStmt->fetchOkay, column,
3309 preparedStmt->out_sqlda->sqld););
3310 raise_error(RANGE_ERROR);
3311 isNull = FALSE;
3312 } else {
3313 sqlvar = &preparedStmt->out_sqlda->sqlvar[column - 1];
3314 sqlind = sqlvar->sqlind;
3315 if (sqlind != NULL && *sqlind == -1) {
3316 isNull = TRUE;
3317 } else if (unlikely(sqlind != NULL && *sqlind != 0)) {
3318 dbInconsistent("sqlColumnInt", "sqlind");
3319 logError(printf("sqlColumnInt: Column " FMT_D ": "
3320 "sqlind has the value %d.\n",
3321 column, *sqlind););
3322 raise_error(DATABASE_ERROR);
3323 isNull = FALSE;
3324 } else {
3325 isNull = FALSE;
3326 } /* if */
3327 } /* if */
3328 logFunction(printf("sqlIsNull --> %s\n", isNull ? "TRUE" : "FALSE"););
3329 return isNull;
3330 } /* sqlIsNull */
3331
3332
3333
sqlPrepare(databaseType database,const const_striType sqlStatementStri)3334 static sqlStmtType sqlPrepare (databaseType database,
3335 const const_striType sqlStatementStri)
3336
3337 {
3338 dbType db;
3339 cstriType query;
3340 memSizeType queryLength;
3341 XSQLDA *out_sqlda;
3342 ISC_STATUS status_vector[20];
3343 char res_buffer[8];
3344 short length;
3345 errInfoType err_info = OKAY_NO_ERROR;
3346 preparedStmtType preparedStmt;
3347
3348 /* sqlPrepare */
3349 logFunction(printf("sqlPrepare(" FMT_U_MEM ", \"%s\")\n",
3350 (memSizeType) database,
3351 striAsUnquotedCStri(sqlStatementStri)););
3352 db = (dbType) database;
3353 if (db->connection == 0) {
3354 logError(printf("sqlPrepare: Database is not open.\n"););
3355 err_info = RANGE_ERROR;
3356 preparedStmt = NULL;
3357 } else {
3358 query = stri_to_cstri8_buf(sqlStatementStri, &queryLength);
3359 if (unlikely(query == NULL)) {
3360 err_info = MEMORY_ERROR;
3361 preparedStmt = NULL;
3362 } else {
3363 if (unlikely(queryLength > UINT16TYPE_MAX)) {
3364 /* It is not possible to cast queryLength to unsigned short. */
3365 logError(printf("sqlPrepare: Statement string too long (length = " FMT_U_MEM ")\n",
3366 queryLength););
3367 err_info = RANGE_ERROR;
3368 preparedStmt = NULL;
3369 } else if (unlikely((out_sqlda = (XSQLDA *) malloc(XSQLDA_LENGTH(1))) == NULL ||
3370 !ALLOC_RECORD2(preparedStmt, preparedStmtRecord,
3371 count.prepared_stmt, count.prepared_stmt_bytes))) {
3372 if (out_sqlda != NULL) {
3373 free(out_sqlda);
3374 } /* if */
3375 err_info = MEMORY_ERROR;
3376 preparedStmt = NULL;
3377 } else {
3378 /* printf("sqlPrepare: query: %s\n", query); */
3379 memset(out_sqlda, 0, XSQLDA_LENGTH(1));
3380 memset(preparedStmt, 0, sizeof(preparedStmtRecord));
3381 out_sqlda->version = SQLDA_VERSION1;
3382 out_sqlda->sqln = 1;
3383 /* The statement handle must be zero when isc_dsql_allocate_statement() is called. */
3384 preparedStmt->ppStmt = 0;
3385 if ((isc_dsql_allocate_statement(status_vector,
3386 &db->connection,
3387 &preparedStmt->ppStmt),
3388 status_vector[0] == 1 && status_vector[1] != 0)) {
3389 setDbErrorMsg("sqlPrepare", "isc_dsql_allocate_statement",
3390 status_vector);
3391 logError(printf("sqlPrepare(" FMT_U_MEM ", \"%s\"): "
3392 "isc_dsql_allocate_statement error:\n%s\n",
3393 (memSizeType) database,
3394 striAsUnquotedCStri(sqlStatementStri),
3395 dbError.message););
3396 free(out_sqlda);
3397 err_info = DATABASE_ERROR;
3398 } else if ((isc_dsql_prepare(status_vector,
3399 &db->trans_handle,
3400 &preparedStmt->ppStmt,
3401 (unsigned short) queryLength,
3402 query,
3403 3, /* dialect, indicates V6.0 functionalities */
3404 out_sqlda),
3405 status_vector[0] == 1 && status_vector[1] != 0)) {
3406 setDbErrorMsg("sqlPrepare", "isc_dsql_prepare",
3407 status_vector);
3408 logError(printf("sqlPrepare(" FMT_U_MEM ", \"%s\"): "
3409 "isc_dsql_prepare error:\n%s\n",
3410 (memSizeType) database,
3411 striAsUnquotedCStri(sqlStatementStri),
3412 dbError.message););
3413 free(out_sqlda);
3414 err_info = DATABASE_ERROR;
3415 } else {
3416 preparedStmt->usage_count = 1;
3417 preparedStmt->sqlFunc = db->sqlFunc;
3418 preparedStmt->executeSuccessful = FALSE;
3419 preparedStmt->fetchOkay = FALSE;
3420 preparedStmt->fetchFinished = TRUE;
3421 preparedStmt->db = db;
3422 err_info = setupParameters(preparedStmt);
3423 if (unlikely(err_info != OKAY_NO_ERROR)) {
3424 free(out_sqlda);
3425 } else {
3426 err_info = setupResult(preparedStmt, out_sqlda);
3427 if (likely(err_info == OKAY_NO_ERROR)) {
3428 isc_dsql_sql_info(status_vector,
3429 &preparedStmt->ppStmt,
3430 sizeof(type_item),
3431 type_item,
3432 sizeof(res_buffer),
3433 res_buffer);
3434 if (unlikely(status_vector[0] == 1 && status_vector[1] != 0)) {
3435 setDbErrorMsg("sqlPrepare", "isc_dsql_sql_info",
3436 status_vector);
3437 logError(printf("sqlPrepare: isc_dsql_sql_info:\n%s\n",
3438 dbError.message););
3439 } else {
3440 if (res_buffer[0] == isc_info_sql_stmt_type) {
3441 length = (short) isc_portable_integer(&res_buffer[1], 2);
3442 preparedStmt->statement_type =
3443 (int) isc_portable_integer(&res_buffer[3], length);
3444 /* printf("statement_type: %d\n", preparedStmt->statement_type); */
3445 } /* if */
3446 } /* if */
3447 } /* if */
3448 } /* if */
3449 } /* if */
3450 if (unlikely(err_info != OKAY_NO_ERROR)) {
3451 freePreparedStmt((sqlStmtType) preparedStmt);
3452 preparedStmt = NULL;
3453 } /* if */
3454 } /* if */
3455 free_cstri8(query, sqlStatementStri);
3456 } /* if */
3457 } /* if */
3458 if (unlikely(err_info != OKAY_NO_ERROR)) {
3459 raise_error(err_info);
3460 } /* if */
3461 logFunction(printf("sqlPrepare --> " FMT_U_MEM "\n",
3462 (memSizeType) preparedStmt););
3463 return (sqlStmtType) preparedStmt;
3464 } /* sqlPrepare */
3465
3466
3467
sqlStmtColumnCount(sqlStmtType sqlStatement)3468 static intType sqlStmtColumnCount (sqlStmtType sqlStatement)
3469
3470 {
3471 preparedStmtType preparedStmt;
3472 intType columnCount;
3473
3474 /* sqlStmtColumnCount */
3475 logFunction(printf("sqlStmtColumnCount(" FMT_U_MEM ")\n",
3476 (memSizeType) sqlStatement););
3477 preparedStmt = (preparedStmtType) sqlStatement;
3478 /* The element sqld has the type ISC_SHORT (short). */
3479 /* Therefore it will always fit into the intType result. */
3480 columnCount = (intType) preparedStmt->out_sqlda->sqld;
3481 logFunction(printf("sqlStmtColumnCount --> " FMT_D "\n", columnCount););
3482 return columnCount;
3483 } /* sqlStmtColumnCount */
3484
3485
3486
sqlStmtColumnName(sqlStmtType sqlStatement,intType column)3487 static striType sqlStmtColumnName (sqlStmtType sqlStatement, intType column)
3488
3489 {
3490 preparedStmtType preparedStmt;
3491 XSQLVAR *sqlvar;
3492 errInfoType err_info = OKAY_NO_ERROR;
3493 striType name;
3494
3495 /* sqlStmtColumnName */
3496 logFunction(printf("sqlStmtColumnName(" FMT_U_MEM ", " FMT_D ")\n",
3497 (memSizeType) sqlStatement, column););
3498 preparedStmt = (preparedStmtType) sqlStatement;
3499 if (unlikely(column < 1 ||
3500 column > preparedStmt->out_sqlda->sqld)) {
3501 logError(printf("sqlStmtColumnName: column: " FMT_D
3502 ", max column: %hd.\n",
3503 column, preparedStmt->out_sqlda->sqld););
3504 raise_error(RANGE_ERROR);
3505 name = NULL;
3506 } else {
3507 sqlvar = &preparedStmt->out_sqlda->sqlvar[column - 1];
3508 if (unlikely(sqlvar->sqlname_length < 0)) {
3509 dbInconsistent("sqlStmtColumnName", "length");
3510 logError(printf("sqlStmtColumnName: Column " FMT_D ": "
3511 "sqlname_length %hd is negative.\n", column,
3512 sqlvar->sqlname_length););
3513 raise_error(DATABASE_ERROR);
3514 name = NULL;
3515 } else {
3516 name = cstri8_buf_to_stri(sqlvar->sqlname,
3517 (memSizeType) sqlvar->sqlname_length, &err_info);
3518 if (unlikely(name == NULL)) {
3519 raise_error(err_info);
3520 } /* if */
3521 } /* if */
3522 } /* if */
3523 logFunction(printf("sqlStmtColumnName --> \"%s\"\n",
3524 striAsUnquotedCStri(name)););
3525 return name;
3526 } /* sqlStmtColumnName */
3527
3528
3529
setupFuncTable(void)3530 static boolType setupFuncTable (void)
3531
3532 { /* setupFuncTable */
3533 if (sqlFunc == NULL) {
3534 if (ALLOC_RECORD(sqlFunc, sqlFuncRecord, count.sql_func)) {
3535 memset(sqlFunc, 0, sizeof(sqlFuncRecord));
3536 sqlFunc->freeDatabase = &freeDatabase;
3537 sqlFunc->freePreparedStmt = &freePreparedStmt;
3538 sqlFunc->sqlBindBigInt = &sqlBindBigInt;
3539 sqlFunc->sqlBindBigRat = &sqlBindBigRat;
3540 sqlFunc->sqlBindBool = &sqlBindBool;
3541 sqlFunc->sqlBindBStri = &sqlBindBStri;
3542 sqlFunc->sqlBindDuration = &sqlBindDuration;
3543 sqlFunc->sqlBindFloat = &sqlBindFloat;
3544 sqlFunc->sqlBindInt = &sqlBindInt;
3545 sqlFunc->sqlBindNull = &sqlBindNull;
3546 sqlFunc->sqlBindStri = &sqlBindStri;
3547 sqlFunc->sqlBindTime = &sqlBindTime;
3548 sqlFunc->sqlClose = &sqlClose;
3549 sqlFunc->sqlColumnBigInt = &sqlColumnBigInt;
3550 sqlFunc->sqlColumnBigRat = &sqlColumnBigRat;
3551 sqlFunc->sqlColumnBool = &sqlColumnBool;
3552 sqlFunc->sqlColumnBStri = &sqlColumnBStri;
3553 sqlFunc->sqlColumnDuration = &sqlColumnDuration;
3554 sqlFunc->sqlColumnFloat = &sqlColumnFloat;
3555 sqlFunc->sqlColumnInt = &sqlColumnInt;
3556 sqlFunc->sqlColumnStri = &sqlColumnStri;
3557 sqlFunc->sqlColumnTime = &sqlColumnTime;
3558 sqlFunc->sqlCommit = &sqlCommit;
3559 sqlFunc->sqlExecute = &sqlExecute;
3560 sqlFunc->sqlFetch = &sqlFetch;
3561 sqlFunc->sqlIsNull = &sqlIsNull;
3562 sqlFunc->sqlPrepare = &sqlPrepare;
3563 sqlFunc->sqlStmtColumnCount = &sqlStmtColumnCount;
3564 sqlFunc->sqlStmtColumnName = &sqlStmtColumnName;
3565 } /* if */
3566 } /* if */
3567 return sqlFunc != NULL;
3568 } /* setupFuncTable */
3569
3570
3571
doAttach(loginType loginData,const_cstriType extension,isc_db_handle * db_handle)3572 static errInfoType doAttach (loginType loginData, const_cstriType extension,
3573 isc_db_handle *db_handle)
3574
3575 {
3576 const const_cstriType charset = "UTF8";
3577 memSizeType charset_length;
3578 memSizeType extension_length;
3579 memSizeType fileName8Length;
3580 cstriType fileName8;
3581 memSizeType dpb_buffer_length;
3582 char *dpb_buffer;
3583 short dpb_length;
3584 char *dpb;
3585 ISC_STATUS status_vector[20];
3586 errInfoType err_info = OKAY_NO_ERROR;
3587
3588 /* doAttach */
3589 extension_length = strlen(extension);
3590 if (loginData->fileName8Length < extension_length ||
3591 memcmp(&loginData->fileName8[loginData->fileName8Length - extension_length],
3592 extension, extension_length) != 0) {
3593 fileName8Length = loginData->fileName8Length + extension_length;
3594 if (unlikely(fileName8Length > 255 ||
3595 !ALLOC_CSTRI(fileName8, fileName8Length))) {
3596 err_info = MEMORY_ERROR;
3597 } else {
3598 memcpy(fileName8, loginData->fileName8, loginData->fileName8Length);
3599 memcpy(&fileName8[loginData->fileName8Length], extension, extension_length);
3600 fileName8[fileName8Length] = '\0';
3601 } /* if */
3602 } else {
3603 fileName8Length = loginData->fileName8Length;
3604 fileName8 = loginData->fileName8;
3605 } /* if */
3606 if (likely(err_info == OKAY_NO_ERROR)) {
3607 charset_length = strlen(charset);
3608 /* Assume that the setting bytes take less then 256 bytes space. */
3609 dpb_buffer_length = fileName8Length + loginData->user8Length +
3610 loginData->password8Length + charset_length + 256;
3611 if (unlikely(!ALLOC_CSTRI(dpb_buffer, dpb_buffer_length))) {
3612 err_info = MEMORY_ERROR;
3613 } else {
3614 /* Construct the database parameter buffer. */
3615 dpb = dpb_buffer;
3616 *dpb++ = isc_dpb_version1;
3617 *dpb++ = isc_dpb_utf8_filename;
3618 *dpb++ = (char) fileName8Length;
3619 memcpy(dpb, fileName8, fileName8Length);
3620 dpb += fileName8Length;
3621 *dpb++ = isc_dpb_user_name;
3622 *dpb++ = (char) loginData->user8Length;
3623 memcpy(dpb, loginData->user8, loginData->user8Length);
3624 dpb += loginData->user8Length;
3625 *dpb++ = isc_dpb_password;
3626 *dpb++ = (char) loginData->password8Length;
3627 memcpy(dpb, loginData->password8, loginData->password8Length);
3628 dpb += loginData->password8Length;
3629 *dpb++ = isc_dpb_set_db_charset;
3630 *dpb++ = (char) charset_length;
3631 memcpy(dpb, charset, charset_length);
3632 dpb += charset_length;
3633 #if 0
3634 /* what does this? */
3635 *dpb++ = isc_num_buffers;
3636 *dpb++ = 1;
3637 *dpb++ = 90;
3638 #endif
3639 /* Add (unnecessary) null byte, to be on the safe side. */
3640 *dpb = '\0';
3641 dpb_length = (short) (dpb - dpb_buffer);
3642 /* Set database handle to zero before attaching to a database. */
3643 *db_handle = 0;
3644 /* Attach to the database. */
3645 isc_attach_database(status_vector, (short) fileName8Length,
3646 fileName8, db_handle, dpb_length, dpb_buffer);
3647 if (status_vector[0] == 1 && status_vector[1] != 0) {
3648 setDbErrorMsg("sqlOpenFire", "isc_attach_database",
3649 status_vector);
3650 logError(printf("sqlOpenFire: isc_attach_database(*, \"%s\", ... )"
3651 " user: \"%s\", password: \"%s\", error:\n%s\n",
3652 fileName8, loginData->user8, loginData->password8,
3653 dbError.message););
3654 err_info = DATABASE_ERROR;
3655 } /* if */
3656 UNALLOC_CSTRI(dpb_buffer, dpb_buffer_length);
3657 } /* if */
3658 if (fileName8 != loginData->fileName8) {
3659 UNALLOC_CSTRI(fileName8, fileName8Length);
3660 } /* if */
3661 } /* if */
3662 return err_info;
3663 } /* doAttach */
3664
3665
3666
sqlOpenFire(const const_striType host,intType port,const const_striType dbName,const const_striType user,const const_striType password)3667 databaseType sqlOpenFire (const const_striType host, intType port,
3668 const const_striType dbName, const const_striType user,
3669 const const_striType password)
3670
3671 {
3672 striType fileName;
3673 const const_cstriType extensions[] = {".fdb", ".gdb", ""};
3674 unsigned int idx;
3675 loginRecord loginData;
3676 isc_db_handle db_handle;
3677 isc_tr_handle trans_handle = 0; /* Set to zero for isc_start_transaction(). */
3678 ISC_STATUS status_vector[20];
3679 errInfoType err_info = OKAY_NO_ERROR;
3680 dbType database;
3681
3682 /* sqlOpenFire */
3683 logFunction(printf("sqlOpenFire(\"%s\", ",
3684 striAsUnquotedCStri(host));
3685 printf(FMT_D ", \"%s\", ",
3686 port, striAsUnquotedCStri(dbName));
3687 printf("\"%s\", ", striAsUnquotedCStri(user));
3688 printf("\"%s\")\n", striAsUnquotedCStri(password)););
3689 if (!findDll()) {
3690 logError(printf("sqlOpenFire: findDll() failed\n"););
3691 err_info = DATABASE_ERROR;
3692 database = NULL;
3693 } else {
3694 fileName = cmdToOsPath(dbName);
3695 if (fileName == NULL) {
3696 database = NULL;
3697 } else {
3698 loginData.fileName8 = stri_to_cstri8_buf(fileName, &loginData.fileName8Length);
3699 if (unlikely(loginData.fileName8 == NULL)) {
3700 err_info = MEMORY_ERROR;
3701 database = NULL;
3702 } else {
3703 loginData.user8 = stri_to_cstri8_buf(user, &loginData.user8Length);
3704 if (unlikely(loginData.user8 == NULL)) {
3705 err_info = MEMORY_ERROR;
3706 database = NULL;
3707 } else {
3708 loginData.password8 = stri_to_cstri8_buf(password, &loginData.password8Length);
3709 if (unlikely(loginData.password8 == NULL)) {
3710 err_info = MEMORY_ERROR;
3711 database = NULL;
3712 } else {
3713 if (loginData.fileName8Length > 255 || loginData.user8Length > 255 ||
3714 loginData.password8Length > 255) {
3715 logError(printf("sqlOpenFire: File name, user or password too long.\n"););
3716 err_info = RANGE_ERROR;
3717 database = NULL;
3718 } else {
3719 idx = 0;
3720 do {
3721 err_info = doAttach(&loginData, extensions[idx], &db_handle);
3722 idx++;
3723 } while (err_info == DATABASE_ERROR &&
3724 idx < sizeof(extensions) / sizeof(cstriType));
3725 if (unlikely(err_info != OKAY_NO_ERROR)) {
3726 database = NULL;
3727 } else {
3728 if ((isc_start_transaction(status_vector,
3729 &trans_handle,
3730 1,
3731 &db_handle,
3732 (unsigned short) sizeof(isc_tbp),
3733 isc_tbp),
3734 status_vector[0] == 1 && status_vector[1] != 0)) {
3735 setDbErrorMsg("sqlOpenFire", "isc_start_transaction",
3736 status_vector);
3737 logError(printf("sqlOpenFire: isc_start_transaction error:\n%s\n",
3738 dbError.message););
3739 err_info = DATABASE_ERROR;
3740 isc_detach_database(status_vector, &db_handle);
3741 database = NULL;
3742 } else if (unlikely(!setupFuncTable() ||
3743 !ALLOC_RECORD2(database, dbRecord,
3744 count.database, count.database_bytes))) {
3745 err_info = MEMORY_ERROR;
3746 isc_rollback_transaction(status_vector, &trans_handle);
3747 isc_detach_database(status_vector, &db_handle);
3748 database = NULL;
3749 } else {
3750 memset(database, 0, sizeof(dbRecord));
3751 database->usage_count = 1;
3752 database->sqlFunc = sqlFunc;
3753 database->driver = DB_CATEGORY_FIREBIRD;
3754 database->connection = db_handle;
3755 database->trans_handle = trans_handle;
3756 } /* if */
3757 } /* if */
3758 } /* if */
3759 free_cstri8(loginData.password8, password);
3760 } /* if */
3761 free_cstri8(loginData.user8, user);
3762 } /* if */
3763 free_cstri8(loginData.fileName8, fileName);
3764 } /* if */
3765 strDestr(fileName);
3766 } /* if */
3767 } /* if */
3768 if (unlikely(err_info != OKAY_NO_ERROR)) {
3769 raise_error(err_info);
3770 } /* if */
3771 logFunction(printf("sqlOpenFire --> " FMT_U_MEM "\n",
3772 (memSizeType) database););
3773 return (databaseType) database;
3774 } /* sqlOpenFire */
3775
3776 #else
3777
3778
3779
sqlOpenFire(const const_striType host,intType port,const const_striType dbName,const const_striType user,const const_striType password)3780 databaseType sqlOpenFire (const const_striType host, intType port,
3781 const const_striType dbName, const const_striType user,
3782 const const_striType password)
3783
3784 { /* sqlOpenFire */
3785 logError(printf("sqlOpenFire(\"%s\", ",
3786 striAsUnquotedCStri(host));
3787 printf(FMT_D ", \"%s\", ",
3788 port, striAsUnquotedCStri(dbName));
3789 printf("\"%s\", ", striAsUnquotedCStri(user));
3790 printf("\"%s\"): Firebird/InterBase driver not present.\n",
3791 striAsUnquotedCStri(password)););
3792 raise_error(RANGE_ERROR);
3793 return NULL;
3794 } /* sqlOpenFire */
3795
3796 #endif
3797