~drizzle-trunk/drizzle/development

2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
1
/*
2
 * Drizzle Client & Protocol Library
3
 *
4
 * Copyright (C) 2008 Eric Day (eday@oddments.org)
5
 * All rights reserved.
6
 *
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
 *
35
 */
36
37
/**
38
 * @file
39
 * @brief Result definitions
40
 */
41
2449.1.2 by Brian Aker
Additional fixes for libdrizzle.
42
#include <libdrizzle-2.0/common.h>
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
43
#include <memory>
44
45
/*
46
 * Common definitions
47
 */
48
2463.1.5 by Brian Aker
Move result over to being behind API.
49
drizzle_result_st *drizzle_result_create(drizzle_con_st *con)
50
{
51
  return drizzle_result_create_with(con, NULL);
52
}
53
54
drizzle_result_st *drizzle_result_create_with(drizzle_con_st *con,
55
                                              drizzle_result_st *result)
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
56
{
57
  if (result == NULL)
58
  {
2461.1.2 by Brian Aker
Pass through refactoring.
59
    result= new (std::nothrow) drizzle_result_st;
60
61
    if (result == NULL)
62
    {
63
      return NULL;
64
    }
65
2461.1.4 by Brian Aker
More updates to libdrizzle-2.0
66
    result->_options.is_allocated= true;
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
67
  }
68
  else
69
  {
70
    result->prev= NULL;
71
    result->options= 0;
72
73
    result->info[0]= '\0';
74
    result->error_code= 0;
75
    result->sqlstate[0]= '\0';
76
    result->insert_id= 0;
77
    result->warning_count= 0;
78
    result->affected_rows= 0;
79
80
    result->column_count= 0;
81
    result->column_current= 0;
82
    result->column_list= NULL;
83
    result->column= NULL;
84
    result->column_buffer= NULL;
85
86
    result->row_count= 0;
87
    result->row_current= 0;
88
89
    result->field_current= 0;
90
    result->field_total= 0;
91
    result->field_offset= 0;
92
    result->field_size= 0;
93
    result->field= NULL;
94
    result->field_buffer= NULL;
95
96
    result->row_list_size= 0;
97
    result->row= NULL;
98
    result->row_list= NULL;
99
    result->field_sizes= NULL;
100
    result->field_sizes_list= NULL;
2461.1.4 by Brian Aker
More updates to libdrizzle-2.0
101
102
    result->_options.is_allocated= false;
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
103
  }
104
105
  result->con= con;
106
  con->result= result;
107
108
  if (con->result_list)
109
    con->result_list->prev= result;
110
  result->next= con->result_list;
111
  con->result_list= result;
112
  con->result_count++;
113
114
  return result;
115
}
116
117
drizzle_result_st *drizzle_result_clone(drizzle_con_st *con,
2463.1.5 by Brian Aker
Move result over to being behind API.
118
                                        drizzle_result_st *source)
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
119
{
2463.1.5 by Brian Aker
Move result over to being behind API.
120
  drizzle_result_st *result= drizzle_result_create(con);
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
121
  if (result == NULL)
2449.1.4 by Brian Aker
Complete update of libdrizzle
122
  {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
123
    return NULL;
2449.1.4 by Brian Aker
Complete update of libdrizzle
124
  }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
125
2463.1.5 by Brian Aker
Move result over to being behind API.
126
  result->options= source->options;
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
127
2463.1.5 by Brian Aker
Move result over to being behind API.
128
  drizzle_result_set_info(result, source->info);
129
  result->error_code= source->error_code;
130
  drizzle_result_set_sqlstate(result, source->sqlstate);
131
  result->warning_count= source->warning_count;
132
  result->insert_id= source->insert_id;
133
  result->affected_rows= source->affected_rows;
134
  result->column_count= source->column_count;
135
  result->row_count= source->row_count;
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
136
137
  return result;
138
}
139
140
void drizzle_result_free(drizzle_result_st *result)
141
{
142
  drizzle_column_st *column;
143
2449.1.4 by Brian Aker
Complete update of libdrizzle
144
  if (result == NULL)
145
  {
146
    return;
147
  }
148
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
149
  for (column= result->column_list; column != NULL; column= result->column_list)
2449.1.4 by Brian Aker
Complete update of libdrizzle
150
  {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
151
    drizzle_column_free(column);
2449.1.4 by Brian Aker
Complete update of libdrizzle
152
  }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
153
2353.3.1 by Mark Atwood
fix cppcheck redundantIfDelete0 warnings. It is safe to deallocate a NULL pointer
154
  delete[] result->column_buffer;
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
155
156
  if (result->options & DRIZZLE_RESULT_BUFFER_ROW)
157
  {
2463.1.5 by Brian Aker
Move result over to being behind API.
158
    for (size_t x= 0; x < result->row_count; x++)
159
    {
160
      drizzle_row_free(result, result->row_list->at(x));
161
    }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
162
163
    delete result->row_list;
164
    delete result->field_sizes_list;
165
  }
166
167
  if (result->con)
168
  {
169
    result->con->result_count--;
170
    if (result->con->result_list == result)
171
      result->con->result_list= result->next;
172
  }
2461.1.4 by Brian Aker
More updates to libdrizzle-2.0
173
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
174
  if (result->prev)
175
    result->prev->next= result->next;
2461.1.4 by Brian Aker
More updates to libdrizzle-2.0
176
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
177
  if (result->next)
178
    result->next->prev= result->prev;
179
2461.1.4 by Brian Aker
More updates to libdrizzle-2.0
180
  if (result->_options.is_allocated)
181
  {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
182
    delete result;
2461.1.4 by Brian Aker
More updates to libdrizzle-2.0
183
  }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
184
}
185
186
void drizzle_result_free_all(drizzle_con_st *con)
187
{
188
  while (con->result_list != NULL)
2449.1.4 by Brian Aker
Complete update of libdrizzle
189
  {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
190
    drizzle_result_free(con->result_list);
2449.1.4 by Brian Aker
Complete update of libdrizzle
191
  }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
192
}
193
194
drizzle_con_st *drizzle_result_drizzle_con(drizzle_result_st *result)
195
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
196
  if (result == NULL)
