~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
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
80
    result->row= (drizzle_row_t)malloc((sizeof(drizzle_field_t) + sizeof(size_t)) * result->column_count);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
81
    if (result->row == NULL)
82
    {
83
      drizzle_set_error(result->con->drizzle, "drizzle_row_buffer", "malloc");
84
      *ret_ptr= DRIZZLE_RETURN_MEMORY;
85
      return NULL;
86
    }
87
88
    result->field_sizes= (size_t *)(result->row + result->column_count);
89
  }
90
91
  while (1)
92
  {
93
    field= drizzle_field_buffer(result, &total, ret_ptr);
94
    if (*ret_ptr == DRIZZLE_RETURN_ROW_END)
95
      break;
96
    if (*ret_ptr != DRIZZLE_RETURN_OK)
97
    {
98
      if (*ret_ptr != DRIZZLE_RETURN_IO_WAIT)
99
      {
100
        free(result->row);
101
        result->row= NULL;
102
        result->field_sizes= NULL;
103
      }
104
105
      return NULL;
106
    }
107
108
    result->row[result->field_current - 1]= field;
109
    result->field_sizes[result->field_current - 1]= total;
110
  }
111
112
  *ret_ptr= DRIZZLE_RETURN_OK;
113
  row= result->row;
114
  result->row= NULL;
115
116
  return row;
117
}
118
119
void drizzle_row_free(drizzle_result_st *result, drizzle_row_t row)
120
{
121
  uint16_t x;
122
123
  for (x= 0; x < result->column_count; x++)
124
      drizzle_field_free(row[x]);
125
126
  free(row);
127
}
128
129
size_t *drizzle_row_field_sizes(drizzle_result_st *result)
130
{
131
  return result->field_sizes;
132
}
133
134
drizzle_row_t drizzle_row_next(drizzle_result_st *result)
135
{
136
  if (result->row_current == result->row_count)
137
    return NULL;
138
139
  result->field_sizes= result->field_sizes_list[result->row_current];
140
  result->row_current++;
141
  return result->row_list[result->row_current - 1];
142
}
143
144
drizzle_row_t drizzle_row_prev(drizzle_result_st *result)
145
{
146
  if (result->row_current == 0)
147
    return NULL;
148
149
  result->row_current--;
150
  result->field_sizes= result->field_sizes_list[result->row_current];
151
  return result->row_list[result->row_current];
152
}
153
154
void drizzle_row_seek(drizzle_result_st *result, uint64_t row)
155
{
156
  if (row <= result->row_count)
157
    result->row_current= row;
158
}
159
160
drizzle_row_t drizzle_row_index(drizzle_result_st *result, uint64_t row)
161
{
162
  if (row >= result->row_count)
163
    return NULL;
164
165
  return result->row_list[row];
166
}
167
168
uint64_t drizzle_row_current(drizzle_result_st *result)
169
{
170
  return result->row_current;
171
}
172
173
/*
174
 * Server definitions
175
 */
176
177
drizzle_return_t drizzle_row_write(drizzle_result_st *result)
178
{
179
  if (drizzle_state_none(result->con))
180
    drizzle_state_push(result->con, drizzle_state_row_write);
181
182
  return drizzle_state_loop(result->con);
183
}
184
185
/*
186
 * Internal state functions.
187
 */
188
189
drizzle_return_t drizzle_state_row_read(drizzle_con_st *con)
190
{
191
  drizzle_log_debug(con->drizzle, "drizzle_state_row_read");
192
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
193
  if (con->packet_size != 0 && con->buffer_size < con->packet_size && 
194
    con->buffer_size < 5)
1843.3.1 by Andrew Hutchings
Port libdrizzle rev.147:
195
  {
196
    drizzle_state_push(con, drizzle_state_read);
197
    return DRIZZLE_RETURN_OK;
198
  }
199
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
200
  if (con->packet_size == 5 && con->buffer_ptr[0] == 254)
201
  {
202
    /* Got EOF packet, no more rows. */
203
    con->result->row_current= 0;
204
    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.
205
    con->status= drizzle_con_status_t(drizzle_get_byte2(con->buffer_ptr + 3));
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
206
    con->buffer_ptr+= 5;
207
    con->buffer_size-= 5;
208
  }
209
  else if (con->buffer_ptr[0] == 255)
210
  {
211
    drizzle_state_pop(con);
212
    drizzle_state_push(con, drizzle_state_result_read);
213
    return DRIZZLE_RETURN_OK;
214
  }
215
  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.
216
  {
217
    con->result->options&= ~int(DRIZZLE_RESULT_ROW_BREAK);
218
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
219
  else
220
  {
221
    con->result->row_count++;
222
    con->result->row_current++;
223
    con->result->field_current= 0;
224
  }
225
226
  drizzle_state_pop(con);
227
  return DRIZZLE_RETURN_OK;
228
}
229
230
drizzle_return_t drizzle_state_row_write(drizzle_con_st *con)
231
{
232
  uint8_t *start= con->buffer_ptr + con->buffer_size;
233
234
  drizzle_log_debug(con->drizzle, "drizzle_state_row_write");
235
236
  /* Flush buffer if there is not enough room. */
237
  if (((size_t)DRIZZLE_MAX_BUFFER_SIZE - (size_t)(start - con->buffer)) < 4)
238
  {
239
    drizzle_state_push(con, drizzle_state_write);
240
    return DRIZZLE_RETURN_OK;
241
  }
242
243
  drizzle_set_byte3(start, con->packet_size);
244
  start[3]= con->packet_number;
245
  con->packet_number++;
246
247
  con->buffer_size+= 4;
248
249
  drizzle_state_pop(con);
250
  return DRIZZLE_RETURN_OK;
251
}