~drizzle-trunk/libdrizzle/jenkins-Libdrizzle-80

« back to all changes in this revision

Viewing changes to tests/unit/datetypes.c

  • Committer: Continuous Integration
  • Date: 2013-03-21 10:44:02 UTC
  • mfrom: (108.1.7 libdrizzle)
  • Revision ID: ci@drizzle.org-20130321104402-9alevcsgdw6fo2k0
Merge lp:~wiml/libdrizzle/unit-tests Build: jenkins-Libdrizzle-75

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 
2
 *
 
3
 *  Drizzle Client & Protocol Library
 
4
 *
 
5
 * Copyright (C) 2013 Drizzle Developer Group
 
6
 * All rights reserved.
 
7
 *
 
8
 * Redistribution and use in source and binary forms, with or without
 
9
 * modification, are permitted provided that the following conditions are
 
10
 * met:
 
11
 *
 
12
 *     * Redistributions of source code must retain the above copyright
 
13
 * notice, this list of conditions and the following disclaimer.
 
14
 *
 
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
 
18
 * distribution.
 
19
 *
 
20
 *     * The names of its contributors may not be used to endorse or
 
21
 * promote products derived from this software without specific prior
 
22
 * written permission.
 
23
 *
 
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.
 
35
 *
 
36
 */
 
37
 
 
38
#include <yatl/lite.h>
 
39
#include "tests/unit/common.h"
 
40
 
 
41
#include <libdrizzle-5.1/libdrizzle.h>
 
42
 
 
43
#include <stdio.h>
 
44
#include <string.h>
 
45
#include <stdlib.h>
 
46
#include <inttypes.h>
 
47
 
 
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);
 
49
 
 
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);
 
51
 
 
52
static const drizzle_column_type_t expected_column_types[10] = {
 
53
  DRIZZLE_COLUMN_TYPE_NONE, /* Columns are 1-indexed */
 
54
  
 
55
  DRIZZLE_COLUMN_TYPE_LONG,
 
56
  
 
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,
 
66
};
 
67
 
 
68
static const char *column_names[10] = {
 
69
  NULL,
 
70
  "a", "b", "c", "d", "e", "f", "g", "h", "i"
 
71
};
 
72
 
 
73
int main(int argc, char *argv[])
 
74
{
 
75
  (void) argc;
 
76
  (void) argv;
 
77
  drizzle_result_st *result;
 
78
  drizzle_return_t driz_ret;
 
79
  drizzle_row_t row;
 
80
  int num_fields;
 
81
  const char *query;
 
82
  drizzle_stmt_st *sth;
 
83
  unsigned rows_in_table;
 
84
  
 
85
  set_up_connection();
 
86
  set_up_schema();
 
87
  
 
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))");
 
89
  rows_in_table = 0;
 
90
  
 
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);
 
96
  rows_in_table += 2;
 
97
    
 
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);
 
102
  
 
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));
 
113
 
 
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);
 
118
  rows_in_table ++;
 
119
  
 
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));
 
130
 
 
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);
 
135
  rows_in_table ++;  
 
136
 
 
137
  CHECK(drizzle_stmt_close(sth));
 
138
 
 
139
  /* Read the table back, with values sent over the wire in text form */
 
140
  CHECKED_QUERY("select * from libdrizzle.dt1 order by a");
 
141
  
 
142
  drizzle_result_buffer(result);
 
143
  num_fields= drizzle_result_column_count(result);
 
144
  
 
145
  ASSERT_EQ_(num_fields, 9, "Retrieved bad number of fields");
 
146
  
 
147
  unsigned int cur_row= 0;
 
148
  drizzle_column_st *column;
 
149
  while ((row = drizzle_row_next(result)))
 
150
  {
 
151
    drizzle_column_seek(result, 0);
 
152
    int cur_column= 0;
 
153
    cur_row++;
 
154
    ASSERT_EQ(drizzle_row_current(result), cur_row);
 
155
    ASSERT_TRUE(cur_row <= 4);
 
156
    
 
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);
 
