~drizzle-trunk/drizzle/development

2472.1.1 by Brian Aker
Formatting, and valgrind cleanups (just mismatch of free/delete).
1
/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab: 
2
 *
3
 *  Drizzle Client & Protocol Library
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
4
 *
5
 * Copyright (C) 2008 Eric Day (eday@oddments.org)
6
 * All rights reserved.
7
 *
1971.2.1 by kalebral at gmail
update files that did not have license or had incorrect license structure
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
 *
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
36
 */
37
38
/**
39
 * @file
40
 * @brief Row definitions
41
 */
42
2478.1.2 by Brian Aker
Fix race condition in bison build, also fix NULL issue on FreeBSD.
43
#include <libdrizzle/common.h>
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
44
45
/*
46
 * Client definitions
47
 */
48
49
uint64_t drizzle_row_read(drizzle_result_st *result, drizzle_return_t *ret_ptr)
50
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
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
2411.1.1 by Andrew Hutchings
Add function drizzle_column_skip_all
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
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
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
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
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
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
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)
2472.1.1 by Brian Aker
Formatting, and valgrind cleanups (just mismatch of free/delete).
103
    {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
104
      return NULL;
2472.1.1 by Brian Aker
Formatting, and valgrind cleanups (just mismatch of free/delete).
105
    }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
106
2472.1.3 by Brian Aker
Mark all cases where you are using realloc.
107
    result->row= (drizzle_row_t)realloc(NULL, (sizeof(drizzle_field_t) + sizeof(size_t)) * result->column_count);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
108
    if (result->row == NULL)
109
    {
2472.1.3 by Brian Aker
Mark all cases where you are using realloc.
110
      drizzle_set_error(result->con->drizzle, __func__, "Failed to allocate.");
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
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;
2472.1.1 by Brian Aker
Formatting, and valgrind cleanups (just mismatch of free/delete).
123
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
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
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
149
  if (result == NULL)
150
  {
151
    return;
152
  }
153
2472.1.1 by Brian Aker
Formatting, and valgrind cleanups (just mismatch of free/delete).
154
  for (uint16_t x= 0; x < result->column_count; x++)
155
  {
156
    drizzle_field_free(row[x]);
157
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
158
159
  free(row);
160
}
161
162
size_t *drizzle_row_field_sizes(drizzle_result_st *result)
163
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
164
  if (result == NULL)
165
  {
166
    return NULL;
167
  }
168
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
169
  return result->field_sizes;
170
}
171
172
drizzle_row_t drizzle_row_next(drizzle_result_st *result)
173
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
174
  if (result == NULL)
175
  {
176
    return drizzle_row_t();
177
  }
178
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
179
  if (result->row_current == result->row_count)
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
180
  {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
181
    return NULL;
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
182
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
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
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
191
  if (result == NULL)
192
  {
193
    return drizzle_row_t();
194
  }
195
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
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
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
206
  if (result == NULL)
207
  {
208
    return;
209
  }
210
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
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
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
217
  if (result == NULL)
218
  {
219
    return drizzle_row_t();
220
  }
221
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
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
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
230
  if (result == NULL)
231
  {
232
    return 0;
233
  }
234
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
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
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
244
  if (result == NULL)
245
  {
246
    return DRIZZLE_RETURN_INVALID_ARGUMENT;
247
  }
248
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
249
  if (drizzle_state_none(result->con))
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
250
  {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
251
    drizzle_state_push(result->con, drizzle_state_row_write);
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
252
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
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
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
263
  if (con == NULL)
264
  {
265
    return DRIZZLE_RETURN_INVALID_ARGUMENT;
266
  }
267
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
268
  drizzle_log_debug(con->drizzle, "drizzle_state_row_read");
269
1843.3.2 by Andrew Hutchings
Add David Mikulec's fix in bug#643772 which fixes the problem which caused the revert of libdrizzle rev.147
270
  if (con->packet_size != 0 && con->buffer_size < con->packet_size && 
271
    con->buffer_size < 5)
1843.3.1 by Andrew Hutchings
Port libdrizzle rev.147:
272
  {
273
    drizzle_state_push(con, drizzle_state_read);
274
    return DRIZZLE_RETURN_OK;
275
  }
276
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
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);
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
282
    con->status= drizzle_con_status_t(drizzle_get_byte2(con->buffer_ptr + 3));
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
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)
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
293
  {
294
    con->result->options&= ~int(DRIZZLE_RESULT_ROW_BREAK);
295
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
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
{
2472.1.2 by Brian Aker
Null safety fix for libdrizzle
309
  if (con == NULL)
310
  {
311
    return DRIZZLE_RETURN_INVALID_ARGUMENT;
312
  }
313
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
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
}