Example #1
0
/*
 * Document-method: unlock
 *
 * call-seq:
 *   database.unlock
 *
 * _database_ のロックを解除する。
 */
static VALUE
rb_grn_database_unlock (VALUE self)
{
    grn_ctx *context;
    grn_obj *database;
    grn_rc rc;

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

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

    return Qnil;
}
/*
 * _key_ にマッチするレコードのIDがキーに入っている
 * {Groonga::Hash} を返す。マッチするレコードがない場合は空の
 * {fGroonga::Hash} が返る。
 * _options_ で +:result+ を指定することにより、そのテーブルにマッ
 * チしたレコードIDがキーのレコードを追加することができる。
 * +:result+ にテーブルを指定した場合は、そのテーブルが返る。
 *
 * @example 複数のキーで検索し、結果を1つのテーブルに集める。
 *   result = nil
 *   keys = ["morita", "gunyara-kun", "yu"]
 *   keys.each do |key|
 *     result = users.search(key, :result => result)
 *   end
 *   result.each do |record|
 *     user = record.key
 *     p user.key # -> "morita"または"gunyara-kun"または"yu"
 *   end
 *
 * @overload search(key, options=nil)
 *   @return [Groonga::Hash]
 *   @param key [String] レコードにマッチさせる値
 *   @param options [::Hash] The name and value
 *     pairs. Omitted names are initialized as the default value.
 *   @option options :result The result
 *     結果を格納するテーブル。
 *   @option options :operator (Groonga::Operator::OR)
 *     マッチしたレコードをどのように扱うか。指定可能な値は以
 *     下の通り。
 *
 *     - Groonga::Operator::OR :=
 *       マッチしたレコードを追加。すでにレコードが追加され
 *       ている場合は何もしない。 =:
 *     - Groonga::Operator::AND :=
 *       マッチしたレコードのスコアを増加。マッチしなかった
 *       レコードを削除。 =:
 *     - Groonga::Operator::AND_NOT :=
 *       マッチしたレコードを削除。 =:
 *     - Groonga::Operator::ADJUST :=
 *       マッチしたレコードのスコアを増加。 =:
 *     - +:type+ :=
 *       ????? =:
 *
 */
static VALUE
rb_grn_double_array_trie_search (int argc, VALUE *argv, VALUE self)
{
    grn_rc rc;
    grn_ctx *context;
    grn_obj *table;
    grn_id domain_id;
    grn_obj *key, *domain, *result;
    grn_operator operator;
    grn_search_optarg search_options;
    grn_bool search_options_is_set = GRN_FALSE;
    VALUE rb_key, options, rb_result, rb_operator, rb_type;

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

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

    RVAL2GRNKEY(rb_key, context, key, domain_id, domain, self);

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

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

    operator = RVAL2GRNOPERATOR(rb_operator);

    rc = grn_obj_search(context, table, key,
                        result, operator,
                        search_options_is_set ? &search_options : NULL);
    rb_grn_rc_check(rc, self);

    return rb_result;
}
Example #3
0
/*
 * _expression_ をコンパイルする。
 *
 * @overload compile
 */
static VALUE
rb_grn_expression_compile (VALUE self)
{
    grn_ctx *context = NULL;
    grn_obj *expression;
    grn_rc rc;

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

    rc = grn_expr_compile(context, expression);
    rb_grn_context_check(context, self);
    rb_grn_rc_check(rc, self);

    return Qnil;
}
Example #4
0
/*
 * call-seq:
 *   table_cursor.delete
 *
 * カレントレコードを削除する。
 */
