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