rroonga 0.9.5 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. data/NEWS.ja.rdoc +13 -0
  2. data/NEWS.rdoc +13 -0
  3. data/README.ja.rdoc +2 -2
  4. data/README.rdoc +2 -2
  5. data/ext/groonga/rb-grn-exception.c +14 -0
  6. data/ext/groonga/rb-grn-index-column.c +13 -1
  7. data/ext/groonga/rb-grn-object.c +2 -2
  8. data/ext/groonga/rb-grn-patricia-trie.c +393 -0
  9. data/ext/groonga/rb-grn-table.c +26 -2
  10. data/ext/groonga/rb-grn.h +3 -3
  11. data/html/index.html +1 -1
  12. data/lib/groonga/schema.rb +1 -1
  13. data/rroonga-build.rb +3 -3
  14. data/test-unit-notify/Rakefile +47 -0
  15. data/test-unit-notify/lib/test/unit/notify.rb +104 -0
  16. data/test-unit/COPYING +56 -0
  17. data/test-unit/GPL +340 -0
  18. data/test-unit/PSFL +271 -0
  19. data/test-unit/Rakefile +18 -5
  20. data/test-unit/html/bar.svg +153 -0
  21. data/test-unit/html/developer.svg +469 -0
  22. data/test-unit/html/favicon.ico +0 -0
  23. data/test-unit/html/favicon.svg +82 -0
  24. data/test-unit/html/heading-mark.svg +393 -0
  25. data/test-unit/html/index.html +235 -13
  26. data/test-unit/html/index.html.ja +258 -15
  27. data/test-unit/html/install.svg +636 -0
  28. data/test-unit/html/logo.svg +483 -0
  29. data/test-unit/html/test-unit.css +339 -0
  30. data/test-unit/html/tutorial.svg +559 -0
  31. data/test-unit/lib/test/unit.rb +6 -1
  32. data/test-unit/lib/test/unit/assertions.rb +115 -11
  33. data/test-unit/lib/test/unit/autorunner.rb +5 -2
  34. data/test-unit/lib/test/unit/collector/load.rb +1 -1
  35. data/test-unit/lib/test/unit/color-scheme.rb +6 -2
  36. data/test-unit/lib/test/unit/diff.rb +17 -1
  37. data/test-unit/lib/test/unit/testcase.rb +7 -0
  38. data/test-unit/lib/test/unit/testresult.rb +34 -2
  39. data/test-unit/lib/test/unit/ui/console/testrunner.rb +9 -45
  40. data/test-unit/lib/test/unit/ui/tap/testrunner.rb +2 -12
  41. data/test-unit/lib/test/unit/ui/testrunner.rb +25 -0
  42. data/test-unit/lib/test/unit/util/backtracefilter.rb +1 -0
  43. data/test-unit/lib/test/unit/util/output.rb +31 -0
  44. data/test-unit/lib/test/unit/version.rb +1 -1
  45. data/test-unit/test/test-color-scheme.rb +4 -2
  46. data/test-unit/test/test_assertions.rb +51 -5
  47. data/test-unit/test/ui/test_tap.rb +33 -0
  48. data/test-unit/test/util/test-output.rb +11 -0
  49. data/test/test-patricia-trie.rb +161 -0
  50. data/test/test-remote.rb +2 -1
  51. data/test/test-table-cursor.rb +35 -1
  52. metadata +26 -10
  53. data/test-unit/html/classic.html +0 -15
data/NEWS.ja.rdoc CHANGED
@@ -1,5 +1,18 @@
1
1
  = お知らせ
2
2
 
3
+ == 1.0.0: 2010-08-29
4
+
5
+ * groonga 1.0.0対応。
6
+ * Groonga::CASErrorを追加。
7
+ * Groonga::Table#open_cursorに:order_byオプションを追加。
8
+ * 前方一致検索がマッチしたレコードを順に取り出すカーソルを作る
9
+ Groonga::PatriciaTrie#open_prefix_cursorを追加。
10
+ * ローマ字・ひらがなでカタカナのキーを検索するカーソルを作る
11
+ Groonga::PatriciaTrie#open_rk_cursorを追加。
12
+ * 値の近い順にレコードを取り出すカーソルを作る
13
+ Groonga::PatriciaTrie#open_near_cursorを追加。
14
+ * インデックスのソースに_keyを指定できるようになった。
15
+
3
16
  == 0.9.5: 2010-07-29
