GHashTable * grn_test_pat_get_pairs(grn_ctx *context, grn_obj *patricia_trie) { GList *node, *ordered_pairs; GHashTable *pairs; grn_table_cursor *cursor; cursor = grn_table_cursor_open(context, patricia_trie, NULL, 0, NULL, 0, 0, -1, GRN_CURSOR_ASCENDING); ordered_pairs = grn_test_pat_cursor_get_pairs(context, cursor); grn_table_cursor_close(context, cursor); pairs = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); for (node = ordered_pairs; node; node = g_list_next(node)) { gchar *key, *value; key = node->data; node = g_list_next(node); if (!node) break; value = node->data; g_hash_table_insert(pairs, key, value); } g_list_free(ordered_pairs); return pairs; }
static void rb_grn_database_mark_existing_ruby_object (grn_ctx *context, grn_obj *database) { grn_table_cursor *cursor; grn_id id; cursor = grn_table_cursor_open(context, database, NULL, 0, NULL, 0, 0, -1, GRN_CURSOR_ASCENDING); if (!cursor) return; while ((id = grn_table_cursor_next(context, cursor)) != GRN_ID_NIL) { grn_obj *object; grn_user_data *user_data; RbGrnObject *rb_grn_object; object = grn_ctx_at(context, id); if (!object) continue; user_data = grn_obj_user_data(context, object); if (!user_data) continue; rb_grn_object = RB_GRN_OBJECT(user_data->ptr); if (!rb_grn_object) continue; rb_gc_mark(rb_grn_object->self); } grn_table_cursor_close(context, cursor); }
const GList * grn_test_table_collect_string(grn_ctx *context, grn_obj *table, const gchar *text_column_name) { GList *records = NULL; grn_table_cursor *cursor; grn_id id; grn_obj *text_column; grn_obj value; cursor = grn_table_cursor_open(context, table, NULL, 0, NULL, 0, 0, -1, GRN_CURSOR_ASCENDING); grn_test_assert_context(context); text_column = grn_obj_column(context, table, text_column_name, strlen(text_column_name)); GRN_TEXT_INIT(&value, 0); while ((id = grn_table_cursor_next(context, cursor)) != GRN_ID_NIL) { GRN_BULK_REWIND(&value); grn_obj_get_value(context, text_column, id, &value); records = g_list_append(records, g_strndup(GRN_TEXT_VALUE(&value), GRN_TEXT_LEN(&value))); } grn_obj_unlink(context, &value); grn_obj_unlink(context, text_column); gcut_take_list(records, g_free); grn_test_assert(grn_table_cursor_close(context, cursor)); grn_test_assert_context(context); return records; }
static GList * result_to_list(void) { GList *list = NULL; grn_table_cursor *cursor; cursor = grn_table_cursor_open(context, result, NULL, 0, NULL, 0, 0, -1, GRN_CURSOR_ASCENDING | GRN_CURSOR_BY_ID); while ((grn_table_cursor_next(context, cursor))) { void *result_key; gint result_key_size; grn_id shop_id; gchar key[GRN_TABLE_MAX_KEY_SIZE]; gint key_size; result_key_size = grn_table_cursor_get_key(context, cursor, &result_key); memcpy(&shop_id, result_key, result_key_size); key_size = grn_table_get_key(context, shops, shop_id, &key, GRN_TABLE_MAX_KEY_SIZE); list = g_list_append(list, g_strndup(key, key_size)); } gcut_take_list(list, g_free); return list; }
const GList * grn_test_view_collect_string(grn_ctx *context, grn_obj *view, const gchar *text_column_name) { GList *records = NULL; grn_table_cursor *cursor; grn_obj id, value; grn_obj *text_column; cursor = grn_table_cursor_open(context, view, NULL, 0, NULL, 0, 0, -1, GRN_CURSOR_ASCENDING); cut_assert_not_null(cursor); GRN_TEXT_INIT(&id, 0); GRN_TEXT_INIT(&value, 0); text_column = grn_obj_column(context, view, text_column_name, strlen(text_column_name)); while (grn_table_cursor_next_o(context, cursor, &id) == GRN_SUCCESS) { GRN_BULK_REWIND(&value); grn_obj_get_value_o(context, text_column, &id, &value); records = g_list_append(records, g_strndup(GRN_TEXT_VALUE(&value), GRN_TEXT_LEN(&value))); } grn_obj_unlink(context, &id); grn_obj_unlink(context, &value); grn_obj_unlink(context, text_column); gcut_take_list(records, g_free); grn_test_assert(grn_table_cursor_close(context, cursor)); grn_test_assert_context(context); return records; }
void test_near_uint32(gpointer data) { grn_id id; int min_size, offset, limit, flags; guint32 max; const GList *expected_keys; GList *actual_keys = NULL; create_uint32_table(); min_size = gcut_data_get_int(data, "min-size"); max = gcut_data_get_uint(data, "max"); offset = gcut_data_get_int(data, "offset"); limit = gcut_data_get_int(data, "limit"); flags = gcut_data_get_int(data, "flags"); cursor = grn_table_cursor_open(context, table, NULL, min_size, &max, sizeof(max), offset, limit, flags | GRN_CURSOR_PREFIX); grn_test_assert_context(context); while ((id = grn_table_cursor_next(context, cursor))) { guint32 *key; int key_size; key_size = grn_table_cursor_get_key(context, cursor, (void **)&key); actual_keys = g_list_append(actual_keys, GUINT_TO_POINTER(*key)); } gcut_take_list(actual_keys, NULL); expected_keys = gcut_data_get_pointer(data, "expected"); gcut_assert_equal_list_uint(expected_keys, actual_keys); }
void test_prefix_error(gpointer data) { const gchar *min = "ab"; int offset, limit; create_short_text_table(gcut_take_new_list_string("abra", "abracada", "abracadabra", "abubu", "あ", "ああ", "あああ", "い", NULL)); offset = gcut_data_get_int(data, "offset"); limit = gcut_data_get_int(data, "limit"); cursor = grn_table_cursor_open(context, table, min, strlen(min), NULL, 0, offset, limit, GRN_CURSOR_PREFIX); grn_test_assert_error(gcut_data_get_uint(data, "rc"), gcut_data_get_string(data, "message"), context); }
/* * データベース内のオブジェクトを順番にブロックに渡す。 * * @example すべてのオブジェクトの名前を表示する: * database.each do |object| * p object.name * end * * @example すべてのオブジェクトの名前をID順で表示する: * database.each(:order_by => :id) do |object| * p object.name * end * * @example すべてのオブジェクトの名前をキー名の降順で表示する: * database.each(:order_by => :key, :order => :desc) do |object| * p object.name * end * * @overload each(options=nil) * @macro [new] database.each.options * @param options [::Hash] * @yield [object] * @option options :order * +:asc+ または +:ascending+ を指定すると昇順にレコードを取 * り出す。(デフォルト) * +:desc+ または +:descending+ を指定すると降順にレコードを * 取り出す。 * @option options :order_by (:key) * +:id+ を指定するとID順にレコードを取り出す。 * +:key+ 指定するとキー順にレコードを取り出す。(デフォル * ト) * @macro database.each.options * * @overload each(options=nil) * @macro database.each.options * @option options :ignore_missing_object (false) * Specify +true+ to ignore missing object. Otherwise, an exception is * raised for missing object. * * @since 2.0.5 */ static VALUE rb_grn_database_each (int argc, VALUE *argv, VALUE self) { grn_ctx *context = NULL; grn_obj *database; grn_table_cursor *cursor; VALUE rb_cursor, rb_options, rb_order, rb_order_by; VALUE rb_ignore_missing_object; int flags = 0; grn_id id; VALUE exception; RETURN_ENUMERATOR(self, argc, argv); rb_grn_database_deconstruct(SELF(self), &database, &context, NULL, NULL, NULL, NULL); rb_scan_args(argc, argv, "01", &rb_options); rb_grn_scan_options(rb_options, "order", &rb_order, "order_by", &rb_order_by, "ignore_missing_object", &rb_ignore_missing_object, NULL); flags |= rb_grn_table_cursor_order_to_flag(rb_order); flags |= rb_grn_table_cursor_order_by_to_flag(GRN_TABLE_PAT_KEY, self, rb_order_by); cursor = grn_table_cursor_open(context, database, NULL, 0, NULL, 0, 0, -1, flags); rb_cursor = GRNTABLECURSOR2RVAL(Qnil, context, cursor); rb_iv_set(self, "cursor", rb_cursor); while ((id = grn_table_cursor_next(context, cursor)) != GRN_ID_NIL) { grn_obj *object; object = grn_ctx_at(context, id); if (!object && RTEST(rb_ignore_missing_object)) { context->rc = GRN_SUCCESS; continue; } exception = rb_grn_context_to_exception(context, self); if (!NIL_P(exception)) { rb_grn_object_close(rb_cursor); rb_iv_set(self, "cursor", Qnil); rb_exc_raise(exception); } if (object) { rb_yield(GRNOBJECT2RVAL(Qnil, context, object, GRN_FALSE)); } } rb_grn_object_close(rb_cursor); rb_iv_set(self, "cursor", Qnil); return Qnil; }
static grn_table_cursor * rb_grn_patricia_trie_open_grn_rk_cursor (int argc, VALUE *argv, VALUE self, grn_ctx **context) { grn_obj *table; grn_table_cursor *cursor; void *prefix = NULL; unsigned prefix_size = 0; int offset = 0, limit = -1; int flags = GRN_CURSOR_PREFIX | GRN_CURSOR_RK; VALUE options, rb_prefix, rb_key_bytes, rb_key_bits; VALUE rb_greater_than, rb_less_than, rb_offset, rb_limit; rb_grn_table_deconstruct((RbGrnTable *)SELF(self), &table, context, NULL, NULL, NULL, NULL, NULL, NULL); rb_scan_args(argc, argv, "11", &rb_prefix, &options); rb_grn_scan_options(options, "key_bytes", &rb_key_bytes, "key_bites", &rb_key_bits, "offset", &rb_offset, "limit", &rb_limit, "greater_than", &rb_greater_than, "less_than", &rb_less_than, NULL); prefix = StringValuePtr(rb_prefix); if (!NIL_P(rb_key_bytes) && !NIL_P(rb_key_bits)) { rb_raise(rb_eArgError, "should not specify both :key_bytes and :key_bits once: %s", rb_grn_inspect(rb_ary_new4(argc, argv))); } else if (!NIL_P(rb_key_bytes)) { prefix_size = NUM2UINT(rb_key_bytes); } else if (!NIL_P(rb_key_bits)) { prefix_size = NUM2UINT(rb_key_bits); flags |= GRN_CURSOR_SIZE_BY_BIT; } else { prefix_size = RSTRING_LEN(rb_prefix); } if (!NIL_P(rb_offset)) offset = NUM2INT(rb_offset); if (!NIL_P(rb_limit)) limit = NUM2INT(rb_limit); if (RVAL2CBOOL(rb_greater_than)) flags |= GRN_CURSOR_GT; if (RVAL2CBOOL(rb_less_than)) flags |= GRN_CURSOR_LT; cursor = grn_table_cursor_open(*context, table, prefix, prefix_size, NULL, 0, offset, limit, flags); rb_grn_context_check(*context, self); return cursor; }
static grn_table_cursor * rb_grn_patricia_trie_open_grn_near_cursor (int argc, VALUE *argv, VALUE self, grn_ctx **context, int flags) { grn_obj *table; grn_obj *key_p = NULL, casted_key; grn_table_cursor *cursor; unsigned min_size = 0; int offset = 0, limit = -1; VALUE options, rb_key, rb_min_size; VALUE rb_greater_than, rb_less_than, rb_offset, rb_limit; flags |= GRN_CURSOR_PREFIX; rb_grn_table_deconstruct((RbGrnTable *)SELF(self), &table, context, NULL, NULL, NULL, NULL, NULL, NULL); rb_scan_args(argc, argv, "11", &rb_key, &options); rb_grn_scan_options(options, "size", &rb_min_size, "offset", &rb_offset, "limit", &rb_limit, "greater_than", &rb_greater_than, "less_than", &rb_less_than, NULL); key_p = RVAL2GRNBULK_WITH_TYPE(rb_key, *context, key_p, table->header.domain, grn_ctx_at(*context, table->header.domain)); GRN_OBJ_INIT(&casted_key, GRN_BULK, 0, table->header.domain); if (key_p->header.domain != table->header.domain) { grn_obj_cast(*context, key_p, &casted_key, 0); key_p = &casted_key; } if (!NIL_P(rb_min_size)) min_size = NUM2UINT(rb_min_size); if (!NIL_P(rb_offset)) offset = NUM2INT(rb_offset); if (!NIL_P(rb_limit)) limit = NUM2INT(rb_limit); if (RVAL2CBOOL(rb_greater_than)) flags |= GRN_CURSOR_GT; if (RVAL2CBOOL(rb_less_than)) flags |= GRN_CURSOR_LT; cursor = grn_table_cursor_open(*context, table, NULL, min_size, GRN_BULK_HEAD(key_p), GRN_BULK_VSIZE(key_p), offset, limit, flags); GRN_OBJ_FIN(*context, &casted_key); rb_grn_context_check(*context, self); return cursor; }
void test_cursor(void) { grn_table_cursor *c; database = grn_db_create(context, NULL, NULL); c = grn_table_cursor_open(context, database, NULL, 0, NULL, 0, 0, -1, 0); cut_assert_true(grn_table_cursor_next(context, c)); grn_table_cursor_close(context, c); }
void test_accessor(void) { int i; grn_obj *t1, *t2, *c1, *c2, r1, r2; t1 = grn_table_create(context, "t1", 2, NULL, GRN_OBJ_TABLE_NO_KEY|GRN_OBJ_PERSISTENT, NULL, NULL); cut_assert_not_null(t1); t2 = grn_table_create(context, "t2", 2, NULL, GRN_OBJ_TABLE_NO_KEY|GRN_OBJ_PERSISTENT, NULL, NULL); cut_assert_not_null(t2); c1 = grn_column_create(context, t1, "c1", 2, NULL, GRN_OBJ_PERSISTENT, t2); cut_assert_not_null(c1); c2 = grn_column_create(context, t2, "c2", 2, NULL, GRN_OBJ_PERSISTENT, t1); cut_assert_not_null(c2); GRN_RECORD_INIT(&r1, 0, grn_obj_id(context, t1)); GRN_RECORD_INIT(&r2, 0, grn_obj_id(context, t2)); for (i = 0; i < NRECORDS; i++) { grn_id i1, i2; i1 = grn_table_add(context, t1, NULL, 0, NULL); i2 = grn_table_add(context, t2, NULL, 0, NULL); GRN_RECORD_SET(context, &r1, i1); GRN_RECORD_SET(context, &r2, i2); grn_obj_set_value(context, c1, i1, &r2, GRN_OBJ_SET); grn_obj_set_value(context, c2, i2, &r1, GRN_OBJ_SET); } { grn_id id; uint64_t et; int nerr = 0; struct timeval tvb, tve; grn_obj *a = grn_obj_column(context, t1, "c1.c2.c1", 8); grn_table_cursor *tc = grn_table_cursor_open(context, t1, NULL, 0, NULL, 0, 0, -1, 0); cut_assert_not_null(a); cut_assert_not_null(tc); gettimeofday(&tvb, NULL); while ((id = grn_table_cursor_next(context, tc))) { GRN_BULK_REWIND(&r2); grn_obj_get_value(context, a, id, &r2); if (GRN_RECORD_VALUE(&r2) != id) { nerr++; } } gettimeofday(&tve, NULL); et = (tve.tv_sec - tvb.tv_sec) * 1000000 + (tve.tv_usec - tvb.tv_usec); // printf("et=%zu\n", et); cut_assert_equal_uint(0, nerr); grn_test_assert(grn_table_cursor_close(context, tc)); grn_test_assert(grn_obj_close(context, a)); } grn_test_assert(grn_obj_close(context, &r1)); grn_test_assert(grn_obj_close(context, &r2)); }
GList * grn_test_pat_get_keys(grn_ctx *context, grn_obj *patricia_trie) { GList *keys; grn_table_cursor *cursor; cursor = grn_table_cursor_open(context, patricia_trie, NULL, 0, NULL, 0, 0, -1, GRN_CURSOR_ASCENDING); keys = grn_test_pat_cursor_get_keys(context, cursor); grn_table_cursor_close(context, cursor); return keys; }
void test_set_value(void) { grn_obj *v; prepare_data(); GRN_EXPR_CREATE_FOR_QUERY(&context, docs, cond, v); cut_assert_not_null(cond); cut_assert_not_null(v); PARSE(cond, "size:14", GRN_EXPR_SYNTAX_QUERY|GRN_EXPR_ALLOW_PRAGMA|GRN_EXPR_ALLOW_COLUMN); res = grn_table_select(&context, docs, cond, NULL, GRN_OP_OR); cut_assert_not_null(res); grn_test_assert_select(&context, gcut_take_new_list_string("moge moge moge", "hoge fuga fuga", "moge hoge hoge", NULL), res, "body"); grn_test_assert(grn_obj_close(&context, res)); res = NULL; GRN_EXPR_CREATE_FOR_QUERY(&context, docs, expr, v); grn_expr_append_obj(&context, expr, v, GRN_OP_PUSH, 1); GRN_TEXT_SETS(&context, &textbuf, "size"); grn_expr_append_const(&context, expr, &textbuf, GRN_OP_PUSH, 1); grn_expr_append_op(&context, expr, GRN_OP_GET_VALUE, 2); GRN_UINT32_SET(&context, &intbuf, 14); grn_expr_append_const(&context, expr, &intbuf, GRN_OP_PUSH, 1); grn_expr_append_op(&context, expr, GRN_OP_ASSIGN, 2); { grn_id id; grn_table_cursor *tc; tc = grn_table_cursor_open(&context, docs, NULL, 0, NULL, 0, 0, -1, 0); cut_assert_not_null(tc); while ((id = grn_table_cursor_next(&context, tc))) { GRN_RECORD_SET(&context, v, id); grn_expr_exec(&context, expr, 0); } grn_test_assert(grn_table_cursor_close(&context, tc)); } res = grn_table_select(&context, docs, cond, NULL, GRN_OP_OR); cut_assert_not_null(res); grn_test_assert_select_all(res); }
void test_table(gpointer data) { grn_obj *table; grn_obj_flags flags = GPOINTER_TO_INT(data); grn_table_cursor *cursor; table = grn_table_create(context, NULL, 0, NULL, flags, get_object("ShortText"), NULL); cursor = grn_table_cursor_open(context, table, NULL, 0, NULL, 0, 0, -1, 0); /* FIXME: grn_test_assert_equal_object() */ cut_assert_equal_pointer(table, grn_table_cursor_table(context, cursor)); }
void test_table(gpointer data) { grn_obj *table; grn_obj_flags flags = GPOINTER_TO_INT(data); grn_table_cursor *cursor; table = grn_table_create(&context, NULL, 0, NULL, flags, OBJECT("<shorttext>"), 0); cursor = grn_table_cursor_open(&context, table, NULL, 0, NULL, 0, 0); /* FIXME: grn_test_assert_equal_object() */ cut_assert_equal_pointer(table, grn_table_cursor_table(&context, cursor)); }
static void rb_grn_database_mark_existing_ruby_object (grn_ctx *context, grn_obj *database) { grn_table_cursor *cursor; grn_id id; cursor = grn_table_cursor_open(context, database, NULL, 0, NULL, 0, 0, -1, GRN_CURSOR_ASCENDING); if (!cursor) return; while ((id = grn_table_cursor_next(context, cursor)) != GRN_ID_NIL) { rb_grn_context_mark_grn_id(context, id); } grn_table_cursor_close(context, cursor); }
void test_proc_call(void) { grn_obj *v; prepare_data(); GRN_EXPR_CREATE_FOR_QUERY(&context, docs, cond, v); cut_assert_not_null(cond); cut_assert_not_null(v); PARSE(cond, "size:>14", GRN_EXPR_SYNTAX_QUERY|GRN_EXPR_ALLOW_PRAGMA|GRN_EXPR_ALLOW_COLUMN); res = grn_table_select(&context, docs, cond, NULL, GRN_OP_OR); cut_assert_not_null(res); grn_test_assert_select(&context, gcut_take_new_list_string("hoge moge moge moge", "moge hoge fuga fuga", "moge hoge moge moge moge", "poyo moge hoge " "moge moge moge", NULL), res, "body"); grn_test_assert(grn_obj_close(&context, res)); res = NULL; GRN_EXPR_CREATE_FOR_QUERY(&context, docs, expr, v); PARSE(expr, "size = rand(14)", GRN_EXPR_SYNTAX_SCRIPT|GRN_EXPR_ALLOW_UPDATE); { grn_id id; grn_table_cursor *tc; tc = grn_table_cursor_open(&context, docs, NULL, 0, NULL, 0, 0, -1, 0); cut_assert_not_null(tc); while ((id = grn_table_cursor_next(&context, tc))) { GRN_RECORD_SET(&context, v, id); grn_expr_exec(&context, expr, 0); } grn_test_assert(grn_table_cursor_close(&context, tc)); } res = grn_table_select(&context, docs, cond, NULL, GRN_OP_OR); cut_assert_not_null(res); grn_test_assert_select_none(res); }
void test_common_prefix_search(gpointer data) { grn_id id; const gchar *max; int min_size, offset, limit, flags; const GList *expected_keys; GList *actual_keys = NULL; cut_omit("crashed. Is it right usage?"); create_short_text_table(gcut_take_new_list_string("abra", "abracada", "abracadabra", "abubu", "あ", "ああ", "あああ", "い", NULL)); min_size = gcut_data_get_int(data, "min-size"); max = gcut_data_get_string(data, "max"); offset = gcut_data_get_int(data, "offset"); limit = gcut_data_get_int(data, "limit"); flags = gcut_data_get_int(data, "flags"); cursor = grn_table_cursor_open(context, table, NULL, min_size, max, strlen(max), offset, limit, flags | GRN_CURSOR_PREFIX); grn_test_assert_context(context); while ((id = grn_table_cursor_next(context, cursor))) { gchar *key; int key_size; key_size = grn_table_cursor_get_key(context, cursor, (void **)&key); actual_keys = g_list_append(actual_keys, g_strndup(key, key_size)); } gcut_take_list(actual_keys, g_free); expected_keys = gcut_data_get_pointer(data, "expected"); gcut_assert_equal_list_string(expected_keys, actual_keys); }
/* * call-seq: * database.each {|object| ...} * database.each(options=nil) {|object| ...} * * データベース内のオブジェクトを順番にブロックに渡す。 * * @example すべてのオブジェクトの名前を表示する: * database.each do |object| * p object.name * end * * @example すべてのオブジェクトの名前をID順で表示する: * database.each(:order_by => :id) do |object| * p object.name * end * * @example すべてのオブジェクトの名前をキー名の降順で表示する: * database.each(:order_by => :key, :order => :desc) do |object| * p object.name * end * * @param options [::Hash] * @option options :order The order * +:asc+ または +:ascending+ を指定すると昇順にレコードを取 * り出す。(デフォルト) * * +:desc+ または +:descending+ を指定すると降順にレコードを * 取り出す。 * * @option options :order_by (:key) The ordef by * +:id+ を指定するとID順にレコードを取り出す。 * * +:key+ 指定するとキー順にレコードを取り出す。(デフォル * ト) * */ static VALUE rb_grn_database_each (int argc, VALUE *argv, VALUE self) { grn_ctx *context = NULL; grn_obj *database; grn_table_cursor *cursor; VALUE rb_cursor, rb_options, rb_order, rb_order_by; int flags = 0; grn_id id; rb_grn_database_deconstruct(SELF(self), &database, &context, NULL, NULL, NULL, NULL); rb_scan_args(argc, argv, "01", &rb_options); rb_grn_scan_options(rb_options, "order", &rb_order, "order_by", &rb_order_by, NULL); flags |= rb_grn_table_cursor_order_to_flag(rb_order); flags |= rb_grn_table_cursor_order_by_to_flag(GRN_TABLE_PAT_KEY, self, rb_order_by); cursor = grn_table_cursor_open(context, database, NULL, 0, NULL, 0, 0, -1, flags); rb_cursor = GRNTABLECURSOR2RVAL(Qnil, context, cursor); rb_iv_set(self, "cursor", rb_cursor); while ((id = grn_table_cursor_next(context, cursor)) != GRN_ID_NIL) { grn_obj *object; object = grn_ctx_at(context, id); if (object) rb_yield(GRNOBJECT2RVAL(Qnil, context, object, GRN_FALSE)); } rb_grn_object_close(rb_cursor); rb_iv_set(self, "cursor", Qnil); return Qnil; }
static void grn_db_reindex(grn_ctx *ctx, grn_obj *db) { grn_table_cursor *cursor; grn_id id; cursor = grn_table_cursor_open(ctx, db, NULL, 0, NULL, 0, 0, -1, GRN_CURSOR_BY_ID); if (!cursor) { return; } while ((id = grn_table_cursor_next(ctx, cursor)) != GRN_ID_NIL) { grn_obj *object; object = grn_ctx_at(ctx, id); if (!object) { ERRCLR(ctx); continue; } switch (object->header.type) { case GRN_TABLE_HASH_KEY : case GRN_TABLE_PAT_KEY : case GRN_TABLE_DAT_KEY : grn_obj_reindex(ctx, object); break; default: break; } grn_obj_unlink(ctx, object); if (ctx->rc != GRN_SUCCESS) { break; } } grn_table_cursor_close(ctx, cursor); }
/* * call-seq: * view.each {|record| ...} * * ビューに登録されているテーブルのレコードを順番にブロック * に渡す。 */ static VALUE rb_grn_view_each (VALUE self) { #ifdef WIN32 rb_raise(rb_eNotImpError, "grn_table_cursor_next_o() isn't available on Windows."); #else RbGrnTable *rb_grn_view; RbGrnObject *rb_grn_object; grn_ctx *context = NULL; grn_obj *view; grn_table_cursor *cursor; VALUE rb_cursor; grn_obj id; grn_rc rc = GRN_SUCCESS; rb_grn_view = SELF(self); rb_grn_table_deconstruct(rb_grn_view, &view, &context, NULL, NULL, NULL, NULL, NULL, NULL); cursor = grn_table_cursor_open(context, view, NULL, 0, NULL, 0, 0, -1, GRN_CURSOR_ASCENDING); rb_cursor = GRNTABLECURSOR2RVAL(Qnil, context, cursor); rb_grn_object = RB_GRN_OBJECT(rb_grn_view); GRN_TEXT_INIT(&id, 0); while (rb_grn_object->object && (rc = grn_table_cursor_next_o(context, cursor, &id)) == GRN_SUCCESS) { rb_yield(rb_grn_view_record_new(self, &id)); } GRN_OBJ_FIN(context, &id); rb_grn_object_close(rb_cursor); if (!(rc == GRN_SUCCESS || rc == GRN_END_OF_DATA)) { rb_grn_context_check(context, self); } #endif return Qnil; }
void do_search(grn_ctx *ctx, grn_index *index) { char buf[4096]; for (;;) { grn_obj *res; if (isatty(0)) { fputs("> ", stderr); } if (!fgets(buf, 4096, stdin)) { break; } if ((res = grn_index_sel(ctx, index, buf, strlen(buf) - 1))) { unsigned int n = grn_table_size(ctx, res); printf("%u hits\n", n); if (n) { grn_table_cursor *tc = grn_table_cursor_open(ctx, res, NULL, 0, NULL, 0, 0); if (tc) { while (grn_table_cursor_next(ctx, tc)) { grn_id *ridp; int keylen; char keybuf[GRN_TABLE_MAX_KEY_SIZE]; if (!grn_table_cursor_get_key(ctx, tc, (void *)&ridp)) { fprintf(stderr, "grn_table_cursor_get_key failed(%d)\n", ctx->rc); } else { if (!(keylen = grn_table_get_key(ctx, index->keys, *ridp, keybuf, GRN_TABLE_MAX_KEY_SIZE))) { fprintf(stderr, "grn_table_get_key failed(%d)\n", ctx->rc); } else { keybuf[keylen] = '\0'; puts(keybuf); } } } grn_table_cursor_close(ctx, tc); } else { fprintf(stderr, "grn_table_cursor_open failed(%d)\n", ctx->rc); } } grn_obj_close(ctx, res); } } }
static grn_table_cursor * rb_grn_double_array_trie_open_grn_prefix_cursor (int argc, VALUE *argv, VALUE self, grn_ctx **context) { grn_obj *table; grn_table_cursor *cursor; void *prefix = NULL; unsigned prefix_size = 0; int offset = 0, limit = -1; int flags = GRN_CURSOR_PREFIX; VALUE options, rb_prefix, rb_key_bytes, rb_key_bits; VALUE rb_order, rb_order_by; VALUE rb_greater_than, rb_less_than, rb_offset, rb_limit; rb_grn_table_deconstruct((RbGrnTable *)SELF(self), &table, context, NULL, NULL, NULL, NULL, NULL, NULL); rb_scan_args(argc, argv, "11", &rb_prefix, &options); rb_grn_scan_options(options, "key_bytes", &rb_key_bytes, "key_bites", &rb_key_bits, "offset", &rb_offset, "limit", &rb_limit, "order", &rb_order, "order_by", &rb_order_by, "greater_than", &rb_greater_than, "less_than", &rb_less_than, NULL); prefix = StringValuePtr(rb_prefix); if (!NIL_P(rb_key_bytes) && !NIL_P(rb_key_bits)) { rb_raise(rb_eArgError, "should not specify both :key_bytes and :key_bits once: %s", rb_grn_inspect(rb_ary_new4(argc, argv))); } else if (!NIL_P(rb_key_bytes)) { prefix_size = NUM2UINT(rb_key_bytes); } else if (!NIL_P(rb_key_bits)) { prefix_size = NUM2UINT(rb_key_bits); flags |= GRN_CURSOR_SIZE_BY_BIT; } else { prefix_size = RSTRING_LEN(rb_prefix); } if (!NIL_P(rb_offset)) offset = NUM2INT(rb_offset); if (!NIL_P(rb_limit)) limit = NUM2INT(rb_limit); if (NIL_P(rb_order)) { } else if (rb_grn_equal_option(rb_order, "asc") || rb_grn_equal_option(rb_order, "ascending")) { flags |= GRN_CURSOR_ASCENDING; } else if (rb_grn_equal_option(rb_order, "desc") || rb_grn_equal_option(rb_order, "descending")) { flags |= GRN_CURSOR_DESCENDING; } else { rb_raise(rb_eArgError, "order should be one of " "[:asc, :ascending, :desc, :descending]: %s", rb_grn_inspect(rb_order)); } if (NIL_P(rb_order_by)) { } else if (rb_grn_equal_option(rb_order_by, "id")) { flags |= GRN_CURSOR_BY_ID; } else if (rb_grn_equal_option(rb_order_by, "key")) { if (table->header.type != GRN_TABLE_PAT_KEY) { rb_raise(rb_eArgError, "order_by => :key is available " "only for Groonga::DoubleArrayTrie: %s", rb_grn_inspect(self)); } flags |= GRN_CURSOR_BY_KEY; } else { rb_raise(rb_eArgError, "order_by should be one of [:id%s]: %s", table->header.type == GRN_TABLE_PAT_KEY ? ", :key" : "", rb_grn_inspect(rb_order_by)); } if (RVAL2CBOOL(rb_greater_than)) flags |= GRN_CURSOR_GT; if (RVAL2CBOOL(rb_less_than)) flags |= GRN_CURSOR_LT; cursor = grn_table_cursor_open(*context, table, prefix, prefix_size, NULL, 0, offset, limit, flags); rb_grn_context_check(*context, self); return cursor; }
/* FIXME: DON'T WORK!!! */ static VALUE rb_grn_view_sort (int argc, VALUE *argv, VALUE self) { VALUE rb_result = Qnil; #ifdef WIN32 rb_raise(rb_eNotImpError, "grn_view_add() isn't available on Windows."); #else grn_ctx *context = NULL; grn_obj *view; grn_obj *result; grn_table_sort_key *keys; int i, n_keys; int n_records, offset = 0, limit = -1; VALUE rb_keys, options; VALUE rb_offset, rb_limit; VALUE *rb_sort_keys; grn_table_cursor *cursor; VALUE exception; grn_obj id; rb_grn_table_deconstruct(SELF(self), &view, &context, NULL, NULL, NULL, NULL, NULL, NULL); rb_scan_args(argc, argv, "11", &rb_keys, &options); if (!RVAL2CBOOL(rb_obj_is_kind_of(rb_keys, rb_cArray))) rb_raise(rb_eArgError, "keys should be an array of key: <%s>", rb_grn_inspect(rb_keys)); n_keys = RARRAY_LEN(rb_keys); rb_sort_keys = RARRAY_PTR(rb_keys); keys = ALLOCA_N(grn_table_sort_key, n_keys); for (i = 0; i < n_keys; i++) { VALUE rb_sort_options, rb_key, rb_resolved_key, rb_order; if (RVAL2CBOOL(rb_obj_is_kind_of(rb_sort_keys[i], rb_cHash))) { rb_sort_options = rb_sort_keys[i]; } else if (RVAL2CBOOL(rb_obj_is_kind_of(rb_sort_keys[i], rb_cArray))) { rb_sort_options = rb_hash_new(); rb_hash_aset(rb_sort_options, RB_GRN_INTERN("key"), rb_ary_entry(rb_sort_keys[i], 0)); rb_hash_aset(rb_sort_options, RB_GRN_INTERN("order"), rb_ary_entry(rb_sort_keys[i], 1)); } else { rb_sort_options = rb_hash_new(); rb_hash_aset(rb_sort_options, RB_GRN_INTERN("key"), rb_sort_keys[i]); } rb_grn_scan_options(rb_sort_options, "key", &rb_key, "order", &rb_order, NULL); if (RVAL2CBOOL(rb_obj_is_kind_of(rb_key, rb_cString))) { rb_resolved_key = rb_grn_table_get_column(self, rb_key); } else { rb_resolved_key = rb_key; } keys[i].key = RVAL2GRNOBJECT(rb_resolved_key, &context); if (!keys[i].key) { rb_raise(rb_eGrnNoSuchColumn, "no such column: <%s>: <%s>", rb_grn_inspect(rb_key), rb_grn_inspect(self)); } if (NIL_P(rb_order)) { keys[i].flags = 0; } else if (rb_grn_equal_option(rb_order, "desc") || rb_grn_equal_option(rb_order, "descending")) { keys[i].flags = GRN_TABLE_SORT_DESC; } else if (rb_grn_equal_option(rb_order, "asc") || rb_grn_equal_option(rb_order, "ascending")) { keys[i].flags = GRN_TABLE_SORT_ASC; } else { rb_raise(rb_eArgError, "order should be one of " "[nil, :desc, :descending, :asc, :ascending]: %s", rb_grn_inspect(rb_order)); } } rb_grn_scan_options(options, "offset", &rb_offset, "limit", &rb_limit, NULL); if (!NIL_P(rb_offset)) offset = NUM2INT(rb_offset); if (!NIL_P(rb_limit)) limit = NUM2INT(rb_limit); result = grn_table_create(context, NULL, 0, NULL, GRN_TABLE_VIEW, NULL, NULL); grn_view_add(context, result, grn_table_create(context, NULL, 0, NULL, GRN_TABLE_NO_KEY, NULL, grn_ctx_get(context, "People", strlen("People")))); grn_view_add(context, result, grn_table_create(context, NULL, 0, NULL, GRN_TABLE_NO_KEY, NULL, grn_ctx_get(context, "People", strlen("People")))); n_records = grn_table_sort(context, view, offset, limit, result, keys, n_keys); exception = rb_grn_context_to_exception(context, self); if (!NIL_P(exception)) { grn_obj_unlink(context, result); rb_exc_raise(exception); } rb_result = rb_ary_new(); cursor = grn_table_cursor_open(context, result, NULL, 0, NULL, 0, 0, -1, GRN_CURSOR_ASCENDING); GRN_TEXT_INIT(&id, 0); while (grn_table_cursor_next_o(context, cursor, &id) == GRN_SUCCESS) { rb_ary_push(rb_result, rb_grn_view_record_new(self, &id)); } GRN_OBJ_FIN(context, &id); grn_table_cursor_close(context, cursor); grn_obj_unlink(context, result); #endif return rb_result; }
static grn_rc sequential_fuzzy_search(grn_ctx *ctx, grn_obj *table, grn_obj *column, grn_obj *query, uint32_t max_distance, uint32_t prefix_match_size, uint32_t max_expansion, int flags, grn_obj *res, grn_operator op) { grn_table_cursor *tc; char *sx = GRN_TEXT_VALUE(query); char *ex = GRN_BULK_CURR(query); if (op == GRN_OP_AND) { tc = grn_table_cursor_open(ctx, res, NULL, 0, NULL, 0, 0, -1, GRN_CURSOR_BY_ID); } else { tc = grn_table_cursor_open(ctx, table, NULL, 0, NULL, 0, 0, -1, GRN_CURSOR_BY_ID); } if (tc) { grn_id id; grn_obj value; score_heap *heap; int i, n; GRN_TEXT_INIT(&value, 0); heap = score_heap_open(ctx, SCORE_HEAP_SIZE); if (!heap) { grn_table_cursor_close(ctx, tc); grn_obj_unlink(ctx, &value); return GRN_NO_MEMORY_AVAILABLE; } while ((id = grn_table_cursor_next(ctx, tc))) { unsigned int distance = 0; grn_obj *domain; GRN_BULK_REWIND(&value); grn_obj_get_value(ctx, column, id, &value); domain = grn_ctx_at(ctx, ((&value))->header.domain); if ((&(value))->header.type == GRN_VECTOR) { n = grn_vector_size(ctx, &value); for (i = 0; i < n; i++) { unsigned int length; const char *vector_value = NULL; length = grn_vector_get_element(ctx, &value, i, &vector_value, NULL, NULL); if (!prefix_match_size || (prefix_match_size > 0 && length >= prefix_match_size && !memcmp(sx, vector_value, prefix_match_size))) { distance = calc_edit_distance(ctx, sx, ex, (char *)vector_value, (char *)vector_value + length, flags); if (distance <= max_distance) { score_heap_push(ctx, heap, id, distance); break; } } } } else if ((&(value))->header.type == GRN_UVECTOR && grn_obj_is_table(ctx, domain)) { n = grn_vector_size(ctx, &value); for (i = 0; i < n; i++) { grn_id rid; char key_name[GRN_TABLE_MAX_KEY_SIZE]; int key_length; rid = grn_uvector_get_element(ctx, &value, i, NULL); key_length = grn_table_get_key(ctx, domain, rid, key_name, GRN_TABLE_MAX_KEY_SIZE); if (!prefix_match_size || (prefix_match_size > 0 && key_length >= prefix_match_size && !memcmp(sx, key_name, prefix_match_size))) { distance = calc_edit_distance(ctx, sx, ex, key_name, key_name + key_length, flags); if (distance <= max_distance) { score_heap_push(ctx, heap, id, distance); break; } } } } else { if (grn_obj_is_reference_column(ctx, column)) { grn_id rid; char key_name[GRN_TABLE_MAX_KEY_SIZE]; int key_length; rid = GRN_RECORD_VALUE(&value); key_length = grn_table_get_key(ctx, domain, rid, key_name, GRN_TABLE_MAX_KEY_SIZE); if (!prefix_match_size || (prefix_match_size > 0 && key_length >= prefix_match_size && !memcmp(sx, key_name, prefix_match_size))) { distance = calc_edit_distance(ctx, sx, ex, key_name, key_name + key_length, flags); if (distance <= max_distance) { score_heap_push(ctx, heap, id, distance); } } } else { if (!prefix_match_size || (prefix_match_size > 0 && GRN_TEXT_LEN(&value) >= prefix_match_size && !memcmp(sx, GRN_TEXT_VALUE(&value), prefix_match_size))) { distance = calc_edit_distance(ctx, sx, ex, GRN_TEXT_VALUE(&value), GRN_BULK_CURR(&value), flags); if (distance <= max_distance) { score_heap_push(ctx, heap, id, distance); } } } } grn_obj_unlink(ctx, domain); } grn_table_cursor_close(ctx, tc); grn_obj_unlink(ctx, &value); for (i = 0; i < heap->n_entries; i++) { if (max_expansion > 0 && i >= max_expansion) { break; } { grn_posting posting; posting.rid = heap->nodes[i].id; posting.sid = 1; posting.pos = 0; posting.weight = max_distance - heap->nodes[i].score; grn_ii_posting_add(ctx, &posting, (grn_hash *)res, op); } } grn_ii_resolve_sel_and(ctx, (grn_hash *)res, op); score_heap_close(ctx, heap); } return GRN_SUCCESS; }
static mrb_value mrb_grn_table_delete(mrb_state *mrb, mrb_value self) { grn_ctx *ctx = (grn_ctx *)mrb->ud; grn_obj *table; mrb_value mrb_options; mrb_value mrb_id; mrb_value mrb_key; mrb_value mrb_expression; table = DATA_PTR(self); mrb_get_args(mrb, "H", &mrb_options); mrb_id = grn_mrb_options_get_lit(mrb, mrb_options, "id"); if (!mrb_nil_p(mrb_id)) { grn_table_delete_by_id(ctx, table, mrb_fixnum(mrb_id)); grn_mrb_ctx_check(mrb); return mrb_nil_value(); } mrb_key = grn_mrb_options_get_lit(mrb, mrb_options, "key"); if (!mrb_nil_p(mrb_key)) { grn_id key_domain_id; void *key; unsigned int key_size; grn_mrb_value_to_raw_data_buffer buffer; key_domain_id = table->header.domain; grn_mrb_value_to_raw_data_buffer_init(mrb, &buffer); grn_mrb_value_to_raw_data(mrb, "key", mrb_key, key_domain_id, &buffer, &key, &key_size); grn_table_delete(ctx, table, key, key_size); grn_mrb_value_to_raw_data_buffer_fin(mrb, &buffer); grn_mrb_ctx_check(mrb); return mrb_nil_value(); } mrb_expression = grn_mrb_options_get_lit(mrb, mrb_options, "expression"); if (!mrb_nil_p(mrb_expression)) { grn_obj *expression; grn_obj *selected_records; grn_table_cursor *cursor; expression = DATA_PTR(mrb_expression); selected_records = grn_table_select(ctx, table, expression, NULL, GRN_OP_OR); grn_mrb_ctx_check(mrb); cursor = grn_table_cursor_open(ctx, selected_records, NULL, 0, NULL, 0, 0, -1, 0); if (cursor) { while (grn_table_cursor_next(ctx, cursor) != GRN_ID_NIL) { grn_id *id; grn_table_cursor_get_key(ctx, cursor, (void **)&id); grn_table_delete_by_id(ctx, table, *id); } grn_table_cursor_close(ctx, cursor); } grn_mrb_ctx_check(mrb); return mrb_nil_value(); } mrb_raisef(mrb, E_ARGUMENT_ERROR, "must have :id, :key or :expression: %S", mrb_options); return mrb_nil_value(); }
void test_expr(void) { int i; grn_obj *t1, *t2, *c1, *c2, r1, r2, buf; t1 = grn_table_create(context, "t1", 2, NULL, GRN_OBJ_TABLE_NO_KEY|GRN_OBJ_PERSISTENT, NULL, NULL); cut_assert_not_null(t1); t2 = grn_table_create(context, "t2", 2, NULL, GRN_OBJ_TABLE_NO_KEY|GRN_OBJ_PERSISTENT, NULL, NULL); cut_assert_not_null(t2); c1 = grn_column_create(context, t1, "c1", 2, NULL, GRN_OBJ_PERSISTENT, t2); cut_assert_not_null(c1); c2 = grn_column_create(context, t2, "c2", 2, NULL, GRN_OBJ_PERSISTENT, t1); cut_assert_not_null(c2); GRN_TEXT_INIT(&buf, 0); GRN_RECORD_INIT(&r1, 0, grn_obj_id(context, t1)); GRN_RECORD_INIT(&r2, 0, grn_obj_id(context, t2)); for (i = 0; i < NRECORDS; i++) { grn_id i1, i2; i1 = grn_table_add(context, t1, NULL, 0, NULL); i2 = grn_table_add(context, t2, NULL, 0, NULL); GRN_RECORD_SET(context, &r1, i1); GRN_RECORD_SET(context, &r2, i2); grn_obj_set_value(context, c1, i1, &r2, GRN_OBJ_SET); grn_obj_set_value(context, c2, i2, &r1, GRN_OBJ_SET); } { grn_obj *r, *v; expr = grn_expr_create(context, NULL, 0); cut_assert_not_null(expr); v = grn_expr_add_var(context, expr, NULL, 0); GRN_RECORD_INIT(v, 0, grn_obj_id(context, t1)); grn_expr_append_obj(context, expr, v, GRN_OP_PUSH, 1); GRN_TEXT_SETS(context, &buf, "c1"); grn_expr_append_const(context, expr, &buf, GRN_OP_PUSH, 1); grn_expr_append_op(context, expr, GRN_OP_GET_VALUE, 2); GRN_TEXT_SETS(context, &buf, "c2"); grn_expr_append_const(context, expr, &buf, GRN_OP_PUSH, 1); grn_expr_append_op(context, expr, GRN_OP_GET_VALUE, 2); GRN_TEXT_SETS(context, &buf, "c1"); grn_expr_append_const(context, expr, &buf, GRN_OP_PUSH, 1); // GRN_TEXT_SETS(context, &buf, "c1.c2.c1"); // grn_expr_append_const(context, expr, &buf); grn_expr_append_op(context, expr, GRN_OP_GET_VALUE, 2); grn_expr_compile(context, expr); { grn_id id; uint64_t et; int nerr = 0; grn_table_cursor *tc; struct timeval tvb, tve; tc = grn_table_cursor_open(context, t1, NULL, 0, NULL, 0, 0, -1, 0); cut_assert_not_null(tc); gettimeofday(&tvb, NULL); while ((id = grn_table_cursor_next(context, tc))) { GRN_RECORD_SET(context, v, id); grn_expr_exec(context, expr, 0); r = grn_ctx_pop(context); if (GRN_RECORD_VALUE(r) != id) { nerr++; } } gettimeofday(&tve, NULL); et = (tve.tv_sec - tvb.tv_sec) * 1000000 + (tve.tv_usec - tvb.tv_usec); // printf("et=%zu\n", et); cut_assert_equal_uint(0, nerr); grn_test_assert(grn_table_cursor_close(context, tc)); } } grn_test_assert(grn_obj_close(context, &r1)); grn_test_assert(grn_obj_close(context, &r2)); grn_test_assert(grn_obj_close(context, &buf)); }
void test_near_geo_point(gpointer data) { grn_id id; int offset, limit; const GList *expected_keys; GList *actual_keys = NULL; grn_table_sort_key keys[2]; grn_obj base, base_string, location; create_geo_table(cut_take_printf(" [\"%s\"],\n" " [\"%s\"],\n" " [\"%s\"],\n" " [\"%s\"],\n" " [\"%s\"],\n" " [\"%s\"],\n" " [\"%s\"],\n" " [\"%s\"],\n" " [\"%s\"],\n" " [\"%s\"],\n" " [\"%s\"],\n" " [\"%s\"],\n" " [\"%s\"],\n" " [\"%s\"],\n" " [\"%s\"]", TAKEN_POINT(0, 0, 0, 180, 0, 0), TAKEN_POINT(0, 0, 0, -179, -59, -59), TAKEN_POINT(-1, -1, -1, 180, 0, 0), TAKEN_POINT(2, 1, 1, 180, 0, 0), TAKEN_POINT(-2, -1, -1, -179, -59, -59), TAKEN_POINT(1, 2, 1, -179, -59, -59), TAKEN_POINT(90, 0, 0, 0, 0, 0), TAKEN_POINT(-90, 0, 0, 1, 0, 0), TAKEN_POINT(1, 0, 0, 1, 0, 0), TAKEN_POINT(1, 1, 0, 1, 1, 0), TAKEN_POINT(1, 1, 1, 1, 1, 1), TAKEN_POINT(-1, 0, 0, 1, 1, 1), TAKEN_POINT(-1, -1, -1, 0, 0, 0), TAKEN_POINT(-1, -2, -1, -1, -1, -1), TAKEN_POINT(1, 1, 10, -1, -1, -1))); result = grn_table_create(context, NULL, 0, NULL, GRN_TABLE_NO_KEY, NULL, table); grn_test_assert_context(context); GRN_TEXT_INIT(&base_string, 0); GRN_TEXT_SETS(context, &base_string, gcut_data_get_string(data, "base")); GRN_WGS84_GEO_POINT_INIT(&base, 0); grn_obj_cast(context, &base_string, &base, FALSE); GRN_OBJ_FIN(context, &base_string); offset = gcut_data_get_int(data, "offset"); if (offset > 0) { cut_omit("geo sort doesn't support offset yet."); } limit = gcut_data_get_int(data, "limit"); keys[0].key = column; keys[0].flags = GRN_TABLE_SORT_GEO; keys[0].offset = 0; keys[1].key = &base; keys[1].flags = 0; keys[1].offset = 0; grn_table_sort(context, table, offset, limit, result, keys, 2); GRN_OBJ_FIN(context, &base); grn_test_assert_context(context); cursor = grn_table_cursor_open(context, result, NULL, 0, NULL, 0, 0, -1, GRN_CURSOR_ASCENDING); grn_test_assert_context(context); GRN_WGS84_GEO_POINT_INIT(&location, 0); while ((id = grn_table_cursor_next(context, cursor))) { gint32 *key; int key_size; gint latitude, longitude; key_size = grn_table_cursor_get_value(context, cursor, (void **)&key); GRN_BULK_REWIND(&location); grn_obj_get_value(context, column, *key, &location); GRN_GEO_POINT_VALUE(&location, latitude, longitude); actual_keys = g_list_append(actual_keys, inspect_point(latitude, longitude)); } GRN_OBJ_FIN(context, &location); gcut_take_list(actual_keys, g_free); expected_keys = gcut_data_get_pointer(data, "expected"); gcut_assert_equal_list_string(expected_keys, actual_keys); }
void test_persistent_expr(void) { int i; grn_obj *t1, *t2, *c1, *c2, buf; t1 = grn_table_create(&context, "t1", 2, NULL, GRN_OBJ_TABLE_NO_KEY|GRN_OBJ_PERSISTENT, NULL, 0); cut_assert_not_null(t1); t2 = grn_table_create(&context, "t2", 2, NULL, GRN_OBJ_TABLE_NO_KEY|GRN_OBJ_PERSISTENT, NULL, 0); cut_assert_not_null(t2); c1 = grn_column_create(&context, t1, "c1", 2, NULL, GRN_OBJ_PERSISTENT, t2); cut_assert_not_null(c1); c2 = grn_column_create(&context, t2, "c2", 2, NULL, GRN_OBJ_PERSISTENT, t1); cut_assert_not_null(c2); GRN_TEXT_INIT(&buf, 0); for (i = 0; i < NRECORDS; i++) { grn_id i1, i2; i1 = grn_table_add(&context, t1, NULL, 0, NULL); i2 = grn_table_add(&context, t2, NULL, 0, NULL); GRN_BULK_REWIND(&buf); grn_bulk_write(&context, &buf, (char *)&i2, sizeof(grn_id)); grn_obj_set_value(&context, c1, i1, &buf, GRN_OBJ_SET); grn_obj_set_value(&context, c2, i2, &buf, GRN_OBJ_SET); } { grn_obj *expr = grn_expr_create(&context, "test", 4); grn_obj *v; cut_assert_not_null(expr); v = grn_expr_add_var(&context, expr, "foo", 3); GRN_RECORD_INIT(v, 0, grn_obj_id(&context, t1)); grn_expr_append_obj(&context, expr, v); GRN_TEXT_SETS(&context, &buf, "c1"); grn_expr_append_const(&context, expr, &buf); grn_expr_append_op(&context, expr, GRN_OP_OBJ_GET_VALUE, 2); GRN_TEXT_SETS(&context, &buf, "c2"); grn_expr_append_const(&context, expr, &buf); grn_expr_append_op(&context, expr, GRN_OP_OBJ_GET_VALUE, 2); GRN_TEXT_SETS(&context, &buf, "c1"); grn_expr_append_const(&context, expr, &buf); /* GRN_TEXT_SETS(&context, &buf, "c1.c2.c1"); grn_expr_append_const(&context, expr, &buf); */ grn_expr_append_op(&context, expr, GRN_OP_OBJ_GET_VALUE, 2); grn_expr_compile(&context, expr); } cut_assert_equal_uint(0, grn_obj_close(&context, &buf)); grn_db_close(&context, database); database = grn_db_open(&context, path); GRN_TEXT_INIT(&buf, 0); { grn_id id; uint64_t et; int nerr = 0; grn_obj *r, *v; grn_table_cursor *tc; struct timeval tvb, tve; grn_obj *expr = grn_ctx_get(&context, "test", 4); v = grn_expr_get_var(&context, expr, "foo", 3); t1 = grn_ctx_get(&context, "t1", 2); tc = grn_table_cursor_open(&context, t1, NULL, 0, NULL, 0, 0); cut_assert_not_null(tc); gettimeofday(&tvb, NULL); while ((id = grn_table_cursor_next(&context, tc))) { GRN_RECORD_SET(&context, v, id); r = grn_expr_exec(&context, expr); if (GRN_RECORD_VALUE(r) != id) { nerr++; } } gettimeofday(&tve, NULL); et = (tve.tv_sec - tvb.tv_sec) * 1000000 + (tve.tv_usec - tvb.tv_usec); // printf("et=%zu\n", et); cut_assert_equal_uint(0, nerr); cut_assert_equal_uint(0, grn_table_cursor_close(&context, tc)); } cut_assert_equal_uint(0, grn_obj_close(&context, &buf)); }