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