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; }
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)); }
static void construct_object(gconstpointer data, grn_builtin_type type, grn_obj *object) { switch (type) { case GRN_DB_VOID: GRN_VOID_INIT(object); break; case GRN_DB_BOOL: GRN_BOOL_INIT(object, 0); GRN_BOOL_SET(&context, object, gcut_data_get_boolean(data, "value")); break; case GRN_DB_INT8: GRN_INT8_INIT(object, 0); GRN_INT8_SET(&context, object, gcut_data_get_int(data, "value")); break; case GRN_DB_UINT8: GRN_UINT8_INIT(object, 0); GRN_UINT8_SET(&context, object, gcut_data_get_uint(data, "value")); break; case GRN_DB_INT16: GRN_INT16_INIT(object, 0); GRN_INT16_SET(&context, object, gcut_data_get_int(data, "value")); break; case GRN_DB_UINT16: GRN_UINT16_INIT(object, 0); GRN_UINT16_SET(&context, object, gcut_data_get_uint(data, "value")); break; case GRN_DB_INT32: GRN_INT32_INIT(object, 0); GRN_INT32_SET(&context, object, gcut_data_get_int(data, "value")); break; case GRN_DB_UINT32: GRN_UINT32_INIT(object, 0); GRN_UINT32_SET(&context, object, gcut_data_get_uint(data, "value")); break; case GRN_DB_INT64: GRN_INT64_INIT(object, 0); GRN_INT64_SET(&context, object, gcut_data_get_int64(data, "value")); break; case GRN_DB_UINT64: GRN_UINT64_INIT(object, 0); GRN_UINT64_SET(&context, object, gcut_data_get_uint64(data, "value")); break; case GRN_DB_FLOAT: GRN_FLOAT_INIT(object, 0); GRN_FLOAT_SET(&context, object, gcut_data_get_double(data, "value")); break; case GRN_DB_TIME: GRN_TIME_INIT(object, 0); GRN_TIME_SET(&context, object, gcut_data_get_int64(data, "value")); break; case GRN_DB_SHORT_TEXT: GRN_SHORT_TEXT_INIT(object, 0); GRN_TEXT_SETS(&context, object, gcut_data_get_string(data, "value")); break; case GRN_DB_TEXT: GRN_TEXT_INIT(object, 0); GRN_TEXT_SETS(&context, object, gcut_data_get_string(data, "value")); break; case GRN_DB_LONG_TEXT: GRN_LONG_TEXT_INIT(object, 0); GRN_TEXT_SETS(&context, object, gcut_data_get_string(data, "value")); break; case GRN_DB_TOKYO_GEO_POINT: GRN_TOKYO_GEO_POINT_INIT(object, 0); GRN_GEO_POINT_SET(&context, object, gcut_data_get_int(data, "latitude"), gcut_data_get_int(data, "longitude")); break; case GRN_DB_WGS84_GEO_POINT: GRN_WGS84_GEO_POINT_INIT(object, 0); GRN_GEO_POINT_SET(&context, object, gcut_data_get_int(data, "latitude"), gcut_data_get_int(data, "longitude")); break; default: cut_fail("unknown type: %d", type); break; } }
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; }
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(); }
static void json_read(grn_ctx *ctx, grn_loader *loader, const char *str, unsigned int str_len) { const char *const beg = str; char c; int len; const char *se = str + str_len; while (str < se) { c = *str; switch (loader->stat) { case GRN_LOADER_BEGIN : if ((len = grn_isspace(str, ctx->encoding))) { str += len; continue; } switch (c) { case '[' : JSON_READ_OPEN_BRACKET(); break; case '{' : JSON_READ_OPEN_BRACE(); break; default : ERR(GRN_INVALID_ARGUMENT, "JSON must start with '[' or '{': <%.*s>", str_len, beg); loader->stat = GRN_LOADER_END; break; } break; case GRN_LOADER_TOKEN : if ((len = grn_isspace(str, ctx->encoding))) { str += len; continue; } switch (c) { case '"' : loader->stat = GRN_LOADER_STRING; values_add(ctx, loader); str++; break; case '[' : JSON_READ_OPEN_BRACKET(); break; case '{' : JSON_READ_OPEN_BRACE(); break; case ':' : str++; break; case ',' : str++; break; case ']' : bracket_close(ctx, loader); loader->stat = GRN_BULK_VSIZE(&loader->level) ? GRN_LOADER_TOKEN : GRN_LOADER_END; if (ctx->rc == GRN_CANCEL) { loader->stat = GRN_LOADER_END; } str++; break; case '}' : brace_close(ctx, loader); loader->stat = GRN_BULK_VSIZE(&loader->level) ? GRN_LOADER_TOKEN : GRN_LOADER_END; if (ctx->rc == GRN_CANCEL) { loader->stat = GRN_LOADER_END; } str++; break; case '+' : case '-' : case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : case '9' : loader->stat = GRN_LOADER_NUMBER; values_add(ctx, loader); break; default : if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || ('_' == c)) { loader->stat = GRN_LOADER_SYMBOL; values_add(ctx, loader); } else { if ((len = grn_charlen(ctx, str, se))) { GRN_LOG(ctx, GRN_LOG_ERROR, "ignored invalid char('%c') at", c); GRN_LOG(ctx, GRN_LOG_ERROR, "%.*s", (int)(str - beg) + len, beg); GRN_LOG(ctx, GRN_LOG_ERROR, "%*s", (int)(str - beg) + 1, "^"); str += len; } else { GRN_LOG(ctx, GRN_LOG_ERROR, "ignored invalid char(\\x%.2x) after", c); GRN_LOG(ctx, GRN_LOG_ERROR, "%.*s", (int)(str - beg), beg); str = se; } } break; } break; case GRN_LOADER_SYMBOL : if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || ('0' <= c && c <= '9') || ('_' == c)) { GRN_TEXT_PUTC(ctx, loader->last, c); str++; } else { char *v = GRN_TEXT_VALUE(loader->last); switch (*v) { case 'n' : if (GRN_TEXT_LEN(loader->last) == 4 && !memcmp(v, "null", 4)) { loader->last->header.domain = GRN_DB_VOID; GRN_BULK_REWIND(loader->last); } break; case 't' : if (GRN_TEXT_LEN(loader->last) == 4 && !memcmp(v, "true", 4)) { loader->last->header.domain = GRN_DB_BOOL; GRN_BOOL_SET(ctx, loader->last, GRN_TRUE); } break; case 'f' : if (GRN_TEXT_LEN(loader->last) == 5 && !memcmp(v, "false", 5)) { loader->last->header.domain = GRN_DB_BOOL; GRN_BOOL_SET(ctx, loader->last, GRN_FALSE); } break; default : break; } loader->stat = GRN_BULK_VSIZE(&loader->level) ? GRN_LOADER_TOKEN : GRN_LOADER_END; } break; case GRN_LOADER_NUMBER : switch (c) { case '+' : case '-' : case '.' : case 'e' : case 'E' : case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : case '9' : GRN_TEXT_PUTC(ctx, loader->last, c); str++; break; default : { const char *cur, *str = GRN_BULK_HEAD(loader->last); const char *str_end = GRN_BULK_CURR(loader->last); int64_t i = grn_atoll(str, str_end, &cur); if (cur == str_end) { loader->last->header.domain = GRN_DB_INT64; GRN_INT64_SET(ctx, loader->last, i); } else if (cur != str) { uint64_t i = grn_atoull(str, str_end, &cur); if (cur == str_end) { loader->last->header.domain = GRN_DB_UINT64; GRN_UINT64_SET(ctx, loader->last, i); } else if (cur != str) { double d; char *end; grn_obj buf; GRN_TEXT_INIT(&buf, 0); GRN_TEXT_PUT(ctx, &buf, str, GRN_BULK_VSIZE(loader->last)); GRN_TEXT_PUTC(ctx, &buf, '\0'); errno = 0; d = strtod(GRN_TEXT_VALUE(&buf), &end); if (!errno && end + 1 == GRN_BULK_CURR(&buf)) { loader->last->header.domain = GRN_DB_FLOAT; GRN_FLOAT_SET(ctx, loader->last, d); } GRN_OBJ_FIN(ctx, &buf); } } } loader->stat = GRN_BULK_VSIZE(&loader->level) ? GRN_LOADER_TOKEN : GRN_LOADER_END; break; } break; case GRN_LOADER_STRING : switch (c) { case '\\' : loader->stat = GRN_LOADER_STRING_ESC; str++; break; case '"' : str++; loader->stat = GRN_BULK_VSIZE(&loader->level) ? GRN_LOADER_TOKEN : GRN_LOADER_END; /* *(GRN_BULK_CURR(loader->last)) = '\0'; GRN_LOG(ctx, GRN_LOG_ALERT, "read str(%s)", GRN_TEXT_VALUE(loader->last)); */ break; default : if ((len = grn_charlen(ctx, str, se))) { GRN_TEXT_PUT(ctx, loader->last, str, len); str += len; } else { GRN_LOG(ctx, GRN_LOG_ERROR, "ignored invalid char(\\x%.2x) after", c); GRN_LOG(ctx, GRN_LOG_ERROR, "%.*s", (int)(str - beg), beg); str = se; } break; } break; case GRN_LOADER_STRING_ESC : switch (c) { case 'b' : GRN_TEXT_PUTC(ctx, loader->last, '\b'); loader->stat = GRN_LOADER_STRING; break; case 'f' : GRN_TEXT_PUTC(ctx, loader->last, '\f'); loader->stat = GRN_LOADER_STRING; break; case 'n' : GRN_TEXT_PUTC(ctx, loader->last, '\n'); loader->stat = GRN_LOADER_STRING; break; case 'r' : GRN_TEXT_PUTC(ctx, loader->last, '\r'); loader->stat = GRN_LOADER_STRING; break; case 't' : GRN_TEXT_PUTC(ctx, loader->last, '\t'); loader->stat = GRN_LOADER_STRING; break; case 'u' : loader->stat = GRN_LOADER_UNICODE0; break; default : GRN_TEXT_PUTC(ctx, loader->last, c); loader->stat = GRN_LOADER_STRING; break; } str++; break; case GRN_LOADER_UNICODE0 : switch (c) { case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : case '9' : loader->unichar = (c - '0') * 0x1000; break; case 'a' : case 'b' : case 'c' : case 'd' : case 'e' : case 'f' : loader->unichar = (c - 'a' + 10) * 0x1000; break; case 'A' : case 'B' : case 'C' : case 'D' : case 'E' : case 'F' : loader->unichar = (c - 'A' + 10) * 0x1000; break; default : ;// todo : error } loader->stat = GRN_LOADER_UNICODE1; str++; break; case GRN_LOADER_UNICODE1 : switch (c) { case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : case '9' : loader->unichar += (c - '0') * 0x100; break; case 'a' : case 'b' : case 'c' : case 'd' : case 'e' : case 'f' : loader->unichar += (c - 'a' + 10) * 0x100; break; case 'A' : case 'B' : case 'C' : case 'D' : case 'E' : case 'F' : loader->unichar += (c - 'A' + 10) * 0x100; break; default : ;// todo : error } loader->stat = GRN_LOADER_UNICODE2; str++; break; case GRN_LOADER_UNICODE2 : switch (c) { case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : case '9' : loader->unichar += (c - '0') * 0x10; break; case 'a' : case 'b' : case 'c' : case 'd' : case 'e' : case 'f' : loader->unichar += (c - 'a' + 10) * 0x10; break; case 'A' : case 'B' : case 'C' : case 'D' : case 'E' : case 'F' : loader->unichar += (c - 'A' + 10) * 0x10; break; default : ;// todo : error } loader->stat = GRN_LOADER_UNICODE3; str++; break; case GRN_LOADER_UNICODE3 : switch (c) { case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : case '9' : loader->unichar += (c - '0'); break; case 'a' : case 'b' : case 'c' : case 'd' : case 'e' : case 'f' : loader->unichar += (c - 'a' + 10); break; case 'A' : case 'B' : case 'C' : case 'D' : case 'E' : case 'F' : loader->unichar += (c - 'A' + 10); break; default : ;// todo : error } { uint32_t u = loader->unichar; if (u >= 0xd800 && u <= 0xdbff) { /* High-surrogate code points */ loader->unichar_hi = u; loader->stat = GRN_LOADER_STRING; str++; break; } if (u >= 0xdc00 && u <= 0xdfff) { /* Low-surrogate code points */ u = 0x10000 + (loader->unichar_hi - 0xd800) * 0x400 + u - 0xdc00; } if (u < 0x80) { GRN_TEXT_PUTC(ctx, loader->last, u); } else { if (u < 0x800) { GRN_TEXT_PUTC(ctx, loader->last, (u >> 6) | 0xc0); } else { if (u < 0x10000) { GRN_TEXT_PUTC(ctx, loader->last, (u >> 12) | 0xe0); } else { GRN_TEXT_PUTC(ctx, loader->last, (u >> 18) | 0xf0); GRN_TEXT_PUTC(ctx, loader->last, ((u >> 12) & 0x3f) | 0x80); } GRN_TEXT_PUTC(ctx, loader->last, ((u >> 6) & 0x3f) | 0x80); } GRN_TEXT_PUTC(ctx, loader->last, (u & 0x3f) | 0x80); }