1/* -*- c-basic-offset: 2 -*- */
2/*
3 Copyright(C) 2009-2016 Brazil
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License version 2.1 as published by the Free Software Foundation.
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#pragma once
20
21#include "grn.h"
22#include "grn_ctx.h"
23#include "grn_store.h"
24#include "grn_rset.h"
25
26#include <groonga/command.h>
27#include <groonga/token_filter.h>
28#include <groonga/scorer.h>
29
30#include <float.h>
31
32#ifdef __cplusplus
33extern "C" {
34#endif
35
36#define GRN_DB_DELIMITER '.'
37#define GRN_DB_PSEUDO_COLUMN_PREFIX '_'
38
39#define GRN_N_RESERVED_TYPES 256
40
41typedef struct _grn_db grn_db;
42typedef struct _grn_proc grn_proc;
43
44struct _grn_db {
45 grn_db_obj obj;
46 grn_obj *keys;
47 grn_ja *specs;
48 grn_hash *config;
49 grn_tiny_array values;
50 grn_critical_section lock;
51};
52
53#define GRN_SERIALIZED_SPEC_INDEX_SPEC 0
54#define GRN_SERIALIZED_SPEC_INDEX_PATH 1
55#define GRN_SERIALIZED_SPEC_INDEX_SOURCE 2
56#define GRN_SERIALIZED_SPEC_INDEX_HOOK 3
57#define GRN_SERIALIZED_SPEC_INDEX_TOKEN_FILTERS 4
58#define GRN_SERIALIZED_SPEC_INDEX_EXPR 4
59
60typedef struct {
61 grn_obj_header header;
62 grn_id range;
63} grn_obj_spec;
64
65grn_bool grn_db_spec_unpack(grn_ctx *ctx,
66 grn_id id,
67 void *encoded_spec,
68 uint32_t encoded_spec_size,
69 grn_obj_spec **spec,
70 grn_obj *decoded_spec,
71 const char *error_message_tag);
72
73#define GRN_DB_SPEC_EACH_BEGIN(ctx, cursor, id, spec) do { \
74 grn_obj *db = grn_ctx_db((ctx)); \
75 grn_db *db_raw = (grn_db *)db; \
76 grn_obj decoded_spec; \
77 grn_io_win iw; \
78 grn_bool iw_need_unref = GRN_FALSE; \
79 GRN_OBJ_INIT(&decoded_spec, GRN_VECTOR, 0, GRN_DB_TEXT); \
80 GRN_TABLE_EACH_BEGIN((ctx), db, cursor, id) { \
81 void *encoded_spec; \
82 uint32_t encoded_spec_size; \
83 grn_bool success; \
84 grn_obj_spec *spec; \
85 \
86 if (iw_need_unref) { \
87 grn_ja_unref(ctx, &iw); \
88 iw_need_unref = GRN_FALSE; \
89 } \
90 encoded_spec = grn_ja_ref((ctx), \
91 db_raw->specs, \
92 id, \
93 &iw, \
94 &encoded_spec_size); \
95 if (!encoded_spec) { \
96 continue; \
97 } \
98 iw_need_unref = GRN_TRUE; \
99 \
100 GRN_BULK_REWIND(&decoded_spec); \
101 success = grn_db_spec_unpack(ctx, \
102 id, \
103 encoded_spec, \
104 encoded_spec_size, \
105 &spec, \
106 &decoded_spec, \
107 __FUNCTION__); \
108 if (!success) { \
109 continue; \
110 } \
111
112#define GRN_DB_SPEC_EACH_END(ctx, cursor) \
113 } GRN_TABLE_EACH_END(ctx, cursor); \
114 if (iw_need_unref) { \
115 grn_ja_unref(ctx, &iw); \
116 } \
117 GRN_OBJ_FIN((ctx), &decoded_spec); \
118} while(GRN_FALSE)
119
120void grn_db_init_from_env(void);
121
122GRN_API grn_rc grn_db_close(grn_ctx *ctx, grn_obj *db);
123
124grn_obj *grn_db_keys(grn_obj *s);
125
126void grn_db_generate_pathname(grn_ctx *ctx,
127 grn_obj *db,
128 grn_id id,
129 char *buffer);
130
131grn_rc _grn_table_delete_by_id(grn_ctx *ctx, grn_obj *table, grn_id id,
132 grn_table_delete_optarg *optarg);
133
134grn_id grn_table_get_v(grn_ctx *ctx, grn_obj *table, const void *key, int key_size,
135 void **value);
136grn_id grn_table_add_v(grn_ctx *ctx, grn_obj *table, const void *key, int key_size,
137 void **value, int *added);
138grn_id grn_table_add_by_key(grn_ctx *ctx,
139 grn_obj *table,
140 grn_obj *key,
141 int *added);
142GRN_API grn_rc grn_table_get_info(grn_ctx *ctx, grn_obj *table, grn_table_flags *flags,
143 grn_encoding *encoding, grn_obj **tokenizer,
144 grn_obj **normalizer,
145 grn_obj **token_filters);
146const char *_grn_table_key(grn_ctx *ctx, grn_obj *table, grn_id id, uint32_t *key_size);
147
148grn_rc grn_table_search(grn_ctx *ctx, grn_obj *table,
149 const void *key, uint32_t key_size,
150 grn_operator mode, grn_obj *res, grn_operator op);
151
152grn_rc grn_table_fuzzy_search(grn_ctx *ctx, grn_obj *table,
153 const void *key, uint32_t key_size,
154 grn_fuzzy_search_optarg *args, grn_obj *res, grn_operator op);
155
156grn_id grn_table_next(grn_ctx *ctx, grn_obj *table, grn_id id);
157
158int grn_table_get_key2(grn_ctx *ctx, grn_obj *table, grn_id id, grn_obj *bulk);
159
160grn_table_cursor *grn_table_cursor_open_by_id(grn_ctx *ctx, grn_obj *table,
161 grn_id min, grn_id max, int flags);
162
163void grn_table_add_subrec(grn_obj *table, grn_rset_recinfo *ri, double score,
164 grn_rset_posinfo *pi, int dir);
165
166grn_obj *grn_obj_graft(grn_ctx *ctx, grn_obj *obj);
167
168grn_rc grn_column_name_(grn_ctx *ctx, grn_obj *obj, grn_obj *buf);
169
170
171typedef enum {
172 PROC_INIT = 0,
173 PROC_NEXT,
174 PROC_FIN
175} grn_proc_phase;
176
177struct _grn_type {
178 grn_db_obj obj;
179};
180
181#define GRN_TYPE_SIZE(type) ((type)->range)
182
183#define GRN_TABLE_SORT_GEO (0x02<<0)
184
185#define GRN_OBJ_TMP_OBJECT 0x80000000
186#define GRN_OBJ_TMP_COLUMN 0x40000000
187
188#define GRN_DB_OBJP(obj) \
189 (obj &&\
190 ((GRN_SNIP == ((grn_db_obj *)obj)->header.type) ||\
191 ((GRN_CURSOR_TABLE_HASH_KEY <= ((grn_db_obj *)obj)->header.type) &&\
192 (((grn_db_obj *)obj)->header.type <= GRN_COLUMN_INDEX))))
193
194#define GRN_OBJ_TABLEP(obj) \
195 (obj &&\
196 (GRN_TABLE_HASH_KEY <= ((grn_db_obj *)obj)->header.type) &&\
197 (((grn_db_obj *)obj)->header.type <= GRN_DB))
198
199#define GRN_OBJ_INDEX_COLUMNP(obj) \
200 (obj &&\
201 DB_OBJ(obj)->header.type == GRN_COLUMN_INDEX)
202
203#define GRN_OBJ_VECTOR_COLUMNP(obj) \
204 (obj &&\
205 DB_OBJ(obj)->header.type == GRN_COLUMN_VAR_SIZE &&\
206 (DB_OBJ(obj)->header.flags & GRN_OBJ_COLUMN_TYPE_MASK) == GRN_OBJ_COLUMN_VECTOR)
207
208#define GRN_OBJ_WEIGHT_VECTOR_COLUMNP(obj) \
209 (GRN_OBJ_VECTOR_COLUMNP(obj) &&\
210 (DB_OBJ(obj)->header.flags & GRN_OBJ_WITH_WEIGHT))
211
212struct _grn_hook {
213 grn_hook *next;
214 grn_proc *proc;
215 uint32_t hld_size;
216};
217
218typedef struct _grn_proc_ctx grn_proc_ctx;
219
220struct _grn_proc_ctx {
221 grn_user_data user_data;
222 grn_proc *proc;
223 grn_obj *caller;
224 // grn_obj *obj;
225 grn_hook *hooks;
226 grn_hook *currh;
227 grn_proc_phase phase;
228 unsigned short nargs;
229 unsigned short offset;
230 grn_user_data data[16];
231};
232
233struct _grn_proc {
234 grn_db_obj obj;
235 grn_obj name_buf;
236 grn_expr_var *vars;
237 uint32_t nvars;
238 /* -- compatible with grn_expr -- */
239 grn_proc_type type;
240 grn_proc_func *funcs[3];
241
242 union {
243 struct {
244 grn_selector_func *selector;
245 grn_operator selector_op;
246 grn_bool is_stable;
247 } function;
248 struct {
249 grn_command_run_func *run;
250 } command;
251 struct {
252 grn_token_filter_init_func *init;
253 grn_token_filter_filter_func *filter;
254 grn_token_filter_fin_func *fin;
255 } token_filter;
256 struct {
257 grn_scorer_score_func *score;
258 } scorer;
259 grn_window_function_func *window_function;
260 } callbacks;
261
262 void *user_data;
263
264 grn_id module;
265 // uint32_t nargs;
266 // uint32_t nresults;
267 // grn_obj results[16];
268};
269
270#define GRN_PROC_GET_VARS() (grn_proc_get_vars(ctx, user_data))
271#define GRN_PROC_GET_VAR(name) (grn_proc_get_var(ctx, user_data, name, strlen(name)))
272#define GRN_PROC_GET_VAR_BY_OFFSET(offset) (grn_proc_get_var_by_offset(ctx, user_data, offset))
273#define GRN_PROC_GET_OR_ADD_VAR(name) (grn_proc_get_or_add_var(ctx, user_data, name, strlen(name)))
274#define GRN_PROC_ALLOC(domain, flags) (grn_proc_alloc(ctx, user_data, domain, flags))
275
276grn_obj *grn_proc_get_vars(grn_ctx *ctx, grn_user_data *user_data);
277
278grn_obj *grn_proc_get_var(grn_ctx *ctx, grn_user_data *user_data,
279 const char *name, unsigned int name_size);
280
281GRN_API grn_obj *grn_proc_get_var_by_offset(grn_ctx *ctx, grn_user_data *user_data,
282 unsigned int offset);
283GRN_API grn_obj *grn_proc_get_or_add_var(grn_ctx *ctx, grn_user_data *user_data,
284 const char *name, unsigned int name_size);
285
286GRN_API grn_obj *grn_proc_alloc(grn_ctx *ctx, grn_user_data *user_data,
287 grn_id domain, unsigned char flags);
288
289GRN_API grn_rc grn_proc_call(grn_ctx *ctx, grn_obj *proc,
290 int nargs, grn_obj *caller);
291
292grn_obj *grn_expr_get_or_add_var(grn_ctx *ctx, grn_obj *expr,
293 const char *name, unsigned int name_size);
294
295
296typedef struct _grn_accessor grn_accessor;
297
298struct _grn_accessor {
299 grn_obj_header header;
300 grn_id range;
301 /* -- compatible with grn_db_obj -- */
302 uint8_t action;
303 int offset;
304 grn_obj *obj;
305 grn_accessor *next;
306};
307
308enum {
309 GRN_ACCESSOR_VOID = 0,
310 GRN_ACCESSOR_GET_ID,
311 GRN_ACCESSOR_GET_KEY,
312 GRN_ACCESSOR_GET_VALUE,
313 GRN_ACCESSOR_GET_SCORE,
314 GRN_ACCESSOR_GET_NSUBRECS,
315 GRN_ACCESSOR_GET_MAX,
316 GRN_ACCESSOR_GET_MIN,
317 GRN_ACCESSOR_GET_SUM,
318 GRN_ACCESSOR_GET_AVG,
319 GRN_ACCESSOR_GET_COLUMN_VALUE,
320 GRN_ACCESSOR_GET_DB_OBJ,
321 GRN_ACCESSOR_LOOKUP,
322 GRN_ACCESSOR_FUNCALL
323};
324
325#define DB_OBJ(obj) ((grn_db_obj *)obj)
326
327GRN_API const char *grn_obj_get_value_(grn_ctx *ctx, grn_obj *obj, grn_id id, uint32_t *size);
328
329/* vector */
330
331/*
332typedef struct _grn_vector grn_vector;
333
334struct _grn_vector {
335 grn_obj str;
336 uint32_t *offsets;
337 int n_entries;
338};
339
340const char *grn_vector_fetch(grn_ctx *ctx, grn_obj *vector, int i, unsigned int *size);
341int grn_vector_delimit(grn_ctx *ctx, grn_obj *vector);
342int grn_vector_size(grn_ctx *ctx, grn_obj *vector);
343*/
344
345grn_rc grn_vector_delimit(grn_ctx *ctx, grn_obj *v, unsigned int weight, grn_id domain);
346grn_rc grn_vector_decode(grn_ctx *ctx, grn_obj *v, const char *data, uint32_t data_size);
347
348
349grn_rc grn_db_init_builtin_types(grn_ctx *ctx);
350
351/* flag value used for grn_obj.header.flags */
352
353#define GRN_OBJ_CUSTOM_NAME (0x01<<12) /* db_obj which has custom name */
354
355#define GRN_OBJ_RESOLVE(ctx,obj) \
356 (((obj)->header.type != GRN_PTR)\
357 ? (obj)\
358 : GRN_PTR_VALUE(obj)\
359 ? GRN_PTR_VALUE(obj)\
360 : grn_ctx_at((ctx), (obj)->header.domain))
361
362/* expr */
363
364typedef struct _grn_expr grn_expr;
365
366#define GRN_EXPR_CODE_RELATIONAL_EXPRESSION (0x01)
367
368typedef struct {
369 grn_obj *value;
370 int32_t nargs;
371 grn_operator op;
372 uint8_t flags;
373 int32_t modify;
374} grn_expr_code;
375
376#define GRN_EXPR_CONST_BLK_SIZE GRN_STACK_SIZE
377
378struct _grn_expr {
379 grn_db_obj obj;
380 grn_obj name_buf;
381 grn_expr_var *vars;
382 uint32_t nvars;
383 /* -- compatible with grn_proc -- */
384
385 uint16_t cacheable;
386 uint16_t taintable;
387 grn_obj **const_blks;
388 grn_obj *values;
389 grn_expr_code *codes;
390 uint32_t nconsts;
391 uint32_t values_curr;
392 uint32_t values_tail;
393 uint32_t values_size;
394 uint32_t codes_curr;
395 uint32_t codes_size;
396
397 grn_obj objs;
398 grn_obj dfi;
399 grn_expr_code *code0;
400};
401
402grn_rc grn_expr_parser_close(grn_ctx *ctx);
403
404/**
405 * grn_table_open:
406 * @name: The table name to be opened. `NULL` means anonymous table.
407 * @path: The path of the table to be opened.
408 *
409 * Opens an existing table. The table is associated with @name in DB
410 * that is used by @ctx. grn_ctx_get() is better rather than this
411 * function when you want to open a permanent named table that is
412 * registered in DB.
413 **/
414GRN_API grn_obj *grn_table_open(grn_ctx *ctx,
415 const char *name, unsigned int name_size,
416 const char *path);
417
418/**
419 * grn_column_open:
420 * @table: The table for the opened column.
421 * @name: The column name to be opened.
422 * @path: The path of the column to be opened.
423 * @type: The type of the column value.
424 *
425 * Opens an existing permanent column. The column is associated with
426 * @name in @table. grn_ctx_get() is better rather than this function
427 * when you want to open a column of an permanent table in DB.
428 **/
429grn_obj *grn_column_open(grn_ctx *ctx, grn_obj *table,
430 const char *name, unsigned int name_size,
431 const char *path, grn_obj *type);
432
433/**
434 * grn_obj_path_rename:
435 * @old_path: The current file path.
436 * @new_path: The new file path.
437 *
438 * It renames object's path that is stored in @old_path to @new_path.
439 **/
440grn_rc grn_obj_path_rename(grn_ctx *ctx, const char *old_path, const char *new_path);
441
442grn_rc grn_db_check_name(grn_ctx *ctx, const char *name, unsigned int name_size);
443#define GRN_DB_CHECK_NAME_ERR(error_context, name, name_size) \
444 ERR(GRN_INVALID_ARGUMENT,\
445 "%s name can't start with '%c' and contains only 0-9, A-Z, a-z, #, @, - or _: <%.*s>",\
446 error_context, GRN_DB_PSEUDO_COLUMN_PREFIX, name_size, name)
447
448#define GRN_DB_P(s) ((s) && ((grn_db *)s)->obj.header.type == GRN_DB)
449#define GRN_DB_PERSISTENT_P(s) (((grn_db *)s)->specs)
450
451#define GRN_OBJ_GET_VALUE_IMD (0xffffffffU)
452
453grn_rc grn_db_obj_init(grn_ctx *ctx, grn_obj *db, grn_id id, grn_db_obj *obj);
454
455#define GRN_ACCESSORP(obj) \
456 ((obj) && (((grn_obj *)(obj))->header.type == GRN_ACCESSOR))
457
458grn_id grn_obj_register(grn_ctx *ctx, grn_obj *db, const char *name, unsigned int name_size);
459int grn_obj_is_persistent(grn_ctx *ctx, grn_obj *obj);
460void grn_obj_spec_save(grn_ctx *ctx, grn_db_obj *obj);
461
462grn_rc grn_obj_reinit_for(grn_ctx *ctx, grn_obj *obj, grn_obj *domain_obj);
463
464void grn_expr_pack(grn_ctx *ctx, grn_obj *buf, grn_obj *expr);
465GRN_API grn_rc grn_expr_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *expr);
466grn_hash *grn_expr_get_vars(grn_ctx *ctx, grn_obj *expr, unsigned int *nvars);
467grn_obj *grn_expr_open(grn_ctx *ctx, grn_obj_spec *spec, const uint8_t *p, const uint8_t *pe);
468
469GRN_API grn_rc grn_table_group_with_range_gap(grn_ctx *ctx, grn_obj *table,
470 grn_table_sort_key *group_key,
471 grn_obj *result_set,
472 uint32_t range_gap);
473
474GRN_API grn_rc grn_column_filter(grn_ctx *ctx, grn_obj *column,
475 grn_operator op,
476 grn_obj *value, grn_obj *result_set,
477 grn_operator set_op);
478
479typedef struct {
480 grn_id target;
481 unsigned int section;
482} grn_obj_default_set_value_hook_data;
483
484grn_obj *grn_obj_default_set_value_hook(grn_ctx *ctx,
485 int nargs,
486 grn_obj **args,
487 grn_user_data *user_data);
488
489grn_rc grn_pvector_fin(grn_ctx *ctx, grn_obj *obj);
490
491#ifdef __cplusplus
492}
493#endif
494