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
00046
00047
00048
00049 drizzle_result_st *drizzle_result_create(drizzle_con_st *con,
00050 drizzle_result_st *result)
00051 {
00052 if (con == NULL)
00053 {
00054 return NULL;
00055 }
00056
00057 if (result == NULL)
00058 {
00059 result= new (std::nothrow) drizzle_result_st;
00060 if (result == NULL)
00061 {
00062 drizzle_set_error(con->drizzle, __func__, "Failed to allocate.");
00063 return NULL;
00064 }
00065
00066 result->options|= DRIZZLE_RESULT_ALLOCATED;
00067 }
00068 else
00069 {
00070 memset(result, 0, sizeof(drizzle_result_st));
00071 }
00072
00073 result->con= con;
00074 con->result= result;
00075
00076 if (con->result_list)
00077 con->result_list->prev= result;
00078 result->next= con->result_list;
00079 con->result_list= result;
00080 con->result_count++;
00081
00082 return result;
00083 }
00084
00085 drizzle_result_st *drizzle_result_clone(drizzle_con_st *con,
00086 drizzle_result_st *result,
00087 drizzle_result_st *from)
00088 {
00089
00090 result= drizzle_result_create(con, result);
00091 if (result == NULL)
00092 {
00093 return NULL;
00094 }
00095
00096 result->options|= (from->options & ~int(DRIZZLE_RESULT_ALLOCATED));
00097
00098 drizzle_result_set_info(result, from->info);
00099 result->error_code= from->error_code;
00100 drizzle_result_set_sqlstate(result, from->sqlstate);
00101 result->warning_count= from->warning_count;
00102 result->insert_id= from->insert_id;
00103 result->affected_rows= from->affected_rows;
00104 result->column_count= from->column_count;
00105 result->row_count= from->row_count;
00106
00107 return result;
00108 }
00109
00110 void drizzle_result_free(drizzle_result_st *result)
00111 {
00112 if (result == NULL)
00113 {
00114 return;
00115 }
00116
00117 for (drizzle_column_st* column= result->column_list; column != NULL; column= result->column_list)
00118 {
00119 drizzle_column_free(column);
00120 }
00121
00122 delete [] result->column_buffer;
00123
00124 if (result->options & DRIZZLE_RESULT_BUFFER_ROW)
00125 {
00126 for (uint64_t x= 0; x < result->row_count; x++)
00127 {
00128 drizzle_row_free(result, result->row_list[x]);
00129 }
00130
00131 free(result->row_list);
00132 free(result->field_sizes_list);
00133 }
00134
00135 if (result->con)
00136 {
00137 result->con->result_count--;
00138 if (result->con->result_list == result)
00139 result->con->result_list= result->next;
00140 }
00141
00142 if (result->prev)
00143 {
00144 result->prev->next= result->next;
00145 }
00146 if (result->next)
00147 {
00148 result->next->prev= result->prev;
00149 }
00150
00151 if (result->options & DRIZZLE_RESULT_ALLOCATED)
00152 {
00153 delete result;
00154 }
00155 }
00156
00157 void drizzle_result_free_all(drizzle_con_st *con)
00158 {
00159 if (con == NULL)
00160 {
00161 return;
00162 }
00163
00164 while (con->result_list != NULL)
00165 {
00166 drizzle_result_free(con->result_list);
00167 }
00168 }
00169
00170 drizzle_con_st *drizzle_result_drizzle_con(drizzle_result_st *result)
00171 {
00172 if (result == NULL)
00173 {
00174 return NULL;
00175 }
00176
00177 return result->con;
00178 }
00179
00180 bool drizzle_result_eof(drizzle_result_st *result)
00181 {
00182 if (result == NULL)
00183 {
00184 return false;
00185 }
00186
00187 return result->options & DRIZZLE_RESULT_EOF_PACKET;
00188 }
00189
00190 const char *drizzle_result_info(drizzle_result_st *result)
00191 {
00192 if (result == NULL)
00193 {
00194 return NULL;
00195 }
00196
00197 return result->info;
00198 }
00199
00200 const char *drizzle_result_error(drizzle_result_st *result)
00201 {
00202 if (result == NULL)
00203 {
00204 return NULL;
00205 }
00206
00207 return result->info;
00208 }
00209
00210 uint16_t drizzle_result_error_code(drizzle_result_st *result)
00211 {
00212 if (result == NULL)
00213 {
00214 return 0;
00215 }
00216
00217 return result->error_code;
00218 }
00219
00220 const char *drizzle_result_sqlstate(drizzle_result_st *result)
00221 {
00222 if (result == NULL)
00223 {
00224 return NULL;
00225 }
00226
00227 return result->sqlstate;
00228 }
00229
00230 uint16_t drizzle_result_warning_count(drizzle_result_st *result)
00231 {
00232 if (result == NULL)
00233 {
00234 return 0;
00235 }
00236
00237 return result->warning_count;
00238 }
00239
00240 uint64_t drizzle_result_insert_id(drizzle_result_st *result)
00241 {
00242 if (result == NULL)
00243 {
00244 return 0;
00245 }
00246
00247 return result->insert_id;
00248 }
00249
00250 uint64_t drizzle_result_affected_rows(drizzle_result_st *result)
00251 {
00252 if (result == NULL)
00253 {
00254 return 0;
00255 }
00256
00257 return result->affected_rows;
00258 }
00259
00260 uint16_t drizzle_result_column_count(drizzle_result_st *result)
00261 {
00262 if (result == NULL)
00263 {
00264 return 0;
00265 }
00266
00267 return result->column_count;
00268 }
00269
00270 uint64_t drizzle_result_row_count(drizzle_result_st *result)
00271 {
00272 if (result == NULL)
00273 {
00274 return 0;
00275 }
00276
00277 return result->row_count;
00278 }
00279
00280
00281
00282
00283
00284 drizzle_result_st *drizzle_result_read(drizzle_con_st *con,
00285 drizzle_result_st *result,
00286 drizzle_return_t *ret_ptr)
00287 {
00288 drizzle_return_t unused;
00289 if (ret_ptr == NULL)
00290 {
00291 ret_ptr= &unused;
00292 }
00293
00294 if (con == NULL)
00295 {
00296 *ret_ptr= DRIZZLE_RETURN_INVALID_ARGUMENT;
00297 return NULL;
00298 }
00299
00300 if (drizzle_state_none(con))
00301 {
00302 con->result= drizzle_result_create(con, result);
00303 if (con->result == NULL)
00304 {
00305 *ret_ptr= DRIZZLE_RETURN_MEMORY;
00306 return NULL;
00307 }
00308
00309 drizzle_state_push(con, drizzle_state_result_read);
00310 drizzle_state_push(con, drizzle_state_packet_read);
00311 }
00312
00313 *ret_ptr= drizzle_state_loop(con);
00314 return con->result;
00315 }
00316
00317 drizzle_return_t drizzle_result_buffer(drizzle_result_st *result)
00318 {
00319 if (result == NULL)
00320 {
00321 return DRIZZLE_RETURN_INVALID_ARGUMENT;
00322 }
00323
00324 drizzle_return_t ret;
00325 drizzle_row_t row;
00326 drizzle_row_t *row_list;
00327 size_t **field_sizes_list;
00328
00329 if (!(result->options & DRIZZLE_RESULT_BUFFER_COLUMN))
00330 {
00331 ret= drizzle_column_buffer(result);
00332 if (ret != DRIZZLE_RETURN_OK)
00333 return ret;
00334 }
00335
00336 if (result->column_count == 0)
00337 {
00338 result->options|= DRIZZLE_RESULT_BUFFER_ROW;
00339 return DRIZZLE_RETURN_OK;
00340 }
00341
00342 while (1)
00343 {
00344 row= drizzle_row_buffer(result, &ret);
00345 if (ret != DRIZZLE_RETURN_OK)
00346 return ret;
00347
00348 if (row == NULL)
00349 break;
00350
00351 if (result->row_list_size < result->row_count)
00352 {
00353 row_list= (drizzle_row_t *)realloc(result->row_list, sizeof(drizzle_row_t) * ((size_t)(result->row_list_size) + DRIZZLE_ROW_GROW_SIZE));
00354 if (row_list == NULL)
00355 {
00356 drizzle_row_free(result, row);
00357 drizzle_set_error(result->con->drizzle, __func__, "Failed to realloc row_list.");
00358 return DRIZZLE_RETURN_MEMORY;
00359 }
00360
00361 result->row_list= row_list;
00362
00363 field_sizes_list= (size_t **)realloc(result->field_sizes_list, sizeof(size_t *) * ((size_t)(result->row_list_size) + DRIZZLE_ROW_GROW_SIZE));
00364 if (field_sizes_list == NULL)
00365 {
00366 drizzle_row_free(result, row);
00367 drizzle_set_error(result->con->drizzle, "drizzle_result_buffer", "Failed to realloc field list.");
00368 return DRIZZLE_RETURN_MEMORY;
00369 }
00370
00371 result->field_sizes_list= field_sizes_list;
00372
00373 result->row_list_size+= DRIZZLE_ROW_GROW_SIZE;
00374 }
00375
00376 result->row_list[result->row_current - 1]= row;
00377 result->field_sizes_list[result->row_current - 1]= result->field_sizes;
00378 }
00379
00380 result->options|= DRIZZLE_RESULT_BUFFER_ROW;
00381 return DRIZZLE_RETURN_OK;
00382 }
00383
00384 size_t drizzle_result_row_size(drizzle_result_st *result)
00385 {
00386 if (result == NULL)
00387 {
00388 return 0;
00389 }
00390
00391 return result->con->packet_size;
00392 }
00393
00394
00395
00396
00397
00398 drizzle_return_t drizzle_result_write(drizzle_con_st *con,
00399 drizzle_result_st *result, bool flush)
00400 {
00401 if (con == NULL)
00402 {
00403 return DRIZZLE_RETURN_INVALID_ARGUMENT;
00404 }
00405
00406 if (drizzle_state_none(con))
00407 {
00408 con->result= result;
00409
00410 if (flush)
00411 drizzle_state_push(con, drizzle_state_write);
00412
00413 drizzle_state_push(con, drizzle_state_result_write);
00414 }
00415
00416 return drizzle_state_loop(con);
00417 }
00418
00419 void drizzle_result_set_row_size(drizzle_result_st *result, size_t size)
00420 {
00421 if (result == NULL)
00422 {
00423 return;
00424 }
00425
00426 result->con->packet_size= size;
00427 }
00428
00429 void drizzle_result_calc_row_size(drizzle_result_st *result,
00430 const drizzle_field_t *field,
00431 const size_t *size)
00432 {
00433 if (result == NULL)
00434 {
00435 return;
00436 }
00437
00438 result->con->packet_size= 0;
00439
00440 for (uint16_t x= 0; x < result->column_count; x++)
00441 {
00442 if (field[x] == NULL)
00443 {
00444 result->con->packet_size++;
00445 }
00446 else if (size[x] < 251)
00447 {
00448 result->con->packet_size+= (1 + size[x]);
00449 }
00450 else if (size[x] < 65536)
00451 {
00452 result->con->packet_size+= (3 + size[x]);
00453 }
00454 else if (size[x] < 16777216)
00455 {
00456 result->con->packet_size+= (4 + size[x]);
00457 }
00458 else
00459 {
00460 result->con->packet_size+= (9 + size[x]);
00461 }
00462 }
00463 }
00464
00465 void drizzle_result_set_eof(drizzle_result_st *result, bool is_eof)
00466 {
00467 if (result == NULL)
00468 {
00469 return;
00470 }
00471
00472 if (is_eof)
00473 result->options|= DRIZZLE_RESULT_EOF_PACKET;
00474 else
00475 result->options&= ~int(DRIZZLE_RESULT_EOF_PACKET);
00476 }
00477
00478 void drizzle_result_set_info(drizzle_result_st *result, const char *info)
00479 {
00480 if (result == NULL)
00481 {
00482 return;
00483 }
00484
00485 if (info == NULL)
00486 {
00487 result->info[0]= 0;
00488 }
00489 else
00490 {
00491 strncpy(result->info, info, DRIZZLE_MAX_INFO_SIZE);
00492 result->info[DRIZZLE_MAX_INFO_SIZE - 1]= 0;
00493 }
00494 }
00495
00496 void drizzle_result_set_error(drizzle_result_st *result, const char *error)
00497 {
00498 if (result == NULL)
00499 {
00500 return;
00501 }
00502
00503 drizzle_result_set_info(result, error);
00504 }
00505
00506 void drizzle_result_set_error_code(drizzle_result_st *result,
00507 uint16_t error_code)
00508 {
00509 if (result == NULL)
00510 {
00511 return;
00512 }
00513
00514 result->error_code= error_code;
00515 }
00516
00517 void drizzle_result_set_sqlstate(drizzle_result_st *result,
00518 const char *sqlstate)
00519 {
00520 if (result == NULL)
00521 {
00522 return;
00523 }
00524
00525 if (sqlstate == NULL)
00526 {
00527 result->sqlstate[0]= 0;
00528 }
00529 else
00530 {
00531 strncpy(result->sqlstate, sqlstate, DRIZZLE_MAX_SQLSTATE_SIZE + 1);
00532 result->sqlstate[DRIZZLE_MAX_SQLSTATE_SIZE]= 0;
00533 }
00534 }
00535
00536 void drizzle_result_set_warning_count(drizzle_result_st *result,
00537 uint16_t warning_count)
00538 {
00539 if (result == NULL)
00540 {
00541 return;
00542 }
00543
00544 result->warning_count= warning_count;
00545 }
00546
00547 void drizzle_result_set_insert_id(drizzle_result_st *result,
00548 uint64_t insert_id)
00549 {
00550 if (result == NULL)
00551 {
00552 return;
00553 }
00554
00555 result->insert_id= insert_id;
00556 }
00557
00558 void drizzle_result_set_affected_rows(drizzle_result_st *result,
00559 uint64_t affected_rows)
00560 {
00561 if (result == NULL)
00562 {
00563 return;
00564 }
00565
00566 result->affected_rows= affected_rows;
00567 }
00568
00569 void drizzle_result_set_column_count(drizzle_result_st *result,
00570 uint16_t column_count)
00571 {
00572 if (result == NULL)
00573 {
00574 return;
00575 }
00576
00577 result->column_count= column_count;
00578 }
00579
00580
00581
00582
00583
00584 drizzle_return_t drizzle_state_result_read(drizzle_con_st *con)
00585 {
00586 drizzle_return_t ret;
00587
00588 if (con == NULL)
00589 {
00590 return DRIZZLE_RETURN_INVALID_ARGUMENT;
00591 }
00592
00593 drizzle_log_debug(con->drizzle, "drizzle_state_result_read");
00594
00595
00596 if (con->buffer_size < con->packet_size)
00597 {
00598 drizzle_state_push(con, drizzle_state_read);
00599 return DRIZZLE_RETURN_OK;
00600 }
00601
00602 if (con->buffer_ptr[0] == 0)
00603 {
00604 con->buffer_ptr++;
00605
00606 con->result->affected_rows= drizzle_unpack_length(con, &ret);
00607 con->result->insert_id= drizzle_unpack_length(con, &ret);
00608 con->status= drizzle_con_status_t(drizzle_get_byte2(con->buffer_ptr));
00609 con->result->warning_count= drizzle_get_byte2(con->buffer_ptr + 2);
00610 con->buffer_ptr+= 4;
00611 con->buffer_size-= 5;
00612 con->packet_size-= 5;
00613 if (con->packet_size > 0)
00614 {
00615
00616 con->buffer_ptr+= 1;
00617 con->buffer_size-= 1;
00618 con->packet_size-= 1;
00619 }
00620 ret= DRIZZLE_RETURN_OK;
00621 }
00622 else if (con->buffer_ptr[0] == 254)
00623 {
00624 con->result->options= DRIZZLE_RESULT_EOF_PACKET;
00625 con->result->warning_count= drizzle_get_byte2(con->buffer_ptr + 1);
00626 con->status= drizzle_con_status_t(drizzle_get_byte2(con->buffer_ptr + 3));
00627 con->buffer_ptr+= 5;
00628 con->buffer_size-= 5;
00629 con->packet_size-= 5;
00630 ret= DRIZZLE_RETURN_OK;
00631 }
00632 else if (con->buffer_ptr[0] == 255)
00633 {
00634 con->result->error_code= drizzle_get_byte2(con->buffer_ptr + 1);
00635 con->drizzle->error_code= con->result->error_code;
00636
00637 memcpy(con->result->sqlstate, con->buffer_ptr + 4,
00638 DRIZZLE_MAX_SQLSTATE_SIZE);
00639 con->result->sqlstate[DRIZZLE_MAX_SQLSTATE_SIZE]= 0;
00640 memcpy(con->drizzle->sqlstate, con->result->sqlstate,
00641 DRIZZLE_MAX_SQLSTATE_SIZE + 1);
00642 con->buffer_ptr+= 9;
00643 con->buffer_size-= 9;
00644 con->packet_size-= 9;
00645 ret= DRIZZLE_RETURN_ERROR_CODE;
00646 }
00647 else
00648 {
00649
00650 con->result->column_count= (uint16_t)drizzle_unpack_length(con, &ret);
00651 ret= DRIZZLE_RETURN_OK;
00652 }
00653
00654 if (con->packet_size > 0)
00655 {
00656 snprintf(con->drizzle->last_error, DRIZZLE_MAX_ERROR_SIZE, "%.*s",
00657 (int32_t)con->packet_size, con->buffer_ptr);
00658 con->drizzle->last_error[DRIZZLE_MAX_ERROR_SIZE-1]= 0;
00659 snprintf(con->result->info, DRIZZLE_MAX_INFO_SIZE, "%.*s",
00660 (int32_t)con->packet_size, con->buffer_ptr);
00661 con->result->info[DRIZZLE_MAX_INFO_SIZE-1]= 0;
00662 con->buffer_ptr+= con->packet_size;
00663 con->buffer_size-= con->packet_size;
00664 con->packet_size= 0;
00665 }
00666
00667 drizzle_state_pop(con);
00668 return ret;
00669 }
00670
00671 drizzle_return_t drizzle_state_result_write(drizzle_con_st *con)
00672 {
00673 if (con == NULL)
00674 {
00675 return DRIZZLE_RETURN_INVALID_ARGUMENT;
00676 }
00677
00678 uint8_t *start= con->buffer_ptr + con->buffer_size;
00679 uint8_t *ptr;
00680 drizzle_result_st *result= con->result;
00681
00682 drizzle_log_debug(con->drizzle, "drizzle_state_result_write");
00683
00684
00685 con->packet_size= 1
00686 + 9
00687 + 9
00688 + 2
00689 + 2
00690 + strlen(result->info);
00691
00692
00693 if ((con->packet_size + 4) > DRIZZLE_MAX_BUFFER_SIZE)
00694 {
00695 drizzle_set_error(con->drizzle, "drizzle_state_result_write",
00696 "buffer too small:%zu", con->packet_size + 4);
00697 return DRIZZLE_RETURN_INTERNAL_ERROR;
00698 }
00699
00700
00701 if (((size_t)DRIZZLE_MAX_BUFFER_SIZE - (size_t)(start - con->buffer)) <
00702 con->packet_size)
00703 {
00704 drizzle_state_push(con, drizzle_state_write);
00705 return DRIZZLE_RETURN_OK;
00706 }
00707
00708
00709 ptr= start;
00710 ptr[3]= con->packet_number;
00711 con->packet_number++;
00712 ptr+= 4;
00713
00714 if (result->options & DRIZZLE_RESULT_EOF_PACKET)
00715 {
00716 ptr[0]= 254;
00717 ptr++;
00718
00719 drizzle_set_byte2(ptr, result->warning_count);
00720 ptr+= 2;
00721
00722 drizzle_set_byte2(ptr, con->status);
00723 ptr+= 2;
00724 }
00725 else if (result->error_code != 0)
00726 {
00727 ptr[0]= 255;
00728 ptr++;
00729
00730 drizzle_set_byte2(ptr, result->error_code);
00731 ptr+= 2;
00732
00733 ptr[0]= '#';
00734 ptr++;
00735
00736 memcpy(ptr, result->sqlstate, DRIZZLE_MAX_SQLSTATE_SIZE);
00737 ptr+= DRIZZLE_MAX_SQLSTATE_SIZE;
00738
00739 memcpy(ptr, result->info, strlen(result->info));
00740 ptr+= strlen(result->info);
00741 }
00742 else if (result->column_count == 0)
00743 {
00744 ptr[0]= 0;
00745 ptr++;
00746
00747 ptr= drizzle_pack_length(result->affected_rows, ptr);
00748 ptr= drizzle_pack_length(result->insert_id, ptr);
00749
00750 drizzle_set_byte2(ptr, con->status);
00751 ptr+= 2;
00752
00753 drizzle_set_byte2(ptr, result->warning_count);
00754 ptr+= 2;
00755
00756 memcpy(ptr, result->info, strlen(result->info));
00757 ptr+= strlen(result->info);
00758 }
00759 else
00760 ptr= drizzle_pack_length(result->column_count, ptr);
00761
00762 con->packet_size= ((size_t)(ptr - start) - 4);
00763 con->buffer_size+= (4 + con->packet_size);
00764
00765
00766 drizzle_set_byte3(start, con->packet_size);
00767
00768 drizzle_state_pop(con);
00769 return DRIZZLE_RETURN_OK;
00770 }