~drizzle-trunk/drizzle/development

1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
1
/*
2
 * Drizzle Client & Protocol Library
3
 *
4
 * Copyright (C) 2008 Eric Day (eday@oddments.org)
5
 * All rights reserved.
6
 *
1971.2.1 by kalebral at gmail
update files that did not have license or had incorrect license structure
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions are
9
 * met:
10
 *
11
 *     * Redistributions of source code must retain the above copyright
12
 * notice, this list of conditions and the following disclaimer.
13
 *
14
 *     * Redistributions in binary form must reproduce the above
15
 * copyright notice, this list of conditions and the following disclaimer
16
 * in the documentation and/or other materials provided with the
17
 * distribution.
18
 *
19
 *     * The names of its contributors may not be used to endorse or
20
 * promote products derived from this software without specific prior
21
 * written permission.
22
 *
23
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
 *
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
35
 */
36
37
/**
38
 * @file
39
 * @brief Row definitions
40
 */
41
2449.1.4 by Brian Aker
Complete update of libdrizzle
42
#include <libdrizzle-1.0/common.h>
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
43
44
/*
45
 * Client definitions
46
 */
47
48
uint64_t drizzle_row_read(drizzle_result_st *result, drizzle_return_t *ret_ptr)
49
{
2411.1.1 by Andrew Hutchings
Add function drizzle_column_skip_all
50
  if ((result->column_current != result->column_count) && (!(result->options & DRIZZLE_RESULT_BUFFER_COLUMN)))
51
  {
52
    drizzle_set_error(result->con->drizzle, "drizzle_row_read", "cannot retrieve rows until all columns are retrieved");
53
    *ret_ptr= DRIZZLE_RETURN_NOT_READY;
54
    return 0;
55
  }
56
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
57
  if (drizzle_state_none(result->con))
58
  {
59
    drizzle_state_push(result->con, drizzle_state_row_read);
60
    drizzle_state_push(result->con, drizzle_state_packet_read);
61
  }
62
63
  *ret_ptr= drizzle_state_loop(result->con);
64
65
  return result->row_current;
66
}
67
68
drizzle_row_t drizzle_row_buffer(drizzle_result_st *result,
69
                                 drizzle_return_t *ret_ptr)
70
{
71
  size_t total;
72
  drizzle_field_t field;
73
  drizzle_row_t row;
74
75
  if (result->row == NULL)
76
  {
77
    if (drizzle_row_read(result, ret_ptr) == 0 || *ret_ptr != DRIZZLE_RETURN_OK)
78
      return NULL;
79
1992.6.7 by Monty Taylor
Revert -Wc++-compat change.
80
    result->row= malloc((sizeof(drizzle_field_t) + sizeof(size_t)) *
81
                        result->column_count);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
82
    if (result->row == NULL)
83
    {
84
      drizzle_set_error(result->con->drizzle, "drizzle_row_buffer", "malloc");
85
      *ret_ptr= DRIZZLE_RETURN_MEMORY;
86
      return NULL;
87
    }
88
89
    result->field_sizes= (size_t *)(result->row + result->column_count);
90
  }
91
92
  while (1)
93
  {
94
    field= drizzle_field_buffer(result, &total, ret_ptr);
95
    if (*ret_ptr == DRIZZLE_RETURN_ROW_END)
96
      break;
97
    if (*ret_ptr != DRIZZLE_RETURN_OK)
98
    {
99
      if (*ret_ptr != DRIZZLE_RETURN_IO_WAIT)
100
      {
101
        free(result->row);
102
        result->row= NULL;
103
        result->field_sizes= NULL;
104
      }
105
106
      return NULL;
107
    }
108
109
    result->row[result->field_current - 1]= field;
110
    result->field_sizes[result->field_current - 1]= total;
111
  }
112
113
  *ret_ptr= DRIZZLE_RETURN_OK;
114
  row= result->row;
115
  result->row= NULL;
116
117
  return row;
118
}
119
120
void drizzle_row_free(drizzle_result_st *result, drizzle_row_t row)
121
{
122
  uint16_t x;
123
124
  for (x= 0; x < result->column_count; x++)
125
      drizzle_field_free(row[x]);
126
127
  free(row);
128
}
129
130
size_t *drizzle_row_field_sizes(drizzle_result_st *result)
131
{
132
  return result->field_sizes;
133
}
134
135
drizzle_row_t drizzle_row_next(drizzle_result_st *result)
136
{
137
  if (result->row_current == result->row_count)
138
    return NULL;
139
140
  result->field_sizes= result->field_sizes_list[result->row_current];
141
  result->row_current++;
142
  return result->row_list[result->row_current - 1];
143
}
144
145
drizzle_row_t drizzle_row_prev(drizzle_result_st *result)
146
{
147
  if (result->row_current == 0)
148
    return NULL;
149
150
  result->row_current--;
151
  result->field_sizes= result->field_sizes_list[result->row_current];
152
  return result->row_list[result->row_current];
153
}
154
155
void drizzle_row_seek(drizzle_result_st *result, uint64_t row)
156
{
157
  if (row <= result->row_count)
158
    result->row_current= row;
159
}
160
161
drizzle_row_t drizzle_row_index(drizzle_result_st *result, uint64_t row)
162
{
163
  if (row >= result->row_count)
164
    return NULL;
165
166
  return result->row_list[row];
167
}
168
169
uint64_t drizzle_row_current(drizzle_result_st *result)
170
{
171
  return result->row_current;
172
}
173
174
/*
175
 * Server definitions
176
 */
