void test_uint64_to_time(void) { long long int sec, usec; grn_obj_reinit(&context, &dest, GRN_DB_TIME, 0); cast_uint64(1259009530); GRN_TIME_UNPACK(GRN_TIME_VALUE(&dest), sec, usec); cut_assert_equal_int(1259009530, sec); cut_assert_equal_int(0, usec); }
void test_text_to_time(void) { long long int sec, usec; grn_obj_reinit(&context, &dest, GRN_DB_TIME, 0); cast_text("2009/11/24 05:52:10.02929"); GRN_TIME_UNPACK(GRN_TIME_VALUE(&dest), sec, usec); cut_assert_equal_int(1259009530, sec); cut_assert_equal_int(29290, usec); }
static VALUE rb_grn_bulk_to_ruby_object_by_range_id (grn_ctx *context, grn_obj *bulk, grn_id range_id, VALUE related_object, VALUE *rb_value) { grn_bool success = GRN_TRUE; switch (range_id) { case GRN_DB_VOID: *rb_value = rb_str_new(GRN_TEXT_VALUE(bulk), GRN_TEXT_LEN(bulk)); break; case GRN_DB_BOOL: *rb_value = GRN_BOOL_VALUE(bulk) ? Qtrue : Qfalse; break; case GRN_DB_INT32: *rb_value = INT2NUM(GRN_INT32_VALUE(bulk)); break; case GRN_DB_UINT32: *rb_value = UINT2NUM(GRN_UINT32_VALUE(bulk)); break; case GRN_DB_INT64: *rb_value = LL2NUM(GRN_INT64_VALUE(bulk)); break; case GRN_DB_UINT64: *rb_value = ULL2NUM(GRN_UINT64_VALUE(bulk)); break; case GRN_DB_FLOAT: *rb_value = rb_float_new(GRN_FLOAT_VALUE(bulk)); break; case GRN_DB_TIME: { int64_t time_value, sec, usec; time_value = GRN_TIME_VALUE(bulk); GRN_TIME_UNPACK(time_value, sec, usec); *rb_value = rb_funcall(rb_cTime, rb_intern("at"), 2, LL2NUM(sec), LL2NUM(usec)); } break; case GRN_DB_SHORT_TEXT: case GRN_DB_TEXT: case GRN_DB_LONG_TEXT: *rb_value = rb_grn_context_rb_string_new(context, GRN_TEXT_VALUE(bulk), GRN_TEXT_LEN(bulk)); break; default: success = GRN_FALSE; break; } return success; }
static grn_obj * func_time_classify_raw(grn_ctx *ctx, int n_args, grn_obj **args, grn_user_data *user_data, const char *function_name, grn_time_classify_unit unit) { grn_obj *time; uint32_t interval_raw = 1; grn_obj *classed_time; grn_bool accept_interval = GRN_TRUE; switch (unit) { case GRN_TIME_CLASSIFY_UNIT_SECOND : case GRN_TIME_CLASSIFY_UNIT_MINUTE : case GRN_TIME_CLASSIFY_UNIT_HOUR : accept_interval = GRN_TRUE; break; case GRN_TIME_CLASSIFY_UNIT_DAY : case GRN_TIME_CLASSIFY_UNIT_WEEK : accept_interval = GRN_FALSE; break; case GRN_TIME_CLASSIFY_UNIT_MONTH : case GRN_TIME_CLASSIFY_UNIT_YEAR : accept_interval = GRN_TRUE; break; } if (accept_interval) { if (!(n_args == 1 || n_args == 2)) { GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT, "%s(): " "wrong number of arguments (%d for 1..2)", function_name, n_args); return NULL; } } else { if (n_args != 1) { GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT, "%s(): " "wrong number of arguments (%d for 1)", function_name, n_args); return NULL; } } time = args[0]; if (!(time->header.type == GRN_BULK && time->header.domain == GRN_DB_TIME)) { grn_obj inspected; GRN_TEXT_INIT(&inspected, 0); grn_inspect(ctx, &inspected, time); GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT, "%s(): " "the first argument must be a time: " "<%.*s>", function_name, (int)GRN_TEXT_LEN(&inspected), GRN_TEXT_VALUE(&inspected)); GRN_OBJ_FIN(ctx, &inspected); return NULL; } if (n_args == 2) { grn_obj *interval; grn_obj casted_interval; interval = args[1]; if (!(interval->header.type == GRN_BULK && grn_type_id_is_number_family(ctx, interval->header.domain))) { grn_obj inspected; GRN_TEXT_INIT(&inspected, 0); grn_inspect(ctx, &inspected, interval); GRN_PLUGIN_ERROR(ctx, GRN_INVALID_ARGUMENT, "%s(): " "the second argument must be a number: " "<%.*s>", function_name, (int)GRN_TEXT_LEN(&inspected), GRN_TEXT_VALUE(&inspected)); GRN_OBJ_FIN(ctx, &inspected); return NULL; } GRN_VALUE_FIX_SIZE_INIT(&casted_interval, 0, GRN_DB_UINT32); grn_obj_cast(ctx, interval, &casted_interval, GRN_FALSE); interval_raw = GRN_UINT32_VALUE(&casted_interval); GRN_OBJ_FIN(ctx, &casted_interval); } { int64_t time_raw; struct tm tm; int64_t classed_time_raw; time_raw = GRN_TIME_VALUE(time); if (!grn_time_to_tm(ctx, time_raw, &tm)) { return NULL; } switch (unit) { case GRN_TIME_CLASSIFY_UNIT_SECOND : tm.tm_sec = (tm.tm_sec / interval_raw) * interval_raw; break; case GRN_TIME_CLASSIFY_UNIT_MINUTE : tm.tm_min = (tm.tm_min / interval_raw) * interval_raw; tm.tm_sec = 0; break; case GRN_TIME_CLASSIFY_UNIT_HOUR : tm.tm_hour = (tm.tm_hour / interval_raw) * interval_raw; tm.tm_min = 0; tm.tm_sec = 0; break; case GRN_TIME_CLASSIFY_UNIT_DAY : tm.tm_hour = 0; tm.tm_min = 0; tm.tm_sec = 0; break; case GRN_TIME_CLASSIFY_UNIT_WEEK : if ((tm.tm_mday - tm.tm_wday) >= 0) { tm.tm_mday -= tm.tm_wday; } else { int n_underflowed_mday = -(tm.tm_mday - tm.tm_wday); int mday; int max_mday = 31; if (tm.tm_mon == 0) { tm.tm_year--; tm.tm_mon = 11; } else { tm.tm_mon--; } for (mday = max_mday; mday > n_underflowed_mday; mday--) { int64_t unused; tm.tm_mday = mday; if (grn_time_from_tm(ctx, &unused, &tm)) { break; } } tm.tm_mday -= n_underflowed_mday; } tm.tm_hour = 0; tm.tm_min = 0; tm.tm_sec = 0; break; case GRN_TIME_CLASSIFY_UNIT_MONTH : tm.tm_mon = (tm.tm_mon / interval_raw) * interval_raw; tm.tm_mday = 1; tm.tm_hour = 0; tm.tm_min = 0; tm.tm_sec = 0; break; case GRN_TIME_CLASSIFY_UNIT_YEAR : tm.tm_year = (((1900 + tm.tm_year) / interval_raw) * interval_raw) - 1900; tm.tm_mon = 0; tm.tm_mday = 1; tm.tm_hour = 0; tm.tm_min = 0; tm.tm_sec = 0; break; } if (!grn_time_from_tm(ctx, &classed_time_raw, &tm)) { return NULL; } classed_time = grn_plugin_proc_alloc(ctx, user_data, time->header.domain, 0); if (!classed_time) { return NULL; } GRN_TIME_SET(ctx, classed_time, classed_time_raw); return classed_time; } }
mrb_value grn_mrb_value_from_bulk(mrb_state *mrb, grn_obj *bulk) { mrb_value mrb_value_; grn_ctx *ctx = (grn_ctx *)mrb->ud; switch (bulk->header.domain) { case GRN_DB_INT32 : { int32_t value; value = GRN_INT32_VALUE(bulk); mrb_value_ = mrb_fixnum_value(value); } break; case GRN_DB_UINT32 : { int64_t value; value = GRN_UINT32_VALUE(bulk); if (!FIXABLE(value)) { mrb_raisef(mrb, E_RANGE_ERROR, "can't handle large number: <%S>: max: <%S>", mrb_fixnum_value(value), /* TODO: This will cause overflow */ mrb_fixnum_value(MRB_INT_MAX)); } mrb_value_ = mrb_fixnum_value(value); } break; case GRN_DB_TIME : { int64_t value; int32_t sec; int32_t usec; value = GRN_TIME_VALUE(bulk); GRN_TIME_UNPACK(value, sec, usec); mrb_value_ = mrb_funcall(mrb, mrb_obj_value(ctx->impl->mrb.builtin.time_class), "at", 2, mrb_fixnum_value(sec), mrb_fixnum_value(usec)); } break; case GRN_DB_SHORT_TEXT : case GRN_DB_TEXT : case GRN_DB_LONG_TEXT : mrb_value_ = mrb_str_new(mrb, GRN_TEXT_VALUE(bulk), GRN_TEXT_LEN(bulk)); break; default : { grn_obj *domain; grn_bool is_record = GRN_FALSE; domain = grn_ctx_at(ctx, bulk->header.domain); if (domain) { switch (domain->header.type) { case GRN_TABLE_HASH_KEY : case GRN_TABLE_PAT_KEY : case GRN_TABLE_DAT_KEY : case GRN_TABLE_NO_KEY : is_record = GRN_TRUE; break; default : break; } } if (is_record) { mrb_value_ = mrb_fixnum_value(GRN_RECORD_VALUE(bulk)); grn_obj_unlink(ctx, domain); } else { #define MESSAGE_SIZE 4096 char message[MESSAGE_SIZE]; char domain_name[GRN_TABLE_MAX_KEY_SIZE]; int domain_name_size; if (domain) { domain_name_size = grn_obj_name(ctx, domain, domain_name, GRN_TABLE_MAX_KEY_SIZE); grn_obj_unlink(ctx, domain); } else { grn_strcpy(domain_name, GRN_TABLE_MAX_KEY_SIZE, "unknown"); domain_name_size = strlen(domain_name); } grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "unsupported bulk value type: <%d>(%.*s)", bulk->header.domain, domain_name_size, domain_name); mrb_raise(mrb, E_RANGE_ERROR, message); } #undef MESSAGE_SIZE } break; } return mrb_value_; }