1 /*
2  * libdbi-drivers - database drivers for libdbi, the database
3  * independent abstraction layer for C.
4 
5  * Copyright (C) 2001-2008, David Parker, Mark Tobenkin, Markus Hoenicka
6  * http://libdbi-drivers.sourceforge.net
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  *
22  * $Id: test_dbi.c,v 1.72 2013/02/24 15:06:57 mhoenicka Exp $
23  */
24 
25 #include <stdio.h>
26 #include <string.h>
27 #include <dbi/dbi.h>
28 #include <dbi/dbi-dev.h> /* need this to access custom functions */
29 #include <time.h>
30 #include <unistd.h>
31 #include <stdlib.h> /* for strtol() */
32 #include <limits.h>
33 #include <cgreen/cgreen.h>
34 
35 #ifdef __MINGW32__
36 #include <windows.h>
37 #define sleep(seconds) Sleep((seconds)*1000)
38 #endif
39 
40 /* this is defined in configure.in, but unavailable if firebird isn't installed */
41 #ifndef FIREBIRD_ISQL
42 #define FIREBIRD_ISQL "cat"
43 #endif
44 
45 #define QUERY_LEN 1024
46 
47 /* this is defined by the Makefile and passed via -D */
48 /* #define DBDIR /usr/local/var/lib/libdbi */
49 
50 /* the dbi instance for the recallable interface */
51 dbi_inst dbi_instance = NULL;
52 dbi_driver test_driver = NULL;
53 dbi_conn conn = NULL;
54 
55 dbi_conn test_conn = NULL;
56 
57 /* structure definitions */
58 struct CONNINFO {
59    int  n_legacy;
60    int  query_log;
61    char driverdir[256];
62    char drivername[64];
63    int  numdrivers;
64    char dbname[64];
65    char initial_dbname[64];
66    char dbdir[256];
67    char username[64];
68    char password[64];
69    char hostname[256];
70    char version[64];
71    char createschema[QUERY_LEN + 1];
72    char createsubschema[5][QUERY_LEN + 1];
73    char dropsubschema[5][QUERY_LEN + 1];
74    char query[QUERY_LEN + 1];
75    char encoding[20];
76 };
77 
78 struct TABLEINFO {
79   int have_double;
80   int have_longlong;
81   int have_ulonglong;
82   int have_datetime;
83   int have_datetime_tz;
84   int have_time_tz;
85   int number_rows;
86 };
87 
88 struct CONNINFO cinfo;
89 struct TABLEINFO tinfo;
90 
91 /* switch for recallable (0) vs. legacy (!=0) interface */
92 int n_legacy = 0;
93 
94 /* some test data */
95 char string_to_quote[] = "Can \'we\' \"quote\" this properly?";
96 char string_to_escape[] = "Can \'we\' \"escape\" this properly?";
97 char numstring[] = "-54321";
98 unsigned char binary_to_quote[] = {'A', 'B', '\0', 'C', '\'', 'D'};
99 unsigned char binary_to_escape[] = {'A', 'B', '\0', 'C', '\'', 'D'};
100 size_t binary_to_quote_length = 6;
101 size_t binary_to_escape_length = 6;
102 
103 const char default_dbdir[] = DBDIR;
104 
105 struct FIELDINFO {
106    char name[32];
107    unsigned short type;
108    unsigned int attrib;
109    unsigned short length;
110    unsigned short figures;
111    union {
112       long long int int_val;
113       unsigned long long int uint_val;
114       double double_val;
115       char string_val[48];
116    } expect_val;
117    long long expect_as_longlong;
118    char expect_as_string[48];
119 };
120 
121 /* these structures define the attributes, types, expected return
122    values, return values as longlong, and return values as string for
123    each supported column type of a particular database engine */
124 struct FIELDINFO firebird_fieldinfo[] = {
125       {"the_char", 1, 4, 0, 0, .expect_val.int_val = -127, -127, "-127"}, /* DBI_INTEGER_SIZE2 */
126       {"the_uchar", 1, 4, 0, 0, .expect_val.uint_val = 127, 127, "127"}, /* DBI_INTEGER_SIZE2 */
127       {"the_short", 1, 4, 0, 0, .expect_val.int_val = -32768, -32768, "-32768"}, /* DBI_INTEGER_SIZE2 */
128       {"the_ushort", 1, 4, 0, 0, .expect_val.uint_val = 32767, 32767, "32767"}, /* DBI_INTEGER_SIZE2 */
129       {"the_long", 1,16, 0, 0, .expect_val.int_val = -2147483648, -2147483648, "-2147483648"}, /* DBI_INTEGER_SIZE4 */
130       {"the_ulong", 1,16, 0, 0, .expect_val.uint_val = 2147483647, 2147483647, "2147483647"}, /* DBI_INTEGER_SIZE4 */
131       {"the_float", 2, 2, 0, 0, .expect_val.double_val = 3.4E+37, -9223372036854775808, "3.400000e+37"}, /* DBI_DECIMAL_SIZE4 */
132       {"the_double", 2, 4, 0, 0, .expect_val.double_val = 1.7E+307, -9223372036854775808, "1.700000e+307"}, /* DBI_DECIMAL_SIZE8 */
133       {"the_conn_quoted_string", 3, 0, 31, 0, .expect_val.string_val = "Can \'we\' \"quote\" this properly?", 0, "Can \'we\' \"quote\" this properly?"}, /* string */
134       {"the_conn_quoted_string_copy", 3, 0, 31, 0, .expect_val.string_val = "Can \'we\' \"quote\" this properly?", 0, "Can \'we\' \"quote\" this properly?"}, /* string */
135       {"the_conn_escaped_string", 3, 0, 32, 0, .expect_val.string_val = "Can 'we' \"escape\" this properly?", 0, "Can 'we' \"escape\" this properly?"}, /* string */
136       {"the_conn_escaped_string_copy", 3, 0, 32, 0, .expect_val.string_val = "Can 'we' \"escape\" this properly?", 0, "Can 'we' \"escape\" this properly?"}, /* string */
137       {"the_numstring", 3, 0, 6, 0, .expect_val.string_val = "-54321", -54321, "-54321"}, /* string */
138       {"the_empty_string", 3, 0, 0, 0, .expect_val.string_val = "", 0, ""}, /* string */
139       {"the_null_string", 3, 0, 0, 0, .expect_val.string_val = "!", 0, ""}, /* string TODO: should be NULL */
140       {"the_binary_quoted_string", 4, 0, 6, 0, .expect_val.string_val = "", 0, ""}, /* binary string */
141       {"the_binary_escaped_string", 4, 0, 6, 0, .expect_val.string_val = "", 0, ""}, /* binary string */
142       {"the_datetime", 5, 3, 0, 0, .expect_val.uint_val = 1009843199, 1009843199, "2001-12-31 23:59:59"}, /* DBI_DATETIME_TIME|DATE */
143       {"the_date", 5, 1, 0, 0, .expect_val.uint_val = 1009756800, 1009756800, "2001-12-31 00:00:00"}, /* DBI_DATETIME_DATE */
144       {"the_time", 5, 2, 0, 0, .expect_val.uint_val = 86399, 86399, "1970-01-01 23:59:59"},/* DBI_DATETIME_TIME */
145       {"_escaped_string", 3, 0, 32, 0, .expect_val.string_val = "Can ''we'' \"escape\" this properly?", 0, "Can ''we'' \"escape\" this properly?"}, /* string */
146       {"_quoted_string", 3, 0, 31, 0, .expect_val.string_val = "'Can ''we'' \"quote\" this properly?'", 0, "'Can ''we'' \"quote\" this properly?'"}, /* string */
147       {"", 0, 0, 0, 0, .expect_val.int_val = 0, 0, ""}
148 };
149 
150 struct FIELDINFO freetds_fieldinfo[] = {
151       /* name, index, type, attrib */
152       {"the_char",  1, 2, 0, 0, .expect_val.int_val = -127, -127, "-127"}, /* DBI_INTEGER_SIZE1 */
153       {"the_uchar", 1, 2, 0, 0, .expect_val.uint_val = 127, 127, "127"}, /* DBI_INTEGER_SIZE1 */
154       {"the_short", 1, 4, 0, 0, .expect_val.int_val = -32768, -32768, "-32768"}, /* DBI_INTEGER_SIZE2 */
155       {"the_ushort", 1, 4, 0, 0, .expect_val.uint_val = 32767, 32768, "32767"}, /* DBI_INTEGER_SIZE2 */
156       {"the_long", 1,16, 0, 0, .expect_val.int_val = -2147483648, -2147483648, "-2147483648"}, /* DBI_INTEGER_SIZE4 */
157       {"the_ulong", 1,16, 0, 0, .expect_val.uint_val = 2147483647, 2147483647, "2147483647"}, /* DBI_INTEGER_SIZE4 */
158       {"the_longlong", 1,32, 0, 0, .expect_val.int_val = -9223372036854775807, -9223372036854775807, "-9223372036854775807"}, /* DBI_INTEGER_SIZE8 */
159       {"the_ulonglong", 1,32, 0, 0, .expect_val.int_val = 9223372036854775807, 9223372036854775807, "9223372036854775807"}, /* DBI_INTEGER_SIZE8 */
160       {"the_float", 2, 2, 0, 0, .expect_val.double_val = 3.402823466E+38, 3.402823466E+38, "3.40280E+38"}, /* DBI_DECIMAL_SIZE4 */
161       {"the_double", 2, 4, 0, 0, .expect_val.double_val = 1.7E+307, 1.7E+307, "1.797693e+307"}, /* DBI_DECIMAL_SIZE8 */
162       {"the_conn_quoted_string", 3, 0, 31, 0, .expect_val.string_val = "Can \'we\' \"quote\" this properly?", 0, "Can \'we\' \"quote\" this properly?"}, /* string */
163       {"the_conn_quoted_string_copy", 3, 0, 32, 0, .expect_val.string_val = "Can \'we\' \"quote\" this properly?", 0, "Can \'we\' \"quote\" this properly?"}, /* string */
164       {"the_conn_escaped_string", 3, 0, 32, 0, .expect_val.string_val = "Can 'we' \"escape\" this properly?", 0, "Can 'we' \"escape\" this properly?"}, /* string */
165       {"the_conn_escaped_string_copy", 3, 0, 32, 0, .expect_val.string_val = "Can 'we' \"escape\" this properly?", 0, "Can 'we' \"escape\" this properly?"}, /* string */
166       {"the_numstring", 3, 0, 0, 0, .expect_val.string_val = "-54321", -54321, "-54321"}, /* string */
167       {"the_empty_string", 3, 0, 0, 0, .expect_val.string_val = "", 0, ""}, /* string */
168       {"the_null_string", 3, 0, 0, 0, .expect_val.string_val = "", 0, ""}, /* string */
169       {"the_binary_quoted_string", 4, 0, 0, 0, .expect_val.string_val = "", 0, ""}, /* string */
170       {"the_binary_escaped_string", 4, 0, 0, 0, .expect_val.string_val = "", 0, ""}, /* string */
171       {"the_datetime", 5, 3, 0, 0, .expect_val.uint_val = 1009843199, 1009843199, "2001-12-31 23:59:59"}, /* DBI_DATETIME_TIME|DATE */
172       {"the_date", 5, 1, 0, 0, .expect_val.uint_val = 1009756800, 1009756800, "2001-12-31 00:00:00"}, /* DBI_DATETIME_DATE */
173       {"the_time", 5, 2, 0, 0, .expect_val.uint_val = 86399, 86399, "1970-01-01 23:59:59"}, /* DBI_DATETIME_TIME */
174       {"", 0, 0, 0, 0, .expect_val.int_val = 0, 0, ""}
175 };
176 
177 
178 struct FIELDINFO ingres_fieldinfo[] = {
179       /* name, index, type,, attrib */
180       {"the_char", 1, 2, 0, 0, .expect_val.int_val = -127, -127, "-127"}, /* DBI_INTEGER_SIZE1 */
181       {"the_uchar", 1, 2, 0, 0, .expect_val.uint_val = 127, 127, "127"}, /* DBI_INTEGER_SIZE1 */
182       {"the_short", 1, 4, 0, 0, .expect_val.int_val = -32768, -32768, "-32768"}, /* DBI_INTEGER_SIZE2 */
183       {"the_ushort", 1, 4, 0, 0, .expect_val.uint_val = 32767, 32768, "32767"}, /* DBI_INTEGER_SIZE2 */
184       {"the_long", 1, 16, 0, 0, .expect_val.int_val = -2147483648, -2147483648, "-2147483648"}, /* DBI_INTEGER_SIZE4 */
185       {"the_ulong", 1, 16, 0, 0, .expect_val.uint_val = 2147483647, 2147483647, "2147483647"}, /* DBI_INTEGER_SIZE4 */
186       {"the_longlong", 1, 32, 0, 0, .expect_val.int_val = -9223372036854775807, -9223372036854775807, "-9223372036854775807"}, /* DBI_INTEGER_SIZE8 */
187       {"the_ulonglong", 1, 32, 0, 0, .expect_val.int_val = 9223372036854775807, 9223372036854775807, "9223372036854775807"}, /* DBI_INTEGER_SIZE8 */
188       {"the_float", 2, 2, 0, 0, .expect_val.double_val = 3.402823466E+38, 3.402823466E+38, "3.40280E+38"}, /* DBI_DECIMAL_SIZE4 */
189       {"the_double", 2, 4, 0, 0, .expect_val.double_val = 1.7E+307, 1.7E+307, "1.797693e+307"}, /* DBI_DECIMAL_SIZE8 */
190       {"the_decimal", 3, 0, 0, 0, .expect_val.double_val = 1234.5678, 1234.5678, "1234.5678"}, /* string */
191       {"the_money", 3, 0, 0, 0, .expect_val.double_val = 567.89, 567.89, "$567.89"},  /* string */
192       {"the_character", 3, 0, 0, 0, .expect_val.string_val = "char column", 0, "char column"}, /* string */
193       {"the_byte", 3, 0, 0, 0, .expect_val.string_val = "", 0, ""}, /* string */ /* TODO: insert useful value */
194       {"the_conn_quoted_string", 3, 0, 0, 0, .expect_val.string_val = "Can \'we\' \"quote\" this properly?", 0, "Can \'we\' \"quote\" this properly?"}, /* string */
195       {"the_conn_quoted_string_copy", 3, 0, 0, 0, .expect_val.string_val = "Can \'we\' \"quote\" this properly?", 0, "Can \'we\' \"quote\" this properly?"}, /* string */
196       {"the_conn_escaped_string", 3, 0, 0, 0, .expect_val.string_val = "Can 'we' \"escape\" this properly?", 0, "Can 'we' \"escape\" this properly?"}, /* string */
197       {"the_conn_escaped_string_copy", 3, 0, 0, 0, .expect_val.string_val = "Can 'we' \"escape\" this properly?", 0, "Can 'we' \"escape\" this properly?"}, /* string */
198       {"the_numstring", 3, 0, 0, 0, .expect_val.string_val = "-54321", -54321, "-54321"}, /* string */
199       {"the_empty_string", 3, 0, 0, 0, .expect_val.string_val = "", 0, ""}, /* string */
200       {"the_null_string", 3, 0, 0, 0, .expect_val.string_val = "", 0, ""}, /* string */
201       {"the_binary_quoted_string", 4, 0, 0, 0, .expect_val.string_val = "", 0, ""}, /* string */
202       {"the_binary_escaped_string", 4, 0, 0, 0, .expect_val.string_val = "", 0, ""}, /* string */
203       {"the_datetime", 5, 3, 0, 0, .expect_val.uint_val = 1009843199, 1009843199, "2001-12-31 23:59:59"}, /* DBI_DATETIME_TIME|DATE */
204       {"the_date", 5, 1, 0, 0, .expect_val.uint_val = 1009756800, 1009756800, "2001-12-31 00:00:00"}, /* DBI_DATETIME_DATE */
205       {"the_time", 5, 2, 0, 0, .expect_val.uint_val = 86399, 86399, "1970-01-01 23:59:59"}, /* DBI_DATETIME_TIME */
206       {"", 0, 0, 0, 0, .expect_val.int_val = 0, 0, ""}
207 };
208 
209 struct FIELDINFO msql_fieldinfo[] = {
210       /* name, index, type,, attrib */
211       {"the_char", 1, 4, 0, 0, .expect_val.int_val = -127, -127, "-127"}, /* DBI_INTEGER_SIZE2 */
212       {"the_uchar", 1, 4, 0, 0, .expect_val.int_val = 127, 127, "127"}, /* DBI_INTEGER_SIZE2 */
213       {"the_short", 1, 4, 0, 0, .expect_val.int_val = -32768, -32768, "-32768"}, /* DBI_INTEGER_SIZE2 */
214       {"the_ushort", 1, 4, 0, 0, .expect_val.int_val = 32768, 32768, "32768"}, /* DBI_INTEGER_SIZE2 */
215       {"the_long", 1, 16, 0, 0, .expect_val.int_val = -2147483648, -2147483648, "-2147483648"}, /* DBI_INTEGER_SIZE4 */
216       {"the_ulong", 1, 16, 0, 0, .expect_val.int_val = 2147483647, 2147483647, "2147483647"}, /* DBI_INTEGER_SIZE4 */
217       {"the_longlong", 1, 32, 0, 0, .expect_val.int_val = -9223372036854775807, -9223372036854775807, "-9223372036854775807"}, /* DBI_INTEGER_SIZE8 */
218       {"the_ulonglong", 1, 32, 0, 0, .expect_val.int_val = 9223372036854775807, 9223372036854775807, "9223372036854775807"}, /* DBI_INTEGER_SIZE8 */
219       {"the_float", 2, 2, 0, 0, .expect_val.double_val = 3.402823466E+38, 3.402823466E+38, "3.40280E+38"}, /* DBI_DECIMAL_SIZE4 */
220       {"the_conn_quoted_string", 3, 0, 0, 0, .expect_val.string_val = "Can \'we\' \"quote\" this properly?", 0, "Can \'we\' \"quote\" this properly?"}, /* string */
221       {"the_conn_quoted_string_copy", 3, 0, 0, 0, .expect_val.string_val = "Can \'we\' \"quote\" this properly?", 0, "Can \'we\' \"quote\" this properly?"}, /* string */
222       {"the_conn_escaped_string", 3, 0, 0, 0, .expect_val.string_val = "Can 'we' \"escape\" this properly?", 0, "Can 'we' \"escape\" this properly?"}, /* string */
223       {"the_conn_escaped_string_copy", 3, 0, 0, 0, .expect_val.string_val = "Can 'we' \"escape\" this properly?", 0, "Can 'we' \"escape\" this properly?"}, /* string */
224       {"the_numstring", 3, 0, 0, 0, .expect_val.string_val = "-54321", -54321, "-54321"}, /* string */
225       {"the_empty_string", 3, 0, 0, 0, .expect_val.string_val = "", 0, ""}, /* string */
226       {"the_null_string", 3, 0, 0, 0, .expect_val.string_val = "", 0, ""}, /* string */
227       {"the_date", 5, 1, 0, 0, .expect_val.uint_val = 1009756800, 1009756800, "2001-12-31 00:00:00"}, /* DBI_DATETIME_DATE */
228       {"the_time", 5, 2, 0, 0, .expect_val.uint_val = 86399, 86399, "1970-01-01 23:59:59"}, /* DBI_DATETIME_TIME */
229       {"the_time_tz", 5, 2, 0, 0, .expect_val.uint_val = 122399, 122399, "1970-01-01 23:59:59"}, /* DBI_DATETIME_TIME */
230       {"", 0, 0, 0, 0, .expect_val.int_val = 0, 0, ""}
231 };
232 
233 
234 struct FIELDINFO mysql_fieldinfo[] = {
235       /* name, index, type,, attrib */
236       {"the_char", 1, 2, 0, 0, .expect_val.int_val = -127, -127, "-127"}, /* DBI_INTEGER_SIZE1 */
237       {"the_uchar", 1, 2, 0, 0, .expect_val.int_val = 127, 127, "127"}, /* DBI_INTEGER_SIZE1 */
238       {"the_short", 1, 4, 0, 0, .expect_val.int_val = -32768, -32768, "-32768"}, /* DBI_INTEGER_SIZE2 */
239       {"the_ushort", 1, 4, 0, 0, .expect_val.int_val = 32767, 32767, "32767"}, /* DBI_INTEGER_SIZE2 */
240       {"the_long", 1,16, 0, 0, .expect_val.int_val = -2147483648, -2147483648, "-2147483648"}, /* DBI_INTEGER_SIZE4 */
241       {"the_ulong", 1,16, 0, 0, .expect_val.int_val = 2147483647, 2147483647, "2147483647"}, /* DBI_INTEGER_SIZE4 */
242       {"the_longlong", 1,32, 0, 0, .expect_val.int_val = -9223372036854775807, -9223372036854775807, "-9223372036854775807"}, /* DBI_INTEGER_SIZE8 */
243       {"the_ulonglong", 1,32, 0, 0, .expect_val.int_val = 9223372036854775807, 9223372036854775807, "9223372036854775807"}, /* DBI_INTEGER_SIZE8 */
244       {"the_float", 2, 2, 0, 5, .expect_val.double_val = 3.402823466E+38, -9223372036854775808, "3.402820e+38"}, /* DBI_DECIMAL_SIZE4 */
245       {"the_double", 2, 4, 0, 7, .expect_val.double_val = 1.797693E+307, -9223372036854775808, "1.797693e+307"}, /* DBI_DECIMAL_SIZE8 */
246       {"the_conn_quoted_string", 3, 0, 31, 0, .expect_val.string_val = "Can \'we\' \"quote\" this properly?", 0, "Can \'we\' \"quote\" this properly?"}, /* string */
247       {"the_conn_quoted_string_copy", 3, 0, 31, 0, .expect_val.string_val = "Can \'we\' \"quote\" this properly?", 0, "Can \'we\' \"quote\" this properly?"}, /* string */
248       {"the_conn_escaped_string", 3, 0, 32, 0, .expect_val.string_val = "Can 'we' \"escape\" this properly?", 0, "Can 'we' \"escape\" this properly?"}, /* string */
249       {"the_conn_escaped_string_copy", 3, 0, 32, 0, .expect_val.string_val = "Can 'we' \"escape\" this properly?", 0, "Can 'we' \"escape\" this properly?"}, /* string */
250       {"the_numstring", 3, 0, 6, 0, .expect_val.string_val = "-54321", -54321, "-54321"}, /* string */
251       {"the_empty_string", 3, 0, 0, 0, .expect_val.string_val = "", 0, ""}, /* string */
252       {"the_null_string", 3, 0, 0, 0, .expect_val.string_val = "!", 0, ""}, /* string */
253       {"the_binary_quoted_string", 4, 0, 6, 0, .expect_val.string_val = "", 0, ""}, /* string */
254       {"the_binary_escaped_string", 4, 0, 6, 0, .expect_val.string_val = "", 0, ""}, /* string */
255       {"the_datetime", 5, 3, 0, 0, .expect_val.uint_val = 1009843199, 1009843199, "2001-12-31 23:59:59"}, /* DBI_DATETIME_DATE|TIME */
256       {"the_datetime_tz", 5, 3, 0, 0, .expect_val.uint_val = 1009843199, 1009843199, "2001-12-31 23:59:59"}, /* DBI_DATETIME_DATE|TIME */
257       {"the_date", 5, 1, 0, 0, .expect_val.uint_val = 1009756800, 1009756800, "2001-12-31 00:00:00"}, /* DBI_DATETIME_DATE */
258       {"the_time", 5, 2, 0, 0, .expect_val.uint_val = 86399, 86399, "1970-01-01 23:59:59"}, /* DBI_DATETIME_TIME */
259       {"the_time_tz", 5, 2, 0, 0, .expect_val.uint_val = 86399, 86399, "1970-01-01 23:59:59"}, /* DBI_DATETIME_TIME */
260       {"_escaped_string", 3, 0, 32, 0, .expect_val.string_val = "Can \\'we\\' \\\"escape\\\" this properly?", 0, "Can \\'we\\' \\\"escape\\\" this properly?"}, /* string */
261       {"_quoted_string", 3, 0, 31, 0, .expect_val.string_val = "'Can \\'we\\' \\\"quote\\\" this properly?'", 0, "'Can \\'we\\' \\\"quote\\\" this properly?'"}, /* string */
262       {"", 0, 0, 0, 0, .expect_val.int_val = 0, 0, ""}
263 };
264 
265 struct FIELDINFO pgsql_fieldinfo[] = {
266       /* name, index, type,, attrib */
267       {"the_char", 1, 4 /* should be 2, but there is no char type */, 0, 0, .expect_val.int_val = -127, -127, "-127"}, /* DBI_INTEGER_SIZE1 */
268       {"the_uchar", 1, 4, 0, 0, .expect_val.uint_val = 127, 127, "127"}, /* DBI_INTEGER_SIZE1 */
269       {"the_short", 1, 4, 0, 0, .expect_val.int_val = -32768, -32768, "-32768"}, /* DBI_INTEGER_SIZE2 */
270       {"the_ushort", 1, 4, 0, 0, .expect_val.int_val = 32767, 32767, "32767"}, /* DBI_INTEGER_SIZE2 */
271       {"the_long", 1,16, 0, 0, .expect_val.int_val = -2147483648, -2147483648, "-2147483648"}, /* DBI_INTEGER_SIZE4 */
272       {"the_ulong", 1,16, 0, 0, .expect_val.int_val = 2147483647, 2147483647, "2147483647"}, /* DBI_INTEGER_SIZE4 */
273       {"the_longlong", 1,32, 0, 0, .expect_val.int_val = -9223372036854775807, -9223372036854775807, "-9223372036854775807"}, /* DBI_INTEGER_SIZE8 */
274       {"the_ulonglong", 1,32, 0, 0, .expect_val.int_val = 9223372036854775807, 9223372036854775807, "9223372036854775807"}, /* DBI_INTEGER_SIZE8 */
275       {"the_float", 2, 2, 0, 5, .expect_val.double_val = 3.402823466E+38, -9223372036854775808, "3.402820e+38"}, /* DBI_DECIMAL_SIZE4 */
276       {"the_double", 2, 4, 0, 7, .expect_val.double_val =  1.797693e+307, -9223372036854775808, " 1.797693e+307"}, /* DBI_DECIMAL_SIZE8 */
277       {"the_conn_quoted_string", 3, 0, 31, 0, .expect_val.string_val = "Can \'we\' \"quote\" this properly?", 0, "Can \'we\' \"quote\" this properly?"}, /* string */
278       {"the_conn_quoted_string_copy", 3, 0, 31, 0, .expect_val.string_val = "Can \'we\' \"quote\" this properly?", 0, "Can \'we\' \"quote\" this properly?"}, /* string */
279       {"the_conn_escaped_string", 3, 0, 32, 0, .expect_val.string_val = "Can 'we' \"escape\" this properly?", 0, "Can 'we' \"escape\" this properly?"}, /* string */
280       {"the_conn_escaped_string_copy", 3, 0, 32, 0, .expect_val.string_val = "Can 'we' \"escape\" this properly?", 0, "Can 'we' \"escape\" this properly?"}, /* string */
281       {"the_numstring", 3, 0, 6, 0, .expect_val.string_val = "-54321", -54321, "-54321"}, /* string */
282       {"the_empty_string", 3, 0, 0, 0, .expect_val.string_val = "", 0, ""}, /* string */
283       {"the_null_string", 3, 0, 0, 0, .expect_val.string_val = "!", 0, ""}, /* string */
284       {"the_binary_quoted_string", 4, 0, 6, 0, .expect_val.string_val = "", 0, ""}, /* string */
285       {"the_binary_escaped_string", 4, 0, 6, 0, .expect_val.string_val = "", 0, ""}, /* string */
286       {"the_datetime", 5, 3, 0, 0, .expect_val.uint_val = 1009843199, 1009843199, "2001-12-31 23:59:59"}, /* DBI_DATETIME_DATE|TIME */
287       {"the_datetime_tz", 5, 3, 0, 0, .expect_val.uint_val = 1009879199, 1009879199, "2001-12-31 23:59:59"}, /* DBI_DATETIME_DATE|TIME */
288       {"the_date", 5, 1, 0, 0, .expect_val.uint_val = 1009756800, 1009756800, "2001-12-31 00:00:00"}, /* DBI_DATETIME_DATE */
289       {"the_time", 5, 2, 0, 0, .expect_val.uint_val = 86399, 86399, "1970-01-01 23:59:59"}, /* DBI_DATETIME_TIME */
290       {"the_time_tz", 5, 2, 0, 0, .expect_val.uint_val = 122399, 122399, "1970-01-01 23:59:59"}, /* DBI_DATETIME_TIME */
291       {"_escaped_string", 3, 0, 32, 0, .expect_val.string_val = "Can ''we'' \"escape\" this properly?", 0, "Can ''we'' \"escape\" this properly?"}, /* string */
292       {"_quoted_string", 3, 0, 31, 0, .expect_val.string_val = "'Can ''we'' \"quote\" this properly?'", 0, "'Can ''we'' \"quote\" this properly?'"}, /* string */
293       {"", 0, 0, 0, 0, .expect_val.int_val = 0, 0, ""}
294 };
295 
296 struct FIELDINFO db2_fieldinfo[] = {
297       /* name, index, type,, attrib */
298       {"the_char", 1, 2, 0, 0, .expect_val.int_val = -127, -127, "-127"}, /* DBI_INTEGER_SIZE1 */
299       {"the_uchar", 1, 2, 0, 0, .expect_val.int_val = 127, 127, "127"}, /* DBI_INTEGER_SIZE1 */
300       {"the_short", 1, 4, 0, 0, .expect_val.int_val = -32768, -32768, "-32768"}, /* DBI_INTEGER_SIZE2 */
301       {"the_ushort", 1, 4, 0, 0, .expect_val.int_val = 32768, 32768, "32768"}, /* DBI_INTEGER_SIZE2 */
302       {"the_long", 1,16, 0, 0, .expect_val.int_val = -2147483648, -2147483648, "-2147483648"}, /* DBI_INTEGER_SIZE4 */
303       {"the_ulong", 1,16, 0, 0, .expect_val.int_val = 2147483647, 2147483647, "2147483647"}, /* DBI_INTEGER_SIZE4 */
304       {"the_longlong", 1,32, 0, 0, .expect_val.int_val = -9223372036854775807, -9223372036854775807, "-9223372036854775807"}, /* DBI_INTEGER_SIZE8 */
305       {"the_ulonglong", 1,32, 0, 0, .expect_val.int_val = 9223372036854775807, 9223372036854775807, "9223372036854775807"}, /* DBI_INTEGER_SIZE8 */
306       {"the_float", 2, 2, 0, 7, .expect_val.double_val = 3.402823466E+38, 3.402823466E+38, "3.40280E+38"}, /* DBI_DECIMAL_SIZE4 */
307       {"the_double", 2, 4, 0, 7, .expect_val.double_val = 1.7E+307, 1.7E+307, "1.797693e+307"}, /* DBI_DECIMAL_SIZE8 */
308       {"the_conn_quoted_string", 3, 0, 0, 0, .expect_val.string_val = "Can \'we\' \"quote\" this properly?", 0, "Can \'we\' \"quote\" this properly?"}, /* string */
309       {"the_conn_quoted_string_copy", 3, 0, 0, 0, .expect_val.string_val = "Can \'we\' \"quote\" this properly?", 0, "Can \'we\' \"quote\" this properly?"}, /* string */
310       {"the_conn_escaped_string", 3, 0, 0, 0, .expect_val.string_val = "Can 'we' \"escape\" this properly?", 0, "Can 'we' \"escape\" this properly?"}, /* string */
311       {"the_conn_escaped_string_copy", 3, 0, 0, 0, .expect_val.string_val = "Can 'we' \"escape\" this properly?", 0, "Can 'we' \"escape\" this properly?"}, /* string */
312       {"the_numstring", 3, 0, 0, 0, .expect_val.string_val = "-54321", -54321, "-54321"}, /* string */
313       {"the_empty_string", 3, 0, 0, 0, .expect_val.string_val = "", 0, ""}, /* string */
314       {"the_null_string", 3, 0, 0, 0, .expect_val.string_val = "", 0, ""}, /* string */
315       {"the_binary_quoted_string", 4, 0, 0, 0, .expect_val.string_val = "", 0, ""}, /* string */
316       {"the_binary_escaped_string", 4, 0, 0, 0, .expect_val.string_val = "", 0, ""}, /* string */
317       {"the_datetime", 5, 3, 0, 0, .expect_val.uint_val = 1009843199, 1009843199, "2001-12-31 23:59:59"}, /* DBI_DATETIME_DATE|TIME */
318       {"the_datetime_tz", 5, 3, 0, 0, .expect_val.uint_val = 1009843199, 1009843199, "2001-12-31 23:59:59"}, /* DBI_DATETIME_DATE|TIME */
319       {"the_date", 5, 1, 0, 0, .expect_val.uint_val = 1009756800, 1009756800, "2001-12-31 00:00:00"}, /* DBI_DATETIME_DATE */
320       {"the_time", 5, 2, 0, 0, .expect_val.uint_val = 86399, 86399, "1970-01-01 23:59:59"}, /* DBI_DATETIME_TIME */
321       {"the_time_tz", 5, 2, 0, 0, .expect_val.uint_val = 122399, 122399, "1970-01-01 23:59:59"}, /* DBI_DATETIME_TIME */
322       {"", 0, 0, 0, 0, .expect_val.int_val = 0, 0, ""}
323 };
324 
325 struct FIELDINFO sqlite_fieldinfo[] = {
326       /* name, index, type,, attrib */
327       {"the_char", 1, 2, 0, 0, .expect_val.int_val = -127, -127, "-127"}, /* DBI_INTEGER_SIZE1 */
328       {"the_uchar", 1, 2, 0, 0, .expect_val.int_val = 127, 127, "127"}, /* DBI_INTEGER_SIZE1 */
329       {"the_short", 1, 4, 0, 0, .expect_val.int_val = -32768, -32768, "-32768"}, /* DBI_INTEGER_SIZE2 */
330       {"the_ushort", 1, 4, 0, 0, .expect_val.int_val = 32767, 32767, "32767"}, /* DBI_INTEGER_SIZE2 */
331       {"the_long", 1,16, 0, 0, .expect_val.int_val = -2147483648, -2147483648, "-2147483648"}, /* DBI_INTEGER_SIZE4 */
332       {"the_ulong", 1,16, 0, 0, .expect_val.int_val = 2147483647, 2147483647, "2147483647"}, /* DBI_INTEGER_SIZE4 */
333       {"the_longlong", 1,32, 0, 0, .expect_val.int_val = -9223372036854775807, -9223372036854775807, "-9223372036854775807"}, /* DBI_INTEGER_SIZE8 */
334       {"the_ulonglong", 1,32, 0, 0, .expect_val.int_val = 9223372036854775807, 9223372036854775807, "9223372036854775807"}, /* DBI_INTEGER_SIZE8 */
335       {"the_float", 2, 2, 0, 7, .expect_val.double_val = 3.402823466E+38, -9223372036854775808, "3.402823e+38"}, /* DBI_DECIMAL_SIZE4 */
336       {"the_double", 2, 4, 0, 7, .expect_val.double_val = 1.797693e+307, -9223372036854775808, "1.797693e+307"}, /* DBI_DECIMAL_SIZE8 */
337       {"the_conn_quoted_string", 3, 0, 31, 0, .expect_val.string_val = "Can \'we\' \"quote\" this properly?", 0, "Can \'we\' \"quote\" this properly?"}, /* string */
338       {"the_conn_quoted_string_copy", 3, 0, 31, 0, .expect_val.string_val = "Can \'we\' \"quote\" this properly?", 0, "Can \'we\' \"quote\" this properly?"}, /* string */
339       {"the_conn_escaped_string", 3, 0, 32, 0, .expect_val.string_val = "Can 'we' \"escape\" this properly?", 0, "Can 'we' \"escape\" this properly?"}, /* string */
340       {"the_conn_escaped_string_copy", 3, 0, 32, 0, .expect_val.string_val = "Can 'we' \"escape\" this properly?", 0, "Can 'we' \"escape\" this properly?"}, /* string */
341       {"the_numstring", 3, 0, 6, 0, .expect_val.string_val = "-54321", -54321, "-54321"}, /* string */
342       {"the_empty_string", 3, 0, 0, 0, .expect_val.string_val = "", 0, ""}, /* string */
343       {"the_null_string", 3, 0, 0, 0, .expect_val.string_val = "!" , 0, ""}, /* string: ! is a null string */
344       {"the_binary_quoted_string", 4, 0, 6, 0, .expect_val.string_val = "", 0, ""}, /* string */
345       {"the_binary_escaped_string", 4, 0, 6, 0, .expect_val.string_val = "", 0, ""}, /* string */
346       {"the_datetime", 5, 3, 0, 0, .expect_val.uint_val = 1009843199, 1009843199, "2001-12-31 23:59:59"}, /* DBI_DATETIME_DATE|TIME */
347       {"the_datetime_tz", 5, 3, 0, 0, .expect_val.uint_val = 1009879199, 1009879199, "2001-12-31 23:59:59"}, /* DBI_DATETIME_DATE|TIME */
348       {"the_date", 5, 1, 0, 0, .expect_val.uint_val = 1009756800, 1009756800, "2001-12-31 00:00:00"}, /* DBI_DATETIME_DATE */
349       {"the_time", 5, 2, 0, 0, .expect_val.uint_val = 86399, 86399, "1970-01-01 23:59:59"}, /* DBI_DATETIME_TIME */
350       {"the_time_tz", 5, 2, 0, .expect_val.uint_val = 122399, 122399, "1970-01-01 23:59:59"}, /* DBI_DATETIME_TIME */
351       {"_escaped_string", 3, 0, 32, 0, .expect_val.string_val = "Can ''we'' \"escape\" this properly?", 0, "Can ''we'' \"escape\" this properly?"}, /* string */
352       {"_quoted_string", 3, 0, 31, 0, .expect_val.string_val = "'Can ''we'' \"quote\" this properly?'", 0, "'Can ''we'' \"quote\" this properly?'"}, /* string */
353       {"", 0, 0, 0, 0, .expect_val.int_val = 0, 0, ""}
354 };
355 
356 
357 /* prototypes */
358 void init_tinfo(struct TABLEINFO* ptr_tinfo, struct CONNINFO* ptr_cinfo);
359 
360 static void create_schema();
361 static void create_schema_five_rows();
362 void drop_schema();
363 int init_schema_tables(struct CONNINFO* prt_cinfo);
364 int ask_for_conninfo(struct CONNINFO* ptr_cinfo);
365 int set_driver_options(struct CONNINFO* ptr_cinfo, dbi_conn conn, const char* encoding);
366 int my_dbi_initialize(const char *driverdir, dbi_inst *Inst);
367 void my_dbi_shutdown(dbi_inst Inst);
368 dbi_driver my_dbi_driver_list(dbi_driver Current, dbi_inst Inst);
369 dbi_conn my_dbi_conn_new(const char *name, dbi_inst Inst);
370 static void usage();
371 
372 static void open_database_driver();
373 static void close_database_driver();
374 static void open_test_database();
375 static void close_test_database();
376 static void create_database();
377 static void drop_database();
378 
379 static struct FIELDINFO* get_fieldinfo(const char* drivername);
380 static int field_index_from_name(const char* fieldname, const char* drivername);
381 static const char* field_name_from_index(int index, const char* drivername);
382 static unsigned int field_attrib_from_name(const char* fieldname, const char* drivername);
383 static unsigned int field_attrib_from_index(int index, const char* drivername);
384 static unsigned short field_type_from_name(const char* fieldname, const char* drivername);
385 static unsigned short field_type_from_index(int index, const char* drivername);
386 static long long expect_longlong_from_name(const char* fieldname, const char* drivername);
387 static long long expect_longlong_from_index(int index, const char* drivername);
388 static unsigned long long expect_ulonglong_from_name(const char* fieldname, const char* drivername);
389 static unsigned long long expect_ulonglong_from_index(int index, const char* drivername);
390 static double expect_double_from_name(const char* fieldname, const char* drivername);
391 static unsigned long long expect_double_from_index(int index, const char* drivername);
392 static const char* expect_string_from_name(const char* fieldname, const char* drivername);
393 static const char* expect_string_from_index(int index, const char* drivername);
394 static long long expect_as_longlong_from_name(const char* fieldname, const char* drivername);
395 static long long expect_as_longlong_from_index(int index, const char* drivername);
396 static const char* expect_as_string_from_name(const char* fieldname, const char* drivername);
397 static const char* expect_as_string_from_index(int index, const char* drivername);
398 
399 static int driver_has_field(const char* fieldname, const char* drivername);
400 static char* assemble_query_string(const char* drivername, int *numfields);
401 
402 /* The following macro is an assert to the result.
403  * The test case can use *errmsg and errnum
404  * to report any problem inside of they. If result is null
405  */
406 #define ASSERT_RESULT                                                                    \
407 		const char *errmsg;                                                              \
408 		int errnum;                                                                      \
409 		if(!result) {                                                                    \
410 			errnum = dbi_conn_error(conn, &errmsg);                                      \
411 			assert_not_equal_with_message(result, NULL,                                  \
412 					"Error '%d': '%s'", errnum, errmsg);                                 \
413 		}
414 
415 #define QUERY_ASSERT_RESULT(res, query)                                                  \
416 		do {                                                                             \
417 			res = dbi_conn_query(conn, query);                                           \
418 			if(!res) {                                                                   \
419 				errnum = dbi_conn_error(conn, &errmsg);                                  \
420 				assert_not_equal_with_message(res, NULL,                                 \
421 						"Error '%d': '%s'", errnum, errmsg);                             \
422 			}                                                                            \
423 		} while (0);
424 
425 
426 /* Macro to open the database inside the test case.
427  * It creates a test_conn handle
428  */
429 #define OPEN_TEST_DATABASE                                                               \
430 		do {                                                                             \
431 			test_conn = my_dbi_conn_new(cinfo.drivername,                                \
432 					dbi_instance);                                                       \
433 					if (!test_conn) {                                                    \
434 						const char *errmsg;                                              \
435 						int errnum = dbi_conn_error(test_conn, &errmsg);                 \
436 						fprintf(stderr,"Error %d dbi_conn_new_i: %s\n",                  \
437 								errnum, errmsg);                                         \
438 								exit(1);                                                 \
439 					}                                                                    \
440 					if (set_driver_options(&cinfo, test_conn, "")) {                     \
441 						my_dbi_shutdown(dbi_instance);                                   \
442 						exit(1);                                                         \
443 					}                                                                    \
444 					dbi_conn_clear_option(test_conn, "dbname");                          \
445 					dbi_conn_set_option(test_conn, "dbname",                             \
446 							cinfo.dbname);                                               \
447 							if (dbi_conn_connect(test_conn) < 0) {                       \
448 								fprintf(stderr, "Could not connect to test"              \
449 										" database\n");                                  \
450 										exit(1);                                         \
451 							}                                                            \
452 		} while(0);                                                                      \
453 
454 /* Macro to close the test database connection */
455 #define CLOSE_TEST_DATABASE                                                              \
456 		dbi_conn_close(test_conn);                                                       \
457 		test_conn = NULL;
458 
459 /* setup fixture */
460 TestSuite *connection_fixture(TestSuite *suite);
461 
462 /* tests cases */
463 TestSuite *test_libdbi();
464 TestSuite *test_database_infrastructure();
465 TestSuite *test_managing_queries();
466 TestSuite *test_transactions();
467 TestSuite *test_dbi_retrieving_fields_data_name();
468 TestSuite *test_dbi_retrieving_fields_data_idx();
469 TestSuite *test_dbi_retrieving_fields_meta_data();
470 TestSuite *test_dbi_retrieving_fields_as();
471 TestSuite *test_managing_results();
472 TestSuite *test_dbi_general_test_case();
473 TestSuite *test_dbi_misc();
474 
main(int argc,char ** argv)475 int main(int argc, char **argv) {
476 
477    CDashInfo pinfo;
478    int withcdashreport = 0;
479    char *build = NULL;
480    char *site_name = NULL;
481    char *type = NULL;
482    char *os_name = NULL;
483    char *os_platform = NULL;
484    char *os_release = NULL;
485    char *os_version = NULL;
486    char *hostname = NULL;
487 
488    int ch;
489    int runsingletest = 0;
490    static char *singletest = "";
491    const char *errmsg;
492 
493 #ifdef __FreeBSD__
494    _malloc_options="J"; /* FreeBSDs little malloc debugging helper */
495 #endif
496 
497    while ((ch = getopt(argc, argv, "N:P:R:V:H:CT:B:S:s:h?")) != -1) {
498       switch (ch) {
499       case 'N':
500          os_name = optarg;
501          break;
502       case 'P':
503          os_platform = optarg;
504          break;
505       case 'R':
506          os_release = optarg;
507          break;
508       case 'V':
509          os_version = optarg;
510          break;
511       case 'H':
512          hostname = optarg;
513          break;
514       case 's':
515          runsingletest = 1;
516          singletest = optarg;
517          break;
518       case 'C':
519          withcdashreport = 1;
520          break;
521       case 'S':
522          site_name = optarg;
523          break;
524       case 'B':
525          build = optarg;
526          break;
527       case 'T':
528          type = optarg;
529          break;
530       case 'h': /* fall through */
531       case '?': /* fall through */
532       default:
533          usage();
534       }
535    }
536    argc -= optind;
537    argv += optind;
538 
539    if (withcdashreport) {
540       if (build && type && site_name) {
541          pinfo.build = build;
542          pinfo.type = type;
543          pinfo.name = site_name;
544       } else {
545          fprintf(stderr, "Please specify a build name (-B) and site name (-S)");
546          usage();
547       }
548 
549       /* inform to cdash about your environment, just a bit */
550       if (os_name && os_release && os_platform && os_version && hostname) {
551          pinfo.hostname = hostname;
552          pinfo.os_name = os_name;
553          pinfo.os_platform = os_platform;
554          pinfo.os_release = os_release;
555          pinfo.os_version = os_version;
556       }
557    }
558 
559    if (ask_for_conninfo(&cinfo)) {
560       exit(1);
561    }
562 
563    init_tinfo(&tinfo, &cinfo);
564 
565    if (init_schema_tables(&cinfo)) {
566       exit(1);
567    }
568 
569    fprintf(stderr, "\nConnection information:\n--------------------\n");
570    fprintf(stderr,
571          "\tLegacy mode:           %d\n"
572          "\tLog query:             %d\n"
573          "\tDriverdir:             %s\n"
574          "\tDrivername:            %s\n"
575          "\tDbdir:                 %s\n"
576          "\tInitial Database:      %s\n"
577          "\tDatabase:              %s\n"
578          "\tUsername:              %s\n"
579          "\tPassword:              %s\n"
580          "\tHostname:              %s\n"
581          "\tVersion:               %s\n"
582          "\tInitial tables schema: %s\n"
583          "\tInitial sub schema:\n"
584          "\t  0: %s\n"
585          "\t  1: %s\n"
586          "\t  2: %s\n"
587          "\t  3: %s\n"
588          "\t  4: %s\n"
589          "\tInitial data schema:   %s\n",
590          cinfo.n_legacy,
591          cinfo.query_log,
592          cinfo.driverdir,
593          cinfo.drivername,
594          cinfo.dbdir,
595          cinfo.initial_dbname,
596          cinfo.dbname,
597          cinfo.username,
598          cinfo.password,
599          cinfo.hostname,
600          cinfo.version,
601          cinfo.createschema,
602          cinfo.createsubschema[0],
603          cinfo.createsubschema[1],
604          cinfo.createsubschema[2],
605          cinfo.createsubschema[3],
606          cinfo.createsubschema[4],
607          cinfo.query);
608    fprintf(stderr, "\nBegin tests:\n--------------------\n");
609 
610    /* choice the report  */
611    if (withcdashreport && runsingletest) {
612       return run_single_test(test_libdbi(), singletest, create_cdash_reporter(&pinfo));
613    }
614    else if (withcdashreport && !runsingletest) {
615       return run_test_suite(test_libdbi(), create_cdash_reporter(&pinfo));
616    }
617    else if (runsingletest) {
618       return run_single_test(test_libdbi(), singletest, create_text_reporter());
619    }
620    else {
621       return run_test_suite(test_libdbi(), create_text_reporter());
622    }
623 }
624 
625 /* helper to obtain a pointer to the appropriate fieldinfo struct */
get_fieldinfo(const char * drivername)626 static struct FIELDINFO* get_fieldinfo(const char* drivername) {
627    if (!strcmp(drivername, "firebird")) {
628       return firebird_fieldinfo;
629    }
630    else if (!strcmp(drivername, "freetds")) {
631       return freetds_fieldinfo;
632    }
633    else if (!strcmp(drivername, "ingres")) {
634       return ingres_fieldinfo;
635    }
636    else if (!strcmp(drivername, "msql")) {
637       return msql_fieldinfo;
638    }
639    else if (!strcmp(drivername, "mysql")) {
640       return mysql_fieldinfo;
641    }
642    else if (!strcmp(drivername, "pgsql")) {
643       return pgsql_fieldinfo;
644    }
645    else if (!strcmp(drivername, "db2")) {
646       return db2_fieldinfo;
647    }
648    else if (!strcmp(drivername, "sqlite")
649          ||!strcmp(drivername, "sqlite3")) {
650       return sqlite_fieldinfo;
651    }
652    return NULL;
653 }
654 
655 /* helper to translate field names into indexes (1-based) for the
656  *_idx family of functions. Returns 0 if the field name or the
657    driver name does not exist */
field_index_from_name(const char * fieldname,const char * drivername)658 static int field_index_from_name(const char* fieldname, const char* drivername) {
659    int i = 0;
660    struct FIELDINFO* ptr_fieldinfo;
661 
662    if ((ptr_fieldinfo = get_fieldinfo(drivername)) == NULL) {
663       return 0;
664    }
665 
666    while(*(ptr_fieldinfo[i].name)) {
667       if (!strcmp(ptr_fieldinfo[i].name, fieldname)) {
668          return i+1;
669       }
670       i++;
671    }
672 
673    return 0;
674 }
675 
676 /* helper to translate field indexes (1-based) into names for the
677    non-*_idx family of functions */
field_name_from_index(int index,const char * drivername)678 static const char* field_name_from_index(int index, const char* drivername) {
679    struct FIELDINFO* ptr_fieldinfo;
680 
681    if ((ptr_fieldinfo = get_fieldinfo(drivername)) == NULL) {
682       return NULL;
683    }
684 
685    return ptr_fieldinfo[index-1].name;
686 }
687 
688 /* helper to translate field names into attributes for the
689  *_get_attrib* family of functions. Returns 0 if the field name does
690    not exist */
field_attrib_from_name(const char * fieldname,const char * drivername)691 static unsigned int field_attrib_from_name(const char* fieldname, const char* drivername) {
692    int i = 0;
693    struct FIELDINFO* ptr_fieldinfo;
694 
695    if ((ptr_fieldinfo = get_fieldinfo(drivername)) == NULL) {
696       return 0;
697    }
698 
699    while(*(ptr_fieldinfo[i].name)) {
700       if (!strcmp(ptr_fieldinfo[i].name, fieldname)) {
701          return ptr_fieldinfo[i].attrib;
702       }
703       i++;
704    }
705 
706    return 0;
707 }
708 
709 /* helper to translate field indexes (1-based) into attributes for the
710  *_get_attrib* family of functions. */
field_attrib_from_index(int index,const char * drivername)711 static unsigned int field_attrib_from_index(int index, const char* drivername) {
712    struct FIELDINFO* ptr_fieldinfo;
713 
714    if ((ptr_fieldinfo = get_fieldinfo(drivername)) == NULL) {
715       return 0;
716    }
717 
718    return ptr_fieldinfo[index-1].attrib;
719 }
720 
721 /* helper to translate field names into types for the *_get_type* family
722    of functions. Returns 0 if the field name does not exist */
field_type_from_name(const char * fieldname,const char * drivername)723 static unsigned short field_type_from_name(const char* fieldname, const char* drivername) {
724    int i = 0;
725    struct FIELDINFO* ptr_fieldinfo;
726 
727    if ((ptr_fieldinfo = get_fieldinfo(drivername)) == NULL) {
728       return 0;
729    }
730 
731    while(*(ptr_fieldinfo[i].name)) {
732       if (!strcmp(ptr_fieldinfo[i].name, fieldname)) {
733          return ptr_fieldinfo[i].type;
734       }
735       i++;
736    }
737 
738    return 0;
739 }
740 
741 /* helper to translate field indexes (1-based) into types for the
742  *_get_attrib* family of functions. */
field_type_from_index(int index,const char * drivername)743 static unsigned short field_type_from_index(int index, const char* drivername) {
744    struct FIELDINFO* ptr_fieldinfo;
745 
746    if ((ptr_fieldinfo = get_fieldinfo(drivername)) == NULL) {
747       return 0;
748    }
749 
750    return ptr_fieldinfo[index-1].type;
751 }
752 
753 /* helper to translate field names into types for the *_get_type* family
754    of functions. Returns 0 if the field name does not exist */
field_length_from_name(const char * fieldname,const char * drivername)755 static unsigned short field_length_from_name(const char* fieldname, const char* drivername) {
756    int i = 0;
757    struct FIELDINFO* ptr_fieldinfo;
758 
759    if ((ptr_fieldinfo = get_fieldinfo(drivername)) == NULL) {
760       return 0;
761    }
762 
763    while(*(ptr_fieldinfo[i].name)) {
764       if (!strcmp(ptr_fieldinfo[i].name, fieldname)) {
765          return ptr_fieldinfo[i].length;
766       }
767       i++;
768    }
769 
770    return 0;
771 }
772 
773 /* helper to translate field indexes (1-based) into types for the
774  *_get_attrib* family of functions. */
field_length_from_index(int index,const char * drivername)775 static unsigned short field_length_from_index(int index, const char* drivername) {
776    struct FIELDINFO* ptr_fieldinfo;
777 
778    if ((ptr_fieldinfo = get_fieldinfo(drivername)) == NULL) {
779       return 0;
780    }
781 
782    return ptr_fieldinfo[index-1].length;
783 }
784 
785 /* helper to translate field names into expected long long
786    values. Returns 0 if the field name does not exist */
expect_longlong_from_name(const char * fieldname,const char * drivername)787 static long long expect_longlong_from_name(const char* fieldname, const char* drivername) {
788    int i = 0;
789    struct FIELDINFO* ptr_fieldinfo;
790 
791    if ((ptr_fieldinfo = get_fieldinfo(drivername)) == NULL) {
792       return 0;
793    }
794 
795    while(*(ptr_fieldinfo[i].name)) {
796       if (!strcmp(ptr_fieldinfo[i].name, fieldname)) {
797          return ptr_fieldinfo[i].expect_val.int_val;
798       }
799       i++;
800    }
801 
802    return 0;
803 }
804 
805 /* helper to translate field indexes (1-based) into expected long long values */
expect_longlong_from_index(int index,const char * drivername)806 static long long expect_longlong_from_index(int index, const char* drivername) {
807    struct FIELDINFO* ptr_fieldinfo;
808 
809    if ((ptr_fieldinfo = get_fieldinfo(drivername)) == NULL) {
810       return 0;
811    }
812 
813    return ptr_fieldinfo[index-1].expect_val.int_val;
814 }
815 
816 /* helper to translate field names into expected unsigned long long
817    values. Returns 0 if the field name does not exist */
expect_ulonglong_from_name(const char * fieldname,const char * drivername)818 static unsigned long long expect_ulonglong_from_name(const char* fieldname, const char* drivername) {
819    int i = 0;
820    struct FIELDINFO* ptr_fieldinfo;
821 
822    if ((ptr_fieldinfo = get_fieldinfo(drivername)) == NULL) {
823       return 0;
824    }
825 
826    while(*(ptr_fieldinfo[i].name)) {
827       if (!strcmp(ptr_fieldinfo[i].name, fieldname)) {
828          return ptr_fieldinfo[i].expect_val.uint_val;
829       }
830       i++;
831    }
832 
833    return 0;
834 }
835 
836 /* helper to translate field indexes (1-based) into expected unsigned
837    long long values */
expect_ulonglong_from_index(int index,const char * drivername)838 static unsigned long long expect_ulonglong_from_index(int index, const char* drivername) {
839    struct FIELDINFO* ptr_fieldinfo;
840 
841    if ((ptr_fieldinfo = get_fieldinfo(drivername)) == NULL) {
842       return 0;
843    }
844 
845    return ptr_fieldinfo[index-1].expect_val.uint_val;
846 }
847 
848 /* helper to translate field names into expected double
849    values. Returns 0 if the field name does not exist */
expect_double_from_name(const char * fieldname,const char * drivername)850 static double expect_double_from_name(const char* fieldname, const char* drivername) {
851    int i = 0;
852    struct FIELDINFO* ptr_fieldinfo;
853 
854    if ((ptr_fieldinfo = get_fieldinfo(drivername)) == NULL) {
855       return 0;
856    }
857 
858    while(*(ptr_fieldinfo[i].name)) {
859       if (!strcmp(ptr_fieldinfo[i].name, fieldname)) {
860          significant_figures_for_assert_double_are(ptr_fieldinfo[i].figures);
861          return ptr_fieldinfo[i].expect_val.double_val;
862       }
863       i++;
864    }
865 
866    return 0;
867 }
868 
869 /* helper to translate field indexes (1-based) into expected double values */
expect_double_from_index(int index,const char * drivername)870 static unsigned long long expect_double_from_index(int index, const char* drivername) {
871    struct FIELDINFO* ptr_fieldinfo;
872 
873    if ((ptr_fieldinfo = get_fieldinfo(drivername)) == NULL) {
874       return 0;
875    }
876 
877    significant_figures_for_assert_double_are(ptr_fieldinfo[index-1].figures);
878    return ptr_fieldinfo[index-1].expect_val.double_val;
879 }
880 
881 /* helper to translate field names into expected string
882    values. Returns 0 if the field name does not exist */
expect_string_from_name(const char * fieldname,const char * drivername)883 static const char* expect_string_from_name(const char* fieldname, const char* drivername) {
884    int i = 0;
885    struct FIELDINFO* ptr_fieldinfo;
886 
887    if ((ptr_fieldinfo = get_fieldinfo(drivername)) == NULL) {
888       return 0;
889    }
890 
891    while(*(ptr_fieldinfo[i].name)) {
892       if (!strcmp(ptr_fieldinfo[i].name, fieldname)) {
893          if (ptr_fieldinfo[i].expect_val.string_val[0] == '!')
894             return NULL;
895 
896          return (const char*)ptr_fieldinfo[i].expect_val.string_val;
897       }
898       i++;
899    }
900 
901    return 0;
902 }
903 
904 /* helper to translate field indexes (1-based) into expected string values */
expect_string_from_index(int index,const char * drivername)905 static const char* expect_string_from_index(int index, const char* drivername) {
906    struct FIELDINFO* ptr_fieldinfo;
907 
908    if ((ptr_fieldinfo = get_fieldinfo(drivername)) == NULL) {
909       return 0;
910    }
911 
912    return ptr_fieldinfo[index-1].expect_val.string_val;
913 }
914 
915 /* helper to translate field names into expected as_longlong
916    values. Returns 0 if the field name does not exist */
expect_as_longlong_from_name(const char * fieldname,const char * drivername)917 static long long expect_as_longlong_from_name(const char* fieldname, const char* drivername) {
918    int i = 0;
919    struct FIELDINFO* ptr_fieldinfo;
920 
921    if ((ptr_fieldinfo = get_fieldinfo(drivername)) == NULL) {
922       return 0;
923    }
924 
925    while(*(ptr_fieldinfo[i].name)) {
926       if (!strcmp(ptr_fieldinfo[i].name, fieldname)) {
927          return ptr_fieldinfo[i].expect_as_longlong;
928       }
929       i++;
930    }
931 
932    return 0;
933 }
934 
935 /* helper to translate field indexes (1-based) into expected as_longlong values */
expect_as_longlong_from_index(int index,const char * drivername)936 static long long expect_as_longlong_from_index(int index, const char* drivername) {
937    struct FIELDINFO* ptr_fieldinfo;
938 
939    if ((ptr_fieldinfo = get_fieldinfo(drivername)) == NULL) {
940       return 0;
941    }
942 
943    return ptr_fieldinfo[index-1].expect_as_longlong;
944 }
945 
946 /* helper to translate field names into expected as_string
947    values. Returns 0 if the field name does not exist */
expect_as_string_from_name(const char * fieldname,const char * drivername)948 static const char* expect_as_string_from_name(const char* fieldname, const char* drivername) {
949    int i = 0;
950    struct FIELDINFO* ptr_fieldinfo;
951 
952    if ((ptr_fieldinfo = get_fieldinfo(drivername)) == NULL) {
953       return 0;
954    }
955 
956    while(*(ptr_fieldinfo[i].name)) {
957       if (!strcmp(ptr_fieldinfo[i].name, fieldname)) {
958          return (const char*)ptr_fieldinfo[i].expect_as_string;
959       }
960       i++;
961    }
962 
963    return 0;
964 }
965 
966 /* helper to translate field indexes (1-based) into expected as_string values */
expect_as_string_from_index(int index,const char * drivername)967 static const char* expect_as_string_from_index(int index, const char* drivername) {
968    struct FIELDINFO* ptr_fieldinfo;
969 
970    if ((ptr_fieldinfo = get_fieldinfo(drivername)) == NULL) {
971       return 0;
972    }
973 
974    return (const char*)ptr_fieldinfo[index-1].expect_as_string;
975 }
976 
977 /* helper to assemble a query string from the table index hashes. The
978    resulting query string retrieves all fields mentioned in the hash
979    in the given order from test_datatypes. The returned string should
980    be freed by the calling function */
assemble_query_string(const char * drivername,int * numfields)981 static char* assemble_query_string(const char* drivername, int *numfields) {
982    char* query_string = NULL;
983    int i = 0;
984    int j = 0;
985    size_t query_string_len = 1024;
986    struct FIELDINFO* ptr_fieldinfo;
987 
988    if ((ptr_fieldinfo = get_fieldinfo(drivername)) == NULL) {
989       return NULL;
990    }
991 
992    *numfields = 0;
993 
994    if ((query_string = malloc(query_string_len)) == NULL) {
995       return NULL;
996    }
997 
998    strcpy(query_string, "SELECT ");
999 
1000    while(*(ptr_fieldinfo[i].name)) {
1001       if (ptr_fieldinfo[i].name[0] == '_') { /* special field,  don't go into schema */
1002          i++;
1003          j++;
1004          continue;
1005       }
1006       strcat(query_string, ptr_fieldinfo[i].name);
1007       strcat(query_string, ",");
1008       i++;
1009       if (i%30 == 0) { /* assume that 30 field names with 32 chars each will fit */
1010          query_string_len += 1024;
1011          if ((query_string = realloc(query_string, query_string_len)) == NULL) {
1012             return NULL;
1013          }
1014       }
1015    }
1016 
1017    query_string[strlen(query_string)-1] = '\0'; /* remove trailing comma */
1018    strcat(query_string, " from test_datatypes");
1019    *numfields = i-j; /* do not count special fields */
1020    return query_string;
1021 }
1022 
1023 /* fill tableinfo structure with values based on the hashes */
init_tinfo(struct TABLEINFO * ptr_tinfo,struct CONNINFO * ptr_cinfo)1024 void init_tinfo(struct TABLEINFO* ptr_tinfo, struct CONNINFO* ptr_cinfo) {
1025    ptr_tinfo->have_double = driver_has_field("the_double", ptr_cinfo->drivername);
1026    ptr_tinfo->have_longlong = driver_has_field("the_longlong", ptr_cinfo->drivername);
1027    ptr_tinfo->have_ulonglong = driver_has_field("the_ulonglong", ptr_cinfo->drivername);
1028    ptr_tinfo->have_datetime = driver_has_field("the_datetime", ptr_cinfo->drivername);
1029    ptr_tinfo->have_datetime_tz = driver_has_field("the_datetime_tz", ptr_cinfo->drivername);
1030    ptr_tinfo->have_time_tz = driver_has_field("the_time_tz", ptr_cinfo->drivername);
1031    ptr_tinfo->number_rows = 1;
1032 }
1033 
driver_has_field(const char * fieldname,const char * drivername)1034 static int driver_has_field(const char* fieldname, const char* drivername) {
1035    int i = 0;
1036    struct FIELDINFO* ptr_fieldinfo;
1037 
1038    if ((ptr_fieldinfo = get_fieldinfo(drivername)) == NULL) {
1039       return 0;
1040    }
1041 
1042    while(*(ptr_fieldinfo[i].name)) {
1043       if (!strcmp(ptr_fieldinfo[i].name, fieldname)) {
1044          return 1;
1045       }
1046       i++;
1047    }
1048 
1049    return 0;
1050 }
1051 
1052 /*
1053  * Before begin a test, create a database and some tables to test
1054  */
create_schema_five_rows()1055 static void create_schema_five_rows() {
1056    tinfo.number_rows = 5;
1057    create_schema();
1058 }
1059 
1060 /*
1061  * This is the setup function. We can change any option using functions
1062  * like create_schema_five_rows above
1063  */
create_schema()1064 static void create_schema() {
1065    dbi_result result = NULL;
1066    const char *errmsg;
1067    int errnum;
1068    int i;
1069    /*  int first_schema = 1;*/
1070 
1071    if (!conn) {
1072       errnum = dbi_conn_error(conn, &errmsg);
1073       printf("Error %d, create_schema, conn is null: %s\n", errnum, errmsg);
1074       my_dbi_shutdown(dbi_instance);
1075       exit(1);
1076    }
1077 
1078    /* First we try to create the schema table. If this was bad
1079     * (i.e: table exists) we try drop table and create again.
1080     */
1081    while (!result) {
1082       if ((result = dbi_conn_query(conn, cinfo.createschema)) == NULL) {
1083          dbi_conn_error(conn, &errmsg);
1084          printf("First try, can't create table! %s\n", errmsg);
1085 
1086          if ((result = dbi_conn_query(conn, "DROP TABLE test_datatypes")) == NULL) {
1087             dbi_conn_error(conn, &errmsg);
1088             printf("Can't drop table! %s\n", errmsg);
1089             my_dbi_shutdown(dbi_instance);
1090             exit(1);
1091          }
1092 
1093          /*      first_schema = 0;*/
1094 
1095          dbi_result_free(result);
1096 
1097          if ((result = dbi_conn_query(conn, cinfo.createschema)) == NULL) {
1098             dbi_conn_error(conn, &errmsg);
1099             printf("Second try, can't create table! %s\n", errmsg);
1100             my_dbi_shutdown(dbi_instance);
1101             exit(1);
1102          }
1103       }
1104    }
1105 
1106    dbi_result_free(result);
1107 
1108    /*  if(first_schema) {*/
1109    for ( i = 0; strlen(cinfo.createsubschema[i]) != 0 ; i++ ) {
1110       if ((result = dbi_conn_query(conn, cinfo.createsubschema[i])) == NULL) {
1111          errnum = dbi_conn_error(conn, &errmsg);
1112          printf("Can't create sub schema data (%d)! %s\n", i, errmsg);
1113          my_dbi_shutdown(dbi_instance);
1114          exit(1);
1115       }
1116       dbi_result_free(result);
1117    }
1118    /*}*/
1119 
1120    for ( i = 1; i <= tinfo.number_rows; i++ ) {
1121       if ((result = dbi_conn_query(conn, cinfo.query)) == NULL) {
1122          errnum = dbi_conn_error(conn, &errmsg);
1123          printf("Can't insert data! %s\n", errmsg);
1124          my_dbi_shutdown(dbi_instance);
1125          exit(1);
1126       }
1127    }
1128 
1129    dbi_result_free(result);
1130 
1131 }
1132 
1133 /*
1134  * Always drop the table (and any other object) after any tests
1135  */
drop_schema()1136 void drop_schema() {
1137    dbi_result result;
1138    const char *errmsg;
1139    int errnum;
1140    int i;
1141 
1142    if (!conn) {
1143       printf("\tError %d, drop_schema, conn is null: %s\n", dbi_conn_error(conn, &errmsg), errmsg);
1144       my_dbi_shutdown(dbi_instance);
1145       exit(1);
1146    }
1147 
1148    if (!strcmp(cinfo.drivername, "firebird")) {
1149      /* firebird does not support DROP TABLE in regular SQL
1150 	but offers it as an isql extension */
1151      char command[1024];
1152 
1153      for ( i = 0; strlen(cinfo.dropsubschema[i]) != 0 ; i++ ) {
1154        if (!*(cinfo.hostname)) {
1155          snprintf(command, 1024,
1156 		  "echo \"CONNECT \'%s/%s\';%s;\""
1157 		  "| %s -e -pas %s "
1158 		  "-u %s -sql_dialect 3", cinfo.dbdir,
1159 		  cinfo.dbname,
1160 		  cinfo.dropsubschema[i],
1161 		  FIREBIRD_ISQL,
1162 		  cinfo.password, cinfo.username);
1163        }
1164        else { /* remote */
1165          snprintf(command, 1024,
1166 		  "echo \"CONNECT \'%s:%s/%s\';%s;\""
1167 		  "| %s -e -pas %s "
1168 		  "-u %s -sql_dialect 3", cinfo.hostname, cinfo.dbdir,
1169 		  cinfo.dbname,
1170 		  cinfo.dropsubschema[i],
1171 		  FIREBIRD_ISQL,
1172 		  cinfo.password, cinfo.username);
1173        }
1174        if (system(command)) {
1175          fprintf(stderr,"\tAAH! Can't drop subschema %s<< connected to database %s! Error message: %s\n", cinfo.dropsubschema[i], cinfo.dbname, errmsg);
1176        }
1177      } /* end for */
1178 
1179      if (!*(cinfo.hostname)) {
1180        snprintf(command, 1024,
1181 		"echo \"CONNECT \'%s/%s\';DROP TABLE test_datatypes;\""
1182 		"| %s -e -pas %s "
1183 		"-u %s -sql_dialect 3", cinfo.dbdir,
1184 		cinfo.dbname,
1185 		FIREBIRD_ISQL,
1186 		cinfo.password, cinfo.username);
1187      }
1188      else { /* remote */
1189        snprintf(command, 1024,
1190 		"echo \"CONNECT \'%s:%s/%s\';DROP TABLE test_datatypes;\""
1191 		"| %s -e -pas %s "
1192 		"-u %s -sql_dialect 3", cinfo.hostname, cinfo.dbdir,
1193 		cinfo.dbname,
1194 		FIREBIRD_ISQL,
1195 		cinfo.password, cinfo.username);
1196      }
1197      if (system(command)) {
1198        fprintf(stderr,"\tAAH! Can't drop table test_datatypes<< connected to database %s! Error message: %s\n", cinfo.dbname, errmsg);
1199      }
1200    }
1201    else { /* not firebird */
1202      for ( i = 0; strlen(cinfo.dropsubschema[i]) != 0 ; i++ ) {
1203        if ((result = dbi_conn_query(conn, cinfo.dropsubschema[i])) == NULL) {
1204          errnum = dbi_conn_error(conn, &errmsg);
1205          printf("\tCan't drop sub schema data (%d)! %s\n", i, errmsg);
1206          my_dbi_shutdown(dbi_instance);
1207          exit(1);
1208        }
1209        dbi_result_free(result);
1210      }
1211 
1212      if ((result = dbi_conn_query(conn, "DROP TABLE test_datatypes")) == NULL) {
1213        errnum = dbi_conn_error(conn, &errmsg);
1214        printf("\tCan't drop table test_datatypes Error '%d' message: %s\n", errnum, errmsg);
1215      }
1216 
1217      dbi_result_free(result);
1218    }
1219 
1220 }
1221 
1222 /*
1223  * We'll need some tables to test, used by many tests
1224  */
init_schema_tables(struct CONNINFO * ptr_cinfo)1225 int init_schema_tables(struct CONNINFO* ptr_cinfo) {
1226 
1227    /* ATTENTION: when changing the table definitions below, please
1228      update the field name vs. index hashes at the top of this file
1229      accordingly */
1230 
1231    if (!strcmp(ptr_cinfo->drivername, "firebird")) {
1232       snprintf(ptr_cinfo->createschema, QUERY_LEN, "CREATE TABLE test_datatypes ( "
1233             "the_char SMALLINT,"
1234             "the_uchar SMALLINT,"
1235             "the_short SMALLINT, "
1236             "the_ushort SMALLINT,"
1237             "the_long INTEGER,"
1238             "the_ulong INTEGER, "
1239             "the_float FLOAT,"
1240             "the_double DOUBLE PRECISION, "
1241             "the_conn_quoted_string VARCHAR(255),"
1242             "the_conn_quoted_string_copy VARCHAR(255),"
1243             "the_conn_escaped_string VARCHAR(255),"
1244             "the_conn_escaped_string_copy VARCHAR(255),"
1245             "the_numstring VARCHAR(255),"
1246             "the_empty_string VARCHAR(255),"
1247             "the_null_string VARCHAR(255), "
1248             "the_binary_quoted_string BLOB,"
1249             "the_binary_escaped_string BLOB,"
1250             "the_datetime TIMESTAMP, "
1251             "the_date DATE,"
1252             "the_time TIME,"
1253             "id INTEGER NOT NULL PRIMARY KEY);");
1254       snprintf(ptr_cinfo->createsubschema[0], QUERY_LEN, "CREATE GENERATOR gen_t1_id;");
1255       snprintf(ptr_cinfo->createsubschema[1], QUERY_LEN, "SET GENERATOR gen_t1_id TO 0;");
1256       snprintf(ptr_cinfo->createsubschema[2], QUERY_LEN,
1257             "CREATE TRIGGER T1_BI FOR TEST_DATATYPES ACTIVE BEFORE INSERT POSITION 0"
1258             " AS"
1259             " BEGIN"
1260             " if (NEW.ID is NULL) then NEW.ID = GEN_ID(GEN_T1_ID, 1);"
1261             " END");
1262       snprintf(ptr_cinfo->dropsubschema[0], QUERY_LEN, "DROP TRIGGER T1_BI");
1263       snprintf(ptr_cinfo->dropsubschema[1], QUERY_LEN, "DROP GENERATOR gen_t1_id");
1264 
1265       snprintf(ptr_cinfo->query, QUERY_LEN, "INSERT INTO test_datatypes ("
1266             "the_char,"
1267             "the_uchar,"
1268             "the_short, "
1269             "the_ushort,"
1270             "the_long,"
1271             "the_ulong,"
1272             "the_float,"
1273             "the_double, "
1274             "the_conn_quoted_string,"
1275             "the_conn_quoted_string_copy,"
1276             "the_conn_escaped_string,"
1277             "the_conn_escaped_string_copy,"
1278             "the_numstring,"
1279             "the_empty_string,"
1280             "the_null_string,"
1281             "the_binary_quoted_string,  "
1282             "the_binary_escaped_string,  "
1283             "the_datetime,"
1284             "the_date,"
1285             "the_time"
1286             ") "
1287             "VALUES ("
1288             "-127,"
1289             "127,"
1290             "-32768,"
1291             "32767,"
1292             "-2147483648,"
1293             "2147483647, "
1294             "3.4e+37,"
1295             "1.7e+307,"
1296             "'Can ''we'' \"quote\" this properly?',"
1297             "'Can ''we'' \"quote\" this properly?',"
1298             "'Can ''we'' \"escape\" this properly?',"
1299             "'Can ''we'' \"escape\" this properly?',"
1300             "'%s',"
1301             "'',"
1302             "NULL,"
1303             "'\x01\x40\x41\xff\x42\x26\x43',"
1304             "'\x01\x40\x41\xff\x42\x26\x43',"
1305             "'2001-12-31 23:59:59',"
1306             "'2001-12-31',"
1307             "'23:59:59'"
1308             ");", numstring);
1309    }
1310    else if (!strcmp(ptr_cinfo->drivername, "freetds")) {
1311       snprintf(ptr_cinfo->createschema, QUERY_LEN, "CREATE TABLE test_datatypes ( "
1312             "the_char TINYINT,"
1313             "the_uchar TINYINT,"
1314             "the_short SMALLINT,"
1315             "the_ushort SMALLINT,"
1316             "the_long INT,"
1317             "the_ulong INT,"
1318             "the_longlong BIGINT,"
1319             "the_ulonglong BIGINT,"
1320             "the_float REAL,"
1321             "the_double FLOAT,"
1322             "the_conn_quoted_string VARCHAR(255),"
1323             "the_conn_quoted_string_copy VARCHAR(255),"
1324             "the_conn_escaped_string VARCHAR(255),"
1325             "the_conn_escaped_string_copy VARCHAR(255),"
1326             "the_numstring VARCHAR(255),"
1327             "the_empty_string VARCHAR(255),"
1328             "the_null_string VARCHAR(255),"
1329             "the_binary_quoted_string IMAGE,"
1330             "the_binary_escaped_string IMAGE,"
1331             "the_datetime DATETIME,"
1332             "the_date DATETIME,"
1333             "the_time DATETIME,"
1334             "id INT IDENTITY,"
1335             "CONSTRAINT tr_test_datatypes PRIMARY KEY (id))");
1336       /*
1337        * For test one byte data type use TINYINT
1338        * this is unsigned type and by insert replace
1339        * -127 to binary equivalent 129
1340        */
1341       snprintf(ptr_cinfo->query, QUERY_LEN, "INSERT INTO test_datatypes ("
1342             "the_char,"
1343             "the_uchar,"
1344             "the_short,"
1345             "the_ushort,"
1346             "the_long,"
1347             "the_ulong,"
1348             "the_longlong,"
1349             "the_ulonglong,"
1350             "the_float,"
1351             "the_double,"
1352             "the_conn_quoted_string,"
1353             "the_conn_quoted_string_copy,"
1354             "the_conn_escaped_string,"
1355             "the_conn_escaped_string_copy,"
1356             "the_numstring,"
1357             "the_empty_string,"
1358             "the_null_string,"
1359             "the_binary_quoted_string,"
1360             "the_binary_escaped_string,"
1361             "the_datetime,"
1362             "the_date,"
1363             "the_time) VALUES ("
1364             "-127,"
1365             "127,"
1366             "-32768,"
1367             "32767,"
1368             "-2147483648,"
1369             "2147483647,"
1370             "-2147483648,"
1371             "2147483647, "
1372             "3.4e+37,"
1373             "1.7e+307,"
1374             "'Can \\'we\\' \"quote\" this properly?',"
1375             "'Can \\'we\\' \"quote\" this properly?',"
1376             "'Can \\'we\\' \"escape\" this properly?',"
1377             "'Can \\'we\\' \"escape\" this properly?',"
1378             "'%s',"
1379             "'',"
1380             "NULL,"
1381             "'\x01\x40\x41\xff\x42\x26\x43',"
1382             "'\x01\x40\x41\xff\x42\x26\x43',"
1383             "'2001-12-31 23:59:59',"
1384             "'2001-12-31',"
1385             "'23:59:59',"
1386             "1)",
1387             numstring);
1388    }
1389    else if (!strcmp(ptr_cinfo->drivername, "ingres")) {
1390       snprintf(ptr_cinfo->createschema, QUERY_LEN, "CREATE TABLE test_datatypes ( "
1391             "the_char TINYINT,"
1392             "the_uchar TINYINT,"
1393             "the_short SMALLINT,"
1394             "the_ushort SMALLINT,"
1395             "the_long INT,"
1396             "the_ulong INT,"
1397             "the_longlong BIGINT,"
1398             "the_ulonglong BIGINT,"
1399             "the_float FLOAT4,"
1400             "the_double FLOAT,"
1401             "the_decimal DECIMAL(12,4),"
1402             "the_money MONEY,"
1403             "the_character CHAR(50),"
1404             "the_byte BYTE(50),"
1405             "the_conn_quoted_string VARCHAR(255),"
1406             "the_conn_quoted_string_copy VARCHAR(255),"
1407             "the_conn_escaped_string VARCHAR(255),"
1408             "the_conn_escaped_string_copy VARCHAR(255),"
1409             "the_numstring VARCHAR(255),"
1410             "the_empty_string VARCHAR(255),"
1411             "the_null_string VARCHAR(255),"
1412             "the_binary_quoted_string BLOB,"
1413             "the_binary_escaped_string BLOB,"
1414             "the_datetime DATE,"
1415             "the_date DATE,"
1416             "the_time DATE,"
1417             "id INT NOT NULL CONSTRAINT id_key PRIMARY KEY)");
1418 
1419       strcat(ptr_cinfo->createschema, "; CREATE SEQUENCE test_datatypes_id_seq");
1420       snprintf(ptr_cinfo->query, QUERY_LEN, "INSERT INTO test_datatypes VALUES ("
1421             "-127,"
1422             "127,"
1423             "-32768,"
1424             "32767,"
1425             "-2147483648,"
1426             "2147483647, "
1427             "-9223372036854775807,"
1428             "9223372036854775807,"
1429             "3.4e+37,"
1430             "1.7e+307,"
1431             "'1234.5678',"
1432             "'$567.89',"
1433             "'char column',"
1434             "X'07ff656667',"
1435             "my_string_to_quote,"
1436             "quoted_string,"
1437             "'my_string_to_escape',"
1438             "'escaped_string,',"
1439             "'%s',"
1440             "'',"
1441             "NULL,"
1442             "quoted_binary,"
1443             "'escaped_binary',"
1444             "'31-dec-2001 23:59:59',"
1445             "'31-dec-2001',"
1446             "'23:59:59',"
1447             "NEXT VALUE FOR test_datatypes_id_seq)",
1448             numstring);
1449    }
1450    else if (!strcmp(ptr_cinfo->drivername, "msql")) {
1451       snprintf(ptr_cinfo->createschema, QUERY_LEN, "CREATE TABLE test_datatypes ( "
1452             "the_char INT8,"
1453             "the_uchar UINT8,"
1454             "the_short INT16,"
1455             "the_ushort UINT16,"
1456             "the_long INT,"
1457             "the_ulong UINT,"
1458             "the_longlong INT64,"
1459             "the_ulonglong UINT64,"
1460             "the_float REAL,"
1461             "the_conn_quoted_string CHAR(255),"
1462             "the_conn_quoted_string_copy CHAR(255),"
1463             "the_conn_escaped_string CHAR(255),"
1464             "the_conn_escaped_string_copy CHAR(255),"
1465             "the_numstring CHAR(255),"
1466             "the_empty_string VARCHAR(255),"
1467             "the_null_string VARCHAR(255),"
1468             "the_date DATE,"
1469             "the_time TIME,"
1470             "the_time_tz TIME,"
1471             "id INT)");
1472 
1473       snprintf(ptr_cinfo->query, QUERY_LEN, "INSERT INTO test_datatypes VALUES ("
1474             "-127,"
1475             "127,"
1476             "-32767,"
1477             "32767,"
1478             "-2147483647,"
1479             "2147483647,"
1480             "-9223372036854775807,"
1481             "9223372036854775807,"
1482             "3.402823466E+38,"
1483             "my_string_to_quote,"
1484             "quoted_string,"
1485             "'my_string_to_escape',"
1486             "'escaped_string',"
1487             "'%s',"
1488             "'',"
1489             "NULL,"
1490             "'11-jul-1977',"
1491             "'23:59:59',"
1492             "NULL)",
1493             numstring);
1494    }
1495    else if (!strcmp(ptr_cinfo->drivername, "mysql")) {
1496       snprintf(ptr_cinfo->createschema, QUERY_LEN, "CREATE TABLE test_datatypes ( "
1497             "the_char TINYINT,"
1498             "the_uchar TINYINT,"
1499             "the_short SMALLINT,"
1500             "the_ushort SMALLINT,"
1501             "the_long INT,"
1502             "the_ulong INT,"
1503             "the_longlong BIGINT,"
1504             "the_ulonglong BIGINT,"
1505             "the_float FLOAT4,"
1506             "the_double FLOAT8,"
1507             "the_conn_quoted_string VARCHAR(255),"
1508             "the_conn_quoted_string_copy VARCHAR(255),"
1509             "the_conn_escaped_string VARCHAR(255),"
1510             "the_conn_escaped_string_copy VARCHAR(255),"
1511             "the_numstring VARCHAR(255),"
1512             "the_empty_string VARCHAR(255),"
1513             "the_null_string VARCHAR(255),"
1514             "the_binary_quoted_string BLOB,"
1515             "the_binary_escaped_string BLOB,"
1516             "the_datetime DATETIME,"
1517             "the_datetime_tz DATETIME,"
1518             "the_date DATE,"
1519             "the_time TIME,"
1520             "the_time_tz TIME,"
1521             "id INT AUTO_INCREMENT,"
1522             "PRIMARY KEY (id)) "
1523 	       "ENGINE=InnoDB");
1524 
1525       snprintf(ptr_cinfo->query, QUERY_LEN, "INSERT INTO test_datatypes ("
1526             "the_char,"
1527             "the_uchar,"
1528             "the_short,"
1529             "the_ushort,"
1530             "the_long,"
1531             "the_ulong,"
1532             "the_longlong,"
1533             "the_ulonglong,"
1534             "the_float,"
1535             "the_double,"
1536             "the_conn_quoted_string,"
1537             "the_conn_quoted_string_copy,"
1538             "the_conn_escaped_string,"
1539             "the_conn_escaped_string_copy,"
1540             "the_numstring,"
1541             "the_empty_string,"
1542             "the_null_string,"
1543             "the_binary_quoted_string,"
1544             "the_binary_escaped_string,"
1545             "the_datetime,"
1546             "the_datetime_tz,"
1547             "the_date,"
1548             "the_time,"
1549             "the_time_tz) VALUES ("
1550             "-127,"
1551             "127,"
1552             "-32768,"
1553             "32767,"
1554             "-2147483648,"
1555             "2147483647,"
1556             "-9223372036854775807,"
1557             "9223372036854775807,"
1558             "3.402823466E+38,"
1559             "1.7976931348623157E+307,"
1560             "'Can ''we'' \"quote\" this properly?',"
1561             "'Can ''we'' \"quote\" this properly?',"
1562             "'Can ''we'' \"escape\" this properly?',"
1563             "'Can ''we'' \"escape\" this properly?',"
1564             "'%s',"
1565             "'',"
1566             "NULL,"
1567             "'AB\\0C\\\'D',"
1568             "'AB\\0C\\\'D',"
1569             "'2001-12-31 23:59:59',"
1570             "'2001-12-31 23:59:59 -10:00',"
1571             "'2001-12-31',"
1572             "'23:59:59',"
1573             "'23:59:59-10:00')",
1574             numstring);
1575    }
1576    else if (!strcmp(ptr_cinfo->drivername, "pgsql")) {
1577       /* PostgreSQL does not have a 1-byte integer, use smallint
1578        instead. This will raise a warning when retrieving the value */
1579       snprintf(ptr_cinfo->createschema, QUERY_LEN, "CREATE TABLE test_datatypes ( "
1580             "the_char SMALLINT,"
1581             "the_uchar SMALLINT,"
1582             "the_short SMALLINT,"
1583             "the_ushort SMALLINT,"
1584             "the_long INT,"
1585             "the_ulong INT,"
1586             "the_longlong BIGINT,"
1587             "the_ulonglong BIGINT,"
1588             "the_float FLOAT4,"
1589             "the_double FLOAT8,"
1590             "the_conn_quoted_string VARCHAR(255),"
1591             "the_conn_quoted_string_copy VARCHAR(255),"
1592             "the_conn_escaped_string VARCHAR(255),"
1593             "the_conn_escaped_string_copy VARCHAR(255),"
1594             "the_numstring VARCHAR(255),"
1595             "the_empty_string VARCHAR(255),"
1596             "the_null_string VARCHAR(255),"
1597             "the_binary_quoted_string BYTEA,"
1598             "the_binary_escaped_string BYTEA,"
1599             "the_datetime TIMESTAMP,"
1600             "the_datetime_tz TIMESTAMP WITH TIME ZONE,"
1601             "the_date DATE,"
1602             "the_time TIME,"
1603             "the_time_tz TIME WITH TIME ZONE,"
1604             "id SERIAL PRIMARY KEY)");
1605 
1606       snprintf(ptr_cinfo->query, QUERY_LEN, "INSERT INTO test_datatypes ("
1607             "the_char,"
1608             "the_uchar,"
1609             "the_short,"
1610             "the_ushort,"
1611             "the_long,"
1612             "the_ulong,"
1613             "the_longlong,"
1614             "the_ulonglong,"
1615             "the_float,"
1616             "the_double,"
1617             "the_conn_quoted_string,"
1618             "the_conn_quoted_string_copy,"
1619             "the_conn_escaped_string,"
1620             "the_conn_escaped_string_copy,"
1621             "the_numstring,"
1622             "the_empty_string,"
1623             "the_null_string,"
1624             "the_binary_quoted_string,"
1625             "the_binary_escaped_string,"
1626             "the_datetime,"
1627             "the_datetime_tz,"
1628             "the_date,"
1629             "the_time,"
1630             "the_time_tz) VALUES ("
1631             "-127,"
1632             "127,"
1633             "-32768,"
1634             "32767,"
1635             "-2147483648,"
1636             "2147483647,"
1637             "-9223372036854775807,"
1638             "9223372036854775807,"
1639             "3.402823466E+38,"
1640             "1.7976931348623157E+307,"
1641             "'Can '\'we\'' \"quote\" this properly?',"
1642             "'Can '\'we\'' \"quote\" this properly?',"
1643             "'Can '\'we\'' \"escape\" this properly?',"
1644             "'Can '\'we\'' \"escape\" this properly?',"
1645             "'%s',"
1646             "'',"
1647             "NULL,"
1648             "'AB\\\\000C''D',"
1649             "'AB\\\\000C''D',"
1650             "'2001-12-31 23:59:59',"
1651             "'2001-12-31 23:59:59 -10:00',"
1652             "'2001-12-31',"
1653             "'23:59:59',"
1654             "'23:59:59-10:00')",
1655             numstring);
1656    }
1657    else if (!strcmp(ptr_cinfo->drivername, "db2")) {
1658       snprintf(ptr_cinfo->createschema, QUERY_LEN, "CREATE TABLE test_datatypes ( "
1659             "the_char SMALLINT,"
1660             "the_uchar SMALLINT,"
1661             "the_short SMALLINT,"
1662             "the_ushort SMALLINT,"
1663             "the_long INT,"
1664             "the_ulong INT,"
1665             "the_longlong BIGINT,"
1666             "the_ulonglong BIGINT,"
1667             "the_float FLOAT,"
1668             "the_double DOUBLE,"
1669             "the_conn_quoted_string VARCHAR(255),"
1670             "the_conn_quoted_string_copy VARCHAR(255),"
1671             "the_conn_escaped_string VARCHAR(255),"
1672             "the_conn_escaped_string_copy VARCHAR(255),"
1673             "the_numstring VARCHAR(255),"
1674             "the_empty_string VARCHAR(255),"
1675             "the_null_string VARCHAR(255),"
1676             "the_binary_quoted_string CLOB,"
1677             "the_binary_escaped_string CLOB,"
1678             "the_datetime TIMESTAMP,"
1679             "the_datetime_tz TIMESTAMP,"
1680             "the_date DATE,"
1681             "the_time TIME,"
1682             "the_time_tz TIME,"
1683             "id INT NOT NULL GENERATED ALWAYS AS IDENTITY"
1684             " (START WITH 1, INCREMENT BY 1, NO CACHE))");
1685 
1686       snprintf(ptr_cinfo->query, QUERY_LEN, "INSERT INTO test_datatypes ("
1687             "the_char,"
1688             "the_uchar,"
1689             "the_short,"
1690             "the_ushort,"
1691             "the_long,"
1692             "the_ulong,"
1693             "the_longlong,"
1694             "the_ulonglong,"
1695             "the_float,"
1696             "the_double,"
1697             "the_conn_quoted_string,"
1698             "the_conn_quoted_string_copy,"
1699             "the_conn_escaped_string,"
1700             "the_conn_escaped_string_copy,"
1701             "the_numstring,"
1702             "the_empty_string,"
1703             "the_null_string,"
1704             "the_binary_quoted_string,"
1705             "the_binary_escaped_string,"
1706             "the_datetime,"
1707             "the_datetime_tz,"
1708             "the_date,"
1709             "the_time,"
1710             "the_time_tz) VALUES ("
1711             "-127,"
1712             "127,"
1713             "-32768,"
1714             "32767,"
1715             "-2147483648,"
1716             "2147483647,"
1717             "-9223372036854775807,"
1718             "9223372036854775807,"
1719             "3.402823466E+38,"
1720             "1.7976931348623157E+307,"
1721             "'Can '\'we\'' \"quote\" this properly?',"
1722             "'Can '\'we\'' \"quote\" this properly?',"
1723             "'Can '\'we\'' \"escape\" this properly?',"
1724             "'Can '\'we\'' \"escape\" this properly?',"
1725             "'%s',"
1726             "'',"
1727             "NULL,"
1728             "'AB\\\\000C''''D',"
1729             "'AB\\\\000C''''D',"
1730             "'2001-12-31-23.59.59',"
1731             "'2001-12-31-23.59.59',"
1732             "'2001-12-31',"
1733             "'23:59:59',"
1734             "'23:59:59')",
1735             numstring);
1736    }
1737    else if (!strcmp(ptr_cinfo->drivername, "sqlite")
1738          || !strcmp(ptr_cinfo->drivername, "sqlite3")){
1739       snprintf(ptr_cinfo->createschema, QUERY_LEN, "CREATE TABLE test_datatypes ( "
1740             "the_char CHAR,"
1741             "the_uchar CHAR,"
1742             "the_short SMALLINT,"
1743             "the_ushort SMALLINT,"
1744             "the_long INT,"
1745             "the_ulong INT,"
1746             "the_longlong BIGINT,"
1747             "the_ulonglong BIGINT,"
1748             "the_float FLOAT4,"
1749             "the_double FLOAT8,"
1750             "the_driver_string VARCHAR(255),"
1751             "the_conn_quoted_string VARCHAR(255),"
1752             "the_conn_quoted_string_copy VARCHAR(255),"
1753             "the_conn_escaped_string VARCHAR(255),"
1754             "the_conn_escaped_string_copy VARCHAR(255),"
1755             "the_numstring VARCHAR(255),"
1756             "the_empty_string VARCHAR(255),"
1757             "the_null_string VARCHAR(255),"
1758             "the_binary_quoted_string BLOB,"
1759             "the_binary_escaped_string BLOB,"
1760             "the_datetime DATETIME,"
1761             "the_datetime_tz DATETIME,"
1762             "the_date DATE,"
1763             "the_time TIME,"
1764             "the_time_tz TIME,"
1765             "id INTEGER AUTO INCREMENT)");
1766 
1767       snprintf(ptr_cinfo->query, QUERY_LEN, "INSERT INTO test_datatypes ("
1768             "the_char,"
1769             "the_uchar,"
1770             "the_short,"
1771             "the_ushort,"
1772             "the_long,"
1773             "the_ulong,"
1774             "the_longlong,"
1775             "the_ulonglong,"
1776             "the_float,"
1777             "the_double,"
1778             "the_conn_quoted_string,"
1779             "the_conn_quoted_string_copy,"
1780             "the_conn_escaped_string,"
1781             "the_conn_escaped_string_copy,"
1782             "the_numstring,"
1783             "the_empty_string,"
1784             "the_null_string,"
1785             "the_binary_quoted_string,"
1786             "the_binary_escaped_string,"
1787             "the_datetime,"
1788             "the_datetime_tz,"
1789             "the_date,"
1790             "the_time,"
1791             "the_time_tz) VALUES ("
1792             "-127,"
1793             "127,"
1794             "-32768,"
1795             "32767,"
1796             "-2147483648,"
1797             "2147483647,"
1798             "-9223372036854775807,"
1799             "9223372036854775807,"
1800             "3.402823466E+38,"
1801             "1.7976931348623157E+307,"
1802             "'Can ''we'' \"quote\" this properly?',"
1803             "'Can ''we'' \"quote\" this properly?',"
1804             "'Can ''we'' \"escape\" this properly?',"
1805             "'Can ''we'' \"escape\" this properly?',"
1806             "'%s',"
1807             "'',"
1808             "NULL,"
1809             "'\x01\x40\x41\xff\x42\x26\x43',"
1810             "'\x01\x40\x41\xff\x42\x26\x43',"
1811             "'2001-12-31 23:59:59',"
1812             "'2001-12-31 23:59:59 -10:00',"
1813             "'2001-12-31',"
1814             "'23:59:59',"
1815             "'23:59:59-10:00')",
1816             numstring);
1817    }
1818    return 0;
1819 }
1820 
1821 /* returns 0 on success, 1 on error */
ask_for_conninfo(struct CONNINFO * ptr_cinfo)1822 int ask_for_conninfo(struct CONNINFO* ptr_cinfo) {
1823    int numdrivers;
1824    char resp[16];
1825 
1826    fprintf(stderr, "\nlibdbi-drivers test program: $Id: test_dbi.c,v 1.72 2013/02/24 15:06:57 mhoenicka Exp $\n\n");
1827 
1828    fprintf(stderr, "test instance-based (i) or legacy (l) libdbi interface? [i] ");
1829    fgets(resp, 16, stdin);
1830    if (*resp == '\n' || *resp == 'i') {
1831       n_legacy = 0;
1832       ptr_cinfo->n_legacy = 0;
1833    }
1834    else {
1835       n_legacy = 1;
1836       ptr_cinfo->n_legacy = 1;
1837    }
1838 
1839    fprintf(stderr, "log query (y|n)? [n] ");
1840    fgets(resp, 16, stdin);
1841    if (*resp == '\n' || *resp == 'n') {
1842       ptr_cinfo->query_log = 0;
1843    }
1844    else {
1845       ptr_cinfo->query_log = 1;
1846    }
1847 
1848    fprintf(stderr, "libdbi driver directory? [%s] ", DBI_DRIVER_DIR);
1849    fgets(ptr_cinfo->driverdir, 256, stdin);
1850    if ((ptr_cinfo->driverdir)[0] == '\n') {
1851       strncpy(ptr_cinfo->driverdir, DBI_DRIVER_DIR, 255), (ptr_cinfo->driverdir)[255] = '\0';
1852    }
1853    else {
1854       (ptr_cinfo->driverdir)[strlen(ptr_cinfo->driverdir)-1] = '\0';
1855    }
1856 
1857    numdrivers = my_dbi_initialize(ptr_cinfo->driverdir, &dbi_instance);
1858 
1859    if (numdrivers < 0) {
1860       fprintf(stderr, "Unable to initialize libdbi! Make sure you specified a valid driver directory.\n");
1861       my_dbi_shutdown(dbi_instance);
1862       return 1;
1863    }
1864    else if (numdrivers == 0) {
1865       fprintf(stderr, "Initialized libdbi, but no drivers were found!\n");
1866       my_dbi_shutdown(dbi_instance);
1867       return 1;
1868    }
1869 
1870    test_driver = NULL;
1871    fprintf(stderr, "%d drivers available: ", numdrivers);
1872    while ((test_driver = my_dbi_driver_list(test_driver, dbi_instance)) != NULL) {
1873       fprintf(stderr, "%s ", dbi_driver_get_name(test_driver));
1874    }
1875    test_driver = NULL;
1876 
1877    (ptr_cinfo->drivername)[0] = '\n';
1878 
1879    while ((ptr_cinfo->drivername)[0] == '\n') {
1880       fprintf(stderr, "\ntest which driver? ");
1881       fgets(ptr_cinfo->drivername, 64, stdin);
1882    }
1883    (ptr_cinfo->drivername)[strlen(ptr_cinfo->drivername)-1] = '\0';
1884 
1885    if (!strcmp(ptr_cinfo->drivername, "mysql")
1886          || !strcmp(ptr_cinfo->drivername, "pgsql")
1887          || !strcmp(ptr_cinfo->drivername, "firebird")
1888          || !strcmp(ptr_cinfo->drivername, "freetds")
1889          || !strcmp(ptr_cinfo->drivername, "db2")) {
1890       fprintf(stderr, "\ndatabase administrator name? ");
1891       fgets(ptr_cinfo->username, 64, stdin);
1892       if (*(ptr_cinfo->username) == '\n') {
1893          *(ptr_cinfo->username) = '\0';
1894       }
1895       else {
1896          (ptr_cinfo->username)[strlen(ptr_cinfo->username)-1] = '\0';
1897       }
1898 
1899       fprintf(stderr, "\ndatabase administrator password? ");
1900       fgets(ptr_cinfo->password, 64, stdin);
1901       if (*(ptr_cinfo->password) == '\n') {
1902          *(ptr_cinfo->password) = '\0';
1903       }
1904       else {
1905          (ptr_cinfo->password)[strlen(ptr_cinfo->password)-1] = '\0';
1906       }
1907    }
1908 
1909    if(!strcmp(ptr_cinfo->drivername, "sqlite")
1910          || !strcmp(ptr_cinfo->drivername, "sqlite3")
1911          || !strcmp(ptr_cinfo->drivername, "firebird")) {
1912      if (!strcmp(ptr_cinfo->drivername, "firebird")) {
1913        /* we use the isql client to create and drop databases. This
1914 	  tool is whacky in that it accepts only darn short arguments,
1915 	  including the path of the database. Therefore do not suggest
1916 	  the libdbi default, but /tmp */
1917        fprintf(stderr, "database directory? [/tmp] ");
1918      }
1919      else {
1920        fprintf(stderr, "database directory? [DEFAULT] ");
1921      }
1922      fgets(ptr_cinfo->dbdir, 256, stdin);
1923      if ((ptr_cinfo->dbdir)[0] == '\n') {
1924        (ptr_cinfo->dbdir)[0] = '\0';
1925      }
1926      else {
1927        (ptr_cinfo->dbdir)[strlen(ptr_cinfo->dbdir)-1] = '\0';
1928      }
1929      if (!strcmp(ptr_cinfo->drivername, "firebird")
1930 	 && (ptr_cinfo->dbdir)[0] == '\0') {
1931        /* strcpy(ptr_cinfo->dbdir, default_dbdir); */
1932        /* strcat(ptr_cinfo->dbdir, "/firebird"); */
1933        strcpy(ptr_cinfo->dbdir, "/tmp");
1934      }
1935    }
1936    /*   else: other drivers do not use a database directory */
1937 
1938    if (!strcmp(ptr_cinfo->drivername, "firebird")
1939          || !strcmp(ptr_cinfo->drivername, "mysql")
1940          || !strcmp(ptr_cinfo->drivername, "pgsql")
1941          || !strcmp(ptr_cinfo->drivername, "freetds")
1942          || !strcmp(ptr_cinfo->drivername, "db2")) {
1943       fprintf(stderr, "\ndatabase hostname? [(blank for local socket if possible)] ");
1944       fgets(ptr_cinfo->hostname, 256, stdin);
1945       if (*(ptr_cinfo->hostname) == '\n') {
1946          if (!strcmp(ptr_cinfo->drivername, "pgsql")
1947                || !strcmp(ptr_cinfo->drivername, "firebird")
1948                || !strcmp(ptr_cinfo->drivername, "msql")) {
1949             *(ptr_cinfo->hostname) = '\0';
1950          }
1951          else {
1952             strcpy(ptr_cinfo->hostname, "localhost");
1953          }
1954       }
1955       else {
1956          (ptr_cinfo->hostname)[strlen(ptr_cinfo->hostname)-1] = '\0';
1957          if (!strcmp(ptr_cinfo->drivername, "pgsql")) {
1958             if (!strcmp(ptr_cinfo->hostname, "localhost")) {
1959                *(ptr_cinfo->hostname) = '\0';
1960             }
1961          }
1962       }
1963    }
1964 
1965    if (!strcmp(ptr_cinfo->drivername, "freetds")) {
1966       fprintf(stderr, "database version? ");
1967       fgets(ptr_cinfo->version, 64, stdin);
1968       (ptr_cinfo->version)[strlen(ptr_cinfo->version)-1] = '\0';
1969    }
1970 
1971    fprintf(stderr, "database name? [libdbitest] ");
1972    fgets(ptr_cinfo->dbname, 64, stdin);
1973    if ((ptr_cinfo->dbname)[0] == '\n') {
1974       strcpy(ptr_cinfo->dbname, "libdbitest");
1975    }
1976    else {
1977       (ptr_cinfo->dbname)[strlen(ptr_cinfo->dbname)-1] = '\0';
1978    }
1979 
1980    fprintf(stderr, "encoding? [] ");
1981    fgets(ptr_cinfo->encoding, 20, stdin);
1982    if ((ptr_cinfo->encoding)[0] == '\n') {
1983       *(ptr_cinfo->encoding) = '\0';
1984    }
1985    else {
1986       (ptr_cinfo->encoding)[strlen(ptr_cinfo->encoding)-1] = '\0';
1987    }
1988 
1989    if (!strcmp(ptr_cinfo->drivername, "mysql")) {
1990       strcpy(ptr_cinfo->initial_dbname, "mysql");
1991    }
1992    else if (!strcmp(ptr_cinfo->drivername, "pgsql")) {
1993       strcpy(ptr_cinfo->initial_dbname, "template1");
1994    }
1995    else if (!strcmp(ptr_cinfo->drivername, "sqlite")
1996          || !strcmp(ptr_cinfo->drivername, "sqlite3")) {
1997       strcpy(ptr_cinfo->initial_dbname, ptr_cinfo->dbname);
1998    }
1999    else if (!strcmp(ptr_cinfo->drivername, "ingres")
2000          || !strcmp(ptr_cinfo->drivername, "firebird")){
2001       strcpy(ptr_cinfo->initial_dbname, ptr_cinfo->dbname);
2002    }
2003    else if (!strcmp(ptr_cinfo->drivername, "freetds")) {
2004       strcpy(ptr_cinfo->initial_dbname, "master");
2005    }
2006    else if (!strcmp(ptr_cinfo->drivername, "db2")) {
2007       strcpy(ptr_cinfo->initial_dbname, "toolsdb");
2008    }
2009 
2010    my_dbi_shutdown(dbi_instance);
2011    dbi_instance = NULL;
2012    return 0;
2013 }
2014 
2015 /* always returns 0 */
set_driver_options(struct CONNINFO * ptr_cinfo,dbi_conn conn,const char * encoding)2016 int set_driver_options(struct CONNINFO* ptr_cinfo, dbi_conn conn, const char* encoding) {
2017    char *versionstring[100];
2018 
2019    if (!strcmp(ptr_cinfo->drivername, "mysql")
2020          || !strcmp(ptr_cinfo->drivername, "pgsql")
2021          || !strcmp(ptr_cinfo->drivername, "freetds")
2022          || !strcmp(ptr_cinfo->drivername, "db2")
2023    ) {
2024       dbi_conn_set_option(conn, "host", ptr_cinfo->hostname);
2025       dbi_conn_set_option(conn, "username", ptr_cinfo->username);
2026       dbi_conn_set_option(conn, "password", ptr_cinfo->password);
2027 
2028       if (!strcmp(ptr_cinfo->drivername, "freetds") && strlen(ptr_cinfo->version)){
2029          dbi_conn_set_option(conn, "freetds_version", ptr_cinfo->version);
2030       }
2031    }
2032    else if (!strcmp(ptr_cinfo->drivername, "msql")) {
2033       if( *(ptr_cinfo->hostname)) {
2034          dbi_conn_set_option(conn, "host", ptr_cinfo->hostname);
2035       }
2036    }
2037    else if (!strcmp(ptr_cinfo->drivername, "sqlite3")) {
2038       if (*(ptr_cinfo->dbdir)) {
2039          dbi_conn_set_option(conn, "sqlite3_dbdir", ptr_cinfo->dbdir);
2040       }
2041    }
2042    else  if (!strcmp(ptr_cinfo->drivername, "sqlite")){
2043       if (*(ptr_cinfo->dbdir)) {
2044          dbi_conn_set_option(conn, "sqlite_dbdir", ptr_cinfo->dbdir);
2045       }
2046    }
2047    else  if (!strcmp(ptr_cinfo->drivername, "firebird")){
2048       if (*(ptr_cinfo->dbdir)) {
2049          dbi_conn_set_option(conn, "firebird_dbdir", ptr_cinfo->dbdir);
2050       }
2051       dbi_conn_set_option(conn, "host", ptr_cinfo->hostname);
2052       dbi_conn_set_option(conn, "username", ptr_cinfo->username);
2053       dbi_conn_set_option(conn, "password", ptr_cinfo->password);
2054    }
2055 
2056    if (!strcmp(ptr_cinfo->drivername, "mysql")) {
2057       strcpy(ptr_cinfo->initial_dbname, "mysql");
2058 
2059       if (encoding && *encoding) {
2060          dbi_conn_set_option(conn, "encoding", encoding);
2061       }
2062    }
2063    else if (!strcmp(ptr_cinfo->drivername, "pgsql")) {
2064       strcpy(ptr_cinfo->initial_dbname, "template1");
2065       if (encoding && *encoding) {
2066          dbi_conn_set_option(conn, "encoding", encoding);
2067       }
2068    }
2069    else if (!strcmp(ptr_cinfo->drivername, "sqlite")
2070          || !strcmp(ptr_cinfo->drivername, "sqlite3")) {
2071       strcpy(ptr_cinfo->initial_dbname, ptr_cinfo->dbname);
2072       if (encoding && *encoding) {
2073          dbi_conn_set_option(conn, "encoding", encoding);
2074       }
2075    }
2076    else if (!strcmp(ptr_cinfo->drivername, "ingres")
2077          || !strcmp(ptr_cinfo->drivername, "firebird")){
2078       strcpy(ptr_cinfo->initial_dbname, ptr_cinfo->dbname);
2079    }
2080    else if (!strcmp(ptr_cinfo->drivername, "freetds")) {
2081       strcpy(ptr_cinfo->initial_dbname, "master");
2082       if (encoding && *encoding) {
2083          dbi_conn_set_option(conn, "encoding", encoding);
2084       }
2085    }
2086    else if (!strcmp(ptr_cinfo->drivername, "db2")) {
2087       strcpy(ptr_cinfo->initial_dbname, "toolsdb");
2088       if (encoding && *encoding) {
2089          dbi_conn_set_option(conn, "encoding", encoding);
2090       }
2091    }
2092    dbi_conn_set_option(conn, "dbname",  ptr_cinfo->dbname);
2093 
2094    dbi_conn_set_option_numeric(conn, "LogQueries", ptr_cinfo->query_log);
2095 
2096    return 0;
2097 }
2098 
2099 /* Open the driver, set options and connect */
open_database_driver()2100 static void open_database_driver() {
2101    const char *errmsg;
2102    int errnum;
2103 
2104    if (!dbi_instance)
2105       cinfo.numdrivers = my_dbi_initialize(cinfo.driverdir, &dbi_instance);
2106 
2107    if (cinfo.numdrivers < 0) {
2108       fprintf(stderr, "Unable to initialize libdbi! Make sure you specified a valid driver directory.\n");
2109       my_dbi_shutdown(dbi_instance);
2110       exit(1);
2111    }
2112    else if (cinfo.numdrivers == 0) {
2113       fprintf(stderr, "Initialized libdbi, but no drivers were found!\n");
2114       my_dbi_shutdown(dbi_instance);
2115       exit(1);
2116    }
2117 
2118    conn = my_dbi_conn_new(cinfo.drivername, dbi_instance);
2119 
2120    if (!conn) {
2121       errnum = dbi_conn_error(conn, &errmsg);
2122       fprintf(stderr,"Error %d dbi_conn_new_i: %s\n", errnum, errmsg);
2123       my_dbi_shutdown(dbi_instance);
2124       exit(1);
2125    }
2126 
2127    if (set_driver_options(&cinfo, conn, "")) {
2128       my_dbi_shutdown(dbi_instance);
2129       exit(1);
2130    }
2131 
2132 }
2133 
create_database()2134 static void create_database() {
2135 
2136    const char *errmsg;
2137    dbi_result result;
2138    char my_enc[32];
2139    char database_path[1024];
2140 
2141    char command[1024];
2142 
2143    if (!strcmp(cinfo.drivername, "firebird")) {
2144       snprintf(database_path, 1024, "%s/%s", cinfo.dbdir, cinfo.dbname);
2145 
2146       if (!*(cinfo.hostname)) {
2147          if (access(database_path, R_OK | W_OK | F_OK) == 0) {
2148             goto noop;
2149          }
2150 
2151          snprintf(command, 1024,
2152                "echo \"CREATE DATABASE \'localhost:%s/%s\';\""
2153                "| %s -e -pas %s "
2154                "-u %s -sql_dialect 3", cinfo.dbdir,
2155                cinfo.dbname,
2156                FIREBIRD_ISQL,
2157                cinfo.password, cinfo.username);
2158       }
2159       else { /* remote */
2160          snprintf(command, 1024,
2161                "echo \"CREATE DATABASE \'%s:%s/%s\';\""
2162                "| %s -e -pas %s "
2163                "-u %s -sql_dialect 3", cinfo.hostname, cinfo.dbdir,
2164                cinfo.dbname,
2165                FIREBIRD_ISQL,
2166                cinfo.password, cinfo.username);
2167       }
2168 
2169       if (system(command)) {
2170          fprintf(stderr, "Could not create initial database\n");
2171          goto error;
2172       }
2173       /*     snprintf(command, 1024, "sudo chmod 666 %s/%s", ptr_cinfo->dbdir, ptr_cinfo->dbname); */
2174       /*     if (system(command)) { */
2175       /*       fprintf(stderr, "Could not set database permissions\n"); */
2176       /*       return 1; */
2177       /*     } */
2178       goto noop;
2179    }
2180    else if (!strcmp(cinfo.drivername, "sqlite")
2181          || !strcmp(cinfo.drivername, "sqlite3")
2182          || !strcmp(cinfo.drivername, "msql")
2183          || !strcmp(cinfo.drivername, "ingres")
2184          || !strcmp(cinfo.drivername, "db2")
2185          || !strcmp(cinfo.drivername, "oracle")) {
2186       goto noop;
2187    }
2188    else {
2189       /* we need to connect to a libdbi instance */
2190       open_database_driver();
2191 
2192       /* change to initial database */
2193       dbi_conn_clear_option(conn, "dbname");
2194       dbi_conn_set_option(conn, "dbname",  cinfo.initial_dbname);
2195 
2196       if (dbi_conn_connect(conn) < 0) {
2197          printf("Could not connect to create the test database\n");
2198          my_dbi_shutdown(dbi_instance);
2199          exit(1);
2200       }
2201 
2202       /* now create a database */
2203       if (cinfo.encoding && *(cinfo.encoding)) {
2204 	if (!strcmp(cinfo.drivername, "mysql")) {
2205 	  result = dbi_conn_queryf(conn, "CREATE DATABASE %s CHARACTER SET %s", cinfo.dbname, (!strcmp(cinfo.encoding, "UTF-8")) ? "utf8":"latin1");
2206 	}
2207 	else if (!strcmp(cinfo.drivername, "pgsql")) {
2208 	  /* the first SQL command used to work until PostgreSQL
2209 	     8.3. Later versions need a matching locale setting along
2210 	     with the encoding. Most modern installations use UNICODE
2211 	     as default encoding, therefore creating such a database
2212 	     should be safe. However, creating a LATIN1 database needs
2213 	     extra care. Apparently PostgreSQL is not supposed to work
2214 	     with databases whose encodings differ from that of the
2215 	     cluster, as set with initdb */
2216 	  unsigned int pgserver_version;
2217 
2218 	  pgserver_version = dbi_conn_get_engine_version(conn);
2219 
2220 	  if (pgserver_version < 80400) {
2221 	    result = dbi_conn_queryf(conn, "CREATE DATABASE %s WITH ENCODING = '%s'", cinfo.dbname, (!strcmp(cinfo.encoding, "UTF-8")) ? "UNICODE":"LATIN1");
2222 	  }
2223 	  else {
2224 	    if (!strcmp(cinfo.encoding, "UTF-8")) {
2225 	      result = dbi_conn_queryf(conn, "CREATE DATABASE %s WITH ENCODING = '%s' LC_COLLATE='en_US.UTF8' LC_CTYPE='en_US.UTF8'", cinfo.dbname, "UTF8");
2226 	    }
2227 	    else {
2228 	      result = dbi_conn_queryf(conn, "CREATE DATABASE %s WITH ENCODING = '%s'  LC_COLLATE='de_DE.ISO8859-1' LC_CTYPE='de_DE.ISO8859-1' TEMPLATE template0", cinfo.dbname, "LATIN1");
2229 	    }
2230 	  }
2231 	}
2232       }
2233       else {
2234          if (!strcmp(cinfo.drivername, "mysql")) {
2235             result = dbi_conn_queryf(conn, "CREATE DATABASE %s", cinfo.dbname);
2236          }
2237          else if (!strcmp(cinfo.drivername, "pgsql")) {
2238             result = dbi_conn_queryf(conn, "CREATE DATABASE %s", cinfo.dbname);
2239          }
2240       }
2241 
2242       if (result == NULL) {
2243          dbi_conn_error(conn, &errmsg);
2244          fprintf(stderr, "\tDarn! Can't create database! Error message: %s\n", errmsg);
2245          goto error;
2246       }
2247       dbi_result_free(result);
2248    }
2249 
2250    if (conn) {
2251       dbi_conn_close(conn);
2252       conn = NULL;
2253    }
2254 
2255    noop:
2256    return;
2257 
2258    error:
2259    exit(1);
2260 
2261 }
2262 
drop_database()2263 static void drop_database() {
2264    const char *errmsg;
2265    dbi_result result;
2266 
2267    if (!strcmp(cinfo.drivername, "sqlite")
2268          || !strcmp(cinfo.drivername, "sqlite3")) {
2269       char dbpath[_POSIX_PATH_MAX];
2270 
2271       /* need this break to grant some time for db unlocking */
2272       sleep(3);
2273 
2274       if (*(cinfo.dbdir)) {
2275          strcpy(dbpath, cinfo.dbdir);
2276       }
2277       else {
2278          if (!strcmp(cinfo.drivername, "sqlite")) {
2279             snprintf(dbpath, _POSIX_PATH_MAX, "%s/sqlite", default_dbdir);
2280          }
2281          else {
2282             snprintf(dbpath, _POSIX_PATH_MAX, "%s/sqlite3", default_dbdir);
2283          }
2284       }
2285       if (dbpath[strlen(dbpath)-1] != '/') {
2286          strcat(dbpath, "/");
2287       }
2288       strcat(dbpath, cinfo.dbname);
2289 
2290       if (unlink(dbpath)) {
2291          fprintf(stderr, "AAH! Can't delete database file!\n");
2292          goto error;
2293       }
2294    }
2295    else if (!strcmp(cinfo.drivername, "msql")
2296          || !strcmp(cinfo.drivername, "ingres")) {
2297       fprintf(stderr, "\tThis is a no-op with the mSQL/Ingres driver.\n");
2298    }
2299    else if (!strcmp(cinfo.drivername, "firebird")) {
2300       /* firebird does not support DROP DATABASE in regular SQL
2301 	       but offers it as an isql extension. In order to get rid
2302 	       of the test database, connect to it and drop it by
2303 	       sending a string to isql */
2304       char command[1024];
2305 
2306       if (!*(cinfo.hostname)) {
2307          snprintf(command, 1024,
2308                "echo \"CONNECT \'%s/%s\';DROP DATABASE;\""
2309                "| %s -e -pas %s "
2310                "-u %s -sql_dialect 3", cinfo.dbdir,
2311                cinfo.dbname,
2312                FIREBIRD_ISQL,
2313                cinfo.password, cinfo.username);
2314       }
2315       else { /* remote */
2316          snprintf(command, 1024,
2317                "echo \"CONNECT \'%s:%s/%s\';DROP DATABASE;\""
2318                "| %s -e -pas %s "
2319                "-u %s -sql_dialect 3", cinfo.hostname, cinfo.dbdir,
2320                cinfo.dbname,
2321                FIREBIRD_ISQL,
2322                cinfo.password, cinfo.username);
2323       }
2324       if (system(command)) {
2325          fprintf(stderr,"\tAAH! Can't drop database %s<< connected to database %s! Error message: %s\n", cinfo.dbname, cinfo.dbname, errmsg);
2326          goto error;
2327       }
2328    }
2329 
2330    else {
2331 
2332       open_database_driver();
2333 
2334       /* change to initial database */
2335       dbi_conn_clear_option(conn, "dbname");
2336       dbi_conn_set_option(conn, "dbname",  cinfo.initial_dbname);
2337 
2338       if (dbi_conn_connect(conn) < 0) {
2339          fprintf(stderr,"Could not connect to drop the test database\n");
2340          my_dbi_shutdown(dbi_instance);
2341          goto error;
2342       }
2343 
2344       if ((result = dbi_conn_queryf(conn, "DROP DATABASE %s",
2345             cinfo.dbname)) == NULL) {
2346          dbi_conn_error(conn, &errmsg);
2347          fprintf(stderr,"\tAAH! Can't drop database %s<< connected to database %s! Error message: %s\n", cinfo.dbname, cinfo.initial_dbname, errmsg);
2348          goto error;
2349       }
2350 
2351       dbi_result_free(result);
2352    }
2353 
2354    /* don't forget to disconnect */
2355    dbi_conn_close(conn);
2356    conn = NULL;
2357 
2358    /* important: this functions is the last to be called
2359     * we need to shutdown libdbi
2360     */
2361    my_dbi_shutdown(dbi_instance);
2362 
2363    error:
2364    return;
2365 
2366 }
2367 
open_test_database()2368 static void open_test_database() {
2369    const char *errmsg;
2370    int errnum;
2371 
2372    open_database_driver();
2373 
2374    /* now we can change to test database and connect */
2375    dbi_conn_clear_option(conn, "dbname");
2376    dbi_conn_set_option(conn, "dbname",  cinfo.dbname);
2377 
2378    if (dbi_conn_connect(conn) < 0) {
2379       printf("Could not connect to test database\n");
2380       my_dbi_shutdown(dbi_instance);
2381       exit(1);
2382    }
2383 
2384 }
2385 
close_database_driver()2386 static void close_database_driver() {
2387   if (conn) {
2388     dbi_conn_close(conn);
2389     conn = NULL;
2390   }
2391   my_dbi_shutdown(dbi_instance);
2392   dbi_instance = NULL;
2393   test_driver = NULL;
2394 }
2395 
close_test_database()2396 static void close_test_database() {
2397    dbi_conn_close(conn);
2398    conn = NULL;
2399 }
2400 
2401 /* convenience wrappers for recallable vs. legacy libdbi interface */
my_dbi_initialize(const char * driverdir,dbi_inst * Inst)2402 int my_dbi_initialize(const char *driverdir, dbi_inst *Inst) {
2403    if (n_legacy) {
2404       return dbi_initialize(driverdir);
2405    }
2406    else {
2407       return dbi_initialize_r(driverdir, Inst);
2408    }
2409 }
2410 
my_dbi_shutdown(dbi_inst Inst)2411 void my_dbi_shutdown(dbi_inst Inst) {
2412    if (n_legacy) {
2413       dbi_shutdown();
2414    }
2415    else {
2416       dbi_shutdown_r(Inst);
2417    }
2418 }
2419 
my_dbi_driver_list(dbi_driver Current,dbi_inst Inst)2420 dbi_driver my_dbi_driver_list(dbi_driver Current, dbi_inst Inst) {
2421    if (n_legacy) {
2422       return dbi_driver_list(Current);
2423    }
2424    else {
2425       return dbi_driver_list_r(Current, Inst);
2426    }
2427 }
2428 
my_dbi_conn_new(const char * name,dbi_inst Inst)2429 dbi_conn my_dbi_conn_new(const char *name, dbi_inst Inst) {
2430    if (n_legacy) {
2431       return dbi_conn_new(name);
2432    }
2433    else {
2434       return dbi_conn_new_r(name, Inst);
2435    }
2436 }
2437 
usage()2438 static void usage() {
2439    fprintf(stderr,
2440          "\nlibdbi-drivers test program: $Id: test_dbi.c,v 1.72 2013/02/24 15:06:57 mhoenicka Exp $\n\n"
2441          "Usage: test_dbi [options]\n"
2442          "       -B                Name of the build. Single submission to the dashboard\n"
2443          "       -C                Generate a XML test report to submit.\n"
2444          "                         for a specific project, environment and build type.\n"
2445          "       -H                Specify hosname in dashboard . Ex.: dbi0 \n"
2446          "       -h, -?            print this message\n\n"
2447          "       -N                Specify OS Name in dashboard. Ex.: Linux\n"
2448          "       -P                Specify OS Platform name in dashboard. Ex.: x86_64, i368\n"
2449          "       -R                Specify OS Release in dashboard Ex.: 2.6.28-15-server\n"
2450          "       -s                run a single test\n"
2451          "       -S                Name of the site submitting the build. Computer\n"
2452          "                         contributing builds to the dashboard. A site might\n"
2453          "                         belong to several projects and submit different build.\n"
2454          "       -T                Can be Nightly or Experimental or Continuous.\n"
2455 	   "       -V                Specify OS Version. Ex.: Ubuntu SMP\n");
2456    exit(1);
2457 }
2458 
2459 /* returns 0 on success, 1 on error */
test_custom_function(struct CONNINFO * ptr_cinfo,dbi_conn conn)2460 int test_custom_function(struct CONNINFO* ptr_cinfo, dbi_conn conn) {
2461    dbi_conn_t *myconn = conn;
2462 
2463    /* attempt to call a trivial function of the client library */
2464    if (!strcmp(ptr_cinfo->drivername, "firebird")) {
2465       fprintf(stderr, "\tnot yet implemented for this driver\n");
2466       return 0;
2467    }
2468    else if (!strcmp(ptr_cinfo->drivername, "freetds")) {
2469       fprintf(stderr, "\tnot yet implemented for this driver\n");
2470       return 0;
2471    }
2472    else if (!strcmp(ptr_cinfo->drivername, "ingres")) {
2473       fprintf(stderr, "\tnot yet implemented for this driver\n");
2474       return 0;
2475    }
2476    else if (!strcmp(ptr_cinfo->drivername, "msql")) {
2477       fprintf(stderr, "\tnot yet implemented for this driver\n");
2478       return 0;
2479    }
2480    else if (!strcmp(ptr_cinfo->drivername, "mysql")) {
2481       int protocol;
2482       unsigned int (*custom_function)(void*);
2483 
2484       if ((custom_function = dbi_driver_specific_function(dbi_conn_get_driver(conn), "mysql_get_proto_info")) != NULL) {
2485          protocol = custom_function(myconn->connection);
2486          printf("\tmysql_get_proto_info returned: %d\n", protocol);
2487          return 0;
2488       }
2489       else {
2490          printf("\tD'uh! Cannot run custom function\n");
2491          return 1;
2492       }
2493    }
2494    else if (!strcmp(ptr_cinfo->drivername, "oracle")) {
2495       fprintf(stderr, "not yet implemented\n");
2496       return 0;
2497    }
2498    else if (!strcmp(ptr_cinfo->drivername, "pgsql")) {
2499       int protocol;
2500       int (*custom_function)(void*);
2501 
2502       if ((custom_function = dbi_driver_specific_function(dbi_conn_get_driver(conn), "PQprotocolVersion")) != NULL) {
2503          protocol = custom_function(myconn->connection);
2504          printf("\tPQprotocolVersion returned: %d\n", protocol);
2505          return 0;
2506       }
2507       else {
2508          printf("\tD'uh! Cannot run custom function\n");
2509          return 1;
2510       }
2511    }
2512    else if (!strcmp(ptr_cinfo->drivername, "sqlite")) {
2513       const char* version;
2514       const char* (*custom_function)(void);
2515 
2516       if ((custom_function = dbi_driver_specific_function(dbi_conn_get_driver(conn), "sqlite_version")) != NULL) {
2517          version = custom_function();
2518          printf("\tsqlite_version returned: %s\n", version);
2519          return 0;
2520       }
2521       else {
2522          printf("\tD'uh! Cannot run custom function\n");
2523          return 1;
2524       }
2525    }
2526    else if (!strcmp(ptr_cinfo->drivername, "sqlite3")) {
2527       const char* version;
2528       const char* (*custom_function)(void);
2529 
2530       if ((custom_function = dbi_driver_specific_function(dbi_conn_get_driver(conn), "sqlite3_libversion")) != NULL) {
2531          version = custom_function();
2532          printf("\tsqlite3_libversion returned: %s\n", version);
2533          return 0;
2534       }
2535       else {
2536          printf("\tD'uh! Cannot run custom function\n");
2537          return 1;
2538       }
2539    }
2540 }
2541 
2542 /* returns 0 on success, 1 on error */
test_custom_function_parameters(struct CONNINFO * ptr_cinfo,dbi_conn conn)2543 int test_custom_function_parameters(struct CONNINFO* ptr_cinfo, dbi_conn conn) {
2544    dbi_conn_t *myconn = conn;
2545 
2546    /* attempt to call a trivial function of the client library */
2547    if (!strcmp(ptr_cinfo->drivername, "firebird")) {
2548       fprintf(stderr, "\tnot yet implemented for this driver\n");
2549       return 0;
2550    }
2551    else if (!strcmp(ptr_cinfo->drivername, "freetds")) {
2552       fprintf(stderr, "\tnot yet implemented for this driver\n");
2553       return 0;
2554    }
2555    else if (!strcmp(ptr_cinfo->drivername, "ingres")) {
2556       fprintf(stderr, "\tnot yet implemented for this driver\n");
2557       return 0;
2558    }
2559    else if (!strcmp(ptr_cinfo->drivername, "msql")) {
2560       fprintf(stderr, "\tnot yet implemented for this driver\n");
2561       return 0;
2562    }
2563    else if (!strcmp(ptr_cinfo->drivername, "mysql")) {
2564       fprintf(stderr, "\tnot yet implemented for this driver\n");
2565       return 0;
2566    }
2567    else if (!strcmp(ptr_cinfo->drivername, "oracle")) {
2568       fprintf(stderr, "not yet implemented\n");
2569       return 0;
2570    }
2571    else if (!strcmp(ptr_cinfo->drivername, "pgsql")) {
2572       int res;
2573       int count = 30;
2574       const char *error = NULL;
2575       const char *errmsg = NULL;
2576       int (*custom_function_copy)(void*, const char*, int) = NULL;
2577       int (*custom_function_end)(void*, const char*) = NULL;
2578       char* (*custom_function_error)(void*) = NULL;
2579       dbi_result result;
2580 
2581       const char *query = "COPY batch FROM STDIN";
2582       const char *query_data1 = "1\t2\t\"A little job\"\n";
2583       const char *query_data2 = "2\t3\t\"Other little job\"\n";
2584       const char *table_batch = "CREATE TABLE batch ( id int, jobid int, jobname varchar)";
2585 
2586       // Start copy
2587 
2588       if ((result = dbi_conn_query(conn, table_batch)) == NULL) {
2589          dbi_conn_error(conn, &errmsg);
2590          printf("\tAAH! Can't create table! Error message: %s\n", errmsg);
2591          return 1;
2592       } else {
2593          printf("\tOk.\n");
2594       }
2595       dbi_result_free(result);
2596 
2597       if ((result = dbi_conn_query(conn, query)) == NULL) {
2598          dbi_conn_error(conn, &errmsg);
2599          printf("\tAAH! Can't query! Error message: %s\n", errmsg);
2600          return 1;
2601       } else {
2602          printf("\tOk %s.\n", query);
2603       }
2604       dbi_result_free(result);
2605 
2606       // Start copy insert
2607       // Insert data two times
2608       if ((custom_function_copy = dbi_driver_specific_function(dbi_conn_get_driver(conn), "PQputCopyData")) != NULL) {
2609 
2610          printf("\tPQputCopyData %s\n", query_data1);
2611          res = custom_function_copy(myconn->connection, query_data1, strlen(query_data1));
2612          printf("\tPQputCopyData returned: %d\n", res);
2613 
2614          if (res <= 0) {
2615             printf("\tD'uh! PQputCopyData error\n");
2616             return 1;
2617          }
2618 
2619          printf("\tPQputCopyData %s\n", query_data2);
2620          res = custom_function_copy(myconn->connection, query_data2, strlen(query_data2));
2621          printf("\tPQputCopyData returned: %d\n", res);
2622 
2623          if (res <= 0) {
2624             printf("\tD'uh! PQputCopyData error\n");
2625             return 1;
2626          }
2627       }
2628 
2629       // End data
2630       if ((custom_function_end = dbi_driver_specific_function(dbi_conn_get_driver(conn), "PQputCopyEnd")) != NULL) {
2631          do {
2632             res = custom_function_end(myconn->connection, error);
2633          } while (res == 0 && --count > 0);
2634       }
2635 
2636       if (res <= 0) {
2637          printf("\tD'uh! PQputCopyEnd error\n");
2638          return 1;
2639       }
2640       printf("\tPQputCopyEnd returned: %d\n\tError: %d %s\n", res, dbi_conn_error(conn, &errmsg), errmsg);
2641       if ((custom_function_error = dbi_driver_specific_function(dbi_conn_get_driver(conn), "PQerrorMessage")) != NULL) {
2642          printf("\tPQerrorMessage returned %s\n", custom_function_error(myconn->connection));
2643       }
2644 
2645       if ((result = dbi_conn_query(conn, "SELECT * from batch")) == NULL) {
2646          dbi_conn_error(conn, &errmsg);
2647          printf("\tAAH! Can't get read data! Error message: %s\n", errmsg);
2648          return 1;
2649       }
2650 
2651       printf("\tGot result, %d rows, try to access rows\n", dbi_result_get_numrows(result));
2652 
2653       while (dbi_result_next_row(result)) {
2654          const char *errmsg = NULL;
2655          long the_long_one = 0;
2656          long the_long_two = 0;
2657          const char* the_string;
2658 
2659          dbi_error_flag errflag;
2660 
2661          /* first retrieve the values */
2662          the_long_one = dbi_result_get_int(result, "id");
2663          errflag = dbi_conn_error(dbi_result_get_conn(result), &errmsg);
2664          if (errflag) {
2665             printf("the_int_one errflag=%s\n", errmsg);
2666          }
2667 
2668          the_long_two = dbi_result_get_int(result, "jobid");
2669          errflag = dbi_conn_error(dbi_result_get_conn(result), &errmsg);
2670          if (errflag) {
2671             printf("the_int_two errflag=%s\n", errmsg);
2672          }
2673 
2674          the_string = dbi_result_get_string(result, "jobname");
2675          errflag = dbi_conn_error(dbi_result_get_conn(result), &errmsg);
2676          if (errflag) {
2677             printf("the_stringr errflag=%s\n", errmsg);
2678          }
2679 
2680          printf("\tResult: the_long_one: %d the_long_two: %d the_string: %s\n",
2681                the_long_one,
2682                the_long_two,
2683                the_string);
2684       }
2685 
2686       return 0;
2687    }
2688    else if (!strcmp(ptr_cinfo->drivername, "sqlite")) {
2689       fprintf(stderr, "\tnot yet implemented for this driver\n");
2690       return 0;
2691    }
2692    else if (!strcmp(ptr_cinfo->drivername, "sqlite3")) {
2693       fprintf(stderr, "\tnot yet implemented for this driver\n");
2694       return 0;
2695    }
2696    else {
2697       printf("\tD'uh! Cannot run custom function\n");
2698       return 1;
2699    }
2700 }
2701 
2702 /*********** tests cases begin ***********/
2703 
2704 /****** driver-specific tests ******/
2705 
test_another_encoding()2706 Ensure test_another_encoding() {
2707 
2708    dbi_conn another_conn = NULL;
2709    dbi_result result;
2710    const char *errmsg;
2711    int status;
2712    const char *encode = NULL;
2713 
2714 #define DROP_DB_ENCODE \
2715 		do { \
2716 			dbi_conn_select_db(another_conn, cinfo.initial_dbname); \
2717 			result = dbi_conn_queryf(another_conn, "DROP DATABASE %s", "dbencode"); \
2718 			if (result == NULL) { \
2719 				dbi_conn_error(another_conn, &errmsg); \
2720 				printf("\tAAH! Can't drop database connected to database Error message: %s\n", errmsg); \
2721 				exit(1); \
2722 			} \
2723 			dbi_result_free(result); \
2724 		} while(0);
2725 
2726    /* test begin */
2727    another_conn = my_dbi_conn_new(cinfo.drivername, dbi_instance);
2728    assert_not_equal(another_conn, NULL);
2729 
2730    set_driver_options(&cinfo, another_conn, "UTF-8");
2731 
2732    status = dbi_conn_connect(another_conn);
2733    assert_equal(status, 0);
2734 
2735    if (!strcmp(cinfo.drivername, "mysql")) {
2736       result = dbi_conn_queryf(another_conn, "CREATE DATABASE %s CHARACTER SET %s",
2737             "dbencode", "utf8");
2738    }
2739    else if (!strcmp(cinfo.drivername, "pgsql")) {
2740       result = dbi_conn_queryf(another_conn,  "CREATE DATABASE %s WITH ENCODING = '%s'",
2741             "dbencode", "UTF-8");
2742    }
2743    else {
2744       exit(1);
2745    }
2746 
2747    if (result == NULL)	{
2748       dbi_conn_error(another_conn, &errmsg);
2749       printf("\tAAH! Can't create database connected to database Error message: %s\n", errmsg);
2750       exit(1);
2751    }
2752 
2753    dbi_conn_select_db(another_conn, "dbencode");
2754 
2755    /* Test: get encoding of UTF-8 database */
2756    encode = dbi_conn_get_encoding(another_conn);
2757 
2758    assert_string_equal(encode, "UTF-8");
2759 
2760    /* drop database */
2761    DROP_DB_ENCODE
2762 
2763    /* we're done with this connection */
2764    dbi_conn_close(another_conn);
2765 
2766    another_conn = NULL;
2767 
2768    /* repeat test for latin1 encoding */
2769    another_conn = my_dbi_conn_new(cinfo.drivername, dbi_instance);
2770    assert_not_equal(another_conn, NULL);
2771 
2772    set_driver_options(&cinfo, another_conn, "ISO-8859-1");
2773 
2774    status = dbi_conn_connect(another_conn);
2775    assert_equal(status, 0);
2776 
2777    if (!strcmp(cinfo.drivername, "mysql")) {
2778       result = dbi_conn_queryf(another_conn, "CREATE DATABASE %s CHARACTER SET %s",
2779             "dbencode", "latin1");
2780    }
2781    else if (!strcmp(cinfo.drivername, "pgsql")) {
2782      unsigned int pgserver_version;
2783 
2784      pgserver_version = dbi_conn_get_engine_version(another_conn);
2785 
2786      if (pgserver_version < 80400) {
2787        result = dbi_conn_queryf(another_conn,  "CREATE DATABASE %s WITH ENCODING = '%s'",
2788 				"dbencode", "LATIN1");
2789      }
2790      else {
2791        result = dbi_conn_queryf(another_conn,  "CREATE DATABASE %s WITH ENCODING = '%s'  LC_COLLATE='de_DE.ISO8859-1' LC_CTYPE='de_DE.ISO8859-1' TEMPLATE template0",
2792 				"dbencode", "LATIN1");
2793      }
2794    }
2795    else {
2796       exit(1);
2797    }
2798 
2799    if (result == NULL)	{
2800       dbi_conn_error(another_conn, &errmsg);
2801       printf("\tAAH! Can't create database connected to database Error message: %s\n", errmsg);
2802       exit(1);
2803    }
2804 
2805    dbi_result_free(result);
2806 
2807    dbi_conn_select_db(another_conn, "dbencode");
2808 
2809    /* Test: get encoding of ISO-8859-1 database */
2810    encode = dbi_conn_get_encoding(another_conn);
2811 
2812    assert_string_equal(encode, "ISO-8859-1");
2813 
2814    /* we're done with this connection */
2815    dbi_conn_close(another_conn);
2816 
2817    another_conn = NULL;
2818 
2819    /* now make a connection to the existing database using a different encoding */
2820    another_conn = my_dbi_conn_new(cinfo.drivername, dbi_instance);
2821    assert_not_equal(another_conn, NULL);
2822 
2823    set_driver_options(&cinfo, another_conn, "UTF-8");
2824 
2825    status = dbi_conn_connect(another_conn);
2826    assert_equal(status, 0);
2827 
2828    dbi_conn_select_db(another_conn, "dbencode");
2829 
2830    /* Test: get encoding of UTF-8 database */
2831    encode = dbi_conn_get_encoding(another_conn);
2832 
2833    assert_string_equal(encode, "UTF-8");
2834 
2835    dbi_conn_close(another_conn);
2836 
2837    another_conn = NULL;
2838 
2839    /* now make a connection to the existing database using the "auto" encoding */
2840    another_conn = my_dbi_conn_new(cinfo.drivername, dbi_instance);
2841    assert_not_equal(another_conn, NULL);
2842 
2843    set_driver_options(&cinfo, another_conn, "auto");
2844 
2845    status = dbi_conn_connect(another_conn);
2846    assert_equal(status, 0);
2847 
2848    dbi_conn_select_db(another_conn, "dbencode");
2849 
2850    /* Test: get encoding of ISO-8859-1 database */
2851    encode = dbi_conn_get_encoding(another_conn);
2852 
2853    assert_string_equal(encode, "ISO-8859-1");
2854 
2855    /* Test: drop ISO-8859-1 database */
2856    DROP_DB_ENCODE
2857 
2858    dbi_conn_close(another_conn);
2859 
2860    another_conn = NULL;
2861 
2862 }
2863 
test_dbi_conn_query()2864 Ensure test_dbi_conn_query() {
2865    const char *errmsg;
2866    int errnum;
2867    dbi_result result;
2868 
2869    if (!strcmp(cinfo.drivername, "firebird")) {
2870       QUERY_ASSERT_RESULT(result, "SELECT the_short FROM test_datatypes"
2871             " WHERE the_short = -32768");
2872 
2873    } else {
2874       QUERY_ASSERT_RESULT(result, "SELECT the_char, the_longlong FROM test_datatypes"
2875             " WHERE the_longlong = -9223372036854775807 and the_char = -127");
2876    }
2877 
2878    while (dbi_result_next_row(result)) {
2879       errmsg = NULL;
2880       long long the_longlong = 0;
2881       signed short the_short = 0;
2882 
2883       if(!strcmp(cinfo.drivername, "firebird")) {
2884          the_short = dbi_result_get_short(result, "the_short");
2885          assert_equal(the_short, expect_longlong_from_name("the_short", cinfo.drivername));
2886       }
2887       else {
2888          the_longlong = dbi_result_get_longlong(result, "the_longlong");
2889          assert_equal(the_longlong, expect_longlong_from_name("the_longlong", cinfo.drivername));
2890       }
2891    }
2892 
2893    dbi_result_free(result);
2894 }
2895 
test_dbi_conn_queryf()2896 Ensure test_dbi_conn_queryf() {
2897 
2898    const char table_test_datatypes[] = "test_datatypes";
2899    long long the_longlong_number = -9223372036854775807;
2900    signed char the_char_number = -127;
2901    signed short the_short_number = -32768;
2902 
2903 
2904    dbi_result result;
2905 
2906    if (!strcmp(cinfo.drivername, "firebird")) {
2907       result = dbi_conn_queryf(conn, "SELECT the_short FROM %s"
2908             " WHERE the_short = '%d'", table_test_datatypes, the_short_number);
2909    } else {
2910       result = dbi_conn_queryf(conn, "SELECT the_char, the_longlong FROM %s"
2911             " WHERE the_longlong = '%lld' and the_char = '%d'", table_test_datatypes,
2912             the_longlong_number, the_char_number);
2913    }
2914 
2915    ASSERT_RESULT
2916 
2917    while (dbi_result_next_row(result)) {
2918       errmsg = NULL;
2919       long long the_longlong = 0;
2920       signed char the_char = 0;
2921       signed short the_short = 0;
2922 
2923       if(!strcmp(cinfo.drivername, "msql")) {
2924          the_longlong = dbi_result_get_longlong(result, "the_longlong");
2925          assert_equal(the_longlong, -9223372036854775807);
2926       }
2927       else if (!strcmp(cinfo.drivername, "firebird")) {
2928          the_short = dbi_result_get_short(result, "the_short");
2929          assert_equal(the_short, -32768);
2930       }
2931       else {
2932          the_longlong = dbi_result_get_longlong(result, "the_longlong");
2933          assert_equal(the_longlong, -9223372036854775807);
2934       }
2935    }
2936 
2937    dbi_result_free(result);
2938 }
2939 
2940 // TODO: test_dbi_conn_query_null()
test_dbi_conn_query_null()2941 Ensure test_dbi_conn_query_null() {
2942 
2943 }
2944 
2945 // TODO: test_dbi_conn_ping()
test_dbi_conn_ping()2946 Ensure test_dbi_conn_ping() {
2947 
2948 }
2949 
test_dbi_conn_sequence_last()2950 Ensure test_dbi_conn_sequence_last() {
2951 
2952    unsigned long long n_last_id = 0;
2953 
2954    if (!strcmp(cinfo.drivername, "pgsql")
2955          || !strcmp(cinfo.drivername, "ingres")) {
2956       n_last_id = dbi_conn_sequence_last(conn, "test_datatypes_id_seq");
2957    } else if (!strcmp(cinfo.drivername, "firebird")) {
2958       n_last_id = dbi_conn_sequence_last(conn, "GEN_T1_ID");
2959    }
2960    else {
2961       n_last_id = dbi_conn_sequence_last(conn, NULL);
2962    }
2963 
2964    assert_equal(n_last_id, 1);
2965 
2966 }
2967 
test_dbi_conn_sequence_next()2968 Ensure test_dbi_conn_sequence_next() {
2969 
2970    unsigned long long n_next_id = 0;
2971 
2972    if (!strcmp(cinfo.drivername, "pgsql") ||
2973          !strcmp(cinfo.drivername, "ingres")) {
2974       n_next_id = dbi_conn_sequence_next(conn, "test_datatypes_id_seq");
2975       assert_equal(n_next_id, 2);
2976    }
2977    else if (!strcmp(cinfo.drivername, "firebird")) {
2978       n_next_id = dbi_conn_sequence_next(conn, "GEN_T1_ID");
2979       assert_equal(n_next_id, 2);
2980    }
2981    else if (!strcmp(cinfo.drivername, "mysql")) {
2982       n_next_id = dbi_conn_sequence_next(conn, NULL);
2983       assert_equal(n_next_id, 0);
2984    }
2985    else {
2986       n_next_id = dbi_conn_sequence_next(conn, NULL);
2987       assert_equal(n_next_id, 0);
2988    }
2989 
2990 }
2991 
test_dbi_conn_quote_binary_copy()2992 Ensure test_dbi_conn_quote_binary_copy() {
2993    dbi_result result;
2994    unsigned char* quoted_binary = NULL;
2995    size_t quoted_binary_length;
2996 
2997    quoted_binary_length = dbi_conn_quote_binary_copy(conn, binary_to_quote, binary_to_quote_length, &quoted_binary);
2998 
2999    if(!strcmp(cinfo.drivername, "mysql")) {
3000       assert_equal(39, quoted_binary[0]);
3001       assert_equal(65, quoted_binary[1]);
3002       assert_equal(66, quoted_binary[2]);
3003       assert_equal(92, quoted_binary[3]);
3004       assert_equal(48, quoted_binary[4]);
3005       assert_equal(67, quoted_binary[5]);
3006       assert_equal(92, quoted_binary[6]);
3007       assert_equal(39, quoted_binary[7]);
3008       assert_equal(68, quoted_binary[8]);
3009       assert_equal(39, quoted_binary[9]);
3010    } else if(!strcmp(cinfo.drivername, "pgsql")) {
3011      unsigned int pgserver_version;
3012 
3013      pgserver_version = dbi_conn_get_engine_version(conn);
3014 
3015      if (pgserver_version < 90000) {
3016        /* server uses old binary format by default */
3017        assert_equal(39, quoted_binary[0]);
3018        assert_equal(65, quoted_binary[1]);
3019        assert_equal(66, quoted_binary[2]);
3020        assert_equal(92, quoted_binary[3]);
3021        assert_equal(92, quoted_binary[4]);
3022        assert_equal(48, quoted_binary[5]);
3023        assert_equal(48, quoted_binary[6]);
3024        assert_equal(48, quoted_binary[7]);
3025        assert_equal(67, quoted_binary[8]);
3026        assert_equal(39, quoted_binary[9]);
3027        assert_equal(39, quoted_binary[10]);
3028        assert_equal(68, quoted_binary[11]);
3029        assert_equal(39, quoted_binary[12]);     }
3030      else {
3031        /* server uses hex format by default */
3032        assert_equal(39, quoted_binary[0]);
3033        assert_equal(92, quoted_binary[1]);
3034        assert_equal(120, quoted_binary[2]);
3035        assert_equal(52, quoted_binary[3]);
3036        assert_equal(49, quoted_binary[4]);
3037        assert_equal(52, quoted_binary[5]);
3038        assert_equal(50, quoted_binary[6]);
3039        assert_equal(48, quoted_binary[7]);
3040        assert_equal(48, quoted_binary[8]);
3041        assert_equal(52, quoted_binary[9]);
3042        assert_equal(51, quoted_binary[10]);
3043        assert_equal(50, quoted_binary[11]);
3044        assert_equal(55, quoted_binary[12]);
3045        assert_equal(52, quoted_binary[13]);
3046        assert_equal(52, quoted_binary[14]);
3047        assert_equal(39, quoted_binary[15]);
3048      }
3049    } else if(!strcmp(cinfo.drivername, "sqlite") || !strcmp(cinfo.drivername, "sqlite3") ||
3050          !strcmp(cinfo.drivername, "firebird")) {
3051       assert_equal(39, quoted_binary[0]);
3052       assert_equal(1,  quoted_binary[1]);
3053       assert_equal(64, quoted_binary[2]);
3054       assert_equal(65, quoted_binary[3]);
3055       assert_equal(255, quoted_binary[4]);
3056       assert_equal(66, quoted_binary[5]);
3057       assert_equal(38, quoted_binary[6]);
3058       assert_equal(67, quoted_binary[7]);
3059       assert_equal(39, quoted_binary[8]);
3060    }
3061 }
3062 
test_dbi_conn_escape_binary_copy()3063 Ensure test_dbi_conn_escape_binary_copy() {
3064    dbi_result result;
3065    unsigned char* escaped_binary = NULL;
3066    size_t escaped_binary_length;
3067 
3068    escaped_binary_length = dbi_conn_escape_binary_copy(conn, binary_to_escape, binary_to_escape_length, &escaped_binary);
3069 
3070    if(!strcmp(cinfo.drivername, "mysql")) {
3071       assert_equal(65, escaped_binary[0]);
3072       assert_equal(66, escaped_binary[1]);
3073       assert_equal(92, escaped_binary[2]);
3074       assert_equal(48, escaped_binary[3]);
3075       assert_equal(67, escaped_binary[4]);
3076       assert_equal(92, escaped_binary[5]);
3077       assert_equal(39, escaped_binary[6]);
3078       assert_equal(68, escaped_binary[7]);
3079    } else if(!strcmp(cinfo.drivername, "pgsql")) {
3080      unsigned int pgserver_version;
3081 
3082      pgserver_version = dbi_conn_get_engine_version(conn);
3083 
3084      if (pgserver_version < 90000) {
3085        /* server uses old binary format by default */
3086        assert_equal(65, escaped_binary[0]);
3087        assert_equal(66, escaped_binary[1]);
3088        assert_equal(92, escaped_binary[2]);
3089        assert_equal(92, escaped_binary[3]);
3090        assert_equal(48, escaped_binary[4]);
3091        assert_equal(48, escaped_binary[5]);
3092        assert_equal(48, escaped_binary[6]);
3093        assert_equal(67, escaped_binary[7]);
3094        assert_equal(39, escaped_binary[8]);
3095        assert_equal(39, escaped_binary[9]);
3096        assert_equal(68, escaped_binary[10]);     }
3097      else {
3098        /* server uses hex format by default */
3099        assert_equal(92, escaped_binary[0]);
3100        assert_equal(120, escaped_binary[1]);
3101        assert_equal(52, escaped_binary[2]);
3102        assert_equal(49, escaped_binary[3]);
3103        assert_equal(52, escaped_binary[4]);
3104        assert_equal(50, escaped_binary[5]);
3105        assert_equal(48, escaped_binary[6]);
3106        assert_equal(48, escaped_binary[7]);
3107        assert_equal(52, escaped_binary[8]);
3108        assert_equal(51, escaped_binary[9]);
3109        assert_equal(50, escaped_binary[10]);
3110        assert_equal(55, escaped_binary[11]);
3111        assert_equal(52, escaped_binary[12]);
3112        assert_equal(52, escaped_binary[13]);
3113      }
3114    } else if(!strcmp(cinfo.drivername, "sqlite") || !strcmp(cinfo.drivername, "sqlite3") ||
3115          !strcmp(cinfo.drivername, "firebird")) {
3116       assert_equal(1,  escaped_binary[0]);
3117       assert_equal(64, escaped_binary[1]);
3118       assert_equal(65, escaped_binary[2]);
3119       assert_equal(255, escaped_binary[3]);
3120       assert_equal(66, escaped_binary[4]);
3121       assert_equal(38, escaped_binary[5]);
3122       assert_equal(67, escaped_binary[6]);
3123    }
3124 }
3125 
test_retrieve_zero_rows()3126 Ensure test_retrieve_zero_rows() {
3127    dbi_result result;
3128    int numfields;
3129 
3130    result = dbi_conn_query(conn, "SELECT * from test_datatypes WHERE '0'='1'");
3131    ASSERT_RESULT
3132 
3133    numfields = dbi_result_get_numfields(result);
3134 
3135    assert_not_equal(numfields, DBI_FIELD_ERROR);
3136 
3137    if (!strcmp(cinfo.drivername, "mysql")) {
3138       assert_equal(numfields, 25);
3139    }
3140    else if (!strcmp(cinfo.drivername, "pgsql")) {
3141       assert_equal(numfields, 25);
3142    }
3143    else if (!strcmp(cinfo.drivername, "sqlite3")) {
3144       assert_equal(numfields, 26);
3145    }
3146    else if (!strcmp(cinfo.drivername, "firebird")) {
3147       assert_equal(numfields, 21);
3148    } else { /* this includes sqlite */
3149       assert_equal(numfields, 0);
3150    }
3151 
3152    dbi_result_free(result);
3153 }
3154 
test_dbi_conn_select_db()3155 Ensure test_dbi_conn_select_db() {
3156    const char *errmsg;
3157 
3158    if (!strcmp(cinfo.drivername, "firebird")) {
3159       /* TODO: firebird can't handle this? */
3160    }
3161    else if (!strcmp(cinfo.drivername, "pgsql")) {
3162      /* TODO: connecting to initial_dbname first, then to dbname causes a SIGPIPE although both asserts succeed */
3163       /* assert_not_equal(dbi_conn_select_db(conn, cinfo.initial_dbname), -1); */
3164       /* printf("about to select previous db\n"); */
3165       /* assert_not_equal(dbi_conn_select_db(conn, cinfo.dbname), -1); */
3166       /* printf("done selecting previous db\n"); */
3167    }
3168    else {
3169       assert_not_equal(dbi_conn_select_db(conn, cinfo.initial_dbname), -1);
3170       dbi_conn_select_db(conn, cinfo.dbname);
3171    }
3172 }
3173 
3174 /* transactions */
test_dbi_conn_transaction_commit()3175 Ensure test_dbi_conn_transaction_commit() {
3176    const char *errmsg;
3177    dbi_result result;
3178    int int_result;
3179    int errnum;
3180 
3181    if (!dbi_conn_cap_get(conn, "transaction_support")) {
3182      /* test not applicable */
3183      return;
3184    }
3185 
3186    /* check initial value */
3187 
3188    QUERY_ASSERT_RESULT(result, "SELECT the_long FROM test_datatypes");
3189 
3190    while (dbi_result_next_row(result)) {
3191       errmsg = NULL;
3192       int the_long = 0;
3193 
3194       the_long = dbi_result_get_int_idx(result, 1);
3195       assert_equal(the_long, -2147483648);
3196    }
3197 
3198    dbi_result_free(result);
3199 
3200    /* start transaction */
3201    int_result = dbi_conn_transaction_begin(conn);
3202    assert_equal(int_result, 0);
3203 
3204    /* update value */
3205    QUERY_ASSERT_RESULT(result, "UPDATE test_datatypes SET the_long=0");
3206 
3207 
3208    /* commit transaction */
3209    int_result = dbi_conn_transaction_commit(conn);
3210    assert_equal(int_result, 0);
3211 
3212 
3213    /* check value again */
3214    QUERY_ASSERT_RESULT(result, "SELECT the_long FROM test_datatypes");
3215 
3216    while (dbi_result_next_row(result)) {
3217       errmsg = NULL;
3218       int the_long = 0;
3219 
3220       the_long = dbi_result_get_int_idx(result, 1);
3221       assert_equal(the_long, 0);
3222    }
3223 
3224    dbi_result_free(result);
3225 
3226 }
3227 
test_dbi_conn_transaction_rollback()3228 Ensure test_dbi_conn_transaction_rollback() {
3229    const char *errmsg;
3230    dbi_result result;
3231    int int_result;
3232    int errnum;
3233 
3234    if (!dbi_conn_cap_get(conn, "transaction_support")) {
3235      /* test not applicable */
3236      return;
3237    }
3238 
3239    /* check initial value */
3240 
3241    QUERY_ASSERT_RESULT(result, "SELECT the_long FROM test_datatypes");
3242 
3243    while (dbi_result_next_row(result)) {
3244       errmsg = NULL;
3245       int the_long = 0;
3246 
3247       the_long = dbi_result_get_int_idx(result, 1);
3248       assert_equal(the_long, -2147483648);
3249    }
3250 
3251    dbi_result_free(result);
3252 
3253    /* start transaction */
3254    int_result = dbi_conn_transaction_begin(conn);
3255    assert_equal(int_result, 0);
3256 
3257    /* update value */
3258    QUERY_ASSERT_RESULT(result, "UPDATE test_datatypes SET the_long=0");
3259 
3260 
3261    /* rollback transaction */
3262    int_result = dbi_conn_transaction_rollback(conn);
3263    assert_equal(int_result, 0);
3264 
3265 
3266    /* check value again */
3267    QUERY_ASSERT_RESULT(result, "SELECT the_long FROM test_datatypes");
3268 
3269    while (dbi_result_next_row(result)) {
3270       errmsg = NULL;
3271       int the_long = 0;
3272 
3273       the_long = dbi_result_get_int_idx(result, 1);
3274       assert_equal(the_long, -2147483648);
3275    }
3276 
3277    dbi_result_free(result);
3278 
3279 }
3280 
test_dbi_conn_rollback_to_savepoint()3281 Ensure test_dbi_conn_rollback_to_savepoint() {
3282    const char *errmsg;
3283    dbi_result result;
3284    int int_result;
3285    int errnum;
3286 
3287    if (!dbi_conn_cap_get(conn, "savepoint_support")) {
3288      /* test not applicable */
3289      return;
3290    }
3291 
3292    /* check initial value */
3293 
3294    QUERY_ASSERT_RESULT(result, "SELECT the_long FROM test_datatypes");
3295 
3296    while (dbi_result_next_row(result)) {
3297       errmsg = NULL;
3298       int the_long = 0;
3299 
3300       the_long = dbi_result_get_int_idx(result, 1);
3301       assert_equal(the_long, -2147483648);
3302    }
3303 
3304    dbi_result_free(result);
3305 
3306    /* start transaction */
3307    int_result = dbi_conn_transaction_begin(conn);
3308    assert_equal(int_result, 0);
3309 
3310    /* set savepoint */
3311    int_result = dbi_conn_savepoint(conn, "my_savepoint");
3312    assert_equal(int_result, 0);
3313 
3314    /* update value */
3315    QUERY_ASSERT_RESULT(result, "UPDATE test_datatypes SET the_long=0");
3316 
3317    /* rollback to savepoint */
3318    int_result = dbi_conn_rollback_to_savepoint(conn, "my_savepoint");
3319    assert_equal(int_result, 0);
3320 
3321    /* commit transaction */
3322    int_result = dbi_conn_transaction_commit(conn);
3323    assert_equal(int_result, 0);
3324 
3325    /* check value again */
3326    QUERY_ASSERT_RESULT(result, "SELECT the_long FROM test_datatypes");
3327 
3328    while (dbi_result_next_row(result)) {
3329       errmsg = NULL;
3330       int the_long = 0;
3331 
3332       the_long = dbi_result_get_int_idx(result, 1);
3333       assert_equal(the_long, -2147483648);
3334    }
3335 
3336    dbi_result_free(result);
3337 
3338 }
3339 
test_dbi_conn_release_savepoint()3340 Ensure test_dbi_conn_release_savepoint() {
3341    const char *errmsg;
3342    dbi_result result;
3343    int int_result;
3344    int errnum;
3345 
3346    if (!dbi_conn_cap_get(conn, "savepoint_support")) {
3347      /* test not applicable */
3348      return;
3349    }
3350 
3351    /* start transaction */
3352    int_result = dbi_conn_transaction_begin(conn);
3353    assert_equal(int_result, 0);
3354 
3355    /* set savepoint */
3356    int_result = dbi_conn_savepoint(conn, "my_savepoint");
3357    assert_equal(int_result, 0);
3358 
3359    /* release savepoint */
3360    int_result = dbi_conn_release_savepoint(conn, "my_savepoint");
3361    assert_equal(int_result, 0);
3362 
3363    /* rollback to savepoint */
3364    int_result = dbi_conn_rollback_to_savepoint(conn, "my_savepoint");
3365    assert_equal(int_result, 1);
3366 
3367    /* commit transaction */
3368    int_result = dbi_conn_transaction_commit(conn);
3369    assert_equal(int_result, 0);
3370 
3371 }
3372 
3373 // TODO: make tests to specific functions
3374 
3375 /* Postgresql specific funtions */
3376 
test_pgsql_copy()3377 Ensure test_pgsql_copy() {
3378 
3379 }
3380 
3381 /****** no driver-specific tests ******/
3382 
test_create_another_connection()3383 Ensure test_create_another_connection() {
3384    dbi_conn another_conn = NULL;
3385    dbi_result result;
3386 
3387    int status;
3388 
3389    another_conn = my_dbi_conn_new(cinfo.drivername, dbi_instance);
3390    assert_not_equal(another_conn, NULL);
3391 
3392    set_driver_options(&cinfo, another_conn, "");
3393 
3394    status = dbi_conn_connect(another_conn);
3395    assert_equal(status, 0);
3396 
3397    result = dbi_conn_query(another_conn, "SELECT the_conn_quoted_string from test_datatypes");
3398 
3399    ASSERT_RESULT
3400 
3401    while (dbi_result_next_row(result)) {
3402       const char* the_quoted_string;
3403 
3404       the_quoted_string = dbi_result_get_string(result, "the_conn_quoted_string");
3405       assert_string_equal(the_quoted_string,  expect_as_string_from_name("the_conn_quoted_string", cinfo.drivername));
3406 
3407    }
3408 
3409    dbi_result_free(result);
3410 
3411    dbi_conn_close(another_conn);
3412 
3413    another_conn = NULL;
3414 }
3415 
test_dbi_conn_quote_string()3416 Ensure test_dbi_conn_quote_string() {
3417    dbi_result result;
3418    char *my_string_to_quote = NULL;
3419 
3420    my_string_to_quote = strdup(string_to_quote);
3421 
3422    dbi_conn_quote_string(conn, &my_string_to_quote);
3423 
3424    assert_string_equal(my_string_to_quote, expect_as_string_from_name("_quoted_string", cinfo.drivername));
3425 
3426    free(my_string_to_quote);
3427 
3428 }
3429 
test_dbi_conn_quote_string_copy()3430 Ensure test_dbi_conn_quote_string_copy() {
3431    dbi_result result;
3432    char *quoted_string = NULL;
3433    size_t quoted_string_length;
3434 
3435    quoted_string_length = dbi_conn_quote_string_copy(conn, string_to_quote, &quoted_string);
3436 
3437    assert_string_equal(quoted_string, expect_as_string_from_name("_quoted_string", cinfo.drivername));
3438 
3439 }
3440 
test_dbi_conn_escape_string()3441 Ensure test_dbi_conn_escape_string() {
3442    dbi_result result;
3443    char *my_string_to_escape = NULL;
3444 
3445    my_string_to_escape = strdup(string_to_escape);
3446 
3447    dbi_conn_escape_string(conn, &my_string_to_escape);
3448 
3449    assert_string_equal(my_string_to_escape, expect_as_string_from_name("_escaped_string", cinfo.drivername));
3450 
3451    free(my_string_to_escape);
3452 }
3453 
test_dbi_conn_escape_string_copy()3454 Ensure test_dbi_conn_escape_string_copy() {
3455    dbi_result result;
3456    char *escaped_string = NULL;
3457    size_t escaped_string_length;
3458 
3459    escaped_string_length = dbi_conn_escape_string_copy(conn, string_to_escape, &escaped_string);
3460 
3461    assert_string_equal(escaped_string, expect_as_string_from_name("_escaped_string", cinfo.drivername));
3462 
3463 }
3464 
test_dbi_result_get_conn()3465 Ensure test_dbi_result_get_conn() {
3466    dbi_result result;
3467    dbi_conn getcon;
3468 
3469    result = dbi_conn_query(conn, "SELECT the_char from test_datatypes");
3470 
3471    ASSERT_RESULT
3472 
3473    getcon = dbi_result_get_conn(result);
3474 
3475    assert_not_equal_with_message(getcon, NULL, "Value: '%d' Error %d: %s",
3476          getcon, dbi_conn_error(conn, &errmsg), errmsg);
3477 
3478    dbi_result_free(result);
3479 
3480 }
3481 
test_dbi_result_free()3482 Ensure test_dbi_result_free() {
3483 
3484 }
3485 
test_dbi_result_seek_row()3486 Ensure test_dbi_result_seek_row() {
3487    dbi_result result;
3488    int seekrow;
3489 
3490    result = dbi_conn_query(conn, "SELECT the_char from test_datatypes");
3491    ASSERT_RESULT
3492 
3493    seekrow = dbi_result_seek_row(result, 3);
3494 
3495    dbi_conn_error(conn, &errmsg);
3496    assert_equal_with_message(seekrow, 1, "Value '%d' Error: %s",
3497          seekrow, errmsg);
3498 
3499    dbi_result_free(result);
3500 
3501 }
3502 
test_dbi_result_first_row()3503 Ensure test_dbi_result_first_row() {
3504    dbi_result result;
3505    int firstrow;
3506 
3507    result = dbi_conn_query(conn, "SELECT the_char from test_datatypes");
3508    ASSERT_RESULT
3509 
3510    firstrow = dbi_result_first_row(result);
3511 
3512    dbi_conn_error(conn, &errmsg);
3513    assert_equal_with_message(firstrow, 1, "Value: '%d' Error: %s",
3514          firstrow, errmsg);
3515 
3516    dbi_result_free(result);
3517 
3518 }
3519 
test_dbi_result_last_row()3520 Ensure test_dbi_result_last_row() {
3521    dbi_result result;
3522    int lastrow;
3523 
3524    result = dbi_conn_query(conn, "SELECT the_char from test_datatypes");
3525    ASSERT_RESULT
3526 
3527    lastrow = dbi_result_last_row(result);
3528 
3529    dbi_conn_error(conn, &errmsg);
3530    assert_equal_with_message(lastrow, 1, "Value: '%d' Error: %s",
3531          lastrow, errmsg);
3532 
3533    dbi_result_free(result);
3534 
3535 }
3536 
test_dbi_result_prev_row()3537 Ensure test_dbi_result_prev_row() {
3538    dbi_result result;
3539    int prevrow;
3540 
3541    result = dbi_conn_query(conn, "SELECT the_char from test_datatypes");
3542    ASSERT_RESULT
3543 
3544    dbi_result_next_row(result);
3545    dbi_result_next_row(result);
3546 
3547    prevrow = dbi_result_prev_row(result);
3548 
3549    dbi_conn_error(conn, &errmsg);
3550    assert_equal_with_message(prevrow, 1, "Value: '%d' Error: %s",
3551          prevrow, errmsg);
3552 
3553    dbi_result_free(result);
3554 
3555 }
3556 
test_dbi_result_next_row()3557 Ensure test_dbi_result_next_row() {
3558    dbi_result result;
3559    int nextrow;
3560 
3561    result = dbi_conn_query(conn, "SELECT the_char from test_datatypes");
3562    ASSERT_RESULT
3563 
3564    nextrow = dbi_result_next_row(result);
3565 
3566    dbi_conn_error(conn, &errmsg);
3567    assert_equal_with_message(nextrow, 1, "Value: '%d' Error: %s",
3568          nextrow, errmsg);
3569 
3570    dbi_result_free(result);
3571 
3572 }
3573 
test_dbi_result_get_currow()3574 Ensure test_dbi_result_get_currow() {
3575    dbi_result result;
3576    unsigned long long currow;
3577 
3578    result = dbi_conn_query(conn, "SELECT the_char from test_datatypes");
3579    ASSERT_RESULT
3580 
3581    dbi_result_next_row(result);
3582    dbi_result_next_row(result);
3583 
3584    currow = dbi_result_get_currow(result);
3585 
3586    dbi_conn_error(conn, &errmsg);
3587    assert_equal_with_message(currow, 2, "Value: '%d' Error: %s",
3588          currow, errmsg);
3589 
3590    dbi_result_free(result);
3591 }
3592 
test_dbi_result_get_numrows()3593 Ensure test_dbi_result_get_numrows() {
3594    dbi_result result;
3595    unsigned long long numrows;
3596 
3597    result = dbi_conn_query(conn, "SELECT the_char from test_datatypes");
3598    ASSERT_RESULT
3599 
3600    numrows = dbi_result_get_numrows(result);
3601 
3602    dbi_conn_error(conn, &errmsg);
3603    assert_equal_with_message(numrows, 5, "Value: '%d' Error: %s",
3604          numrows, errmsg);
3605 
3606    dbi_result_free(result);
3607 }
3608 
test_dbi_result_get_numrows_affected()3609 Ensure test_dbi_result_get_numrows_affected() {
3610    dbi_result result;
3611    unsigned long long numrows;
3612 
3613    result = dbi_conn_query(conn, "UPDATE test_datatypes set the_char=-126 where the_char=-127 ");
3614    ASSERT_RESULT
3615 
3616    numrows = dbi_result_get_numrows_affected(result);
3617 
3618    dbi_conn_error(conn, &errmsg);
3619    assert_equal_with_message(numrows, 5, "Value: '%d' Error: %s",
3620          numrows, errmsg);
3621 
3622    dbi_result_free(result);
3623 }
3624 
test_dummy()3625 Ensure test_dummy() {
3626    dbi_result result;
3627    const char *errmsg;
3628    int numfields;
3629    char smt[1024];
3630    int i;
3631 
3632    result = dbi_conn_query(conn, "CREATE TABLE test0 (the_char SMALLINT, the_long INTEGER)");
3633    dbi_result_free(result);
3634 
3635    for(i = 0; i < 30; i++) {
3636       sprintf(smt, "INSERT INTO test0 VALUES (%d, %d)", i, i );
3637       result = dbi_conn_query(conn, smt);
3638       dbi_result_free(result);
3639    }
3640 
3641    result = dbi_conn_query(conn, "SELECT the_long from test0");
3642    assert_not_equal_with_message( result, NULL, "Value: '%p' Error %d: '%s'",
3643          result, dbi_conn_error(conn, &errmsg), errmsg);
3644 
3645    while (dbi_result_next_row(result)) {
3646       errmsg = NULL;
3647       long long the_long = 0;
3648 
3649       the_long = dbi_result_get_as_longlong(result, "the_long");
3650 
3651    }
3652 
3653    dbi_result_free(result);
3654 
3655    result = dbi_conn_query(conn, "DROP TABLE test0");
3656 
3657    dbi_result_free(result);
3658 }
3659 
test_dbi_result_get_as_longlong()3660 Ensure test_dbi_result_get_as_longlong() {
3661    dbi_result result;
3662    char *query_string;
3663    int numfields;
3664 
3665    query_string = assemble_query_string(cinfo.drivername, &numfields);
3666 
3667    result = dbi_conn_query(conn, query_string);
3668    ASSERT_RESULT
3669 
3670    free(query_string);
3671 
3672    while (dbi_result_next_row(result)) {
3673       const char *errmsg = NULL;
3674       long long the_char_as_ll = 0;
3675       long long the_uchar_as_ll = 0;
3676       long long the_short_as_ll = 0;
3677       long long the_ushort_as_ll = 0;
3678       long long the_long_as_ll = 0;
3679       long long the_ulong_as_ll = 0;
3680       long long the_longlong_as_ll = 0;
3681       long long the_ulonglong_as_ll = 0;
3682       long long the_float_as_ll = 0;
3683       long long the_double_as_ll = 0;
3684       long long the_string_as_ll = 0;
3685       long long the_numstring_as_ll = 0;
3686       long long the_empty_string_as_ll = 0;
3687       long long the_null_string_as_ll = 0;
3688       long long the_binary_as_ll = 0;
3689       long long the_date_as_ll = 0;
3690       long long the_time_as_ll = 0;
3691       long long the_datetime_as_ll = 0;
3692 
3693       the_char_as_ll = dbi_result_get_as_longlong(result, "the_char");
3694       the_uchar_as_ll = dbi_result_get_as_longlong(result, "the_uchar");
3695       the_short_as_ll = dbi_result_get_as_longlong(result, "the_short");
3696       the_ushort_as_ll = dbi_result_get_as_longlong(result, "the_ushort");
3697       the_long_as_ll = dbi_result_get_as_longlong(result, "the_long");
3698       the_ulong_as_ll = dbi_result_get_as_longlong(result, "the_ulong");
3699 
3700       if (tinfo.have_longlong) {
3701          the_longlong_as_ll = dbi_result_get_as_longlong(result, "the_longlong");
3702       }
3703       if (tinfo.have_ulonglong) {
3704          the_ulonglong_as_ll = dbi_result_get_as_longlong(result, "the_ulonglong");
3705       }
3706       the_float_as_ll = dbi_result_get_as_longlong(result, "the_float");
3707       if(tinfo.have_double) {
3708          the_double_as_ll = dbi_result_get_as_longlong(result, "the_double");
3709       }
3710 
3711       the_string_as_ll = dbi_result_get_as_longlong(result, "the_conn_quoted_string_copy");
3712       the_numstring_as_ll = dbi_result_get_as_longlong(result, "the_numstring");
3713       the_empty_string_as_ll = dbi_result_get_as_longlong(result, "the_empty_string");
3714       the_null_string_as_ll = dbi_result_get_as_longlong(result, "the_null_string");
3715       the_binary_as_ll = dbi_result_get_as_longlong(result, "the_binary_quoted_string");
3716 
3717       if(tinfo.have_datetime) {
3718          the_datetime_as_ll = dbi_result_get_as_longlong(result, "the_datetime");
3719       }
3720 
3721       the_date_as_ll = dbi_result_get_as_longlong(result, "the_date");
3722       the_time_as_ll = dbi_result_get_as_longlong(result, "the_time");
3723 
3724       assert_equal(the_char_as_ll, expect_as_longlong_from_name("the_char", cinfo.drivername));
3725       assert_equal(the_uchar_as_ll, expect_as_longlong_from_name("the_uchar", cinfo.drivername));
3726       assert_equal(the_short_as_ll, expect_as_longlong_from_name("the_short", cinfo.drivername));
3727       assert_equal(the_ushort_as_ll, expect_as_longlong_from_name("the_ushort", cinfo.drivername));
3728       assert_equal(the_long_as_ll, expect_as_longlong_from_name("the_long", cinfo.drivername));
3729       assert_equal(the_ulong_as_ll, expect_as_longlong_from_name("the_ulong", cinfo.drivername));
3730       assert_equal(the_longlong_as_ll, expect_as_longlong_from_name("the_longlong", cinfo.drivername));
3731       assert_equal(the_ulonglong_as_ll, expect_as_longlong_from_name("the_ulonglong", cinfo.drivername));
3732       assert_equal(the_float_as_ll, expect_as_longlong_from_name("the_float", cinfo.drivername));
3733       assert_equal(the_double_as_ll, expect_as_longlong_from_name("the_double", cinfo.drivername));
3734       assert_equal(the_string_as_ll, expect_as_longlong_from_name("the_conn_quoted_string_copy", cinfo.drivername));
3735       assert_equal(the_numstring_as_ll, expect_as_longlong_from_name("the_numstring", cinfo.drivername));
3736       assert_equal(the_empty_string_as_ll, expect_as_longlong_from_name("the_empty_string", cinfo.drivername));
3737       assert_equal(the_null_string_as_ll, expect_as_longlong_from_name("the_null_string", cinfo.drivername));
3738       assert_equal(the_datetime_as_ll, expect_as_longlong_from_name("the_datetime", cinfo.drivername));
3739       assert_equal(the_date_as_ll, expect_as_longlong_from_name("the_date", cinfo.drivername));
3740       assert_equal(the_time_as_ll, expect_as_longlong_from_name("the_time", cinfo.drivername));
3741 
3742    }
3743 
3744    dbi_result_free(result);
3745 }
3746 
test_dbi_result_get_as_string()3747 Ensure test_dbi_result_get_as_string() {
3748    dbi_result result;
3749    char *query_string;
3750    int numfields;
3751 
3752    query_string = assemble_query_string(cinfo.drivername, &numfields);
3753 
3754    result = dbi_conn_query(conn, query_string);
3755    ASSERT_RESULT
3756 
3757    free(query_string);
3758 
3759    while (dbi_result_next_row(result)) {
3760       const char *errmsg = NULL;
3761       char* the_char_as_string = NULL;
3762       char* the_uchar_as_string = NULL;
3763       char* the_short_as_string = NULL;
3764       char* the_ushort_as_string = NULL;
3765       char* the_long_as_string = NULL;
3766       char* the_ulong_as_string = NULL;
3767       char* the_longlong_as_string = NULL;
3768       char* the_ulonglong_as_string = NULL;
3769       char* the_float_as_string = NULL;
3770       char* the_double_as_string = NULL;
3771       char* the_string_as_string = NULL;
3772       char* the_numstring_as_string = NULL;
3773       char* the_empty_string_as_string = NULL;
3774       char* the_null_string_as_string = NULL;
3775       char* the_binary_as_string = NULL;
3776       char* the_date_as_string = NULL;
3777       char* the_time_as_string = NULL;
3778       char* the_datetime_as_string = NULL;
3779 
3780       /* get data */
3781       the_char_as_string = dbi_result_get_as_string_copy(result, "the_char");
3782       the_uchar_as_string = dbi_result_get_as_string_copy(result, "the_uchar");
3783       the_short_as_string = dbi_result_get_as_string_copy(result, "the_short");
3784       the_ushort_as_string = dbi_result_get_as_string_copy(result, "the_ushort");
3785       the_long_as_string = dbi_result_get_as_string_copy(result, "the_long");
3786       the_ulong_as_string = dbi_result_get_as_string_copy(result, "the_ulong");
3787       if (tinfo.have_longlong) {
3788          the_longlong_as_string = dbi_result_get_as_string_copy(result, "the_longlong");
3789       }
3790       if (tinfo.have_ulonglong) {
3791          the_ulonglong_as_string = dbi_result_get_as_string_copy(result, "the_ulonglong");
3792       }
3793       the_float_as_string = dbi_result_get_as_string_copy(result, "the_float");
3794       if(tinfo.have_double) {
3795          the_double_as_string = dbi_result_get_as_string_copy(result, "the_double");
3796       }
3797       the_string_as_string = dbi_result_get_as_string_copy(result, "the_conn_quoted_string_copy");
3798       the_numstring_as_string = dbi_result_get_as_string_copy(result, "the_numstring");
3799       the_empty_string_as_string = dbi_result_get_as_string_copy(result, "the_empty_string");
3800       the_null_string_as_string = dbi_result_get_as_string_copy(result, "the_null_string");
3801       the_binary_as_string = dbi_result_get_as_string_copy(result, "the_binary_quoted_string");
3802       if(tinfo.have_datetime) {
3803          the_datetime_as_string = dbi_result_get_as_string_copy(result, "the_datetime");
3804       }
3805 
3806       if(!strcmp(cinfo.drivername, "msql")) {
3807          the_date_as_string = dbi_result_get_as_string_copy(result, "the_date");
3808          the_time_as_string = dbi_result_get_as_string_copy(result, "the_time");
3809       } else { //not msql
3810          the_date_as_string = dbi_result_get_as_string_copy(result, "the_date");
3811          the_time_as_string = dbi_result_get_as_string_copy(result, "the_time");
3812       }
3813 
3814       /* do asserts */
3815       assert_string_equal(the_char_as_string, expect_as_string_from_name("the_char", cinfo.drivername));
3816       assert_string_equal(the_uchar_as_string, expect_as_string_from_name("the_uchar", cinfo.drivername));
3817       assert_string_equal(the_short_as_string, expect_as_string_from_name("the_short", cinfo.drivername));
3818       assert_string_equal(the_ushort_as_string, expect_as_string_from_name("the_ushort", cinfo.drivername));
3819       assert_string_equal(the_long_as_string, expect_as_string_from_name("the_long", cinfo.drivername));
3820       assert_string_equal(the_ulong_as_string, expect_as_string_from_name("the_ulong", cinfo.drivername));
3821       assert_string_equal(the_longlong_as_string, expect_as_string_from_name("the_longlong", cinfo.drivername));
3822       assert_string_equal(the_ulonglong_as_string, expect_as_string_from_name("the_ulonglong", cinfo.drivername));
3823       assert_string_equal(the_float_as_string, expect_as_string_from_name("the_float", cinfo.drivername));
3824       assert_string_equal(the_string_as_string, expect_as_string_from_name("the_conn_quoted_string_copy", cinfo.drivername));
3825       assert_string_equal(the_numstring_as_string, expect_as_string_from_name("the_numstring", cinfo.drivername));
3826       assert_string_equal(the_empty_string_as_string, expect_as_string_from_name("the_empty_string", cinfo.drivername));
3827       assert_string_equal(the_null_string_as_string, expect_as_string_from_name("the_null_string", cinfo.drivername));
3828       assert_string_equal(the_datetime_as_string, expect_as_string_from_name("the_datetime", cinfo.drivername));
3829       assert_string_equal(the_date_as_string, expect_as_string_from_name("the_date", cinfo.drivername));
3830       assert_string_equal(the_time_as_string, expect_as_string_from_name("the_time", cinfo.drivername));
3831 
3832       if (the_char_as_string) {
3833          free(the_char_as_string);
3834       }
3835       if (the_uchar_as_string) {
3836          free(the_uchar_as_string);
3837       }
3838       if (the_short_as_string) {
3839          free(the_short_as_string);
3840       }
3841       if (the_ushort_as_string) {
3842          free(the_ushort_as_string);
3843       }
3844       if (the_long_as_string) {
3845          free(the_long_as_string);
3846       }
3847       if (the_ulong_as_string) {
3848          free(the_ulong_as_string);
3849       }
3850       if (the_longlong_as_string) {
3851          free(the_longlong_as_string);
3852       }
3853       if (the_ulonglong_as_string) {
3854          free(the_ulonglong_as_string);
3855       }
3856       if (the_float_as_string) {
3857          free(the_float_as_string);
3858       }
3859       if (the_double_as_string) {
3860          free(the_double_as_string);
3861       }
3862       if (the_string_as_string) {
3863          free(the_string_as_string);
3864       }
3865       if (the_numstring_as_string) {
3866          free(the_numstring_as_string);
3867       }
3868       if (the_empty_string_as_string) {
3869          free(the_empty_string_as_string);
3870       }
3871       if (the_null_string_as_string) {
3872          free(the_null_string_as_string);
3873       }
3874       if (the_binary_as_string) {
3875          free(the_binary_as_string);
3876       }
3877       if (the_date_as_string) {
3878          free(the_date_as_string);
3879       }
3880       if (the_time_as_string) {
3881          free(the_time_as_string);
3882       }
3883       if (the_datetime_as_string) {
3884          free(the_datetime_as_string);
3885       }
3886    }
3887    dbi_result_free(result);
3888 }
3889 
test_dbi_result_get_char_idx()3890 Ensure test_dbi_result_get_char_idx() {
3891    dbi_result result;
3892 
3893    unsigned short type_expected = 0;
3894 
3895    type_expected = field_attrib_from_index(0 /* the_char */, cinfo.drivername);
3896 
3897    if (type_expected == 2) { /* skip test for db engines which do not support a true one-byte char type */
3898      result = dbi_conn_query(conn, "SELECT the_char from test_datatypes");
3899 
3900      ASSERT_RESULT
3901 
3902        while (dbi_result_next_row(result)) {
3903 	 errmsg = NULL;
3904 	 signed char the_char = 0;
3905 
3906 	 the_char = dbi_result_get_char_idx(result, 1);
3907 
3908 	 assert_equal(the_char, expect_longlong_from_name("the_char", cinfo.drivername));
3909 
3910        }
3911 
3912      dbi_result_free(result);
3913    }
3914 }
3915 
test_dbi_result_get_uchar_idx()3916 Ensure test_dbi_result_get_uchar_idx() {
3917    dbi_result result;
3918    unsigned short type_expected = 0;
3919 
3920    type_expected = field_attrib_from_index(0 /* the_char */, cinfo.drivername);
3921 
3922    if (type_expected == 2) { /* skip test for db engines which do not support a true one-byte char type */
3923 
3924      result = dbi_conn_query(conn, "SELECT the_uchar from test_datatypes");
3925 
3926      ASSERT_RESULT
3927 
3928        while (dbi_result_next_row(result)) {
3929 	 errmsg = NULL;
3930 	 unsigned char the_uchar = 0;
3931 
3932 	 the_uchar = dbi_result_get_uchar_idx(result, 1);
3933 
3934 	 assert_equal(the_uchar, expect_ulonglong_from_name("the_uchar", cinfo.drivername));
3935 
3936        }
3937 
3938      dbi_result_free(result);
3939    }
3940 }
3941 
test_dbi_result_get_short_idx()3942 Ensure test_dbi_result_get_short_idx() {
3943    dbi_result result;
3944 
3945    result = dbi_conn_query(conn, "SELECT the_short from test_datatypes");
3946 
3947    ASSERT_RESULT
3948 
3949    while (dbi_result_next_row(result)) {
3950       errmsg = NULL;
3951       short the_short = 0;
3952 
3953       the_short = dbi_result_get_short_idx(result, 1);
3954 
3955       assert_equal(the_short, expect_longlong_from_name("the_short", cinfo.drivername));
3956 
3957    }
3958 
3959    dbi_result_free(result);
3960 }
3961 
test_dbi_result_get_ushort_idx()3962 Ensure test_dbi_result_get_ushort_idx() {
3963    dbi_result result;
3964 
3965    result = dbi_conn_query(conn, "SELECT the_ushort from test_datatypes");
3966 
3967    ASSERT_RESULT
3968 
3969    while (dbi_result_next_row(result)) {
3970       errmsg = NULL;
3971       unsigned short the_ushort = 0;
3972 
3973       the_ushort = dbi_result_get_ushort_idx(result, 1);
3974 
3975       assert_equal(the_ushort, expect_ulonglong_from_name("the_ushort", cinfo.drivername));
3976 
3977    }
3978 
3979    dbi_result_free(result);
3980 }
3981 
test_dbi_result_get_int_idx()3982 Ensure test_dbi_result_get_int_idx() {
3983    dbi_result result;
3984 
3985    result = dbi_conn_query(conn, "SELECT the_long from test_datatypes");
3986 
3987    ASSERT_RESULT
3988 
3989    while (dbi_result_next_row(result)) {
3990       errmsg = NULL;
3991       int the_int = 0;
3992 
3993       the_int = dbi_result_get_int_idx(result, 1);
3994 
3995       assert_equal(the_int, expect_longlong_from_name("the_long", cinfo.drivername));
3996 
3997    }
3998 
3999    dbi_result_free(result);
4000 }
4001 
test_dbi_result_get_uint_idx()4002 Ensure test_dbi_result_get_uint_idx() {
4003    dbi_result result;
4004 
4005    result = dbi_conn_query(conn, "SELECT the_ulong from test_datatypes");
4006 
4007    ASSERT_RESULT
4008 
4009    while (dbi_result_next_row(result)) {
4010       errmsg = NULL;
4011       unsigned int the_uint = 0;
4012 
4013       the_uint = dbi_result_get_uint_idx(result, 1);
4014 
4015       assert_equal(the_uint, expect_ulonglong_from_name("the_ulong", cinfo.drivername));
4016 
4017    }
4018 
4019    dbi_result_free(result);
4020 }
4021 
test_dbi_result_get_longlong_idx()4022 Ensure test_dbi_result_get_longlong_idx() {
4023    dbi_result result;
4024 
4025    result = dbi_conn_query(conn, "SELECT the_longlong from test_datatypes");
4026 
4027    ASSERT_RESULT
4028 
4029    while (dbi_result_next_row(result)) {
4030       errmsg = NULL;
4031       long long the_longlong = 0;
4032 
4033       the_longlong = dbi_result_get_longlong_idx(result, 1);
4034 
4035 
4036       assert_equal(the_longlong, expect_longlong_from_name("the_longlong", cinfo.drivername));
4037 
4038    }
4039 
4040    dbi_result_free(result);
4041 }
4042 
test_dbi_result_get_ulonglong_idx()4043 Ensure test_dbi_result_get_ulonglong_idx() {
4044    dbi_result result;
4045 
4046    result = dbi_conn_query(conn, "SELECT the_ulonglong from test_datatypes");
4047 
4048    ASSERT_RESULT
4049 
4050    while (dbi_result_next_row(result)) {
4051       errmsg = NULL;
4052       unsigned long long the_ulonglong = 0;
4053 
4054       the_ulonglong = dbi_result_get_ulonglong_idx(result, 1);
4055 
4056       assert_equal(the_ulonglong, expect_ulonglong_from_name("the_ulonglong", cinfo.drivername));
4057 
4058    }
4059 
4060    dbi_result_free(result);
4061 }
4062 
test_dbi_result_get_float_idx()4063 Ensure test_dbi_result_get_float_idx() {
4064    dbi_result result;
4065 
4066    result = dbi_conn_query(conn, "SELECT the_float from test_datatypes");
4067 
4068    ASSERT_RESULT
4069 
4070    while (dbi_result_next_row(result)) {
4071       errmsg = NULL;
4072       float the_float = 0;
4073 
4074       the_float = dbi_result_get_float_idx(result, 1);
4075 
4076       assert_double_equal(the_float, expect_double_from_name("the_float", cinfo.drivername));
4077 
4078    }
4079 
4080    dbi_result_free(result);
4081 }
4082 
test_dbi_result_get_double_idx()4083 Ensure test_dbi_result_get_double_idx() {
4084    dbi_result result;
4085 
4086    result = dbi_conn_query(conn, "SELECT the_double from test_datatypes");
4087 
4088    ASSERT_RESULT
4089 
4090    while (dbi_result_next_row(result)) {
4091       errmsg = NULL;
4092       double the_double = 0;
4093 
4094       the_double = dbi_result_get_double_idx(result, 1);
4095 
4096       assert_double_equal(the_double, expect_double_from_name("the_double", cinfo.drivername));
4097 
4098    }
4099 
4100    dbi_result_free(result);
4101 }
4102 
test_dbi_result_get_string_idx()4103 Ensure test_dbi_result_get_string_idx() {
4104    dbi_result result;
4105 
4106    result = dbi_conn_query(conn, "SELECT the_null_string, the_conn_escaped_string, the_empty_string,"
4107          " the_conn_quoted_string from test_datatypes");
4108 
4109    ASSERT_RESULT
4110 
4111    while (dbi_result_next_row(result)) {
4112       errmsg = NULL;
4113       const char* the_quoted_string;
4114       const char* the_escaped_string;
4115       const char* the_null_string;
4116       const char* the_empty_string;
4117 
4118       the_quoted_string = dbi_result_get_string_idx(result, 4);
4119       assert_string_equal(the_quoted_string,  expect_as_string_from_name("the_conn_quoted_string", cinfo.drivername));
4120 
4121       the_escaped_string = dbi_result_get_string_idx(result, 2);
4122       assert_string_equal(the_escaped_string, expect_as_string_from_name("the_conn_escaped_string", cinfo.drivername));
4123 
4124       the_null_string = dbi_result_get_string_idx(result, 1);
4125       assert_string_equal(the_null_string, expect_string_from_name("the_null_string", cinfo.drivername));
4126 
4127       the_empty_string = dbi_result_get_string_idx(result, 3);
4128       assert_string_equal(the_empty_string, expect_as_string_from_name("the_empty_string", cinfo.drivername));
4129 
4130    }
4131 
4132    dbi_result_free(result);
4133 }
4134 
test_dbi_result_get_string_copy_idx()4135 Ensure test_dbi_result_get_string_copy_idx() {
4136    dbi_result result;
4137 
4138    result = dbi_conn_query(conn, "SELECT the_conn_quoted_string, the_conn_escaped_string_copy"
4139          " from test_datatypes");
4140 
4141    ASSERT_RESULT
4142 
4143    while (dbi_result_next_row(result)) {
4144       errmsg = NULL;
4145       const char* the_quoted_string_copy;
4146       const char* the_escaped_string_copy;
4147 
4148       the_quoted_string_copy = dbi_result_get_string_copy_idx(result, 1);
4149       assert_string_equal(the_quoted_string_copy, expect_as_string_from_name("the_conn_quoted_string", cinfo.drivername));
4150 
4151       the_escaped_string_copy = dbi_result_get_string_copy_idx(result, 2);
4152       assert_string_equal(the_escaped_string_copy, expect_as_string_from_name("the_conn_escaped_string_copy", cinfo.drivername));
4153 
4154    }
4155 
4156    dbi_result_free(result);
4157 }
4158 
test_dbi_result_get_binary_idx()4159 Ensure test_dbi_result_get_binary_idx() {
4160    dbi_result result;
4161 
4162    result = dbi_conn_query(conn, "SELECT the_binary_quoted_string from test_datatypes");
4163 
4164    ASSERT_RESULT
4165 
4166    while (dbi_result_next_row(result)) {
4167       errmsg = NULL;
4168       const unsigned char* the_binary;
4169 
4170       the_binary = dbi_result_get_binary_idx(result, 1);
4171 
4172       assert_equal(65, the_binary[0]);
4173       assert_equal(66, the_binary[1]);
4174       assert_equal(0,  the_binary[2]);
4175       assert_equal(67, the_binary[3]);
4176       assert_equal(39, the_binary[4]);
4177       assert_equal(68, the_binary[5]);
4178    }
4179 
4180    dbi_result_free(result);
4181 }
4182 
test_dbi_result_get_binary_copy_idx()4183 Ensure test_dbi_result_get_binary_copy_idx() {
4184    dbi_result result;
4185 
4186    result = dbi_conn_query(conn, "SELECT the_binary_escaped_string from test_datatypes");
4187 
4188    ASSERT_RESULT
4189 
4190    while (dbi_result_next_row(result)) {
4191       errmsg = NULL;
4192       unsigned char* the_binary_copy = NULL;
4193 
4194       the_binary_copy = dbi_result_get_binary_copy_idx(result, 1);
4195 
4196       assert_equal(65, the_binary_copy[0]);
4197       assert_equal(66, the_binary_copy[1]);
4198       assert_equal(0, the_binary_copy[2]);
4199       assert_equal(67, the_binary_copy[3]);
4200       assert_equal(39, the_binary_copy[4]);
4201       assert_equal(68, the_binary_copy[5]);
4202 
4203    }
4204 
4205    dbi_result_free(result);
4206 }
4207 
test_dbi_result_get_datetime_idx()4208 Ensure test_dbi_result_get_datetime_idx() {
4209    dbi_result result;
4210 
4211    result = dbi_conn_query(conn, "SELECT the_datetime, the_date, the_time from test_datatypes");
4212 
4213    ASSERT_RESULT
4214 
4215    while (dbi_result_next_row(result)) {
4216       errmsg = NULL;
4217       time_t the_datetime = 0;
4218       time_t the_date = 0;
4219       time_t the_time = 0;
4220 
4221       the_datetime = dbi_result_get_datetime_idx(result, 1);
4222       assert_equal( the_datetime, expect_longlong_from_name("the_datetime", cinfo.drivername));
4223 
4224       the_date = dbi_result_get_datetime_idx(result, 2);
4225       assert_equal(the_date, expect_longlong_from_name("the_date", cinfo.drivername));
4226 
4227       the_time = dbi_result_get_datetime_idx(result, 3);
4228       assert_equal(the_time, expect_longlong_from_name("the_time", cinfo.drivername));
4229 
4230    }
4231 
4232    dbi_result_free(result);
4233 
4234 }
4235 
test_dbi_result_get_datetime_tz_idx()4236 Ensure test_dbi_result_get_datetime_tz_idx() {
4237    dbi_result result;
4238 
4239    result = dbi_conn_query(conn, "SELECT the_datetime_tz from test_datatypes");
4240 
4241    ASSERT_RESULT
4242 
4243    while (dbi_result_next_row(result)) {
4244       errmsg = NULL;
4245       time_t the_datetime_tz = 0;
4246 
4247       the_datetime_tz = dbi_result_get_datetime_idx(result, 1);
4248 
4249       assert_equal( the_datetime_tz, expect_longlong_from_name("the_datetime_tz", cinfo.drivername));
4250 
4251    }
4252 
4253    dbi_result_free(result);
4254 }
4255 
test_dbi_result_get_datetime_time_tz_idx()4256 Ensure test_dbi_result_get_datetime_time_tz_idx() {
4257    dbi_result result;
4258 
4259    result = dbi_conn_query(conn, "SELECT the_datetime_tz, the_time_tz from test_datatypes");
4260 
4261    ASSERT_RESULT
4262 
4263    while (dbi_result_next_row(result)) {
4264       errmsg = NULL;
4265       time_t the_datetime_tz = 0;
4266       time_t the_time_dt_tz = 0;
4267 
4268       the_datetime_tz = dbi_result_get_datetime_idx(result, 1);
4269       the_time_dt_tz = dbi_result_get_datetime_idx(result, 2);
4270 
4271       assert_equal( the_datetime_tz, expect_longlong_from_name("the_datetime_tz", cinfo.drivername));
4272       assert_equal( the_time_dt_tz, expect_longlong_from_name("the_time_tz", cinfo.drivername));
4273 
4274    }
4275 
4276    dbi_result_free(result);
4277 
4278 }
4279 
test_dbi_result_get_char()4280 Ensure test_dbi_result_get_char() {
4281    dbi_result result;
4282 
4283    result = dbi_conn_query(conn, "SELECT the_char from test_datatypes");
4284    ASSERT_RESULT
4285 
4286    while (dbi_result_next_row(result)) {
4287       errmsg = NULL;
4288       signed char the_char = 0;
4289       unsigned short type_expected = 0;
4290 
4291       type_expected = field_attrib_from_index(0 /* the_char */, cinfo.drivername);
4292       if (type_expected == 2) {
4293 	the_char = dbi_result_get_char(result, "the_char");
4294       }
4295       else { /* does not support one-byte char type */
4296 	the_char = (signed char)dbi_result_get_short(result, "the_char");
4297       }
4298 
4299       assert_equal(the_char, expect_longlong_from_name("the_char", cinfo.drivername));
4300 
4301    }
4302 
4303    dbi_result_free(result);
4304 }
4305 
test_dbi_result_get_uchar()4306 Ensure test_dbi_result_get_uchar() {
4307    dbi_result result;
4308 
4309    result = dbi_conn_query(conn, "SELECT the_uchar from test_datatypes");
4310    ASSERT_RESULT
4311 
4312    while (dbi_result_next_row(result)) {
4313       errmsg = NULL;
4314       unsigned char the_uchar = 0;
4315       unsigned short type_expected = 0;
4316 
4317       type_expected = field_attrib_from_index(1 /* the_uchar */, cinfo.drivername);
4318       if (type_expected == 2) {
4319 	the_uchar = dbi_result_get_uchar(result, "the_uchar");
4320       }
4321       else { /* does not support one-byte uchar type */
4322 	the_uchar = dbi_result_get_ushort(result, "the_uchar");
4323       }
4324 
4325       assert_equal(the_uchar, expect_ulonglong_from_name("the_uchar", cinfo.drivername));
4326    }
4327 
4328    dbi_result_free(result);
4329 }
4330 
test_dbi_result_get_short()4331 Ensure test_dbi_result_get_short() {
4332    dbi_result result;
4333 
4334    result = dbi_conn_query(conn, "SELECT the_short from test_datatypes");
4335    ASSERT_RESULT
4336 
4337    while (dbi_result_next_row(result)) {
4338       errmsg = NULL;
4339       short the_short = 0;
4340 
4341       the_short = dbi_result_get_short(result, "the_short");
4342 
4343       assert_equal(the_short, expect_longlong_from_name("the_short", cinfo.drivername));
4344    }
4345 
4346    dbi_result_free(result);
4347 }
4348 
test_dbi_result_get_ushort()4349 Ensure test_dbi_result_get_ushort() {
4350    const char *errmsg;
4351    int errnum;
4352    dbi_result result;
4353 
4354    QUERY_ASSERT_RESULT(result, "SELECT the_ushort from test_datatypes");
4355 
4356    while (dbi_result_next_row(result)) {
4357       errmsg = NULL;
4358       unsigned short the_ushort = 0;
4359 
4360       the_ushort = dbi_result_get_ushort(result, "the_ushort");
4361 
4362       assert_equal(the_ushort, expect_longlong_from_name("the_ushort", cinfo.drivername));
4363    }
4364 
4365    dbi_result_free(result);
4366 
4367 }
4368 
test_dbi_result_get_int()4369 Ensure test_dbi_result_get_int() {
4370    dbi_result result;
4371    const char *errmsg;
4372    int errnum;
4373 
4374    QUERY_ASSERT_RESULT(result, "SELECT the_long from test_datatypes");
4375 
4376    while (dbi_result_next_row(result)) {
4377       errmsg = NULL;
4378       int the_int = 0;
4379 
4380       the_int = dbi_result_get_int(result, "the_long");
4381 
4382       assert_equal(the_int, expect_longlong_from_name("the_long", cinfo.drivername));
4383 
4384    }
4385 
4386    dbi_result_free(result);
4387 
4388 }
4389 
test_dbi_result_get_uint()4390 Ensure test_dbi_result_get_uint() {
4391    dbi_result result;
4392 
4393    result = dbi_conn_query(conn, "SELECT the_ulong from test_datatypes");
4394    ASSERT_RESULT
4395 
4396    while (dbi_result_next_row(result)) {
4397       errmsg = NULL;
4398       unsigned int the_uint = 0;
4399 
4400       the_uint = dbi_result_get_uint(result, "the_ulong");
4401 
4402       assert_equal(the_uint, expect_ulonglong_from_name("the_ulong", cinfo.drivername));
4403 
4404    }
4405 
4406    dbi_result_free(result);
4407 }
4408 
test_dbi_result_get_longlong()4409 Ensure test_dbi_result_get_longlong() {
4410    dbi_result result;
4411 
4412    result = dbi_conn_query(conn, "SELECT the_longlong from test_datatypes");
4413    ASSERT_RESULT
4414 
4415    while (dbi_result_next_row(result)) {
4416       errmsg = NULL;
4417       long long the_longlong = 0;
4418 
4419       the_longlong = dbi_result_get_longlong(result, "the_longlong");
4420 
4421       assert_equal(the_longlong, expect_longlong_from_name("the_longlong", cinfo.drivername));
4422 
4423    }
4424 
4425    dbi_result_free(result);
4426 }
4427 
test_dbi_result_get_ulonglong()4428 Ensure test_dbi_result_get_ulonglong() {
4429    dbi_result result;
4430 
4431    result = dbi_conn_query(conn, "SELECT the_ulonglong from test_datatypes");
4432    ASSERT_RESULT
4433 
4434    while (dbi_result_next_row(result)) {
4435       errmsg = NULL;
4436       unsigned long long the_ulonglong = 0;
4437 
4438       the_ulonglong = dbi_result_get_ulonglong(result, "the_ulonglong");
4439 
4440       assert_equal(the_ulonglong, expect_ulonglong_from_name("the_ulonglong", cinfo.drivername));
4441 
4442    }
4443 
4444    dbi_result_free(result);
4445 }
4446 
test_dbi_result_get_float()4447 Ensure test_dbi_result_get_float() {
4448    dbi_result result;
4449 
4450    result = dbi_conn_query(conn, "SELECT the_float from test_datatypes");
4451    ASSERT_RESULT
4452 
4453    while (dbi_result_next_row(result)) {
4454       errmsg = NULL;
4455       float the_float = 0;
4456 
4457       the_float = dbi_result_get_float(result, "the_float");
4458 
4459       assert_equal(the_float, expect_double_from_name("the_float", cinfo.drivername));
4460 
4461    }
4462 
4463    dbi_result_free(result);
4464 }
4465 
test_dbi_result_get_double()4466 Ensure test_dbi_result_get_double() {
4467    dbi_result result;
4468 
4469    result = dbi_conn_query(conn, "SELECT the_double from test_datatypes");
4470    ASSERT_RESULT
4471 
4472    while (dbi_result_next_row(result)) {
4473       errmsg = NULL;
4474       double the_double = 0;
4475 
4476       the_double = dbi_result_get_double(result, "the_double");
4477 
4478       assert_equal(the_double, expect_double_from_name("the_double", cinfo.drivername));
4479 
4480    }
4481 
4482    dbi_result_free(result);
4483 }
4484 
test_dbi_result_get_string()4485 Ensure test_dbi_result_get_string() {
4486    dbi_result result;
4487 
4488    result = dbi_conn_query(conn, "SELECT the_conn_quoted_string, the_conn_escaped_string,"
4489          "the_null_string, the_empty_string from test_datatypes");
4490    ASSERT_RESULT
4491 
4492    while (dbi_result_next_row(result)) {
4493       errmsg = NULL;
4494       const char* the_quoted_string;
4495       const char* the_escaped_string;
4496       const char* the_null_string;
4497       const char* the_empty_string;
4498 
4499       the_quoted_string = dbi_result_get_string(result, "the_conn_quoted_string");
4500       assert_string_equal(the_quoted_string, expect_as_string_from_name("the_conn_quoted_string", cinfo.drivername));
4501 
4502       the_escaped_string = dbi_result_get_string(result, "the_conn_escaped_string");
4503       assert_string_equal(the_escaped_string, expect_as_string_from_name("the_conn_escaped_string", cinfo.drivername));
4504 
4505       the_null_string = dbi_result_get_string(result, "the_null_string");
4506       assert_string_equal(the_null_string, expect_string_from_name("the_null_string", cinfo.drivername));
4507 
4508       the_empty_string = dbi_result_get_string(result, "the_empty_string");
4509       assert_string_equal(the_empty_string, expect_as_string_from_name("the_empty_string", cinfo.drivername));
4510 
4511    }
4512 
4513    dbi_result_free(result);
4514 }
4515 
test_dbi_result_get_string_copy()4516 Ensure test_dbi_result_get_string_copy() {
4517    dbi_result result;
4518 
4519    result = dbi_conn_query(conn, "SELECT the_conn_quoted_string_copy, the_conn_escaped_string_copy"
4520          " from test_datatypes");
4521    ASSERT_RESULT
4522 
4523    while (dbi_result_next_row(result)) {
4524       errmsg = NULL;
4525       const char* the_quoted_string_copy;
4526       const char* the_escaped_string_copy;
4527 
4528       the_quoted_string_copy = dbi_result_get_string_copy(result, "the_conn_quoted_string_copy");
4529       assert_string_equal(the_quoted_string_copy, expect_as_string_from_name("the_conn_quoted_string_copy", cinfo.drivername));
4530 
4531       the_escaped_string_copy = dbi_result_get_string_copy(result, "the_conn_escaped_string_copy");
4532       assert_string_equal(the_escaped_string_copy, expect_as_string_from_name("the_conn_escaped_string_copy", cinfo.drivername));
4533 
4534    }
4535 
4536    dbi_result_free(result);
4537 }
4538 
test_dbi_result_get_binary()4539 Ensure test_dbi_result_get_binary() {
4540    dbi_result result;
4541 
4542    result = dbi_conn_query(conn, "SELECT the_binary_quoted_string from test_datatypes");
4543    ASSERT_RESULT
4544 
4545    while (dbi_result_next_row(result)) {
4546       errmsg = NULL;
4547       const unsigned char* the_binary;
4548 
4549       the_binary = dbi_result_get_binary(result, "the_binary_quoted_string");
4550 
4551       assert_equal(65, the_binary[0]);
4552       assert_equal(66, the_binary[1]);
4553       assert_equal(0,  the_binary[2]);
4554       assert_equal(67, the_binary[3]);
4555       assert_equal(39, the_binary[4]);
4556       assert_equal(68, the_binary[5]);
4557    }
4558 
4559    dbi_result_free(result);
4560 }
4561 
test_dbi_result_get_binary_copy()4562 Ensure test_dbi_result_get_binary_copy() {
4563    dbi_result result;
4564 
4565    result = dbi_conn_query(conn, "SELECT the_binary_escaped_string from test_datatypes");
4566    ASSERT_RESULT
4567 
4568    while (dbi_result_next_row(result)) {
4569       errmsg = NULL;
4570       unsigned char* the_binary_copy = NULL;
4571 
4572       the_binary_copy = dbi_result_get_binary_copy(result, "the_binary_escaped_string");
4573 
4574       assert_equal(65, the_binary_copy[0]);
4575       assert_equal(66, the_binary_copy[1]);
4576       assert_equal(0, the_binary_copy[2]);
4577       assert_equal(67, the_binary_copy[3]);
4578       assert_equal(39, the_binary_copy[4]);
4579       assert_equal(68, the_binary_copy[5]);
4580 
4581    }
4582 
4583    dbi_result_free(result);
4584 }
4585 
test_dbi_result_get_datetime()4586 Ensure test_dbi_result_get_datetime() {
4587    dbi_result result;
4588 
4589    result = dbi_conn_query(conn, "SELECT the_datetime, the_date, the_time from test_datatypes");
4590    ASSERT_RESULT
4591 
4592    while (dbi_result_next_row(result)) {
4593       errmsg = NULL;
4594       time_t the_datetime = 0;
4595       time_t the_date = 0;
4596       time_t the_time = 0;
4597 
4598       the_datetime = dbi_result_get_datetime(result, "the_datetime");
4599       assert_equal( the_datetime, expect_longlong_from_name("the_datetime", cinfo.drivername));
4600 
4601       if(!strcmp(cinfo.drivername, "msql")) {
4602          the_date = dbi_result_get_string(result, "the_date");
4603          assert_string_equal(the_date, "11-jul-1977");
4604 
4605          the_time = dbi_result_get_string(result, "the_time");
4606          assert_string_equal(the_time, "23:59:59");
4607       }
4608       else {
4609          the_date = dbi_result_get_datetime(result, "the_date");
4610          assert_equal(the_date, expect_longlong_from_name("the_date", cinfo.drivername));
4611 
4612          the_time = dbi_result_get_datetime(result, "the_time");
4613          assert_equal(the_time, expect_longlong_from_name("the_time", cinfo.drivername));
4614       }
4615    }
4616 
4617    dbi_result_free(result);
4618 
4619 }
4620 
test_dbi_result_get_datetime_tz()4621 Ensure test_dbi_result_get_datetime_tz() {
4622    dbi_result result;
4623 
4624    result = dbi_conn_query(conn, "SELECT the_datetime_tz from test_datatypes");
4625    ASSERT_RESULT
4626 
4627    while (dbi_result_next_row(result)) {
4628       errmsg = NULL;
4629       time_t the_datetime_tz = 0;
4630 
4631       the_datetime_tz = dbi_result_get_datetime(result, "the_datetime_tz");
4632 
4633       assert_equal( the_datetime_tz, expect_longlong_from_name("the_datetime_tz", cinfo.drivername));
4634 
4635    }
4636 
4637    dbi_result_free(result);
4638 }
4639 
test_dbi_result_get_datetime_time_tz()4640 Ensure test_dbi_result_get_datetime_time_tz() {
4641    dbi_result result;
4642 
4643    result = dbi_conn_query(conn, "SELECT the_datetime_tz, the_time_tz from test_datatypes");
4644    ASSERT_RESULT
4645 
4646 
4647    while (dbi_result_next_row(result)) {
4648       errmsg = NULL;
4649       time_t the_datetime_tz = 0;
4650       time_t the_time_dt_tz = 0;
4651 
4652       the_datetime_tz = dbi_result_get_datetime(result, "the_datetime_tz");
4653       the_time_dt_tz = dbi_result_get_datetime(result, "the_time_tz");
4654 
4655       assert_equal( the_datetime_tz, expect_longlong_from_name("the_datetime_tz", cinfo.drivername));
4656       assert_equal( the_time_dt_tz, expect_longlong_from_name("the_time_tz", cinfo.drivername));
4657 
4658    }
4659 
4660    dbi_result_free(result);
4661 
4662 }
4663 
test_dbi_result_get_field_type_mismatch()4664 Ensure test_dbi_result_get_field_type_mismatch() {
4665    dbi_result result;
4666 
4667    result = dbi_conn_query(conn, "SELECT the_long from test_datatypes");
4668    ASSERT_RESULT
4669 
4670    while (dbi_result_next_row(result)) {
4671       errmsg = NULL;
4672       dbi_error_flag errflag;
4673 
4674       dbi_result_get_string(result, "the_long");
4675       errflag = dbi_conn_error(dbi_result_get_conn(result), &errmsg);
4676       assert_equal( errflag, DBI_ERROR_BADTYPE);
4677 
4678    }
4679 
4680    dbi_result_free(result);
4681 }
4682 
test_dbi_result_get_field_bad_name()4683 Ensure test_dbi_result_get_field_bad_name() {
4684    dbi_result result;
4685 
4686    result = dbi_conn_query(conn, "SELECT the_nonexistent from test_datatypes");
4687    ASSERT_RESULT
4688 
4689    while (dbi_result_next_row(result)) {
4690       errmsg = NULL;
4691       dbi_error_flag errflag;
4692 
4693       dbi_result_get_string(result, "the_nonexistent");
4694       errflag = dbi_conn_error(dbi_result_get_conn(result), &errmsg);
4695       assert_equal( errflag, DBI_ERROR_BADNAME);
4696 
4697    }
4698 
4699    dbi_result_free(result);
4700 }
4701 
test_dbi_result_get_fields()4702 Ensure test_dbi_result_get_fields() {
4703    dbi_result result;
4704    char *query_string = NULL;
4705    int numfields;
4706 
4707    if ((query_string = assemble_query_string(cinfo.drivername, &numfields)) == NULL) {
4708       /* todo: make noise */
4709       return;
4710    }
4711 
4712    result = dbi_conn_query(conn, query_string);
4713 
4714    ASSERT_RESULT
4715 
4716    while (dbi_result_next_row(result)) {
4717       errmsg = NULL;
4718       unsigned int num;
4719       signed char the_char = 0;
4720       unsigned char the_uchar = 0;
4721       signed short the_short = 0;
4722       unsigned short the_ushort = 0;
4723       signed int the_long = 0;
4724       unsigned int the_ulong = 0;
4725       signed long long the_longlong = 0;
4726       unsigned long long the_ulonglong = 0;
4727       float the_float = 0;
4728       double the_double = 0;
4729       const char* the_conn_quoted_string = NULL;
4730       unsigned short type_expected = 0;
4731 
4732       type_expected = field_attrib_from_index(0 /* the_char */, cinfo.drivername);
4733 
4734       num = dbi_result_get_fields(result,
4735 				  "the_char.%c the_uchar.%uc "
4736 				  "the_short.%h the_ushort.%uh "
4737 				  "the_long.%l the_ulong.%ul "
4738 				  "the_longlong.%L the_ulonglong.%uL "
4739 				  "the_float.%f the_double.%d "
4740 				  "the_conn_quoted_string.%s",
4741 				  &the_char, &the_uchar,
4742 				  &the_short, &the_ushort,
4743 				  &the_long, &the_ulong,
4744 				  &the_longlong, &the_ulonglong,
4745 				  &the_float, &the_double,
4746 				  &the_conn_quoted_string);
4747 
4748 
4749       if (type_expected == 2) { /* skip test for db engines which do not support a true one-byte char type */
4750 	assert_equal(the_char, expect_longlong_from_name("the_char", cinfo.drivername));
4751 	assert_equal(the_uchar, expect_ulonglong_from_name("the_uchar", cinfo.drivername));
4752       }
4753 
4754       assert_equal(the_short, expect_longlong_from_name("the_short", cinfo.drivername));
4755       assert_equal(the_ushort, expect_ulonglong_from_name("the_ushort", cinfo.drivername));
4756 
4757       assert_equal(the_long, expect_longlong_from_name("the_long", cinfo.drivername));
4758       assert_equal(the_ulong, expect_ulonglong_from_name("the_ulong", cinfo.drivername));
4759 
4760       assert_equal(the_longlong, expect_longlong_from_name("the_longlong", cinfo.drivername));
4761       assert_equal(the_ulonglong, expect_ulonglong_from_name("the_ulonglong", cinfo.drivername));
4762 
4763       assert_double_equal(the_float, expect_double_from_name("the_float", cinfo.drivername));
4764 
4765       assert_double_equal(the_double, expect_double_from_name("the_double", cinfo.drivername));
4766 
4767       assert_string_equal(the_conn_quoted_string,  expect_string_from_name("the_conn_quoted_string", cinfo.drivername));
4768 
4769    }
4770 
4771    dbi_result_free(result);
4772 
4773 }
4774 
test_dbi_result_bind_char()4775 Ensure test_dbi_result_bind_char() {
4776    dbi_result result;
4777    signed char the_char;
4778    int bind;
4779    unsigned short type_expected = 0;
4780 
4781    type_expected = field_attrib_from_index(0 /* the_char */, cinfo.drivername);
4782 
4783    if (type_expected == 2) { /* skip test for db engines which do not support a true one-byte char type */
4784      result = dbi_conn_query(conn, "SELECT the_char from test_datatypes");
4785      ASSERT_RESULT
4786 
4787        bind = dbi_result_bind_char(result, "the_char", &the_char);
4788      assert_equal(bind, 0);
4789 
4790      while (dbi_result_next_row(result)) {
4791        errmsg = NULL;
4792 
4793        assert_equal(the_char, expect_longlong_from_name("the_char", cinfo.drivername));
4794 
4795      }
4796 
4797      dbi_result_free(result);
4798    }
4799 }
4800 
test_dbi_result_bind_uchar()4801 Ensure test_dbi_result_bind_uchar() {
4802    dbi_result result;
4803    unsigned char the_uchar;
4804    int bind;
4805    unsigned short type_expected = 0;
4806 
4807    type_expected = field_attrib_from_index(0 /* the_char */, cinfo.drivername);
4808 
4809    if (type_expected == 2) { /* skip test for db engines which do not support a true one-byte char type */
4810      result = dbi_conn_query(conn, "SELECT the_uchar from test_datatypes");
4811      ASSERT_RESULT
4812 
4813        bind = dbi_result_bind_uchar(result, "the_uchar", &the_uchar);
4814      assert_equal(bind, 0);
4815 
4816      while (dbi_result_next_row(result)) {
4817        errmsg = NULL;
4818 
4819        assert_equal(the_uchar, expect_ulonglong_from_name("the_uchar", cinfo.drivername));
4820 
4821      }
4822 
4823      dbi_result_free(result);
4824    }
4825 }
4826 
test_dbi_result_bind_short()4827 Ensure test_dbi_result_bind_short() {
4828    dbi_result result;
4829    short the_short;
4830    int bind;
4831 
4832    result = dbi_conn_query(conn, "SELECT the_short from test_datatypes");
4833    ASSERT_RESULT
4834 
4835    bind = dbi_result_bind_short(result, "the_short", &the_short);
4836    assert_equal(bind, 0);
4837 
4838    while (dbi_result_next_row(result)) {
4839       errmsg = NULL;
4840 
4841       assert_equal(the_short, expect_longlong_from_name("the_short", cinfo.drivername));
4842 
4843    }
4844 
4845    dbi_result_free(result);
4846 }
4847 
test_dbi_result_bind_ushort()4848 Ensure test_dbi_result_bind_ushort() {
4849    dbi_result result;
4850    unsigned short the_ushort;
4851    int bind;
4852 
4853    result = dbi_conn_query(conn, "SELECT the_ushort from test_datatypes");
4854    ASSERT_RESULT
4855 
4856    bind = dbi_result_bind_ushort(result, "the_ushort", &the_ushort);
4857    assert_equal(bind, 0);
4858 
4859    while (dbi_result_next_row(result)) {
4860       errmsg = NULL;
4861 
4862       assert_equal(the_ushort, expect_ulonglong_from_name("the_ushort", cinfo.drivername));
4863 
4864    }
4865 
4866    dbi_result_free(result);
4867 }
4868 
test_dbi_result_bind_int()4869 Ensure test_dbi_result_bind_int() {
4870    dbi_result result;
4871    int the_int;
4872    int bind;
4873 
4874    result = dbi_conn_query(conn, "SELECT the_long from test_datatypes");
4875    ASSERT_RESULT
4876 
4877    bind = dbi_result_bind_int(result, "the_long", &the_int);
4878    assert_equal(bind, 0);
4879 
4880    while (dbi_result_next_row(result)) {
4881       errmsg = NULL;
4882 
4883       assert_equal(the_int, expect_longlong_from_name("the_long", cinfo.drivername));
4884 
4885    }
4886 
4887    dbi_result_free(result);
4888 }
4889 
test_dbi_result_bind_uint()4890 Ensure test_dbi_result_bind_uint() {
4891    dbi_result result;
4892    unsigned int the_uint;
4893    int bind;
4894 
4895    result = dbi_conn_query(conn, "SELECT the_ulong from test_datatypes");
4896    ASSERT_RESULT
4897 
4898    bind = dbi_result_bind_uint(result, "the_ulong", &the_uint);
4899    assert_equal(bind, 0);
4900 
4901    while (dbi_result_next_row(result)) {
4902       errmsg = NULL;
4903 
4904       assert_equal(the_uint, expect_ulonglong_from_name("the_ulong", cinfo.drivername));
4905 
4906    }
4907 
4908    dbi_result_free(result);
4909 }
4910 
test_dbi_result_bind_longlong()4911 Ensure test_dbi_result_bind_longlong() {
4912    dbi_result result;
4913    long long the_longlong;
4914    int bind;
4915 
4916    result = dbi_conn_query(conn, "SELECT the_longlong from test_datatypes");
4917    ASSERT_RESULT
4918 
4919    bind = dbi_result_bind_longlong(result, "the_longlong", &the_longlong);
4920    assert_equal(bind, 0);
4921 
4922    while (dbi_result_next_row(result)) {
4923       errmsg = NULL;
4924 
4925       assert_equal(the_longlong, expect_longlong_from_name("the_longlong", cinfo.drivername));
4926 
4927    }
4928 
4929    dbi_result_free(result);
4930 }
4931 
test_dbi_result_bind_ulonglong()4932 Ensure test_dbi_result_bind_ulonglong() {
4933    dbi_result result;
4934    unsigned long long the_ulonglong;
4935    int bind;
4936 
4937    result = dbi_conn_query(conn, "SELECT the_ulonglong from test_datatypes");
4938    ASSERT_RESULT
4939 
4940    bind = dbi_result_bind_ulonglong(result, "the_ulonglong", &the_ulonglong);
4941    assert_equal(bind, 0);
4942 
4943    while (dbi_result_next_row(result)) {
4944       errmsg = NULL;
4945 
4946       assert_equal(the_ulonglong, expect_ulonglong_from_name("the_ulonglong", cinfo.drivername));
4947 
4948    }
4949 
4950    dbi_result_free(result);
4951 }
4952 
test_dbi_result_bind_float()4953 Ensure test_dbi_result_bind_float() {
4954    dbi_result result;
4955    float the_float;
4956    int bind;
4957 
4958    result = dbi_conn_query(conn, "SELECT the_float from test_datatypes");
4959    ASSERT_RESULT
4960 
4961    bind = dbi_result_bind_float(result, "the_float", &the_float);
4962    assert_equal(bind, 0);
4963 
4964    while (dbi_result_next_row(result)) {
4965       errmsg = NULL;
4966 
4967       assert_double_equal(the_float, expect_double_from_name("the_float", cinfo.drivername));
4968 
4969    }
4970 
4971    dbi_result_free(result);
4972 }
4973 
test_dbi_result_bind_double()4974 Ensure test_dbi_result_bind_double() {
4975    dbi_result result;
4976    double the_double;
4977    int bind;
4978 
4979    result = dbi_conn_query(conn, "SELECT the_double from test_datatypes");
4980    ASSERT_RESULT
4981 
4982    bind = dbi_result_bind_double(result, "the_double", &the_double);
4983    assert_equal(bind, 0);
4984 
4985    while (dbi_result_next_row(result)) {
4986       errmsg = NULL;
4987 
4988       assert_double_equal(the_double, expect_double_from_name("the_double", cinfo.drivername));
4989 
4990    }
4991 
4992    dbi_result_free(result);
4993 }
4994 
test_dbi_result_bind_string()4995 Ensure test_dbi_result_bind_string() {
4996    dbi_result result;
4997    const char* the_quoted_string;
4998    const char* the_null_string;
4999    const char* the_escaped_string;
5000    const char* the_empty_string;
5001    int bind;
5002 
5003    result = dbi_conn_query(conn, "SELECT the_null_string, the_conn_escaped_string, the_empty_string,"
5004          " the_conn_quoted_string from test_datatypes");
5005    ASSERT_RESULT
5006 
5007    bind = dbi_result_bind_string(result, "the_conn_quoted_string", &the_quoted_string);
5008    assert_equal(bind, 0);
5009 
5010    bind = dbi_result_bind_string(result, "the_null_string", &the_null_string);
5011    assert_equal(bind, 0);
5012 
5013    bind = dbi_result_bind_string(result, "the_conn_escaped_string", &the_escaped_string);
5014    assert_equal(bind, 0);
5015 
5016    bind = dbi_result_bind_string(result, "the_empty_string", &the_empty_string);
5017    assert_equal(bind, 0);
5018 
5019    while (dbi_result_next_row(result)) {
5020       errmsg = NULL;
5021 
5022       assert_string_equal(the_quoted_string, expect_string_from_name("the_conn_quoted_string", cinfo.drivername));
5023 
5024       assert_string_equal(the_null_string, expect_string_from_name("the_null_string", cinfo.drivername));
5025 
5026       assert_string_equal(the_escaped_string, expect_string_from_name("the_conn_escaped_string", cinfo.drivername));
5027 
5028       assert_string_equal(the_empty_string, expect_string_from_name("the_empty_string", cinfo.drivername));
5029 
5030    }
5031 
5032    dbi_result_free(result);
5033 }
5034 
test_dbi_result_bind_string_copy()5035 Ensure test_dbi_result_bind_string_copy() {
5036    dbi_result result;
5037    char* the_quoted_string_copy;
5038    char* the_escaped_string_copy;
5039    int bind;
5040 
5041    result = dbi_conn_query(conn, "SELECT the_conn_quoted_string_copy, the_conn_escaped_string_copy"
5042          " from test_datatypes");
5043    ASSERT_RESULT
5044 
5045    bind = dbi_result_bind_string_copy(result, "the_conn_quoted_string_copy", &the_quoted_string_copy);
5046    assert_equal(bind, 0);
5047 
5048    bind = dbi_result_bind_string_copy(result, "the_conn_escaped_string_copy", &the_escaped_string_copy);
5049    assert_equal(bind, 0);
5050 
5051    while (dbi_result_next_row(result)) {
5052       errmsg = NULL;
5053 
5054       assert_string_equal(the_quoted_string_copy, expect_string_from_name("the_conn_quoted_string_copy", cinfo.drivername));
5055 
5056       assert_string_equal(the_escaped_string_copy, expect_string_from_name("the_conn_escaped_string_copy", cinfo.drivername));
5057 
5058    }
5059 
5060    dbi_result_free(result);
5061 }
5062 
test_dbi_result_bind_binary()5063 Ensure test_dbi_result_bind_binary() {
5064    dbi_result result;
5065    const unsigned char* the_quoted_binary;
5066    int bind;
5067 
5068    result = dbi_conn_query(conn, "SELECT the_binary_quoted_string from test_datatypes");
5069    ASSERT_RESULT
5070 
5071    bind = dbi_result_bind_binary(result, "the_binary_quoted_string", &the_quoted_binary);
5072    assert_equal(bind, 0);
5073 
5074    while (dbi_result_next_row(result)) {
5075       errmsg = NULL;
5076 
5077       assert_equal(65, the_quoted_binary[0]);
5078       assert_equal(66, the_quoted_binary[1]);
5079       assert_equal(0,  the_quoted_binary[2]);
5080       assert_equal(67, the_quoted_binary[3]);
5081       assert_equal(39, the_quoted_binary[4]);
5082       assert_equal(68, the_quoted_binary[5]);
5083    }
5084 
5085    dbi_result_free(result);
5086 }
5087 
test_dbi_result_bind_binary_copy()5088 Ensure test_dbi_result_bind_binary_copy() {
5089    dbi_result result;
5090    unsigned char* the_escaped_binary_copy;
5091    int bind;
5092 
5093    result = dbi_conn_query(conn, "SELECT the_binary_escaped_string from test_datatypes");
5094    ASSERT_RESULT
5095 
5096    bind = dbi_result_bind_binary_copy(result, "the_binary_escaped_string", &the_escaped_binary_copy);
5097    assert_equal(bind, 0);
5098 
5099    while (dbi_result_next_row(result)) {
5100       errmsg = NULL;
5101 
5102       assert_equal(65, the_escaped_binary_copy[0]);
5103       assert_equal(66, the_escaped_binary_copy[1]);
5104       assert_equal(0,  the_escaped_binary_copy[2]);
5105       assert_equal(67, the_escaped_binary_copy[3]);
5106       assert_equal(39, the_escaped_binary_copy[4]);
5107       assert_equal(68, the_escaped_binary_copy[5]);
5108    }
5109 
5110    dbi_result_free(result);
5111 }
5112 
test_dbi_result_bind_datetime()5113 Ensure test_dbi_result_bind_datetime() {
5114    dbi_result result;
5115    time_t the_datetime = 0;
5116    time_t the_date_dt = 0;
5117    time_t the_time_dt = 0;
5118    const char *the_date;
5119    const char *the_time;
5120    int bind;
5121 
5122    result = dbi_conn_query(conn, "SELECT the_datetime, the_date, the_time from test_datatypes");
5123    ASSERT_RESULT
5124 
5125    bind = dbi_result_bind_datetime(result, "the_datetime", &the_datetime);
5126    assert_equal(bind, 0);
5127 
5128    bind = dbi_result_bind_datetime(result, "the_date", &the_date_dt);
5129    assert_equal(bind, 0);
5130    bind = dbi_result_bind_datetime(result, "the_time", &the_time_dt);
5131    assert_equal(bind, 0);
5132 
5133    while (dbi_result_next_row(result)) {
5134       errmsg = NULL;
5135 
5136       assert_equal(the_datetime, expect_longlong_from_name("the_datetime", cinfo.drivername));
5137 
5138       if(!strcmp(cinfo.drivername, "msql")) {
5139 
5140          assert_string_equal(the_date, "11-jul-1977");
5141 
5142          assert_string_equal(the_time, "23:59:59");
5143       }
5144       else {
5145 
5146          assert_equal(the_date_dt, expect_longlong_from_name("the_date", cinfo.drivername));
5147 
5148          assert_equal(the_time_dt, expect_longlong_from_name("the_time", cinfo.drivername));
5149       }
5150    }
5151 
5152    dbi_result_free(result);
5153 
5154 }
5155 
test_dbi_result_bind_datetime_tz()5156 Ensure test_dbi_result_bind_datetime_tz() {
5157    dbi_result result;
5158    time_t the_datetime_tz = 0;
5159    int bind;
5160 
5161    result = dbi_conn_query(conn, "SELECT the_datetime_tz from test_datatypes");
5162    ASSERT_RESULT
5163 
5164    bind = dbi_result_bind_datetime(result, "the_datetime_tz", &the_datetime_tz);
5165    assert_equal(bind, 0);
5166 
5167    while (dbi_result_next_row(result)) {
5168       errmsg = NULL;
5169 
5170       assert_equal(the_datetime_tz, expect_longlong_from_name("the_datetime_tz", cinfo.drivername));
5171 
5172    }
5173 
5174    dbi_result_free(result);
5175 }
5176 
test_dbi_result_bind_datetime_time_tz()5177 Ensure test_dbi_result_bind_datetime_time_tz() {
5178    dbi_result result;
5179    time_t the_datetime_tz = 0;
5180    time_t the_time_dt_tz = 0;
5181    int bind;
5182 
5183    result = dbi_conn_query(conn, "SELECT the_datetime_tz, the_time_tz from test_datatypes");
5184    ASSERT_RESULT
5185 
5186    bind = dbi_result_bind_datetime(result, "the_datetime_tz", &the_datetime_tz);
5187    assert_equal(bind, 0);
5188 
5189    bind = dbi_result_bind_datetime(result, "the_time_tz", &the_time_dt_tz);
5190    assert_equal(bind, 0);
5191 
5192    while (dbi_result_next_row(result)) {
5193       errmsg = NULL;
5194 
5195       assert_equal(the_datetime_tz, expect_longlong_from_name("the_datetime_tz", cinfo.drivername));
5196       assert_equal(the_time_dt_tz, expect_longlong_from_name("the_time_tz", cinfo.drivername));
5197 
5198    }
5199 
5200    dbi_result_free(result);
5201 
5202 }
5203 
test_dbi_result_bind_fields()5204 Ensure test_dbi_result_bind_fields() {
5205    dbi_result result;
5206    char *query_string;
5207    int bind;
5208    int numfields;
5209    unsigned int num;
5210    signed char the_char = 0;
5211    unsigned char the_uchar = 0;
5212    signed short the_short = 0;
5213    unsigned short the_ushort = 0;
5214    signed int the_long = 0;
5215    unsigned int the_ulong = 0;
5216    signed long long the_longlong = 0;
5217    unsigned long long the_ulonglong = 0;
5218    float the_float = 0;
5219    double the_double = 0;
5220    const char* the_conn_quoted_string = NULL;
5221 
5222    query_string = assemble_query_string(cinfo.drivername, &numfields);
5223 
5224    result = dbi_conn_query(conn, query_string);
5225 
5226    ASSERT_RESULT
5227 
5228    free(query_string);
5229 
5230    bind = dbi_result_bind_fields(result, "the_char.%c the_uchar.%uc the_short.%h the_ushort.%uh the_long.%l the_ulong.%ul "
5231          "the_longlong.%L the_ulonglong.%uL the_float.%f the_double.%d the_conn_quoted_string.%s",
5232          &the_char, &the_uchar, &the_short, &the_ushort, &the_long, &the_ulong, &the_longlong, &the_ulonglong,
5233          &the_float, &the_double, &the_conn_quoted_string);
5234    assert_equal(bind, 11);
5235 
5236    while (dbi_result_next_row(result)) {
5237      unsigned short type_expected = 0;
5238 
5239      type_expected = field_attrib_from_index(0 /* the_char */, cinfo.drivername);
5240 
5241      if (type_expected == 2) { /* skip test for db engines which do not support a true one-byte char type */
5242        assert_equal(the_char, expect_longlong_from_name("the_char", cinfo.drivername));
5243 
5244        assert_equal(the_uchar, expect_ulonglong_from_name("the_uchar", cinfo.drivername));
5245      }
5246 
5247       assert_equal(the_short, expect_longlong_from_name("the_short", cinfo.drivername));
5248 
5249       assert_equal(the_long, expect_longlong_from_name("the_long", cinfo.drivername));
5250 
5251       assert_equal(the_ulong, expect_ulonglong_from_name("the_ulong", cinfo.drivername));
5252 
5253       assert_equal(the_longlong, expect_longlong_from_name("the_longlong", cinfo.drivername));
5254 
5255       assert_equal(the_ulonglong, expect_ulonglong_from_name("the_ulonglong", cinfo.drivername));
5256 
5257       assert_double_equal(the_float, expect_double_from_name("the_float", cinfo.drivername));
5258 
5259       assert_string_equal(the_conn_quoted_string,  expect_as_string_from_name("the_conn_quoted_string", cinfo.drivername));
5260 
5261    }
5262 
5263    dbi_result_free(result);
5264 
5265 }
5266 
test_dbi_result_get_field_length()5267 Ensure test_dbi_result_get_field_length() {
5268    dbi_result result;
5269    char *query_string;
5270    int numfields;
5271 
5272    query_string = assemble_query_string(cinfo.drivername, &numfields);
5273 
5274    result = dbi_conn_query(conn, query_string);
5275 
5276    ASSERT_RESULT
5277 
5278    free(query_string);
5279 
5280    while (dbi_result_next_row(result)) {
5281       errmsg = NULL;
5282       unsigned int length = 0;
5283 
5284       length = dbi_result_get_field_length(result, "the_conn_quoted_string");
5285       assert_equal(length, field_length_from_name("the_conn_quoted_string", cinfo.drivername));
5286 
5287       length = dbi_result_get_field_length(result, "the_conn_quoted_string_copy");
5288       assert_equal(length, field_length_from_name("the_conn_quoted_string_copy", cinfo.drivername));
5289 
5290       length = dbi_result_get_field_length(result, "the_conn_escaped_string");
5291       assert_equal(length, field_length_from_name("the_conn_escaped_string", cinfo.drivername));
5292 
5293       length = dbi_result_get_field_length(result, "the_conn_escaped_string_copy");
5294       assert_equal(length, field_length_from_name("the_conn_escaped_string_copy", cinfo.drivername));
5295 
5296       length = dbi_result_get_field_length(result, "the_null_string");
5297       assert_equal(length, field_length_from_name("the_null_string", cinfo.drivername));
5298 
5299       length = dbi_result_get_field_length(result, "the_numstring");
5300       assert_equal(length, field_length_from_name("the_numstring", cinfo.drivername));
5301 
5302       length = dbi_result_get_field_length(result, "the_empty_string");
5303       assert_equal(length, field_length_from_name("the_empty_string", cinfo.drivername));
5304 
5305       length = dbi_result_get_field_length(result, "the_binary_quoted_string");
5306       assert_equal(length, field_length_from_name("the_binary_quoted_string", cinfo.drivername));
5307 
5308       length = dbi_result_get_field_length(result, "the_binary_escaped_string");
5309       assert_equal(length, field_length_from_name("the_binary_escaped_string", cinfo.drivername));
5310 
5311    }
5312 
5313    dbi_result_free(result);
5314 }
5315 
test_dbi_result_get_field_length_idx()5316 Ensure test_dbi_result_get_field_length_idx() {
5317    dbi_result result;
5318    char *query_string;
5319    int numfields;
5320 
5321    query_string = assemble_query_string(cinfo.drivername, &numfields);
5322 
5323    result = dbi_conn_query(conn, query_string);
5324 
5325    ASSERT_RESULT
5326 
5327    while (dbi_result_next_row(result)) {
5328       unsigned int length = 0;
5329 
5330       length = dbi_result_get_field_length_idx(result, 1);
5331       assert_equal(length, field_length_from_index(1, cinfo.drivername));
5332 
5333       length = dbi_result_get_field_length_idx(result, 2);
5334       assert_equal(length, field_length_from_index(2, cinfo.drivername));
5335 
5336       length = dbi_result_get_field_length_idx(result, 3);
5337       assert_equal(length, field_length_from_index(3, cinfo.drivername));
5338 
5339       length = dbi_result_get_field_length_idx(result, 4);
5340       assert_equal(length, field_length_from_index(4, cinfo.drivername));
5341 
5342       length = dbi_result_get_field_length_idx(result, 5);
5343       assert_equal(length, field_length_from_index(5, cinfo.drivername));
5344 
5345       length = dbi_result_get_field_length_idx(result, 6);
5346       assert_equal(length, field_length_from_index(6, cinfo.drivername));
5347 
5348       length = dbi_result_get_field_length_idx(result, 7);
5349       assert_equal(length, field_length_from_index(7, cinfo.drivername));
5350 
5351       length = dbi_result_get_field_length_idx(result, 8);
5352       assert_equal(length, field_length_from_index(8, cinfo.drivername));
5353 
5354       length = dbi_result_get_field_length_idx(result, 9);
5355       assert_equal(length, field_length_from_index(9, cinfo.drivername));
5356 
5357    }
5358 
5359    dbi_result_free(result);
5360 }
5361 
test_dbi_result_get_field_idx()5362 Ensure test_dbi_result_get_field_idx() {
5363    dbi_result result;
5364    char *query_string;
5365    int numfields;
5366 
5367    query_string = assemble_query_string(cinfo.drivername, &numfields);
5368 
5369    result = dbi_conn_query(conn, query_string);
5370 
5371    ASSERT_RESULT
5372 
5373    free(query_string);
5374 
5375    while (dbi_result_next_row(result)) {
5376       errmsg = NULL;
5377       unsigned int idx = 0;
5378 
5379       idx = dbi_result_get_field_idx(result, "the_numstring");
5380       assert_equal(idx, field_index_from_name("the_numstring", cinfo.drivername));
5381    }
5382 
5383    dbi_result_free(result);
5384 }
5385 
test_dbi_result_get_field_name()5386 Ensure test_dbi_result_get_field_name() {
5387    dbi_result result;
5388    char *query_string;
5389    int numfields;
5390 
5391    query_string = assemble_query_string(cinfo.drivername, &numfields);
5392 
5393    result = dbi_conn_query(conn, query_string);
5394 
5395    ASSERT_RESULT
5396 
5397    free(query_string);
5398 
5399    while (dbi_result_next_row(result)) {
5400       errmsg = NULL;
5401       const char *name;
5402 
5403       name = dbi_result_get_field_name(result, 15);
5404 
5405       if(!strcmp(cinfo.drivername, "db2")) {
5406          assert_string_equal(name, "THE_NUMSTRING");
5407       }
5408       else if (!strcmp(cinfo.drivername, "firebird")) {
5409          /* firebird uses fewer fields, hence field 15 is something else */
5410          assert_string_equal(name, "THE_NULL_STRING");
5411       }
5412       else {
5413          assert_string_equal(name, "the_numstring");
5414       }
5415    }
5416 
5417    dbi_result_free(result);
5418 
5419 }
5420 
test_dbi_result_get_numfields()5421 Ensure test_dbi_result_get_numfields() {
5422    dbi_result result;
5423 
5424    result = dbi_conn_query(conn, "SELECT the_conn_quoted_string, the_conn_quoted_string_copy,"
5425          " the_conn_escaped_string, the_conn_escaped_string_copy, the_numstring,"
5426          " the_empty_string, the_null_string, the_binary_quoted_string, the_binary_escaped_string"
5427          " from test_datatypes");
5428 
5429    ASSERT_RESULT
5430 
5431    while (dbi_result_next_row(result)) {
5432       errmsg = NULL;
5433       unsigned int num;
5434 
5435       num = dbi_result_get_numfields(result);
5436       assert_equal(num, 9);
5437    }
5438 
5439    dbi_result_free(result);
5440 
5441 }
5442 
test_dbi_result_get_field_type()5443 Ensure test_dbi_result_get_field_type() {
5444    dbi_result result;
5445    char *query_string = NULL;
5446    int i, numfields;
5447 
5448    if ((query_string = assemble_query_string(cinfo.drivername, &numfields)) == NULL) {
5449       /* todo: make noise */
5450       return;
5451    }
5452 
5453    result = dbi_conn_query(conn, query_string);
5454    free(query_string);
5455    query_string = NULL;
5456 
5457    ASSERT_RESULT
5458 
5459    while (dbi_result_next_row(result)) {
5460       errmsg = NULL;
5461       unsigned short type_found, type_expected;
5462 
5463       for (i = 1; i <= numfields; i++) {
5464          type_found = dbi_result_get_field_type(result, field_name_from_index(i, cinfo.drivername));
5465          type_expected = field_type_from_index(i, cinfo.drivername);
5466          assert_equal_with_message(type_found, type_expected, "[%d] should match [%d] for field name [%s]", type_found, type_expected, field_name_from_index(i, cinfo.drivername));
5467       }
5468    }
5469 
5470    dbi_result_free(result);
5471 
5472 }
5473 
test_dbi_result_get_field_type_idx()5474 Ensure test_dbi_result_get_field_type_idx() {
5475    dbi_result result;
5476    char *query_string = NULL;
5477    int i, numfields;
5478 
5479    if ((query_string = assemble_query_string(cinfo.drivername, &numfields)) == NULL) {
5480       /* todo: make noise */
5481       return;
5482    }
5483 
5484    result = dbi_conn_query(conn, query_string);
5485    free(query_string);
5486    query_string = NULL;
5487 
5488    ASSERT_RESULT
5489 
5490    while (dbi_result_next_row(result)) {
5491       errmsg = NULL;
5492       unsigned short type_found, type_expected;
5493 
5494       for (i = 1; i <= numfields; i++) {
5495          type_found = dbi_result_get_field_type_idx(result, i);
5496          type_expected = field_type_from_index(i, cinfo.drivername);
5497          assert_equal_with_message(type_found, type_expected, "[%d] should match [%d] for field index [%d]", type_found, type_expected, i);
5498       }
5499    }
5500 
5501    dbi_result_free(result);
5502 }
5503 
test_dbi_result_get_field_attrib()5504 Ensure test_dbi_result_get_field_attrib() {
5505    dbi_result result;
5506    char *query_string = NULL;
5507    int i, numfields;
5508 
5509    if ((query_string = assemble_query_string(cinfo.drivername, &numfields)) == NULL) {
5510       /* todo: make noise */
5511       return;
5512    }
5513 
5514    result = dbi_conn_query(conn, query_string);
5515    free(query_string);
5516    query_string = NULL;
5517 
5518    ASSERT_RESULT
5519 
5520    while (dbi_result_next_row(result)) {
5521       errmsg = NULL;
5522       unsigned int type_found, type_expected;
5523 
5524       for (i = 1; i <= numfields; i++) {
5525          type_found = dbi_result_get_field_attrib(result, field_name_from_index(i, cinfo.drivername), DBI_INTEGER_UNSIGNED, DBI_INTEGER_SIZE8);
5526          type_expected = field_attrib_from_index(i, cinfo.drivername);
5527          assert_equal_with_message(type_found, type_expected, "[%d] should match [%d] for field name [%s]", type_found, type_expected, field_name_from_index(i, cinfo.drivername));
5528       }
5529    }
5530 
5531    dbi_result_free(result);
5532 
5533 }
5534 
test_dbi_result_get_field_attrib_idx()5535 Ensure test_dbi_result_get_field_attrib_idx() {
5536    dbi_result result;
5537    char *query_string = NULL;
5538    int i, numfields;
5539 
5540    if ((query_string = assemble_query_string(cinfo.drivername, &numfields)) == NULL) {
5541       /* todo: make noise */
5542       return;
5543    }
5544 
5545    result = dbi_conn_query(conn, query_string);
5546    free(query_string);
5547    query_string = NULL;
5548 
5549    ASSERT_RESULT
5550 
5551    while (dbi_result_next_row(result)) {
5552       errmsg = NULL;
5553       unsigned int type_found, type_expected;
5554 
5555       for (i = 1; i <= numfields; i++) {
5556          type_found = dbi_result_get_field_attrib_idx(result, i, DBI_INTEGER_UNSIGNED, DBI_INTEGER_SIZE8);
5557          type_expected = field_attrib_from_index(i, cinfo.drivername);
5558          assert_equal_with_message(type_found, type_expected, "[%d] should match [%d] for field index [%d]", type_found, type_expected, i);
5559       }
5560    }
5561 
5562    dbi_result_free(result);
5563 
5564 }
5565 
test_dbi_result_get_field_attribs()5566 Ensure test_dbi_result_get_field_attribs() {
5567    dbi_result result;
5568    char *query_string = NULL;
5569    int i, numfields;
5570 
5571    if ((query_string = assemble_query_string(cinfo.drivername, &numfields)) == NULL) {
5572       /* todo: make noise */
5573       return;
5574    }
5575 
5576    result = dbi_conn_query(conn, query_string);
5577    free(query_string);
5578    query_string = NULL;
5579 
5580    ASSERT_RESULT
5581 
5582    while (dbi_result_next_row(result)) {
5583       errmsg = NULL;
5584       unsigned int type_found, type_expected;
5585 
5586       for (i = 1; i <= numfields; i++) {
5587          type_found = dbi_result_get_field_attribs(result, field_name_from_index(i, cinfo.drivername));
5588          type_expected = field_attrib_from_index(i, cinfo.drivername);
5589          assert_equal_with_message(type_found, type_expected, "[%d] should match [%d] for field name [%s]", type_found, type_expected, field_name_from_index(i, cinfo.drivername));
5590       }
5591    }
5592 
5593    dbi_result_free(result);
5594 }
5595 
test_dbi_result_get_field_attribs_idx()5596 Ensure test_dbi_result_get_field_attribs_idx() {
5597    dbi_result result;
5598    char *query_string = NULL;
5599    int i, numfields;
5600 
5601    if ((query_string = assemble_query_string(cinfo.drivername, &numfields)) == NULL) {
5602       /* todo: make noise */
5603       return;
5604    }
5605 
5606    result = dbi_conn_query(conn, query_string);
5607    free(query_string);
5608    query_string = NULL;
5609 
5610    ASSERT_RESULT
5611 
5612    while (dbi_result_next_row(result)) {
5613       errmsg = NULL;
5614       unsigned int type_found, type_expected;
5615 
5616       for (i = 1; i <= numfields; i++) {
5617          type_found = dbi_result_get_field_attribs_idx(result, i);
5618          type_expected = field_attrib_from_index(i, cinfo.drivername);
5619          assert_equal_with_message(type_found, type_expected, "[%d] should match [%d] for field index [%d]", type_found, type_expected, i);
5620       }
5621    }
5622 
5623    dbi_result_free(result);
5624 }
5625 
test_dbi_result_field_is_null()5626 Ensure test_dbi_result_field_is_null() {
5627    dbi_result result;
5628 
5629    result = dbi_conn_query(conn, "SELECT the_null_string from test_datatypes");
5630 
5631    ASSERT_RESULT
5632 
5633    while (dbi_result_next_row(result)) {
5634       errmsg = NULL;
5635       int isnull = 0;
5636 
5637       isnull = dbi_result_field_is_null(result, "the_null_string");
5638       assert_equal(isnull, 1);
5639    }
5640 
5641    dbi_result_free(result);
5642 
5643 }
5644 
test_dbi_result_field_is_null_idx()5645 Ensure test_dbi_result_field_is_null_idx() {
5646    dbi_result result;
5647 
5648    result = dbi_conn_query(conn, "SELECT the_null_string from test_datatypes");
5649 
5650    ASSERT_RESULT
5651 
5652    while (dbi_result_next_row(result)) {
5653       errmsg = NULL;
5654       int isnull = 0;
5655 
5656       isnull = dbi_result_field_is_null_idx(result, 1);
5657       assert_equal(isnull, 1);
5658    }
5659 
5660    dbi_result_free(result);
5661 
5662 }
5663 
test_dbi_conn_get_table_list()5664 Ensure test_dbi_conn_get_table_list() {
5665    dbi_result result;
5666 
5667    result = dbi_conn_get_table_list(conn, cinfo.dbname, "test_datatypes");
5668    ASSERT_RESULT
5669 
5670    while (dbi_result_next_row(result)) {
5671       const char *tablename = NULL;
5672       tablename = dbi_result_get_string_idx(result, 1);
5673       assert_string_equal("test_datatypes", tablename);
5674    }
5675 
5676    assert_equal(dbi_result_free(result), 0);
5677 }
5678 
test_dbi_conn_get_table_list_no_pattern()5679 Ensure test_dbi_conn_get_table_list_no_pattern() {
5680    dbi_result result;
5681 
5682    result = dbi_conn_get_table_list(conn, cinfo.dbname, NULL);
5683    ASSERT_RESULT
5684 
5685    while (dbi_result_next_row(result)) {
5686       const char *tablename = NULL;
5687       tablename = dbi_result_get_string_idx(result, 1);
5688 
5689       assert_string_equal("test_datatypes", tablename);
5690 
5691    }
5692 
5693    assert_equal(dbi_result_free(result), 0);
5694 }
5695 
5696 /****** TestSuite declarations ******/
5697 
test_libdbi()5698 TestSuite *test_libdbi() {
5699 
5700    TestSuite *suite = create_named_test_suite(cinfo.drivername);
5701 
5702    add_suite(suite, test_dbi_general_test_case());
5703 
5704    add_suite(suite, test_database_infrastructure());
5705    add_suite(suite, test_managing_results());
5706    add_suite(suite, test_transactions());
5707 
5708    add_suite(suite, test_managing_queries());
5709    add_suite(suite, test_dbi_retrieving_fields_meta_data());
5710 
5711    add_suite(suite, test_dbi_retrieving_fields_data_name());
5712    add_suite(suite, test_dbi_retrieving_fields_data_idx());
5713    add_suite(suite, test_dbi_retrieving_fields_as());
5714    add_suite(suite, test_dbi_misc());
5715 
5716    /* todo: Specific tests for the databases functions */
5717    if (!strcmp(cinfo.drivername, "firebird")) {
5718 
5719    } else if (!strcmp(cinfo.drivername, "freetds")) {
5720 
5721    } else if (!strcmp(cinfo.drivername, "ingres")) {
5722 
5723    } else if (!strcmp(cinfo.drivername, "msql")) {
5724 
5725    } else if (!strcmp(cinfo.drivername, "mysql")) {
5726       /* add_suite(suite, test_mysql_specific_functions()); */
5727    } else if (!strcmp(cinfo.drivername, "pgsql")) {
5728       /* add_suite(suite, test_pgsql_specific_functions()); */
5729    } else if (!strcmp(cinfo.drivername, "sqlite") || !strcmp(cinfo.drivername,
5730          "sqlite3")) {
5731 
5732    }
5733 
5734    TestSuite *database_fixture = create_named_test_suite("libdbi framework test");
5735    add_suite(database_fixture, suite);
5736    setup(database_fixture, create_database);
5737    teardown(database_fixture, drop_database);
5738    return database_fixture;
5739 }
5740 
test_pgsql_specific_functions()5741 TestSuite *test_pgsql_specific_functions() {
5742    TestSuite *suite = create_named_test_suite("Postgresql specific functions");
5743    setup(suite, create_schema);
5744    teardown(suite, drop_schema);
5745    add_test(suite, test_pgsql_copy);
5746    connection_fixture(suite);
5747 }
5748 
test_mysql_specific_functions()5749 TestSuite *test_mysql_specific_functions() {
5750    TestSuite *suite = create_named_test_suite("Mysql specific functions");
5751    setup(suite, create_schema);
5752    teardown(suite, drop_schema);
5753    //add_test(suite, test_dbi_conn_escape_string);
5754    connection_fixture(suite);
5755 }
5756 
test_dbi_instance_infrastructure()5757 TestSuite *test_dbi_instance_infrastructure() {
5758    TestSuite *suite = create_named_test_suite("Instance infrastructure fields as");
5759    setup(suite, create_schema);
5760    teardown(suite, drop_schema);
5761    add_test(suite, test_create_another_connection);
5762    return connection_fixture(suite);
5763 }
5764 
test_dbi_general_test_case()5765 TestSuite *test_dbi_general_test_case() {
5766    TestSuite *suite = create_named_test_suite("Test DBI general test cases");
5767    setup(suite, create_schema);
5768    teardown(suite, drop_schema);
5769    add_test(suite, test_create_another_connection);
5770    if (!strcmp(cinfo.drivername, "mysql") ||
5771          !strcmp(cinfo.drivername, "pgsql")) {
5772       add_test(suite, test_another_encoding);
5773    }
5774    return connection_fixture(suite);
5775 }
5776 
test_managing_queries()5777 TestSuite *test_managing_queries() {
5778    TestSuite *suite = create_named_test_suite("Managing Queries");
5779    setup(suite, create_schema);
5780    teardown(suite, drop_schema);
5781    add_test(suite, test_dbi_conn_query);
5782    add_test(suite, test_dbi_conn_queryf);
5783    add_test(suite, test_dbi_conn_sequence_last);
5784    add_test(suite, test_dbi_conn_sequence_next);
5785    add_test(suite, test_dbi_conn_quote_string);
5786    add_test(suite, test_dbi_conn_quote_string_copy);
5787    add_test(suite, test_dbi_conn_quote_binary_copy);
5788    add_test(suite, test_dbi_conn_escape_string);
5789    add_test(suite, test_dbi_conn_escape_string_copy);
5790    add_test(suite, test_dbi_conn_escape_binary_copy);
5791    connection_fixture(suite);
5792 }
5793 
test_transactions()5794 TestSuite *test_transactions() {
5795    TestSuite *suite = create_named_test_suite("Managing Transactions");
5796    setup(suite, create_schema);
5797    teardown(suite, drop_schema);
5798    add_test(suite, test_dbi_conn_transaction_commit);
5799    add_test(suite, test_dbi_conn_transaction_rollback);
5800    add_test(suite, test_dbi_conn_rollback_to_savepoint);
5801    add_test(suite, test_dbi_conn_release_savepoint);
5802    connection_fixture(suite);
5803 }
5804 
test_managing_results()5805 TestSuite *test_managing_results() {
5806    TestSuite *suite = create_named_test_suite("Managing results");
5807    // set the number of rows we need, 5 rows is good.
5808    // call function to setup the number of rows
5809    setup(suite, create_schema_five_rows);
5810    teardown(suite, drop_schema);
5811    add_test(suite, test_dbi_result_get_conn);
5812    add_test(suite, test_dbi_result_free);
5813    add_test(suite, test_dbi_result_seek_row);
5814    add_test(suite, test_dbi_result_first_row);
5815    add_test(suite, test_dbi_result_last_row);
5816    add_test(suite, test_dbi_result_prev_row);
5817    add_test(suite, test_dbi_result_next_row);
5818    add_test(suite, test_dbi_result_get_currow);
5819    add_test(suite, test_dbi_result_get_numrows);
5820    add_test(suite, test_dbi_result_get_numrows_affected);
5821    return connection_fixture(suite);
5822 }
5823 
test_dbi_misc()5824 TestSuite *test_dbi_misc() {
5825    TestSuite *suite = create_named_test_suite("Test select cases");
5826    setup(suite, create_schema);
5827    teardown(suite, drop_schema);
5828    add_test(suite, test_retrieve_zero_rows);
5829    add_test(suite, test_dummy);
5830    return connection_fixture(suite);
5831 }
5832 
test_dbi_retrieving_fields_as()5833 TestSuite *test_dbi_retrieving_fields_as() {
5834    TestSuite *suite = create_named_test_suite("Retrieving fields as");
5835    setup(suite, create_schema);
5836    teardown(suite, drop_schema);
5837    // todo bug firebird
5838    add_test(suite, test_dbi_result_get_as_string);
5839    // todo bug firebird
5840    add_test(suite, test_dbi_result_get_as_longlong);
5841    return connection_fixture(suite);
5842 }
5843 
test_dbi_retrieving_fields_data_idx()5844 TestSuite *test_dbi_retrieving_fields_data_idx() {
5845    TestSuite *suite = create_named_test_suite("Retrieving fields data by index");
5846    setup(suite, create_schema);
5847    teardown(suite, drop_schema);
5848    add_test(suite, test_dbi_result_get_char_idx);
5849    add_test(suite, test_dbi_result_get_uchar_idx);
5850    add_test(suite, test_dbi_result_get_short_idx);
5851    add_test(suite, test_dbi_result_get_ushort_idx);
5852    add_test(suite, test_dbi_result_get_int_idx);
5853    add_test(suite, test_dbi_result_get_uint_idx);
5854    if (tinfo.have_longlong) {
5855       add_test(suite, test_dbi_result_get_longlong_idx);
5856    }
5857    if (tinfo.have_ulonglong) {
5858       add_test(suite, test_dbi_result_get_ulonglong_idx);
5859    }
5860    add_test(suite, test_dbi_result_get_float_idx);
5861    if(tinfo.have_double) {
5862       add_test(suite, test_dbi_result_get_double_idx);
5863    }
5864    add_test(suite, test_dbi_result_get_string_idx);
5865    add_test(suite, test_dbi_result_get_string_copy_idx);
5866    // todo bug firebird
5867    add_test(suite, test_dbi_result_get_binary_idx);
5868    // todo bug firebird
5869    add_test(suite, test_dbi_result_get_binary_copy_idx);
5870    if(tinfo.have_datetime) {
5871       add_test(suite, test_dbi_result_get_datetime_idx);
5872    }
5873    if(tinfo.have_datetime_tz) {
5874       add_test(suite, test_dbi_result_get_datetime_tz_idx);
5875    }
5876    if (tinfo.have_time_tz) {
5877       add_test(suite, test_dbi_result_get_datetime_time_tz_idx);
5878    }
5879    connection_fixture(suite);
5880 }
5881 
test_dbi_retrieving_fields_data_name()5882 TestSuite *test_dbi_retrieving_fields_data_name() {
5883    TestSuite *suite = create_named_test_suite("Retrieving fields data by name");
5884    setup(suite, create_schema);
5885    teardown(suite, drop_schema);
5886    add_test(suite, test_dbi_result_get_char);
5887    add_test(suite, test_dbi_result_get_uchar);
5888    add_test(suite, test_dbi_result_get_short);
5889    add_test(suite, test_dbi_result_get_ushort);
5890    add_test(suite, test_dbi_result_get_int);
5891    add_test(suite, test_dbi_result_get_uint);
5892    if (tinfo.have_longlong) {
5893       add_test(suite, test_dbi_result_get_longlong);
5894    }
5895    if (tinfo.have_ulonglong) {
5896       add_test(suite, test_dbi_result_get_ulonglong);
5897    }
5898    add_test(suite, test_dbi_result_get_float);
5899    if(tinfo.have_double) {
5900       add_test(suite, test_dbi_result_get_double);
5901    }
5902    add_test(suite, test_dbi_result_get_string);
5903    add_test(suite, test_dbi_result_get_string_copy);
5904    // todo bug firebird
5905    add_test(suite, test_dbi_result_get_binary);
5906    // todo bug firebird
5907    add_test(suite, test_dbi_result_get_binary_copy);
5908    if(tinfo.have_datetime) {
5909       add_test(suite, test_dbi_result_get_datetime);
5910    }
5911    if(tinfo.have_datetime_tz) {
5912       add_test(suite, test_dbi_result_get_datetime_tz);
5913    }
5914    if (tinfo.have_time_tz) {
5915       add_test(suite, test_dbi_result_get_datetime_time_tz);
5916    }
5917    add_test(suite, test_dbi_result_get_field_type_mismatch);
5918    //add_test(suite, test_dbi_result_get_field_bad_name);
5919    // todo bug firebird
5920    add_test(suite, test_dbi_result_get_fields);
5921    add_test(suite, test_dbi_result_bind_char);
5922    add_test(suite, test_dbi_result_bind_uchar);
5923    add_test(suite, test_dbi_result_bind_short);
5924    add_test(suite, test_dbi_result_bind_ushort);
5925    add_test(suite, test_dbi_result_bind_int);
5926    add_test(suite, test_dbi_result_bind_uint);
5927    if (tinfo.have_longlong) {
5928       add_test(suite, test_dbi_result_bind_longlong);
5929    }
5930    if (tinfo.have_ulonglong) {
5931       add_test(suite, test_dbi_result_bind_ulonglong);
5932    }
5933    add_test(suite, test_dbi_result_bind_float);
5934    if(tinfo.have_double) {
5935       add_test(suite, test_dbi_result_bind_double);
5936    }
5937    add_test(suite, test_dbi_result_bind_string);
5938    // todo bug firebird
5939    add_test(suite, test_dbi_result_bind_binary);
5940    add_test(suite, test_dbi_result_bind_string_copy);
5941    // todo bug firebird
5942    add_test(suite, test_dbi_result_bind_binary_copy);
5943    if(tinfo.have_datetime) {
5944       add_test(suite, test_dbi_result_bind_datetime);
5945    }
5946    if(tinfo.have_datetime_tz) {
5947       add_test(suite, test_dbi_result_bind_datetime_tz);
5948    }
5949    if (tinfo.have_time_tz) {
5950       add_test(suite, test_dbi_result_bind_datetime_time_tz);
5951    }
5952    // todo bug firebird
5953    add_test(suite, test_dbi_result_bind_fields);
5954 
5955    connection_fixture(suite);
5956 }
5957 
test_dbi_retrieving_fields_meta_data()5958 TestSuite *test_dbi_retrieving_fields_meta_data() {
5959    TestSuite *suite = create_named_test_suite("Retrieving fields meta-data");
5960    setup(suite, create_schema);
5961    teardown(suite, drop_schema);
5962    add_test(suite, test_dbi_result_get_field_length);
5963    add_test(suite, test_dbi_result_get_field_length_idx);
5964    add_test(suite, test_dbi_result_get_field_idx);
5965    add_test(suite, test_dbi_result_get_field_name);
5966    add_test(suite, test_dbi_result_get_numfields);
5967    add_test(suite, test_dbi_result_get_field_type);
5968    add_test(suite, test_dbi_result_get_field_type_idx);
5969    add_test(suite, test_dbi_result_get_field_attrib);
5970    add_test(suite, test_dbi_result_get_field_attrib_idx);
5971    add_test(suite, test_dbi_result_get_field_attribs);
5972    add_test(suite, test_dbi_result_get_field_attribs_idx);
5973    add_test(suite, test_dbi_result_field_is_null);
5974    add_test(suite, test_dbi_result_field_is_null_idx);
5975    return connection_fixture(suite);
5976 }
5977 
test_database_infrastructure()5978 TestSuite *test_database_infrastructure() {
5979    TestSuite *suite = create_named_test_suite("Database Infrastructure");
5980    setup(suite, create_schema);
5981    teardown(suite, drop_schema);
5982    add_test(suite, test_dbi_conn_get_table_list);
5983    //  add_test(suite, test_dbi_conn_get_table_list_no_pattern);
5984    /* the test test_dbi_conn_select_db need to be called by last because
5985     * some database engines reconnect to the database. So the fixture
5986     * below close the database for us.
5987     */
5988    add_test(suite, test_dbi_conn_select_db);
5989    connection_fixture(suite);
5990 }
5991 
5992 /* helper TestSuite */
5993 
connection_fixture(TestSuite * suite)5994 TestSuite *connection_fixture(TestSuite *suite) {
5995    TestSuite *fixture = create_named_test_suite("libdbi connection");
5996    add_suite(fixture, suite);
5997    setup(fixture, open_test_database);
5998    teardown(fixture, close_test_database);
5999    return fixture;
6000 }
6001