/*
 * call-seq:
 *   patricia_trie.prefix_search(prefix) -> Groonga::Hash
 *
 * キーが_prefix_に前方一致するレコードのIDがキーに入っている
 * Groonga::Hashを返す。マッチするレコードがない場合は空の
 * Groonga::Hashが返る。
 *
 */
static VALUE
rb_grn_patricia_trie_prefix_search (VALUE self, VALUE rb_prefix)
{
    grn_ctx *context;
    grn_obj *table, *key, *domain, *result;
    grn_id domain_id;
    VALUE rb_result;

    rb_grn_table_key_support_deconstruct(SELF(self), &table, &context,
					 &key, &domain_id, &domain,
					 NULL, NULL, NULL,
					 NULL);

    result = grn_table_create(context, NULL, 0, NULL,
			      GRN_OBJ_TABLE_HASH_KEY,
			      table, 0);
    rb_grn_context_check(context, self);
    rb_result = GRNOBJECT2RVAL(Qnil, context, result, GRN_TRUE);

    GRN_BULK_REWIND(key);
    RVAL2GRNKEY(rb_prefix, context, key, domain_id, domain, self);
    grn_pat_prefix_search(context, (grn_pat *)table,
			  GRN_BULK_HEAD(key), GRN_BULK_VSIZE(key),
			  (grn_hash *)result);
    rb_grn_context_check(context, self);

    return rb_result;
}
Exemple #2
0
/*
 * call-seq:
 *   Groonga::Array.create(options={})                -> Groonga::Array
 *   Groonga::Array.create(options={}) {|table| ... }
 *
 * キーのないテーブルを生成する。ブロックを指定すると、そのブ
 * ロックに生成したテーブルが渡され、ブロックを抜けると自動的
 * にテーブルが破棄される。
 *
 * @example
 *   #無名一時テーブルを生成する。
 *   Groonga::Array.create
 *
 *   #無名永続テーブルを生成する。
 *   Groonga::Array.create(:path => "/tmp/array.grn")
 *
 *   #名前付き永続テーブルを生成する。ただし、ファイル名は気にしない。
 *   Groonga::Array.create(:name => "Bookmarks",
 *                         :persistent => true)
 *
 *   #それぞれのレコードに512バイトの値を格納できる無名一時テーブルを生成する。
 *   Groonga::Array.create(:value => 512)
 *
 * @param [::Hash] options The name and value
 *   pairs. Omitted names are initialized as the default value.
 * @option options [Grrnga::Context] :context (Groonga::Context.default) The context
 *   テーブルが利用するGrrnga::Context
 * @option options :name The name
 *   テーブルの名前。名前をつけると、Groonga::Context#[]に名
 *   前を指定してテーブルを取得することができる。省略すると
 *   無名テーブルになり、テーブルIDでのみ取得できる。
 * @option options :path The path
 *   テーブルを保存するパス。パスを指定すると永続テーブルとな
 *   り、プロセス終了後もレコードは保持される。次回起動時に
 *   Groonga::Context#[]で保存されたレコードを利用することが
 *   できる。省略すると一時テーブルになり、プロセスが終了する
 *   とレコードは破棄される。
 * @option options :persistent The persistent
 *   +true+ を指定すると永続テーブルとなる。 +path+ を省略した
 *   場合は自動的にパスが付加される。 +:context+ で指定した
 *   Groonga::Contextに結びついているデータベースが一時デー
 *   タベースの場合は例外が発生する。
 * @option options :value_type (nil) The value_type
 *   値の型を指定する。省略すると値のための領域を確保しない。
 *   値を保存したい場合は必ず指定すること。
 *   参考: Groonga::Type.new
 * @option options [Groonga::Record#n_sub_records] :sub_records The sub_records
 *   +true+ を指定すると#groupでグループ化したときに、
 *   Groonga::Record#n_sub_recordsでグループに含まれるレコー
 *   ドの件数を取得できる。
 */
static VALUE
rb_grn_array_s_create (int argc, VALUE *argv, VALUE klass)
{
    grn_ctx *context = NULL;
    grn_obj *value_type = NULL, *table;
    const char *name = NULL, *path = NULL;
    unsigned name_size = 0;
    grn_obj_flags flags = GRN_OBJ_TABLE_NO_KEY;
    VALUE rb_table;
    VALUE options, rb_context, rb_name, rb_path, rb_persistent;
    VALUE rb_value_type, rb_sub_records;

    rb_scan_args(argc, argv, "01", &options);

    rb_grn_scan_options(options,
			"context", &rb_context,
			"name", &rb_name,
                        "path", &rb_path,
			"persistent", &rb_persistent,
			"value_type", &rb_value_type,
			"sub_records", &rb_sub_records,
			NULL);

    context = rb_grn_context_ensure(&rb_context);

    if (!NIL_P(rb_name)) {
        name = StringValuePtr(rb_name);
	name_size = RSTRING_LEN(rb_name);
	flags |= GRN_OBJ_PERSISTENT;
    }

    if (!NIL_P(rb_path)) {
        path = StringValueCStr(rb_path);
	flags |= GRN_OBJ_PERSISTENT;
    }

    if (RVAL2CBOOL(rb_persistent))
	flags |= GRN_OBJ_PERSISTENT;

    if (!NIL_P(rb_value_type))
	value_type = RVAL2GRNOBJECT(rb_value_type, &context);

    if (RVAL2CBOOL(rb_sub_records))
	flags |= GRN_OBJ_WITH_SUBREC;

    table = grn_table_create(context, name, name_size, path,
			     flags, NULL, value_type);
    if (!table)
	rb_grn_context_check(context, rb_ary_new4(argc, argv));
    rb_table = GRNOBJECT2RVAL(klass, context, table, GRN_TRUE);
    rb_grn_context_check(context, rb_table);
    rb_iv_set(rb_table, "@context", rb_context);

    if (rb_block_given_p())
        return rb_ensure(rb_yield, rb_table, rb_grn_object_close, rb_table);
    else
        return rb_table;
}
Exemple #3
0
/*
 * Sets a configuration key and value pair.
 *
 * @overload config[]=(key, value)
 *   @param [String] key The key.
 *   @param [String] value The value to be assigned.
 *   @return [String] `value`.
 */
