rroonga 0.9.2-mswin32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (202) hide show
  1. data/AUTHORS +5 -0
  2. data/NEWS.ja.rdoc +114 -0
  3. data/NEWS.rdoc +116 -0
  4. data/README.ja.rdoc +65 -0
  5. data/README.rdoc +66 -0
  6. data/Rakefile +217 -0
  7. data/benchmark/common.rb +49 -0
  8. data/benchmark/read-write-many-small-items.rb +144 -0
  9. data/benchmark/write-many-small-items.rb +135 -0
  10. data/example/bookmark.rb +161 -0
  11. data/example/index-html.rb +89 -0
  12. data/example/search/config.ru +211 -0
  13. data/example/search/public/css/groonga.css +122 -0
  14. data/ext/.gitignore +2 -0
  15. data/ext/libruby-groonga.a +0 -0
  16. data/ext/rb-grn-accessor.c +52 -0
  17. data/ext/rb-grn-array-cursor.c +36 -0
  18. data/ext/rb-grn-array.c +210 -0
  19. data/ext/rb-grn-column.c +573 -0
  20. data/ext/rb-grn-context.c +655 -0
  21. data/ext/rb-grn-database.c +472 -0
  22. data/ext/rb-grn-encoding-support.c +64 -0
  23. data/ext/rb-grn-encoding.c +257 -0
  24. data/ext/rb-grn-exception.c +1110 -0
  25. data/ext/rb-grn-expression-builder.c +75 -0
  26. data/ext/rb-grn-expression.c +735 -0
  27. data/ext/rb-grn-fix-size-column.c +166 -0
  28. data/ext/rb-grn-hash-cursor.c +38 -0
  29. data/ext/rb-grn-hash.c +294 -0
  30. data/ext/rb-grn-index-column.c +488 -0
  31. data/ext/rb-grn-logger.c +504 -0
  32. data/ext/rb-grn-object.c +1369 -0
  33. data/ext/rb-grn-operation.c +198 -0
  34. data/ext/rb-grn-patricia-trie-cursor.c +39 -0
  35. data/ext/rb-grn-patricia-trie.c +488 -0
  36. data/ext/rb-grn-procedure.c +52 -0
  37. data/ext/rb-grn-query.c +260 -0
  38. data/ext/rb-grn-record.c +40 -0
  39. data/ext/rb-grn-snippet.c +334 -0
  40. data/ext/rb-grn-table-cursor-key-support.c +69 -0
  41. data/ext/rb-grn-table-cursor.c +247 -0
  42. data/ext/rb-grn-table-key-support.c +731 -0
  43. data/ext/rb-grn-table.c +2141 -0
  44. data/ext/rb-grn-type.c +181 -0
  45. data/ext/rb-grn-utils.c +769 -0
  46. data/ext/rb-grn-variable-size-column.c +36 -0
  47. data/ext/rb-grn-variable.c +108 -0
  48. data/ext/rb-grn-view-accessor.c +53 -0
  49. data/ext/rb-grn-view-cursor.c +35 -0
  50. data/ext/rb-grn-view-record.c +41 -0
  51. data/ext/rb-grn-view.c +421 -0
  52. data/ext/rb-grn.h +700 -0
  53. data/ext/rb-groonga.c +117 -0
  54. data/extconf.rb +266 -0
  55. data/html/bar.svg +153 -0
  56. data/html/developer.html +117 -0
  57. data/html/developer.svg +469 -0
  58. data/html/download.svg +253 -0
  59. data/html/favicon.ico +0 -0
  60. data/html/favicon.xcf +0 -0
  61. data/html/footer.html.erb +28 -0
  62. data/html/head.html.erb +4 -0
  63. data/html/header.html.erb +17 -0
  64. data/html/index.html +147 -0
  65. data/html/install.svg +636 -0
  66. data/html/logo.xcf +0 -0
  67. data/html/ranguba.css +250 -0
  68. data/html/tutorial.svg +559 -0
  69. data/lib/groonga.rb +90 -0
  70. data/lib/groonga/context.rb +184 -0
  71. data/lib/groonga/expression-builder.rb +285 -0
  72. data/lib/groonga/patricia-trie.rb +53 -0
  73. data/lib/groonga/record.rb +311 -0
  74. data/lib/groonga/schema.rb +1191 -0
  75. data/lib/groonga/view-record.rb +56 -0
  76. data/license/GPL +340 -0
  77. data/license/LGPL +504 -0
  78. data/license/RUBY +59 -0
  79. data/misc/grnop2ruby.rb +49 -0
  80. data/pkg-config.rb +333 -0
  81. data/test-unit/Rakefile +40 -0
  82. data/test-unit/TODO +5 -0
  83. data/test-unit/bin/testrb +5 -0
  84. data/test-unit/html/classic.html +15 -0
  85. data/test-unit/html/index.html +25 -0
  86. data/test-unit/html/index.html.ja +27 -0
  87. data/test-unit/lib/test/unit.rb +323 -0
  88. data/test-unit/lib/test/unit/assertionfailederror.rb +25 -0
  89. data/test-unit/lib/test/unit/assertions.rb +1230 -0
  90. data/test-unit/lib/test/unit/attribute.rb +125 -0
  91. data/test-unit/lib/test/unit/autorunner.rb +360 -0
  92. data/test-unit/lib/test/unit/collector.rb +36 -0
  93. data/test-unit/lib/test/unit/collector/descendant.rb +23 -0
  94. data/test-unit/lib/test/unit/collector/dir.rb +108 -0
  95. data/test-unit/lib/test/unit/collector/load.rb +136 -0
  96. data/test-unit/lib/test/unit/collector/objectspace.rb +34 -0
  97. data/test-unit/lib/test/unit/color-scheme.rb +102 -0
  98. data/test-unit/lib/test/unit/color.rb +96 -0
  99. data/test-unit/lib/test/unit/diff.rb +724 -0
  100. data/test-unit/lib/test/unit/error.rb +130 -0
  101. data/test-unit/lib/test/unit/exceptionhandler.rb +39 -0
  102. data/test-unit/lib/test/unit/failure.rb +136 -0
  103. data/test-unit/lib/test/unit/fixture.rb +176 -0
  104. data/test-unit/lib/test/unit/notification.rb +129 -0
  105. data/test-unit/lib/test/unit/omission.rb +191 -0
  106. data/test-unit/lib/test/unit/pending.rb +150 -0
  107. data/test-unit/lib/test/unit/priority.rb +180 -0
  108. data/test-unit/lib/test/unit/runner/console.rb +52 -0
  109. data/test-unit/lib/test/unit/runner/emacs.rb +8 -0
  110. data/test-unit/lib/test/unit/runner/tap.rb +8 -0
  111. data/test-unit/lib/test/unit/testcase.rb +476 -0
  112. data/test-unit/lib/test/unit/testresult.rb +89 -0
  113. data/test-unit/lib/test/unit/testsuite.rb +110 -0
  114. data/test-unit/lib/test/unit/ui/console/outputlevel.rb +14 -0
  115. data/test-unit/lib/test/unit/ui/console/testrunner.rb +466 -0
  116. data/test-unit/lib/test/unit/ui/emacs/testrunner.rb +63 -0
  117. data/test-unit/lib/test/unit/ui/tap/testrunner.rb +92 -0
  118. data/test-unit/lib/test/unit/ui/testrunner.rb +28 -0
  119. data/test-unit/lib/test/unit/ui/testrunnermediator.rb +77 -0
  120. data/test-unit/lib/test/unit/ui/testrunnerutilities.rb +41 -0
  121. data/test-unit/lib/test/unit/util/backtracefilter.rb +41 -0
  122. data/test-unit/lib/test/unit/util/method-owner-finder.rb +28 -0
  123. data/test-unit/lib/test/unit/util/observable.rb +90 -0
  124. data/test-unit/lib/test/unit/util/procwrapper.rb +48 -0
  125. data/test-unit/lib/test/unit/version.rb +7 -0
  126. data/test-unit/sample/adder.rb +13 -0
  127. data/test-unit/sample/subtracter.rb +12 -0
  128. data/test-unit/sample/test_adder.rb +20 -0
  129. data/test-unit/sample/test_subtracter.rb +20 -0
  130. data/test-unit/sample/test_user.rb +23 -0
  131. data/test-unit/test/collector/test-descendant.rb +133 -0
  132. data/test-unit/test/collector/test-load.rb +348 -0
  133. data/test-unit/test/collector/test_dir.rb +406 -0
  134. data/test-unit/test/collector/test_objectspace.rb +100 -0
  135. data/test-unit/test/run-test.rb +15 -0
  136. data/test-unit/test/test-attribute.rb +86 -0
  137. data/test-unit/test/test-color-scheme.rb +67 -0
  138. data/test-unit/test/test-color.rb +47 -0
  139. data/test-unit/test/test-diff.rb +518 -0
  140. data/test-unit/test/test-emacs-runner.rb +60 -0
  141. data/test-unit/test/test-fixture.rb +287 -0
  142. data/test-unit/test/test-notification.rb +33 -0
  143. data/test-unit/test/test-omission.rb +81 -0
  144. data/test-unit/test/test-pending.rb +70 -0
  145. data/test-unit/test/test-priority.rb +119 -0
  146. data/test-unit/test/test-testcase.rb +544 -0
  147. data/test-unit/test/test_assertions.rb +1151 -0
  148. data/test-unit/test/test_error.rb +26 -0
  149. data/test-unit/test/test_failure.rb +33 -0
  150. data/test-unit/test/test_testresult.rb +113 -0
  151. data/test-unit/test/test_testsuite.rb +129 -0
  152. data/test-unit/test/testunit-test-util.rb +14 -0
  153. data/test-unit/test/ui/test_testrunmediator.rb +20 -0
  154. data/test-unit/test/util/test-method-owner-finder.rb +38 -0
  155. data/test-unit/test/util/test_backtracefilter.rb +41 -0
  156. data/test-unit/test/util/test_observable.rb +102 -0
  157. data/test-unit/test/util/test_procwrapper.rb +36 -0
  158. data/test/.gitignore +1 -0
  159. data/test/groonga-test-utils.rb +133 -0
  160. data/test/run-test.rb +58 -0
  161. data/test/test-array.rb +97 -0
  162. data/test/test-column.rb +316 -0
  163. data/test/test-context-select.rb +93 -0
  164. data/test/test-context.rb +73 -0
  165. data/test/test-database.rb +113 -0
  166. data/test/test-encoding.rb +33 -0
  167. data/test/test-exception.rb +93 -0
  168. data/test/test-expression-builder.rb +156 -0
  169. data/test/test-expression.rb +134 -0
  170. data/test/test-fix-size-column.rb +65 -0
  171. data/test/test-gqtp.rb +72 -0
  172. data/test/test-hash.rb +312 -0
  173. data/test/test-index-column.rb +81 -0
  174. data/test/test-logger.rb +37 -0
  175. data/test/test-patricia-trie.rb +189 -0
  176. data/test/test-procedure.rb +37 -0
  177. data/test/test-query.rb +22 -0
  178. data/test/test-record.rb +279 -0
  179. data/test/test-remote.rb +54 -0
  180. data/test/test-schema-view.rb +90 -0
  181. data/test/test-schema.rb +459 -0
  182. data/test/test-snippet.rb +130 -0
  183. data/test/test-table-cursor.rb +153 -0
  184. data/test/test-table-offset-and-limit.rb +102 -0
  185. data/test/test-table-select-normalize.rb +53 -0
  186. data/test/test-table-select.rb +150 -0
  187. data/test/test-table.rb +690 -0
  188. data/test/test-type.rb +71 -0
  189. data/test/test-variable-size-column.rb +98 -0
  190. data/test/test-variable.rb +28 -0
  191. data/test/test-vector-column.rb +76 -0
  192. data/test/test-version.rb +31 -0
  193. data/test/test-view.rb +72 -0
  194. data/text/TUTORIAL.ja.rdoc +392 -0
  195. data/text/expression.rdoc +284 -0
  196. data/vendor/local/bin/grntest.exe +0 -0
  197. data/vendor/local/bin/groonga.exe +0 -0
  198. data/vendor/local/bin/libgroonga.dll +0 -0
  199. data/vendor/local/bin/libmecab.dll +0 -0
  200. data/vendor/local/include/groonga.h +2285 -0
  201. data/vendor/local/lib/libgroonga.lib +0 -0
  202. metadata +280 -0
