Пример #1
0
/*
 * Document-method: column_value
 *
 * call-seq:
 *   view.column_value(id, name) -> 値
 *
 * _view_の_id_に対応するカラム_name_の値を返す。
 */
static VALUE
rb_grn_view_get_column_value (VALUE self, VALUE rb_id, VALUE rb_name)
{
    VALUE rb_value = Qnil;
#ifdef WIN32
    rb_raise(rb_eNotImpError,
             "grn_obj_get_value_o() isn't available on Windows.");
#else
    RbGrnTable *rb_view;
    grn_ctx *context = NULL;
    grn_obj *view, *value, *accessor;
    grn_obj id;

    rb_view = SELF(self);
    rb_grn_table_deconstruct(rb_view, &view, &context,
                             NULL, NULL,
                             &value, NULL, NULL,
                             NULL);
    GRN_BULK_REWIND(value);
    GRN_TEXT_INIT(&id, 0);
    GRN_TEXT_PUT(context, &id, RSTRING_PTR(rb_id), RSTRING_LEN(rb_id));
    accessor = grn_obj_column(context, view,
                              RSTRING_PTR(rb_name), RSTRING_LEN(rb_name));
    grn_obj_get_value_o(context, accessor, &id, value);
    grn_obj_unlink(context, accessor);
    rb_value = GRNOBJ2RVAL(Qnil, context, value, self);
    GRN_OBJ_FIN(context, &id);
#endif

    return rb_value;
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
/*
 * call-seq:
 *   view.add_table(table)
 *
 * _table_をビューからアクセスできるようにする。
 */
static VALUE
rb_grn_view_add_table (VALUE self, VALUE rb_table)
{
#ifdef WIN32
    rb_raise(rb_eNotImpError, "grn_view_add() isn't available on Windows.");
#else
    grn_ctx *context = NULL;
    grn_obj *view, *table;

    rb_grn_table_deconstruct(SELF(self), &view, &context,
                             NULL, NULL,
                             NULL, NULL, NULL,
                             NULL);
    table = RVAL2GRNOBJECT(rb_table, &context);
    grn_view_add(context, view, table);
    rb_grn_context_check(context, self);
#endif

    return Qnil;
}
Пример #5
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;
}
Пример #6
0
void
rb_grn_table_key_support_deconstruct (RbGrnTableKeySupport *rb_grn_table_key_support,
                                      grn_obj **table_key_support,
                                      grn_ctx **context,
                                      grn_obj **key,
                                      grn_id *domain_id,
                                      grn_obj **domain,
                                      grn_obj **value,
                                      grn_id *range_id,
                                      grn_obj **range,
                                      VALUE *columns)
{
    RbGrnTable *rb_grn_table;

    rb_grn_table = RB_GRN_TABLE(rb_grn_table_key_support);

    rb_grn_table_deconstruct(rb_grn_table, table_key_support, context,
                             domain_id, domain,
                             value, range_id, range,
                             columns);

    if (key)
        *key = rb_grn_table_key_support->key;
}
Пример #7
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;
}
Пример #8
0
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;
}