1
/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
* Drizzle Client & Protocol Library
5
* Copyright (C) 2013 Drizzle Developer Group
8
* Redistribution and use in source and binary forms, with or without
9
* modification, are permitted provided that the following conditions are
12
* * Redistributions of source code must retain the above copyright
13
* notice, this list of conditions and the following disclaimer.
15
* * Redistributions in binary form must reproduce the above
16
* copyright notice, this list of conditions and the following disclaimer
17
* in the documentation and/or other materials provided with the
20
* * The names of its contributors may not be used to endorse or
21
* promote products derived from this software without specific prior
24
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
#include <yatl/lite.h>
39
#include "tests/unit/common.h"
41
#include <libdrizzle-5.1/libdrizzle.h>
48
#define CHECKED_QUERY(cmd) result = drizzle_query(con, cmd, 0, &driz_ret); ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, from \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), cmd);
50
#define CHECK(s) driz_ret = (s); ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, in \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), #s);
52
static const drizzle_column_type_t expected_column_types[10] = {
53
DRIZZLE_COLUMN_TYPE_NONE, /* Columns are 1-indexed */
55
DRIZZLE_COLUMN_TYPE_LONG,
57
DRIZZLE_COLUMN_TYPE_DATE,
58
DRIZZLE_COLUMN_TYPE_YEAR,
59
DRIZZLE_COLUMN_TYPE_TIMESTAMP,
60
DRIZZLE_COLUMN_TYPE_TIMESTAMP,
61
DRIZZLE_COLUMN_TYPE_TIME,
62
DRIZZLE_COLUMN_TYPE_TIME,
63
DRIZZLE_COLUMN_TYPE_DATETIME,
64
// DRIZZLE_COLUMN_TYPE_NEWDATE,
65
DRIZZLE_COLUMN_TYPE_DATETIME,
68
static const char *column_names[10] = {
70
"a", "b", "c", "d", "e", "f", "g", "h", "i"
73
int main(int argc, char *argv[])
77
drizzle_result_st *result;
78
drizzle_return_t driz_ret;
83
unsigned rows_in_table;
88
CHECKED_QUERY("create table libdrizzle.dt1 (a int primary key not null, b date, c year(4), d timestamp(0), e timestamp(6), f time(0), g time(6), h datetime(0), i datetime(6))");
91
/* Insert rows with pk 1 and 2 */
92
CHECKED_QUERY("insert into libdrizzle.dt1 (a,b,c,d,e,f,g,h,i) values "
93
"(1, '1970-01-01', '2112', '2013-03-13 09:22:00.001', '2013-03-13 09:22:00.001', '6:15:03', '23:59:59.75', '1642-12-25 12:15:01', '1642-12-25 12:12:00.125'),"
94
"(2, '84-02-29', '12', NOW(), NOW(), '3 6:15:03', '23:59:59.0625', '1642-12-25 12:15:01', '1642-12-25 12:12:00.000000');");
95
ASSERT_EQ(drizzle_result_affected_rows(result), 2);
98
/* Insert row with pk 3 and 4 - test marshaling values we transmit */
99
query = "insert into libdrizzle.dt1 (a,b,c,d,e,f,g,h,i) values (?,?,?,?,?,?,?,?,?)";
100
sth = drizzle_stmt_prepare(con, query, strlen(query), &driz_ret);
101
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, preparing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
103
/* Row 3 should be the same as row 1, above */
104
CHECK(drizzle_stmt_set_short(sth, 0, 3, 0));
105
CHECK(drizzle_stmt_set_timestamp(sth, 1, 1970, 1, 1, 0, 0, 0, 0));
106
CHECK(drizzle_stmt_set_int(sth, 2, 2112, 0));
107
CHECK(drizzle_stmt_set_timestamp(sth, 3, 2013, 3, 13, 9, 22, 0, 1000));
108
CHECK(drizzle_stmt_set_timestamp(sth, 4, 2013, 3, 13, 9, 22, 0, 1000));
109
CHECK(drizzle_stmt_set_time(sth, 5, 0, 6, 15, 3, 0, 0));
110
CHECK(drizzle_stmt_set_time(sth, 6, 0, 23, 59, 59, 750000, 0));
111
CHECK(drizzle_stmt_set_timestamp(sth, 7, 1642, 12, 25, 12, 15, 1, 0));
112
CHECK(drizzle_stmt_set_timestamp(sth, 8, 1642, 12, 25, 12, 12, 0, 125000));
114
driz_ret = drizzle_stmt_execute(sth);
115
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, executing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
116
driz_ret = drizzle_stmt_buffer(sth);
117
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, buffering \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
120
/* Row 4 is similar to row 2, above. But 2-digit years aren't automatically y2k-promoted if we send them raw. */
121
CHECK(drizzle_stmt_set_short(sth, 0, 4, 0));
122
CHECK(drizzle_stmt_set_timestamp(sth, 1, 84, 2, 9, 0, 0, 0, 0));
123
CHECK(drizzle_stmt_set_int(sth, 2, 12, 0)); /* 12 will become 2012 because we're sending an int, not a YEAR */
124
CHECK(drizzle_stmt_set_timestamp(sth, 3, 2013, 3, 13, 9, 22, 0, 1000));
125
CHECK(drizzle_stmt_set_timestamp(sth, 4, 2013, 3, 13, 9, 22, 0, 1000));
126
CHECK(drizzle_stmt_set_time(sth, 5, 3, 6, 15, 3, 0, 0));
127
CHECK(drizzle_stmt_set_time(sth, 6, 0, 23, 59, 59, 62500, 0));
128
CHECK(drizzle_stmt_set_timestamp(sth, 7, 1642, 12, 25, 12, 15, 1, 0));
129
CHECK(drizzle_stmt_set_timestamp(sth, 8, 1642, 12, 25, 12, 12, 0, 0));
131
driz_ret = drizzle_stmt_execute(sth);
132
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, executing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
133
driz_ret = drizzle_stmt_buffer(sth);
134
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, buffering \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
137
CHECK(drizzle_stmt_close(sth));
139
/* Read the table back, with values sent over the wire in text form */
140
CHECKED_QUERY("select * from libdrizzle.dt1 order by a");
142
drizzle_result_buffer(result);
143
num_fields= drizzle_result_column_count(result);
145
ASSERT_EQ_(num_fields, 9, "Retrieved bad number of fields");
147
unsigned int cur_row= 0;
148
drizzle_column_st *column;
149
while ((row = drizzle_row_next(result)))
151
drizzle_column_seek(result, 0);
154
ASSERT_EQ(drizzle_row_current(result), cur_row);
155
ASSERT_TRUE(cur_row <= 4);
157
char expected_colA[10];
158
sprintf(expected_colA, "%d", cur_row);
159
ASSERT_EQ_(strcmp(row[0], expected_colA), 0, "Retrieved bad row value; row=%d got=%s expected=%s", cur_row, row[0], expected_colA);
161
while ((column= drizzle_column_next(result)))
164
ASSERT_EQ_(strcmp(drizzle_column_db(column), "libdrizzle"), 0, "Column has bad DB name");
165
ASSERT_EQ_(strcmp(drizzle_column_table(column), "dt1"), 0, "Column %d had bad table name", cur_column);
166
ASSERT_EQ(drizzle_column_current(result), cur_column);
167
ASSERT_STREQ_(drizzle_column_name(column), column_names[cur_column], "Column %d name", cur_column);
168
ASSERT_EQ_(drizzle_column_type(column), expected_column_types[cur_column], "Column %d has type=%d expected=%d", cur_column, drizzle_column_type(column), expected_column_types[cur_column]);
170
ASSERT_EQ_(cur_column, 9, "Wrong column count");
172
if (cur_row == 1 || cur_row == 3) {
173
ASSERT_STREQ("1970-01-01", row[1]);
174
ASSERT_STREQ("2112", row[2]);
175
ASSERT_STREQ("06:15:03", row[5]);
176
ASSERT_STREQ("23:59:59.750000", row[6]);
177
ASSERT_STREQ("1642-12-25 12:15:01", row[7]);
178
ASSERT_STREQ("1642-12-25 12:12:00.125000", row[8]);
182
ASSERT_STREQ("1984-02-29", row[1]);
183
ASSERT_STREQ("2012", row[2]);
184
} else if (cur_row == 4) {
185
ASSERT_STREQ("0084-02-09", row[1]);
186
ASSERT_STREQ("2012", row[2]);
189
if (cur_row == 2 || cur_row == 4) {
190
ASSERT_STREQ("78:15:03", row[5]);
191
ASSERT_STREQ("23:59:59.062500", row[6]);
192
ASSERT_STREQ("1642-12-25 12:15:01", row[7]);
193
ASSERT_STREQ("1642-12-25 12:12:00.000000", row[8]);
196
ASSERT_EQ_(cur_row, rows_in_table, "Retrieved bad number of rows");
198
drizzle_result_free(result);
200
/* Read the table back, with values sent over the wire in binary form */
201
query = "select a,b,c,d,e,f,g,h,i from libdrizzle.dt1 order by a";
202
sth = drizzle_stmt_prepare(con, query, strlen(query), &driz_ret);
203
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, preparing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
204
driz_ret = drizzle_stmt_execute(sth);
205
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, executing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
206
driz_ret = drizzle_stmt_buffer(sth);
207
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, buffering \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
209
ASSERT_EQ(rows_in_table, drizzle_stmt_row_count(sth));
211
while (drizzle_stmt_fetch(sth) != DRIZZLE_RETURN_ROW_END)
214
const char *col_strval;
218
printf("Row %d\n", cur_row);
220
int columnA = drizzle_stmt_get_int(sth, 0, &driz_ret);
221
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, column %d of row %d", drizzle_strerror(driz_ret), drizzle_error(con), 1, cur_row);
222
ASSERT_EQ(cur_row, (unsigned)columnA);
224
#define ASSERT_COL_STREQ_(coln, expected, ...) \
225
col_strval = drizzle_stmt_get_string(sth, coln-1, <h, &driz_ret); \
226
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Fetching column %u of row %u", coln, cur_row); \
227
ASSERT_STREQ_(expected, col_strval, "Stringified value of column %u of row %u", coln, cur_row); \
228
ASSERT_EQ_(lth, strlen(col_strval), "Length of stringified value of column %u of row %u", coln, cur_row);
233
ASSERT_COL_STREQ_(2, "1970-01-01");
234
ASSERT_COL_STREQ_(3, "2112");
235
ASSERT_COL_STREQ_(6, "06:15:03");
236
ASSERT_COL_STREQ_(7, "23:59:59.750000");
237
ASSERT_COL_STREQ_(8, "1642-12-25 12:15:01");
238
ASSERT_COL_STREQ_(9, "1642-12-25 12:12:00.125000");
242
ASSERT_COL_STREQ_(3, "2012");
243
ASSERT_COL_STREQ_(6, "78:15:03");
244
ASSERT_COL_STREQ_(7, "23:59:59.062500");
245
ASSERT_COL_STREQ_(8, "1642-12-25 12:15:01");
246
ASSERT_COL_STREQ_(9, "1642-12-25 12:12:00.000000");
251
ASSERT_COL_STREQ_(2, "1984-02-29");
252
} else if (cur_row == 4) {
253
ASSERT_COL_STREQ_(2, "0084-02-29"); /* Yes, year 84, during the reign of Domitian */
256
/* TODO: libdrizzle currently has no way to give us access to the actual returned values for time/date fields. If that changes, test the values here. */
258
col_intval = drizzle_stmt_get_int(sth, 3-1, &driz_ret);
259
ASSERT_EQ(driz_ret, DRIZZLE_RETURN_OK);
263
ASSERT_EQ(2112, col_intval);
267
ASSERT_EQ(2012, col_intval);
271
ASSERT_EQ(cur_row, rows_in_table);
272
driz_ret = drizzle_stmt_close(sth);
273
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s", drizzle_strerror(driz_ret), drizzle_error(con));
275
/* Check that libdrizzle stringifies values the same way the server does */
276
for (unsigned checking_column = 2; checking_column < 10; checking_column ++) {
277
const char *col_name = column_names[checking_column];
278
char *query_buf = NULL;
279
asprintf(&query_buf, "select a, %s, cast(%s as char) from libdrizzle.dt1",
283
sth = drizzle_stmt_prepare(con, query, strlen(query), &driz_ret);
284
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, preparing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
285
driz_ret = drizzle_stmt_execute(sth);
286
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, executing \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
287
driz_ret = drizzle_stmt_buffer(sth);
288
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s, buffering \"%s\"", drizzle_strerror(driz_ret), drizzle_error(con), query);
294
ASSERT_EQ(rows_in_table, drizzle_stmt_row_count(sth));
296
while (drizzle_stmt_fetch(sth) != DRIZZLE_RETURN_ROW_END)
298
size_t server_strval_lth, drizzle_strval_lth;
299
const char *server_strval, *drizzle_strval;
303
unsigned columnA = drizzle_stmt_get_int(sth, 0, &driz_ret);
304
ASSERT_EQ(driz_ret, DRIZZLE_RETURN_OK);
306
drizzle_strval = drizzle_stmt_get_string(sth, 1, &drizzle_strval_lth, &driz_ret);
307
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Raw column '%s' of row %u", col_name, columnA);
308
ASSERT_EQ(strlen(drizzle_strval), drizzle_strval_lth);
310
server_strval = drizzle_stmt_get_string(sth, 2, &server_strval_lth, &driz_ret);
311
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Cast column '%s' of row %u", col_name, columnA);
312
ASSERT_EQ(strlen(server_strval), server_strval_lth);
314
printf("row=%u col=%s: '%s' / '%s'\n",
315
columnA, col_name, drizzle_strval, server_strval);
317
ASSERT_STREQ_(server_strval, drizzle_strval, "Row %u, column '%s': server strval does not match libdrizzle strval", columnA, col_name);
319
ASSERT_EQ(rows_in_table, cur_row);
321
driz_ret = drizzle_stmt_close(sth);
322
ASSERT_EQ_(driz_ret, DRIZZLE_RETURN_OK, "Error (%s): %s", drizzle_strerror(driz_ret), drizzle_error(con));
325
CHECKED_QUERY("DROP TABLE libdrizzle.dt1");