197
  {
198
    return NULL;
199
  }
200
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
201
  return result->con;
202
}
203
204
bool drizzle_result_eof(drizzle_result_st *result)
205
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
206
  if (result == NULL)
207
  {
208
    return false;
209
  }
210
2265.1.1 by Monty Taylor
Fixed the windows build related to the new libdrizzle-2.0 stuff.
211
  return (result->options & DRIZZLE_RESULT_EOF_PACKET) ? true : false;
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
212
}
213
214
const char *drizzle_result_info(drizzle_result_st *result)
215
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
216
  if (result == NULL)
217
  {
218
    return NULL;
219
  }
220
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
221
  return result->info;
222
}
223
224
const char *drizzle_result_error(drizzle_result_st *result)
225
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
226
  if (result == NULL)
227
  {
228
    return NULL;
229
  }
230
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
231
  return result->info;
232
}
233
234
uint16_t drizzle_result_error_code(drizzle_result_st *result)
235
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
236
  if (result == NULL)
237
  {
238
    return 0;
239
  }
240
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
241
  return result->error_code;
242
}
243
244
const char *drizzle_result_sqlstate(drizzle_result_st *result)
245
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
246
  if (result == NULL)
247
  {
248
    return NULL;
249
  }
250
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
251
  return result->sqlstate;
252
}
253
254
uint16_t drizzle_result_warning_count(drizzle_result_st *result)
255
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
256
  if (result == NULL)
257
  {
258
    return 0;
259
  }
260
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
261
  return result->warning_count;
262
}
263
264
uint64_t drizzle_result_insert_id(drizzle_result_st *result)
265
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
266
  if (result == NULL)
267
  {
268
    return 0;
269
  }
