Example #1
0
void
grn_time_now(grn_ctx *ctx, grn_obj *obj)
{
  grn_timeval tv;
  grn_timeval_now(ctx, &tv);
  GRN_TIME_SET(ctx, obj, GRN_TIME_PACK(tv.tv_sec,
                                       GRN_TIME_NSEC_TO_USEC(tv.tv_nsec)));
}
Example #2
0
grn_bool
grn_time_from_tm(grn_ctx *ctx, int64_t *time, struct tm *tm)
{
  time_t sec_time_t;
  int64_t sec;
  int32_t usec = 0;

  if (!grn_time_t_from_tm(ctx, &sec_time_t, tm)) {
    return GRN_FALSE;
  }

  sec = sec_time_t;
  *time = GRN_TIME_PACK(sec, usec);
  return GRN_TRUE;
}
Example #3
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));
}
Example #4
0
void
data_text_otoj(void)
{
#define ADD_DATUM(label, expected, type, ...)                   \
  gcut_add_datum(label,                                         \
                 "expected", G_TYPE_STRING, expected,           \
                 "type", G_TYPE_INT, type,                      \
                 __VA_ARGS__);

  ADD_DATUM("Void", "", GRN_DB_VOID, NULL);
  ADD_DATUM("Bool", "true", GRN_DB_BOOL,
            "value", G_TYPE_BOOLEAN, TRUE,
            NULL);
  ADD_DATUM("Bool", "false", GRN_DB_BOOL,
            "value", G_TYPE_BOOLEAN, FALSE,
            NULL);
  ADD_DATUM("Int8 (min)", cut_take_printf("%d", INT8_MIN), GRN_DB_INT8,
            "value", G_TYPE_INT, INT8_MIN,
            NULL);
  ADD_DATUM("Int8 (max)", cut_take_printf("%d", INT8_MAX), GRN_DB_INT8,
            "value", G_TYPE_INT, INT8_MAX,
            NULL);
  ADD_DATUM("UInt8 (min)", "0", GRN_DB_UINT8,
            "value", G_TYPE_UINT, 0,
            NULL);
  ADD_DATUM("UInt8 (max)", cut_take_printf("%u", UINT8_MAX), GRN_DB_UINT8,
            "value", G_TYPE_UINT, UINT8_MAX,
            NULL);
  ADD_DATUM("Int16 (min)", cut_take_printf("%d", INT16_MIN), GRN_DB_INT16,
            "value", G_TYPE_INT, INT16_MIN,
            NULL);
  ADD_DATUM("Int16 (max)", cut_take_printf("%d", INT16_MAX), GRN_DB_INT16,
            "value", G_TYPE_INT, INT16_MAX,
            NULL);
  ADD_DATUM("UInt16 (min)", "0", GRN_DB_UINT16,
            "value", G_TYPE_UINT, 0,
            NULL);
  ADD_DATUM("UInt16 (max)", cut_take_printf("%u", UINT16_MAX), GRN_DB_UINT16,
            "value", G_TYPE_UINT, UINT16_MAX,
            NULL);
  ADD_DATUM("Int32 (min)", cut_take_printf("%d", INT32_MIN), GRN_DB_INT32,
            "value", G_TYPE_INT, INT32_MIN,
            NULL);
  ADD_DATUM("Int32 (max)", cut_take_printf("%d", INT32_MAX), GRN_DB_INT32,
            "value", G_TYPE_INT, INT32_MAX,
            NULL);
  ADD_DATUM("UInt32 (min)", "0", GRN_DB_UINT32,
            "value", G_TYPE_UINT, 0,
            NULL);
  ADD_DATUM("UInt32 (max)", cut_take_printf("%u", UINT32_MAX), GRN_DB_UINT32,
            "value", G_TYPE_UINT, UINT32_MAX,
            NULL);
  ADD_DATUM("Int64 (min)",
            cut_take_printf("%" G_GINT64_FORMAT, INT64_MIN), GRN_DB_INT64,
            "value", G_TYPE_INT64, INT64_MIN,
            NULL);
  ADD_DATUM("Int64 (max)",
            cut_take_printf("%" G_GINT64_FORMAT, INT64_MAX), GRN_DB_INT64,
            "value", G_TYPE_INT64, INT64_MAX,
            NULL);
  ADD_DATUM("UInt64 (min)", "0", GRN_DB_UINT64,
            "value", G_TYPE_UINT64, G_GUINT64_CONSTANT(0),
            NULL);
  ADD_DATUM("UInt64 (max)",
            cut_take_printf("%" G_GUINT64_FORMAT, UINT64_MAX), GRN_DB_UINT64,
            "value", G_TYPE_UINT64, UINT64_MAX,
            NULL);
  ADD_DATUM("Float", cut_take_printf("%g", 2.9), GRN_DB_FLOAT,
            "value", G_TYPE_DOUBLE, 2.9,
            NULL);
  ADD_DATUM("Time", "1271053050.21148", GRN_DB_TIME,
            "value", G_TYPE_INT64, GRN_TIME_PACK(1271053050, 211479),
            NULL);
  ADD_DATUM("ShortText",
            "\"\\\"'\\\\aAzZ09 \\n\\t\\r日本語\"", GRN_DB_SHORT_TEXT,
            "value", G_TYPE_STRING, "\"'\\aAzZ09 \n\t\r日本語",
            NULL);
  ADD_DATUM("Text",
            "\"\\\"'\\\\aAzZ09 \\n\\t\\r日本語\"", GRN_DB_TEXT,
            "value", G_TYPE_STRING, "\"'\\aAzZ09 \n\t\r日本語",
            NULL);
  ADD_DATUM("LongText",
            "\"\\\"'\\\\aAzZ09 \\n\\t\\r日本語\"", GRN_DB_LONG_TEXT,
            "value", G_TYPE_STRING, "\"'\\aAzZ09 \n\t\r日本語",
            NULL);
  ADD_DATUM("TokyoGeoPoint", "\"35681396x139766049\"", GRN_DB_TOKYO_GEO_POINT,
            "latitude", G_TYPE_INT, 35681396,
            "longitude", G_TYPE_INT, 139766049,
            NULL);
  ADD_DATUM("WGS84GeoPoint", "\"36032548x140164867\"", GRN_DB_WGS84_GEO_POINT,
            "latitude", G_TYPE_INT, 36032548,
            "longitude", G_TYPE_INT, 140164867,
            NULL);

  /* FIXME* unknown bulk */
  /* FIXME: GRN_UVECTOR */
  /* FIXME: GRN_VECTOR */
  /* FIXME: table with format */
  /* FIXME: table without format */
  /* FIXME: grn_text_atoj */

#undef ADD_DATUM
}
Example #5
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;
}
Example #6
0
grn_obj *
rb_grn_bulk_from_ruby_object (VALUE object, grn_ctx *context, grn_obj *bulk)
{
    if (bulk && bulk->header.domain == GRN_DB_TIME)
        return RVAL2GRNBULK_WITH_TYPE(object, context, bulk,
                                      bulk->header.domain,
                                      grn_ctx_at(context, bulk->header.domain));

    if (!bulk) {
        bulk = grn_obj_open(context, GRN_BULK, 0, GRN_ID_NIL);
        rb_grn_context_check(context, object);
    }

    switch (TYPE(object)) {
    case T_NIL:
        grn_obj_reinit(context, bulk, GRN_DB_VOID, 0);
        break;
    case T_SYMBOL:
        object = rb_funcall(object, rb_intern("to_s"), 0);
    case T_STRING:
        grn_obj_reinit(context, bulk, GRN_DB_TEXT, 0);
        rb_grn_context_text_set(context, bulk, object);
        break;
    case T_FIXNUM:
    case T_BIGNUM: {
        int64_t int64_value;
        int64_value = NUM2LL(object);
        if (int64_value <= INT32_MAX) {
            grn_obj_reinit(context, bulk, GRN_DB_INT32, 0);
            GRN_INT32_SET(context, bulk, int64_value);
        } else {
            grn_obj_reinit(context, bulk, GRN_DB_INT64, 0);
            GRN_INT64_SET(context, bulk, int64_value);
        }
        break;
    }
    case T_FLOAT:
        grn_obj_reinit(context, bulk, GRN_DB_FLOAT, 0);
        GRN_FLOAT_SET(context, bulk, NUM2DBL(object));
        break;
    case T_TRUE:
        grn_obj_reinit(context, bulk, GRN_DB_BOOL, 0);
        GRN_BOOL_SET(context, bulk, GRN_TRUE);
        break;
    case T_FALSE:
        grn_obj_reinit(context, bulk, GRN_DB_BOOL, 0);
        GRN_BOOL_SET(context, bulk, GRN_FALSE);
        break;
    default:
        if (RVAL2CBOOL(rb_obj_is_kind_of(object, rb_cTime))) {
            VALUE sec, usec;
            int64_t time_value;

            sec = rb_funcall(object, rb_intern("to_i"), 0);
            usec = rb_funcall(object, rb_intern("usec"), 0);
            time_value = GRN_TIME_PACK(NUM2LL(sec), NUM2LL(usec));
            grn_obj_reinit(context, bulk, GRN_DB_TIME, 0);
            GRN_TIME_SET(context, bulk, time_value);
        } else if (RVAL2CBOOL(rb_obj_is_kind_of(object, rb_cGrnObject))) {
            grn_obj *grn_object;
            grn_id id_value;

            grn_object = RVAL2GRNOBJECT(object, &context);
            grn_obj_reinit(context, bulk, grn_object->header.domain, 0);
            id_value = grn_obj_id(context, grn_object);
            GRN_RECORD_SET(context, bulk, id_value);
        } else if (RVAL2CBOOL(rb_obj_is_kind_of(object, rb_cGrnRecord))) {
            grn_obj *table;
            grn_id id_value;

            table = RVAL2GRNOBJECT(rb_funcall(object, rb_intern("table"), 0),
                                   &context);
            id_value = NUM2UINT(rb_funcall(object, rb_intern("id"), 0));
            grn_obj_reinit(context, bulk, grn_obj_id(context, table), 0);
            GRN_RECORD_SET(context, bulk, id_value);
        } else {
            rb_raise(rb_eTypeError,
                     "bulked object should be one of "
                     "[nil, true, false, String, Symbol, Integer, Float, Time, "
                     "Groonga::Object, Groonga::Record]: %s",
                     rb_grn_inspect(object));
        }
        break;
    }

    return bulk;
}
Example #7
0
static mrb_value
mrb_grn_expression_append_constant(mrb_state *mrb, mrb_value self)
{
  grn_ctx *ctx = (grn_ctx *)mrb->ud;
  grn_obj *expr;
  mrb_value mrb_constant;
  mrb_value mrb_op;
  grn_operator op;
  int n_args;

  expr = DATA_PTR(self);
  mrb_get_args(mrb, "ooi", &mrb_constant, &mrb_op, &n_args);

  op = grn_mrb_value_to_operator(mrb, mrb_op);
  switch (mrb_type(mrb_constant)) {
  case MRB_TT_FALSE :
    if (mrb_nil_p(mrb_constant)) {
      grn_obj constant;
      GRN_VOID_INIT(&constant);
      grn_expr_append_const(ctx, expr, &constant, op, n_args);
      GRN_OBJ_FIN(ctx, &constant);
    } else {
      grn_obj constant;
      GRN_BOOL_INIT(&constant, 0);
      GRN_BOOL_SET(ctx, &constant, GRN_FALSE);
      grn_expr_append_const(ctx, expr, &constant, op, n_args);
      GRN_OBJ_FIN(ctx, &constant);
    }
    break;
  case MRB_TT_TRUE :
    {
      grn_obj constant;
      GRN_BOOL_INIT(&constant, 0);
      GRN_BOOL_SET(ctx, &constant, GRN_TRUE);
      grn_expr_append_const(ctx, expr, &constant, op, n_args);
      GRN_OBJ_FIN(ctx, &constant);
    }
    break;
  case MRB_TT_FIXNUM :
    grn_expr_append_const_int(ctx, expr, mrb_fixnum(mrb_constant), op, n_args);
    break;
  case MRB_TT_SYMBOL :
    {
      const char *value;
      mrb_int value_length;

      value = mrb_sym2name_len(mrb, mrb_symbol(mrb_constant), &value_length);
      grn_expr_append_const_str(ctx, expr, value, value_length, op, n_args);
    }
    break;
  case MRB_TT_FLOAT :
    {
      grn_obj constant;
      GRN_FLOAT_INIT(&constant, 0);
      GRN_FLOAT_SET(ctx, &constant, mrb_float(mrb_constant));
      grn_expr_append_const(ctx, expr, &constant, op, n_args);
      GRN_OBJ_FIN(ctx, &constant);
    }
    break;
  case MRB_TT_STRING :
    grn_expr_append_const_str(ctx, expr,
                              RSTRING_PTR(mrb_constant),
                              RSTRING_LEN(mrb_constant),
                              op, n_args);
    break;
  default :
    {
      struct RClass *klass;

      klass = mrb_class(mrb, mrb_constant);
      if (klass == ctx->impl->mrb.builtin.time_class) {
        grn_obj constant;
        mrb_value mrb_sec;
        mrb_value mrb_usec;

        mrb_sec = mrb_funcall(mrb, mrb_constant, "to_i", 0);
        mrb_usec = mrb_funcall(mrb, mrb_constant, "usec", 0);
        GRN_TIME_INIT(&constant, 0);
        GRN_TIME_SET(ctx, &constant,
                     GRN_TIME_PACK(mrb_fixnum(mrb_sec), mrb_fixnum(mrb_usec)));
        grn_expr_append_const(ctx, expr, &constant, op, n_args);
        GRN_OBJ_FIN(ctx, &constant);
      } else {
        mrb_raisef(mrb, E_ARGUMENT_ERROR,
                   "unsupported constant to append to expression: %S",
                   mrb_constant);
      }
    }
    break;
  }

  grn_mrb_ctx_check(mrb);

  return mrb_nil_value();
}
Example #8
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;
}
Example #9
0
void
grn_mrb_value_to_raw_data(mrb_state *mrb,
                          const char *context,
                          mrb_value mrb_value_,
                          grn_id domain_id,
                          grn_mrb_value_to_raw_data_buffer *buffer,
                          void **raw_value,
                          unsigned int *raw_value_size)
{
  grn_ctx *ctx = (grn_ctx *)mrb->ud;
  enum mrb_vtype mrb_value_type;
  grn_bool try_cast = GRN_FALSE;
  grn_obj *from_bulk = NULL;

  if (mrb_nil_p(mrb_value_)) {
    *raw_value = NULL;
    *raw_value_size = 0;
    return;
  }

  mrb_value_type = mrb_type(mrb_value_);

  switch (mrb_value_type) {
  case MRB_TT_STRING :
    switch (domain_id) {
    case GRN_DB_SHORT_TEXT :
    case GRN_DB_TEXT :
    case GRN_DB_LONG_TEXT :
      *raw_value = RSTRING_PTR(mrb_value_);
      *raw_value_size = RSTRING_LEN(mrb_value_);
      break;
    default :
      try_cast = GRN_TRUE;
      break;
    }
    break;
  default :
    {
      struct RClass *klass;
      grn_mrb_data *data = &(ctx->impl->mrb);

      klass = mrb_class(mrb, mrb_value_);
      if (domain_id == GRN_DB_TIME &&
          klass == data->builtin.time_class) {
        mrb_value mrb_sec;
        mrb_value mrb_usec;

        mrb_sec = mrb_funcall(mrb, mrb_value_, "to_i", 0);
        mrb_usec = mrb_funcall(mrb, mrb_value_, "usec", 0);
        buffer->value.time_value = GRN_TIME_PACK(mrb_fixnum(mrb_sec),
                                                 mrb_fixnum(mrb_usec));
        *raw_value = &(buffer->value.time_value);
        *raw_value_size = sizeof(buffer->value.time_value);
      } else {
        try_cast = GRN_TRUE;
        if (mrb_value_type == MRB_TT_DATA &&
            klass == mrb_class_get_under(mrb, data->module, "Bulk")) {
          from_bulk = DATA_PTR(mrb_value_);
        }
      }
    }
    break;
  }

  if (!try_cast) {
    return;
  }

  if (!from_bulk) {
    from_bulk = &(buffer->from);
    grn_mrb_value_to_bulk(mrb, mrb_value_, from_bulk);
  }
  if (!grn_mrb_bulk_cast(mrb, from_bulk, &(buffer->to), domain_id)) {
    grn_obj *domain;
    char domain_name[GRN_TABLE_MAX_KEY_SIZE];
    int domain_name_size;

    domain = grn_ctx_at(ctx, domain_id);
    domain_name_size = grn_obj_name(ctx, domain, domain_name,
                                    GRN_TABLE_MAX_KEY_SIZE);
    mrb_raisef(mrb, E_ARGUMENT_ERROR,
               "%S: failed to convert to %S: %S",
               mrb_str_new_static(mrb, context, strlen(context)),
               mrb_str_new_static(mrb, domain_name, domain_name_size),
               mrb_funcall(mrb, mrb_value_, "inspect", 0));
  }
  *raw_value = GRN_BULK_HEAD(&(buffer->to));
  *raw_value_size = GRN_BULK_VSIZE(&(buffer->to));
}