Kouhei Sutou
null+****@clear*****
Tue Jun 14 15:04:16 JST 2016
Kouhei Sutou 2016-06-14 15:04:16 +0900 (Tue, 14 Jun 2016) New Revision: 995e5a16a1489a2ec3bd3500a7fa7a2d47c26fea https://github.com/ranguba/rroonga/commit/995e5a16a1489a2ec3bd3500a7fa7a2d47c26fea Message: Create Groonga::DataColumn It's for providing methods only to fixed size column and variable size column. (= not index column.) Added files: ext/groonga/rb-grn-data-column.c test/test-data-column.rb Modified files: ext/groonga/rb-grn-column.c ext/groonga/rb-grn-fix-size-column.c ext/groonga/rb-grn-variable-size-column.c ext/groonga/rb-grn.h test/test-column.rb Modified: ext/groonga/rb-grn-column.c (+1 -78) =================================================================== --- ext/groonga/rb-grn-column.c 2016-06-14 14:28:05 +0900 (2160513) +++ ext/groonga/rb-grn-column.c 2016-06-14 15:04:16 +0900 (6252bf4) @@ -812,79 +812,6 @@ rb_grn_column_rename (VALUE self, VALUE rb_name) return self; } -/* - * Applies the window function to records in the table of the - * column. Results are stored into the column. - * - * @overload apply_window_function(options={}) {|record| } - * @param options [::Hash] The name and value pairs. - * @option options [::Array<String>] :sort_keys - * - * @since 6.0.4 - */ -static VALUE -rb_grn_column_apply_window_function (int argc, VALUE *argv, VALUE self) -{ - grn_rc rc; - grn_ctx *context; - grn_obj *column; - grn_obj *table; - VALUE rb_table; - grn_window_definition definition; - grn_obj *window_function_call = NULL; - VALUE rb_options; - VALUE rb_sort_keys; - VALUE rb_builder; - VALUE rb_window_function_call; - - rb_grn_column_deconstruct(SELF(self), &column, &context, - NULL, &table, - NULL, NULL, NULL); - rb_table = GRNOBJECT2RVAL(Qnil, context, table, GRN_FALSE); - - memset(&definition, 0, sizeof(grn_window_definition)); - - rb_scan_args(argc, argv, "01", &rb_options); - rb_grn_scan_options(rb_options, - "sort_keys", &rb_sort_keys, - NULL); - - if (!NIL_P(rb_sort_keys)) { - VALUE rb_table; - - if (!RVAL2CBOOL(rb_obj_is_kind_of(rb_sort_keys, rb_cArray))) - rb_raise(rb_eArgError, ":sort_keys should be an array of key: <%s>", - rb_grn_inspect(rb_sort_keys)); - - definition.n_sort_keys = RARRAY_LEN(rb_sort_keys); - definition.sort_keys = ALLOCA_N(grn_table_sort_key, - definition.n_sort_keys); - rb_table = GRNOBJECT2RVAL(Qnil, context, table, GRN_FALSE); - rb_grn_table_sort_keys_fill(context, - definition.sort_keys, - definition.n_sort_keys, - rb_sort_keys, - rb_table); - } - - rb_builder = rb_grn_record_expression_builder_new(rb_table, Qnil); - rb_window_function_call = - rb_grn_record_expression_builder_build(rb_builder); - rb_grn_object_deconstruct(RB_GRN_OBJECT(DATA_PTR(rb_window_function_call)), - &window_function_call, NULL, - NULL, NULL, NULL, NULL); - - rc = grn_table_apply_window_function(context, - table, - column, - &definition, - window_function_call); - rb_grn_context_check(context, self); - rb_grn_rc_check(rc, self); - - return self; -} - void rb_grn_init_column (VALUE mGrn) { @@ -919,10 +846,6 @@ rb_grn_init_column (VALUE mGrn) rb_define_method(rb_cGrnColumn, "rename", rb_grn_column_rename, 1); - rb_define_method(rb_cGrnColumn, "apply_window_function", - rb_grn_column_apply_window_function, -1); - - rb_grn_init_fix_size_column(mGrn); - rb_grn_init_variable_size_column(mGrn); + rb_grn_init_data_column(mGrn); rb_grn_init_index_column(mGrn); } Added: ext/groonga/rb-grn-data-column.c (+157 -0) 100644 =================================================================== --- /dev/null +++ ext/groonga/rb-grn-data-column.c 2016-06-14 15:04:16 +0900 (609b316) @@ -0,0 +1,157 @@ +/* -*- coding: utf-8; mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* vim: set sts=4 sw=4 ts=8 noet: */ +/* + Copyright (C) 2016 Kouhei Sutou <kou �� clear-code.com> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "rb-grn.h" + +#define SELF(object) ((RbGrnColumn *)DATA_PTR(object)) + +VALUE rb_cGrnDataColumn; + +/* + * Document-class: Groonga::DataColumn < Groonga::Column + * + * The superclass for data columns such as {Groonga::FixSizeColumn} + * and {Groonga::VariableSizeColumn}. + */ + +/* + * Applies the window function to records in the table of the + * column. Results are stored into the column. + * + * @example Set the nth record. + * + * Groonga::Schema.define do |schema| + * schema.create_table("Comments") do |table| + * # The column for storing window function result. + * table.uint32("nth") + * end + * end + * comments = Groonga["Comments"] + * nth = Groonga["Comments.nth"] + * + * 5.times do + * comments.add + * end + * + * options = { + * # Sort by _id in descending order. + * :sort_keys => [["_id", "desc"]], + * } + * nth.apply_window_function(options) do |record| + * # record_number() returns Nth record in the sorted order. + * record.call("record_number") + * end + * + * comments.each do |comment| + * p [comment.id, comment.nth] + * # -> [1, 5] + * # -> [2, 4] + * # -> [3, 3] + * # -> [4, 2] + * # -> [5, 1] + * end + * + * @overload apply_window_function(options={}) {|record| } + * @param options [::Hash] The name and value pairs. + * @option options [::Array<String>] :sort_keys + * + * @yield [record] + * It yields an object that builds expression. The block must + * build an expression that calls a window function. + * @yieldparam [Groonga::RecordExpressionBuilder] record + * The expression builder to create a window function call. + * @yieldreturn [Groonga::ExpressionBuilder] + * It must be an expression that calls a window function. + * + * @since 6.0.4 + */ +static VALUE +rb_grn_data_column_apply_window_function (int argc, VALUE *argv, VALUE self) +{ + grn_rc rc; + grn_ctx *context; + grn_obj *column; + grn_obj *table; + VALUE rb_table; + grn_window_definition definition; + grn_obj *window_function_call = NULL; + VALUE rb_options; + VALUE rb_sort_keys; + VALUE rb_builder; + VALUE rb_window_function_call; + + rb_grn_column_deconstruct(SELF(self), &column, &context, + NULL, &table, + NULL, NULL, NULL); + rb_table = GRNOBJECT2RVAL(Qnil, context, table, GRN_FALSE); + + memset(&definition, 0, sizeof(grn_window_definition)); + + rb_scan_args(argc, argv, "01", &rb_options); + rb_grn_scan_options(rb_options, + "sort_keys", &rb_sort_keys, + NULL); + + if (!NIL_P(rb_sort_keys)) { + VALUE rb_table; + + if (!RVAL2CBOOL(rb_obj_is_kind_of(rb_sort_keys, rb_cArray))) + rb_raise(rb_eArgError, ":sort_keys should be an array of key: <%s>", + rb_grn_inspect(rb_sort_keys)); + + definition.n_sort_keys = RARRAY_LEN(rb_sort_keys); + definition.sort_keys = ALLOCA_N(grn_table_sort_key, + definition.n_sort_keys); + rb_table = GRNOBJECT2RVAL(Qnil, context, table, GRN_FALSE); + rb_grn_table_sort_keys_fill(context, + definition.sort_keys, + definition.n_sort_keys, + rb_sort_keys, + rb_table); + } + + rb_builder = rb_grn_record_expression_builder_new(rb_table, Qnil); + rb_window_function_call = + rb_grn_record_expression_builder_build(rb_builder); + rb_grn_object_deconstruct(RB_GRN_OBJECT(DATA_PTR(rb_window_function_call)), + &window_function_call, NULL, + NULL, NULL, NULL, NULL); + + rc = grn_table_apply_window_function(context, + table, + column, + &definition, + window_function_call); + rb_grn_context_check(context, self); + rb_grn_rc_check(rc, self); + + return self; +} + +void +rb_grn_init_data_column (VALUE mGrn) +{ + rb_cGrnDataColumn = rb_define_class_under(mGrn, "DataColumn", rb_cGrnColumn); + + rb_define_method(rb_cGrnDataColumn, "apply_window_function", + rb_grn_data_column_apply_window_function, -1); + + rb_grn_init_fix_size_column(mGrn); + rb_grn_init_variable_size_column(mGrn); +} Modified: ext/groonga/rb-grn-fix-size-column.c (+2 -2) =================================================================== --- ext/groonga/rb-grn-fix-size-column.c 2016-06-14 14:28:05 +0900 (8ea1007) +++ ext/groonga/rb-grn-fix-size-column.c 2016-06-14 15:04:16 +0900 (8008618) @@ -1,6 +1,6 @@ /* -*- coding: utf-8; mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* - Copyright (C) 2009-2010 Kouhei Sutou <kou �� clear-code.com> + Copyright (C) 2009-2016 Kouhei Sutou <kou �� clear-code.com> Copyright (C) 2016 Masafumi Yokoyama <yokoyama �� clear-code.com> This library is free software; you can redistribute it and/or @@ -227,7 +227,7 @@ void rb_grn_init_fix_size_column (VALUE mGrn) { rb_cGrnFixSizeColumn = - rb_define_class_under(mGrn, "FixSizeColumn", rb_cGrnColumn); + rb_define_class_under(mGrn, "FixSizeColumn", rb_cGrnDataColumn); rb_define_method(rb_cGrnFixSizeColumn, "[]", rb_grn_fix_size_column_array_reference, 1); Modified: ext/groonga/rb-grn-variable-size-column.c (+2 -2) =================================================================== --- ext/groonga/rb-grn-variable-size-column.c 2016-06-14 14:28:05 +0900 (206c725) +++ ext/groonga/rb-grn-variable-size-column.c 2016-06-14 15:04:16 +0900 (a6a01dc) @@ -1,6 +1,6 @@ /* -*- coding: utf-8; mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* - Copyright (C) 2009-2014 Kouhei Sutou <kou �� clear-code.com> + Copyright (C) 2009-2016 Kouhei Sutou <kou �� clear-code.com> Copyright (C) 2014-2016 Masafumi Yokoyama <yokoyama �� clear-code.com> This library is free software; you can redistribute it and/or @@ -648,7 +648,7 @@ void rb_grn_init_variable_size_column (VALUE mGrn) { rb_cGrnVariableSizeColumn = - rb_define_class_under(mGrn, "VariableSizeColumn", rb_cGrnColumn); + rb_define_class_under(mGrn, "VariableSizeColumn", rb_cGrnDataColumn); rb_define_method(rb_cGrnVariableSizeColumn, "[]", rb_grn_variable_size_column_array_reference, 1); Modified: ext/groonga/rb-grn.h (+10 -2) =================================================================== --- ext/groonga/rb-grn.h 2016-06-14 14:28:05 +0900 (0199c97) +++ ext/groonga/rb-grn.h 2016-06-14 15:04:16 +0900 (02a9349) @@ -179,17 +179,23 @@ struct _RbGrnColumn grn_obj *value; }; +typedef struct _RbGrnDataColumn RbGrnDataColumn; +struct _RbGrnDataColumn +{ + RbGrnColumn parent; +}; + typedef struct _RbGrnVariableSizeColumn RbGrnVariableSizeColumn; struct _RbGrnVariableSizeColumn { - RbGrnColumn parent; + RbGrnDataColumn parent; grn_obj *element_value; }; typedef struct _RbGrnIndexColumn RbGrnIndexColumn; struct _RbGrnIndexColumn { - RbGrnColumn parent; + RbGrnDataColumn parent; grn_obj *old_value; grn_obj *set_value; grn_obj *id_query; @@ -268,6 +274,7 @@ RB_GRN_VAR VALUE rb_cGrnArrayCursor; RB_GRN_VAR VALUE rb_cGrnType; RB_GRN_VAR VALUE rb_cGrnProcedure; RB_GRN_VAR VALUE rb_cGrnColumn; +RB_GRN_VAR VALUE rb_cGrnDataColumn; RB_GRN_VAR VALUE rb_cGrnFixSizeColumn; RB_GRN_VAR VALUE rb_cGrnVariableSizeColumn; RB_GRN_VAR VALUE rb_cGrnIndexColumn; @@ -324,6 +331,7 @@ void rb_grn_init_type (VALUE mGrn); void rb_grn_init_procedure (VALUE mGrn); void rb_grn_init_procedure_type (VALUE mGrn); void rb_grn_init_column (VALUE mGrn); +void rb_grn_init_data_column (VALUE mGrn); void rb_grn_init_fix_size_column (VALUE mGrn); void rb_grn_init_variable_size_column (VALUE mGrn); void rb_grn_init_index_column (VALUE mGrn); Modified: test/test-column.rb (+0 -29) =================================================================== --- test/test-column.rb 2016-06-14 14:28:05 +0900 (bdeb70d) +++ test/test-column.rb 2016-06-14 15:04:16 +0900 (2124afd) @@ -349,35 +349,6 @@ class ColumnTest < Test::Unit::TestCase end end - def test_apply_window_function - Groonga::Schema.define do |schema| - schema.create_table("Comments") do |table| - table.uint32("nth") - end - end - comments = Groonga["Comments"] - nth = Groonga["Comments.nth"] - - 5.times do - comments.add - end - - options = { - :sort_keys => [["_id", "desc"]], - } - nth.apply_window_function(options) do |record| - record.call("record_number") - end - assert_equal([ - [1, 5], - [2, 4], - [3, 3], - [4, 2], - [5, 1], - ], - comments.collect {|comment| [comment.id, comment.nth]}) - end - private def assert_content_search(expected_records, term) records = @bookmarks_index_content.search(term).records Added: test/test-data-column.rb (+53 -0) 100644 =================================================================== --- /dev/null +++ test/test-data-column.rb 2016-06-14 15:04:16 +0900 (105a2ea) @@ -0,0 +1,53 @@ +# Copyright (C) 2016 Kouhei Sutou <kou �� clear-code.com> +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1 as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +class DataColumnTest < Test::Unit::TestCase + include GroongaTestUtils + + def setup + setup_database + end + + sub_test_case "#apply_window_function" do + def test_no_argument + Groonga::Schema.define do |schema| + schema.create_table("Comments") do |table| + table.uint32("nth") + end + end + comments = Groonga["Comments"] + nth = Groonga["Comments.nth"] + + 5.times do + comments.add + end + + options = { + :sort_keys => [["_id", "desc"]], + } + nth.apply_window_function(options) do |record| + record.call("record_number") + end + assert_equal([ + [1, 5], + [2, 4], + [3, 3], + [4, 2], + [5, 1], + ], + comments.collect {|comment| [comment.id, comment.nth]}) + end + end +end -------------- next part -------------- HTML����������������������������... Download