libdrizzle Developer Documentation

column.c
Go to the documentation of this file.
1/*
2 * Drizzle Client & Protocol Library
3 *
4 * Copyright (C) 2008 Eric Day (eday@oddments.org)
5 * All rights reserved.
6 *
7 * Use and distribution licensed under the BSD license. See
8 * the COPYING file in this directory for full text.
9 */
10
16#include "common.h"
17
18/*
19 * Private variables.
20 */
21
37
39{
50
61
72
83
94
105
116
127
138
149
160
171
182
193
204
215
226
237
248
259
270
281
292
303
314
321};
322
323/*
324 * Common definitions
325 */
326
328 drizzle_column_st *column)
329{
330 if (column == NULL)
331 {
332 column= malloc(sizeof(drizzle_column_st));
333 if (column == NULL)
334 {
335 drizzle_set_error(result->con->drizzle, "drizzle_column_create",
336 "malloc");
337 return NULL;
338 }
339
340 memset(column, 0, sizeof(drizzle_column_st));
342 }
343 else
344 memset(column, 0, sizeof(drizzle_column_st));
345
346 column->result= result;
347
348 if (result->column_list)
349 result->column_list->prev= column;
350 column->next= result->column_list;
351 result->column_list= column;
352
353 return column;
354}
355
357{
358 if (column->result->column_list == column)
359 column->result->column_list= column->next;
360 if (column->prev)
361 column->prev->next= column->next;
362 if (column->next)
363 column->next->prev= column->prev;
364
365 if (column->options & DRIZZLE_COLUMN_ALLOCATED)
366 free(column);
367}
368
373
375{
376 return column->catalog;
377}
378
380{
381 return column->db;
382}
383
385{
386 return column->table;
387}
388
390{
391 return column->orig_table;
392}
393
395{
396 return column->name;
397}
398
400{
401 return column->orig_name;
402}
403
408
410{
411 return column->size;
412}
413
415{
416 return column->max_size;
417}
418
420{
421 column->max_size= size;
422}
423
428
434
439
441{
442 return column->decimals;
443}
444
446 size_t *size)
447{
448 *size= column->default_value_size;
449 return column->default_value;
450}
451
452/*
453 * Client definitions
454 */
455
468
470 drizzle_column_st *column,
471 drizzle_return_t *ret_ptr)
472{
473 if (drizzle_state_none(result->con))
474 {
475 result->column= column;
476
479 }
480
481 *ret_ptr= drizzle_state_loop(result->con);
482 return result->column;
483}
484
486{
488
489 if (result->column_buffer == NULL)
490 {
491 if (result->column_count == 0)
492 {
494 return DRIZZLE_RETURN_OK;
495 }
496
497 result->column_buffer= malloc(sizeof(drizzle_column_st) *
498 result->column_count);
499 if (result->column_buffer == NULL)
500 {
501 drizzle_set_error(result->con->drizzle, "drizzle_column_buffer",
502 "malloc");
504 }
505 }
506
507 /* No while body, just keep calling to buffer columns. */
508 while (drizzle_column_read(result,
509 &(result->column_buffer[result->column_current]),
510 &ret) != NULL && ret == DRIZZLE_RETURN_OK);
511 if (ret == DRIZZLE_RETURN_OK)
512 {
513 result->column_current= 0;
515 }
516
517 return ret;
518}
519
521{
522 if (result->column_current == result->column_count)
523 return NULL;
524
525 result->column_current++;
526 return &(result->column_buffer[result->column_current - 1]);
527}
528
530{
531 if (result->column_current == 0)
532 return NULL;
533
534 result->column_current--;
535 return &(result->column_buffer[result->column_current]);
536}
537
538void drizzle_column_seek(drizzle_result_st *result, uint16_t column)
539{
540 if (column <= result->column_count)
541 result->column_current= column;
542}
543
545 uint16_t column)
546{
547 if (column >= result->column_count)
548 return NULL;
549
550 return &(result->column_buffer[column]);
551}
552
554{
555 return result->column_current;
556}
557
558/*
559 * Server definitions
560 */
561
563 drizzle_column_st *column)
564{
565 if (drizzle_state_none(result->con))
566 {
567 result->column= column;
568
570 }
571
572 return drizzle_state_loop(result->con);
573}
574
575void drizzle_column_set_catalog(drizzle_column_st *column, const char *catalog)
576{
577 if (catalog == NULL)
578 column->catalog[0]= 0;
579 else
580 {
581 strncpy(column->catalog, catalog, DRIZZLE_MAX_CATALOG_SIZE);
582 column->catalog[DRIZZLE_MAX_CATALOG_SIZE - 1]= 0;
583 }
584}
585
586void drizzle_column_set_db(drizzle_column_st *column, const char *db)
587{
588 if (db == NULL)
589 column->db[0]= 0;
590 else
591 {
592 strncpy(column->db, db, DRIZZLE_MAX_DB_SIZE);
593 column->db[DRIZZLE_MAX_DB_SIZE - 1]= 0;
594 }
595}
596
597void drizzle_column_set_table(drizzle_column_st *column, const char *table)
598{
599 if (table == NULL)
600 column->table[0]= 0;
601 else
602 {
603 strncpy(column->table, table, DRIZZLE_MAX_TABLE_SIZE);
604 column->table[DRIZZLE_MAX_TABLE_SIZE - 1]= 0;
605 }
606}
607
609 const char *orig_table)
610{
611 if (orig_table == NULL)
612 column->orig_table[0]= 0;
613 else
614 {
615 strncpy(column->orig_table, orig_table, DRIZZLE_MAX_TABLE_SIZE);
616 column->orig_table[DRIZZLE_MAX_TABLE_SIZE - 1]= 0;
617 }
618}
619
620void drizzle_column_set_name(drizzle_column_st *column, const char *name)
621{
622 if (name == NULL)
623 column->name[0]= 0;
624 else
625 {
626 strncpy(column->name, name, DRIZZLE_MAX_COLUMN_NAME_SIZE);
627 column->name[DRIZZLE_MAX_COLUMN_NAME_SIZE - 1]= 0;
628 }
629}
630
632 const char *orig_name)
633{
634 if (orig_name == NULL)
635 column->orig_name[0]= 0;
636 else
637 {
638 strncpy(column->orig_name, orig_name, DRIZZLE_MAX_COLUMN_NAME_SIZE);
640 }
641}
642
644 drizzle_charset_t charset)
645{
646 column->charset= charset;
647}
648
649void drizzle_column_set_size(drizzle_column_st *column, uint32_t size)
650{
651 column->size= size;
652}
653
656{
657 column->type= type;
658}
659
662{
663 column->flags= flags;
664}
665
666void drizzle_column_set_decimals(drizzle_column_st *column, uint8_t decimals)
667{
668 column->decimals= decimals;
669}
670
672 const uint8_t *default_value,
673 size_t size)
674{
675 if (default_value == NULL)
676 column->default_value[0]= 0;
677 else
678 {
680 {
681 memcpy(column->default_value, default_value, size);
682 column->default_value[size]= 0;
683 column->default_value_size= size;
684 }
685 else
686 {
687 memcpy(column->default_value, default_value,
691 }
692 }
693}
694
695/*
696 * Internal state functions.
697 */
698
700{
701 drizzle_column_st *column;
703
704 drizzle_log_debug(con->drizzle, "drizzle_state_column_read");
705
706 /* Assume the entire column packet will fit in the buffer. */
707 if (con->buffer_size < con->packet_size)
708 {
710 return DRIZZLE_RETURN_OK;
711 }
712
713 if (con->packet_size == 5 && con->buffer_ptr[0] == 254)
714 {
715 /* EOF packet marking end of columns. */
716 con->result->column= NULL;
718 con->status= drizzle_get_byte2(con->buffer_ptr + 3);
719 con->buffer_ptr+= 5;
720 con->buffer_size-= 5;
721
723 }
725 {
726 con->buffer_ptr+= con->packet_size;
727 con->buffer_size-= con->packet_size;
728 con->packet_size= 0;
729
731 }
732 else
733 {
734 column= drizzle_column_create(con->result, con->result->column);
735 if (column == NULL)
737
738 con->result->column= column;
739
740 /* These functions can only fail if they need to read data, but we know we
741 buffered the entire packet, so ignore returns. */
743 (void)drizzle_unpack_string(con, column->db, DRIZZLE_MAX_DB_SIZE);
745 (void)drizzle_unpack_string(con, column->orig_table,
747 (void)drizzle_unpack_string(con, column->name,
749 (void)drizzle_unpack_string(con, column->orig_name,
751
752 /* Skip one filler byte. */
754 column->size= drizzle_get_byte4(con->buffer_ptr + 3);
755
756 if (con->options & DRIZZLE_CON_MYSQL)
757 column->type= con->buffer_ptr[7];
758 else
759 {
760 drizzle_type= con->buffer_ptr[7];
761 if (drizzle_type >= DRIZZLE_COLUMN_TYPE_DRIZZLE_MAX)
763 column->type= _column_type_drizzle_map_to[drizzle_type];
764 }
765
766 column->flags= drizzle_get_byte2(con->buffer_ptr + 8);
767 if (column->type <= DRIZZLE_COLUMN_TYPE_INT24 &&
769 {
771 }
772
773 column->decimals= con->buffer_ptr[10];
774 /* Skip two reserved bytes. */
775
776 con->buffer_ptr+= 13;
777 con->buffer_size-= 13;
778 con->packet_size-= 13;
779
780 if (con->packet_size > 0)
781 {
783 con->packet_size);
784
785 con->buffer_ptr+= con->packet_size;
786 con->buffer_size-= con->packet_size;
787 }
788 else
789 column->default_value[0]= 0;
790
791 con->result->column_current++;
792
794 }
795
796 return DRIZZLE_RETURN_OK;
797}
798
800{
801 uint8_t *start= con->buffer_ptr + con->buffer_size;
802 uint8_t *ptr;
803 drizzle_column_st *column= con->result->column;
804
805 drizzle_log_debug(con->drizzle, "drizzle_state_column_write");
806
807 /* Calculate max packet size. */
808 con->packet_size= 9 + strlen(column->catalog)
809 + 9 + strlen(column->db)
810 + 9 + strlen(column->table)
811 + 9 + strlen(column->orig_table)
812 + 9 + strlen(column->name)
813 + 9 + strlen(column->orig_name)
814 + 1 /* Unused */
815 + 2 /* Charset */
816 + 4 /* Size */
817 + 1 /* Type */
818 + 2 /* Flags */
819 + 1 /* Decimals */
820 + 2 /* Unused */
821 + column->default_value_size;
822
823 /* Assume the entire column packet will fit in the buffer. */
824 if ((con->packet_size + 4) > DRIZZLE_MAX_BUFFER_SIZE)
825 {
826 drizzle_set_error(con->drizzle, "drizzle_state_column_write",
827 "buffer too small:%zu", con->packet_size + 4);
829 }
830
831 /* Flush buffer if there is not enough room. */
832 if (((size_t)DRIZZLE_MAX_BUFFER_SIZE - (size_t)(start - con->buffer)) <
833 con->packet_size)
834 {
836 return DRIZZLE_RETURN_OK;
837 }
838
839 /* Store packet size at the end since it may change. */
840 ptr= start;
841 ptr[3]= con->packet_number;
842 con->packet_number++;
843 ptr+= 4;
844
845 ptr= drizzle_pack_string(column->catalog, ptr);
846 ptr= drizzle_pack_string(column->db, ptr);
847 ptr= drizzle_pack_string(column->table, ptr);
848 ptr= drizzle_pack_string(column->orig_table, ptr);
849 ptr= drizzle_pack_string(column->name, ptr);
850 ptr= drizzle_pack_string(column->orig_name, ptr);
851
852 /* This unused byte is set to 12 for some reason. */
853 ptr[0]= 12;
854 ptr++;
855
856 drizzle_set_byte2(ptr, column->charset);
857 ptr+= 2;
858
859 drizzle_set_byte4(ptr, column->size);
860 ptr+= 4;
861
862 if (con->options & DRIZZLE_CON_MYSQL)
863 ptr[0]= column->type;
864 else
865 ptr[0]= _column_type_drizzle_map_from[column->type];
866 ptr++;
867
868 drizzle_set_byte2(ptr, column->flags);
869 ptr+= 2;
870
871 ptr[0]= column->decimals;
872 ptr++;
873
874 memset(ptr, 0, 2);
875 ptr+= 2;
876
877 if (column->default_value_size > 0)
878 {
879 memcpy(ptr, column->default_value, column->default_value_size);
880 ptr+= column->default_value_size;
881 }
882
883 con->packet_size= ((size_t)(ptr - start) - 4);
884 con->buffer_size+= (4 + con->packet_size);
885
886 /* Store packet size now. */
887 drizzle_set_byte3(start, con->packet_size);
888
889 con->result->column_current++;
890
892
893 return DRIZZLE_RETURN_OK;
894}
static drizzle_column_type_t _column_type_drizzle_map_to[]
Definition column.c:22
static drizzle_column_type_drizzle_t _column_type_drizzle_map_from[]
Definition column.c:38
System Include Files.
drizzle_column_st * drizzle_column_next(drizzle_result_st *result)
Definition column.c:520
drizzle_return_t drizzle_column_buffer(drizzle_result_st *result)
Definition column.c:485
drizzle_return_t drizzle_column_skip(drizzle_result_st *result)
Definition column.c:456
uint16_t drizzle_column_current(drizzle_result_st *result)
Definition column.c:553
drizzle_column_st * drizzle_column_read(drizzle_result_st *result, drizzle_column_st *column, drizzle_return_t *ret_ptr)
Definition column.c:469
drizzle_column_st * drizzle_column_prev(drizzle_result_st *result)
Definition column.c:529
drizzle_column_st * drizzle_column_index(drizzle_result_st *result, uint16_t column)
Definition column.c:544
void drizzle_column_seek(drizzle_result_st *result, uint16_t column)
Definition column.c:538
void drizzle_column_set_orig_table(drizzle_column_st *column, const char *orig_table)
Definition column.c:608
void drizzle_column_set_charset(drizzle_column_st *column, drizzle_charset_t charset)
Definition column.c:643
void drizzle_column_set_size(drizzle_column_st *column, uint32_t size)
Definition column.c:649
drizzle_return_t drizzle_column_write(drizzle_result_st *result, drizzle_column_st *column)
Definition column.c:562
void drizzle_column_set_decimals(drizzle_column_st *column, uint8_t decimals)
Definition column.c:666
void drizzle_column_set_db(drizzle_column_st *column, const char *db)
Definition column.c:586
void drizzle_column_set_type(drizzle_column_st *column, drizzle_column_type_t type)
Definition column.c:654
void drizzle_column_set_name(drizzle_column_st *column, const char *name)
Definition column.c:620
void drizzle_column_set_table(drizzle_column_st *column, const char *table)
Definition column.c:597
void drizzle_column_set_flags(drizzle_column_st *column, drizzle_column_flags_t flags)
Definition column.c:660
void drizzle_column_set_default_value(drizzle_column_st *column, const uint8_t *default_value, size_t size)
Definition column.c:671
void drizzle_column_set_catalog(drizzle_column_st *column, const char *catalog)
Definition column.c:575
void drizzle_column_set_orig_name(drizzle_column_st *column, const char *orig_name)
Definition column.c:631
const char * drizzle_column_catalog(drizzle_column_st *column)
Definition column.c:374
drizzle_column_type_t
Definition constants.h:314
const char * drizzle_column_orig_name(drizzle_column_st *column)
Definition column.c:399
drizzle_column_flags_t
Definition constants.h:370
drizzle_result_st * drizzle_column_drizzle_result(drizzle_column_st *column)
Definition column.c:369
const char * drizzle_column_name(drizzle_column_st *column)
Definition column.c:394
drizzle_column_type_drizzle_t
Definition constants.h:349
void drizzle_column_set_max_size(drizzle_column_st *column, size_t size)
Definition column.c:419
const uint8_t * drizzle_column_default_value(drizzle_column_st *column, size_t *size)
Definition column.c:445
drizzle_column_type_drizzle_t drizzle_column_type_drizzle(drizzle_column_st *column)
Definition column.c:430
void drizzle_column_free(drizzle_column_st *column)
Definition column.c:356
drizzle_column_st * drizzle_column_create(drizzle_result_st *result, drizzle_column_st *column)
Definition column.c:327
drizzle_column_flags_t drizzle_column_flags(drizzle_column_st *column)
Definition column.c:435
const char * drizzle_column_table(drizzle_column_st *column)
Definition column.c:384
drizzle_charset_t drizzle_column_charset(drizzle_column_st *column)
Definition column.c:404
const char * drizzle_column_db(drizzle_column_st *column)
Definition column.c:379
drizzle_column_type_t drizzle_column_type(drizzle_column_st *column)
Definition column.c:424
uint8_t drizzle_column_decimals(drizzle_column_st *column)
Definition column.c:440
uint32_t drizzle_column_size(drizzle_column_st *column)
Definition column.c:409
const char * drizzle_column_orig_table(drizzle_column_st *column)
Definition column.c:389
size_t drizzle_column_max_size(drizzle_column_st *column)
Definition column.c:414
@ DRIZZLE_COLUMN_TYPE_VARCHAR
Definition constants.h:330
@ DRIZZLE_COLUMN_TYPE_TINY
Definition constants.h:316
@ DRIZZLE_COLUMN_TYPE_TIMESTAMP
Definition constants.h:322
@ DRIZZLE_COLUMN_TYPE_INT24
Definition constants.h:324
@ DRIZZLE_COLUMN_TYPE_DOUBLE
Definition constants.h:320
@ DRIZZLE_COLUMN_TYPE_BLOB
Definition constants.h:338
@ DRIZZLE_COLUMN_TYPE_LONG
Definition constants.h:318
@ DRIZZLE_COLUMN_TYPE_ENUM
Definition constants.h:333
@ DRIZZLE_COLUMN_TYPE_NULL
Definition constants.h:321
@ DRIZZLE_COLUMN_TYPE_NEWDATE
Definition constants.h:329
@ DRIZZLE_COLUMN_TYPE_DATETIME
Definition constants.h:327
@ DRIZZLE_COLUMN_TYPE_LONGLONG
Definition constants.h:323
@ DRIZZLE_COLUMN_TYPE_NEWDECIMAL
Definition constants.h:332
@ DRIZZLE_COLUMN_FLAGS_NUM
Definition constants.h:387
@ DRIZZLE_COLUMN_TYPE_DRIZZLE_TIMESTAMP
Definition constants.h:354
@ DRIZZLE_COLUMN_TYPE_DRIZZLE_MAX
Definition constants.h:362
@ DRIZZLE_COLUMN_TYPE_DRIZZLE_TINY
Definition constants.h:350
@ DRIZZLE_COLUMN_TYPE_DRIZZLE_VARCHAR
Definition constants.h:358
@ DRIZZLE_COLUMN_TYPE_DRIZZLE_LONGLONG
Definition constants.h:355
@ DRIZZLE_COLUMN_TYPE_DRIZZLE_BLOB
Definition constants.h:361
@ DRIZZLE_COLUMN_TYPE_DRIZZLE_DOUBLE
Definition constants.h:352
@ DRIZZLE_COLUMN_TYPE_DRIZZLE_DATE
Definition constants.h:357
@ DRIZZLE_COLUMN_TYPE_DRIZZLE_ENUM
Definition constants.h:360
@ DRIZZLE_COLUMN_TYPE_DRIZZLE_DATETIME
Definition constants.h:356
@ DRIZZLE_COLUMN_TYPE_DRIZZLE_NULL
Definition constants.h:353
@ DRIZZLE_COLUMN_TYPE_DRIZZLE_NEWDECIMAL
Definition constants.h:359
@ DRIZZLE_COLUMN_TYPE_DRIZZLE_LONG
Definition constants.h:351
@ DRIZZLE_COLUMN_ALLOCATED
Definition constants.h:306
static void drizzle_state_pop(drizzle_con_st *con)
Definition conn_local.h:73
static void drizzle_state_push(drizzle_con_st *con, drizzle_state_fn *function)
Definition conn_local.h:57
static bool drizzle_state_none(drizzle_con_st *con)
Definition conn_local.h:45
@ DRIZZLE_CON_MYSQL
Definition constants.h:135
#define DRIZZLE_MAX_DEFAULT_VALUE_SIZE
Definition constants.h:53
#define DRIZZLE_MAX_BUFFER_SIZE
Definition constants.h:55
#define DRIZZLE_MAX_CATALOG_SIZE
Definition constants.h:50
#define DRIZZLE_MAX_TABLE_SIZE
Definition constants.h:51
drizzle_return_t
Definition constants.h:69
#define DRIZZLE_MAX_DB_SIZE
Definition constants.h:47
#define DRIZZLE_MAX_COLUMN_NAME_SIZE
Definition constants.h:52
@ DRIZZLE_RETURN_OK
Definition constants.h:70
@ DRIZZLE_RETURN_INTERNAL_ERROR
Definition constants.h:76
@ DRIZZLE_RETURN_MEMORY
Definition constants.h:74
static void drizzle_log_debug(drizzle_st *drizzle, const char *format,...)
void drizzle_set_error(drizzle_st *drizzle, const char *function, const char *format,...)
Definition drizzle.c:633
#define drizzle_set_byte3(__buffer, __int)
Definition constants.h:478
#define drizzle_set_byte4(__buffer, __int)
Definition constants.h:482
#define drizzle_get_byte2(__buffer)
Definition constants.h:452
#define drizzle_get_byte4(__buffer)
Definition constants.h:459
#define drizzle_set_byte2(__buffer, __int)
Definition constants.h:475
uint8_t * drizzle_pack_string(char *string, uint8_t *ptr)
Definition pack.c:120
drizzle_return_t drizzle_unpack_string(drizzle_con_st *con, char *buffer, uint64_t max_length)
Definition pack.c:134
@ DRIZZLE_RESULT_SKIP_COLUMN
Definition constants.h:293
@ DRIZZLE_RESULT_BUFFER_COLUMN
Definition constants.h:294
drizzle_return_t drizzle_state_packet_read(drizzle_con_st *con)
Definition state.c:40
drizzle_return_t drizzle_state_write(drizzle_con_st *con)
Definition conn.c:975
drizzle_return_t drizzle_state_read(drizzle_con_st *con)
Definition conn.c:897
drizzle_return_t drizzle_state_column_read(drizzle_con_st *con)
Definition column.c:699
drizzle_return_t drizzle_state_loop(drizzle_con_st *con)
Definition state.c:18
drizzle_return_t drizzle_state_column_write(drizzle_con_st *con)
Definition column.c:799
uint8_t drizzle_charset_t
Definition constants.h:414
drizzle_column_st * next
Definition structs.h:188
drizzle_column_type_t type
Definition structs.h:200
drizzle_charset_t charset
Definition structs.h:197
char orig_name[DRIZZLE_MAX_COLUMN_NAME_SIZE]
Definition structs.h:196
char catalog[DRIZZLE_MAX_CATALOG_SIZE]
Definition structs.h:191
char table[DRIZZLE_MAX_TABLE_SIZE]
Definition structs.h:193
uint32_t size
Definition structs.h:198
char orig_table[DRIZZLE_MAX_TABLE_SIZE]
Definition structs.h:194
drizzle_column_flags_t flags
Definition structs.h:201
char db[DRIZZLE_MAX_DB_SIZE]
Definition structs.h:192
drizzle_column_st * prev
Definition structs.h:189
uint8_t decimals
Definition structs.h:202
uint8_t default_value[DRIZZLE_MAX_DEFAULT_VALUE_SIZE]
Definition structs.h:203
drizzle_column_options_t options
Definition structs.h:190
drizzle_result_st * result
Definition structs.h:187
char name[DRIZZLE_MAX_COLUMN_NAME_SIZE]
Definition structs.h:195
size_t default_value_size
Definition structs.h:204
uint8_t packet_number
Definition structs.h:76
uint8_t buffer[DRIZZLE_MAX_BUFFER_SIZE]
Definition structs.h:115
drizzle_st * drizzle
Definition structs.h:103
drizzle_result_st * result
Definition structs.h:107
drizzle_con_options_t options
Definition structs.h:84
drizzle_con_status_t status
Definition structs.h:86
size_t packet_size
Definition structs.h:96
uint8_t * buffer_ptr
Definition structs.h:98
size_t buffer_size
Definition structs.h:92
uint16_t column_current
Definition structs.h:160
drizzle_column_st * column_buffer
Definition structs.h:163
drizzle_column_st * column
Definition structs.h:162
uint16_t warning_count
Definition structs.h:156
drizzle_con_st * con
Definition structs.h:147
drizzle_result_options_t options
Definition structs.h:150
drizzle_column_st * column_list
Definition structs.h:161
uint16_t column_count
Definition structs.h:159