static VALUE
rb_grn_table_cursor_delete (VALUE self)
{
    grn_ctx *context;
    grn_table_cursor *cursor;

    rb_grn_table_cursor_deconstruct(SELF(self), &cursor, &context,
				    NULL, NULL, NULL, NULL);
    if (context && cursor) {
        grn_rc rc;

        rc = grn_table_cursor_delete(context, cursor);
        rb_grn_rc_check(rc, self);
    }

    return Qnil;
}
/*
 * Recreates all index columns for the column.
 *
 * This method is useful when you have any broken index columns for
 * the column. You don't need to specify each index column. But this
 * method spends more time rather than you specify only reindex
 * needed index columns.
 *
 * You can use {Groonga::Database#reindex} to recreate all index
 * columns in a database.
 *
 * You can use {Groonga::TableKeySupport#reindex} to recreate all
 * index columns in a table.
 *
 * You can use {Groonga::IndexColumn#reindex} to specify the reindex
 * target index column.
 *
 * @example How to recreate all index columns for the column
 *   Groonga::Schema.define do |schema|
 *     schema.create_table("Memos") do |table|
 *       table.short_text("title")
 *       table.text("content")
 *     end
 *
 *     schema.create_table("BigramTerms",
 *                         :type => :patricia_trie,
 *                         :key_type => :short_text,
 *                         :normalizer => "NormalizerAuto",
 *                         :default_tokenizer => "TokenBigram") do |table|
 *       table.index("Memos.title")
 *       table.index("Memos.content")
 *     end
 *
 *     schema.create_table("MeCabTerms",
 *                         :type => :patricia_trie,
 *                         :key_type => :short_text,
 *                         :normalizer => "NormalizerAuto",
 *                         :default_tokenizer => "TokenMecab") do |table|
 *       table.index("Memos.title")
 *       table.index("Memos.content")
 *     end
 *   end
 *
 *   Groonga["Memos.content"].reindex
 *   # They are called:
 *   #   Groonga["BigramTerms.Memos_content"].reindex
 *   #   Groonga["MeCabTerms.Memos_content"].reindex
 *   #
 *   # They aren't called:
 *   #   Groonga["BigramTerms.Memos_title"].reindex
 *   #   Groonga["MeCabTerms.Memos_title"].reindex
 *
 * @overload reindex
 *   @return [void]
 *
 * @see Groonga::Database#reindex
 * @see Groonga::TableKeySupport#reindex
 * @see Groonga::FixSizeColumn#reindex
 * @see Groonga::IndexColumn#reindex
 *
 * @since 5.1.1
 */
static VALUE
rb_grn_variable_size_column_reindex (VALUE self)
{
    grn_rc rc;
    grn_ctx *context;
    grn_obj *column;

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

    rc = grn_obj_reindex(context, column);
    rb_grn_context_check(context, self);
    rb_grn_rc_check(rc, self);

    return Qnil;
}
Example #6
0
void
Init_groonga (void)
{
    VALUE mGrn;

    mGrn = rb_define_module("Groonga");

    rb_grn_init_exception(mGrn);

    rb_grn_rc_check(grn_init(), Qnil);
    rb_set_end_proc(finish_groonga, Qnil);

    rb_grn_init_version(mGrn);
    rb_grn_init_lock_timeout(mGrn);

    rb_grn_init_utils(mGrn);
    rb_grn_init_encoding(mGrn);
    rb_grn_init_encoding_support(mGrn);
    rb_grn_init_context(mGrn);
    rb_grn_init_object(mGrn);
    rb_grn_init_database(mGrn);
    rb_grn_init_table(mGrn);
    rb_grn_init_table_cursor(mGrn);
    rb_grn_init_index_cursor(mGrn);
    rb_grn_init_posting(mGrn);
    rb_grn_init_type(mGrn);
    rb_grn_init_procedure(mGrn);
    rb_grn_init_procedure_type(mGrn);
    rb_grn_init_column(mGrn);
    rb_grn_init_accessor(mGrn);
    rb_grn_init_geo_point(mGrn);
    rb_grn_init_record(mGrn);
    rb_grn_init_variable(mGrn);
    rb_grn_init_operator(mGrn);
    rb_grn_init_expression(mGrn);
    rb_grn_init_expression_builder(mGrn);
    rb_grn_init_logger(mGrn);
    rb_grn_init_query_logger(mGrn);
    rb_grn_init_snippet(mGrn);
    rb_grn_init_plugin(mGrn);
    rb_grn_init_normalizer(mGrn);
}
Example #7
0
/*
 * Removes an object forcibly.
 *
 * Normally, you should use {Groonga::Object#remove}.
 *
 * @overload remove_force(name)
 *
 *   @param [String] name The target object name.
 *
 * @since 6.0.9
 */
