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