Groonga 3.0.9 Source Code Document
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
test-command-dump.c
Go to the documentation of this file.
1 /* -*- c-basic-offset: 2; coding: utf-8 -*- */
2 /*
3  Copyright (C) 2010 Brazil
4  Copyright (C) 2009 Ryo Onodera <onodera@clear-code.com>
5  Copyright (C) 2009-2013 Kouhei Sutou <kou@clear-code.com>
6 
7  This library is free software; you can redistribute it and/or
8  modify it under the terms of the GNU Lesser General Public
9  License version 2.1 as published by the Free Software Foundation.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public
17  License along with this library; if not, write to the Free Software
18  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20 
21 #include "str.h"
22 #include <stdio.h>
23 
24 #include <gcutter.h>
25 
26 #include "../lib/grn-assertions.h"
27 
28 void data_table_create(void);
29 void test_table_create(gconstpointer data);
30 void data_column_create(void);
31 void test_column_create(gconstpointer data);
32 void data_uvector_column(void);
33 void data_vector_column(void);
34 void test_uvector_column(gconstpointer data);
35 void test_vector_column(gconstpointer data);
37 void test_nil_reference(void);
39 void test_tables_argument(void);
40 
41 static gchar *tmp_directory;
42 
43 static grn_ctx *context;
44 static grn_obj *database;
45 
46 void
48 {
49  tmp_directory = g_build_filename(grn_test_get_tmp_dir(),
50  "command-dump",
51  NULL);
52 }
53 
54 void
56 {
57  g_free(tmp_directory);
58 }
59 
60 static void
61 remove_tmp_directory(void)
62 {
63  cut_remove_path(tmp_directory, NULL);
64 }
65 
66 void
67 cut_setup(void)
68 {
69  const gchar *database_path;
70 
71  remove_tmp_directory();
72  g_mkdir_with_parents(tmp_directory, 0700);
73 
74  context = g_new0(grn_ctx, 1);
75  grn_ctx_init(context, 0);
76 
77  database_path = cut_build_path(tmp_directory, "dump.db", NULL);
78  database = grn_db_create(context, database_path, NULL);
79 }
80 
81 void
83 {
84  if (context) {
85  grn_obj_unlink(context, database);
86  grn_ctx_fin(context);
87  g_free(context);
88  }
89 
90  remove_tmp_directory();
91 }
92 
93 static grn_obj *
94 table_create(const gchar *name, grn_obj_flags flags,
95  const gchar *key_type_name, const gchar *value_type_name)
96 {
97  grn_obj *table;
98  grn_obj *key_type = NULL, *value_type = NULL;
99 
100  if (key_type_name)
101  key_type = get_object(key_type_name);
102  if (value_type_name)
103  value_type = get_object(value_type_name);
104 
105  table = grn_table_create(context,
106  name, strlen(name),
107  NULL,
108  flags | GRN_OBJ_PERSISTENT,
109  key_type, value_type);
110  grn_test_assert_context(context);
111  return table;
112 }
113 
114 static grn_obj *
115 column_create(const gchar *table_name, const gchar *name, grn_obj_flags flags,
116  const gchar *type_name, const gchar *sources)
117 {
118  grn_obj *column;
119  grn_obj *table = NULL, *type = NULL;
120 
121  if (table_name)
122  table = get_object(table_name);
123  if (type_name)
124  type = get_object(type_name);
125 
126  column = grn_column_create(context,
127  table,
128  name, strlen(name),
129  NULL,
130  flags | GRN_OBJ_PERSISTENT,
131  type);
132  grn_test_assert_context(context);
133  return column;
134 }
135 
136 #define ADD_DATA(label, expected, name, flags, \
137  key_type_name, value_type_name) \
138  gcut_add_datum(label, \
139  "expected", G_TYPE_STRING, expected, \
140  "name", G_TYPE_STRING, name, \
141  "flags", G_TYPE_UINT, flags, \
142  "key_type_name", G_TYPE_STRING, key_type_name, \
143  "value_type_name", G_TYPE_STRING, value_type_name, \
144  NULL)
145 
146 static void
147 data_hash_table_create(void)
148 {
149  ADD_DATA("hash",
150  "table_create Blog TABLE_HASH_KEY ShortText",
151  "Blog",
153  "ShortText",
154  NULL);
155  ADD_DATA("hash - without key",
156  "table_create Blog TABLE_HASH_KEY",
157  "Blog",
159  NULL,
160  NULL);
161  ADD_DATA("hash - key normalize",
162  "table_create Blog TABLE_HASH_KEY ShortText --normalizer NormalizerAuto",
163  "Blog",
165  "ShortText",
166  NULL);
167  ADD_DATA("hash - key normalize - value",
168  "table_create Blog TABLE_HASH_KEY ShortText Int32 --normalizer NormalizerAuto",
169  "Blog",
171  "ShortText",
172  "Int32");
173 }
174 
175 static void
176 data_patricia_trie_create(void)
177 {
178  ADD_DATA("patricia trie",
179  "table_create Blog TABLE_PAT_KEY ShortText",
180  "Blog",
182  "ShortText",
183  NULL);
184 }
185 
186 static void
187 data_double_array_trie_create(void)
188 {
189  ADD_DATA("double-array trie",
190  "table_create Blog TABLE_DAT_KEY ShortText",
191  "Blog",
193  "ShortText",
194  NULL);
195 }
196 
197 static void
198 data_array_create(void)
199 {
200  ADD_DATA("array",
201  "table_create Blog TABLE_NO_KEY",
202  "Blog",
204  NULL,
205  NULL);
206  ADD_DATA("array with value",
207  "table_create Blog TABLE_NO_KEY --value_type Int32",
208  "Blog",
210  NULL,
211  "Int32");
212 }
213 
214 void
216 {
217  data_hash_table_create();
218  data_patricia_trie_create();
219  data_double_array_trie_create();
220  data_array_create();
221 }
222 #undef ADD_DATA
223 
224 void
225 test_table_create(gconstpointer data)
226 {
227  table_create(gcut_data_get_string(data, "name"),
228  gcut_data_get_uint(data, "flags"),
229  gcut_data_get_string(data, "key_type_name"),
230  gcut_data_get_string(data, "value_type_name"));
231  cut_assert_equal_string(gcut_data_get_string(data, "expected"),
232  send_command("dump"));
233 }
234 
235 #define ADD_DATA(label, expected, table, name, flags, type_name, source)\
236  gcut_add_datum(label, \
237  "expected", G_TYPE_STRING, expected, \
238  "table", G_TYPE_STRING, table, \
239  "name", G_TYPE_STRING, name, \
240  "flags", G_TYPE_UINT, flags, \
241  "type_name", G_TYPE_STRING, type_name, \
242  "source", G_TYPE_STRING, source, \
243  NULL)
244 
245 void
247 {
248  ADD_DATA("scalar",
249  "column_create Blog body COLUMN_SCALAR Text",
250  "Blog",
251  "body",
253  "Text",
254  NULL);
255  ADD_DATA("vector",
256  "column_create Blog body COLUMN_VECTOR Text",
257  "Blog",
258  "body",
260  "Text",
261  NULL);
262 }
263 #undef ADD_DATA
264 
265 void
266 test_column_create(gconstpointer data)
267 {
268  const gchar *expected;
269  table_create("Blog", 0, NULL, NULL);
270  column_create(gcut_data_get_string(data, "table"),
271  gcut_data_get_string(data, "name"),
272  gcut_data_get_uint(data, "flags"),
273  gcut_data_get_string(data, "type_name"),
274  gcut_data_get_string(data, "source"));
275  expected = gcut_data_get_string(data, "expected");
276  cut_assert_equal_string(
277  cut_take_printf("table_create Blog TABLE_HASH_KEY\n%s", expected),
278  send_command("dump"));
279 }
280 
281 #define ADD_DATA(label, expected, type_name, element_type, \
282  first_element, second_element, third_element) do { \
283  gcut_add_datum(label, \
284  "expected", G_TYPE_STRING, expected, \
285  "type_name", G_TYPE_STRING, type_name, \
286  "first_element", element_type, first_element, \
287  "second_element", element_type, second_element, \
288  "third_element", element_type, third_element, \
289  NULL); \
290 } while(0)
291 
292 void
294 {
295  ADD_DATA("int32", "[-322,7,9270]", "Int32",
296  G_TYPE_INT, -322, 7, 9270);
297  ADD_DATA("float", "[0.5,12.5,-1.0]", "Float",
298  G_TYPE_DOUBLE, 0.5, 12.5, -1.0);
299  ADD_DATA("bool", "[true,false,true]", "Bool",
300  G_TYPE_BOOLEAN, TRUE, FALSE, TRUE);
301 }
302 
303 void
305 {
306  ADD_DATA("text", "[\"groonga\",\"is\",\"cool\"]", "Text",
307  G_TYPE_STRING, "groonga", "is", "cool");
308 }
309 
310 #undef ADD_DATA
311 
312 static grn_obj *
313 construct_elements(gconstpointer data)
314 {
315  const int n_of_elements = 3;
316  grn_obj *elements;
317  const gchar *type_name;
318 
319  elements = g_new0(grn_obj, n_of_elements);
320  type_name = gcut_data_get_string(data, "type_name");
321 
322 #define SET_VALUE(index, name) \
323  if (g_str_equal(type_name, "Int32")) { \
324  GRN_INT32_INIT(&elements[index], 0); \
325  GRN_INT32_SET(context, &elements[index], \
326  gcut_data_get_int(data, name)); \
327  } if (g_str_equal(type_name, "Float")) { \
328  GRN_FLOAT_INIT(&elements[index], 0); \
329  GRN_FLOAT_SET(context, &elements[index], \
330  gcut_data_get_double(data, name)); \
331  } if (g_str_equal(type_name, "Bool")) { \
332  GRN_BOOL_INIT(&elements[index], 0); \
333  GRN_BOOL_SET(context, &elements[index], \
334  gcut_data_get_boolean(data, name)); \
335  } if (g_str_equal(type_name, "Text")) { \
336  GRN_TEXT_INIT(&elements[index], 0); \
337  GRN_TEXT_SETS(context, &elements[index], \
338  gcut_data_get_string(data, name)); \
339  }
340 
341  SET_VALUE(0, "first_element");
342  SET_VALUE(1, "second_element");
343  SET_VALUE(2, "third_element");
344 
345 #undef SET_VALUE
346 
347  cut_take_memory(elements);
348 
349  return elements;
350 }
351 
352 void
353 test_uvector_column(gconstpointer data)
354 {
355  const gchar *expected;
356  grn_id id, type_id;
357  grn_obj uvector;
358  grn_obj *elements;
359  grn_obj *table, *column;
360  const gchar *type_name;
361  type_name = gcut_data_get_string(data, "type_name");
362  type_id = grn_obj_id(context, get_object(type_name));
363 
364  table = table_create("Table", GRN_OBJ_TABLE_NO_KEY, NULL, NULL);
365  grn_test_assert_context(context);
366  column = column_create("Table", "Column", GRN_OBJ_COLUMN_VECTOR,
367  type_name, NULL);
368  grn_test_assert_context(context);
369  id = grn_table_add(context, table, NULL, 0, NULL);
370  grn_test_assert_context(context);
371  cut_assert_equal_int(1, id);
372  elements = construct_elements(data);
373 
374  GRN_OBJ_INIT(&uvector, GRN_UVECTOR, 0, type_id);
375  grn_bulk_write(context, &uvector,
376  GRN_BULK_HEAD(&elements[0]), GRN_BULK_VSIZE(&elements[0]));
377  grn_bulk_write(context, &uvector,
378  GRN_BULK_HEAD(&elements[1]), GRN_BULK_VSIZE(&elements[1]));
379  grn_bulk_write(context, &uvector,
380  GRN_BULK_HEAD(&elements[2]), GRN_BULK_VSIZE(&elements[2]));
381  grn_obj_set_value(context, column, id, &uvector, GRN_OBJ_SET);
382 
383  expected = cut_take_printf("table_create Table TABLE_NO_KEY\n"
384  "column_create Table Column COLUMN_VECTOR %s\n"
385  "load --table Table\n"
386  "[\n"
387  "[\"_id\",\"Column\"],\n"
388  "[1,%s]\n"
389  "]",
390  type_name,
391  gcut_data_get_string(data, "expected"));
392  cut_assert_equal_string(expected, send_command("dump"));
393  GRN_OBJ_FIN(context, &uvector);
394 }
395 
396 void
397 test_vector_column(gconstpointer data)
398 {
399  const gchar *expected;
400  grn_id id, type_id;
401  grn_obj vector;
402  grn_obj *elements;
403  grn_obj *table, *column;
404  const gchar *type_name;
405  type_name = gcut_data_get_string(data, "type_name");
406  type_id = grn_obj_id(context, get_object(type_name));
407 
408  table = table_create("Table", GRN_OBJ_TABLE_NO_KEY, NULL, NULL);
409  grn_test_assert_context(context);
410  column = column_create("Table", "Column", GRN_OBJ_COLUMN_VECTOR,
411  type_name, NULL);
412  grn_test_assert_context(context);
413  id = grn_table_add(context, table, NULL, 0, NULL);
414  grn_test_assert_context(context);
415  cut_assert_equal_int(1, id);
416  elements = construct_elements(data);
417 
418  GRN_TEXT_INIT(&vector, GRN_OBJ_VECTOR);
419  grn_vector_add_element(context, &vector,
420  GRN_TEXT_VALUE(&elements[0]),
421  GRN_TEXT_LEN(&elements[0]), 0, type_id);
422  grn_vector_add_element(context, &vector,
423  GRN_TEXT_VALUE(&elements[1]),
424  GRN_TEXT_LEN(&elements[1]), 0, type_id);
425  grn_vector_add_element(context, &vector,
426  GRN_TEXT_VALUE(&elements[2]),
427  GRN_TEXT_LEN(&elements[2]), 0, type_id);
428  grn_obj_set_value(context, column, id, &vector, GRN_OBJ_SET);
429 
430  expected = cut_take_printf("table_create Table TABLE_NO_KEY\n"
431  "column_create Table Column COLUMN_VECTOR %s\n"
432  "load --table Table\n"
433  "[\n"
434  "[\"_id\",\"Column\"],\n"
435  "[1,%s]\n"
436  "]",
437  type_name,
438  gcut_data_get_string(data, "expected"));
439  cut_assert_equal_string(expected, send_command("dump"));
440  GRN_OBJ_FIN(context, &vector);
441 }
442 
443 void
445 {
446  grn_obj *table;
447  grn_id id, expected_id = 1;
448  const gchar *keys[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
449  int i, n_keys = sizeof(keys) / sizeof(keys[0]);
450 
451  table = table_create("Weekdays", GRN_OBJ_TABLE_HASH_KEY, "ShortText", NULL);
452  grn_test_assert_context(context);
453 
454  for (i = 0; i < n_keys; ++i) {
455  id = grn_table_add(context, table, keys[i], strlen(keys[i]), NULL);
456  cut_assert_equal_int(expected_id++, id);
457  grn_test_assert_context(context);
458  }
459 
460  grn_table_delete_by_id(context, table, 3);
461  grn_table_delete_by_id(context, table, 6);
462 
463  cut_assert_equal_string("table_create Weekdays TABLE_HASH_KEY ShortText\n"
464  "load --table Weekdays\n"
465  "[\n"
466  "[\"_key\"],\n"
467  "[\"Sun\"],\n"
468  "[\"Mon\"],\n"
469  "[\"Wed\"],\n"
470  "[\"Thu\"],\n"
471  "[\"Sat\"]\n"
472  "]",
473  send_command("dump"));
474 }
475 
476 void
478 {
479  assert_send_command("table_create Users TABLE_HASH_KEY ShortText");
480  assert_send_command("table_create Initials TABLE_PAT_KEY ShortText");
481  assert_send_command("column_create Users initial COLUMN_SCALAR Initials");
482 
483  cut_assert_equal_string(
484  "2",
485  send_command("load --table Initials --columns '_key'\n"
486  "[\n"
487  " [\"U\"],\n"
488  " [\"ア\"]\n"
489  "]"));
490  cut_assert_equal_string(
491  "1",
492  send_command("load --table Users --columns '_key'\n"
493  "[\n"
494  " [\"mori\"]\n"
495  "]"));
496 
497  cut_assert_equal_string("table_create Users TABLE_HASH_KEY ShortText\n"
498  "table_create Initials TABLE_PAT_KEY ShortText\n"
499  "column_create Users initial COLUMN_SCALAR Initials\n"
500  "load --table Users\n"
501  "[\n"
502  "[\"_key\",\"initial\"],\n"
503  "[\"mori\",\"\"]\n"
504  "]\n"
505  "load --table Initials\n"
506  "[\n"
507  "[\"_key\"],\n"
508  "[\"U\"],\n"
509  "[\"ア\"]\n"
510  "]",
511  send_command("dump"));
512 }
513 
514 void
516 {
517  const gchar *commands =
518  "table_create users TABLE_HASH_KEY Int32\n"
519  "column_create users name COLUMN_SCALAR ShortText\n"
520  "table_create comments TABLE_PAT_KEY ShortText\n"
521  "column_create comments text COLUMN_SCALAR ShortText\n"
522  "column_create comments author COLUMN_VECTOR users\n"
523  "load --table users\n"
524  "[\n"
525  "[\"_key\",\"name\"],\n"
526  "[1000,\"ryoqun\"],\n"
527  "[1001,\"hayamiz\"]\n"
528  "]\n"
529  "load --table comments\n"
530  "[\n"
531  "[\"_key\",\"author\",\"text\"],\n"
532  "[\"groonga\",[1000,1001],\"it is fast\"]\n"
533  "]";
534 
535  assert_send_commands(commands);
536  cut_assert_equal_string(commands, send_command("dump"));
537 }
538 
539 void
541 {
542  const gchar *define_schema_commands =
543  "table_create users TABLE_HASH_KEY Int32\n"
544  "column_create users name COLUMN_SCALAR ShortText\n"
545  "table_create comments TABLE_PAT_KEY ShortText\n"
546  "column_create comments text COLUMN_SCALAR ShortText\n"
547  "table_create sites TABLE_NO_KEY\n"
548  "column_create sites url COLUMN_SCALAR ShortText\n"
549  "column_create comments author COLUMN_VECTOR users";
550  const gchar *load_users_commands =
551  "load --table users\n"
552  "[\n"
553  "[\"_key\",\"name\"],\n"
554  "[1000,\"ryoqun\"],\n"
555  "[1001,\"hayamiz\"]\n"
556  "]";
557  const gchar *load_comments_commands =
558  "load --table comments\n"
559  "[\n"
560  "[\"_key\",\"text\",\"author\"],\n"
561  "[\"groonga\",\"it is fast\",[1000,1001]]\n"
562  "]";
563  const gchar *load_sites_commands =
564  "load --table sites\n"
565  "[\n"
566  "[\"_id\",\"url\"],\n"
567  "[1,\"http://groonga.org/\"],\n"
568  "[2,\"http://qwik.jp/senna/\"]\n"
569  "]";
570 
571  assert_send_commands(define_schema_commands);
572  assert_send_commands(load_users_commands);
573  assert_send_commands(load_comments_commands);
574  assert_send_commands(load_sites_commands);
575  cut_assert_equal_string(cut_take_printf("%s\n"
576  "%s\n"
577  "%s",
578  define_schema_commands,
579  load_users_commands,
580  load_sites_commands),
581  send_command("dump --tables users,sites"));
582 }