示例#1
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;
}
示例#2
0
static int
grn_token_cursor_next_apply_token_filters(grn_ctx *ctx,
                                          grn_token_cursor *token_cursor,
                                          grn_obj *current_token_data,
                                          grn_obj *status)
{
  grn_obj *token_filters = token_cursor->token_filter.objects;
  unsigned int i, n_token_filters;
  grn_token current_token;
  grn_token next_token;

  if (token_filters) {
    n_token_filters = GRN_BULK_VSIZE(token_filters) / sizeof(grn_obj *);
  } else {
    n_token_filters = 0;
  }

  GRN_TEXT_INIT(&(current_token.data), GRN_OBJ_DO_SHALLOW_COPY);
  GRN_TEXT_SET(ctx, &(current_token.data),
               GRN_TEXT_VALUE(current_token_data),
               GRN_TEXT_LEN(current_token_data));
  current_token.status = GRN_INT32_VALUE(status);
  GRN_TEXT_INIT(&(next_token.data), GRN_OBJ_DO_SHALLOW_COPY);
  GRN_TEXT_SET(ctx, &(next_token.data),
               GRN_TEXT_VALUE(&(current_token.data)),
               GRN_TEXT_LEN(&(current_token.data)));
  next_token.status = current_token.status;

  for (i = 0; i < n_token_filters; i++) {
    grn_obj *token_filter_object = GRN_PTR_VALUE_AT(token_filters, i);
    grn_proc *token_filter = (grn_proc *)token_filter_object;
    void *data = token_cursor->token_filter.data[i];

#define SKIP_FLAGS\
    (GRN_TOKEN_SKIP |\
     GRN_TOKEN_SKIP_WITH_POSITION)
    if (current_token.status & SKIP_FLAGS) {
      break;
    }
#undef SKIP_FLAGS

    token_filter->callbacks.token_filter.filter(ctx,
                                                &current_token,
                                                &next_token,
                                                data);
    GRN_TEXT_SET(ctx, &(current_token.data),
                 GRN_TEXT_VALUE(&(next_token.data)),
                 GRN_TEXT_LEN(&(next_token.data)));
    current_token.status = next_token.status;
  }

  token_cursor->curr =
    (const unsigned char *)GRN_TEXT_VALUE(&(current_token.data));
  token_cursor->curr_size = GRN_TEXT_LEN(&(current_token.data));

  return current_token.status;
}
示例#3
0
grn_obj *
grn_mrb_value_to_bulk(mrb_state *mrb, mrb_value mrb_value_, grn_obj *bulk)
{
  grn_ctx *ctx = (grn_ctx *)mrb->ud;

  switch (mrb_type(mrb_value_)) {
  case MRB_TT_FALSE :
    if (mrb_nil_p(mrb_value_)) {
      grn_obj_reinit(ctx, bulk, GRN_DB_VOID, 0);
    } else {
      grn_obj_reinit(ctx, bulk, GRN_DB_BOOL, 0);
      GRN_BOOL_SET(ctx, bulk, GRN_FALSE);
    }
    break;
  case MRB_TT_TRUE :
    grn_obj_reinit(ctx, bulk, GRN_DB_BOOL, 0);
    GRN_BOOL_SET(ctx, bulk, GRN_TRUE);
    break;
  case MRB_TT_FIXNUM :
    grn_obj_reinit(ctx, bulk, GRN_DB_INT64, 0);
    GRN_INT64_SET(ctx, bulk, mrb_fixnum(mrb_value_));
    break;
  case MRB_TT_SYMBOL :
    {
      const char *name;
      mrb_int name_length;

      grn_obj_reinit(ctx, bulk, GRN_DB_TEXT, 0);
      name = mrb_sym2name_len(mrb, mrb_symbol(mrb_value_), &name_length);
      GRN_TEXT_SET(ctx, bulk, name, name_length);
    }
    break;
  case MRB_TT_FLOAT :
    grn_obj_reinit(ctx, bulk, GRN_DB_FLOAT, 0);
    GRN_FLOAT_SET(ctx, bulk, mrb_float(mrb_value_));
    break;
  case MRB_TT_STRING :
    grn_obj_reinit(ctx, bulk, GRN_DB_TEXT, 0);
    GRN_TEXT_SET(ctx, bulk, RSTRING_PTR(mrb_value_), RSTRING_LEN(mrb_value_));
    break;
  default :
    mrb_raisef(mrb, E_ARGUMENT_ERROR,
               "unsupported object to convert to bulk: %S",
               mrb_value_);
    break;
  }

  return bulk;
}
示例#4
0
文件: token.c 项目: groonga/groonga
grn_rc
grn_token_copy(grn_ctx *ctx,
               grn_token *token,
               grn_token *source)
{
  GRN_API_ENTER;
  if (!token) {
    ERR(GRN_INVALID_ARGUMENT, "[token][copy] token must not be NULL");
    goto exit;
  }
  GRN_TEXT_SET(ctx,
               &(token->data),
               GRN_TEXT_VALUE(&(source->data)),
               GRN_TEXT_LEN(&(source->data)));
  token->status = source->status;
  token->source_offset = source->source_offset;
  token->source_length = source->source_length;
  token->source_first_character_length = source->source_first_character_length;
  token->have_overlap = source->have_overlap;
  grn_token_metadata_reset(ctx, &(token->metadata));
  grn_token_metadata_copy(ctx, &(token->metadata), &(source->metadata));
  token->force_prefix_search = source->force_prefix_search;
  token->position = source->position;
exit:
  GRN_API_RETURN(ctx->rc);
}
示例#5
0
static void query_expand(mrn::QueryExpandInfo *info, UDF_ARGS *args)
{
  grn_ctx *ctx = info->ctx;
  const char *query = args->args[3];
  unsigned int query_length = args->lengths[3];

  mrn::QueryParser query_parser(info->ctx,
                                current_thd,
                                NULL,
                                NULL,
                                0,
                                NULL);
  const char *raw_query;
  size_t raw_query_length;
  grn_operator default_operator;
  grn_expr_flags flags;
  query_parser.parse_pragma(query,
                            query_length,
                            &raw_query,
                            &raw_query_length,
                            &default_operator,
                            &flags);
  GRN_TEXT_SET(info->ctx,
               &(info->expanded_query),
               query,
               raw_query - query);
  grn_expr_syntax_expand_query_by_table(ctx,
                                        raw_query,
                                        raw_query_length,
                                        flags,
                                        info->term_column,
                                        info->expanded_term_column,
                                        &(info->expanded_query));
}
示例#6
0
static mrb_value
mrb_grn_expression_allocate_constant(mrb_state *mrb, mrb_value self)
{
  grn_ctx *ctx = (grn_ctx *)mrb->ud;
  grn_obj *expr;
  mrb_value mrb_object;
  grn_obj *grn_object;

  mrb_get_args(mrb, "o", &mrb_object);
  expr = DATA_PTR(self);

  switch (mrb_type(mrb_object)) {
  case MRB_TT_STRING:
    grn_object = grn_expr_alloc_const(ctx, expr);
    if (!grn_object) {
      grn_mrb_ctx_check(mrb);
    }
    GRN_TEXT_INIT(grn_object, 0);
    GRN_TEXT_SET(ctx, grn_object,
                 RSTRING_PTR(mrb_object), RSTRING_LEN(mrb_object));
    break;
  default:
    mrb_raisef(mrb, E_ARGUMENT_ERROR, "unsupported type: %S", mrb_object);
    break;
  }

  return grn_mrb_value_from_grn_obj(mrb, grn_object);
}
示例#7
0
grn_obj *
rb_grn_key_from_ruby_object (VALUE rb_key, grn_ctx *context,
                             grn_obj *key, grn_id domain_id, grn_obj *domain,
                             VALUE related_object)
{
    grn_id id;

    if (!domain)
        return RVAL2GRNBULK(rb_key, context, key);

    switch (domain->header.type) {
    case GRN_TYPE:
        return RVAL2GRNBULK_WITH_TYPE(rb_key, context, key, domain_id, domain);
        break;
    case GRN_TABLE_HASH_KEY:
    case GRN_TABLE_PAT_KEY:
    case GRN_TABLE_DAT_KEY:
    case GRN_TABLE_NO_KEY:
        id = RVAL2GRNID(rb_key, context, domain, related_object);
        break;
    default:
        if (!RVAL2CBOOL(rb_obj_is_kind_of(rb_key, rb_cInteger)))
            rb_raise(rb_eGrnError,
                     "should be unsigned integer: <%s>: <%s>",
                     rb_grn_inspect(rb_key),
                     rb_grn_inspect(related_object));

        id = NUM2UINT(rb_key);
        break;
    }

    GRN_TEXT_SET(context, key, &id, sizeof(id));
    return key;
}
示例#8
0
static void
insert_document(const gchar *author_content, const gchar *body_content)
{
  uint32_t s = (uint32_t)strlen(body_content);
  grn_id docid = grn_table_add(&context, docs, NULL, 0, NULL);

  if (author_content) {
    GRN_TEXT_SET(&context, &text_buf, author_content, strlen(author_content));
    grn_test_assert(grn_obj_set_value(&context, author, docid, &text_buf,
                                      GRN_OBJ_SET));
  }

  GRN_TEXT_SET(&context, &text_buf, body_content, s);
  grn_test_assert(grn_obj_set_value(&context, body, docid, &text_buf,
                                    GRN_OBJ_SET));

  GRN_UINT32_SET(&context, &int_buf, s);
  grn_test_assert(grn_obj_set_value(&context, size, docid, &int_buf,
                                    GRN_OBJ_SET));
}
示例#9
0
VALUE
rb_grn_key_to_ruby_object (grn_ctx *context, const void *key, int key_size,
                           grn_obj *table, VALUE related_object)
{
    grn_obj bulk;

    GRN_OBJ_INIT(&bulk, GRN_BULK, GRN_OBJ_DO_SHALLOW_COPY, table->header.domain);
    GRN_TEXT_SET(context, &bulk, key, key_size);

    return GRNBULK2RVAL(context, &bulk, NULL, related_object);
}
示例#10
0
static void
insert_document(const gchar *body_content)
{
  uint32_t s = (uint32_t)strlen(body_content);
  grn_id docid = grn_table_add(&context, docs, NULL, 0, NULL);
  const gchar *size_string;
  struct tm time;

  GRN_TEXT_SET(&context, &textbuf, body_content, s);
  grn_test_assert(grn_obj_set_value(&context, body, docid, &textbuf,
                                    GRN_OBJ_SET));

  GRN_UINT32_SET(&context, &intbuf, s);
  grn_test_assert(grn_obj_set_value(&context, size, docid, &intbuf,
                                    GRN_OBJ_SET));

  size_string = cut_take_printf("%u", s);
  GRN_TEXT_SET(&context, &textbuf, size_string, strlen(size_string));
  grn_test_assert(grn_obj_set_value(&context, size_in_string, docid, &textbuf,
                                    GRN_OBJ_SET));

  GRN_FLOAT_SET(&context, &floatbuf, s);
  grn_test_assert(grn_obj_set_value(&context, size_in_float, docid, &floatbuf,
                                    GRN_OBJ_SET));

  time.tm_sec = s;
  time.tm_min = 16;
  time.tm_hour = 15;
  time.tm_mday = 2;
  time.tm_mon = 11;
  time.tm_year = 109;
  time.tm_wday = 3;
  time.tm_yday = 336;
  time.tm_isdst = 0;
  GRN_TIME_SET(&context, &timebuf, GRN_TIME_PACK(mktime(&time), 0));
  grn_test_assert(grn_obj_set_value(&context, created_at, docid, &timebuf,
                                    GRN_OBJ_SET));
}
示例#11
0
  void ConditionConverter::append_const_item(const Item_field *field_item,
                                             Item *const_item,
                                             grn_obj *expression) {
    MRN_DBUG_ENTER_METHOD();

    enum_field_types field_type = field_item->field_type();
    NormalizedType normalized_type = normalize_field_type(field_type);

    switch (normalized_type) {
    case STRING_TYPE:
      grn_obj_reinit(ctx_, &value_, GRN_DB_TEXT, 0);
      {
        String *string;
        string = const_item->val_str(NULL);
        GRN_TEXT_SET(ctx_, &value_, string->ptr(), string->length());
      }
      break;
    case INT_TYPE:
      grn_obj_reinit(ctx_, &value_, GRN_DB_INT64, 0);
      GRN_INT64_SET(ctx_, &value_, const_item->val_int());
      break;
    case TIME_TYPE:
      grn_obj_reinit(ctx_, &value_, GRN_DB_TIME, 0);
      {
        MYSQL_TIME mysql_time;
        get_time_value(field_item, const_item, &mysql_time);
        bool truncated = false;
        TimeConverter time_converter;
        long long int time =
          time_converter.mysql_time_to_grn_time(&mysql_time, &truncated);
        GRN_TIME_SET(ctx_, &value_, time);
      }
      break;
    case UNSUPPORTED_TYPE:
      // Should not be occurred.
      DBUG_PRINT("error",
                 ("mroonga: append_const_item: unsupported type: <%d> "
                  "This case should not be occurred.",
                  field_type));
      grn_obj_reinit(ctx_, &value_, GRN_DB_VOID, 0);
      break;
    }
    grn_expr_append_const(ctx_, expression, &value_, GRN_OP_PUSH, 1);

    DBUG_VOID_RETURN;
  }