270
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
271
  return result->insert_id;
272
}
273
274
uint64_t drizzle_result_affected_rows(drizzle_result_st *result)
275
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
276
  if (result == NULL)
277
  {
278
    return 0;
279
  }
280
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
281
  return result->affected_rows;
282
}
283
284
uint16_t drizzle_result_column_count(drizzle_result_st *result)
285
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
286
  if (result == NULL)
287
  {
288
    return 0;
289
  }
290
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
291
  return result->column_count;
292
}
293
294
uint64_t drizzle_result_row_count(drizzle_result_st *result)
295
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
296
  if (result == NULL)
297
  {
298
    return 0;
299
  }
300
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
301
  return result->row_count;
302
}
303
304
/*
305
 * Client definitions
306
 */
307
308
drizzle_result_st *drizzle_result_read(drizzle_con_st *con,
309
                                       drizzle_result_st *result,
310
                                       drizzle_return_t *ret_ptr)
311
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
312
  drizzle_return_t unused;
313
  if (ret_ptr == NULL)
314
  {
315
    ret_ptr= &unused;
316
  }
317
318
  if (con == NULL)
319
  {
320
    *ret_ptr= DRIZZLE_RETURN_INVALID_ARGUMENT;
321
    return NULL;
322
  }
323
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
324
  if (drizzle_state_none(con))
325
  {
2463.1.5 by Brian Aker
Move result over to being behind API.
326
    con->result= drizzle_result_create_with(con, result);
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
327
    if (con->result == NULL)
328
    {
329
      *ret_ptr= DRIZZLE_RETURN_MEMORY;
330
      return NULL;
331
    }
332
333
    drizzle_state_push(con, drizzle_state_result_read);
334
    drizzle_state_push(con, drizzle_state_packet_read);
335
  }
336
337
  *ret_ptr= drizzle_state_loop(con);
338
  return con->result;
339
}
340
341
drizzle_return_t drizzle_result_buffer(drizzle_result_st *result)
342
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
343
  if (result == NULL)
344
  {
345
    return DRIZZLE_RETURN_INVALID_ARGUMENT;
346
  }
347
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
348
  if (!(result->options & DRIZZLE_RESULT_BUFFER_COLUMN))
349
  {
2461.1.2 by Brian Aker
Pass through refactoring.
350
    drizzle_return_t ret= drizzle_column_buffer(result);
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
351
    if (ret != DRIZZLE_RETURN_OK)
2461.1.2 by Brian Aker
Pass through refactoring.
352
    {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
353
      return ret;
2461.1.2 by Brian Aker
Pass through refactoring.
354
    }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
355
  }
356
357
  if (result->column_count == 0)
358
  {
359
    result->options|= DRIZZLE_RESULT_BUFFER_ROW;
360
    return DRIZZLE_RETURN_OK;
361
  }
362
363
  while (1)
364
  {
2461.1.2 by Brian Aker
Pass through refactoring.
365
    drizzle_return_t ret;
366
    drizzle_row_t row= drizzle_row_buffer(result, &ret);
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
367
    if (ret != DRIZZLE_RETURN_OK)
2461.1.2 by Brian Aker
Pass through refactoring.
368
    {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
369
      return ret;
2461.1.2 by Brian Aker
Pass through refactoring.
370
    }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
371
372
    if (row == NULL)
2461.1.2 by Brian Aker
Pass through refactoring.
373
    {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
374
      break;
2461.1.2 by Brian Aker
Pass through refactoring.
375
    }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
376
377
    if (result->row_list == NULL)
378
    {
2461.1.2 by Brian Aker
Pass through refactoring.
379
      result->row_list= new (std::nothrow) drizzle_row_list_t;
380
381
      if (result->row_list == NULL)
382
      {
383
        return DRIZZLE_RETURN_MEMORY;
384
      }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
385
    }
386
387
388
    if (result->field_sizes_list == NULL)
389
    {
2461.1.2 by Brian Aker
Pass through refactoring.
390
      result->field_sizes_list= new (std::nothrow) drizzle_field_sizes_list_t;
391
392
      if (result->field_sizes_list == NULL)
393
      {
394
      }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
395
    }
396
397
    result->row_list->push_back(row);
398
    result->field_sizes_list->push_back(result->field_sizes);
399
  }
