~drizzle-trunk/drizzle/development

2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
1
/*
2
 * Drizzle Client & Protocol Library
3
 *
4
 * Copyright (C) 2008 Eric Day (eday@oddments.org)
5
 * All rights reserved.
6
 *
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
 *
35
 */
36
37
/**
38
 * @file
39
 * @brief Drizzle Definitions
40
 */
41
2449.1.2 by Brian Aker
Additional fixes for libdrizzle.
42
#include <libdrizzle-2.0/common.h>
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
43
44
/**
45
 * @addtogroup drizzle_static Static Drizzle Declarations
46
 * @ingroup drizzle
47
 * @{
48
 */
49
50
/**
51
 * Names of the verbose levels provided.
52
 */
53
static const char *_verbose_name[DRIZZLE_VERBOSE_MAX]=
54
{
55
  "NEVER",
56
  "FATAL",
57
  "ERROR",
58
  "INFO",
59
  "DEBUG",
60
  "CRAZY"
61
};
62
63
/** @} */
64
65
/*
66
 * Common Definitions
67
 */
68
2318.5.28 by Olaf van der Spek
Refactor
69
const char *drizzle_version()
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
70
{
71
  return PACKAGE_VERSION;
72
}
73
2318.5.28 by Olaf van der Spek
Refactor
74
const char *drizzle_bugreport()
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
75
{
76
  return PACKAGE_BUGREPORT;
77
}
78
79
const char *drizzle_verbose_name(drizzle_verbose_t verbose)
80
{
81
  if (verbose >= DRIZZLE_VERBOSE_MAX)
2461.1.2 by Brian Aker
Pass through refactoring.
82
  {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
83
    return "UNKNOWN";
2461.1.2 by Brian Aker
Pass through refactoring.
84
  }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
85
86
  return _verbose_name[verbose];
87
}
88
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.
89
drizzle_st *drizzle_create()
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
90
{
91
#if defined(_WIN32)
92
  /* if it is MS windows, invoke WSAStartup */
93
  WSADATA wsaData;
94
  if ( WSAStartup( MAKEWORD(2,2), &wsaData ) != 0 )
95
    printf("Error at WSAStartup()\n");
96
#else
97
  struct sigaction act;
98
  memset(&act, 0, sizeof(act));
99
100
  act.sa_handler = SIG_IGN;
101
  sigaction(SIGPIPE, &act, NULL);
102
#endif
103
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.
104
  drizzle_st *drizzle= new (std::nothrow) drizzle_st;
105
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
106
  if (drizzle == NULL)
107
  {
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.
108
    return NULL;
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
109
  }
110
111
  /* @todo remove this default free flag with new API. */
2461.1.2 by Brian Aker
Pass through refactoring.
112
  drizzle->options.is_free_objects= true;
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
113
  drizzle->error_code= 0;
2461.1.2 by Brian Aker
Pass through refactoring.
114
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
115
  /* drizzle->options set above */
116
  drizzle->verbose= DRIZZLE_VERBOSE_NEVER;
117
  drizzle->con_count= 0;
118
  drizzle->pfds_size= 0;
119
  drizzle->query_count= 0;
120
  drizzle->query_new= 0;
121
  drizzle->query_running= 0;
122
  drizzle->last_errno= 0;
123
  drizzle->timeout= -1;
124
  drizzle->con_list= NULL;
125
  drizzle->context= NULL;
126
  drizzle->context_free_fn= NULL;
127
  drizzle->event_watch_fn= NULL;
128
  drizzle->event_watch_context= NULL;
129
  drizzle->log_fn= NULL;
130
  drizzle->log_context= NULL;
131
  drizzle->pfds= NULL;
132
  drizzle->query_list= NULL;
133
  drizzle->sqlstate[0]= 0;
134
  drizzle->last_error[0]= 0;
135
136
  return drizzle;
137
}
138
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.
139
drizzle_st *drizzle_clone(const drizzle_st *source)
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
140
{
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.
141
  drizzle_st *drizzle= drizzle_create();
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
142
  if (drizzle == NULL)
2461.1.2 by Brian Aker
Pass through refactoring.
143
  {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
144
    return NULL;
2461.1.2 by Brian Aker
Pass through refactoring.
145
  }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
146
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.
147
  for (drizzle_con_st* con= source->con_list; con != NULL; con= con->next)
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
148
  {
2463.1.4 by Brian Aker
Remove con from being passed object.
149
    if (drizzle_con_clone(drizzle, con) == NULL)
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
150
    {
151
      drizzle_free(drizzle);
152
      return NULL;
153
    }
154
  }
155
156
  return drizzle;
157
}
158
159
void drizzle_free(drizzle_st *drizzle)
160
{
161
  if (drizzle->context != NULL && drizzle->context_free_fn != NULL)
2461.1.2 by Brian Aker
Pass through refactoring.
162
  {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
163
    drizzle->context_free_fn(drizzle, drizzle->context);
2461.1.2 by Brian Aker
Pass through refactoring.
164
  }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
165
2461.1.2 by Brian Aker
Pass through refactoring.
166
  if (drizzle->options.is_free_objects)
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
167
  {
168
    drizzle_con_free_all(drizzle);
169
    drizzle_query_free_all(drizzle);
170
  }
2461.1.2 by Brian Aker
Pass through refactoring.
171
  else if (drizzle->options.is_assert_dangling)
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
172
  {
173
    assert(drizzle->con_list == NULL);
2318.5.28 by Olaf van der Spek
Refactor
174
    assert(drizzle->query_list == NULL);
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
175
  }
176
2353.3.1 by Mark Atwood
fix cppcheck redundantIfDelete0 warnings. It is safe to deallocate a NULL pointer
177
  free(drizzle->pfds);
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
178
2463.1.4 by Brian Aker
Remove con from being passed object.
179
  delete drizzle;
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
180
#if defined(_WIN32)
181
  /* if it is MS windows, invoke WSACleanup() at the end*/
182
  WSACleanup();
183
#endif
184
}
185
186
const char *drizzle_error(const drizzle_st *drizzle)
187
{
2318.5.28 by Olaf van der Spek
Refactor
188
  return drizzle->last_error;
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
189
}
190
2463.1.3 by Brian Aker
Redo the way options are handled.
191
drizzle_return_t drizzle_set_option(drizzle_st *drizzle, drizzle_options_t arg, bool set)
192
{
193
  switch (arg)
194
  {
195
  case DRIZZLE_NON_BLOCKING:
196
    drizzle->options.is_non_blocking= set;
197
    return DRIZZLE_RETURN_OK;
198
199
  case DRIZZLE_FREE_OBJECTS:
200
    return DRIZZLE_RETURN_OK;
201
202
  case DRIZZLE_ASSERT_DANGLING:
203
    return DRIZZLE_RETURN_OK;
204
205
  default:
206
    break;
207
  }
208
209
  return DRIZZLE_RETURN_INVALID_ARGUMENT;
210
}
211
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
212
int drizzle_errno(const drizzle_st *drizzle)
213
{
214
  return drizzle->last_errno;
215
}
216
217
uint16_t drizzle_error_code(const drizzle_st *drizzle)
218
{
219
  return drizzle->error_code;
220
}
221
222
const char *drizzle_sqlstate(const drizzle_st *drizzle)
223
{
224
  return drizzle->sqlstate;
225
}
226
227
void *drizzle_context(const drizzle_st *drizzle)
228
{
229
  return drizzle->context;
230
}
231
232
void drizzle_set_context(drizzle_st *drizzle, void *context)
233
{
234
  drizzle->context= context;
235
}
236
237
void drizzle_set_context_free_fn(drizzle_st *drizzle,
238
                                 drizzle_context_free_fn *function)
