示例#1
0
GList *
grn_test_pat_cursor_get_pairs(grn_ctx *context, grn_table_cursor *cursor)
{
  grn_id id;
  GList *pairs = NULL;

  id = grn_table_cursor_next(context, cursor);
  while (id != GRN_ID_NIL) {
    int length;
    void *key, *value;
    GString *null_terminated_key, *null_terminated_value;

    length = grn_table_cursor_get_key(context, cursor, &key);
    null_terminated_key = g_string_new_len(key, length);
    pairs = g_list_append(pairs,
                          g_string_free(null_terminated_key, FALSE));

    length = grn_table_cursor_get_value(context, cursor, &value);
    null_terminated_value = g_string_new_len(value, length);
    pairs = g_list_append(pairs,
                          g_string_free(null_terminated_value, FALSE));

    id = grn_table_cursor_next(context, cursor);
  }

  return pairs;
}
示例#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);
}
示例#3
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;
}
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);
}
示例#5
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;
}
示例#6
0
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;
}
示例#7
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);
}
示例#8
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));
}
示例#9
0
static mrb_value
mrb_grn_table_cursor_next(mrb_state *mrb, mrb_value self)
{
  grn_ctx *ctx = (grn_ctx *)mrb->ud;
  grn_id id;

  id = grn_table_cursor_next(ctx, DATA_PTR(self));
  grn_mrb_ctx_check(mrb);

  return mrb_fixnum_value(id);
}
示例#10
0
GList *
grn_test_pat_cursor_get_keys(grn_ctx *context, grn_table_cursor *cursor)
{
  GList *keys = NULL;
  grn_id id;

  id = grn_table_cursor_next(context, cursor);
  while (id != GRN_ID_NIL) {
    void *key;
    GString *null_terminated_key;
    int size;

    size = grn_table_cursor_get_key(context, cursor, &key);
    null_terminated_key = g_string_new_len(key, size);
    keys = g_list_append(keys, g_string_free(null_terminated_key, FALSE));
    id = grn_table_cursor_next(context, cursor);
  }

  return keys;
}
示例#11
0
static mrb_value
mrb_grn_table_cursor_count(mrb_state *mrb, mrb_value self)
{
  grn_ctx *ctx = (grn_ctx *)mrb->ud;
  int n_records = 0;

  while (grn_table_cursor_next(ctx, DATA_PTR(self)) != GRN_ID_NIL) {
    n_records++;
  }

  return mrb_fixnum_value(n_records);
}
示例#12
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);
}
示例#13
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);
}
示例#14
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);
}
示例#15
0
/*
 * call-seq:
 *   table_cursor.each {|record| ...}
 *
 * カーソルの範囲内にあるレコードを順番にブロックに渡す。
 */
static VALUE
rb_grn_table_cursor_each (VALUE self)
{
    grn_id record_id;
    grn_ctx *context;
    grn_table_cursor *cursor;

    rb_grn_table_cursor_deconstruct(SELF(self), &cursor, &context,
				    NULL, NULL, NULL, NULL);

    if (context && cursor) {
	while ((record_id = grn_table_cursor_next(context, cursor))) {
	    rb_yield(rb_grn_record_new(rb_iv_get(self, "@table"),
				       record_id, Qnil));
	}
    }

    return Qnil;
}
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);
}
示例#17
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;
}
示例#18
0
/*
 * call-seq:
 *   table_cursor.next -> Groonga::Record
 *
 * カレントレコードを一件進めてそのレコードを返す。
 */
