2
* Drizzle Client & Protocol Library
4
* Copyright (C) 2008 Eric Day (eday@oddments.org)
7
* Use and distribution licensed under the BSD license. See
8
* the COPYING file in this directory for full text.
21
#include <libdrizzle/drizzle_client.h>
41
drizzle_result_st result;
42
drizzle_column_st column;
51
client_con_st *client_con_list;
52
uint32_t client_con_count;
58
char client_process(client_st *client, client_con_st *client_con);
59
void con_info(drizzle_con_st *con);
60
void result_info(drizzle_result_st *result);
61
void column_info(drizzle_column_st *column);
63
#define CLIENT_ERROR(__function, __ret, __client) { \
64
printf(__function ":%d:%s\n", __ret, \
65
drizzle_error(&((__client)->drizzle))); \
68
int main(int argc, char *argv[])
75
int wait_for_connections= 0;
77
client_con_st *client_con;
84
memset(&client, 0, sizeof(client_st));
86
/* Use one connection by default. */
87
client.client_con_count= 1;
89
while ((c = getopt(argc, argv, "bB:c:d:h:Hmp:P:u:")) != -1)
98
if (!strcasecmp(optarg, "none"))
99
client.level= BUFFER_NONE;
100
else if (!strcasecmp(optarg, "field"))
101
client.level= BUFFER_FIELD;
102
else if (!strcasecmp(optarg, "row"))
103
client.level= BUFFER_ROW;
104
else if (!strcasecmp(optarg, "all"))
105
client.level= BUFFER_ALL;
108
printf("Invalid buffer level: %s\n", optarg);
114
client.client_con_count= (uint32_t)atoi(optarg);
126
client.mysql_protocol= true;
134
port= (in_port_t)atoi(optarg);
143
printf("\nUsage: %s [options] [query]\n", argv[0]);
144
printf("\t-b - Use blocking sockets\n");
145
printf("\t-B <level> - Use buffer <level>, options are:\n");
146
printf("\t none - Don't buffer anything (default)\n");
147
printf("\t field - Only buffer individual fields\n");
148
printf("\t row - Only buffer individual rows\n");
149
printf("\t all - Buffer entire result\n");
150
printf("\t-c <cons> - Create <cons> connections\n");
151
printf("\t-d <db> - Use <db> for the connection\n");
152
printf("\t-h <host> - Connect to <host>\n");
153
printf("\t-H - Print this help menu\n");
154
printf("\t-m - Use MySQL protocol\n");
155
printf("\t-p <password> - Use <password> for authentication\n");
156
printf("\t-P <port> - Connect to <port>\n");
157
printf("\t-u <user> - Use <user> for authentication\n");
164
client.query= argv[optind];
165
client.query_len= strlen(client.query);
168
if (client.client_con_count > 0)
170
client.client_con_list= calloc(client.client_con_count,
171
sizeof(client_con_st));
172
if (client.client_con_list == NULL)
174
printf("calloc:%d\n", errno);
179
/* This may fail if there is other initialization that fails. See docs. */
180
if (drizzle_create(&(client.drizzle)) == NULL)
182
printf("drizzle_create failed\n");
187
drizzle_add_options(&(client.drizzle), DRIZZLE_NON_BLOCKING);
189
/* Start all connections, and if in non-blocking mode, return as soon as the
190
connection would block. In blocking mode, this completes the entire
191
connection/query/result. */
192
for (x= 0; x < client.client_con_count; x++)
194
/* This may fail if there is other initialization that fails. See docs. */
195
con= drizzle_con_add_tcp(&(client.drizzle),
196
&(client.client_con_list[x].con),
197
host, port, user, password, db,
198
client.mysql_protocol ? DRIZZLE_CON_MYSQL : 0);
200
CLIENT_ERROR("drizzle_con_add_tcp", 0, &client);
201
drizzle_con_set_context(&(client.client_con_list[x].con),
202
&(client.client_con_list[x]));
204
if (client_process(&client, &(client.client_con_list[x])) == 1)
205
wait_for_connections++;
208
/* If in non-blocking mode, continue to process connections as they become
209
ready. Loop exits when all connections have completed. */
210
while (wait_for_connections != 0)
212
ret= drizzle_con_wait(&(client.drizzle));
213
if (ret != DRIZZLE_RETURN_OK)
214
CLIENT_ERROR("drizzle_con_wait", ret, &client);
216
while ((con= drizzle_con_ready(&(client.drizzle))) != NULL)
218
client_con= (client_con_st *)drizzle_con_context(con);
220
if (client_process(&client, client_con) == 0)
221
wait_for_connections--;
225
for (x= 0; x < client.client_con_count; x++)
226
drizzle_con_free(&(client.client_con_list[x].con));
228
drizzle_free(&(client.drizzle));
230
if (client.client_con_list != NULL)
231
free(client.client_con_list);
236
char client_process(client_st *client, client_con_st *client_con)
238
drizzle_return_t ret;
239
drizzle_column_st *column;
243
drizzle_field_t field;
248
switch (client_con->state)
251
if (client->query == NULL)
254
/* This may fail if some allocation fails, but it will set ret. */
255
(void)drizzle_query(&(client_con->con), &(client_con->result),
256
client->query, client->query_len, &ret);
257
if (ret == DRIZZLE_RETURN_IO_WAIT)
259
else if (ret != DRIZZLE_RETURN_OK)
260
CLIENT_ERROR("drizzle_query", ret, client);
262
result_info(&(client_con->result));
264
if (drizzle_result_column_count(&(client_con->result)) == 0)
267
client_con->state= CLIENT_FIELDS;
270
if (client->level == BUFFER_ALL)
272
ret= drizzle_result_buffer(&(client_con->result));
273
if (ret == DRIZZLE_RETURN_IO_WAIT)
275
else if (ret != DRIZZLE_RETURN_OK)
276
CLIENT_ERROR("drizzle_result_buffer", ret, client);
278
while ((column= drizzle_column_next(&(client_con->result))) != NULL)
285
column= drizzle_column_read(&(client_con->result),
286
&(client_con->column), &ret);
287
if (ret == DRIZZLE_RETURN_IO_WAIT)
289
else if (ret != DRIZZLE_RETURN_OK)
290
CLIENT_ERROR("drizzle_column_read", ret, client);
296
drizzle_column_free(column);
300
client_con->state= CLIENT_ROWS;
303
if (client->level == BUFFER_ALL)
305
/* Everything has been buffered, just loop through and print. */
306
while ((row= drizzle_row_next(&(client_con->result))) != NULL)
308
field_sizes= drizzle_row_field_sizes(&(client_con->result));
310
printf("Row: %" PRId64 "\n",
311
drizzle_row_current(&(client_con->result)));
313
for (x= 0; x < drizzle_result_column_count(&(client_con->result)); x++)
319
printf(" (%zd) %.*s\n", field_sizes[x], (int32_t)field_sizes[x],
327
drizzle_result_free(&(client_con->result));
333
if (client->level == BUFFER_NONE || client->level == BUFFER_FIELD)
335
/* Still need to read a row at a time, and then each field. */
336
if (client_con->row == 0)
338
client_con->row= drizzle_row_read(&(client_con->result), &ret);
339
if (ret == DRIZZLE_RETURN_IO_WAIT)
344
else if (ret != DRIZZLE_RETURN_OK)
345
CLIENT_ERROR("drizzle_row", ret, client);
347
if (client_con->row == 0)
349
drizzle_result_free(&(client_con->result));
353
printf("Row: %" PRId64 "\n", client_con->row);
358
if (client->level == BUFFER_FIELD)
360
/* Since an entire field is buffered, we don't need to worry about
362
field= drizzle_field_buffer(&(client_con->result), &total, &ret);
367
field= drizzle_field_read(&(client_con->result), &offset, &length,
371
if (ret == DRIZZLE_RETURN_IO_WAIT)
373
else if (ret == DRIZZLE_RETURN_ROW_END)
375
else if (ret != DRIZZLE_RETURN_OK)
376
CLIENT_ERROR("drizzle_field_read", ret, client);
381
printf("%.*s", (int32_t)length, field);
383
printf(" (%zd) %.*s", total, (int32_t)length, field);
385
if (offset + length == total)
388
/* If we buffered the entire field, be sure to free it. */
389
if (client->level == BUFFER_FIELD)
390
drizzle_field_free(field);
396
else if (client->level == BUFFER_ROW)
398
/* The entire row will be buffered here, so no need to worry about
400
row = drizzle_row_buffer(&(client_con->result), &ret);
401
if (ret == DRIZZLE_RETURN_IO_WAIT)
403
else if (ret != DRIZZLE_RETURN_OK)
404
CLIENT_ERROR("drizzle_row", ret, client);
406
/* This marks the end of rows. */
410
field_sizes= drizzle_row_field_sizes(&(client_con->result));
412
printf("Row: %" PRId64 "\n",
413
drizzle_row_current(&(client_con->result)));
415
for (x= 0; x < drizzle_result_column_count(&(client_con->result)); x++)
421
printf(" (%zd) %.*s\n", field_sizes[x], (int32_t)field_sizes[x],
426
drizzle_row_free(&(client_con->result), row);
431
drizzle_result_free(&(client_con->result));
435
/* This should be impossible. */
442
void con_info(drizzle_con_st *con)
444
printf("Connected: protocol_version=%u\n"
450
drizzle_con_protocol_version(con), drizzle_con_server_version(con),
451
drizzle_con_thread_id(con), drizzle_con_capabilities(con),
452
drizzle_con_charset(con), drizzle_con_status(con));
455
void result_info(drizzle_result_st *result)
457
printf("Result: row_count=%" PRId64 "\n"
458
" insert_id=%" PRId64 "\n"
459
" warning_count=%u\n"
461
" affected_rows=%" PRId64 "\n\n",
462
drizzle_result_row_count(result),
463
drizzle_result_insert_id(result),
464
drizzle_result_warning_count(result),
465
drizzle_result_column_count(result),
466
drizzle_result_affected_rows(result));
469
void column_info(drizzle_column_st *column)
471
printf("Field: catalog=%s\n"
482
drizzle_column_catalog(column), drizzle_column_db(column),
483
drizzle_column_table(column), drizzle_column_orig_table(column),
484
drizzle_column_name(column), drizzle_column_orig_name(column),
485
drizzle_column_charset(column), drizzle_column_size(column),
486
drizzle_column_max_size(column), drizzle_column_type(column),
487
drizzle_column_flags(column));