static VALUE
rb_grn_database_remove_force (VALUE self, VALUE rb_name)
{
    grn_rc rc;
    grn_ctx *context;
    char *name;
    int name_size;

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

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

    rc = grn_obj_remove_force(context, name, name_size);
    rb_grn_context_check(context, self);
    rb_grn_rc_check(rc, self);

    return Qnil;
}
Example #8
0
/*
 * call-seq:
 *   cursor.value = 値
 *
 * カレントレコードの値を設定する。既存の値は上書きされる。
 */
static VALUE
rb_grn_table_cursor_set_value (VALUE self, VALUE value)
{
    grn_ctx *context;
    grn_table_cursor *cursor;

    rb_grn_table_cursor_deconstruct(SELF(self), &cursor, &context,
				    NULL, NULL, NULL, NULL);
    if (context && cursor) {
        grn_rc rc;

        rc = grn_table_cursor_set_value(context,
                                        cursor,
                                        StringValuePtr(value),
					GRN_OBJ_SET);
        rb_grn_rc_check(rc, self);
    }

    return Qnil;
}
/*
 * Specifies the normalizer used by {Groonga::IndexColumn}.
 *
 * @example
 *   # Uses NFKC normalizer.
 *   table.normalizer = "NormalizerNFKC51"
 *   # Specifies normalizer object.
 *   table.normalizer = Groonga::Context["NormalizerNFKC51"]
 *   # Uses auto normalizer that is a normalizer for backward compatibility.
 *   table.normalizer = "TNormalizerAuto"
 *
 * @overload normalizer=(name)
 *    @param [String] name Set a nomalizer named @name@.
 *
 * @overload normalizer=(normalizer)
 *    @param [Groonga::Procedure] normalizer Set the normalizer object.
 *
 * @overload normalizer=(normalizer)
 *    @param [nil] normalizer Unset normalizer.
 */
static VALUE
rb_grn_table_key_support_set_normalizer (VALUE self, VALUE rb_normalizer)
{
    grn_ctx *context;
    grn_obj *table;
    grn_obj *normalizer;
    grn_rc rc;

    rb_grn_table_key_support_deconstruct(SELF(self), &table, &context,
                                         NULL, NULL, NULL,
                                         NULL, NULL, NULL,
                                         NULL);

    normalizer = RVAL2GRNOBJECT(rb_normalizer, &context);
    rc = grn_obj_set_info(context, table, GRN_INFO_NORMALIZER, normalizer);
    rb_grn_context_check(context, self);
    rb_grn_rc_check(rc, self);

    return Qnil;
}
Example #10
0
/*
 * インデックス対象となる複数のカラムを配列で設定する。
 *
 * @overload sources=(columns)
 *   @param [::Array<Groonga::Column>] columns インデックス対象となるカラムの配列
 */
static VALUE
rb_grn_index_column_set_sources (VALUE self, VALUE rb_sources)
{
    VALUE exception;
    grn_ctx *context = NULL;
    grn_obj *column;
    int i, n;
    VALUE *rb_source_values;
    grn_id range_id;
    grn_id *sources;
    grn_rc rc;

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

    n = RARRAY_LEN(rb_sources);
    rb_source_values = RARRAY_PTR(rb_sources);
    sources = ALLOCA_N(grn_id, n);
    for (i = 0; i < n; i++) {
        sources[i] = resolve_source_id(context, column, range_id,
                                       rb_source_values[i]);
    }

    {
        grn_obj bulk_sources;
        GRN_OBJ_INIT(&bulk_sources, GRN_BULK, 0, GRN_ID_NIL);
        GRN_TEXT_SET(context, &bulk_sources, sources, n * sizeof(grn_id));
        rc = grn_obj_set_info(context, column, GRN_INFO_SOURCE, &bulk_sources);
        exception = rb_grn_context_to_exception(context, self);
        grn_obj_unlink(context, &bulk_sources);
    }

    if (!NIL_P(exception))
        rb_exc_raise(exception);
    rb_grn_rc_check(rc, self);

    return Qnil;
}
Example #11
0
/*
 * call-seq:
 *   snippet.add_keyword(keyword, options={})
 *
 * _keyword_を追加する。_options_に指定可能な値は以下の通
 * り。
 *
 * [+:open_tag+]
 *   開始タグ。省略した場合はGroonga::Snippet.newで指定し
 *   た+:default_open_tag+。
 *
 * [+:close_tag+]
 *   終了タグ。省略した場合はGroonga::Snippet.newで指定し
 *   た+:default_close_tag+。
 */
