[groonga-dev,00251] CursorのoffsetとlimitもRuby/groongaで設定可能にする

Back to archive index

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




groonga-dev メーリングリストの案内
Back to archive index