Kouhei Sutou
null+****@clear*****
Tue Feb 10 00:03:18 JST 2015
Kouhei Sutou 2015-02-10 00:03:18 +0900 (Tue, 10 Feb 2015) New Revision: 8375d68ff5ff8f3babec9fea4d723775887376b5 https://github.com/groonga/groonga/commit/8375d68ff5ff8f3babec9fea4d723775887376b5 Message: mrb: add Table#sort but not perfect :< TODO: * Refine it. Modified files: lib/mrb/mrb_table.c Modified: lib/mrb/mrb_table.c (+97 -0) =================================================================== --- lib/mrb/mrb_table.c 2015-02-10 00:02:58 +0900 (049065e) +++ lib/mrb/mrb_table.c 2015-02-10 00:03:18 +0900 (2b86fdb) @@ -23,6 +23,8 @@ #include <mruby/class.h> #include <mruby/data.h> #include <mruby/hash.h> +#include <mruby/array.h> +#include <mruby/string.h> #include "mrb_ctx.h" #include "mrb_table.h" @@ -103,6 +105,99 @@ mrb_grn_table_select(mrb_state *mrb, mrb_value self) return grn_mrb_value_from_grn_obj(mrb, result); } +/* TODO: Fix memory leak on error */ +static mrb_value +mrb_grn_table_sort(mrb_state *mrb, mrb_value self) +{ + grn_ctx *ctx = (grn_ctx *)mrb->ud; + grn_obj *table; + grn_obj *result = NULL; + grn_table_sort_key *keys; + int i, n_keys; + int offset = 0; + int limit = -1; + mrb_value mrb_keys; + mrb_value mrb_options = mrb_nil_value(); + + table = DATA_PTR(self); + mrb_get_args(mrb, "o|H", &mrb_keys, &mrb_options); + + mrb_keys = mrb_convert_type(mrb, mrb_keys, + MRB_TT_ARRAY, "Array", "to_ary"); + + n_keys = RARRAY_LEN(mrb_keys); + keys = GRN_MALLOCN(grn_table_sort_key, n_keys); + for (i = 0; i < n_keys; i++) { + mrb_value mrb_sort_options; + mrb_value mrb_sort_key; + mrb_value mrb_sort_order; + + mrb_sort_options = RARRAY_PTR(mrb_keys)[i]; + mrb_sort_key = mrb_hash_get(mrb, mrb_sort_options, + mrb_symbol_value(mrb_intern_lit(mrb, "key"))); + switch (mrb_type(mrb_sort_key)) { + case MRB_TT_STRING : + keys[i].key = grn_obj_column(ctx, table, + RSTRING_PTR(mrb_sort_key), + RSTRING_LEN(mrb_sort_key)); + break; + case MRB_TT_SYMBOL : + { + const char *name; + mrb_int name_length; + name = mrb_sym2name_len(mrb, mrb_symbol(mrb_sort_key), &name_length); + keys[i].key = grn_obj_column(ctx, table, name, name_length); + } + break; + default : + /* TODO: free */ + mrb_raisef(mrb, E_ARGUMENT_ERROR, + "sort key must be string or symbol: %S", + mrb_sort_key); + break; + } + + keys[i].flags = 0; + mrb_sort_order = + mrb_hash_get(mrb, mrb_sort_options, + mrb_symbol_value(mrb_intern_lit(mrb, "order"))); + if (mrb_nil_p(mrb_sort_order) || + (mrb_symbol(mrb_sort_order) == mrb_intern_lit(mrb, "ascending"))) { + keys[i].flags |= GRN_TABLE_SORT_ASC; + } else { + keys[i].flags |= GRN_TABLE_SORT_DESC; + } + } + + if (!mrb_nil_p(mrb_options)) { + mrb_value mrb_offset; + mrb_value mrb_limit; + + mrb_offset = mrb_hash_get(mrb, mrb_options, + mrb_symbol_value(mrb_intern_lit(mrb, "offset"))); + if (!mrb_nil_p(mrb_offset)) { + offset = mrb_fixnum(mrb_offset); + } + + mrb_limit = mrb_hash_get(mrb, mrb_options, + mrb_symbol_value(mrb_intern_lit(mrb, "limit"))); + if (!mrb_nil_p(mrb_limit)) { + limit = mrb_fixnum(mrb_limit); + } + } + + result = grn_table_create(ctx, NULL, 0, NULL, GRN_TABLE_NO_KEY, + NULL, table); + grn_table_sort(ctx, table, offset, limit, result, keys, n_keys); + for (i = 0; i < n_keys; i++) { + grn_obj_unlink(ctx, keys[i].key); + } + GRN_FREE(keys); + grn_mrb_ctx_check(mrb); + + return grn_mrb_value_from_grn_obj(mrb, result); +} + void grn_mrb_table_init(grn_ctx *ctx) { @@ -125,5 +220,7 @@ grn_mrb_table_init(grn_ctx *ctx) mrb_define_method(mrb, klass, "select", mrb_grn_table_select, MRB_ARGS_ARG(1, 1)); + mrb_define_method(mrb, klass, "sort", + mrb_grn_table_sort, MRB_ARGS_ARG(1, 1)); } #endif -------------- next part -------------- HTML����������������������������... Download