rroonga 5.0.0 → 5.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -0
  3. data/Rakefile +1 -10
  4. data/ext/groonga/extconf.rb +3 -1
  5. data/ext/groonga/rb-grn-array.c +1 -1
  6. data/ext/groonga/rb-grn-column.c +33 -67
  7. data/ext/groonga/rb-grn-context.c +5 -5
  8. data/ext/groonga/rb-grn-database.c +2 -2
  9. data/ext/groonga/rb-grn-double-array-trie.c +4 -2
  10. data/ext/groonga/rb-grn-encoding-support.c +7 -1
  11. data/ext/groonga/rb-grn-equal-operator.c +85 -0
  12. data/ext/groonga/rb-grn-exception.c +17 -0
  13. data/ext/groonga/rb-grn-expression.c +85 -43
  14. data/ext/groonga/rb-grn-greater-equal-operator.c +88 -0
  15. data/ext/groonga/rb-grn-greater-operator.c +85 -0
  16. data/ext/groonga/rb-grn-hash.c +1 -1
  17. data/ext/groonga/rb-grn-index-column.c +150 -11
  18. data/ext/groonga/rb-grn-less-equal-operator.c +88 -0
  19. data/ext/groonga/rb-grn-less-operator.c +85 -0
  20. data/ext/groonga/rb-grn-logger.c +5 -5
  21. data/ext/groonga/rb-grn-match-operator.c +86 -0
  22. data/ext/groonga/rb-grn-normalizer.c +8 -1
  23. data/ext/groonga/rb-grn-not-equal-operator.c +85 -0
  24. data/ext/groonga/rb-grn-object.c +170 -36
  25. data/ext/groonga/rb-grn-operator.c +395 -172
  26. data/ext/groonga/rb-grn-patricia-trie.c +10 -8
  27. data/ext/groonga/rb-grn-plugin.c +51 -3
  28. data/ext/groonga/rb-grn-prefix-operator.c +86 -0
  29. data/ext/groonga/rb-grn-procedure-type.c +4 -0
  30. data/ext/groonga/rb-grn-query-logger.c +4 -4
  31. data/ext/groonga/rb-grn-regexp-operator.c +85 -0
  32. data/ext/groonga/rb-grn-snippet.c +1 -1
  33. data/ext/groonga/rb-grn-table-key-support.c +9 -5
  34. data/ext/groonga/rb-grn-table.c +52 -66
  35. data/ext/groonga/rb-grn-type.c +1 -1
  36. data/ext/groonga/rb-grn-utils.c +22 -3
  37. data/ext/groonga/rb-grn.h +31 -4
  38. data/ext/groonga/rb-groonga.c +9 -9
  39. data/lib/groonga/context.rb +31 -0
  40. data/lib/groonga/expression-builder.rb +14 -1
  41. data/lib/groonga/record.rb +10 -8
  42. data/lib/groonga/schema.rb +3 -1
  43. data/rroonga-build.rb +2 -2
  44. data/rroonga.gemspec +3 -3
  45. data/test/groonga-test-utils.rb +4 -0
  46. data/test/test-column.rb +28 -26
  47. data/test/test-exception.rb +1 -0
  48. data/test/test-expression-builder.rb +83 -1
  49. data/test/test-expression.rb +80 -48
  50. data/test/test-index-column.rb +102 -29
  51. data/test/test-normalizer.rb +35 -29
  52. data/test/test-operator.rb +214 -0
  53. data/test/test-plugin.rb +24 -6
  54. data/test/test-procedure.rb +29 -0
  55. data/test/test-schema-type.rb +14 -0
  56. data/test/test-table-select-mecab.rb +1 -4
  57. data/test/test-table.rb +7 -0
  58. data/test/test-token-regexp.rb +30 -0
  59. data/test/test-type.rb +24 -0
  60. metadata +61 -49
  61. data/doc/text/news.textile +0 -1217
@@ -99,6 +99,7 @@ static VALUE eGrnNormalizerError;
99
99
  static VALUE eGrnTokenFilterError;
100
100
  static VALUE eGrnCommandError;
101
101
  static VALUE eGrnPluginError;
102
+ static VALUE eGrnScorerError;
102
103
 
