groonga 0.0.1

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 (148) hide show
  1. data/AUTHORS +1 -0
  2. data/NEWS.ja.rdoc +5 -0
  3. data/NEWS.rdoc +5 -0
  4. data/README.ja.rdoc +53 -0
  5. data/README.rdoc +54 -0
  6. data/Rakefile +209 -0
  7. data/TUTORIAL.ja.rdoc +160 -0
  8. data/benchmark/small-many-items.rb +175 -0
  9. data/example/bookmark.rb +38 -0
  10. data/ext/.gitignore +2 -0
  11. data/ext/rb-grn-accessor.c +52 -0
  12. data/ext/rb-grn-array-cursor.c +28 -0
  13. data/ext/rb-grn-array.c +168 -0
  14. data/ext/rb-grn-column.c +273 -0
  15. data/ext/rb-grn-context.c +333 -0
  16. data/ext/rb-grn-database.c +128 -0
  17. data/ext/rb-grn-encoding.c +163 -0
  18. data/ext/rb-grn-exception.c +1014 -0
  19. data/ext/rb-grn-hash-cursor.c +30 -0
  20. data/ext/rb-grn-hash.c +40 -0
  21. data/ext/rb-grn-logger.c +277 -0
  22. data/ext/rb-grn-object.c +985 -0
  23. data/ext/rb-grn-patricia-trie-cursor.c +30 -0
  24. data/ext/rb-grn-patricia-trie.c +40 -0
  25. data/ext/rb-grn-procedure.c +52 -0
  26. data/ext/rb-grn-query.c +207 -0
  27. data/ext/rb-grn-record.c +33 -0
  28. data/ext/rb-grn-snippet.c +274 -0
  29. data/ext/rb-grn-table-cursor-key-support.c +55 -0
  30. data/ext/rb-grn-table-cursor.c +294 -0
  31. data/ext/rb-grn-table-key-support.c +299 -0
  32. data/ext/rb-grn-table.c +706 -0
  33. data/ext/rb-grn-type.c +114 -0
  34. data/ext/rb-grn-utils.c +578 -0
  35. data/ext/rb-grn.h +346 -0
  36. data/ext/rb-groonga.c +98 -0
  37. data/extconf.rb +171 -0
  38. data/html/bar.svg +153 -0
  39. data/html/developer.html +121 -0
  40. data/html/developer.svg +469 -0
  41. data/html/download.svg +253 -0
  42. data/html/footer.html.erb +28 -0
  43. data/html/head.html.erb +4 -0
  44. data/html/header.html.erb +17 -0
  45. data/html/index.html +153 -0
  46. data/html/install.svg +636 -0
  47. data/html/logo.xcf +0 -0
  48. data/html/ranguba.css +248 -0
  49. data/html/tutorial.svg +559 -0
  50. data/lib/groonga.rb +50 -0
  51. data/lib/groonga/record.rb +98 -0
  52. data/license/GPL +340 -0
  53. data/license/LGPL +504 -0
  54. data/license/RUBY +59 -0
  55. data/pkg-config.rb +328 -0
  56. data/test-unit/Rakefile +35 -0
  57. data/test-unit/TODO +5 -0
  58. data/test-unit/bin/testrb +5 -0
  59. data/test-unit/html/classic.html +15 -0
  60. data/test-unit/html/index.html +25 -0
  61. data/test-unit/html/index.html.ja +27 -0
  62. data/test-unit/lib/test/unit.rb +342 -0
  63. data/test-unit/lib/test/unit/assertionfailederror.rb +14 -0
  64. data/test-unit/lib/test/unit/assertions.rb +1149 -0
  65. data/test-unit/lib/test/unit/attribute.rb +125 -0
  66. data/test-unit/lib/test/unit/autorunner.rb +306 -0
  67. data/test-unit/lib/test/unit/collector.rb +43 -0
  68. data/test-unit/lib/test/unit/collector/descendant.rb +23 -0
  69. data/test-unit/lib/test/unit/collector/dir.rb +108 -0
  70. data/test-unit/lib/test/unit/collector/load.rb +135 -0
  71. data/test-unit/lib/test/unit/collector/objectspace.rb +34 -0
  72. data/test-unit/lib/test/unit/color-scheme.rb +86 -0
  73. data/test-unit/lib/test/unit/color.rb +96 -0
  74. data/test-unit/lib/test/unit/diff.rb +538 -0
  75. data/test-unit/lib/test/unit/error.rb +124 -0
  76. data/test-unit/lib/test/unit/exceptionhandler.rb +39 -0
  77. data/test-unit/lib/test/unit/failure.rb +110 -0
  78. data/test-unit/lib/test/unit/fixture.rb +176 -0
  79. data/test-unit/lib/test/unit/notification.rb +125 -0
  80. data/test-unit/lib/test/unit/omission.rb +143 -0
  81. data/test-unit/lib/test/unit/pending.rb +146 -0
  82. data/test-unit/lib/test/unit/priority.rb +161 -0
  83. data/test-unit/lib/test/unit/runner/console.rb +52 -0
  84. data/test-unit/lib/test/unit/runner/emacs.rb +8 -0
  85. data/test-unit/lib/test/unit/testcase.rb +360 -0
  86. data/test-unit/lib/test/unit/testresult.rb +89 -0
  87. data/test-unit/lib/test/unit/testsuite.rb +110 -0
  88. data/test-unit/lib/test/unit/ui/console/outputlevel.rb +14 -0
  89. data/test-unit/lib/test/unit/ui/console/testrunner.rb +220 -0
  90. data/test-unit/lib/test/unit/ui/emacs/testrunner.rb +49 -0
  91. data/test-unit/lib/test/unit/ui/testrunner.rb +20 -0
  92. data/test-unit/lib/test/unit/ui/testrunnermediator.rb +77 -0
  93. data/test-unit/lib/test/unit/ui/testrunnerutilities.rb +41 -0
  94. data/test-unit/lib/test/unit/util/backtracefilter.rb +41 -0
  95. data/test-unit/lib/test/unit/util/method-owner-finder.rb +28 -0
  96. data/test-unit/lib/test/unit/util/observable.rb +90 -0
  97. data/test-unit/lib/test/unit/util/procwrapper.rb +48 -0
  98. data/test-unit/lib/test/unit/version.rb +7 -0
  99. data/test-unit/sample/adder.rb +13 -0
  100. data/test-unit/sample/subtracter.rb +12 -0
  101. data/test-unit/sample/tc_adder.rb +18 -0
  102. data/test-unit/sample/tc_subtracter.rb +18 -0
  103. data/test-unit/sample/test_user.rb +22 -0
  104. data/test-unit/sample/ts_examples.rb +7 -0
  105. data/test-unit/test/collector/test-descendant.rb +135 -0
  106. data/test-unit/test/collector/test-load.rb +333 -0
  107. data/test-unit/test/collector/test_dir.rb +406 -0
  108. data/test-unit/test/collector/test_objectspace.rb +98 -0
  109. data/test-unit/test/run-test.rb +13 -0
  110. data/test-unit/test/test-attribute.rb +86 -0
  111. data/test-unit/test/test-color-scheme.rb +56 -0
  112. data/test-unit/test/test-color.rb +47 -0
  113. data/test-unit/test/test-diff.rb +477 -0
  114. data/test-unit/test/test-emacs-runner.rb +60 -0
  115. data/test-unit/test/test-fixture.rb +287 -0
  116. data/test-unit/test/test-notification.rb +33 -0
  117. data/test-unit/test/test-omission.rb +81 -0
  118. data/test-unit/test/test-pending.rb +70 -0
  119. data/test-unit/test/test-priority.rb +119 -0
  120. data/test-unit/test/test_assertions.rb +1082 -0
  121. data/test-unit/test/test_error.rb +26 -0
  122. data/test-unit/test/test_failure.rb +33 -0
  123. data/test-unit/test/test_testcase.rb +478 -0
  124. data/test-unit/test/test_testresult.rb +113 -0
  125. data/test-unit/test/test_testsuite.rb +129 -0
  126. data/test-unit/test/testunit-test-util.rb +14 -0
  127. data/test-unit/test/ui/test_testrunmediator.rb +20 -0
  128. data/test-unit/test/util/test-method-owner-finder.rb +38 -0
  129. data/test-unit/test/util/test_backtracefilter.rb +41 -0
  130. data/test-unit/test/util/test_observable.rb +102 -0
  131. data/test-unit/test/util/test_procwrapper.rb +36 -0
  132. data/test/.gitignore +1 -0
  133. data/test/groonga-test-utils.rb +90 -0
  134. data/test/run-test.rb +54 -0
  135. data/test/test-column.rb +190 -0
  136. data/test/test-context.rb +90 -0
  137. data/test/test-database.rb +62 -0
  138. data/test/test-encoding.rb +33 -0
  139. data/test/test-exception.rb +85 -0
  140. data/test/test-procedure.rb +35 -0
  141. data/test/test-query.rb +22 -0
  142. data/test/test-record.rb +188 -0
  143. data/test/test-snippet.rb +121 -0
  144. data/test/test-table-cursor.rb +51 -0
  145. data/test/test-table.rb +447 -0
  146. data/test/test-type.rb +52 -0
  147. data/test/test-version.rb +31 -0
  148. metadata +213 -0