4
17
 
5
18
  * groonga 0.7.4対応。
data/NEWS.rdoc CHANGED
@@ -1,5 +1,18 @@
1
1
  = NEWS
2
2
 
3
+ == 1.0.0: 2010-08-29
4
+
5
+ * Supported groonga 1.0.0.
6
+ * Added Groonga::CASError.
7
+ * Added :order_by option to Groonga::Table#open_cursor.
8
+ * Added Groonga::PatriciaTrie#open_prefix_cursor that creates a cursor
9
+ to retrieve each records by prefix search.
10
+ * Added Groonga::PatriciaTrie#open_rk_cursor that creats a cursor to
11
+ retrieve katakana keys from roman letters and/or hiragana.
12
+ * Added Groonga::PatriciaTrie#open_near_cursor that creates a cursor to
13
+ retrieve records order by distance from key.
14
+ * Supported _key as index source.
15
+
3
16
  == 0.9.5: 2010-07-20
4
17
 
5
18
  * Supported groonga 0.7.4.
data/README.ja.rdoc CHANGED
@@ -35,8 +35,8 @@ pkg-config.rbはrcairoに付属しているもので、これはRubyライセ
35
35
 
36
36
  == 依存ソフトウェア
37
37
 
38
- * Ruby >= 1.8 (1.9.1対応)
39
- * groonga >= 0.1.9
38
+ * Ruby >= 1.8 (1.9.1, 1.9.2対応)
39
+ * groonga >= 1.0.0
40
40
 
41
41
  == インストール
42
42
 
data/README.rdoc CHANGED
@@ -36,8 +36,8 @@ license/GPL for details.
36
36
 
37
37
  == Dependencies
38
38
 
39
- * Ruby >= 1.8 (including 1.9.1)
40
- * groonga >= 0.1.9
39
+ * Ruby >= 1.8 (including 1.9.1 and 1.9.2)
40
+ * groonga >= 1.0.0
41
41
 
42
42
  == Install
43
43
 
@@ -92,6 +92,7 @@ static VALUE eGrnUpdateNotAllowed;
92
92
  static VALUE eGrnTooSmallOffset;
93
93
  static VALUE eGrnTooLargeOffset;
94
94
  static VALUE eGrnTooSmallLimit;
95
+ static VALUE eGrnCASError;
95
96
 
96
97
  VALUE
97
98
  rb_grn_rc_to_exception (grn_rc rc)
@@ -312,6 +313,9 @@ rb_grn_rc_to_exception (grn_rc rc)
312
313
  case GRN_TOO_SMALL_LIMIT:
313
314
  exception = eGrnTooSmallLimit;
314
315
  break;
316
+ case GRN_CAS_ERROR:
317
+ exception = eGrnCASError;
318
+ break;
315
319
  }
316
320
 
317
321
  if (NIL_P(exception))
@@ -539,6 +543,9 @@ rb_grn_rc_to_message (grn_rc rc)
539
543
  case GRN_TOO_SMALL_LIMIT:
540
544
  message = "too small limit";
541
545
  break;
546
+ case GRN_CAS_ERROR:
547
+ message = "CAS error";
548
+ break;
542
549
  }
543
550
 
544
551
  if (!message)
@@ -1152,4 +1159,11 @@ rb_grn_init_exception (VALUE mGrn)
1152
1159
  */
1153
1160
  eGrnTooSmallLimit =
1154
1161
  rb_define_class_under(mGrn, "TooSmallLimit", rb_eGrnError);
1162
+
1163
+ /*
1164
+ * Document-class: Groonga::CASError
1165
+ *
1166
+ * CAS(Compare and Swap)が失敗したときに発生する。
1167
+ */
1168
+ eGrnCASError = rb_define_class_under(mGrn, "CASError", rb_eGrnError);
1155
1169
  }
@@ -307,7 +307,19 @@ resolve_source_id (grn_ctx *context, grn_obj *column, VALUE rb_source)
307
307
  source = RVAL2GRNOBJECT(rb_source, &context);
308
308
  }
309
309
  rb_grn_context_check(context, rb_source);