103
104
  VALUE
104
105
  rb_grn_rc_to_exception (grn_rc rc)
@@ -337,6 +338,9 @@ rb_grn_rc_to_exception (grn_rc rc)
337
338
  case GRN_PLUGIN_ERROR:
338
339
  exception = eGrnPluginError;
339
340
  break;
341
+ case GRN_SCORER_ERROR:
342
+ exception = eGrnScorerError;
343
+ break;
340
344
  }
341
345
 
342
346
  if (NIL_P(exception))
@@ -582,6 +586,9 @@ rb_grn_rc_to_message (grn_rc rc)
582
586
  case GRN_PLUGIN_ERROR:
583
587
  message = "plugin error";
584
588
  break;
589
+ case GRN_SCORER_ERROR:
590
+ message = "scorer error";
591
+ break;
585
592
  }
586
593
 
587
594
  if (!message)
@@ -1261,4 +1268,14 @@ rb_grn_init_exception (VALUE mGrn)
1261
1268
  */
1262
1269
  eGrnPluginError =
1263
1270
  rb_define_class_under(mGrn, "PluginError", rb_eGrnError);
1271
+
1272
+ /*
1273
+ * Document-class: Groonga::ScorerError
1274
+ *
1275
+ * It is used when a scorer causes an error.
1276
+ *
1277
+ * @since 5.0.1
1278
+ */
1279
+ eGrnPluginError =
1280
+ rb_define_class_under(mGrn, "ScorerError", rb_eGrnError);
1264
1281
  }
