Line data Source code
1 : #include "common.h"
2 :
3 : #include <stdarg.h>
4 :
5 : static const char *query =
6 : "insert into #ctparam_lang (name,name2,age,cost,bdate,fval) values (@in1, @in2, @in3, @moneyval, @dateval, @floatval)";
7 :
8 : static int insert_test(CS_CONNECTION *conn, CS_COMMAND *cmd, int useNames);
9 :
10 : /* Testing: binding of data via ct_param */
11 10 : TEST_MAIN()
12 : {
13 10 : int errCode = 0;
14 :
15 : CS_CONTEXT *ctx;
16 : CS_CONNECTION *conn;
17 : CS_COMMAND *cmd;
18 10 : int verbose = 0;
19 :
20 : CS_CHAR cmdbuf[4096];
21 :
22 10 : if (argc > 1 && (0 == strcmp(argv[1], "-v")))
23 0 : verbose = 1;
24 :
25 10 : printf("%s: submit language query with variables using ct_param\n", __FILE__);
26 10 : if (verbose) {
27 0 : printf("Trying login\n");
28 : }
29 10 : check_call(try_ctlogin, (&ctx, &conn, &cmd, verbose));
30 10 : error_to_stdout = true;
31 :
32 10 : strcpy(cmdbuf, "create table #ctparam_lang (id numeric identity not null, \
33 : name varchar(30), name2 varchar(20), age int, cost money, bdate datetime, fval float) ");
34 :
35 10 : check_call(run_command, (cmd, cmdbuf));
36 :
37 : /* test by name */
38 10 : errCode = insert_test(conn, cmd, 1);
39 : /* if worked, test by position */
40 10 : if (0 == errCode)
41 10 : errCode = insert_test(conn, cmd, 0);
42 10 : query = "insert into #ctparam_lang (name,name2,age,cost,bdate,fval) values (?, ?, ?, ?, ?, ?)";
43 10 : if (0 == errCode)
44 10 : errCode = insert_test(conn, cmd, 0);
45 :
46 10 : if (verbose && (0 == errCode))
47 0 : printf("lang_ct_param tests successful\n");
48 :
49 10 : if (verbose) {
50 0 : printf("Trying logout\n");
51 : }
52 10 : check_call(try_ctlogout, (ctx, conn, cmd, verbose));
53 :
54 10 : return errCode;
55 : }
56 :
57 : static int
58 30 : insert_test(CS_CONNECTION *conn, CS_COMMAND *cmd, int useNames)
59 : {
60 : CS_CONTEXT *ctx;
61 :
62 : CS_RETCODE ret;
63 : CS_INT res_type;
64 :
65 : CS_DATAFMT datafmt;
66 : CS_DATAFMT srcfmt;
67 : CS_DATAFMT destfmt;
68 : CS_INT intvar;
69 : CS_FLOAT floatvar;
70 : CS_MONEY moneyvar;
71 : CS_DATEREC datevar;
72 : char moneystring[10];
73 : char dummy_name[30];
74 : char dummy_name2[20];
75 : CS_INT destlen;
76 30 : CS_INT rowsAffected = -1;
77 30 : int rows_found = 0;
78 :
79 : /* clear table */
80 30 : run_command(cmd, "delete #ctparam_lang");
81 :
82 : /*
83 : * Assign values to the variables used for parameter passing.
84 : */
85 :
86 30 : intvar = 2;
87 30 : floatvar = 0.12;
88 30 : strcpy(dummy_name, "joe blow");
89 30 : strcpy(dummy_name2, "");
90 30 : strcpy(moneystring, "300.90");
91 :
92 : /*
93 : * Clear and setup the CS_DATAFMT structures used to convert datatypes.
94 : */
95 :
96 30 : memset(&srcfmt, 0, sizeof(CS_DATAFMT));
97 : srcfmt.datatype = CS_CHAR_TYPE;
98 30 : srcfmt.maxlength = (CS_INT) strlen(moneystring);
99 30 : srcfmt.precision = 5;
100 30 : srcfmt.scale = 2;
101 : srcfmt.locale = NULL;
102 :
103 30 : memset(&destfmt, 0, sizeof(CS_DATAFMT));
104 30 : destfmt.datatype = CS_MONEY_TYPE;
105 30 : destfmt.maxlength = sizeof(CS_MONEY);
106 30 : destfmt.precision = 5;
107 30 : destfmt.scale = 2;
108 : destfmt.locale = NULL;
109 :
110 : /*
111 : * Convert the string representing the money value
112 : * to a CS_MONEY variable. Since this routine does not have the
113 : * context handle, we use the property functions to get it.
114 : */
115 30 : check_call(ct_cmd_props, (cmd, CS_GET, CS_PARENT_HANDLE, &conn, CS_UNUSED, NULL));
116 30 : check_call(ct_con_props, (conn, CS_GET, CS_PARENT_HANDLE, &ctx, CS_UNUSED, NULL));
117 30 : check_call(cs_convert, (ctx, &srcfmt, (CS_VOID *) moneystring, &destfmt, &moneyvar, &destlen));
118 :
119 : /*
120 : * create the command
121 : */
122 30 : check_call(ct_command, (cmd, CS_LANG_CMD, (CS_CHAR *) query, (CS_INT) strlen(query), CS_UNUSED));
123 :
124 : /*
125 : * Clear and setup the CS_DATAFMT structure, then pass
126 : * each of the parameters for the query.
127 : */
128 30 : memset(&datafmt, 0, sizeof(datafmt));
129 30 : if (useNames)
130 10 : strcpy(datafmt.name, "@in1");
131 : else
132 : datafmt.name[0] = 0;
133 30 : datafmt.maxlength = 255;
134 30 : datafmt.namelen = CS_NULLTERM;
135 : datafmt.datatype = CS_CHAR_TYPE;
136 30 : datafmt.status = CS_INPUTVALUE;
137 :
138 : /*
139 : * The character string variable is filled in by the RPC so pass NULL
140 : * for the data 0 for data length, and -1 for the indicator arguments.
141 : */
142 30 : check_call(ct_param, (cmd, &datafmt, dummy_name, (CS_INT) strlen(dummy_name), 0));
143 :
144 30 : if (useNames)
145 10 : strcpy(datafmt.name, "@in2");
146 : else
147 20 : datafmt.name[0] = 0;
148 30 : datafmt.maxlength = 255;
149 30 : datafmt.namelen = CS_NULLTERM;
150 30 : datafmt.datatype = CS_CHAR_TYPE;
151 30 : datafmt.status = CS_INPUTVALUE;
152 :
153 30 : check_call(ct_param, (cmd, &datafmt, dummy_name2, (CS_INT) strlen(dummy_name2), 0));
154 :
155 30 : if (useNames)
156 10 : strcpy(datafmt.name, "@in3");
157 : else
158 20 : datafmt.name[0] = 0;
159 30 : datafmt.namelen = CS_NULLTERM;
160 30 : datafmt.datatype = CS_INT_TYPE;
161 30 : datafmt.status = CS_INPUTVALUE;
162 :
163 30 : check_call(ct_param, (cmd, &datafmt, (CS_VOID *) & intvar, CS_SIZEOF(CS_INT), 0));
164 :
165 30 : if (useNames)
166 10 : strcpy(datafmt.name, "@moneyval");
167 : else
168 20 : datafmt.name[0] = 0;
169 30 : datafmt.namelen = CS_NULLTERM;
170 30 : datafmt.datatype = CS_MONEY_TYPE;
171 30 : datafmt.status = CS_INPUTVALUE;
172 :
173 30 : check_call(ct_param, (cmd, &datafmt, (CS_VOID *) & moneyvar, CS_SIZEOF(CS_MONEY), 0));
174 :
175 30 : if (useNames)
176 10 : strcpy(datafmt.name, "@dateval");
177 : else
178 20 : datafmt.name[0] = 0;
179 30 : datafmt.namelen = CS_NULLTERM;
180 30 : datafmt.datatype = CS_DATETIME_TYPE;
181 30 : datafmt.status = CS_INPUTVALUE;
182 30 : memset(&datevar, 0, sizeof(CS_DATEREC));
183 30 : datevar.dateyear = 2003;
184 30 : datevar.datemonth = 2;
185 30 : datevar.datedmonth = 1;
186 :
187 30 : check_call(ct_param, (cmd, &datafmt, &datevar, 0, 0));
188 :
189 30 : if (useNames)
190 10 : strcpy(datafmt.name, "@floatval");
191 : else
192 20 : datafmt.name[0] = 0;
193 30 : datafmt.namelen = CS_NULLTERM;
194 30 : datafmt.datatype = CS_FLOAT_TYPE;
195 30 : datafmt.status = CS_INPUTVALUE;
196 :
197 30 : check_call(ct_param, (cmd, &datafmt, &floatvar, 0, 0));
198 :
199 : /*
200 : * Send the command to the server
201 : */
202 30 : check_call(ct_send, (cmd));
203 :
204 : /*
205 : * Process the results.
206 : */
207 120 : while ((ret = ct_results(cmd, &res_type)) == CS_SUCCEED) {
208 60 : switch ((int) res_type) {
209 :
210 60 : case CS_CMD_SUCCEED:
211 : case CS_CMD_DONE:
212 : {
213 60 : CS_INT rowsAffected=0;
214 60 : ct_res_info(cmd, CS_ROW_COUNT, &rowsAffected, CS_UNUSED, NULL);
215 60 : if (1 != rowsAffected)
216 0 : fprintf(stderr, "insert touched %d rows instead of 1\n", rowsAffected);
217 : else
218 : rows_found = 1;
219 : }
220 60 : break;
221 :
222 0 : case CS_CMD_FAIL:
223 : /*
224 : * The server encountered an error while
225 : * processing our command.
226 : */
227 0 : fprintf(stderr, "ct_results returned CS_CMD_FAIL.\n");
228 0 : break;
229 :
230 0 : case CS_STATUS_RESULT:
231 : /*
232 : * The server encountered an error while
233 : * processing our command.
234 : */
235 0 : fprintf(stderr, "ct_results returned CS_STATUS_RESULT.\n");
236 0 : break;
237 :
238 0 : default:
239 : /*
240 : * We got something unexpected.
241 : */
242 0 : fprintf(stderr, "ct_results returned unexpected result type %d\n", res_type);
243 0 : return 1;
244 : }
245 : }
246 30 : if (ret != CS_END_RESULTS) {
247 0 : fprintf(stderr, "ct_results returned unexpected result %d.\n", (int) ret);
248 0 : exit(1);
249 : }
250 :
251 30 : if (!rows_found) {
252 0 : fprintf(stderr, "expected 1 rows inserted, inserted %d.\n", (int) rowsAffected);
253 0 : exit(1);
254 : }
255 :
256 : /* test row inserted */
257 30 : check_call(run_command, (cmd, "if not exists("
258 : "select * from #ctparam_lang where name = 'joe blow' and name2 is not null and age = 2"
259 : ") select 1"));
260 :
261 30 : return 0;
262 : }
|