~drizzle-trunk/drizzle/development

1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1
/*
2
 * Drizzle Client & Protocol Library
3
 *
4
 * Copyright (C) 2008 Eric Day (eday@oddments.org)
5
 * All rights reserved.
6
 *
1971.2.1 by kalebral at gmail
update files that did not have license or had incorrect license structure
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions are
9
 * met:
10
 *
11
 *     * Redistributions of source code must retain the above copyright
12
 * notice, this list of conditions and the following disclaimer.
13
 *
14
 *     * Redistributions in binary form must reproduce the above
15
 * copyright notice, this list of conditions and the following disclaimer
16
 * in the documentation and/or other materials provided with the
17
 * distribution.
18
 *
19
 *     * The names of its contributors may not be used to endorse or
20
 * promote products derived from this software without specific prior
21
 * written permission.
22
 *
23
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
 *
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
35
 */
36
1971.2.1 by kalebral at gmail
update files that did not have license or had incorrect license structure
37
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
38
#include <config.h>
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
39
40
#include <errno.h>
41
#include <stdbool.h>
42
#include <stdint.h>
43
#include <stdio.h>
44
#include <stdlib.h>
45
#include <string.h>
46
#include <unistd.h>
47
2449.1.2 by Brian Aker
Additional fixes for libdrizzle.
48
#include <libdrizzle-2.0/drizzle_client.h>
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
49
50
typedef enum
51
{
52
  CLIENT_QUERY,
53
  CLIENT_FIELDS,
54
  CLIENT_ROWS
55
} client_state;
56
57
typedef enum
58
{
59
  BUFFER_NONE,
60
  BUFFER_FIELD,
61
  BUFFER_ROW,
62
  BUFFER_ALL
63
} buffer_level;
64
65
typedef struct
66
{
67
  drizzle_con_st con;
68
  drizzle_result_st result;
69
  drizzle_column_st column;
70
  client_state state;
71
  uint64_t row;
72
} client_con_st;
73
74
typedef struct
75
{
2463.1.2 by Brian Aker
First pass, drizzle_create() no longer takes an argument. This means that we can now change drizzle_st without being concerned about ABI.
76
  drizzle_st *drizzle;
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
77
  bool mysql_protocol;
78
  client_con_st *client_con_list;
79
  uint32_t client_con_count;
80
  buffer_level level;
81
  char *query;
82
  size_t query_len;
83
} client_st;
84
85
char client_process(client_st *client, client_con_st *client_con);
86
void con_info(drizzle_con_st *con);
87
void result_info(drizzle_result_st *result);
88
void column_info(drizzle_column_st *column);
89
90
#define CLIENT_ERROR(__function, __ret, __client) { \
2463.1.2 by Brian Aker
First pass, drizzle_create() no longer takes an argument. This means that we can now change drizzle_st without being concerned about ABI.
91
    fprintf(stderr, __function ":%d:%s\n", __ret, \
92
           drizzle_error(((__client)->drizzle))); \
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
93
    exit(1); }