static VALUE
rb_grn_snippet_add_keyword (int argc, VALUE *argv, VALUE self)
{
    RbGrnSnippet *rb_grn_snippet;
    grn_rc rc;
    VALUE rb_keyword, options;
    VALUE rb_open_tag, rb_close_tag;
    char *keyword, *open_tag = NULL, *close_tag = NULL;
    unsigned int keyword_length, open_tag_length = 0, close_tag_length = 0;

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

    rb_grn_snippet = SELF(self);

    keyword = StringValuePtr(rb_keyword);
    keyword_length = RSTRING_LEN(rb_keyword);

    rb_grn_scan_options(options,
                        "open_tag", &rb_open_tag,
                        "close_tag", &rb_close_tag,
                        NULL);

    if (!NIL_P(rb_open_tag)) {
        open_tag = StringValuePtr(rb_open_tag);
        open_tag_length = RSTRING_LEN(rb_open_tag);
    }

    if (!NIL_P(rb_close_tag)) {
        close_tag = StringValuePtr(rb_close_tag);
        close_tag_length = RSTRING_LEN(rb_close_tag);
    }

    rc = grn_snip_add_cond(rb_grn_snippet->context,
                           rb_grn_snippet->snippet,
                           keyword, keyword_length,
                           open_tag, open_tag_length,
                           close_tag, close_tag_length);
    rb_grn_rc_check(rc, self);

    return Qnil;
}
Example #12
0
/*
 * {Groonga::IndexColumn} で使用するトークナイザを設定する。
 *
 * @example
 *   # 2-gramを使用。
 *   table.default_tokenizer = "TokenBigram"
 *   # オブジェクトで指定
 *   table.default_tokenizer = Groonga::Context.default["TokenBigram"]
 *   # オブジェクトIDで指定
 *   table.default_tokenizer = Groonga::Type::BIGRAM
 *   # N-gram用のトークナイザを使うときはGroonga::IndexColumn
 *   # には自動的に:with_section => trueが指定される。
 *   index = table.define_index_column("blog_content", "Blogs",
 *                                     :source => "content")
 *   p index # -> #<Groonga::IndexColumn ... flags: <WITH_POSITION|...>>
 *
 *   # MeCabを使用
 *   table.default_tokenizer = "TokenMecab"
 *
 * @overload default_tokenizer=(tokenizer)
 */
