~drizzle-trunk/drizzle/development

2472.1.1 by Brian Aker
Formatting, and valgrind cleanups (just mismatch of free/delete).
1
/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
2
 *
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
3
 * Drizzle Client & Protocol Library
4
 *
5
 * Copyright (C) 2008 Eric Day (eday@oddments.org)
6
 * All rights reserved.
7
 *
1971.2.1 by kalebral at gmail
update files that did not have license or had incorrect license structure
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions are
10
 * met:
11
 *
12
 *     * Redistributions of source code must retain the above copyright
13
 * notice, this list of conditions and the following disclaimer.
14
 *
15
 *     * Redistributions in binary form must reproduce the above
16
 * copyright notice, this list of conditions and the following disclaimer
17
 * in the documentation and/or other materials provided with the
18
 * distribution.
19
 *
20
 *     * The names of its contributors may not be used to endorse or
21
 * promote products derived from this software without specific prior
22
 * written permission.
23
 *
24
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
 *
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
36
 */
37
38
/**
39
 * @file
40
 * @brief Result definitions
41
 */
42
2449.1.4 by Brian Aker
Complete update of libdrizzle
43
#include <libdrizzle-1.0/common.h>
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
44
45
/*
46
 * Common definitions
47
 */
48
49
drizzle_result_st *drizzle_result_create(drizzle_con_st *con,
50
                                         drizzle_result_st *result)
51
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
52
  if (con == NULL)
53
  {
54
    return NULL;
55
  }
56
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
57
  if (result == NULL)
58
  {
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
59
    result= new drizzle_result_st;
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
60
    if (result == NULL)
61
    {
62
      drizzle_set_error(con->drizzle, "drizzle_result_create", "malloc");
63
      return NULL;
64
    }
65
66
    memset(result, 0, sizeof(drizzle_result_st));
67
    result->options|= DRIZZLE_RESULT_ALLOCATED;
68
  }
69
  else
2449.1.4 by Brian Aker
Complete update of libdrizzle
70
  {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
71
    memset(result, 0, sizeof(drizzle_result_st));
2449.1.4 by Brian Aker
Complete update of libdrizzle
72
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
73
74
  result->con= con;
75
  con->result= result;
76
77
  if (con->result_list)
78
    con->result_list->prev= result;
79
  result->next= con->result_list;
80
  con->result_list= result;
81
  con->result_count++;
82
83
  return result;
84
}
85
86
drizzle_result_st *drizzle_result_clone(drizzle_con_st *con,
87
                                        drizzle_result_st *result,
88
                                        drizzle_result_st *from)
89
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
90
  // A NULL con will return a NULL result
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
91
  result= drizzle_result_create(con, result);
92
  if (result == NULL)