400
401
  result->options|= DRIZZLE_RESULT_BUFFER_ROW;
2461.1.2 by Brian Aker
Pass through refactoring.
402
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
403
  return DRIZZLE_RETURN_OK;
404
}
405
406
size_t drizzle_result_row_size(drizzle_result_st *result)
407
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
408
  if (result == NULL)
409
  {
410
    return 0;
411
  }
412
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
413
  return result->con->packet_size;
414
}
415
416
/*
417
 * Server definitions
418
 */
419
420
drizzle_return_t drizzle_result_write(drizzle_con_st *con,
421
                                      drizzle_result_st *result, bool flush)
422
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
423
  if (con == NULL)
424
  {
425
    return DRIZZLE_RETURN_INVALID_ARGUMENT;
426
  }
427
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
428
  if (drizzle_state_none(con))
429
  {
430
    con->result= result;
431
432
    if (flush)
433
      drizzle_state_push(con, drizzle_state_write);
434
435
    drizzle_state_push(con, drizzle_state_result_write);
436
  }
437
438
  return drizzle_state_loop(con);
439
}
440
441
void drizzle_result_set_row_size(drizzle_result_st *result, size_t size)
442
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
443
  if (result == NULL)
444
  {
445
    return;
446
  }
447
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
448
  result->con->packet_size= size;
449
}
450
451
void drizzle_result_calc_row_size(drizzle_result_st *result,
452
                                  const drizzle_field_t *field,
453
                                  const size_t *size)
454
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
455
  if (result == NULL)
456
  {
457
    return;
458
  }
459
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
460
  result->con->packet_size= 0;
461
2461.1.2 by Brian Aker
Pass through refactoring.
462
  for (uint16_t x= 0; x < result->column_count; x++)
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
463
  {
464
    if (field[x] == NULL)
2461.1.2 by Brian Aker
Pass through refactoring.
465
    {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
466
      result->con->packet_size++;
2461.1.2 by Brian Aker
Pass through refactoring.
467
    }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
468
    else if (size[x] < 251)
2461.1.2 by Brian Aker
Pass through refactoring.
469
    {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
470
      result->con->packet_size+= (1 + size[x]);
2461.1.2 by Brian Aker
Pass through refactoring.
471
    }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
472
    else if (size[x] < 65536)
2461.1.2 by Brian Aker
Pass through refactoring.
473
    {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
474
      result->con->packet_size+= (3 + size[x]);
2461.1.2 by Brian Aker
Pass through refactoring.
475
    }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
476
    else if (size[x] < 16777216)
2461.1.2 by Brian Aker
Pass through refactoring.
477
    {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
478
      result->con->packet_size+= (4 + size[x]);
2461.1.2 by Brian Aker
Pass through refactoring.
479
    }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
480
    else
2461.1.2 by Brian Aker
Pass through refactoring.
481
    {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
482
      result->con->packet_size+= (9 + size[x]);
2461.1.2 by Brian Aker
Pass through refactoring.
483
    }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
484
  }
485
}
486
487
void drizzle_result_set_eof(drizzle_result_st *result, bool is_eof)
488
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
489
  if (result == NULL)
490
  {
491
    return;
492
  }
493
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
494
  if (is_eof)
2461.1.2 by Brian Aker
Pass through refactoring.
495
  {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
496
    result->options|= DRIZZLE_RESULT_EOF_PACKET;
2461.1.2 by Brian Aker
Pass through refactoring.
497
  }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
498
  else
2461.1.2 by Brian Aker
Pass through refactoring.
499
  {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
500
    result->options&= ~DRIZZLE_RESULT_EOF_PACKET;
2461.1.2 by Brian Aker
Pass through refactoring.
501
  }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
