Drizzled Public API Documentation

query.cc
Go to the documentation of this file.
1 /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
2  *
3  * Drizzle Client & Protocol Library
4  *
5  * Copyright (C) 2008 Eric Day (eday@oddments.org)
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are
10  * met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * * Redistributions in binary form must reproduce the above
16  * copyright notice, this list of conditions and the following disclaimer
17  * in the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * * The names of its contributors may not be used to endorse or
21  * promote products derived from this software without specific prior
22  * written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35  *
36  */
37 
43 #include <libdrizzle/common.h>
44 
45 drizzle_result_st *drizzle_query(drizzle_con_st *con, drizzle_result_st *result,
46  const char *query, size_t size,
47  drizzle_return_t *ret_ptr)
48 {
49  return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_QUERY,
50  (uint8_t *)query, size, size, ret_ptr);
51 }
52 
53 drizzle_result_st *drizzle_query_str(drizzle_con_st *con,
54  drizzle_result_st *result,
55  const char *query,
56  drizzle_return_t *ret_ptr)
57 {
58  if (query == NULL)
59  {
60  return NULL;
61  }
62 
63  size_t size= strlen(query);
64 
65  return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_QUERY,
66  (uint8_t *)query, size, size, ret_ptr);
67 }
68 
69 drizzle_result_st *drizzle_query_inc(drizzle_con_st *con,
70  drizzle_result_st *result,
71  const char *query, size_t size,
72  size_t total, drizzle_return_t *ret_ptr)
73 {
74  return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_QUERY,
75  (uint8_t *)query, size, total, ret_ptr);
76 }
77 
78 drizzle_query_st *drizzle_query_add(drizzle_st *drizzle,
79  drizzle_query_st *query,
80  drizzle_con_st *con,
81  drizzle_result_st *result,
82  const char *query_string, size_t size,
83  drizzle_query_options_t options,
84  void *context)
85 {
86  if (drizzle == NULL)
87  {
88  return NULL;
89  }
90 
91  query= drizzle_query_create(drizzle, query);
92  if (query == NULL)
93  {
94  return NULL;
95  }
96 
97  drizzle_query_set_con(query, con);
98  drizzle_query_set_result(query, result);
99  drizzle_query_set_string(query, query_string, size);
100  drizzle_query_add_options(query, options);
101  drizzle_query_set_context(query, context);
102 
103  return query;
104 }
105 
106 drizzle_query_st *drizzle_query_create(drizzle_st *drizzle,
107  drizzle_query_st *query)
108 {
109  if (drizzle == NULL)
110  {
111  return NULL;
112  }
113 
114  if (query == NULL)
115  {
116  query= new (std::nothrow) drizzle_query_st;
117  if (query == NULL)
118  {
119  drizzle_set_error(drizzle, __func__, "Failed to allocate.");
120  return NULL;
121  }
122 
123  query->options|= DRIZZLE_CON_ALLOCATED;
124  }
125  else
126  {
127  memset(query, 0, sizeof(drizzle_query_st));
128  }
129 
130  query->drizzle= drizzle;
131 
132  if (drizzle->query_list)
133  drizzle->query_list->prev= query;
134  query->next= drizzle->query_list;
135  drizzle->query_list= query;
136  drizzle->query_count++;
137  drizzle->query_new++;
138 
139  return query;
140 }
141 
142 void drizzle_query_free(drizzle_query_st *query)
143 {
144  if (query == NULL)
145  {
146  return;
147  }
148 
149  if (query->context != NULL && query->context_free_fn != NULL)
150  query->context_free_fn(query, query->context);
151 
152  if (query->drizzle->query_list == query)
153  query->drizzle->query_list= query->next;
154 
155  if (query->prev)
156  query->prev->next= query->next;
157 
158  if (query->next)
159  query->next->prev= query->prev;
160  query->drizzle->query_count--;
161 
162  if (query->options & DRIZZLE_QUERY_ALLOCATED)
163  {
164  delete query;
165  }
166 }
167 
168 void drizzle_query_free_all(drizzle_st *drizzle)
169 {
170  if (drizzle == NULL)
171  {
172  return;
173  }
174 
175  while (drizzle->query_list != NULL)
176  {
177  drizzle_query_free(drizzle->query_list);
178  }
179 }
180 
181 drizzle_con_st *drizzle_query_con(drizzle_query_st *query)
182 {
183  if (query == NULL)
184  {
185  return NULL;
186  }
187 
188  return query->con;
189 }
190 
191 void drizzle_query_set_con(drizzle_query_st *query, drizzle_con_st *con)
192 {
193  if (query == NULL)
194  {
195  return;
196  }
197 
198  query->con= con;
199 }
200 
201 drizzle_result_st *drizzle_query_result(drizzle_query_st *query)
202 {
203  if (query == NULL)
204  {
205  return NULL;
206  }
207 
208  return query->result;
209 }
210 
211 void drizzle_query_set_result(drizzle_query_st *query,
212  drizzle_result_st *result)
213 {
214  if (query == NULL)
215  {
216  return;
217  }
218 
219  query->result= result;
220 }
221 
222 char *drizzle_query_string(drizzle_query_st *query, size_t *size)
223 {
224  if (query == NULL)
225  {
226  return NULL;
227  }
228 
229  if (size)
230  {
231  *size= query->size;
232  }
233 
234  return (char *)(query->string);
235 }
236 
237 void drizzle_query_set_string(drizzle_query_st *query, const char *string,
238  size_t size)
239 {
240  if (query == NULL)
241  {
242  return;
243  }
244 
245  query->string= string;
246  query->size= size;
247 }
248 
249 drizzle_query_options_t drizzle_query_options(drizzle_query_st *query)
250 {
251  if (query == NULL)
252  {
253  return drizzle_query_options_t();
254  }
255 
256  return drizzle_query_options_t(query->options);
257 }
258 
259 void drizzle_query_set_options(drizzle_query_st *query,
260  drizzle_query_options_t options)
261 {
262  if (query == NULL)
263  {
264  return;
265  }
266 
267  query->options= options;
268 }
269 
270 void drizzle_query_add_options(drizzle_query_st *query,
271  drizzle_query_options_t options)
272 {
273  if (query == NULL)
274  {
275  return;
276  }
277 
278  query->options|= options;
279 }
280 
281 void drizzle_query_remove_options(drizzle_query_st *query,
282  drizzle_query_options_t options)
283 {
284  if (query == NULL)
285  {
286  return;
287  }
288 
289  query->options&= ~options;
290 }
291 
292 void *drizzle_query_context(drizzle_query_st *query)
293 {
294  if (query == NULL)
295  {
296  return NULL;
297  }
298 
299  return query->context;
300 }
301 
302 void drizzle_query_set_context(drizzle_query_st *query, void *context)
303 {
304  if (query == NULL)
305  {
306  return;
307  }
308 
309  query->context= context;
310 }
311 
312 void drizzle_query_set_context_free_fn(drizzle_query_st *query,
313  drizzle_query_context_free_fn *function)
314 {
315  if (query == NULL)
316  {
317  return;
318  }
319 
320  query->context_free_fn= function;
321 }
322 
323 static void drizzle_query_run_state(drizzle_query_st* query,
324  drizzle_return_t* ret_ptr)
325 {
326  drizzle_return_t unused_ret;
327  if (ret_ptr == NULL)
328  {
329  ret_ptr= &unused_ret;
330  }
331 
332  if (query == NULL)
333  {
334  *ret_ptr= DRIZZLE_RETURN_INVALID_ARGUMENT;
335  return;
336  }
337 
338  switch (query->state)
339  {
340  case DRIZZLE_QUERY_STATE_INIT:
341  query->state= DRIZZLE_QUERY_STATE_QUERY;
342  case DRIZZLE_QUERY_STATE_QUERY:
343  query->result= drizzle_query(query->con, query->result, query->string,
344  query->size, ret_ptr);
345  if (*ret_ptr == DRIZZLE_RETURN_IO_WAIT)
346  {
347  return;
348  }
349  else if (*ret_ptr != DRIZZLE_RETURN_OK)
350  {
351  query->state= DRIZZLE_QUERY_STATE_DONE;
352  return;
353  }
354 
355  query->state= DRIZZLE_QUERY_STATE_RESULT;
356 
357  case DRIZZLE_QUERY_STATE_RESULT:
358  *ret_ptr= drizzle_result_buffer(query->result);
359  if (*ret_ptr == DRIZZLE_RETURN_IO_WAIT)
360  {
361  return;
362  }
363 
364  query->state= DRIZZLE_QUERY_STATE_DONE;
365  return;
366 
367  default:
368  case DRIZZLE_QUERY_STATE_DONE:
369  return;
370  }
371 }
372 
373 drizzle_query_st *drizzle_query_run(drizzle_st *drizzle,
374  drizzle_return_t *ret_ptr)
375 {
376  drizzle_return_t unused_ret;
377  if (ret_ptr == NULL)
378  {
379  ret_ptr= &unused_ret;
380  }
381 
382  if (drizzle == NULL)
383  {
384  *ret_ptr= DRIZZLE_RETURN_INVALID_ARGUMENT;
385  return NULL;
386  }
387 
388  int options;
389  drizzle_query_st *query;
390  drizzle_con_st *con;
391 
392  if (drizzle->query_new == 0 && drizzle->query_running == 0)
393  {
394  *ret_ptr= DRIZZLE_RETURN_OK;
395  return NULL;
396  }
397 
398  options= int(drizzle->options);
399  drizzle->options|= int(DRIZZLE_NON_BLOCKING);
400 
401  /* Check to see if any queries need to be started. */
402  if (drizzle->query_new > 0)
403  {
404  for (query= drizzle->query_list; query != NULL; query= query->next)
405  {
406  if (query->state != DRIZZLE_QUERY_STATE_INIT)
407  continue;
408 
409  drizzle->query_new--;
410  drizzle->query_running++;
411  assert(query->con->query == NULL);
412  query->con->query= query;
413 
414  drizzle_query_run_state(query, ret_ptr);
415  if (*ret_ptr != DRIZZLE_RETURN_IO_WAIT)
416  {
417  assert(query->state == DRIZZLE_QUERY_STATE_DONE);
418  drizzle->query_running--;
419  drizzle->options= int(options);
420  query->con->query= NULL;
421  if (*ret_ptr == DRIZZLE_RETURN_ERROR_CODE || *ret_ptr == DRIZZLE_RETURN_OK)
422  {
423  return query;
424  }
425  return NULL;
426  }
427  }
428  assert(drizzle->query_new == 0);
429  }
430 
431  while (1)
432  {
433  /* Loop through each active connection. */
434  while ((con= drizzle_con_ready(drizzle)) != NULL)
435  {
436  query= con->query;
437  drizzle_query_run_state(query, ret_ptr);
438  if (query->state == DRIZZLE_QUERY_STATE_DONE)
439  {
440  drizzle->query_running--;
441  drizzle->options= options;
442  con->query= NULL;
443  return query;
444  }
445  assert(*ret_ptr == DRIZZLE_RETURN_IO_WAIT);
446  }
447 
448  if (options & DRIZZLE_NON_BLOCKING)
449  {
450  *ret_ptr= DRIZZLE_RETURN_IO_WAIT;
451  return NULL;
452  }
453 
454  *ret_ptr= drizzle_con_wait(drizzle);
455  if (*ret_ptr != DRIZZLE_RETURN_OK)
456  {
457  drizzle->options= options;
458  return NULL;
459  }
460  }
461 }
462 
463 drizzle_return_t drizzle_query_run_all(drizzle_st *drizzle)
464 {
465  if (drizzle == NULL)
466  {
467  return DRIZZLE_RETURN_INVALID_ARGUMENT;
468  }
469 
470  while (drizzle->query_new > 0 || drizzle->query_running > 0)
471  {
472  drizzle_return_t ret;
473 
474  (void)drizzle_query_run(drizzle, &ret);
475  if (ret != DRIZZLE_RETURN_OK && ret != DRIZZLE_RETURN_ERROR_CODE)
476  return ret;
477  }
478 
479  return DRIZZLE_RETURN_OK;
480 }
481 
482 ssize_t drizzle_safe_escape_string(char *to, const size_t max_to_size, const char *from, const size_t from_size)
483 {
484  if (to == NULL or max_to_size == 0 or from == NULL or from_size == 0)
485  {
486  return -1;
487  }
488 
489  ssize_t to_size= 0;
490  char newchar;
491 
492  for (const char *end= from +from_size; from < end; from++)
493  {
494  newchar= 0;
495  /* All multi-byte UTF8 characters have the high bit set for all bytes. */
496  if (!(*from & 0x80))
497  {
498  switch (*from)
499  {
500  case 0:
501  newchar= '0';
502  break;
503  case '\n':
504  newchar= 'n';
505  break;
506  case '\r':
507  newchar= 'r';
508  break;
509  case '\032':
510  newchar= 'Z';
511  break;
512  case '\\':
513  newchar= '\\';
514  break;
515  case '\'':
516  newchar= '\'';
517  break;
518  case '"':
519  newchar= '"';
520  break;
521  default:
522  break;
523  }
524  }
525  if (newchar != '\0')
526  {
527  if ((size_t)to_size + 2 > max_to_size)
528  return -1;
529 
530  *to++= '\\';
531  *to++= newchar;
532  to_size++;
533  }
534  else
535  {
536  if ((size_t)to_size + 1 > max_to_size)
537  return -1;
538 
539  *to++= *from;
540  }
541  to_size++;
542  }
543 
544  *to= 0;
545 
546  return to_size;
547 }
548 
549 size_t drizzle_escape_string(char *to, const char *from, const size_t from_size)
550 {
551  return size_t(drizzle_safe_escape_string(to, (from_size * 2), from, from_size));
552 }
553 
554 size_t drizzle_hex_string(char *to, const char *from, const size_t from_size)
555 {
556  if (to == NULL or from == NULL or from_size == 0)
557  {
558  return size_t(-1);
559  }
560 
561  static const char hex_map[]= "0123456789ABCDEF";
562  const char *from_end;
563 
564  for (from_end= from + from_size; from != from_end; from++)
565  {
566  *to++= hex_map[((unsigned char) *from) >> 4];
567  *to++= hex_map[((unsigned char) *from) & 0xF];
568  }
569 
570  *to= 0;
571 
572  return from_size * 2;
573 }
574 
575 void drizzle_mysql_password_hash(char *to, const char *from, const size_t from_size)
576 {
577  SHA1_CTX ctx;
578  uint8_t hash_tmp1[SHA1_DIGEST_LENGTH];
579  uint8_t hash_tmp2[SHA1_DIGEST_LENGTH];
580 
581  SHA1Init(&ctx);
582  SHA1Update(&ctx, (const uint8_t*)from, from_size);
583  SHA1Final(hash_tmp1, &ctx);
584 
585  SHA1Init(&ctx);
586  SHA1Update(&ctx, hash_tmp1, SHA1_DIGEST_LENGTH);
587  SHA1Final(hash_tmp2, &ctx);
588 
589  (void)drizzle_hex_string(to, (char*)hash_tmp2, SHA1_DIGEST_LENGTH);
590 }
void drizzle_set_error(drizzle_st *drizzle, const char *function, const char *format,...)
Definition: drizzle.cc:881
Definition: sha1.h:28
System Include Files.