rroonga 0.9.2-x86-mingw32

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 (199) 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 +206 -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 +230 -0
  13. data/example/search/public/css/groonga.css +122 -0
  14. data/ext/.gitignore +2 -0
  15. data/ext/groonga/extconf.rb +93 -0
  16. data/ext/groonga/rb-grn-accessor.c +52 -0
  17. data/ext/groonga/rb-grn-array-cursor.c +36 -0
  18. data/ext/groonga/rb-grn-array.c +210 -0
  19. data/ext/groonga/rb-grn-column.c +573 -0
  20. data/ext/groonga/rb-grn-context.c +662 -0
  21. data/ext/groonga/rb-grn-database.c +472 -0
  22. data/ext/groonga/rb-grn-encoding-support.c +64 -0
  23. data/ext/groonga/rb-grn-encoding.c +257 -0
  24. data/ext/groonga/rb-grn-exception.c +1110 -0
  25. data/ext/groonga/rb-grn-expression-builder.c +75 -0
  26. data/ext/groonga/rb-grn-expression.c +731 -0
  27. data/ext/groonga/rb-grn-fix-size-column.c +166 -0
  28. data/ext/groonga/rb-grn-hash-cursor.c +38 -0
  29. data/ext/groonga/rb-grn-hash.c +294 -0
  30. data/ext/groonga/rb-grn-index-column.c +488 -0
  31. data/ext/groonga/rb-grn-logger.c +504 -0
  32. data/ext/groonga/rb-grn-object.c +1369 -0
  33. data/ext/groonga/rb-grn-operation.c +198 -0
  34. data/ext/groonga/rb-grn-patricia-trie-cursor.c +39 -0
  35. data/ext/groonga/rb-grn-patricia-trie.c +488 -0
  36. data/ext/groonga/rb-grn-procedure.c +52 -0
  37. data/ext/groonga/rb-grn-query.c +260 -0
  38. data/ext/groonga/rb-grn-record.c +40 -0
  39. data/ext/groonga/rb-grn-snippet.c +334 -0
  40. data/ext/groonga/rb-grn-table-cursor-key-support.c +69 -0
  41. data/ext/groonga/rb-grn-table-cursor.c +247 -0
  42. data/ext/groonga/rb-grn-table-key-support.c +714 -0
  43. data/ext/groonga/rb-grn-table.c +1977 -0
  44. data/ext/groonga/rb-grn-type.c +181 -0
  45. data/ext/groonga/rb-grn-utils.c +769 -0
  46. data/ext/groonga/rb-grn-variable-size-column.c +36 -0
  47. data/ext/groonga/rb-grn-variable.c +108 -0
  48. data/ext/groonga/rb-grn-view-accessor.c +53 -0
  49. data/ext/groonga/rb-grn-view-cursor.c +35 -0
  50. data/ext/groonga/rb-grn-view-record.c +41 -0
  51. data/ext/groonga/rb-grn-view.c +421 -0
  52. data/ext/groonga/rb-grn.h +698 -0
  53. data/ext/groonga/rb-groonga.c +107 -0
  54. data/extconf.rb +130 -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/1.8/groonga.so +0 -0
  70. data/lib/1.9/groonga.so +0 -0
  71. data/lib/groonga.rb +90 -0
  72. data/lib/groonga/context.rb +184 -0
  73. data/lib/groonga/expression-builder.rb +324 -0
  74. data/lib/groonga/patricia-trie.rb +85 -0
  75. data/lib/groonga/record.rb +311 -0
  76. data/lib/groonga/schema.rb +1191 -0
  77. data/lib/groonga/view-record.rb +56 -0
  78. data/license/GPL +340 -0
  79. data/license/LGPL +504 -0
  80. data/license/RUBY +59 -0
  81. data/misc/grnop2ruby.rb +49 -0
  82. data/pkg-config.rb +333 -0
  83. data/rroonga-build.rb +57 -0
  84. data/test-unit/Rakefile +40 -0
  85. data/test-unit/TODO +5 -0
  86. data/test-unit/bin/testrb +5 -0
  87. data/test-unit/html/classic.html +15 -0
  88. data/test-unit/html/index.html +25 -0
  89. data/test-unit/html/index.html.ja +27 -0
  90. data/test-unit/lib/test/unit.rb +323 -0
  91. data/test-unit/lib/test/unit/assertionfailederror.rb +25 -0
  92. data/test-unit/lib/test/unit/assertions.rb +1230 -0
  93. data/test-unit/lib/test/unit/attribute.rb +125 -0
  94. data/test-unit/lib/test/unit/autorunner.rb +360 -0
  95. data/test-unit/lib/test/unit/collector.rb +36 -0
  96. data/test-unit/lib/test/unit/collector/descendant.rb +23 -0
  97. data/test-unit/lib/test/unit/collector/dir.rb +108 -0
  98. data/test-unit/lib/test/unit/collector/load.rb +144 -0
  99. data/test-unit/lib/test/unit/collector/objectspace.rb +34 -0
  100. data/test-unit/lib/test/unit/color-scheme.rb +102 -0
  101. data/test-unit/lib/test/unit/color.rb +96 -0
  102. data/test-unit/lib/test/unit/diff.rb +724 -0
  103. data/test-unit/lib/test/unit/error.rb +130 -0
  104. data/test-unit/lib/test/unit/exceptionhandler.rb +39 -0
  105. data/test-unit/lib/test/unit/failure.rb +136 -0
  106. data/test-unit/lib/test/unit/fixture.rb +176 -0
  107. data/test-unit/lib/test/unit/notification.rb +129 -0
  108. data/test-unit/lib/test/unit/omission.rb +191 -0
  109. data/test-unit/lib/test/unit/pending.rb +150 -0
  110. data/test-unit/lib/test/unit/priority.rb +180 -0
  111. data/test-unit/lib/test/unit/runner/console.rb +52 -0
  112. data/test-unit/lib/test/unit/runner/emacs.rb +8 -0
  113. data/test-unit/lib/test/unit/runner/tap.rb +8 -0
  114. data/test-unit/lib/test/unit/testcase.rb +476 -0
  115. data/test-unit/lib/test/unit/testresult.rb +89 -0
  116. data/test-unit/lib/test/unit/testsuite.rb +110 -0
  117. data/test-unit/lib/test/unit/ui/console/outputlevel.rb +14 -0
  118. data/test-unit/lib/test/unit/ui/console/testrunner.rb +466 -0
  119. data/test-unit/lib/test/unit/ui/emacs/testrunner.rb +63 -0
  120. data/test-unit/lib/test/unit/ui/tap/testrunner.rb +92 -0
  121. data/test-unit/lib/test/unit/ui/testrunner.rb +28 -0
  122. data/test-unit/lib/test/unit/ui/testrunnermediator.rb +77 -0
  123. data/test-unit/lib/test/unit/ui/testrunnerutilities.rb +41 -0
  124. data/test-unit/lib/test/unit/util/backtracefilter.rb +41 -0
  125. data/test-unit/lib/test/unit/util/method-owner-finder.rb +28 -0
  126. data/test-unit/lib/test/unit/util/observable.rb +90 -0
  127. data/test-unit/lib/test/unit/util/procwrapper.rb +48 -0
  128. data/test-unit/lib/test/unit/version.rb +7 -0
  129. data/test-unit/sample/adder.rb +13 -0
  130. data/test-unit/sample/subtracter.rb +12 -0
  131. data/test-unit/sample/test_adder.rb +20 -0
  132. data/test-unit/sample/test_subtracter.rb +20 -0
  133. data/test-unit/sample/test_user.rb +23 -0
  134. data/test-unit/test/collector/test-descendant.rb +133 -0
  135. data/test-unit/test/collector/test-load.rb +442 -0
  136. data/test-unit/test/collector/test_dir.rb +406 -0
  137. data/test-unit/test/collector/test_objectspace.rb +100 -0
  138. data/test-unit/test/run-test.rb +15 -0
  139. data/test-unit/test/test-attribute.rb +86 -0
  140. data/test-unit/test/test-color-scheme.rb +67 -0
  141. data/test-unit/test/test-color.rb +47 -0
  142. data/test-unit/test/test-diff.rb +518 -0
  143. data/test-unit/test/test-emacs-runner.rb +60 -0
  144. data/test-unit/test/test-fixture.rb +287 -0
  145. data/test-unit/test/test-notification.rb +33 -0
  146. data/test-unit/test/test-omission.rb +81 -0
  147. data/test-unit/test/test-pending.rb +70 -0
  148. data/test-unit/test/test-priority.rb +119 -0
  149. data/test-unit/test/test-testcase.rb +544 -0
  150. data/test-unit/test/test_assertions.rb +1151 -0
  151. data/test-unit/test/test_error.rb +26 -0
  152. data/test-unit/test/test_failure.rb +33 -0
  153. data/test-unit/test/test_testresult.rb +113 -0
  154. data/test-unit/test/test_testsuite.rb +129 -0
  155. data/test-unit/test/testunit-test-util.rb +14 -0
  156. data/test-unit/test/ui/test_testrunmediator.rb +20 -0
  157. data/test-unit/test/util/test-method-owner-finder.rb +38 -0
  158. data/test-unit/test/util/test_backtracefilter.rb +41 -0
  159. data/test-unit/test/util/test_observable.rb +102 -0
  160. data/test-unit/test/util/test_procwrapper.rb +36 -0
  161. data/test/.gitignore +1 -0
  162. data/test/groonga-test-utils.rb +134 -0
  163. data/test/run-test.rb +58 -0
  164. data/test/test-array.rb +90 -0
  165. data/test/test-column.rb +316 -0
  166. data/test/test-context-select.rb +93 -0
  167. data/test/test-context.rb +73 -0
  168. data/test/test-database.rb +113 -0
  169. data/test/test-encoding.rb +33 -0
  170. data/test/test-exception.rb +93 -0
  171. data/test/test-expression-builder.rb +217 -0
  172. data/test/test-expression.rb +134 -0
  173. data/test/test-fix-size-column.rb +65 -0
  174. data/test/test-gqtp.rb +72 -0
  175. data/test/test-hash.rb +305 -0
  176. data/test/test-index-column.rb +81 -0
  177. data/test/test-logger.rb +37 -0
  178. data/test/test-patricia-trie.rb +205 -0
  179. data/test/test-procedure.rb +37 -0
  180. data/test/test-query.rb +22 -0
  181. data/test/test-record.rb +243 -0
  182. data/test/test-remote.rb +54 -0
  183. data/test/test-schema-view.rb +90 -0
  184. data/test/test-schema.rb +459 -0
  185. data/test/test-snippet.rb +130 -0
  186. data/test/test-table-cursor.rb +153 -0
  187. data/test/test-table-offset-and-limit.rb +102 -0
  188. data/test/test-table-select-normalize.rb +53 -0
  189. data/test/test-table-select.rb +150 -0
  190. data/test/test-table.rb +594 -0
  191. data/test/test-type.rb +71 -0
  192. data/test/test-variable-size-column.rb +98 -0
  193. data/test/test-variable.rb +28 -0
  194. data/test/test-vector-column.rb +76 -0
  195. data/test/test-version.rb +31 -0
  196. data/test/test-view.rb +72 -0
  197. data/text/TUTORIAL.ja.rdoc +392 -0
  198. data/text/expression.rdoc +284 -0
  199. metadata +276 -0