239
{
240
  drizzle->context_free_fn= function;
241
}
242
243
int drizzle_timeout(const drizzle_st *drizzle)
244
{
245
  return drizzle->timeout;
246
}
247
248
void drizzle_set_timeout(drizzle_st *drizzle, int timeout)
249
{
250
  drizzle->timeout= timeout;
251
}
252
253
drizzle_verbose_t drizzle_verbose(const drizzle_st *drizzle)
254
{
255
  return drizzle->verbose;
256
}
257
258
void drizzle_set_verbose(drizzle_st *drizzle, drizzle_verbose_t verbose)
259
{
260
  drizzle->verbose= verbose;
261
}
262
263
void drizzle_set_log_fn(drizzle_st *drizzle, drizzle_log_fn *function,
264
                        void *context)
265
{
266
  drizzle->log_fn= function;
267
  drizzle->log_context= context;
268
}
269
270
void drizzle_set_event_watch_fn(drizzle_st *drizzle,
271
                                drizzle_event_watch_fn *function,
272
                                void *context)
273
{
274
  drizzle->event_watch_fn= function;
275
  drizzle->event_watch_context= context;
276
}
277
2463.1.4 by Brian Aker
Remove con from being passed object.
278
drizzle_con_st *drizzle_con_create(drizzle_st *drizzle)
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
279
{
2463.1.4 by Brian Aker
Remove con from being passed object.
280
  if (drizzle == NULL)
281
  {
282
    return NULL;
283
  }
284
285
  drizzle_con_st *con= new (std::nothrow) drizzle_con_st;
286
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
287
  if (con == NULL)
288
  {
2463.1.4 by Brian Aker
Remove con from being passed object.
289
    return NULL;
2461.1.2 by Brian Aker
Pass through refactoring.
290
  }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
291
292
  if (drizzle->con_list != NULL)
2463.1.4 by Brian Aker
Remove con from being passed object.
293
  {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
294
    drizzle->con_list->prev= con;
2463.1.4 by Brian Aker
Remove con from being passed object.
295
  }
2461.1.2 by Brian Aker
Pass through refactoring.
296
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
297
  con->next= drizzle->con_list;
298
  con->prev= NULL;
299
  drizzle->con_list= con;
300
  drizzle->con_count++;
301
302
  con->packet_number= 0;
303
  con->protocol_version= 0;
304
  con->state_current= 0;
305
  con->events= 0;
306
  con->revents= 0;
307
  con->capabilities= DRIZZLE_CAPABILITIES_NONE;
308
  con->charset= 0;
309
  con->command= DRIZZLE_COMMAND_SLEEP;
310
  con->options|= DRIZZLE_CON_MYSQL;
311
  con->socket_type= DRIZZLE_CON_SOCKET_TCP;
312
  con->status= DRIZZLE_CON_STATUS_NONE;
313
  con->max_packet_size= DRIZZLE_MAX_PACKET_SIZE;
314
  con->result_count= 0;
315
  con->thread_id= 0;
316
  con->backlog= DRIZZLE_DEFAULT_BACKLOG;
317
  con->fd= -1;
318
  con->buffer_size= 0;
319
  con->command_offset= 0;
320
  con->command_size= 0;
321
  con->command_total= 0;
322
  con->packet_size= 0;
323
  con->addrinfo_next= NULL;
324
  con->buffer_ptr= con->buffer;
325
  con->command_buffer= NULL;
326
  con->command_data= NULL;
327
  con->context= NULL;
328
  con->context_free_fn= NULL;
329
  con->drizzle= drizzle;
330
  /* con->next set above */
331
  /* con->prev set above */
332
  con->query= NULL;
333
  /* con->result doesn't need to be set */
334
  con->result_list= NULL;
335
  con->scramble= NULL;
336
  con->socket.tcp.addrinfo= NULL;
337
  con->socket.tcp.host= NULL;
338
  con->socket.tcp.port= 0;
339
  /* con->buffer doesn't need to be set */
2461.1.1 by Brian Aker
Fix safety issues around calling API with no check for NULL
340
  con->schema[0]= 0;
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
341
  con->password[0]= 0;
342
  /* con->scramble_buffer doesn't need to be set */
343
  con->server_version[0]= 0;
344
  /* con->state_stack doesn't need to be set */
345
  con->user[0]= 0;
346
347
  return con;
348
}
349
2463.1.4 by Brian Aker
Remove con from being passed object.
350
drizzle_con_st *drizzle_con_clone(drizzle_st *drizzle, drizzle_con_st *source)
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
351
{
2463.1.4 by Brian Aker
Remove con from being passed object.
352
  drizzle_con_st *con= drizzle_con_create(drizzle);
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
353
  if (con == NULL)
2461.1.2 by Brian Aker
Pass through refactoring.
354
  {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
355
    return NULL;
2461.1.2 by Brian Aker
Pass through refactoring.
356
  }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
357
358
  /* Clear "operational" options such as IO status. */
2463.1.4 by Brian Aker
Remove con from being passed object.
359
  con->options|= (source->options & ~(DRIZZLE_CON_ALLOCATED|DRIZZLE_CON_READY|
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
360
                  DRIZZLE_CON_NO_RESULT_READ|DRIZZLE_CON_IO_READY|
361
                  DRIZZLE_CON_LISTEN));
2463.1.4 by Brian Aker
Remove con from being passed object.
362
  con->backlog= source->backlog;
363
  strcpy(con->schema, source->schema);
364
  strcpy(con->password, source->password);
365
  strcpy(con->user, source->user);
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
366
2463.1.4 by Brian Aker
Remove con from being passed object.
367
  switch (source->socket_type)
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
368
  {
369
  case DRIZZLE_CON_SOCKET_TCP:
2463.1.4 by Brian Aker
Remove con from being passed object.
370
    drizzle_con_set_tcp(con, source->socket.tcp.host, source->socket.tcp.port);
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
371
    break;
372
373
  case DRIZZLE_CON_SOCKET_UDS:
2463.1.4 by Brian Aker
Remove con from being passed object.
374
    drizzle_con_set_uds(con, source->socket.uds.sockaddr.sun_path);
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
375
    break;
376
  }
377
378
  return con;
379
}
380
381
void drizzle_con_free(drizzle_con_st *con)
382
{
383
  if (con->context != NULL && con->context_free_fn != NULL)
2461.1.2 by Brian Aker
Pass through refactoring.
384
  {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
385
    con->context_free_fn(con, con->context);
2461.1.2 by Brian Aker
Pass through refactoring.
386
  }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
387
2461.1.2 by Brian Aker
Pass through refactoring.
388
  if (con->drizzle->options.is_free_objects)
389
  {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
390
    drizzle_result_free_all(con);
2461.1.2 by Brian Aker
Pass through refactoring.
391
  }
392
  else if (con->drizzle->options.is_assert_dangling)
393
  {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
394
    assert(con->result_list == NULL);
2461.1.2 by Brian Aker
Pass through refactoring.
395
  }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
396
397
  if (con->fd != -1)
2461.1.2 by Brian Aker
Pass through refactoring.
398
  {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
399
    drizzle_con_close(con);
2461.1.2 by Brian Aker
Pass through refactoring.
400
  }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
401
402
  drizzle_con_reset_addrinfo(con);
403
404
  if (con->drizzle->con_list == con)
2461.1.2 by Brian Aker
Pass through refactoring.
405
  {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
406
    con->drizzle->con_list= con->next;
2461.1.2 by Brian Aker
Pass through refactoring.
407
  }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
408
  if (con->prev != NULL)
2461.1.2 by Brian Aker
Pass through refactoring.
409
  {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
410
    con->prev->next= con->next;
2461.1.2 by Brian Aker
Pass through refactoring.
411
  }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
412
  if (con->next != NULL)
2461.1.2 by Brian Aker
Pass through refactoring.
413
  {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
414
    con->next->prev= con->prev;
2461.1.2 by Brian Aker
Pass through refactoring.
415
  }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
416
  con->drizzle->con_count--;
417
2463.1.4 by Brian Aker
Remove con from being passed object.
418
  delete con;
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
419
}
420
421
void drizzle_con_free_all(drizzle_st *drizzle)
422
{
423
  while (drizzle->con_list != NULL)
2461.1.2 by Brian Aker
Pass through refactoring.
424
  {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
425
    drizzle_con_free(drizzle->con_list);
2461.1.2 by Brian Aker
Pass through refactoring.
426
  }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
427
}
428
429
drizzle_return_t drizzle_con_wait(drizzle_st *drizzle)
430
{
431
  struct pollfd *pfds;
432
  int ret;
433
  drizzle_return_t dret;
434
435
  if (drizzle->pfds_size < drizzle->con_count)
436
  {
437
    pfds= (struct pollfd *)realloc(drizzle->pfds, drizzle->con_count * sizeof(struct pollfd));
438
    if (pfds == NULL)
439
    {
440
      drizzle_set_error(drizzle, "drizzle_con_wait", "realloc");
441
      return DRIZZLE_RETURN_MEMORY;
442
    }
443
444
    drizzle->pfds= pfds;
445
    drizzle->pfds_size= drizzle->con_count;
446
  }
447
  else
2461.1.2 by Brian Aker
Pass through refactoring.
448
  {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
449
    pfds= drizzle->pfds;
2461.1.2 by Brian Aker
Pass through refactoring.
450
  }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
451
2318.5.28 by Olaf van der Spek
Refactor
452
  uint32_t x= 0;
453
  for (drizzle_con_st* con= drizzle->con_list; con != NULL; con= con->next)
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
454
  {
455
    if (con->events == 0)
456
      continue;
457
458
    pfds[x].fd= con->fd;
459
    pfds[x].events= con->events;
460
    pfds[x].revents= 0;
461
    x++;
462
  }
463
464
  if (x == 0)
465
  {
466
    drizzle_set_error(drizzle, "drizzle_con_wait",
467
                      "no active file descriptors");
468
    return DRIZZLE_RETURN_NO_ACTIVE_CONNECTIONS;
469
  }
470
471
  while (1)
472
  {
473
    drizzle_log_crazy(drizzle, "poll count=%d timeout=%d", x,
474
                      drizzle->timeout);
475
476
    ret= poll(pfds, x, drizzle->timeout);
477
478
    drizzle_log_crazy(drizzle, "poll return=%d errno=%d", ret, errno);
479
480
    if (ret == -1)
481
    {
482
      if (errno == EINTR)
483
        continue;
484
485
      drizzle_set_error(drizzle, "drizzle_con_wait", "poll:%d", errno);
486
      drizzle->last_errno= errno;
487
      return DRIZZLE_RETURN_ERRNO;
488
    }
489
490
    break;
491
  }
492
493
  if (ret == 0)
494
  {
495
    drizzle_set_error(drizzle, "drizzle_con_wait", "timeout reached");
496
    return DRIZZLE_RETURN_TIMEOUT;
497
  }
498
499
  x= 0;
2318.5.28 by Olaf van der Spek
Refactor
500
  for (drizzle_con_st* con= drizzle->con_list; con != NULL; con= con->next)
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
501
  {
502
    if (con->events == 0)
503
      continue;
504
505
    dret= drizzle_con_set_revents(con, pfds[x].revents);
506
    if (dret != DRIZZLE_RETURN_OK)
507
      return dret;
508
509
    x++;
510
  }
511
512
  return DRIZZLE_RETURN_OK;
513
}
514
515
drizzle_con_st *drizzle_con_ready(drizzle_st *drizzle)
516
{
517
  /* We can't keep state between calls since connections may be removed during
518
     processing. If this list ever gets big, we may want something faster. */
519
2318.5.28 by Olaf van der Spek
Refactor
520
  for (drizzle_con_st* con= drizzle->con_list; con != NULL; con= con->next)
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
521
  {
522
    if (con->options & DRIZZLE_CON_IO_READY)
523
    {
524
      con->options&= ~DRIZZLE_CON_IO_READY;
525
      return con;
526
    }
527
  }
528
  return NULL;
529
}
530
531
drizzle_con_st *drizzle_con_ready_listen(drizzle_st *drizzle)
532
{
533
  /* We can't keep state between calls since connections may be removed during
534
     processing. If this list ever gets big, we may want something faster. */
535
2318.5.28 by Olaf van der Spek
Refactor
536
  for (drizzle_con_st* con= drizzle->con_list; con != NULL; con= con->next)
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
537
  {
538
    if ((con->options & (DRIZZLE_CON_IO_READY | DRIZZLE_CON_LISTEN)) ==
539
        (DRIZZLE_CON_IO_READY | DRIZZLE_CON_LISTEN))
540
    {
541
      con->options&= ~DRIZZLE_CON_IO_READY;
542
      return con;
543
    }
544
  }
545
  return NULL;
546
}
547
548
/*
549
 * Client Definitions
550
 */
