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

Go to the SVN repository for this file.

1 /* Testing large objects */
2 /* Test from Sebastien Flaesch */
3 
4 #include "common.h"
5 #include <ctype.h>
6 
7 #include <common/test_assert.h>
8 
9 #define NBYTES 10000u
10 
11 static int failed = 0;
12 
13 static void
14 fill_chars(char *buf, size_t len, unsigned int start, unsigned int step)
15 {
16  size_t n;
17 
18  for (n = 0; n < len; ++n)
19  buf[n] = 'a' + ((start+n) * step % ('z' - 'a' + 1));
20 }
21 
22 static void
23 fill_hex(char *buf, size_t len, unsigned int start, unsigned int step)
24 {
25  size_t n;
26 
27  for (n = 0; n < len; ++n)
28  sprintf(buf + 2*n, "%2x", (unsigned int)('a' + ((start+n) * step % ('z' - 'a' + 1))));
29 }
30 
31 
32 static int
33 check_chars(const char *buf, size_t len, SQLLEN start, unsigned int step)
34 {
35  size_t n;
36 
37  for (n = 0; n < len; ++n)
38  if (buf[n] != 'a' + ((start+n) * step % ('z' - 'a' + 1)))
39  return 0;
40 
41  return 1;
42 }
43 
44 static int
45 check_hex(const char *buf, size_t len, SQLLEN start, unsigned int step)
46 {
47  size_t n;
48  char symbol[3];
49 
50  for (n = 0; n < len; ++n) {
51  sprintf(symbol, "%2x", (unsigned int)('a' + ((start+n) / 2 * step % ('z' - 'a' + 1))));
52  if (tolower((unsigned char) buf[n]) != symbol[(start+n) % 2])
53  return 0;
54  }
55 
56  return 1;
57 }
58 
59 #define MAX_TESTS 10
60 typedef struct {
61  unsigned num;
63  const char *db_type;
64  unsigned gen1, gen2;
66  char *buf;
67 } test_info;
68 
70 static unsigned num_tests = 0;
71 
72 static void
73 dump(FILE* out, const char* start, void* buf, SQLULEN len)
74 {
75  SQLULEN n;
76  char s[17];
77  if (len >= 16)
78  len = 16;
79  fprintf(out, "%s", start);
80  for (n = 0; n < len; ++n) {
81  unsigned char c = ((unsigned char*)buf)[n];
82  fprintf(out, " %02X", c);
83  s[n] = (c >= 0x20 && c < 127) ? (char) c : '.';
84  }
85  s[len] = 0;
86  fprintf(out, " - %s\n", s);
87 }
88 
89 static void
91 {
92  SQLRETURN rc;
93  char buf[4096];
94  SQLLEN len, total = 0;
95  int i = 0;
96  int check;
97 
98  printf(">> readBlob field %d\n", t->num);
99  while (1) {
100  i++;
101  rc = CHKGetData(t->num, SQL_C_BINARY, (SQLPOINTER) buf, (SQLINTEGER) sizeof(buf), &len, "SINo");
102  if (rc == SQL_NO_DATA || len <= 0)
103  break;
104  if (len > (SQLLEN) sizeof(buf))
105  len = (SQLLEN) sizeof(buf);
106  printf(">> step %d: %d bytes readed\n", i, (int) len);
107  check = check_chars(buf, len, t->gen1 + total, t->gen2);
108  if (!check) {
109  fprintf(stderr, "Wrong buffer content\n");
110  dump(stderr, " buf ", buf, len);
111  failed = 1;
112  }
113  total += len;
114  }
115  printf(">> total bytes read = %d \n", (int) total);
116  if (total != 10000) {
117  fprintf(stderr, "Wrong buffer length, expected 20000\n");
118  failed = 1;
119  }
120 }
121 
122 static void
123 readBlobAsChar(test_info *t, int step, int wide)
124 {
126  char buf[8192];
127  SQLLEN len, total = 0, len2;
128  int i = 0;
129  int check;
130  int bufsize;
131 
133  unsigned int char_len = 1;
134  if (wide) {
135  char_len = sizeof(SQLWCHAR);
136  type = SQL_C_WCHAR;
137  }
138 
139  if (step%2) bufsize = sizeof(buf) - char_len;
140  else bufsize = sizeof(buf);
141 
142  printf(">> readBlobAsChar field %d\n", t->num);
143  while (rc == SQL_SUCCESS_WITH_INFO) {
144  i++;
145  rc = CHKGetData(t->num, type, (SQLPOINTER) buf, (SQLINTEGER) bufsize, &len, "SINo");
146  if (rc == SQL_SUCCESS_WITH_INFO && len == SQL_NO_TOTAL) {
147  len = bufsize - char_len;
148  rc = SQL_SUCCESS;
149  }
150  if (rc == SQL_NO_DATA || len <= 0)
151  break;
152  rc = CHKGetData(t->num, type, (SQLPOINTER) buf, 0, &len2, "SINo");
153  if (rc == SQL_SUCCESS_WITH_INFO && len2 != SQL_NO_TOTAL)
154  len = len - len2;
155 #if 0
156  if (len > (SQLLEN) (bufsize - char_len))
157  len = (SQLLEN) (bufsize - char_len);
158  len -= len % (2u * char_len);
159 #endif
160  printf(">> step %d: %d bytes readed\n", i, (int) len);
161 
162  if (wide) {
163  len /= sizeof(SQLWCHAR);
164  odbc_from_sqlwchar((char *) buf, (SQLWCHAR *) buf, len + 1);
165  }
166 
167  check = check_hex(buf, len, 2*t->gen1 + total, t->gen2);
168  if (!check) {
169  fprintf(stderr, "Wrong buffer content\n");
170  dump(stderr, " buf ", buf, len);
171  failed = 1;
172  }
173  total += len;
174  }
175  printf(">> total bytes read = %d \n", (int) total);
176  if (total != 20000) {
177  fprintf(stderr, "Wrong buffer length, expected 20000\n");
178  failed = 1;
179  }
180 }
181 
182 static void
183 add_test(SQLSMALLINT c_type, SQLSMALLINT sql_type, const char *db_type, unsigned gen1, unsigned gen2)
184 {
185  test_info *t = NULL;
186  int buf_len;
187 
188  if (num_tests >= MAX_TESTS) {
189  fprintf(stderr, "too max tests\n");
190  exit(1);
191  }
192 
193  t = &test_infos[num_tests++];
194  t->num = num_tests;
195  t->c_type = c_type;
196  t->sql_type = sql_type;
197  t->db_type = db_type;
198  t->gen1 = gen1;
199  t->gen2 = gen2;
200  t->vind = 0;
201  switch (c_type) {
202  case SQL_C_CHAR:
203  buf_len = NBYTES*2+1;
204  break;
205  case SQL_C_WCHAR:
206  buf_len = (NBYTES*2+1) * sizeof(SQLWCHAR);
207  break;
208  default:
209  buf_len = NBYTES;
210  }
211  t->buf = (char*) malloc(buf_len);
212  if (!t->buf) {
213  fprintf(stderr, "memory error\n");
214  exit(1);
215  }
216  if (c_type != SQL_C_CHAR && c_type != SQL_C_WCHAR)
217  fill_chars(t->buf, NBYTES, t->gen1, t->gen2);
218  else
219  memset(t->buf, 0, buf_len);
220  t->vind = SQL_LEN_DATA_AT_EXEC((SQLLEN) buf_len);
221 }
222 
223 static void
225 {
226  while (num_tests > 0) {
228  free(t->buf);
229  t->buf = NULL;
230  }
231 }
232 
233 int
234 main(int argc, char **argv)
235 {
236  SQLRETURN RetCode;
237  SQLHSTMT old_odbc_stmt = SQL_NULL_HSTMT;
238  int i;
239 
240  int key;
241  SQLLEN vind0;
242  int cnt = 2, wide;
243  char sql[256];
244  test_info *t = NULL;
245 
246  odbc_use_version3 = 1;
247  odbc_connect();
248 
249  /* tests (W)CHAR/BINARY -> (W)CHAR/BINARY (9 cases) */
250  add_test(SQL_C_BINARY, SQL_LONGVARCHAR, "TEXT", 123, 1 );
251  add_test(SQL_C_BINARY, SQL_LONGVARBINARY, "IMAGE", 987, 25);
252  add_test(SQL_C_CHAR, SQL_LONGVARBINARY, "IMAGE", 987, 25);
253  add_test(SQL_C_CHAR, SQL_LONGVARCHAR, "TEXT", 343, 47);
254  add_test(SQL_C_WCHAR, SQL_LONGVARBINARY, "IMAGE", 561, 29);
255  add_test(SQL_C_WCHAR, SQL_LONGVARCHAR, "TEXT", 698, 24);
256  if (odbc_db_is_microsoft()) {
257  add_test(SQL_C_BINARY, SQL_WLONGVARCHAR, "NTEXT", 765, 12);
258  add_test(SQL_C_CHAR, SQL_WLONGVARCHAR, "NTEXT", 237, 71);
259  add_test(SQL_C_WCHAR, SQL_WLONGVARCHAR, "NTEXT", 687, 68);
260  }
261 
262  strcpy(sql, "CREATE TABLE #tt(k INT");
263  for (t = test_infos; t < test_infos+num_tests; ++t)
264  sprintf(strchr(sql, 0), ",f%u %s", t->num, t->db_type);
265  strcat(sql, ",v INT)");
266  odbc_command(sql);
267 
268  old_odbc_stmt = odbc_stmt;
270 
271  /* Insert rows ... */
272 
273  for (i = 0; i < cnt; i++) {
274  /* MS do not save correctly char -> binary */
275  if (!odbc_driver_is_freetds() && i)
276  continue;
277 
279 
280  strcpy(sql, "INSERT INTO #tt VALUES(?");
281  for (t = test_infos; t < test_infos+num_tests; ++t)
282  strcat(sql, ",?");
283  strcat(sql, ",?)");
284  CHKPrepare(T(sql), SQL_NTS, "S");
285 
286  CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0, "S");
287  for (t = test_infos; t < test_infos+num_tests; ++t)
288  CHKBindParameter(t->num+1, SQL_PARAM_INPUT, t->c_type, t->sql_type, 0x10000000, 0, t->buf, 0, &t->vind, "S");
289 
290  CHKBindParameter(num_tests+2, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0, "S");
291 
292  key = i;
293  vind0 = 0;
294 
295  printf(">> insert... %d\n", i);
296  RetCode = CHKExecute("SINe");
297  while (RetCode == SQL_NEED_DATA) {
298  char *p;
299 
300  RetCode = CHKParamData((SQLPOINTER *) & p, "SINe");
301  printf(">> SQLParamData: ptr = %p RetCode = %d\n", (void *) p, RetCode);
302  if (RetCode == SQL_NEED_DATA) {
303  for (t = test_infos; t < test_infos+num_tests && t->buf != p; ++t)
304  ;
306  if (t->c_type == SQL_C_CHAR || t->c_type == SQL_C_WCHAR) {
307  unsigned char_len = 1;
308 
309  fill_hex(p, NBYTES, t->gen1, t->gen2);
310  if (t->c_type == SQL_C_WCHAR) {
311  char_len = sizeof(SQLWCHAR);
312  odbc_to_sqlwchar((SQLWCHAR*) p, p, NBYTES * 2);
313  }
314 
315  CHKPutData(p, (NBYTES - (i&1)) * char_len, "S");
316 
317  printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES - (i&1));
318 
319  CHKPutData(p + (NBYTES - (i&1)) * char_len, (NBYTES + (i&1)) * char_len, "S");
320 
321  printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES + (i&1));
322  } else {
323  CHKPutData(p, NBYTES, "S");
324 
325  printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES);
326  }
327  }
328  }
329 
332  }
333 
334  /* Now fetch rows ... */
335 
336  for (wide = 0; wide < 2; ++wide)
337  for (i = 0; i < cnt; i++) {
338  /* MS do not save correctly char -> binary */
339  if (!odbc_driver_is_freetds() && i)
340  continue;
341 
342 
344 
345  if (odbc_db_is_microsoft()) {
348  }
349 
350  strcpy(sql, "SELECT ");
351  for (t = test_infos; t < test_infos+num_tests; ++t)
352  sprintf(strchr(sql, 0), "f%u,", t->num);
353  strcat(sql, "v FROM #tt WHERE k = ?");
354  CHKPrepare(T(sql), SQL_NTS, "S");
355 
356  CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &i, 0, &vind0, "S");
357 
358  for (t = test_infos; t < test_infos+num_tests; ++t) {
359  t->vind = SQL_DATA_AT_EXEC;
360  CHKBindCol(t->num, SQL_C_BINARY, NULL, 0, &t->vind, "S");
361  }
362  CHKBindCol(num_tests+1, SQL_C_LONG, &key, 0, &vind0, "S");
363 
364  vind0 = 0;
365 
366  CHKExecute("S");
367 
369  printf(">> fetch... %d\n", i);
370 
371  for (t = test_infos; t < test_infos+num_tests; ++t) {
372  if (t->c_type == SQL_C_CHAR || t->c_type == SQL_C_WCHAR)
373  readBlobAsChar(t, i, wide);
374  else
375  readBlob(t);
376  }
377 
378  CHKCloseCursor("S");
381  }
382 
383  odbc_stmt = old_odbc_stmt;
384 
385  free_tests();
386  odbc_disconnect();
387 
388  if (!failed)
389  printf("ok!\n");
390 
391  return failed ? 1 : 0;
392 }
393 
static unsigned num_tests
Definition: blob1.c:70
static test_info test_infos[10]
Definition: blob1.c:69
static int check_chars(const char *buf, size_t len, SQLINTEGER start, unsigned int step)
Definition: blob1.c:33
static void dump(FILE *out, const char *start, void *buf, SQLUINTEGER len)
Definition: blob1.c:73
static void readBlob(test_info *t)
Definition: blob1.c:90
static void readBlobAsChar(test_info *t, int step, int wide)
Definition: blob1.c:123
#define MAX_TESTS
Definition: blob1.c:59
int main(int argc, char **argv)
Definition: blob1.c:234
static void fill_hex(char *buf, size_t len, unsigned int start, unsigned int step)
Definition: blob1.c:23
static void fill_chars(char *buf, size_t len, unsigned int start, unsigned int step)
Definition: blob1.c:14
static int check_hex(const char *buf, size_t len, SQLINTEGER start, unsigned int step)
Definition: blob1.c:45
static void add_test(SQLSMALLINT c_type, SQLSMALLINT sql_type, const char *db_type, unsigned gen1, unsigned gen2)
Definition: blob1.c:183
static void free_tests(void)
Definition: blob1.c:224
static int failed
Definition: blob1.c:11
#define NBYTES
Definition: blob1.c:9
#define CHKBindParameter(a, b, c, d, e, f, g, h, i, res)
Definition: common.h:96
#define CHKPrepare(a, b, res)
Definition: common.h:146
#define CHKAllocHandle(a, b, c, res)
Definition: common.h:92
#define CHKGetData(a, b, c, d, e, res)
Definition: common.h:136
#define odbc_command(cmd)
Definition: common.h:179
#define CHKBindCol(a, b, c, d, e, res)
Definition: common.h:94
#define CHKPutData(a, b, res)
Definition: common.h:148
#define CHKExecute(res)
Definition: common.h:114
#define CHKFetchScroll(a, b, res)
Definition: common.h:120
#define CHKFreeHandle(a, b, res)
Definition: common.h:122
#define T(s)
Definition: common.h:230
#define CHKCloseCursor(res)
Definition: common.h:100
#define CHKSetStmtAttr(a, b, c, res)
Definition: common.h:158
#define CHKParamData(a, res)
Definition: common.h:142
#define check(s)
Definition: describecol2.c:21
std::ofstream out("events_result.xml")
main entry point for tests
#define NULL
Definition: ncbistd.hpp:225
exit(2)
char * buf
int i
yy_size_t n
int len
const struct ncbi::grid::netcache::search::fields::KEY key
EIPRangeType t
Definition: ncbi_localip.c:101
int tolower(Uchar c)
Definition: ncbictype.hpp:72
static unsigned cnt[256]
HSTMT odbc_stmt
Definition: common.c:33
int odbc_disconnect(void)
Definition: common.c:290
SQLINTEGER odbc_to_sqlwchar(SQLWCHAR *dst, const char *src, SQLINTEGER n)
Definition: common.c:654
int odbc_use_version3
Definition: common.c:34
int odbc_db_is_microsoft(void)
Definition: common.c:325
HDBC odbc_conn
Definition: common.c:32
int odbc_driver_is_freetds(void)
Definition: common.c:345
SQLINTEGER odbc_from_sqlwchar(char *dst, const SQLWCHAR *src, SQLINTEGER n)
Definition: common.c:663
static SQLRETURN odbc_connect(TDS_DBC *dbc, TDSLOGIN *login)
Definition: odbc.c:356
#define SQLULEN
Definition: odbc.h:49
#define SQLLEN
Definition: odbc.h:52
static int bufsize
Definition: pcregrep.c:162
static char sql[1024]
Definition: putdata.c:19
#define strcat(s, k)
#define SQL_HANDLE_STMT
Definition: sql.h:66
#define SQL_NULL_HSTMT
Definition: sql.h:277
#define SQL_SUCCESS
Definition: sql.h:31
#define SQL_ATTR_CURSOR_SCROLLABLE
Definition: sql.h:87
#define SQL_DATA_AT_EXEC
Definition: sql.h:30
#define SQL_FETCH_NEXT
Definition: sql.h:261
#define SQL_NEED_DATA
Definition: sql.h:39
#define SQL_NONSCROLLABLE
Definition: sql.h:93
#define SQL_INTEGER
Definition: sql.h:170
#define SQL_SUCCESS_WITH_INFO
Definition: sql.h:32
#define SQL_NTS
Definition: sql.h:49
#define SQL_ATTR_CURSOR_SENSITIVITY
Definition: sql.h:88
#define SQL_SENSITIVE
Definition: sql.h:191
#define SQL_NO_DATA
Definition: sql.h:34
#define SQL_PARAM_INPUT
Definition: sqlext.h:1852
#define SQL_LONGVARBINARY
Definition: sqlext.h:435
#define SQL_LEN_DATA_AT_EXEC(length)
Definition: sqlext.h:618
#define SQL_LONGVARCHAR
Definition: sqlext.h:432
#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_IS_UINTEGER
Definition: sqlext.h:306
#define SQL_C_CHAR
Definition: sqlext.h:511
void * SQLPOINTER
Definition: sqltypes.h:195
WCHAR SQLWCHAR
Definition: sqltypes.h:458
long SQLINTEGER
Definition: sqltypes.h:176
SQLHANDLE SQLHSTMT
Definition: sqltypes.h:216
void * SQLHANDLE
Definition: sqltypes.h:213
signed short int SQLSMALLINT
Definition: sqltypes.h:201
SQLSMALLINT SQLRETURN
Definition: sqltypes.h:210
#define SQL_C_WCHAR
Definition: sqlucode.h:17
#define SQL_WLONGVARCHAR
Definition: sqlucode.h:16
#define assert(x)
Definition: srv_diag.hpp:58
SQLINTEGER vind
Definition: blob1.c:65
unsigned gen2
Definition: blob1.c:64
SQLSMALLINT sql_type
Definition: blob1.c:62
unsigned num
Definition: blob1.c:61
const char * db_type
Definition: blob1.c:63
char * buf
Definition: blob1.c:66
Definition: type.c:6
void free(voidpf ptr)
voidp malloc(uInt size)
Modified on Thu Dec 07 10:09:51 2023 by modify_doxy.py rev. 669887