177
178
drizzle_return_t drizzle_row_write(drizzle_result_st *result)
179
{
180
  if (drizzle_state_none(result->con))
181
    drizzle_state_push(result->con, drizzle_state_row_write);
182
183
  return drizzle_state_loop(result->con);
184
}
185
186
/*
187
 * Internal state functions.
188
 */
189
190
drizzle_return_t drizzle_state_row_read(drizzle_con_st *con)
191
{
192
  drizzle_log_debug(con->drizzle, "drizzle_state_row_read");
193
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
194
  if (con->packet_size != 0 && con->buffer_size < con->packet_size && 
195
    con->buffer_size < 5)
1843.3.1 by Andrew Hutchings
Port libdrizzle rev.147:
196
  {
197
    drizzle_state_push(con, drizzle_state_read);
198
    return DRIZZLE_RETURN_OK;
199
  }
200
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
201
  if (con->packet_size == 5 && con->buffer_ptr[0] == 254)
202
  {
203
    /* Got EOF packet, no more rows. */
204
    con->result->row_current= 0;
205
    con->result->warning_count= drizzle_get_byte2(con->buffer_ptr + 1);
1992.6.7 by Monty Taylor
Revert -Wc++-compat change.
206
    con->status= drizzle_get_byte2(con->buffer_ptr + 3);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
207
    con->buffer_ptr+= 5;
208
    con->buffer_size-= 5;
209
  }
210
  else if (con->buffer_ptr[0] == 255)
211
  {
212
    drizzle_state_pop(con);
213
    drizzle_state_push(con, drizzle_state_result_read);
214
    return DRIZZLE_RETURN_OK;
215
  }
216
  else if (con->result->options & DRIZZLE_RESULT_ROW_BREAK)
217
    con->result->options&= (drizzle_result_options_t)~DRIZZLE_RESULT_ROW_BREAK;
218
  else
219
  {
220
    con->result->row_count++;
221
    con->result->row_current++;
222
    con->result->field_current= 0;
223
  }
224
225
  drizzle_state_pop(con);
226
  return DRIZZLE_RETURN_OK;
227
}
228
229
drizzle_return_t drizzle_state_row_write(drizzle_con_st *con)
230
{
231
  uint8_t *start= con->buffer_ptr + con->buffer_size;
232
233
  drizzle_log_debug(con->drizzle, "drizzle_state_row_write");
234
235
  /* Flush buffer if there is not enough room. */
236
  if (((size_t)DRIZZLE_MAX_BUFFER_SIZE - (size_t)(start - con->buffer)) < 4)
237
  {
238
    drizzle_state_push(con, drizzle_state_write);
239
    return DRIZZLE_RETURN_OK;
240
  }
241
242
  drizzle_set_byte3(start, con->packet_size);
243
  start[3]= con->packet_number;
244
  con->packet_number++;
245
246
  con->buffer_size+= 4;
247
248
  drizzle_state_pop(con);
249
  return DRIZZLE_RETURN_OK;
250
}