static VALUE
rb_grn_table_key_support_set_default_tokenizer (VALUE self, VALUE rb_tokenizer)
{
    grn_ctx *context;
    grn_obj *table;
    grn_obj *tokenizer;
    grn_rc rc;

    rb_grn_table_key_support_deconstruct(SELF(self), &table, &context,
                                         NULL, NULL, NULL,
                                         NULL, NULL, NULL,
                                         NULL);

    tokenizer = RVAL2GRNOBJECT(rb_tokenizer, &context);
    rc = grn_obj_set_info(context, table,
                          GRN_INFO_DEFAULT_TOKENIZER, tokenizer);
    rb_grn_context_check(context, self);
    rb_grn_rc_check(rc, self);

    return Qnil;
}
Example #13
0
/*
 * Deletes a record that has @value@ content from 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 Deletes sentences of an article to 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)
 *
 *   content = <<-CONTENT
 *   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.
 *
 *   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.
 *
 *   The basic functions of groonga are provided in a C library. Also,
 *   libraries for using groonga in other languages, such as Ruby, are
 *   provided by related projects. In addition, groonga-based storage
 *   engines are provided for MySQL and PostgreSQL. These libraries
 *   and storage engines allow any application to use groonga. See
 *   usage examples.
 *   CONTENT
 *
 *   groonga = articles.add(:title => "groonga", :content => content)
 *
 *   content.split(/\n{2,}/).each_with_index do |sentence, i|
 *     content_index.add(groonga, sentence, :section => i + 1)
 *   end
 *
 *   content_index.search("engine").each do |record|
 *     p record.key["title"] # -> "groonga"
 *   end
 *
 *   content.split(/\n{2,}/).each_with_index do |sentence, i|
 *     content_index.delete(groonga, sentence, :section => i + 1)
 *   end
 *
 *   p content_index.search("engine").size # -> 0
 *
 * @overload delete(record, value, options={})
 *   @param [Groonga::Record, Integer] record
 *     The record that has a @value@ as its value. It can be Integer as
 *     record id.
 *   @param [String] value
 *     The 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_delete (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;
    VALUE rb_record, rb_value, rb_options, rb_section;

    rb_scan_args(argc, argv, "21", &rb_record, &rb_value, &rb_options);

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

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

    GRN_BULK_REWIND(old_value);
    RVAL2GRNBULK(rb_value, context, old_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, NULL);
    rb_grn_context_check(context, self);
    rb_grn_rc_check(rc, self);

    return self;
}
static VALUE
rb_grn_double_array_trie_update_by_id (VALUE self, VALUE rb_id, VALUE rb_new_key)
{
    grn_ctx *context;
    grn_obj *table;
    grn_id id, domain_id;
    grn_obj *new_key, *domain;
    grn_rc rc;

    rb_grn_double_array_trie_deconstruct(SELF(self), &table, &context,
                                         NULL, &new_key, &domain_id, &domain,
                                         NULL, NULL, NULL,
                                         NULL);

    id = NUM2UINT(rb_id);
    RVAL2GRNKEY(rb_new_key, context, new_key, domain_id, domain, self);
    rc = grn_table_update_by_id(context, table, id,
                                GRN_BULK_HEAD(new_key), GRN_BULK_VSIZE(new_key));
    rb_grn_rc_check(rc, self);

    return Qnil;
}
Example #15
0
/*
 * Document-method: rename
 *
 * call-seq:
 *   table.rename(name)
 *
 * Renames the table to name.
 *
 * @param name [String] the new name
 * @since 1.3.0
 */
static VALUE
rb_grn_column_rename (VALUE self, VALUE rb_name)
{
    int rc;
    grn_ctx *context;
    grn_obj *column;
    char *name;
    int name_size;

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

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

    rc = grn_column_rename(context, column, name, name_size);
    rb_grn_context_check(context, self);
    rb_grn_rc_check(rc, self);

    return self;
}
Example #16
0
/*
 * _key_ にマッチするレコードのIDがキーに入っている
 * {Groonga::Hash} を返す。マッチするレコードがない場合は空の
 * {Groonga::Hash} が返る。
 *
 * _options_ で +:result+ を指定することにより、そのテーブルにマッ
 * チしたレコードIDがキーのレコードを追加することができる。
 * +:result+ にテーブルを指定した場合は、そのテーブルが返る。
 *
 * @example 複数のキーで検索し、結果を1つのテーブルに集める。
 *   result = nil
 *   keys = ["morita", "gunyara-kun", "yu"]
 *   keys.each do |key|
 *     result = users.search(key, :result => result)
 *   end
 *   result.each do |record|
 *     user = record.key
 *     p user.key # -> "morita"または"gunyara-kun"または"yu"
 *   end
 *
 * @overload search(key, options=nil)
 *   @param [::Hash] options The name and value
 *     pairs. Omitted names are initialized as the default value
 *   @option options :result
 *     結果を格納するテーブル。
 * @return [Groonga::Hash]
 */
