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
32extern "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
40typedef 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
48struct st_mysql_lex_string
49{
50 char *str;
51 size_t length;
52};
53typedef struct st_mysql_lex_string MYSQL_LEX_STRING;
54typedef 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
75enum 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
87typedef DYNAMIC_STRING DYNAMIC_COLUMN;
88
89enum 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
103typedef enum enum_dynamic_column_type DYNAMIC_COLUMN_TYPE;
104
105struct 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
125typedef struct st_dynamic_column_value DYNAMIC_COLUMN_VALUE;
126
127#ifdef MADYNCOL_DEPRECATED
128enum enum_dyncol_func_result
129dynamic_column_create(DYNAMIC_COLUMN *str,
130 uint column_nr, DYNAMIC_COLUMN_VALUE *value);
131
132enum enum_dyncol_func_result
133dynamic_column_create_many(DYNAMIC_COLUMN *str,
134 uint column_count,
135 uint *column_numbers,
136 DYNAMIC_COLUMN_VALUE *values);
137enum enum_dyncol_func_result
138dynamic_column_update(DYNAMIC_COLUMN *org, uint column_nr,
139 DYNAMIC_COLUMN_VALUE *value);
140enum enum_dyncol_func_result
141dynamic_column_update_many(DYNAMIC_COLUMN *str,
142 uint add_column_count,
143 uint *column_numbers,
144 DYNAMIC_COLUMN_VALUE *values);
145
146enum enum_dyncol_func_result
147dynamic_column_exists(DYNAMIC_COLUMN *org, uint column_nr);
148
149enum enum_dyncol_func_result
150dynamic_column_list(DYNAMIC_COLUMN *org, DYNAMIC_ARRAY *array_of_uint);
151
152enum enum_dyncol_func_result
153dynamic_column_get(DYNAMIC_COLUMN *org, uint column_nr,
154 DYNAMIC_COLUMN_VALUE *store_it_here);
155#endif
156
157/* new functions */
158enum enum_dyncol_func_result
159mariadb_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);
164enum enum_dyncol_func_result
165mariadb_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
172enum enum_dyncol_func_result
173mariadb_dyncol_update_many_num(DYNAMIC_COLUMN *str,
174 uint add_column_count,
175 uint *column_keys,
176 DYNAMIC_COLUMN_VALUE *values);
177enum enum_dyncol_func_result
178mariadb_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
184enum enum_dyncol_func_result
185mariadb_dyncol_exists_num(DYNAMIC_COLUMN *org, uint column_nr);
186enum enum_dyncol_func_result
187mariadb_dyncol_exists_named(DYNAMIC_COLUMN *str, MYSQL_LEX_STRING *name);
188
189/* List of not NULL columns */
190enum enum_dyncol_func_result
191mariadb_dyncol_list_num(DYNAMIC_COLUMN *str, uint *count, uint **nums);
192enum enum_dyncol_func_result
193mariadb_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*/
199enum enum_dyncol_func_result
200mariadb_dyncol_get_num(DYNAMIC_COLUMN *org, uint column_nr,
201 DYNAMIC_COLUMN_VALUE *store_it_here);
202enum enum_dyncol_func_result
203mariadb_dyncol_get_named(DYNAMIC_COLUMN *str, MYSQL_LEX_STRING *name,
204 DYNAMIC_COLUMN_VALUE *store_it_here);
205
206my_bool mariadb_dyncol_has_names(DYNAMIC_COLUMN *str);
207
208enum enum_dyncol_func_result
209mariadb_dyncol_check(DYNAMIC_COLUMN *str);
210
211enum enum_dyncol_func_result
212mariadb_dyncol_json(DYNAMIC_COLUMN *str, DYNAMIC_STRING *json);
213
214#define mariadb_dyncol_init(A) memset((A), 0, sizeof(*(A)))
215void mariadb_dyncol_free(DYNAMIC_COLUMN *str);
216
217/* conversion of values to 3 base types */
218enum enum_dyncol_func_result
219mariadb_dyncol_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val,
220 CHARSET_INFO *cs, my_bool quote);
221enum enum_dyncol_func_result
222mariadb_dyncol_val_long(longlong *ll, DYNAMIC_COLUMN_VALUE *val);
223enum enum_dyncol_func_result
224mariadb_dyncol_val_double(double *dbl, DYNAMIC_COLUMN_VALUE *val);
225
226
227enum enum_dyncol_func_result
228mariadb_dyncol_unpack(DYNAMIC_COLUMN *str,
229 uint *count,
230 MYSQL_LEX_STRING **names, DYNAMIC_COLUMN_VALUE **vals);
231
232void mariadb_dyncol_unpack_free(MYSQL_LEX_STRING *names,
233 DYNAMIC_COLUMN_VALUE *vals);
234
235int mariadb_dyncol_column_cmp_named(const MYSQL_LEX_STRING *s1,
236 const MYSQL_LEX_STRING *s2);
237
238enum enum_dyncol_func_result
239mariadb_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*/
246void mariadb_dyncol_prepare_decimal(DYNAMIC_COLUMN_VALUE *value);
247
248#ifdef __cplusplus
249}
250#endif
251#endif
252