Groonga 3.0.9 Source Code Document
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
test-expr-query.c
Go to the documentation of this file.
1 /* -*- c-basic-offset: 2; coding: utf-8 -*- */
2 /* Copyright(C) 2009 Brazil
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Lesser General Public
6  License as published by the Free Software Foundation; either
7  version 2.1 of the License, or (at your option) any later version.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Lesser General Public License for more details.
13 
14  You should have received a copy of the GNU Lesser General Public
15  License along with this library; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
19 #include "db.h"
20 #include <stdio.h>
21 #include <time.h>
22 
23 #include <gcutter.h>
24 
25 #include "../lib/grn-assertions.h"
26 
27 static gchar *tmp_directory;
28 static gchar *path;
29 static grn_ctx context;
30 static grn_obj *database;
31 static grn_obj *res, *expr;
32 static grn_obj textbuf, intbuf, floatbuf, timebuf;
33 
34 void data_allow_column(void);
35 void test_allow_column(gconstpointer data);
36 void data_allow_update(void);
37 void test_allow_update(gconstpointer data);
38 
39 void
41 {
42  tmp_directory = g_build_filename(grn_test_get_tmp_dir(),
43  "test-expr-query",
44  NULL);
45 }
46 
47 void
49 {
50  g_free(tmp_directory);
51 }
52 
53 void
54 cut_setup(void)
55 {
56  cut_remove_path(tmp_directory, NULL);
57  g_mkdir_with_parents(tmp_directory, 0700);
58  path = g_build_filename(tmp_directory, "text-expr", NULL);
59  grn_ctx_init(&context, 0);
60  database = grn_db_create(&context, path, NULL);
61 
62  expr = NULL;
63  res = NULL;
64 
65  GRN_TEXT_INIT(&textbuf, 0);
66  GRN_UINT32_INIT(&intbuf, 0);
67  GRN_FLOAT_INIT(&floatbuf, 0);
68  GRN_TIME_INIT(&timebuf, 0);
69 }
70 
71 void
73 {
74  grn_obj_close(&context, &textbuf);
75  grn_obj_close(&context, &intbuf);
76  grn_obj_close(&context, &floatbuf);
77  grn_obj_close(&context, &timebuf);
78 
79  if (res)
80  grn_obj_close(&context, res);
81  if (expr)
82  grn_obj_close(&context, expr);
83 
84  grn_db_close(&context, database);
85  grn_ctx_fin(&context);
86  cut_remove_path(tmp_directory, NULL);
87  g_free(path);
88 }
89 
90 #define PARSE(expr, str, flags) \
91  grn_test_assert(grn_expr_parse(&context, (expr), (str), strlen(str), \
92  body, GRN_OP_MATCH, GRN_OP_AND, flags))
93 
94 static grn_obj *docs, *terms, *body, *created_at, *index_body;
95 static grn_obj *size, *size_in_string, *size_in_float;
96 
97 static void
98 insert_document(const gchar *body_content)
99 {
100  uint32_t s = (uint32_t)strlen(body_content);
101  grn_id docid = grn_table_add(&context, docs, NULL, 0, NULL);
102  const gchar *size_string;
103  struct tm time;
104 
105  GRN_TEXT_SET(&context, &textbuf, body_content, s);
106  grn_test_assert(grn_obj_set_value(&context, body, docid, &textbuf,
107  GRN_OBJ_SET));
108 
109  GRN_UINT32_SET(&context, &intbuf, s);
110  grn_test_assert(grn_obj_set_value(&context, size, docid, &intbuf,
111  GRN_OBJ_SET));
112 
113  size_string = cut_take_printf("%u", s);
114  GRN_TEXT_SET(&context, &textbuf, size_string, strlen(size_string));
115  grn_test_assert(grn_obj_set_value(&context, size_in_string, docid, &textbuf,
116  GRN_OBJ_SET));
117 
118  GRN_FLOAT_SET(&context, &floatbuf, s);
119  grn_test_assert(grn_obj_set_value(&context, size_in_float, docid, &floatbuf,
120  GRN_OBJ_SET));
121 
122  time.tm_sec = s;
123  time.tm_min = 16;
124  time.tm_hour = 15;
125  time.tm_mday = 2;
126  time.tm_mon = 11;
127  time.tm_year = 109;
128  time.tm_wday = 3;
129  time.tm_yday = 336;
130  time.tm_isdst = 0;
131  GRN_TIME_SET(&context, &timebuf, GRN_TIME_PACK(mktime(&time), 0));
132  grn_test_assert(grn_obj_set_value(&context, created_at, docid, &timebuf,
133  GRN_OBJ_SET));
134 }
135 
136 #define INSERT_DOCUMENT(body) \
137  cut_trace(insert_document(body))
138 
139 static void
140 create_documents_table(void)
141 {
142  docs = grn_table_create(&context, "docs", 4, NULL,
144  cut_assert_not_null(docs);
145 
146  size = grn_column_create(&context, docs, "size", 4, NULL,
148  grn_ctx_at(&context, GRN_DB_UINT32));
149  cut_assert_not_null(size);
150 
151  size_in_string = grn_column_create(&context, docs, "size_in_string", 14, NULL,
153  grn_ctx_at(&context, GRN_DB_TEXT));
154  cut_assert_not_null(size_in_string);
155 
156  size_in_float = grn_column_create(&context, docs, "size_in_float", 13, NULL,
158  grn_ctx_at(&context, GRN_DB_FLOAT));
159  cut_assert_not_null(size_in_float);
160 
161  created_at = grn_column_create(&context, docs, "created_at", 10, NULL,
163  grn_ctx_at(&context, GRN_DB_TIME));
164  cut_assert_not_null(created_at);
165 
166  body = grn_column_create(&context, docs, "body", 4, NULL,
168  grn_ctx_at(&context, GRN_DB_TEXT));
169  cut_assert_not_null(body);
170 }
171 
172 static void
173 create_terms_table(void)
174 {
175  terms = grn_table_create(&context, "terms", 5, NULL,
177  grn_ctx_at(&context, GRN_DB_SHORT_TEXT), NULL);
178  cut_assert_not_null(terms);
180  grn_ctx_at(&context, GRN_DB_BIGRAM)));
181 
182  index_body = grn_column_create(&context, terms, "docs_body", 4, NULL,
184  docs);
185  cut_assert_not_null(index_body);
186 
187  GRN_UINT32_SET(&context, &intbuf, grn_obj_id(&context, body));
188  grn_obj_set_info(&context, index_body, GRN_INFO_SOURCE, &intbuf);
189 }
190 
191 static void
192 insert_data(void)
193 {
194  INSERT_DOCUMENT("hoge");
195  INSERT_DOCUMENT("fuga fuga");
196  INSERT_DOCUMENT("moge moge moge");
197  INSERT_DOCUMENT("hoge hoge");
198  INSERT_DOCUMENT("hoge fuga fuga");
199  INSERT_DOCUMENT("hoge moge moge moge");
200  INSERT_DOCUMENT("moge hoge hoge");
201  INSERT_DOCUMENT("moge hoge fuga fuga");
202  INSERT_DOCUMENT("moge hoge moge moge moge");
203  INSERT_DOCUMENT("poyo moge hoge moge moge moge");
204  INSERT_DOCUMENT("=poyo_moge_hoge_moge_moge_moge");
205 }
206 
207 static void
208 prepare_data(void)
209 {
210  create_documents_table();
211  create_terms_table();
212  insert_data();
213 }
214 
215 void
217 {
218 #define ADD_DATUM(label, expected_keys, query) \
219  gcut_add_datum(label, \
220  "expected_keys", G_TYPE_POINTER, expected_keys, \
221  gcut_list_string_free, \
222  "query", G_TYPE_STRING, query, \
223  NULL)
224 
225  ADD_DATUM("empty",
226  gcut_list_string_new("fuga fuga", "hoge hoge", NULL),
227  "size:9");
228  ADD_DATUM("= - without ALLOW_UPDATE",
229  gcut_list_string_new("=poyo_moge_hoge_moge_moge_moge", NULL),
230  "body:=poyo_moge_hoge_moge_moge_moge");
231 
232 #undef ADD_DATUM
233 }
234 
235 void
236 test_allow_column(gconstpointer data)
237 {
238  grn_obj *v;
239 
240  prepare_data();
241 
242  expr = grn_expr_create(&context, NULL, 0);
243  cut_assert_not_null(expr);
244  v = grn_expr_add_var(&context, expr, NULL, 0);
245  cut_assert_not_null(v);
246  GRN_RECORD_INIT(v, 0, grn_obj_id(&context, docs));
247  PARSE(expr,
248  gcut_data_get_string(data, "query"),
250 
251  res = grn_table_select(&context, docs, expr, NULL, GRN_OP_OR);
252  cut_assert_not_null(res);
253  grn_test_assert_select(&context,
254  gcut_data_get_pointer(data, "expected_keys"),
255  res,
256  "body");
257 }
258 
259 void
261 {
262 #define ADD_DATUM(label, expected_keys, query) \
263  gcut_add_datum(label, \
264  "expected_keys", G_TYPE_POINTER, expected_keys, \
265  gcut_list_string_free, \
266  "query", G_TYPE_STRING, query, \
267  NULL)
268 
269  ADD_DATUM("=",
270  gcut_list_string_new("fuga fuga", "hoge", "hoge hoge", NULL),
271  "size:<=9 size:=9 size:9");
272 
273 #undef ADD_DATUM
274 }
275 
276 void
277 test_allow_update(gconstpointer data)
278 {
279  grn_obj *v;
280 
281  prepare_data();
282 
283  expr = grn_expr_create(&context, NULL, 0);
284  cut_assert_not_null(expr);
285  v = grn_expr_add_var(&context, expr, NULL, 0);
286  cut_assert_not_null(v);
287  GRN_RECORD_INIT(v, 0, grn_obj_id(&context, docs));
288  PARSE(expr,
289  gcut_data_get_string(data, "query"),
291 
292  res = grn_table_select(&context, docs, expr, NULL, GRN_OP_OR);
293  cut_assert_not_null(res);
294  grn_test_assert_select(&context,
295  gcut_data_get_pointer(data, "expected_keys"),
296  res,
297  "body");
298 }