rroonga 0.9.2-x86-mingw32

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