1 /********************************************************************/
2 /* */
3 /* sql_tds.c Database access functions for Tabular Data Stream. */
4 /* Copyright (C) 1989 - 2020 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_tds.c */
27 /* Changes: 2017, 2019, 2020 Thomas Mertes */
28 /* Content: Database access functions for Tabular Data Stream. */
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 "time.h"
41 #ifdef TDS_INCLUDE
42 #if TDS_INCLUDE_SYBFRONT_H
43 #include "sybfront.h"
44 #endif
45 #include TDS_INCLUDE
46 #endif
47
48 #include "common.h"
49 #include "data_rtl.h"
50 #include "striutl.h"
51 #include "heaputl.h"
52 #include "numutl.h"
53 #include "int_rtl.h"
54 #include "flt_rtl.h"
55 #include "str_rtl.h"
56 #include "tim_rtl.h"
57 #include "bst_rtl.h"
58 #include "big_drv.h"
59 #include "rtl_err.h"
60 #include "dll_drv.h"
61 #include "sql_base.h"
62 #include "sql_drv.h"
63
64 #ifdef TDS_INCLUDE
65
66
67 typedef struct {
68 uintType usage_count;
69 sqlFuncType sqlFunc;
70 intType driver;
71 DBPROCESS *dbproc;
72 boolType autoCommit;
73 } dbRecord, *dbType;
74
75 typedef struct {
76 striType buffer;
77 } bindDataRecord, *bindDataType;
78
79 typedef struct {
80 int buffer_type;
81 memSizeType buffer_length;
82 void *buffer;
83 } resultDataRecord, *resultDataType;
84
85 typedef struct {
86 uintType usage_count;
87 sqlFuncType sqlFunc;
88 DBPROCESS *dbproc;
89 striType *stmtPartArray;
90 memSizeType stmtPartArrayCharCount;
91 memSizeType param_array_size;
92 bindDataType param_array;
93 memSizeType result_array_size;
94 resultDataType result_array;
95 boolType executeSuccessful;
96 boolType fetchOkay;
97 boolType fetchFinished;
98 } preparedStmtRecord, *preparedStmtType;
99
100 typedef struct {
101 DBPROCESS *dbproc;
102 int severity;
103 int dberr;
104 int oserr;
105 char *dberrstr;
106 char *oserrstr;
107 } errorDescrRecord, *errorDescrType;
108
109 #define SQL_MAX_NUMERIC_LEN 32
110 typedef struct {
111 unsigned char precision;
112 unsigned char scale;
113 unsigned char sign;
114 unsigned char val[SQL_MAX_NUMERIC_LEN];
115 } numericRecord, *numericType;
116
117 static sqlFuncType sqlFunc = NULL;
118 static striType quoteQuote = NULL;
119
120 unsigned int precisionToBytes[] = {0, /* not used */
121 1, 1, 2, 2, 3, 3, 3, 4, 4, 5,
122 5, 5, 6, 6, 7, 7, 8, 8, 8, 9,
123 9, 10, 10, 10, 11, 11, 12, 12, 13, 13,
124 13, 14, 14, 15, 15, 15, 16, 16, 17, 17,
125 18, 18, 18, 19, 19, 20, 20, 20, 21, 21,
126 22, 22, 23, 23, 23, 24, 24, 25, 25, 25,
127 26, 26, 27, 27, 27, 28, 28, 29, 29, 30,
128 30, 30, 31, 31, 32, 32, 32, 33, 33, 34,
129 34, 35, 35, 35, 36, 36, 37, 37, 37, 38,
130 38, 39, 39, 40, 40, 40, 41, 41, 42, 42};
131
132 #define DEFAULT_DECIMAL_SCALE 1000
133 #define INITIAL_ARRAY_SIZE 256
134 #define STMT_TABLE_SIZE_INCREMENT 256
135 #define QUOTE_IN_STRING_LEN 2
136 #define MAX_TIME_LITERAL_LENGTH 34
137
138
139 #ifdef TDS_DLL
140 typedef RETCODE (*tp_dbbind) (DBPROCESS *dbproc,
141 int column,
142 int vartype,
143 DBINT varlen,
144 BYTE *varaddr);
145 typedef void (*tp_dbclose) (DBPROCESS * dbproc);
146 typedef RETCODE (*tp_dbcmd) (DBPROCESS *dbproc, const char *cmdstring);
147 typedef DBINT (*tp_dbcollen) (DBPROCESS *dbproc, int column);
148 typedef char *(*tp_dbcolname) (DBPROCESS *dbproc, int column);
149 typedef int (*tp_dbcoltype) (DBPROCESS *dbproc, int column);
150 typedef BYTE *(*tp_dbdata) (DBPROCESS *dbproc, int column);
151 typedef DBINT (*tp_dbdatlen) (DBPROCESS *dbproc, int column);
152 typedef EHANDLEFUNC (*tp_dberrhandle) (EHANDLEFUNC handler);
153 typedef void (*tp_dbexit) (void);
154 typedef RETCODE (*tp_dbinit) (void);
155 typedef LOGINREC *(*tp_dblogin) (void);
156 typedef void (*tp_dbloginfree) (LOGINREC *loginptr);
157 typedef MHANDLEFUNC (*tp_dbmsghandle) (MHANDLEFUNC handler);
158 typedef RETCODE (*tp_dbnextrow) (DBPROCESS *dbproc);
159 typedef int (*tp_dbnumcols) (DBPROCESS *dbproc);
160 typedef RETCODE (*tp_dbresults) (DBPROCESS *dbproc);
161 typedef RETCODE (*tp_dbsetlname) (LOGINREC * login, const char *value, int which);
162 typedef RETCODE (*tp_dbsqlexec) (DBPROCESS *dbproc);
163 typedef RETCODE (*tp_dbtablecolinfo) (DBPROCESS *dbproc,
164 DBINT column,
165 DBCOL *pdbcol);
166 typedef RETCODE (*tp_dbuse) (DBPROCESS * dbproc, const char *name);
167 typedef DBPROCESS *(*tp_tdsdbopen) (LOGINREC * login, const char *server, int msdblib);
168
169 static tp_dbbind ptr_dbbind;
170 static tp_dbclose ptr_dbclose;
171 static tp_dbcmd ptr_dbcmd;
172 static tp_dbcollen ptr_dbcollen;
173 static tp_dbcolname ptr_dbcolname;
174 static tp_dbcoltype ptr_dbcoltype;
175 static tp_dbdata ptr_dbdata;
176 static tp_dbdatlen ptr_dbdatlen;
177 static tp_dberrhandle ptr_dberrhandle;
178 static tp_dbexit ptr_dbexit;
179 static tp_dbinit ptr_dbinit;
180 static tp_dblogin ptr_dblogin;
181 static tp_dbloginfree ptr_dbloginfree;
182 static tp_dbmsghandle ptr_dbmsghandle;
183 static tp_dbnextrow ptr_dbnextrow;
184 static tp_dbnumcols ptr_dbnumcols;
185 static tp_dbresults ptr_dbresults;
186 static tp_dbsetlname ptr_dbsetlname;
187 static tp_dbsqlexec ptr_dbsqlexec;
188 static tp_dbtablecolinfo ptr_dbtablecolinfo;
189 static tp_dbuse ptr_dbuse;
190 static tp_tdsdbopen ptr_tdsdbopen;
191
192 #define dbbind ptr_dbbind
193 #define dbclose ptr_dbclose
194 #define dbcmd ptr_dbcmd
195 #define dbcollen ptr_dbcollen
196 #define dbcolname ptr_dbcolname
197 #define dbcoltype ptr_dbcoltype
198 #define dbdata ptr_dbdata
199 #define dbdatlen ptr_dbdatlen
200 #define dberrhandle ptr_dberrhandle
201 #define dbexit ptr_dbexit
202 #define dbinit ptr_dbinit
203 #define dblogin ptr_dblogin
204 #define dbloginfree ptr_dbloginfree
205 #define dbmsghandle ptr_dbmsghandle
206 #define dbnextrow ptr_dbnextrow
207 #define dbnumcols ptr_dbnumcols
208 #define dbresults ptr_dbresults
209 #define dbsetlname ptr_dbsetlname
210 #define dbsqlexec ptr_dbsqlexec
211 #define dbtablecolinfo ptr_dbtablecolinfo
212 #define dbuse ptr_dbuse
213 #define tdsdbopen ptr_tdsdbopen
214
215
216
setupDll(const char * dllName)217 static boolType setupDll (const char *dllName)
218
219 {
220 static void *dbDll = NULL;
221
222 /* setupDll */
223 logFunction(printf("setupDll(\"%s\")\n", dllName););
224 if (dbDll == NULL) {
225 dbDll = dllOpen(dllName);
226 if (dbDll != NULL) {
227 if ((dbbind = (tp_dbbind) dllFunc(dbDll, "dbbind")) == NULL ||
228 (dbclose = (tp_dbclose) dllFunc(dbDll, "dbclose")) == NULL ||
229 (dbcmd = (tp_dbcmd) dllFunc(dbDll, "dbcmd")) == NULL ||
230 (dbcollen = (tp_dbcollen) dllFunc(dbDll, "dbcollen")) == NULL ||
231 (dbcolname = (tp_dbcolname) dllFunc(dbDll, "dbcolname")) == NULL ||
232 (dbcoltype = (tp_dbcoltype) dllFunc(dbDll, "dbcoltype")) == NULL ||
233 (dbdata = (tp_dbdata) dllFunc(dbDll, "dbdata")) == NULL ||
234 (dbdatlen = (tp_dbdatlen) dllFunc(dbDll, "dbdatlen")) == NULL ||
235 (dberrhandle = (tp_dberrhandle) dllFunc(dbDll, "dberrhandle")) == NULL ||
236 (dbexit = (tp_dbexit) dllFunc(dbDll, "dbexit")) == NULL ||
237 (dbinit = (tp_dbinit) dllFunc(dbDll, "dbinit")) == NULL ||
238 (dblogin = (tp_dblogin) dllFunc(dbDll, "dblogin")) == NULL ||
239 (dbloginfree = (tp_dbloginfree) dllFunc(dbDll, "dbloginfree")) == NULL ||
240 (dbmsghandle = (tp_dbmsghandle) dllFunc(dbDll, "dbmsghandle")) == NULL ||
241 (dbnextrow = (tp_dbnextrow) dllFunc(dbDll, "dbnextrow")) == NULL ||
242 (dbnumcols = (tp_dbnumcols) dllFunc(dbDll, "dbnumcols")) == NULL ||
243 (dbresults = (tp_dbresults) dllFunc(dbDll, "dbresults")) == NULL ||
244 (dbsetlname = (tp_dbsetlname) dllFunc(dbDll, "dbsetlname")) == NULL ||
245 (dbsqlexec = (tp_dbsqlexec) dllFunc(dbDll, "dbsqlexec")) == NULL ||
246 (dbtablecolinfo = (tp_dbtablecolinfo) dllFunc(dbDll, "dbtablecolinfo")) == NULL ||
247 (dbuse = (tp_dbuse) dllFunc(dbDll, "dbuse")) == NULL ||
248 (tdsdbopen = (tp_tdsdbopen) dllFunc(dbDll, "tdsdbopen")) == NULL) {
249 dbDll = NULL;
250 } /* if */
251 } /* if */
252 } /* if */
253 logFunction(printf("setupDll --> %d\n", dbDll != NULL););
254 return dbDll != NULL;
255 } /* setupDll */
256
257
258
findDll(void)259 static boolType findDll (void)
260
261 {
262 const char *dllList[] = { TDS_DLL };
263 unsigned int pos;
264 boolType found = FALSE;
265
266 /* findDll */
267 for (pos = 0; pos < sizeof(dllList) / sizeof(char *) && !found; pos++) {
268 found = setupDll(dllList[pos]);
269 } /* for */
270 if (!found) {
271 dllErrorMessage("sqlOpenTds", "findDll", dllList,
272 sizeof(dllList) / sizeof(char *));
273 } /* if */
274 return found;
275 } /* findDll */
276
277 #else
278
279 #define findDll() TRUE
280
281 #endif
282
283
284
285 static void sqlClose (databaseType database);
286
287
288
err_handler(DBPROCESS * dbproc,int severity,int dberr,int oserr,char * dberrstr,char * oserrstr)289 static int err_handler (DBPROCESS *dbproc, int severity, int dberr,
290 int oserr, char *dberrstr, char *oserrstr)
291
292 { /* err_handler */
293 logFunction(printf("err_handler(*, %d, %d, %d, %s, %s)\n",
294 severity, dberr, oserr, dberrstr, oserrstr););
295 snprintf(dbError.message, DB_ERR_MESSAGE_SIZE,
296 "%s\ndberr: %d\n%s\noserr: %d\nseverity: %d\n",
297 dberrstr, dberr, oserrstr, oserr, severity);
298 dbError.errorCode = dberr;
299 if (dberr == SYBETIME) {
300 return INT_TIMEOUT;
301 } else {
302 return INT_CANCEL;
303 } /* if */
304 } /* err_handler */
305
306
307
msg_handler(DBPROCESS * dbproc,DBINT msgno,int msgstate,int severity,char * msgtext,char * srvname,char * procname,int line)308 static int msg_handler (DBPROCESS *dbproc, DBINT msgno, int msgstate,
309 int severity, char *msgtext, char *srvname, char *procname, int line)
310
311 { /* msg_handler */
312 logFunction(printf("msg_handler(*, %d, %d, %d, %s, %s, %s, %d)\n",
313 msgno, msgstate, severity, msgtext, srvname, procname, line););
314 return 0;
315 } /* msg_handler */
316
317
318
setDbErrorMsg(const char * funcName,const char * dbFuncName)319 static void setDbErrorMsg (const char *funcName, const char *dbFuncName)
320
321 { /* setDbErrorMsg */
322 dbError.funcName = funcName;
323 dbError.dbFuncName = dbFuncName;
324 } /* setDbErrorMsg */
325
326
327
doExecute(DBPROCESS * dbproc,const const_cstriType query,errInfoType * err_info)328 static void doExecute (DBPROCESS *dbproc, const const_cstriType query,
329 errInfoType *err_info)
330
331 {
332 RETCODE retCode;
333
334 /* doExecute */
335 logFunction(printf("doExecute(*, \"%s\", %d)\n", query, *err_info););
336 if (likely(*err_info == OKAY_NO_ERROR)) {
337 if (unlikely(dbcmd(dbproc, query) != SUCCEED)) {
338 logError(printf("doExecute: dbcmd(" FMT_U_MEM ", \"%s\") failed.\n",
339 (memSizeType) dbproc, query););
340 *err_info = DATABASE_ERROR;
341 } else if (unlikely(dbsqlexec(dbproc) != SUCCEED)) {
342 logError(printf("doExecute: dbsqlexec(" FMT_U_MEM ") with \"%s\" failed.\n",
343 (memSizeType) dbproc, query););
344 *err_info = DATABASE_ERROR;
345 } else {
346 retCode = dbresults(dbproc);
347 /* printf("dbresults returns: %d\n", retCode); */
348 if (unlikely(retCode == FAIL)) {
349 logError(printf("doExecute: dbresults() failed.\n"););
350 *err_info = DATABASE_ERROR;
351 } /* if */
352 } /* if */
353 } /* if */
354 logFunction(printf("doExecute --> (err_info=%d)\n", *err_info););
355 } /* doExecute */
356
357
358
359 /**
360 * Closes a database and frees the memory used by it.
361 */
freeDatabase(databaseType database)362 static void freeDatabase (databaseType database)
363
364 {
365 dbType db;
366
367 /* freeDatabase */
368 logFunction(printf("freeDatabase(" FMT_U_MEM ")\n",
369 (memSizeType) database););
370 sqlClose(database);
371 db = (dbType) database;
372 FREE_RECORD2(db, dbRecord, count.database, count.database_bytes);
373 logFunction(printf("freeDatabase -->\n"););
374 } /* freeDatabase */
375
376
377
freeStmtParts(striType * stmtPartArray,memSizeType partArraySize)378 static void freeStmtParts (striType *stmtPartArray, memSizeType partArraySize)
379
380 {
381 memSizeType pos;
382
383 /* freeStmtParts */
384 for (pos = 0; pos < partArraySize; pos++) {
385 FREE_STRI(stmtPartArray[pos], stmtPartArray[pos]->size);
386 } /* for */
387 } /* freeStmtParts */
388
389
390
391 /**
392 * Closes a prepared statement and frees the memory used by it.
393 */
freePreparedStmt(sqlStmtType sqlStatement)394 static void freePreparedStmt (sqlStmtType sqlStatement)
395
396 {
397 preparedStmtType preparedStmt;
398 memSizeType pos;
399
400 /* freePreparedStmt */
401 logFunction(printf("freePreparedStmt(" FMT_U_MEM ")\n",
402 (memSizeType) sqlStatement););
403 preparedStmt = (preparedStmtType) sqlStatement;
404 freeStmtParts(preparedStmt->stmtPartArray, preparedStmt->param_array_size + 1);
405 if (preparedStmt->param_array != NULL) {
406 for (pos = 0; pos < preparedStmt->param_array_size; pos++) {
407 strDestr(preparedStmt->param_array[pos].buffer);
408 } /* for */
409 FREE_TABLE(preparedStmt->param_array, bindDataRecord, preparedStmt->param_array_size);
410 } /* if */
411 if (preparedStmt->result_array != NULL) {
412 for (pos = 0; pos < preparedStmt->result_array_size; pos++) {
413 if (preparedStmt->result_array[pos].buffer != NULL) {
414 free(preparedStmt->result_array[pos].buffer);
415 } /* if */
416 } /* for */
417 FREE_TABLE(preparedStmt->result_array, resultDataRecord, preparedStmt->result_array_size);
418 } /* if */
419 FREE_RECORD2(preparedStmt, preparedStmtRecord,
420 count.prepared_stmt, count.prepared_stmt_bytes);
421 logFunction(printf("freePreparedStmt -->\n"););
422 } /* freePreparedStmt */
423
424
425
426 #if LOG_FUNCTIONS_EVERYWHERE || LOG_FUNCTIONS || VERBOSE_EXCEPTIONS_EVERYWHERE || VERBOSE_EXCEPTIONS
nameOfBufferType(int buffer_type)427 static const char *nameOfBufferType (int buffer_type)
428
429 {
430 static char buffer[50];
431 const char *typeName;
432
433 /* nameOfBufferType */
434 logFunction(printf("nameOfBufferType(%d)\n", buffer_type););
435 switch (buffer_type) {
436 case SYBVOID: typeName = "SYBVOID"; break;
437 case SYBIMAGE: typeName = "SYBIMAGE"; break;
438 case SYBTEXT: typeName = "SYBTEXT"; break;
439 case SYBVARBINARY: typeName = "SYBVARBINARY"; break;
440 case SYBINTN: typeName = "SYBINTN"; break;
441 case SYBVARCHAR: typeName = "SYBVARCHAR"; break;
442 case SYBMSDATE: typeName = "SYBMSDATE"; break;
443 case SYBMSTIME: typeName = "SYBMSTIME"; break;
444 case SYBMSDATETIME2: typeName = "SYBMSDATETIME2"; break;
445 case SYBMSDATETIMEOFFSET: typeName = "SYBMSDATETIMEOFFSET"; break;
446 case SYBBINARY: typeName = "SYBBINARY"; break;
447 case SYBCHAR: typeName = "SYBCHAR"; break;
448 case SYBINT1: typeName = "SYBINT1"; break;
449 case SYBDATE: typeName = "SYBDATE"; break;
450 case SYBBIT: typeName = "SYBBIT"; break;
451 case SYBTIME: typeName = "SYBTIME"; break;
452 case SYBINT2: typeName = "SYBINT2"; break;
453 case SYBINT4: typeName = "SYBINT4"; break;
454 case SYBDATETIME4: typeName = "SYBDATETIME4"; break;
455 case SYBREAL: typeName = "SYBREAL"; break;
456 case SYBMONEY: typeName = "SYBMONEY"; break;
457 case SYBDATETIME: typeName = "SYBDATETIME"; break;
458 case SYBFLT8: typeName = "SYBFLT8"; break;
459 case SYBNTEXT: typeName = "SYBNTEXT"; break;
460 case SYBNVARCHAR: typeName = "SYBNVARCHAR"; break;
461 case SYBBITN: typeName = "SYBBITN"; break;
462 case SYBDECIMAL: typeName = "SYBDECIMAL"; break;
463 case SYBNUMERIC: typeName = "SYBNUMERIC"; break;
464 case SYBFLTN: typeName = "SYBFLTN"; break;
465 case SYBMONEYN: typeName = "SYBMONEYN"; break;
466 case SYBDATETIMN: typeName = "SYBDATETIMN"; break;
467 case SYBMONEY4: typeName = "SYBMONEY4"; break;
468 case SYBINT8: typeName = "SYBINT8"; break;
469 case SYBBIGDATETIME: typeName = "SYBBIGDATETIME"; break;
470 case SYBBIGTIME: typeName = "SYBBIGTIME"; break;
471 default:
472 sprintf(buffer, "%d", buffer_type);
473 typeName = buffer;
474 break;
475 } /* switch */
476 logFunction(printf("nameOfBufferType --> %s\n", typeName););
477 return typeName;
478 } /* nameOfBufferType */
479 #endif
480
481
482
storeStmtPart(striType * stmtPartArray,memSizeType partIndex,striType stmtPart,memSizeType stmtPartLength)483 static striType *storeStmtPart (striType *stmtPartArray, memSizeType partIndex,
484 striType stmtPart, memSizeType stmtPartLength)
485
486 {
487 striType *resizedStmtPartArray;
488 striType copiedStmtPart;
489
490 /* storeStmtPart */
491 if ((partIndex & (STMT_TABLE_SIZE_INCREMENT - 1)) == 0) {
492 resizedStmtPartArray = REALLOC_TABLE(stmtPartArray, striType, partIndex,
493 partIndex + STMT_TABLE_SIZE_INCREMENT);
494 if (unlikely(resizedStmtPartArray == NULL)) {
495 if (stmtPartArray != NULL) {
496 freeStmtParts(stmtPartArray, partIndex);
497 stmtPartArray = NULL;
498 } /* if */
499 } else {
500 stmtPartArray = resizedStmtPartArray;
501 COUNT3_TABLE(striType, partIndex, partIndex + STMT_TABLE_SIZE_INCREMENT);
502 } /* if */
503 } /* if */
504 if (likely(stmtPartArray != NULL)) {
505 if (unlikely(!ALLOC_STRI_SIZE_OK(copiedStmtPart, stmtPartLength))) {
506 freeStmtParts(stmtPartArray, partIndex);
507 stmtPartArray = NULL;
508 } else {
509 copiedStmtPart->size = stmtPartLength;
510 memcpy(copiedStmtPart->mem, stmtPart->mem, stmtPartLength * sizeof(strElemType));
511 /* printf("stmtPart: \"%s\"\n", striAsUnquotedCStri(copiedStmtPart)); */
512 stmtPartArray[partIndex] = copiedStmtPart;
513 } /* if */
514 } /* if */
515 return stmtPartArray;
516 } /* storeStmtPart */
517
518
519
520 /**
521 * Process the bind variables in a statement string.
522 * Literals and comments are processed to avoid the misinterpretation
523 * of question marks (?).
524 */
processStatementStri(const const_striType sqlStatementStri,memSizeType * numBindParameters,errInfoType * err_info)525 static striType *processStatementStri (const const_striType sqlStatementStri,
526 memSizeType *numBindParameters, errInfoType *err_info)
527
528 {
529 memSizeType pos = 0;
530 strElemType ch;
531 strElemType delimiter;
532 memSizeType destPos = 0;
533 striType processed;
534 memSizeType partIndex = 0;
535 striType *stmtPartArray = NULL;
536
537 /* processStatementStri */
538 logFunction(printf("processStatementStri(\"%s\", *, *)\n",
539 striAsUnquotedCStri(sqlStatementStri)););
540 if (unlikely(sqlStatementStri->size > MAX_STRI_LEN ||
541 !ALLOC_STRI_SIZE_OK(processed, sqlStatementStri->size))) {
542 *err_info = MEMORY_ERROR;
543 *numBindParameters = 0;
544 } else {
545 while (pos < sqlStatementStri->size && *err_info == OKAY_NO_ERROR) {
546 ch = sqlStatementStri->mem[pos];
547 if (ch == '?') {
548 if (destPos == 0 || processed->mem[destPos - 1] != ' ') {
549 /* Make sure that a space precedes the bind parameter. */
550 processed->mem[destPos++] = ' ';
551 } /* if */
552 stmtPartArray = storeStmtPart(stmtPartArray, partIndex, processed, destPos);
553 if (unlikely(stmtPartArray == NULL)) {
554 *err_info = MEMORY_ERROR;
555 } else {
556 partIndex++;
557 destPos = 0;
558 pos++;
559 if (pos < sqlStatementStri->size && sqlStatementStri->mem[pos] != ' ') {
560 /* Make sure that a space succeeds the bind parameter. */
561 processed->mem[destPos++] = ' ';
562 } /* if */
563 } /* if */
564 } else if (ch == '\'' || ch == '"') {
565 delimiter = ch;
566 processed->mem[destPos++] = delimiter;
567 pos++;
568 while (pos < sqlStatementStri->size &&
569 (ch = sqlStatementStri->mem[pos]) != delimiter) {
570 processed->mem[destPos++] = ch;
571 pos++;
572 } /* while */
573 if (pos < sqlStatementStri->size) {
574 processed->mem[destPos++] = delimiter;
575 pos++;
576 } /* if */
577 } else if (ch == '/') {
578 pos++;
579 if (pos >= sqlStatementStri->size || sqlStatementStri->mem[pos] != '*') {
580 processed->mem[destPos++] = ch;
581 } else {
582 pos++;
583 do {
584 while (pos < sqlStatementStri->size && sqlStatementStri->mem[pos] != '*') {
585 pos++;
586 } /* while */
587 pos++;
588 } while (pos < sqlStatementStri->size && sqlStatementStri->mem[pos] != '/');
589 pos++;
590 /* Replace the comment with a space. */
591 processed->mem[destPos++] = ' ';
592 } /* if */
593 } else if (ch == '-') {
594 pos++;
595 if (pos >= sqlStatementStri->size || sqlStatementStri->mem[pos] != '-') {
596 processed->mem[destPos++] = ch;
597 } else {
598 pos++;
599 while (pos < sqlStatementStri->size && sqlStatementStri->mem[pos] != '\n') {
600 pos++;
601 } /* while */
602 /* The final newline replaces the comment. */
603 } /* if */
604 } else {
605 processed->mem[destPos++] = ch;
606 pos++;
607 } /* if */
608 } /* while */
609 if (likely(*err_info == OKAY_NO_ERROR)) {
610 stmtPartArray = storeStmtPart(stmtPartArray, partIndex, processed, destPos);
611 if (unlikely(stmtPartArray == NULL)) {
612 *err_info = MEMORY_ERROR;
613 } /* if */
614 } /* if */
615 FREE_STRI(processed, sqlStatementStri->size);
616 *numBindParameters = partIndex;
617 } /* if */
618 logFunction(printf("processStatementStri(\"%s\", " FMT_U_MEM ", %d) --> ",
619 striAsUnquotedCStri(sqlStatementStri),
620 *numBindParameters, *err_info);
621 if (stmtPartArray == NULL) {
622 printf("NULL");
623 } else {
624 for (partIndex = 0; partIndex <= *numBindParameters; partIndex++) {
625 printf("\"%s\" ", striAsUnquotedCStri(stmtPartArray[partIndex]));
626 }
627 }
628 printf("\n"););
629 return stmtPartArray;
630 } /* processStatementStri */
631
632
633
getSizeOfBoundStatement(preparedStmtType preparedStmt,errInfoType * err_info)634 static memSizeType getSizeOfBoundStatement (preparedStmtType preparedStmt,
635 errInfoType *err_info)
636
637 {
638 memSizeType paramIndex;
639 bindDataType bindData;
640 memSizeType sizeOfBoundStatement;
641
642 /* getSizeOfBoundStatement */
643 sizeOfBoundStatement = preparedStmt->stmtPartArrayCharCount;
644 for (paramIndex = 0; paramIndex < preparedStmt->param_array_size; paramIndex++) {
645 bindData = &preparedStmt->param_array[paramIndex];
646 if (unlikely(bindData->buffer == NULL)) {
647 logError(printf("sqlExecute: Unbound parameter " FMT_U_MEM ".\n",
648 paramIndex + 1););
649 *err_info = RANGE_ERROR;
650 return 0;
651 } else if (unlikely(sizeOfBoundStatement > MAX_STRI_LEN - bindData->buffer->size)) {
652 *err_info = MEMORY_ERROR;
653 return 0;
654 } else {
655 sizeOfBoundStatement += bindData->buffer->size;
656 } /* if */
657 } /* for */
658 return sizeOfBoundStatement;
659 } /* getSizeOfBoundStatement */
660
661
662
getBoundStatement(preparedStmtType preparedStmt,errInfoType * err_info)663 static striType getBoundStatement (preparedStmtType preparedStmt, errInfoType *err_info)
664
665 {
666 memSizeType paramIndex;
667 memSizeType pos = 0;
668 memSizeType sizeOfBoundStatement = 0;
669 striType boundStatement;
670
671 /* getBoundStatement */
672 logFunction(printf("getBoundStatement(*, %d)\n", *err_info););
673 sizeOfBoundStatement = getSizeOfBoundStatement(preparedStmt, err_info);
674 if (unlikely(*err_info != OKAY_NO_ERROR)) {
675 boundStatement = NULL;
676 } else if (unlikely(sizeOfBoundStatement > MAX_STRI_LEN ||
677 !ALLOC_STRI_SIZE_OK(boundStatement, sizeOfBoundStatement))) {
678 *err_info = MEMORY_ERROR;
679 boundStatement = NULL;
680 } else {
681 boundStatement->size = sizeOfBoundStatement;
682 for (paramIndex = 0; paramIndex < preparedStmt->param_array_size; paramIndex++) {
683 memcpy(&boundStatement->mem[pos], preparedStmt->stmtPartArray[paramIndex]->mem,
684 preparedStmt->stmtPartArray[paramIndex]->size * sizeof(strElemType));
685 pos += preparedStmt->stmtPartArray[paramIndex]->size;
686 memcpy(&boundStatement->mem[pos], preparedStmt->param_array[paramIndex].buffer->mem,
687 preparedStmt->param_array[paramIndex].buffer->size * sizeof(strElemType));
688 pos += preparedStmt->param_array[paramIndex].buffer->size;
689 } /* while */
690 memcpy(&boundStatement->mem[pos], preparedStmt->stmtPartArray[paramIndex]->mem,
691 preparedStmt->stmtPartArray[paramIndex]->size * sizeof(strElemType));
692 /* pos += preparedStmt->stmtPartArray[paramIndex]->size; */
693 /* pos should be equal to boundStatement->size */
694 } /* if */
695 logFunction(printf("getBoundStatement --> \"%s\"\n",
696 striAsUnquotedCStri(boundStatement)););
697 return boundStatement;
698 } /* getBoundStatement */
699
700
701
setStmtPartArrayCharCount(preparedStmtType preparedStmt,memSizeType numBindParameters)702 static errInfoType setStmtPartArrayCharCount (preparedStmtType preparedStmt,
703 memSizeType numBindParameters)
704
705 {
706 memSizeType partIndex;
707 memSizeType stmtPartArrayCharCount = 0;
708 errInfoType err_info = OKAY_NO_ERROR;
709
710 /* setStmtPartArrayCharCount */
711 logFunction(printf("setStmtPartArrayCharCount\n"););
712 for (partIndex = 0; partIndex <= numBindParameters; partIndex++) {
713 if (unlikely(stmtPartArrayCharCount > MAX_STRI_LEN -
714 preparedStmt->stmtPartArray[partIndex]->size)) {
715 err_info = MEMORY_ERROR;
716 return 0;
717 } else {
718 stmtPartArrayCharCount += preparedStmt->stmtPartArray[partIndex]->size;
719 } /* if */
720 } /* for */
721 preparedStmt->stmtPartArrayCharCount = stmtPartArrayCharCount;
722 logFunction(printf("setStmtPartArrayCharCount --> %d (count=" FMT_U_MEM ")\n",
723 err_info, stmtPartArrayCharCount););
724 return err_info;
725 } /* setStmtPartArrayCharCount */
726
727
728
setupParameters(preparedStmtType preparedStmt,memSizeType numBindParameters)729 static errInfoType setupParameters (preparedStmtType preparedStmt,
730 memSizeType numBindParameters)
731
732 {
733 errInfoType err_info = OKAY_NO_ERROR;
734
735 /* setupParameters */
736 logFunction(printf("setupParameters\n"););
737 if (!ALLOC_TABLE(preparedStmt->param_array,
738 bindDataRecord, (memSizeType) numBindParameters)) {
739 err_info = MEMORY_ERROR;
740 } else {
741 preparedStmt->param_array_size = (memSizeType) numBindParameters;
742 memset(preparedStmt->param_array, 0,
743 (memSizeType) numBindParameters * sizeof(bindDataRecord));
744 } /* if */
745 logFunction(printf("setupParameters --> %d\n", err_info););
746 return err_info;
747 } /* setupParameters */
748
749
750
setupResultColumn(preparedStmtType preparedStmt,int column_num,resultDataType columnData)751 static errInfoType setupResultColumn (preparedStmtType preparedStmt,
752 int column_num, resultDataType columnData)
753
754 {
755 DBINT buffer_length;
756 DBCOL dbcol;
757 int bind_type;
758 errInfoType err_info = OKAY_NO_ERROR;
759
760 /* setupResultColumn */
761 logFunction(printf("setupResultColumn: column_num=%d\n", column_num););
762 dbcol.SizeOfStruct = sizeof(DBCOL);
763 /* The function dbtablecolinfo() distinguishes SYBCHAR from SYBVARCHAR. */
764 /* The functions dbcoltype() and dbcolinfo() do not distinguish SYBCHAR */
765 /* from SYBVARCHAR. In sqlColumnStri() trailing spaces of SYBCHAR fields */
766 /* are removed. For SYBVARCHAR fields trailing spaces are preserved. */
767 if (unlikely(dbtablecolinfo(preparedStmt->dbproc,
768 column_num, &dbcol) != SUCCEED)) {
769 setDbErrorMsg("setupResultColumn", "dbtablecolinfo");
770 logError(printf("setupResultColumn: dbtablecolinfo did not succeed:\n%s\n",
771 dbError.message););
772 err_info = DATABASE_ERROR;
773 } else {
774 /* printf("Type: " FMT_D16 ", VarLength: %d\n", dbcol.Type, dbcol.VarLength); */
775 columnData->buffer_type = dbcol.Type;
776 /* printf("buffer_type: %s\n", nameOfBufferType(columnData->buffer_type)); */
777 switch (columnData->buffer_type) {
778 case SYBCHAR:
779 bind_type = STRINGBIND;
780 buffer_length = dbcollen(preparedStmt->dbproc, column_num);
781 break;
782 case SYBVARCHAR:
783 bind_type = VARYCHARBIND;
784 buffer_length = dbcollen(preparedStmt->dbproc, column_num);
785 break;
786 case SYBINT1:
787 bind_type = TINYBIND;
788 buffer_length = dbcollen(preparedStmt->dbproc, column_num);
789 break;
790 case SYBINT2:
791 bind_type = SMALLBIND;
792 buffer_length = dbcollen(preparedStmt->dbproc, column_num);
793 break;
794 case SYBINT4:
795 bind_type = INTBIND;
796 buffer_length = dbcollen(preparedStmt->dbproc, column_num);
797 break;
798 case SYBINT8:
799 bind_type = INTBIND;
800 buffer_length = dbcollen(preparedStmt->dbproc, column_num);
801 break;
802 case SYBREAL:
803 bind_type = REALBIND;
804 buffer_length = dbcollen(preparedStmt->dbproc, column_num);
805 break;
806 case SYBFLT8:
807 bind_type = FLT8BIND;
808 buffer_length = dbcollen(preparedStmt->dbproc, column_num);
809 break;
810 case SYBDECIMAL:
811 bind_type = DECIMALBIND;
812 buffer_length = dbcollen(preparedStmt->dbproc, column_num);
813 break;
814 case SYBNUMERIC:
815 bind_type = NUMERICBIND;
816 buffer_length = dbcollen(preparedStmt->dbproc, column_num);
817 break;
818 case SYBMSDATE:
819 bind_type = DATEBIND;
820 buffer_length = dbcollen(preparedStmt->dbproc, column_num);
821 break;
822 case SYBMSTIME:
823 bind_type = TIMEBIND;
824 buffer_length = dbcollen(preparedStmt->dbproc, column_num);
825 break;
826 case SYBMSDATETIME2:
827 bind_type = DATETIME2BIND;
828 buffer_length = dbcollen(preparedStmt->dbproc, column_num);
829 break;
830 case SYBBINARY:
831 bind_type = BINARYBIND;
832 buffer_length = dbcollen(preparedStmt->dbproc, column_num);
833 break;
834 case SYBVARBINARY:
835 bind_type = VARYBINBIND;
836 buffer_length = dbcollen(preparedStmt->dbproc, column_num);
837 break;
838 default:
839 logError(printf("setupResultColumn: Column %hd has the unknown type %s.\n",
840 column_num, nameOfBufferType(columnData->buffer_type)););
841 err_info = RANGE_ERROR;
842 break;
843 } /* switch */
844 if (err_info == OKAY_NO_ERROR) {
845 /* printf("buffer_length[%d]: " FMT_D32 "\n", column_num, buffer_length); */
846 columnData->buffer_length = (memSizeType) buffer_length;
847 /* Binding with dbbind() is not used. The data is retrieved with dbdata() instead. */
848 if (FALSE && buffer_length != 0) {
849 columnData->buffer = malloc((memSizeType) buffer_length);
850 if (unlikely(columnData->buffer == NULL)) {
851 err_info = MEMORY_ERROR;
852 } else {
853 memset(columnData->buffer, 0, (memSizeType) buffer_length);
854 if (unlikely(dbbind(preparedStmt->dbproc, column_num, bind_type,
855 buffer_length, (BYTE *) columnData->buffer) != SUCCEED)) {
856 setDbErrorMsg("setupResultColumn", "dbbind");
857 logError(printf("setupResultColumn: dbbind did not succeed:\n%s\n",
858 dbError.message););
859 err_info = DATABASE_ERROR;
860 } /* if */
861 } /* if */
862 } /* if */
863 } /* if */
864 } /* if */
865 logFunction(printf("setupResultColumn --> %d\n", err_info););
866 return err_info;
867 } /* setupResultColumn */
868
869
870
setupResult(preparedStmtType preparedStmt)871 static errInfoType setupResult (preparedStmtType preparedStmt)
872
873 {
874 int num_columns;
875 int column_index;
876 errInfoType err_info = OKAY_NO_ERROR;
877
878 /* setupResult */
879 logFunction(printf("setupResult\n"););
880 num_columns = dbnumcols(preparedStmt->dbproc);
881 /* printf("num_columns: %d\n", num_columns); */
882 if (unlikely(num_columns < 0)) {
883 dbInconsistent("setupResult", "dbnumcols");
884 logError(printf("setupResult: dbnumcols returns negative number: %d\n",
885 num_columns););
886 err_info = DATABASE_ERROR;
887 } else if (num_columns == 0) {
888 /* malloc(0) may return NULL, which would wrongly trigger a MEMORY_ERROR. */
889 preparedStmt->result_array_size = 0;
890 preparedStmt->result_array = NULL;
891 } else if (unlikely(!ALLOC_TABLE(preparedStmt->result_array,
892 resultDataRecord, (memSizeType) num_columns))) {
893 err_info = MEMORY_ERROR;
894 } else {
895 preparedStmt->result_array_size = (memSizeType) num_columns;
896 memset(preparedStmt->result_array, 0,
897 (memSizeType) num_columns * sizeof(resultDataRecord));
898 for (column_index = 0; column_index < num_columns &&
899 err_info == OKAY_NO_ERROR; column_index++) {
900 err_info = setupResultColumn(preparedStmt, column_index + 1,
901 &preparedStmt->result_array[column_index]);
902 } /* for */
903 } /* if */
904 logFunction(printf("setupResult --> %d\n", err_info););
905 return err_info;
906 } /* setupResult */
907
908
909
getNumericAsCStri(numericType numStruct)910 static cstriType getNumericAsCStri (numericType numStruct)
911
912 {
913 memSizeType numBytes;
914 bigIntType mantissa;
915 striType stri;
916 memSizeType decimalLen;
917 memSizeType decimalIdx = 0;
918 memSizeType idx;
919 cstriType decimal;
920
921 /* getNumericAsCStri */
922 if (unlikely(numStruct->precision == 0 || numStruct->precision > 100)) {
923 raise_error(RANGE_ERROR);
924 decimal = 0;
925 } else {
926 numBytes = (memSizeType) precisionToBytes[numStruct->precision];
927 mantissa = bigFromByteBufferBe(numBytes, numStruct->val, FALSE);
928 if (unlikely(mantissa == NULL)) {
929 decimal = NULL;
930 } else {
931 stri = bigStr(mantissa);
932 if (unlikely(stri == NULL)) {
933 bigDestr(mantissa);
934 raise_error(MEMORY_ERROR);
935 decimal = NULL;
936 } else {
937 if (numStruct->scale < 0) {
938 decimalLen = stri->size + (memSizeType) (-numStruct->scale) + 1 /* Space for decimal point */;
939 } else if (numStruct->scale <= stri->size) {
940 decimalLen = stri->size + 1 /* Space for decimal point */;
941 } else {
942 decimalLen = (memSizeType) numStruct->scale + 1 /* Space for decimal point */;
943 } /* if */
944 if (numStruct->sign != 0) {
945 decimalLen++; /* Space for sign */
946 } /* if */
947 if (unlikely(!ALLOC_CSTRI(decimal, decimalLen))) {
948 bigDestr(mantissa);
949 strDestr(stri);
950 raise_error(MEMORY_ERROR);
951 } else {
952 if (numStruct->sign != 0) {
953 decimal[decimalIdx++] = '-';
954 } /* if */
955 for (idx = 0; idx < stri->size; idx++) {
956 decimal[decimalIdx++] = (char) stri->mem[idx];
957 } /* for */
958 /* decimal[decimalIdx] = '\0';
959 printf("# \"%s\", scale: %d, size: " FMT_U_MEM ", len: " FMT_U_MEM "\n",
960 decimal, numStruct->scale, stri->size, decimalLen); */
961 if (numStruct->scale < 0) {
962 memset(&decimal[decimalIdx], '0', (memSizeType) (-numStruct->scale));
963 decimal[decimalLen - 1] = '.';
964 decimal[decimalLen] = '\0';
965 } else if (numStruct->scale <= stri->size) {
966 memmove(&decimal[decimalLen - (memSizeType) numStruct->scale],
967 &decimal[decimalLen - (memSizeType) numStruct->scale - 1],
968 (memSizeType) numStruct->scale);
969 decimal[decimalLen - (memSizeType) numStruct->scale - 1] = '.';
970 decimal[decimalLen] = '\0';
971 } else {
972 memmove(&decimal[decimalLen - stri->size],
973 &decimal[decimalLen - (memSizeType) numStruct->scale - 1],
974 stri->size);
975 memset(&decimal[decimalLen - (memSizeType) numStruct->scale], '0',
976 (memSizeType) numStruct->scale - stri->size);
977 decimal[decimalLen - (memSizeType) numStruct->scale - 1] = '.';
978 decimal[decimalLen] = '\0';
979 } /* if */
980 bigDestr(mantissa);
981 strDestr(stri);
982 } /* if */
983 } /* if */
984 } /* if */
985 } /* if */
986 logFunction(printf("getNumericAsCStri --> %s\n",
987 decimal != NULL ? decimal : "NULL"));
988 return decimal;
989 } /* getNumericAsCStri */
990
991
992
getNumericInt(const void * buffer)993 static intType getNumericInt (const void *buffer)
994
995 {
996 numericType numStruct;
997 memSizeType numBytes;
998 bigIntType bigIntValue;
999 bigIntType powerOfTen;
1000 intType intValue = 0;
1001
1002 /* getNumericInt */
1003 numStruct = (numericType) buffer;
1004 logFunction(printf("getNumericInt\n");
1005 printf("numStruct->precision: %u\n", numStruct->precision);
1006 printf("numStruct->scale: %d\n", numStruct->scale);
1007 printf("numStruct->sign: %u\n", numStruct->sign);
1008 printf("numStruct->val:");
1009 {
1010 int pos;
1011 for (pos = 0; pos < SQL_MAX_NUMERIC_LEN; pos++) {
1012 printf(" %d", numStruct->val[pos]);
1013 }
1014 printf("\n");
1015 });
1016 if (unlikely(numStruct->scale > 0 ||
1017 numStruct->precision == 0 || numStruct->precision > 100)) {
1018 raise_error(RANGE_ERROR);
1019 intValue = 0;
1020 } else {
1021 numBytes = (memSizeType) precisionToBytes[numStruct->precision];
1022 bigIntValue = bigFromByteBufferBe(numBytes, numStruct->val, FALSE);
1023 #if 0
1024 if (bigIntValue != NULL) {
1025 printf("numStruct->val: ");
1026 prot_bigint(bigIntValue);
1027 printf("\n");
1028 }
1029 #endif
1030 if (bigIntValue != NULL && numStruct->scale < 0) {
1031 powerOfTen = bigIPowSignedDigit(10, (intType) -numStruct->scale);
1032 if (powerOfTen != NULL) {
1033 bigMultAssign(&bigIntValue, powerOfTen);
1034 bigDestr(powerOfTen);
1035 } /* if */
1036 } /* if */
1037 if (bigIntValue != NULL && numStruct->sign != 0) {
1038 bigIntValue = bigNegateTemp(bigIntValue);
1039 } /* if */
1040 if (bigIntValue != NULL) {
1041 #if 0
1042 printf("numStruct->val: ");
1043 prot_bigint(bigIntValue);
1044 printf("\n");
1045 #endif
1046 #if INTTYPE_SIZE == 32
1047 intValue = bigToInt32(bigIntValue, NULL);
1048 #elif INTTYPE_SIZE == 64
1049 intValue = bigToInt64(bigIntValue, NULL);
1050 #endif
1051 bigDestr(bigIntValue);
1052 } /* if */
1053 } /* if */
1054 logFunction(printf("getNumericInt --> " FMT_D "\n", intValue););
1055 return intValue;
1056 } /* getNumericInt */
1057
1058
1059
getNumericBigInt(const void * buffer)1060 static bigIntType getNumericBigInt (const void *buffer)
1061
1062 {
1063 numericType numStruct;
1064 memSizeType numBytes;
1065 bigIntType powerOfTen;
1066 bigIntType bigIntValue;
1067
1068 /* getNumericBigInt */
1069 numStruct = (numericType) buffer;
1070 logFunction(printf("getNumericBigInt\n");
1071 printf("numStruct->precision: %u\n", numStruct->precision);
1072 printf("numStruct->scale: %d\n", numStruct->scale);
1073 printf("numStruct->sign: %u\n", numStruct->sign);
1074 printf("numStruct->val:");
1075 {
1076 int pos;
1077 for (pos = 0; pos < SQL_MAX_NUMERIC_LEN; pos++) {
1078 printf(" %d", numStruct->val[pos]);
1079 }
1080 printf("\n");
1081 });
1082 if (unlikely(numStruct->scale > 0 ||
1083 numStruct->precision == 0 || numStruct->precision > 100)) {
1084 raise_error(RANGE_ERROR);
1085 bigIntValue = NULL;
1086 } else {
1087 numBytes = (memSizeType) precisionToBytes[numStruct->precision];
1088 bigIntValue = bigFromByteBufferBe(numBytes, numStruct->val, FALSE);
1089 #if 0
1090 if (bigIntValue != NULL) {
1091 printf("numStruct->val: ");
1092 prot_bigint(bigIntValue);
1093 printf("\n");
1094 } /* if */
1095 #endif
1096 if (bigIntValue != NULL && numStruct->scale < 0) {
1097 powerOfTen = bigIPowSignedDigit(10, (intType) -numStruct->scale);
1098 if (powerOfTen != NULL) {
1099 bigMultAssign(&bigIntValue, powerOfTen);
1100 bigDestr(powerOfTen);
1101 } /* if */
1102 } /* if */
1103 if (bigIntValue != NULL && numStruct->sign != 0) {
1104 bigIntValue = bigNegateTemp(bigIntValue);
1105 } /* if */
1106 } /* if */
1107 logFunction(printf("getNumericBigInt --> ");
1108 prot_bigint(bigIntValue);
1109 printf("\n"););
1110 return bigIntValue;
1111 } /* getNumericBigInt */
1112
1113
1114
getNumericBigRational(const void * buffer,bigIntType * denominator)1115 static bigIntType getNumericBigRational (const void *buffer, bigIntType *denominator)
1116
1117 {
1118 numericType numStruct;
1119 memSizeType numBytes;
1120 bigIntType powerOfTen;
1121 bigIntType numerator;
1122
1123 /* getNumericBigRational */
1124 numStruct = (numericType) buffer;
1125 logFunction(printf("getNumericBigRational\n");
1126 printf("numStruct->precision: %u\n", numStruct->precision);
1127 printf("numStruct->scale: %d\n", numStruct->scale);
1128 printf("numStruct->sign: %u\n", numStruct->sign);
1129 printf("numStruct->val:");
1130 {
1131 int pos;
1132 for (pos = 0; pos < SQL_MAX_NUMERIC_LEN; pos++) {
1133 printf(" %d", numStruct->val[pos]);
1134 }
1135 printf("\n");
1136 });
1137 if (unlikely(numStruct->precision == 0 || numStruct->precision > 100)) {
1138 raise_error(RANGE_ERROR);
1139 numerator = NULL;
1140 } else {
1141 numBytes = (memSizeType) precisionToBytes[numStruct->precision];
1142 numerator = bigFromByteBufferBe(numBytes, numStruct->val, FALSE);
1143 #if 0
1144 if (numerator != NULL) {
1145 printf("numStruct->val: ");
1146 prot_bigint(numerator);
1147 printf("\n");
1148 } /* if */
1149 #endif
1150 if (numerator != NULL && numStruct->sign != 0) {
1151 numerator = bigNegateTemp(numerator);
1152 } /* if */
1153 if (numerator != NULL) {
1154 if (numStruct->scale < 0) {
1155 powerOfTen = bigIPowSignedDigit(10, (intType) -numStruct->scale);
1156 if (powerOfTen != NULL) {
1157 bigMultAssign(&numerator, powerOfTen);
1158 bigDestr(powerOfTen);
1159 } /* if */
1160 *denominator = bigFromInt32(1);
1161 } else {
1162 *denominator = bigIPowSignedDigit(10, (intType) numStruct->scale);
1163 } /* if */
1164 } /* if */
1165 } /* if */
1166 return numerator;
1167 } /* getNumericBigRational */
1168
1169
1170
getNumericFloat(const void * buffer)1171 static floatType getNumericFloat (const void *buffer)
1172
1173 {
1174 numericType numStruct;
1175 cstriType decimal;
1176 floatType floatValue;
1177
1178 /* getNumericFloat */
1179 numStruct = (numericType) buffer;
1180 logFunction(printf("getNumericFloat\n");
1181 printf("numStruct->precision: %u\n", numStruct->precision);
1182 printf("numStruct->scale: %d\n", numStruct->scale);
1183 printf("numStruct->sign: %u\n", numStruct->sign);
1184 printf("numStruct->val:");
1185 {
1186 int pos;
1187 for (pos = 0; pos < SQL_MAX_NUMERIC_LEN; pos++) {
1188 printf(" %d", numStruct->val[pos]);
1189 }
1190 printf("\n");
1191 });
1192 if (unlikely((decimal = getNumericAsCStri(numStruct)) == NULL)) {
1193 floatValue = 0.0;
1194 } else {
1195 floatValue = (floatType) strtod(decimal, NULL);
1196 UNALLOC_CSTRI(decimal, strlen(decimal));
1197 } /* if */
1198 logFunction(printf("getNumericFloat --> " FMT_E "\n", floatValue););
1199 return floatValue;
1200 } /* getNumericFloat */
1201
1202
1203
genSqlStringLiteral(const const_striType stri)1204 static striType genSqlStringLiteral (const const_striType stri)
1205
1206 {
1207 /* A string literal starts and ends with double quotes ("): */
1208 const memSizeType numOfQuotes = 2;
1209 register strElemType character;
1210 register memSizeType position;
1211 memSizeType striSize;
1212 memSizeType pos;
1213 striType resized_literal;
1214 striType literal;
1215
1216 /* genSqlStringLiteral */
1217 striSize = stri->size;
1218 if (unlikely(striSize > (MAX_STRI_LEN - numOfQuotes) / QUOTE_IN_STRING_LEN ||
1219 !ALLOC_STRI_SIZE_OK(literal, QUOTE_IN_STRING_LEN * striSize + numOfQuotes))) {
1220 raise_error(MEMORY_ERROR);
1221 literal = NULL;
1222 } else {
1223 literal->mem[0] = (strElemType) '\'';
1224 pos = 1;
1225 for (position = 0; position < striSize; position++) {
1226 character = (strElemType) stri->mem[position];
1227 if (character == '\'') {
1228 literal->mem[pos] = (strElemType) '\'';
1229 literal->mem[pos + 1] = (strElemType) '\'';
1230 pos += 2;
1231 } else {
1232 literal->mem[pos] = character;
1233 pos++;
1234 } /* if */
1235 } /* for */
1236 literal->mem[pos] = (strElemType) '\'';
1237 pos++;
1238 literal->size = pos;
1239 REALLOC_STRI_SIZE_SMALLER(resized_literal, literal,
1240 QUOTE_IN_STRING_LEN * striSize + numOfQuotes, pos);
1241 if (unlikely(resized_literal == NULL)) {
1242 FREE_STRI(literal, QUOTE_IN_STRING_LEN * striSize + numOfQuotes);
1243 raise_error(MEMORY_ERROR);
1244 literal = NULL;
1245 } else {
1246 literal = resized_literal;
1247 COUNT3_STRI(QUOTE_IN_STRING_LEN * striSize + numOfQuotes, pos);
1248 } /* if */
1249 } /* if */
1250 return literal;
1251 } /* genSqlStringLiteral */
1252
1253
1254
sqlBindBigInt(sqlStmtType sqlStatement,intType pos,const const_bigIntType value)1255 static void sqlBindBigInt (sqlStmtType sqlStatement, intType pos,
1256 const const_bigIntType value)
1257
1258 {
1259 preparedStmtType preparedStmt;
1260
1261 /* sqlBindBigInt */
1262 logFunction(printf("sqlBindBigInt(" FMT_U_MEM ", " FMT_D ", %s)\n",
1263 (memSizeType) sqlStatement, pos, bigHexCStri(value)););
1264 preparedStmt = (preparedStmtType) sqlStatement;
1265 if (unlikely(pos < 1 || (uintType) pos > preparedStmt->param_array_size)) {
1266 logError(printf("sqlBindBigInt: pos: " FMT_D ", max pos: " FMT_U_MEM ".\n",
1267 pos, preparedStmt->param_array_size););
1268 raise_error(RANGE_ERROR);
1269 } else {
1270 strDestr(preparedStmt->param_array[pos - 1].buffer);
1271 preparedStmt->param_array[pos - 1].buffer = bigStr(value);
1272 } /* if */
1273 } /* sqlBindBigInt */
1274
1275
1276
sqlBindBigRat(sqlStmtType sqlStatement,intType pos,const const_bigIntType numerator,const const_bigIntType denominator)1277 static void sqlBindBigRat (sqlStmtType sqlStatement, intType pos,
1278 const const_bigIntType numerator, const const_bigIntType denominator)
1279
1280 {
1281 preparedStmtType preparedStmt;
1282 ustriType decimal;
1283 memSizeType length;
1284 errInfoType err_info = OKAY_NO_ERROR;
1285
1286 /* sqlBindBigRat */
1287 logFunction(printf("sqlBindBigRat(" FMT_U_MEM ", " FMT_D ", %s, %s)\n",
1288 (memSizeType) sqlStatement, pos,
1289 bigHexCStri(numerator), bigHexCStri(denominator)););
1290 preparedStmt = (preparedStmtType) sqlStatement;
1291 if (unlikely(pos < 1 || (uintType) pos > preparedStmt->param_array_size)) {
1292 logError(printf("sqlBindBigRat: pos: " FMT_D ", max pos: " FMT_U_MEM ".\n",
1293 pos, preparedStmt->param_array_size););
1294 raise_error(RANGE_ERROR);
1295 } else {
1296 if (bigEqSignedDigit(denominator, 1)) {
1297 decimal = bigIntToDecimal(numerator, &length, &err_info);
1298 } else {
1299 decimal = bigRatToDecimal(numerator, denominator, DEFAULT_DECIMAL_SCALE,
1300 &length, &err_info);
1301 } /* if */
1302 if (unlikely(decimal == NULL)) {
1303 raise_error(err_info);
1304 } else {
1305 strDestr(preparedStmt->param_array[pos - 1].buffer);
1306 preparedStmt->param_array[pos - 1].buffer =
1307 cstri_buf_to_stri((cstriType) decimal, length);
1308 free(decimal);
1309 if (unlikely(preparedStmt->param_array[pos - 1].buffer == NULL)) {
1310 raise_error(MEMORY_ERROR);
1311 } /* if */
1312 } /* if */
1313 } /* if */
1314 } /* sqlBindBigRat */
1315
1316
1317
sqlBindBool(sqlStmtType sqlStatement,intType pos,boolType value)1318 static void sqlBindBool (sqlStmtType sqlStatement, intType pos, boolType value)
1319
1320 {
1321 preparedStmtType preparedStmt;
1322
1323 /* sqlBindBool */
1324 logFunction(printf("sqlBindBool(" FMT_U_MEM ", " FMT_D ", %s)\n",
1325 (memSizeType) sqlStatement, pos, value ? "TRUE" : "FALSE"););
1326 preparedStmt = (preparedStmtType) sqlStatement;
1327 if (unlikely(pos < 1 || (uintType) pos > preparedStmt->param_array_size)) {
1328 logError(printf("sqlBindBool: pos: " FMT_D ", max pos: " FMT_U_MEM ".\n",
1329 pos, preparedStmt->param_array_size););
1330 raise_error(RANGE_ERROR);
1331 } else {
1332 strDestr(preparedStmt->param_array[pos - 1].buffer);
1333 preparedStmt->param_array[pos - 1].buffer = intStr(value);
1334 } /* if */
1335 } /* sqlBindBool */
1336
1337
1338
sqlBindBStri(sqlStmtType sqlStatement,intType pos,const const_bstriType bstri)1339 static void sqlBindBStri (sqlStmtType sqlStatement, intType pos,
1340 const const_bstriType bstri)
1341
1342 {
1343 const unsigned char digit[] = {'0', '1', '2', '3', '4', '5', '6', '7',
1344 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
1345 preparedStmtType preparedStmt;
1346 striType stri;
1347 memSizeType idx;
1348
1349 /* sqlBindBStri */
1350 logFunction(printf("sqlBindBStri(" FMT_U_MEM ", " FMT_D ", \"%s\")\n",
1351 (memSizeType) sqlStatement, pos, bstriAsUnquotedCStri(bstri)););
1352 preparedStmt = (preparedStmtType) sqlStatement;
1353 if (unlikely(pos < 1 || (uintType) pos > preparedStmt->param_array_size)) {
1354 logError(printf("sqlBindBStri: pos: " FMT_D ", max pos: " FMT_U_MEM ".\n",
1355 pos, preparedStmt->param_array_size););
1356 raise_error(RANGE_ERROR);
1357 } else {
1358 strDestr(preparedStmt->param_array[pos - 1].buffer);
1359 if (unlikely(bstri->size > (MAX_STRI_LEN - 2) / 2 ||
1360 !ALLOC_STRI_CHECK_SIZE(stri, 2 + 2 * bstri->size))) {
1361 raise_error(MEMORY_ERROR);
1362 } else {
1363 stri->size = 2 + 2 * bstri->size;
1364 stri->mem[0] = '0';
1365 stri->mem[1] = 'x';
1366 for (idx = 0; idx < bstri->size; idx++) {
1367 stri->mem[(idx << 1) + 2] = digit[bstri->mem[idx] >> 4];
1368 stri->mem[(idx << 1) + 3] = digit[bstri->mem[idx] & 0xf];
1369 } /* for */
1370 preparedStmt->param_array[pos - 1].buffer = stri;
1371 } /* if */
1372 } /* if */
1373 } /* sqlBindBStri */
1374
1375
1376
sqlBindDuration(sqlStmtType sqlStatement,intType pos,intType year,intType month,intType day,intType hour,intType minute,intType second,intType micro_second)1377 static void sqlBindDuration (sqlStmtType sqlStatement, intType pos,
1378 intType year, intType month, intType day, intType hour,
1379 intType minute, intType second, intType micro_second)
1380
1381 {
1382 preparedStmtType preparedStmt;
1383
1384 /* sqlBindDuration */
1385 logFunction(printf("sqlBindDuration(" FMT_U_MEM ", " FMT_D ", P"
1386 FMT_D "Y" FMT_D "M" FMT_D "DT"
1387 FMT_D "H" FMT_D "M%s%lu.%06luS)\n",
1388 (memSizeType) sqlStatement, pos,
1389 year, month, day, hour, minute,
1390 second < 0 || micro_second < 0 ? "-" : "",
1391 intAbs(second), intAbs(micro_second)););
1392 preparedStmt = (preparedStmtType) sqlStatement;
1393 if (unlikely(pos < 1 || (uintType) pos > preparedStmt->param_array_size)) {
1394 logError(printf("sqlBindDuration: pos: " FMT_D ", max pos: " FMT_U_MEM ".\n",
1395 pos, preparedStmt->param_array_size););
1396 raise_error(RANGE_ERROR);
1397 } else if (unlikely(year < -9999 || year > 9999 || month < -12 || month > 12 ||
1398 day < -31 || day > 31 || hour <= -24 || hour >= 24 ||
1399 minute <= -60 || minute >= 60 || second <= -60 || second >= 60 ||
1400 micro_second <= -1000000 || micro_second >= 1000000)) {
1401 logError(printf("sqlBindDuration: Duration not in allowed range.\n"););
1402 raise_error(RANGE_ERROR);
1403 } else {
1404 } /* if */
1405 } /* sqlBindDuration */
1406
1407
1408
sqlBindFloat(sqlStmtType sqlStatement,intType pos,floatType value)1409 static void sqlBindFloat (sqlStmtType sqlStatement, intType pos, floatType value)
1410
1411 {
1412 preparedStmtType preparedStmt;
1413
1414 /* sqlBindFloat */
1415 logFunction(printf("sqlBindFloat(" FMT_U_MEM ", " FMT_D ", " FMT_E ")\n",
1416 (memSizeType) sqlStatement, pos, value););
1417 preparedStmt = (preparedStmtType) sqlStatement;
1418 if (unlikely(pos < 1 || (uintType) pos > preparedStmt->param_array_size)) {
1419 logError(printf("sqlBindFloat: pos: " FMT_D ", max pos: " FMT_U_MEM ".\n",
1420 pos, preparedStmt->param_array_size););
1421 raise_error(RANGE_ERROR);
1422 } else {
1423 strDestr(preparedStmt->param_array[pos - 1].buffer);
1424 preparedStmt->param_array[pos - 1].buffer = fltStr(value);
1425 } /* if */
1426 } /* sqlBindFloat */
1427
1428
1429
sqlBindInt(sqlStmtType sqlStatement,intType pos,intType value)1430 static void sqlBindInt (sqlStmtType sqlStatement, intType pos, intType value)
1431
1432 {
1433 preparedStmtType preparedStmt;
1434
1435 /* sqlBindInt */
1436 logFunction(printf("sqlBindInt(" FMT_U_MEM ", " FMT_D ", " FMT_D ")\n",
1437 (memSizeType) sqlStatement, pos, value););
1438 preparedStmt = (preparedStmtType) sqlStatement;
1439 if (unlikely(pos < 1 || (uintType) pos > preparedStmt->param_array_size)) {
1440 logError(printf("sqlBindInt: pos: " FMT_D ", max pos: " FMT_U_MEM ".\n",
1441 pos, preparedStmt->param_array_size););
1442 raise_error(RANGE_ERROR);
1443 } else {
1444 strDestr(preparedStmt->param_array[pos - 1].buffer);
1445 preparedStmt->param_array[pos - 1].buffer = intStr(value);
1446 } /* if */
1447 } /* sqlBindInt */
1448
1449
1450
sqlBindNull(sqlStmtType sqlStatement,intType pos)1451 static void sqlBindNull (sqlStmtType sqlStatement, intType pos)
1452
1453 {
1454 preparedStmtType preparedStmt;
1455
1456 /* sqlBindNull */
1457 logFunction(printf("sqlBindNull(" FMT_U_MEM ", " FMT_D ")\n",
1458 (memSizeType) sqlStatement, pos););
1459 preparedStmt = (preparedStmtType) sqlStatement;
1460 if (unlikely(pos < 1 || (uintType) pos > preparedStmt->param_array_size)) {
1461 logError(printf("sqlBindNull: pos: " FMT_D ", max pos: " FMT_U_MEM ".\n",
1462 pos, preparedStmt->param_array_size););
1463 raise_error(RANGE_ERROR);
1464 } else {
1465 strDestr(preparedStmt->param_array[pos - 1].buffer);
1466 preparedStmt->param_array[pos - 1].buffer = cstri_to_stri("NULL");
1467 if (unlikely(preparedStmt->param_array[pos - 1].buffer == NULL)) {
1468 raise_error(MEMORY_ERROR);
1469 } /* if */
1470 } /* if */
1471 } /* sqlBindNull */
1472
1473
1474
sqlBindStri(sqlStmtType sqlStatement,intType pos,const const_striType stri)1475 static void sqlBindStri (sqlStmtType sqlStatement, intType pos,
1476 const const_striType stri)
1477
1478 {
1479 preparedStmtType preparedStmt;
1480
1481 /* sqlBindStri */
1482 logFunction(printf("sqlBindStri(" FMT_U_MEM ", " FMT_D ", \"%s\")\n",
1483 (memSizeType) sqlStatement, pos, striAsUnquotedCStri(stri)););
1484 preparedStmt = (preparedStmtType) sqlStatement;
1485 if (unlikely(pos < 1 || (uintType) pos > preparedStmt->param_array_size)) {
1486 logError(printf("sqlBindStri: pos: " FMT_D ", max pos: " FMT_U_MEM ".\n",
1487 pos, preparedStmt->param_array_size););
1488 raise_error(RANGE_ERROR);
1489 } else {
1490 strDestr(preparedStmt->param_array[pos - 1].buffer);
1491 preparedStmt->param_array[pos - 1].buffer = genSqlStringLiteral(stri);
1492 } /* if */
1493 } /* sqlBindStri */
1494
1495
1496
sqlBindTime(sqlStmtType sqlStatement,intType pos,intType year,intType month,intType day,intType hour,intType minute,intType second,intType micro_second,intType time_zone)1497 static void sqlBindTime (sqlStmtType sqlStatement, intType pos,
1498 intType year, intType month, intType day, intType hour,
1499 intType minute, intType second, intType micro_second,
1500 intType time_zone)
1501
1502 {
1503 preparedStmtType preparedStmt;
1504 char timeLiteral[MAX_TIME_LITERAL_LENGTH + NULL_TERMINATION_LEN];
1505 memSizeType idx;
1506
1507 /* sqlBindTime */
1508 logFunction(printf("sqlBindTime(" FMT_U_MEM ", " FMT_D ", "
1509 F_D(04) "-" F_D(02) "-" F_D(02) " "
1510 F_D(02) ":" F_D(02) ":" F_D(02) "." F_D(06) ", "
1511 FMT_D ")\n",
1512 (memSizeType) sqlStatement, pos,
1513 year, month, day,
1514 hour, minute, second, micro_second,
1515 time_zone););
1516 preparedStmt = (preparedStmtType) sqlStatement;
1517 if (unlikely(pos < 1 || (uintType) pos > preparedStmt->param_array_size)) {
1518 logError(printf("sqlBindTime: pos: " FMT_D ", max pos: " FMT_U_MEM ".\n",
1519 pos, preparedStmt->param_array_size););
1520 raise_error(RANGE_ERROR);
1521 } else if (unlikely(year < -9999 || year > 9999 || month < 1 || month > 12 ||
1522 day < 1 || day > 31 || hour < 0 || hour >= 24 ||
1523 minute < 0 || minute >= 60 || second < 0 || second >= 60 ||
1524 micro_second < 0 || micro_second >= 1000000)) {
1525 logError(printf("sqlBindTime: Time not in allowed range.\n"););
1526 raise_error(RANGE_ERROR);
1527 } else {
1528 if ((hour == 0 && minute == 0 && second == 0 && micro_second == 0) &&
1529 (year != 0 || month != 1 || day != 1)) {
1530 sprintf(timeLiteral, "'" F_D(04) "-" F_D(02) "-" F_D(02) "'",
1531 year, month, day);
1532 } else {
1533 if (year == 0 && month == 1 && day == 1) {
1534 sprintf(timeLiteral, "'" F_D(02) ":" F_D(02) ":" F_D(02),
1535 hour, minute, second);
1536 } else {
1537 sprintf(timeLiteral, "'" F_D(04) "-" F_D(02) "-" F_D(02)
1538 " " F_D(02) ":" F_D(02) ":" F_D(02),
1539 year, month, day, hour, minute, second);
1540 } /* if */
1541 if (micro_second == 0) {
1542 strcat(timeLiteral, "'");
1543 } else {
1544 sprintf(&timeLiteral[strlen(timeLiteral)], "." F_U(06),
1545 micro_second);
1546 idx = strlen(timeLiteral);
1547 do {
1548 idx--;
1549 } while (timeLiteral[idx] == '0');
1550 timeLiteral[idx + 1] = '\'';
1551 timeLiteral[idx + 2] = '\0';
1552 } /* if */
1553 } /* if */
1554 strDestr(preparedStmt->param_array[pos - 1].buffer);
1555 preparedStmt->param_array[pos - 1].buffer = cstri_to_stri(timeLiteral);
1556 if (unlikely(preparedStmt->param_array[pos - 1].buffer == NULL)) {
1557 raise_error(MEMORY_ERROR);
1558 } /* if */
1559 } /* if */
1560 } /* sqlBindTime */
1561
1562
1563
sqlClose(databaseType database)1564 static void sqlClose (databaseType database)
1565
1566 {
1567 dbType db;
1568
1569 /* sqlClose */
1570 logFunction(printf("sqlClose(" FMT_U_MEM ")\n",
1571 (memSizeType) database););
1572 db = (dbType) database;
1573 if (db->dbproc != NULL) {
1574 dbclose(db->dbproc);
1575 db->dbproc = NULL;
1576 } /* if */
1577 logFunction(printf("sqlClose -->\n"););
1578 } /* sqlClose */
1579
1580
1581
sqlColumnBigInt(sqlStmtType sqlStatement,intType column)1582 static bigIntType sqlColumnBigInt (sqlStmtType sqlStatement, intType column)
1583
1584 {
1585 preparedStmtType preparedStmt;
1586 resultDataType columnData;
1587 BYTE *data;
1588 DBINT length;
1589 bigIntType columnValue;
1590
1591 /* sqlColumnBigInt */
1592 logFunction(printf("sqlColumnBigInt(" FMT_U_MEM ", " FMT_D ")\n",
1593 (memSizeType) sqlStatement, column););
1594 preparedStmt = (preparedStmtType) sqlStatement;
1595 if (unlikely(!preparedStmt->fetchOkay || column < 1 ||
1596 (uintType) column > preparedStmt->result_array_size)) {
1597 logError(printf("sqlColumnBigInt: Fetch okay: %d, column: " FMT_D
1598 ", max column: " FMT_U_MEM ".\n",
1599 preparedStmt->fetchOkay, column,
1600 preparedStmt->result_array_size););
1601 raise_error(RANGE_ERROR);
1602 columnValue = NULL;
1603 } else {
1604 columnData = &preparedStmt->result_array[column - 1];
1605 data = dbdata(preparedStmt->dbproc, (int) column);
1606 if (data == NULL) {
1607 length = dbdatlen(preparedStmt->dbproc, (int) column);
1608 if (likely(length == 0)) {
1609 columnValue = bigZero();
1610 } else {
1611 dbInconsistent("sqlColumnBigInt", "dbdatlen");
1612 logError(printf("sqlColumnBigInt: Column " FMT_D ": "
1613 "dbdatlen returns %d.\n", column, length););
1614 raise_error(DATABASE_ERROR);
1615 columnValue = NULL;
1616 } /* if */
1617 } else {
1618 /* printf("buffer: %s\n", (unsigned char *) columnData->buffer); */
1619 /* printf("buffer_type: %s\n",
1620 nameOfBufferType(columnData->buffer_type)); */
1621 switch (columnData->buffer_type) {
1622 case SYBINT1:
1623 #if SYBINT1_IS_SIGNED
1624 columnValue = bigFromInt32((int32Type) *(int8Type *) data);
1625 #else
1626 columnValue = bigFromInt32((int32Type) *(uint8Type *) data);
1627 #endif
1628 break;
1629 case SYBINT2:
1630 columnValue = bigFromInt32((int32Type) *(int16Type *) data);
1631 break;
1632 case SYBINT4:
1633 columnValue = bigFromInt32(*(int32Type *) data);
1634 break;
1635 case SYBINT8:
1636 columnValue = bigFromInt64(*(int64Type *) data);
1637 break;
1638 case SYBDECIMAL:
1639 case SYBNUMERIC:
1640 columnValue = getNumericBigInt(data);
1641 break;
1642 default:
1643 logError(printf("sqlColumnBigInt: Column " FMT_D " has the unknown type %s.\n",
1644 column, nameOfBufferType(columnData->buffer_type)););
1645 raise_error(RANGE_ERROR);
1646 columnValue = NULL;
1647 break;
1648 } /* switch */
1649 } /* if */
1650 } /* if */
1651 logFunction(printf("sqlColumnBigInt --> %s\n", bigHexCStri(columnValue)););
1652 return columnValue;
1653 } /* sqlColumnBigInt */
1654
1655
1656
sqlColumnBigRat(sqlStmtType sqlStatement,intType column,bigIntType * numerator,bigIntType * denominator)1657 static void sqlColumnBigRat (sqlStmtType sqlStatement, intType column,
1658 bigIntType *numerator, bigIntType *denominator)
1659
1660 {
1661 preparedStmtType preparedStmt;
1662 resultDataType columnData;
1663 BYTE *data;
1664 DBINT length;
1665
1666 /* sqlColumnBigRat */
1667 logFunction(printf("sqlColumnBigRat(" FMT_U_MEM ", " FMT_D ", *, *)\n",
1668 (memSizeType) sqlStatement, column););
1669 preparedStmt = (preparedStmtType) sqlStatement;
1670 if (unlikely(!preparedStmt->fetchOkay || column < 1 ||
1671 (uintType) column > preparedStmt->result_array_size)) {
1672 logError(printf("sqlColumnBigRat: Fetch okay: %d, column: " FMT_D
1673 ", max column: " FMT_U_MEM ".\n",
1674 preparedStmt->fetchOkay, column,
1675 preparedStmt->result_array_size););
1676 raise_error(RANGE_ERROR);
1677 } else {
1678 columnData = &preparedStmt->result_array[column - 1];
1679 data = dbdata(preparedStmt->dbproc, (int) column);
1680 if (data == NULL) {
1681 length = dbdatlen(preparedStmt->dbproc, (int) column);
1682 if (likely(length == 0)) {
1683 *numerator = bigZero();
1684 *denominator = bigFromInt32(1);
1685 } else {
1686 dbInconsistent("sqlColumnBigRat", "dbdatlen");
1687 logError(printf("sqlColumnBigRat: Column " FMT_D ": "
1688 "dbdatlen returns %d.\n", column, length););
1689 raise_error(DATABASE_ERROR);
1690 } /* if */
1691 } else {
1692 /* printf("buffer: %s\n", (unsigned char *) columnData->buffer); */
1693 /* printf("buffer_type: %s\n",
1694 nameOfBufferType(columnData->buffer_type)); */
1695 switch (columnData->buffer_type) {
1696 case SYBINT1:
1697 #if SYBINT1_IS_SIGNED
1698 *numerator = bigFromInt32((int32Type) *(int8Type *) data);
1699 #else
1700 *numerator = bigFromInt32((int32Type) *(uint8Type *) data);
1701 #endif
1702 *denominator = bigFromInt32(1);
1703 break;
1704 case SYBINT2:
1705 *numerator = bigFromInt32((int32Type) *(int16Type *) data);
1706 *denominator = bigFromInt32(1);
1707 break;
1708 case SYBINT4:
1709 *numerator = bigFromInt32(*(int32Type *) data);
1710 *denominator = bigFromInt32(1);
1711 break;
1712 case SYBINT8:
1713 *numerator = bigFromInt64(*(int64Type *) data);
1714 *denominator = bigFromInt32(1);
1715 break;
1716 case SYBDECIMAL:
1717 case SYBNUMERIC:
1718 *numerator = getNumericBigRational(data, denominator);
1719 break;
1720 default:
1721 logError(printf("sqlColumnBigRat: Column " FMT_D " has the unknown type %s.\n",
1722 column, nameOfBufferType(columnData->buffer_type)););
1723 raise_error(RANGE_ERROR);
1724 break;
1725 } /* switch */
1726 } /* if */
1727 } /* if */
1728 logFunction(printf("sqlColumnBigRat(" FMT_U_MEM ", " FMT_D ", %s, %s) -->\n",
1729 (memSizeType) sqlStatement, column,
1730 bigHexCStri(*numerator), bigHexCStri(*denominator)););
1731 } /* sqlColumnBigRat */
1732
1733
1734
sqlColumnBool(sqlStmtType sqlStatement,intType column)1735 static boolType sqlColumnBool (sqlStmtType sqlStatement, intType column)
1736
1737 {
1738 preparedStmtType preparedStmt;
1739 resultDataType columnData;
1740 BYTE *data;
1741 DBINT length;
1742 intType columnValue;
1743
1744 /* sqlColumnBool */
1745 logFunction(printf("sqlColumnBool(" FMT_U_MEM ", " FMT_D ")\n",
1746 (memSizeType) sqlStatement, column););
1747 preparedStmt = (preparedStmtType) sqlStatement;
1748 if (unlikely(!preparedStmt->fetchOkay || column < 1 ||
1749 (uintType) column > preparedStmt->result_array_size)) {
1750 logError(printf("sqlColumnBool: Fetch okay: %d, column: " FMT_D
1751 ", max column: " FMT_U_MEM ".\n",
1752 preparedStmt->fetchOkay, column,
1753 preparedStmt->result_array_size););
1754 raise_error(RANGE_ERROR);
1755 columnValue = 0;
1756 } else {
1757 columnData = &preparedStmt->result_array[column - 1];
1758 data = dbdata(preparedStmt->dbproc, (int) column);
1759 if (data == NULL) {
1760 length = dbdatlen(preparedStmt->dbproc, (int) column);
1761 if (likely(length == 0)) {
1762 columnValue = 0;
1763 } else {
1764 dbInconsistent("sqlColumnBool", "dbdatlen");
1765 logError(printf("sqlColumnBool: Column " FMT_D ": "
1766 "dbdatlen returns %d.\n", column, length););
1767 raise_error(DATABASE_ERROR);
1768 columnValue = 0;
1769 } /* if */
1770 } else {
1771 /* printf("buffer: %s\n", (unsigned char *) columnData->buffer); */
1772 /* printf("buffer_type: %s\n",
1773 nameOfBufferType(columnData->buffer_type)); */
1774 switch (columnData->buffer_type) {
1775 case SYBINT1:
1776 #if SYBINT1_IS_SIGNED
1777 columnValue = *(int8Type *) data;
1778 #else
1779 columnValue = *(uint8Type *) data;
1780 #endif
1781 break;
1782 case SYBINT2:
1783 columnValue = *(int16Type *) data;
1784 break;
1785 case SYBINT4:
1786 columnValue = *(int32Type *) data;
1787 break;
1788 case SYBINT8:
1789 columnValue = *(int64Type *) data;
1790 break;
1791 case SYBDECIMAL:
1792 case SYBNUMERIC:
1793 columnValue = getNumericInt(data);
1794 break;
1795 case SYBCHAR:
1796 case SYBVARCHAR:
1797 length = dbdatlen(preparedStmt->dbproc, (int) column);
1798 /* printf("length: " FMT_D32 "\n", length); */
1799 if (length == -1) {
1800 columnValue = 0;
1801 } else if (unlikely(length != 1)) {
1802 logError(printf("sqlColumnBool: Column " FMT_D ": "
1803 "The size of a boolean field must be 1.\n", column););
1804 raise_error(RANGE_ERROR);
1805 columnValue = 0;
1806 } else {
1807 columnValue = *(const_cstriType) data - '0';
1808 } /* if */
1809 break;
1810 default:
1811 logError(printf("sqlColumnBool: Column " FMT_D " has the unknown type %s.\n",
1812 column, nameOfBufferType(columnData->buffer_type)););
1813 raise_error(RANGE_ERROR);
1814 columnValue = 0;
1815 break;
1816 } /* switch */
1817 if (unlikely((uintType) columnValue >= 2)) {
1818 logError(printf("sqlColumnBool: Column " FMT_D ": "
1819 FMT_D " is not an allowed boolean value.\n",
1820 column, columnValue););
1821 raise_error(RANGE_ERROR);
1822 } /* if */
1823 } /* if */
1824 } /* if */
1825 logFunction(printf("sqlColumnBool --> %s\n", columnValue ? "TRUE" : "FALSE"););
1826 return columnValue != 0;
1827 } /* sqlColumnBool */
1828
1829
1830
sqlColumnBStri(sqlStmtType sqlStatement,intType column)1831 static bstriType sqlColumnBStri (sqlStmtType sqlStatement, intType column)
1832
1833 {
1834 preparedStmtType preparedStmt;
1835 resultDataType columnData;
1836 DBINT length;
1837 bstriType columnValue;
1838
1839 /* sqlColumnBStri */
1840 logFunction(printf("sqlColumnBStri(" FMT_U_MEM ", " FMT_D ")\n",
1841 (memSizeType) sqlStatement, column););
1842 preparedStmt = (preparedStmtType) sqlStatement;
1843 if (unlikely(!preparedStmt->fetchOkay || column < 1 ||
1844 (uintType) column > preparedStmt->result_array_size)) {
1845 logError(printf("sqlColumnBStri: Fetch okay: %d, column: " FMT_D
1846 ", max column: " FMT_U_MEM ".\n",
1847 preparedStmt->fetchOkay, column,
1848 preparedStmt->result_array_size););
1849 raise_error(RANGE_ERROR);
1850 columnValue = NULL;
1851 } else {
1852 columnData = &preparedStmt->result_array[column - 1];
1853 /* printf("buffer: %s\n", (unsigned char *) columnData->buffer); */
1854 /* printf("buffer_type: %s\n",
1855 nameOfBufferType(columnData->buffer_type)); */
1856 switch (columnData->buffer_type) {
1857 case SYBBINARY:
1858 case SYBVARBINARY:
1859 length = dbdatlen(preparedStmt->dbproc, (int) column);
1860 /* printf("length: " FMT_D32 "\n", length); */
1861 if (unlikely(length < 0)) {
1862 dbInconsistent("sqlColumnBStri", "dbdatlen");
1863 logError(printf("sqlColumnBStri: Column " FMT_D ": "
1864 "dbdatlen returns %d.\n", column, length););
1865 raise_error(DATABASE_ERROR);
1866 columnValue = NULL;
1867 } else if (unlikely(!ALLOC_BSTRI_CHECK_SIZE(columnValue, (memSizeType) length))) {
1868 raise_error(MEMORY_ERROR);
1869 } else {
1870 columnValue->size = (memSizeType) length;
1871 memcpy(columnValue->mem,
1872 (ustriType) dbdata(preparedStmt->dbproc, (int) column),
1873 (memSizeType) length);
1874 } /* if */
1875 break;
1876 default:
1877 logError(printf("sqlColumnBStri: Column " FMT_D " has the unknown type %s.\n",
1878 column, nameOfBufferType(columnData->buffer_type)););
1879 raise_error(RANGE_ERROR);
1880 columnValue = NULL;
1881 break;
1882 } /* switch */
1883 } /* if */
1884 logFunction(printf("sqlColumnBStri --> \"%s\"\n", bstriAsUnquotedCStri(columnValue)););
1885 return columnValue;
1886 } /* sqlColumnBStri */
1887
1888
1889
sqlColumnDuration(sqlStmtType sqlStatement,intType column,intType * year,intType * month,intType * day,intType * hour,intType * minute,intType * second,intType * micro_second)1890 static void sqlColumnDuration (sqlStmtType sqlStatement, intType column,
1891 intType *year, intType *month, intType *day, intType *hour,
1892 intType *minute, intType *second, intType *micro_second)
1893
1894 {
1895 preparedStmtType preparedStmt;
1896 resultDataType columnData;
1897 BYTE *data;
1898 DBINT length;
1899
1900 /* sqlColumnDuration */
1901 logFunction(printf("sqlColumnDuration(" FMT_U_MEM ", " FMT_D ", *)\n",
1902 (memSizeType) sqlStatement, column););
1903 preparedStmt = (preparedStmtType) sqlStatement;
1904 if (unlikely(!preparedStmt->fetchOkay || column < 1 ||
1905 (uintType) column > preparedStmt->result_array_size)) {
1906 logError(printf("sqlColumnDuration: Fetch okay: %d, column: " FMT_D
1907 ", max column: " FMT_U_MEM ".\n",
1908 preparedStmt->fetchOkay, column,
1909 preparedStmt->result_array_size););
1910 raise_error(RANGE_ERROR);
1911 } else {
1912 columnData = &preparedStmt->result_array[column - 1];
1913 data = dbdata(preparedStmt->dbproc, (int) column);
1914 if (data == NULL) {
1915 length = dbdatlen(preparedStmt->dbproc, (int) column);
1916 /* printf("length: " FMT_D32 "\n", length); */
1917 if (likely(length == 0)) {
1918 /* printf("Column is NULL -> Use default value: P0D\n"); */
1919 *year = 0;
1920 *month = 0;
1921 *day = 0;
1922 *hour = 0;
1923 *minute = 0;
1924 *second = 0;
1925 *micro_second = 0;
1926 } else {
1927 dbInconsistent("sqlColumnDuration", "dbdatlen");
1928 logError(printf("sqlColumnDuration: Column " FMT_D ": "
1929 "dbdatlen returns %d.\n", column, length););
1930 raise_error(DATABASE_ERROR);
1931 } /* if */
1932 } else {
1933 /* printf("buffer: %s\n", (unsigned char *) columnData->buffer); */
1934 /* printf("buffer_type: %s\n",
1935 nameOfBufferType(columnData->buffer_type)); */
1936 switch (columnData->buffer_type) {
1937 default:
1938 logError(printf("sqlColumnDuration: Column " FMT_D " has the unknown type %s.\n",
1939 column, nameOfBufferType(columnData->buffer_type)););
1940 raise_error(RANGE_ERROR);
1941 break;
1942 } /* switch */
1943 } /* if */
1944 } /* if */
1945 logFunction(printf("sqlColumnDuration(" FMT_U_MEM ", " FMT_D ") --> P"
1946 FMT_D "Y" FMT_D "M" FMT_D "DT"
1947 FMT_D "H" FMT_D "M%s" FMT_U "." F_U(06) "S\n",
1948 (memSizeType) sqlStatement, column,
1949 *year, *month, *day, *hour, *minute,
1950 *second < 0 || *micro_second < 0 ? "-" : "",
1951 intAbs(*second), intAbs(*micro_second)););
1952 } /* sqlColumnDuration */
1953
1954
1955
sqlColumnFloat(sqlStmtType sqlStatement,intType column)1956 static floatType sqlColumnFloat (sqlStmtType sqlStatement, intType column)
1957
1958 {
1959 preparedStmtType preparedStmt;
1960 resultDataType columnData;
1961 BYTE *data;
1962 DBINT length;
1963 floatType columnValue;
1964
1965 /* sqlColumnFloat */
1966 logFunction(printf("sqlColumnFloat(" FMT_U_MEM ", " FMT_D ")\n",
1967 (memSizeType) sqlStatement, column););
1968 preparedStmt = (preparedStmtType) sqlStatement;
1969 if (unlikely(!preparedStmt->fetchOkay || column < 1 ||
1970 (uintType) column > preparedStmt->result_array_size)) {
1971 logError(printf("sqlColumnFloat: Fetch okay: %d, column: " FMT_D
1972 ", max column: " FMT_U_MEM ".\n",
1973 preparedStmt->fetchOkay, column,
1974 preparedStmt->result_array_size););
1975 raise_error(RANGE_ERROR);
1976 columnValue = 0.0;
1977 } else {
1978 columnData = &preparedStmt->result_array[column - 1];
1979 data = dbdata(preparedStmt->dbproc, (int) column);
1980 if (data == NULL) {
1981 length = dbdatlen(preparedStmt->dbproc, (int) column);
1982 if (likely(length == 0)) {
1983 columnValue = 0.0;
1984 } else {
1985 dbInconsistent("sqlColumnFloat", "dbdatlen");
1986 logError(printf("sqlColumnFloat: Column " FMT_D ": "
1987 "dbdatlen returns %d.\n", column, length););
1988 raise_error(DATABASE_ERROR);
1989 columnValue = 0.0;
1990 } /* if */
1991 } else {
1992 /* printf("buffer: %s\n", (unsigned char *) columnData->buffer); */
1993 /* printf("buffer_type: %s\n",
1994 nameOfBufferType(columnData->buffer_type)); */
1995 switch (columnData->buffer_type) {
1996 case SYBINT1:
1997 #if SYBINT1_IS_SIGNED
1998 columnValue = (floatType) *(int8Type *) data;
1999 #else
2000 columnValue = (floatType) *(uint8Type *) data;
2001 #endif
2002 break;
2003 case SYBINT2:
2004 columnValue = (floatType) *(int16Type *) data;
2005 break;
2006 case SYBINT4:
2007 columnValue = (floatType) *(int32Type *) data;
2008 break;
2009 case SYBINT8:
2010 columnValue = (floatType) *(int64Type *) data;
2011 break;
2012 case SYBREAL:
2013 columnValue = *(float *) data;
2014 break;
2015 case SYBFLT8:
2016 columnValue = *(double *) data;
2017 break;
2018 case SYBDECIMAL:
2019 case SYBNUMERIC:
2020 columnValue = getNumericFloat(data);
2021 break;
2022 default:
2023 logError(printf("sqlColumnFloat: Column " FMT_D " has the unknown type %s.\n",
2024 column, nameOfBufferType(columnData->buffer_type)););
2025 raise_error(RANGE_ERROR);
2026 columnValue = 0.0;
2027 break;
2028 } /* switch */
2029 } /* if */
2030 } /* if */
2031 logFunction(printf("sqlColumnFloat --> " FMT_E "\n", columnValue););
2032 return columnValue;
2033 } /* sqlColumnFloat */
2034
2035
2036
sqlColumnInt(sqlStmtType sqlStatement,intType column)2037 static intType sqlColumnInt (sqlStmtType sqlStatement, intType column)
2038
2039 {
2040 preparedStmtType preparedStmt;
2041 resultDataType columnData;
2042 BYTE *data;
2043 DBINT length;
2044 intType columnValue;
2045
2046 /* sqlColumnInt */
2047 logFunction(printf("sqlColumnInt(" FMT_U_MEM ", " FMT_D ")\n",
2048 (memSizeType) sqlStatement, column););
2049 preparedStmt = (preparedStmtType) sqlStatement;
2050 if (unlikely(!preparedStmt->fetchOkay || column < 1 ||
2051 (uintType) column > preparedStmt->result_array_size)) {
2052 logError(printf("sqlColumnInt: Fetch okay: %d, column: " FMT_D
2053 ", max column: " FMT_U_MEM ".\n",
2054 preparedStmt->fetchOkay, column,
2055 preparedStmt->result_array_size););
2056 raise_error(RANGE_ERROR);
2057 columnValue = 0;
2058 } else {
2059 columnData = &preparedStmt->result_array[column - 1];
2060 data = dbdata(preparedStmt->dbproc, (int) column);
2061 if (data == NULL) {
2062 length = dbdatlen(preparedStmt->dbproc, (int) column);
2063 if (likely(length == 0)) {
2064 columnValue = 0.0;
2065 } else {
2066 dbInconsistent("sqlColumnInt", "dbdatlen");
2067 logError(printf("sqlColumnInt: Column " FMT_D ": "
2068 "dbdatlen returns %d.\n", column, length););
2069 raise_error(DATABASE_ERROR);
2070 columnValue = 0.0;
2071 } /* if */
2072 } else {
2073 /* printf("buffer: %s\n", (unsigned char *) columnData->buffer); */
2074 /* printf("buffer_type: %s\n",
2075 nameOfBufferType(columnData->buffer_type)); */
2076 switch (columnData->buffer_type) {
2077 case SYBINT1:
2078 #if SYBINT1_IS_SIGNED
2079 columnValue = *(int8Type *) data;
2080 #else
2081 columnValue = *(uint8Type *) data;
2082 #endif
2083 break;
2084 case SYBINT2:
2085 columnValue = *(int16Type *) data;
2086 break;
2087 case SYBINT4:
2088 columnValue = *(int32Type *) data;
2089 break;
2090 case SYBINT8:
2091 columnValue = *(int64Type *) data;
2092 break;
2093 case SYBDECIMAL:
2094 case SYBNUMERIC:
2095 columnValue = getNumericInt(data);
2096 break;
2097 default:
2098 logError(printf("sqlColumnInt: Column " FMT_D " has the unknown type %s.\n",
2099 column, nameOfBufferType(columnData->buffer_type)););
2100 raise_error(RANGE_ERROR);
2101 columnValue = 0;
2102 break;
2103 } /* switch */
2104 } /* if */
2105 } /* if */
2106 logFunction(printf("sqlColumnInt --> " FMT_D "\n", columnValue););
2107 return columnValue;
2108 } /* sqlColumnInt */
2109
2110
2111
sqlColumnStri(sqlStmtType sqlStatement,intType column)2112 static striType sqlColumnStri (sqlStmtType sqlStatement, intType column)
2113
2114 {
2115 preparedStmtType preparedStmt;
2116 resultDataType columnData;
2117 BYTE *data;
2118 DBINT length;
2119 errInfoType err_info = OKAY_NO_ERROR;
2120 striType columnValue;
2121
2122 /* sqlColumnStri */
2123 logFunction(printf("sqlColumnStri(" FMT_U_MEM ", " FMT_D ")\n",
2124 (memSizeType) sqlStatement, column););
2125 preparedStmt = (preparedStmtType) sqlStatement;
2126 if (unlikely(!preparedStmt->fetchOkay || column < 1 ||
2127 (uintType) column > preparedStmt->result_array_size)) {
2128 logError(printf("sqlColumnStri: Fetch okay: %d, column: " FMT_D
2129 ", max column: " FMT_U_MEM ".\n",
2130 preparedStmt->fetchOkay, column,
2131 preparedStmt->result_array_size););
2132 raise_error(RANGE_ERROR);
2133 columnValue = NULL;
2134 } else {
2135 columnData = &preparedStmt->result_array[column - 1];
2136 data = dbdata(preparedStmt->dbproc, (int) column);
2137 /* printf("data: " FMT_U_MEM "\n", (memSizeType) data); */
2138 length = dbdatlen(preparedStmt->dbproc, (int) column);
2139 /* printf("length: " FMT_D32 "\n", length); */
2140 if (unlikely(length < 0)) {
2141 dbInconsistent("sqlColumnStri", "dbdatlen");
2142 logError(printf("sqlColumnStri: Column " FMT_D ": "
2143 "dbdatlen returns %d.\n", column, length););
2144 raise_error(DATABASE_ERROR);
2145 columnValue = NULL;
2146 } else if (data == NULL) {
2147 if (likely(length == 0)) {
2148 columnValue = strEmpty();
2149 } else {
2150 dbInconsistent("sqlColumnStri", "dbdatlen");
2151 logError(printf("sqlColumnStri: Column " FMT_D ": "
2152 "dbdatlen returns %d.\n", column, length););
2153 raise_error(DATABASE_ERROR);
2154 columnValue = NULL;
2155 } /* if */
2156 } else {
2157 /* printf("buffer: %s\n", (unsigned char *) columnData->buffer); */
2158 /* printf("buffer_type: %s\n",
2159 nameOfBufferType(columnData->buffer_type)); */
2160 switch (columnData->buffer_type) {
2161 case SYBCHAR:
2162 while (length > 0 && data[length - 1] == ' ') {
2163 length--;
2164 } /* if */
2165 columnValue = cstri8_buf_to_stri((const_cstriType) data,
2166 (memSizeType) length, &err_info);
2167 if (unlikely(columnValue == NULL)) {
2168 raise_error(err_info);
2169 } /* if */
2170 break;
2171 case SYBVARCHAR:
2172 columnValue = cstri8_buf_to_stri((const_cstriType) data,
2173 (memSizeType) length, &err_info);
2174 if (unlikely(columnValue == NULL)) {
2175 raise_error(err_info);
2176 } /* if */
2177 break;
2178 case SYBBINARY:
2179 case SYBVARBINARY:
2180 if (unlikely(!ALLOC_STRI_CHECK_SIZE(columnValue, (memSizeType) length))) {
2181 raise_error(MEMORY_ERROR);
2182 } else {
2183 memcpy_to_strelem(columnValue->mem, (ustriType) data,
2184 (memSizeType) length);
2185 columnValue->size = (memSizeType) length;
2186 } /* if */
2187 break;
2188 default:
2189 logError(printf("sqlColumnStri: Column " FMT_D " has the unknown type %s.\n",
2190 column, nameOfBufferType(columnData->buffer_type)););
2191 raise_error(RANGE_ERROR);
2192 columnValue = NULL;
2193 break;
2194 } /* switch */
2195 } /* if */
2196 } /* if */
2197 logFunction(printf("sqlColumnStri --> \"%s\"\n", striAsUnquotedCStri(columnValue)););
2198 return columnValue;
2199 } /* sqlColumnStri */
2200
2201
2202
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)2203 static void sqlColumnTime (sqlStmtType sqlStatement, intType column,
2204 intType *year, intType *month, intType *day, intType *hour,
2205 intType *minute, intType *second, intType *micro_second,
2206 intType *time_zone, boolType *is_dst)
2207
2208 {
2209 preparedStmtType preparedStmt;
2210 resultDataType columnData;
2211 BYTE *data;
2212 DBINT length;
2213 DBDATETIMEALL *dateTimeAll;
2214 uint64Type numTimeUnits;
2215 errInfoType err_info = OKAY_NO_ERROR;
2216
2217 /* sqlColumnTime */
2218 logFunction(printf("sqlColumnTime(" FMT_U_MEM ", " FMT_D ", *)\n",
2219 (memSizeType) sqlStatement, column););
2220 preparedStmt = (preparedStmtType) sqlStatement;
2221 if (unlikely(!preparedStmt->fetchOkay || column < 1 ||
2222 (uintType) column > preparedStmt->result_array_size)) {
2223 logError(printf("sqlColumnTime: Fetch okay: %d, column: " FMT_D
2224 ", max column: " FMT_U_MEM ".\n",
2225 preparedStmt->fetchOkay, column,
2226 preparedStmt->result_array_size););
2227 raise_error(RANGE_ERROR);
2228 } else {
2229 columnData = &preparedStmt->result_array[column - 1];
2230 data = dbdata(preparedStmt->dbproc, (int) column);
2231 if (data == NULL) {
2232 length = dbdatlen(preparedStmt->dbproc, (int) column);
2233 /* printf("length: " FMT_D32 "\n", length); */
2234 if (likely(length == 0)) {
2235 /* printf("Column is NULL -> Use default value: 0-01-01 00:00:00\n"); */
2236 *year = 0;
2237 *month = 1;
2238 *day = 1;
2239 *hour = 0;
2240 *minute = 0;
2241 *second = 0;
2242 *micro_second = 0;
2243 *time_zone = 0;
2244 *is_dst = 0;
2245 } else {
2246 dbInconsistent("sqlColumnTime", "dbdatlen");
2247 logError(printf("sqlColumnTime: Column " FMT_D ": "
2248 "dbdatlen returns %d.\n", column, length););
2249 raise_error(DATABASE_ERROR);
2250 } /* if */
2251 } else {
2252 /* printf("buffer: %s\n", (unsigned char *) columnData->buffer); */
2253 /* printf("buffer_type: %s\n",
2254 nameOfBufferType(columnData->buffer_type)); */
2255 switch (columnData->buffer_type) {
2256 case SYBMSDATE:
2257 case SYBMSTIME:
2258 case SYBMSDATETIME2:
2259 length = dbdatlen(preparedStmt->dbproc, (int) column);
2260 /* printf("length: " FMT_D32 "\n", length); */
2261 if (unlikely(length < 0)) {
2262 dbInconsistent("sqlColumnTime", "dbdatlen");
2263 logError(printf("sqlColumnTime: Column " FMT_D ": "
2264 "dbdatlen returns %d.\n", column, length););
2265 raise_error(DATABASE_ERROR);
2266 } else if (unlikely(length != sizeof(DBDATETIMEALL))) {
2267 logError(printf("sqlColumnTime: In column " FMT_D
2268 " the DBDATETIMEALL length of " FMT_D32 " is wrong.\n",
2269 column, length););
2270 err_info = RANGE_ERROR;
2271 } else {
2272 dateTimeAll = (DBDATETIMEALL *) data;
2273 if (columnData->buffer_type == SYBMSTIME) {
2274 *year = 0;
2275 *month = 1;
2276 *day = 1;
2277 } else {
2278 dateFromDaysSince1900(dateTimeAll->date, year, month, day);
2279 } /* if */
2280 *micro_second = (intType) ((dateTimeAll->time % 10000000) / 10);
2281 numTimeUnits = dateTimeAll->time / 10000000;
2282 *second = (intType) (numTimeUnits % 60);
2283 numTimeUnits /= 60;
2284 *minute = (intType) (numTimeUnits % 60);
2285 *hour = (intType) (numTimeUnits / 60);
2286 } /* if */
2287 if (unlikely(err_info != OKAY_NO_ERROR)) {
2288 raise_error(err_info);
2289 } /* if */
2290 break;
2291 default:
2292 logError(printf("sqlColumnTime: Column " FMT_D " has the unknown type %s.\n",
2293 column, nameOfBufferType(columnData->buffer_type)););
2294 raise_error(RANGE_ERROR);
2295 break;
2296 } /* switch */
2297 } /* if */
2298 } /* if */
2299 logFunction(printf("sqlColumnTime(" FMT_U_MEM ", " FMT_D ", "
2300 F_D(04) "-" F_D(02) "-" F_D(02) " "
2301 F_D(02) ":" F_D(02) ":" F_D(02) "."
2302 F_D(06) ", " FMT_D ", %d) -->\n",
2303 (memSizeType) sqlStatement, column,
2304 *year, *month, *day, *hour, *minute, *second,
2305 *micro_second, *time_zone, *is_dst););
2306 } /* sqlColumnTime */
2307
2308
2309
sqlCommit(databaseType database)2310 static void sqlCommit (databaseType database)
2311
2312 {
2313 dbType db;
2314 errInfoType err_info = OKAY_NO_ERROR;
2315
2316 /* sqlCommit */
2317 logFunction(printf("sqlCommit(" FMT_U_MEM ")\n",
2318 (memSizeType) database););
2319 db = (dbType) database;
2320 if (unlikely(db->dbproc == NULL)) {
2321 logError(printf("sqlCommit: Database is not open.\n"););
2322 raise_error(RANGE_ERROR);
2323 } else if (!db->autoCommit) {
2324 doExecute(db->dbproc, "COMMIT", &err_info);
2325 doExecute(db->dbproc, "BEGIN TRANSACTION", &err_info);
2326 if (unlikely(err_info != OKAY_NO_ERROR)) {
2327 raise_error(err_info);
2328 } /* if */
2329 } /* if */
2330 logFunction(printf("sqlCommit -->\n"););
2331 } /* sqlCommit */
2332
2333
2334
sqlExecute(sqlStmtType sqlStatement)2335 static void sqlExecute (sqlStmtType sqlStatement)
2336
2337 {
2338 preparedStmtType preparedStmt;
2339 striType boundStatement;
2340 cstriType query;
2341 RETCODE retCode;
2342 errInfoType err_info = OKAY_NO_ERROR;
2343
2344 /* sqlExecute */
2345 logFunction(printf("sqlExecute(" FMT_U_MEM ")\n",
2346 (memSizeType) sqlStatement););
2347 preparedStmt = (preparedStmtType) sqlStatement;
2348 boundStatement = getBoundStatement(preparedStmt, &err_info);
2349 if (unlikely(boundStatement == NULL)) {
2350 if (err_info == RANGE_ERROR) {
2351 dbLibError("sqlExecute", "SQLExecute",
2352 "Unbound statement parameter(s).\n");
2353 raise_error(DATABASE_ERROR);
2354 } else {
2355 raise_error(err_info);
2356 } /* if */
2357 } else {
2358 query = stri_to_cstri8(boundStatement, &err_info);
2359 if (likely(query != NULL)) {
2360 /* printf("ppStmt: " FMT_X_MEM "\n", (memSizeType) preparedStmt->ppStmt); */
2361 preparedStmt->fetchOkay = FALSE;
2362 if (unlikely(dbcmd(preparedStmt->dbproc, query) != SUCCEED)) {
2363 logError(printf("sqlExecute: dbcmd(" FMT_U_MEM ", \"%s\") failed.\n",
2364 (memSizeType) preparedStmt->dbproc, query););
2365 preparedStmt->executeSuccessful = FALSE;
2366 err_info = DATABASE_ERROR;
2367 } else if (unlikely(dbsqlexec(preparedStmt->dbproc) != SUCCEED)) {
2368 logError(printf("sqlExecute: dbsqlexec(" FMT_U_MEM ") with \"%s\" failed.\n",
2369 (memSizeType) preparedStmt->dbproc, query););
2370 preparedStmt->executeSuccessful = FALSE;
2371 err_info = DATABASE_ERROR;
2372 } else {
2373 retCode = dbresults(preparedStmt->dbproc);
2374 /* printf("dbresults returns: %d\n", retCode); */
2375 if (unlikely(retCode == FAIL)) {
2376 logError(printf("sqlExecute: dbresults() failed.\n"););
2377 preparedStmt->executeSuccessful = FALSE;
2378 err_info = DATABASE_ERROR;
2379 } else {
2380 preparedStmt->executeSuccessful = TRUE;
2381 preparedStmt->fetchFinished = FALSE;
2382 err_info = setupResult(preparedStmt);
2383 } /* if */
2384 } /* if */
2385 free_cstri8(query, boundStatement);
2386 } /* if */
2387 FREE_STRI(boundStatement, boundStatement->size);
2388 if (unlikely(err_info != OKAY_NO_ERROR)) {
2389 raise_error(err_info);
2390 } /* if */
2391 } /* if */
2392 logFunction(printf("sqlExecute -->\n"););
2393 } /* sqlExecute */
2394
2395
2396
sqlFetch(sqlStmtType sqlStatement)2397 static boolType sqlFetch (sqlStmtType sqlStatement)
2398
2399 {
2400 preparedStmtType preparedStmt;
2401 RETCODE fetch_result;
2402
2403 /* sqlFetch */
2404 logFunction(printf("sqlFetch(" FMT_U_MEM ")\n",
2405 (memSizeType) sqlStatement););
2406 preparedStmt = (preparedStmtType) sqlStatement;
2407 if (unlikely(!preparedStmt->executeSuccessful)) {
2408 dbLibError("sqlFetch", "OCIStmtExecute",
2409 "Execute was not successful.\n");
2410 logError(printf("sqlFetch: Execute was not successful.\n"););
2411 preparedStmt->fetchOkay = FALSE;
2412 raise_error(DATABASE_ERROR);
2413 } else {
2414 fetch_result = dbnextrow(preparedStmt->dbproc);
2415 /* printf("fetch_result: %d\n", fetch_result); */
2416 if (fetch_result == NO_MORE_ROWS) {
2417 preparedStmt->fetchOkay = FALSE;
2418 preparedStmt->fetchFinished = TRUE;
2419 } else {
2420 preparedStmt->fetchOkay = TRUE;
2421 } /* if */
2422 } /* if */
2423 logFunction(printf("sqlFetch --> %d\n", preparedStmt->fetchOkay););
2424 return preparedStmt->fetchOkay;
2425 } /* sqlFetch */
2426
2427
2428
sqlGetAutoCommit(databaseType database)2429 static boolType sqlGetAutoCommit (databaseType database)
2430
2431 {
2432 dbType db;
2433 boolType autoCommit;
2434
2435 /* sqlGetAutoCommit */
2436 logFunction(printf("sqlGetAutoCommit(" FMT_U_MEM ")\n",
2437 (memSizeType) database););
2438 db = (dbType) database;
2439 if (unlikely(db->dbproc == NULL)) {
2440 logError(printf("sqlGetAutoCommit: Database is not open.\n"););
2441 raise_error(RANGE_ERROR);
2442 autoCommit = FALSE;
2443 } else {
2444 autoCommit = db->autoCommit;
2445 } /* if */
2446 logFunction(printf("sqlGetAutoCommit --> %d\n", autoCommit););
2447 return autoCommit;
2448 } /* sqlGetAutoCommit */
2449
2450
2451
sqlIsNull(sqlStmtType sqlStatement,intType column)2452 static boolType sqlIsNull (sqlStmtType sqlStatement, intType column)
2453
2454 {
2455 preparedStmtType preparedStmt;
2456 boolType isNull;
2457
2458 /* sqlIsNull */
2459 logFunction(printf("sqlIsNull(" FMT_U_MEM ", " FMT_D ")\n",
2460 (memSizeType) sqlStatement, column););
2461 preparedStmt = (preparedStmtType) sqlStatement;
2462 if (unlikely(!preparedStmt->fetchOkay || column < 1 ||
2463 (uintType) column > preparedStmt->result_array_size)) {
2464 logError(printf("sqlIsNull: Fetch okay: %d, column: " FMT_D
2465 ", max column: " FMT_U_MEM ".\n",
2466 preparedStmt->fetchOkay, column,
2467 preparedStmt->result_array_size););
2468 raise_error(RANGE_ERROR);
2469 isNull = FALSE;
2470 } else {
2471 isNull = dbdatlen(preparedStmt->dbproc, (int) column) == 0;
2472 } /* if */
2473 logFunction(printf("sqlIsNull --> %s\n", isNull ? "TRUE" : "FALSE"););
2474 return isNull;
2475 } /* sqlIsNull */
2476
2477
2478
sqlPrepare(databaseType database,const const_striType sqlStatementStri)2479 static sqlStmtType sqlPrepare (databaseType database,
2480 const const_striType sqlStatementStri)
2481
2482 {
2483 dbType db;
2484 striType *stmtPartArray;
2485 memSizeType numBindParameters;
2486 errInfoType err_info = OKAY_NO_ERROR;
2487 preparedStmtType preparedStmt;
2488
2489 /* sqlPrepare */
2490 logFunction(printf("sqlPrepare(" FMT_U_MEM ", \"%s\")\n",
2491 (memSizeType) database,
2492 striAsUnquotedCStri(sqlStatementStri)););
2493 db = (dbType) database;
2494 if (unlikely(db->dbproc == NULL)) {
2495 logError(printf("sqlPrepare: Database is not open.\n"););
2496 err_info = RANGE_ERROR;
2497 preparedStmt = NULL;
2498 } else {
2499 stmtPartArray = processStatementStri(sqlStatementStri, &numBindParameters, &err_info);
2500 if (stmtPartArray == NULL) {
2501 preparedStmt = NULL;
2502 } else {
2503 if (!ALLOC_RECORD2(preparedStmt, preparedStmtRecord,
2504 count.prepared_stmt, count.prepared_stmt_bytes)) {
2505 err_info = MEMORY_ERROR;
2506 } else {
2507 memset(preparedStmt, 0, sizeof(preparedStmtRecord));
2508 preparedStmt->usage_count = 1;
2509 preparedStmt->sqlFunc = db->sqlFunc;
2510 preparedStmt->dbproc = db->dbproc;
2511 preparedStmt->stmtPartArray = stmtPartArray;
2512 err_info = setStmtPartArrayCharCount(preparedStmt, numBindParameters);
2513 if (likely(err_info == OKAY_NO_ERROR)) {
2514 err_info = setupParameters(preparedStmt, numBindParameters);
2515 } /* if */
2516 if (unlikely(err_info != OKAY_NO_ERROR)) {
2517 freePreparedStmt((sqlStmtType) preparedStmt);
2518 preparedStmt = NULL;
2519 } /* if */
2520 } /* if */
2521 } /* if */
2522 } /* if */
2523 if (unlikely(err_info != OKAY_NO_ERROR)) {
2524 raise_error(err_info);
2525 } /* if */
2526 logFunction(printf("sqlPrepare --> " FMT_U_MEM "\n",
2527 (memSizeType) preparedStmt););
2528 return (sqlStmtType) preparedStmt;
2529 } /* sqlPrepare */
2530
2531
2532
sqlRollback(databaseType database)2533 static void sqlRollback (databaseType database)
2534
2535 {
2536 dbType db;
2537 errInfoType err_info = OKAY_NO_ERROR;
2538
2539 /* sqlRollback */
2540 logFunction(printf("sqlRollback(" FMT_U_MEM ")\n",
2541 (memSizeType) database););
2542 db = (dbType) database;
2543 if (unlikely(db->dbproc == NULL)) {
2544 logError(printf("sqlRollback: Database is not open.\n"););
2545 raise_error(RANGE_ERROR);
2546 } else if (!db->autoCommit) {
2547 doExecute(db->dbproc, "ROLLBACK", &err_info);
2548 doExecute(db->dbproc, "BEGIN TRANSACTION", &err_info);
2549 if (unlikely(err_info != OKAY_NO_ERROR)) {
2550 raise_error(err_info);
2551 } /* if */
2552 } /* if */
2553 logFunction(printf("sqlRollback -->\n"););
2554 } /* sqlRollback */
2555
2556
2557
sqlSetAutoCommit(databaseType database,boolType autoCommit)2558 static void sqlSetAutoCommit (databaseType database, boolType autoCommit)
2559
2560 {
2561 dbType db;
2562 errInfoType err_info = OKAY_NO_ERROR;
2563
2564 /* sqlSetAutoCommit */
2565 logFunction(printf("sqlSetAutoCommit(" FMT_U_MEM ", %d)\n",
2566 (memSizeType) database, autoCommit););
2567 db = (dbType) database;
2568 if (unlikely(db->dbproc == NULL)) {
2569 logError(printf("sqlSetAutoCommit: Database is not open.\n"););
2570 raise_error(RANGE_ERROR);
2571 } else {
2572 if (db->autoCommit != autoCommit) {
2573 if (autoCommit) {
2574 doExecute(db->dbproc, "COMMIT", &err_info);
2575 } else {
2576 doExecute(db->dbproc, "BEGIN TRANSACTION", &err_info);
2577 } /* if */
2578 if (unlikely(err_info != OKAY_NO_ERROR)) {
2579 raise_error(err_info);
2580 } else {
2581 db->autoCommit = autoCommit;
2582 } /* if */
2583 } /* if */
2584 } /* if */
2585 logFunction(printf("sqlSetAutoCommit -->\n"););
2586 } /* sqlSetAutoCommit */
2587
2588
2589
sqlStmtColumnCount(sqlStmtType sqlStatement)2590 static intType sqlStmtColumnCount (sqlStmtType sqlStatement)
2591
2592 {
2593 preparedStmtType preparedStmt;
2594 intType columnCount;
2595
2596 /* sqlStmtColumnCount */
2597 logFunction(printf("sqlStmtColumnCount(" FMT_U_MEM ")\n",
2598 (memSizeType) sqlStatement););
2599 preparedStmt = (preparedStmtType) sqlStatement;
2600 if (unlikely(preparedStmt->result_array_size > INTTYPE_MAX)) {
2601 logError(printf("sqlStmtColumnCount: "
2602 "result_array_size (=" FMT_U_MEM ") > INTTYPE_MAX\n",
2603 preparedStmt->result_array_size););
2604 raise_error(RANGE_ERROR);
2605 columnCount = 0;
2606 } else {
2607 columnCount = (intType) preparedStmt->result_array_size;
2608 } /* if */
2609 logFunction(printf("sqlStmtColumnCount --> " FMT_D "\n", columnCount););
2610 return columnCount;
2611 } /* sqlStmtColumnCount */
2612
2613
2614
sqlStmtColumnName(sqlStmtType sqlStatement,intType column)2615 static striType sqlStmtColumnName (sqlStmtType sqlStatement, intType column)
2616
2617 {
2618 preparedStmtType preparedStmt;
2619 char *columnName;
2620 errInfoType err_info = OKAY_NO_ERROR;
2621 striType name;
2622
2623 /* sqlStmtColumnName */
2624 logFunction(printf("sqlStmtColumnName(" FMT_U_MEM ", " FMT_D ")\n",
2625 (memSizeType) sqlStatement, column););
2626 preparedStmt = (preparedStmtType) sqlStatement;
2627 if (unlikely(column < 1 ||
2628 (uintType) column > preparedStmt->result_array_size)) {
2629 logError(printf("sqlStmtColumnName: column: " FMT_D
2630 ", max column: " FMT_U_MEM ".\n",
2631 column, preparedStmt->result_array_size););
2632 err_info = RANGE_ERROR;
2633 name = NULL;
2634 } else {
2635 columnName = dbcolname(preparedStmt->dbproc, (int) column);
2636 if (unlikely(columnName == NULL)) {
2637 dbLibError("sqlStmtColumnName", "dbcolname", "dbcolname() returns NULL.\n");
2638 logError(printf("sqlStmtColumnName: dbcolname() returns NULL.\n"););
2639 err_info = DATABASE_ERROR;
2640 name = NULL;
2641 } else {
2642 name = cstri8_to_stri(columnName, &err_info);
2643 } /* if */
2644 } /* if */
2645 if (unlikely(name == NULL)) {
2646 raise_error(err_info);
2647 } /* if */
2648 logFunction(printf("sqlStmtColumnName --> \"%s\"\n",
2649 striAsUnquotedCStri(name)););
2650 return name;
2651 } /* sqlStmtColumnName */
2652
2653
2654
setupFuncTable(void)2655 static boolType setupFuncTable (void)
2656
2657 { /* setupFuncTable */
2658 if (sqlFunc == NULL) {
2659 if (ALLOC_RECORD(sqlFunc, sqlFuncRecord, count.sql_func)) {
2660 memset(sqlFunc, 0, sizeof(sqlFuncRecord));
2661 sqlFunc->freeDatabase = &freeDatabase;
2662 sqlFunc->freePreparedStmt = &freePreparedStmt;
2663 sqlFunc->sqlBindBigInt = &sqlBindBigInt;
2664 sqlFunc->sqlBindBigRat = &sqlBindBigRat;
2665 sqlFunc->sqlBindBool = &sqlBindBool;
2666 sqlFunc->sqlBindBStri = &sqlBindBStri;
2667 sqlFunc->sqlBindDuration = &sqlBindDuration;
2668 sqlFunc->sqlBindFloat = &sqlBindFloat;
2669 sqlFunc->sqlBindInt = &sqlBindInt;
2670 sqlFunc->sqlBindNull = &sqlBindNull;
2671 sqlFunc->sqlBindStri = &sqlBindStri;
2672 sqlFunc->sqlBindTime = &sqlBindTime;
2673 sqlFunc->sqlClose = &sqlClose;
2674 sqlFunc->sqlColumnBigInt = &sqlColumnBigInt;
2675 sqlFunc->sqlColumnBigRat = &sqlColumnBigRat;
2676 sqlFunc->sqlColumnBool = &sqlColumnBool;
2677 sqlFunc->sqlColumnBStri = &sqlColumnBStri;
2678 sqlFunc->sqlColumnDuration = &sqlColumnDuration;
2679 sqlFunc->sqlColumnFloat = &sqlColumnFloat;
2680 sqlFunc->sqlColumnInt = &sqlColumnInt;
2681 sqlFunc->sqlColumnStri = &sqlColumnStri;
2682 sqlFunc->sqlColumnTime = &sqlColumnTime;
2683 sqlFunc->sqlCommit = &sqlCommit;
2684 sqlFunc->sqlExecute = &sqlExecute;
2685 sqlFunc->sqlFetch = &sqlFetch;
2686 sqlFunc->sqlGetAutoCommit = &sqlGetAutoCommit;
2687 sqlFunc->sqlIsNull = &sqlIsNull;
2688 sqlFunc->sqlPrepare = &sqlPrepare;
2689 sqlFunc->sqlRollback = &sqlRollback;
2690 sqlFunc->sqlSetAutoCommit = &sqlSetAutoCommit;
2691 sqlFunc->sqlStmtColumnCount = &sqlStmtColumnCount;
2692 sqlFunc->sqlStmtColumnName = &sqlStmtColumnName;
2693 } /* if */
2694 } /* if */
2695 if (quoteQuote == NULL) {
2696 quoteQuote = CSTRI_LITERAL_TO_STRI("''");
2697 } /* if */
2698 return sqlFunc != NULL;
2699 } /* setupFuncTable */
2700
2701
2702
sqlOpenTds(const const_striType host,intType port,const const_striType dbName,const const_striType user,const const_striType password)2703 databaseType sqlOpenTds (const const_striType host, intType port,
2704 const const_striType dbName, const const_striType user,
2705 const const_striType password)
2706
2707 {
2708 const_cstriType host8;
2709 memSizeType host8Length;
2710 const_cstriType dbName8;
2711 const_cstriType user8;
2712 const_cstriType password8;
2713 char portName[1 + INTTYPE_DECIMAL_SIZE + NULL_TERMINATION_LEN];
2714 memSizeType portNameLength;
2715 cstriType hostAndPort = NULL;
2716 const_cstriType server;
2717 LOGINREC *login;
2718 DBPROCESS *dbproc;
2719 RETCODE erc;
2720 errInfoType err_info = OKAY_NO_ERROR;
2721 dbType database;
2722
2723 /* sqlOpenTds */
2724 logFunction(printf("sqlOpenTds(\"%s\", ",
2725 striAsUnquotedCStri(host));
2726 printf(FMT_D ", \"%s\", ",
2727 port, striAsUnquotedCStri(dbName));
2728 printf("\"%s\", ", striAsUnquotedCStri(user));
2729 printf("\"%s\")\n", striAsUnquotedCStri(password)););
2730 if (!findDll()) {
2731 logError(printf("sqlOpenTds: findDll() failed\n"););
2732 err_info = DATABASE_ERROR;
2733 database = NULL;
2734 } else if (unlikely((host8 = stri_to_cstri8(host, &err_info)) == NULL)) {
2735 database = NULL;
2736 } else {
2737 if (port == 0) {
2738 server = host8;
2739 } else {
2740 host8Length = strlen(host8);
2741 portNameLength = (memSizeType) sprintf(portName, ":" FMT_D, port);
2742 if (unlikely(!ALLOC_CSTRI(hostAndPort, host8Length + portNameLength))) {
2743 err_info = MEMORY_ERROR;
2744 database = NULL;
2745 } else {
2746 memcpy(hostAndPort, host8, host8Length);
2747 memcpy(&hostAndPort[host8Length], portName,
2748 portNameLength + NULL_TERMINATION_LEN);
2749 server = hostAndPort;
2750 } /* if */
2751 } /* if */
2752 if (likely(err_info == OKAY_NO_ERROR)) {
2753 dbName8 = stri_to_cstri8(dbName, &err_info);
2754 if (unlikely(dbName8 == NULL)) {
2755 database = NULL;
2756 } else {
2757 user8 = stri_to_cstri8(user, &err_info);
2758 if (unlikely(user8 == NULL)) {
2759 database = NULL;
2760 } else {
2761 password8 = stri_to_cstri8(password, &err_info);
2762 if (unlikely(password8 == NULL)) {
2763 database = NULL;
2764 } else {
2765 if (dbinit() == FAIL) {
2766 dbLibError("sqlOpenTds", "dbinit", "dbinit() failed.\n");
2767 logError(printf("sqlOpenTds: dbinit() failed.\n"););
2768 err_info = DATABASE_ERROR;
2769 database = NULL;
2770 } else {
2771 dberrhandle(err_handler);
2772 dbmsghandle(msg_handler);
2773 if ((login = dblogin()) == NULL) {
2774 setDbErrorMsg("sqlOpenTds", "dblogin");
2775 logError(printf("sqlOpenTds: dblogin() failed.\n%s\n",
2776 dbError.message););
2777 err_info = MEMORY_ERROR;
2778 database = NULL;
2779 } else {
2780 if (server[0] != '\0') {
2781 DBSETLHOST(login, server);
2782 } /* if */
2783 DBSETLUSER(login, user8);
2784 DBSETLPWD(login, password8);
2785 DBSETLCHARSET(login, "UTF-8");
2786 if ((dbproc = dbopen(login, server)) == NULL) {
2787 setDbErrorMsg("sqlOpenTds", "dbopen");
2788 logError(printf("sqlOpenTds: dbopen(\"%s\"/\"***Pwd***\", \"%s\"):\n%s\n",
2789 user8, server, dbError.message););
2790 err_info = DATABASE_ERROR;
2791 dbexit();
2792 database = NULL;
2793 } else if ((erc = dbuse(dbproc, dbName8)) == FAIL) {
2794 setDbErrorMsg("sqlOpenTds", "dbuse");
2795 logError(printf("sqlOpenTds: dbuse(*, \"%s\"):\n%s\n",
2796 dbName8, dbError.message););
2797 err_info = DATABASE_ERROR;
2798 dbclose(dbproc);
2799 dbexit();
2800 database = NULL;
2801 } else {
2802 /* CHAR fields are padded with spaces up to the field */
2803 /* width and all spaces are retrieved. For VARCHAR */
2804 /* fields trailing spaces are stored and retrieved. */
2805 doExecute(dbproc, "SET ANSI_PADDING ON", &err_info);
2806 /* Set the default nullability of new created columns. */
2807 /* By default connections from DB-Library applications */
2808 /* create non nullable columns. This is changed such */
2809 /* that nullable columns are created by default. */
2810 doExecute(dbproc, "SET ANSI_NULL_DFLT_ON ON", &err_info);
2811 /* Identifiers can be delimited by double quotation */
2812 /* marks ("), and literals must be delimited by single */
2813 /* quotation marks ('). */
2814 doExecute(dbproc, "SET QUOTED_IDENTIFIER ON", &err_info);
2815 /* Terminate a query if an overflow or divide-by-zero */
2816 /* error occurs during query execution. */
2817 doExecute(dbproc, "SET ARITHABORT ON", &err_info);
2818 /* Specify the size of varchar(max), nvarchar(max) and */
2819 /* varbinary(max) returned by a SELECT statement. */
2820 /* The default value would be 4 KB. Unlimited is -1. */
2821 doExecute(dbproc, "SET TEXTSIZE -1", &err_info);
2822 if (unlikely(err_info != OKAY_NO_ERROR)) {
2823 dbclose(dbproc);
2824 dbexit();
2825 database = NULL;
2826 } else if (unlikely(!setupFuncTable() ||
2827 !ALLOC_RECORD2(database, dbRecord,
2828 count.database,
2829 count.database_bytes))) {
2830 err_info = MEMORY_ERROR;
2831 dbclose(dbproc);
2832 dbexit();
2833 database = NULL;
2834 } else {
2835 memset(database, 0, sizeof(dbRecord));
2836 database->usage_count = 1;
2837 database->sqlFunc = sqlFunc;
2838 database->driver = DB_CATEGORY_TDS;
2839 database->dbproc = dbproc;
2840 database->autoCommit = TRUE;
2841 } /* if */
2842 } /* if */
2843 dbloginfree(login);
2844 } /* if */
2845 } /* if */
2846 free_cstri8(password8, password);
2847 } /* if */
2848 free_cstri8(user8, user);
2849 } /* if */
2850 free_cstri8(dbName8, dbName);
2851 } /* if */
2852 } /* if */
2853 if (hostAndPort != NULL) {
2854 UNALLOC_CSTRI(hostAndPort, host8Length + portNameLength);
2855 } /* if */
2856 free_cstri8(host8, host);
2857 } /* if */
2858 if (unlikely(err_info != OKAY_NO_ERROR)) {
2859 raise_error(err_info);
2860 } /* if */
2861 logFunction(printf("sqlOpenTds --> " FMT_U_MEM "\n",
2862 (memSizeType) database););
2863 return (databaseType) database;
2864 } /* sqlOpenTds */
2865
2866 #else
2867
2868
2869
sqlOpenTds(const const_striType host,intType port,const const_striType dbName,const const_striType user,const const_striType password)2870 databaseType sqlOpenTds (const const_striType host, intType port,
2871 const const_striType dbName, const const_striType user,
2872 const const_striType password)
2873
2874 { /* sqlOpenTds */
2875 logError(printf("sqlOpenTds(\"%s\", ",
2876 striAsUnquotedCStri(host));
2877 printf(FMT_D ", \"%s\", ",
2878 port, striAsUnquotedCStri(dbName));
2879 printf("\"%s\", ", striAsUnquotedCStri(user));
2880 printf("\"%s\"): TDS driver not present.\n",
2881 striAsUnquotedCStri(password)););
2882 raise_error(RANGE_ERROR);
2883 return NULL;
2884 } /* sqlOpenTds */
2885
2886 #endif
2887