502
}
503
504
void drizzle_result_set_info(drizzle_result_st *result, const char *info)
505
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
506
  if (result == NULL)
507
  {
508
    return;
509
  }
510
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
511
  if (info == NULL)
2449.1.4 by Brian Aker
Complete update of libdrizzle
512
  {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
513
    result->info[0]= 0;
2449.1.4 by Brian Aker
Complete update of libdrizzle
514
  }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
515
  else
516
  {
517
    strncpy(result->info, info, DRIZZLE_MAX_INFO_SIZE);
518
    result->info[DRIZZLE_MAX_INFO_SIZE - 1]= 0;
519
  }
520
}
521
522
void drizzle_result_set_error(drizzle_result_st *result, const char *error)
523
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
524
  if (result == NULL)
525
  {
526
    return;
527
  }
528
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
529
  drizzle_result_set_info(result, error);
530
}
531
532
void drizzle_result_set_error_code(drizzle_result_st *result,
533
                                   uint16_t error_code)
534
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
535
  if (result == NULL)
536
  {
537
    return;
538
  }
539
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
540
  result->error_code= error_code;
541
}
542
543
void drizzle_result_set_sqlstate(drizzle_result_st *result,
544
                                 const char *sqlstate)
545
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
546
  if (result == NULL)
547
  {
548
    return;
549
  }
550
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
551
  if (sqlstate == NULL)
2449.1.4 by Brian Aker
Complete update of libdrizzle
552
  {
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
553
    result->sqlstate[0]= 0;
2449.1.4 by Brian Aker
Complete update of libdrizzle
554
  }
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
555
  else
556
  {
557
    strncpy(result->sqlstate, sqlstate, DRIZZLE_MAX_SQLSTATE_SIZE + 1);
558
    result->sqlstate[DRIZZLE_MAX_SQLSTATE_SIZE]= 0;
559
  }
560
}
561
562
void drizzle_result_set_warning_count(drizzle_result_st *result,
563
                                      uint16_t warning_count)
564
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
565
  if (result == NULL)
566
  {
567
    return;
568
  }
569
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
570
  result->warning_count= warning_count;
571
}
572
573
void drizzle_result_set_insert_id(drizzle_result_st *result,
574
                                  uint64_t insert_id)
575
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
576
  if (result == NULL)
577
  {
578
    return;
579
  }
580
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
581
  result->insert_id= insert_id;
582
}
583
584
void drizzle_result_set_affected_rows(drizzle_result_st *result,
585
                                      uint64_t affected_rows)
586
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
587
  if (result == NULL)
588
  {
589
    return;
590
  }
591
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
592
  result->affected_rows= affected_rows;
593
}
594
595
void drizzle_result_set_column_count(drizzle_result_st *result,
596
                                     uint16_t column_count)
597
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
598
  if (result == NULL)
599
  {
600
    return;
601
  }
602
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
603
  result->column_count= column_count;
604
}
605
606
/*
607
 * Internal state functions.
608
 */
