1 /* Copyright (c) 2011, Monty Program Ab 2 Copyright (c) 2011, Oleksandr Byelkin 3 4 Redistribution and use in source and binary forms, with or without 5 modification, are permitted provided that the following conditions are 6 met: 7 8 1. Redistributions of source code must retain the above copyright 9 notice, this list of conditions and the following disclaimer. 10 11 2. Redistributions in binary form must the following disclaimer in 12 the documentation and/or other materials provided with the 13 distribution. 14 15 THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND ANY 16 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR 19 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 22 USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 SUCH DAMAGE. 27 */ 28 29 #ifndef ma_dyncol_h 30 #define ma_dyncol_h 31 32 #ifdef __cplusplus 33 extern "C" { 34 #endif 35 36 #ifndef LIBMARIADB 37 #include <decimal.h> 38 #include <my_decimal_limits.h> 39 #endif 40 #include <mysql.h> 41 42 #ifndef longlong_defined 43 #if defined(HAVE_LONG_LONG) && SIZEOF_LONG != 8 44 typedef unsigned long long int ulonglong; /* ulong or unsigned long long */ 45 typedef long long int longlong; 46 #else 47 typedef unsigned long ulonglong; /* ulong or unsigned long long */ 48 typedef long longlong; 49 #endif 50 #define longlong_defined 51 #endif 52 53 54 #ifndef _my_sys_h 55 typedef struct st_dynamic_string 56 { 57 char *str; 58 size_t length,max_length,alloc_increment; 59 } DYNAMIC_STRING; 60 #endif 61 62 struct st_mysql_lex_string 63 { 64 char *str; 65 size_t length; 66 }; 67 typedef struct st_mysql_lex_string MYSQL_LEX_STRING; 68 typedef struct st_mysql_lex_string LEX_STRING; 69 /* 70 Limits of implementation 71 */ 72 #define MAX_TOTAL_NAME_LENGTH 65535 73 #define MAX_NAME_LENGTH (MAX_TOTAL_NAME_LENGTH/4) 74 75 /* NO and OK is the same used just to show semantics */ 76 #define ER_DYNCOL_NO ER_DYNCOL_OK 77 78 enum enum_dyncol_func_result 79 { 80 ER_DYNCOL_OK= 0, 81 ER_DYNCOL_YES= 1, /* For functions returning 0/1 */ 82 ER_DYNCOL_FORMAT= -1, /* Wrong format of the encoded string */ 83 ER_DYNCOL_LIMIT= -2, /* Some limit reached */ 84 ER_DYNCOL_RESOURCE= -3, /* Out of resourses */ 85 ER_DYNCOL_DATA= -4, /* Incorrect input data */ 86 ER_DYNCOL_UNKNOWN_CHARSET= -5, /* Unknown character set */ 87 ER_DYNCOL_TRUNCATED= 2 /* OK, but data was truncated */ 88 }; 89 90 typedef DYNAMIC_STRING DYNAMIC_COLUMN; 91 92 enum enum_dynamic_column_type 93 { 94 DYN_COL_NULL= 0, 95 DYN_COL_INT, 96 DYN_COL_UINT, 97 DYN_COL_DOUBLE, 98 DYN_COL_STRING, 99 DYN_COL_DECIMAL, 100 DYN_COL_DATETIME, 101 DYN_COL_DATE, 102 DYN_COL_TIME, 103 DYN_COL_DYNCOL 104 }; 105 106 typedef enum enum_dynamic_column_type DYNAMIC_COLUMN_TYPE; 107 108 struct st_dynamic_column_value 109 { 110 DYNAMIC_COLUMN_TYPE type; 111 union 112 { 113 long long long_value; 114 unsigned long long ulong_value; 115 double double_value; 116 struct { 117 MYSQL_LEX_STRING value; 118 MARIADB_CHARSET_INFO *charset; 119 } string; 120 #ifndef LIBMARIADB 121 struct { 122 decimal_digit_t buffer[DECIMAL_BUFF_LENGTH]; 123 decimal_t value; 124 } decimal; 125 #endif 126 MYSQL_TIME time_value; 127 } x; 128 }; 129 130 typedef struct st_dynamic_column_value DYNAMIC_COLUMN_VALUE; 131 132 #ifdef MADYNCOL_DEPRECATED 133 enum enum_dyncol_func_result 134 dynamic_column_create(DYNAMIC_COLUMN *str, 135 uint column_nr, DYNAMIC_COLUMN_VALUE *value); 136 137 enum enum_dyncol_func_result 138 dynamic_column_create_many(DYNAMIC_COLUMN *str, 139 uint column_count, 140 uint *column_numbers, 141 DYNAMIC_COLUMN_VALUE *values); 142 enum enum_dyncol_func_result 143 dynamic_column_update(DYNAMIC_COLUMN *org, uint column_nr, 144 DYNAMIC_COLUMN_VALUE *value); 145 enum enum_dyncol_func_result 146 dynamic_column_update_many(DYNAMIC_COLUMN *str, 147 uint add_column_count, 148 uint *column_numbers, 149 DYNAMIC_COLUMN_VALUE *values); 150 151 enum enum_dyncol_func_result 152 dynamic_column_exists(DYNAMIC_COLUMN *org, uint column_nr); 153 154 enum enum_dyncol_func_result 155 dynamic_column_list(DYNAMIC_COLUMN *org, DYNAMIC_ARRAY *array_of_uint); 156 157 enum enum_dyncol_func_result 158 dynamic_column_get(DYNAMIC_COLUMN *org, uint column_nr, 159 DYNAMIC_COLUMN_VALUE *store_it_here); 160 #endif 161 162 /* new functions */ 163 enum enum_dyncol_func_result 164 mariadb_dyncol_create_many_num(DYNAMIC_COLUMN *str, 165 uint column_count, 166 uint *column_numbers, 167 DYNAMIC_COLUMN_VALUE *values, 168 my_bool new_string); 169 enum enum_dyncol_func_result 170 mariadb_dyncol_create_many_named(DYNAMIC_COLUMN *str, 171 uint column_count, 172 MYSQL_LEX_STRING *column_keys, 173 DYNAMIC_COLUMN_VALUE *values, 174 my_bool new_string); 175 176 177 enum enum_dyncol_func_result 178 mariadb_dyncol_update_many_num(DYNAMIC_COLUMN *str, 179 uint add_column_count, 180 uint *column_keys, 181 DYNAMIC_COLUMN_VALUE *values); 182 enum enum_dyncol_func_result 183 mariadb_dyncol_update_many_named(DYNAMIC_COLUMN *str, 184 uint add_column_count, 185 MYSQL_LEX_STRING *column_keys, 186 DYNAMIC_COLUMN_VALUE *values); 187 188 189 enum enum_dyncol_func_result 190 mariadb_dyncol_exists_num(DYNAMIC_COLUMN *org, uint column_nr); 191 enum enum_dyncol_func_result 192 mariadb_dyncol_exists_named(DYNAMIC_COLUMN *str, MYSQL_LEX_STRING *name); 193 194 /* List of not NULL columns */ 195 enum enum_dyncol_func_result 196 mariadb_dyncol_list_num(DYNAMIC_COLUMN *str, uint *count, uint **nums); 197 enum enum_dyncol_func_result 198 mariadb_dyncol_list_named(DYNAMIC_COLUMN *str, uint *count, 199 MYSQL_LEX_STRING **names); 200 201 /* 202 if the column do not exists it is NULL 203 */ 204 enum enum_dyncol_func_result 205 mariadb_dyncol_get_num(DYNAMIC_COLUMN *org, uint column_nr, 206 DYNAMIC_COLUMN_VALUE *store_it_here); 207 enum enum_dyncol_func_result 208 mariadb_dyncol_get_named(DYNAMIC_COLUMN *str, MYSQL_LEX_STRING *name, 209 DYNAMIC_COLUMN_VALUE *store_it_here); 210 211 my_bool mariadb_dyncol_has_names(DYNAMIC_COLUMN *str); 212 213 enum enum_dyncol_func_result 214 mariadb_dyncol_check(DYNAMIC_COLUMN *str); 215 216 enum enum_dyncol_func_result 217 mariadb_dyncol_json(DYNAMIC_COLUMN *str, DYNAMIC_STRING *json); 218 219 void mariadb_dyncol_free(DYNAMIC_COLUMN *str); 220 221 #define mariadb_dyncol_init(A) memset((A), 0, sizeof(DYNAMIC_COLUMN)) 222 #define dynamic_column_initialize(A) mariadb_dyncol_init((A)) 223 #define dynamic_column_column_free(A) mariadb_dyncol_free((A)) 224 225 /* conversion of values to 3 base types */ 226 enum enum_dyncol_func_result 227 mariadb_dyncol_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val, 228 MARIADB_CHARSET_INFO *cs, char quote); 229 enum enum_dyncol_func_result 230 mariadb_dyncol_val_long(longlong *ll, DYNAMIC_COLUMN_VALUE *val); 231 enum enum_dyncol_func_result 232 mariadb_dyncol_val_double(double *dbl, DYNAMIC_COLUMN_VALUE *val); 233 234 enum enum_dyncol_func_result 235 mariadb_dyncol_unpack(DYNAMIC_COLUMN *str, 236 uint *count, 237 MYSQL_LEX_STRING **names, DYNAMIC_COLUMN_VALUE **vals); 238 239 int mariadb_dyncol_column_cmp_named(const MYSQL_LEX_STRING *s1, 240 const MYSQL_LEX_STRING *s2); 241 242 enum enum_dyncol_func_result 243 mariadb_dyncol_column_count(DYNAMIC_COLUMN *str, uint *column_count); 244 245 #define mariadb_dyncol_value_init(V) \ 246 do {\ 247 (V)->type= DYN_COL_NULL;\ 248 } while(0) 249 250 /* 251 Prepare value for using as decimal 252 */ 253 void mariadb_dyncol_prepare_decimal(DYNAMIC_COLUMN_VALUE *value); 254 255 256 #ifdef __cplusplus 257 } 258 #endif 259 #endif 260