@@ -0,0 +1,706 @@
1
+ /* -*- c-file-style: "ruby" -*- */
2
+ /*
3
+ Copyright (C) 2009 Kouhei Sutou <kou@clear-code.com>
4
+
5
+ This library is free software; you can redistribute it and/or
6
+ modify it under the terms of the GNU Lesser General Public
7
+ License version 2.1 as published by the Free Software Foundation.
8
+
9
+ This library is distributed in the hope that it will be useful,
10
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ Lesser General Public License for more details.
13
+
14
+ You should have received a copy of the GNU Lesser General Public
15
+ License along with this library; if not, write to the Free Software
16
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
+ */
18
+
19
+ #include "rb-grn.h"
20
+
21
+ #define SELF(object, context) (RVAL2GRNTABLE(object, context))
22
+
23
+ VALUE rb_cGrnTable;
24
+
25
+ grn_obj *
26
+ rb_grn_table_from_ruby_object (VALUE object, grn_ctx **context)
27
+ {
28
+ if (!RVAL2CBOOL(rb_obj_is_kind_of(object, rb_cGrnTable))) {
29
+ rb_raise(rb_eTypeError, "not a groonga table");
30
+ }
31
+
32
+ return RVAL2GRNOBJECT(object, context);
33
+ }
34
+
35
+ VALUE
36
+ rb_grn_table_to_ruby_object (grn_ctx *context, grn_obj *table,
37
+ rb_grn_boolean owner)
38
+ {
39
+ return GRNOBJECT2RVAL(rb_cGrnTable, context, table, owner);
40
+ }
41
+
42
+ VALUE
43
+ rb_grn_table_s_create (int argc, VALUE *argv, VALUE klass,
44
+ grn_obj_flags key_store)
45
+ {
46
+ grn_ctx *context;
47
+ grn_obj *key_type = NULL, *table;
48
+ const char *name = NULL, *path = NULL;
49
+ unsigned name_size = 0, value_size = 0;
50
+ grn_obj_flags flags = key_store;
51
+ VALUE rb_table;
52
+ VALUE options, rb_context, rb_name, rb_path, rb_persistent;
53
+ VALUE rb_key_normalize, rb_key_with_sis, rb_key_type;
54
+ VALUE rb_value_size;
55
+
56
+ rb_scan_args(argc, argv, "01", &options);
57
+
58
+ rb_grn_scan_options(options,
59
+ "context", &rb_context,
60
+ "name", &rb_name,
61
+ "path", &rb_path,
62
+ "persistent", &rb_persistent,
63
+ "key_normalize", &rb_key_normalize,
64
+ "key_with_sis", &rb_key_with_sis,
65
+ "key_type", &rb_key_type,
66
+ "value_size", &rb_value_size,
67
+ NULL);
68
+
69
+ context = rb_grn_context_ensure(rb_context);
70
+
71
+ if (!NIL_P(rb_name)) {
72
+ name = StringValuePtr(rb_name);
73
+ name_size = RSTRING_LEN(rb_name);
74
+ }
75
+
76
+ if (!NIL_P(rb_path)) {
77
+ path = StringValueCStr(rb_path);
78
+ flags |= GRN_OBJ_PERSISTENT;
79
+ }
80
+
81
+ if (RVAL2CBOOL(rb_persistent))
82
+ flags |= GRN_OBJ_PERSISTENT;
83
+
84
+ if (RVAL2CBOOL(rb_key_normalize))
85
+ flags |= GRN_OBJ_KEY_NORMALIZE;
86
+
87
+ if (RVAL2CBOOL(rb_key_with_sis))
88
+ flags |= GRN_OBJ_KEY_WITH_SIS;
89
+
90
+ if (NIL_P(rb_key_type)) {
91
+ flags |= GRN_OBJ_KEY_VAR_SIZE;
92
+ } else {
93
+ key_type = RVAL2GRNOBJECT(rb_key_type, &context);
94
+ }
95
+
96
+ if (!NIL_P(rb_value_size))
97
+ value_size = NUM2UINT(rb_value_size);
98
+
99
+ table = grn_table_create(context, name, name_size, path,
100
+ flags, key_type, value_size);
101
+ rb_table = GRNOBJECT2RVAL(klass, context, table, RB_GRN_TRUE);
102
+ rb_grn_context_check(context, rb_table);
103
+
104
+ if (rb_block_given_p())
105
+ return rb_ensure(rb_yield, rb_table, rb_grn_object_close, rb_table);
106
+ else
107
+ return rb_table;
108
+ }
109
+
110
+ static grn_obj *
111
+ rb_grn_table_open (int argc, VALUE *argv, grn_ctx **context)
112
+ {
113
+ grn_obj *table;
114
+ char *name = NULL, *path = NULL;
115
+ unsigned name_size = 0;
116
+ VALUE rb_path, options, rb_context, rb_name;
117
+
118
+ rb_scan_args(argc, argv, "01", &options);
119
+
120
+ rb_grn_scan_options(options,
121
+ "context", &rb_context,
122
+ "name", &rb_name,
123
+ "path", &rb_path,
124
+ NULL);
125
+
126
+ *context = rb_grn_context_ensure(rb_context);
127
+
128
+ if (!NIL_P(rb_name)) {
129
+ name = StringValuePtr(rb_name);
130
+ name_size = RSTRING_LEN(rb_name);
131
+ }
132
+
133
+ if (!NIL_P(rb_path))
134
+ path = StringValueCStr(rb_path);
135
+
136
+ table = grn_table_open(*context, name, name_size, path);
137
+ return table;
138
+ }
139
+
140
+ static VALUE
141
+ rb_grn_table_initialize (int argc, VALUE *argv, VALUE self)
142
+ {
143
+ grn_ctx *context = NULL;
144
+ grn_obj *table;
145
+
146
+ table = rb_grn_table_open(argc, argv, &context);
147
+ rb_grn_object_initialize(self, context, table);
148
+ rb_grn_context_check(context, self);
149
+
150
+ return Qnil;
151
+ }
152
+
153
+ static VALUE
154
+ rb_grn_table_s_open (int argc, VALUE *argv, VALUE klass)
155
+ {
156
+ grn_ctx *context = NULL;
157
+ grn_obj *table;
158
+ VALUE rb_table, rb_class;
159
+
160
+ table = rb_grn_table_open(argc, argv, &context);
161
+ rb_grn_context_check(context, rb_ary_new4(argc, argv));
162
+ if (klass != rb_cGrnTable) {
163
+ rb_class = GRNOBJECT2RCLASS(table);
164
+ if (klass != rb_class)
165
+ rb_raise(rb_eTypeError,
166
+ "unexpected existing table type: %s: expected %s",
167
+ rb_grn_inspect(rb_class),
168
+ rb_grn_inspect(klass));
169
+ }
170
+
171
+ rb_table = rb_grn_object_alloc(klass);
172
+ rb_grn_table_initialize(argc, argv, rb_table);
173
+ if (rb_block_given_p())
174
+ return rb_ensure(rb_yield, rb_table, rb_grn_object_close, rb_table);
175
+ else
176
+ return rb_table;
177
+ }
178
+
179
+ static VALUE
180
+ rb_grn_table_inspect_content (VALUE self, VALUE inspected)
181
+ {
182
+ grn_ctx *context = NULL;
183
+ grn_obj *table;
184
+
185
+ table = SELF(self, &context);
186
+
187
+ if (!table)
188
+ return inspected;
189
+
190
+ if (table->header.type != GRN_TABLE_NO_KEY) {
191
+ grn_obj value;
192
+ grn_encoding encoding;
193
+
194
+ rb_str_cat2(inspected, ", ");
195
+ rb_str_cat2(inspected, "encoding: <");
196
+ GRN_OBJ_INIT(&value, GRN_BULK, 0);
197
+ grn_obj_get_info(context, table, GRN_INFO_ENCODING, &value);
198
+ encoding = *((grn_encoding *)GRN_BULK_HEAD(&value));
199
+ grn_obj_close(context, &value);
200
+
201
+ if (context->rc == GRN_SUCCESS)
202
+ rb_str_concat(inspected, rb_inspect(GRNENCODING2RVAL(encoding)));
203
+ else
204
+ rb_str_cat2(inspected, "invalid");
205
+
206
+ rb_str_cat2(inspected, ">");
207
+ }
208
+
209
+ rb_str_cat2(inspected, ", ");
210
+ rb_str_cat2(inspected, "size: <");
211
+ {
212
+ char buf[21]; /* ceil(log10(2 ** 64)) + 1('\0') == 21 */
213
+ snprintf(buf, sizeof(buf), "%u", grn_table_size(context, table));
214
+ rb_str_cat2(inspected, buf);
215
+ }
216
+ rb_str_cat2(inspected, ">");
217
+
218
+ return inspected;
219
+ }
220
+
221
+ static VALUE
222
+ rb_grn_table_inspect (VALUE self)
223
+ {
224
+ VALUE inspected;
225
+
226
+ inspected = rb_str_new2("");
227
+ rb_grn_object_inspect_header(self, inspected);
228
+ rb_grn_object_inspect_content(self, inspected);
229
+ rb_grn_table_inspect_content(self, inspected);
230
+ rb_grn_object_inspect_footer(self, inspected);
231
+
232
+ return inspected;
233
+ }
234
+
235
+ static VALUE
236
+ rb_grn_table_define_column (int argc, VALUE *argv, VALUE self)
237
+ {
238
+ grn_ctx *context = NULL;
239
+ grn_obj *table;
240
+ grn_obj *value_type, *column;
241
+ char *name = NULL, *path = NULL;
242
+ unsigned name_size = 0;
243
+ grn_obj_flags flags = 0;
244
+ rb_grn_boolean use_default_type = RB_GRN_FALSE;
245
+ VALUE rb_name, rb_value_type;
246
+ VALUE options, rb_path, rb_persistent, rb_type;
247
+ VALUE rb_compress, rb_with_section, rb_with_weight, rb_with_position;
248
+
249
+ table = SELF(self, &context);
250
+
251
+ rb_scan_args(argc, argv, "21", &rb_name, &rb_value_type, &options);
252
+
253
+ name = StringValuePtr(rb_name);
254
+ name_size = RSTRING_LEN(rb_name);
255
+
256
+ rb_grn_scan_options(options,
257
+ "path", &rb_path,
258
+ "persistent", &rb_persistent,
259
+ "type", &rb_type,
260
+ "compress", &rb_compress,
261
+ "with_section", &rb_with_section,
262
+ "with_weight", &rb_with_weight,
263
+ "with_position", &rb_with_position,
264
+ NULL);
265
+
266
+ value_type = RVAL2GRNOBJECT(rb_value_type, &context);
267
+
268
+ if (!NIL_P(rb_path)) {
269
+ path = StringValueCStr(rb_path);
270
+ flags |= GRN_OBJ_PERSISTENT;
271
+ }
272
+
273
+ if (RVAL2CBOOL(rb_persistent))
274
+ flags |= GRN_OBJ_PERSISTENT;
275
+
276
+ if (NIL_P(rb_type)) {
277
+ use_default_type = RB_GRN_TRUE;
278
+ } else if (rb_grn_equal_option(rb_type, "index")) {
279
+ flags |= GRN_OBJ_COLUMN_INDEX;
280
+ } else if (rb_grn_equal_option(rb_type, "scalar")) {
281
+ flags |= GRN_OBJ_COLUMN_SCALAR;
282
+ } else if (rb_grn_equal_option(rb_type, "vector")) {
283
+ flags |= GRN_OBJ_COLUMN_VECTOR;
284
+ } else {
285
+ rb_raise(rb_eArgError,
286
+ "invalid column type: %s: "
287
+ "available types: [:index, :scalar, :vector, nil]",
288
+ rb_grn_inspect(rb_type));
289
+ }
290
+
291
+ if (NIL_P(rb_compress)) {
292
+ } else if (rb_grn_equal_option(rb_compress, "zlib")) {
293
+ flags |= GRN_OBJ_COMPRESS_ZLIB;
294
+ } else if (rb_grn_equal_option(rb_compress, "lzo")) {
295
+ flags |= GRN_OBJ_COMPRESS_LZO;
296
+ } else {
297
+ rb_raise(rb_eArgError,
298
+ "invalid compress type: %s: "
299
+ "available types: [:zlib, :lzo, nil]",
300
+ rb_grn_inspect(rb_compress));
301
+ }
302
+
303
+ if (RVAL2CBOOL(rb_with_section)) {
304
+ if (use_default_type)
305
+ flags |= GRN_OBJ_COLUMN_INDEX;
306
+ if (flags & GRN_OBJ_COLUMN_INDEX)
307
+ flags |= GRN_OBJ_WITH_SECTION;
308
+ else
309
+ rb_raise(rb_eArgError,
310
+ "{:with_section => true} requires "
311
+ "{:type => :index} option.");
312
+ }
313
+
314
+ if (RVAL2CBOOL(rb_with_weight)) {
315
+ if (use_default_type)
316
+ flags |= GRN_OBJ_COLUMN_INDEX;
317
+ if (flags & GRN_OBJ_COLUMN_INDEX)
318
+ flags |= GRN_OBJ_WITH_WEIGHT;
319
+ else
320
+ rb_raise(rb_eArgError,
321
+ "{:with_weight => true} requires "
322
+ "{:type => :index} option.");
323
+ }
324
+
325
+ if (RVAL2CBOOL(rb_with_position)) {
326
+ if (use_default_type)
327
+ flags |= GRN_OBJ_COLUMN_INDEX;
328
+ if (flags & GRN_OBJ_COLUMN_INDEX)
329
+ flags |= GRN_OBJ_WITH_POSITION;
330
+ else
331
+ rb_raise(rb_eArgError,
332
+ "{:with_position => true} requires "
333
+ "{:type => :index} option.");
334
+ }
335
+
336
+ column = grn_column_create(context, table, name, name_size,
337
+ path, flags, value_type);
338
+ rb_grn_context_check(context, self);
339
+
340
+ return GRNCOLUMN2RVAL(Qnil, context, column, RB_GRN_TRUE);
341
+ }
342
+
343
+ static VALUE
344
+ rb_grn_table_add_column (VALUE self, VALUE rb_name, VALUE rb_value_type,
345
+ VALUE rb_path)
346
+ {
347
+ grn_ctx *context = NULL;
348
+ grn_obj *table;
349
+ grn_obj *value_type, *column;
350
+ char *name = NULL, *path = NULL;
351
+ unsigned name_size = 0;
352
+
353
+ table = SELF(self, &context);
354
+
355
+ name = StringValuePtr(rb_name);
356
+ name_size = RSTRING_LEN(rb_name);
357
+
358
+ value_type = RVAL2GRNOBJECT(rb_value_type, &context);
359
+
360
+ path = StringValueCStr(rb_path);
361
+
362
+ column = grn_column_open(context, table, name, name_size,
363
+ path, value_type);
364
+ rb_grn_context_check(context, self);
365
+
366
+ return GRNCOLUMN2RVAL(Qnil, context, column, RB_GRN_TRUE);
367
+ }
368
+
369
+ static VALUE
370
+ rb_grn_table_get_column (VALUE self, VALUE rb_name)
371
+ {
372
+ grn_ctx *context = NULL;
373
+ grn_obj *table;
374
+ grn_obj *column;
375
+ char *name = NULL;
376
+ unsigned name_size = 0;
377
+ rb_grn_boolean owner;
378
+
379
+ table = SELF(self, &context);
380
+
381
+ name = StringValuePtr(rb_name);
382
+ name_size = RSTRING_LEN(rb_name);
383
+
384
+ column = grn_table_column(context, table, name, name_size);
385
+ rb_grn_context_check(context, self);
386
+
387
+ owner = (column && column->header.type == GRN_ACCESSOR);
388
+ return GRNCOLUMN2RVAL(Qnil, context, column, owner);
389
+ }
390
+
391
+ static VALUE
392
+ rb_grn_table_get_columns (int argc, VALUE *argv, VALUE self)
393
+ {
394
+ grn_ctx *context = NULL;
395
+ grn_obj *table;
396
+ grn_obj *columns;
397
+ grn_rc rc;
398
+ int n;
399
+ grn_table_cursor *cursor;
400
+ VALUE rb_name, rb_columns;
401
+ char *name = NULL;
402
+ unsigned name_size = 0;
403
+
404
+ table = SELF(self, &context);
405
+
406
+ rb_scan_args(argc, argv, "01", &rb_name);
407
+
408
+ if (!NIL_P(rb_name)) {
409
+ name = StringValuePtr(rb_name);
410
+ name_size = RSTRING_LEN(rb_name);
411
+ }
412
+
413
+ columns = grn_table_create(context, NULL, 0, NULL, GRN_TABLE_HASH_KEY,
414
+ NULL, 0);
415
+ n = grn_table_columns(context, table, name, name_size, columns);
416
+ rb_grn_context_check(context, self);
417
+
418
+ rb_columns = rb_ary_new2(n);
419
+ if (n == 0)
420
+ return rb_columns;
421
+
422
+ cursor = grn_table_cursor_open(context, columns, NULL, 0, NULL, 0,
423
+ GRN_CURSOR_ASCENDING);
424
+ rb_grn_context_check(context, self);
425
+ while (grn_table_cursor_next(context, cursor) != GRN_ID_NIL) {
426
+ void *key;
427
+ grn_id *column_id;
428
+ grn_obj *column;
429
+ VALUE rb_column;
430
+
431
+ grn_table_cursor_get_key(context, cursor, &key);
432
+ column_id = key;
433
+ column = grn_ctx_get(context, *column_id);
434
+ rb_column = GRNOBJECT2RVAL(Qnil, context, column, RB_GRN_FALSE);
435
+ rb_ary_push(rb_columns, rb_column);
436
+ }
437
+ rc = grn_table_cursor_close(context, cursor);
438
+ if (rc != GRN_SUCCESS) {
439
+ rb_grn_context_check(context, self);
440
+ rb_grn_rc_check(rc, self);
441
+ }
442
+
443
+ return rb_columns;
444
+ }
445
+
446
+ static grn_table_cursor *
447
+ rb_grn_table_open_grn_cursor (int argc, VALUE *argv, VALUE self,
448
+ grn_ctx **context)
449
+ {
450
+ grn_obj *table;
451
+ grn_table_cursor *cursor;
452
+ void *min_key = NULL, *max_key = NULL;
453
+ unsigned min_key_size = 0, max_key_size = 0;
454
+ int flags = 0;
455
+ VALUE options, rb_min, rb_max, rb_order, rb_greater_than, rb_less_than;
456
+
457
+ table = SELF(self, context);
458
+
459
+ rb_scan_args(argc, argv, "01", &options);
460
+
461
+ rb_grn_scan_options(options,
462
+ "min", &rb_min,
463
+ "max", &rb_max,
464
+ "order", &rb_order,
465
+ "greater_than", &rb_greater_than,
466
+ "less_than", &rb_less_than,
467
+ NULL);
468
+
469
+ if (!NIL_P(rb_min)) {
470
+ min_key = StringValuePtr(rb_min);
471
+ min_key_size = RSTRING_LEN(rb_min);
472
+ }
473
+ if (!NIL_P(rb_max)) {
474
+ max_key = StringValuePtr(rb_max);
475
+ max_key_size = RSTRING_LEN(rb_max);
476
+ }
477
+
478
+ if (NIL_P(rb_order)) {
479
+ } else if (rb_grn_equal_option(rb_order, "asc") ||
480
+ rb_grn_equal_option(rb_order, "ascending")) {
481
+ flags |= GRN_CURSOR_ASCENDING;
482
+ } else if (rb_grn_equal_option(rb_order, "desc") ||
483
+ rb_grn_equal_option(rb_order, "descending")) {
484
+ flags |= GRN_CURSOR_DESCENDING;
485
+ } else {
486
+ rb_raise(rb_eArgError,
487
+ "order should be one of "
488
+ "[:asc, :ascending, :desc, :descending]: %s",
489
+ rb_grn_inspect(rb_order));
490
+ }
491
+
492
+ if (RVAL2CBOOL(rb_greater_than))
493
+ flags |= GRN_CURSOR_GT;
494
+ if (RVAL2CBOOL(rb_less_than))
495
+ flags |= GRN_CURSOR_LT;
496
+
497
+ cursor = grn_table_cursor_open(*context, table,
498
+ min_key, min_key_size,
499
+ max_key, max_key_size,
500
+ flags);
501
+ rb_grn_context_check(*context, self);
502
+
503
+ return cursor;
504
+ }
505
+
506
+ static VALUE
507
+ rb_grn_table_open_cursor (int argc, VALUE *argv, VALUE self)
508
+ {
509
+ grn_ctx *context = NULL;
510
+ grn_table_cursor *cursor;
511
+ VALUE rb_cursor;
512
+
513
+ cursor = rb_grn_table_open_grn_cursor(argc, argv, self, &context);
514
+ rb_cursor = GRNTABLECURSOR2RVAL(Qnil, context, cursor);
515
+ rb_iv_set(rb_cursor, "@table", self); /* FIXME: cursor should mark table */
516
+ if (rb_block_given_p())
517
+ return rb_ensure(rb_yield, rb_cursor,
518
+ rb_grn_table_cursor_close, rb_cursor);
519
+ else
520
+ return rb_cursor;
521
+ }
522
+
523
+ static VALUE
524
+ rb_grn_table_get_records (int argc, VALUE *argv, VALUE self)
525
+ {
526
+ grn_ctx *context = NULL;
527
+ grn_table_cursor *cursor;
528
+ grn_id record_id;
529
+ VALUE records;
530
+
531
+ cursor = rb_grn_table_open_grn_cursor(argc, argv, self, &context);
532
+ records = rb_ary_new();
533
+ while ((record_id = grn_table_cursor_next(context, cursor))) {
534
+ rb_ary_push(records, rb_grn_record_new(self, record_id));
535
+ }
536
+ grn_table_cursor_close(context, cursor);
537
+
538
+ return records;
539
+ }
540
+
541
+ static VALUE
542
+ rb_grn_table_get_size (VALUE self)
543
+ {
544
+ grn_ctx *context = NULL;
545
+ grn_obj *table;
546
+ unsigned int size;
547
+
548
+ table = SELF(self, &context);
549
+ size = grn_table_size(context, table);
550
+ return UINT2NUM(size);
551
+ }
552
+
553
+ static VALUE
554
+ rb_grn_table_truncate (VALUE self)
555
+ {
556
+ grn_ctx *context = NULL;
557
+ grn_obj *table;
558
+ grn_rc rc;
559
+
560
+ table = SELF(self, &context);
561
+ rc = grn_table_truncate(context, table);
562
+ rb_grn_rc_check(rc, self);
563
+
564
+ return Qnil;
565
+ }
566
+
567
+ static VALUE
568
+ rb_grn_table_each (VALUE self)
569
+ {
570
+ grn_ctx *context = NULL;
571
+ grn_obj *table;
572
+ grn_table_cursor *cursor;
573
+ grn_id id;
574
+
575
+ table = SELF(self, &context);
576
+ cursor = grn_table_cursor_open(context, table, NULL, 0, NULL, 0, 0);
577
+ rb_iv_set(self, "cursor", GRNTABLECURSOR2RVAL(Qnil, context, cursor));
578
+ while ((id = grn_table_cursor_next(context, cursor)) != GRN_ID_NIL) {
579
+ rb_yield(rb_grn_record_new(self, id));
580
+ }
581
+ grn_table_cursor_close(context, cursor);
582
+ rb_iv_set(self, "cursor", Qnil);
583
+
584
+ return Qnil;
585
+ }
586
+
587
+ static VALUE
588
+ rb_grn_table_delete (VALUE self, VALUE rb_id)
589
+ {
590
+ grn_ctx *context = NULL;
591
+ grn_obj *table;
592
+ grn_id id;
593
+ grn_rc rc;
594
+
595
+ table = SELF(self, &context);
596
+
597
+ id = NUM2UINT(rb_id);
598
+ rc = grn_table_delete_by_id(context, table, id);
599
+ rb_grn_rc_check(rc, self);
600
+
601
+ return Qnil;
602
+ }
603
+
604
+ static VALUE
605
+ rb_grn_table_sort (int argc, VALUE *argv, VALUE self)
606
+ {
607
+ grn_ctx *context = NULL;
608
+ grn_obj *table;
609
+ grn_obj *result;
610
+ grn_table_sort_key *keys;
611
+ int n_records, limit = 0;
612
+ int i, n_keys;
613
+ VALUE rb_keys, options;
614
+ VALUE rb_limit;
615
+ VALUE *rb_sort_keys;
616
+
617
+ table = SELF(self, &context);
618
+
619
+ rb_scan_args(argc, argv, "11", &rb_keys, &options);
620
+ rb_grn_scan_options(options,
621
+ "limit", &rb_limit,
622
+ NULL);
623
+
624
+ n_keys = RARRAY_LEN(rb_keys);
625
+ rb_sort_keys = RARRAY_PTR(rb_keys);
626
+ keys = ALLOCA_N(grn_table_sort_key, n_keys);
627
+ for (i = 0; i < n_keys; i++) {
628
+ VALUE rb_sort_options, rb_key, rb_order;
629
+
630
+ if (RVAL2CBOOL(rb_obj_is_kind_of(rb_sort_keys[i], rb_cHash))) {
631
+ rb_sort_options = rb_sort_keys[i];
632
+ } else {
633
+ rb_sort_options = rb_hash_new();
634
+ rb_hash_aset(rb_sort_options,
635
+ RB_GRN_INTERN("key"),
636
+ rb_sort_keys[i]);
637
+ }
638
+ rb_grn_scan_options(rb_sort_options,
639
+ "key", &rb_key,
640
+ "order", &rb_order,
641
+ NULL);
642
+ if (RVAL2CBOOL(rb_obj_is_kind_of(rb_key, rb_cString)))
643
+ rb_key = rb_grn_table_get_column(self, rb_key);
644
+ keys[i].key = RVAL2GRNOBJECT(rb_key, &context);
645
+ if (NIL_P(rb_order)) {
646
+ keys[i].flags = 0;
647
+ } else if (rb_grn_equal_option(rb_order, "desc") ||
648
+ rb_grn_equal_option(rb_order, "descending")) {
649
+ keys[i].flags = GRN_TABLE_SORT_DESC;
650
+ } else {
651
+ /* FIXME: validation */
652
+ keys[i].flags = GRN_TABLE_SORT_ASC;
653
+ }
654
+ }
655
+
656
+ if (!NIL_P(rb_limit))
657
+ limit = NUM2INT(rb_limit);
658
+
659
+ result = grn_table_create(context, NULL, 0, NULL, GRN_TABLE_NO_KEY,
660
+ table, sizeof(grn_id));
661
+ n_records = grn_table_sort(context, table, limit,
662
+ result, keys, n_keys);
663
+
664
+ return GRNOBJECT2RVAL(Qnil, context, result, RB_GRN_TRUE);
665
+ }
666
+
667
+ void
668
+ rb_grn_init_table (VALUE mGrn)
669
+ {
670
+ rb_cGrnTable = rb_define_class_under(mGrn, "Table", rb_cGrnObject);
671
+
672
+ rb_include_module(rb_cGrnTable, rb_mEnumerable);
673
+
674
+ rb_define_singleton_method(rb_cGrnTable, "open",
675
+ rb_grn_table_s_open, -1);
676
+
677
+ rb_define_method(rb_cGrnTable, "initialize", rb_grn_table_initialize, -1);
678
+
679
+ rb_define_method(rb_cGrnTable, "inspect", rb_grn_table_inspect, 0);
680
+
681
+ rb_define_method(rb_cGrnTable, "define_column",
682
+ rb_grn_table_define_column, -1);
683
+ rb_define_method(rb_cGrnTable, "add_column",
684
+ rb_grn_table_add_column, 3);
685
+ rb_define_method(rb_cGrnTable, "column",
686
+ rb_grn_table_get_column, 1);
687
+ rb_define_method(rb_cGrnTable, "columns",
688
+ rb_grn_table_get_columns, -1);
689
+
690
+ rb_define_method(rb_cGrnTable, "open_cursor", rb_grn_table_open_cursor, -1);
691
+ rb_define_method(rb_cGrnTable, "records", rb_grn_table_get_records, -1);
692
+
693
+ rb_define_method(rb_cGrnTable, "size", rb_grn_table_get_size, 0);
694
+ rb_define_method(rb_cGrnTable, "truncate", rb_grn_table_truncate, 0);
695
+
696
+ rb_define_method(rb_cGrnTable, "each", rb_grn_table_each, 0);
697
+
698
+ rb_define_method(rb_cGrnTable, "delete", rb_grn_table_delete, 1);
699
+
700
+ rb_define_method(rb_cGrnTable, "sort", rb_grn_table_sort, -1);
701
+
702
+ rb_grn_init_table_key_support(mGrn);
703
+ rb_grn_init_array(mGrn);
704
+ rb_grn_init_hash(mGrn);
705
+ rb_grn_init_patricia_trie(mGrn);
706
+ }