00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00043 #include <libdrizzle/common.h>
00044
00045 drizzle_result_st *drizzle_query(drizzle_con_st *con, drizzle_result_st *result,
00046 const char *query, size_t size,
00047 drizzle_return_t *ret_ptr)
00048 {
00049 return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_QUERY,
00050 (uint8_t *)query, size, size, ret_ptr);
00051 }
00052
00053 drizzle_result_st *drizzle_query_str(drizzle_con_st *con,
00054 drizzle_result_st *result,
00055 const char *query,
00056 drizzle_return_t *ret_ptr)
00057 {
00058 if (query == NULL)
00059 {
00060 return NULL;
00061 }
00062
00063 size_t size= strlen(query);
00064
00065 return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_QUERY,
00066 (uint8_t *)query, size, size, ret_ptr);
00067 }
00068
00069 drizzle_result_st *drizzle_query_inc(drizzle_con_st *con,
00070 drizzle_result_st *result,
00071 const char *query, size_t size,
00072 size_t total, drizzle_return_t *ret_ptr)
00073 {
00074 return drizzle_con_command_write(con, result, DRIZZLE_COMMAND_QUERY,
00075 (uint8_t *)query, size, total, ret_ptr);
00076 }
00077
00078 drizzle_query_st *drizzle_query_add(drizzle_st *drizzle,
00079 drizzle_query_st *query,
00080 drizzle_con_st *con,
00081 drizzle_result_st *result,
00082 const char *query_string, size_t size,
00083 drizzle_query_options_t options,
00084 void *context)
00085 {
00086 if (drizzle == NULL)
00087 {
00088 return NULL;
00089 }
00090
00091 query= drizzle_query_create(drizzle, query);
00092 if (query == NULL)
00093 {
00094 return NULL;
00095 }
00096
00097 drizzle_query_set_con(query, con);
00098 drizzle_query_set_result(query, result);
00099 drizzle_query_set_string(query, query_string, size);
00100 drizzle_query_add_options(query, options);
00101 drizzle_query_set_context(query, context);
00102
00103 return query;
00104 }
00105
00106 drizzle_query_st *drizzle_query_create(drizzle_st *drizzle,
00107 drizzle_query_st *query)
00108 {
00109 if (drizzle == NULL)
00110 {
00111 return NULL;
00112 }
00113
00114 if (query == NULL)
00115 {
00116 query= new (std::nothrow) drizzle_query_st;
00117 if (query == NULL)
00118 {
00119 drizzle_set_error(drizzle, __func__, "Failed to allocate.");
00120 return NULL;
00121 }
00122
00123 query->options|= DRIZZLE_CON_ALLOCATED;
00124 }
00125 else
00126 {
00127 memset(query, 0, sizeof(drizzle_query_st));
00128 }
00129
00130 query->drizzle= drizzle;
00131
00132 if (drizzle->query_list)
00133 drizzle->query_list->prev= query;
00134 query->next= drizzle->query_list;
00135 drizzle->query_list= query;
00136 drizzle->query_count++;
00137 drizzle->query_new++;
00138
00139 return query;
00140 }
00141
00142 void drizzle_query_free(drizzle_query_st *query)
00143 {
00144 if (query == NULL)
00145 {
00146 return;
00147 }
00148
00149 if (query->context != NULL && query->context_free_fn != NULL)
00150 query->context_free_fn(query, query->context);
00151
00152 if (query->drizzle->query_list == query)
00153 query->drizzle->query_list= query->next;
00154
00155 if (query->prev)
00156 query->prev->next= query->next;
00157
00158 if (query->next)
00159 query->next->prev= query->prev;
00160 query->drizzle->query_count--;
00161
00162 if (query->options & DRIZZLE_QUERY_ALLOCATED)
00163 {
00164 delete query;
00165 }
00166 }
00167
00168 void drizzle_query_free_all(drizzle_st *drizzle)
00169 {
00170 if (drizzle == NULL)
00171 {
00172 return;
00173 }
00174
00175 while (drizzle->query_list != NULL)
00176 {
00177 drizzle_query_free(drizzle->query_list);
00178 }
00179 }
00180
00181 drizzle_con_st *drizzle_query_con(drizzle_query_st *query)
00182 {
00183 if (query == NULL)
00184 {
00185 return NULL;
00186 }
00187
00188 return query->con;
00189 }
00190
00191 void drizzle_query_set_con(drizzle_query_st *query, drizzle_con_st *con)
00192 {
00193 if (query == NULL)
00194 {
00195 return;
00196 }
00197
00198 query->con= con;
00199 }
00200
00201 drizzle_result_st *drizzle_query_result(drizzle_query_st *query)
00202 {
00203 if (query == NULL)
00204 {
00205 return NULL;
00206 }
00207
00208 return query->result;
00209 }
00210
00211 void drizzle_query_set_result(drizzle_query_st *query,
00212 drizzle_result_st *result)
00213 {
00214 if (query == NULL)
00215 {
00216 return;
00217 }
00218
00219 query->result= result;
00220 }
00221
00222 char *drizzle_query_string(drizzle_query_st *query, size_t *size)
00223 {
00224 if (query == NULL)
00225 {
00226 return NULL;
00227 }
00228
00229 if (size)
00230 {
00231 *size= query->size;
00232 }
00233
00234 return (char *)(query->string);
00235 }
00236
00237 void drizzle_query_set_string(drizzle_query_st *query, const char *string,
00238 size_t size)
00239 {
00240 if (query == NULL)
00241 {
00242 return;
00243 }
00244
00245 query->string= string;
00246 query->size= size;
00247 }
00248
00249 drizzle_query_options_t drizzle_query_options(drizzle_query_st *query)
00250 {
00251 if (query == NULL)
00252 {
00253 return drizzle_query_options_t();
00254 }
00255
00256 return drizzle_query_options_t(query->options);
00257 }
00258
00259 void drizzle_query_set_options(drizzle_query_st *query,
00260 drizzle_query_options_t options)
00261 {
00262 if (query == NULL)
00263 {
00264 return;
00265 }
00266
00267 query->options= options;
00268 }
00269
00270 void drizzle_query_add_options(drizzle_query_st *query,
00271 drizzle_query_options_t options)
00272 {
00273 if (query == NULL)
00274 {
00275 return;
00276 }
00277
00278 query->options|= options;
00279 }
00280
00281 void drizzle_query_remove_options(drizzle_query_st *query,
00282 drizzle_query_options_t options)
00283 {
00284 if (query == NULL)
00285 {
00286 return;
00287 }
00288
00289 query->options&= ~options;
00290 }
00291
00292 void *drizzle_query_context(drizzle_query_st *query)
00293 {
00294 if (query == NULL)
00295 {
00296 return NULL;
00297 }
00298
00299 return query->context;
00300 }
00301
00302 void drizzle_query_set_context(drizzle_query_st *query, void *context)
00303 {
00304 if (query == NULL)
00305 {
00306 return;
00307 }
00308
00309 query->context= context;
00310 }
00311
00312 void drizzle_query_set_context_free_fn(drizzle_query_st *query,
00313 drizzle_query_context_free_fn *function)
00314 {
00315 if (query == NULL)
00316 {
00317 return;
00318 }
00319
00320 query->context_free_fn= function;
00321 }
00322
00323 static void drizzle_query_run_state(drizzle_query_st* query,
00324 drizzle_return_t* ret_ptr)
00325 {
00326 drizzle_return_t unused_ret;
00327 if (ret_ptr == NULL)
00328 {
00329 ret_ptr= &unused_ret;
00330 }
00331
00332 if (query == NULL)
00333 {
00334 *ret_ptr= DRIZZLE_RETURN_INVALID_ARGUMENT;
00335 return;
00336 }
00337
00338 switch (query->state)
00339 {
00340 case DRIZZLE_QUERY_STATE_INIT:
00341 query->state= DRIZZLE_QUERY_STATE_QUERY;
00342 case DRIZZLE_QUERY_STATE_QUERY:
00343 query->result= drizzle_query(query->con, query->result, query->string,
00344 query->size, ret_ptr);
00345 if (*ret_ptr == DRIZZLE_RETURN_IO_WAIT)
00346 {
00347 return;
00348 }
00349 else if (*ret_ptr != DRIZZLE_RETURN_OK)
00350 {
00351 query->state= DRIZZLE_QUERY_STATE_DONE;
00352 return;
00353 }
00354
00355 query->state= DRIZZLE_QUERY_STATE_RESULT;
00356
00357 case DRIZZLE_QUERY_STATE_RESULT:
00358 *ret_ptr= drizzle_result_buffer(query->result);
00359 if (*ret_ptr == DRIZZLE_RETURN_IO_WAIT)
00360 {
00361 return;
00362 }
00363
00364 query->state= DRIZZLE_QUERY_STATE_DONE;
00365 return;
00366
00367 default:
00368 case DRIZZLE_QUERY_STATE_DONE:
00369 return;
00370 }
00371 }
00372
00373 drizzle_query_st *drizzle_query_run(drizzle_st *drizzle,
00374 drizzle_return_t *ret_ptr)
00375 {
00376 drizzle_return_t unused_ret;
00377 if (ret_ptr == NULL)
00378 {
00379 ret_ptr= &unused_ret;
00380 }
00381
00382 if (drizzle == NULL)
00383 {
00384 *ret_ptr= DRIZZLE_RETURN_INVALID_ARGUMENT;
00385 return NULL;
00386 }
00387
00388 int options;
00389 drizzle_query_st *query;
00390 drizzle_con_st *con;
00391
00392 if (drizzle->query_new == 0 && drizzle->query_running == 0)
00393 {
00394 *ret_ptr= DRIZZLE_RETURN_OK;
00395 return NULL;
00396 }
00397
00398 options= int(drizzle->options);
00399 drizzle->options|= int(DRIZZLE_NON_BLOCKING);
00400
00401
00402 if (drizzle->query_new > 0)
00403 {
00404 for (query= drizzle->query_list; query != NULL; query= query->next)
00405 {
00406 if (query->state != DRIZZLE_QUERY_STATE_INIT)
00407 continue;
00408
00409 drizzle->query_new--;
00410 drizzle->query_running++;
00411 assert(query->con->query == NULL);
00412 query->con->query= query;
00413
00414 drizzle_query_run_state(query, ret_ptr);
00415 if (*ret_ptr != DRIZZLE_RETURN_IO_WAIT)
00416 {
00417 assert(query->state == DRIZZLE_QUERY_STATE_DONE);
00418 drizzle->query_running--;
00419 drizzle->options= int(options);
00420 query->con->query= NULL;
00421 if (*ret_ptr == DRIZZLE_RETURN_ERROR_CODE || *ret_ptr == DRIZZLE_RETURN_OK)
00422 {
00423 return query;
00424 }
00425 return NULL;
00426 }
00427 }
00428 assert(drizzle->query_new == 0);
00429 }
00430
00431 while (1)
00432 {
00433
00434 while ((con= drizzle_con_ready(drizzle)) != NULL)
00435 {
00436 query= con->query;
00437 drizzle_query_run_state(query, ret_ptr);
00438 if (query->state == DRIZZLE_QUERY_STATE_DONE)
00439 {
00440 drizzle->query_running--;
00441 drizzle->options= options;
00442 con->query= NULL;
00443 return query;
00444 }
00445 assert(*ret_ptr == DRIZZLE_RETURN_IO_WAIT);
00446 }
00447
00448 if (options & DRIZZLE_NON_BLOCKING)
00449 {
00450 *ret_ptr= DRIZZLE_RETURN_IO_WAIT;
00451 return NULL;
00452 }
00453
00454 *ret_ptr= drizzle_con_wait(drizzle);
00455 if (*ret_ptr != DRIZZLE_RETURN_OK)
00456 {
00457 drizzle->options= options;
00458 return NULL;
00459 }
00460 }
00461 }
00462
00463 drizzle_return_t drizzle_query_run_all(drizzle_st *drizzle)
00464 {
00465 if (drizzle == NULL)
00466 {
00467 return DRIZZLE_RETURN_INVALID_ARGUMENT;
00468 }
00469
00470 while (drizzle->query_new > 0 || drizzle->query_running > 0)
00471 {
00472 drizzle_return_t ret;
00473
00474 (void)drizzle_query_run(drizzle, &ret);
00475 if (ret != DRIZZLE_RETURN_OK && ret != DRIZZLE_RETURN_ERROR_CODE)
00476 return ret;
00477 }
00478
00479 return DRIZZLE_RETURN_OK;
00480 }
00481
00482 ssize_t drizzle_safe_escape_string(char *to, const size_t max_to_size, const char *from, const size_t from_size)
00483 {
00484 if (to == NULL or max_to_size == 0 or from == NULL or from_size == 0)
00485 {
00486 return -1;
00487 }
00488
00489 ssize_t to_size= 0;
00490 char newchar;
00491
00492 for (const char *end= from +from_size; from < end; from++)
00493 {
00494 newchar= 0;
00495
00496 if (!(*from & 0x80))
00497 {
00498 switch (*from)
00499 {
00500 case 0:
00501 newchar= '0';
00502 break;
00503 case '\n':
00504 newchar= 'n';
00505 break;
00506 case '\r':
00507 newchar= 'r';
00508 break;
00509 case '\032':
00510 newchar= 'Z';
00511 break;
00512 case '\\':
00513 newchar= '\\';
00514 break;
00515 case '\'':
00516 newchar= '\'';
00517 break;
00518 case '"':
00519 newchar= '"';
00520 break;
00521 default:
00522 break;
00523 }
00524 }
00525 if (newchar != '\0')
00526 {
00527 if ((size_t)to_size + 2 > max_to_size)
00528 return -1;
00529
00530 *to++= '\\';
00531 *to++= newchar;
00532 to_size++;
00533 }
00534 else
00535 {
00536 if ((size_t)to_size + 1 > max_to_size)
00537 return -1;
00538
00539 *to++= *from;
00540 }
00541 to_size++;
00542 }
00543
00544 *to= 0;
00545
00546 return to_size;
00547 }
00548
00549 size_t drizzle_escape_string(char *to, const char *from, const size_t from_size)
00550 {
00551 return size_t(drizzle_safe_escape_string(to, (from_size * 2), from, from_size));
00552 }
00553
00554 size_t drizzle_hex_string(char *to, const char *from, const size_t from_size)
00555 {
00556 if (to == NULL or from == NULL or from_size == 0)
00557 {
00558 return size_t(-1);
00559 }
00560
00561 static const char hex_map[]= "0123456789ABCDEF";
00562 const char *from_end;
00563
00564 for (from_end= from + from_size; from != from_end; from++)
00565 {
00566 *to++= hex_map[((unsigned char) *from) >> 4];
00567 *to++= hex_map[((unsigned char) *from) & 0xF];
00568 }
00569
00570 *to= 0;
00571
00572 return from_size * 2;
00573 }
00574
00575 void drizzle_mysql_password_hash(char *to, const char *from, const size_t from_size)
00576 {
00577 SHA1_CTX ctx;
00578 uint8_t hash_tmp1[SHA1_DIGEST_LENGTH];
00579 uint8_t hash_tmp2[SHA1_DIGEST_LENGTH];
00580
00581 SHA1Init(&ctx);
00582 SHA1Update(&ctx, (const uint8_t*)from, from_size);
00583 SHA1Final(hash_tmp1, &ctx);
00584
00585 SHA1Init(&ctx);
00586 SHA1Update(&ctx, hash_tmp1, SHA1_DIGEST_LENGTH);
00587 SHA1Final(hash_tmp2, &ctx);
00588
00589 (void)drizzle_hex_string(to, (char*)hash_tmp2, SHA1_DIGEST_LENGTH);
00590 }