static VALUE
rb_grn_config_set (VALUE self, VALUE rb_key, VALUE rb_value)
{
    VALUE rb_value_original = rb_value;
    VALUE rb_context;
    grn_ctx *context;
    const char *key;
    int key_size;
    const char *value;
    int value_size;

    rb_context = rb_iv_get(self, "@context");
    context = rb_grn_context_ensure(&rb_context);

    rb_key = rb_grn_convert_to_string(rb_key);
    key = RSTRING_PTR(rb_key);
    key_size = RSTRING_LEN(rb_key);

    rb_value = rb_grn_convert_to_string(rb_value);
    value = RSTRING_PTR(rb_value);
    value_size = RSTRING_LEN(rb_value);

    {
        grn_rc rc;
        rc = grn_config_set(context,
                            key, key_size,
                            value, value_size);
        rb_grn_context_check(context, self);
        rb_grn_rc_check(rc, self);
    }

    return rb_value_original;
}
Exemple #4
0
/*
 * Gets a configuration value for key.
 *
 * @overload config[](key)
 *   @param [String] key The key.
 *   @return [String, nil] The value associated with `key`.
 *
 * @since 5.0.9
 */
static VALUE
rb_grn_config_get (VALUE self, VALUE rb_key)
{
    VALUE rb_context;
    VALUE rb_value;
    grn_ctx *context;
    const char *key;
    int key_size;
    const char *value;
    uint32_t value_size;

    rb_context = rb_iv_get(self, "@context");
    context = rb_grn_context_ensure(&rb_context);

    rb_key = rb_grn_convert_to_string(rb_key);
    key = RSTRING_PTR(rb_key);
    key_size = RSTRING_LEN(rb_key);

    {
        grn_rc rc;
        rc = grn_config_get(context,
                            key, key_size,
                            &value, &value_size);
        rb_grn_context_check(context, self);
        rb_grn_rc_check(rc, self);
    }

    if (value_size == 0) {
        rb_value = Qnil;
    } else {
        rb_value = rb_grn_context_rb_string_new(context, value, value_size);
    }

    return rb_value;
}
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;
}
/*
 * Normalizes the @string@.
 *
 * @example
 *   # Normalizes "ABC" with the default normalizer
 *   Groonga::Normalizer.normalize("AbC") # => "abc"
 *
 * @overload normalize(string)
 *   @return [String] The normalized string
 *   @param [String] string The original string
 */
static VALUE
rb_grn_normalizer_s_normalize (VALUE klass, VALUE rb_string)
{
    VALUE rb_context = Qnil;
    VALUE rb_encoded_string;
    VALUE rb_normalized_string;
    grn_ctx *context = NULL;
    grn_obj *grn_string;
    grn_obj *normalizer = GRN_NORMALIZER_AUTO;
    /* TODO: make customizable */
    int flags = GRN_STRING_REMOVE_BLANK;
    const char *normalized_string;
    unsigned int normalized_string_length;

    context = rb_grn_context_ensure(&rb_context);
    rb_encoded_string = rb_grn_context_rb_string_encode(context, rb_string);
    grn_string = grn_string_open(context,
                                 RSTRING_PTR(rb_encoded_string),
                                 RSTRING_LEN(rb_encoded_string),
                                 normalizer,
                                 flags);
    rb_grn_context_check(context, rb_string);
    grn_string_get_normalized(context, grn_string,
                              &normalized_string, &normalized_string_length,
                              NULL);
    rb_normalized_string =
        rb_grn_context_rb_string_new(context,
                                     normalized_string,
                                     normalized_string_length);
    grn_obj_close(context, grn_string);

    return rb_normalized_string;
}
/*
 * @overload register(event_source_name, options={})
 *
 *   Registers Windows Event Log based logger that uses
 *   `event_source_name` as event source name.
 *
 *   @param event_source_name [String] The event source name.
 *   @param options [::Hash]
 *   @option options :context [Groonga::Context] (Groonga::Context.default)
 *     The context to be set logger.
 *
 *   @return [void]
 *
 *   @since 5.0.5
 */
static VALUE
rb_grn_windows_event_logger_s_register (int argc,
                                        VALUE *argv,
                                        VALUE klass)
{
    VALUE rb_event_source_name;
    VALUE rb_options;
    VALUE rb_context;
    const char *event_source_name;
    grn_ctx *context;
    grn_rc rc;

    rb_scan_args(argc, argv, "11", &rb_event_source_name, &rb_options);
    rb_event_source_name = rb_grn_convert_to_string(rb_event_source_name);
    event_source_name = StringValueCStr(rb_event_source_name);

    rb_grn_scan_options(rb_options,
                        "context", &rb_context,
                        NULL);
    context = rb_grn_context_ensure(&rb_context);

    rc = grn_windows_event_logger_set(context, event_source_name);
    rb_grn_context_check(context, rb_event_source_name);
    rb_grn_rc_check(rc, rb_event_source_name);

    return Qnil;
}
Exemple #8
0
/*
 * call-seq:
 *   column.sources -> Groonga::Columnの配列
 *
 * インデックス対象となっているカラムの配列を返す。
 */
static VALUE
rb_grn_index_column_get_sources (VALUE self)
{
    grn_ctx *context = NULL;
    grn_obj *column;
    grn_obj sources;
    grn_id *source_ids;
    VALUE rb_sources;
    int i, n;

    rb_grn_index_column_deconstruct(SELF(self), &column, &context,
				    NULL, NULL,
				    NULL, NULL, NULL, NULL,
				    NULL, NULL);

    GRN_OBJ_INIT(&sources, GRN_BULK, 0, GRN_ID_NIL);
    grn_obj_get_info(context, column, GRN_INFO_SOURCE, &sources);
    rb_grn_context_check(context, self);

    n = GRN_BULK_VSIZE(&sources) / sizeof(grn_id);
    source_ids = (grn_id *)GRN_BULK_HEAD(&sources);
    rb_sources = rb_ary_new2(n);
    for (i = 0; i < n; i++) {
	grn_obj *source;
	VALUE rb_source;

	source = grn_ctx_at(context, *source_ids);
	rb_source = GRNOBJECT2RVAL(Qnil, context, source, RB_GRN_FALSE);
	rb_ary_push(rb_sources, rb_source);
	source_ids++;
    }
    grn_obj_unlink(context, &sources);

    return rb_sources;
}
Exemple #9
0
/*
 * @overload [](id)
 *   @param id [Integer, Groonga::Record] The record ID for the
 *     column value.
 *
 *   @return [Object] The value for the record ID.
 */
