const GList * grn_test_view_collect_string(grn_ctx *context, grn_obj *view, const gchar *text_column_name) { GList *records = NULL; grn_table_cursor *cursor; grn_obj id, value; grn_obj *text_column; cursor = grn_table_cursor_open(context, view, NULL, 0, NULL, 0, 0, -1, GRN_CURSOR_ASCENDING); cut_assert_not_null(cursor); GRN_TEXT_INIT(&id, 0); GRN_TEXT_INIT(&value, 0); text_column = grn_obj_column(context, view, text_column_name, strlen(text_column_name)); while (grn_table_cursor_next_o(context, cursor, &id) == GRN_SUCCESS) { GRN_BULK_REWIND(&value); grn_obj_get_value_o(context, text_column, &id, &value); records = g_list_append(records, g_strndup(GRN_TEXT_VALUE(&value), GRN_TEXT_LEN(&value))); } grn_obj_unlink(context, &id); grn_obj_unlink(context, &value); grn_obj_unlink(context, text_column); gcut_take_list(records, g_free); grn_test_assert(grn_table_cursor_close(context, cursor)); grn_test_assert_context(context); return records; }
/* * call-seq: * view.each {|record| ...} * * ビューに登録されているテーブルのレコードを順番にブロック * に渡す。 */ static VALUE rb_grn_view_each (VALUE self) { #ifdef WIN32 rb_raise(rb_eNotImpError, "grn_table_cursor_next_o() isn't available on Windows."); #else RbGrnTable *rb_grn_view; RbGrnObject *rb_grn_object; grn_ctx *context = NULL; grn_obj *view; grn_table_cursor *cursor; VALUE rb_cursor; grn_obj id; grn_rc rc = GRN_SUCCESS; rb_grn_view = SELF(self); rb_grn_table_deconstruct(rb_grn_view, &view, &context, NULL, NULL, NULL, NULL, NULL, NULL); cursor = grn_table_cursor_open(context, view, NULL, 0, NULL, 0, 0, -1, GRN_CURSOR_ASCENDING); rb_cursor = GRNTABLECURSOR2RVAL(Qnil, context, cursor); rb_grn_object = RB_GRN_OBJECT(rb_grn_view); GRN_TEXT_INIT(&id, 0); while (rb_grn_object->object && (rc = grn_table_cursor_next_o(context, cursor, &id)) == GRN_SUCCESS) { rb_yield(rb_grn_view_record_new(self, &id)); } GRN_OBJ_FIN(context, &id); rb_grn_object_close(rb_cursor); if (!(rc == GRN_SUCCESS || rc == GRN_END_OF_DATA)) { rb_grn_context_check(context, self); } #endif return Qnil; }
/* FIXME: DON'T WORK!!! */ static VALUE rb_grn_view_sort (int argc, VALUE *argv, VALUE self) { VALUE rb_result = Qnil; #ifdef WIN32 rb_raise(rb_eNotImpError, "grn_view_add() isn't available on Windows."); #else grn_ctx *context = NULL; grn_obj *view; grn_obj *result; grn_table_sort_key *keys; int i, n_keys; int n_records, offset = 0, limit = -1; VALUE rb_keys, options; VALUE rb_offset, rb_limit; VALUE *rb_sort_keys; grn_table_cursor *cursor; VALUE exception; grn_obj id; rb_grn_table_deconstruct(SELF(self), &view, &context, NULL, NULL, NULL, NULL, NULL, NULL); rb_scan_args(argc, argv, "11", &rb_keys, &options); if (!RVAL2CBOOL(rb_obj_is_kind_of(rb_keys, rb_cArray))) rb_raise(rb_eArgError, "keys should be an array of key: <%s>", rb_grn_inspect(rb_keys)); n_keys = RARRAY_LEN(rb_keys); rb_sort_keys = RARRAY_PTR(rb_keys); keys = ALLOCA_N(grn_table_sort_key, n_keys); for (i = 0; i < n_keys; i++) { VALUE rb_sort_options, rb_key, rb_resolved_key, rb_order; if (RVAL2CBOOL(rb_obj_is_kind_of(rb_sort_keys[i], rb_cHash))) { rb_sort_options = rb_sort_keys[i]; } else if (RVAL2CBOOL(rb_obj_is_kind_of(rb_sort_keys[i], rb_cArray))) { rb_sort_options = rb_hash_new(); rb_hash_aset(rb_sort_options, RB_GRN_INTERN("key"), rb_ary_entry(rb_sort_keys[i], 0)); rb_hash_aset(rb_sort_options, RB_GRN_INTERN("order"), rb_ary_entry(rb_sort_keys[i], 1)); } else { rb_sort_options = rb_hash_new(); rb_hash_aset(rb_sort_options, RB_GRN_INTERN("key"), rb_sort_keys[i]); } rb_grn_scan_options(rb_sort_options, "key", &rb_key, "order", &rb_order, NULL); if (RVAL2CBOOL(rb_obj_is_kind_of(rb_key, rb_cString))) { rb_resolved_key = rb_grn_table_get_column(self, rb_key); } else { rb_resolved_key = rb_key; } keys[i].key = RVAL2GRNOBJECT(rb_resolved_key, &context); if (!keys[i].key) { rb_raise(rb_eGrnNoSuchColumn, "no such column: <%s>: <%s>", rb_grn_inspect(rb_key), rb_grn_inspect(self)); } if (NIL_P(rb_order)) { keys[i].flags = 0; } else if (rb_grn_equal_option(rb_order, "desc") || rb_grn_equal_option(rb_order, "descending")) { keys[i].flags = GRN_TABLE_SORT_DESC; } else if (rb_grn_equal_option(rb_order, "asc") || rb_grn_equal_option(rb_order, "ascending")) { keys[i].flags = GRN_TABLE_SORT_ASC; } else { rb_raise(rb_eArgError, "order should be one of " "[nil, :desc, :descending, :asc, :ascending]: %s", rb_grn_inspect(rb_order)); } } rb_grn_scan_options(options, "offset", &rb_offset, "limit", &rb_limit, NULL); if (!NIL_P(rb_offset)) offset = NUM2INT(rb_offset); if (!NIL_P(rb_limit)) limit = NUM2INT(rb_limit); result = grn_table_create(context, NULL, 0, NULL, GRN_TABLE_VIEW, NULL, NULL); grn_view_add(context, result, grn_table_create(context, NULL, 0, NULL, GRN_TABLE_NO_KEY, NULL, grn_ctx_get(context, "People", strlen("People")))); grn_view_add(context, result, grn_table_create(context, NULL, 0, NULL, GRN_TABLE_NO_KEY, NULL, grn_ctx_get(context, "People", strlen("People")))); n_records = grn_table_sort(context, view, offset, limit, result, keys, n_keys); exception = rb_grn_context_to_exception(context, self); if (!NIL_P(exception)) { grn_obj_unlink(context, result); rb_exc_raise(exception); } rb_result = rb_ary_new(); cursor = grn_table_cursor_open(context, result, NULL, 0, NULL, 0, 0, -1, GRN_CURSOR_ASCENDING); GRN_TEXT_INIT(&id, 0); while (grn_table_cursor_next_o(context, cursor, &id) == GRN_SUCCESS) { rb_ary_push(rb_result, rb_grn_view_record_new(self, &id)); } GRN_OBJ_FIN(context, &id); grn_table_cursor_close(context, cursor); grn_obj_unlink(context, result); #endif return rb_result; }
void grn_output_obj(grn_ctx *ctx, grn_obj *outbuf, grn_content_type output_type, grn_obj *obj, grn_obj_format *format) { grn_obj buf; GRN_TEXT_INIT(&buf, 0); switch (obj->header.type) { case GRN_BULK : switch (obj->header.domain) { case GRN_DB_VOID : grn_output_void(ctx, outbuf, output_type, GRN_BULK_HEAD(obj), GRN_BULK_VSIZE(obj)); break; case GRN_DB_SHORT_TEXT : case GRN_DB_TEXT : case GRN_DB_LONG_TEXT : grn_output_str(ctx, outbuf, output_type, GRN_BULK_HEAD(obj), GRN_BULK_VSIZE(obj)); break; case GRN_DB_BOOL : grn_output_bool(ctx, outbuf, output_type, GRN_BULK_VSIZE(obj) ? GRN_UINT8_VALUE(obj) : 0); break; case GRN_DB_INT8 : grn_output_int32(ctx, outbuf, output_type, GRN_BULK_VSIZE(obj) ? GRN_INT8_VALUE(obj) : 0); break; case GRN_DB_UINT8 : grn_output_int32(ctx, outbuf, output_type, GRN_BULK_VSIZE(obj) ? GRN_UINT8_VALUE(obj) : 0); break; case GRN_DB_INT16 : grn_output_int32(ctx, outbuf, output_type, GRN_BULK_VSIZE(obj) ? GRN_INT16_VALUE(obj) : 0); break; case GRN_DB_UINT16 : grn_output_int32(ctx, outbuf, output_type, GRN_BULK_VSIZE(obj) ? GRN_UINT16_VALUE(obj) : 0); break; case GRN_DB_INT32 : grn_output_int32(ctx, outbuf, output_type, GRN_BULK_VSIZE(obj) ? GRN_INT32_VALUE(obj) : 0); break; case GRN_DB_UINT32 : grn_output_int64(ctx, outbuf, output_type, GRN_BULK_VSIZE(obj) ? GRN_UINT32_VALUE(obj) : 0); break; case GRN_DB_INT64 : grn_output_int64(ctx, outbuf, output_type, GRN_BULK_VSIZE(obj) ? GRN_INT64_VALUE(obj) : 0); break; case GRN_DB_UINT64 : grn_output_uint64(ctx, outbuf, output_type, GRN_BULK_VSIZE(obj) ? GRN_UINT64_VALUE(obj) : 0); break; case GRN_DB_FLOAT : grn_output_float(ctx, outbuf, output_type, GRN_BULK_VSIZE(obj) ? GRN_FLOAT_VALUE(obj) : 0); break; case GRN_DB_TIME : grn_output_time(ctx, outbuf, output_type, GRN_BULK_VSIZE(obj) ? GRN_INT64_VALUE(obj) : 0); break; case GRN_DB_TOKYO_GEO_POINT : case GRN_DB_WGS84_GEO_POINT : grn_output_geo_point(ctx, outbuf, output_type, GRN_BULK_VSIZE(obj) ? (grn_geo_point *)GRN_BULK_HEAD(obj) : NULL); break; default : if (format) { int j; int ncolumns = GRN_BULK_VSIZE(&format->columns)/sizeof(grn_obj *); grn_obj **columns = (grn_obj **)GRN_BULK_HEAD(&format->columns); if (format->flags & GRN_OBJ_FORMAT_WITH_COLUMN_NAMES) { grn_output_array_open(ctx, outbuf, output_type, "COLUMNS", ncolumns); for (j = 0; j < ncolumns; j++) { grn_id range_id; grn_output_array_open(ctx, outbuf, output_type, "COLUMN", 2); GRN_BULK_REWIND(&buf); grn_column_name_(ctx, columns[j], &buf); grn_output_obj(ctx, outbuf, output_type, &buf, NULL); /* column range */ range_id = grn_obj_get_range(ctx, columns[j]); if (range_id == GRN_ID_NIL) { GRN_TEXT_PUTS(ctx, outbuf, "null"); } else { int name_len; grn_obj *range_obj; char name_buf[GRN_TABLE_MAX_KEY_SIZE]; range_obj = grn_ctx_at(ctx, range_id); name_len = grn_obj_name(ctx, range_obj, name_buf, GRN_TABLE_MAX_KEY_SIZE); GRN_BULK_REWIND(&buf); GRN_TEXT_PUT(ctx, &buf, name_buf, name_len); grn_output_obj(ctx, outbuf, output_type, &buf, NULL); } grn_output_array_close(ctx, outbuf, output_type); } grn_output_array_close(ctx, outbuf, output_type); } grn_output_array_open(ctx, outbuf, output_type, "HIT", ncolumns); for (j = 0; j < ncolumns; j++) { grn_text_atoj_o(ctx, outbuf, output_type, columns[j], obj); } grn_output_array_close(ctx, outbuf, output_type); } else { grn_obj *table = grn_ctx_at(ctx, obj->header.domain); grn_id id = *((grn_id *)GRN_BULK_HEAD(obj)); if (table && table->header.type != GRN_TABLE_NO_KEY) { grn_obj *accessor = grn_obj_column(ctx, table, "_key", 4); if (accessor) { grn_obj_get_value(ctx, accessor, id, &buf); grn_obj_unlink(ctx, accessor); } grn_output_obj(ctx, outbuf, output_type, &buf, format); } else { grn_output_int64(ctx, outbuf, output_type, id); } } break; } break; case GRN_UVECTOR : if (format) { int i, j; grn_id *v = (grn_id *)GRN_BULK_HEAD(obj), *ve = (grn_id *)GRN_BULK_CURR(obj); int ncolumns = GRN_BULK_VSIZE(&format->columns) / sizeof(grn_obj *); grn_obj **columns = (grn_obj **)GRN_BULK_HEAD(&format->columns); grn_output_array_open(ctx, outbuf, output_type, "RESULTSET", -1); grn_output_array_open(ctx, outbuf, output_type, "NHITS", 1); grn_text_itoa(ctx, outbuf, ve - v); grn_output_array_close(ctx, outbuf, output_type); if (v < ve) { if (format->flags & GRN_OBJ_FORMAT_WITH_COLUMN_NAMES) { grn_output_array_open(ctx, outbuf, output_type, "COLUMNS", -1); for (j = 0; j < ncolumns; j++) { grn_id range_id; grn_output_array_open(ctx, outbuf, output_type, "COLUMN", -1); GRN_BULK_REWIND(&buf); grn_column_name_(ctx, columns[j], &buf); grn_output_obj(ctx, outbuf, output_type, &buf, NULL); /* column range */ range_id = grn_obj_get_range(ctx, columns[j]); if (range_id == GRN_ID_NIL) { GRN_TEXT_PUTS(ctx, outbuf, "null"); } else { int name_len; grn_obj *range_obj; char name_buf[GRN_TABLE_MAX_KEY_SIZE]; range_obj = grn_ctx_at(ctx, range_id); name_len = grn_obj_name(ctx, range_obj, name_buf, GRN_TABLE_MAX_KEY_SIZE); GRN_BULK_REWIND(&buf); GRN_TEXT_PUT(ctx, &buf, name_buf, name_len); grn_output_obj(ctx, outbuf, output_type, &buf, NULL); } grn_output_array_close(ctx, outbuf, output_type); } grn_output_array_close(ctx, outbuf, output_type); } for (i = 0;; i++) { grn_output_array_open(ctx, outbuf, output_type, "HITS", -1); for (j = 0; j < ncolumns; j++) { GRN_BULK_REWIND(&buf); grn_obj_get_value(ctx, columns[j], *v, &buf); grn_output_obj(ctx, outbuf, output_type, &buf, NULL); } grn_output_array_close(ctx, outbuf, output_type); v++; if (v < ve) { } else { break; } } } grn_output_array_close(ctx, outbuf, output_type); } else { grn_obj *range = grn_ctx_at(ctx, obj->header.domain); if (range && range->header.type == GRN_TYPE) { int value_size = ((struct _grn_type *)range)->obj.range; char *v = (char *)GRN_BULK_HEAD(obj), *ve = (char *)GRN_BULK_CURR(obj); grn_output_array_open(ctx, outbuf, output_type, "VECTOR", -1); if (v < ve) { for (;;) { grn_obj value; GRN_OBJ_INIT(&value, GRN_BULK, 0, obj->header.domain); grn_bulk_write_from(ctx, &value, v, 0, value_size); grn_output_obj(ctx, outbuf, output_type, &value, NULL); v += value_size; if (v < ve) { } else { break; } } } grn_output_array_close(ctx, outbuf, output_type); } else { grn_id *v = (grn_id *)GRN_BULK_HEAD(obj), *ve = (grn_id *)GRN_BULK_CURR(obj); grn_output_array_open(ctx, outbuf, output_type, "VECTOR", ve - v); if (v < ve) { grn_obj key; GRN_OBJ_INIT(&key, GRN_BULK, 0, range->header.domain); for (;;) { if (range->header.type != GRN_TABLE_NO_KEY) { grn_table_get_key2(ctx, range, *v, &key); grn_output_obj(ctx, outbuf, output_type, &key, NULL); GRN_BULK_REWIND(&key); } else { grn_obj id; GRN_UINT32_INIT(&id, 0); GRN_UINT32_SET(ctx, &id, *v); grn_output_obj(ctx, outbuf, output_type, &id, NULL); GRN_OBJ_FIN(ctx, &id); } v++; if (v < ve) { } else { break; } } GRN_OBJ_FIN(ctx, &key); } grn_output_array_close(ctx, outbuf, output_type); } } break; case GRN_VECTOR : if (obj->header.domain == GRN_DB_VOID) { ERR(GRN_INVALID_ARGUMENT, "invalid obj->header.domain"); } if (format) { ERR(GRN_FUNCTION_NOT_IMPLEMENTED, "cannot print GRN_VECTOR using grn_obj_format"); } else { unsigned int i, n; grn_obj value; GRN_VOID_INIT(&value); n = grn_vector_size(ctx, obj); grn_output_array_open(ctx, outbuf, output_type, "VECTOR", -1); for (i = 0; i < n; i++) { const char *_value; unsigned int weight, length; grn_id domain; length = grn_vector_get_element(ctx, obj, i, &_value, &weight, &domain); if (domain != GRN_DB_VOID) { grn_obj_reinit(ctx, &value, domain, 0); } else { grn_obj_reinit(ctx, &value, obj->header.domain, 0); } grn_bulk_write(ctx, &value, _value, length); grn_output_obj(ctx, outbuf, output_type, &value, NULL); } grn_output_array_close(ctx, outbuf, output_type); GRN_OBJ_FIN(ctx, &value); } break; case GRN_PVECTOR : if (format) { ERR(GRN_FUNCTION_NOT_IMPLEMENTED, "cannot print GRN_PVECTOR using grn_obj_format"); } else { unsigned int i, n; grn_output_array_open(ctx, outbuf, output_type, "VECTOR", -1); n = GRN_BULK_VSIZE(obj) / sizeof(grn_obj *); for (i = 0; i < n; i++) { grn_obj *value; value = GRN_PTR_VALUE_AT(obj, i); grn_output_obj(ctx, outbuf, output_type, value, NULL); } grn_output_array_close(ctx, outbuf, output_type); } break; case GRN_TABLE_HASH_KEY : case GRN_TABLE_PAT_KEY : case GRN_TABLE_NO_KEY : case GRN_TABLE_VIEW : if (format) { int i, j; int ncolumns = GRN_BULK_VSIZE(&format->columns)/sizeof(grn_obj *); grn_obj **columns = (grn_obj **)GRN_BULK_HEAD(&format->columns); grn_table_cursor *tc = grn_table_cursor_open(ctx, obj, NULL, 0, NULL, 0, format->offset, format->limit, GRN_CURSOR_ASCENDING); int resultset_size = -1; if (!tc) { ERRCLR(ctx); } #ifdef HAVE_MESSAGE_PACK resultset_size = 1; /* [NHITS, (COLUMNS), (HITS)] */ if (format->flags & GRN_OBJ_FORMAT_WITH_COLUMN_NAMES) { resultset_size++; } resultset_size += format->limit; #endif grn_output_array_open(ctx, outbuf, output_type, "RESULTSET", resultset_size); grn_output_array_open(ctx, outbuf, output_type, "NHITS", 1); if (output_type == GRN_CONTENT_XML) { grn_text_itoa(ctx, outbuf, format->nhits); } else { grn_output_int32(ctx, outbuf, output_type, format->nhits); } grn_output_array_close(ctx, outbuf, output_type); if (format->flags & GRN_OBJ_FORMAT_WITH_COLUMN_NAMES) { grn_output_array_open(ctx, outbuf, output_type, "COLUMNS", ncolumns); for (j = 0; j < ncolumns; j++) { grn_id range_id; grn_output_array_open(ctx, outbuf, output_type, "COLUMN", 2); GRN_BULK_REWIND(&buf); grn_column_name_(ctx, columns[j], &buf); grn_output_obj(ctx, outbuf, output_type, &buf, NULL); /* column range */ range_id = grn_obj_get_range(ctx, columns[j]); if (range_id == GRN_ID_NIL) { GRN_TEXT_PUTS(ctx, outbuf, "null"); } else { int name_len; grn_obj *range_obj; char name_buf[GRN_TABLE_MAX_KEY_SIZE]; range_obj = grn_ctx_at(ctx, range_id); name_len = grn_obj_name(ctx, range_obj, name_buf, GRN_TABLE_MAX_KEY_SIZE); GRN_BULK_REWIND(&buf); GRN_TEXT_PUT(ctx, &buf, name_buf, name_len); grn_output_obj(ctx, outbuf, output_type, &buf, NULL); } grn_output_array_close(ctx, outbuf, output_type); } grn_output_array_close(ctx, outbuf, output_type); } if (tc) { grn_obj id; GRN_TEXT_INIT(&id, 0); for (i = 0; !grn_table_cursor_next_o(ctx, tc, &id); i++) { grn_output_array_open(ctx, outbuf, output_type, "HIT", ncolumns); for (j = 0; j < ncolumns; j++) { grn_text_atoj_o(ctx, outbuf, output_type, columns[j], &id); } grn_output_array_close(ctx, outbuf, output_type); } GRN_OBJ_FIN(ctx, &id); grn_table_cursor_close(ctx, tc); } grn_output_array_close(ctx, outbuf, output_type); } else { int i; grn_obj *column = grn_obj_column(ctx, obj, "_key", 4); grn_table_cursor *tc = grn_table_cursor_open(ctx, obj, NULL, 0, NULL, 0, 0, -1, GRN_CURSOR_ASCENDING); grn_output_array_open(ctx, outbuf, output_type, "HIT", -1); if (tc) { grn_obj id; GRN_TEXT_INIT(&id, 0); for (i = 0; !grn_table_cursor_next_o(ctx, tc, &id); i++) { /* todo: grn_text_atoj_o(ctx, outbuf, output_type, column, &id); */ GRN_BULK_REWIND(&buf); grn_obj_get_value_o(ctx, column, &id, &buf); grn_text_esc(ctx, outbuf, GRN_BULK_HEAD(&buf), GRN_BULK_VSIZE(&buf)); } GRN_OBJ_FIN(ctx, &id); grn_table_cursor_close(ctx, tc); } grn_output_array_close(ctx, outbuf, output_type); grn_obj_unlink(ctx, column); } break; } GRN_OBJ_FIN(ctx, &buf); }