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

Go to the SVN repository for this file.

1 #include "common.h"
2 #include <ctype.h>
3 
4 #include <common/test_assert.h>
5 
6 /*
7  * SQLSetStmtAttr
8  */
9 
10 static int g_result = 0;
11 static unsigned int line_num;
12 
13 #ifdef __GNUC__
14 static void fatal(const char *msg, ...) __attribute__((noreturn));
15 #endif
16 
17 static void
18 fatal(const char *msg, ...)
19 {
20  va_list ap;
21 
22  va_start(ap, msg);
23  vfprintf(stderr, msg, ap);
24  va_end(ap);
25 
26  exit(1);
27 }
28 
29 static int
30 get_int(const char *s)
31 {
32  char *end;
33  long l;
34 
35  if (!s)
36  fatal("Line %u: NULL int\n", line_num);
37  l = strtol(s, &end, 0);
38  if (end[0])
39  fatal("Line %u: Invalid int\n", line_num);
40  return (int) l;
41 }
42 
43 struct lookup_int
44 {
45  const char *name;
46  int value;
47 };
48 
49 static int
50 lookup(const char *name, const struct lookup_int *table)
51 {
52  if (!table)
53  return get_int(name);
54 
55  for (; table->name; ++table)
56  if (strcmp(table->name, name) == 0)
57  return table->value;
58 
59  return get_int(name);
60 }
61 
62 static const char *
63 unlookup(int value, const struct lookup_int *table)
64 {
65  if (!table)
66  return "??";
67 
68  for (; table->name; ++table)
69  if (table->value == value)
70  return table->name;
71 
72  return "??";
73 }
74 
75 static struct lookup_int concurrency[] = {
76 #define TYPE(s) { #s, s }
81 #undef TYPE
82  { NULL, 0 }
83 };
84 
85 static struct lookup_int scrollable[] = {
86 #define TYPE(s) { #s, s }
89 #undef TYPE
90  { NULL, 0 }
91 };
92 
93 static struct lookup_int sensitivity[] = {
94 #define TYPE(s) { #s, s }
98 #undef TYPE
99  { NULL, 0 }
100 };
101 
102 static struct lookup_int cursor_type[] = {
103 #define TYPE(s) { #s, s }
108 #undef TYPE
109  { NULL, 0 }
110 };
111 
112 static struct lookup_int noscan[] = {
113 #define TYPE(s) { #s, s }
116 #undef TYPE
117  { NULL, 0 }
118 };
119 
120 static struct lookup_int retrieve_data[] = {
121 #define TYPE(s) { #s, s }
122  TYPE(SQL_RD_ON),
123  TYPE(SQL_RD_OFF),
124 #undef TYPE
125  { NULL, 0 }
126 };
127 
128 static struct lookup_int simulate_cursor[] = {
129 #define TYPE(s) { #s, s }
133 #undef TYPE
134  { NULL, 0 }
135 };
136 
137 static struct lookup_int use_bookmarks[] = {
138 #define TYPE(s) { #s, s }
139  TYPE(SQL_UB_OFF),
142 #undef TYPE
143  { NULL, 0 }
144 };
145 
146 typedef enum
147 {
154  type_VOIDP
156 
157 struct attribute
158 {
159  const char *name;
160  int value;
162  const struct lookup_int *lookup;
163 };
164 
165 static const struct attribute attributes[] = {
166 #define ATTR(s,t) { #s, s, type_##t, NULL }
167 #define ATTR2(s,t,l) { #s, s, type_##t, l }
170  ATTR(SQL_ATTR_ASYNC_ENABLE, UINTEGER),
175  ATTR(SQL_ATTR_ENABLE_AUTO_IPD, UINTEGER),
179  ATTR(SQL_ATTR_KEYSET_SIZE, UINTEGER),
180  ATTR(SQL_ATTR_MAX_LENGTH, UINTEGER),
181  ATTR(SQL_ATTR_MAX_ROWS, UINTEGER),
182  ATTR(SQL_ATTR_METADATA_ID, UINTEGER),
183  ATTR2(SQL_ATTR_NOSCAN, UINTEGER, noscan),
186  ATTR(SQL_ATTR_PARAM_BIND_TYPE, UINTEGER),
190  ATTR(SQL_ATTR_PARAMSET_SIZE, UINTEGER),
191  ATTR(SQL_ATTR_QUERY_TIMEOUT, UINTEGER),
193  ATTR(SQL_ATTR_ROW_ARRAY_SIZE, UINTEGER),
195  ATTR(SQL_ATTR_ROW_BIND_TYPE, UINTEGER),
196  ATTR(SQL_ATTR_ROW_NUMBER, UINTEGER),
202 #undef ATTR2
203 #undef ATTR
204 };
205 
206 static const struct attribute *
207 lookup_attr(const char *name)
208 {
209  unsigned int i;
210 
211  if (!name)
212  fatal("Line %u: NULL attribute\n", line_num);
213  for (i = 0; i < sizeof(attributes) / sizeof(attributes[0]); ++i)
214  if (strcmp(attributes[i].name, name) == 0 || strcmp(attributes[i].name + 4, name) == 0)
215  return &attributes[i];
216  fatal("Line %u: attribute %s not found\n", line_num, name);
217  return NULL;
218 }
219 
220 #define SEP " \t\n"
221 
222 #define ATTR_PARAMS const struct attribute *attr, int expected
224 
225 static int
227 {
228  SQLINTEGER i, ind;
229  SQLSMALLINT si;
230  SQLLEN li;
231  SQLRETURN ret;
232 
233  ret = SQL_ERROR;
234  switch (attr->type) {
235  case type_INTEGER:
236  case type_UINTEGER:
237  i = 0xdeadbeef;
238  ret = SQLGetStmtAttr(odbc_stmt, attr->value, (SQLPOINTER) & i, sizeof(SQLINTEGER), &ind);
239  break;
240  case type_SMALLINT:
241  si = 0xbeef;
242  ret = SQLGetStmtAttr(odbc_stmt, attr->value, (SQLPOINTER) & si, sizeof(SQLSMALLINT), &ind);
243  i = si;
244  break;
245  case type_LEN:
246  li = 0xdeadbeef;
247  ret = SQLGetStmtAttr(odbc_stmt, attr->value, (SQLPOINTER) & li, sizeof(SQLLEN), &ind);
248  i = li;
249  break;
250  case type_VOIDP:
251  case type_DESC:
252  case type_CHARP:
253  fatal("Line %u: CHAR* check still not supported\n", line_num);
254  break;
255  }
256  if (!SQL_SUCCEEDED(ret))
257  fatal("Line %u: failure not expected\n", line_num);
258  return i;
259 }
260 
261 #if 0
262 /* do not retry any attribute just return expected value so to make caller happy */
263 static int
264 get_attr_none(ATTR_PARAMS)
265 {
266  return expected;
267 }
268 #endif
269 
270 int
271 main(int argc, char *argv[])
272 {
273 #define TEST_FILE "attributes.in"
274  const char *in_file = FREETDS_SRCDIR "/" TEST_FILE;
275  FILE *f;
276  char buf[256];
277  SQLINTEGER i;
278  SQLLEN len;
279  get_attr_t get_attr_p = get_attr_stmt;
280 
281  odbc_connect();
282  /* TODO find another way */
284  odbc_command("SET TEXTSIZE 4096");
285 
286  SQLBindCol(odbc_stmt, 1, SQL_C_SLONG, &i, sizeof(i), &len);
287 
288  f = fopen(in_file, "r");
289  if (!f)
290  f = fopen(TEST_FILE, "r");
291  if (!f) {
292  fprintf(stderr, "error opening test file\n");
293  exit(1);
294  }
295 
296  line_num = 0;
297  while (fgets(buf, sizeof(buf), f)) {
298  char *p = buf, *cmd;
299 
300  ++line_num;
301 
302  while (isspace((unsigned char) *p))
303  ++p;
304  cmd = strtok(p, SEP);
305 
306  /* skip comments */
307  if (!cmd || cmd[0] == '#' || cmd[0] == 0 || cmd[0] == '\n')
308  continue;
309 
310  if (strcmp(cmd, "odbc") == 0) {
311  int odbc3 = get_int(strtok(NULL, SEP)) == 3 ? 1 : 0;
312 
313  if (odbc_use_version3 != odbc3) {
314  odbc_use_version3 = odbc3;
315  odbc_disconnect();
316  odbc_connect();
317  odbc_command("SET TEXTSIZE 4096");
318  SQLBindCol(odbc_stmt, 1, SQL_C_SLONG, &i, sizeof(i), &len);
319  }
320  continue;
321  }
322 
323  /* set attribute */
324  if (strcmp(cmd, "set") == 0) {
325  const struct attribute *attr = lookup_attr(strtok(NULL, SEP));
326  char *value = strtok(NULL, SEP);
327  SQLRETURN ret;
328 
329  if (!value)
330  fatal("Line %u: value not defined\n", line_num);
331 
332  ret = SQL_ERROR;
333  switch (attr->type) {
334  case type_UINTEGER:
335  case type_INTEGER:
336  ret = SQLSetStmtAttr(odbc_stmt, attr->value, int2ptr(lookup(value, attr->lookup)),
337  sizeof(SQLINTEGER));
338  break;
339  case type_SMALLINT:
340  ret = SQLSetStmtAttr(odbc_stmt, attr->value, int2ptr(lookup(value, attr->lookup)),
341  sizeof(SQLSMALLINT));
342  break;
343  case type_LEN:
344  ret = SQLSetStmtAttr(odbc_stmt, attr->value, int2ptr(lookup(value, attr->lookup)),
345  sizeof(SQLLEN));
346  break;
347  case type_CHARP:
349  break;
350  case type_VOIDP:
351  case type_DESC:
352  fatal("Line %u: not implemented\n");
353  }
354  if (!SQL_SUCCEEDED(ret))
355  fatal("Line %u: failure not expected setting statement attribute\n", line_num);
356  get_attr_p = get_attr_stmt;
357  continue;
358  }
359 
360  /* test attribute */
361  if (strcmp(cmd, "attr") == 0) {
362  const struct attribute *attr = lookup_attr(strtok(NULL, SEP));
363  char *value = strtok(NULL, SEP);
364  int i, expected = lookup(value, attr->lookup);
365 
366  if (!value)
367  fatal("Line %u: value not defined\n", line_num);
368 
369  i = get_attr_p(attr, expected);
370  if (i != expected) {
371  g_result = 1;
372  fprintf(stderr, "Line %u: invalid %s got %d(%s) expected %s\n", line_num, attr->name, i, unlookup(i, attr->lookup), value);
373  }
374  continue;
375  }
376 
377  if (strcmp(cmd, "reset") == 0) {
379  continue;
380  }
381 
382  fatal("Line %u: command '%s' not handled\n", line_num, cmd);
383  }
384 
385  fclose(f);
386  odbc_disconnect();
387 
388  printf("Done.\n");
389  return g_result;
390 }
int(* get_attr_t)(const struct attribute *attr, int expected)
Definition: attributes.c:223
static struct lookup_int concurrency[]
Definition: attributes.c:75
static int get_attr_stmt(const struct attribute *attr, int expected)
Definition: attributes.c:226
int main(int argc, char *argv[])
Definition: attributes.c:271
static int get_int(const char *s)
Definition: attributes.c:30
static struct lookup_int cursor_type[]
Definition: attributes.c:102
static struct lookup_int simulate_cursor[]
Definition: attributes.c:128
static struct lookup_int sensitivity[]
Definition: attributes.c:93
static struct lookup_int use_bookmarks[]
Definition: attributes.c:137
static unsigned int line_num
Definition: attributes.c:11
static const struct attribute * lookup_attr(const char *name)
Definition: attributes.c:207
test_type_t
Definition: attributes.c:147
@ type_UINTEGER
Definition: attributes.c:149
@ type_DESC
Definition: attributes.c:153
@ type_CHARP
Definition: attributes.c:152
@ type_LEN
Definition: attributes.c:151
@ type_VOIDP
Definition: attributes.c:154
@ type_INTEGER
Definition: attributes.c:148
@ type_SMALLINT
Definition: attributes.c:150
#define ATTR_PARAMS
Definition: attributes.c:222
#define TEST_FILE
static int lookup(const char *name, const struct lookup_int *table)
Definition: attributes.c:50
#define ATTR2(s, t, l)
static struct lookup_int scrollable[]
Definition: attributes.c:85
static struct lookup_int noscan[]
Definition: attributes.c:112
#define SEP
Definition: attributes.c:220
#define TYPE(s)
static const struct attribute attributes[]
Definition: attributes.c:165
static int g_result
Definition: attributes.c:10
static struct lookup_int retrieve_data[]
Definition: attributes.c:120
static const char * unlookup(int value, const struct lookup_int *table)
Definition: attributes.c:63
#define ATTR(s, t)
static void fatal(const char *msg,...)
Definition: attributes.c:18
char value[7]
Definition: config.c:431
static CS_COMMAND * cmd
Definition: ct_dynamic.c:26
#define int2ptr(i)
Definition: common.h:101
#define FREETDS_SRCDIR
Definition: common.h:43
#define odbc_reset_statement()
Definition: common.h:71
#define odbc_command(cmd)
Definition: common.h:179
static const char si[8][64]
Definition: des.c:146
#define NULL
Definition: ncbistd.hpp:225
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
<!DOCTYPE HTML >< html > n< header > n< title > PubSeq Gateway Help Page</title > n< style > n table
exit(2)
char * buf
int i
int len
int strcmp(const char *str1, const char *str2)
Definition: odbc_utils.hpp:160
int isspace(Uchar c)
Definition: ncbictype.hpp:69
double f(double x_, const double &y_)
Definition: njn_root.hpp:188
static const char * expected[]
Definition: bcp.c:42
HSTMT odbc_stmt
Definition: common.c:33
void odbc_check_cursor(void)
Definition: common.c:548
int odbc_disconnect(void)
Definition: common.c:290
int odbc_use_version3
Definition: common.c:34
static SQLRETURN odbc_connect(TDS_DBC *dbc, TDSLOGIN *login)
Definition: odbc.c:356
#define SQLLEN
Definition: odbc.h:52
#define SQL_ATTR_APP_ROW_DESC
Definition: sql.h:83
#define SQL_UNSPECIFIED
Definition: sql.h:189
#define SQL_ATTR_APP_PARAM_DESC
Definition: sql.h:84
#define SQL_ATTR_CURSOR_SCROLLABLE
Definition: sql.h:87
#define SQL_SCROLLABLE
Definition: sql.h:94
#define SQL_ATTR_IMP_PARAM_DESC
Definition: sql.h:86
#define SQL_NONSCROLLABLE
Definition: sql.h:93
#define SQL_INSENSITIVE
Definition: sql.h:190
SQLRETURN SQLSetStmtAttr(SQLHSTMT StatementHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER StringLength)
SQLRETURN SQLGetStmtAttr(SQLHSTMT StatementHandle, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER *StringLength)
#define SQL_NTS
Definition: sql.h:49
#define SQL_ATTR_CURSOR_SENSITIVITY
Definition: sql.h:88
#define SQL_SUCCEEDED(rc)
Definition: sql.h:40
#define SQL_ATTR_METADATA_ID
Definition: sql.h:78
SQLRETURN SQLBindCol(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, SQLPOINTER TargetValue, SQLINTEGER BufferLength, SQLINTEGER *StrLen_or_Ind)
#define SQL_ATTR_IMP_ROW_DESC
Definition: sql.h:85
#define SQL_SENSITIVE
Definition: sql.h:191
#define SQL_ERROR
Definition: sql.h:36
#define SQL_NOSCAN_OFF
Definition: sqlext.h:325
#define SQL_ATTR_NOSCAN
Definition: sqlext.h:264
#define SQL_ATTR_ROWS_FETCHED_PTR
Definition: sqlext.h:278
#define SQL_ATTR_ROW_ARRAY_SIZE
Definition: sqlext.h:279
#define SQL_SC_UNIQUE
Definition: sqlext.h:364
#define SQL_CURSOR_FORWARD_ONLY
Definition: sqlext.h:349
#define SQL_ATTR_ROW_STATUS_PTR
Definition: sqlext.h:277
#define SQL_NOSCAN_ON
Definition: sqlext.h:326
#define SQL_SC_TRY_UNIQUE
Definition: sqlext.h:363
#define SQL_ATTR_ROW_OPERATION_PTR
Definition: sqlext.h:276
#define SQL_ATTR_PARAMS_PROCESSED_PTR
Definition: sqlext.h:269
#define SQL_CONCUR_VALUES
Definition: sqlext.h:345
#define SQL_UB_OFF
Definition: sqlext.h:372
#define SQL_ATTR_SIMULATE_CURSOR
Definition: sqlext.h:280
#define SQL_RD_ON
Definition: sqlext.h:368
#define SQL_CONCUR_READ_ONLY
Definition: sqlext.h:342
#define SQL_SC_NON_UNIQUE
Definition: sqlext.h:362
#define SQL_C_SLONG
Definition: sqlext.h:553
#define SQL_CURSOR_KEYSET_DRIVEN
Definition: sqlext.h:350
#define SQL_ATTR_ROW_BIND_OFFSET_PTR
Definition: sqlext.h:273
#define SQL_ATTR_PARAM_STATUS_PTR
Definition: sqlext.h:268
#define SQL_ATTR_FETCH_BOOKMARK_PTR
Definition: sqlext.h:260
#define SQL_ATTR_CURSOR_TYPE
Definition: sqlext.h:258
#define SQL_ATTR_PARAM_OPERATION_PTR
Definition: sqlext.h:267
#define SQL_CONCUR_LOCK
Definition: sqlext.h:343
#define SQL_ATTR_QUERY_TIMEOUT
Definition: sqlext.h:271
#define SQL_ATTR_PARAM_BIND_TYPE
Definition: sqlext.h:266
#define SQL_ATTR_ENABLE_AUTO_IPD
Definition: sqlext.h:259
#define SQL_ATTR_RETRIEVE_DATA
Definition: sqlext.h:272
#define SQL_ATTR_KEYSET_SIZE
Definition: sqlext.h:261
#define SQL_CURSOR_DYNAMIC
Definition: sqlext.h:351
#define SQL_ATTR_MAX_ROWS
Definition: sqlext.h:263
#define SQL_ATTR_ROW_BIND_TYPE
Definition: sqlext.h:274
#define SQL_ATTR_CONCURRENCY
Definition: sqlext.h:257
#define SQL_ATTR_PARAMSET_SIZE
Definition: sqlext.h:270
#define SQL_CURSOR_STATIC
Definition: sqlext.h:352
#define SQL_ATTR_PARAM_BIND_OFFSET_PTR
Definition: sqlext.h:265
#define SQL_ATTR_ROW_NUMBER
Definition: sqlext.h:275
#define SQL_RD_OFF
Definition: sqlext.h:367
#define SQL_CONCUR_ROWVER
Definition: sqlext.h:344
#define SQL_UB_FIXED
Definition: sqlext.h:378
#define SQL_ATTR_ASYNC_ENABLE
Definition: sqlext.h:256
#define SQL_ATTR_USE_BOOKMARKS
Definition: sqlext.h:281
#define SQL_UB_VARIABLE
Definition: sqlext.h:379
#define SQL_ATTR_MAX_LENGTH
Definition: sqlext.h:262
void * SQLPOINTER
Definition: sqltypes.h:195
long SQLINTEGER
Definition: sqltypes.h:176
signed short int SQLSMALLINT
Definition: sqltypes.h:201
SQLSMALLINT SQLRETURN
Definition: sqltypes.h:210
test_type_t type
Definition: attributes.c:161
const struct lookup_int * lookup
Definition: attributes.c:162
const char * name
Definition: attributes.c:159
const char * name
Definition: attributes.c:45
Modified on Thu Mar 28 17:04:57 2024 by modify_doxy.py rev. 669887