609
610
drizzle_return_t drizzle_state_result_read(drizzle_con_st *con)
611
{
612
  drizzle_return_t ret;
613
2449.1.4 by Brian Aker
Complete update of libdrizzle
614
  if (con == NULL)
615
  {
616
    return DRIZZLE_RETURN_INVALID_ARGUMENT;
617
  }
618
619
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
620
  drizzle_log_debug(con->drizzle, "drizzle_state_result_read");
621
622
  /* Assume the entire result packet will fit in the buffer. */
623
  if (con->buffer_size < con->packet_size)
624
  {
625
    drizzle_state_push(con, drizzle_state_read);
2461.1.2 by Brian Aker
Pass through refactoring.
626
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
627
    return DRIZZLE_RETURN_OK;
628
  }
629
630
  if (con->buffer_ptr[0] == 0)
631
  {
632
    con->buffer_ptr++;
633
    /* We can ignore the returns since we've buffered the entire packet. */
634
    con->result->affected_rows= drizzle_unpack_length(con, &ret);
635
    con->result->insert_id= drizzle_unpack_length(con, &ret);
636
    con->status= (drizzle_con_status_t)drizzle_get_byte2(con->buffer_ptr);
637
    con->result->warning_count= drizzle_get_byte2(con->buffer_ptr + 2);
638
    con->buffer_ptr+= 4;
639
    con->buffer_size-= 5;
640
    con->packet_size-= 5;
641
    if (con->packet_size > 0)
642
    {
643
      /* Skip one byte for message size. */
644
      con->buffer_ptr+= 1;
645
      con->buffer_size-= 1;
646
      con->packet_size-= 1;
647
    }
648
    ret= DRIZZLE_RETURN_OK;
649
  }
650
  else if (con->buffer_ptr[0] == 254)
651
  {
652
    con->result->options= DRIZZLE_RESULT_EOF_PACKET;
653
    con->result->warning_count= drizzle_get_byte2(con->buffer_ptr + 1);
654
    con->status= (drizzle_con_status_t)drizzle_get_byte2(con->buffer_ptr + 3);
655
    con->buffer_ptr+= 5;
656
    con->buffer_size-= 5;
657
    con->packet_size-= 5;
658
    ret= DRIZZLE_RETURN_OK;
659
  }
660
  else if (con->buffer_ptr[0] == 255)
661
  {
662
    con->result->error_code= drizzle_get_byte2(con->buffer_ptr + 1);
663
    con->drizzle->error_code= con->result->error_code;
664
    /* Byte 3 is always a '#' character, skip it. */
665
    memcpy(con->result->sqlstate, con->buffer_ptr + 4,
666
           DRIZZLE_MAX_SQLSTATE_SIZE);
667
    con->result->sqlstate[DRIZZLE_MAX_SQLSTATE_SIZE]= 0;
668
    memcpy(con->drizzle->sqlstate, con->result->sqlstate,
669
           DRIZZLE_MAX_SQLSTATE_SIZE + 1);
670
    con->buffer_ptr+= 9;
671
    con->buffer_size-= 9;
672
    con->packet_size-= 9;
673
    ret= DRIZZLE_RETURN_ERROR_CODE;
674
  }
675
  else
676
  {
677
    /* We can ignore the return since we've buffered the entire packet. */
678
    con->result->column_count= (uint16_t)drizzle_unpack_length(con, &ret);
679
    ret= DRIZZLE_RETURN_OK;
680
  }
681
682
  if (con->packet_size > 0)
683
  {
684
    snprintf(con->drizzle->last_error, DRIZZLE_MAX_ERROR_SIZE, "%.*s",
685
             (int32_t)con->packet_size, con->buffer_ptr);
2269.2.1 by Marc Isambart
Various libdrizzle Windows fixes, including closesocket() instead of close(), snprintf handling and WSAECONNREFUSED mapping
686
    con->drizzle->last_error[DRIZZLE_MAX_ERROR_SIZE-1]= 0;
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
687
    snprintf(con->result->info, DRIZZLE_MAX_INFO_SIZE, "%.*s",
688
             (int32_t)con->packet_size, con->buffer_ptr);
2269.2.1 by Marc Isambart
Various libdrizzle Windows fixes, including closesocket() instead of close(), snprintf handling and WSAECONNREFUSED mapping
689
    con->result->info[DRIZZLE_MAX_INFO_SIZE-1]= 0;
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
690
    con->buffer_ptr+= con->packet_size;
691
    con->buffer_size-= con->packet_size;
692
    con->packet_size= 0;
693
  }
694
695
  drizzle_state_pop(con);
2461.1.2 by Brian Aker
Pass through refactoring.
696
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
697
  return ret;
698
}
699
700
drizzle_return_t drizzle_state_result_write(drizzle_con_st *con)
701
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
702
  if (con == NULL)