310
- source_id = grn_obj_id(context, source);
310
+ if (source->header.type == GRN_ACCESSOR) {
311
+ char name[256];
312
+ int length;
313
+ length = grn_column_name(context, source, name, sizeof(name));
314
+ name[length] = '\0';
315
+ if (strcmp(name, "_key") != 0) {
316
+ rb_raise(rb_eArgError,
317
+ "source accessor must be '_key': <%s>", name);
318
+ }
319
+ source_id = grn_obj_id(context, column);
320
+ } else {
321
+ source_id = grn_obj_id(context, source);
322
+ }
311
323
  }
312
324
 
313
325
  return source_id;
@@ -766,8 +766,8 @@ rb_grn_object_inspect_content_flags_with_label (VALUE inspected,
766
766
  rb_ary_push(inspected_flags, rb_str_new2("WITH_WEIGHT"));
767
767
  if (flags & GRN_OBJ_WITH_POSITION)
768
768
  rb_ary_push(inspected_flags, rb_str_new2("WITH_POSITION"));
769
- if (flags & GRN_OBJ_WITH_BUFFER)
770
- rb_ary_push(inspected_flags, rb_str_new2("WITH_BUFFER"));
769
+ if (flags & GRN_OBJ_RING_BUFFER)
770
+ rb_ary_push(inspected_flags, rb_str_new2("RING_BUFFER"));
771
771
 
772
772
  if (flags & GRN_OBJ_WITH_SUBREC) {
773
773
  rb_ary_push(inspected_flags, rb_str_new2("WITH_SUBREC"));
@@ -19,6 +19,8 @@
19
19
 
20
20
  #include "rb-grn.h"
21
21
 
22
+ grn_rc grn_obj_cast(grn_ctx *ctx, grn_obj *src, grn_obj *dest, int addp);
23
+
22
24
  #define SELF(object) ((RbGrnTableKeySupport *)DATA_PTR(object))
23
25
 
24
26
  VALUE rb_cGrnPatriciaTrie;
@@ -488,6 +490,387 @@ rb_grn_patricia_trie_register_key_with_sis_p (VALUE self)
488
490
  return CBOOL2RVAL(table->header.flags & GRN_OBJ_KEY_WITH_SIS);
489
491
  }
490
492
 
493
+ static grn_table_cursor *
494
+ rb_grn_patricia_trie_open_grn_prefix_cursor (int argc, VALUE *argv, VALUE self,
495
+ grn_ctx **context)
496
+ {
497
+ grn_obj *table;
498
+ grn_table_cursor *cursor;
499
+ void *prefix = NULL;
500
+ unsigned prefix_size = 0;
501
+ int offset = 0, limit = -1;
502
+ int flags = GRN_CURSOR_PREFIX;
503
+ VALUE options, rb_prefix, rb_key_bytes, rb_key_bits;
504
+ VALUE rb_order, rb_order_by;
505
+ VALUE rb_greater_than, rb_less_than, rb_offset, rb_limit;
506
+
507
+ rb_grn_table_deconstruct((RbGrnTable *)SELF(self), &table, context,
508
+ NULL, NULL,
509
+ NULL, NULL, NULL,
510
+ NULL);
511
+
512
+ rb_scan_args(argc, argv, "11", &rb_prefix, &options);
513
+
514
+ rb_grn_scan_options(options,
515
+ "key_bytes", &rb_key_bytes,
516
+ "key_bites", &rb_key_bits,
517
+ "offset", &rb_offset,
518
+ "limit", &rb_limit,
519
+ "order", &rb_order,
520
+ "order_by", &rb_order_by,
521
+ "greater_than", &rb_greater_than,
522
+ "less_than", &rb_less_than,
523
+ NULL);
524
+
525
+ prefix = StringValuePtr(rb_prefix);
526
+ if (!NIL_P(rb_key_bytes) && !NIL_P(rb_key_bits)) {
527
+ rb_raise(rb_eArgError,
528
+ "should not specify both :key_bytes and :key_bits once: %s",
529
+ rb_grn_inspect(rb_ary_new4(argc, argv)));
530
+ } else if (!NIL_P(rb_key_bytes)) {
531
+ prefix_size = NUM2UINT(rb_key_bytes);
532
+ } else if (!NIL_P(rb_key_bits)) {
533
+ prefix_size = NUM2UINT(rb_key_bits);
534
+ flags |= GRN_CURSOR_SIZE_BY_BIT;
535
+ } else {
536
+ prefix_size = RSTRING_LEN(rb_prefix);
537
+ }
538
+ if (!NIL_P(rb_offset))
539
+ offset = NUM2INT(rb_offset);
540
+ if (!NIL_P(rb_limit))
541
+ limit = NUM2INT(rb_limit);
542
+
543
+ if (NIL_P(rb_order)) {
544
+ } else if (rb_grn_equal_option(rb_order, "asc") ||
545
+ rb_grn_equal_option(rb_order, "ascending")) {
546
+ flags |= GRN_CURSOR_ASCENDING;
547
+ } else if (rb_grn_equal_option(rb_order, "desc") ||
548
+ rb_grn_equal_option(rb_order, "descending")) {
549
+ flags |= GRN_CURSOR_DESCENDING;
550
+ } else {
551
+ rb_raise(rb_eArgError,
552
+ "order should be one of "
553
+ "[:asc, :ascending, :desc, :descending]: %s",
554
+ rb_grn_inspect(rb_order));
555
+ }
556
+ if (NIL_P(rb_order_by)) {
557
+ } else if (rb_grn_equal_option(rb_order_by, "id")) {
558
+ flags |= GRN_CURSOR_BY_ID;
559
+ } else if (rb_grn_equal_option(rb_order_by, "key")) {
560
+ if (table->header.type != GRN_TABLE_PAT_KEY) {
561
+ rb_raise(rb_eArgError,
562
+ "order_by => :key is available "
563
+ "only for Groonga::PatriciaTrie: %s",
564
+ rb_grn_inspect(self));
565
+ }
566
+ flags |= GRN_CURSOR_BY_KEY;
567
+ } else {
568
+ rb_raise(rb_eArgError,
569
+ "order_by should be one of [:id%s]: %s",
570
+ table->header.type == GRN_TABLE_PAT_KEY ? ", :key" : "",
571
+ rb_grn_inspect(rb_order_by));
572
+ }
573
+
574
+ if (RVAL2CBOOL(rb_greater_than))
575
+ flags |= GRN_CURSOR_GT;
576
+ if (RVAL2CBOOL(rb_less_than))
577
+ flags |= GRN_CURSOR_LT;
578
+
579
+ cursor = grn_table_cursor_open(*context, table,
580
+ prefix, prefix_size,
581
+ NULL, 0,
582
+ offset, limit, flags);
583
+ rb_grn_context_check(*context, self);
584
+
585
+ return cursor;
586
+ }
587
+
588
+
589
+ /*
590
+ * call-seq:
591
+ * table.open_prefix_cursor(prefix, options={}) -> Groonga::PatriciaTrieCursor
592
+ * table.open_prefix_cursor(prefix, options={}) {|cursor| ... }
593
+ *
594
+ * _prefix_に前方一致検索をするカーソルを生成して返す。ブロッ
595
+ * クを指定すると、そのブロックに生成したカーソルが渡され、ブ
596
+ * ロックを抜けると自動的にカーソルが破棄される。
597
+ *
598
+ * _options_に指定可能な値は以下の通り。
599
+ *
600
+ * [+:key_bytes+]
601
+ * _prefix_のサイズ(byte)
602
+ *
603
+ * [+:key_bits+]
604
+ * _prefix_のサイズ(bit)
605
+ *
606
+ * [+:offset+]
607
+ * 該当する範囲のレコードのうち、(0ベースで)_:offset_番目
608
+ * からレコードを取り出す。
609
+ *
610
+ * [+:limit+]
611
+ * 該当する範囲のレコードのうち、_:limit_件のみを取り出す。
612
+ * 省略された場合または-1が指定された場合は、全件が指定され
613
+ * たものとみなす。
614
+ *
615
+ * [+:order+]
616
+ * +:asc+または+:ascending+を指定すると昇順にレコードを取
617
+ * り出す。
618
+ * +:desc+または+:descending+を指定すると降順にレコードを
619
+ * 取り出す。
620
+ *
621
+ * [+:order_by+]
622
+ * +:id+を指定するとID順にレコードを取り出す。(デフォルト)
623
+ *
624
+ * +:key+指定するとキー順にレコードを取り出す。
625
+ *
626
+ * [+:greater_than+]
627
+ * +true+を指定すると_prefix_で指定した値に一致した[+key+]を
628
+ * 範囲に含まない。
629
+ *
630
+ * [+:less_than+]
631
+ * +true+を指定すると_prefix_で指定した値に一致した[+key+]を
632
+ * 範囲に含まない。
633
+ */
634
+ static VALUE
635
+ rb_grn_patricia_trie_open_prefix_cursor (int argc, VALUE *argv, VALUE self)
636
+ {
637
+ grn_ctx *context = NULL;
638
+ grn_table_cursor *cursor;
639
+ VALUE rb_cursor;
640
+
641
+ cursor = rb_grn_patricia_trie_open_grn_prefix_cursor(argc, argv,
642
+ self, &context);
643
+ rb_cursor = GRNTABLECURSOR2RVAL(Qnil, context, cursor);
644
+ rb_iv_set(rb_cursor, "@table", self); /* FIXME: cursor should mark table */
645
+ if (rb_block_given_p())
646
+ return rb_ensure(rb_yield, rb_cursor, rb_grn_object_close, rb_cursor);
647
+ else
648
+ return rb_cursor;
649
+ }
650
+
651
+ static grn_table_cursor *
652
+ rb_grn_patricia_trie_open_grn_rk_cursor (int argc, VALUE *argv, VALUE self,
653
+ grn_ctx **context)
654
+ {
655
+ grn_obj *table;
656
+ grn_table_cursor *cursor;
657
+ void *prefix = NULL;
658
+ unsigned prefix_size = 0;
659
+ int offset = 0, limit = -1;
660
+ int flags = GRN_CURSOR_PREFIX | GRN_CURSOR_RK;
661
+ VALUE options, rb_prefix, rb_key_bytes, rb_key_bits;
662
+ VALUE rb_greater_than, rb_less_than, rb_offset, rb_limit;
663
+
664
+ rb_grn_table_deconstruct((RbGrnTable *)SELF(self), &table, context,
665
+ NULL, NULL,
666
+ NULL, NULL, NULL,
667
+ NULL);
668
+
669
+ rb_scan_args(argc, argv, "11", &rb_prefix, &options);
670
+
671
+ rb_grn_scan_options(options,
672
+ "key_bytes", &rb_key_bytes,
673
+ "key_bites", &rb_key_bits,
674
+ "offset", &rb_offset,
675
+ "limit", &rb_limit,
676
+ "greater_than", &rb_greater_than,
677
+ "less_than", &rb_less_than,
678
+ NULL);
679
+
680
+ prefix = StringValuePtr(rb_prefix);
681
+ if (!NIL_P(rb_key_bytes) && !NIL_P(rb_key_bits)) {
682
+ rb_raise(rb_eArgError,
683
+ "should not specify both :key_bytes and :key_bits once: %s",
684
+ rb_grn_inspect(rb_ary_new4(argc, argv)));
685
+ } else if (!NIL_P(rb_key_bytes)) {
686
+ prefix_size = NUM2UINT(rb_key_bytes);
687
+ } else if (!NIL_P(rb_key_bits)) {
688
+ prefix_size = NUM2UINT(rb_key_bits);
689
+ flags |= GRN_CURSOR_SIZE_BY_BIT;
690
+ } else {
691
+ prefix_size = RSTRING_LEN(rb_prefix);
692
+ }
693
+ if (!NIL_P(rb_offset))
694
+ offset = NUM2INT(rb_offset);
695
+ if (!NIL_P(rb_limit))
696
+ limit = NUM2INT(rb_limit);
697
+
698
+ if (RVAL2CBOOL(rb_greater_than))
699
+ flags |= GRN_CURSOR_GT;
700
+ if (RVAL2CBOOL(rb_less_than))
701
+ flags |= GRN_CURSOR_LT;
702
+
703
+ cursor = grn_table_cursor_open(*context, table,
704
+ prefix, prefix_size,
705
+ NULL, 0,
706
+ offset, limit, flags);
707
+ rb_grn_context_check(*context, self);
708
+
709
+ return cursor;
710
+ }
711
+
712
+ /*
713
+ * call-seq:
714
+ * table.open_rk_cursor(key, options={}) -> Groonga::PatriciaTrieCursor
715
+ * table.open_rk_cursor(key, options={}) {|cursor| ... }
716
+ *
717
+ * _table_のキーはカタカナである必要がある。また、エンコーディ
718
+ * ングはUTF-8である必要がある。ローマ字やひらがなで_key_を指
719
+ * 定しても、_key_に対応するカタカナのキーを検索するカーソル
720
+ * を生成して返す。ブロックを指定すると、そのブロックに生成し
721
+ * たカーソルが渡され、ブロックを抜けると自動的にカーソルが破
722
+ * 棄される。
723
+ *
724
+ * _options_に指定可能な値は以下の通り。
725
+ *
726
+ * [+:key_bytes+]
727
+ * _key_のサイズ(byte)
728
+ *
729
+ * [+:key_bits+]
730
+ * _key_のサイズ(bit)(現在は未サポート)
731
+ *
732
+ * [+:offset+]
733
+ * 該当する範囲のレコードのうち、(0ベースで)_:offset_番目
734
+ * からレコードを取り出す。
735
+ *
736
+ * [+:limit+]
737
+ * 該当する範囲のレコードのうち、_:limit_件のみを取り出す。
738
+ * 省略された場合または-1が指定された場合は、全件が指定され
739
+ * たものとみなす。
740
+ *
741
+ * [+:greater_than+]
742
+ * +true+を指定すると_key_で指定した値に一致した[+key+]を
743
+ * 範囲に含まない。
744
+ *
745
+ * [+:less_than+]
746
+ * +true+を指定すると_key_で指定した値に一致した[+key+]を
747
+ * 範囲に含まない。
748
+ */
749
+ static VALUE
750
+ rb_grn_patricia_trie_open_rk_cursor (int argc, VALUE *argv, VALUE self)
751
+ {
752
+ grn_ctx *context = NULL;
753
+ grn_table_cursor *cursor;
754
+ VALUE rb_cursor;
755
+
756
+ cursor = rb_grn_patricia_trie_open_grn_rk_cursor(argc, argv,
757
+ self, &context);
758
+ rb_cursor = GRNTABLECURSOR2RVAL(Qnil, context, cursor);
759
+ rb_iv_set(rb_cursor, "@table", self); /* FIXME: cursor should mark table */
760
+ if (rb_block_given_p())
761
+ return rb_ensure(rb_yield, rb_cursor, rb_grn_object_close, rb_cursor);
762
+ else
763
+ return rb_cursor;
764
+ }
765
+
766
+
767
+ static grn_table_cursor *
768
+ rb_grn_patricia_trie_open_grn_near_cursor (int argc, VALUE *argv, VALUE self,
769
+ grn_ctx **context, int flags)
770
+ {
771
+ grn_obj *table;
772
+ grn_obj *key_p = NULL, casted_key;
773
+ grn_table_cursor *cursor;
774
+ unsigned min_size = 0;
775
+ int offset = 0, limit = -1;
776
+ VALUE options, rb_key, rb_min_size;
777
+ VALUE rb_greater_than, rb_less_than, rb_offset, rb_limit;
778
+
779
+ flags |= GRN_CURSOR_PREFIX;
780
+
781
+ rb_grn_table_deconstruct((RbGrnTable *)SELF(self), &table, context,
782
+ NULL, NULL,
783
+ NULL, NULL, NULL,
784
+ NULL);
785
+
786
+ rb_scan_args(argc, argv, "11", &rb_key, &options);
787
+
788
+ rb_grn_scan_options(options,
789
+ "size", &rb_min_size,
790
+ "offset", &rb_offset,
791
+ "limit", &rb_limit,
792
+ "greater_than", &rb_greater_than,
793
+ "less_than", &rb_less_than,
794
+ NULL);
795
+
796
+ key_p = RVAL2GRNBULK_WITH_TYPE(rb_key, *context, key_p,
797
+ table->header.domain, grn_ctx_at(*context, table->header.domain));
798
+ GRN_OBJ_INIT(&casted_key, GRN_BULK, 0, table->header.domain);
799
+ if (key_p->header.domain != table->header.domain) {
800
+ grn_obj_cast(*context, key_p, &casted_key, 0);
801
+ key_p = &casted_key;
802
+ }
803
+
804
+ if (!NIL_P(rb_min_size))
805
+ min_size = NUM2UINT(rb_min_size);
806
+ if (!NIL_P(rb_offset))
807
+ offset = NUM2INT(rb_offset);
808
+ if (!NIL_P(rb_limit))
809
+ limit = NUM2INT(rb_limit);
810
+
811
+ if (RVAL2CBOOL(rb_greater_than))
812
+ flags |= GRN_CURSOR_GT;
813
+ if (RVAL2CBOOL(rb_less_than))
814
+ flags |= GRN_CURSOR_LT;
815
+
816
+ cursor = grn_table_cursor_open(*context, table,
817
+ NULL, min_size,
818
+ GRN_BULK_HEAD(key_p), GRN_BULK_VSIZE(key_p),
819
+ offset, limit, flags);
820
+ GRN_OBJ_FIN(*context, &casted_key);
821
+ rb_grn_context_check(*context, self);
822
+
823
+ return cursor;
824
+ }
825
+
826
+ /*
827
+ * call-seq:
828
+ * table.open_near_cursor(key, options={}) -> Groonga::PatriciaTrieCursor
829
+ * table.open_near_cursor(key, options={}) {|cursor| ... }
830
+ *
831
+ * _key_に近い順にレコードを取り出すカーソルを生成して返す。
832
+ * ブロックを指定すると、そのブロックに生成したカーソルが渡さ
833
+ * れ、ブロックを抜けると自動的にカーソルが破棄される。
834
+ *
835
+ * _options_に指定可能な値は以下の通り。
836
+ *
837
+ * [+:size+]
838
+ * _size_バイト以降のデータが同じキーのレコードに限定する。
839
+ *
840
+ * [+:offset+]
841
+ * 該当する範囲のレコードのうち、(0ベースで)_:offset_番目
842
+ * からレコードを取り出す。
843
+ *
844
+ * [+:limit+]
845
+ * 該当する範囲のレコードのうち、_:limit_件のみを取り出す。
846
+ * 省略された場合または-1が指定された場合は、全件が指定され
847
+ * たものとみなす。
848
+ *
849
+ * [+:greater_than+]
850
+ * +true+を指定すると_key_で指定した値に一致した[+key+]を
851
+ * 範囲に含まない。
852
+ *
853
+ * [+:less_than+]
854
+ * +true+を指定すると_key_で指定した値に一致した[+key+]を
855
+ * 範囲に含まない。
856
+ */
857
+ static VALUE
858
+ rb_grn_patricia_trie_open_near_cursor (int argc, VALUE *argv, VALUE self)
859
+ {
860
+ grn_ctx *context = NULL;
861
+ grn_table_cursor *cursor;
862
+ VALUE rb_cursor;
863
+
864
+ cursor = rb_grn_patricia_trie_open_grn_near_cursor(argc, argv,
865
+ self, &context, GRN_CURSOR_RK);
866
+ rb_cursor = GRNTABLECURSOR2RVAL(Qnil, context, cursor);
867
+ rb_iv_set(rb_cursor, "@table", self); /* FIXME: cursor should mark table */
868
+ if (rb_block_given_p())
869
+ return rb_ensure(rb_yield, rb_cursor, rb_grn_object_close, rb_cursor);
870
+ else
871
+ return rb_cursor;
872
+ }
873
+
491
874
  void
492
875
  rb_grn_init_patricia_trie (VALUE mGrn)
493
876
  {
@@ -507,4 +890,14 @@ rb_grn_init_patricia_trie (VALUE mGrn)
507
890
 
508
891
  rb_define_method(rb_cGrnPatriciaTrie, "register_key_with_sis?",
509
892
  rb_grn_patricia_trie_register_key_with_sis_p, 0);
893
+
894
+ rb_define_method(rb_cGrnPatriciaTrie, "open_prefix_cursor",
895
+ rb_grn_patricia_trie_open_prefix_cursor,
896
+ -1);
897
+ rb_define_method(rb_cGrnPatriciaTrie, "open_rk_cursor",
898
+ rb_grn_patricia_trie_open_rk_cursor,
899
+ -1);
900
+ rb_define_method(rb_cGrnPatriciaTrie, "open_near_cursor",
901
+ rb_grn_patricia_trie_open_near_cursor,
902
+ -1);
510
903
  }