Drizzled Public API Documentation

row.cc
Go to the documentation of this file.
1 /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
2  *
3  * Drizzle Client & Protocol Library
4  *
5  * Copyright (C) 2008 Eric Day (eday@oddments.org)
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are
10  * met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * * Redistributions in binary form must reproduce the above
16  * copyright notice, this list of conditions and the following disclaimer
17  * in the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * * The names of its contributors may not be used to endorse or
21  * promote products derived from this software without specific prior
22  * written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35  *
36  */
37 
43 #include <libdrizzle/common.h>
44 
45 /*
46  * Client definitions
47  */
48 
49 uint64_t drizzle_row_read(drizzle_result_st *result, drizzle_return_t *ret_ptr)
50 {
51  drizzle_return_t unused_ret;
52  if (ret_ptr == NULL)
53  {
54  ret_ptr= &unused_ret;
55  }
56 
57  if (result == NULL)
58  {
59  *ret_ptr= DRIZZLE_RETURN_INVALID_ARGUMENT;
60  return 0;
61  }
62 
63  if ((result->column_current != result->column_count) && (!(result->options & DRIZZLE_RESULT_BUFFER_COLUMN)))
64  {
65  drizzle_set_error(result->con->drizzle, "drizzle_row_read", "cannot retrieve rows until all columns are retrieved");
66  *ret_ptr= DRIZZLE_RETURN_NOT_READY;
67  return 0;
68  }
69 
70  if (drizzle_state_none(result->con))
71  {
72  drizzle_state_push(result->con, drizzle_state_row_read);
73  drizzle_state_push(result->con, drizzle_state_packet_read);
74  }
75 
76  *ret_ptr= drizzle_state_loop(result->con);
77 
78  return result->row_current;
79 }
80 
81 drizzle_row_t drizzle_row_buffer(drizzle_result_st *result,
82  drizzle_return_t *ret_ptr)
83 {
84  drizzle_return_t unused_ret;
85  if (ret_ptr == NULL)
86  {
87  ret_ptr= &unused_ret;
88  }
89 
90  if (result == NULL)
91  {
92  *ret_ptr= DRIZZLE_RETURN_INVALID_ARGUMENT;
93  return 0;
94  }
95 
96  size_t total;
97  drizzle_field_t field;
98  drizzle_row_t row;
99 
100  if (result->row == NULL)
101  {
102  if (drizzle_row_read(result, ret_ptr) == 0 || *ret_ptr != DRIZZLE_RETURN_OK)
103  {
104  return NULL;
105  }
106 
107  result->row= (drizzle_row_t)realloc(NULL, (sizeof(drizzle_field_t) + sizeof(size_t)) * result->column_count);
108  if (result->row == NULL)
109  {
110  drizzle_set_error(result->con->drizzle, __func__, "Failed to allocate.");
111  *ret_ptr= DRIZZLE_RETURN_MEMORY;
112  return NULL;
113  }
114 
115  result->field_sizes= (size_t *)(result->row + result->column_count);
116  }
117 
118  while (1)
119  {
120  field= drizzle_field_buffer(result, &total, ret_ptr);
121  if (*ret_ptr == DRIZZLE_RETURN_ROW_END)
122  break;
123 
124  if (*ret_ptr != DRIZZLE_RETURN_OK)
125  {
126  if (*ret_ptr != DRIZZLE_RETURN_IO_WAIT)
127  {
128  free(result->row);
129  result->row= NULL;
130  result->field_sizes= NULL;
131  }
132 
133  return NULL;
134  }
135 
136  result->row[result->field_current - 1]= field;
137  result->field_sizes[result->field_current - 1]= total;
138  }
139 
140  *ret_ptr= DRIZZLE_RETURN_OK;
141  row= result->row;
142  result->row= NULL;
143 
144  return row;
145 }
146 
147 void drizzle_row_free(drizzle_result_st *result, drizzle_row_t row)
148 {
149  if (result == NULL)
150  {
151  return;
152  }
153 
154  for (uint16_t x= 0; x < result->column_count; x++)
155  {
156  drizzle_field_free(row[x]);
157  }
158 
159  free(row);
160 }
161 
162 size_t *drizzle_row_field_sizes(drizzle_result_st *result)
163 {
164  if (result == NULL)
165  {
166  return NULL;
167  }
168 
169  return result->field_sizes;
170 }
171 
172 drizzle_row_t drizzle_row_next(drizzle_result_st *result)
173 {
174  if (result == NULL)
175  {
176  return drizzle_row_t();
177  }
178 
179  if (result->row_current == result->row_count)
180  {
181  return NULL;
182  }
183 
184  result->field_sizes= result->field_sizes_list[result->row_current];
185  result->row_current++;
186  return result->row_list[result->row_current - 1];
187 }
188 
189 drizzle_row_t drizzle_row_prev(drizzle_result_st *result)
190 {
191  if (result == NULL)
192  {
193  return drizzle_row_t();
194  }
195 
196  if (result->row_current == 0)
197  return NULL;
198 
199  result->row_current--;
200  result->field_sizes= result->field_sizes_list[result->row_current];
201  return result->row_list[result->row_current];
202 }
203 
204 void drizzle_row_seek(drizzle_result_st *result, uint64_t row)
205 {
206  if (result == NULL)
207  {
208  return;
209  }
210 
211  if (row <= result->row_count)
212  result->row_current= row;
213 }
214 
215 drizzle_row_t drizzle_row_index(drizzle_result_st *result, uint64_t row)
216 {
217  if (result == NULL)
218  {
219  return drizzle_row_t();
220  }
221 
222  if (row >= result->row_count)
223  return NULL;
224 
225  return result->row_list[row];
226 }
227 
228 uint64_t drizzle_row_current(drizzle_result_st *result)
229 {
230  if (result == NULL)
231  {
232  return 0;
233  }
234 
235  return result->row_current;
236 }
237 
238 /*
239  * Server definitions
240  */
241 
242 drizzle_return_t drizzle_row_write(drizzle_result_st *result)
243 {
244  if (result == NULL)
245  {
246  return DRIZZLE_RETURN_INVALID_ARGUMENT;
247  }
248 
249  if (drizzle_state_none(result->con))
250  {
251  drizzle_state_push(result->con, drizzle_state_row_write);
252  }
253 
254  return drizzle_state_loop(result->con);
255 }
256 
257 /*
258  * Internal state functions.
259  */
260 
261 drizzle_return_t drizzle_state_row_read(drizzle_con_st *con)
262 {
263  if (con == NULL)
264  {
265  return DRIZZLE_RETURN_INVALID_ARGUMENT;
266  }
267 
268  drizzle_log_debug(con->drizzle, "drizzle_state_row_read");
269 
270  if (con->packet_size != 0 && con->buffer_size < con->packet_size &&
271  con->buffer_size < 5)
272  {
273  drizzle_state_push(con, drizzle_state_read);
274  return DRIZZLE_RETURN_OK;
275  }
276 
277  if (con->packet_size == 5 && con->buffer_ptr[0] == 254)
278  {
279  /* Got EOF packet, no more rows. */
280  con->result->row_current= 0;
281  con->result->warning_count= drizzle_get_byte2(con->buffer_ptr + 1);
282  con->status= drizzle_con_status_t(drizzle_get_byte2(con->buffer_ptr + 3));
283  con->buffer_ptr+= 5;
284  con->buffer_size-= 5;
285  }
286  else if (con->buffer_ptr[0] == 255)
287  {
288  drizzle_state_pop(con);
289  drizzle_state_push(con, drizzle_state_result_read);
290  return DRIZZLE_RETURN_OK;
291  }
292  else if (con->result->options & DRIZZLE_RESULT_ROW_BREAK)
293  {
294  con->result->options&= ~int(DRIZZLE_RESULT_ROW_BREAK);
295  }
296  else
297  {
298  con->result->row_count++;
299  con->result->row_current++;
300  con->result->field_current= 0;
301  }
302 
303  drizzle_state_pop(con);
304  return DRIZZLE_RETURN_OK;
305 }
306 
307 drizzle_return_t drizzle_state_row_write(drizzle_con_st *con)
308 {
309  if (con == NULL)
310  {
311  return DRIZZLE_RETURN_INVALID_ARGUMENT;
312  }
313 
314  uint8_t *start= con->buffer_ptr + con->buffer_size;
315 
316  drizzle_log_debug(con->drizzle, "drizzle_state_row_write");
317 
318  /* Flush buffer if there is not enough room. */
319  if (((size_t)DRIZZLE_MAX_BUFFER_SIZE - (size_t)(start - con->buffer)) < 4)
320  {
321  drizzle_state_push(con, drizzle_state_write);
322  return DRIZZLE_RETURN_OK;
323  }
324 
325  drizzle_set_byte3(start, con->packet_size);
326  start[3]= con->packet_number;
327  con->packet_number++;
328 
329  con->buffer_size+= 4;
330 
331  drizzle_state_pop(con);
332  return DRIZZLE_RETURN_OK;
333 }
static void drizzle_state_pop(drizzle_con_st *con)
Definition: conn_local.h:104
static bool drizzle_state_none(drizzle_con_st *con)
Definition: conn_local.h:71
static void drizzle_state_push(drizzle_con_st *con, drizzle_state_fn *function)
Definition: conn_local.h:88
void drizzle_set_error(drizzle_st *drizzle, const char *function, const char *format,...)
Definition: drizzle.cc:881
drizzle_return_t drizzle_state_loop(drizzle_con_st *con)
Definition: state.cc:45
static void drizzle_log_debug(drizzle_st *drizzle, const char *format,...)
System Include Files.