static VALUE
rb_grn_table_cursor_next (VALUE self)
{
    VALUE rb_record = Qnil;
    grn_ctx *context;
    grn_table_cursor *cursor;

    rb_grn_table_cursor_deconstruct(SELF(self), &cursor, &context,
				    NULL, NULL, NULL, NULL);
    if (context && cursor) {
        grn_id record_id;

        record_id = grn_table_cursor_next(context, cursor);
        if (record_id != GRN_ID_NIL) /* FIXME: use grn_table_cursor_table */
            rb_record = rb_grn_record_new(rb_iv_get(self, "@table"),
					  record_id, Qnil);
    }

    return rb_record;
}
示例#19
0
文件: obj.c 项目: digideskio/groonga
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);
}
示例#20
0
文件: index.c 项目: ikdttr/groonga
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);
    }
  }
}
示例#21
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;
}
示例#22
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();
}
void
test_prefix_geo_point(gpointer data)
{
  grn_id id;
  grn_obj min, min_string;
  int offset, limit, flags;
  unsigned min_size;
  const GList *expected_keys;
  GList *actual_keys = NULL;

  create_geo_point_table(
    geo_byte_load_data(
      "00000000 00111111 01010000 00110000 01001010 01011100 01101010 00010001",
      "00000000 00111111 01010000 00001101 01011101 01011011 01011001 01010011",
      "00000000 00111111 01010000 00000001 00011110 01010001 01101001 00110000",
      "00000000 00111111 01010000 00011000 01110000 00001011 00101110 01001010",
      "00000000 00111111 01010000 00010010 00110001 00110111 01111000 01110000",
      "00000000 00111111 01010000 00010010 00110001 00001000 00001010 00110011",
      "00000000 00111111 01010000 00101110 01110010 00111001 00011011 01101010",
      "00000000 00111111 01010000 00101101 00101000 00111111 01010110 00010110",
      "00000000 00111111 01010000 00101111 01001010 01101000 01000100 01100011",
      "00000000 00111111 01010000 00101111 00011000 01000110 00100101 01011110",
      "00000000 00111111 01000101 01011001 01010110 00000111 00110100 01111111",
      "00000000 00111111 01000101 01010010 01100101 01100110 00010111 01111110",
      "00000000 00111111 01000101 01111111 01011011 01111101 00001001 01100001",
      "00000000 00111111 01010000 00100011 00001010 00000000 00001101 00111010",
      "00000000 00111111 01010000 00101110 01010011 00101001 00101001 00100011",
      "00000000 00111111 01010000 00111010 01011111 00000010 00101001 01010000",
      "00000000 00111111 01010000 00111001 00111101 00001001 00001011 01010011",
      "00000000 00111111 01000101 01011100 00001100 01000001 01011010 00010011",
      "00000000 00111111 01010000 00100011 00000001 00000111 01011100 01110011",
      "00000000 00111111 01010000 00100011 01100100 01011000 00000111 01110010",
      "00000000 00111111 01010000 00111000 01100100 01101011 01111100 01111011",
      "00000000 00111111 01010000 00001111 00101011 00011111 00110011 00001001",
      "00000000 00111111 01000101 01111011 01001011 01101011 00001001 00000001",
      "00000000 00111111 01000101 01011010 00110100 00000010 01111010 00000000",
      "00000000 00111111 01000101 01011011 00011010 00010111 00011000 00100000",
      "00000000 00111111 01010000 00100000 00010111 01000111 00110100 00101010",
      "00000000 00111111 01010000 00000000 01111101 00010000 00011101 00001111",
      "00000000 00111111 01000101 01000100 01010010 00100100 01100011 00111011",
      "00000000 00111111 01000101 01010001 00011100 01010110 00100110 00000110",
      "00000000 00111111 01010000 00101101 01111100 01101100 00111000 01111001",
      "00000000 00111111 01000101 01001101 00111110 00000101 00101010 01000101",
      "00000000 00111111 01000101 01000100 01111100 01101011 01101111 00010101",
      "00000000 00111111 01000101 01110111 01010100 01110100 01111000 01111000",
      "00000000 00111111 01010000 00100010 00111011 01000000 00111000 01100100",
      "00000000 00111111 01010000 00100010 00100111 01000011 00000010 01101001",
      "00000000 00111111 01000101 01011100 00110110 00100010 00111000 01100001",
      "00000000 00111101 01010101 00111101 01110000 01001011 01110011 00101100",
      "00000000 00111101 00000101 00111101 01110000 01001011 01110011 00101100",
      NULL));

  GRN_TEXT_INIT(&min_string, 0);
  GRN_TEXT_PUTS(context, &min_string,
                geo_byte_parse(gcut_data_get_string(data, "min")));
  GRN_WGS84_GEO_POINT_INIT(&min, 0);
  grn_obj_cast(context, &min_string, &min, FALSE);
  grn_obj_unlink(context, &min_string);

  min_size = gcut_data_get_uint(data, "min-size");
  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,
                                 GRN_BULK_HEAD(&min), min_size,
                                 NULL, 0,
                                 offset, limit,
                                 flags | GRN_CURSOR_PREFIX);
  grn_obj_unlink(context, &min);
  grn_test_assert_context(context);
  while ((id = grn_table_cursor_next(context, cursor))) {
    grn_geo_point *key;
    int i, j, key_size;
    uint8_t encoded_key[sizeof(grn_geo_point)];
    GString *geo_byte;

    key_size = grn_table_cursor_get_key(context, cursor, (void **)&key);
    grn_gton(encoded_key, key, key_size);
    geo_byte = g_string_new(NULL);
    for (i = 0; i < sizeof(grn_geo_point); i++) {
      if (i != 0) {
        g_string_append(geo_byte, " ");
      }
      for (j = 0; j < 8; j++) {
        g_string_append_printf(geo_byte, "%d", (encoded_key[i] >> (7 - j)) & 1);
      }
    }
    actual_keys = g_list_append(actual_keys, g_string_free(geo_byte, FALSE));
  }
  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_prefix_rk(gpointer data)
{
  grn_id id;
  const gchar *min;
  int offset, limit;
  const GList *expected_keys;
  GList *actual_keys = NULL;

  create_short_text_table(
    gcut_take_new_list_string("インデックス",
                              "エヌグラム",
                              "エンジン",
                              "カネソナエタ",
                              "カノウ",
                              "キノウ",
                              "キョウカ",
                              "クミコミ",
                              "クミコム",
                              "グルンガ",
                              "ケンサク",
                              "ケンサクヨウキュウ",
                              "ゲンゴ",
                              "コウセイド",
                              "コウソク",
                              "コンパクト",
                              "サクセイ",
                              "ショリ",
                              "ショリケイ",
                              "ジッソウ",
                              "ジュンスイ",
                              "スクリプト",
                              "セッケイ",
                              "ゼンブン",
                              "タイプ",
                              "タンゴ",
                              "ダイキボ",
                              "テンチ",
                              "ディービーエムエス",
                              "トウ",
                              "トクチョウ",
                              "ブンショリョウ",
                              "ヨウキュウ",
                              NULL));

  min = gcut_data_get_string(data, "min");
  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_CURSOR_RK);
  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));
  }
  actual_keys = g_list_sort(actual_keys, (GCompareFunc)strcmp);
  gcut_take_list(actual_keys, g_free);

  expected_keys = gcut_data_get_pointer(data, "expected");
  gcut_assert_equal_list_string(expected_keys, actual_keys);
}
示例#25
0
void
test_array_sort(gpointer data)
{
  const gint32 values[] = {
    5, 6, 18, 9, 0, 4, 13, 12, 8, 14, 19, 11, 7, 3, 1, 10, 15, 2, 17, 16
  };
  const int n_values = sizeof(values) / sizeof(values[0]);
  const gchar table_name[] = "Store";
  const gchar column_name[] = "sample_column";
  const int n_keys = 1;
  grn_table_sort_key keys[n_keys];

  grn_obj *table, *column, *result;
  grn_table_cursor *cursor;
  int n_results;
  guint i;

  guint n_expected_values;
  GList *expected_values, *sorted_values = NULL;

  table = grn_table_create(context, table_name, strlen(table_name),
                           NULL,
                           GRN_OBJ_TABLE_NO_KEY | GRN_OBJ_PERSISTENT,
                           NULL,
                           NULL);
  column = grn_column_create(context,
                             table,
                             column_name,
                             strlen(column_name),
                             NULL, 0,
                             get_object("Int32"));

  keys[0].key = column;
  keys[0].flags = GRN_TABLE_SORT_ASC;

  for(i = 0; i < n_values; ++i) {
    grn_obj record_value;
    grn_id record_id;
    record_id = grn_table_add(context, table, NULL, 0, NULL);

    GRN_INT32_INIT(&record_value, 0);
    GRN_INT32_SET(context, &record_value, values[i]);
    grn_test_assert(grn_obj_set_value(context, column, record_id,
                                      &record_value, GRN_OBJ_SET));
    GRN_OBJ_FIN(context, &record_value);
  }
  cut_assert_equal_int(n_values, grn_table_size(context, table));

  result = grn_table_create(context, NULL, 0, NULL, GRN_TABLE_NO_KEY,
                            NULL, table);
  n_results = grn_table_sort(context, table,
                             gcut_data_get_int(data, "offset"),
                             gcut_data_get_int(data, "limit"),
                             result, keys, n_keys);
  expected_values = (GList *)gcut_data_get_pointer(data, "expected_values");
  n_expected_values = g_list_length(expected_values);
  cut_assert_equal_int(n_expected_values, n_results);
  cut_assert_equal_int(n_expected_values, grn_table_size(context, result));

  cursor = grn_table_cursor_open(context, result, NULL, 0, NULL, 0,
                                 0, -1, GRN_CURSOR_ASCENDING);
  while (grn_table_cursor_next(context, cursor) != GRN_ID_NIL) {
    void *value;
    grn_id *id;
    grn_obj record_value;

    grn_table_cursor_get_value(context, cursor, &value);
    id = value;

    GRN_INT32_INIT(&record_value, 0);
    grn_obj_get_value(context, column, *id, &record_value);
    sorted_values = g_list_append(sorted_values,
                                  GINT_TO_POINTER(GRN_INT32_VALUE(&record_value)));
    GRN_OBJ_FIN(context, &record_value);
  }
  gcut_take_list(sorted_values, NULL);
  gcut_assert_equal_list_int(expected_values, sorted_values);

  grn_table_cursor_close(context, cursor);
  grn_obj_close(context, result);
}
示例#26
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));
}
示例#27
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);
}
void
test_near_geo_point(gpointer data)
{
  grn_id id;
  int min_size, offset, limit, flags;
  grn_obj max_string, max;
  const GList *expected_keys;
  GList *actual_keys = NULL;

  create_geo_point_table(
    cut_take_printf(" [\"%s\"],"
                    " [\"%s\"],"
                    " [\"%s\"],"
                    " [\"%s\"],"
                    " [\"%s\"],"
                    " [\"%s\"],"
                    " [\"%s\"],"
                    " [\"%s\"],"
                    " [\"%s\"]",
                    TAKEN_POINT(1, 2, 3,
                                4, 5, 6),
                    TAKEN_POINT(1, 2, 3,
                                7, 8, 9),
                    TAKEN_POINT(7, 8, 9,
                                4, 5, 6),
                    TAKEN_POINT(89, 59, 59,
                                179, 59, 59),
                    TAKEN_POINT(89, 59, 59,
                                179, -59, -59),
                    TAKEN_POINT(88, 58, 58,
                                178, 58, 58),
                    TAKEN_POINT(-89, -59, -59,
                                -179, -59, -59),
                    TAKEN_POINT(-89, -59, -59,
                                179, 59, 59),
                    TAKEN_POINT(-88, -58, -58,
                                -178, -58, -58)));

  min_size = gcut_data_get_int(data, "min-size");
  GRN_TEXT_INIT(&max_string, 0);
  GRN_TEXT_PUTS(context, &max_string, gcut_data_get_string(data, "max"));
  GRN_WGS84_GEO_POINT_INIT(&max, 0);
  grn_obj_cast(context, &max_string, &max, FALSE);
  grn_obj_unlink(context, &max_string);
  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,
                                 GRN_BULK_HEAD(&max), GRN_BULK_VSIZE(&max),
                                 offset, limit,
                                 flags | GRN_CURSOR_PREFIX);
  grn_obj_unlink(context, &max);
  grn_test_assert_context(context);
  while ((id = grn_table_cursor_next(context, cursor))) {
    grn_geo_point *key;
    int key_size;

    key_size = grn_table_cursor_get_key(context, cursor, (void **)&key);
    actual_keys = g_list_append(actual_keys,
                                g_strdup_printf("%dx%d",
                                                key->latitude,
                                                key->longitude));
  }
  gcut_take_list(actual_keys, g_free);

  expected_keys = gcut_data_get_pointer(data, "expected");
  gcut_assert_equal_list_string(expected_keys, actual_keys);
}
示例#29
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));
}
示例#30
0
void
test_mroonga_index_score(void)
{
    grn_obj *t1,*c1,*lc,*ft;
    grn_obj buff;
    grn_id r1,r2,r3,r4;

    remove_tmp_directory();
    g_mkdir_with_parents(tmp_directory,0700);
    g_chdir(tmp_directory);
    g_mkdir_with_parents("mrn",0700);

    db = grn_db_create(context,"mroonga.grn",NULL);
    cut_assert_not_null(db);

    /* actual table */
    t1 = grn_table_create(context,"t1",2,"mrn/t1.grn",
                          GRN_OBJ_TABLE_NO_KEY|GRN_OBJ_PERSISTENT,NULL,0);
    cut_assert_not_null(t1);

    /* lexicon table */
    lc = grn_table_create(context,"lc",2,"mrn/lc.grn",
                          GRN_OBJ_TABLE_PAT_KEY|GRN_OBJ_PERSISTENT,
                          grn_ctx_at(context, GRN_DB_SHORT_TEXT), 0);
    cut_assert_not_null(lc);
    grn_test_assert(grn_obj_set_info(context, lc, GRN_INFO_DEFAULT_TOKENIZER,
                                     grn_ctx_at(context, GRN_DB_BIGRAM)));

    /* actual column */
    c1 = grn_column_create(context,t1,"c1",2,"mrn/t1.c1.grn",
                           GRN_OBJ_COLUMN_SCALAR|GRN_OBJ_PERSISTENT,
                           grn_ctx_at(context, GRN_DB_TEXT));
    cut_assert_not_null(c1);

    /* fulltext index */
    ft = grn_column_create(context,lc,"ft",2,"mrn/lc.ft.grn",
                           GRN_OBJ_COLUMN_INDEX|GRN_OBJ_PERSISTENT,t1);
    cut_assert_not_null(ft);

    GRN_TEXT_INIT(&buff,0);

    /* link between actual column and fulltext index */
    GRN_UINT32_SET(context, &buff, grn_obj_id(context, c1));
    grn_obj_set_info(context, ft, GRN_INFO_SOURCE, &buff); /* need to use grn_id */

    /* insert row */
    r1 = grn_table_add(context, t1, NULL, 0, NULL);
    cut_assert_equal_int(1,r1);
    GRN_TEXT_SETS(context, &buff, "abcde");
    grn_test_assert(grn_obj_set_value(context, c1, r1, &buff, GRN_OBJ_SET));

    r2 = grn_table_add(context, t1, NULL, 0, NULL);
    cut_assert_equal_int(2,r2);
    GRN_TEXT_SETS(context, &buff, "fghij");
    grn_test_assert(grn_obj_set_value(context, c1, r2, &buff, GRN_OBJ_SET));

    r3 = grn_table_add(context, t1, NULL, 0, NULL);
    cut_assert_equal_int(3,r3);
    GRN_TEXT_SETS(context, &buff, "11 22 33");
    grn_test_assert(grn_obj_set_value(context, c1, r3, &buff, GRN_OBJ_SET));

    r4 = grn_table_add(context, t1, NULL, 0, NULL);
    cut_assert_equal_int(4,r4);
    GRN_TEXT_SETS(context, &buff, "44 22 55");
    grn_test_assert(grn_obj_set_value(context, c1, r4, &buff, GRN_OBJ_SET));

    /* confirm record are inserted in both column and index */
    cut_assert_equal_int(4,grn_table_size(context,t1));
    cut_assert_equal_int(23,grn_table_size(context,lc));

    /* nlq search */
    {
        grn_id id, docid;
        grn_obj *res;
        grn_table_cursor *tc;
        grn_obj score, *score_column;
        res = grn_table_create(context, NULL, 0, NULL,
                               GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC, t1, 0);
        GRN_UINT32_INIT(&score, 0);
        GRN_BULK_REWIND(&buff);
        GRN_TEXT_SETS(context, &buff, "hij");
        grn_obj_search(context, ft, &buff, res, GRN_OP_OR, NULL);
        cut_assert_equal_int(1, grn_table_size(context, res));
        score_column = grn_obj_column(context, res, ".:score", 7);
        tc = grn_table_cursor_open(context, res, NULL, 0, NULL, 0, 0, 0, 0);
        while ((id = grn_table_cursor_next(context, tc))) {
            GRN_BULK_REWIND(&buff);
            grn_table_get_key(context, res, id, &docid, sizeof(grn_id));
            cut_assert_equal_int(2, docid);
            cut_assert_not_null(grn_obj_get_value(context, c1, docid, &buff));
            cut_assert_equal_int(5 ,GRN_TEXT_LEN(&buff));
            cut_assert_equal_substring("fghij", (char*) GRN_BULK_HEAD(&buff),GRN_TEXT_LEN(&buff));
            grn_obj_get_value(context, score_column, id, &score);
            cut_assert_equal_uint(1, GRN_UINT32_VALUE(&score));
        }
        grn_table_cursor_close(context, tc);
        grn_obj_close(context, score_column);
        grn_obj_close(context, res);
    }

    /* boolean search */
    {
        grn_id id, docid;
        grn_obj *res;
        grn_query *query;
        grn_table_cursor *tc;
        grn_obj score, *score_column;
        const char *qstr = "+22 -55";
        res = grn_table_create(context, NULL, 0, NULL,
                               GRN_TABLE_HASH_KEY|GRN_OBJ_WITH_SUBREC, t1, 0);
        GRN_UINT32_INIT(&score, 0);
        query = grn_query_open(context, qstr, strlen(qstr), GRN_OP_OR, 32);
        grn_obj_search(context, ft, (grn_obj*) query, res, GRN_OP_OR, NULL);
        cut_assert_equal_int(1, grn_table_size(context, res));
        score_column = grn_obj_column(context, res, ".:score", 7);
        tc = grn_table_cursor_open(context, res, NULL, 0, NULL, 0, 0, 0, 0);
        while ((id = grn_table_cursor_next(context, tc))) {
            GRN_BULK_REWIND(&buff);
            grn_table_get_key(context, res, id, &docid, sizeof(grn_id));
            cut_assert_equal_int(3, docid);
            cut_assert_not_null(grn_obj_get_value(context, c1, docid, &buff));
            cut_assert_equal_int(8 ,GRN_TEXT_LEN(&buff));
            cut_assert_equal_substring("11 22 33", (char*) GRN_BULK_HEAD(&buff),GRN_TEXT_LEN(&buff));
            grn_obj_get_value(context, score_column, id, &score);
            cut_assert_equal_uint(5, GRN_UINT32_VALUE(&score));
        }
        grn_query_close(context, query);
        grn_table_cursor_close(context ,tc);
        grn_obj_close(context, score_column);
        grn_obj_close(context, res);
    }

    grn_obj_close(context, &buff);
    grn_obj_close(context, ft);
    grn_obj_close(context, c1);
    grn_obj_close(context, lc);
    grn_obj_close(context, t1);
}