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 #ifdef __cplusplus 32 extern "C" { 33 #endif 34 35 #include <decimal.h> 36 #include <my_decimal_limits.h> 37 #include <mysql_time.h> 38 39 #ifndef _my_sys_h 40 typedef struct st_dynamic_string 41 { 42 char *str; 43 size_t length,max_length,alloc_increment; 44 } DYNAMIC_STRING; 45 #endif 46 47 #ifndef MY_GLOBAL_INCLUDED 48 struct st_mysql_lex_string 49 { 50 char *str; 51 size_t length; 52 }; 53 typedef struct st_mysql_lex_string MYSQL_LEX_STRING; 54 typedef struct st_mysql_lex_string LEX_STRING; 55 #endif 56 57 /* 58 Limits of implementation 59 */ 60 #define MAX_TOTAL_NAME_LENGTH 65535 61 #define MAX_NAME_LENGTH (MAX_TOTAL_NAME_LENGTH/4) 62 63 /* NO and OK is the same used just to show semantics */ 64 #define ER_DYNCOL_NO ER_DYNCOL_OK 65 66 #ifdef HAVE_CHARSET_utf8mb4 67 #define DYNCOL_UTF (&my_charset_utf8mb4_general_ci) 68 #else 69 #define DYNCOL_UTF (&my_charset_utf8_general_ci) 70 #endif 71 72 /* escape json strings */ 73 #define DYNCOL_JSON_ESC ((char)1) 74 75 enum enum_dyncol_func_result 76 { 77 ER_DYNCOL_OK= 0, 78 ER_DYNCOL_YES= 1, /* For functions returning 0/1 */ 79 ER_DYNCOL_FORMAT= -1, /* Wrong format of the encoded string */ 80 ER_DYNCOL_LIMIT= -2, /* Some limit reached */ 81 ER_DYNCOL_RESOURCE= -3, /* Out of resourses */ 82 ER_DYNCOL_DATA= -4, /* Incorrect input data */ 83 ER_DYNCOL_UNKNOWN_CHARSET= -5, /* Unknown character set */ 84 ER_DYNCOL_TRUNCATED= 2 /* OK, but data was truncated */ 85 }; 86 87 typedef DYNAMIC_STRING DYNAMIC_COLUMN; 88 89 enum enum_dynamic_column_type 90 { 91 DYN_COL_NULL= 0, 92 DYN_COL_INT, 93 DYN_COL_UINT, 94 DYN_COL_DOUBLE, 95 DYN_COL_STRING, 96 DYN_COL_DECIMAL, 97 DYN_COL_DATETIME, 98 DYN_COL_DATE, 99 DYN_COL_TIME, 100 DYN_COL_DYNCOL 101 }; 102 103 typedef enum enum_dynamic_column_type DYNAMIC_COLUMN_TYPE; 104 105 struct st_dynamic_column_value 106 { 107 DYNAMIC_COLUMN_TYPE type; 108 union 109 { 110 long long long_value; 111 unsigned long long ulong_value; 112 double double_value; 113 struct { 114 MYSQL_LEX_STRING value; 115 CHARSET_INFO *charset; 116 } string; 117 struct { 118 decimal_digit_t buffer[DECIMAL_BUFF_LENGTH]; 119 decimal_t value; 120 } decimal; 121 MYSQL_TIME time_value; 122 } x; 123 }; 124 125 typedef struct st_dynamic_column_value DYNAMIC_COLUMN_VALUE; 126 127 #ifdef MADYNCOL_DEPRECATED 128 enum enum_dyncol_func_result 129 dynamic_column_create(DYNAMIC_COLUMN *str, 130 uint column_nr, DYNAMIC_COLUMN_VALUE *value); 131 132 enum enum_dyncol_func_result 133 dynamic_column_create_many(DYNAMIC_COLUMN *str, 134 uint column_count, 135 uint *column_numbers, 136 DYNAMIC_COLUMN_VALUE *values); 137 enum enum_dyncol_func_result 138 dynamic_column_update(DYNAMIC_COLUMN *org, uint column_nr, 139 DYNAMIC_COLUMN_VALUE *value); 140 enum enum_dyncol_func_result 141 dynamic_column_update_many(DYNAMIC_COLUMN *str, 142 uint add_column_count, 143 uint *column_numbers, 144 DYNAMIC_COLUMN_VALUE *values); 145 146 enum enum_dyncol_func_result 147 dynamic_column_exists(DYNAMIC_COLUMN *org, uint column_nr); 148 149 enum enum_dyncol_func_result 150 dynamic_column_list(DYNAMIC_COLUMN *org, DYNAMIC_ARRAY *array_of_uint); 151 152 enum enum_dyncol_func_result 153 dynamic_column_get(DYNAMIC_COLUMN *org, uint column_nr, 154 DYNAMIC_COLUMN_VALUE *store_it_here); 155 #endif 156 157 /* new functions */ 158 enum enum_dyncol_func_result 159 mariadb_dyncol_create_many_num(DYNAMIC_COLUMN *str, 160 uint column_count, 161 uint *column_numbers, 162 DYNAMIC_COLUMN_VALUE *values, 163 my_bool new_string); 164 enum enum_dyncol_func_result 165 mariadb_dyncol_create_many_named(DYNAMIC_COLUMN *str, 166 uint column_count, 167 MYSQL_LEX_STRING *column_keys, 168 DYNAMIC_COLUMN_VALUE *values, 169 my_bool new_string); 170 171 172 enum enum_dyncol_func_result 173 mariadb_dyncol_update_many_num(DYNAMIC_COLUMN *str, 174 uint add_column_count, 175 uint *column_keys, 176 DYNAMIC_COLUMN_VALUE *values); 177 enum enum_dyncol_func_result 178 mariadb_dyncol_update_many_named(DYNAMIC_COLUMN *str, 179 uint add_column_count, 180 MYSQL_LEX_STRING *column_keys, 181 DYNAMIC_COLUMN_VALUE *values); 182 183 184 enum enum_dyncol_func_result 185 mariadb_dyncol_exists_num(DYNAMIC_COLUMN *org, uint column_nr); 186 enum enum_dyncol_func_result 187 mariadb_dyncol_exists_named(DYNAMIC_COLUMN *str, MYSQL_LEX_STRING *name); 188 189 /* List of not NULL columns */ 190 enum enum_dyncol_func_result 191 mariadb_dyncol_list_num(DYNAMIC_COLUMN *str, uint *count, uint **nums); 192 enum enum_dyncol_func_result 193 mariadb_dyncol_list_named(DYNAMIC_COLUMN *str, uint *count, 194 MYSQL_LEX_STRING **names); 195 196 /* 197 if the column do not exists it is NULL 198 */ 199 enum enum_dyncol_func_result 200 mariadb_dyncol_get_num(DYNAMIC_COLUMN *org, uint column_nr, 201 DYNAMIC_COLUMN_VALUE *store_it_here); 202 enum enum_dyncol_func_result 203 mariadb_dyncol_get_named(DYNAMIC_COLUMN *str, MYSQL_LEX_STRING *name, 204 DYNAMIC_COLUMN_VALUE *store_it_here); 205 206 my_bool mariadb_dyncol_has_names(DYNAMIC_COLUMN *str); 207 208 enum enum_dyncol_func_result 209 mariadb_dyncol_check(DYNAMIC_COLUMN *str); 210 211 enum enum_dyncol_func_result 212 mariadb_dyncol_json(DYNAMIC_COLUMN *str, DYNAMIC_STRING *json); 213 214 #define mariadb_dyncol_init(A) memset((A), 0, sizeof(*(A))) 215 void mariadb_dyncol_free(DYNAMIC_COLUMN *str); 216 217 /* conversion of values to 3 base types */ 218 enum enum_dyncol_func_result 219 mariadb_dyncol_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val, 220 CHARSET_INFO *cs, my_bool quote); 221 enum enum_dyncol_func_result 222 mariadb_dyncol_val_long(longlong *ll, DYNAMIC_COLUMN_VALUE *val); 223 enum enum_dyncol_func_result 224 mariadb_dyncol_val_double(double *dbl, DYNAMIC_COLUMN_VALUE *val); 225 226 227 enum enum_dyncol_func_result 228 mariadb_dyncol_unpack(DYNAMIC_COLUMN *str, 229 uint *count, 230 MYSQL_LEX_STRING **names, DYNAMIC_COLUMN_VALUE **vals); 231 232 void mariadb_dyncol_unpack_free(MYSQL_LEX_STRING *names, 233 DYNAMIC_COLUMN_VALUE *vals); 234 235 int mariadb_dyncol_column_cmp_named(const MYSQL_LEX_STRING *s1, 236 const MYSQL_LEX_STRING *s2); 237 238 enum enum_dyncol_func_result 239 mariadb_dyncol_column_count(DYNAMIC_COLUMN *str, uint *column_count); 240 241 #define mariadb_dyncol_value_init(V) (V)->type= DYN_COL_NULL 242 243 /* 244 Prepare value for using as decimal 245 */ 246 void mariadb_dyncol_prepare_decimal(DYNAMIC_COLUMN_VALUE *value); 247 248 #ifdef __cplusplus 249 } 250 #endif 251 #endif 252