groonga 0.9.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (186) hide show
  1. metadata +38 -227
  2. data/AUTHORS +0 -5
  3. data/NEWS.ja.rdoc +0 -114
  4. data/NEWS.rdoc +0 -116
  5. data/README.ja.rdoc +0 -63
  6. data/README.rdoc +0 -64
  7. data/Rakefile +0 -216
  8. data/benchmark/common.rb +0 -49
  9. data/benchmark/read-write-many-small-items.rb +0 -144
  10. data/benchmark/write-many-small-items.rb +0 -135
  11. data/example/bookmark.rb +0 -161
  12. data/example/index-html.rb +0 -89
  13. data/example/search/config.ru +0 -211
  14. data/example/search/public/css/groonga.css +0 -122
  15. data/ext/.gitignore +0 -2
  16. data/ext/rb-grn-accessor.c +0 -52
  17. data/ext/rb-grn-array-cursor.c +0 -36
  18. data/ext/rb-grn-array.c +0 -210
  19. data/ext/rb-grn-column.c +0 -570
  20. data/ext/rb-grn-context.c +0 -655
  21. data/ext/rb-grn-database.c +0 -415
  22. data/ext/rb-grn-encoding-support.c +0 -64
  23. data/ext/rb-grn-encoding.c +0 -257
  24. data/ext/rb-grn-exception.c +0 -1110
  25. data/ext/rb-grn-expression-builder.c +0 -75
  26. data/ext/rb-grn-expression.c +0 -732
  27. data/ext/rb-grn-fix-size-column.c +0 -166
  28. data/ext/rb-grn-hash-cursor.c +0 -38
  29. data/ext/rb-grn-hash.c +0 -294
  30. data/ext/rb-grn-index-column.c +0 -488
  31. data/ext/rb-grn-logger.c +0 -325
  32. data/ext/rb-grn-object.c +0 -1335
  33. data/ext/rb-grn-operation.c +0 -198
  34. data/ext/rb-grn-patricia-trie-cursor.c +0 -39
  35. data/ext/rb-grn-patricia-trie.c +0 -488
  36. data/ext/rb-grn-procedure.c +0 -52
  37. data/ext/rb-grn-query.c +0 -260
  38. data/ext/rb-grn-record.c +0 -40
  39. data/ext/rb-grn-snippet.c +0 -328
  40. data/ext/rb-grn-table-cursor-key-support.c +0 -69
  41. data/ext/rb-grn-table-cursor.c +0 -246
  42. data/ext/rb-grn-table-key-support.c +0 -731
  43. data/ext/rb-grn-table.c +0 -2038
  44. data/ext/rb-grn-type.c +0 -181
  45. data/ext/rb-grn-utils.c +0 -769
  46. data/ext/rb-grn-variable-size-column.c +0 -36
  47. data/ext/rb-grn-variable.c +0 -108
  48. data/ext/rb-grn.h +0 -684
  49. data/ext/rb-groonga.c +0 -113
  50. data/extconf.rb +0 -216
  51. data/html/bar.svg +0 -153
  52. data/html/developer.html +0 -121
  53. data/html/developer.svg +0 -469
  54. data/html/download.svg +0 -253
  55. data/html/favicon.ico +0 -0
  56. data/html/favicon.xcf +0 -0
  57. data/html/footer.html.erb +0 -28
  58. data/html/head.html.erb +0 -4
  59. data/html/header.html.erb +0 -17
  60. data/html/index.html +0 -147
  61. data/html/install.svg +0 -636
  62. data/html/logo.xcf +0 -0
  63. data/html/ranguba.css +0 -248
  64. data/html/tutorial.svg +0 -559
  65. data/lib/groonga.rb +0 -83
  66. data/lib/groonga/expression-builder.rb +0 -285
  67. data/lib/groonga/patricia-trie.rb +0 -53
  68. data/lib/groonga/record.rb +0 -276
  69. data/lib/groonga/schema.rb +0 -916
  70. data/license/GPL +0 -340
  71. data/license/LGPL +0 -504
  72. data/license/RUBY +0 -59
  73. data/misc/grnop2ruby.rb +0 -49
  74. data/pkg-config.rb +0 -333
  75. data/src/rb-grn-table-cursor.c +0 -296
  76. data/test-unit/Rakefile +0 -40
  77. data/test-unit/TODO +0 -5
  78. data/test-unit/bin/testrb +0 -5
  79. data/test-unit/html/classic.html +0 -15
  80. data/test-unit/html/index.html +0 -25
  81. data/test-unit/html/index.html.ja +0 -27
  82. data/test-unit/lib/test/unit.rb +0 -323
  83. data/test-unit/lib/test/unit/assertionfailederror.rb +0 -25
  84. data/test-unit/lib/test/unit/assertions.rb +0 -1230
  85. data/test-unit/lib/test/unit/attribute.rb +0 -125
  86. data/test-unit/lib/test/unit/autorunner.rb +0 -353
  87. data/test-unit/lib/test/unit/collector.rb +0 -36
  88. data/test-unit/lib/test/unit/collector/descendant.rb +0 -23
  89. data/test-unit/lib/test/unit/collector/dir.rb +0 -108
  90. data/test-unit/lib/test/unit/collector/load.rb +0 -136
  91. data/test-unit/lib/test/unit/collector/objectspace.rb +0 -34
  92. data/test-unit/lib/test/unit/color-scheme.rb +0 -102
  93. data/test-unit/lib/test/unit/color.rb +0 -96
  94. data/test-unit/lib/test/unit/diff.rb +0 -724
  95. data/test-unit/lib/test/unit/error.rb +0 -130
  96. data/test-unit/lib/test/unit/exceptionhandler.rb +0 -39
  97. data/test-unit/lib/test/unit/failure.rb +0 -136
  98. data/test-unit/lib/test/unit/fixture.rb +0 -176
  99. data/test-unit/lib/test/unit/notification.rb +0 -129
  100. data/test-unit/lib/test/unit/omission.rb +0 -191
  101. data/test-unit/lib/test/unit/pending.rb +0 -150
  102. data/test-unit/lib/test/unit/priority.rb +0 -181
  103. data/test-unit/lib/test/unit/runner/console.rb +0 -52
  104. data/test-unit/lib/test/unit/runner/emacs.rb +0 -8
  105. data/test-unit/lib/test/unit/runner/tap.rb +0 -8
  106. data/test-unit/lib/test/unit/testcase.rb +0 -476
  107. data/test-unit/lib/test/unit/testresult.rb +0 -89
  108. data/test-unit/lib/test/unit/testsuite.rb +0 -110
  109. data/test-unit/lib/test/unit/ui/console/outputlevel.rb +0 -14
  110. data/test-unit/lib/test/unit/ui/console/testrunner.rb +0 -464
  111. data/test-unit/lib/test/unit/ui/emacs/testrunner.rb +0 -63
  112. data/test-unit/lib/test/unit/ui/tap/testrunner.rb +0 -92
  113. data/test-unit/lib/test/unit/ui/testrunner.rb +0 -28
  114. data/test-unit/lib/test/unit/ui/testrunnermediator.rb +0 -77
  115. data/test-unit/lib/test/unit/ui/testrunnerutilities.rb +0 -41
  116. data/test-unit/lib/test/unit/util/backtracefilter.rb +0 -41
  117. data/test-unit/lib/test/unit/util/method-owner-finder.rb +0 -28
  118. data/test-unit/lib/test/unit/util/observable.rb +0 -90
  119. data/test-unit/lib/test/unit/util/procwrapper.rb +0 -48
  120. data/test-unit/lib/test/unit/version.rb +0 -7
  121. data/test-unit/sample/adder.rb +0 -13
  122. data/test-unit/sample/subtracter.rb +0 -12
  123. data/test-unit/sample/test_adder.rb +0 -20
  124. data/test-unit/sample/test_subtracter.rb +0 -20
  125. data/test-unit/sample/test_user.rb +0 -23
  126. data/test-unit/test/collector/test-descendant.rb +0 -133
  127. data/test-unit/test/collector/test-load.rb +0 -329
  128. data/test-unit/test/collector/test_dir.rb +0 -406
  129. data/test-unit/test/collector/test_objectspace.rb +0 -100
  130. data/test-unit/test/run-test.rb +0 -15
  131. data/test-unit/test/test-attribute.rb +0 -86
  132. data/test-unit/test/test-color-scheme.rb +0 -67
  133. data/test-unit/test/test-color.rb +0 -47
  134. data/test-unit/test/test-diff.rb +0 -518
  135. data/test-unit/test/test-emacs-runner.rb +0 -60
  136. data/test-unit/test/test-fixture.rb +0 -287
  137. data/test-unit/test/test-notification.rb +0 -33
  138. data/test-unit/test/test-omission.rb +0 -81
  139. data/test-unit/test/test-pending.rb +0 -70
  140. data/test-unit/test/test-priority.rb +0 -119
  141. data/test-unit/test/test-testcase.rb +0 -554
  142. data/test-unit/test/test_assertions.rb +0 -1151
  143. data/test-unit/test/test_error.rb +0 -26
  144. data/test-unit/test/test_failure.rb +0 -33
  145. data/test-unit/test/test_testresult.rb +0 -113
  146. data/test-unit/test/test_testsuite.rb +0 -129
  147. data/test-unit/test/testunit-test-util.rb +0 -14
  148. data/test-unit/test/ui/test_testrunmediator.rb +0 -20
  149. data/test-unit/test/util/test-method-owner-finder.rb +0 -38
  150. data/test-unit/test/util/test_backtracefilter.rb +0 -41
  151. data/test-unit/test/util/test_observable.rb +0 -102
  152. data/test-unit/test/util/test_procwrapper.rb +0 -36
  153. data/test/.gitignore +0 -1
  154. data/test/groonga-test-utils.rb +0 -106
  155. data/test/run-test.rb +0 -58
  156. data/test/test-array.rb +0 -97
  157. data/test/test-column.rb +0 -298
  158. data/test/test-context.rb +0 -73
  159. data/test/test-database.rb +0 -113
  160. data/test/test-encoding.rb +0 -33
  161. data/test/test-exception.rb +0 -93
  162. data/test/test-expression-builder.rb +0 -156
  163. data/test/test-expression.rb +0 -133
  164. data/test/test-fix-size-column.rb +0 -65
  165. data/test/test-gqtp.rb +0 -70
  166. data/test/test-hash.rb +0 -312
  167. data/test/test-index-column.rb +0 -81
  168. data/test/test-patricia-trie.rb +0 -189
  169. data/test/test-procedure.rb +0 -37
  170. data/test/test-query.rb +0 -22
  171. data/test/test-record.rb +0 -268
  172. data/test/test-remote.rb +0 -53
  173. data/test/test-schema.rb +0 -416
  174. data/test/test-snippet.rb +0 -121
  175. data/test/test-table-cursor.rb +0 -153
  176. data/test/test-table-offset-and-limit.rb +0 -102
  177. data/test/test-table-select-normalize.rb +0 -48
  178. data/test/test-table-select.rb +0 -145
  179. data/test/test-table.rb +0 -642
  180. data/test/test-type.rb +0 -61
  181. data/test/test-variable-size-column.rb +0 -98
  182. data/test/test-variable.rb +0 -28
  183. data/test/test-vector-column.rb +0 -76
  184. data/test/test-version.rb +0 -31
  185. data/text/TUTORIAL.ja.rdoc +0 -392
  186. data/text/expression.rdoc +0 -284