@@ -1,6 +1,6 @@
1
1
  /* -*- coding: utf-8; mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
2
  /*
3
- Copyright (C) 2009-2014 Kouhei Sutou <kou@clear-code.com>
3
+ Copyright (C) 2009-2015 Kouhei Sutou <kou@clear-code.com>
4
4
  Copyright (C) 2014 Masafumi Yokoyama <myokoym@gmail.com>
5
5
 
6
6
  This library is free software; you can redistribute it and/or
@@ -107,6 +107,45 @@ rb_grn_expression_initialize (int argc, VALUE *argv, VALUE self)
107
107
  return Qnil;
108
108
  }
109
109
 
110
+ static VALUE
111
+ rb_grn_expression_inspect (VALUE self)
112
+ {
113
+ grn_ctx *context = NULL;
114
+ grn_obj *expression;
115
+ grn_obj inspected;
116
+ VALUE rb_inspected;
117
+
118
+ rb_grn_expression_deconstruct(SELF(self), &expression, &context,
119
+ NULL, NULL,
120
+ NULL, NULL, NULL);
121
+
122
+ rb_inspected = rb_str_new_cstr("");
123
+ rb_grn_object_inspect_header(self, rb_inspected);
124
+
125
+ GRN_TEXT_INIT(&inspected, 0);
126
+ grn_inspect(context, &inspected, expression);
127
+ grn_bulk_truncate(context, &inspected, GRN_TEXT_LEN(&inspected) - 2);
128
+ {
129
+ size_t prefix_length;
130
+ const char *content;
131
+ size_t content_length;
132
+
133
+ prefix_length = strlen("#<expr");
134
+ content = GRN_TEXT_VALUE(&inspected) + prefix_length;
135
+ content_length = GRN_TEXT_LEN(&inspected) - prefix_length;
136
+ rb_str_concat(rb_inspected,
137
+ rb_grn_context_rb_string_new(context,
138
+ content,
139
+ content_length));
140
+ }
141
+
142
+ GRN_OBJ_FIN(context, &inspected);
143
+
144
+ rb_grn_object_inspect_footer(self, rb_inspected);
145
+
146
+ return rb_inspected;
147
+ }
148
+
110
149
  /*
111
150
  * _expression_ で使用可能な変数を作成する。
112
151
  *
@@ -436,7 +475,10 @@ rb_grn_expression_parse (int argc, VALUE *argv, VALUE self)
436
475
  if (rc != GRN_SUCCESS) {
437
476
  VALUE related_object;
438
477
 
439
- related_object = rb_ary_new3(2, self, rb_ary_new4(argc, argv));
478
+ related_object =
479
+ rb_ary_new_from_args(2,
480
+ self,
481
+ rb_ary_new_from_values(argc, argv));
440
482
  exception = rb_grn_context_to_exception(context, related_object);
441
483
  }
442
484
  if (default_column_is_created)
@@ -561,43 +603,6 @@ rb_grn_expression_array_reference (VALUE self, VALUE rb_name_or_offset)
561
603
  return GRNVARIABLE2RVAL(context, variable);
562
604
  }
563
605
 
564
- /* REMOVE ME */
565
- grn_rc grn_expr_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *expr);
566
-
567
- /*
568
- * _expression_ の中身を人に見やすい文字列で返す。
569
- *
570
- * @overload inspect
571
- * @return [String]
572
- */
573
- static VALUE
574
- rb_grn_expression_inspect (VALUE self)
575
- {
576
- grn_ctx *context = NULL;
577
- grn_obj inspected;
578
- grn_obj *expression;
579
- VALUE rb_inspected;
580
-
581
- rb_grn_expression_deconstruct(SELF(self), &expression, &context,
582
- NULL, NULL,
583
- NULL, NULL, NULL);
584
-
585
- GRN_TEXT_INIT(&inspected, 0);
586
- GRN_TEXT_PUTS(context, &inspected, "#<Groonga::Expression ");
587
- #ifdef WIN32
588
- GRN_TEXT_PUTS(context, &inspected, "(not supported on Windows)");
589
- #else
590
- grn_expr_inspect(context, &inspected, expression);
591
- #endif
592
- GRN_TEXT_PUTS(context, &inspected, ">");
593
- rb_inspected = rb_grn_context_rb_string_new(context,
594
- GRN_TEXT_VALUE(&inspected),
595
- GRN_TEXT_LEN(&inspected));
596
- GRN_OBJ_FIN(context, &inspected);
597
-
598
- return rb_inspected;
599
- }
600
-
601
606
  /*
602
607
  * _expression_ から {Groonga::Snippet} を生成する。 _tags_ には
603
608
  * キーワードの前後に挿入するタグの配列を以下のような形式で指定
@@ -692,7 +697,7 @@ rb_grn_expression_snippet (int argc, VALUE *argv, VALUE self)
692
697
  }
693
698
 
694
699
  if (TYPE(RARRAY_PTR(rb_tags)[0]) == T_STRING) {
695
- rb_tags = rb_ary_new3(1, rb_tags);
700
+ rb_tags = rb_ary_new_from_args(1, rb_tags);
696
701
  }
697
702
 
698
703
  rb_tag_values = RARRAY_PTR(rb_tags);
@@ -738,7 +743,8 @@ rb_grn_expression_snippet (int argc, VALUE *argv, VALUE self)
738
743
  (const char **)open_tags, open_tag_lengths,
739
744
  (const char **)close_tags, close_tag_lengths,
740
745
  mapping);
741
- related_object = rb_ary_new3(2, self, rb_ary_new4(argc, argv));
746
+ related_object =
747
+ rb_ary_new_from_args(2, self, rb_ary_new_from_values(argc, argv));
742
748
  rb_grn_context_check(context, related_object);
743
749
 
744
750
  return GRNOBJECT2RVAL(Qnil, context, snippet, GRN_TRUE);
@@ -785,6 +791,39 @@ rb_grn_expression_get_keywords (VALUE self)
785
791
  return rb_keywords;
786
792
  }
787
793
 
794
+ /*
795
+ * Estimates the number of matched records when `expression` is
796
+ * executed.
797
+ *
798
+ * Note that the estimated size isn't correct value. It's just
799
+ * estimated size.
800
+ *
801
+ * @example
802
+ * expression.parse("Ruby OR Groonga")
803
+ * expression.estimate_size # => 10
804
+ *
805
+ * @overload estimate_size
806
+ * @return [Integer] the estimated number of matched records when
807
+ * `expression` is executed.
808
+ *
809
+ * @since 5.0.1
810
+ */
811
+ static VALUE
812
+ rb_grn_expression_estimate_size (VALUE self)
813
+ {
814
+ grn_ctx *context = NULL;
815
+ grn_obj *expression;
816
+ unsigned int size;
817
+
818
+ rb_grn_expression_deconstruct(SELF(self), &expression, &context,
819
+ NULL, NULL,
820
+ NULL, NULL, NULL);
821
+
822
+ size = grn_expr_estimate_size(context, expression);
823
+
824
+ return UINT2NUM(size);
825
+ }
826
+
788
827
  void
