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

Go to the SVN repository for this file.

1 #define MSDBLIB 1
2 #include "common.h"
3 
4 #include <common/test_assert.h>
5 
6 static void
7 dump_addr(FILE *out, const char *msg, const void *p, size_t len)
8 {
9  size_t n;
10  if (msg)
11  fprintf(out, "%s", msg);
12  for (n = 0; n < len; ++n)
13  fprintf(out, " %02X", ((unsigned char*) p)[n]);
14  fprintf(out, "\n");
15 }
16 
17 static void
18 chk(RETCODE ret, const char *msg)
19 {
20  printf("%s: res %d\n", msg, ret);
21  if (ret == SUCCEED)
22  return;
23  fprintf(stderr, "error: %s\n", msg);
24  exit(1);
25 }
26 
27 static void
29 {
30  /* 27213 == math.floor(math.log(10,256)*65536) */
31  unsigned len = 4u+num->precision*27213u/65536u;
32  if (num->precision < 1 || num->precision > 77)
33  return;
34  assert(len >= 4 && len <= sizeof(*num));
35  memset(((char*) num) + len, 0, sizeof(*num) - len);
36 }
37 
38 static int msdblib;
39 
40 static void
41 test(int bind_type, const char *bind_name, int override_prec, int override_scale, int out_prec, int out_scale, int line)
42 {
43  LOGINREC *login;
45  DBNUMERIC *num = NULL, *num2 = NULL;
46  RETCODE ret;
47  DBTYPEINFO ti;
48  int i;
49 
50  printf("*** Starting test msdblib %d bind %s prec %d scale %d out prec %d out scale %d line %d\n",
51  msdblib, bind_name, override_prec, override_scale, out_prec, out_scale, line);
52  chk(sql_rewind(), "sql_rewind");
53  login = dblogin();
54 
57  DBSETLAPP(login, "numeric");
58  dbsetmaxprocs(25);
60 
63  login = NULL;
64  if (strlen(DATABASE))
66 
67  sql_cmd(dbproc);
69  while (dbresults(dbproc) != NO_MORE_RESULTS) {
70  /* nop */
71  }
72 
73  sql_cmd(dbproc);
75  while (dbresults(dbproc) != NO_MORE_RESULTS) {
76  /* nop */
77  }
78 
79  if (DBTDS_5_0 < DBTDS(dbproc)) {
80  ret = dbcmd(dbproc,
81  "SET ARITHABORT ON;"
82  "SET CONCAT_NULL_YIELDS_NULL ON;"
83  "SET ANSI_NULLS ON;"
84  "SET ANSI_NULL_DFLT_ON ON;"
85  "SET ANSI_PADDING ON;"
86  "SET ANSI_WARNINGS ON;"
87  "SET ANSI_NULL_DFLT_ON ON;"
88  "SET CURSOR_CLOSE_ON_COMMIT ON;"
89  "SET QUOTED_IDENTIFIER ON");
90  chk(ret, "dbcmd");
91  ret = dbsqlexec(dbproc);
92  chk(ret, "dbsqlexec");
93 
94  ret = dbcancel(dbproc);
95  chk(ret, "dbcancel");
96  }
97 
98  ret = dbrpcinit(dbproc, "testDecimal", 0);
99  chk(ret, "dbrpcinit");
100 
101  num = (DBDECIMAL *) calloc(1, sizeof(DBDECIMAL));
102  ti.scale = 5;
103  ti.precision = 16;
104  ret = dbconvert_ps(dbproc, SYBVARCHAR, (const BYTE *) "123.45", -1, SYBDECIMAL, (BYTE *) num, sizeof(*num), &ti);
105  chk(ret > 0, "dbconvert_ps");
106 
107  ret = dbrpcparam(dbproc, "@idecimal", 0, SYBDECIMAL, -1, sizeof(DBDECIMAL), (BYTE *) num);
108  chk(ret, "dbrpcparam");
109  ret = dbrpcsend(dbproc);
110  chk(ret, "dbrpcsend");
111  ret = dbsqlok(dbproc);
112  chk(ret, "dbsqlok");
113 
114  /* TODO check MS/Sybase format */
115  num2 = (DBDECIMAL *) calloc(1, sizeof(DBDECIMAL));
116  ti.precision = override_prec;
117  ti.scale = override_scale;
118  ret = dbconvert_ps(dbproc, SYBVARCHAR, (const BYTE *) "246.9", -1, SYBDECIMAL, (BYTE *) num2, sizeof(*num2), &ti);
119  chk(ret > 0, "dbconvert_ps");
120 
121  for (i=0; (ret = dbresults(dbproc)) != NO_MORE_RESULTS; ++i) {
122  RETCODE row_code;
123 
124  switch (ret) {
125  case SUCCEED:
126  if (DBROWS(dbproc) == FAIL)
127  continue;
129  printf("dbrows() returned SUCCEED, processing rows\n");
130 
131  memset(num, 0, sizeof(*num));
132  num->precision = out_prec ? out_prec : num2->precision;
133  num->scale = out_scale ? out_scale : num2->scale;
134  dbbind(dbproc, 1, bind_type, 0, (BYTE *) num);
135 
136  while ((row_code = dbnextrow(dbproc)) != NO_MORE_ROWS) {
137  if (row_code == REG_ROW) {
138  zero_end(num);
139  zero_end(num2);
140  if (memcmp(num, num2, sizeof(*num)) != 0) {
141  fprintf(stderr, "Failed. Output results does not match\n");
142  dump_addr(stderr, "got: ", num, sizeof(*num));
143  dump_addr(stderr, "expected: ", num2, sizeof(*num2));
144  exit(1);
145  }
146  } else {
147  /* not supporting computed rows in this unit test */
148  fprintf(stderr, "Failed. Expected a row\n");
149  exit(1);
150  }
151  }
152  break;
153  case FAIL:
154  fprintf(stderr, "dbresults returned FAIL\n");
155  exit(1);
156  default:
157  fprintf(stderr, "unexpected return code %d from dbresults\n", ret);
158  exit(1);
159  }
160  } /* while dbresults */
161 
162  sql_cmd(dbproc);
163 
164  free(num2);
165  free(num);
166 
167  dbclose(dbproc);
168 }
169 
170 #define test(a,b,c,d,e) test(a, #a, b, c, d, e, __LINE__)
171 
172 int
173 main(int argc, char **argv)
174 {
175  read_login_info(argc, argv);
176 
177  /* dbsetversion(DBVERSION_100); */
178  dbinit();
179 
180  /* tests with MS behaviour */
181  msdblib = 1;
182  test(DECIMALBIND, 20, 10, 0, 0);
183  test(NUMERICBIND, 20, 10, 0, 0);
184  test(SRCDECIMALBIND, 20, 10, 0, 0);
185  test(SRCNUMERICBIND, 20, 10, 0, 0);
186  /* in these 2 case MS override what server returns */
187  test(DECIMALBIND, 10, 4, 10, 4);
188  test(NUMERICBIND, 10, 4, 10, 4);
189  test(SRCDECIMALBIND, 20, 10, 10, 4);
190  test(SRCNUMERICBIND, 20, 10, 10, 4);
191 
192  /* tests with Sybase behaviour */
193  msdblib = 0;
194  test(DECIMALBIND, 20, 10, 0, 0);
195  test(NUMERICBIND, 20, 10, 0, 0);
196  test(SRCDECIMALBIND, 20, 10, 0, 0);
197  test(SRCNUMERICBIND, 20, 10, 0, 0);
198  /* no matter what Sybase return always according to source */
199  test(DECIMALBIND, 20, 10, 10, 4);
200  test(NUMERICBIND, 20, 10, 10, 4);
201  test(SRCDECIMALBIND, 20, 10, 10, 4);
202  test(SRCNUMERICBIND, 20, 10, 10, 4);
203 
204  chk(sql_reopen("numeric_2"), "sql_reopen");
205 
206  msdblib = 1;
207  /* on MS use always output */
208  test(DECIMALBIND, 20, 0, 20, 0);
209  test(NUMERICBIND, 19, 0, 19, 0);
210  test(SRCDECIMALBIND, 18, 0, 18, 0);
211  test(SRCNUMERICBIND, 17, 0, 17, 0);
212 
213  msdblib = 0;
214  test(DECIMALBIND, 18, 0, 20, 0);
215  test(NUMERICBIND, 18, 0, 19, 0);
216  /* this is MS only and behave like MS */
217  test(SRCDECIMALBIND, 18, 0, 18, 0);
218  test(SRCNUMERICBIND, 17, 0, 17, 0);
219 
220  dbexit();
221 
222  printf("Succeed\n");
223  return 0;
224 }
225 
char PASSWORD[512]
Definition: common.c:31
char DATABASE[512]
Definition: common.c:32
CS_RETCODE read_login_info(void)
Definition: common.c:71
char SERVER[512]
Definition: common.c:30
static TDSLOGIN * login
Definition: dataread.c:31
RETCODE sql_cmd(DBPROCESS *dbproc)
Definition: common.c:280
RETCODE sql_reopen(const char *fn)
Definition: common.c:317
RETCODE sql_rewind(void)
Definition: common.c:308
static void chk(RETCODE ret, const char *msg)
Definition: numeric.c:18
int main(int argc, char **argv)
Definition: numeric.c:173
static void dump_addr(FILE *out, const char *msg, const void *p, size_t len)
Definition: numeric.c:7
#define test(a, b, c, d, e)
Definition: numeric.c:170
static int msdblib
Definition: numeric.c:38
static void zero_end(DBNUMERIC *num)
Definition: numeric.c:28
DBPROCESS * tdsdbopen(LOGINREC *login, const char *server, int msdblib)
Definition: dblib.c:1174
STATUS dbnextrow(DBPROCESS *dbproc)
Definition: dblib.c:2076
static int bind_type(int sybtype)
Definition: dbpivot.c:424
std::ofstream out("events_result.xml")
main entry point for tests
#define USER
Definition: fastme_common.h:43
#define NULL
Definition: ncbistd.hpp:225
#define DBSETLPWD(x, y)
Set the password in the login packet.
Definition: sybdb.h:1259
#define DBSETLAPP(x, y)
Set the (client) application name in the login packet.
Definition: sybdb.h:1266
#define DBSETLHOST(x, y)
Set the (client) host name in the login packet.
Definition: sybdb.h:1253
#define DBSETLUSER(x, y)
Set the username in the login packet.
Definition: sybdb.h:1256
LOGINREC * dblogin(void)
Allocate a LOGINREC structure.
Definition: dblib.c:719
#define DBTDS(a)
Sybase macro, maps to the internal (lower-case) function.
Definition: sybdb.h:1233
#define DBROWS(x)
Sybase macro mapping to the Microsoft (lower-case) function.
Definition: sybdb.h:881
RETCODE dbresults(DBPROCESS *dbproc)
Set up query results.
Definition: dblib.c:1706
RETCODE dbinit(void)
Initialize db-lib.
Definition: dblib.c:674
RETCODE dbcancel(DBPROCESS *dbproc)
Cancel the current command batch.
Definition: dblib.c:3279
RETCODE dbuse(DBPROCESS *dbproc, const char *name)
Change current database.
Definition: dblib.c:1449
RETCODE dbbind(DBPROCESS *dbproc, int column, int vartype, DBINT varlen, BYTE *varaddr)
Tie a host variable to a resultset column.
Definition: dblib.c:2645
RETCODE dbcmd(DBPROCESS *dbproc, const char cmdstring[])
Append SQL to the command buffer.
Definition: dblib.c:1377
DBINT dbconvert_ps(DBPROCESS *dbproc, int db_srctype, const BYTE *src, DBINT srclen, int db_desttype, BYTE *dest, DBINT destlen, DBTYPEINFO *typeinfo)
Convert one datatype to another.
Definition: dblib.c:2303
RETCODE dbsqlexec(DBPROCESS *dbproc)
send the SQL command to the server and wait for an answer.
Definition: dblib.c:1423
void dbloginfree(LOGINREC *login)
free the LOGINREC
Definition: dblib.c:751
void dbexit()
Close server connections and free all related structures.
Definition: dblib.c:1559
RETCODE dbsqlok(DBPROCESS *dbproc)
Wait for results of a query from the server.
Definition: dblib.c:4722
void dbclose(DBPROCESS *dbproc)
Close a connection to the server and free associated resources.
Definition: dblib.c:1492
RETCODE dbsetmaxprocs(int maxprocs)
Set maximum simultaneous connections db-lib will open to the server.
Definition: dblib.c:3994
RETCODE dbrpcinit(DBPROCESS *dbproc, const char rpcname[], DBSMALLINT options)
Initialize a remote procedure call.
Definition: rpc.c:72
RETCODE dbrpcparam(DBPROCESS *dbproc, const char paramname[], BYTE status, int db_type, DBINT maxlen, DBINT datalen, BYTE *value)
Add a parameter to a remote procedure call.
Definition: rpc.c:155
RETCODE dbrpcsend(DBPROCESS *dbproc)
Execute the procedure and free associated memory.
Definition: rpc.c:281
exit(2)
int i
yy_size_t n
int len
#define assert(x)
Definition: srv_diag.hpp:58
unsigned char scale
Definition: sybdb.h:279
unsigned char precision
Definition: sybdb.h:278
DBINT precision
Definition: sybdb.h:339
DBINT scale
Definition: sybdb.h:340
#define REG_ROW
Definition: sybdb.h:580
#define SYBVARCHAR
Definition: sybdb.h:162
#define SRCNUMERICBIND
Definition: sybdb.h:565
#define NUMERICBIND
Definition: sybdb.h:563
int RETCODE
Definition: sybdb.h:121
#define SRCDECIMALBIND
Definition: sybdb.h:566
unsigned char BYTE
Definition: sybdb.h:334
#define NO_MORE_ROWS
Definition: sybdb.h:582
#define SYBDECIMAL
Definition: sybdb.h:204
#define SUCCEED
Definition: sybdb.h:585
#define DECIMALBIND
Definition: sybdb.h:564
#define DBTDS_5_0
Definition: sybdb.h:97
#define FAIL
Definition: sybdb.h:586
#define NO_MORE_RESULTS
Definition: sybdb.h:584
DBPROCESS * dbproc
Definition: t0013.c:18
void free(voidpf ptr)
voidp calloc(uInt items, uInt size)
Modified on Wed Dec 06 07:12:12 2023 by modify_doxy.py rev. 669887