Ryo Onodera
onode****@clear*****
2009年 10月 26日 (月) 14:56:29 JST
これが午前中に話したCursorに:offsetと:limitオプションを追加するパッチです。 今回も同じ様なヘルパー関数を使っています。前のパッチのヘルパー関数の使い 方を反映させてあります。今回は次のように使うようにしました。 bookmarks = create_bookmarks add_ids(bookmarks) Index: ext/rb-grn-table.c =================================================================== --- ext/rb-grn-table.c (revision 730) +++ ext/rb-grn-table.c (working copy) @@ -644,8 +644,10 @@ grn_table_cursor *cursor; void *min_key = NULL, *max_key = NULL; unsigned min_key_size = 0, max_key_size = 0; + unsigned offset = 0, limit = 0; int flags = 0; VALUE options, rb_min, rb_max, rb_order, rb_greater_than, rb_less_than; + VALUE rb_offset, rb_limit; rb_grn_table_deconstruct(SELF(self), &table, context, NULL, NULL, @@ -656,6 +658,8 @@ rb_grn_scan_options(options, "min", &rb_min, "max", &rb_max, + "offset", &rb_offset, + "limit", &rb_limit, "order", &rb_order, "greater_than", &rb_greater_than, "less_than", &rb_less_than, @@ -669,6 +673,10 @@ max_key = StringValuePtr(rb_max); max_key_size = RSTRING_LEN(rb_max); } + if (!NIL_P(rb_offset)) + offset = NUM2INT(rb_offset); + if (!NIL_P(rb_limit)) + limit = NUM2INT(rb_limit); if (NIL_P(rb_order)) { } else if (rb_grn_equal_option(rb_order, "asc") || @@ -689,11 +697,10 @@ if (RVAL2CBOOL(rb_less_than)) flags |= GRN_CURSOR_LT; - /* FIXME: should support offset and limit */ cursor = grn_table_cursor_open(*context, table, min_key, min_key_size, max_key, max_key_size, - 0, 0, flags); + offset, limit, flags); rb_grn_context_check(*context, self); return cursor; Index: test/test-table-cursor.rb =================================================================== --- test/test-table-cursor.rb (revision 730) +++ test/test-table-cursor.rb (working copy) @@ -48,4 +48,71 @@ [@groonga_bookmark, "groonga"]], record_and_key_list) end + + def test_without_limit_and_offset + bookmarks = create_bookmarks + add_ids(bookmarks) + results = [] + bookmarks.open_cursor do |cursor| + while record = cursor.next + results << record["id"] + end + end + + assert_equal((100..199).to_a, results) + end + + def test_with_limit + bookmarks = create_bookmarks + add_ids(bookmarks) + results = [] + bookmarks.open_cursor(:limit => 20) do |cursor| + while record = cursor.next + results << record["id"] + end + end + + assert_equal((100...120).to_a, results) + end + + def test_with_offset + bookmarks = create_bookmarks + add_ids(bookmarks) + results = [] + bookmarks.open_cursor(:offset => 20) do |cursor| + while record = cursor.next + results << record["id"] + end + end + + assert_equal((120...200).to_a, results) + end + + def test_with_limit_and_offset + bookmarks = create_bookmarks + add_ids(bookmarks) + results = [] + bookmarks.open_cursor(:limit => 20, :offset => 20) do |cursor| + while record = cursor.next + results << record["id"] + end + end + + assert_equal((120...140).to_a, results) + end + + private + def create_bookmarks + bookmarks = Groonga::Array.create(:name => "<bookmarks>") + bookmarks.define_column("id", "<int>") + bookmarks + end + + def add_ids(bookmarks) + (0...100).to_a.each do |i| + bookmark = bookmarks.add + bookmark["id"] = i + 100 + end + bookmarks + end end