static VALUE
rb_grn_hash_search (int argc, VALUE *argv, VALUE self)
{
    grn_rc rc;
    grn_ctx *context;
    grn_obj *table;
    grn_id domain_id;
    grn_obj *key, *domain, *result;
    VALUE rb_key, options, rb_result;

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

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

    RVAL2GRNKEY(rb_key, context, key, domain_id, domain, self);

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

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

    rc = grn_obj_search(context, table, key,
                        result, GRN_OP_OR, NULL);
    rb_grn_rc_check(rc, self);

    return rb_result;
}
Example #17
0
static VALUE
rb_grn_table_key_support_delete_by_key (VALUE self, VALUE rb_key)
{
    grn_ctx *context;
    grn_obj *table;
    grn_id domain_id;
    grn_obj *key, *domain;
    grn_rc rc;

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

    GRN_BULK_REWIND(key);
    RVAL2GRNKEY(rb_key, context, key, domain_id, domain, self);
    rc = grn_table_delete(context, table,
                          GRN_BULK_HEAD(key), GRN_BULK_VSIZE(key));
    rb_grn_context_check(context, self);
    rb_grn_rc_check(rc, self);

    return Qnil;
}
Example #18
0
/*
 * Document-method: lock
 *
 * call-seq:
 *   column.lock(options={})
 *   column.lock(options={}) {...}
 *
 * _column_をロックする。ロックに失敗した場合は
 * Groonga::ResourceDeadlockAvoided例外が発生する。
 *
 * ブロックを指定した場合はブロックを抜けたときにunlockする。
 *
 * 利用可能なオプションは以下の通り。
 *
 * [_:timeout_]
 *   ロックを獲得できなかった場合は_:timeout_秒間ロックの獲
 *   得を試みる。_:timeout_秒以内にロックを獲得できなかった
 *   場合は例外が発生する。
 * [_:id_]
 *   _:id_で指定したレコードをロックする。(注: groonga側が
 *   未実装のため、現在は無視される)
 */
static VALUE
rb_grn_column_lock (int argc, VALUE *argv, VALUE self)
{
    grn_id id = GRN_ID_NIL;
    grn_ctx *context;
    grn_obj *column;
    int timeout = 0;
    grn_rc rc;
    VALUE options, rb_timeout, 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,
			"timeout", &rb_timeout,
			"id", &rb_id,
			NULL);

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

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

    rc = grn_obj_lock(context, column, id, 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_column_unlock_ensure, self);
    } else {
	return Qnil;
    }
}
Example #19
0
static VALUE
rb_grn_table_key_support_set_value_by_key (VALUE self,
                                           VALUE rb_key, VALUE rb_value)
{
    grn_ctx *context;
    grn_obj *table;
    grn_id id;
    grn_obj *value;
    grn_rc rc;

    if (NIL_P(rb_key)) {
        rb_raise(rb_eArgError, "key should not be nil: <%s>",
                 rb_grn_inspect(self));
    }

    rb_grn_table_key_support_deconstruct(SELF(self), &table, &context,
                                         NULL, NULL, NULL,
                                         &value, NULL, NULL,
                                         NULL);

    id = rb_grn_table_key_support_add_raw(self, rb_key, NULL);
    if (GRN_ID_NIL == id) {
        rb_raise(rb_eGrnError,
                 "failed to add new record with key: <%s>: <%s>",
                 rb_grn_inspect(rb_key),
                 rb_grn_inspect(self));
    }

    GRN_BULK_REWIND(value);
    RVAL2GRNBULK(rb_value, context, value);
    rc = grn_obj_set_value(context, table, id, value, GRN_OBJ_SET);
    rb_grn_context_check(context, self);
    rb_grn_rc_check(rc, self);

    return rb_value;
}
/*
 * Sets token filters that used in {Groonga::IndexColumn}.
 *
 * @example
 *   # Use "TokenFilterStem" and "TokenfilterStopWord"
 *   table.token_filters = ["TokenFilterStem", "TokenFilterStopWord"]
 *
 * @overload token_filters=(token_filters)
 *   @param token_filters [::Array<String>] Token filter names.
 */