2449.1.4 by Brian Aker
Complete update of libdrizzle
93
  {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
94
    return NULL;
2449.1.4 by Brian Aker
Complete update of libdrizzle
95
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
96
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
97
  result->options|= (from->options & ~int(DRIZZLE_RESULT_ALLOCATED));
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
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
2472.1.1 by Brian Aker
Formatting, and valgrind cleanups (just mismatch of free/delete).
118
  for (drizzle_column_st* column= result->column_list; column != NULL; column= result->column_list)
2449.1.4 by Brian Aker
Complete update of libdrizzle
119
  {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
120
    drizzle_column_free(column);
2449.1.4 by Brian Aker
Complete update of libdrizzle
121
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
122
2472.1.1 by Brian Aker
Formatting, and valgrind cleanups (just mismatch of free/delete).
123
  delete [] result->column_buffer;
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
124
125
  if (result->options & DRIZZLE_RESULT_BUFFER_ROW)
126
  {
2472.1.1 by Brian Aker
Formatting, and valgrind cleanups (just mismatch of free/delete).
127
    for (uint64_t x= 0; x < result->row_count; x++)
128
    {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
129
      drizzle_row_free(result, result->row_list[x]);
2472.1.1 by Brian Aker
Formatting, and valgrind cleanups (just mismatch of free/delete).
130
    }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
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
  {
2472.1.1 by Brian Aker
Formatting, and valgrind cleanups (just mismatch of free/delete).
154
    delete 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
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
436
  if (result == NULL)
437
  {
438
    return;
439
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
440
441
  result->con->packet_size= 0;
442
2472.1.1 by Brian Aker
Formatting, and valgrind cleanups (just mismatch of free/delete).
443
  for (uint16_t x= 0; x < result->column_count; x++)
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
444
  {
445
    if (field[x] == NULL)
2472.1.1 by Brian Aker
Formatting, and valgrind cleanups (just mismatch of free/delete).
446
    {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
447
      result->con->packet_size++;
2472.1.1 by Brian Aker
Formatting, and valgrind cleanups (just mismatch of free/delete).
448
    }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
449
    else if (size[x] < 251)
2472.1.1 by Brian Aker
Formatting, and valgrind cleanups (just mismatch of free/delete).
450
    {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
451
      result->con->packet_size+= (1 + size[x]);
2472.1.1 by Brian Aker
Formatting, and valgrind cleanups (just mismatch of free/delete).
452
    }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
453
    else if (size[x] < 65536)
2472.1.1 by Brian Aker
Formatting, and valgrind cleanups (just mismatch of free/delete).
454
    {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
455
      result->con->packet_size+= (3 + size[x]);
2472.1.1 by Brian Aker
Formatting, and valgrind cleanups (just mismatch of free/delete).
456
    }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
457
    else if (size[x] < 16777216)
2472.1.1 by Brian Aker
Formatting, and valgrind cleanups (just mismatch of free/delete).
458
    {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
459
      result->con->packet_size+= (4 + size[x]);
2472.1.1 by Brian Aker
Formatting, and valgrind cleanups (just mismatch of free/delete).
460
    }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
461
    else
2472.1.1 by Brian Aker
Formatting, and valgrind cleanups (just mismatch of free/delete).
462
    {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
463
      result->con->packet_size+= (9 + size[x]);
2472.1.1 by Brian Aker
Formatting, and valgrind cleanups (just mismatch of free/delete).
464
    }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
465
  }
466
}
467
468
void drizzle_result_set_eof(drizzle_result_st *result, bool is_eof)
469
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
470
  if (result == NULL)
471
  {
472
    return;
473
  }
474
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
475
  if (is_eof)
476
    result->options|= DRIZZLE_RESULT_EOF_PACKET;
477
  else
2464.1.2 by Brian Aker
Fix compiling issues for 1.0, and cleanup header files.
478
    result->options&= ~int(DRIZZLE_RESULT_EOF_PACKET);
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
479
}
480
481
void drizzle_result_set_info(drizzle_result_st *result, const char *info)
482
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
483
  if (result == NULL)
484
  {
485
    return;
486
  }
487
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
488
  if (info == NULL)
2449.1.4 by Brian Aker
Complete update of libdrizzle
489
  {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
490
    result->info[0]= 0;
2449.1.4 by Brian Aker
Complete update of libdrizzle
491
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
492
  else
493
  {
494
    strncpy(result->info, info, DRIZZLE_MAX_INFO_SIZE);
495
    result->info[DRIZZLE_MAX_INFO_SIZE - 1]= 0;
496
  }
497
}
498
499
void drizzle_result_set_error(drizzle_result_st *result, const char *error)
500
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
501
  if (result == NULL)
502
  {
503
    return;
504
  }
505
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
506
  drizzle_result_set_info(result, error);
507
}
508
509
void drizzle_result_set_error_code(drizzle_result_st *result,
510
                                   uint16_t error_code)
511
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
512
  if (result == NULL)
513
  {
514
    return;
515
  }
516
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
517
  result->error_code= error_code;
518
}
519
520
void drizzle_result_set_sqlstate(drizzle_result_st *result,
521
                                 const char *sqlstate)
522
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
523
  if (result == NULL)
524
  {
525
    return;
526
  }
527
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
528
  if (sqlstate == NULL)
2449.1.4 by Brian Aker
Complete update of libdrizzle
529
  {
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
530
    result->sqlstate[0]= 0;
2449.1.4 by Brian Aker
Complete update of libdrizzle
531
  }
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
532
  else
533
  {
534
    strncpy(result->sqlstate, sqlstate, DRIZZLE_MAX_SQLSTATE_SIZE + 1);
535
    result->sqlstate[DRIZZLE_MAX_SQLSTATE_SIZE]= 0;
536
  }
537
}
538
539
void drizzle_result_set_warning_count(drizzle_result_st *result,
540
                                      uint16_t warning_count)
541
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
542
  if (result == NULL)
543
  {
544
    return;
545
  }
546
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
547
  result->warning_count= warning_count;