static VALUE
rb_grn_column_cache_array_reference (VALUE self, VALUE rb_id)
{
    RbGrnColumnCache *rb_grn_column_cache;
    grn_id id;
    void *value;
    size_t value_size = 0;

    TypedData_Get_Struct(self,
                         RbGrnColumnCache,
                         &data_type,
                         rb_grn_column_cache);

    if (!rb_grn_column_cache->column_cache) {
        return Qnil;
    }

    id = rb_grn_id_from_ruby_object(rb_id,
                                    rb_grn_column_cache->context,
                                    rb_grn_column_cache->table,
                                    self);
    value = grn_column_cache_ref(rb_grn_column_cache->context,
                                 rb_grn_column_cache->column_cache,
                                 id,
                                 &value_size);
    rb_grn_context_check(rb_grn_column_cache->context, self);
    GRN_TEXT_SET_REF(&(rb_grn_column_cache->buffer),
                     value,
                     value_size);

    return GRNBULK2RVAL(rb_grn_column_cache->context,
                        &(rb_grn_column_cache->buffer),
                        rb_grn_column_cache->range,
                        self);
}
Exemple #10
0
/*
 * 既存のデータベースを開く。ブロックを指定した場合はブロッ
 * クに開いたデータベースを渡し、ブロックを抜けるときに閉じ
 * る。
 *
 * @overload new(path, options=nil)
 *   @!macro [new] database.new.arguments
 *     @param options [::Hash] The name and value
 *       pairs. Omitted names are initialized as the default value.
 *     @option options :context (Groonga::Context.default)
 *       データベースを結びつけるコンテキスト。省略すると
 *       {Groonga::Context.default} を利用する。
 *   @!macro database.new.arguments
 *   @return [Groonga::Database]
 * @overload new(path, options=nil)
 *   @!macro database.new.arguments
 *   @yield [database]
 *   @yieldparam [Groonga::Database] database 開いたデータベース
 */
static VALUE
rb_grn_database_initialize (int argc, VALUE *argv, VALUE self)
{
    grn_ctx *context;
    grn_obj *old_database, *database;
    const char *path;
    VALUE rb_path, options, rb_context;

    rb_scan_args(argc, argv, "11", &rb_path, &options);

    path = StringValuePtr(rb_path);
    rb_grn_scan_options(options,
                        "context", &rb_context,
                        NULL);

    context = rb_grn_context_ensure(&rb_context);

    old_database = grn_ctx_db(context);
    if (old_database)
        grn_obj_unlink(context, old_database);
    reset_floating_objects(rb_context);
    database = grn_db_open(context, path);
    rb_grn_object_assign(Qnil, self, rb_context, context, database);
    rb_grn_context_check(context, self);

    rb_iv_set(self, "@context", rb_context);
    if (!NIL_P(rb_context))
        rb_iv_set(rb_context, "database", self);

    return Qnil;
}
Exemple #11
0
/*
 * Flush memory mapped data to disk.
 *
 * @overload flush(options={})
 *   @param [::Hash] options
 *   @option options [Boolean] :recursive (true) Whether to flush objects
 *     which a target object has recursively.
 *   @return [void]
 */
static VALUE
rb_grn_flushable_flush (int argc, VALUE *argv, VALUE self)
{
    grn_ctx *context = NULL;
    grn_obj *object = NULL;
    VALUE rb_recursive_p;
    VALUE rb_options;

    rb_scan_args(argc, argv, "01", &rb_options);
    rb_grn_scan_options(rb_options,
                        "recursive", &rb_recursive_p,
                        NULL);
    if (NIL_P(rb_recursive_p)) {
        rb_recursive_p = Qtrue;
    }

    rb_grn_object_deconstruct(SELF(self), &object, &context,
                              NULL, NULL, NULL, NULL);
    if (!object) {
        rb_raise(rb_eGrnClosed,
                 "can't access already closed Groonga object: <%s>",
                 rb_grn_inspect(self));
    }

    if (RVAL2CBOOL(rb_recursive_p)) {
        grn_obj_flush_recursive(context, object);
    } else {
        grn_obj_flush(context, object);
    }
    rb_grn_context_check(context, self);

    return Qnil;
}
Exemple #12
0
/*
 * _object_ を追加し、 _n_arguments_ 個の引数を取る _operation_ を追加する。
 *
 * @overload append_object(object, operation=Groonga::Operator::PUSH, n_arguments=1)
 *   @param [Object] object 追加するオブジェクト
 *   @param [Groonga::Operator::XXX] operation 追加する _operation_
 *   @param [Integer] n_arguments _operation_ の取る引数
 * @return [Self] self
 *
 */