160
    
 
161
    while ((column= drizzle_column_next(result)))
 
162
    {
 
163
      cur_column++;
 
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]);
 
169
    }
 
170
    ASSERT_EQ_(cur_column, 9, "Wrong column count");
 
171
    
 
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]);
 
179
    }
 
180
 
 
181
    if (cur_row == 2) {
 
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]);
 
187
    }
 
188
    
 
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]);
 
194
    }
 
195
  }
 
196
  ASSERT_EQ_(cur_row, rows_in_table, "Retrieved bad number of rows");
 
197
  
 
198
  drizzle_result_free(result);
 
199
 
 
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);
 
208
  
 
209
  ASSERT_EQ(rows_in_table, drizzle_stmt_row_count(sth));
 
210
  cur_row = 0;
 
211
  while (drizzle_stmt_fetch(sth) != DRIZZLE_RETURN_ROW_END)
 
212
  {
 
213
    size_t lth;
 
214
    const char *col_strval;
 
215
    int col_intval;
 
216
    
 
217
    cur_row ++;
 
218
    printf("Row %d\n", cur_row);
 
219
    
 
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);
 
223
    
 
224
#define ASSERT_COL_STREQ_(coln, expected, ...) \
 
225
    col_strval = drizzle_stmt_get_string(sth, coln-1, &lth, &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);
 
229
 
 
230
    switch (cur_row) {
 
231
      case 1:
 
232
      case 3:
 
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");
 
239
        break;
 
240
      case 2:
 
241
      case 4:
 
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");
 
247
        break;
 
248
    }
 
249
    
 
250
    if (cur_row == 2) {
 
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 */
 
254
    }
 
255
 
 
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. */
 
257
    
 
258
    col_intval = drizzle_stmt_get_int(sth, 3-1, &driz_ret);
 
259
    ASSERT_EQ(driz_ret, DRIZZLE_RETURN_OK);
 
260
    switch (cur_row) {
 
261
    case 1:
 
262
    case 3:
 
263
      ASSERT_EQ(2112, col_intval);
 
264
      break;
 
265
    case 2:
 
266
    case 4:
 
267
      ASSERT_EQ(2012, col_intval);
 
268
      break;
 
269
    }
 
270
  }
 
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));
 
274
 
 
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",
 
280
             col_name, col_name);
 
281
    query = query_buf;
 
282
 
 
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);
 
289
  
 
290
    free(query_buf);
 
291
    query_buf = NULL;
 
292
    query = NULL;
 
293
 
 
294
    ASSERT_EQ(rows_in_table, drizzle_stmt_row_count(sth));
 
295
    cur_row = 0;
 
296
    while (drizzle_stmt_fetch(sth) != DRIZZLE_RETURN_ROW_END)
 
297
    {
 
298
      size_t server_strval_lth, drizzle_strval_lth;
 
299
      const char *server_strval, *drizzle_strval;
 
300
 
 
301
      cur_row ++;
 
302
      
 
303
      unsigned columnA = drizzle_stmt_get_int(sth, 0, &driz_ret);
 
304
      ASSERT_EQ(driz_ret, DRIZZLE_RETURN_OK);
 
305
      
 
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);
 
309
 
 
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);
 
313
      
 
314
      printf("row=%u col=%s: '%s' / '%s'\n",
 
315
             columnA, col_name, drizzle_strval, server_strval);
 
316
 
 
317
      ASSERT_STREQ_(server_strval, drizzle_strval, "Row %u, column '%s': server strval does not match libdrizzle strval", columnA, col_name);
 
318
    }
 
319
    ASSERT_EQ(rows_in_table, cur_row);
 
320
    
 
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));
 
323
  }
 
324
  
 
325
  CHECKED_QUERY("DROP TABLE libdrizzle.dt1");
 
326
  
 
327
  tear_down_schema();
 
328
    
 
329
  return EXIT_SUCCESS;
 
330
}