@@ -0,0 +1,488 @@
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
+ #include <string.h>
22
+
23
+ #define SELF(object) ((RbGrnIndexColumn *)DATA_PTR(object))
24
+
25
+ VALUE rb_cGrnIndexColumn;
26
+
27
+ /*
28
+ * Document-class: Groonga::IndexColumn < Groonga::Column
29
+ *
30
+ * 転置索引エントリを格納するカラム。このカラムを利用するこ
31
+ * とにより高速な全文検索を実現できる。
32
+ *
33
+ * テーブルにGroonga::IndexColumnを定義する方法は
34
+ * Groonga::Table#define_index_columnを参照。
35
+ */
36
+
37
+ void
38
+ rb_grn_index_column_finalizer (grn_ctx *context, grn_obj *object,
39
+ RbGrnIndexColumn *rb_grn_index_column)
40
+ {
41
+ if (!context)
42
+ return;
43
+
44
+ grn_obj_unlink(context, rb_grn_index_column->id_query);
45
+ grn_obj_unlink(context, rb_grn_index_column->string_query);
46
+ grn_obj_unlink(context, rb_grn_index_column->old_value);
47
+
48
+ rb_grn_column_finalizer(context, object, RB_GRN_COLUMN(rb_grn_index_column));
49
+ }
50
+
51
+ void
52
+ rb_grn_index_column_bind (RbGrnIndexColumn *rb_grn_index_column,
53
+ grn_ctx *context, grn_obj *column)
54
+ {
55
+ RbGrnObject *rb_grn_object;
56
+
57
+ rb_grn_column_bind(RB_GRN_COLUMN(rb_grn_index_column), context, column);
58
+ rb_grn_object = RB_GRN_OBJECT(rb_grn_index_column);
59
+
60
+ rb_grn_index_column->old_value = grn_obj_open(context, GRN_BULK, 0,
61
+ rb_grn_object->range_id);
62
+
63
+ rb_grn_index_column->id_query = grn_obj_open(context, GRN_BULK, 0,
64
+ rb_grn_object->domain_id);
65
+ rb_grn_index_column->string_query = grn_obj_open(context, GRN_BULK,
66
+ GRN_OBJ_DO_SHALLOW_COPY,
67
+ GRN_ID_NIL);
68
+ }
69
+
70
+ void
71
+ rb_grn_index_column_deconstruct (RbGrnIndexColumn *rb_grn_index_column,
72
+ grn_obj **column,
73
+ grn_ctx **context,
74
+ grn_id *domain_id,
75
+ grn_obj **domain,
76
+ grn_obj **value,
77
+ grn_obj **old_value,
78
+ grn_id *range_id,
79
+ grn_obj **range,
80
+ grn_obj **id_query,
81
+ grn_obj **string_query)
82
+ {
83
+ RbGrnObject *rb_grn_object;
84
+
85
+ rb_grn_object = RB_GRN_OBJECT(rb_grn_index_column);
86
+ rb_grn_column_deconstruct(RB_GRN_COLUMN(rb_grn_object), column, context,
87
+ domain_id, domain, value,
88
+ range_id, range);
89
+
90
+ if (old_value)
91
+ *old_value = rb_grn_index_column->old_value;
92
+ if (id_query)
93
+ *id_query = rb_grn_index_column->id_query;
94
+ if (string_query)
95
+ *string_query = rb_grn_index_column->string_query;
96
+ }
97
+
98
+ /*
99
+ * call-seq:
100
+ * column[id] = value
101
+ * column[id] = options
102
+ *
103
+ * IDが_id_であるレコードを高速に全文検索するため転置索引を作
104
+ * 成する。多くの場合、Groonga::Table#define_index_columnで
105
+ * +:source+オプションを指定することにより、自動的に全文検索
106
+ * 用の索引は更新されるので、明示的にこのメソッドを使うこと
107
+ * は少ない。
108
+ *
109
+ * _value_には文字列を指定する。
110
+ *
111
+ * _options_を指定することにより、より索引の作成を制御できる。
112
+ * _options_に指定可能な値は以下の通り。
113
+ *
114
+ * [+:section+]
115
+ * 段落番号を指定する。省略した場合は1を指定したとみなされ
116
+ * る。
117
+ *
118
+ * Groonga::Table#define_index_columnで
119
+ * <tt>{:with_section => true}</tt>を指定していなければい
120
+ * けない。
121
+ *
122
+ * [+:old_value+]
123
+ * 以前の値を指定する。省略した場合は現在の値が用いられる。
124
+ * 通常は指定する必要はない。
125
+ *
126
+ * [+:value+]
127
+ * 新しい値を指定する。_value_を指定した場合と_options_で
128
+ * <tt>{:value => value}</tt>を指定した場合は同じ動作とな
129
+ * る。
130
+ *
131
+ * 記事の段落毎に索引を作成する。
132
+ * articles = Groonga::Array.create(:name => "<articles>")
133
+ * articles.define_column("title", "ShortText")
134
+ * articles.define_column("content", "Text")
135
+ *
136
+ * terms = Groonga::Hash.create(:name => "<terms>",
137
+ * :default_tokenizer => "TokenBigram")
138
+ * content_index = terms.define_index_column("content", articles,
139
+ * :with_section => true)
140
+ *
141
+ * content = <<-EOC
142
+ * groonga は組み込み型の全文検索エンジンライブラリです。
143
+ * DBMSやスクリプト言語処理系等に組み込むことによって、その
144
+ * 全文検索機能を強化することができます。また、リレーショナ
145
+ * ルモデルに基づくデータストア機能を内包しており、groonga
146
+ * 単体でも高速なデータストアサーバとして使用することができ
147
+ * ます。
148
+ *
149
+ * ■全文検索方式
150
+ * 転置索引型の全文検索エンジンです。転置索引は圧縮されてファ
151
+ * イルに格納され、検索時のディスク読み出し量を小さく、かつ
152
+ * 局所的に抑えるように設計されています。用途に応じて以下の
153
+ * 索引タイプを選択できます。
154
+ * EOC
155
+ *
156
+ * groonga = articles.add(:title => "groonga", :content => content)
157
+ *
158
+ * content.split(/\n{2,}/).each_with_index do |sentence, i|
159
+ * content_index[groonga] = {:value => sentence, :section => i + 1}
160
+ * end
161
+ *
162
+ * content_index.search("エンジン").collect do |record|
163
+ * p record.key["title"] # -> "groonga"
164
+ * end
165
+ */
166
+ static VALUE
167
+ rb_grn_index_column_array_set (VALUE self, VALUE rb_id, VALUE rb_value)
168
+ {
169
+ grn_ctx *context = NULL;
170
+ grn_obj *column, *range;
171
+ grn_rc rc;
172
+ grn_id id;
173
+ unsigned int section;
174
+ grn_obj *old_value, *new_value;
175
+ VALUE original_rb_value, rb_section, rb_old_value, rb_new_value;
176
+
177
+ original_rb_value = rb_value;
178
+
179
+ rb_grn_index_column_deconstruct(SELF(self), &column, &context,
180
+ NULL, NULL,
181
+ &new_value, &old_value,
182
+ NULL, &range,
183
+ NULL, NULL);
184
+
185
+ id = RVAL2GRNID(rb_id, context, range, self);
186
+
187
+ if (!RVAL2CBOOL(rb_obj_is_kind_of(rb_value, rb_cHash))) {
188
+ VALUE hash_value;
189
+ hash_value = rb_hash_new();
190
+ rb_hash_aset(hash_value, RB_GRN_INTERN("value"), rb_value);
191
+ rb_value = hash_value;
192
+ }
193
+
194
+ rb_grn_scan_options(rb_value,
195
+ "section", &rb_section,
196
+ "old_value", &rb_old_value,
197
+ "value", &rb_new_value,
198
+ NULL);
199
+
200
+ if (NIL_P(rb_section))
201
+ section = 1;
202
+ else
203
+ section = NUM2UINT(rb_section);
204
+
205
+ if (NIL_P(rb_old_value)) {
206
+ old_value = NULL;
207
+ } else {
208
+ GRN_BULK_REWIND(old_value);
209
+ RVAL2GRNBULK(rb_old_value, context, old_value);
210
+ }
211
+
212
+ if (NIL_P(rb_new_value)) {
213
+ new_value = NULL;
214
+ } else {
215
+ GRN_BULK_REWIND(new_value);
216
+ RVAL2GRNBULK(rb_new_value, context, new_value);
217
+ }
218
+
219
+ rc = grn_column_index_update(context, column,
220
+ id, section, old_value, new_value);
221
+ rb_grn_context_check(context, self);
222
+ rb_grn_rc_check(rc, self);
223
+
224
+ return original_rb_value;
225
+ }
226
+
227
+ /*
228
+ * call-seq:
229
+ * column.sources -> Groonga::Columnの配列
230
+ *
231
+ * インデックス対象となっているカラムの配列を返す。
232
+ */
233
+ static VALUE
234
+ rb_grn_index_column_get_sources (VALUE self)
235
+ {
236
+ grn_ctx *context = NULL;
237
+ grn_obj *column;
238
+ grn_obj sources;
239
+ grn_id *source_ids;
240
+ VALUE rb_sources;
241
+ int i, n;
242
+
243
+ rb_grn_index_column_deconstruct(SELF(self), &column, &context,
244
+ NULL, NULL,
245
+ NULL, NULL, NULL, NULL,
246
+ NULL, NULL);
247
+
248
+ GRN_OBJ_INIT(&sources, GRN_BULK, 0, GRN_ID_NIL);
249
+ grn_obj_get_info(context, column, GRN_INFO_SOURCE, &sources);
250
+ rb_grn_context_check(context, self);
251
+
252
+ n = GRN_BULK_VSIZE(&sources) / sizeof(grn_id);
253
+ source_ids = (grn_id *)GRN_BULK_HEAD(&sources);
254
+ rb_sources = rb_ary_new2(n);
255
+ for (i = 0; i < n; i++) {
256
+ grn_obj *source;
257
+ VALUE rb_source;
258
+
259
+ source = grn_ctx_at(context, *source_ids);
260
+ rb_source = GRNOBJECT2RVAL(Qnil, context, source, RB_GRN_FALSE);
261
+ rb_ary_push(rb_sources, rb_source);
262
+ source_ids++;
263
+ }
264
+ grn_obj_unlink(context, &sources);
265
+
266
+ return rb_sources;
267
+ }
268
+
269
+ static grn_id
270
+ resolve_source_id (grn_ctx *context, grn_obj *column, VALUE rb_source)
271
+ {
272
+ grn_id source_id;
273
+
274
+ if (CBOOL2RVAL(rb_obj_is_kind_of(rb_source, rb_cInteger))) {
275
+ source_id = NUM2UINT(rb_source);
276
+ } else {
277
+ grn_obj *source;
278
+
279
+ if (TYPE(rb_source) == T_STRING) {
280
+ grn_obj *table;
281
+ const char *name;
282
+ const char *dot_point;
283
+ int length;
284
+
285
+ table = grn_ctx_at(context, grn_obj_get_range(context, column));
286
+ name = StringValueCStr(rb_source);
287
+ length = RSTRING_LEN(rb_source);
288
+ dot_point = strstr(name, ".");
289
+ if (dot_point) {
290
+ char table_name[4096];
291
+ int table_name_length;
292
+
293
+ table_name_length = grn_obj_name(context, table,
294
+ table_name, sizeof(table_name));
295
+ table_name[table_name_length] = '\0';
296
+ if (strncmp(table_name, name, dot_point - name) != 0) {
297
+ rb_raise(rb_eArgError,
298
+ "wrong table's column: <%s>: "
299
+ "expected table: <%s>",
300
+ name, table_name);
301
+ }
302
+ length -= (dot_point - name) + 1;
303
+ name = dot_point + 1;
304
+ }
305
+ source = grn_obj_column(context, table, name, length);
306
+ } else {
307
+ source = RVAL2GRNOBJECT(rb_source, &context);
308
+ }
309
+ rb_grn_context_check(context, rb_source);
310
+ source_id = grn_obj_id(context, source);
311
+ }
312
+
313
+ return source_id;
314
+ }
315
+
316
+ /*
317
+ * call-seq:
318
+ * column.sources = Groonga::Columnの配列
319
+ *
320
+ * インデックス対象となる複数のカラムを配列で設定する。
321
+ */
322
+ static VALUE
323
+ rb_grn_index_column_set_sources (VALUE self, VALUE rb_sources)
324
+ {
325
+ VALUE exception;
326
+ grn_ctx *context = NULL;
327
+ grn_obj *column;
328
+ int i, n;
329
+ VALUE *rb_source_values;
330
+ grn_id *sources;
331
+ grn_rc rc;
332
+
333
+ rb_grn_index_column_deconstruct(SELF(self), &column, &context,
334
+ NULL, NULL,
335
+ NULL, NULL, NULL, NULL,
336
+ NULL, NULL);
337
+
338
+ n = RARRAY_LEN(rb_sources);
339
+ rb_source_values = RARRAY_PTR(rb_sources);
340
+ sources = ALLOCA_N(grn_id, n);
341
+ for (i = 0; i < n; i++) {
342
+ sources[i] = resolve_source_id(context, column, rb_source_values[i]);
343
+ }
344
+
345
+ {
346
+ grn_obj bulk_sources;
347
+ GRN_OBJ_INIT(&bulk_sources, GRN_BULK, 0, GRN_ID_NIL);
348
+ GRN_TEXT_SET(context, &bulk_sources, sources, n * sizeof(grn_id));
349
+ rc = grn_obj_set_info(context, column, GRN_INFO_SOURCE, &bulk_sources);
350
+ exception = rb_grn_context_to_exception(context, self);
351
+ grn_obj_unlink(context, &bulk_sources);
352
+ }
353
+
354
+ if (!NIL_P(exception))
355
+ rb_exc_raise(exception);
356
+ rb_grn_rc_check(rc, self);
357
+
358
+ return Qnil;
359
+ }
360
+
361
+ /*
362
+ * call-seq:
363
+ * column.source = Groonga::Column
364
+ *
365
+ * インデックス対象となるカラムを設定する。
366
+ */
367
+ static VALUE
368
+ rb_grn_index_column_set_source (VALUE self, VALUE rb_source)
369
+ {
370
+ if (!RVAL2CBOOL(rb_obj_is_kind_of(rb_source, rb_cArray)))
371
+ rb_source = rb_ary_new3(1, rb_source);
372
+
373
+ return rb_grn_index_column_set_sources(self, rb_source);
374
+ }
375
+
376
+ /*
377
+ * Document-method: search
378
+ *
379
+ * call-seq:
380
+ * column.search(query, options={}) -> Groonga::Hash
381
+ *
382
+ * _object_から_query_に対応するオブジェクトを検索し、見つかっ
383
+ * たオブジェクトのIDがキーになっているGroonga::Hashを返す。
384
+ *
385
+ * 利用可能なオプションは以下の通り。
386
+ *
387
+ * [_:result_]
388
+ * 結果を格納するGroonga::Hash。指定しない場合は新しく
389
+ * Groonga::Hashを生成し、それに結果を格納して返す。
390
+ * [_:operator_]
391
+ * 以下のどれかの値を指定する。+nil+, <tt>"or"</tt>, <tt>"||"</tt>,
392
+ * <tt>"and"</tt>, <tt>"+"</tt>, <tt>"&&"</tt>, <tt>"but"</tt>,
393
+ * <tt>"not"</tt>, <tt>"-"</tt>, <tt>"adjust"</tt>, <tt>">"</tt>。
394
+ * それぞれ以下のようになる。(FIXME: 「以下」)
395
+ * [_:exact_]
396
+ * +true+を指定すると完全一致で検索する
397
+ * [_:longest_common_prefix_]
398
+ * +true+を指定すると_query_と同じ接頭辞をもつエントリのう
399
+ * ち、もっとも長いエントリを検索する
400
+ * [_:suffix_]
401
+ * +true+を指定すると_query_が後方一致するエントリを検索す
402
+ * る
403
+ * [_:prefix_]
404
+ * +true+を指定すると_query_が前方一致するレコードを検索す
405
+ * る
406
+ * [_:near_]
407
+ * +true+を指定すると_query_に指定した複数の語が近傍に含ま
408
+ * れるレコードを検索する
409
+ * [...]
410
+ * ...
411
+ */
412
+ static VALUE
413
+ rb_grn_index_column_search (int argc, VALUE *argv, VALUE self)
414
+ {
415
+ grn_ctx *context;
416
+ grn_obj *column;
417
+ grn_obj *range;
418
+ grn_obj *query = NULL, *id_query = NULL, *string_query = NULL;
419
+ grn_obj *result;
420
+ grn_operator operator;
421
+ grn_rc rc;
422
+ VALUE rb_query, options, rb_result, rb_operator;
423
+
424
+ rb_grn_index_column_deconstruct(SELF(self), &column, &context,
425
+ NULL, NULL,
426
+ NULL, NULL, NULL, &range,
427
+ &id_query, &string_query);
428
+
429
+ rb_scan_args(argc, argv, "11", &rb_query, &options);
430
+
431
+ if (CBOOL2RVAL(rb_obj_is_kind_of(rb_query, rb_cGrnQuery))) {
432
+ grn_query *_query;
433
+ _query = RVAL2GRNQUERY(rb_query);
434
+ query = (grn_obj *)_query;
435
+ } else if (CBOOL2RVAL(rb_obj_is_kind_of(rb_query, rb_cInteger))) {
436
+ grn_id id;
437
+ id = NUM2UINT(rb_query);
438
+ GRN_TEXT_SET(context, id_query, &id, sizeof(grn_id));
439
+ query = id_query;
440
+ } else {
441
+ const char *_query;
442
+ _query = StringValuePtr(rb_query);
443
+ GRN_TEXT_SET(context, string_query, _query, RSTRING_LEN(rb_query));
444
+ query = string_query;
445
+ }
446
+
447
+ rb_grn_scan_options(options,
448
+ "result", &rb_result,
449
+ "operator", &rb_operator,
450
+ NULL);
451
+
452
+ if (NIL_P(rb_result)) {
453
+ result = grn_table_create(context, NULL, 0, NULL,
454
+ GRN_OBJ_TABLE_HASH_KEY | GRN_OBJ_WITH_SUBREC,
455
+ range, 0);
456
+ rb_grn_context_check(context, self);
457
+ rb_result = GRNOBJECT2RVAL(Qnil, context, result, RB_GRN_TRUE);
458
+ } else {
459
+ result = RVAL2GRNOBJECT(rb_result, &context);
460
+ }
461
+
462
+ operator = RVAL2GRNOPERATOR(rb_operator);
463
+
464
+ rc = grn_obj_search(context, column, query, result, operator, NULL);
465
+ rb_grn_rc_check(rc, self);
466
+
467
+ return rb_result;
468
+ }
469
+
470
+ void
471
+ rb_grn_init_index_column (VALUE mGrn)
472
+ {
473
+ rb_cGrnIndexColumn =
474
+ rb_define_class_under(mGrn, "IndexColumn", rb_cGrnColumn);
475
+
476
+ rb_define_method(rb_cGrnIndexColumn, "[]=",
477
+ rb_grn_index_column_array_set, 2);
478
+
479
+ rb_define_method(rb_cGrnIndexColumn, "sources",
480
+ rb_grn_index_column_get_sources, 0);
481
+ rb_define_method(rb_cGrnIndexColumn, "sources=",
482
+ rb_grn_index_column_set_sources, 1);
483
+ rb_define_method(rb_cGrnIndexColumn, "source=",
484
+ rb_grn_index_column_set_source, 1);
485
+
486
+ rb_define_method(rb_cGrnIndexColumn, "search",
487
+ rb_grn_index_column_search, -1);
488
+ }