551
2463.1.4 by Brian Aker
Remove con from being passed object.
552
drizzle_con_st *drizzle_con_add_tcp(drizzle_st *drizzle,
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
553
                                    const char *host, in_port_t port,
554
                                    const char *user, const char *password,
555
                                    const char *db,
556
                                    drizzle_con_options_t options)
557
{
2463.1.4 by Brian Aker
Remove con from being passed object.
558
  drizzle_con_st *con= drizzle_con_create(drizzle);
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
559
  if (con == NULL)
2461.1.2 by Brian Aker
Pass through refactoring.
560
  {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
561
    return NULL;
2461.1.2 by Brian Aker
Pass through refactoring.
562
  }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
563
564
  drizzle_con_set_tcp(con, host, port);
565
  drizzle_con_set_auth(con, user, password);
566
  drizzle_con_set_db(con, db);
567
  drizzle_con_add_options(con, options);
568
569
  return con;
570
}
571
2463.1.4 by Brian Aker
Remove con from being passed object.
572
drizzle_con_st *drizzle_con_add_uds(drizzle_st *drizzle,
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
573
                                    const char *uds, const char *user,
574
                                    const char *password, const char *db,
575
                                    drizzle_con_options_t options)
576
{
2463.1.4 by Brian Aker
Remove con from being passed object.
577
  drizzle_con_st *con= drizzle_con_create(drizzle);
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
578
  if (con == NULL)
2461.1.2 by Brian Aker
Pass through refactoring.
579
  {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
580
    return NULL;
2461.1.2 by Brian Aker
Pass through refactoring.
581
  }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
582
583
  drizzle_con_set_uds(con, uds);
584
  drizzle_con_set_auth(con, user, password);
585
  drizzle_con_set_db(con, db);
586
  drizzle_con_add_options(con, options);
587
588
  return con;
589
}
590
591
/*
592
 * Server Definitions
593
 */
