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
33extern "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
44typedef unsigned long long int ulonglong; /* ulong or unsigned long long */
45typedef long long int longlong;
46#else
47typedef unsigned long ulonglong; /* ulong or unsigned long long */
48typedef long longlong;
49#endif
50#define longlong_defined
51#endif
52
53
54#ifndef _my_sys_h
55typedef struct st_dynamic_string
56{
57 char *str;
58 size_t length,max_length,alloc_increment;
59} DYNAMIC_STRING;
60#endif
61
62struct st_mysql_lex_string
63{
64 char *str;
65 size_t length;
66};
67typedef struct st_mysql_lex_string MYSQL_LEX_STRING;
68typedef 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
78enum 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
90typedef DYNAMIC_STRING DYNAMIC_COLUMN;
91
92enum 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
106typedef enum enum_dynamic_column_type DYNAMIC_COLUMN_TYPE;
107
108struct 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
130typedef struct st_dynamic_column_value DYNAMIC_COLUMN_VALUE;
131
132#ifdef MADYNCOL_DEPRECATED
133enum enum_dyncol_func_result
134dynamic_column_create(DYNAMIC_COLUMN *str,
135 uint column_nr, DYNAMIC_COLUMN_VALUE *value);
136
137enum enum_dyncol_func_result
138dynamic_column_create_many(DYNAMIC_COLUMN *str,
139 uint column_count,
140 uint *column_numbers,
141 DYNAMIC_COLUMN_VALUE *values);
142enum enum_dyncol_func_result
143dynamic_column_update(DYNAMIC_COLUMN *org, uint column_nr,
144 DYNAMIC_COLUMN_VALUE *value);
145enum enum_dyncol_func_result
146dynamic_column_update_many(DYNAMIC_COLUMN *str,
147 uint add_column_count,
148 uint *column_numbers,
149 DYNAMIC_COLUMN_VALUE *values);
150
151enum enum_dyncol_func_result
152dynamic_column_exists(DYNAMIC_COLUMN *org, uint column_nr);
153
154enum enum_dyncol_func_result
155dynamic_column_list(DYNAMIC_COLUMN *org, DYNAMIC_ARRAY *array_of_uint);
156
157enum enum_dyncol_func_result
158dynamic_column_get(DYNAMIC_COLUMN *org, uint column_nr,
159 DYNAMIC_COLUMN_VALUE *store_it_here);
160#endif
161
162/* new functions */
163enum enum_dyncol_func_result
164mariadb_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);
169enum enum_dyncol_func_result
170mariadb_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
177enum enum_dyncol_func_result
178mariadb_dyncol_update_many_num(DYNAMIC_COLUMN *str,
179 uint add_column_count,
180 uint *column_keys,
181 DYNAMIC_COLUMN_VALUE *values);
182enum enum_dyncol_func_result
183mariadb_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
189enum enum_dyncol_func_result
190mariadb_dyncol_exists_num(DYNAMIC_COLUMN *org, uint column_nr);
191enum enum_dyncol_func_result
192mariadb_dyncol_exists_named(DYNAMIC_COLUMN *str, MYSQL_LEX_STRING *name);
193
194/* List of not NULL columns */
195enum enum_dyncol_func_result
196mariadb_dyncol_list_num(DYNAMIC_COLUMN *str, uint *count, uint **nums);
197enum enum_dyncol_func_result
198mariadb_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*/
204enum enum_dyncol_func_result
205mariadb_dyncol_get_num(DYNAMIC_COLUMN *org, uint column_nr,
206 DYNAMIC_COLUMN_VALUE *store_it_here);
207enum enum_dyncol_func_result
208mariadb_dyncol_get_named(DYNAMIC_COLUMN *str, MYSQL_LEX_STRING *name,
209 DYNAMIC_COLUMN_VALUE *store_it_here);
210
211my_bool mariadb_dyncol_has_names(DYNAMIC_COLUMN *str);
212
213enum enum_dyncol_func_result
214mariadb_dyncol_check(DYNAMIC_COLUMN *str);
215
216enum enum_dyncol_func_result
217mariadb_dyncol_json(DYNAMIC_COLUMN *str, DYNAMIC_STRING *json);
218
219void 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 */
226enum enum_dyncol_func_result
227mariadb_dyncol_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val,
228 MARIADB_CHARSET_INFO *cs, my_bool quote);
229enum enum_dyncol_func_result
230mariadb_dyncol_val_long(longlong *ll, DYNAMIC_COLUMN_VALUE *val);
231enum enum_dyncol_func_result
232mariadb_dyncol_val_double(double *dbl, DYNAMIC_COLUMN_VALUE *val);
233
234enum enum_dyncol_func_result
235mariadb_dyncol_unpack(DYNAMIC_COLUMN *str,
236 uint *count,
237 MYSQL_LEX_STRING **names, DYNAMIC_COLUMN_VALUE **vals);
238
239int mariadb_dyncol_column_cmp_named(const MYSQL_LEX_STRING *s1,
240 const MYSQL_LEX_STRING *s2);
241
242enum enum_dyncol_func_result
243mariadb_dyncol_column_count(DYNAMIC_COLUMN *str, uint *column_count);
244
245#define mariadb_dyncol_value_init(V) (V)->type= DYN_COL_NULL
246
247/*
248 Prepare value for using as decimal
249*/
250void mariadb_dyncol_prepare_decimal(DYNAMIC_COLUMN_VALUE *value);
251
252
253#ifdef __cplusplus
254}
255#endif
256#endif
257