libdrizzle Developer Documentation

result.c
Go to the documentation of this file.
1/*
2 * Drizzle Client & Protocol Library
3 *
4 * Copyright (C) 2008 Eric Day (eday@oddments.org)
5 * All rights reserved.
6 *
7 * Use and distribution licensed under the BSD license. See
8 * the COPYING file in this directory for full text.
9 */
10
16#include "common.h"
17
18/*
19 * Common definitions
20 */
21
23 drizzle_result_st *result)
24{
25 if (result == NULL)
26 {
27 result= malloc(sizeof(drizzle_result_st));
28 if (result == NULL)
29 {
30 drizzle_set_error(con->drizzle, "drizzle_result_create", "malloc");
31 return NULL;
32 }
33
34 memset(result, 0, sizeof(drizzle_result_st));
36 }
37 else
38 memset(result, 0, sizeof(drizzle_result_st));
39
40 result->con= con;
41 con->result= result;
42
43 if (con->result_list)
44 con->result_list->prev= result;
45 result->next= con->result_list;
46 con->result_list= result;
47 con->result_count++;
48
49 return result;
50}
51
53 drizzle_result_st *result,
55{
56 result= drizzle_result_create(con, result);
57 if (result == NULL)
58 return NULL;
59
60 result->options|= (from->options &
61 (drizzle_result_options_t)~DRIZZLE_RESULT_ALLOCATED);
62
63 drizzle_result_set_info(result, from->info);
64 result->error_code= from->error_code;
66 result->warning_count= from->warning_count;
67 result->insert_id= from->insert_id;
68 result->affected_rows= from->affected_rows;
69 result->column_count= from->column_count;
70 result->row_count= from->row_count;
71
72 return result;
73}
74
76{
77 drizzle_column_st *column;
78 uint64_t x;
79
80 for (column= result->column_list; column != NULL; column= result->column_list)
81 drizzle_column_free(column);
82
83 if (result->column_buffer != NULL)
84 free(result->column_buffer);
85
87 {
88 for (x= 0; x < result->row_count; x++)
89 drizzle_row_free(result, result->row_list[x]);
90
91 free(result->row_list);
92 free(result->field_sizes_list);
93 }
94
95 if (result->con->result_list == result)
96 result->con->result_list= result->next;
97 if (result->prev)
98 result->prev->next= result->next;
99 if (result->next)
100 result->next->prev= result->prev;
101 result->con->result_count--;
102
103 if (result->options & DRIZZLE_RESULT_ALLOCATED)
104 free(result);
105}
106
108{
109 while (con->result_list != NULL)
111}
112
114{
115 return result->con;
116}
117
119{
120 return result->options & DRIZZLE_RESULT_EOF_PACKET;
121}
122
124{
125 return result->info;
126}
127
129{
130 return result->info;
131}
132
134{
135 return result->error_code;
136}
137
139{
140 return result->sqlstate;
141}
142
144{
145 return result->warning_count;
146}
147
149{
150 return result->insert_id;
151}
152
154{
155 return result->affected_rows;
156}
157
159{
160 return result->column_count;
161}
162
164{
165 return result->row_count;
166}
167
168/*
169 * Client definitions
170 */
171
173 drizzle_result_st *result,
174 drizzle_return_t *ret_ptr)
175{
176 if (drizzle_state_none(con))
177 {
178 con->result= drizzle_result_create(con, result);
179 if (con->result == NULL)
180 {
181 *ret_ptr= DRIZZLE_RETURN_MEMORY;
182 return NULL;
183 }
184
187 }
188
189 *ret_ptr= drizzle_state_loop(con);
190 return con->result;
191}
192
194{
196 drizzle_row_t row;
197 drizzle_row_t *row_list;
198 size_t **field_sizes_list;
199
200 if (!(result->options & DRIZZLE_RESULT_BUFFER_COLUMN))
201 {
202 ret= drizzle_column_buffer(result);
203 if (ret != DRIZZLE_RETURN_OK)
204 return ret;
205 }
206
207 if (result->column_count == 0)
208 {
210 return DRIZZLE_RETURN_OK;
211 }
212
213 while (1)
214 {
215 row= drizzle_row_buffer(result, &ret);
216 if (ret != DRIZZLE_RETURN_OK)
217 return ret;
218
219 if (row == NULL)
220 break;
221
222 if (result->row_list_size < result->row_count)
223 {
224 row_list= realloc(result->row_list, sizeof(drizzle_row_t) *
225 ((size_t)(result->row_list_size) +
227 if (row_list == NULL)
228 {
229 drizzle_row_free(result, row);
230 drizzle_set_error(result->con->drizzle, "drizzle_result_buffer",
231 "realloc");
233 }
234
235 result->row_list= row_list;
236
237 field_sizes_list= realloc(result->field_sizes_list, sizeof(size_t *) *
238 ((size_t)(result->row_list_size) +
240 if (field_sizes_list == NULL)
241 {
242 drizzle_row_free(result, row);
243 drizzle_set_error(result->con->drizzle, "drizzle_result_buffer",
244 "realloc");
246 }
247
248 result->field_sizes_list= field_sizes_list;
249
251 }
252
253 result->row_list[result->row_current - 1]= row;
254 result->field_sizes_list[result->row_current - 1]= result->field_sizes;
255 }
256
258 return DRIZZLE_RETURN_OK;
259}
260
262{
263 return result->con->packet_size;
264}
265
266/*
267 * Server definitions
268 */
269
271 drizzle_result_st *result, bool flush)
272{
273 if (drizzle_state_none(con))
274 {
275 con->result= result;
276
277 if (flush)
279
281 }
282
283 return drizzle_state_loop(con);
284}
285
287{
288 result->con->packet_size= size;
289}
290
292 const drizzle_field_t *field,
293 const size_t *size)
294{
295 uint16_t x;
296
297 result->con->packet_size= 0;
298
299 for (x= 0; x < result->column_count; x++)
300 {
301 if (field[x] == NULL)
302 result->con->packet_size++;
303 else if (size[x] < 251)
304 result->con->packet_size+= (1 + size[x]);
305 else if (size[x] < 65536)
306 result->con->packet_size+= (3 + size[x]);
307 else if (size[x] < 16777216)
308 result->con->packet_size+= (4 + size[x]);
309 else
310 result->con->packet_size+= (9 + size[x]);
311 }
312}
313
315{
316 if (eof)
318 else
320}
321
322void drizzle_result_set_info(drizzle_result_st *result, const char *info)
323{
324 if (info == NULL)
325 result->info[0]= 0;
326 else
327 {
328 strncpy(result->info, info, DRIZZLE_MAX_INFO_SIZE);
329 result->info[DRIZZLE_MAX_INFO_SIZE - 1]= 0;
330 }
331}
332
333void drizzle_result_set_error(drizzle_result_st *result, const char *error)
334{
335 drizzle_result_set_info(result, error);
336}
337
339 uint16_t error_code)
340{
341 result->error_code= error_code;
342}
343
345 const char *sqlstate)
346{
347 if (sqlstate == NULL)
348 result->sqlstate[0]= 0;
349 else
350 {
351 strncpy(result->sqlstate, sqlstate, DRIZZLE_MAX_SQLSTATE_SIZE + 1);
353 }
354}
355
357 uint16_t warning_count)
358{
359 result->warning_count= warning_count;
360}
361
363 uint64_t insert_id)
364{
365 result->insert_id= insert_id;
366}
367
369 uint64_t affected_rows)
370{
371 result->affected_rows= affected_rows;
372}
373
375 uint16_t column_count)
376{
377 result->column_count= column_count;
378}
379
380/*
381 * Internal state functions.
382 */
383
385{
387
388 drizzle_log_debug(con->drizzle, "drizzle_state_result_read");
389
390 /* Assume the entire result packet will fit in the buffer. */
391 if (con->buffer_size < con->packet_size)
392 {
394 return DRIZZLE_RETURN_OK;
395 }
396
397 if (con->buffer_ptr[0] == 0)
398 {
399 con->buffer_ptr++;
400 /* We can ignore the returns since we've buffered the entire packet. */
402 con->result->insert_id= drizzle_unpack_length(con, &ret);
405 con->buffer_ptr+= 4;
406 con->buffer_size-= 5;
407 con->packet_size-= 5;
408 if (con->packet_size > 0)
409 {
410 /* Skip one byte for message size. */
411 con->buffer_ptr+= 1;
412 con->buffer_size-= 1;
413 con->packet_size-= 1;
414 }
416 }
417 else if (con->buffer_ptr[0] == 254)
418 {
421 con->status= drizzle_get_byte2(con->buffer_ptr + 3);
422 con->buffer_ptr+= 5;
423 con->buffer_size-= 5;
424 con->packet_size-= 5;
426 }
427 else if (con->buffer_ptr[0] == 255)
428 {
430 con->drizzle->error_code= con->result->error_code;
431 /* Byte 3 is always a '#' character, skip it. */
432 memcpy(con->result->sqlstate, con->buffer_ptr + 4,
435 memcpy(con->drizzle->sqlstate, con->result->sqlstate,
437 con->buffer_ptr+= 9;
438 con->buffer_size-= 9;
439 con->packet_size-= 9;
441 }
442 else
443 {
444 /* We can ignore the return since we've buffered the entire packet. */
445 con->result->column_count= (uint16_t)drizzle_unpack_length(con, &ret);
447 }
448
449 if (con->packet_size > 0)
450 {
451 snprintf(con->drizzle->last_error, DRIZZLE_MAX_ERROR_SIZE, "%.*s",
452 (int32_t)con->packet_size, con->buffer_ptr);
453 snprintf(con->result->info, DRIZZLE_MAX_INFO_SIZE, "%.*s",
454 (int32_t)con->packet_size, con->buffer_ptr);
455 con->buffer_ptr+= con->packet_size;
456 con->buffer_size-= con->packet_size;
457 con->packet_size= 0;
458 }
459
461 return ret;
462}
463
465{
466 uint8_t *start= con->buffer_ptr + con->buffer_size;
467 uint8_t *ptr;
468 drizzle_result_st *result= con->result;
469
470 drizzle_log_debug(con->drizzle, "drizzle_state_result_write");
471
472 /* Calculate max packet size. */
473 con->packet_size= 1 /* OK/Field Count/EOF/Error */
474 + 9 /* Affected rows */
475 + 9 /* Insert ID */
476 + 2 /* Status */
477 + 2 /* Warning count */
478 + strlen(result->info); /* Info/error message */
479
480 /* Assume the entire result packet will fit in the buffer. */
481 if ((con->packet_size + 4) > DRIZZLE_MAX_BUFFER_SIZE)
482 {
483 drizzle_set_error(con->drizzle, "drizzle_state_result_write",
484 "buffer too small:%zu", con->packet_size + 4);
486 }
487
488 /* Flush buffer if there is not enough room. */
489 if (((size_t)DRIZZLE_MAX_BUFFER_SIZE - (size_t)(start - con->buffer)) <
490 con->packet_size)
491 {
493 return DRIZZLE_RETURN_OK;
494 }
495
496 /* Store packet size at the end since it may change. */
497 ptr= start;
498 ptr[3]= con->packet_number;
499 con->packet_number++;
500 ptr+= 4;
501
503 {
504 ptr[0]= 254;
505 ptr++;
506
507 drizzle_set_byte2(ptr, result->warning_count);
508 ptr+= 2;
509
510 drizzle_set_byte2(ptr, con->status);
511 ptr+= 2;
512 }
513 else if (result->error_code != 0)
514 {
515 ptr[0]= 255;
516 ptr++;
517
518 drizzle_set_byte2(ptr, result->error_code);
519 ptr+= 2;
520
521 ptr[0]= '#';
522 ptr++;
523
524 memcpy(ptr, result->sqlstate, DRIZZLE_MAX_SQLSTATE_SIZE);
526
527 memcpy(ptr, result->info, strlen(result->info));
528 ptr+= strlen(result->info);
529 }
530 else if (result->column_count == 0)
531 {
532 ptr[0]= 0;
533 ptr++;
534
535 ptr= drizzle_pack_length(result->affected_rows, ptr);
536 ptr= drizzle_pack_length(result->insert_id, ptr);
537
538 drizzle_set_byte2(ptr, con->status);
539 ptr+= 2;
540
541 drizzle_set_byte2(ptr, result->warning_count);
542 ptr+= 2;
543
544 memcpy(ptr, result->info, strlen(result->info));
545 ptr+= strlen(result->info);
546 }
547 else
548 ptr= drizzle_pack_length(result->column_count, ptr);
549
550 con->packet_size= ((size_t)(ptr - start) - 4);
551 con->buffer_size+= (4 + con->packet_size);
552
553 /* Store packet size now. */
554 drizzle_set_byte3(start, con->packet_size);
555
557 return DRIZZLE_RETURN_OK;
558}
System Include Files.
drizzle_return_t drizzle_column_buffer(drizzle_result_st *result)
Definition column.c:485
void drizzle_column_free(drizzle_column_st *column)
Definition column.c:356
static void drizzle_state_pop(drizzle_con_st *con)
Definition conn_local.h:73
static void drizzle_state_push(drizzle_con_st *con, drizzle_state_fn *function)
Definition conn_local.h:57
static bool drizzle_state_none(drizzle_con_st *con)
Definition conn_local.h:45
#define DRIZZLE_MAX_BUFFER_SIZE
Definition constants.h:55
#define DRIZZLE_MAX_ERROR_SIZE
Definition constants.h:44
drizzle_return_t
Definition constants.h:69
#define DRIZZLE_MAX_SQLSTATE_SIZE
Definition constants.h:49
#define DRIZZLE_ROW_GROW_SIZE
Definition constants.h:60
#define DRIZZLE_MAX_INFO_SIZE
Definition constants.h:48
@ DRIZZLE_RETURN_ERROR_CODE
Definition constants.h:87
@ DRIZZLE_RETURN_OK
Definition constants.h:70
@ DRIZZLE_RETURN_INTERNAL_ERROR
Definition constants.h:76
@ DRIZZLE_RETURN_MEMORY
Definition constants.h:74
static void drizzle_log_debug(drizzle_st *drizzle, const char *format,...)
void drizzle_set_error(drizzle_st *drizzle, const char *function, const char *format,...)
Definition drizzle.c:633
#define drizzle_set_byte3(__buffer, __int)
Definition constants.h:478
#define drizzle_get_byte2(__buffer)
Definition constants.h:452
#define drizzle_set_byte2(__buffer, __int)
Definition constants.h:475
uint8_t * drizzle_pack_length(uint64_t number, uint8_t *ptr)
Definition pack.c:40
uint64_t drizzle_unpack_length(drizzle_con_st *con, drizzle_return_t *ret_ptr)
Definition pack.c:72
drizzle_return_t drizzle_result_buffer(drizzle_result_st *result)
Definition result.c:193
size_t drizzle_result_row_size(drizzle_result_st *result)
Definition result.c:261
drizzle_result_st * drizzle_result_read(drizzle_con_st *con, drizzle_result_st *result, drizzle_return_t *ret_ptr)
Definition result.c:172
void drizzle_result_set_warning_count(drizzle_result_st *result, uint16_t warning_count)
Definition result.c:356
void drizzle_result_set_error(drizzle_result_st *result, const char *error)
Definition result.c:333
void drizzle_result_set_error_code(drizzle_result_st *result, uint16_t error_code)
Definition result.c:338
void drizzle_result_set_eof(drizzle_result_st *result, bool eof)
Definition result.c:314
void drizzle_result_set_row_size(drizzle_result_st *result, size_t size)
Definition result.c:286
drizzle_return_t drizzle_result_write(drizzle_con_st *con, drizzle_result_st *result, bool flush)
Definition result.c:270
void drizzle_result_set_affected_rows(drizzle_result_st *result, uint64_t affected_rows)
Definition result.c:368
void drizzle_result_calc_row_size(drizzle_result_st *result, const drizzle_field_t *field, const size_t *size)
Definition result.c:291
void drizzle_result_set_column_count(drizzle_result_st *result, uint16_t column_count)
Definition result.c:374
void drizzle_result_set_insert_id(drizzle_result_st *result, uint64_t insert_id)
Definition result.c:362
void drizzle_result_set_info(drizzle_result_st *result, const char *info)
Definition result.c:322
void drizzle_result_set_sqlstate(drizzle_result_st *result, const char *sqlstate)
Definition result.c:344
drizzle_result_options_t
Definition constants.h:290
drizzle_result_st * drizzle_result_create(drizzle_con_st *con, drizzle_result_st *result)
Definition result.c:22
uint16_t drizzle_result_column_count(drizzle_result_st *result)
Definition result.c:158
uint64_t drizzle_result_insert_id(drizzle_result_st *result)
Definition result.c:148
void drizzle_result_free_all(drizzle_con_st *con)
Definition result.c:107
bool drizzle_result_eof(drizzle_result_st *result)
Definition result.c:118
const char * drizzle_result_error(drizzle_result_st *result)
Definition result.c:128
drizzle_con_st * drizzle_result_drizzle_con(drizzle_result_st *result)
Definition result.c:113
const char * drizzle_result_sqlstate(drizzle_result_st *result)
Definition result.c:138
uint64_t drizzle_result_affected_rows(drizzle_result_st *result)
Definition result.c:153
uint16_t drizzle_result_error_code(drizzle_result_st *result)
Definition result.c:133
void drizzle_result_free(drizzle_result_st *result)
Definition result.c:75
const char * drizzle_result_info(drizzle_result_st *result)
Definition result.c:123
drizzle_result_st * drizzle_result_clone(drizzle_con_st *con, drizzle_result_st *result, drizzle_result_st *from)
Definition result.c:52
uint16_t drizzle_result_warning_count(drizzle_result_st *result)
Definition result.c:143
uint64_t drizzle_result_row_count(drizzle_result_st *result)
Definition result.c:163
@ DRIZZLE_RESULT_EOF_PACKET
Definition constants.h:296
@ DRIZZLE_RESULT_ALLOCATED
Definition constants.h:292
@ DRIZZLE_RESULT_BUFFER_ROW
Definition constants.h:295
@ DRIZZLE_RESULT_BUFFER_COLUMN
Definition constants.h:294
drizzle_row_t drizzle_row_buffer(drizzle_result_st *result, drizzle_return_t *ret_ptr)
Definition row.c:35
void drizzle_row_free(drizzle_result_st *result, drizzle_row_t row)
Definition row.c:88
drizzle_return_t drizzle_state_packet_read(drizzle_con_st *con)
Definition state.c:40
drizzle_return_t drizzle_state_write(drizzle_con_st *con)
Definition conn.c:975
drizzle_return_t drizzle_state_read(drizzle_con_st *con)
Definition conn.c:897
drizzle_return_t drizzle_state_loop(drizzle_con_st *con)
Definition state.c:18
drizzle_return_t drizzle_state_result_read(drizzle_con_st *con)
Definition result.c:384
drizzle_return_t drizzle_state_result_write(drizzle_con_st *con)
Definition result.c:464
drizzle_field_t * drizzle_row_t
Definition constants.h:413
char * drizzle_field_t
Definition constants.h:412
uint8_t packet_number
Definition structs.h:76
uint8_t buffer[DRIZZLE_MAX_BUFFER_SIZE]
Definition structs.h:115
drizzle_result_st * result_list
Definition structs.h:108
drizzle_st * drizzle
Definition structs.h:103
drizzle_result_st * result
Definition structs.h:107
drizzle_con_status_t status
Definition structs.h:86
size_t packet_size
Definition structs.h:96
uint8_t * buffer_ptr
Definition structs.h:98
uint32_t result_count
Definition structs.h:88
size_t buffer_size
Definition structs.h:92
drizzle_result_st * next
Definition structs.h:148
char info[DRIZZLE_MAX_INFO_SIZE]
Definition structs.h:152
size_t ** field_sizes_list
Definition structs.h:179
uint64_t row_current
Definition structs.h:166
drizzle_row_t * row_list
Definition structs.h:177
drizzle_column_st * column_buffer
Definition structs.h:163
drizzle_result_st * prev
Definition structs.h:149
size_t * field_sizes
Definition structs.h:178
uint64_t row_count
Definition structs.h:165
uint16_t warning_count
Definition structs.h:156
uint64_t affected_rows
Definition structs.h:157
drizzle_con_st * con
Definition structs.h:147
drizzle_result_options_t options
Definition structs.h:150
uint64_t insert_id
Definition structs.h:155
uint64_t row_list_size
Definition structs.h:175
uint16_t error_code
Definition structs.h:153
drizzle_column_st * column_list
Definition structs.h:161
uint16_t column_count
Definition structs.h:159
char sqlstate[DRIZZLE_MAX_SQLSTATE_SIZE+1]
Definition structs.h:154
char sqlstate[DRIZZLE_MAX_SQLSTATE_SIZE+1]
Definition structs.h:47
char last_error[DRIZZLE_MAX_ERROR_SIZE]
Definition structs.h:48
uint16_t error_code
Definition structs.h:28