rroonga 0.9.5 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
  }