static VALUE
rb_grn_expression_append_object (int argc, VALUE *argv, VALUE self)
{
    VALUE rb_object, rb_operation, rb_n_arguments;
    grn_ctx *context = NULL;
    grn_obj *expression, *object;
    grn_operator operation = GRN_OP_PUSH;
    int n_arguments = 1;

    rb_scan_args(argc, argv, "12", &rb_object, &rb_operation, &rb_n_arguments);
    if (!NIL_P(rb_operation))
        operation = RVAL2GRNOPERATOR(rb_operation);
    if (!NIL_P(rb_n_arguments))
        n_arguments = NUM2INT(rb_n_arguments);

    rb_grn_expression_deconstruct(SELF(self), &expression, &context,
                                  NULL, NULL,
                                  NULL, NULL, NULL);

    object = RVAL2GRNOBJECT(rb_object, &context);
    grn_expr_append_obj(context, expression, object,
                        operation, n_arguments);
    rb_grn_context_check(context, self);
    rb_ary_push(rb_iv_get(self, "@objects"), rb_object);

    return self;
}
Exemple #13
0
static VALUE
rb_grn_expression_initialize (int argc, VALUE *argv, VALUE self)
{
    grn_ctx *context = NULL;
    grn_obj *expression;
    VALUE options, rb_context, rb_name;
    char *name = NULL;
    unsigned name_size = 0;

    rb_scan_args(argc, argv, "01", &options);
    rb_grn_scan_options(options,
                        "context", &rb_context,
                        "name", &rb_name,
                        NULL);

    context = rb_grn_context_ensure(&rb_context);

    if (!NIL_P(rb_name)) {
        name = StringValuePtr(rb_name);
        name_size = RSTRING_LEN(rb_name);
    }

    expression = grn_expr_create(context, name, name_size);
    rb_grn_context_check(context, self);
    rb_grn_object_assign(Qnil, self, rb_context, context, expression);
    rb_grn_context_register_floating_object(DATA_PTR(self));

    rb_iv_set(self, "@objects", rb_ary_new());

    return Qnil;
}
Exemple #14
0
/*
 * _database_ をロックする。ロックに失敗した場合は
 * {Groonga::ResourceDeadlockAvoided} 例外が発生する。
 *
 * @overload lock(options={})
 *   @!macro [new] database.lock.arguments
 *     @param [::Hash] options 利用可能なオプションは以下の通り。
 *     @option options :timeout
 *       ロックを獲得できなかった場合は _:timeout_ 秒間ロックの獲
 *       得を試みる。 _:timeout_ 秒以内にロックを獲得できなかった
 *       場合は例外が発生する。
 *   @!macro database.lock.arguments
 * @overload lock(options={})
 *   @yield ブロックを指定した場合はブロックを抜けたときにunlockする。
 *   @!macro database.lock.arguments
 */
static VALUE
rb_grn_database_lock (int argc, VALUE *argv, VALUE self)
{
    grn_ctx *context;
    grn_obj *database;
    int timeout = 0;
    grn_rc rc;
    VALUE options, rb_timeout;

    rb_scan_args(argc, argv, "01",  &options);

    rb_grn_database_deconstruct(SELF(self), &database, &context,
                                NULL, NULL, NULL, NULL);

    rb_grn_scan_options(options,
                        "timeout", &rb_timeout,
                        NULL);

    if (!NIL_P(rb_timeout))
        timeout = NUM2UINT(rb_timeout);

    rc = grn_obj_lock(context, database, GRN_ID_NIL, timeout);
    rb_grn_context_check(context, self);
    rb_grn_rc_check(rc, self);

    if (rb_block_given_p()) {
        return rb_ensure(rb_yield, Qnil, rb_grn_database_unlock, self);
    } else {
        return Qnil;
    }
}
Exemple #15
0
grn_obj *
rb_grn_value_from_ruby_object (VALUE object, grn_ctx *context,
                               grn_obj *value, grn_id type_id, grn_obj *type)
{
    grn_bool string_p, table_type_p;

    string_p = rb_type(object) == T_STRING;
    table_type_p = (GRN_TABLE_HASH_KEY <= type->header.type &&
                    type->header.type <= GRN_TABLE_NO_KEY);
    if (!string_p) {
        return RVAL2GRNBULK_WITH_TYPE(object, context, value, type_id, type);
    }

    if (table_type_p && RSTRING_LEN(object) == 0) {
        if (value) {
            if (value->header.domain != type_id) {
                grn_obj_reinit(context, value, type_id, 0);
            }
        } else {
            value = grn_obj_open(context, GRN_BULK, 0, type_id);
            rb_grn_context_check(context, object);
        }
        GRN_RECORD_SET(context, value, GRN_ID_NIL);
        return value;
    }

    return RVAL2GRNBULK(object, context, value);
}
Exemple #16
0
static int
rb_grn_hash_from_ruby_hash_body (VALUE rb_key,
                                 VALUE rb_value,
                                 VALUE user_data)
{
    RbGrnHashFromRubyHashData *data = (RbGrnHashFromRubyHashData *)user_data;
    grn_obj *value;
    int added;

    rb_key = rb_grn_convert_to_string(rb_key);

    grn_hash_add(data->context,
                 data->hash,
                 RSTRING_PTR(rb_key),
                 RSTRING_LEN(rb_key),
                 (void **)&value,
                 &added);
    rb_grn_context_check(data->context, data->rb_hash);

    if (added) {
        GRN_VOID_INIT(value);
    }
    RVAL2GRNBULK(rb_value, data->context, value);

    return ST_CONTINUE;
}
Exemple #17
0
/*
 * Pushes a record to the array. The record should be filled in the
 * given block. The pushed record can be pulled by
 * {Groonga::Array#pull}.
 *
 * @example A program that pushes a job without error handling
 *   queue = Groonga::Array.create(:name => "CrawlURLQueue")
 *   queue.define_column("url", "ShortText")
 *   urls = ["http://groonga.org/", "http://ranguba.org/"]
 *   urls.each do |url|
 *     queue.push do |record|
 *       record.url = url
 *     end
 *   end
 *
 * @example A program that pulls a job without error handling
 *   queue = Groonga::Array.open(:name => "CrawlURLQueue")
 *   loop do
 *     url = nil
 *     queue.pull do |record|
 *       url = record.url
 *       record.delete
 *     end
 *     # Crawl URL
 *   end
 *
 * The record that is passed to the given block may be nil. You need
 * to handle the case. For example, just ignoring it or reports an
 * error.
 *
 * @example A program that pushes a job with error handling
 *   queue = Groonga::Array.create(:name => "CrawlURLQueue")
 *   queue.define_column("url", "ShortText")
 *   urls = ["http://groonga.org/", "http://ranguba.org/"]
 *   urls.each do |url|
 *     queue.push do |record|
 *       record.url = url if record # check record is not nil
 *     end
 *   end
 *
 * If an error is occurred in the given block, the pushed record may
 * not be filled completely. You should handle the case in pull side.
 *
 * @example A program that has an error in push block
 *   queue = Groonga::Array.create(:name => "CrawlURLQueue")
 *   queue.define_column("url", "ShortText")
 *   urls = ["http://groonga.org/", "http://ranguba.org/"]
 *   urls.each do |url|
 *     queue.push do |record|
 *       record.url = uri # Typo! It should be ur*l* not ur*i*
 *       # record.url isn't set
 *     end
 *   end
 *
 * @example A program that pulls a job with error handling
 *   queue = Groonga::Array.open(:name => "CrawlURLQueue")
 *   loop do
 *     url = nil
 *     queue.pull do |record|
 *       url = record.url # record.url is nil!
 *       record.delete
 *     end
 *     next if url.nil? # Ignore an uncompleted added job
 *     # Crawl URL
 *   end
 *
 * @overload push
 *   @yield [record] Filles columns of a pushed record in the given block.
 *   @yieldparam record [Groonga::Record or nil]
 *     A pushed record. It is nil when pushing is failed.
 *   @return [Groonga::Record or nil] A pushed record that is yielded.
 *
 */