@@ -0,0 +1,75 @@
1
+ /* -*- c-file-style: "ruby" -*- */
2
+ /*
3
+ Copyright (C) 2009 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
+ */
18
+
19
+ #include "rb-grn.h"
20
+
21
+ VALUE rb_cGrnRecordExpressionBuilder;
22
+ VALUE rb_cGrnColumnExpressionBuilder;
23
+
24
+ VALUE
25
+ rb_grn_record_expression_builder_new (VALUE table, VALUE name)
26
+ {
27
+ return rb_funcall(rb_cGrnRecordExpressionBuilder,
28
+ rb_intern("new"), 2, table, name);
29
+ }
30
+
31
+ VALUE
32
+ rb_grn_column_expression_builder_new (VALUE column, VALUE name, VALUE query)
33
+ {
34
+ return rb_funcall(rb_cGrnColumnExpressionBuilder,
35
+ rb_intern("new"), 3, column, name, query);
36
+ }
37
+
38
+ static VALUE
39
+ build (VALUE self)
40
+ {
41
+ return rb_funcall(self, rb_intern("build"), 0);
42
+ }
43
+
44
+ static VALUE
45
+ build_block (VALUE self)
46
+ {
47
+ return rb_funcall(rb_block_proc(), rb_intern("call"), 1, self);
48
+ }
49
+
50
+ VALUE
51
+ rb_grn_record_expression_builder_build (VALUE self)
52
+ {
53
+ if (rb_block_given_p())
54
+ return rb_iterate(build, self, build_block, self);
55
+ else
56
+ return build(self);
57
+ }
58
+
59
+ VALUE
60
+ rb_grn_column_expression_builder_build (VALUE self)
61
+ {
62
+ if (rb_block_given_p())
63
+ return rb_iterate(build, self, build_block, self);
64
+ else
65
+ return build(self);
66
+ }
67
+
68
+ void
69
+ rb_grn_init_expression_builder (VALUE mGrn)
70
+ {
71
+ rb_cGrnRecordExpressionBuilder =
72
+ rb_const_get(mGrn, rb_intern("RecordExpressionBuilder"));
73
+ rb_cGrnColumnExpressionBuilder =
74
+ rb_const_get(mGrn, rb_intern("ColumnExpressionBuilder"));
75
+ }
@@ -0,0 +1,735 @@
1
+ /* -*- c-file-style: "ruby" -*- */
2
+ /*
3
+ Copyright (C) 2009-2010 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
+ */
18
+
19
+ #include "rb-grn.h"
20
+
21
+ #define SELF(object) ((RbGrnExpression *)DATA_PTR(object))
22
+
23
+ VALUE rb_cGrnExpression;
24
+
25
+ /*
26
+ * Document-class: Groonga::Expression < Groonga::Object
27
+ *
28
+ * 検索条件やデータベースへの操作を表現するオブジェクト。
29
+ *
30
+ */
31
+
32
+ void
33
+ rb_grn_expression_finalizer (grn_ctx *context, grn_obj *object,
34
+ RbGrnExpression *rb_grn_expression)
35
+ {
36
+ if (context && rb_grn_expression->value)
37
+ grn_obj_unlink(context, rb_grn_expression->value);
38
+
39
+ rb_grn_expression->value = NULL;
40
+ }
41
+
42
+ void
43
+ rb_grn_expression_bind (RbGrnExpression *rb_grn_expression,
44
+ grn_ctx *context, grn_obj *expression)
45
+ {
46
+ RbGrnObject *rb_grn_object;
47
+
48
+ rb_grn_object = RB_GRN_OBJECT(rb_grn_expression);
49
+
50
+ rb_grn_expression->value = grn_obj_open(context, GRN_BULK, 0,
51
+ rb_grn_object->range_id);
52
+ }
53
+
54
+ void
55
+ rb_grn_expression_deconstruct (RbGrnExpression *rb_grn_expression,
56
+ grn_obj **expression,
57
+ grn_ctx **context,
58
+ grn_id *domain_id,
59
+ grn_obj **domain,
60
+ grn_obj **value,
61
+ grn_id *range_id,
62
+ grn_obj **range)
63
+ {
64
+ RbGrnObject *rb_grn_object;
65
+
66
+ rb_grn_object = RB_GRN_OBJECT(rb_grn_expression);
67
+ rb_grn_object_deconstruct(rb_grn_object, expression, context,
68
+ domain_id, domain,
69
+ range_id, range);
70
+
71
+ if (value)
72
+ *value = rb_grn_expression->value;
73
+ }
74
+
75
+ static VALUE
76
+ rb_grn_expression_initialize (int argc, VALUE *argv, VALUE self)
77
+ {
78
+ grn_ctx *context = NULL;
79
+ grn_obj *expression;
80
+ VALUE options, rb_context, rb_name;
81
+ char *name = NULL;
82
+ unsigned name_size = 0;
83
+
84
+ rb_scan_args(argc, argv, "01", &options);
85
+ rb_grn_scan_options(options,
86
+ "context", &rb_context,
87
+ "name", &rb_name,
88
+ NULL);
89
+
90
+ context = rb_grn_context_ensure(&rb_context);
91
+
92
+ if (!NIL_P(rb_name)) {
93
+ name = StringValuePtr(rb_name);
94
+ name_size = RSTRING_LEN(rb_name);
95
+ }
96
+
97
+ expression = grn_expr_create(context, name, name_size);
98
+ rb_grn_object_assign(Qnil, self, rb_context, context, expression);
99
+ rb_grn_context_check(context, self);
100
+
101
+ return Qnil;
102
+ }
103
+
104
+ /*
105
+ * call-seq:
106
+ * expression.define_variable(options={}) -> Groonga::Variable
107
+ *
108
+ * _expression_で使用可能な変数を作成する。
109
+ *
110
+ * _options_に指定可能な値は以下の通り。
111
+ *
112
+ * [+:name+]
113
+ * 変数の名前。省略した場合は名前を付けない。
114
+ *
115
+ * [+:domain+]
116
+ * テーブルを指定すると、そのテーブル用のレコードとして初期化する。
117
+ */
118
+ static VALUE
119
+ rb_grn_expression_define_variable (int argc, VALUE *argv, VALUE self)
120
+ {
121
+ grn_ctx *context = NULL;
122
+ grn_obj *expression, *variable;
123
+ char *name = NULL;
124
+ unsigned name_size = 0;
125
+ VALUE options, rb_name, rb_domain, rb_variable;
126
+
127
+ rb_scan_args(argc, argv, "01", &options);
128
+
129
+ rb_grn_expression_deconstruct(SELF(self), &expression, &context,
130
+ NULL, NULL,
131
+ NULL, NULL, NULL);
132
+
133
+ rb_grn_scan_options(options,
134
+ "name", &rb_name,
135
+ "domain", &rb_domain,
136
+ NULL);
137
+
138
+ if (!NIL_P(rb_name)) {
139
+ name = StringValuePtr(rb_name);
140
+ name_size = RSTRING_LEN(rb_name);
141
+ }
142
+
143
+ variable = grn_expr_add_var(context, expression, name, name_size);
144
+ rb_variable = GRNVARIABLE2RVAL(context, variable);
145
+
146
+ if (RVAL2CBOOL(rb_obj_is_kind_of(rb_domain, rb_cGrnTable))) {
147
+ grn_id domain_id;
148
+ domain_id = NUM2UINT(rb_funcall(rb_domain, rb_intern("id"), 0));
149
+ GRN_RECORD_INIT(variable, 0, domain_id);
150
+ }
151
+
152
+ return rb_variable;
153
+ }
154
+
155
+ /*
156
+ * call-seq:
157
+ * expression.append_object(object,
158
+ * operation=Groonga::Operation::PUSH,
159
+ * n_arguments=1) -> self
160
+ *
161
+ * _object_を追加し、_n_arguments_個の引数を取る_operation_を追加する。
162
+ */
163
+ static VALUE
164
+ rb_grn_expression_append_object (int argc, VALUE *argv, VALUE self)
165
+ {
166
+ VALUE rb_object, rb_operation, rb_n_arguments;
167
+ grn_ctx *context = NULL;
168
+ grn_obj *expression, *object;
169
+ grn_operator operation = GRN_OP_PUSH;
170
+ int n_arguments = 1;
171
+
172
+ rb_scan_args(argc, argv, "12", &rb_object, &rb_operation, &rb_n_arguments);
173
+ if (!NIL_P(rb_operation))
174
+ operation = NUM2INT(rb_operation);
175
+ if (!NIL_P(rb_n_arguments))
176
+ n_arguments = NUM2INT(rb_n_arguments);
177
+
178
+ rb_grn_expression_deconstruct(SELF(self), &expression, &context,
179
+ NULL, NULL,
180
+ NULL, NULL, NULL);
181
+
182
+ object = RVAL2GRNOBJECT(rb_object, &context);
183
+ grn_expr_append_obj(context, expression, object,
184
+ operation, n_arguments);
185
+ rb_grn_context_check(context, self);
186
+ return self;
187
+ }
188
+
189
+ /*
190
+ * call-seq:
191
+ * expression.append_constant(constant,
192
+ * operation=Groonga::Operation::PUSH,
193
+ * n_arguments=1) -> self
194
+ *
195
+ * _constant_を追加し、_n_arguments_個の引数を取る_operation_を追加する。
196
+ */
197
+ static VALUE
198
+ rb_grn_expression_append_constant (int argc, VALUE *argv, VALUE self)
199
+ {
200
+ VALUE rb_constant, rb_operator, rb_n_arguments;
201
+ VALUE exception;
202
+ grn_ctx *context = NULL;
203
+ grn_obj *expression, *constant = NULL;
204
+ grn_operator operator = GRN_OP_PUSH;
205
+ int n_arguments = 1;
206
+
207
+ rb_scan_args(argc, argv, "12", &rb_constant, &rb_operator, &rb_n_arguments);
208
+ if (!NIL_P(rb_operator))
209
+ operator = NUM2INT(rb_operator);
210
+ if (!NIL_P(rb_n_arguments))
211
+ n_arguments = NUM2INT(rb_n_arguments);
212
+
213
+ rb_grn_expression_deconstruct(SELF(self), &expression, &context,
214
+ NULL, NULL, NULL,
215
+ NULL, NULL);
216
+
217
+ RVAL2GRNOBJ(rb_constant, context, &constant);
218
+ grn_expr_append_const(context, expression, constant, operator, n_arguments);
219
+
220
+ exception = rb_grn_context_to_exception(context, self);
221
+ grn_obj_unlink(context, constant);
222
+ if (!NIL_P(exception))
223
+ rb_exc_raise(exception);
224
+
225
+ return self;
226
+ }
227
+
228
+ /*
229
+ * call-seq:
230
+ * expression.append_operation(operation, n_arguments)
231
+ *
232
+ * _n_arguments_個の引数を取る_operation_を追加する。
233
+ */
234
+ static VALUE
235
+ rb_grn_expression_append_operation (VALUE self, VALUE rb_operation,
236
+ VALUE rb_n_arguments)
237
+ {
238
+ grn_ctx *context = NULL;
239
+ grn_obj *expression;
240
+ grn_operator operation;
241
+ int n_arguments = 0;
242
+
243
+ rb_grn_expression_deconstruct(SELF(self), &expression, &context,
244
+ NULL, NULL,
245
+ NULL, NULL, NULL);
246
+
247
+ operation = NUM2INT(rb_operation);
248
+ n_arguments = NUM2INT(rb_n_arguments);
249
+ grn_expr_append_op(context, expression, operation, n_arguments);
250
+ rb_grn_context_check(context, self);
251
+ return Qnil;
252
+ }
253
+
254
+ /*
255
+ * call-seq:
256
+ * expression.parse(query, options={})
257
+ *
258
+ * 文字列_query_をパースする。
259
+ *
260
+ * _options_に指定可能な値は以下の通り。
261
+ *
262
+ * [+:default_column+]
263
+ * "column_name:hoge"ではなく"hoge"のようにcolumn_nameが指
264
+ * 定されない条件の検索対象となるカラムを指定する。
265
+ *
266
+ * [+:default_operator+]
267
+ * "+"や"OR"で繋がれず、ただ列挙された複数の条件があった時、
268
+ * _expression_全体として各レコードをヒットとみなすかの論理
269
+ * 条件を指定する。省略した場合はGroonga::Operation::AND。
270
+ *
271
+ * [Groonga::Operation::OR]
272
+ * レコードはいずれかの条件にマッチすればいい。
273
+ * [Groonga::Operation::AND]
274
+ * レコードは全ての条件にマッチしなければならない。
275
+ * [Groonga::Operation::BUT]
276
+ * 最初の条件にレコードはマッチし、残りの条件にレコードは
277
+ * マッチしてはならない。
278
+ *
279
+ * [+:default_mode+]
280
+ * 検索時のモードを指定する。省略した場合は
281
+ * Groonga::Operation::MATCH。(FIXME: モードによってどう
282
+ * いう動作になるかを書く。)
283
+ *
284
+ * [+:syntax+]
285
+ * _query_の構文を指定する。指定可能な値は以下の通り。省略
286
+ * した場合は+:query+。
287
+ *
288
+ * [+nil+]
289
+ * +:query+と同様。
290
+ * [+:query+]
291
+ * 「文字列1 OR 文字列2」で「"文字列1"あるいは"文字列2"
292
+ * にマッチという検索エンジンで利用できるような構文を使
293
+ * う。
294
+ *
295
+ * 参考: grn式のquery形式(link:text/expression_rdoc.html)
296
+ * [+:script+]
297
+ * 「[カラム名] == [値]」というようにECMAScript風の構文
298
+ * を使う。
299
+ *
300
+ * 参考: grn式のscript形式(link:text/expression_rdoc.html)
301
+ *
302
+ * [+:allow_pragma+]
303
+ * _query_の構文にqueryを用いているとき(+:syntax+オプショ
304
+ * ン参照)、「*E-1」というようにクエリの先頭でpragmaを利
305
+ * 用できるようにする。script構文を用いているときはこのオ
306
+ * プションを利用できない。
307
+ *
308
+ * デフォルトではプラグマを利用できる。
309
+ *
310
+ * 参考: grn式のquery形式(link:text/expression_rdoc.html)
311
+ *
312
+ * [+:allow_column+]
313
+ * _query_の構文にqueryを用いているとき(+:syntax+オプショ
314
+ * ン参照)、「カラム名:値」というようにカラム名を指定した
315
+ * 条件式を利用できるようにする。script構文を用いていると
316
+ * きはこのオプションを利用できない。
317
+ *
318
+ * デフォルトではカラム名を指定した条件式を利用できる。
319
+ *
320
+ * 参考: grn式のquery形式(link:text/expression_rdoc.html)
321
+ *
322
+ * [+:allow_update+]
323
+ * _query_の構文にscriptを用いているとき(+:syntax+オプショ
324
+ * ン参照)、「カラム名 = 値」というように更新操作を利用で
325
+ * きるようにする。query構文を用いているときはこのオプショ
326
+ * ンを利用できない。
327
+ *
328
+ * デフォルトでは更新操作を利用できる。
329
+ *
330
+ * 参考: grn式のscript形式(link:text/expression_rdoc.html)
331
+ */
332
+ static VALUE
333
+ rb_grn_expression_parse (int argc, VALUE *argv, VALUE self)
334
+ {
335
+ grn_ctx *context = NULL;
336
+ grn_obj *expression, *default_column = NULL;
337
+ grn_operator default_operator = GRN_OP_AND;
338
+ grn_operator default_mode = GRN_OP_MATCH;
339
+ grn_rc rc;
340
+ char *query = NULL;
341
+ unsigned query_size = 0;
342
+ grn_expr_flags flags = 0;
343
+ VALUE options, rb_query, rb_default_column, rb_default_operator;
344
+ VALUE rb_default_mode, rb_syntax;
345
+ VALUE rb_allow_pragma, rb_allow_column, rb_allow_update;
346
+ VALUE exception = Qnil;
347
+
348
+ rb_scan_args(argc, argv, "11", &rb_query, &options);
349
+ rb_grn_scan_options(options,
350
+ "default_column", &rb_default_column,
351
+ "default_operator", &rb_default_operator,
352
+ "default_mode", &rb_default_mode,
353
+ "syntax", &rb_syntax,
354
+ "allow_pragma", &rb_allow_pragma,
355
+ "allow_column", &rb_allow_column,
356
+ "allow_update", &rb_allow_update,
357
+ NULL);
358
+
359
+ query = StringValuePtr(rb_query);
360
+ query_size = RSTRING_LEN(rb_query);
361
+
362
+ rb_grn_expression_deconstruct(SELF(self), &expression, &context,
363
+ NULL, NULL,
364
+ NULL, NULL, NULL);
365
+
366
+ default_column = RVAL2GRNBULK(rb_default_column, context, default_column);
367
+ if (!NIL_P(rb_default_mode))
368
+ default_mode = RVAL2GRNOPERATOR(rb_default_mode);
369
+ if (!NIL_P(rb_default_operator))
370
+ default_operator = RVAL2GRNOPERATOR(rb_default_operator);
371
+
372
+ if (NIL_P(rb_syntax) ||
373
+ rb_grn_equal_option(rb_syntax, "query")) {
374
+ flags = GRN_EXPR_SYNTAX_QUERY;
375
+ } else if (rb_grn_equal_option(rb_syntax, "script")) {
376
+ flags = GRN_EXPR_SYNTAX_SCRIPT;
377
+ } else {
378
+ rb_raise(rb_eArgError,
379
+ "syntax should be one of "
380
+ "[nil, :query, :script]: %s",
381
+ rb_grn_inspect(rb_syntax));
382
+ }
383
+
384
+ if (NIL_P(rb_allow_pragma)) {
385
+ if ((flags & GRN_EXPR_SYNTAX_QUERY) == GRN_EXPR_SYNTAX_QUERY)
386
+ flags |= GRN_EXPR_ALLOW_PRAGMA;
387
+ } else {
388
+ if ((flags & GRN_EXPR_SYNTAX_SCRIPT) == GRN_EXPR_SYNTAX_SCRIPT)
389
+ rb_raise(rb_eArgError,
390
+ ":allow_pragma isn't allowed in script syntax");
391
+ if (RVAL2CBOOL(rb_allow_pragma))
392
+ flags |= GRN_EXPR_ALLOW_PRAGMA;
393
+ }
394
+
395
+ if (NIL_P(rb_allow_column)) {
396
+ if ((flags & GRN_EXPR_SYNTAX_QUERY) == GRN_EXPR_SYNTAX_QUERY)
397
+ flags |= GRN_EXPR_ALLOW_COLUMN;
398
+ } else {
399
+ if ((flags & GRN_EXPR_SYNTAX_SCRIPT) == GRN_EXPR_SYNTAX_SCRIPT)
400
+ rb_raise(rb_eArgError,
401
+ ":allow_column isn't allowed in script syntax");
402
+ if (RVAL2CBOOL(rb_allow_column))
403
+ flags |= GRN_EXPR_ALLOW_COLUMN;
404
+ }
405
+
406
+ if (NIL_P(rb_allow_update)) {
407
+ if ((flags & GRN_EXPR_SYNTAX_SCRIPT) == GRN_EXPR_SYNTAX_SCRIPT)
408
+ flags |= GRN_EXPR_ALLOW_UPDATE;
409
+ } else {
410
+ if ((flags & GRN_EXPR_SYNTAX_QUERY) == GRN_EXPR_SYNTAX_QUERY)
411
+ rb_raise(rb_eArgError,
412
+ ":allow_update isn't allowed in query syntax");
413
+ if (RVAL2CBOOL(rb_allow_update))
414
+ flags |= GRN_EXPR_ALLOW_UPDATE;
415
+ }
416
+
417
+ rc = grn_expr_parse(context, expression, query, query_size,
418
+ default_column, default_mode, default_operator,
419
+ flags);
420
+ if (rc != GRN_SUCCESS) {
421
+ VALUE related_object;
422
+
423
+ related_object = rb_ary_new3(2, self, rb_ary_new4(argc, argv));
424
+ exception = rb_grn_context_to_exception(context, related_object);
425
+ }
426
+ grn_obj_unlink(context, default_column);
427
+
428
+ if (!NIL_P(exception))
429
+ rb_exc_raise(exception);
430
+
431
+ return Qnil;
432
+ }
433
+
434
+ /*
435
+ * call-seq:
436
+ * expression.execute
437
+ *
438
+ * _expression_を実行する。
439
+ */
440
+ static VALUE
441
+ rb_grn_expression_execute (VALUE self)
442
+ {
443
+ grn_ctx *context = NULL;
444
+ grn_obj *expression;
445
+ grn_rc rc;
446
+
447
+ rb_grn_expression_deconstruct(SELF(self), &expression, &context,
448
+ NULL, NULL,
449
+ NULL, NULL, NULL);
450
+
451
+ rc = grn_expr_exec(context, expression, 0);
452
+ rb_grn_context_check(context, self);
453
+ rb_grn_rc_check(rc, self);
454
+
455
+ return Qnil;
456
+ }
457
+
458
+ /*
459
+ * call-seq:
460
+ * expression.compile
461
+ *
462
+ * _expression_をコンパイルする。
463
+ */
464
+ static VALUE
465
+ rb_grn_expression_compile (VALUE self)
466
+ {
467
+ grn_ctx *context = NULL;
468
+ grn_obj *expression;
469
+ grn_rc rc;
470
+
471
+ rb_grn_expression_deconstruct(SELF(self), &expression, &context,
472
+ NULL, NULL,
473
+ NULL, NULL, NULL);
474
+
475
+ rc = grn_expr_compile(context, expression);
476
+ rb_grn_context_check(context, self);
477
+ rb_grn_rc_check(rc, self);
478
+
479
+ return Qnil;
480
+ }
481
+
482
+ /*
483
+ * call-seq:
484
+ * expression[name] -> 変数の値
485
+ * expression[offset] -> 変数の値
486
+ *
487
+ * _expression_で使用可能な変数のうち、名前が_name_または
488
+ * _offset_番目にExpression#append_objectされた変数の値を返
489
+ * す。
490
+ */
491
+ static VALUE
492
+ rb_grn_expression_array_reference (VALUE self, VALUE rb_name_or_offset)
493
+ {
494
+ grn_ctx *context = NULL;
495
+ grn_obj *expression, *variable, *value;
496
+ char *name = NULL;
497
+ unsigned name_size = 0;
498
+ int offset;
499
+
500
+ rb_grn_expression_deconstruct(SELF(self), &expression, &context,
501
+ NULL, NULL,
502
+ NULL, NULL, NULL);
503
+
504
+ switch (TYPE(rb_name_or_offset)) {
505
+ case T_STRING:
506
+ name = RSTRING_PTR(rb_name_or_offset);
507
+ name_size = RSTRING_LEN(rb_name_or_offset);
508
+ variable = grn_expr_get_var(context, expression, name, name_size);
509
+ return GRNBULK2RVAL(context, variable, NULL, self);
510
+ break;
511
+ case T_FIXNUM:
512
+ offset = NUM2INT(rb_name_or_offset);
513
+ value = grn_expr_get_var_by_offset(context, expression, offset);
514
+ return GRNBULK2RVAL(context, value, NULL, self);
515
+ break;
516
+ default:
517
+ rb_raise(rb_eArgError, "xxx");
518
+ break;
519
+ }
520
+
521
+ return Qnil;
522
+ }
523
+
524
+ /* REMOVE ME */
525
+ grn_rc grn_expr_inspect(grn_ctx *ctx, grn_obj *buf, grn_obj *expr);
526
+
527
+ /*
528
+ * call-seq:
529
+ * _expression_.inspect -> String
530
+ *
531
+ * _expression_の中身を人に見やすい文字列で返す。
532
+ */
533
+ static VALUE
534
+ rb_grn_expression_inspect (VALUE self)
535
+ {
536
+ grn_ctx *context = NULL;
537
+ grn_obj inspected;
538
+ grn_obj *expression;
539
+ VALUE rb_inspected;
540
+
541
+ rb_grn_expression_deconstruct(SELF(self), &expression, &context,
542
+ NULL, NULL,
543
+ NULL, NULL, NULL);
544
+
545
+ GRN_TEXT_INIT(&inspected, 0);
546
+ GRN_TEXT_PUTS(context, &inspected, "#<Groonga::Expression ");
547
+ #ifdef WIN32
548
+ GRN_TEXT_PUTS(context, &inspected, "(not supported on Windows)");
549
+ #else
550
+ grn_expr_inspect(context, &inspected, expression);
551
+ #endif
552
+ GRN_TEXT_PUTS(context, &inspected, ">");
553
+ rb_inspected = rb_str_new(GRN_TEXT_VALUE(&inspected),
554
+ GRN_TEXT_LEN(&inspected));
555
+ GRN_OBJ_FIN(context, &inspected);
556
+
557
+ return rb_inspected;
558
+ }
559
+
560
+ /*
561
+ * call-seq:
562
+ * expression.snippet(tags, options) -> Groonga::Snippet
563
+ *
564
+ * _expression_からGroonga::Snippetを生成する。_tags_にはキー
565
+ * ワードの前後に挿入するタグの配列を以下のような形式で指定
566
+ * する。
567
+ *
568
+ * [
569
+ * ["キーワード前に挿入する文字列1", "キーワード後に挿入する文字列1"],
570
+ * ["キーワード前に挿入する文字列2", "キーワード後に挿入する文字列2"],
571
+ * ...,
572
+ * ]
573
+ *
574
+ * もし、1つのスニペットの中に_tags_で指定したタグより多くの
575
+ * キーワードが含まれている場合は、以下のように、また、先頭
576
+ * のタグから順番に使われる。
577
+ *
578
+ * expression.parse("Ruby groonga 検索")
579
+ * tags = [["<tag1>", "</tag1>"], ["<tag2>", "</tag2>"]]
580
+ * snippet = expression.snippet(tags)
581
+ * p snippet.execute("Rubyでgroonga使って全文検索、高速検索。")
582
+ * # => ["<tag1>Ruby</tag1>で<tag2>groonga</tag2>"
583
+ * # "使って全文<tag1>検索</tag1>、高速<tag2>検索</tag2>。"]
584
+ *
585
+ * _options_に指定可能な値は以下の通り。
586
+ *
587
+ * [+:normalize+]
588
+ * キーワード文字列・スニペット元の文字列を正規化するかど
589
+ * うか。省略した場合は+false+で正規化しない。
590
+ *
591
+ * [+:skip_leading_spaces+]
592
+ * 先頭の空白を無視するかどうか。省略した場合は+false+で無
593
+ * 視しない。
594
+ *
595
+ * [+:width+]
596
+ * スニペット文字列の長さ。省略した場合は100文字。
597
+ *
598
+ * [+:max_results+]
599
+ * 生成するスニペットの最大数。省略した場合は3。
600
+ *
601
+ * [+:html_escape+]
602
+ * スニペット内の+<+, +>+, +&+, +"+をHTMLエスケープするか
603
+ * どうか。省略した場合は+false+で、HTMLエスケープしない。
604
+ */
605
+ static VALUE
606
+ rb_grn_expression_snippet (int argc, VALUE *argv, VALUE self)
607
+ {
608
+ grn_ctx *context = NULL;
609
+ grn_obj *expression;
610
+ grn_snip *snippet;
611
+ VALUE options;
612
+ VALUE rb_normalize, rb_skip_leading_spaces;
613
+ VALUE rb_width, rb_max_results, rb_tags;
614
+ VALUE rb_html_escape;
615
+ VALUE *rb_tag_values;
616
+ unsigned int i;
617
+ int flags = GRN_SNIP_COPY_TAG;
618
+ unsigned int width = 100;
619
+ unsigned int max_results = 3;
620
+ unsigned int n_tags = 0;
621
+ char **open_tags = NULL;
622
+ unsigned int *open_tag_lengths = NULL;
623
+ char **close_tags = NULL;
624
+ unsigned int *close_tag_lengths = NULL;
625
+ grn_snip_mapping *mapping = NULL;
626
+
627
+ rb_grn_expression_deconstruct(SELF(self), &expression, &context,
628
+ NULL, NULL,
629
+ NULL, NULL, NULL);
630
+
631
+ rb_scan_args(argc, argv, "11", &rb_tags, &options);
632
+
633
+ rb_grn_scan_options(options,
634
+ "normalize", &rb_normalize,
635
+ "skip_leading_spaces", &rb_skip_leading_spaces,
636
+ "width", &rb_width,
637
+ "max_results", &rb_max_results,
638
+ "html_escape", &rb_html_escape,
639
+ NULL);
640
+
641
+ if (TYPE(rb_tags) != T_ARRAY) {
642
+ rb_raise(rb_eArgError,
643
+ "tags should be "
644
+ "[\"open_tag\", \"close_tag\"] or"
645
+ "[[\"open_tag1\", \"close_tag1\"], ...]: %s",
646
+ rb_grn_inspect(rb_tags));
647
+ }
648
+
649
+ if (TYPE(RARRAY_PTR(rb_tags)[0]) == T_STRING) {
650
+ rb_tags = rb_ary_new3(1, rb_tags);
651
+ }
652
+
653
+ rb_tag_values = RARRAY_PTR(rb_tags);
654
+ n_tags = RARRAY_LEN(rb_tags);
655
+ open_tags = ALLOCA_N(char *, n_tags);
656
+ open_tag_lengths = ALLOCA_N(unsigned int, n_tags);
657
+ close_tags = ALLOCA_N(char *, n_tags);
658
+ close_tag_lengths = ALLOCA_N(unsigned int, n_tags);
659
+ for (i = 0; i < n_tags; i++) {
660
+ VALUE *tag_pair;
661
+
662
+ if (TYPE(rb_tag_values[i]) != T_ARRAY ||
663
+ RARRAY_LEN(rb_tag_values[i]) != 2) {
664
+ rb_raise(rb_eArgError,
665
+ "tags should be "
666
+ "[\"open_tag\", \"close_tag\"] or"
667
+ "[[\"open_tag1\", \"close_tag1\"], ...]: %s",
668
+ rb_grn_inspect(rb_tags));
669
+ }
670
+ tag_pair = RARRAY_PTR(rb_tag_values[i]);
671
+ open_tags[i] = StringValuePtr(tag_pair[0]);
672
+ open_tag_lengths[i] = RSTRING_LEN(tag_pair[0]);
673
+ close_tags[i] = StringValuePtr(tag_pair[1]);
674
+ close_tag_lengths[i] = RSTRING_LEN(tag_pair[1]);
675
+ }
676
+
677
+ if (RVAL2CBOOL(rb_normalize))
678
+ flags |= GRN_SNIP_NORMALIZE;
679
+ if (RVAL2CBOOL(rb_skip_leading_spaces))
680
+ flags |= GRN_SNIP_SKIP_LEADING_SPACES;
681
+
682
+ if (!NIL_P(rb_width))
683
+ width = NUM2UINT(rb_width);
684
+
685
+ if (!NIL_P(rb_max_results))
686
+ max_results = NUM2UINT(rb_max_results);
687
+
688
+ if (RVAL2CBOOL(rb_html_escape))
689
+ mapping = (grn_snip_mapping *)-1;
690
+
691
+ snippet = grn_expr_snip(context, expression, flags, width, max_results,
692
+ n_tags,
693
+ (const char **)open_tags, open_tag_lengths,
694
+ (const char **)close_tags, close_tag_lengths,
695
+ mapping);
696
+ rb_grn_context_check(context,
697
+ rb_ary_new3(2, self, rb_ary_new4(argc, argv)));
698
+
699
+ return GRNSNIPPET2RVAL(context, snippet, RB_GRN_TRUE);
700
+ }
701
+
702
+ void
703
+ rb_grn_init_expression (VALUE mGrn)
704
+ {
705
+ rb_cGrnExpression = rb_define_class_under(mGrn, "Expression", rb_cGrnObject);
706
+
707
+ rb_define_method(rb_cGrnExpression, "initialize",
708
+ rb_grn_expression_initialize, -1);
709
+
710
+ rb_define_method(rb_cGrnExpression, "define_variable",
711
+ rb_grn_expression_define_variable, -1);
712
+ rb_define_method(rb_cGrnExpression, "append_object",
713
+ rb_grn_expression_append_object, -1);
714
+ rb_define_method(rb_cGrnExpression, "append_constant",
715
+ rb_grn_expression_append_constant, -1);
716
+ rb_define_method(rb_cGrnExpression, "append_operation",
717
+ rb_grn_expression_append_operation, 2);
718
+
719
+ rb_define_method(rb_cGrnExpression, "parse",
720
+ rb_grn_expression_parse, -1);
721
+
722
+ rb_define_method(rb_cGrnExpression, "execute",
723
+ rb_grn_expression_execute, 0);
724
+ rb_define_method(rb_cGrnExpression, "compile",
725
+ rb_grn_expression_compile, 0);
726
+
727
+ rb_define_method(rb_cGrnExpression, "[]",
728
+ rb_grn_expression_array_reference, 1);
729
+
730
+ rb_define_method(rb_cGrnExpression, "snippet",
731
+ rb_grn_expression_snippet, -1);
732
+
733
+ rb_define_method(rb_cGrnExpression, "inspect",
734
+ rb_grn_expression_inspect, 0);
735
+ }