594
595
drizzle_con_st *drizzle_con_add_tcp_listen(drizzle_st *drizzle,
596
                                           const char *host, in_port_t port,
597
                                           int backlog,
598
                                           drizzle_con_options_t options)
599
{
2463.1.4 by Brian Aker
Remove con from being passed object.
600
  drizzle_con_st *con= drizzle_con_create(drizzle);
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
601
  if (con == NULL)
2461.1.2 by Brian Aker
Pass through refactoring.
602
  {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
603
    return NULL;
2461.1.2 by Brian Aker
Pass through refactoring.
604
  }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
605
606
  drizzle_con_set_tcp(con, host, port);
607
  drizzle_con_set_backlog(con, backlog);
608
  drizzle_con_add_options(con, options | DRIZZLE_CON_LISTEN);
609
610
  return con;
611
}
612
613
drizzle_con_st *drizzle_con_add_uds_listen(drizzle_st *drizzle,
614
                                           const char *uds, int backlog,
615
                                           drizzle_con_options_t options)
616
{
2463.1.4 by Brian Aker
Remove con from being passed object.
617
  drizzle_con_st *con= drizzle_con_create(drizzle);
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
618
  if (con == NULL)
2461.1.2 by Brian Aker
Pass through refactoring.
619
  {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
620
    return NULL;
2461.1.2 by Brian Aker
Pass through refactoring.
621
  }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
622
623
  drizzle_con_set_uds(con, uds);
624
  drizzle_con_set_backlog(con, backlog);
625
  drizzle_con_add_options(con, options | DRIZZLE_CON_LISTEN);
626
627
  return con;
628
}
629
2463.1.4 by Brian Aker
Remove con from being passed object.
630
drizzle_con_st *drizzle_con_accept(drizzle_st *drizzle,
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
631
                                   drizzle_return_t *ret_ptr)