static VALUE
rb_grn_table_key_support_set_token_filters (VALUE self,
                                            VALUE rb_token_filters)
{
    grn_ctx *context;
    grn_obj *table;
    grn_obj token_filters;
    grn_rc rc;

    rb_grn_table_key_support_deconstruct(SELF(self), &table, &context,
                                         NULL, NULL, NULL,
                                         NULL, NULL, NULL,
                                         NULL);

    GRN_PTR_INIT(&token_filters, GRN_OBJ_VECTOR, GRN_ID_NIL);
    RVAL2GRNPVECTOR(rb_token_filters, context, &token_filters);
    rc = grn_obj_set_info(context, table,
                          GRN_INFO_TOKEN_FILTERS, &token_filters);
    grn_obj_unlink(context, &token_filters);
    rb_grn_context_check(context, self);
    rb_grn_rc_check(rc, self);

    return Qnil;
}
Example #21
0
/*
 * call-seq:
 *   context.connect(options=nil)
 *
 * groongaサーバに接続する。_options_に指定可能な値は以下の通
 * り。
 *
 * [+:host+]
 *   groongaサーバのホスト名。またはIPアドレス。省略すると
 *   "localhost"に接続する。
 *
 * [+:port+]
 *   groongaサーバのポート番号。省略すると10041番ポートに接
 *   続する。
 */
static VALUE
rb_grn_context_connect (int argc, VALUE *argv, VALUE self)
{
    grn_ctx *context;
    const char *host;
    int port;
    int flags = 0;
    grn_rc rc;
    VALUE options, rb_host, rb_port;

    rb_scan_args(argc, argv, "01", &options);
    rb_grn_scan_options(options,
			"host", &rb_host,
			"port", &rb_port,
			NULL);

    context = SELF(self);

    if (NIL_P(rb_host)) {
	host = "localhost";
    } else {
	host = StringValueCStr(rb_host);
    }

    if (NIL_P(rb_port)) {
	port = 10041;
    } else {
	port = NUM2INT(rb_port);
    }

    rc = grn_ctx_connect(context, host, port, flags);
    rb_grn_context_check(context, self);
    rb_grn_rc_check(rc, self);

    return Qnil;
}
/*
 * It updates a value of variable size column value for the record
 * that ID is _id_.
 *
 * Weight vector column is a special variable size column. This
 * description describes only weight vector column. Other variable
 * size column works what you think.
 *
 * @example Use weight vector as matrix search result weight
 *    Groonga::Schema.define do |schema|
 *      schema.create_table("Products",
 *                          :type => :patricia_trie,
 *                          :key_type => "ShortText") do |table|
 *        # This is weight vector.
 *        # ":with_weight => true" is important for matrix search result weight.
 *        table.short_text("tags",
 *                         :type => :vector,
 *                         :with_weight => true)
 *      end
 *
 *      schema.create_table("Tags",
 *                          :type => :hash,
 *                          :key_type => "ShortText") do |table|
 *        # This is inverted index. It also needs ":with_weight => true".
 *        table.index("Products.tags", :with_weight => true)
 *      end
 *    end
 *
 *    products = Groonga["Products"]
 *    groonga = products.add("Groonga")
 *    groonga.tags = [
 *      {
 *        :value  => "groonga",
 *        :weight => 100,
 *      },
 *    ]
 *    rroonga = products.add("Rroonga")
 *    rroonga.tags = [
 *      {
 *        :value  => "ruby",
 *        :weight => 100,
 *      },
 *      {
 *        :value  => "groonga",
 *        :weight => 10,
 *      },
 *    ]
 *
 *    result = products.select do |record|
 *      # Search by "groonga"
 *      record.match("groonga") do |match_target|
 *        match_target.tags
 *      end
 *    end
 *
 *    result.each do |record|
 *      p [record.key.key, record.score]
 *    end
 *    # Matches all records with weight.
 *    # => ["Groonga", 101]
 *    #    ["Rroonga", 11]
 *
 *    # Increases score for "ruby" 10 times
 *    products.select(# The previous search result. Required.
 *                    :result => result,
 *                    # It just adds score to existing records in the result. Required.
 *                    :operator => Groonga::Operator::ADJUST) do |record|
 *      record.match("ruby") do |target|
 *        target.tags * 10 # 10 times
 *      end
 *    end
 *
 *    result.each do |record|
 *      p [record.key.key, record.score]
 *    end
 *    # Weight is used for increasing score.
 *    # => ["Groonga", 101]  <- Not changed.
 *    #    ["Rroonga", 1021] <- 1021 (= 101 * 10 + 1) increased.
 *
 * @overload []=(id, elements)
 *   This description is for weight vector column.
 *
 *   @param [Integer, Record] id The record ID.
 *   @param [Array<Hash<Symbol, String>>] elements An array of values
 *     for weight vector.
 *     Each value is a Hash like the following form:
 *
 *     <pre>
 *     {
 *       :value  => [KEY],
 *       :weight => [WEIGHT],
 *     }
 *     </pre>
 *
 *     @[KEY]@ must be the same type of the key of the table that is
 *     specified as range on creating the weight vector.
 *
 *     @[WEIGHT]@ must be an positive integer. Note that search
 *     becomes @weight + 1@. It means that You want to get 10 as
 *     score, you should set 9 as weight.
 *
 * @overload []=(id, value)
 *   This description is for variable size columns except weight
 *   vector column.
 *
 *   @param [Integer, Record] id The record ID.
 *   @param [::Object] value A new value.
 *   @see Groonga::Object#[]=
 *
 * @since 4.0.1
 */
