예제 #1
0
/*
 * call-seq:
 *   column.local_name
 *
 * テーブル名を除いたカラム名を返す。
 *
 *   items = Groonga::Array.create(:name => "Items")
 *   title = items.define_column("title", "ShortText")
 *   title.name # => "Items.title"
 *   title.local_name # => "title"
 */
static VALUE
rb_grn_column_get_local_name (VALUE self)
{
    RbGrnColumn *rb_grn_column;
    grn_ctx *context = NULL;
    grn_obj *column;
    VALUE rb_name;
    char *name;
    int name_size;

    rb_grn_column = SELF(self);
    rb_grn_object_deconstruct(RB_GRN_OBJECT(rb_grn_column), &column, &context,
			      NULL, NULL,
			      NULL, NULL);
    name_size = grn_column_name(context, column, NULL, 0);
    if (name_size == 0)
	return Qnil;

    name = xmalloc(name_size);
    grn_column_name(context, column, name, name_size);
    rb_name = rb_str_new(name, name_size);
    xfree(name);

    return rb_name;
}
예제 #2
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;
}
예제 #3
0
/*
 * 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);
}
예제 #4
0
/*
 * Returns whether the column is compressed or not. If
 * @type@ is specified, it returns whether the column is
 * compressed by @type@ or not.
 * @overload compressed?
 *   @return [Boolean] whether the column is compressed or not.
 * @overload compressed?(type)
 *   @param [:zlib, :lz4] type (nil)
 *   @return [Boolean] whether specified compressed type is used or not.
 * @since 1.3.1
 */
static VALUE
rb_grn_variable_size_column_compressed_p (int argc, VALUE *argv, VALUE self)
{
    RbGrnVariableSizeColumn *rb_grn_column;
    grn_ctx *context = NULL;
    grn_obj *column;
    grn_obj_flags flags;
    VALUE type;
    grn_bool compressed_p = GRN_FALSE;
    grn_bool accept_any_type = GRN_FALSE;
    grn_bool need_zlib_check = GRN_FALSE;
    grn_bool need_lz4_check = GRN_FALSE;

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

    if (NIL_P(type)) {
        accept_any_type = GRN_TRUE;
    } else {
        if (rb_grn_equal_option(type, "zlib")) {
            need_zlib_check = GRN_TRUE;
        } else if (rb_grn_equal_option(type, "lzo")) {
            /* TODO: for backward compatibility */
            need_lz4_check = GRN_TRUE;
        } else if (rb_grn_equal_option(type, "lz4")) {
            need_lz4_check = GRN_TRUE;
        } else {
            rb_raise(rb_eArgError,
                     "compressed type should be <:zlib> or <:lz4>: <%s>",
                     rb_grn_inspect(type));
        }
    }

    rb_grn_column = SELF(self);
    rb_grn_object_deconstruct(RB_GRN_OBJECT(rb_grn_column), &column, &context,
                              NULL, NULL,
                              NULL, NULL);

    flags = column->header.flags;
    switch (flags & GRN_OBJ_COMPRESS_MASK) {
      case GRN_OBJ_COMPRESS_ZLIB:
        if (accept_any_type || need_zlib_check) {
            grn_obj support_p;
            GRN_BOOL_INIT(&support_p, 0);
            grn_obj_get_info(context, NULL, GRN_INFO_SUPPORT_ZLIB, &support_p);
            compressed_p = GRN_BOOL_VALUE(&support_p);
        }
        break;
      case GRN_OBJ_COMPRESS_LZ4:
        if (accept_any_type || need_lz4_check) {
            grn_obj support_p;
            GRN_BOOL_INIT(&support_p, 0);
            grn_obj_get_info(context, NULL, GRN_INFO_SUPPORT_LZ4, &support_p);
            compressed_p = GRN_BOOL_VALUE(&support_p);
        }
        break;
    }

    return CBOOL2RVAL(compressed_p);
}
예제 #5
0
void
rb_grn_snippet_deconstruct (RbGrnSnippet *rb_grn_snippet,
                            grn_obj **snippet,
                            grn_ctx **context)
{
    RbGrnObject *rb_grn_object;

    rb_grn_object = RB_GRN_OBJECT(rb_grn_snippet);
    rb_grn_object_deconstruct(rb_grn_object, snippet, context,
                              NULL, NULL,
                              NULL, NULL);
}
예제 #6
0
static void
rb_grn_database_deconstruct (RbGrnObject *rb_grn_database,
                             grn_obj **database,
                             grn_ctx **context,
                             grn_id *domain_id,
                             grn_obj **domain,
                             grn_id *range_id,
                             grn_obj **range)
{
    rb_grn_object_deconstruct(rb_grn_database, database, context,
                              domain_id, domain,
                              range_id, range);
}
예제 #7
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);
}
예제 #8
0
void
rb_grn_table_cursor_deconstruct (RbGrnTableCursor *rb_grn_table_cursor,
				 grn_table_cursor **cursor,
				 grn_ctx **context,
				 grn_id *domain_id,
				 grn_obj **domain,
				 grn_id *range_id,
				 grn_obj **range)
{
    RbGrnObject *rb_grn_object;

    rb_grn_object = RB_GRN_OBJECT(rb_grn_table_cursor);
    rb_grn_object_deconstruct(rb_grn_object, cursor, context,
			      domain_id, domain,
			      range_id, range);
}
예제 #9
0
void
rb_grn_column_deconstruct (RbGrnColumn *rb_column,
			   grn_obj **column,
			   grn_ctx **context,
			   grn_id *domain_id,
			   grn_obj **domain,
			   grn_obj **value,
			   grn_id *range_id,
			   grn_obj **range)
{
    RbGrnObject *rb_grn_object;

    rb_grn_object = RB_GRN_OBJECT(rb_column);
    rb_grn_object_deconstruct(rb_grn_object, column, context,
			      domain_id, domain,
			      range_id, range);

    if (value)
	*value = rb_column->value;
}
예제 #10
0
void
rb_grn_expression_deconstruct (RbGrnExpression *rb_grn_expression,
                               grn_obj **expression,
                               grn_ctx **context,
                               grn_id *domain_id,
                               grn_obj **domain,
                               grn_obj **value,
                               grn_id *range_id,
                               grn_obj **range)
{
    RbGrnObject *rb_grn_object;

    rb_grn_object = RB_GRN_OBJECT(rb_grn_expression);
    rb_grn_object_deconstruct(rb_grn_object, expression, context,
                              domain_id, domain,
                              range_id, range);

    if (value)
        *value = rb_grn_expression->value;
}
예제 #11
0
/*
 * 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;
}