libdrizzle Developer Documentation

query.c
Go to the documentation of this file.
1 /*
2  * Drizzle Client & Protocol Library
3  *
4  * Copyright (C) 2008 Eric Day (eday@oddments.org)
5  * All rights reserved.
6  *
7  * Use and distribution licensed under the BSD license. See
8  * the COPYING file in this directory for full text.
9  */
10 
16 #include "common.h"
17 
19  const char *query, size_t size,
20  drizzle_return_t *ret_ptr)
21 {
23  (uint8_t *)query, size, size, ret_ptr);
24 }
25 
27  drizzle_result_st *result,
28  const char *query,
29  drizzle_return_t *ret_ptr)
30 {
31  size_t size;
32 
33  size= strlen(query);
34 
36  (uint8_t *)query, size, size, ret_ptr);
37 }
38 
40  drizzle_result_st *result,
41  const char *query, size_t size,
42  size_t total, drizzle_return_t *ret_ptr)
43 {
45  (uint8_t *)query, size, total, ret_ptr);
46 }
47 
49  drizzle_query_st *query,
50  drizzle_con_st *con,
51  drizzle_result_st *result,
52  const char *query_string, size_t size,
54  void *context)
55 {
56  query= drizzle_query_create(drizzle, query);
57  if (query == NULL)
58  return NULL;
59 
60  drizzle_query_set_con(query, con);
61  drizzle_query_set_result(query, result);
62  drizzle_query_set_string(query, query_string, size);
63  drizzle_query_add_options(query, options);
64  drizzle_query_set_context(query, context);
65 
66  return query;
67 }
68 
70  drizzle_query_st *query)
71 {
72  if (query == NULL)
73  {
74  query= malloc(sizeof(drizzle_query_st));
75  if (query == NULL)
76  {
77  drizzle_set_error(drizzle, "drizzle_query_create", "malloc");
78  return NULL;
79  }
80 
81  memset(query, 0, sizeof(drizzle_query_st));
83  }
84  else
85  memset(query, 0, sizeof(drizzle_query_st));
86 
87  query->drizzle= drizzle;
88 
89  if (drizzle->query_list)
90  drizzle->query_list->prev= query;
91  query->next= drizzle->query_list;
92  drizzle->query_list= query;
93  drizzle->query_count++;
94  drizzle->query_new++;
95 
96  return query;
97 }
98 
100 {
101  if (query->context != NULL && query->context_free_fn != NULL)
102  query->context_free_fn(query, query->context);
103 
104  if (query->drizzle->query_list == query)
105  query->drizzle->query_list= query->next;
106  if (query->prev)
107  query->prev->next= query->next;
108  if (query->next)
109  query->next->prev= query->prev;
110  query->drizzle->query_count--;
111 
112  if (query->options & DRIZZLE_QUERY_ALLOCATED)
113  free(query);
114 }
115 
117 {
118  while (drizzle->query_list != NULL)
119  drizzle_query_free(drizzle->query_list);
120 }
121 
123 {
124  return query->con;
125 }
126 
128 {
129  query->con= con;
130 }
131 
133 {
134  return query->result;
135 }
136 
138  drizzle_result_st *result)
139 {
140  query->result= result;
141 }
142 
143 char *drizzle_query_string(drizzle_query_st *query, size_t *size)
144 {
145  *size= query->size;
146  return (char *)(query->string);
147 }
148 
149 void drizzle_query_set_string(drizzle_query_st *query, const char *string,
150  size_t size)
151 {
152  query->string= string;
153  query->size= size;
154 }
155 
157 {
158  return query->options;
159 }
160 
162  drizzle_query_options_t options)
163 {
164  query->options= options;
165 }
166 
168  drizzle_query_options_t options)
169 {
170  query->options|= options;
171 }
172 
174  drizzle_query_options_t options)
175 {
176  query->options&= ~options;
177 }
178 
180 {
181  return query->context;
182 }
183 
184 void drizzle_query_set_context(drizzle_query_st *query, void *context)
185 {
186  query->context= context;
187 }
188 
191 {
192  query->context_free_fn= function;
193 }
194 
196  drizzle_return_t* ret_ptr)
197 {
198  switch (query->state)
199  {
203  query->result= drizzle_query(query->con, query->result, query->string,
204  query->size, ret_ptr);
205  if (*ret_ptr == DRIZZLE_RETURN_IO_WAIT)
206  {
207  return;
208  }
209  else if (*ret_ptr != DRIZZLE_RETURN_OK)
210  {
212  return;
213  }
214 
216 
218  *ret_ptr= drizzle_result_buffer(query->result);
219  if (*ret_ptr == DRIZZLE_RETURN_IO_WAIT)
220  {
221  return;
222  }
223 
225  return;
226 
227  default:
229  return;
230  }
231 }
232 
234  drizzle_return_t *ret_ptr)
235 {
236  drizzle_options_t options;
237  drizzle_query_st *query;
238  drizzle_con_st *con;
239 
240  if (drizzle->query_new == 0 && drizzle->query_running == 0)
241  {
242  *ret_ptr= DRIZZLE_RETURN_OK;
243  return NULL;
244  }
245 
246  options= drizzle->options;
247  drizzle->options|= DRIZZLE_NON_BLOCKING;
248 
249  /* Check to see if any queries need to be started. */
250  if (drizzle->query_new > 0)
251  {
252  for (query= drizzle->query_list; query != NULL; query= query->next)
253  {
254  if (query->state != DRIZZLE_QUERY_STATE_INIT)
255  continue;
256 
257  drizzle->query_new--;
258  drizzle->query_running++;
259  assert(query->con->query == NULL);
260  query->con->query= query;
261 
262  drizzle_query_run_state(query, ret_ptr);
263  if (*ret_ptr != DRIZZLE_RETURN_IO_WAIT)
264  {
265  assert(query->state == DRIZZLE_QUERY_STATE_DONE);
266  drizzle->query_running--;
267  drizzle->options= options;
268  query->con->query= NULL;
269  if (*ret_ptr == DRIZZLE_RETURN_ERROR_CODE || *ret_ptr == DRIZZLE_RETURN_OK)
270  {
271  return query;
272  }
273  return NULL;
274  }
275  }
276  assert(drizzle->query_new == 0);
277  }
278 
279  while (1)
280  {
281  /* Loop through each active connection. */
282  while ((con= drizzle_con_ready(drizzle)) != NULL)
283  {
284  query= con->query;
285  drizzle_query_run_state(query, ret_ptr);
286  if (query->state == DRIZZLE_QUERY_STATE_DONE)
287  {
288  drizzle->query_running--;
289  drizzle->options= options;
290  con->query= NULL;
291  return query;
292  }
293  assert(*ret_ptr == DRIZZLE_RETURN_IO_WAIT);
294  }
295 
296  if (options & DRIZZLE_NON_BLOCKING)
297  {
298  *ret_ptr= DRIZZLE_RETURN_IO_WAIT;
299  return NULL;
300  }
301 
302  *ret_ptr= drizzle_con_wait(drizzle);
303  if (*ret_ptr != DRIZZLE_RETURN_OK)
304  {
305  drizzle->options= options;
306  return NULL;
307  }
308  }
309 }
310 
312 {
313  drizzle_return_t ret;
314 
315  while (drizzle->query_new > 0 || drizzle->query_running > 0)
316  {
317  (void)drizzle_query_run(drizzle, &ret);
318  if (ret != DRIZZLE_RETURN_OK && ret != DRIZZLE_RETURN_ERROR_CODE)
319  return ret;
320  }
321 
322  return DRIZZLE_RETURN_OK;
323 }
324 
325 size_t drizzle_escape_string(char *to, const char *from, size_t from_size)
326 {
327  size_t to_size= 0;
328 
329  while (from_size > 0)
330  {
331  /* All multi-byte UTF8 characters have the high bit set for all bytes. */
332  if (!(*from & 0x80))
333  {
334  switch (*from)
335  {
336  case 0:
337  case '\n':
338  case '\r':
339  case '\\':
340  case '\'':
341  case '"':
342  case '\032':
343  *to++= '\\';
344  to_size++;
345  default:
346  break;
347  }
348  }
349 
350  *to++= *from++;
351  from_size--;
352  to_size++;
353  }
354 
355  *to= 0;
356 
357  return to_size;
358 }
359 
360 size_t drizzle_hex_string(char *to, const char *from, size_t from_size)
361 {
362  static const char hex_map[]= "0123456789ABCDEF";
363  const char *from_end;
364 
365  for (from_end= from + from_size; from != from_end; from++)
366  {
367  *to++= hex_map[((unsigned char) *from) >> 4];
368  *to++= hex_map[((unsigned char) *from) & 0xF];
369  }
370 
371  *to= 0;
372 
373  return from_size * 2;
374 }