static VALUE
rb_grn_array_push (VALUE self)
{
    grn_ctx *context = NULL;
    grn_obj *table;
    YieldRecordCallbackData data;

    if (!rb_block_given_p()) {
        rb_raise(rb_eArgError,
                 "tried to call Groonga::Array#push without a block");
    }

    table = SELF(self, &context);

    data.self = self;
    data.record = Qnil;
    data.status = 0;
    grn_array_push(context, (grn_array *)table, yield_record_callback, &data);
    if (data.status != 0) {
        rb_jump_tag(data.status);
    }
    rb_grn_context_check(context, self);

    return data.record;
}
/*
 * Defrags the column.
 *
 * @overload defrag(options={})
 *   @param options [::Hash] The name and value
 *     pairs. Omitted names are initialized as the default value.
 *   @option options [Integer] :threshold (0) the threshold to
 *     determine whether a segment is defraged. Available
 *     values are -4..22. -4 means all segments are defraged.
 *     22 means no segment is defraged.
 * @return [Integer] the number of defraged segments
 * @since 1.2.6
 */
static VALUE
rb_grn_variable_size_column_defrag (int argc, VALUE *argv, VALUE self)
{
    RbGrnVariableSizeColumn *rb_grn_column;
    grn_ctx *context = NULL;
    grn_obj *column;
    int n_segments;
    VALUE options, rb_threshold;
    int threshold = 0;

    rb_scan_args(argc, argv, "01", &options);
    rb_grn_scan_options(options,
                        "threshold", &rb_threshold,
                        NULL);
    if (!NIL_P(rb_threshold)) {
        threshold = NUM2INT(rb_threshold);
    }

    rb_grn_column = SELF(self);
    rb_grn_object_deconstruct(RB_GRN_OBJECT(rb_grn_column), &column, &context,
                              NULL, NULL,
                              NULL, NULL);
    n_segments = grn_obj_defrag(context, column, threshold);
    rb_grn_context_check(context, self);

    return INT2NUM(n_segments);
}
/*
 * IDが _id_ であるレコードを高速に全文検索するため転置索引を作
 * 成する。多くの場合、 {Groonga::Table#define_index_column} で
 * +:source+ オプションを指定することにより、自動的に全文検索
 * 用の索引は更新されるので、明示的にこのメソッドを使うこと
 * は少ない。
 *
 * @example 記事の段落毎に索引を作成する。
 *   articles = Groonga::Array.create(:name => "<articles>")
 *   articles.define_column("title", "ShortText")
 *   articles.define_column("content", "Text")
 *
 *   terms = Groonga::Hash.create(:name => "<terms>",
 *                                :default_tokenizer => "TokenBigram")
 *   content_index = terms.define_index_column("content", articles,
 *                                             :with_section => true)
 *
 *   content = <<-EOC
 *   groonga は組み込み型の全文検索エンジンライブラリです。
 *   DBMSやスクリプト言語処理系等に組み込むことによって、その
 *   全文検索機能を強化することができます。また、リレーショナ
 *   ルモデルに基づくデータストア機能を内包しており、groonga
 *   単体でも高速なデータストアサーバとして使用することができ
 *   ます。
 *
 *   ■全文検索方式
 *   転置索引型の全文検索エンジンです。転置索引は圧縮されてファ
 *   イルに格納され、検索時のディスク読み出し量を小さく、かつ
 *   局所的に抑えるように設計されています。用途に応じて以下の
 *   索引タイプを選択できます。
 *   EOC
 *
 *   groonga = articles.add(:title => "groonga", :content => content)
 *
 *   content.split(/\n{2,}/).each_with_index do |sentence, i|
 *     content_index[groonga] = {:value => sentence, :section => i + 1}
 *   end
 *
 *   content_index.search("エンジン").collect do |record|
 *     p record.key["title"] # -> "groonga"
 *   end
 *
 * @overload []=(id, value)
 *   @param [String] value 新しい値
 * @overload []=(id, options)
 *   _options_ を指定することにより、 _value_ を指定したときよりも索引の作
 *   成を制御できる。
 *   @param [::Hash] options The name and value
 *     pairs. Omitted names are initialized as the default value
 *   @option options :section
 *     段落番号を指定する。省略した場合は1を指定したとみなされ
 *     る。
 *     {Groonga::Table#define_index_column} で
 *     @{:with_section => true}@ を指定していなければい
 *     けない。
 *   @option options :old_value
 *     以前の値を指定する。省略した場合は現在の値が用いられる。
 *     通常は指定する必要はない。
 *   @option options :value
 *     新しい値を指定する。 _value_ を指定した場合と _options_ で
 *     @{:value => value}@ を指定した場合は同じ動作とな
 *     る。
 *
 * @deprecated Since 3.0.2. Use {#add}, {#delete} or {#update} instead.
 */
