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.
13
* @brief Drizzle Definitions
16
#include "libdrizzle/common.h"
20
* @addtogroup drizzle_static Static Drizzle Declarations
26
* Names of the verbose levels provided.
28
static const char *_verbose_name[DRIZZLE_VERBOSE_MAX]=
44
const char *drizzle_version(void)
46
return PACKAGE_VERSION;
49
const char *drizzle_bugreport(void)
51
return PACKAGE_BUGREPORT;
54
const char *drizzle_verbose_name(drizzle_verbose_t verbose)
56
if (verbose >= DRIZZLE_VERBOSE_MAX)
59
return _verbose_name[verbose];
62
drizzle_st *drizzle_create(drizzle_st *drizzle)
65
/* if it is MS windows, invoke WSAStartup */
67
if ( WSAStartup( MAKEWORD(2,2), &wsaData ) != 0 )
68
printf("Error at WSAStartup()\n");
72
drizzle= malloc(sizeof(drizzle_st));
76
drizzle->options= DRIZZLE_ALLOCATED;
79
drizzle->options= DRIZZLE_NONE;
81
/* @todo remove this default free flag with new API. */
82
drizzle->options|= DRIZZLE_FREE_OBJECTS;
83
drizzle->error_code= 0;
84
/* drizzle->options set above */
85
drizzle->verbose= DRIZZLE_VERBOSE_NEVER;
86
drizzle->con_count= 0;
87
drizzle->pfds_size= 0;
88
drizzle->query_count= 0;
89
drizzle->query_new= 0;
90
drizzle->query_running= 0;
91
drizzle->last_errno= 0;
93
drizzle->con_list= NULL;
94
drizzle->context= NULL;
95
drizzle->context_free_fn= NULL;
96
drizzle->event_watch_fn= NULL;
97
drizzle->event_watch_context= NULL;
98
drizzle->log_fn= NULL;
99
drizzle->log_context= NULL;
101
drizzle->query_list= NULL;
102
drizzle->sqlstate[0]= 0;
103
drizzle->last_error[0]= 0;
108
drizzle_st *drizzle_clone(drizzle_st *drizzle, const drizzle_st *from)
112
drizzle= drizzle_create(drizzle);
116
drizzle->options|= (from->options & (drizzle_options_t)~DRIZZLE_ALLOCATED);
118
for (con= from->con_list; con != NULL; con= con->next)
120
if (drizzle_con_clone(drizzle, NULL, con) == NULL)
122
drizzle_free(drizzle);
130
void drizzle_free(drizzle_st *drizzle)
132
if (drizzle->context != NULL && drizzle->context_free_fn != NULL)
133
drizzle->context_free_fn(drizzle, drizzle->context);
135
if (drizzle->options & DRIZZLE_FREE_OBJECTS)
137
drizzle_con_free_all(drizzle);
138
drizzle_query_free_all(drizzle);
140
else if (drizzle->options & DRIZZLE_ASSERT_DANGLING)
142
assert(drizzle->con_list == NULL);
143
assert(drizzle->con_list == NULL);
146
if (drizzle->pfds != NULL)
149
if (drizzle->options & DRIZZLE_ALLOCATED)
152
/* if it is MS windows, invoke WSACleanup() at the end*/
157
const char *drizzle_error(const drizzle_st *drizzle)
159
return (const char *)drizzle->last_error;
162
int drizzle_errno(const drizzle_st *drizzle)
164
return drizzle->last_errno;
167
uint16_t drizzle_error_code(const drizzle_st *drizzle)
169
return drizzle->error_code;
172
const char *drizzle_sqlstate(const drizzle_st *drizzle)
174
return drizzle->sqlstate;
177
drizzle_options_t drizzle_options(const drizzle_st *drizzle)
179
return drizzle->options;
182
void drizzle_set_options(drizzle_st *drizzle, drizzle_options_t options)
184
drizzle->options= options;
187
void drizzle_add_options(drizzle_st *drizzle, drizzle_options_t options)
189
drizzle->options|= options;
192
void drizzle_remove_options(drizzle_st *drizzle, drizzle_options_t options)
194
drizzle->options&= ~options;
197
void *drizzle_context(const drizzle_st *drizzle)
199
return drizzle->context;
202
void drizzle_set_context(drizzle_st *drizzle, void *context)
204
drizzle->context= context;
207
void drizzle_set_context_free_fn(drizzle_st *drizzle,
208
drizzle_context_free_fn *function)
210
drizzle->context_free_fn= function;
213
int drizzle_timeout(const drizzle_st *drizzle)
215
return drizzle->timeout;
218
void drizzle_set_timeout(drizzle_st *drizzle, int timeout)
220
drizzle->timeout= timeout;
223
drizzle_verbose_t drizzle_verbose(const drizzle_st *drizzle)
225
return drizzle->verbose;
228
void drizzle_set_verbose(drizzle_st *drizzle, drizzle_verbose_t verbose)
230
drizzle->verbose= verbose;
233
void drizzle_set_log_fn(drizzle_st *drizzle, drizzle_log_fn *function,
236
drizzle->log_fn= function;
237
drizzle->log_context= context;
240
void drizzle_set_event_watch_fn(drizzle_st *drizzle,
241
drizzle_event_watch_fn *function,
244
drizzle->event_watch_fn= function;
245
drizzle->event_watch_context= context;
248
drizzle_con_st *drizzle_con_create(drizzle_st *drizzle, drizzle_con_st *con)
252
con= malloc(sizeof(drizzle_con_st));
256
drizzle_set_error(drizzle, "drizzle_con_create", "malloc");
260
con->options= DRIZZLE_CON_ALLOCATED;
265
if (drizzle->con_list != NULL)
266
drizzle->con_list->prev= con;
267
con->next= drizzle->con_list;
269
drizzle->con_list= con;
270
drizzle->con_count++;
272
con->packet_number= 0;
273
con->protocol_version= 0;
274
con->state_current= 0;
277
con->capabilities= DRIZZLE_CAPABILITIES_NONE;
280
con->options|= DRIZZLE_CON_MYSQL;
281
con->socket_type= DRIZZLE_CON_SOCKET_TCP;
282
con->status= DRIZZLE_CON_STATUS_NONE;
283
con->max_packet_size= DRIZZLE_MAX_PACKET_SIZE;
284
con->result_count= 0;
286
con->backlog= DRIZZLE_DEFAULT_BACKLOG;
289
con->command_offset= 0;
290
con->command_size= 0;
291
con->command_total= 0;
293
con->addrinfo_next= NULL;
294
con->buffer_ptr= con->buffer;
295
con->command_buffer= NULL;
296
con->command_data= NULL;
298
con->context_free_fn= NULL;
299
con->drizzle= drizzle;
300
/* con->next set above */
301
/* con->prev set above */
303
/* con->result doesn't need to be set */
304
con->result_list= NULL;
306
con->socket.tcp.addrinfo= NULL;
307
con->socket.tcp.host= NULL;
308
con->socket.tcp.port= 0;
309
/* con->buffer doesn't need to be set */
312
/* con->scramble_buffer doesn't need to be set */
313
con->server_version[0]= 0;
314
/* con->state_stack doesn't need to be set */
320
drizzle_con_st *drizzle_con_clone(drizzle_st *drizzle, drizzle_con_st *con,
321
const drizzle_con_st *from)
323
con= drizzle_con_create(drizzle, con);
327
/* Clear "operational" options such as IO status. */
328
con->options|= (from->options & (drizzle_con_options_t)~(
329
DRIZZLE_CON_ALLOCATED|DRIZZLE_CON_READY|
330
DRIZZLE_CON_NO_RESULT_READ|DRIZZLE_CON_IO_READY|
331
DRIZZLE_CON_LISTEN));
332
con->backlog= from->backlog;
333
strcpy(con->db, from->db);
334
strcpy(con->password, from->password);
335
strcpy(con->user, from->user);
337
switch (from->socket_type)
339
case DRIZZLE_CON_SOCKET_TCP:
340
drizzle_con_set_tcp(con, from->socket.tcp.host, from->socket.tcp.port);
343
case DRIZZLE_CON_SOCKET_UDS:
344
drizzle_con_set_uds(con, from->socket.uds.sockaddr.sun_path);
354
void drizzle_con_free(drizzle_con_st *con)
356
if (con->context != NULL && con->context_free_fn != NULL)
357
con->context_free_fn(con, con->context);
359
if (con->drizzle->options & DRIZZLE_FREE_OBJECTS)
360
drizzle_result_free_all(con);
361
else if (con->drizzle->options & DRIZZLE_ASSERT_DANGLING)
362
assert(con->result_list == NULL);
365
drizzle_con_close(con);
367
drizzle_con_reset_addrinfo(con);
369
if (con->drizzle->con_list == con)
370
con->drizzle->con_list= con->next;
371
if (con->prev != NULL)
372
con->prev->next= con->next;
373
if (con->next != NULL)
374
con->next->prev= con->prev;
375
con->drizzle->con_count--;
377
if (con->options & DRIZZLE_CON_ALLOCATED)
381
void drizzle_con_free_all(drizzle_st *drizzle)
383
while (drizzle->con_list != NULL)
384
drizzle_con_free(drizzle->con_list);
387
drizzle_return_t drizzle_con_wait(drizzle_st *drizzle)
393
drizzle_return_t dret;
395
if (drizzle->pfds_size < drizzle->con_count)
397
pfds= realloc(drizzle->pfds, drizzle->con_count * sizeof(struct pollfd));
400
drizzle_set_error(drizzle, "drizzle_con_wait", "realloc");
401
return DRIZZLE_RETURN_MEMORY;
405
drizzle->pfds_size= drizzle->con_count;
411
for (con= drizzle->con_list; con != NULL; con= con->next)
413
if (con->events == 0)
417
pfds[x].events= con->events;
424
drizzle_set_error(drizzle, "drizzle_con_wait",
425
"no active file descriptors");
426
return DRIZZLE_RETURN_NO_ACTIVE_CONNECTIONS;
431
drizzle_log_crazy(drizzle, "poll count=%d timeout=%d", x,
434
ret= poll(pfds, x, drizzle->timeout);
436
drizzle_log_crazy(drizzle, "poll return=%d errno=%d", ret, errno);
443
drizzle_set_error(drizzle, "drizzle_con_wait", "poll:%d", errno);
444
drizzle->last_errno= errno;
445
return DRIZZLE_RETURN_ERRNO;
453
drizzle_set_error(drizzle, "drizzle_con_wait", "timeout reached");
454
return DRIZZLE_RETURN_TIMEOUT;
458
for (con= drizzle->con_list; con != NULL; con= con->next)
460
if (con->events == 0)
463
dret= drizzle_con_set_revents(con, pfds[x].revents);
464
if (dret != DRIZZLE_RETURN_OK)
470
return DRIZZLE_RETURN_OK;
473
drizzle_con_st *drizzle_con_ready(drizzle_st *drizzle)
477
/* We can't keep state between calls since connections may be removed during
478
processing. If this list ever gets big, we may want something faster. */
480
for (con= drizzle->con_list; con != NULL; con= con->next)
482
if (con->options & DRIZZLE_CON_IO_READY)
484
con->options&= (drizzle_con_options_t)~DRIZZLE_CON_IO_READY;
492
drizzle_con_st *drizzle_con_ready_listen(drizzle_st *drizzle)
496
/* We can't keep state between calls since connections may be removed during
497
processing. If this list ever gets big, we may want something faster. */
499
for (con= drizzle->con_list; con != NULL; con= con->next)
501
if ((con->options & (DRIZZLE_CON_IO_READY | DRIZZLE_CON_LISTEN)) ==
502
(DRIZZLE_CON_IO_READY | DRIZZLE_CON_LISTEN))
504
con->options&= (drizzle_con_options_t)~DRIZZLE_CON_IO_READY;
516
drizzle_con_st *drizzle_con_add_tcp(drizzle_st *drizzle, drizzle_con_st *con,
517
const char *host, in_port_t port,
518
const char *user, const char *password,
520
drizzle_con_options_t options)
522
con= drizzle_con_create(drizzle, con);
526
drizzle_con_set_tcp(con, host, port);
527
drizzle_con_set_auth(con, user, password);
528
drizzle_con_set_db(con, db);
529
drizzle_con_add_options(con, options);
534
drizzle_con_st *drizzle_con_add_uds(drizzle_st *drizzle, drizzle_con_st *con,
535
const char *uds, const char *user,
536
const char *password, const char *db,
537
drizzle_con_options_t options)
539
con= drizzle_con_create(drizzle, con);
543
drizzle_con_set_uds(con, uds);
544
drizzle_con_set_auth(con, user, password);
545
drizzle_con_set_db(con, db);
546
drizzle_con_add_options(con, options);
555
drizzle_con_st *drizzle_con_add_tcp_listen(drizzle_st *drizzle,
557
const char *host, in_port_t port,
559
drizzle_con_options_t options)
561
con= drizzle_con_create(drizzle, con);
565
drizzle_con_set_tcp(con, host, port);
566
drizzle_con_set_backlog(con, backlog);
567
drizzle_con_add_options(con, DRIZZLE_CON_LISTEN | options);
572
drizzle_con_st *drizzle_con_add_uds_listen(drizzle_st *drizzle,
574
const char *uds, int backlog,
575
drizzle_con_options_t options)
577
con= drizzle_con_create(drizzle, con);
581
drizzle_con_set_uds(con, uds);
582
drizzle_con_set_backlog(con, backlog);
583
drizzle_con_add_options(con, DRIZZLE_CON_LISTEN | options);
588
drizzle_con_st *drizzle_con_accept(drizzle_st *drizzle, drizzle_con_st *con,
589
drizzle_return_t *ret_ptr)
591
drizzle_con_st *ready;
596
if ((ready= drizzle_con_ready_listen(drizzle)) != NULL)
598
fd= accept(ready->fd, NULL, NULL);
600
con= drizzle_con_create(drizzle, con);
604
*ret_ptr= DRIZZLE_RETURN_MEMORY;
608
*ret_ptr= drizzle_con_set_fd(con, fd);
609
if (*ret_ptr != DRIZZLE_RETURN_OK)
615
if (ready->options & DRIZZLE_CON_MYSQL)
616
drizzle_con_add_options(con, DRIZZLE_CON_MYSQL);
618
*ret_ptr= DRIZZLE_RETURN_OK;
622
if (drizzle->options & DRIZZLE_NON_BLOCKING)
624
*ret_ptr= DRIZZLE_RETURN_IO_WAIT;
628
for (ready= drizzle->con_list; ready != NULL; ready= ready->next)
630
if (ready->options & DRIZZLE_CON_LISTEN)
631
drizzle_con_set_events(ready, POLLIN);
634
*ret_ptr= drizzle_con_wait(drizzle);
635
if (*ret_ptr != DRIZZLE_RETURN_OK)
644
void drizzle_set_error(drizzle_st *drizzle, const char *function,
645
const char *format, ...)
649
char log_buffer[DRIZZLE_MAX_ERROR_SIZE];
652
size= strlen(function);
653
ptr= memcpy(log_buffer, function, size);
659
va_start(args, format);
660
size+= (size_t)vsnprintf(ptr, DRIZZLE_MAX_ERROR_SIZE - size, format, args);
663
if (drizzle->log_fn == NULL)
665
if (size >= DRIZZLE_MAX_ERROR_SIZE)
666
size= DRIZZLE_MAX_ERROR_SIZE - 1;
668
memcpy(drizzle->last_error, log_buffer, size + 1);
671
drizzle->log_fn(log_buffer, DRIZZLE_VERBOSE_ERROR, drizzle->log_context);
674
void drizzle_log(drizzle_st *drizzle, drizzle_verbose_t verbose,
675
const char *format, va_list args)
677
char log_buffer[DRIZZLE_MAX_ERROR_SIZE];
679
if (drizzle->log_fn == NULL)
681
printf("%5s: ", drizzle_verbose_name(verbose));
682
vprintf(format, args);
687
vsnprintf(log_buffer, DRIZZLE_MAX_ERROR_SIZE, format, args);
688
drizzle->log_fn(log_buffer, verbose, drizzle->log_context);