1 /*
2 Copyright (c) 2013 Monty Program AB. All rights reserved.
3 
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published
6 by the Free Software Foundation; version 2 of the License.
7 
8 This program is distributed in the hope that it will be useful, but
9 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 for more details.
12 
13 You should have received a copy of the GNU General Public License along
14 with this program; if not, write to the Free Software Foundation, Inc.,
15 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
16 */
17 
18 #include "my_test.h"
19 #include "mariadb_dyncol.h"
20 
21 static int create_dyncol_named(MYSQL *mysql)
22 {
23   DYNAMIC_COLUMN dyncol;
24   DYNAMIC_COLUMN_VALUE *vals;
25   uint i, column_count= 6;
26   int rc;
27   const char *strval[]= {"Val1", "Val2", "Val3", "Val4", "Val5", "Val6"};
28   MYSQL_LEX_STRING keys1[]= {{(char *)"key1", 4}, {(char *)"key2", 4},
29                              {(char *)"key3", 4}, {(char *)"key4", 4},
30                              {(char *)"key5", 4}, {(char *)"key6", 4}},
31 
32                    keys2[]= {{(char *)"key1", 4}, {(char *)"key1", 4},
33                              {(char *)"key3", 4}, {(char *)"key4", 4},
34                              {(char *)"key5", 4}, {(char *)"key6", 4}},
35 
36                    keys3[]= {{(char *)"\x70\x61\x72\x61\x00\x30", 6},
37                              {(char *)"\x70\x61\x72\x61\x00\x31", 6},
38                              {(char *)"\x70\x61\x72\x61\x00\x32", 6},
39                              {(char *)"\x70\x61\x72\x61\x00\x33", 6},
40                              {(char *)"\x70\x61\x72\x61\x00\x34", 6},
41                              {(char *)"\x70\x61\x72\x61\x00\x35", 6}};
42   MYSQL_LEX_STRING *my_keys;
43   uint my_count;
44 
45   vals= (DYNAMIC_COLUMN_VALUE *)malloc(column_count * sizeof(DYNAMIC_COLUMN_VALUE));
46 
47   for (i=0; i < column_count; i++)
48   {
49     vals[i].type= DYN_COL_STRING;
50     vals[i].x.string.value.str= (char *)strval[i];
51     vals[i].x.string.value.length= strlen(strval[i]);
52     vals[i].x.string.charset= (MARIADB_CHARSET_INFO *)mysql->charset;
53     diag("%s", keys3[i].str);
54   }
55 
56   mariadb_dyncol_init(&dyncol);
57   rc= mariadb_dyncol_create_many_named(&dyncol, column_count, keys1, vals, 0);
58   mariadb_dyncol_free(&dyncol);
59   FAIL_IF(mariadb_dyncol_create_many_named(&dyncol, column_count, keys1, vals, 1) < 0, "Error");
60   column_count= 0;
61   FAIL_IF(mariadb_dyncol_column_count(&dyncol, &column_count) < 0, "Error");
62 
63   FAIL_IF(column_count != 6, "6 columns expected");
64   mariadb_dyncol_free(&dyncol);
65 
66   rc= mariadb_dyncol_create_many_named(&dyncol, column_count, keys3, vals, 1);
67   if (rc < 0) {
68     diag("Error!!: %d", rc);
69     return FAIL;
70   }
71   column_count= 0;
72   FAIL_IF(mariadb_dyncol_column_count(&dyncol, &column_count) < 0, "Error");
73 
74   FAIL_IF(column_count != 6, "6 columns expected");
75 
76   mariadb_dyncol_free(&dyncol);
77 
78   /* Now try to add a duplicate key */
79 
80   FAIL_IF(mariadb_dyncol_create_many_named(&dyncol, column_count, keys2, vals, 1) >=0, "Error expected");
81   mariadb_dyncol_free(&dyncol);
82 
83   /* binary keys */
84   rc= mariadb_dyncol_create_many_named(&dyncol, column_count, keys3, vals, 1);
85   FAIL_IF(rc < 0, "binary keys failed");
86 
87   /* get keys*/
88   rc= mariadb_dyncol_list_named(&dyncol, &my_count, &my_keys);
89   FAIL_IF(rc < 0, "list named failed");
90 
91   for (i=0; i < my_count; i++)
92   {
93     if (memcmp(my_keys[i].str, keys3[i].str, keys3[i].length) != 0)
94       diag("error key %d", i);
95     vals[i].type=DYN_COL_NULL;
96   }
97   rc= mariadb_dyncol_update_many_named(&dyncol, column_count, keys3, vals);
98   FAIL_IF(rc < 0, "update failed");
99   mariadb_dyncol_free(&dyncol);
100 
101   keys3[0].str= (char *)"test";
102   for (i=0; i < column_count; i++)
103     diag("%s", my_keys[i].str);
104 
105   free(vals);
106   free(my_keys);
107   return OK;
108 }
109 
110 static int mdev_4994(MYSQL *unused __attribute__((unused)))
111 {
112   DYNAMIC_COLUMN dyncol;
113   uint key= 1;
114   DYNAMIC_COLUMN_VALUE val;
115   int rc;
116 
117 
118   val.type= DYN_COL_NULL;
119 
120   mariadb_dyncol_init(&dyncol);
121   rc= mariadb_dyncol_create_many_num(&dyncol, 1, &key, &val, 0);
122   FAIL_IF(rc < 0, "Unexpected error");
123   mariadb_dyncol_free(&dyncol);
124   return OK;
125 }
126 
127 static int create_dyncol_num(MYSQL *mysql)
128 {
129   DYNAMIC_COLUMN dyncol;
130   DYNAMIC_COLUMN_VALUE vals[5];
131   uint i, column_count= 5;
132   uint my_count;
133   MYSQL_LEX_STRING *my_keys;
134   DYNAMIC_COLUMN_VALUE *my_vals;
135   int rc;
136   const char *strval[]= {"Val1", "Val2", "Val3", "Val4", "Val5"};
137 
138   uint keys1[5]= {1,2,3,4,5},
139        keys2[5]= {1,2,2,4,5};
140   MYSQL_LEX_STRING key1= {(char *)"1",1};
141 
142   for (i=0; i < column_count; i++)
143   {
144     vals[i].type= DYN_COL_STRING;
145     vals[i].x.string.value.str= (char *)strval[i];
146     vals[i].x.string.value.length= strlen(strval[i]);
147     vals[i].x.string.charset= (MARIADB_CHARSET_INFO *)mysql->charset;
148   }
149   FAIL_IF(mariadb_dyncol_create_many_num(&dyncol, column_count, keys1, vals, 1) <0, "Error (keys1)");
150 
151   vals[0].x.string.value.str= (char *)strval[1];
152   rc= mariadb_dyncol_update_many_named(&dyncol,1, &key1, vals);
153   diag("update: %d", rc);
154 
155   rc= mariadb_dyncol_unpack(&dyncol, &my_count, &my_keys, &my_vals);
156   diag("unpack: %d %d", rc, my_count);
157 
158   free(my_keys);
159   free(my_vals);
160 
161   FAIL_IF(mariadb_dyncol_column_count(&dyncol, &column_count) < 0, "Error");
162   FAIL_IF(column_count != 5, "5 columns expected");
163   mariadb_dyncol_free(&dyncol);
164   FAIL_IF(mariadb_dyncol_create_many_num(&dyncol, column_count, keys2, vals, 1) >=0, "Error expected (keys2)");
165   mariadb_dyncol_free(&dyncol);
166   return OK;
167 }
168 
169 static int mdev_x1(MYSQL *mysql)
170 {
171   int rc;
172   uint i;
173   uint num_keys[5]= {1,2,3,4,5};
174   const char *strval[]= {"Val1", "Val2", "Val3", "Val4", "Val5"};
175   DYNAMIC_COLUMN_VALUE vals[5];
176   DYNAMIC_COLUMN dynstr;
177   MYSQL_LEX_STRING my_key= {(char *)"1", 2};
178   uint unpack_columns;
179   MYSQL_LEX_STRING *unpack_keys;
180   DYNAMIC_COLUMN_VALUE *unpack_vals;
181 
182   for (i=0; i < 5; i++)
183   {
184     vals[i].type= DYN_COL_STRING;
185     vals[i].x.string.value.str= (char *)strval[i];
186     vals[i].x.string.value.length= strlen(strval[i]);
187     vals[i].x.string.charset= (MARIADB_CHARSET_INFO *)mysql->charset;
188   }
189 
190   mariadb_dyncol_init(&dynstr);
191 
192   /* create numeric */
193   rc= mariadb_dyncol_create_many_num(&dynstr, 5, num_keys, vals, 1);
194   if (rc < 0)
195   {
196     diag("Error: %d", rc);
197     return FAIL;
198   }
199 
200   /* unpack and print values */
201   rc= mariadb_dyncol_unpack(&dynstr, &unpack_columns, &unpack_keys, &unpack_vals);
202   if (rc < 0)
203   {
204     diag("Error: %d", rc);
205     return FAIL;
206   }
207 
208   for (i=0; i < unpack_columns; i++)
209     if (memcmp(unpack_vals[i].x.string.value.str, vals[i].x.string.value.str, vals[i].x.string.value.length))
210       diag("Error1: key: %1s val: %s %s", unpack_keys[i].str, unpack_vals[i].x.string.value.str, vals[i].x.string.value.str);
211 
212   free(unpack_keys);
213   free(unpack_vals);
214 
215   /* change one value and update with named key */
216 /*  vals[0].x.string.value.str= strval[1]; */
217   rc= mariadb_dyncol_update_many_named(&dynstr, 1, &my_key, vals);
218   if (rc < 0)
219   {
220     diag("Error: %d", rc);
221     return FAIL;
222   }
223 
224   /* unpack and print values */
225   rc= mariadb_dyncol_unpack(&dynstr, &unpack_columns, &unpack_keys, &unpack_vals);
226   if (rc < 0)
227   {
228     diag("Error: %d", rc);
229     return FAIL;
230   }
231   diag("Columns: %d", unpack_columns);
232 
233   for (i=0; i < unpack_columns; i++)
234     diag("Key: %s Len: %lu", unpack_keys[i].str, (unsigned long)unpack_keys[i].length);
235 
236 
237   free(unpack_keys);
238   free(unpack_vals);
239 
240   mariadb_dyncol_free(&dynstr);
241   return OK;
242 }
243 
244 static int dyncol_column_count(MYSQL *unused __attribute__((unused)))
245 {
246   DYNAMIC_COLUMN dyncol;
247   uint column_count= 5;
248   int rc;
249 
250   mariadb_dyncol_init(&dyncol); /* memset(&dyncol, 0, sizeof(DYNAMIC_COLUMN)) */
251   rc= mariadb_dyncol_column_count(&dyncol, &column_count);
252   diag("rc=%d", rc);
253   FAIL_IF(rc < 0, "unexpected error");
254   FAIL_IF(column_count > 0, "Expected column_count=0");
255   return OK;
256 }
257 
258 static int dyncol_nested(MYSQL *mysql __attribute__((unused)))
259 {
260   DYNAMIC_COLUMN col1, col2;
261   DYNAMIC_COLUMN_VALUE value[2];
262   MYSQL_LEX_STRING cols[2]= {{(char *)"0",1},{(char *)"1",1}};
263   DYNAMIC_STRING s;
264 
265   mariadb_dyncol_init(&col1);
266   mariadb_dyncol_init(&col2);
267 
268   memset(&value, 0, sizeof(DYNAMIC_COLUMN_VALUE));
269 
270   value[0].type= DYN_COL_UINT;
271   value[0].x.ulong_value = 17;
272 
273   mariadb_dyncol_create_many_named(&col1, 1, cols, value, 0);
274   if (mariadb_dyncol_check(&col1) != ER_DYNCOL_OK)
275   {
276     diag("Error while creating col1");
277     return FAIL;
278   }
279 
280   value[1].type= DYN_COL_DYNCOL;
281   value[1].x.string.value.str= col1.str;
282   value[1].x.string.value.length= col1.length;
283 
284   mariadb_dyncol_create_many_named(&col2, 2, cols, value, 0);
285   if (mariadb_dyncol_check(&col2) != ER_DYNCOL_OK)
286   {
287     diag("Error while creating col1");
288     return FAIL;
289   }
290   mariadb_dyncol_json(&col2, &s);
291   if (strcmp(s.str, "{\"0\":17,\"1\":{\"0\":17}}") != 0)
292   {
293     diag("%s != %s", s.str, "{\"0\":17,\"1\":{\"0\":17}}");
294     return FAIL;
295   }
296   ma_dynstr_free(&s);
297   mariadb_dyncol_free(&col1);
298   mariadb_dyncol_free(&col2);
299   return OK;
300 }
301 
302 struct my_tests_st my_tests[] = {
303   {"mdev_x1", mdev_x1, TEST_CONNECTION_NEW, 0, NULL, NULL},
304   {"mdev_4994", mdev_4994, TEST_CONNECTION_NEW, 0, NULL, NULL},
305   {"create_dyncol_named", create_dyncol_named, TEST_CONNECTION_NEW, 0, NULL, NULL},
306   {"create_dyncol_num", create_dyncol_num, TEST_CONNECTION_NEW, 0, NULL, NULL},
307   {"dyncol_column_count", dyncol_column_count, TEST_CONNECTION_NEW, 0, NULL, NULL},
308   {"dyncol_nested", dyncol_nested, TEST_CONNECTION_NEW, 0, NULL, NULL},
309   {NULL, NULL, 0, 0, NULL, 0}
310 };
311 
312 
313 int main(int argc, char **argv)
314 {
315   if (argc > 1)
316    get_options(argc, argv);
317 
318   get_envvars();
319 
320   run_tests(my_tests);
321 
322   return(exit_status());
323 }
324