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
00042 #include "common.h"
00043
00044
00045
00046
00047
00048 drizzle_result_st *drizzle_result_create(drizzle_con_st *con,
00049 drizzle_result_st *result)
00050 {
00051 if (result == NULL)
00052 {
00053 result= malloc(sizeof(drizzle_result_st));
00054 if (result == NULL)
00055 {
00056 drizzle_set_error(con->drizzle, "drizzle_result_create", "malloc");
00057 return NULL;
00058 }
00059
00060 memset(result, 0, sizeof(drizzle_result_st));
00061 result->options|= DRIZZLE_RESULT_ALLOCATED;
00062 }
00063 else
00064 memset(result, 0, sizeof(drizzle_result_st));
00065
00066 result->con= con;
00067 con->result= result;
00068
00069 if (con->result_list)
00070 con->result_list->prev= result;
00071 result->next= con->result_list;
00072 con->result_list= result;
00073 con->result_count++;
00074
00075 return result;
00076 }
00077
00078 drizzle_result_st *drizzle_result_clone(drizzle_con_st *con,
00079 drizzle_result_st *result,
00080 drizzle_result_st *from)
00081 {
00082 result= drizzle_result_create(con, result);
00083 if (result == NULL)
00084 return NULL;
00085
00086 result->options|= (from->options &
00087 (drizzle_result_options_t)~DRIZZLE_RESULT_ALLOCATED);
00088
00089 drizzle_result_set_info(result, from->info);
00090 result->error_code= from->error_code;
00091 drizzle_result_set_sqlstate(result, from->sqlstate);
00092 result->warning_count= from->warning_count;
00093 result->insert_id= from->insert_id;
00094 result->affected_rows= from->affected_rows;
00095 result->column_count= from->column_count;
00096 result->row_count= from->row_count;
00097
00098 return result;
00099 }
00100
00101 void drizzle_result_free(drizzle_result_st *result)
00102 {
00103 drizzle_column_st *column;
00104 uint64_t x;
00105
00106 for (column= result->column_list; column != NULL; column= result->column_list)
00107 drizzle_column_free(column);
00108
00109 if (result->column_buffer != NULL)
00110 free(result->column_buffer);
00111
00112 if (result->options & DRIZZLE_RESULT_BUFFER_ROW)
00113 {
00114 for (x= 0; x < result->row_count; x++)
00115 drizzle_row_free(result, result->row_list[x]);
00116
00117 free(result->row_list);
00118 free(result->field_sizes_list);
00119 }
00120
00121 if (result->con)
00122 {
00123 result->con->result_count--;
00124 if (result->con->result_list == result)
00125 result->con->result_list= result->next;
00126 }
00127 if (result->prev)
00128 result->prev->next= result->next;
00129 if (result->next)
00130 result->next->prev= result->prev;
00131
00132 if (result->options & DRIZZLE_RESULT_ALLOCATED)
00133 free(result);
00134 }
00135
00136 void drizzle_result_free_all(drizzle_con_st *con)
00137 {
00138 while (con->result_list != NULL)
00139 drizzle_result_free(con->result_list);
00140 }
00141
00142 drizzle_con_st *drizzle_result_drizzle_con(drizzle_result_st *result)
00143 {
00144 return result->con;
00145 }
00146
00147 bool drizzle_result_eof(drizzle_result_st *result)
00148 {
00149 return result->options & DRIZZLE_RESULT_EOF_PACKET;
00150 }
00151
00152 const char *drizzle_result_info(drizzle_result_st *result)
00153 {
00154 return result->info;
00155 }
00156
00157 const char *drizzle_result_error(drizzle_result_st *result)
00158 {
00159 return result->info;
00160 }
00161
00162 uint16_t drizzle_result_error_code(drizzle_result_st *result)
00163 {
00164 return result->error_code;
00165 }
00166
00167 const char *drizzle_result_sqlstate(drizzle_result_st *result)
00168 {
00169 return result->sqlstate;
00170 }
00171
00172 uint16_t drizzle_result_warning_count(drizzle_result_st *result)
00173 {
00174 return result->warning_count;
00175 }
00176
00177 uint64_t drizzle_result_insert_id(drizzle_result_st *result)
00178 {
00179 return result->insert_id;
00180 }
00181
00182 uint64_t drizzle_result_affected_rows(drizzle_result_st *result)
00183 {
00184 return result->affected_rows;
00185 }
00186
00187 uint16_t drizzle_result_column_count(drizzle_result_st *result)
00188 {
00189 return result->column_count;
00190 }
00191
00192 uint64_t drizzle_result_row_count(drizzle_result_st *result)
00193 {
00194 return result->row_count;
00195 }
00196
00197
00198
00199
00200
00201 drizzle_result_st *drizzle_result_read(drizzle_con_st *con,
00202 drizzle_result_st *result,
00203 drizzle_return_t *ret_ptr)
00204 {
00205 if (drizzle_state_none(con))
00206 {
00207 con->result= drizzle_result_create(con, result);
00208 if (con->result == NULL)
00209 {
00210 *ret_ptr= DRIZZLE_RETURN_MEMORY;
00211 return NULL;
00212 }
00213
00214 drizzle_state_push(con, drizzle_state_result_read);
00215 drizzle_state_push(con, drizzle_state_packet_read);
00216 }
00217
00218 *ret_ptr= drizzle_state_loop(con);
00219 return con->result;
00220 }
00221
00222 drizzle_return_t drizzle_result_buffer(drizzle_result_st *result)
00223 {
00224 drizzle_return_t ret;
00225 drizzle_row_t row;
00226 drizzle_row_t *row_list;
00227 size_t **field_sizes_list;
00228
00229 if (!(result->options & DRIZZLE_RESULT_BUFFER_COLUMN))
00230 {
00231 ret= drizzle_column_buffer(result);
00232 if (ret != DRIZZLE_RETURN_OK)
00233 return ret;
00234 }
00235
00236 if (result->column_count == 0)
00237 {
00238 result->options|= DRIZZLE_RESULT_BUFFER_ROW;
00239 return DRIZZLE_RETURN_OK;
00240 }
00241
00242 while (1)
00243 {
00244 row= drizzle_row_buffer(result, &ret);
00245 if (ret != DRIZZLE_RETURN_OK)
00246 return ret;
00247
00248 if (row == NULL)
00249 break;
00250
00251 if (result->row_list_size < result->row_count)
00252 {
00253 row_list= realloc(result->row_list, sizeof(drizzle_row_t) *
00254 ((size_t)(result->row_list_size) +
00255 DRIZZLE_ROW_GROW_SIZE));
00256 if (row_list == NULL)
00257 {
00258 drizzle_row_free(result, row);
00259 drizzle_set_error(result->con->drizzle, "drizzle_result_buffer",
00260 "realloc");
00261 return DRIZZLE_RETURN_MEMORY;
00262 }
00263
00264 result->row_list= row_list;
00265
00266 field_sizes_list= realloc(result->field_sizes_list, sizeof(size_t *) *
00267 ((size_t)(result->row_list_size) +
00268 DRIZZLE_ROW_GROW_SIZE));
00269 if (field_sizes_list == NULL)
00270 {
00271 drizzle_row_free(result, row);
00272 drizzle_set_error(result->con->drizzle, "drizzle_result_buffer",
00273 "realloc");
00274 return DRIZZLE_RETURN_MEMORY;
00275 }
00276
00277 result->field_sizes_list= field_sizes_list;
00278
00279 result->row_list_size+= DRIZZLE_ROW_GROW_SIZE;
00280 }
00281
00282 result->row_list[result->row_current - 1]= row;
00283 result->field_sizes_list[result->row_current - 1]= result->field_sizes;
00284 }
00285
00286 result->options|= DRIZZLE_RESULT_BUFFER_ROW;
00287 return DRIZZLE_RETURN_OK;
00288 }
00289
00290 size_t drizzle_result_row_size(drizzle_result_st *result)
00291 {
00292 return result->con->packet_size;
00293 }
00294
00295
00296
00297
00298
00299 drizzle_return_t drizzle_result_write(drizzle_con_st *con,
00300 drizzle_result_st *result, bool flush)
00301 {
00302 if (drizzle_state_none(con))
00303 {
00304 con->result= result;
00305
00306 if (flush)
00307 drizzle_state_push(con, drizzle_state_write);
00308
00309 drizzle_state_push(con, drizzle_state_result_write);
00310 }
00311
00312 return drizzle_state_loop(con);
00313 }
00314
00315 void drizzle_result_set_row_size(drizzle_result_st *result, size_t size)
00316 {
00317 result->con->packet_size= size;
00318 }
00319
00320 void drizzle_result_calc_row_size(drizzle_result_st *result,
00321 const drizzle_field_t *field,
00322 const size_t *size)
00323 {
00324 uint16_t x;
00325
00326 result->con->packet_size= 0;
00327
00328 for (x= 0; x < result->column_count; x++)
00329 {
00330 if (field[x] == NULL)
00331 result->con->packet_size++;
00332 else if (size[x] < 251)
00333 result->con->packet_size+= (1 + size[x]);
00334 else if (size[x] < 65536)
00335 result->con->packet_size+= (3 + size[x]);
00336 else if (size[x] < 16777216)
00337 result->con->packet_size+= (4 + size[x]);
00338 else
00339 result->con->packet_size+= (9 + size[x]);
00340 }
00341 }
00342
00343 void drizzle_result_set_eof(drizzle_result_st *result, bool is_eof)
00344 {
00345 if (is_eof)
00346 result->options|= DRIZZLE_RESULT_EOF_PACKET;
00347 else
00348 result->options&= (drizzle_result_options_t)~DRIZZLE_RESULT_EOF_PACKET;
00349 }
00350
00351 void drizzle_result_set_info(drizzle_result_st *result, const char *info)
00352 {
00353 if (info == NULL)
00354 result->info[0]= 0;
00355 else
00356 {
00357 strncpy(result->info, info, DRIZZLE_MAX_INFO_SIZE);
00358 result->info[DRIZZLE_MAX_INFO_SIZE - 1]= 0;
00359 }
00360 }
00361
00362 void drizzle_result_set_error(drizzle_result_st *result, const char *error)
00363 {
00364 drizzle_result_set_info(result, error);
00365 }
00366
00367 void drizzle_result_set_error_code(drizzle_result_st *result,
00368 uint16_t error_code)
00369 {
00370 result->error_code= error_code;
00371 }
00372
00373 void drizzle_result_set_sqlstate(drizzle_result_st *result,
00374 const char *sqlstate)
00375 {
00376 if (sqlstate == NULL)
00377 result->sqlstate[0]= 0;
00378 else
00379 {
00380 strncpy(result->sqlstate, sqlstate, DRIZZLE_MAX_SQLSTATE_SIZE + 1);
00381 result->sqlstate[DRIZZLE_MAX_SQLSTATE_SIZE]= 0;
00382 }
00383 }
00384
00385 void drizzle_result_set_warning_count(drizzle_result_st *result,
00386 uint16_t warning_count)
00387 {
00388 result->warning_count= warning_count;
00389 }
00390
00391 void drizzle_result_set_insert_id(drizzle_result_st *result,
00392 uint64_t insert_id)
00393 {
00394 result->insert_id= insert_id;
00395 }
00396
00397 void drizzle_result_set_affected_rows(drizzle_result_st *result,
00398 uint64_t affected_rows)
00399 {
00400 result->affected_rows= affected_rows;
00401 }
00402
00403 void drizzle_result_set_column_count(drizzle_result_st *result,
00404 uint16_t column_count)
00405 {
00406 result->column_count= column_count;
00407 }
00408
00409
00410
00411
00412
00413 drizzle_return_t drizzle_state_result_read(drizzle_con_st *con)
00414 {
00415 drizzle_return_t ret;
00416
00417 drizzle_log_debug(con->drizzle, "drizzle_state_result_read");
00418
00419
00420 if (con->buffer_size < con->packet_size)
00421 {
00422 drizzle_state_push(con, drizzle_state_read);
00423 return DRIZZLE_RETURN_OK;
00424 }
00425
00426 if (con->buffer_ptr[0] == 0)
00427 {
00428 con->buffer_ptr++;
00429
00430 con->result->affected_rows= drizzle_unpack_length(con, &ret);
00431 con->result->insert_id= drizzle_unpack_length(con, &ret);
00432 con->status= drizzle_get_byte2(con->buffer_ptr);
00433 con->result->warning_count= drizzle_get_byte2(con->buffer_ptr + 2);
00434 con->buffer_ptr+= 4;
00435 con->buffer_size-= 5;
00436 con->packet_size-= 5;
00437 if (con->packet_size > 0)
00438 {
00439
00440 con->buffer_ptr+= 1;
00441 con->buffer_size-= 1;
00442 con->packet_size-= 1;
00443 }
00444 ret= DRIZZLE_RETURN_OK;
00445 }
00446 else if (con->buffer_ptr[0] == 254)
00447 {
00448 con->result->options= DRIZZLE_RESULT_EOF_PACKET;
00449 con->result->warning_count= drizzle_get_byte2(con->buffer_ptr + 1);
00450 con->status= drizzle_get_byte2(con->buffer_ptr + 3);
00451 con->buffer_ptr+= 5;
00452 con->buffer_size-= 5;
00453 con->packet_size-= 5;
00454 ret= DRIZZLE_RETURN_OK;
00455 }
00456 else if (con->buffer_ptr[0] == 255)
00457 {
00458 con->result->error_code= drizzle_get_byte2(con->buffer_ptr + 1);
00459 con->drizzle->error_code= con->result->error_code;
00460
00461 memcpy(con->result->sqlstate, con->buffer_ptr + 4,
00462 DRIZZLE_MAX_SQLSTATE_SIZE);
00463 con->result->sqlstate[DRIZZLE_MAX_SQLSTATE_SIZE]= 0;
00464 memcpy(con->drizzle->sqlstate, con->result->sqlstate,
00465 DRIZZLE_MAX_SQLSTATE_SIZE + 1);
00466 con->buffer_ptr+= 9;
00467 con->buffer_size-= 9;
00468 con->packet_size-= 9;
00469 ret= DRIZZLE_RETURN_ERROR_CODE;
00470 }
00471 else
00472 {
00473
00474 con->result->column_count= (uint16_t)drizzle_unpack_length(con, &ret);
00475 ret= DRIZZLE_RETURN_OK;
00476 }
00477
00478 if (con->packet_size > 0)
00479 {
00480 snprintf(con->drizzle->last_error, DRIZZLE_MAX_ERROR_SIZE, "%.*s",
00481 (int32_t)con->packet_size, con->buffer_ptr);
00482 snprintf(con->result->info, DRIZZLE_MAX_INFO_SIZE, "%.*s",
00483 (int32_t)con->packet_size, con->buffer_ptr);
00484 con->buffer_ptr+= con->packet_size;
00485 con->buffer_size-= con->packet_size;
00486 con->packet_size= 0;
00487 }
00488
00489 drizzle_state_pop(con);
00490 return ret;
00491 }
00492
00493 drizzle_return_t drizzle_state_result_write(drizzle_con_st *con)
00494 {
00495 uint8_t *start= con->buffer_ptr + con->buffer_size;
00496 uint8_t *ptr;
00497 drizzle_result_st *result= con->result;
00498
00499 drizzle_log_debug(con->drizzle, "drizzle_state_result_write");
00500
00501
00502 con->packet_size= 1
00503 + 9
00504 + 9
00505 + 2
00506 + 2
00507 + strlen(result->info);
00508
00509
00510 if ((con->packet_size + 4) > DRIZZLE_MAX_BUFFER_SIZE)
00511 {
00512 drizzle_set_error(con->drizzle, "drizzle_state_result_write",
00513 "buffer too small:%zu", con->packet_size + 4);
00514 return DRIZZLE_RETURN_INTERNAL_ERROR;
00515 }
00516
00517
00518 if (((size_t)DRIZZLE_MAX_BUFFER_SIZE - (size_t)(start - con->buffer)) <
00519 con->packet_size)
00520 {
00521 drizzle_state_push(con, drizzle_state_write);
00522 return DRIZZLE_RETURN_OK;
00523 }
00524
00525
00526 ptr= start;
00527 ptr[3]= con->packet_number;
00528 con->packet_number++;
00529 ptr+= 4;
00530
00531 if (result->options & DRIZZLE_RESULT_EOF_PACKET)
00532 {
00533 ptr[0]= 254;
00534 ptr++;
00535
00536 drizzle_set_byte2(ptr, result->warning_count);
00537 ptr+= 2;
00538
00539 drizzle_set_byte2(ptr, con->status);
00540 ptr+= 2;
00541 }
00542 else if (result->error_code != 0)
00543 {
00544 ptr[0]= 255;
00545 ptr++;
00546
00547 drizzle_set_byte2(ptr, result->error_code);
00548 ptr+= 2;
00549
00550 ptr[0]= '#';
00551 ptr++;
00552
00553 memcpy(ptr, result->sqlstate, DRIZZLE_MAX_SQLSTATE_SIZE);
00554 ptr+= DRIZZLE_MAX_SQLSTATE_SIZE;
00555
00556 memcpy(ptr, result->info, strlen(result->info));
00557 ptr+= strlen(result->info);
00558 }
00559 else if (result->column_count == 0)
00560 {
00561 ptr[0]= 0;
00562 ptr++;
00563
00564 ptr= drizzle_pack_length(result->affected_rows, ptr);
00565 ptr= drizzle_pack_length(result->insert_id, ptr);
00566
00567 drizzle_set_byte2(ptr, con->status);
00568 ptr+= 2;
00569
00570 drizzle_set_byte2(ptr, result->warning_count);
00571 ptr+= 2;
00572
00573 memcpy(ptr, result->info, strlen(result->info));
00574 ptr+= strlen(result->info);
00575 }
00576 else
00577 ptr= drizzle_pack_length(result->column_count, ptr);
00578
00579 con->packet_size= ((size_t)(ptr - start) - 4);
00580 con->buffer_size+= (4 + con->packet_size);
00581
00582
00583 drizzle_set_byte3(start, con->packet_size);
00584
00585 drizzle_state_pop(con);
00586 return DRIZZLE_RETURN_OK;
00587 }