548
}
549
550
void drizzle_result_set_insert_id(drizzle_result_st *result,
551
                                  uint64_t insert_id)
552
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
553
  if (result == NULL)
554
  {
555
    return;
556
  }
557
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
558
  result->insert_id= insert_id;
559
}
560
561
void drizzle_result_set_affected_rows(drizzle_result_st *result,
562
                                      uint64_t affected_rows)
563
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
564
  if (result == NULL)
565
  {
566
    return;
567
  }
568
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
569
  result->affected_rows= affected_rows;
570
}
571
572
void drizzle_result_set_column_count(drizzle_result_st *result,
573
                                     uint16_t column_count)
574
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
575
  if (result == NULL)
576
  {
577
    return;
578
  }
579
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
580
  result->column_count= column_count;
581
}
582
583
/*
584
 * Internal state functions.
585
 */
586
587
drizzle_return_t drizzle_state_result_read(drizzle_con_st *con)
588
{
589
  drizzle_return_t ret;
590
2449.1.4 by Brian Aker
Complete update of libdrizzle
591
  if (con == NULL)
592
  {
593
    return DRIZZLE_RETURN_INVALID_ARGUMENT;
594
  }
595
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
596
  drizzle_log_debug(con->drizzle, "drizzle_state_result_read");
597
598
  /* Assume the entire result packet will fit in the buffer. */
599
  if (con->buffer_size < con->packet_size)
600
  {
601
    drizzle_state_push(con, drizzle_state_read);
602
    return DRIZZLE_RETURN_OK;
603
  }
604
605
  if (con->buffer_ptr[0] == 0)
606
  {
607
    con->buffer_ptr++;
608
    /* We can ignore the returns since we've buffered the entire packet. */
609
    con->result->affected_rows= drizzle_unpack_length(con, &ret);
610
    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.
611
    con->status= drizzle_con_status_t(drizzle_get_byte2(con->buffer_ptr));
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
612
    con->result->warning_count= drizzle_get_byte2(con->buffer_ptr + 2);
613
    con->buffer_ptr+= 4;
614
    con->buffer_size-= 5;
615
    con->packet_size-= 5;
616
    if (con->packet_size > 0)
617
    {
618
      /* Skip one byte for message size. */
619
      con->buffer_ptr+= 1;
620
      con->buffer_size-= 1;
621
      con->packet_size-= 1;
622
    }
623
    ret= DRIZZLE_RETURN_OK;
624
  }
625
  else if (con->buffer_ptr[0] == 254)
626
  {
627
    con->result->options= DRIZZLE_RESULT_EOF_PACKET;
628
    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.
629
    con->status= drizzle_con_status_t(drizzle_get_byte2(con->buffer_ptr + 3));
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
630
    con->buffer_ptr+= 5;
631
    con->buffer_size-= 5;
632
    con->packet_size-= 5;
633
    ret= DRIZZLE_RETURN_OK;
634
  }
635
  else if (con->buffer_ptr[0] == 255)
636
  {
637
    con->result->error_code= drizzle_get_byte2(con->buffer_ptr + 1);
638
    con->drizzle->error_code= con->result->error_code;
639
    /* Byte 3 is always a '#' character, skip it. */
640
    memcpy(con->result->sqlstate, con->buffer_ptr + 4,
641
           DRIZZLE_MAX_SQLSTATE_SIZE);
642
    con->result->sqlstate[DRIZZLE_MAX_SQLSTATE_SIZE]= 0;
643
    memcpy(con->drizzle->sqlstate, con->result->sqlstate,
644
           DRIZZLE_MAX_SQLSTATE_SIZE + 1);
645
    con->buffer_ptr+= 9;
646
    con->buffer_size-= 9;
647
    con->packet_size-= 9;
648
    ret= DRIZZLE_RETURN_ERROR_CODE;
649
  }
650
  else
651
  {
652
    /* We can ignore the return since we've buffered the entire packet. */
653
    con->result->column_count= (uint16_t)drizzle_unpack_length(con, &ret);
654
    ret= DRIZZLE_RETURN_OK;
655
  }
656
657
  if (con->packet_size > 0)
658
  {
659
    snprintf(con->drizzle->last_error, DRIZZLE_MAX_ERROR_SIZE, "%.*s",
660
             (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
661
    con->drizzle->last_error[DRIZZLE_MAX_ERROR_SIZE-1]= 0;
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
662
    snprintf(con->result->info, DRIZZLE_MAX_INFO_SIZE, "%.*s",
663
             (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
664
    con->result->info[DRIZZLE_MAX_INFO_SIZE-1]= 0;
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
665
    con->buffer_ptr+= con->packet_size;
666
    con->buffer_size-= con->packet_size;
667
    con->packet_size= 0;
668
  }
669
670
  drizzle_state_pop(con);
671
  return ret;
672
}
673
674
drizzle_return_t drizzle_state_result_write(drizzle_con_st *con)
675
{
2449.1.4 by Brian Aker
Complete update of libdrizzle
676
  if (con == NULL)
677
  {
678
    return DRIZZLE_RETURN_INVALID_ARGUMENT;
679
  }
680
1712.1.1 by Monty Taylor
Merged libdrizzle directly into tree.
681
  uint8_t *start= con->buffer_ptr + con->buffer_size;
682
  uint8_t *ptr;
683
  drizzle_result_st *result= con->result;
684
685
  drizzle_log_debug(con->drizzle, "drizzle_state_result_write");
686
687
  /* Calculate max packet size. */
688
  con->packet_size= 1 /* OK/Field Count/EOF/Error */
689
                  + 9 /* Affected rows */
690
                  + 9 /* Insert ID */
691
                  + 2 /* Status */
692
                  + 2 /* Warning count */
693
                  + strlen(result->info); /* Info/error message */
694
695
  /* Assume the entire result packet will fit in the buffer. */
696
  if ((con->packet_size + 4) > DRIZZLE_MAX_BUFFER_SIZE)
697
  {
698
    drizzle_set_error(con->drizzle, "drizzle_state_result_write",
699
                      "buffer too small:%zu", con->packet_size + 4);
700
    return DRIZZLE_RETURN_INTERNAL_ERROR;
701
  }
702
703
  /* Flush buffer if there is not enough room. */
704
  if (((size_t)DRIZZLE_MAX_BUFFER_SIZE - (size_t)(start - con->buffer)) <
705
      con->packet_size)
706
  {
707
    drizzle_state_push(con, drizzle_state_write);
708
    return DRIZZLE_RETURN_OK;
709
  }
710
711
  /* Store packet size at the end since it may change. */
712
  ptr= start;
713
  ptr[3]= con->packet_number;
714
  con->packet_number++;
715
  ptr+= 4;
716
717
  if (result->options & DRIZZLE_RESULT_EOF_PACKET)
718
  {
719
    ptr[0]= 254;
720
    ptr++;
721
722
    drizzle_set_byte2(ptr, result->warning_count);
723
    ptr+= 2;
724
725
    drizzle_set_byte2(ptr, con->status);
726
    ptr+= 2;
727
  }
728
  else if (result->error_code != 0)
729
  {
730
    ptr[0]= 255;
731
    ptr++;
732
733
    drizzle_set_byte2(ptr, result->error_code);
734
    ptr+= 2;
735
736
    ptr[0]= '#';
737
    ptr++;
738
739
    memcpy(ptr, result->sqlstate, DRIZZLE_MAX_SQLSTATE_SIZE);
740
    ptr+= DRIZZLE_MAX_SQLSTATE_SIZE;
741
742
    memcpy(ptr, result->info, strlen(result->info));
743
    ptr+= strlen(result->info);
744
  }
745
  else if (result->column_count == 0)
746
  {
747
    ptr[0]= 0;
748
    ptr++;
749
750
    ptr= drizzle_pack_length(result->affected_rows, ptr);
751
    ptr= drizzle_pack_length(result->insert_id, ptr);
752
753
    drizzle_set_byte2(ptr, con->status);
754
    ptr+= 2;
755
756
    drizzle_set_byte2(ptr, result->warning_count);
757
    ptr+= 2;
758
759
    memcpy(ptr, result->info, strlen(result->info));
760
    ptr+= strlen(result->info);
761
  }
762
  else
763
    ptr= drizzle_pack_length(result->column_count, ptr);
764
765
  con->packet_size= ((size_t)(ptr - start) - 4);
766
  con->buffer_size+= (4 + con->packet_size);
767
768
  /* Store packet size now. */
769
  drizzle_set_byte3(start, con->packet_size);
770
771
  drizzle_state_pop(con);
772
  return DRIZZLE_RETURN_OK;
773
}