632
{
2463.1.4 by Brian Aker
Remove con from being passed object.
633
  drizzle_return_t unused;
634
  if (ret_ptr == NULL)
635
  {
636
    ret_ptr= &unused;
637
  }
638
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
639
  while (1)
640
  {
2318.5.28 by Olaf van der Spek
Refactor
641
    if (drizzle_con_st* ready= drizzle_con_ready_listen(drizzle))
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
642
    {
2318.5.28 by Olaf van der Spek
Refactor
643
      int fd= accept(ready->fd, NULL, NULL);
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
644
2463.1.4 by Brian Aker
Remove con from being passed object.
645
      drizzle_con_st *con= drizzle_con_create(drizzle);
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
646
      if (con == NULL)
647
      {
2269.2.1 by Marc Isambart
Various libdrizzle Windows fixes, including closesocket() instead of close(), snprintf handling and WSAECONNREFUSED mapping
648
        (void)closesocket(fd);
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
649
        *ret_ptr= DRIZZLE_RETURN_MEMORY;
650
        return NULL;
651
      }
652
653
      *ret_ptr= drizzle_con_set_fd(con, fd);
654
      if (*ret_ptr != DRIZZLE_RETURN_OK)
655
      {
2269.2.1 by Marc Isambart
Various libdrizzle Windows fixes, including closesocket() instead of close(), snprintf handling and WSAECONNREFUSED mapping
656
        (void)closesocket(fd);
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
657
        return NULL;
658
      }
659
660
      if (ready->options & DRIZZLE_CON_MYSQL)
661
        drizzle_con_add_options(con, DRIZZLE_CON_MYSQL);
662
663
      *ret_ptr= DRIZZLE_RETURN_OK;
664
      return con;
665
    }
666
2461.1.2 by Brian Aker
Pass through refactoring.
667
    if (drizzle->options.is_non_blocking)
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
668
    {
669
      *ret_ptr= DRIZZLE_RETURN_IO_WAIT;
670
      return NULL;
671
    }
672
2318.5.28 by Olaf van der Spek
Refactor
673
    for (drizzle_con_st* ready= drizzle->con_list; ready != NULL; ready= ready->next)
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
674
    {
675
      if (ready->options & DRIZZLE_CON_LISTEN)
2463.1.4 by Brian Aker
Remove con from being passed object.
676
      {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
677
        drizzle_con_set_events(ready, POLLIN);
2463.1.4 by Brian Aker
Remove con from being passed object.
678
      }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
679
    }
680
681
    *ret_ptr= drizzle_con_wait(drizzle);
682
    if (*ret_ptr != DRIZZLE_RETURN_OK)
2463.1.4 by Brian Aker
Remove con from being passed object.
683
    {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
684
      return NULL;
2463.1.4 by Brian Aker
Remove con from being passed object.
685
    }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
686
  }
687
}
688
689
/*
690
 * Local Definitions
691
 */