static VALUE
rb_grn_index_column_array_set (VALUE self, VALUE rb_id, VALUE rb_value)
{
    grn_ctx *context = NULL;
    grn_obj *column, *range;
    grn_rc rc;
    grn_id id;
    unsigned int section;
    grn_obj *old_value, *new_value;
    VALUE original_rb_value, rb_section, rb_old_value, rb_new_value;

    original_rb_value = rb_value;

    rb_grn_index_column_deconstruct(SELF(self), &column, &context,
                                    NULL, NULL,
                                    &new_value, &old_value,
                                    NULL, &range,
                                    NULL, NULL);

    id = RVAL2GRNID(rb_id, context, range, self);

    if (!RVAL2CBOOL(rb_obj_is_kind_of(rb_value, rb_cHash))) {
        VALUE hash_value;
        hash_value = rb_hash_new();
        rb_hash_aset(hash_value, RB_GRN_INTERN("value"), rb_value);
        rb_value = hash_value;
    }

    rb_grn_scan_options(rb_value,
                        "section", &rb_section,
                        "old_value", &rb_old_value,
                        "value", &rb_new_value,
                        NULL);

    if (NIL_P(rb_section))
        section = 1;
    else
        section = NUM2UINT(rb_section);

    if (NIL_P(rb_old_value)) {
        old_value = NULL;
    } else {
        GRN_BULK_REWIND(old_value);
        RVAL2GRNBULK(rb_old_value, context, old_value);
    }

    if (NIL_P(rb_new_value)) {
        new_value = NULL;
    } else {
        GRN_BULK_REWIND(new_value);
        RVAL2GRNBULK(rb_new_value, context, new_value);
    }

    rc = grn_column_index_update(context, column,
                                 id, section, old_value, new_value);
    rb_grn_context_check(context, self);
    rb_grn_rc_check(rc, self);

    return original_rb_value;
}
Exemple #20
0
/*
 * Document-method: unlock
 *
 * call-seq:
 *   column.unlock(options={})
 *
 * _column_のロックを解除する。
 *
 * 利用可能なオプションは以下の通り。
 *
 * [_:id_]
 *   _:id_で指定したレコードのロックを解除する。(注:
 *   groonga側が未実装のため、現在は無視される)
 */
static VALUE
rb_grn_column_unlock (int argc, VALUE *argv, VALUE self)
{
    grn_id id = GRN_ID_NIL;
    grn_ctx *context;
    grn_obj *column;
    grn_rc rc;
    VALUE options, rb_id;

    rb_scan_args(argc, argv, "01",  &options);

    rb_grn_column_deconstruct(SELF(self), &column, &context,
			     NULL, NULL,
			     NULL, NULL, NULL);

    rb_grn_scan_options(options,
			"id", &rb_id,
			NULL);

    if (!NIL_P(rb_id))
	id = NUM2UINT(rb_id);

    rc = grn_obj_unlock(context, column, id);
    rb_grn_context_check(context, self);
    rb_grn_rc_check(rc, self);

    return Qnil;
}
Exemple #21
0
/*
 * 名前が _name_ の型を作成する。
 *
 * @overload new(name, options={})
 *   @param name [String] 作成する型の名前
 *   @param options [::Hash] The name and value
 *     pairs. Omitted names are initialized as the default value
 *   @option options [Symbol] :type (:variable)
 *     :integer(符号付き整数)、:int(:integerの省略
 *     形)、:unsigned_integer(符号なし整
 *     数)、:uint(:unsigned_integerの省略形)、:float(浮動小数点
 *     数)、:variable(可変長文字列)のいずれかを指定する。省略した場
 *     合は:variableを指定したものと扱う。
 *     :variableを指定した場合は必ず +:size+ を指定しなければいけない。
 *   @option options [Context] :context
 *     型の作成時に利用するGroonga::Contextを指定する。省略すると
 *     Groonga::Context.defaultを用いる。
 *   @option options [Integer] :size
 *     +:option+ が:variableの場合は最大長、それ以外の場合は長さを
 *     指定する(単位:byte)。
 */
static VALUE
rb_grn_type_initialize (int argc, VALUE *argv, VALUE self)
{
    grn_ctx *context;
    grn_obj *type;
    const char *name = NULL;
    unsigned name_size, size = 0;
    grn_obj_flags flags = 0;
    VALUE rb_name, options, rb_context, rb_type, rb_size;

    rb_scan_args(argc, argv, "11", &rb_name, &options);

    rb_grn_scan_options(options,
                        "context", &rb_context,
                        "type", &rb_type,
                        "size", &rb_size,
                        NULL);

    name = StringValuePtr(rb_name);
    name_size = RSTRING_LEN(rb_name);

    context = rb_grn_context_ensure(&rb_context);

    if (NIL_P(rb_type) ||
        rb_grn_equal_option(rb_type, "variable")) {
        flags = GRN_OBJ_KEY_VAR_SIZE;
    } else if (rb_grn_equal_option(rb_type, "integer") ||
               rb_grn_equal_option(rb_type, "int")) {
        flags = GRN_OBJ_KEY_INT;
        size = sizeof(int);
    } else if (rb_grn_equal_option(rb_type, "unsigned_integer") ||
               rb_grn_equal_option(rb_type, "uint")) {
        flags = GRN_OBJ_KEY_UINT;
        size = sizeof(unsigned int);
    } else if (rb_grn_equal_option(rb_type, "float")) {
        flags = GRN_OBJ_KEY_FLOAT;
        size = sizeof(double);
    } else {
        rb_raise(rb_eArgError,
                 ":type should be one of "
                 "[:integer, :int, :unsigned_integer, :uint, "
                 ":float, :variable]: %s",
                 rb_grn_inspect(options));
    }

    if (NIL_P(rb_size)) {
        if (size == 0)
            rb_raise(rb_eArgError, "size is missing: %s",
                     rb_grn_inspect(options));
    } else {
        size = NUM2UINT(rb_size);
    }

    type = grn_type_create(context, name, name_size, flags, size);
    rb_grn_object_assign(Qnil, self, rb_context, context, type);
    rb_grn_context_check(context, rb_ary_new4(argc, argv));

    return Qnil;
}
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;
}
Exemple #23
0
/*
 * 新しくデータベースを作成する。
 * _options_ にはハッシュでオプションを指定する。
 *
 * @example
 *   # 一時データベースを作成:
 *   Groonga::Database.create
 *
 *   # 永続データベースを作成:
 *   Groonga::Database.create(:path => "/tmp/db.groonga")
 *
 * @overload create(options=nil)
 *   @return [Groonga::Database] 作成されたデータベースを返す。
 *   @param [::Hash] options The name and value
 *     pairs. Omitted names are initialized as the default value.
 *   @option options :path
 *     データベースを保存するパス。省略すると一時データベース
 *     となる。
 *   @option options :context (Groonga::Context.default)
 *     データベースを結びつけるコンテキスト。省略すると
 *     {Groonga::Context.default} を利用する。
 */
