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