692
693
void drizzle_set_error(drizzle_st *drizzle, const char *function,
694
                       const char *format, ...)
695
{
2463.1.4 by Brian Aker
Remove con from being passed object.
696
  if (drizzle == NULL)
697
  {
698
    return;
699
  }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
700
  char log_buffer[DRIZZLE_MAX_ERROR_SIZE];
701
2318.5.28 by Olaf van der Spek
Refactor
702
  size_t size= strlen(function);
703
  char* ptr= (char *)memcpy(log_buffer, function, size);
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
704
  ptr+= size;
705
  ptr[0]= ':';
706
  size++;
707
  ptr++;
708
2318.5.28 by Olaf van der Spek
Refactor
709
  va_list args;
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
710
  va_start(args, format);
2318.5.28 by Olaf van der Spek
Refactor
711
  int written= vsnprintf(ptr, DRIZZLE_MAX_ERROR_SIZE - size, format, args);
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
712
  va_end(args);
713
2461.1.2 by Brian Aker
Pass through refactoring.
714
  if (written < 0) 
715
  {
716
    size= DRIZZLE_MAX_ERROR_SIZE;
717
  }
718
  else 
719
  {
720
    size+= written;
721
  }
722
2269.2.1 by Marc Isambart
Various libdrizzle Windows fixes, including closesocket() instead of close(), snprintf handling and WSAECONNREFUSED mapping
723
  if (size >= DRIZZLE_MAX_ERROR_SIZE)
2461.1.2 by Brian Aker
Pass through refactoring.
724
  {
2269.2.1 by Marc Isambart
Various libdrizzle Windows fixes, including closesocket() instead of close(), snprintf handling and WSAECONNREFUSED mapping
725
    size= DRIZZLE_MAX_ERROR_SIZE - 1;
2461.1.2 by Brian Aker
Pass through refactoring.
726
  }
2269.2.1 by Marc Isambart
Various libdrizzle Windows fixes, including closesocket() instead of close(), snprintf handling and WSAECONNREFUSED mapping
727
  log_buffer[size]= 0;
728
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
729
  if (drizzle->log_fn == NULL)
2461.1.2 by Brian Aker
Pass through refactoring.
730
  {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
731
    memcpy(drizzle->last_error, log_buffer, size + 1);
2461.1.2 by Brian Aker
Pass through refactoring.
732
  }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
733
  else
2461.1.2 by Brian Aker
Pass through refactoring.
734
  {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
735
    drizzle->log_fn(log_buffer, DRIZZLE_VERBOSE_ERROR, drizzle->log_context);
2461.1.2 by Brian Aker
Pass through refactoring.
736
  }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
737
}
738
739
void drizzle_log(drizzle_st *drizzle, drizzle_verbose_t verbose,
740
                 const char *format, va_list args)
741
{
742
  char log_buffer[DRIZZLE_MAX_ERROR_SIZE];
743
2463.1.4 by Brian Aker
Remove con from being passed object.
744
  if (drizzle == NULL)
745
  {
746
    return;
747
  }
748
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
749
  if (drizzle->log_fn == NULL)
750
  {
751
    printf("%5s: ", drizzle_verbose_name(verbose));
752
    vprintf(format, args);
753
    printf("\n");
754
  }
755
  else
756
  {
757
    vsnprintf(log_buffer, DRIZZLE_MAX_ERROR_SIZE, format, args);
2269.2.1 by Marc Isambart
Various libdrizzle Windows fixes, including closesocket() instead of close(), snprintf handling and WSAECONNREFUSED mapping
758
    log_buffer[DRIZZLE_MAX_ERROR_SIZE-1]= 0;
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
759
    drizzle->log_fn(log_buffer, verbose, drizzle->log_context);
760
  }
761
}