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