Beispiel #1
0
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;
}
Beispiel #2
0
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);
}
Beispiel #3
0
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;
}
Beispiel #5
0
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);
}
Beispiel #8
0
/*
 * データベース内のオブジェクトを順番にブロックに渡す。
 *
 * @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;
}
Beispiel #11
0
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);
}
Beispiel #12
0
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));
}
Beispiel #13
0
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;
}
Beispiel #14
0
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);
}
Beispiel #15
0
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));
}
Beispiel #16
0
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));
}
Beispiel #17
0
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);
}
Beispiel #18
0
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);
}
Beispiel #20
0
/*
 * 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;
}
Beispiel #21
0
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);
}
Beispiel #22
0
/*
 * 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;
}
Beispiel #23
0
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;
}
Beispiel #25
0
/* 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;
}
Beispiel #26
0
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;
}
Beispiel #27
0
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();
}
Beispiel #28
0
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));
}
Beispiel #29
0
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);
}
Beispiel #30
0
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));
}