static VALUE
rb_grn_database_s_create (int argc, VALUE *argv, VALUE klass)
{
    grn_ctx *context;
    grn_obj *old_database, *database;
    grn_db_create_optarg create_args;
    const char *path = NULL;
    VALUE rb_database;
    VALUE rb_path, options, rb_context, builtin_type_names;
    grn_bool owner;

    rb_scan_args(argc, argv, "01", &options);

    rb_grn_scan_options(options,
                        "path", &rb_path,
                        "context", &rb_context,
                        "builtin_type_names", &builtin_type_names,
                        NULL);

    if (!NIL_P(rb_path))
        path = StringValuePtr(rb_path);
    context = rb_grn_context_ensure(&rb_context);

    create_args.builtin_type_names = NULL;
    create_args.n_builtin_type_names = 0;

    old_database = grn_ctx_db(context);
    if (old_database)
        grn_obj_unlink(context, old_database);
    reset_floating_objects(rb_context);
    database = grn_db_create(context, path, &create_args);
    rb_grn_context_check(context, rb_ary_new_from_values(argc, argv));
    owner = (context->flags & GRN_CTX_PER_DB) ? GRN_FALSE : GRN_TRUE;
    rb_database = GRNOBJECT2RVAL(klass, context, database, owner);
    rb_iv_set(rb_database, "@context", rb_context);
    if (!NIL_P(rb_context))
        rb_iv_set(rb_context, "database", rb_database);
    rb_grn_context_check(context, rb_ary_new_from_values(argc, argv));

    if (rb_block_given_p())
        return rb_ensure(rb_yield, rb_database,
                         rb_grn_database_close, rb_database);
    else
        return rb_database;
}
Exemple #24
0
/*
 * Document-method: search
 *
 * call-seq:
 *   column.search(query, options={}) -> Groonga::Hash
 *
 * _object_から_query_に対応するオブジェクトを検索し、見つかっ
 * たオブジェクトのIDがキーになっているGroonga::Hashを返す。
 *
 * 利用可能なオプションは以下の通り。
 *
 * [_:result_]
 *   結果を格納するGroonga::Hash。指定しない場合は新しく
 *   Groonga::Hashを生成し、それに結果を格納して返す。
 * [_:operator_]
 *   以下のどれかの値を指定する。+nil+, <tt>"or"</tt>, <tt>"||"</tt>,
 *   <tt>"and"</tt>, <tt>"+"</tt>, <tt>"&&"</tt>, <tt>"but"</tt>,
 *   <tt>"not"</tt>, <tt>"-"</tt>, <tt>"adjust"</tt>, <tt>">"</tt>。
 *   それぞれ以下のようになる。(FIXME: 「以下」)
 * [_:exact_]
 *   +true+を指定すると完全一致で検索する
 * [_:longest_common_prefix_]
 *   +true+を指定すると_query_と同じ接頭辞をもつエントリのう
 *   ち、もっとも長いエントリを検索する
 * [_:suffix_]
 *   +true+を指定すると_query_が後方一致するエントリを検索す
 *   る
 * [_:prefix_]
 *   +true+を指定すると_query_が前方一致するレコードを検索す
 *   る
 * [_:near_]
 *   +true+を指定すると_query_に指定した複数の語が近傍に含ま
 *   れるレコードを検索する
 * [...]
 *   ...
 */
static VALUE
rb_grn_index_column_search (int argc, VALUE *argv, VALUE self)
{
    grn_ctx *context;
    grn_obj *column;
    grn_obj *range;
    grn_obj *query = NULL, *id_query = NULL, *string_query = NULL;
    grn_obj *result;
    grn_operator operator;
    grn_rc rc;
    VALUE rb_query, options, rb_result, rb_operator;

    rb_grn_index_column_deconstruct(SELF(self), &column, &context,
				    NULL, NULL,
				    NULL, NULL, NULL, &range,
				    &id_query, &string_query);

    rb_scan_args(argc, argv, "11", &rb_query, &options);

    if (CBOOL2RVAL(rb_obj_is_kind_of(rb_query, rb_cGrnQuery))) {
	grn_query *_query;
	_query = RVAL2GRNQUERY(rb_query);
	query = (grn_obj *)_query;
    } else if (CBOOL2RVAL(rb_obj_is_kind_of(rb_query, rb_cInteger))) {
	grn_id id;
	id = NUM2UINT(rb_query);
	GRN_TEXT_SET(context, id_query, &id, sizeof(grn_id));
	query = id_query;
    } else {
	const char *_query;
	_query = StringValuePtr(rb_query);
	GRN_TEXT_SET(context, string_query, _query, RSTRING_LEN(rb_query));
	query = string_query;
    }

    rb_grn_scan_options(options,
			"result", &rb_result,
			"operator", &rb_operator,
			NULL);

    if (NIL_P(rb_result)) {
	result = grn_table_create(context, NULL, 0, NULL,
				  GRN_OBJ_TABLE_HASH_KEY | GRN_OBJ_WITH_SUBREC,
				  range, 0);
	rb_grn_context_check(context, self);
	rb_result = GRNOBJECT2RVAL(Qnil, context, result, RB_GRN_TRUE);
    } else {
	result = RVAL2GRNOBJECT(rb_result, &context);
    }

    operator = RVAL2GRNOPERATOR(rb_operator);

    rc = grn_obj_search(context, column, query, result, operator, NULL);
    rb_grn_rc_check(rc, self);

    return rb_result;
}
/*
 * Updates a record that has @new_value@ as new content and
 * @old_value@ as old content in inverted index. Normally, this method
 * is not used explicitly. Inverted index for fulltext search is
 * updated automatically by using @:source@ option of
 * {Groonga::Table#define_index_column}.
 *
 * @example Updates sentences of an article in index
 *   articles = Groonga::Array.create(:name => "Articles")
 *   articles.define_column("title", "ShortText")
 *   articles.define_column("content", "Text")
 *
 *   terms = Groonga::Hash.create(:name => "Terms",
 *                                :key_type => "ShortText",
 *                                :default_tokenizer => "TokenBigram")
 *   content_index = terms.define_index_column("content", articles,
 *                                             :with_position => true,
 *                                             :with_section => true)
 *
 *   old_sentence = <<-SENTENCE
 *   Groonga is a fast and accurate full text search engine based on
 *   inverted index. One of the characteristics of groonga is that a
 *   newly registered document instantly appears in search
 *   results. Also, groonga allows updates without read locks. These
 *   characteristics result in superior performance on real-time
 *   applications.
 *   SENTENCE
 *
 *   new_sentence = <<-SENTENCE
 *   Groonga is also a column-oriented database management system
 *   (DBMS). Compared with well-known row-oriented systems, such as
 *   MySQL and PostgreSQL, column-oriented systems are more suited for
 *   aggregate queries. Due to this advantage, groonga can cover
 *   weakness of row-oriented systems.
 *   SENTENCE
 *
 *   groonga = articles.add(:title => "groonga", :content => old_sentence)
 *
 *   content_index.add(groonga, old_sentence, :section => 1)
 *   p content_index.search("engine").size # -> 1
 *   p content_index.search("MySQL").size  # -> 0
 *
 *   groonga[:content] = new_sentence
 *   content_index.update(groonga, old_sentence, new_sentence, :section => 1)
 *   p content_index.search("engine").size # -> 0
 *   p content_index.search("MySQL").size  # -> 1
 *
 * @overload update(record, old_value, new_value, options={})
 *   @param [Groonga::Record, Integer] record
 *     The record that has a @new_value@ as its new value and
 *     @old_value@ as its old value. It can be Integer as record id.
 *   @param [String] old_value
 *     The old value of the @record@.
 *   @param [String] new_value
 *     The new value of the @record@.
 *   @param [::Hash] options
 *     The options.
 *   @option options [Integer] :section (1)
 *     The section number. It is one-origin.
 *
 *     You must specify @{:with_section => true}@ in
 *     {Groonga::Table#define_index_column} to use this option.
 *   @return [void]
 *
 * @since 3.0.2
 */