data/ext/rb-grn-table.c DELETED
@@ -1,2038 +0,0 @@
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) ((RbGrnTable *)DATA_PTR(object))
22
-
23
- VALUE rb_cGrnTable;
24
-
25
- static ID id_array_reference;
26
- static ID id_array_set;
27
-
28
- /*
29
- * Document-class: Groonga::Table < Groonga::Object
30
- *
31
- * Ruby/groongaが提供するテーブルのベースとなるクラス。このクラス
32
- * からGroonga::Array, Groonga::Hash, Groonga::PatriciaTrie
33
- * が継承されている。
34
- */
35
-
36
- grn_obj *
37
- rb_grn_table_from_ruby_object (VALUE object, grn_ctx **context)
38
- {
39
- if (!RVAL2CBOOL(rb_obj_is_kind_of(object, rb_cGrnTable))) {
40
- rb_raise(rb_eTypeError, "not a groonga table");
41
- }
42
-
43
- return RVAL2GRNOBJECT(object, context);
44
- }
45
-
46
- VALUE
47
- rb_grn_table_to_ruby_object (grn_ctx *context, grn_obj *table,
48
- rb_grn_boolean owner)
49
- {
50
- return GRNOBJECT2RVAL(Qnil, context, table, owner);
51
- }
52
-
53
- void
54
- rb_grn_table_finalizer (grn_ctx *context, grn_obj *object,
55
- RbGrnTable *rb_grn_table)
56
- {
57
- if (context && rb_grn_table->value)
58
- grn_obj_close(context, rb_grn_table->value);
59
- rb_grn_table->value = NULL;
60
- rb_grn_table->columns = Qnil;
61
- }
62
-
63
- void
64
- rb_grn_table_bind (RbGrnTable *rb_grn_table,
65
- grn_ctx *context, grn_obj *table)
66
- {
67
- RbGrnObject *rb_grn_object;
68
-
69
- rb_grn_object = RB_GRN_OBJECT(rb_grn_table);
70
- rb_grn_table->value = grn_obj_open(context, GRN_BULK, 0,
71
- rb_grn_object->range_id);
72
- rb_grn_table->columns = rb_ary_new();
73
- }
74
-
75
- void
76
- rb_grn_table_deconstruct (RbGrnTable *rb_grn_table,
77
- grn_obj **table,
78
- grn_ctx **context,
79
- grn_id *domain_id,
80
- grn_obj **domain,
81
- grn_obj **value,
82
- grn_id *range_id,
83
- grn_obj **range,
84
- VALUE *columns)
85
- {
86
- RbGrnObject *rb_grn_object;
87
-
88
- rb_grn_object = RB_GRN_OBJECT(rb_grn_table);
89
- rb_grn_object_deconstruct(rb_grn_object, table, context,
90
- domain_id, domain,
91
- range_id, range);
92
-
93
- if (value)
94
- *value = rb_grn_table->value;
95
- if (columns)
96
- *columns = rb_grn_table->columns;
97
- }
98
-
99
- static void
100
- rb_grn_table_mark (void *data)
101
- {
102
- RbGrnObject *rb_grn_object = data;
103
- RbGrnTable *rb_grn_table = data;
104
- grn_ctx *context;
105
- grn_obj *table;
106
-
107
- if (!rb_grn_object)
108
- return;
109
-
110
- context = rb_grn_object->context;
111
- table = rb_grn_object->object;
112
- if (!context || !table)
113
- return;
114
-
115
- if (!grn_obj_path(context, table))
116
- return;
117
-
118
- if (grn_obj_name(context, table, NULL, 0) == 0)
119
- return;
120
-
121
- rb_gc_mark(rb_grn_table->columns);
122
- }
123
-
124
- static VALUE
125
- rb_grn_table_alloc (VALUE klass)
126
- {
127
- return Data_Wrap_Struct(klass, rb_grn_table_mark, rb_grn_object_free, NULL);
128
- }
129
-
130
- grn_obj *
131
- rb_grn_table_open_raw (int argc, VALUE *argv,
132
- grn_ctx **context, VALUE *rb_context)
133
- {
134
- grn_obj *table;
135
- char *name = NULL, *path = NULL;
136
- unsigned name_size = 0;
137
- VALUE rb_path, options, rb_name;
138
-
139
- rb_scan_args(argc, argv, "01", &options);
140
-
141
- rb_grn_scan_options(options,
142
- "context", rb_context,
143
- "name", &rb_name,
144
- "path", &rb_path,
145
- NULL);
146
-
147
- *context = rb_grn_context_ensure(rb_context);
148
-
149
- if (!NIL_P(rb_name)) {
150
- name = StringValuePtr(rb_name);
151
- name_size = RSTRING_LEN(rb_name);
152
- }
153
-
154
- if (!NIL_P(rb_path))
155
- path = StringValueCStr(rb_path);
156
-
157
- table = grn_table_open(*context, name, name_size, path);
158
- return table;
159
- }
160
-
161
- static VALUE
162
- rb_grn_table_initialize (int argc, VALUE *argv, VALUE self)
163
- {
164
- grn_ctx *context = NULL;
165
- grn_obj *table;
166
- VALUE rb_context;
167
-
168
- table = rb_grn_table_open_raw(argc, argv, &context, &rb_context);
169
- rb_grn_object_assign(Qnil, self, rb_context, context, table);
170
- rb_grn_context_check(context, self);
171
-
172
- return Qnil;
173
- }
174
-
175
- /*
176
- * call-seq:
177
- * Groonga::Table.open(options={}) -> Groonga::Table
178
- * Groonga::Table.open(options={}) {|table| ... }
179
- *
180
- * 既存のテーブルを開く。ブロックを指定すると、そのブロック
181
- * に開かれたテーブルが渡され、ブロックを抜けると自動的にテ
182
- * ーブルが破棄される。
183
- *
184
- * _options_に指定可能な値は以下の通り。
185
- *
186
- * [+:context+]
187
- * テーブルが利用するGroonga::Context。省略すると
188
- * Groonga::Context.defaultを用いる。
189
- *
190
- * [+:name+]
191
- * 開こうとするテーブルの名前。
192
- *
193
- * [+:path+]
194
- * 開こうとするテーブルのパス。
195
- */
196
- static VALUE
197
- rb_grn_table_s_open (int argc, VALUE *argv, VALUE klass)
198
- {
199
- grn_user_data *user_data;
200
- VALUE rb_table = Qnil;
201
- grn_obj *table;
202
- grn_ctx *context = NULL;
203
- VALUE rb_context;
204
-
205
- table = rb_grn_table_open_raw(argc, argv, &context, &rb_context);
206
- rb_grn_context_check(context, rb_ary_new4(argc, argv));
207
-
208
- if (!table)
209
- rb_raise(rb_eGrnError,
210
- "unable to open table: %s: %s",
211
- rb_grn_inspect(klass),
212
- rb_grn_inspect(rb_ary_new4(argc, argv)));
213
-
214
- user_data = grn_obj_user_data(context, table);
215
- if (user_data && user_data->ptr) {
216
- rb_table = RB_GRN_OBJECT(user_data->ptr)->self;
217
- } else {
218
- if (klass == rb_cGrnTable) {
219
- klass = GRNOBJECT2RCLASS(table);
220
- } else {
221
- VALUE rb_class;
222
-
223
- rb_class = GRNOBJECT2RCLASS(table);
224
- if (rb_class != klass) {
225
- rb_raise(rb_eTypeError,
226
- "unexpected existing table type: %s: expected %s",
227
- rb_grn_inspect(rb_class),
228
- rb_grn_inspect(klass));
229
- }
230
- }
231
-
232
- rb_table = GRNOBJECT2RVAL(klass, context, table, RB_GRN_TRUE);
233
- }
234
-
235
- if (rb_block_given_p())
236
- return rb_ensure(rb_yield, rb_table, rb_grn_object_close, rb_table);
237
- else
238
- return rb_table;
239
- }
240
-
241
- static VALUE
242
- rb_grn_table_inspect_content (VALUE self, VALUE inspected)
243
- {
244
- RbGrnTable *rb_grn_table;
245
- grn_ctx *context = NULL;
246
- grn_obj *table;
247
- VALUE columns;
248
-
249
- rb_grn_table = SELF(self);
250
- if (!rb_grn_table)
251
- return inspected;
252
-
253
- rb_grn_table_deconstruct(rb_grn_table, &table, &context,
254
- NULL, NULL,
255
- NULL, NULL, NULL,
256
- &columns);
257
-
258
- if (!table)
259
- return inspected;
260
- if (!context)
261
- return inspected;
262
-
263
- if (table->header.type != GRN_TABLE_NO_KEY) {
264
- grn_obj value;
265
- grn_encoding encoding;
266
-
267
- rb_str_cat2(inspected, ", ");
268
- rb_str_cat2(inspected, "encoding: <");
269
- GRN_OBJ_INIT(&value, GRN_BULK, 0, GRN_ID_NIL);
270
- grn_obj_get_info(context, table, GRN_INFO_ENCODING, &value);
271
- encoding = *((grn_encoding *)GRN_BULK_HEAD(&value));
272
- grn_obj_close(context, &value);
273
-
274
- if (context->rc == GRN_SUCCESS)
275
- rb_str_concat(inspected, rb_inspect(GRNENCODING2RVAL(encoding)));
276
- else
277
- rb_str_cat2(inspected, "invalid");
278
-
279
- rb_str_cat2(inspected, ">");
280
- }
281
-
282
- rb_str_cat2(inspected, ", ");
283
- rb_str_cat2(inspected, "size: <");
284
- {
285
- char buf[21]; /* ceil(log10(2 ** 64)) + 1('\0') == 21 */
286
- snprintf(buf, sizeof(buf), "%u", grn_table_size(context, table));
287
- rb_str_cat2(inspected, buf);
288
- }
289
- rb_str_cat2(inspected, ">");
290
-
291
- /*
292
- rb_str_cat2(inspected, ", ");
293
- rb_str_cat2(inspected, "columns: <");
294
- rb_str_concat(inspected, rb_inspect(columns));
295
- rb_str_cat2(inspected, ">");
296
- */
297
-
298
- return inspected;
299
- }
300
-
301
- /*
302
- * call-seq:
303
- * _table_.inspect -> String
304
- *
305
- * テーブルの中身を人に見やすい文字列で返す。
306
- */
307
- static VALUE
308
- rb_grn_table_inspect (VALUE self)
309
- {
310
- VALUE inspected;
311
-
312
- inspected = rb_str_new2("");
313
- rb_grn_object_inspect_header(self, inspected);
314
- rb_grn_object_inspect_content(self, inspected);
315
- rb_grn_table_inspect_content(self, inspected);
316
- rb_grn_object_inspect_footer(self, inspected);
317
-
318
- return inspected;
319
- }
320
-
321
- /*
322
- * call-seq:
323
- * table.define_column(name, value_type, options={}) ->
324
- * Groonga::FixSizeColumnかGroonga::VariableSizeColumn
325
- *
326
- * テーブルに名前が_name_で型が_value_type_のカラムを定義
327
- * し、新しく定義されたカラムを返す。
328
- *
329
- * _options_に指定可能な値は以下の通り。
330
- *
331
- * [+:path+]
332
- * カラムを保存するパス。
333
- *
334
- * [+:persistent+]
335
- * +true+を指定すると永続カラムとなる。省略した場合は永
336
- * 続カラムとなる。+:path+を省略した場合は自動的にパスが
337
- * 付加される。
338
- *
339
- * [+:type+]
340
- * カラムの値の格納方法について指定する。省略した場合は、
341
- * +:scalar+になる。
342
- *
343
- * [+:scalar+]
344
- * スカラ値(単独の値)を格納する。
345
- *
346
- * [+:vector+]
347
- * 値の配列を格納する。
348
- *
349
- * [+:compress+]
350
- * 値の圧縮方法を指定する。省略した場合は、圧縮しない。
351
- *
352
- * [+:zlib+]
353
- * 値をzlib圧縮して格納する。
354
- *
355
- * [+:lzo+]
356
- * 値をlzo圧縮して格納する。
357
- */
358
- static VALUE
359
- rb_grn_table_define_column (int argc, VALUE *argv, VALUE self)
360
- {
361
- grn_ctx *context = NULL;
362
- grn_obj *table;
363
- grn_obj *value_type, *column;
364
- char *name = NULL, *path = NULL;
365
- unsigned name_size = 0;
366
- grn_obj_flags flags = 0;
367
- VALUE rb_name, rb_value_type;
368
- VALUE options, rb_path, rb_persistent, rb_compress, rb_type;
369
- VALUE columns;
370
- VALUE rb_column;
371
-
372
- rb_grn_table_deconstruct(SELF(self), &table, &context,
373
- NULL, NULL,
374
- NULL, NULL, NULL,
375
- &columns);
376
-
377
- rb_scan_args(argc, argv, "21", &rb_name, &rb_value_type, &options);
378
-
379
- name = StringValuePtr(rb_name);
380
- name_size = RSTRING_LEN(rb_name);
381
-
382
- rb_grn_scan_options(options,
383
- "path", &rb_path,
384
- "persistent", &rb_persistent,
385
- "type", &rb_type,
386
- "compress", &rb_compress,
387
- NULL);
388
-
389
- value_type = RVAL2GRNOBJECT(rb_value_type, &context);
390
-
391
- if ((NIL_P(rb_persistent) && grn_obj_path(context, table)) ||
392
- RVAL2CBOOL(rb_persistent)) {
393
- flags |= GRN_OBJ_PERSISTENT;
394
- }
395
-
396
- if (!NIL_P(rb_path)) {
397
- path = StringValueCStr(rb_path);
398
- if ((flags & GRN_OBJ_PERSISTENT) != GRN_OBJ_PERSISTENT) {
399
- rb_raise(rb_eArgError,
400
- "should not pass :path if :persistent is false: <%s>",
401
- path);
402
- }
403
- flags |= GRN_OBJ_PERSISTENT;
404
- }
405
-
406
- if (NIL_P(rb_type) ||
407
- (rb_grn_equal_option(rb_type, "scalar"))) {
408
- flags |= GRN_OBJ_COLUMN_SCALAR;
409
- } else if (rb_grn_equal_option(rb_type, "vector")) {
410
- flags |= GRN_OBJ_COLUMN_VECTOR;
411
- } else {
412
- rb_raise(rb_eArgError,
413
- "invalid column type: %s: "
414
- "available types: [:scalar, :vector, nil]",
415
- rb_grn_inspect(rb_type));
416
- }
417
-
418
- if (NIL_P(rb_compress)) {
419
- } else if (rb_grn_equal_option(rb_compress, "zlib")) {
420
- flags |= GRN_OBJ_COMPRESS_ZLIB;
421
- } else if (rb_grn_equal_option(rb_compress, "lzo")) {
422
- flags |= GRN_OBJ_COMPRESS_LZO;
423
- } else {
424
- rb_raise(rb_eArgError,
425
- "invalid compress type: %s: "
426
- "available types: [:zlib, :lzo, nil]",
427
- rb_grn_inspect(rb_compress));
428
- }
429
-
430
- column = grn_column_create(context, table, name, name_size,
431
- path, flags, value_type);
432
- rb_grn_context_check(context, self);
433
-
434
- rb_column = GRNCOLUMN2RVAL(Qnil, context, column, RB_GRN_TRUE);
435
- rb_ary_push(columns, rb_column);
436
- rb_grn_named_object_set_name(RB_GRN_NAMED_OBJECT(DATA_PTR(rb_column)),
437
- name, name_size);
438
-
439
- return rb_column;
440
- }
441
-
442
- /*
443
- * call-seq:
444
- * table.define_index_column(name, value_type, options={}) -> Groonga::IndexColumn
445
- *
446
- * テーブルに名前が_name_で型が_value_type_のインデックスカ
447
- * ラムを定義し、新しく定義されたカラムを返す。
448
- *
449
- * _options_に指定可能な値は以下の通り。
450
- *
451
- * [+:path+]
452
- * カラムを保存するパス。
453
- *
454
- * [+:persistent+]
455
- * +true+を指定すると永続カラムとなる。省略した場合は永
456
- * 続カラムとなる。+:path+を省略した場合は自動的にパスが
457
- * 付加される。
458
- *
459
- * [+:with_section+]
460
- * 転置索引にsection(段落情報)を合わせて格納する。
461
- *
462
- * [+:with_weight+]
463
- * 転置索引にweight情報を合わせて格納する。
464
- *
465
- * [+:with_position+]
466
- * 転置索引に出現位置情報を合わせて格納する。
467
- *
468
- * [+:source+]
469
- * インデックス対象となるカラムを指定する。+:sources+との併用はできない。
470
- *
471
- * [+:sources+]
472
- * インデックス対象となる複数のカラムを指定する。+:source+との併用はできない。
473
- */
474
- static VALUE
475
- rb_grn_table_define_index_column (int argc, VALUE *argv, VALUE self)
476
- {
477
- grn_ctx *context = NULL;
478
- grn_obj *table;
479
- grn_obj *value_type, *column;
480
- char *name = NULL, *path = NULL;
481
- unsigned name_size = 0;
482
- grn_obj_flags flags = GRN_OBJ_COLUMN_INDEX;
483
- VALUE rb_name, rb_value_type;
484
- VALUE options, rb_path, rb_persistent;
485
- VALUE rb_with_section, rb_with_weight, rb_with_position;
486
- VALUE rb_column, rb_source, rb_sources;
487
- VALUE columns;
488
-
489
- rb_grn_table_deconstruct(SELF(self), &table, &context,
490
- NULL, NULL,
491
- NULL, NULL, NULL,
492
- &columns);
493
-
494
- rb_scan_args(argc, argv, "21", &rb_name, &rb_value_type, &options);
495
-
496
- name = StringValuePtr(rb_name);
497
- name_size = RSTRING_LEN(rb_name);
498
-
499
- rb_grn_scan_options(options,
500
- "path", &rb_path,
501
- "persistent", &rb_persistent,
502
- "with_section", &rb_with_section,
503
- "with_weight", &rb_with_weight,
504
- "with_position", &rb_with_position,
505
- "source", &rb_source,
506
- "sources", &rb_sources,
507
- NULL);
508
-
509
- value_type = RVAL2GRNOBJECT(rb_value_type, &context);
510
-
511
- if ((NIL_P(rb_persistent) && grn_obj_path(context, table)) ||
512
- RVAL2CBOOL(rb_persistent)) {
513
- flags |= GRN_OBJ_PERSISTENT;
514
- }
515
-
516
- if (!NIL_P(rb_path)) {
517
- path = StringValueCStr(rb_path);
518
- if ((flags & GRN_OBJ_PERSISTENT) != GRN_OBJ_PERSISTENT) {
519
- rb_raise(rb_eArgError,
520
- "should not pass :path if :persistent is false: <%s>",
521
- path);
522
- }
523
- flags |= GRN_OBJ_PERSISTENT;
524
- }
525
-
526
- if (RVAL2CBOOL(rb_with_section))
527
- flags |= GRN_OBJ_WITH_SECTION;
528
-
529
- if (RVAL2CBOOL(rb_with_weight))
530
- flags |= GRN_OBJ_WITH_WEIGHT;
531
-
532
- if (NIL_P(rb_with_position) &&
533
- (table->header.type == GRN_TABLE_HASH_KEY ||
534
- table->header.type == GRN_TABLE_PAT_KEY)) {
535
- grn_id tokenizer_id;
536
- grn_obj *tokenizer;
537
-
538
- tokenizer = grn_obj_get_info(context, table,
539
- GRN_INFO_DEFAULT_TOKENIZER,
540
- NULL);
541
- tokenizer_id = grn_obj_id(context, tokenizer);
542
- if ((tokenizer_id == GRN_DB_UNIGRAM) ||
543
- (tokenizer_id == GRN_DB_BIGRAM) ||
544
- (tokenizer_id == GRN_DB_TRIGRAM)) {
545
- rb_with_position = Qtrue;
546
- }
547
- }
548
- if (RVAL2CBOOL(rb_with_position))
549
- flags |= GRN_OBJ_WITH_POSITION;
550
-
551
- if (!NIL_P(rb_source) && !NIL_P(rb_sources))
552
- rb_raise(rb_eArgError, "should not pass both of :source and :sources.");
553
-
554
- column = grn_column_create(context, table, name, name_size,
555
- path, flags, value_type);
556
- rb_grn_context_check(context, self);
557
-
558
- rb_column = GRNCOLUMN2RVAL(Qnil, context, column, RB_GRN_TRUE);
559
- if (!NIL_P(rb_source))
560
- rb_funcall(rb_column, rb_intern("source="), 1, rb_source);
561
- if (!NIL_P(rb_sources))
562
- rb_funcall(rb_column, rb_intern("sources="), 1, rb_sources);
563
-
564
- rb_ary_push(columns, rb_column);
565
- rb_grn_named_object_set_name(RB_GRN_NAMED_OBJECT(DATA_PTR(rb_column)),
566
- name, name_size);
567
-
568
- return rb_column;
569
- }
570
-
571
- /*
572
- * call-seq:
573
- * table.add_column(name, value_type, path)
574
- *
575
- * _value_type_を値の型として、_path_に保存されている永続的
576
- * なカラムを、テーブルの_name_に対応するカラムとして開く。
577
- */
578
- static VALUE
579
- rb_grn_table_add_column (VALUE self, VALUE rb_name, VALUE rb_value_type,
580
- VALUE rb_path)
581
- {
582
- grn_ctx *context = NULL;
583
- grn_obj *table;
584
- grn_obj *value_type, *column;
585
- char *name = NULL, *path = NULL;
586
- unsigned name_size = 0;
587
- VALUE rb_column;
588
- VALUE columns;
589
-
590
- rb_grn_table_deconstruct(SELF(self), &table, &context,
591
- NULL, NULL,
592
- NULL, NULL, NULL,
593
- &columns);
594
-
595
- name = StringValuePtr(rb_name);
596
- name_size = RSTRING_LEN(rb_name);
597
-
598
- value_type = RVAL2GRNOBJECT(rb_value_type, &context);
599
-
600
- path = StringValueCStr(rb_path);
601
-
602
- column = grn_column_open(context, table, name, name_size,
603
- path, value_type);
604
- rb_grn_context_check(context, self);
605
-
606
- rb_column = GRNCOLUMN2RVAL(Qnil, context, column, RB_GRN_TRUE);
607
- rb_iv_set(rb_column, "table", self);
608
- rb_ary_push(columns, rb_column);
609
- rb_grn_named_object_set_name(RB_GRN_NAMED_OBJECT(DATA_PTR(rb_column)),
610
- name, name_size);
611
-
612
- return rb_column;
613
- }
614
-
615
- /*
616
- * call-seq:
617
- * table.column(name) -> Groonga::Column or nil
618
- *
619
- * テーブルの_name_に対応するカラムを返す。カラムが存在しな
620
- * い場合は+nil+を返す。
621
- */
622
- VALUE
623
- rb_grn_table_get_column (VALUE self, VALUE rb_name)
624
- {
625
- grn_user_data *user_data;
626
- grn_ctx *context = NULL;
627
- grn_obj *table;
628
- grn_obj *column;
629
- const char *name = NULL;
630
- unsigned name_size = 0;
631
- rb_grn_boolean owner;
632
- VALUE rb_column;
633
- VALUE columns;
634
- VALUE *raw_columns;
635
- long i, n;
636
-
637
- rb_grn_table_deconstruct(SELF(self), &table, &context,
638
- NULL, NULL,
639
- NULL, NULL, NULL,
640
- &columns);
641
-
642
- switch (TYPE(rb_name)) {
643
- case T_SYMBOL:
644
- name = rb_id2name(SYM2ID(rb_name));
645
- name_size = strlen(name);
646
- break;
647
- case T_STRING:
648
- name = StringValuePtr(rb_name);
649
- name_size = RSTRING_LEN(rb_name);
650
- break;
651
- default:
652
- rb_raise(rb_eArgError,
653
- "column name should be String or Symbol: %s",
654
- rb_grn_inspect(rb_name));
655
- break;
656
- }
657
-
658
- raw_columns = RARRAY_PTR(columns);
659
- n = RARRAY_LEN(columns);
660
- for (i = 0; i < n; i++) {
661
- VALUE rb_column = raw_columns[i];
662
- RbGrnNamedObject *rb_grn_named_object;
663
-
664
- rb_grn_named_object = RB_GRN_NAMED_OBJECT(DATA_PTR(rb_column));
665
- if (rb_grn_named_object->name_size > 0 &&
666
- strncmp(name, rb_grn_named_object->name, name_size) == 0) {
667
- return rb_column;
668
- }
669
- }
670
-
671
- column = grn_obj_column(context, table, name, name_size);
672
- rb_grn_context_check(context, self);
673
- if (!column)
674
- return Qnil;
675
-
676
- user_data = grn_obj_user_data(context, column);
677
- if (user_data) {
678
- RbGrnObject *rb_grn_object;
679
- rb_grn_object = user_data->ptr;
680
- if (rb_grn_object) {
681
- rb_ary_push(columns, rb_grn_object->self);
682
- return rb_grn_object->self;
683
- }
684
- }
685
-
686
- owner = column->header.type == GRN_ACCESSOR;
687
- rb_column = GRNCOLUMN2RVAL(Qnil, context, column, owner);
688
- if (owner) {
689
- rb_iv_set(rb_column, "table", self);
690
- }
691
- rb_ary_push(columns, rb_column);
692
-
693
- return rb_column;
694
- }
695
-
696
- VALUE
697
- rb_grn_table_get_column_surely (VALUE self, VALUE rb_name)
698
- {
699
- VALUE rb_column;
700
-
701
- rb_column = rb_grn_table_get_column(self, rb_name);
702
- if (NIL_P(rb_column)) {
703
- rb_raise(rb_eGrnNoSuchColumn,
704
- "no such column: <%s>: <%s>",
705
- rb_grn_inspect(rb_name), rb_grn_inspect(self));
706
- }
707
- return rb_column;
708
- }
709
-
710
- /*
711
- * call-seq:
712
- * table.columns(name=nil) -> Groonga::Columnの配列
713
- *
714
- * テーブルの全てのカラムを返す。_name_が指定された場合はカ
715
- * ラム名の先頭が_name_で始まるカラムを返す。
716
- */
717
- static VALUE
718
- rb_grn_table_get_columns (int argc, VALUE *argv, VALUE self)
719
- {
720
- grn_ctx *context = NULL;
721
- grn_obj *table;
722
- grn_obj *columns;
723
- grn_rc rc;
724
- int n;
725
- grn_table_cursor *cursor;
726
- VALUE rb_name, rb_columns;
727
- char *name = NULL;
728
- unsigned name_size = 0;
729
-
730
- rb_grn_table_deconstruct(SELF(self), &table, &context,
731
- NULL, NULL,
732
- NULL, NULL, NULL,
733
- NULL);
734
-
735
- rb_scan_args(argc, argv, "01", &rb_name);
736
-
737
- if (!NIL_P(rb_name)) {
738
- name = StringValuePtr(rb_name);
739
- name_size = RSTRING_LEN(rb_name);
740
- }
741
-
742
- columns = grn_table_create(context, NULL, 0, NULL, GRN_TABLE_HASH_KEY,
743
- NULL, 0);
744
- n = grn_table_columns(context, table, name, name_size, columns);
745
- rb_grn_context_check(context, self);
746
-
747
- rb_columns = rb_ary_new2(n);
748
- if (n == 0)
749
- return rb_columns;
750
-
751
- cursor = grn_table_cursor_open(context, columns, NULL, 0, NULL, 0,
752
- 0, -1, GRN_CURSOR_ASCENDING);
753
- rb_grn_context_check(context, self);
754
- while (grn_table_cursor_next(context, cursor) != GRN_ID_NIL) {
755
- void *key;
756
- grn_id *column_id;
757
- grn_obj *column;
758
- VALUE rb_column;
759
-
760
- grn_table_cursor_get_key(context, cursor, &key);
761
- column_id = key;
762
- column = grn_ctx_at(context, *column_id);
763
- rb_column = GRNOBJECT2RVAL(Qnil, context, column, RB_GRN_FALSE);
764
- rb_ary_push(rb_columns, rb_column);
765
- }
766
- rc = grn_table_cursor_close(context, cursor);
767
- if (rc != GRN_SUCCESS) {
768
- rb_grn_context_check(context, self);
769
- rb_grn_rc_check(rc, self);
770
- }
771
-
772
- return rb_columns;
773
- }
774
-
775
- static grn_table_cursor *
776
- rb_grn_table_open_grn_cursor (int argc, VALUE *argv, VALUE self,
777
- grn_ctx **context)
778
- {
779
- grn_obj *table;
780
- grn_table_cursor *cursor;
781
- void *min_key = NULL, *max_key = NULL;
782
- unsigned min_key_size = 0, max_key_size = 0;
783
- int offset = 0, limit = -1;
784
- int flags = 0;
785
- VALUE options, rb_min, rb_max, rb_order, rb_greater_than, rb_less_than;
786
- VALUE rb_offset, rb_limit;
787
-
788
- rb_grn_table_deconstruct(SELF(self), &table, context,
789
- NULL, NULL,
790
- NULL, NULL, NULL,
791
- NULL);
792
-
793
- rb_scan_args(argc, argv, "01", &options);
794
-
795
- rb_grn_scan_options(options,
796
- "min", &rb_min,
797
- "max", &rb_max,
798
- "offset", &rb_offset,
799
- "limit", &rb_limit,
800
- "order", &rb_order,
801
- "greater_than", &rb_greater_than,
802
- "less_than", &rb_less_than,
803
- NULL);
804
-
805
- if (!NIL_P(rb_min)) {
806
- min_key = StringValuePtr(rb_min);
807
- min_key_size = RSTRING_LEN(rb_min);
808
- }
809
- if (!NIL_P(rb_max)) {
810
- max_key = StringValuePtr(rb_max);
811
- max_key_size = RSTRING_LEN(rb_max);
812
- }
813
- if (!NIL_P(rb_offset))
814
- offset = NUM2INT(rb_offset);
815
- if (!NIL_P(rb_limit))
816
- limit = NUM2INT(rb_limit);
817
-
818
- if (NIL_P(rb_order)) {
819
- } else if (rb_grn_equal_option(rb_order, "asc") ||
820
- rb_grn_equal_option(rb_order, "ascending")) {
821
- flags |= GRN_CURSOR_ASCENDING;
822
- } else if (rb_grn_equal_option(rb_order, "desc") ||
823
- rb_grn_equal_option(rb_order, "descending")) {
824
- flags |= GRN_CURSOR_DESCENDING;
825
- } else {
826
- rb_raise(rb_eArgError,
827
- "order should be one of "
828
- "[:asc, :ascending, :desc, :descending]: %s",
829
- rb_grn_inspect(rb_order));
830
- }
831
-
832
- if (RVAL2CBOOL(rb_greater_than))
833
- flags |= GRN_CURSOR_GT;
834
- if (RVAL2CBOOL(rb_less_than))
835
- flags |= GRN_CURSOR_LT;
836
-
837
- cursor = grn_table_cursor_open(*context, table,
838
- min_key, min_key_size,
839
- max_key, max_key_size,
840
- offset, limit, flags);
841
- rb_grn_context_check(*context, self);
842
-
843
- return cursor;
844
- }
845
-
846
- /*
847
- * call-seq:
848
- * table.open_cursor(options={}) -> Groonga::TableCursor
849
- * table.open_cursor(options={}) {|cursor| ... }
850
- *
851
- * カーソルを生成して返す。ブロックを指定すると、そのブロッ
852
- * クに生成したカーソルが渡され、ブロックを抜けると自動的に
853
- * カーソルが破棄される。
854
- *
855
- * _options_に指定可能な値は以下の通り。
856
- *
857
- * [+:min+]
858
- * キーの下限
859
- *
860
- * [+:max+]
861
- * キーの上限
862
- *
863
- * [+:offset+]
864
- * 該当する範囲のレコードのうち、(0ベースで)_:offset_番目
865
- * からレコードを取り出す。
866
- *
867
- * [+:limit+]
868
- * 該当する範囲のレコードのうち、_:limit_件のみを取り出す。
869
- * 省略された場合または-1が指定された場合は、全件が指定され
870
- * たものとみなす。
871
- *
872
- * [+:order+]
873
- * +:asc+または+:ascending+を指定すると昇順にレコードを取
874
- * り出す。
875
- * +:desc+または+:descending+を指定すると降順にレコードを
876
- * 取り出す。
877
- *
878
- * [+:greater_than+]
879
- * +true+を指定すると+:min+で指定した値に一致した[+key+]を
880
- * 範囲に含まない。
881
- *
882
- * [+:less_than+]
883
- * +true+を指定すると+:max+で指定した値に一致した[+key+]を
884
- * 範囲に含まない。
885
- */
886
- static VALUE
887
- rb_grn_table_open_cursor (int argc, VALUE *argv, VALUE self)
888
- {
889
- grn_ctx *context = NULL;
890
- grn_table_cursor *cursor;
891
- VALUE rb_cursor;
892
-
893
- cursor = rb_grn_table_open_grn_cursor(argc, argv, self, &context);
894
- rb_cursor = GRNTABLECURSOR2RVAL(Qnil, context, cursor);
895
- rb_iv_set(rb_cursor, "@table", self); /* FIXME: cursor should mark table */
896
- if (rb_block_given_p())
897
- return rb_ensure(rb_yield, rb_cursor, rb_grn_object_close, rb_cursor);
898
- else
899
- return rb_cursor;
900
- }
901
-
902
- /*
903
- * call-seq:
904
- * table.records -> Groonga::Recordの配列
905
- *
906
- * テーブルに登録されている全てのレコードが入っている配列を
907
- * 返す。
908
- */
909
- static VALUE
910
- rb_grn_table_get_records (int argc, VALUE *argv, VALUE self)
911
- {
912
- grn_ctx *context = NULL;
913
- grn_table_cursor *cursor;
914
- grn_id record_id;
915
- VALUE records;
916
-
917
- cursor = rb_grn_table_open_grn_cursor(argc, argv, self, &context);
918
- records = rb_ary_new();
919
- while ((record_id = grn_table_cursor_next(context, cursor))) {
920
- rb_ary_push(records, rb_grn_record_new(self, record_id, Qnil));
921
- }
922
- grn_table_cursor_close(context, cursor);
923
-
924
- return records;
925
- }
926
-
927
- /*
928
- * call-seq:
929
- * table.size -> レコード数
930
- *
931
- * テーブルに登録されているレコード数を返す。
932
- */
933
- static VALUE
934
- rb_grn_table_get_size (VALUE self)
935
- {
936
- grn_ctx *context = NULL;
937
- grn_obj *table;
938
- unsigned int size;
939
-
940
- rb_grn_table_deconstruct(SELF(self), &table, &context,
941
- NULL, NULL,
942
- NULL, NULL, NULL,
943
- NULL);
944
- size = grn_table_size(context, table);
945
- return UINT2NUM(size);
946
- }
947
-
948
- /*
949
- * call-seq:
950
- * table.truncate
951
- *
952
- * テーブルの全レコードを一括して削除する。
953
- */
954
- static VALUE
955
- rb_grn_table_truncate (VALUE self)
956
- {
957
- grn_ctx *context = NULL;
958
- grn_obj *table;
959
- grn_rc rc;
960
-
961
- rb_grn_table_deconstruct(SELF(self), &table, &context,
962
- NULL, NULL,
963
- NULL, NULL, NULL,
964
- NULL);
965
- rc = grn_table_truncate(context, table);
966
- rb_grn_rc_check(rc, self);
967
-
968
- return Qnil;
969
- }
970
-
971
- /*
972
- * call-seq:
973
- * table.each {|record| ...}
974
- *
975
- * テーブルに登録されているレコードを順番にブロックに渡す。
976
- */
977
- static VALUE
978
- rb_grn_table_each (VALUE self)
979
- {
980
- RbGrnTable *rb_table;
981
- RbGrnObject *rb_grn_object;
982
- grn_ctx *context = NULL;
983
- grn_obj *table;
984
- grn_table_cursor *cursor;
985
- VALUE rb_cursor;
986
- grn_id id;
987
-
988
- rb_table = SELF(self);
989
- rb_grn_table_deconstruct(rb_table, &table, &context,
990
- NULL, NULL,
991
- NULL, NULL, NULL,
992
- NULL);
993
- cursor = grn_table_cursor_open(context, table, NULL, 0, NULL, 0,
994
- 0, -1, GRN_CURSOR_ASCENDING);
995
- rb_cursor = GRNTABLECURSOR2RVAL(Qnil, context, cursor);
996
- rb_grn_object = RB_GRN_OBJECT(rb_table);
997
- while (rb_grn_object->object &&
998
- (id = grn_table_cursor_next(context, cursor)) != GRN_ID_NIL) {
999
- rb_yield(rb_grn_record_new(self, id, Qnil));
1000
- }
1001
- rb_grn_object_close(rb_cursor);
1002
-
1003
- return Qnil;
1004
- }
1005
-
1006
- /*
1007
- * call-seq:
1008
- * table.delete(id)
1009
- *
1010
- * テーブルの_id_に対応するレコードを削除する。
1011
- */
1012
- VALUE
1013
- rb_grn_table_delete (VALUE self, VALUE rb_id)
1014
- {
1015
- grn_ctx *context = NULL;
1016
- grn_obj *table;
1017
- grn_id id;
1018
- grn_rc rc;
1019
-
1020
- rb_grn_table_deconstruct(SELF(self), &table, &context,
1021
- NULL, NULL,
1022
- NULL, NULL, NULL,
1023
- NULL);
1024
-
1025
- id = NUM2UINT(rb_id);
1026
- rc = grn_table_delete_by_id(context, table, id);
1027
- rb_grn_rc_check(rc, self);
1028
-
1029
- return Qnil;
1030
- }
1031
-
1032
- /*
1033
- * call-seq:
1034
- * table.sort(keys, options={}) -> Groonga::Recordの配列
1035
- *
1036
- * テーブルに登録されているレコードを_keys_で指定されたルー
1037
- * ルに従ってソートしたレコードの配列を返す。
1038
- *
1039
- * [
1040
- * {:key => "カラム名", :order => :asc, :ascending,
1041
- * :desc, :descendingのいずれか},
1042
- * {:key => "カラム名", :order => :asc, :ascending,
1043
- * :desc, :descendingのいずれか},
1044
- * ...,
1045
- * ]
1046
- *
1047
- * _options_に指定可能な値は以下の通り。
1048
- *
1049
- * [+:offset+]
1050
- * ソートされたレコードのうち、(0ベースで)_:offset_番目
1051
- * からレコードを取り出す。
1052
- *
1053
- * [+:limit+]
1054
- * ソートされたレコードのうち、_:limit_件のみを取り出す。
1055
- * 省略された場合または-1が指定された場合は、全件が指定され
1056
- * たものとみなす。
1057
- */
1058
- static VALUE
1059
- rb_grn_table_sort (int argc, VALUE *argv, VALUE self)
1060
- {
1061
- grn_ctx *context = NULL;
1062
- grn_obj *table;
1063
- grn_obj *result;
1064
- grn_table_sort_key *keys;
1065
- int i, n_keys;
1066
- int n_records, offset = 0, limit = -1;
1067
- VALUE rb_keys, options;
1068
- VALUE rb_offset, rb_limit;
1069
- VALUE *rb_sort_keys;
1070
- grn_table_cursor *cursor;
1071
- VALUE rb_result;
1072
- VALUE exception;
1073
-
1074
- rb_grn_table_deconstruct(SELF(self), &table, &context,
1075
- NULL, NULL,
1076
- NULL, NULL, NULL,
1077
- NULL);
1078
-
1079
- rb_scan_args(argc, argv, "11", &rb_keys, &options);
1080
-
1081
- if (!RVAL2CBOOL(rb_obj_is_kind_of(rb_keys, rb_cArray)))
1082
- rb_raise(rb_eArgError, "keys should be an array of key: <%s>",
1083
- rb_grn_inspect(rb_keys));
1084
-
1085
- n_keys = RARRAY_LEN(rb_keys);
1086
- rb_sort_keys = RARRAY_PTR(rb_keys);
1087
- keys = ALLOCA_N(grn_table_sort_key, n_keys);
1088
- for (i = 0; i < n_keys; i++) {
1089
- VALUE rb_sort_options, rb_key, rb_order;
1090
-
1091
- if (RVAL2CBOOL(rb_obj_is_kind_of(rb_sort_keys[i], rb_cHash))) {
1092
- rb_sort_options = rb_sort_keys[i];
1093
- } else if (RVAL2CBOOL(rb_obj_is_kind_of(rb_sort_keys[i], rb_cArray))) {
1094
- rb_sort_options = rb_hash_new();
1095
- rb_hash_aset(rb_sort_options,
1096
- RB_GRN_INTERN("key"),
1097
- rb_ary_entry(rb_sort_keys[i], 0));
1098
- rb_hash_aset(rb_sort_options,
1099
- RB_GRN_INTERN("order"),
1100
- rb_ary_entry(rb_sort_keys[i], 1));
1101
- } else {
1102
- rb_sort_options = rb_hash_new();
1103
- rb_hash_aset(rb_sort_options,
1104
- RB_GRN_INTERN("key"),
1105
- rb_sort_keys[i]);
1106
- }
1107
- rb_grn_scan_options(rb_sort_options,
1108
- "key", &rb_key,
1109
- "order", &rb_order,
1110
- NULL);
1111
- if (RVAL2CBOOL(rb_obj_is_kind_of(rb_key, rb_cString)))
1112
- rb_key = rb_grn_table_get_column(self, rb_key);
1113
- keys[i].key = RVAL2GRNOBJECT(rb_key, &context);
1114
- if (NIL_P(rb_order)) {
1115
- keys[i].flags = 0;
1116
- } else if (rb_grn_equal_option(rb_order, "desc") ||
1117
- rb_grn_equal_option(rb_order, "descending")) {
1118
- keys[i].flags = GRN_TABLE_SORT_DESC;
1119
- } else if (rb_grn_equal_option(rb_order, "asc") ||
1120
- rb_grn_equal_option(rb_order, "ascending")) {
1121
- keys[i].flags = GRN_TABLE_SORT_ASC;
1122
- } else {
1123
- rb_raise(rb_eArgError,
1124
- "order should be one of "
1125
- "[nil, :desc, :descending, :asc, :ascending]: %s",
1126
- rb_grn_inspect(rb_order));
1127
- }
1128
- }
1129
-
1130
- rb_grn_scan_options(options,
1131
- "offset", &rb_offset,
1132
- "limit", &rb_limit,
1133
- NULL);
1134
-
1135
- if (!NIL_P(rb_offset))
1136
- offset = NUM2INT(rb_offset);
1137
- if (!NIL_P(rb_limit))
1138
- limit = NUM2INT(rb_limit);
1139
-
1140
- result = grn_table_create(context, NULL, 0, NULL, GRN_TABLE_NO_KEY,
1141
- NULL, table);
1142
- n_records = grn_table_sort(context, table, offset, limit,
1143
- result, keys, n_keys);
1144
- exception = rb_grn_context_to_exception(context, self);
1145
- if (!NIL_P(exception)) {
1146
- grn_obj_close(context, result);
1147
- rb_exc_raise(exception);
1148
- }
1149
-
1150
- rb_result = rb_ary_new();
1151
- cursor = grn_table_cursor_open(context, result, NULL, 0, NULL, 0,
1152
- 0, -1, GRN_CURSOR_ASCENDING);
1153
- while (grn_table_cursor_next(context, cursor) != GRN_ID_NIL) {
1154
- void *value;
1155
- grn_id *id;
1156
-
1157
- grn_table_cursor_get_value(context, cursor, &value);
1158
- id = value;
1159
- rb_ary_push(rb_result, rb_grn_record_new(self, *id, Qnil));
1160
- }
1161
- grn_table_cursor_close(context, cursor);
1162
- grn_obj_close(context, result);
1163
-
1164
- return rb_result;
1165
- }
1166
-
1167
- /*
1168
- * call-seq:
1169
- * table.group(column, options={}) -> Groonga::Hash
1170
- * table.group(column1, column2, ..., options={}) -> [Groonga::Hash, ...]
1171
- *
1172
- * _table_のレコードを_column1_, _column2_, _..._で指定したカ
1173
- * ラムの値でグループ化する。カラムはカラム名(文字列)でも
1174
- * 指定可能。
1175
- *
1176
- * このAPIは将来変更されます。
1177
- */
1178
- static VALUE
1179
- rb_grn_table_group (int argc, VALUE *argv, VALUE self)
1180
- {
1181
- grn_ctx *context = NULL;
1182
- grn_obj *table;
1183
- grn_table_sort_key *keys;
1184
- grn_table_group_result *results;
1185
- int i, n_keys, n_results;
1186
- grn_rc rc;
1187
- VALUE rb_keys;
1188
- VALUE *rb_sort_keys;
1189
- VALUE rb_results;
1190
-
1191
- rb_grn_table_deconstruct(SELF(self), &table, &context,
1192
- NULL, NULL,
1193
- NULL, NULL, NULL,
1194
- NULL);
1195
-
1196
- rb_scan_args(argc, argv, "00*", &rb_keys);
1197
-
1198
- n_keys = RARRAY_LEN(rb_keys);
1199
- rb_sort_keys = RARRAY_PTR(rb_keys);
1200
- if (n_keys == 1 && TYPE(rb_sort_keys[0]) == T_ARRAY) {
1201
- n_keys = RARRAY_LEN(rb_sort_keys[0]);
1202
- rb_sort_keys = RARRAY_PTR(rb_sort_keys[0]);
1203
- }
1204
- keys = ALLOCA_N(grn_table_sort_key, n_keys);
1205
- for (i = 0; i < n_keys; i++) {
1206
- VALUE rb_sort_options, rb_key;
1207
-
1208
- if (RVAL2CBOOL(rb_obj_is_kind_of(rb_sort_keys[i], rb_cHash))) {
1209
- rb_sort_options = rb_sort_keys[i];
1210
- } else {
1211
- rb_sort_options = rb_hash_new();
1212
- rb_hash_aset(rb_sort_options,
1213
- RB_GRN_INTERN("key"),
1214
- rb_sort_keys[i]);
1215
- }
1216
- rb_grn_scan_options(rb_sort_options,
1217
- "key", &rb_key,
1218
- NULL);
1219
- if (RVAL2CBOOL(rb_obj_is_kind_of(rb_key, rb_cString)))
1220
- rb_key = rb_grn_table_get_column(self, rb_key);
1221
- keys[i].key = RVAL2GRNOBJECT(rb_key, &context);
1222
- keys[i].flags = 0;
1223
- }
1224
-
1225
- n_results = n_keys;
1226
- results = ALLOCA_N(grn_table_group_result, n_results);
1227
- rb_results = rb_ary_new();
1228
- for (i = 0; i < n_results; i++) {
1229
- grn_obj *result;
1230
- grn_id range_id;
1231
- VALUE rb_result;
1232
-
1233
- range_id = grn_obj_get_range(context, keys[i].key);
1234
- result = grn_table_create(context, NULL, 0, NULL,
1235
- GRN_TABLE_HASH_KEY | GRN_OBJ_WITH_SUBREC,
1236
- grn_ctx_at(context, range_id), 0);
1237
- results[i].table = result;
1238
- results[i].key_begin = 0;
1239
- results[i].key_end = 0;
1240
- results[i].limit = 0;
1241
- results[i].flags = 0;
1242
- results[i].op = GRN_OP_OR;
1243
-
1244
- rb_result = GRNOBJECT2RVAL(Qnil, context, result, RB_GRN_TRUE);
1245
- rb_ary_push(rb_results, rb_result);
1246
- }
1247
-
1248
- rc = grn_table_group(context, table, keys, n_keys, results, n_results);
1249
- rb_grn_context_check(context, self);
1250
- rb_grn_rc_check(rc, self);
1251
-
1252
- if (n_results == 1)
1253
- return rb_ary_pop(rb_results);
1254
- else
1255
- return rb_results;
1256
- }
1257
-
1258
- /*
1259
- * Document-method: []
1260
- *
1261
- * call-seq:
1262
- * table[id] -> Groonga::Record
1263
- *
1264
- * _table_の_id_に対応するGroonga::Recordを返す。
1265
- *
1266
- * 0.9.0から値ではなくGroonga::Recordを返すようになった。
1267
- */
1268
- VALUE
1269
- rb_grn_table_array_reference (VALUE self, VALUE rb_id)
1270
- {
1271
- return rb_grn_record_new_raw(self, rb_id, Qnil);
1272
- }
1273
-
1274
- VALUE
1275
- rb_grn_table_get_value (VALUE self, VALUE rb_id)
1276
- {
1277
- grn_id id;
1278
- grn_ctx *context;
1279
- grn_obj *table;
1280
- grn_obj *range;
1281
- grn_obj *value;
1282
-
1283
- rb_grn_table_deconstruct(SELF(self), &table, &context,
1284
- NULL, NULL,
1285
- &value, NULL, &range,
1286
- NULL);
1287
-
1288
- id = NUM2UINT(rb_id);
1289
- GRN_BULK_REWIND(value);
1290
- grn_obj_get_value(context, table, id, value);
1291
- rb_grn_context_check(context, self);
1292
-
1293
- return GRNBULK2RVAL(context, value, range, self);
1294
- }
1295
-
1296
- /*
1297
- * Document-method: value
1298
- *
1299
- * call-seq:
1300
- * table.value(id) -> 値
1301
- * table.value(id, :id => true) -> 値
1302
- *
1303
- * _table_の_id_に対応する値を返す。
1304
- *
1305
- * <tt>:id => true</tt>が指定できるのは利便性のため。
1306
- * Groonga::ArrayでもGroonga::HashやGroonga::PatriciaTrieと
1307
- * 同じ引数で動くようになる。
1308
- */
1309
- static VALUE
1310
- rb_grn_table_get_value_convenience (int argc, VALUE *argv, VALUE self)
1311
- {
1312
- VALUE rb_id, rb_options;
1313
-
1314
- rb_scan_args(argc, argv, "11", &rb_id, &rb_options);
1315
- if (!NIL_P(rb_options)) {
1316
- VALUE rb_option_id;
1317
- rb_grn_scan_options(rb_options,
1318
- "id", &rb_option_id,
1319
- NULL);
1320
- if (!(NIL_P(rb_option_id) || RVAL2CBOOL(rb_option_id))) {
1321
- rb_raise(rb_eArgError, ":id options must be true or nil: %s: %s",
1322
- rb_grn_inspect(rb_option_id),
1323
- rb_grn_inspect(rb_ary_new3(2,
1324
- self, rb_ary_new4(argc, argv))));
1325
- }
1326
- }
1327
-
1328
- return rb_grn_table_get_value(self, rb_id);
1329
- }
1330
-
1331
- VALUE
1332
- rb_grn_table_set_value (VALUE self, VALUE rb_id, VALUE rb_value)
1333
- {
1334
- grn_id id;
1335
- grn_ctx *context;
1336
- grn_obj *table;
1337
- grn_obj *range;
1338
- grn_obj *value;
1339
- grn_rc rc;
1340
-
1341
- rb_grn_table_deconstruct(SELF(self), &table, &context,
1342
- NULL, NULL,
1343
- &value, NULL, &range,
1344
- NULL);
1345
-
1346
- id = NUM2UINT(rb_id);
1347
- GRN_BULK_REWIND(value);
1348
- RVAL2GRNBULK(rb_value, context, value);
1349
- rc = grn_obj_set_value(context, table, id, value, GRN_OBJ_SET);
1350
- rb_grn_context_check(context, self);
1351
- rb_grn_rc_check(rc, self);
1352
-
1353
- return Qnil;
1354
- }
1355
-
1356
- /*
1357
- * Document-method: set_value
1358
- *
1359
- * call-seq:
1360
- * table.set_value(id, value)
1361
- * table.set_value(id, value, :id => true)
1362
- *
1363
- * _table_の_id_に対応する値として_value_設定する。既存の値は
1364
- * 上書きされる。
1365
- *
1366
- * <tt>:id => true</tt>が指定できるのは利便性のため。
1367
- * Groonga::ArrayでもGroonga::HashやGroonga::PatriciaTrieと
1368
- * 同じ引数で動くようになる。
1369
- */
1370
- static VALUE
1371
- rb_grn_table_set_value_convenience (int argc, VALUE *argv, VALUE self)
1372
- {
1373
- VALUE rb_id, rb_value, rb_options;
1374
-
1375
- rb_scan_args(argc, argv, "21", &rb_id, &rb_value, &rb_options);
1376
- if (!NIL_P(rb_options)) {
1377
- VALUE rb_option_id;
1378
- rb_grn_scan_options(rb_options,
1379
- "id", &rb_option_id,
1380
- NULL);
1381
- if (!(NIL_P(rb_option_id) || RVAL2CBOOL(rb_option_id))) {
1382
- rb_raise(rb_eArgError, ":id options must be true or nil: %s: %s",
1383
- rb_grn_inspect(rb_option_id),
1384
- rb_grn_inspect(rb_ary_new3(2,
1385
- self, rb_ary_new4(argc, argv))));
1386
- }
1387
- }
1388
-
1389
- return rb_grn_table_set_value(self, rb_id, rb_value);
1390
- }
1391
-
1392
- VALUE
1393
- rb_grn_table_get_column_value_raw (VALUE self, grn_id id, VALUE rb_name)
1394
- {
1395
- VALUE rb_column;
1396
-
1397
- rb_column = rb_grn_table_get_column_surely(self, rb_name);
1398
-
1399
- /* TODO: improve speed. */
1400
- return rb_funcall(rb_column, id_array_reference, 1, INT2NUM(id));
1401
- }
1402
-
1403
- VALUE
1404
- rb_grn_table_get_column_value (VALUE self, VALUE rb_id, VALUE rb_name)
1405
- {
1406
- return rb_grn_table_get_column_value_raw(self, NUM2INT(rb_id), rb_name);
1407
- }
1408
-
1409
- /*
1410
- * Document-method: column_value
1411
- *
1412
- * call-seq:
1413
- * table.column_value(id, name) -> 値
1414
- * table.column_value(id, name, :id => true) -> 値
1415
- *
1416
- * _table_の_id_に対応するカラム_name_の値を返す。
1417
- *
1418
- * <tt>:id => true</tt>が指定できるのは利便性のため。
1419
- * Groonga::ArrayでもGroonga::HashやGroonga::PatriciaTrieと
1420
- * 同じ引数で動くようになる。
1421
- */
1422
- static VALUE
1423
- rb_grn_table_get_column_value_convenience (int argc, VALUE *argv, VALUE self)
1424
- {
1425
- VALUE rb_id, rb_name, rb_options;
1426
-
1427
- rb_scan_args(argc, argv, "21", &rb_id, &rb_name, &rb_options);
1428
- if (!NIL_P(rb_options)) {
1429
- VALUE rb_option_id;
1430
- rb_grn_scan_options(rb_options,
1431
- "id", &rb_option_id,
1432
- NULL);
1433
- if (!(NIL_P(rb_option_id) || RVAL2CBOOL(rb_option_id))) {
1434
- rb_raise(rb_eArgError, ":id options must be true or nil: %s: %s",
1435
- rb_grn_inspect(rb_option_id),
1436
- rb_grn_inspect(rb_ary_new3(2,
1437
- self,
1438
- rb_ary_new4(argc, argv))));
1439
- }
1440
- }
1441
-
1442
- return rb_grn_table_get_column_value(self, rb_id, rb_name);
1443
- }
1444
-
1445
- VALUE
1446
- rb_grn_table_set_column_value_raw (VALUE self, grn_id id,
1447
- VALUE rb_name, VALUE rb_value)
1448
- {
1449
- VALUE rb_column;
1450
-
1451
- rb_column = rb_grn_table_get_column_surely(self, rb_name);
1452
-
1453
- /* TODO: improve speed. */
1454
- return rb_funcall(rb_column, id_array_set, 2, INT2NUM(id), rb_value);
1455
- }
1456
-
1457
- VALUE
1458
- rb_grn_table_set_column_value (VALUE self, VALUE rb_id,
1459
- VALUE rb_name, VALUE rb_value)
1460
- {
1461
- return rb_grn_table_set_column_value_raw(self, NUM2INT(rb_id),
1462
- rb_name, rb_value);
1463
- }
1464
-
1465
- /*
1466
- * Document-method: set_column_value
1467
- *
1468
- * call-seq:
1469
- * table.set_column_value(id, name, value)
1470
- * table.set_column_value(id, name, value, :id => true)
1471
- *
1472
- * _table_の_id_に対応するカラム_name_の値として_value_設定す
1473
- * る。既存の値は上書きされる。
1474
- *
1475
- * <tt>:id => true</tt>が指定できるのは利便性のため。
1476
- * Groonga::ArrayでもGroonga::HashやGroonga::PatriciaTrieと
1477
- * 同じ引数で動くようになる。
1478
- */
1479
- static VALUE
1480
- rb_grn_table_set_column_value_convenience (int argc, VALUE *argv, VALUE self)
1481
- {
1482
- VALUE rb_id, rb_name, rb_value, rb_options;
1483
-
1484
- rb_scan_args(argc, argv, "31", &rb_id, &rb_name, &rb_value, &rb_options);
1485
- if (!NIL_P(rb_options)) {
1486
- VALUE rb_option_id;
1487
- rb_grn_scan_options(rb_options,
1488
- "id", &rb_option_id,
1489
- NULL);
1490
- if (!(NIL_P(rb_option_id) || RVAL2CBOOL(rb_option_id))) {
1491
- rb_raise(rb_eArgError, ":id options must be true or nil: %s: %s",
1492
- rb_grn_inspect(rb_option_id),
1493
- rb_grn_inspect(rb_ary_new3(2,
1494
- self,
1495
- rb_ary_new4(argc, argv))));
1496
- }
1497
- }
1498
-
1499
- return rb_grn_table_set_column_value(self, rb_id, rb_name, rb_value);
1500
- }
1501
-
1502
- /*
1503
- * Document-method: unlock
1504
- *
1505
- * call-seq:
1506
- * table.unlock(options={})
1507
- *
1508
- * _table_のロックを解除する。
1509
- *
1510
- * 利用可能なオプションは以下の通り。
1511
- *
1512
- * [_:id_]
1513
- * _:id_で指定したレコードのロックを解除する。(注:
1514
- * groonga側が未実装のため、現在は無視される)
1515
- */
1516
- static VALUE
1517
- rb_grn_table_unlock (int argc, VALUE *argv, VALUE self)
1518
- {
1519
- grn_id id = GRN_ID_NIL;
1520
- grn_ctx *context;
1521
- grn_obj *table;
1522
- grn_rc rc;
1523
- VALUE options, rb_id;
1524
-
1525
- rb_scan_args(argc, argv, "01", &options);
1526
-
1527
- rb_grn_table_deconstruct(SELF(self), &table, &context,
1528
- NULL, NULL,
1529
- NULL, NULL, NULL,
1530
- NULL);
1531
-
1532
- rb_grn_scan_options(options,
1533
- "id", &rb_id,
1534
- NULL);
1535
-
1536
- if (!NIL_P(rb_id))
1537
- id = NUM2UINT(rb_id);
1538
-
1539
- rc = grn_obj_unlock(context, table, id);
1540
- rb_grn_context_check(context, self);
1541
- rb_grn_rc_check(rc, self);
1542
-
1543
- return Qnil;
1544
- }
1545
-
1546
- static VALUE
1547
- rb_grn_table_unlock_ensure (VALUE self)
1548
- {
1549
- return rb_grn_table_unlock(0, NULL, self);
1550
- }
1551
-
1552
- /*
1553
- * Document-method: lock
1554
- *
1555
- * call-seq:
1556
- * table.lock(options={})
1557
- * table.lock(options={}) {...}
1558
- *
1559
- * _table_をロックする。ロックに失敗した場合は
1560
- * Groonga::ResourceDeadlockAvoided例外が発生する。
1561
- *
1562
- * ブロックを指定した場合はブロックを抜けたときにunlockする。
1563
- *
1564
- * 利用可能なオプションは以下の通り。
1565
- *
1566
- * [_:timeout_]
1567
- * ロックを獲得できなかった場合は_:timeout_秒間ロックの獲
1568
- * 得を試みる。_:timeout_秒以内にロックを獲得できなかった
1569
- * 場合は例外が発生する。
1570
- * [_:id_]
1571
- * _:id_で指定したレコードをロックする。(注: groonga側が
1572
- * 未実装のため、現在は無視される)
1573
- */
1574
- static VALUE
1575
- rb_grn_table_lock (int argc, VALUE *argv, VALUE self)
1576
- {
1577
- grn_id id = GRN_ID_NIL;
1578
- grn_ctx *context;
1579
- grn_obj *table;
1580
- int timeout = 0;
1581
- grn_rc rc;
1582
- VALUE options, rb_timeout, rb_id;
1583
-
1584
- rb_scan_args(argc, argv, "01", &options);
1585
-
1586
- rb_grn_table_deconstruct(SELF(self), &table, &context,
1587
- NULL, NULL,
1588
- NULL, NULL, NULL,
1589
- NULL);
1590
-
1591
- rb_grn_scan_options(options,
1592
- "timeout", &rb_timeout,
1593
- "id", &rb_id,
1594
- NULL);
1595
-
1596
- if (!NIL_P(rb_timeout))
1597
- timeout = NUM2UINT(rb_timeout);
1598
-
1599
- if (!NIL_P(rb_id))
1600
- id = NUM2UINT(rb_id);
1601
-
1602
- rc = grn_obj_lock(context, table, id, timeout);
1603
- rb_grn_context_check(context, self);
1604
- rb_grn_rc_check(rc, self);
1605
-
1606
- if (rb_block_given_p()) {
1607
- return rb_ensure(rb_yield, Qnil, rb_grn_table_unlock_ensure, self);
1608
- } else {
1609
- return Qnil;
1610
- }
1611
- }
1612
-
1613
- /*
1614
- * Document-method: clear_lock
1615
- *
1616
- * call-seq:
1617
- * table.clear_lock(options={})
1618
- *
1619
- * _table_のロックを強制的に解除する。
1620
- *
1621
- * 利用可能なオプションは以下の通り。
1622
- *
1623
- * [_:id_]
1624
- * _:id_で指定したレコードのロックを強制的に解除する。
1625
- * (注: groonga側が未実装のため、現在は無視される。実装さ
1626
- * れるのではないかと思っているが、実装されないかもしれな
1627
- * い。)
1628
- */
1629
- static VALUE
1630
- rb_grn_table_clear_lock (int argc, VALUE *argv, VALUE self)
1631
- {
1632
- grn_id id = GRN_ID_NIL;
1633
- grn_ctx *context;
1634
- grn_obj *table;
1635
- VALUE options, rb_id;
1636
-
1637
- rb_scan_args(argc, argv, "01", &options);
1638
-
1639
- rb_grn_table_deconstruct(SELF(self), &table, &context,
1640
- NULL, NULL,
1641
- NULL, NULL, NULL,
1642
- NULL);
1643
-
1644
- rb_grn_scan_options(options,
1645
- "id", &rb_id,
1646
- NULL);
1647
-
1648
- if (!NIL_P(rb_id))
1649
- id = NUM2UINT(rb_id);
1650
-
1651
- grn_obj_clear_lock(context, table);
1652
-
1653
- return Qnil;
1654
- }
1655
-
1656
- /*
1657
- * Document-method: locked?
1658
- *
1659
- * call-seq:
1660
- * table.locked?(options={})
1661
- *
1662
- * _table_がロックされていれば+true+を返す。
1663
- *
1664
- * 利用可能なオプションは以下の通り。
1665
- *
1666
- * [_:id_]
1667
- * _:id_で指定したレコードがロックされていれば+true+を返す。
1668
- * (注: groonga側が未実装のため、現在は無視される。実装さ
1669
- * れるのではないかと思っているが、実装されないかもしれな
1670
- * い。)
1671
- */
1672
- static VALUE
1673
- rb_grn_table_is_locked (int argc, VALUE *argv, VALUE self)
1674
- {
1675
- grn_id id = GRN_ID_NIL;
1676
- grn_ctx *context;
1677
- grn_obj *table;
1678
- VALUE options, rb_id;
1679
-
1680
- rb_scan_args(argc, argv, "01", &options);
1681
-
1682
- rb_grn_table_deconstruct(SELF(self), &table, &context,
1683
- NULL, NULL,
1684
- NULL, NULL, NULL,
1685
- NULL);
1686
-
1687
- rb_grn_scan_options(options,
1688
- "id", &rb_id,
1689
- NULL);
1690
-
1691
- if (!NIL_P(rb_id))
1692
- id = NUM2UINT(rb_id);
1693
-
1694
- return CBOOL2RVAL(grn_obj_is_locked(context, table));
1695
- }
1696
-
1697
- /*
1698
- * call-seq:
1699
- * table.select(options) {|record| ...} -> Groonga::Hash
1700
- * table.select(query, options) -> Groonga::Hash
1701
- * table.select(expression, options) -> Groonga::Hash
1702
- *
1703
- * _table_からブロックまたは文字列で指定した条件にマッチする
1704
- * レコードを返す。返されたテーブルには+expression+という特
1705
- * 異メソッドがあり、指定した条件を表している
1706
- * Groonga::Expressionを取得できる。
1707
- * Groonga::Expression#snippetを使うことにより、指定した条件
1708
- * 用のスニペットを簡単に生成できる。
1709
- *
1710
- * results = table.select do |record|
1711
- * record["description"] =~ "groonga"
1712
- * end
1713
- * snippet = results.expression.snippet([["<em>", "</em>"]])
1714
- * results.each do |record|
1715
- * puts "#{record['name']}の説明文の中で「groonga」が含まれる部分"
1716
- * snippet.execute(record["description"].each do |snippet|
1717
- * puts "---"
1718
- * puts "#{snippet}..."
1719
- * puts "---"
1720
- * end
1721
- * end
1722
- *
1723
- * 出力例
1724
- * Ruby/groongaの説明文の中で「groonga」が含まれる部分
1725
- * ---
1726
- * Ruby/<em>groonga</em>は<em>groonga</em>のいわゆるDB-APIの層の...
1727
- * ---
1728
- *
1729
- * _query_には「[カラム名]:[演算子][値]」という書式で条件を
1730
- * 指定する。演算子は以下の通り。
1731
- *
1732
- * [なし]
1733
- * [カラム値] == [値]
1734
- * [<tt>!</tt>]
1735
- * [カラム値] != [値]
1736
- * [<tt><</tt>]
1737
- * [カラム値] < [値]
1738
- * [<tt>></tt>]
1739
- * [カラム値] > [値]
1740
- * [<tt><=</tt>]
1741
- * [カラム値] <= [値]
1742
- * [<tt>>=</tt>]
1743
- * [カラム値] >= [値]
1744
- * [<tt>@</tt>]
1745
- * [カラム値]が[値]を含んでいるかどうか
1746
- *
1747
- * 例:
1748
- * "name:daijiro" # "name"カラムの値が"daijiro"のレコードにマッチ
1749
- * "description:@groonga" # "description"カラムが
1750
- * # "groonga"を含んでいるレコードにマッチ
1751
- *
1752
- * _expression_には既に作成済みのGroonga::Expressionを渡す
1753
- *
1754
- * ブロックで条件を指定する場合は
1755
- * Groonga::RecordExpressionBuilderを参照。
1756
- *
1757
- * _options_に指定可能な値は以下の通り。
1758
- *
1759
- * [+:operator+]
1760
- * マッチしたレコードをどのように扱うか。指定可能な値は以
1761
- * 下の通り。省略した場合はGroonga::Operation::OR。
1762
- *
1763
- * [Groonga::Operation::OR]
1764
- * マッチしたレコードを追加。すでにレコードが追加され
1765
- * ている場合は何もしない。
1766
- * [Groonga::Operation::AND]
1767
- * マッチしたレコードのスコアを増加。マッチしなかった
1768
- * レコードを削除。
1769
- * [Groonga::Operation::BUT]
1770
- * マッチしたレコードを削除。
1771
- * [Groonga::Operation::ADJUST]
1772
- * マッチしたレコードのスコアを増加。
1773
- *
1774
- * [+:result+]
1775
- * 検索結果を格納するテーブル。マッチしたレコードが追加さ
1776
- * れていく。省略した場合は新しくテーブルを作成して返す。
1777
- *
1778
- * [+:name+]
1779
- * 条件の名前。省略した場合は名前を付けない。
1780
- *
1781
- * [+:syntax+]
1782
- * _query_の構文。省略した場合は+:query+。
1783
- *
1784
- * 参考: Groonga::Expression#parse.
1785
- *
1786
- * [+:allow_pragma+]
1787
- * query構文時にプラグマを利用するかどうか。省略した場合は
1788
- * 利用する。
1789
- *
1790
- * 参考: Groonga::Expression#parse.
1791
- *
1792
- * [+:allow_column+]
1793
- * query構文時にカラム指定を利用するかどうか。省略した場合
1794
- * は利用する。
1795
- *
1796
- * 参考: Groonga::Expression#parse.
1797
- *
1798
- * [+:allow_update+]
1799
- * script構文時に更新操作を利用するかどうか。省略した場合
1800
- * は利用する。
1801
- *
1802
- * 参考: Groonga::Expression#parse.
1803
- */
1804
- static VALUE
1805
- rb_grn_table_select (int argc, VALUE *argv, VALUE self)
1806
- {
1807
- grn_ctx *context;
1808
- grn_obj *table, *result, *expression;
1809
- grn_operator operator = GRN_OP_OR;
1810
- VALUE rb_query = Qnil, condition_or_options, options;
1811
- VALUE rb_name, rb_operator, rb_result, rb_syntax;
1812
- VALUE rb_allow_pragma, rb_allow_column, rb_allow_update;
1813
- VALUE rb_expression = Qnil, builder;
1814
-
1815
- rb_scan_args(argc, argv, "02", &condition_or_options, &options);
1816
-
1817
- rb_grn_table_deconstruct(SELF(self), &table, &context,
1818
- NULL, NULL,
1819
- NULL, NULL, NULL,
1820
- NULL);
1821
-
1822
- if (RVAL2CBOOL(rb_obj_is_kind_of(condition_or_options, rb_cString))) {
1823
- rb_query = condition_or_options;
1824
- } else if (RVAL2CBOOL(rb_obj_is_kind_of(condition_or_options,
1825
- rb_cGrnExpression))) {
1826
- rb_expression = condition_or_options;
1827
- } else {
1828
- if (!NIL_P(options))
1829
- rb_raise(rb_eArgError,
1830
- "should be [query_string, option_hash], "
1831
- "[expression, opion_hash] "
1832
- "or [option_hash]: %s",
1833
- rb_grn_inspect(rb_ary_new4(argc, argv)));
1834
- options = condition_or_options;
1835
- }
1836
-
1837
- rb_grn_scan_options(options,
1838
- "operator", &rb_operator,
1839
- "result", &rb_result,
1840
- "name", &rb_name,
1841
- "syntax", &rb_syntax,
1842
- "allow_pragma", &rb_allow_pragma,
1843
- "allow_column", &rb_allow_column,
1844
- "allow_update", &rb_allow_update,
1845
- NULL);
1846
-
1847
- if (!NIL_P(rb_operator))
1848
- operator = NUM2INT(rb_operator);
1849
-
1850
- if (NIL_P(rb_result)) {
1851
- result = grn_table_create(context, NULL, 0, NULL,
1852
- GRN_TABLE_HASH_KEY | GRN_OBJ_WITH_SUBREC,
1853
- table,
1854
- 0);
1855
- rb_result = GRNTABLE2RVAL(context, result, RB_GRN_TRUE);
1856
- } else {
1857
- result = RVAL2GRNTABLE(rb_result, &context);
1858
- }
1859
-
1860
- if (NIL_P(rb_expression)) {
1861
- builder = rb_grn_record_expression_builder_new(self, rb_name);
1862
- rb_funcall(builder, rb_intern("query="), 1, rb_query);
1863
- rb_funcall(builder, rb_intern("syntax="), 1, rb_syntax);
1864
- rb_funcall(builder, rb_intern("allow_pragma="), 1, rb_allow_pragma);
1865
- rb_funcall(builder, rb_intern("allow_column="), 1, rb_allow_column);
1866
- rb_funcall(builder, rb_intern("allow_update="), 1, rb_allow_update);
1867
- rb_expression = rb_grn_record_expression_builder_build(builder);
1868
- }
1869
- rb_grn_object_deconstruct(RB_GRN_OBJECT(DATA_PTR(rb_expression)),
1870
- &expression, NULL,
1871
- NULL, NULL, NULL, NULL);
1872
-
1873
- grn_table_select(context, table, expression, result, operator);
1874
- rb_grn_context_check(context, self);
1875
-
1876
- rb_attr(rb_singleton_class(rb_result),
1877
- rb_intern("expression"),
1878
- RB_GRN_TRUE, RB_GRN_FALSE, RB_GRN_FALSE);
1879
- rb_iv_set(rb_result, "@expression", rb_expression);
1880
-
1881
- return rb_result;
1882
- }
1883
-
1884
- static VALUE
1885
- rb_grn_table_set_operation_bang (VALUE self, VALUE rb_other,
1886
- grn_operator operator)
1887
- {
1888
- grn_ctx *context;
1889
- grn_obj *table, *other;
1890
- grn_rc rc;
1891
-
1892
- rb_grn_table_deconstruct(SELF(self), &table, &context,
1893
- NULL, NULL,
1894
- NULL, NULL, NULL,
1895
- NULL);
1896
- rb_grn_table_deconstruct(SELF(rb_other), &other, NULL,
1897
- NULL, NULL,
1898
- NULL, NULL, NULL,
1899
- NULL);
1900
-
1901
- rc = grn_table_setoperation(context, table, other, table, operator);
1902
- rb_grn_context_check(context, self);
1903
- rb_grn_rc_check(rc, self);
1904
-
1905
- return self;
1906
- }
1907
-
1908
- /*
1909
- * call-seq:
1910
- * table.union!(other) -> Groonga::Table
1911
- *
1912
- * キーを比較し、_table_には登録されていない_other_のレコー
1913
- * ドを_table_に作成する。
1914
- *
1915
- */
1916
- static VALUE
1917
- rb_grn_table_union_bang (VALUE self, VALUE rb_other)
1918
- {
1919
- return rb_grn_table_set_operation_bang(self, rb_other, GRN_OP_OR);
1920
- }
1921
-
1922
-
1923
- /*
1924
- * call-seq:
1925
- * table.intersection!(other) -> Groonga::Table
1926
- *
1927
- * キーを比較し、_other_には登録されていないレコードを
1928
- * _table_から削除する。
1929
- *
1930
- */
1931
- static VALUE
1932
- rb_grn_table_intersection_bang (VALUE self, VALUE rb_other)
1933
- {
1934
- return rb_grn_table_set_operation_bang(self, rb_other, GRN_OP_AND);
1935
- }
1936
-
1937
- /*
1938
- * call-seq:
1939
- * table.difference!(other) -> Groonga::Table
1940
- *
1941
- * キーを比較し、_other_にも登録されているレコードを_table_
1942
- * から削除する。
1943
- *
1944
- */
1945
- static VALUE
1946
- rb_grn_table_difference_bang (VALUE self, VALUE rb_other)
1947
- {
1948
- return rb_grn_table_set_operation_bang(self, rb_other, GRN_OP_BUT);
1949
- }
1950
-
1951
- /*
1952
- * call-seq:
1953
- * table.merge!(other) -> Groonga::Table
1954
- *
1955
- * キーを比較し、_other_にも登録されている_table_のレコード
1956
- * のスコアを_other_のスコアと同値にする。
1957
- *
1958
- */
1959
- static VALUE
1960
- rb_grn_table_merge_bang (VALUE self, VALUE rb_other)
1961
- {
1962
- return rb_grn_table_set_operation_bang(self, rb_other, GRN_OP_ADJUST);
1963
- }
1964
-
1965
- void
1966
- rb_grn_init_table (VALUE mGrn)
1967
- {
1968
- id_array_reference = rb_intern("[]");
1969
- id_array_set = rb_intern("[]=");
1970
-
1971
- rb_cGrnTable = rb_define_class_under(mGrn, "Table", rb_cGrnObject);
1972
- rb_define_alloc_func(rb_cGrnTable, rb_grn_table_alloc);
1973
-
1974
- rb_include_module(rb_cGrnTable, rb_mEnumerable);
1975
-
1976
- rb_define_singleton_method(rb_cGrnTable, "open",
1977
- rb_grn_table_s_open, -1);
1978
-
1979
- rb_define_method(rb_cGrnTable, "initialize", rb_grn_table_initialize, -1);
1980
-
1981
- rb_define_method(rb_cGrnTable, "inspect", rb_grn_table_inspect, 0);
1982
-
1983
- rb_define_method(rb_cGrnTable, "define_column",
1984
- rb_grn_table_define_column, -1);
1985
- rb_define_method(rb_cGrnTable, "define_index_column",
1986
- rb_grn_table_define_index_column, -1);
1987
- rb_define_method(rb_cGrnTable, "add_column",
1988
- rb_grn_table_add_column, 3);
1989
- rb_define_method(rb_cGrnTable, "column",
1990
- rb_grn_table_get_column, 1);
1991
- rb_define_method(rb_cGrnTable, "columns",
1992
- rb_grn_table_get_columns, -1);
1993
-
1994
- rb_define_method(rb_cGrnTable, "open_cursor", rb_grn_table_open_cursor, -1);
1995
- rb_define_method(rb_cGrnTable, "records", rb_grn_table_get_records, -1);
1996
-
1997
- rb_define_method(rb_cGrnTable, "size", rb_grn_table_get_size, 0);
1998
- rb_define_method(rb_cGrnTable, "truncate", rb_grn_table_truncate, 0);
1999
-
2000
- rb_define_method(rb_cGrnTable, "each", rb_grn_table_each, 0);
2001
-
2002
- rb_define_method(rb_cGrnTable, "delete", rb_grn_table_delete, 1);
2003
-
2004
- rb_define_method(rb_cGrnTable, "sort", rb_grn_table_sort, -1);
2005
- rb_define_method(rb_cGrnTable, "group", rb_grn_table_group, -1);
2006
-
2007
- rb_define_method(rb_cGrnTable, "[]", rb_grn_table_array_reference, 1);
2008
- rb_undef_method(rb_cGrnTable, "[]=");
2009
-
2010
- rb_define_method(rb_cGrnTable, "value",
2011
- rb_grn_table_get_value_convenience, -1);
2012
- rb_define_method(rb_cGrnTable, "set_value",
2013
- rb_grn_table_set_value_convenience, -1);
2014
- rb_define_method(rb_cGrnTable, "column_value",
2015
- rb_grn_table_get_column_value_convenience, -1);
2016
- rb_define_method(rb_cGrnTable, "set_column_value",
2017
- rb_grn_table_set_column_value_convenience, -1);
2018
-
2019
- rb_define_method(rb_cGrnTable, "lock", rb_grn_table_lock, -1);
2020
- rb_define_method(rb_cGrnTable, "unlock", rb_grn_table_unlock, -1);
2021
- rb_define_method(rb_cGrnTable, "clear_lock", rb_grn_table_clear_lock, -1);
2022
- rb_define_method(rb_cGrnTable, "locked?", rb_grn_table_is_locked, -1);
2023
-
2024
- rb_define_method(rb_cGrnTable, "select", rb_grn_table_select, -1);
2025
-
2026
- rb_define_method(rb_cGrnTable, "union!", rb_grn_table_union_bang, 1);
2027
- rb_define_method(rb_cGrnTable, "intersection!",
2028
- rb_grn_table_intersection_bang, 1);
2029
- rb_define_method(rb_cGrnTable, "difference!",
2030
- rb_grn_table_difference_bang, 1);
2031
- rb_define_method(rb_cGrnTable, "merge!",
2032
- rb_grn_table_merge_bang, 1);
2033
-
2034
- rb_grn_init_table_key_support(mGrn);
2035
- rb_grn_init_array(mGrn);
2036
- rb_grn_init_hash(mGrn);
2037
- rb_grn_init_patricia_trie(mGrn);
2038
- }