static VALUE
rb_grn_variable_size_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;
    grn_obj *value, *element_value;
    int flags = GRN_OBJ_SET;

    rb_grn_variable_size_column_deconstruct(SELF(self), &column, &context,
                                            NULL, NULL, &value, &element_value,
                                            NULL, &range);

    if (!(column->header.flags & GRN_OBJ_WITH_WEIGHT)) {
        VALUE args[2];
        args[0] = rb_id;
        args[1] = rb_value;
        return rb_call_super(2, args);
    }

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

    grn_obj_reinit(context, value,
                   value->header.domain,
                   value->header.flags | GRN_OBJ_VECTOR);
    value->header.flags |= GRN_OBJ_WITH_WEIGHT;
    if (RVAL2CBOOL(rb_obj_is_kind_of(rb_value, rb_cArray))) {
        int i, n;
        n = RARRAY_LEN(rb_value);
        for (i = 0; i < n; i++) {
            unsigned int weight = 0;
            VALUE rb_element_value, rb_weight;

            rb_grn_scan_options(RARRAY_PTR(rb_value)[i],
                                "value", &rb_element_value,
                                "weight", &rb_weight,
                                NULL);

            if (!NIL_P(rb_weight)) {
                weight = NUM2UINT(rb_weight);
            }

            if (value->header.type == GRN_UVECTOR) {
                grn_id id = RVAL2GRNID(rb_element_value, context, range, self);
                grn_uvector_add_element(context, value, id, weight);
            } else {
                GRN_BULK_REWIND(element_value);
                if (!NIL_P(rb_element_value)) {
                    RVAL2GRNBULK(rb_element_value, context, element_value);
                }

                grn_vector_add_element(context, value,
                                       GRN_BULK_HEAD(element_value),
                                       GRN_BULK_VSIZE(element_value),
                                       weight,
                                       element_value->header.domain);
            }
        }
    } else if (RVAL2CBOOL(rb_obj_is_kind_of(rb_value, rb_cHash))) {
        HashElementToVectorElementData data;
        data.self = self;
        data.context = context;
        data.vector = value;
        data.element_value = element_value;
        data.range = range;
        rb_hash_foreach(rb_value, hash_element_to_vector_element, (VALUE)&data);
    } else {
        rb_raise(rb_eArgError,
                 "<%s>: "
                 "weight vector value must be an array of index value or "
                 "a hash that key is vector value and value is vector weight: "
                 "<%s>",
                 rb_grn_inspect(self),
                 rb_grn_inspect(rb_value));
    }

    rc = grn_obj_set_value(context, column, id, value, flags);
    rb_grn_context_check(context, self);
    rb_grn_rc_check(rc, self);

    return rb_value;
}