示例#12
0
grn_rc
grn_token_set_data(grn_ctx *ctx,
                   grn_token *token,
                   const char *str_ptr,
                   int str_length)
{
  GRN_API_ENTER;
  if (!token) {
    ERR(GRN_INVALID_ARGUMENT, "token must not be NULL");
    goto exit;
  }
  if (str_length == -1) {
    str_length = strlen(str_ptr);
  }
  GRN_TEXT_SET(ctx, &(token->data), str_ptr, str_length);
exit:
  GRN_API_RETURN(ctx->rc);
}
示例#13
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;
}
示例#14
0
static mrb_value
mrb_grn_cache_update(mrb_state *mrb, mrb_value self)
{
  grn_ctx *ctx = (grn_ctx *)mrb->ud;
  grn_cache *cache;
  char *key;
  mrb_int key_size;
  char *value;
  mrb_int value_size;
  grn_obj value_buffer;

  cache = DATA_PTR(self);
  mrb_get_args(mrb, "ss", &key, &key_size, &value, &value_size);

  GRN_TEXT_INIT(&value_buffer, GRN_OBJ_DO_SHALLOW_COPY);
  GRN_TEXT_SET(ctx, &value_buffer, value, value_size);
  grn_cache_update(ctx, cache, key, key_size, &value_buffer);
  GRN_OBJ_FIN(ctx, &value_buffer);

  return mrb_nil_value();
}
示例#15
0
VALUE
rb_grn_uvector_to_ruby_object (grn_ctx *context, grn_obj *uvector,
                               grn_obj *range, VALUE related_object)
{
    VALUE array = Qnil;

    if (!uvector)
        return Qnil;

    if (!range) {
        rb_raise(rb_eTypeError,
                 "unknown range uvector can't be converted: <%s>",
                 rb_grn_inspect(related_object));
    }

    switch (range->header.type) {
    case GRN_TYPE: {
        const char *current, *end;
        grn_id range_id;
        grn_obj value;
        int value_size;
        value_size = grn_obj_get_range(context, range);
        array = rb_ary_new();
        current = GRN_BULK_HEAD(uvector);
        end = GRN_BULK_CURR(uvector);
        range_id = grn_obj_id(context, range);
        GRN_OBJ_INIT(&value, GRN_BULK, GRN_OBJ_DO_SHALLOW_COPY, range_id);
        while (current < end) {
            VALUE rb_value;
            GRN_TEXT_SET(context, &value, current, value_size);
            rb_value = GRNBULK2RVAL(context, &value, range, related_object);
            rb_ary_push(array, rb_value);
            current += value_size;
        }
        GRN_OBJ_FIN(context, &value);
        break;
    }
    case GRN_TABLE_HASH_KEY:
    case GRN_TABLE_PAT_KEY:
    case GRN_TABLE_DAT_KEY:
    case GRN_TABLE_NO_KEY: {
        grn_id *current, *end;
        VALUE rb_range = Qnil;
        array = rb_ary_new();
        rb_range = GRNTABLE2RVAL(context, range, GRN_FALSE);
        current = (grn_id *)GRN_BULK_HEAD(uvector);
        end = (grn_id *)GRN_BULK_CURR(uvector);
        while (current < end) {
            VALUE record = Qnil;
            if (*current != GRN_ID_NIL) {
                record = rb_grn_record_new(rb_range, *current, Qnil);
            }
            rb_ary_push(array, record);
            current++;
        }
        break;
    }
    default:
        rb_raise(rb_eTypeError,
                 "unknown range uvector can't be converted: %s(%#x): <%s>",
                 rb_grn_inspect_type(range->header.type),
                 range->header.type,
                 rb_grn_inspect(related_object));
        break;
    }

    return array;
}
示例#16
0
grn_obj *
rb_grn_bulk_from_ruby_object_with_type (VALUE object, grn_ctx *context,
                                        grn_obj *bulk,
                                        grn_id type_id, grn_obj *type)
{
    const char *string;
    unsigned int size;
    union {
        int8_t int8_value;
        uint8_t uint8_value;
        int16_t int16_value;
        uint16_t uint16_value;
        int32_t int32_value;
        uint32_t uint32_value;
        int64_t int64_value;
        uint64_t uint64_value;
        int64_t time_value;
        double double_value;
        grn_geo_point geo_point_value;
        grn_id record_id;
    } value;
    grn_id range;
    VALUE rb_type_object;
    grn_obj_flags flags = 0;
    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);

    switch (type_id) {
    case GRN_DB_INT8:
        value.int8_value = NUM2SHORT(object);
        string = (const char *)&(value.int8_value);
        size = sizeof(value.int8_value);
        break;
    case GRN_DB_UINT8:
        value.uint8_value = NUM2USHORT(object);
        string = (const char *)&(value.uint8_value);
        size = sizeof(value.uint8_value);
        break;
    case GRN_DB_INT16:
        value.int16_value = NUM2SHORT(object);
        string = (const char *)&(value.int16_value);
        size = sizeof(value.int16_value);
        break;
    case GRN_DB_UINT16:
        value.uint16_value = NUM2USHORT(object);
        string = (const char *)&(value.uint16_value);
        size = sizeof(value.uint16_value);
        break;
    case GRN_DB_INT32:
        value.int32_value = NUM2INT(object);
        string = (const char *)&(value.int32_value);
        size = sizeof(value.int32_value);
        break;
    case GRN_DB_UINT32:
        value.uint32_value = NUM2UINT(object);
        string = (const char *)&(value.uint32_value);
        size = sizeof(value.uint32_value);
        break;
    case GRN_DB_INT64:
        value.int64_value = NUM2LL(object);
        string = (const char *)&(value.int64_value);
        size = sizeof(value.int64_value);
        break;
    case GRN_DB_UINT64:
        value.uint64_value = NUM2ULL(object);
        string = (const char *)&(value.uint64_value);
        size = sizeof(value.uint64_value);
        break;
    case GRN_DB_FLOAT:
        value.double_value = NUM2DBL(object);
        string = (const char *)&(value.double_value);
        size = sizeof(value.double_value);
        break;
    case GRN_DB_TIME: {
        VALUE rb_sec, rb_usec;
        int64_t sec;
        int32_t usec;

        if (string_p) {
            ID id_parse;
            CONST_ID(id_parse, "parse");
            object = rb_funcall(rb_cTime, id_parse, 1, object);
        }

        switch (TYPE(object)) {
        case T_FIXNUM:
        case T_BIGNUM:
            sec = NUM2LL(object);
            usec = 0;
            break;
        case T_FLOAT:
            rb_sec = rb_funcall(object, rb_intern("to_i"), 0);
            rb_usec = rb_funcall(object, rb_intern("remainder"), 1,
                                 INT2NUM(1));

            sec = NUM2LL(rb_sec);
            usec = (int32_t)(NUM2DBL(rb_usec) * 1000000);
            break;
        case T_NIL:
            sec = 0;
            usec = 0;
            break;
        default:
            sec = NUM2LL(rb_funcall(object, rb_intern("to_i"), 0));
            usec = NUM2INT(rb_funcall(object, rb_intern("usec"), 0));
            break;
        }

        value.time_value = GRN_TIME_PACK(sec, usec);
        string = (const char *)&(value.time_value);
        size = sizeof(value.time_value);
        break;
    }
    case GRN_DB_SHORT_TEXT:
    case GRN_DB_TEXT:
    case GRN_DB_LONG_TEXT:
        string = StringValuePtr(object);
        size = RSTRING_LEN(object);
        range = grn_obj_get_range(context, type);
        if (size > range)
            rb_raise(rb_eArgError,
                     "string is too large: expected: %u <= %u",
                     size, range);
        flags |= GRN_OBJ_DO_SHALLOW_COPY;
        break;
    case GRN_DB_TOKYO_GEO_POINT:
    case GRN_DB_WGS84_GEO_POINT: {
        VALUE rb_geo_point;
        VALUE rb_latitude, rb_longitude;
        if (type_id == GRN_DB_TOKYO_GEO_POINT) {
            rb_geo_point = rb_funcall(rb_cGrnTokyoGeoPoint,
                                      rb_intern("new"), 1, object);
        } else {
            rb_geo_point = rb_funcall(rb_cGrnWGS84GeoPoint,
                                      rb_intern("new"), 1, object);
        }
        rb_geo_point = rb_funcall(rb_geo_point, rb_intern("to_msec"), 0);
        rb_latitude  = rb_funcall(rb_geo_point, rb_intern("latitude"), 0);
        rb_longitude = rb_funcall(rb_geo_point, rb_intern("longitude"), 0);
        value.geo_point_value.latitude = NUM2INT(rb_latitude);
        value.geo_point_value.longitude = NUM2INT(rb_longitude);
        string = (const char *)&(value.geo_point_value);
        size = sizeof(value.geo_point_value);
        break;
    }
    case GRN_DB_VOID:
    case GRN_DB_DELIMIT:
    case GRN_DB_UNIGRAM:
    case GRN_DB_BIGRAM:
    case GRN_DB_TRIGRAM:
    case GRN_DB_MECAB:
        rb_type_object = GRNOBJECT2RVAL(Qnil, context, type, GRN_FALSE);
        rb_raise(rb_eArgError,
                 "unbulkable type: %s",
                 rb_grn_inspect(rb_type_object));
        break;
    default:
        if (table_type_p &&
            (NIL_P(object) || (string_p && RSTRING_LEN(object) == 0))) {
            value.record_id = GRN_ID_NIL;
            string = (const char *)&(value.record_id);
            size = sizeof(value.record_id);
            if (bulk && bulk->header.domain != type_id) {
                grn_obj_reinit(context, bulk, type_id, 0);
            }
        } else {
            return RVAL2GRNBULK(object, context, bulk);
        }
        break;
    }

    if (!bulk) {
        bulk = grn_obj_open(context, GRN_BULK, flags, GRN_ID_NIL);
        rb_grn_context_check(context, object);
    }
    GRN_TEXT_SET(context, bulk, string, size);

    return bulk;
}
示例#17
0
void
test_mroonga_index(void)
{
  grn_obj *t1,*c1,*lc,*ft;
  grn_obj buff;
  grn_id c1_id,r1,r2,r3,r4;
  const gchar *mrn_dir;

  mrn_dir = cut_build_path(tmp_directory, "mrn", NULL);
  g_mkdir_with_parents(mrn_dir, 0700);

  grn_obj_close(context, db);
  db = grn_db_create(context,
                     cut_build_path(mrn_dir, "mroonga.grn", NULL),
                     NULL);
  cut_assert_not_null(db);

  /* actual table */
  t1 = grn_table_create(context, "t1", 2,
                        cut_build_path(mrn_dir, "t1.grn", NULL),
			GRN_OBJ_TABLE_NO_KEY|GRN_OBJ_PERSISTENT, NULL, 0);
  cut_assert_not_null(t1);

  /* lexicon table */
  lc = grn_table_create(context, "lc", 2,
                        cut_build_path(mrn_dir, "lc.grn", NULL),
			GRN_OBJ_TABLE_PAT_KEY|GRN_OBJ_PERSISTENT,
                        grn_ctx_at(context, GRN_DB_SHORT_TEXT), 0);
  cut_assert_not_null(lc);
  grn_test_assert(grn_obj_set_info(context, lc, GRN_INFO_DEFAULT_TOKENIZER,
				   grn_ctx_at(context, GRN_DB_BIGRAM)));

  /* actual column */
  c1 = grn_column_create(context, t1, "c1", 2,
                         cut_build_path(mrn_dir, "t1.c1.grn", NULL),
			 GRN_OBJ_COLUMN_SCALAR|GRN_OBJ_PERSISTENT,
			 grn_ctx_at(context, GRN_DB_TEXT));
  cut_assert_not_null(c1);

  /* fulltext index */
  ft = grn_column_create(context, lc, "ft", 2,
                         cut_build_path(mrn_dir, "lc.ft.grn", NULL),
			 GRN_OBJ_COLUMN_INDEX|GRN_OBJ_PERSISTENT, t1);
  cut_assert_not_null(ft);

  GRN_TEXT_INIT(&buff,0);

  /* link between actual column and fulltext index */
  c1_id = grn_obj_id(context, c1);
  GRN_TEXT_SET(context, &buff, (char*)&c1_id, sizeof(grn_id));
  grn_obj_set_info(context, ft, GRN_INFO_SOURCE, &buff); /* need to use grn_id */

  /* insert row */
  r1 = grn_table_add(context, t1, NULL, 0, NULL);
  cut_assert_equal_int(1,r1);
  GRN_TEXT_SET(context, &buff, "abcde", 5);
  grn_test_assert(grn_obj_set_value(context, c1, r1, &buff, GRN_OBJ_SET));

  r2 = grn_table_add(context, t1, NULL, 0, NULL);
  cut_assert_equal_int(2,r2);
  GRN_TEXT_SET(context, &buff, "fghij", 5);
  grn_test_assert(grn_obj_set_value(context, c1, r2, &buff, GRN_OBJ_SET));

  r3 = grn_table_add(context, t1, NULL, 0, NULL);
  cut_assert_equal_int(3,r3);
  GRN_TEXT_SET(context, &buff, "11 22 33", 8);
  grn_test_assert(grn_obj_set_value(context, c1, r3, &buff, GRN_OBJ_SET));

  r4 = grn_table_add(context, t1, NULL, 0, NULL);
  cut_assert_equal_int(4,r4);
  GRN_TEXT_SET(context, &buff, "44 22 55", 8);
  grn_test_assert(grn_obj_set_value(context, c1, r4, &buff, GRN_OBJ_SET));

  /* confirm record are inserted in both column and index */
  cut_assert_equal_int(4,grn_table_size(context,t1));
  cut_assert_equal_int(23,grn_table_size(context,lc));

  /* nlq search */
  {
    grn_id id, docid;
    grn_obj *res;
    grn_table_cursor *tc;
    res = grn_table_create(context, NULL, 0, NULL, GRN_TABLE_HASH_KEY, t1, 0);
    GRN_BULK_REWIND(&buff);
    GRN_TEXT_SET(context, &buff, "hi", 2);
    grn_obj_search(context, ft, &buff, res, GRN_OP_OR, NULL);
    cut_assert_equal_int(1, grn_table_size(context, res));
    tc = grn_table_cursor_open(context, res, NULL, 0, NULL, 0, 0, -1, 0);
    while ((id = grn_table_cursor_next(context, tc))) {
      GRN_BULK_REWIND(&buff);
      grn_table_get_key(context, res, id, &docid, sizeof(grn_id));
      cut_assert_equal_int(2, docid);
      cut_assert_not_null(grn_obj_get_value(context, c1, docid, &buff));
      cut_assert_equal_int(5 ,GRN_TEXT_LEN(&buff));
      cut_assert_equal_substring("fghij", (char*) GRN_BULK_HEAD(&buff),GRN_TEXT_LEN(&buff));
    }
    grn_table_cursor_close(context, tc);
    grn_obj_close(context, res);
  }

  /* boolean search */
  {
    grn_id id, docid;
    grn_obj *match_columns, *match_columns_variable;
    grn_obj *expression, *expression_variable;
    grn_obj *res;
    grn_table_cursor *tc;
    const char *match_columns_expression = "c1";
    const char *qstr = "+22 -55";

    GRN_EXPR_CREATE_FOR_QUERY(context, t1,
                              match_columns, match_columns_variable);
    grn_expr_parse(context, match_columns,
                   match_columns_expression,
                   strlen(match_columns_expression),
                   NULL, GRN_OP_MATCH, GRN_OP_AND,
                   GRN_EXPR_SYNTAX_SCRIPT);
    GRN_EXPR_CREATE_FOR_QUERY(context, t1, expression, expression_variable);
    res = grn_table_create(context, NULL, 0, NULL, GRN_TABLE_HASH_KEY, t1, 0);
    grn_test_assert(grn_expr_parse(context, expression,
                                   qstr, strlen(qstr),
                                   match_columns,
                                   GRN_OP_MATCH, GRN_OP_OR,
                                   GRN_EXPR_SYNTAX_QUERY));
    grn_table_select(context, t1, expression, res, GRN_OP_OR);
    cut_assert_equal_int(1, grn_table_size(context, res));
    tc = grn_table_cursor_open(context, res, NULL, 0, NULL, 0, 0, -1, 0);
    while ((id = grn_table_cursor_next(context, tc))) {
      GRN_BULK_REWIND(&buff);
      grn_table_get_key(context, res, id, &docid, sizeof(grn_id));
      cut_assert_equal_int(3, docid);
      cut_assert_not_null(grn_obj_get_value(context, c1, docid, &buff));
      cut_assert_equal_int(8 ,GRN_TEXT_LEN(&buff));
      cut_assert_equal_substring("11 22 33", (char*) GRN_BULK_HEAD(&buff),GRN_TEXT_LEN(&buff));
    }
    grn_obj_close(context, expression);
    grn_obj_close(context, match_columns);
    grn_table_cursor_close(context ,tc);
    grn_obj_close(context, res);
  }

  grn_obj_close(context, &buff);
  grn_obj_close(context, ft);
  grn_obj_close(context, c1);
  grn_obj_close(context, lc);
  grn_obj_close(context, t1);
}
示例#18
0
void
test_mroonga_index(void)
{
    grn_obj *t1,*c1,*lc,*ft;
    grn_obj buff;
    grn_id c1_id,r1,r2,r3,r4;

    remove_tmp_directory();
    g_mkdir_with_parents(tmp_directory,0700);
    g_chdir(tmp_directory);
    g_mkdir_with_parents("mrn",0700);

    db = grn_db_create(context,"mroonga.grn",NULL);
    cut_assert_not_null(db);

    /* actual table */
    t1 = grn_table_create(context,"t1",2,"mrn/t1.grn",
                          GRN_OBJ_TABLE_NO_KEY|GRN_OBJ_PERSISTENT,NULL,0);
    cut_assert_not_null(t1);

    /* lexicon table */
    lc = grn_table_create(context,"lc",2,"mrn/lc.grn",
                          GRN_OBJ_TABLE_PAT_KEY|GRN_OBJ_PERSISTENT,
                          grn_ctx_at(context, GRN_DB_SHORT_TEXT), 0);
    cut_assert_not_null(lc);
    grn_test_assert(grn_obj_set_info(context, lc, GRN_INFO_DEFAULT_TOKENIZER,
                                     grn_ctx_at(context, GRN_DB_BIGRAM)));

    /* actual column */
    c1 = grn_column_create(context,t1,"c1",2,"mrn/t1.c1.grn",
                           GRN_OBJ_COLUMN_SCALAR|GRN_OBJ_PERSISTENT,
                           grn_ctx_at(context, GRN_DB_TEXT));
    cut_assert_not_null(c1);

    /* fulltext index */
    ft = grn_column_create(context,lc,"ft",2,"mrn/lc.ft.grn",
                           GRN_OBJ_COLUMN_INDEX|GRN_OBJ_PERSISTENT,t1);
    cut_assert_not_null(ft);

    GRN_TEXT_INIT(&buff,0);

    /* link between actual column and fulltext index */
    c1_id = grn_obj_id(context, c1);
    GRN_TEXT_SET(context, &buff, (char*)&c1_id, sizeof(grn_id));
    grn_obj_set_info(context, ft, GRN_INFO_SOURCE, &buff); /* need to use grn_id */

    /* insert row */
    r1 = grn_table_add(context, t1, NULL, 0, NULL);
    cut_assert_equal_int(1,r1);
    GRN_TEXT_SET(context, &buff, "abcde", 5);
    grn_test_assert(grn_obj_set_value(context, c1, r1, &buff, GRN_OBJ_SET));

    r2 = grn_table_add(context, t1, NULL, 0, NULL);
    cut_assert_equal_int(2,r2);
    GRN_TEXT_SET(context, &buff, "fghij", 5);
    grn_test_assert(grn_obj_set_value(context, c1, r2, &buff, GRN_OBJ_SET));

    r3 = grn_table_add(context, t1, NULL, 0, NULL);
    cut_assert_equal_int(3,r3);
    GRN_TEXT_SET(context, &buff, "11 22 33", 8);
    grn_test_assert(grn_obj_set_value(context, c1, r3, &buff, GRN_OBJ_SET));

    r4 = grn_table_add(context, t1, NULL, 0, NULL);
    cut_assert_equal_int(4,r4);
    GRN_TEXT_SET(context, &buff, "44 22 55", 8);
    grn_test_assert(grn_obj_set_value(context, c1, r4, &buff, GRN_OBJ_SET));

    /* confirm record are inserted in both column and index */
    cut_assert_equal_int(4,grn_table_size(context,t1));
    cut_assert_equal_int(23,grn_table_size(context,lc));

    /* nlq search */
    {
        grn_id id, docid;
        grn_obj *res;
        grn_table_cursor *tc;
        res = grn_table_create(context, NULL, 0, NULL, GRN_TABLE_HASH_KEY, t1, 0);
        GRN_BULK_REWIND(&buff);
        GRN_TEXT_SET(context, &buff, "hi", 2);
        grn_obj_search(context, ft, &buff, res, GRN_OP_OR, NULL);
        cut_assert_equal_int(1, grn_table_size(context, res));
        tc = grn_table_cursor_open(context, res, NULL, 0, NULL, 0, 0, 0, 0);
        while ((id = grn_table_cursor_next(context, tc))) {
            GRN_BULK_REWIND(&buff);
            grn_table_get_key(context, res, id, &docid, sizeof(grn_id));
            cut_assert_equal_int(2, docid);
            cut_assert_not_null(grn_obj_get_value(context, c1, docid, &buff));
            cut_assert_equal_int(5 ,GRN_TEXT_LEN(&buff));
            cut_assert_equal_substring("fghij", (char*) GRN_BULK_HEAD(&buff),GRN_TEXT_LEN(&buff));
        }
        grn_table_cursor_close(context, tc);
        grn_obj_close(context, res);
    }

    /* boolean search */
    {
        grn_id id, docid;
        grn_obj *res;
        grn_query *query;
        grn_table_cursor *tc;
        const char *qstr = "+22 -55";
        res = grn_table_create(context, NULL, 0, NULL, GRN_TABLE_HASH_KEY, t1, 0);
        query = grn_query_open(context, qstr, strlen(qstr), GRN_OP_OR, 32);
        grn_obj_search(context, ft, (grn_obj*) query, res, GRN_OP_OR, NULL);
        cut_assert_equal_int(1, grn_table_size(context, res));
        tc = grn_table_cursor_open(context, res, NULL, 0, NULL, 0, 0, 0, 0);
        while ((id = grn_table_cursor_next(context, tc))) {
            GRN_BULK_REWIND(&buff);
            grn_table_get_key(context, res, id, &docid, sizeof(grn_id));
            cut_assert_equal_int(3, docid);
            cut_assert_not_null(grn_obj_get_value(context, c1, docid, &buff));
            cut_assert_equal_int(8 ,GRN_TEXT_LEN(&buff));
            cut_assert_equal_substring("11 22 33", (char*) GRN_BULK_HEAD(&buff),GRN_TEXT_LEN(&buff));
        }
        grn_query_close(context, query);
        grn_table_cursor_close(context ,tc);
        grn_obj_close(context, res);
    }

    grn_obj_close(context, &buff);
    grn_obj_close(context, ft);
    grn_obj_close(context, c1);
    grn_obj_close(context, lc);
    grn_obj_close(context, t1);
}
示例#19
0
grn_obj *
rb_grn_bulk_from_ruby_object_with_type (VALUE object, grn_ctx *context,
					grn_obj *bulk,
					grn_id type_id, grn_obj *type)
{
    const char *string;
    unsigned int size;
    int32_t int32_value;
    uint32_t uint32_value;
    int64_t int64_value;
    uint64_t uint64_value;
    int64_t time_value;
    double double_value;
    grn_id record_id, range;
    VALUE rb_type_object;
    grn_obj_flags flags = 0;
    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_VIEW);
    if (string_p && !table_type_p) {
	return RVAL2GRNBULK(object, context, bulk);
    }

    switch (type_id) {
      case GRN_DB_INT32:
	int32_value = NUM2INT(object);
	string = (const char *)&int32_value;
	size = sizeof(int32_value);
	break;
      case GRN_DB_UINT32:
	uint32_value = NUM2UINT(object);
	string = (const char *)&uint32_value;
	size = sizeof(uint32_value);
	break;
      case GRN_DB_INT64:
	int64_value = NUM2LL(object);
	string = (const char *)&int64_value;
	size = sizeof(int64_value);
	break;
      case GRN_DB_UINT64:
	uint64_value = NUM2ULL(object);
	string = (const char *)&uint64_value;
	size = sizeof(uint64_value);
	break;
      case GRN_DB_FLOAT:
	double_value = NUM2DBL(object);
	string = (const char *)&double_value;
	size = sizeof(double_value);
	break;
      case GRN_DB_TIME:
	{
	    VALUE rb_sec, rb_usec;
            int64_t sec;
            int32_t usec;

            switch (TYPE(object)) {
            case T_FIXNUM:
            case T_BIGNUM:
                sec = NUM2LL(object);
                usec = 0;
                break;
            case T_FLOAT:
                rb_sec = rb_funcall(object, rb_intern("to_i"), 0);
                rb_usec = rb_funcall(object, rb_intern("remainder"), 1,
				     INT2NUM(1));

                sec = NUM2LL(rb_sec);
                usec = (int32_t)(NUM2DBL(rb_usec) * 1000000);
                break;
	    case T_NIL:
	        sec = 0;
	        usec = 0;
	        break;
            default:
                sec = NUM2LL(rb_funcall(object, rb_intern("to_i"), 0));
                usec = NUM2INT(rb_funcall(object, rb_intern("usec"), 0));
                break;
            }

	    time_value = GRN_TIME_PACK(sec, usec);
	}
	string = (const char *)&time_value;
	size = sizeof(time_value);
	break;
      case GRN_DB_SHORT_TEXT:
      case GRN_DB_TEXT:
      case GRN_DB_LONG_TEXT:
	string = StringValuePtr(object);
	size = RSTRING_LEN(object);
	range = grn_obj_get_range(context, type);
	if (size > range)
	    rb_raise(rb_eArgError,
		     "string is too large: expected: %u <= %u",
		     size, range);
	flags |= GRN_OBJ_DO_SHALLOW_COPY;
	break;
      case GRN_DB_VOID:
      case GRN_DB_DELIMIT:
      case GRN_DB_UNIGRAM:
      case GRN_DB_BIGRAM:
      case GRN_DB_TRIGRAM:
      case GRN_DB_MECAB:
	rb_type_object = GRNOBJECT2RVAL(Qnil, context, type, GRN_FALSE);
	rb_raise(rb_eArgError,
		 "unbulkable type: %s",
		 rb_grn_inspect(rb_type_object));
	break;
      default:
	if (table_type_p &&
	    (NIL_P(object) || (string_p && RSTRING_LEN(object) == 0))) {
	    record_id = GRN_ID_NIL;
	    string = (const char *)&record_id;
	    size = sizeof(record_id);
	    if (bulk && bulk->header.domain != type_id) {
		grn_obj_reinit(context, bulk, type_id, 0);
	    }
	} else {
	    return RVAL2GRNBULK(object, context, bulk);
	}
	break;
    }

    if (!bulk) {
	bulk = grn_obj_open(context, GRN_BULK, flags, GRN_ID_NIL);
	rb_grn_context_check(context, object);
    }
    GRN_TEXT_SET(context, bulk, string, size);

    return bulk;
}
示例#20
0
void
rb_grn_context_text_set (grn_ctx *context, grn_obj *bulk, VALUE rb_string)
{
    rb_string = rb_grn_context_rb_string_encode(context, rb_string);
    GRN_TEXT_SET(context, bulk, RSTRING_PTR(rb_string), RSTRING_LEN(rb_string));
}