789
828
  rb_grn_init_expression (VALUE mGrn)
790
829
  {
@@ -793,6 +832,9 @@ rb_grn_init_expression (VALUE mGrn)
793
832
  rb_define_method(rb_cGrnExpression, "initialize",
794
833
  rb_grn_expression_initialize, -1);
795
834
 
835
+ rb_define_method(rb_cGrnExpression, "inspect",
836
+ rb_grn_expression_inspect, 0);
837
+
796
838
  rb_define_method(rb_cGrnExpression, "define_variable",
797
839
  rb_grn_expression_define_variable, -1);
798
840
  rb_define_method(rb_cGrnExpression, "append_object",
@@ -821,6 +863,6 @@ rb_grn_init_expression (VALUE mGrn)
821
863
  rb_define_method(rb_cGrnExpression, "keywords",
822
864
  rb_grn_expression_get_keywords, 0);
823
865
 
824
- rb_define_method(rb_cGrnExpression, "inspect",
825
- rb_grn_expression_inspect, 0);
866
+ rb_define_method(rb_cGrnExpression, "estimate_size",
867
+ rb_grn_expression_estimate_size, 0);
826
868
  }
@@ -0,0 +1,88 @@
1
+ /* -*- coding: utf-8; mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
+ /*
3
+ Copyright (C) 2015 Kouhei Sutou <kou@clear-code.com>
4
+
5
+ This library is free software; you can redistribute it and/or
6
+ modify it under the terms of the GNU Lesser General Public
7
+ License version 2.1 as published by the Free Software Foundation.
8
+
9
+ This library is distributed in the hope that it will be useful,
10
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ Lesser General Public License for more details.
13
+
14
+ You should have received a copy of the GNU Lesser General Public
15
+ License along with this library; if not, write to the Free Software
16
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
+ */
18
+
19
+ #include "rb-grn.h"
20
+
21
+ VALUE rb_cGrnGreaterEqualOperator;
22
+
23
+ /*
24
+ * Executes a greater-or-equal operation.
25
+ *
26
+ * @example Executes greater-or-equal operations with the default context
27
+ * Groonga::Operator::GREATER_EQUAL.exec(1, 1) # => true
28
+ * Groonga::Operator::GREATER_EQUAL.exec(2, 1) # => true
29
+ * Groonga::Operator::GREATER_EQUAL.exec(1, 2) # => false
30
+ *
31
+ * @example Executes greater-or-equal operations with the specified context
32
+ * context = Groonga::Context.new
33
+ * Groonga::Operator::GREATER_EQUAL.exec(1, 1,
34
+ * :context => context) # => true
35
+ * Groonga::Operator::GREATER_EQUAL.exec(2, 1,
36
+ * :context => context) # => true
37
+ * Groonga::Operator::GREATER_EQUAL.exec(1, 2,
38
+ * :context => context) # => false
39
+ *
40
+ * @overload exec(x, y, options={})
41
+ * @param x [::Object] The left hand side value.
42
+ * @param y [::Object] The right hand side value.
43
+ * @param options [::Hash] The options.
44
+ * @option options [Groonga::Context] (Groonga::Context.default)
45
+ * The context to executes the operation.
46
+ * @return [Boolean] `true` if `x` is greater than or equal to`y`,
47
+ * `false` otherwise.
48
+ */
49
+ static VALUE
50
+ rb_grn_greater_equal_operator_exec (int argc, VALUE *argv, VALUE self)
51
+ {
52
+ grn_bool greater_equal;
53
+ VALUE rb_x;
54
+ VALUE rb_y;
55
+ VALUE rb_options;
56
+ VALUE rb_context;
57
+ grn_ctx *context;
58
+ grn_obj x;
59
+ grn_obj y;
60
+
61
+ rb_scan_args(argc, argv, "21", &rb_x, &rb_y, &rb_options);
62
+
63
+ rb_grn_scan_options(rb_options,
64
+ "context", &rb_context,
65
+ NULL);
66
+ context = rb_grn_context_ensure(&rb_context);
67
+
68
+ GRN_VOID_INIT(&x);
69
+ GRN_VOID_INIT(&y);
70
+ RVAL2GRNBULK(rb_x, context, &x);
71
+ RVAL2GRNBULK(rb_y, context, &y);
72
+ greater_equal = grn_operator_exec_greater_equal(context, &x, &y);
73
+ GRN_OBJ_FIN(context, &x);
74
+ GRN_OBJ_FIN(context, &y);
75
+
76
+ return CBOOL2RVAL(greater_equal);
77
+ }
78
+
79
+ void
80
+ rb_grn_init_greater_equal_operator (VALUE mGrn)
81
+ {
82
+ rb_cGrnGreaterEqualOperator = rb_define_class_under(mGrn,
83
+ "GreaterEqualOperator",
84
+ rb_cGrnOperator);
85
+
86
+ rb_define_method(rb_cGrnGreaterEqualOperator, "exec",
87
+ rb_grn_greater_equal_operator_exec, -1);
88
+ }
@@ -0,0 +1,85 @@
1
+ /* -*- coding: utf-8; mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
+ /*
3
+ Copyright (C) 2015 Kouhei Sutou <kou@clear-code.com>
4
+
5
+ This library is free software; you can redistribute it and/or
6
+ modify it under the terms of the GNU Lesser General Public
7
+ License version 2.1 as published by the Free Software Foundation.
8
+
9
+ This library is distributed in the hope that it will be useful,
10
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ Lesser General Public License for more details.
13
+
14
+ You should have received a copy of the GNU Lesser General Public
15
+ License along with this library; if not, write to the Free Software
16
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
+ */
18
+
19
+ #include "rb-grn.h"
20
+
21
+ VALUE rb_cGrnGreaterOperator;
22
+
23
+ /*
24
+ * Executes a greater operation.
25
+ *
26
+ * @example Executes greater operations with the default context
27
+ * Groonga::Operator::GREATER.exec(2, 1) # => true
28
+ * Groonga::Operator::GREATER.exec(1, 2) # => false
29
+ *
30
+ * @example Executes greater operations with the specified context
31
+ * context = Groonga::Context.new
32
+ * Groonga::Operator::GREATER.exec(2, 1,
33
+ * :context => context) # => true
34
+ * Groonga::Operator::GREATER.exec(1, 2,
35
+ * :context => context) # => false
36
+ *
37
+ * @overload exec(x, y, options={})
38
+ * @param x [::Object] The left hand side value.
39
+ * @param y [::Object] The right hand side value.
40
+ * @param options [::Hash] The options.
41
+ * @option options [Groonga::Context] (Groonga::Context.default)
42
+ * The context to executes the operation.
43
+ * @return [Boolean] `true` if `x` is greater than `y`, `false`
44
+ * otherwise.
45
+ */
46
+ static VALUE
47
+ rb_grn_greater_operator_exec (int argc, VALUE *argv, VALUE self)
48
+ {
49
+ grn_bool greater;
50
+ VALUE rb_x;
51
+ VALUE rb_y;
52
+ VALUE rb_options;
53
+ VALUE rb_context;
54
+ grn_ctx *context;
55
+ grn_obj x;
56
+ grn_obj y;
57
+
58
+ rb_scan_args(argc, argv, "21", &rb_x, &rb_y, &rb_options);
59
+
60
+ rb_grn_scan_options(rb_options,
61
+ "context", &rb_context,
62
+ NULL);
63
+ context = rb_grn_context_ensure(&rb_context);
64
+
65
+ GRN_VOID_INIT(&x);
66
+ GRN_VOID_INIT(&y);
67
+ RVAL2GRNBULK(rb_x, context, &x);
68
+ RVAL2GRNBULK(rb_y, context, &y);
69
+ greater = grn_operator_exec_greater(context, &x, &y);
70
+ GRN_OBJ_FIN(context, &x);
71
+ GRN_OBJ_FIN(context, &y);
72
+
73
+ return CBOOL2RVAL(greater);
74
+ }
75
+
76
+ void
77
+ rb_grn_init_greater_operator (VALUE mGrn)
78
+ {
79
+ rb_cGrnGreaterOperator = rb_define_class_under(mGrn,
80
+ "GreaterOperator",
81
+ rb_cGrnOperator);
82
+
83
+ rb_define_method(rb_cGrnGreaterOperator, "exec",
84
+ rb_grn_greater_operator_exec, -1);
85
+ }
@@ -216,7 +216,7 @@ rb_grn_hash_s_create (int argc, VALUE *argv, VALUE klass)
216
216
  table = grn_table_create(context, name, name_size, path,
217
217
  flags, key_type, value_type);
218
218
  if (!table)
219
- rb_grn_context_check(context, rb_ary_new4(argc, argv));
219
+ rb_grn_context_check(context, rb_ary_new_from_values(argc, argv));
220
220
  rb_table = GRNOBJECT2RVAL(klass, context, table, GRN_TRUE);
221
221
 
222
222
  if (!NIL_P(rb_default_tokenizer))
@@ -1,6 +1,6 @@
1
1
  /* -*- coding: utf-8; mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
2
  /*
3
- Copyright (C) 2009-2014 Kouhei Sutou <kou@clear-code.com>
3
+ Copyright (C) 2009-2015 Kouhei Sutou <kou@clear-code.com>
4
4
 
5
5
  This library is free software; you can redistribute it and/or
6
6
  modify it under the terms of the GNU Lesser General Public
@@ -181,7 +181,7 @@ rb_grn_index_column_inspect (VALUE self)
181
181
  {
182
182
  VALUE inspected;
183
183
 
184
- inspected = rb_str_new2("");
184
+ inspected = rb_str_new_cstr("");
185
185
  rb_grn_object_inspect_header(self, inspected);
186
186
  rb_grn_object_inspect_content(self, inspected);
187
187
  rb_grn_index_column_inspect_content(self, inspected);
@@ -588,7 +588,7 @@ resolve_source_id (grn_ctx *context, grn_obj *column, grn_id range_id,
588
588
  {
589
589
  grn_id source_id;
590
590
 
591
- if (CBOOL2RVAL(rb_obj_is_kind_of(rb_source, rb_cInteger))) {
591
+ if (RVAL2CBOOL(rb_obj_is_kind_of(rb_source, rb_cInteger))) {
592
592
  source_id = NUM2UINT(rb_source);
593
593
  } else {
594
594
  grn_obj *source;
@@ -709,7 +709,7 @@ static VALUE
709
709
  rb_grn_index_column_set_source (VALUE self, VALUE rb_source)
710
710
  {
711
711
  if (!RVAL2CBOOL(rb_obj_is_kind_of(rb_source, rb_cArray)))
712
- rb_source = rb_ary_new3(1, rb_source);
712
+ rb_source = rb_ary_new_from_args(1, rb_source);
713
713
 
714
714
  return rb_grn_index_column_set_sources(self, rb_source);
715
715
  }
@@ -796,6 +796,7 @@ rb_grn_index_column_search (int argc, VALUE *argv, VALUE self)
796
796
 
797
797
  operator = RVAL2GRNOPERATOR(rb_operator);
798
798
 
799
+ memset(&options, 0, sizeof(grn_search_optarg));
799
800
  if (NIL_P(rb_mode)) {
800
801
  options.mode = GRN_OP_EXACT;
801
802
  } else {
@@ -956,7 +957,8 @@ rb_grn_index_column_open_cursor (int argc, VALUE *argv, VALUE self)
956
957
  }
957
958
 
958
959
  /*
959
- * Estimates the number of documents found by the given token ID.
960
+ * Estimates the number of documents found by the given token ID,
961
+ * query or lexicon cursor.
960
962
  *
961
963
  * @example Token ID style
962
964
  * # Define schema
@@ -1020,21 +1022,109 @@ rb_grn_index_column_open_cursor (int argc, VALUE *argv, VALUE self)
1020
1022
  * p @index.estimate_size(@terms["fast"]) # => 7
1021
1023
  * p @index.estimate_size(@terms["Groonga"]) # => 1
1022
1024
  *
1025
+ * @example Query style
1026
+ * # Define schema
1027
+ * Groonga::Schema.define do |schema|
1028
+ * schema.create_table("Articles") do |table|
1029
+ * table.text("content")
1030
+ * end
1031
+ *
1032
+ * schema.create_table("Terms",
1033
+ * :type => :hash,
1034
+ * :key_type => "ShortText",
1035
+ * :default_tokenizer => "TokenBigramSplitSymbolAlpha",
1036
+ * :normalizer => "NormalizerAuto") do |table|
1037
+ * table.index("Articles.content",
1038
+ * :name => "articles_content",
1039
+ * :with_position => true,
1040
+ * :with_section => true)
1041
+ * end
1042
+ * end
1043
+ * articles = Groonga["Articles"]
1044
+ * index = Groonga["Terms.articles_content"]
1045
+ *
1046
+ * # Add data
1047
+ * articles.add(:content => "Groonga is fast")
1048
+ * articles.add(:content => "Rroonga is fast")
1049
+ * articles.add(:content => "Mroonga is fast")
1050
+ *
1051
+ * # Estimate the number of documents found by query
1052
+ * p @index.estimate_size("roonga") # => 6
1053
+ *
1054
+ * @example Lexicon cursor style
1055
+ * # Define schema
1056
+ * Groonga::Schema.define do |schema|
1057
+ * schema.create_table("Memos",
1058
+ * :type => :hash,
1059
+ * :key_type => "ShortText") do |table|
1060
+ * table.short_text("tags", :type => :vector)
1061
+ * end
1062
+ *
1063
+ * schema.create_table("Tags",
1064
+ * :type => :patricia_trie,
1065
+ * :key_type => "ShortText") do |table|
1066
+ * table.index("Memos.tags",
1067
+ * :name => "memos_tags")
1068
+ * end
1069
+ * end
1070
+ * memos = Groonga["Memos"]
1071
+ * tags = Groonga["Tags"]
1072
+ * index = Groonga["Tags.memos_tags"]
1073
+ *
1074
+ * # Add data
1075
+ * memos.add(:tags => ["Groonga"])
1076
+ * memos.add(:tags => ["Rroonga", "Ruby"])
1077
+ * memos.add(:tags => ["grndump", "Rroonga"])
1078
+ *
1079
+ * # Estimate the number of documents found by lexicon cursor
1080
+ * # Iterates tags that start with "R".
1081
+ * tags.open_prefix_cursor("R") do |cursor|
1082
+ * # The cursor iterates "Rroonga" and "Ruby".
1083
+ * p index.estimate_size(cursor) # => 6
1084
+ * end
1085
+ *
1023
1086
  * @overload estimate_size(token_id)
1024
- * @param [Integer, Record] token_id The token ID to be estimated.
1087
+ * @param token_id [Integer, Record] The token ID to be estimated.
1025
1088
  * @return [Integer] The estimated number of documents found by the
1026
1089
  * given token ID.
1027
1090
  *
1091
+ * @overload estimate_size(query, options={})
1092
+ * @param query [String] The query to be estimated.
1093
+ * @param options [::Hash] The options.
1094
+ * @option options [Groonga::Operator, String, Symbol] :mode
1095
+ * (Groonga::Operator::EXACT)
1096
+ *
1097
+ * The operation mode for search. It must be one of the followings:
1098
+ *
1099
+ * * `Groonga::Operator::EXACT`, `"exact"`, `:exact`
1100
+ * * `Groonga::Operator::NEAR`, `"near"`, `:near`
1101
+ * * `Groonga::Operator::NEAR2`, `"near2"`, `:near2`
1102
+ * * `Groonga::Operator::SIMILAR`, `"similar"`, `:similar`
1103
+ * * `Groonga::Operator::REGEXP`, `"regexp"`, `:regexp`
1104
+ *
1105
+ * @return [Integer] The estimated number of documents found by the
1106
+ * given query.
1107
+ *
1108
+ * @since 5.0.1
1109
+ *
1110
+ * @overload estimate_size(lexicon_cursor)
1111
+ * @param lexicon_cursor [Groonga::TableCursor] The cursor for lexicon.
1112
+ * @return [Integer] The estimated number of documents found by term IDS
1113
+ * in the given lexicon cursor.
1114
+ *
1115
+ * @since 5.0.1
1116
+ *
1028
1117
  * @since 4.0.7
1029
1118
  */
1030
1119
  static VALUE
1031
- rb_grn_index_column_estimate_size (VALUE self, VALUE rb_token_id)
1120
+ rb_grn_index_column_estimate_size (int argc, VALUE *argv, VALUE self)
1032
1121
  {
1033
1122
  grn_ctx *context;
1034
1123
  grn_obj *column;
1035
1124
  grn_obj *domain_object;
1036
- grn_id token_id;
1037
1125
  unsigned int size;
1126
+ VALUE rb_target;
1127
+ VALUE rb_options;
1038
1128
 
1039
1129
  rb_grn_index_column_deconstruct(SELF(self), &column, &context,
1040
1130
  NULL, &domain_object,
@@ -1042,8 +1132,57 @@ rb_grn_index_column_estimate_size (VALUE self, VALUE rb_token_id)
1042
1132
  NULL, NULL,
1043
1133
  NULL, NULL);
1044
1134
 
1045
- token_id = RVAL2GRNID(rb_token_id, context, domain_object, self);
1046
- size = grn_ii_estimate_size(context, (grn_ii *)column, token_id);
1135
+ rb_scan_args(argc, argv, "11", &rb_target, &rb_options);
1136
+
1137
+ if (TYPE(rb_target) == T_STRING) {
1138
+ const char *query;
1139
+ unsigned int query_length;
1140
+ grn_search_optarg options;
1141
+ VALUE rb_mode;
1142
+
1143
+ query = StringValueCStr(rb_target);
1144
+ query_length = RSTRING_LEN(rb_target);
1145
+
1146
+ rb_grn_scan_options(rb_options,
1147
+ "mode", &rb_mode,
1148
+ NULL);
1149
+
1150
+ memset(&options, 0, sizeof(grn_search_optarg));
1151
+ if (NIL_P(rb_mode)) {
1152
+ options.mode = GRN_OP_EXACT;
1153
+ } else {
1154
+ options.mode = RVAL2GRNOPERATOR(rb_mode);
1155
+ }
1156
+ switch (options.mode) {
1157
+ case GRN_OP_EXACT:
1158
+ case GRN_OP_NEAR:
1159
+ case GRN_OP_NEAR2:
1160
+ case GRN_OP_SIMILAR:
1161
+ case GRN_OP_REGEXP:
1162
+ /* valid */
1163
+ break;
1164
+ default:
1165
+ rb_raise(rb_eArgError,
1166
+ ":mode must be one of "
1167
+ "nil, :exact, :near, :near2, :similar or :regexp: <%s>",
1168
+ rb_grn_inspect(rb_mode));
1169
+ break;
1170
+ }
1171
+
1172
+ size = grn_ii_estimate_size_for_query(context, (grn_ii *)column,
1173
+ query, query_length, &options);
1174
+ } else if (RVAL2CBOOL(rb_obj_is_kind_of(rb_target, rb_cGrnTableCursor))) {
1175
+ grn_table_cursor *lexicon_cursor;
1176
+
1177
+ lexicon_cursor = RVAL2GRNTABLECURSOR(rb_target, &context);
1178
+ size = grn_ii_estimate_size_for_lexicon_cursor(context,
1179
+ (grn_ii *)column,
1180
+ lexicon_cursor);
1181
+ } else {
1182
+ grn_id token_id;
1183
+ token_id = RVAL2GRNID(rb_target, context, domain_object, self);
1184
+ size = grn_ii_estimate_size(context, (grn_ii *)column, token_id);
1185
+ }
1047
1186
 
1048
1187
  return UINT2NUM(size);
1049
1188
  }
@@ -1085,5 +1224,5 @@ rb_grn_init_index_column (VALUE mGrn)
1085
1224
  rb_grn_index_column_open_cursor, -1);
1086
1225
 
1087
1226
  rb_define_method(rb_cGrnIndexColumn, "estimate_size",
1088
- rb_grn_index_column_estimate_size, 1);
1227
+ rb_grn_index_column_estimate_size, -1);
1089
1228
  }