703
  {
704
    return DRIZZLE_RETURN_INVALID_ARGUMENT;
705
  }
706
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
707
  uint8_t *start= con->buffer_ptr + con->buffer_size;
708
  uint8_t *ptr;
709
  drizzle_result_st *result= con->result;
710
711
  drizzle_log_debug(con->drizzle, "drizzle_state_result_write");
712
713
  /* Calculate max packet size. */
714
  con->packet_size= 1 /* OK/Field Count/EOF/Error */
715
                  + 9 /* Affected rows */
716
                  + 9 /* Insert ID */
717
                  + 2 /* Status */
718
                  + 2 /* Warning count */
719
                  + strlen(result->info); /* Info/error message */
720
721
  /* Assume the entire result packet will fit in the buffer. */
722
  if ((con->packet_size + 4) > DRIZZLE_MAX_BUFFER_SIZE)
723
  {
2461.1.2 by Brian Aker
Pass through refactoring.
724
    drizzle_set_error(con->drizzle, "drizzle_state_result_write", "buffer too small:%zu", con->packet_size + 4);
725
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
726
    return DRIZZLE_RETURN_INTERNAL_ERROR;
727
  }
728
729
  /* Flush buffer if there is not enough room. */
730
  if (((size_t)DRIZZLE_MAX_BUFFER_SIZE - (size_t)(start - con->buffer)) <
731
      con->packet_size)
732
  {
733
    drizzle_state_push(con, drizzle_state_write);
2461.1.2 by Brian Aker
Pass through refactoring.
734
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
735
    return DRIZZLE_RETURN_OK;
736
  }
737
738
  /* Store packet size at the end since it may change. */
739
  ptr= start;
740
  ptr[3]= con->packet_number;
741
  con->packet_number++;
742
  ptr+= 4;
743
744
  if (result->options & DRIZZLE_RESULT_EOF_PACKET)
745
  {
746
    ptr[0]= 254;
747
    ptr++;
748
749
    drizzle_set_byte2(ptr, result->warning_count);
750
    ptr+= 2;
751
752
    drizzle_set_byte2(ptr, con->status);
753
    ptr+= 2;
754
  }
755
  else if (result->error_code != 0)
756
  {
757
    ptr[0]= 255;
758
    ptr++;
759
760
    drizzle_set_byte2(ptr, result->error_code);
761
    ptr+= 2;
762
763
    ptr[0]= '#';
764
    ptr++;
765
766
    memcpy(ptr, result->sqlstate, DRIZZLE_MAX_SQLSTATE_SIZE);
767
    ptr+= DRIZZLE_MAX_SQLSTATE_SIZE;
768
769
    memcpy(ptr, result->info, strlen(result->info));
770
    ptr+= strlen(result->info);
771
  }
772
  else if (result->column_count == 0)
773
  {
774
    ptr[0]= 0;
775
    ptr++;
776
777
    ptr= drizzle_pack_length(result->affected_rows, ptr);
778
    ptr= drizzle_pack_length(result->insert_id, ptr);
779
780
    drizzle_set_byte2(ptr, con->status);
781
    ptr+= 2;
782
783
    drizzle_set_byte2(ptr, result->warning_count);
784
    ptr+= 2;
785
786
    memcpy(ptr, result->info, strlen(result->info));
787
    ptr+= strlen(result->info);
788
  }
789
  else
790
    ptr= drizzle_pack_length(result->column_count, ptr);
791
792
  con->packet_size= ((size_t)(ptr - start) - 4);
793
  con->buffer_size+= (4 + con->packet_size);
794
795
  /* Store packet size now. */
796
  drizzle_set_byte3(start, con->packet_size);
797
798
  drizzle_state_pop(con);
2461.1.2 by Brian Aker
Pass through refactoring.
799
2244.1.1 by Monty Taylor
Split libdrizzle into 1.0 and 2.0. Applied the C++ changes to 2.0 branch.
800
  return DRIZZLE_RETURN_OK;
801
}