94
95
int main(int argc, char *argv[])
96
{
97
  client_st client;
98
  int c;
99
  char blocking= 0;
100
  drizzle_return_t ret;
101
  uint32_t x;
102
  int wait_for_connections= 0;
103
  client_con_st *client_con;
104
  char *host= NULL;
105
  in_port_t port= 0;
106
  char *user= NULL;
107
  char *password= NULL;
108
  char *db= NULL;
109
110
  memset(&client, 0, sizeof(client_st));
111
112
  /* Use one connection by default. */
113
  client.client_con_count= 1;
114
115
  while ((c = getopt(argc, argv, "bB:c:d:h:Hmp:P:u:")) != -1)
116
  {
117
    switch(c)
118
    {
119
    case 'b':
120
      blocking= 1;
121
      break;
122
123
    case 'B':
124
      if (!strcasecmp(optarg, "none"))
125
        client.level= BUFFER_NONE;
126
      else if (!strcasecmp(optarg, "field"))
127
        client.level= BUFFER_FIELD;
128
      else if (!strcasecmp(optarg, "row"))
129
        client.level= BUFFER_ROW;
130
      else if (!strcasecmp(optarg, "all"))
131
        client.level= BUFFER_ALL;
132
      else
133
      {
2463.1.3 by Brian Aker
Redo the way options are handled.
134
        fprintf(stderr, "Invalid buffer level: %s\n", optarg);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
135
        exit(0);
136
      }
137
      break;
138
139
    case 'c':
140
      client.client_con_count= (uint32_t)atoi(optarg);
141
      break;
142
143
    case 'd':
144
      db= optarg;
145
      break;
146
147
    case 'h':
148
      host= optarg;
149
      break;
150
151
    case 'm':
152
      client.mysql_protocol= true;
153
      break;
154
155
    case 'p':
156
      password= optarg;
157
      break;
158
159
    case 'P':
160
      port= (in_port_t)atoi(optarg);
161
      break;
162
163
    case 'u':
164
      user= optarg;
165
      break;
166
167
    case 'H':
168
    default:
169
      printf("\nUsage: %s [options] [query]\n", argv[0]);
170
      printf("\t-b            - Use blocking sockets\n");
171
      printf("\t-B <level>    - Use buffer <level>, options are:\n");
172
      printf("\t                none - Don't buffer anything (default)\n");
173
      printf("\t                field - Only buffer individual fields\n");
174
      printf("\t                row - Only buffer individual rows\n");
175
      printf("\t                all - Buffer entire result\n");
176
      printf("\t-c <cons>     - Create <cons> connections\n");
177
      printf("\t-d <db>       - Use <db> for the connection\n");
178
      printf("\t-h <host>     - Connect to <host>\n");
179
      printf("\t-H            - Print this help menu\n");
180
      printf("\t-m            - Use MySQL protocol\n");
181
      printf("\t-p <password> - Use <password> for authentication\n");
182
      printf("\t-P <port>     - Connect to <port>\n");
183
      printf("\t-u <user>     - Use <user> for authentication\n");
184
      exit(0);
185
    }
186
  }
187
188
  if (argc != optind)
189
  {
190
    client.query= argv[optind];
191
    client.query_len= strlen(client.query);
192
  }
193
194
  if (client.client_con_count > 0)
195
  {
1992.6.2 by Monty Taylor
Cleaned up for additional gcc 4.5 warnings.
196
    client.client_con_list= (client_con_st *)calloc(client.client_con_count,
197
                                                    sizeof(client_con_st));
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
198
    if (client.client_con_list == NULL)
199
    {
2463.1.3 by Brian Aker
Redo the way options are handled.
200
      fprintf(stderr, "calloc:%d\n", errno);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
201
      exit(1);
202
    }
203
  }
204
205
  /* This may fail if there is other initialization that fails. See docs. */
2463.1.2 by Brian Aker
First pass, drizzle_create() no longer takes an argument. This means that we can now change drizzle_st without being concerned about ABI.
206
  if ((client.drizzle= drizzle_create()) == NULL)
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
207
  {
2463.1.3 by Brian Aker
Redo the way options are handled.
208
    fprintf(stderr, "drizzle_create failed\n");
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
209
    exit(1);
210
  }
211
212
  if (blocking == 0)
2463.1.2 by Brian Aker
First pass, drizzle_create() no longer takes an argument. This means that we can now change drizzle_st without being concerned about ABI.
213
  {
2463.1.3 by Brian Aker
Redo the way options are handled.
214
    drizzle_set_option(client.drizzle, DRIZZLE_NON_BLOCKING, true);
2463.1.2 by Brian Aker
First pass, drizzle_create() no longer takes an argument. This means that we can now change drizzle_st without being concerned about ABI.
215
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
216
217
  /* Start all connections, and if in non-blocking mode, return as soon as the
218
     connection would block. In blocking mode, this completes the entire
219
     connection/query/result. */
220
  for (x= 0; x < client.client_con_count; x++)
221
  {
222
    /* This may fail if there is other initialization that fails. See docs. */
2463.1.4 by Brian Aker
Remove con from being passed object.
223
    drizzle_con_st *con= drizzle_con_add_tcp(client.drizzle,
224
                                             host, port, user, password, db,
225
                                             client.mysql_protocol
226
                                             ? DRIZZLE_CON_MYSQL
227
                                             : DRIZZLE_CON_NONE);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
228
    if (con == NULL)
2463.1.2 by Brian Aker
First pass, drizzle_create() no longer takes an argument. This means that we can now change drizzle_st without being concerned about ABI.
229
    {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
230
      CLIENT_ERROR("drizzle_con_add_tcp", 0, &client);
2463.1.2 by Brian Aker
First pass, drizzle_create() no longer takes an argument. This means that we can now change drizzle_st without being concerned about ABI.
231
    }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
232
    drizzle_con_set_context(&(client.client_con_list[x].con),
233
                            &(client.client_con_list[x]));
234
235
    if (client_process(&client, &(client.client_con_list[x])) == 1)
236
      wait_for_connections++;
237
  }
238
239
  /* If in non-blocking mode, continue to process connections as they become
240
     ready. Loop exits when all connections have completed. */
241
  while (wait_for_connections != 0)
242
  {
2463.1.2 by Brian Aker
First pass, drizzle_create() no longer takes an argument. This means that we can now change drizzle_st without being concerned about ABI.
243
    ret= drizzle_con_wait(client.drizzle);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
244
    if (ret != DRIZZLE_RETURN_OK)
2463.1.2 by Brian Aker
First pass, drizzle_create() no longer takes an argument. This means that we can now change drizzle_st without being concerned about ABI.
245
    {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
246
      CLIENT_ERROR("drizzle_con_wait", ret, &client);
2463.1.2 by Brian Aker
First pass, drizzle_create() no longer takes an argument. This means that we can now change drizzle_st without being concerned about ABI.
247
    }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
248
2463.1.4 by Brian Aker
Remove con from being passed object.
249
    drizzle_con_st* con;
2463.1.2 by Brian Aker
First pass, drizzle_create() no longer takes an argument. This means that we can now change drizzle_st without being concerned about ABI.
250
    while ((con= drizzle_con_ready(client.drizzle)) != NULL)
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
251
    {
252
      client_con= (client_con_st *)drizzle_con_context(con);
253
254
      if (client_process(&client, client_con) == 0)
2463.1.2 by Brian Aker
First pass, drizzle_create() no longer takes an argument. This means that we can now change drizzle_st without being concerned about ABI.
255
      {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
256
        wait_for_connections--;
2463.1.2 by Brian Aker
First pass, drizzle_create() no longer takes an argument. This means that we can now change drizzle_st without being concerned about ABI.
257
      }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
258
    }
259
  }
260
261
  for (x= 0; x < client.client_con_count; x++)
2463.1.2 by Brian Aker
First pass, drizzle_create() no longer takes an argument. This means that we can now change drizzle_st without being concerned about ABI.
262
  {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
263
    drizzle_con_free(&(client.client_con_list[x].con));
2463.1.2 by Brian Aker
First pass, drizzle_create() no longer takes an argument. This means that we can now change drizzle_st without being concerned about ABI.
264
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
265
2463.1.2 by Brian Aker
First pass, drizzle_create() no longer takes an argument. This means that we can now change drizzle_st without being concerned about ABI.
266
  drizzle_free(client.drizzle);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
267
2353.3.1 by Mark Atwood
fix cppcheck redundantIfDelete0 warnings. It is safe to deallocate a NULL pointer
268
  free(client.client_con_list);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
269
270
  return 0;
271
}
272
273
char client_process(client_st *client, client_con_st *client_con)
274
{
275
  drizzle_return_t ret;
276
  drizzle_column_st *column;
277
  size_t offset= 0;
278
  size_t length;
279
  size_t total;
280
  drizzle_field_t field;
281
  drizzle_row_t row;
282
  size_t *field_sizes;
283
  uint16_t x;
284
285
  switch (client_con->state)
286
  {
287
  case CLIENT_QUERY:
288
    if (client->query == NULL)
289
      break;
290
291
    /* This may fail if some allocation fails, but it will set ret. */
292
    (void)drizzle_query(&(client_con->con), &(client_con->result),
293
                        client->query, client->query_len, &ret);
294
    if (ret == DRIZZLE_RETURN_IO_WAIT)
2463.1.2 by Brian Aker
First pass, drizzle_create() no longer takes an argument. This means that we can now change drizzle_st without being concerned about ABI.
295
    {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
296
      return 1;
2463.1.2 by Brian Aker
First pass, drizzle_create() no longer takes an argument. This means that we can now change drizzle_st without being concerned about ABI.
297
    }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
298
    else if (ret != DRIZZLE_RETURN_OK)
2463.1.2 by Brian Aker
First pass, drizzle_create() no longer takes an argument. This means that we can now change drizzle_st without being concerned about ABI.
299
    {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
300
      CLIENT_ERROR("drizzle_query", ret, client);
2463.1.2 by Brian Aker
First pass, drizzle_create() no longer takes an argument. This means that we can now change drizzle_st without being concerned about ABI.
301
    }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
302
303
    result_info(&(client_con->result));
304
305
    if (drizzle_result_column_count(&(client_con->result)) == 0)
2463.1.2 by Brian Aker
First pass, drizzle_create() no longer takes an argument. This means that we can now change drizzle_st without being concerned about ABI.
306
    {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
307
      break;
2463.1.2 by Brian Aker
First pass, drizzle_create() no longer takes an argument. This means that we can now change drizzle_st without being concerned about ABI.
308
    }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
309
310
    client_con->state= CLIENT_FIELDS;
311
312
  case CLIENT_FIELDS:
313
    if (client->level == BUFFER_ALL)
314
    {
315
      ret= drizzle_result_buffer(&(client_con->result));
316
      if (ret == DRIZZLE_RETURN_IO_WAIT)
2463.1.2 by Brian Aker
First pass, drizzle_create() no longer takes an argument. This means that we can now change drizzle_st without being concerned about ABI.
317
      {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
318
        return 1;
2463.1.2 by Brian Aker
First pass, drizzle_create() no longer takes an argument. This means that we can now change drizzle_st without being concerned about ABI.
319
      }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
320
      else if (ret != DRIZZLE_RETURN_OK)
2463.1.2 by Brian Aker
First pass, drizzle_create() no longer takes an argument. This means that we can now change drizzle_st without being concerned about ABI.
321
      {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
322
        CLIENT_ERROR("drizzle_result_buffer", ret, client);
2463.1.2 by Brian Aker
First pass, drizzle_create() no longer takes an argument. This means that we can now change drizzle_st without being concerned about ABI.
323
      }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
324
325
      while ((column= drizzle_column_next(&(client_con->result))) != NULL)
326
        column_info(column);
327
    }
328
    else
329
    {
330
      while (1)
331
      {
332
        column= drizzle_column_read(&(client_con->result),
333
                                    &(client_con->column), &ret);
334
        if (ret == DRIZZLE_RETURN_IO_WAIT)
2463.1.3 by Brian Aker
Redo the way options are handled.
335
        {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
336
          return 1;
2463.1.3 by Brian Aker
Redo the way options are handled.
337
        }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
338
        else if (ret != DRIZZLE_RETURN_OK)
2463.1.3 by Brian Aker
Redo the way options are handled.
339
        {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
340
          CLIENT_ERROR("drizzle_column_read", ret, client);
2463.1.3 by Brian Aker
Redo the way options are handled.
341
        }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
342
343
        if (column == NULL)
344
          break;
345
346
        column_info(column);
347
        drizzle_column_free(column);
348
      }
349
    }
350
351
    client_con->state= CLIENT_ROWS;
352
353
  case CLIENT_ROWS:
354
    if (client->level == BUFFER_ALL)
355
    {
356
      /* Everything has been buffered, just loop through and print. */
357
      while ((row= drizzle_row_next(&(client_con->result))) != NULL)
358
      {
359
        field_sizes= drizzle_row_field_sizes(&(client_con->result));
360
2463.1.3 by Brian Aker
Redo the way options are handled.
361
        printf("Row: %" PRId64 "\n", drizzle_row_current(&(client_con->result)));
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
362
363
        for (x= 0; x < drizzle_result_column_count(&(client_con->result)); x++)
364
        {
365
          if (row[x] == NULL)
2463.1.3 by Brian Aker
Redo the way options are handled.
366
          {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
367
            printf("     (NULL)\n");
2463.1.3 by Brian Aker
Redo the way options are handled.
368
          }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
369
          else
370
          {
2463.1.3 by Brian Aker
Redo the way options are handled.
371
            printf("     (%"PRIu64") %.*s\n", static_cast<uint64_t>(field_sizes[x]), (int32_t)field_sizes[x], row[x]);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
372
          }
373
        }
374
375
        printf("\n");
376
      }
377
378
      drizzle_result_free(&(client_con->result));
379
      break;
380
    }
381
382
    while (1)
383
    {
384
      if (client->level == BUFFER_NONE || client->level == BUFFER_FIELD)
385
      {
386
        /* Still need to read a row at a time, and then each field. */
387
        if (client_con->row == 0)
388
        {
389
          client_con->row= drizzle_row_read(&(client_con->result), &ret);
390
          if (ret == DRIZZLE_RETURN_IO_WAIT)
391
          {
392
            client_con->row= 0;
393
            return 1;
394
          }
395
          else if (ret != DRIZZLE_RETURN_OK)
396
            CLIENT_ERROR("drizzle_row", ret, client);
397
398
          if (client_con->row == 0)
399
          {
400
            drizzle_result_free(&(client_con->result));
401
            break;
402
          }
403
404
          printf("Row: %" PRId64 "\n", client_con->row);
405
        }
406
407
        while (1)
408
        {
409
          if (client->level == BUFFER_FIELD)
410
          {
411
            /* Since an entire field is buffered, we don't need to worry about
412
               partial reads. */
413
            field= drizzle_field_buffer(&(client_con->result), &total, &ret);
414
            length= total;
415
          }
416
          else
417
          {
418
            field= drizzle_field_read(&(client_con->result), &offset, &length,
419
                                      &total, &ret);
420
          }
421
422
          if (ret == DRIZZLE_RETURN_IO_WAIT)
423
            return 1;
424
          else if (ret == DRIZZLE_RETURN_ROW_END)
425
            break;
426
          else if (ret != DRIZZLE_RETURN_OK)
427
            CLIENT_ERROR("drizzle_field_read", ret, client);
428
429
          if (field == NULL)
2463.1.3 by Brian Aker
Redo the way options are handled.
430
          {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
431
            printf("     (NULL)");
2463.1.3 by Brian Aker
Redo the way options are handled.
432
          }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
433
          else if (offset > 0)
2463.1.3 by Brian Aker
Redo the way options are handled.
434
          {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
435
            printf("%.*s", (int32_t)length, field);
2463.1.3 by Brian Aker
Redo the way options are handled.
436
          }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
437
          else
2463.1.3 by Brian Aker
Redo the way options are handled.
438
          {
439
            printf("     (%" PRIu64 " %.*s", (uint64_t)total, (int32_t)length, field);
440
          }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
441
442
          if (offset + length == total)
2463.1.3 by Brian Aker
Redo the way options are handled.
443
          {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
444
            printf("\n");
2463.1.3 by Brian Aker
Redo the way options are handled.
445
          }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
446
447
          /* If we buffered the entire field, be sure to free it. */
448
          if (client->level == BUFFER_FIELD)
449
            drizzle_field_free(field);
450
        }
451
452
        client_con->row= 0;
453
        printf("\n");
454
      }
455
      else if (client->level == BUFFER_ROW)
456
      {
457
        /* The entire row will be buffered here, so no need to worry about
458
           partial reads. */
459
        row = drizzle_row_buffer(&(client_con->result), &ret);
460
        if (ret == DRIZZLE_RETURN_IO_WAIT)
461
          return 1;
462
        else if (ret != DRIZZLE_RETURN_OK)
463
          CLIENT_ERROR("drizzle_row", ret, client);
464
465
        /* This marks the end of rows. */
466
        if (row == NULL)
467
          break;
468
469
        field_sizes= drizzle_row_field_sizes(&(client_con->result));
470
471
        printf("Row: %" PRId64 "\n",
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
472
               static_cast<uint64_t>(drizzle_row_current(&(client_con->result))));
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
473
474
        for (x= 0; x < drizzle_result_column_count(&(client_con->result)); x++)
475
        {
476
          if (row[x] == NULL)
477
            printf("     (NULL)\n");
478
          else
479
          {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
480
            printf("     (%" PRIu64 " %.*s\n", static_cast<uint64_t>(field_sizes[x]), (int32_t)field_sizes[x],
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
481
                   row[x]);
482
          }
483
        }
484
485
        drizzle_row_free(&(client_con->result), row);
486
        printf("\n");
487
      }
488
    }
489
490
    drizzle_result_free(&(client_con->result));
491
    break;
492
493
  default:
494
    /* This should be impossible. */
495
    return 1;
496
  }
497
498
  return 0;
499
}
500
501
void con_info(drizzle_con_st *con)
502
{
503
  printf("Connected: protocol_version=%u\n"
504
         "                    version=%s\n"
505
         "                  thread_id=%u\n"
506
         "               capabilities=%u\n"
507
         "                   language=%u\n"
508
         "                     status=%u\n\n",
509
         drizzle_con_protocol_version(con), drizzle_con_server_version(con),
510
         drizzle_con_thread_id(con), drizzle_con_capabilities(con),
511
         drizzle_con_charset(con), drizzle_con_status(con));
512
}
513
514
void result_info(drizzle_result_st *result)
515
{
516
  printf("Result:     row_count=%" PRId64 "\n"
517
         "            insert_id=%" PRId64 "\n"
518
         "        warning_count=%u\n"
519
         "         column_count=%u\n"
520
         "        affected_rows=%" PRId64 "\n\n",
521
         drizzle_result_row_count(result),
522
         drizzle_result_insert_id(result),
523
         drizzle_result_warning_count(result),
524
         drizzle_result_column_count(result),
525
         drizzle_result_affected_rows(result));
526
}
527
528
void column_info(drizzle_column_st *column)
529
{
530
  printf("Field:   catalog=%s\n"
531
         "              db=%s\n"
532
         "           table=%s\n"
533
         "       org_table=%s\n"
534
         "            name=%s\n"
535
         "        org_name=%s\n"
536
         "         charset=%u\n"
537
         "            size=%u\n"
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
538
         "        max_size=%" PRIu64 "\n"
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
539
         "            type=%u\n"
540
         "           flags=%u\n\n",
541
         drizzle_column_catalog(column), drizzle_column_db(column),
542
         drizzle_column_table(column), drizzle_column_orig_table(column),
543
         drizzle_column_name(column), drizzle_column_orig_name(column),
544
         drizzle_column_charset(column), drizzle_column_size(column),
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
545
         static_cast<uint64_t>(drizzle_column_max_size(column)), drizzle_column_type(column),
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
546
         drizzle_column_flags(column));
547
}