NCBI C++ ToolKit
getdata.c
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /*
2  * Test reading data with SQLGetData
3  */
4 #include "common.h"
5 
6 #include <common/test_assert.h>
7 
8 static void
9 test_err(const char *data, int c_type, const char *state)
10 {
11  char sql[128];
12  SQLLEN ind;
13  const unsigned int buf_size = 128;
14  char *buf = (char *) malloc(buf_size);
15 
16  sprintf(sql, "SELECT '%s'", data);
19  CHKGetData(1, c_type, buf, buf_size, &ind, "E");
20  free(buf);
22  if (strcmp(odbc_sqlstate, state) != 0) {
23  fprintf(stderr, "Unexpected sql state returned\n");
25  exit(1);
26  }
28 }
29 
30 static int lc;
31 static int type;
32 
33 static int
34 mycmp(const char *s1, const char *s2)
35 {
36  SQLWCHAR buf[128], *wp;
37  size_t l;
38 
39  if (type == SQL_C_CHAR)
40  return strcmp(s1, s2);
41 
42  l = strlen(s2);
43  assert(l < (sizeof(buf)/sizeof(buf[0])));
44  wp = buf;
45  do {
46  *wp++ = *s2;
47  } while (*s2++);
48 
49  return memcmp(s1, buf, l * lc + lc);
50 }
51 
52 static void
53 test_split(const char *n_flag)
54 {
55 #define CheckLen(x) do { \
56  if (len != (x)) { \
57  fprintf(stderr, "Wrong len %ld at line %d expected %d\n", (long int) len, __LINE__, (x)); \
58  exit(1); \
59  } \
60  } while(0)
61 
62  char sql[80];
63  char *buf = NULL;
64  SQLLEN len;
65 
66  /* TODO test with VARCHAR too */
67  sprintf(sql, "SELECT CONVERT(%sTEXT,'Prova' + REPLICATE('x',500))", n_flag);
69 
70  CHKFetch("S");
71 
72  /* these 2 tests test an old severe BUG in FreeTDS */
73  buf = (char *) ODBC_GET(1);
74  CHKGetData(1, type, buf, 0, &len, "I");
75  if (len != SQL_NO_TOTAL)
76  CheckLen(505*lc);
77  CHKGetData(1, type, buf, 0, &len, "I");
78  if (len != SQL_NO_TOTAL)
79  CheckLen(505*lc);
80  buf = (char *) ODBC_GET(3*lc);
81  CHKGetData(1, type, buf, 3 * lc, &len, "I");
82  if (len != SQL_NO_TOTAL)
83  CheckLen(505*lc);
84  if (mycmp(buf, "Pr") != 0) {
85  printf("Wrong data result 1\n");
86  exit(1);
87  }
88 
89  buf = (char *) ODBC_GET(16*lc);
90  CHKGetData(1, type, buf, 16 * lc, &len, "I");
91  if (len != SQL_NO_TOTAL)
92  CheckLen(503*lc);
93  if (mycmp(buf, "ovaxxxxxxxxxxxx") != 0) {
94  printf("Wrong data result 2 res = '%s'\n", buf);
95  exit(1);
96  }
97 
98  buf = (char *) ODBC_GET(256*lc);
99  CHKGetData(1, type, buf, 256 * lc, &len, "I");
100  if (len != SQL_NO_TOTAL)
101  CheckLen(488*lc);
102  CHKGetData(1, type, buf, 256 * lc, &len, "S");
103  CheckLen(233*lc);
104  CHKGetData(1, type, buf, 256 * lc, &len, "No");
105 
107 
108  /* test with varchar, not blob but variable */
109  sprintf(sql, "SELECT CONVERT(%sVARCHAR(100), 'Other test')", n_flag);
110  odbc_command(sql);
111 
112  CHKFetch("S");
113 
114  buf = (char *) ODBC_GET(7*lc);
115  CHKGetData(1, type, buf, 7 * lc, NULL, "I");
116  if (mycmp(buf, "Other ") != 0) {
117  printf("Wrong data result 1\n");
118  exit(1);
119  }
120 
121  buf = (char *) ODBC_GET(5*lc);
122  CHKGetData(1, type, buf, 20, NULL, "S");
123  if (mycmp(buf, "test") != 0) {
124  printf("Wrong data result 2 res = '%s'\n", buf);
125  exit(1);
126  }
127  ODBC_FREE();
128 
130 }
131 
132 int
133 main(int argc, char *argv[])
134 {
135  char buf[32];
136  SQLINTEGER int_buf;
137  SQLLEN len;
138  SQLRETURN rc;
139 
140  odbc_connect();
141 
142  lc = 1;
143  type = SQL_C_CHAR;
144  test_split("");
145 
146  lc = sizeof(SQLWCHAR);
147  type = SQL_C_WCHAR;
148  test_split("");
149 
150  if (odbc_db_is_microsoft() && odbc_db_version_int() >= 0x07000000u) {
151  lc = 1;
152  type = SQL_C_CHAR;
153  test_split("N");
154 
155  lc = sizeof(SQLWCHAR);
156  type = SQL_C_WCHAR;
157  test_split("N");
158  }
159 
160  /* test with fixed length */
161  odbc_command("SELECT CONVERT(INT, 12345)");
162 
163  CHKFetch("S");
164 
165  int_buf = 0xdeadbeef;
166  CHKGetData(1, SQL_C_SLONG, &int_buf, 0, NULL, "S");
167  if (int_buf != 12345) {
168  printf("Wrong data result\n");
169  exit(1);
170  }
171 
172  CHKGetData(1, SQL_C_SLONG, &int_buf, 0, NULL, "No");
173  if (int_buf != 12345) {
174  printf("Wrong data result 2 res = %d\n", (int) int_buf);
175  exit(1);
176  }
177 
179 
180  /* test with numeric */
181  odbc_command("SELECT CONVERT(NUMERIC(18,5), 1850000000000)");
182 
183  CHKFetch("S");
184 
185  memset(buf, 'x', sizeof(buf));
186  CHKGetData(1, SQL_C_CHAR, buf, 14, NULL, "S");
187  buf[sizeof(buf)-1] = 0;
188  if (strcmp(buf, "1850000000000") != 0) {
189  printf("Wrong data result: %s\n", buf);
190  exit(1);
191  }
192 
193  /* should give NO DATA */
194  CHKGetData(1, SQL_C_CHAR, buf, 14, NULL, "No");
195  buf[sizeof(buf)-1] = 0;
196  if (strcmp(buf, "1850000000000") != 0) {
197  printf("Wrong data result 3 res = %s\n", buf);
198  exit(1);
199  }
200 
202 
203 
204  /* test int to truncated string */
205  odbc_command("SELECT CONVERT(INTEGER, 12345)");
206  CHKFetch("S");
207 
208  /* error 22003 */
209  memset(buf, 'x', sizeof(buf));
210  CHKGetData(1, SQL_C_CHAR, buf, 4, NULL, "E");
211 #ifdef ENABLE_DEVELOPING
212  buf[4] = 0;
213  if (strcmp(buf, "xxxx") != 0) {
214  fprintf(stderr, "Wrong buffer result buf = %s\n", buf);
215  exit(1);
216  }
217 #endif
218  odbc_read_error();
219  if (strcmp(odbc_sqlstate, "22003") != 0) {
220  fprintf(stderr, "Unexpected sql state %s returned\n", odbc_sqlstate);
221  odbc_disconnect();
222  exit(1);
223  }
224  CHKGetData(1, SQL_C_CHAR, buf, 2, NULL, "No");
226 
227  /* test unique identifier to truncated string */
228  rc = odbc_command2("SELECT CONVERT(UNIQUEIDENTIFIER, 'AA7DF450-F119-11CD-8465-00AA00425D90')", "SENo");
229  if (rc != SQL_ERROR) {
230  CHKFetch("S");
231 
232  /* error 22003 */
233  CHKGetData(1, SQL_C_CHAR, buf, 17, NULL, "E");
234  odbc_read_error();
235  if (strcmp(odbc_sqlstate, "22003") != 0) {
236  fprintf(stderr, "Unexpected sql state %s returned\n", odbc_sqlstate);
237  odbc_disconnect();
238  exit(1);
239  }
240  CHKGetData(1, SQL_C_CHAR, buf, 2, NULL, "No");
241  }
243 
244 
245  odbc_disconnect();
246 
247  odbc_use_version3 = 1;
248  odbc_connect();
249 
250  /* test error from SQLGetData */
251  /* wrong constant, SQL_VARCHAR is invalid as C type */
252  test_err("prova 123", SQL_VARCHAR, "HY003");
253  /* use ARD but no ARD data column */
254  test_err("prova 123", SQL_ARD_TYPE, "07009");
255  /* wrong conversion, int */
256  test_err("prova 123", SQL_C_LONG, "22018");
257  /* wrong conversion, date */
258  test_err("prova 123", SQL_C_TIMESTAMP, "22018");
259  /* overflow */
260  test_err("1234567890123456789", SQL_C_LONG, "22003");
261 
262  /* test for empty string from mssql */
263  if (odbc_db_is_microsoft()) {
264  lc = 1;
265  type = SQL_C_CHAR;
266 
267  for (;;) {
268  void *buf = ODBC_GET(lc);
269 
270  odbc_command("SELECT CONVERT(TEXT,'')");
271 
272  CHKFetch("S");
273 
274  len = 1234;
275  CHKGetData(1, type, buf, lc, &len, "S");
276 
277  if (len != 0) {
278  fprintf(stderr, "Wrong len returned, returned %ld\n", (long) len);
279  return 1;
280  }
281 
282  CHKGetData(1, type, buf, lc, NULL, "No");
284  ODBC_FREE();
285 
286  buf = ODBC_GET(4096*lc);
287 
288  odbc_command("SELECT CONVERT(TEXT,'')");
289 
290  CHKFetch("S");
291 
292  len = 1234;
293  CHKGetData(1, type, buf, lc*4096, &len, "S");
294 
295  if (len != 0) {
296  fprintf(stderr, "Wrong len returned, returned %ld\n", (long) len);
297  return 1;
298  }
299 
300  CHKGetData(1, type, buf, lc*4096, NULL, "No");
302  ODBC_FREE();
303 
304  if (type != SQL_C_CHAR)
305  break;
306  lc = sizeof(SQLWCHAR);
307  type = SQL_C_WCHAR;
308  }
309 
310  odbc_command("SELECT CONVERT(TEXT,'')");
311 
312  CHKFetch("S");
313 
314  len = 1234;
315  CHKGetData(1, SQL_C_BINARY, buf, 1, &len, "S");
316 
317  if (len != 0) {
318  fprintf(stderr, "Wrong len returned, returned %ld\n", (long) len);
319  return 1;
320  }
321 
322  CHKGetData(1, SQL_C_BINARY, buf, 1, NULL, "No");
323  }
324 
325  odbc_disconnect();
326 
327  printf("Done.\n");
328  return 0;
329 }
#define ODBC_GET(s)
Definition: common.h:217
#define odbc_reset_statement()
Definition: common.h:71
#define CHKGetData(a, b, c, d, e, res)
Definition: common.h:136
#define odbc_command(cmd)
Definition: common.h:179
#define ODBC_FREE()
Definition: common.h:218
#define odbc_command2(cmd, res)
Definition: common.h:180
#define CHKFetch(res)
Definition: common.h:118
int main(int argc, char *argv[])
Definition: getdata.c:133
#define CheckLen(x)
static void test_err(const char *data, int c_type, const char *state)
Definition: getdata.c:9
static int mycmp(const char *s1, const char *s2)
Definition: getdata.c:34
static void test_split(const char *n_flag)
Definition: getdata.c:53
static int type
Definition: getdata.c:31
static int lc
Definition: getdata.c:30
#define NULL
Definition: ncbistd.hpp:225
exit(2)
char * buf
int len
int strcmp(const char *str1, const char *str2)
Definition: odbc_utils.hpp:160
HSTMT odbc_stmt
Definition: common.c:33
char odbc_sqlstate[6]
Definition: common.c:635
unsigned int odbc_db_version_int(void)
Definition: common.c:483
int odbc_disconnect(void)
Definition: common.c:290
int odbc_use_version3
Definition: common.c:34
int odbc_db_is_microsoft(void)
Definition: common.c:325
void odbc_read_error(void)
Definition: common.c:638
static SQLRETURN odbc_connect(TDS_DBC *dbc, TDSLOGIN *login)
Definition: odbc.c:356
#define SQLLEN
Definition: odbc.h:52
static char sql[1024]
Definition: putdata.c:19
SQLRETURN SQLFetch(SQLHSTMT StatementHandle)
Definition: odbc.c:3997
#define SQL_ARD_TYPE
Definition: sql.h:206
#define SQL_VARCHAR
Definition: sql.h:178
#define SQL_ERROR
Definition: sql.h:36
#define SQL_C_SLONG
Definition: sqlext.h:553
#define SQL_C_BINARY
Definition: sqlext.h:546
#define SQL_C_LONG
Definition: sqlext.h:512
#define SQL_NO_TOTAL
Definition: sqlext.h:671
#define SQL_C_TIMESTAMP
Definition: sqlext.h:527
#define SQL_C_CHAR
Definition: sqlext.h:511
WCHAR SQLWCHAR
Definition: sqltypes.h:458
long SQLINTEGER
Definition: sqltypes.h:176
SQLSMALLINT SQLRETURN
Definition: sqltypes.h:210
#define SQL_C_WCHAR
Definition: sqlucode.h:17
#define assert(x)
Definition: srv_diag.hpp:58
Definition: type.c:6
Modified on Sat Sep 30 23:15:36 2023 by modify_doxy.py rev. 669887