/* * Document-method: reference? * * call-seq: * column.reference? -> true/false * * _column_ の値がテーブルのレコードとなる場合は +true+ を返し、 * そうでない場合は +false+ を返す。 * * @since 1.0.5 */ static VALUE rb_grn_column_reference_p (VALUE self) { grn_ctx *context; grn_obj *column; grn_id range_id; grn_obj *range; unsigned short int type; rb_grn_column_deconstruct(SELF(self), &column, &context, NULL, NULL, NULL, NULL, NULL); range_id = grn_obj_get_range(context, column); range = grn_ctx_at(context, range_id); type = range->header.type; grn_obj_unlink(context, range); switch (type) { case GRN_TABLE_HASH_KEY: case GRN_TABLE_PAT_KEY: case GRN_TABLE_NO_KEY: return Qtrue; default: return Qfalse; } }
/* * Document-method: clear_lock * * call-seq: * column.clear_lock(options={}) * * _column_のロックを強制的に解除する。 * * 利用可能なオプションは以下の通り。 * * [_:id_] * _:id_で指定したレコードのロックを強制的に解除する。 * (注: groonga側が未実装のため、現在は無視される。実装さ * れるのではないかと思っているが、実装されないかもしれな * い。) */ static VALUE rb_grn_column_clear_lock (int argc, VALUE *argv, VALUE self) { grn_id id = GRN_ID_NIL; grn_ctx *context; grn_obj *column; 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); grn_obj_clear_lock(context, column); return Qnil; }
void rb_grn_index_column_deconstruct (RbGrnIndexColumn *rb_grn_index_column, grn_obj **column, grn_ctx **context, grn_id *domain_id, grn_obj **domain, grn_obj **value, grn_obj **old_value, grn_id *range_id, grn_obj **range, grn_obj **id_query, grn_obj **string_query) { RbGrnObject *rb_grn_object; rb_grn_object = RB_GRN_OBJECT(rb_grn_index_column); rb_grn_column_deconstruct(RB_GRN_COLUMN(rb_grn_object), column, context, domain_id, domain, value, range_id, range); if (old_value) *old_value = rb_grn_index_column->old_value; if (id_query) *id_query = rb_grn_index_column->id_query; if (string_query) *string_query = rb_grn_index_column->string_query; }
/* * Document-method: index? * * call-seq: * column.index? -> true/false * * _column_ がGroonga::IndexColumnの場合は +true+ を返し、 * そうでない場合は +false+ を返す。 * * @since 1.0.5 */ static VALUE rb_grn_column_index_p (VALUE self) { grn_ctx *context; grn_obj *column; rb_grn_column_deconstruct(SELF(self), &column, &context, NULL, NULL, NULL, NULL, NULL); if (column->header.type == GRN_COLUMN_INDEX) { return Qtrue; } else { return Qfalse; } }
/* * Document-method: vector? * * call-seq: * column.vector? -> true/false * * _column_ がベクターカラムの場合は +true+ を返し、 * そうでない場合は +false+ を返す。 * * @since 1.0.5 */ static VALUE rb_grn_column_vector_p (VALUE self) { grn_ctx *context; grn_obj *column; rb_grn_column_deconstruct(SELF(self), &column, &context, NULL, NULL, NULL, NULL, NULL); if (column->header.type == GRN_COLUMN_VAR_SIZE && ((column->header.flags & GRN_OBJ_COLUMN_TYPE_MASK) == GRN_OBJ_COLUMN_VECTOR)) { return Qtrue; } else { return Qfalse; } }
static void rb_grn_variable_size_column_deconstruct (RbGrnVariableSizeColumn *rb_column, grn_obj **column, grn_ctx **context, grn_id *domain_id, grn_obj **domain, grn_obj **value, grn_obj **element_value, grn_id *range_id, grn_obj **range) { RbGrnColumn *rb_grn_column; rb_grn_column = RB_GRN_COLUMN(rb_column); rb_grn_column_deconstruct(rb_grn_column, column, context, domain_id, domain, value, range_id, range); if (element_value) *element_value = rb_column->element_value; }
/* * 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; }
/* * Document-method: indexes * * call-seq: * column.indexes(operator=Groonga::Operator::MATCH) -> [index_column, ...] * * _operation_ を実行できる _column_ のインデックスを返す。 * * @since 1.0.9 */ static VALUE rb_grn_column_get_indexes (int argc, VALUE *argv, VALUE self) { grn_ctx *context; grn_obj *column; grn_obj **indexes = NULL; int i, n_indexes; grn_operator operator = GRN_OP_MATCH; VALUE rb_operator, rb_indexes; rb_scan_args(argc, argv, "01", &rb_operator); rb_grn_column_deconstruct(SELF(self), &column, &context, NULL, NULL, NULL, NULL, NULL); if (!NIL_P(rb_operator)) { operator = RVAL2GRNOPERATOR(rb_operator); } rb_indexes = rb_ary_new(); n_indexes = grn_column_index(context, column, operator, NULL, 0, NULL); if (n_indexes == 0) return rb_indexes; indexes = xmalloc(sizeof(grn_obj *) * n_indexes); n_indexes = grn_column_index(context, column, operator, indexes, n_indexes, NULL); for (i = 0; i < n_indexes; i++) { VALUE rb_index; rb_index = GRNOBJECT2RVAL(Qnil, context, indexes[i], GRN_FALSE); rb_ary_push(rb_indexes, rb_index); grn_obj_unlink(context, indexes[i]); } xfree(indexes); return rb_indexes; }
/* * 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; } }
/* * Document-method: scalar? * * call-seq: * column.scalar? -> true/false * * _column_ がスカラーカラムの場合は +true+ を返し、 * そうでない場合は +false+ を返す。 * * @since 1.0.5 */ static VALUE rb_grn_column_scalar_p (VALUE self) { grn_ctx *context; grn_obj *column; rb_grn_column_deconstruct(SELF(self), &column, &context, NULL, NULL, NULL, NULL, NULL); switch (column->header.type) { case GRN_COLUMN_FIX_SIZE: return Qtrue; case GRN_COLUMN_VAR_SIZE: if ((column->header.flags & GRN_OBJ_COLUMN_TYPE_MASK) == GRN_OBJ_COLUMN_SCALAR) { return Qtrue; } else { return Qfalse; } default: return Qfalse; } }
/* * call-seq: * column.select(options) {|record| ...} -> Groonga::Hash * column.select(query, options) -> Groonga::Hash * column.select(expression, options) -> Groonga::Hash * * カラムが所属するテーブルからブロックまたは文字列で指定し * た条件にマッチするレコードを返す。返されたテーブルには * +expression+という特異メソッドがあり、指定した条件を表し * ているGroonga::Expressionを取得できる。 * Groonga::Expression#snippetを使うことにより、指定した条件 * 用のスニペットを簡単に生成できる。 * * results = description_column.select do |column| * column =~ "groonga" * end * snippet = results.expression.snippet([["<em>", "</em>"]]) * results.each do |record| * puts "#{record['name']}の説明文の中で「groonga」が含まれる部分" * snippet.execute(record["description"].each do |snippet| * puts "---" * puts "#{snippet}..." * puts "---" * end * end * * 出力例 * Ruby/groongaの説明文の中で「groonga」が含まれる部分 * --- * Ruby/<em>groonga</em>は<em>groonga</em>のいわゆるDB-APIの層の... * --- * * _query_には「[カラム名]:[演算子][値]」という書式で条件を * 指定する。演算子は以下の通り。 * * [なし] * [カラム値] == [値] * [<tt>!</tt>] * [カラム値] != [値] * [<tt><</tt>] * [カラム値] < [値] * [<tt>></tt>] * [カラム値] > [値] * [<tt><=</tt>] * [カラム値] <= [値] * [<tt>>=</tt>] * [カラム値] >= [値] * [<tt>@</tt>] * [カラム値]が[値]を含んでいるかどうか * * 例: * "groonga" # _column_カラムの値が"groonga"のレコードにマッチ * "name:daijiro" # _column_カラムが属しているテーブルの * # "name"カラムの値が"daijiro"のレコードにマッチ * "description:@groonga" # _column_カラムが属しているテーブルの * # "description"カラムが * # "groonga"を含んでいるレコードにマッチ * * _expression_には既に作成済みのGroonga::Expressionを渡す * * ブロックで条件を指定する場合は * Groonga::ColumnExpressionBuilderを参照。 * * _options_に指定可能な値は以下の通り。 * * [+:operator+] * マッチしたレコードをどのように扱うか。指定可能な値は以 * 下の通り。省略した場合はGroonga::Operation::OR。 * * [Groonga::Operation::OR] * マッチしたレコードを追加。すでにレコードが追加され * ている場合は何もしない。 * [Groonga::Operation::AND] * マッチしたレコードのスコアを増加。マッチしなかった * レコードを削除。 * [Groonga::Operation::BUT] * マッチしたレコードを削除。 * [Groonga::Operation::ADJUST] * マッチしたレコードのスコアを増加。 * * [+:result+] * 検索結果を格納するテーブル。マッチしたレコードが追加さ * れていく。省略した場合は新しくテーブルを作成して返す。 * * [+:name+] * 条件の名前。省略した場合は名前を付けない。 * * [+:syntax+] * _query_の構文。省略した場合は+:query+。 * * 参考: Groonga::Expression#parse. * * [+:allow_pragma+] * query構文時にプラグマを利用するかどうか。省略した場合は * 利用する。 * * 参考: Groonga::Expression#parse. * * [+:allow_column+] * query構文時にカラム指定を利用するかどうか。省略した場合 * は利用する。 * * 参考: Groonga::Expression#parse. * * [+:allow_update+] * script構文時に更新操作を利用するかどうか。省略した場合 * は利用する。 * * 参考: Groonga::Expression#parse. */ static VALUE rb_grn_column_select (int argc, VALUE *argv, VALUE self) { grn_ctx *context; grn_obj *table, *column, *result, *expression; grn_operator operator = GRN_OP_OR; VALUE options; VALUE rb_query, condition_or_options; VALUE rb_name, rb_operator, rb_result, rb_syntax; VALUE rb_allow_pragma, rb_allow_column, rb_allow_update; VALUE builder; VALUE rb_expression = Qnil; rb_query = Qnil; rb_scan_args(argc, argv, "02", &condition_or_options, &options); rb_grn_column_deconstruct(SELF(self), &column, &context, NULL, NULL, NULL, NULL, NULL); table = grn_column_table(context, column); if (RVAL2CBOOL(rb_obj_is_kind_of(condition_or_options, rb_cString))) { rb_query = condition_or_options; } else if (RVAL2CBOOL(rb_obj_is_kind_of(condition_or_options, rb_cGrnExpression))) { rb_expression = condition_or_options; } else { if (!NIL_P(options)) rb_raise(rb_eArgError, "should be [query_string, option_hash], " "[expression, option_hash] " "or [option_hash]: %s", rb_grn_inspect(rb_ary_new4(argc, argv))); options = condition_or_options; } rb_grn_scan_options(options, "operator", &rb_operator, "result", &rb_result, "name", &rb_name, "syntax", &rb_syntax, "allow_pragma", &rb_allow_pragma, "allow_column", &rb_allow_column, "allow_update", &rb_allow_update, NULL); if (!NIL_P(rb_operator)) operator = NUM2INT(rb_operator); if (NIL_P(rb_result)) { result = grn_table_create(context, NULL, 0, NULL, GRN_TABLE_HASH_KEY | GRN_OBJ_WITH_SUBREC, table, 0); rb_result = GRNTABLE2RVAL(context, result, RB_GRN_TRUE); } else { result = RVAL2GRNTABLE(rb_result, &context); } if (NIL_P(rb_expression)) { builder = rb_grn_column_expression_builder_new(self, rb_name, rb_query); rb_funcall(builder, rb_intern("syntax="), 1, rb_syntax); rb_funcall(builder, rb_intern("allow_pragma="), 1, rb_allow_pragma); rb_funcall(builder, rb_intern("allow_column="), 1, rb_allow_column); rb_funcall(builder, rb_intern("allow_update="), 1, rb_allow_update); rb_expression = rb_grn_column_expression_builder_build(builder); } rb_grn_object_deconstruct(RB_GRN_OBJECT(DATA_PTR(rb_expression)), &expression, NULL, NULL, NULL, NULL, NULL); grn_table_select(context, table, expression, result, operator); rb_grn_context_check(context, self); rb_attr(rb_singleton_class(rb_result), rb_intern("expression"), RB_GRN_TRUE, RB_GRN_FALSE, RB_GRN_FALSE); rb_iv_set(rb_result, "@expression", rb_expression); return rb_result; }