static VALUE
rb_grn_index_column_update (int argc, VALUE *argv, VALUE self)
{
    grn_ctx *context = NULL;
    grn_obj *column, *range;
    grn_rc rc;
    grn_id id;
    unsigned int section;
    grn_obj *old_value, *new_value;
    VALUE rb_record, rb_old_value, rb_new_value, rb_options, rb_section;

    rb_scan_args(argc, argv, "31",
                 &rb_record, &rb_old_value, &rb_new_value, &rb_options);

    rb_grn_index_column_deconstruct(SELF(self), &column, &context,
                                    NULL, NULL,
                                    &new_value, &old_value,
                                    NULL, &range,
                                    NULL, NULL);

    id = RVAL2GRNID(rb_record, context, range, self);

    if (NIL_P(rb_old_value)) {
        old_value = NULL;
    } else {
        GRN_BULK_REWIND(old_value);
        RVAL2GRNBULK(rb_old_value, context, old_value);
    }

    if (NIL_P(rb_new_value)) {
        new_value = NULL;
    } else {
        GRN_BULK_REWIND(new_value);
        RVAL2GRNBULK(rb_new_value, context, new_value);
    }

    rb_grn_scan_options(rb_options,
                        "section", &rb_section,
                        NULL);

    if (NIL_P(rb_section)) {
        section = 1;
    } else {
        section = NUM2UINT(rb_section);
    }

    rc = grn_column_index_update(context, column, id, section,
                                 old_value, new_value);
    rb_grn_context_check(context, self);
    rb_grn_rc_check(rc, self);

    return self;
}
Exemple #26
0
/*
 * Sends reopen request to the current query logger. It is useful for
 * rotating log file.
 *
 * @overload reopen
 * @return void
 */
static VALUE
rb_grn_query_logger_s_reopen (VALUE klass)
{
    VALUE rb_context = Qnil;
    grn_ctx *context;

    context = rb_grn_context_ensure(&rb_context);
    grn_query_logger_reopen(context);
    rb_grn_context_check(context, klass);

    return Qnil;
}
Exemple #27
0
static VALUE
rb_grn_logger_s_reopen_with_related_object (VALUE klass, VALUE related_object)
{
    VALUE rb_context = Qnil;
    grn_ctx *context;

    context = rb_grn_context_ensure(&rb_context);
    rb_grn_logger_reset_with_error_check(klass, context);
    grn_logger_reopen(context);
    rb_grn_context_check(context, related_object);

    return Qnil;
}
Exemple #28
0
/*
 * call-seq:
 *   column.table -> Groonga::Table
 *
 * カラムが所属するテーブルを返す。
 */
static VALUE
rb_grn_column_get_table (VALUE self)
{
    grn_ctx *context = NULL;
    grn_obj *column;
    grn_obj *table;

    rb_grn_object_deconstruct((RbGrnObject *)(SELF(self)), &column, &context,
			      NULL, NULL,
			      NULL, NULL);
    table = grn_column_table(context, column);
    rb_grn_context_check(context, self);

    return GRNOBJECT2RVAL(Qnil, context, table, RB_GRN_FALSE);
}
Exemple #29
0
/*
 * @overload unmap()
 *
 *   Unmaps all mapped tables and columns in database.
 *
 *   It frees resources for them.
 *
 *   Normally, you don't need to unmap explicitly. Because OS manages
 *   resourced for mapped tables and columns cleverly.
 *
 *   @return [void]
 *
 * @since 5.0.5
 */
static VALUE
rb_grn_database_unmap (VALUE self)
{
    grn_rc rc;
    grn_ctx *context;
    grn_obj *database;

    rb_grn_database_deconstruct(SELF(self), &database, &context,
                                NULL, NULL, NULL, NULL);
    rc = grn_db_unmap(context, database);
    rb_grn_context_check(context, self);
    rb_grn_rc_check(rc, self);

    return Qnil;
}
Exemple #30
0
/*
 * call-seq:
 *   context.receive -> [ID, String]
 *
 * groongaサーバからクエリ実行結果文字列を受信する。
 */
static VALUE
rb_grn_context_receive (VALUE self)
{
    grn_ctx *context;
    char *string;
    unsigned string_size;
    int flags = 0;
    unsigned int query_id;

    context = SELF(self);
    query_id = grn_ctx_recv(context, &string, &string_size, &flags);
    rb_grn_context_check(context, self);

    return rb_ary_new3(2, UINT2NUM(query_id), rb_str_new(string, string_size));
}