groonga 0.9.1 → 1.0.0

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 (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
- }