rroonga 0.9.2-x86-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (199) hide show
  1. data/AUTHORS +5 -0
  2. data/NEWS.ja.rdoc +114 -0
  3. data/NEWS.rdoc +116 -0
  4. data/README.ja.rdoc +65 -0
  5. data/README.rdoc +66 -0
  6. data/Rakefile +206 -0
  7. data/benchmark/common.rb +49 -0
  8. data/benchmark/read-write-many-small-items.rb +144 -0
  9. data/benchmark/write-many-small-items.rb +135 -0
  10. data/example/bookmark.rb +161 -0
  11. data/example/index-html.rb +89 -0
  12. data/example/search/config.ru +230 -0
  13. data/example/search/public/css/groonga.css +122 -0
  14. data/ext/.gitignore +2 -0
  15. data/ext/groonga/extconf.rb +93 -0
  16. data/ext/groonga/rb-grn-accessor.c +52 -0
  17. data/ext/groonga/rb-grn-array-cursor.c +36 -0
  18. data/ext/groonga/rb-grn-array.c +210 -0
  19. data/ext/groonga/rb-grn-column.c +573 -0
  20. data/ext/groonga/rb-grn-context.c +662 -0
  21. data/ext/groonga/rb-grn-database.c +472 -0
  22. data/ext/groonga/rb-grn-encoding-support.c +64 -0
  23. data/ext/groonga/rb-grn-encoding.c +257 -0
  24. data/ext/groonga/rb-grn-exception.c +1110 -0
  25. data/ext/groonga/rb-grn-expression-builder.c +75 -0
  26. data/ext/groonga/rb-grn-expression.c +731 -0
  27. data/ext/groonga/rb-grn-fix-size-column.c +166 -0
  28. data/ext/groonga/rb-grn-hash-cursor.c +38 -0
  29. data/ext/groonga/rb-grn-hash.c +294 -0
  30. data/ext/groonga/rb-grn-index-column.c +488 -0
  31. data/ext/groonga/rb-grn-logger.c +504 -0
  32. data/ext/groonga/rb-grn-object.c +1369 -0
  33. data/ext/groonga/rb-grn-operation.c +198 -0
  34. data/ext/groonga/rb-grn-patricia-trie-cursor.c +39 -0
  35. data/ext/groonga/rb-grn-patricia-trie.c +488 -0
  36. data/ext/groonga/rb-grn-procedure.c +52 -0
  37. data/ext/groonga/rb-grn-query.c +260 -0
  38. data/ext/groonga/rb-grn-record.c +40 -0
  39. data/ext/groonga/rb-grn-snippet.c +334 -0
  40. data/ext/groonga/rb-grn-table-cursor-key-support.c +69 -0
  41. data/ext/groonga/rb-grn-table-cursor.c +247 -0
  42. data/ext/groonga/rb-grn-table-key-support.c +714 -0
  43. data/ext/groonga/rb-grn-table.c +1977 -0
  44. data/ext/groonga/rb-grn-type.c +181 -0
  45. data/ext/groonga/rb-grn-utils.c +769 -0
  46. data/ext/groonga/rb-grn-variable-size-column.c +36 -0
  47. data/ext/groonga/rb-grn-variable.c +108 -0
  48. data/ext/groonga/rb-grn-view-accessor.c +53 -0
  49. data/ext/groonga/rb-grn-view-cursor.c +35 -0
  50. data/ext/groonga/rb-grn-view-record.c +41 -0
  51. data/ext/groonga/rb-grn-view.c +421 -0
  52. data/ext/groonga/rb-grn.h +698 -0
  53. data/ext/groonga/rb-groonga.c +107 -0
  54. data/extconf.rb +130 -0
  55. data/html/bar.svg +153 -0
  56. data/html/developer.html +117 -0
  57. data/html/developer.svg +469 -0
  58. data/html/download.svg +253 -0
  59. data/html/favicon.ico +0 -0
  60. data/html/favicon.xcf +0 -0
  61. data/html/footer.html.erb +28 -0
  62. data/html/head.html.erb +4 -0
  63. data/html/header.html.erb +17 -0
  64. data/html/index.html +147 -0
  65. data/html/install.svg +636 -0
  66. data/html/logo.xcf +0 -0
  67. data/html/ranguba.css +250 -0
  68. data/html/tutorial.svg +559 -0
  69. data/lib/1.8/groonga.so +0 -0
  70. data/lib/1.9/groonga.so +0 -0
  71. data/lib/groonga.rb +90 -0
  72. data/lib/groonga/context.rb +184 -0
  73. data/lib/groonga/expression-builder.rb +324 -0
  74. data/lib/groonga/patricia-trie.rb +85 -0
  75. data/lib/groonga/record.rb +311 -0
  76. data/lib/groonga/schema.rb +1191 -0
  77. data/lib/groonga/view-record.rb +56 -0
  78. data/license/GPL +340 -0
  79. data/license/LGPL +504 -0
  80. data/license/RUBY +59 -0
  81. data/misc/grnop2ruby.rb +49 -0
  82. data/pkg-config.rb +333 -0
  83. data/rroonga-build.rb +57 -0
  84. data/test-unit/Rakefile +40 -0
  85. data/test-unit/TODO +5 -0
  86. data/test-unit/bin/testrb +5 -0
  87. data/test-unit/html/classic.html +15 -0
  88. data/test-unit/html/index.html +25 -0
  89. data/test-unit/html/index.html.ja +27 -0
  90. data/test-unit/lib/test/unit.rb +323 -0
  91. data/test-unit/lib/test/unit/assertionfailederror.rb +25 -0
  92. data/test-unit/lib/test/unit/assertions.rb +1230 -0
  93. data/test-unit/lib/test/unit/attribute.rb +125 -0
  94. data/test-unit/lib/test/unit/autorunner.rb +360 -0
  95. data/test-unit/lib/test/unit/collector.rb +36 -0
  96. data/test-unit/lib/test/unit/collector/descendant.rb +23 -0
  97. data/test-unit/lib/test/unit/collector/dir.rb +108 -0
  98. data/test-unit/lib/test/unit/collector/load.rb +144 -0
  99. data/test-unit/lib/test/unit/collector/objectspace.rb +34 -0
  100. data/test-unit/lib/test/unit/color-scheme.rb +102 -0
  101. data/test-unit/lib/test/unit/color.rb +96 -0
  102. data/test-unit/lib/test/unit/diff.rb +724 -0
  103. data/test-unit/lib/test/unit/error.rb +130 -0
  104. data/test-unit/lib/test/unit/exceptionhandler.rb +39 -0
  105. data/test-unit/lib/test/unit/failure.rb +136 -0
  106. data/test-unit/lib/test/unit/fixture.rb +176 -0
  107. data/test-unit/lib/test/unit/notification.rb +129 -0
  108. data/test-unit/lib/test/unit/omission.rb +191 -0
  109. data/test-unit/lib/test/unit/pending.rb +150 -0
  110. data/test-unit/lib/test/unit/priority.rb +180 -0
  111. data/test-unit/lib/test/unit/runner/console.rb +52 -0
  112. data/test-unit/lib/test/unit/runner/emacs.rb +8 -0
  113. data/test-unit/lib/test/unit/runner/tap.rb +8 -0
  114. data/test-unit/lib/test/unit/testcase.rb +476 -0
  115. data/test-unit/lib/test/unit/testresult.rb +89 -0
  116. data/test-unit/lib/test/unit/testsuite.rb +110 -0
  117. data/test-unit/lib/test/unit/ui/console/outputlevel.rb +14 -0
  118. data/test-unit/lib/test/unit/ui/console/testrunner.rb +466 -0
  119. data/test-unit/lib/test/unit/ui/emacs/testrunner.rb +63 -0
  120. data/test-unit/lib/test/unit/ui/tap/testrunner.rb +92 -0
  121. data/test-unit/lib/test/unit/ui/testrunner.rb +28 -0
  122. data/test-unit/lib/test/unit/ui/testrunnermediator.rb +77 -0
  123. data/test-unit/lib/test/unit/ui/testrunnerutilities.rb +41 -0
  124. data/test-unit/lib/test/unit/util/backtracefilter.rb +41 -0
  125. data/test-unit/lib/test/unit/util/method-owner-finder.rb +28 -0
  126. data/test-unit/lib/test/unit/util/observable.rb +90 -0
  127. data/test-unit/lib/test/unit/util/procwrapper.rb +48 -0
  128. data/test-unit/lib/test/unit/version.rb +7 -0
  129. data/test-unit/sample/adder.rb +13 -0
  130. data/test-unit/sample/subtracter.rb +12 -0
  131. data/test-unit/sample/test_adder.rb +20 -0
  132. data/test-unit/sample/test_subtracter.rb +20 -0
  133. data/test-unit/sample/test_user.rb +23 -0
  134. data/test-unit/test/collector/test-descendant.rb +133 -0
  135. data/test-unit/test/collector/test-load.rb +442 -0
  136. data/test-unit/test/collector/test_dir.rb +406 -0
  137. data/test-unit/test/collector/test_objectspace.rb +100 -0
  138. data/test-unit/test/run-test.rb +15 -0
  139. data/test-unit/test/test-attribute.rb +86 -0
  140. data/test-unit/test/test-color-scheme.rb +67 -0
  141. data/test-unit/test/test-color.rb +47 -0
  142. data/test-unit/test/test-diff.rb +518 -0
  143. data/test-unit/test/test-emacs-runner.rb +60 -0
  144. data/test-unit/test/test-fixture.rb +287 -0
  145. data/test-unit/test/test-notification.rb +33 -0
  146. data/test-unit/test/test-omission.rb +81 -0
  147. data/test-unit/test/test-pending.rb +70 -0
  148. data/test-unit/test/test-priority.rb +119 -0
  149. data/test-unit/test/test-testcase.rb +544 -0
  150. data/test-unit/test/test_assertions.rb +1151 -0
  151. data/test-unit/test/test_error.rb +26 -0
  152. data/test-unit/test/test_failure.rb +33 -0
  153. data/test-unit/test/test_testresult.rb +113 -0
  154. data/test-unit/test/test_testsuite.rb +129 -0
  155. data/test-unit/test/testunit-test-util.rb +14 -0
  156. data/test-unit/test/ui/test_testrunmediator.rb +20 -0
  157. data/test-unit/test/util/test-method-owner-finder.rb +38 -0
  158. data/test-unit/test/util/test_backtracefilter.rb +41 -0
  159. data/test-unit/test/util/test_observable.rb +102 -0
  160. data/test-unit/test/util/test_procwrapper.rb +36 -0
  161. data/test/.gitignore +1 -0
  162. data/test/groonga-test-utils.rb +134 -0
  163. data/test/run-test.rb +58 -0
  164. data/test/test-array.rb +90 -0
  165. data/test/test-column.rb +316 -0
  166. data/test/test-context-select.rb +93 -0
  167. data/test/test-context.rb +73 -0
  168. data/test/test-database.rb +113 -0
  169. data/test/test-encoding.rb +33 -0
  170. data/test/test-exception.rb +93 -0
  171. data/test/test-expression-builder.rb +217 -0
  172. data/test/test-expression.rb +134 -0
  173. data/test/test-fix-size-column.rb +65 -0
  174. data/test/test-gqtp.rb +72 -0
  175. data/test/test-hash.rb +305 -0
  176. data/test/test-index-column.rb +81 -0
  177. data/test/test-logger.rb +37 -0
  178. data/test/test-patricia-trie.rb +205 -0
  179. data/test/test-procedure.rb +37 -0
  180. data/test/test-query.rb +22 -0
  181. data/test/test-record.rb +243 -0
  182. data/test/test-remote.rb +54 -0
  183. data/test/test-schema-view.rb +90 -0
  184. data/test/test-schema.rb +459 -0
  185. data/test/test-snippet.rb +130 -0
  186. data/test/test-table-cursor.rb +153 -0
  187. data/test/test-table-offset-and-limit.rb +102 -0
  188. data/test/test-table-select-normalize.rb +53 -0
  189. data/test/test-table-select.rb +150 -0
  190. data/test/test-table.rb +594 -0
  191. data/test/test-type.rb +71 -0
  192. data/test/test-variable-size-column.rb +98 -0
  193. data/test/test-variable.rb +28 -0
  194. data/test/test-vector-column.rb +76 -0
  195. data/test/test-version.rb +31 -0
  196. data/test/test-view.rb +72 -0
  197. data/text/TUTORIAL.ja.rdoc +392 -0
  198. data/text/expression.rdoc +284 -0
  199. metadata +276 -0
@@ -0,0 +1,1369 @@
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
+ /*
20
+ * Document-class: Groonga::Object
21
+ *
22
+ * Ruby/groongaが提供するクラスのベースとなるクラス。
23
+ * Groonga::ContextとGroonga::Logger以外はGroonga::Objectを継
24
+ * 承している。
25
+ */
26
+
27
+ #include "rb-grn.h"
28
+
29
+ #define SELF(object) ((RbGrnObject *)DATA_PTR(object))
30
+
31
+ VALUE rb_cGrnObject;
32
+
33
+ grn_obj *
34
+ rb_grn_object_from_ruby_object (VALUE object, grn_ctx **context)
35
+ {
36
+ RbGrnObject *rb_grn_object;
37
+
38
+ if (NIL_P(object))
39
+ return NULL;
40
+
41
+ if (context && *context) {
42
+ grn_obj *grn_object;
43
+ if (RVAL2CBOOL(rb_obj_is_kind_of(object, rb_cString))) {
44
+ const char *name;
45
+ unsigned int name_size;
46
+
47
+ name = StringValuePtr(object);
48
+ name_size = RSTRING_LEN(object);
49
+ grn_object = rb_grn_context_get_backward_compatibility(*context,
50
+ name,
51
+ name_size);
52
+ if (!grn_object)
53
+ rb_raise(rb_eArgError,
54
+ "unregistered groonga object: name: <%s>",
55
+ rb_grn_inspect(object));
56
+ return grn_object;
57
+ } else if (RVAL2CBOOL(rb_obj_is_kind_of(object, rb_cInteger))) {
58
+ grn_object = grn_ctx_at(*context, NUM2UINT(object));
59
+ if (!grn_object)
60
+ rb_raise(rb_eArgError,
61
+ "unregistered groonga object: ID: <%s>",
62
+ rb_grn_inspect(object));
63
+ return grn_object;
64
+ }
65
+ }
66
+
67
+ if (!RVAL2CBOOL(rb_obj_is_kind_of(object, rb_cGrnObject))) {
68
+ rb_raise(rb_eTypeError, "not a groonga object: <%s>",
69
+ rb_grn_inspect(object));
70
+ }
71
+
72
+ Data_Get_Struct(object, RbGrnObject, rb_grn_object);
73
+ if (!rb_grn_object)
74
+ rb_raise(rb_eGrnError, "groonga object is NULL");
75
+
76
+ if (context && !*context)
77
+ *context = rb_grn_object->context;
78
+
79
+ return rb_grn_object->object;
80
+ }
81
+
82
+ static grn_obj *
83
+ rb_grn_object_finalizer (grn_ctx *context, int n_args, grn_obj **grn_objects,
84
+ grn_user_data *user_data)
85
+ {
86
+ RbGrnObject *rb_grn_object;
87
+ grn_obj *grn_object = *grn_objects;
88
+
89
+ if (rb_grn_exited)
90
+ return NULL;
91
+
92
+ rb_grn_object = user_data->ptr;
93
+
94
+ grn_obj_user_data(context, grn_object)->ptr = NULL;
95
+ grn_obj_set_finalizer(context, grn_object, NULL);
96
+
97
+ debug("finalize: %p:%p:%p:%p:%p 0x%x\n",
98
+ context, grn_object, rb_grn_object,
99
+ rb_grn_object->context, rb_grn_object->object,
100
+ grn_object->header.type);
101
+
102
+ rb_grn_object->context = NULL;
103
+ rb_grn_object->object = NULL;
104
+
105
+ switch (grn_object->header.type) {
106
+ case GRN_DB:
107
+ grn_ctx_use(context, NULL);
108
+ break;
109
+ case GRN_TYPE:
110
+ case GRN_PROC:
111
+ case GRN_CURSOR_TABLE_HASH_KEY:
112
+ case GRN_CURSOR_TABLE_PAT_KEY:
113
+ case GRN_CURSOR_TABLE_NO_KEY:
114
+ case GRN_CURSOR_TABLE_VIEW:
115
+ break;
116
+ case GRN_TABLE_HASH_KEY:
117
+ case GRN_TABLE_PAT_KEY:
118
+ rb_grn_table_key_support_finalizer(context, grn_object,
119
+ RB_GRN_TABLE_KEY_SUPPORT(rb_grn_object));
120
+ break;
121
+ case GRN_TABLE_NO_KEY:
122
+ case GRN_TABLE_VIEW:
123
+ rb_grn_table_finalizer(context, grn_object,
124
+ RB_GRN_TABLE(rb_grn_object));
125
+ break;
126
+ case GRN_COLUMN_FIX_SIZE:
127
+ case GRN_COLUMN_VAR_SIZE:
128
+ rb_grn_column_finalizer(context, grn_object,
129
+ RB_GRN_COLUMN(rb_grn_object));
130
+ break;
131
+ case GRN_COLUMN_INDEX:
132
+ rb_grn_index_column_finalizer(context, grn_object,
133
+ RB_GRN_INDEX_COLUMN(rb_grn_object));
134
+ break;
135
+ case GRN_ACCESSOR:
136
+ rb_grn_named_object_finalizer(context, grn_object,
137
+ RB_GRN_NAMED_OBJECT(rb_grn_object));
138
+ break;
139
+ case GRN_EXPR:
140
+ rb_grn_expression_finalizer(context, grn_object,
141
+ RB_GRN_EXPRESSION(rb_grn_object));
142
+ break;
143
+ default:
144
+ rb_raise(rb_eTypeError,
145
+ "unsupported groonga object type for finalizer: 0x%x",
146
+ grn_object->header.type);
147
+ break;
148
+ }
149
+
150
+ return NULL;
151
+ }
152
+
153
+ void
154
+ rb_grn_object_free (RbGrnObject *rb_grn_object)
155
+ {
156
+ grn_ctx *context;
157
+ grn_obj *grn_object;
158
+
159
+ context = rb_grn_object->context;
160
+ grn_object = rb_grn_object->object;
161
+ debug("rb-free: %p:%p:%p; %d\n", context, grn_object, rb_grn_object,
162
+ rb_grn_object->have_finalizer);
163
+ if (!rb_grn_exited && context && grn_object && rb_grn_object->have_finalizer) {
164
+ grn_user_data *user_data;
165
+
166
+ user_data = grn_obj_user_data(context, grn_object);
167
+ debug("type: %x; need_close: %d; user_data: %p; ptr: %p\n",
168
+ grn_object->header.type,
169
+ rb_grn_object->need_close,
170
+ user_data,
171
+ user_data ? user_data->ptr : NULL);
172
+ if (user_data && user_data->ptr) {
173
+ rb_grn_object_finalizer(context, 1, &grn_object, user_data);
174
+ }
175
+ if (rb_grn_object->need_close) {
176
+ grn_obj_unlink(context, grn_object);
177
+ }
178
+ }
179
+ xfree(rb_grn_object);
180
+ }
181
+
182
+ VALUE
183
+ rb_grn_object_to_ruby_class (grn_obj *object)
184
+ {
185
+ VALUE klass = Qnil;
186
+
187
+ switch (object->header.type) {
188
+ case GRN_DB:
189
+ klass = rb_cGrnDatabase;
190
+ break;
191
+ case GRN_TABLE_HASH_KEY:
192
+ klass = rb_cGrnHash;
193
+ break;
194
+ case GRN_TABLE_PAT_KEY:
195
+ klass = rb_cGrnPatriciaTrie;
196
+ break;
197
+ case GRN_TABLE_NO_KEY:
198
+ klass = rb_cGrnArray;
199
+ break;
200
+ case GRN_TABLE_VIEW:
201
+ klass = rb_cGrnView;
202
+ break;
203
+ case GRN_TYPE:
204
+ klass = rb_cGrnType;
205
+ break;
206
+ case GRN_ACCESSOR:
207
+ klass = rb_cGrnAccessor;
208
+ break;
209
+ case GRN_ACCESSOR_VIEW:
210
+ klass = rb_cGrnViewAccessor;
211
+ break;
212
+ case GRN_PROC:
213
+ klass = rb_cGrnProcedure;
214
+ break;
215
+ case GRN_COLUMN_FIX_SIZE:
216
+ klass = rb_cGrnFixSizeColumn;
217
+ break;
218
+ case GRN_COLUMN_VAR_SIZE:
219
+ klass = rb_cGrnVariableSizeColumn;
220
+ break;
221
+ case GRN_COLUMN_INDEX:
222
+ klass = rb_cGrnIndexColumn;
223
+ break;
224
+ case GRN_EXPR:
225
+ klass = rb_cGrnExpression;
226
+ break;
227
+ case GRN_CURSOR_TABLE_HASH_KEY:
228
+ klass = rb_cGrnHashCursor;
229
+ break;
230
+ case GRN_CURSOR_TABLE_PAT_KEY:
231
+ klass = rb_cGrnPatriciaTrieCursor;
232
+ break;
233
+ case GRN_CURSOR_TABLE_NO_KEY:
234
+ klass = rb_cGrnArrayCursor;
235
+ break;
236
+ case GRN_CURSOR_TABLE_VIEW:
237
+ klass = rb_cGrnViewCursor;
238
+ break;
239
+ default:
240
+ rb_raise(rb_eTypeError,
241
+ "unsupported groonga object type for class detection: 0x%x",
242
+ object->header.type);
243
+ break;
244
+ }
245
+
246
+ return klass;
247
+ }
248
+
249
+ VALUE
250
+ rb_grn_object_to_ruby_object (VALUE klass, grn_ctx *context, grn_obj *object,
251
+ rb_grn_boolean owner)
252
+ {
253
+ RbGrnContext *rb_grn_context;
254
+ VALUE rb_object, rb_context = Qnil;
255
+ grn_user_data *user_data;
256
+
257
+ if (!object)
258
+ return Qnil;
259
+
260
+ user_data = grn_obj_user_data(context, object);
261
+ if (user_data && user_data->ptr) {
262
+ return RB_GRN_OBJECT(user_data->ptr)->self;
263
+ }
264
+
265
+ if (NIL_P(klass))
266
+ klass = GRNOBJECT2RCLASS(object);
267
+
268
+ rb_grn_context = GRN_CTX_USER_DATA(context)->ptr;
269
+ if (rb_grn_context)
270
+ rb_context = rb_grn_context->self;
271
+ rb_object = rb_obj_alloc(klass);
272
+ rb_grn_object_assign(klass, rb_object, rb_context, context, object);
273
+
274
+ return rb_object;
275
+ }
276
+
277
+ VALUE
278
+ rb_grn_object_alloc (VALUE klass)
279
+ {
280
+ return Data_Wrap_Struct(klass, NULL, rb_grn_object_free, NULL);
281
+ }
282
+
283
+ static void
284
+ rb_grn_object_bind_common (VALUE klass, VALUE self, VALUE rb_context,
285
+ RbGrnObject *rb_grn_object,
286
+ grn_ctx *context, grn_obj *object)
287
+ {
288
+ grn_user_data *user_data;
289
+
290
+ rb_grn_object->context = context;
291
+ rb_grn_object->object = object;
292
+ rb_grn_object->self = self;
293
+ rb_grn_object->need_close = RB_GRN_TRUE;
294
+ rb_grn_object->have_finalizer = RB_GRN_FALSE;
295
+
296
+ user_data = grn_obj_user_data(context, object);
297
+ if (user_data) {
298
+ debug("set-finalizer: %p:%p:%p 0x%x\n",
299
+ context, object, rb_grn_object,
300
+ object->header.type);
301
+ user_data->ptr = rb_grn_object;
302
+ grn_obj_set_finalizer(context, object, rb_grn_object_finalizer);
303
+ rb_grn_object->have_finalizer = RB_GRN_TRUE;
304
+ }
305
+
306
+ switch (object->header.type) {
307
+ case GRN_PROC:
308
+ case GRN_TYPE:
309
+ rb_grn_object->need_close = RB_GRN_FALSE;
310
+ break;
311
+ default:
312
+ if (klass == rb_cGrnVariable)
313
+ rb_grn_object->need_close = RB_GRN_FALSE;
314
+ break;
315
+ }
316
+
317
+ rb_grn_object->domain_id = GRN_ID_NIL;
318
+ if (object)
319
+ rb_grn_object->domain_id = object->header.domain;
320
+ if (rb_grn_object->domain_id == GRN_ID_NIL)
321
+ rb_grn_object->domain = NULL;
322
+ else
323
+ rb_grn_object->domain = grn_ctx_at(context, rb_grn_object->domain_id);
324
+
325
+ rb_grn_object->range_id = GRN_ID_NIL;
326
+ if (object && object->header.type != GRN_TYPE)
327
+ rb_grn_object->range_id = grn_obj_get_range(context, object);
328
+ if (rb_grn_object->range_id == GRN_ID_NIL)
329
+ rb_grn_object->range = NULL;
330
+ else
331
+ rb_grn_object->range = grn_ctx_at(context, rb_grn_object->range_id);
332
+
333
+ DATA_PTR(self) = rb_grn_object;
334
+ rb_iv_set(self, "@context", rb_context);
335
+ }
336
+
337
+ void
338
+ rb_grn_object_assign (VALUE klass, VALUE self, VALUE rb_context,
339
+ grn_ctx *context, grn_obj *object)
340
+ {
341
+ void *rb_grn_object;
342
+
343
+ if (!object)
344
+ return;
345
+
346
+ if (NIL_P(klass))
347
+ klass = rb_obj_class(self);
348
+
349
+ if (klass == rb_cGrnDatabase ||
350
+ (RVAL2CBOOL(rb_obj_is_kind_of(self, rb_cGrnType))) ||
351
+ klass == rb_cGrnHashCursor ||
352
+ klass == rb_cGrnPatriciaTrieCursor ||
353
+ klass == rb_cGrnArrayCursor ||
354
+ klass == rb_cGrnViewCursor ||
355
+ klass == rb_cGrnProcedure ||
356
+ klass == rb_cGrnVariable) {
357
+ rb_grn_object = ALLOC(RbGrnObject);
358
+ rb_grn_object_bind_common(klass, self, rb_context, rb_grn_object,
359
+ context, object);
360
+ } else if (RVAL2CBOOL(rb_obj_is_kind_of(self, rb_mGrnTableKeySupport))) {
361
+ rb_grn_object = ALLOC(RbGrnTableKeySupport);
362
+ rb_grn_object_bind_common(klass, self, rb_context, rb_grn_object,
363
+ context, object);
364
+ rb_grn_table_key_support_bind(RB_GRN_TABLE_KEY_SUPPORT(rb_grn_object),
365
+ context, object);
366
+ } else if (RVAL2CBOOL(rb_obj_is_kind_of(self, rb_cGrnTable))) {
367
+ rb_grn_object = ALLOC(RbGrnTable);
368
+ rb_grn_object_bind_common(klass, self, rb_context, rb_grn_object,
369
+ context, object);
370
+ rb_grn_table_bind(RB_GRN_TABLE(rb_grn_object), context, object);
371
+ } else if (RVAL2CBOOL(rb_obj_is_kind_of(self, rb_cGrnIndexColumn))) {
372
+ rb_grn_object = ALLOC(RbGrnIndexColumn);
373
+ rb_grn_object_bind_common(klass, self, rb_context, rb_grn_object,
374
+ context, object);
375
+ rb_grn_index_column_bind(RB_GRN_INDEX_COLUMN(rb_grn_object),
376
+ context, object);
377
+ } else if (RVAL2CBOOL(rb_obj_is_kind_of(self, rb_cGrnColumn))) {
378
+ rb_grn_object = ALLOC(RbGrnColumn);
379
+ rb_grn_object_bind_common(klass, self, rb_context, rb_grn_object,
380
+ context, object);
381
+ rb_grn_column_bind(RB_GRN_COLUMN(rb_grn_object), context, object);
382
+ } else if (klass == rb_cGrnAccessor ||
383
+ klass == rb_cGrnViewAccessor) {
384
+ rb_grn_object = ALLOC(RbGrnNamedObject);
385
+ rb_grn_object_bind_common(klass, self, rb_context, rb_grn_object,
386
+ context, object);
387
+ rb_grn_named_object_bind(RB_GRN_NAMED_OBJECT(rb_grn_object),
388
+ context, object);
389
+ } else if (klass == rb_cGrnExpression) {
390
+ rb_grn_object = ALLOC(RbGrnExpression);
391
+ rb_grn_object_bind_common(klass, self, rb_context, rb_grn_object,
392
+ context, object);
393
+ rb_grn_expression_bind(RB_GRN_EXPRESSION(rb_grn_object),
394
+ context, object);
395
+ } else {
396
+ rb_raise(rb_eTypeError,
397
+ "unsupported groonga object type for assignment: 0x%x",
398
+ object->header.type);
399
+ }
400
+
401
+ debug("assign: %p:%p:%p 0x%x\n", context, object, rb_grn_object,
402
+ object->header.type);
403
+ }
404
+
405
+ void
406
+ rb_grn_named_object_bind (RbGrnNamedObject *rb_grn_named_object,
407
+ grn_ctx *context, grn_obj *object)
408
+ {
409
+ RbGrnObject *rb_grn_object;
410
+
411
+ rb_grn_object = RB_GRN_OBJECT(rb_grn_named_object);
412
+
413
+ rb_grn_named_object->name = NULL;
414
+ rb_grn_named_object->name_size = 0;
415
+ }
416
+
417
+ void
418
+ rb_grn_named_object_finalizer (grn_ctx *context, grn_obj *grn_object,
419
+ RbGrnNamedObject *rb_grn_named_object)
420
+ {
421
+ if (rb_grn_named_object->name)
422
+ xfree(rb_grn_named_object->name);
423
+ rb_grn_named_object->name = NULL;
424
+ rb_grn_named_object->name_size = 0;
425
+ }
426
+
427
+ void
428
+ rb_grn_named_object_set_name (RbGrnNamedObject *rb_grn_named_object,
429
+ const char *name, unsigned name_size)
430
+ {
431
+ if (rb_grn_named_object->name) {
432
+ free(rb_grn_named_object->name);
433
+ rb_grn_named_object->name = NULL;
434
+ }
435
+ if (name_size > 0) {
436
+ rb_grn_named_object->name = ALLOC_N(char, name_size + 1);
437
+ memcpy(rb_grn_named_object->name, name, name_size);
438
+ rb_grn_named_object->name[name_size] = '\0';
439
+ debug("set-name: %p:%p:%p 0x%x: <%.*s>\n",
440
+ RB_GRN_OBJECT(rb_grn_named_object)->context,
441
+ RB_GRN_OBJECT(rb_grn_named_object)->object,
442
+ rb_grn_named_object,
443
+ RB_GRN_OBJECT(rb_grn_named_object)->object->header.type,
444
+ name_size, name);
445
+ }
446
+ rb_grn_named_object->name_size = name_size;
447
+ }
448
+
449
+
450
+ void
451
+ rb_grn_object_deconstruct (RbGrnObject *rb_grn_object,
452
+ grn_obj **object,
453
+ grn_ctx **context,
454
+ grn_id *domain_id,
455
+ grn_obj **domain,
456
+ grn_id *range_id,
457
+ grn_obj **range)
458
+ {
459
+ if (!rb_grn_object)
460
+ return;
461
+
462
+ if (!rb_grn_object->object) {
463
+ rb_raise(rb_eGrnObjectClosed,
464
+ "can't access already closed groonga object: %s",
465
+ rb_grn_inspect(CLASS_OF(rb_grn_object->self)));
466
+ }
467
+
468
+ if (object)
469
+ *object = rb_grn_object->object;
470
+ if (context)
471
+ *context = rb_grn_object->context;
472
+ if (domain_id)
473
+ *domain_id = rb_grn_object->domain_id;
474
+ if (domain)
475
+ *domain = rb_grn_object->domain;
476
+ if (range_id)
477
+ *range_id = rb_grn_object->range_id;
478
+ if (range)
479
+ *range = rb_grn_object->range;
480
+ }
481
+
482
+ /*
483
+ * Document-method: close
484
+ *
485
+ * call-seq:
486
+ * object.close
487
+ *
488
+ * _object_が使用しているリソースを開放する。これ以降_object_を
489
+ * 使うことはできない。
490
+ */
491
+ VALUE
492
+ rb_grn_object_close (VALUE self)
493
+ {
494
+ grn_obj *object;
495
+ grn_ctx *context;
496
+
497
+ rb_grn_object_deconstruct(SELF(self), &object, &context,
498
+ NULL, NULL, NULL, NULL);
499
+ if (object && context)
500
+ grn_obj_unlink(context, object);
501
+ return Qnil;
502
+ }
503
+
504
+ /*
505
+ * Document-method: closed?
506
+ *
507
+ * call-seq:
508
+ * object.closed? -> true/false
509
+ *
510
+ * _object_が開放済みの場合は+true+を返し、そうでない場合は
511
+ * +false+を返す。
512
+ */
513
+ VALUE
514
+ rb_grn_object_closed_p (VALUE self)
515
+ {
516
+ RbGrnObject *rb_grn_object;
517
+
518
+ rb_grn_object = SELF(self);
519
+ if (rb_grn_object->context && rb_grn_object->object) {
520
+ return Qfalse;
521
+ } else {
522
+ return Qtrue;
523
+ }
524
+ }
525
+
526
+ VALUE
527
+ rb_grn_object_inspect_object (VALUE inspected, grn_ctx *context, grn_obj *object)
528
+ {
529
+ VALUE rb_object;
530
+
531
+ rb_object = GRNOBJECT2RVAL(Qnil, context, object, RB_GRN_FALSE);
532
+ rb_str_concat(inspected, rb_inspect(rb_object));
533
+
534
+ return inspected;
535
+ }
536
+
537
+ VALUE
538
+ rb_grn_object_inspect_header (VALUE self, VALUE inspected)
539
+ {
540
+ rb_str_cat2(inspected, "#<");
541
+ rb_str_concat(inspected, rb_inspect(rb_obj_class(self)));
542
+
543
+ return inspected;
544
+ }
545
+
546
+ static VALUE
547
+ rb_grn_object_inspect_content_id_with_label (VALUE inspected,
548
+ grn_ctx *context, grn_obj *object)
549
+ {
550
+ grn_id id;
551
+
552
+ rb_str_cat2(inspected, "id: <");
553
+ id = grn_obj_id(context, object);
554
+ if (id == GRN_ID_NIL)
555
+ rb_str_cat2(inspected, "nil");
556
+ else
557
+ rb_str_concat(inspected, rb_obj_as_string(UINT2NUM(id)));
558
+ rb_str_cat2(inspected, ">");
559
+
560
+ return inspected;
561
+ }
562
+
563
+ static VALUE
564
+ rb_grn_object_inspect_content_name (VALUE inspected,
565
+ grn_ctx *context, grn_obj *object)
566
+ {
567
+ int name_size;
568
+
569
+ name_size = grn_obj_name(context, object, NULL, 0);
570
+ if (name_size == 0) {
571
+ rb_str_cat2(inspected, "(anonymous)");
572
+ } else {
573
+ grn_obj name;
574
+
575
+ GRN_OBJ_INIT(&name, GRN_BULK, 0, GRN_ID_NIL);
576
+ grn_bulk_space(context, &name, name_size);
577
+ grn_obj_name(context, object, GRN_BULK_HEAD(&name), name_size);
578
+ GRN_TEXT_PUTC(context, &name, '\0');
579
+ rb_str_cat2(inspected, "<");
580
+ rb_str_cat2(inspected, GRN_BULK_HEAD(&name));
581
+ rb_str_cat2(inspected, ">");
582
+ grn_obj_unlink(context, &name);
583
+ }
584
+
585
+ return inspected;
586
+ }
587
+
588
+ static VALUE
589
+ rb_grn_object_inspect_content_name_with_label (VALUE inspected,
590
+ grn_ctx *context, grn_obj *object)
591
+ {
592
+
593
+ rb_str_cat2(inspected, "name: ");
594
+ rb_grn_object_inspect_content_name(inspected, context, object);
595
+ return inspected;
596
+ }
597
+
598
+ static VALUE
599
+ rb_grn_object_inspect_content_path_with_label (VALUE inspected,
600
+ grn_ctx *context, grn_obj *object)
601
+ {
602
+ const char *path;
603
+
604
+ rb_str_cat2(inspected, "path: ");
605
+ path = grn_obj_path(context, object);
606
+ if (path) {
607
+ rb_str_cat2(inspected, "<");
608
+ rb_str_cat2(inspected, path);
609
+ rb_str_cat2(inspected, ">");
610
+ } else {
611
+ rb_str_cat2(inspected, "(temporary)");
612
+ }
613
+
614
+ return inspected;
615
+ }
616
+
617
+ static VALUE
618
+ rb_grn_object_inspect_content_domain_with_label (VALUE inspected,
619
+ grn_ctx *context,
620
+ grn_obj *object)
621
+ {
622
+ grn_id domain;
623
+
624
+ rb_str_cat2(inspected, "domain: ");
625
+ domain = object->header.domain;
626
+ if (domain == GRN_ID_NIL) {
627
+ rb_str_cat2(inspected, "(nil)");
628
+ } else {
629
+ grn_obj *domain_object;
630
+
631
+ domain_object = grn_ctx_at(context, domain);
632
+ if (domain_object) {
633
+ if (domain_object == object) {
634
+ rb_str_cat2(inspected, "(self)");
635
+ } else {
636
+ rb_grn_object_inspect_content_name(inspected,
637
+ context, domain_object);
638
+ }
639
+ } else {
640
+ rb_str_cat2(inspected, "(");
641
+ rb_str_concat(inspected, rb_obj_as_string(UINT2NUM(domain)));
642
+ rb_str_cat2(inspected, ")");
643
+ }
644
+ }
645
+
646
+ return inspected;
647
+ }
648
+
649
+ static VALUE
650
+ rb_grn_object_inspect_content_range_with_label (VALUE inspected,
651
+ grn_ctx *context,
652
+ grn_obj *object)
653
+ {
654
+ grn_id range;
655
+
656
+ rb_str_cat2(inspected, "range: ");
657
+
658
+ range = grn_obj_get_range(context, object);
659
+ switch (object->header.type) {
660
+ case GRN_TYPE:
661
+ rb_str_cat2(inspected, "<");
662
+ rb_str_concat(inspected, rb_inspect(UINT2NUM(range)));
663
+ rb_str_cat2(inspected, ">");
664
+ break;
665
+ default:
666
+ if (range == GRN_ID_NIL) {
667
+ rb_str_cat2(inspected, "(nil)");
668
+ } else {
669
+ grn_obj *range_object;
670
+
671
+ range_object = grn_ctx_at(context, range);
672
+ if (range_object) {
673
+ if (range_object == object) {
674
+ rb_str_cat2(inspected, "(self)");
675
+ } else {
676
+ rb_grn_object_inspect_content_name(inspected,
677
+ context, range_object);
678
+ }
679
+ } else {
680
+ rb_str_cat2(inspected, "(");
681
+ rb_str_concat(inspected, rb_obj_as_string(UINT2NUM(range)));
682
+ rb_str_cat2(inspected, ")");
683
+ }
684
+ }
685
+ }
686
+
687
+ return inspected;
688
+ }
689
+
690
+ static VALUE
691
+ rb_grn_object_inspect_content_flags_with_label (VALUE inspected,
692
+ grn_ctx *context,
693
+ grn_obj *object)
694
+ {
695
+ grn_obj_flags flags;
696
+ VALUE inspected_flags;
697
+
698
+ rb_str_cat2(inspected, "flags: ");
699
+
700
+ flags = object->header.flags;
701
+
702
+ inspected_flags = rb_ary_new();
703
+
704
+ if (0) {
705
+ if (flags & GRN_OBJ_TABLE_HASH_KEY)
706
+ rb_ary_push(inspected_flags, rb_str_new2("TABLE_HASH_KEY"));
707
+ if (flags & GRN_OBJ_TABLE_PAT_KEY)
708
+ rb_ary_push(inspected_flags, rb_str_new2("TABLE_PAT_KEY"));
709
+ if (flags & GRN_OBJ_TABLE_NO_KEY)
710
+ rb_ary_push(inspected_flags, rb_str_new2("TABLE_NO_KEY"));
711
+ if (flags & GRN_OBJ_TABLE_VIEW)
712
+ rb_ary_push(inspected_flags, rb_str_new2("TABLE_VIEW"));
713
+ }
714
+
715
+ switch (object->header.type) {
716
+ case GRN_COLUMN_FIX_SIZE:
717
+ case GRN_COLUMN_VAR_SIZE:
718
+ case GRN_TYPE:
719
+ if (flags & GRN_OBJ_KEY_UINT)
720
+ rb_ary_push(inspected_flags, rb_str_new2("KEY_UINT"));
721
+ if (flags & GRN_OBJ_KEY_INT)
722
+ rb_ary_push(inspected_flags, rb_str_new2("KEY_INT"));
723
+ if (flags & GRN_OBJ_KEY_FLOAT)
724
+ rb_ary_push(inspected_flags, rb_str_new2("KEY_FLOAT"));
725
+ break;
726
+ default:
727
+ break;
728
+ }
729
+
730
+ switch (object->header.type) {
731
+ case GRN_TABLE_HASH_KEY:
732
+ case GRN_TABLE_PAT_KEY:
733
+ if (flags & GRN_OBJ_KEY_WITH_SIS)
734
+ rb_ary_push(inspected_flags, rb_str_new2("KEY_WITH_SIS"));
735
+ if (flags & GRN_OBJ_KEY_NORMALIZE)
736
+ rb_ary_push(inspected_flags, rb_str_new2("KEY_NORMALIZE"));
737
+ break;
738
+ default:
739
+ break;
740
+ }
741
+
742
+ if (0) {
743
+ if (flags & GRN_OBJ_COLUMN_SCALAR)
744
+ rb_ary_push(inspected_flags, rb_str_new2("COLUMN_SCALAR"));
745
+ if (flags & GRN_OBJ_COLUMN_VECTOR)
746
+ rb_ary_push(inspected_flags, rb_str_new2("COLUMN_VECTOR"));
747
+ if (flags & GRN_OBJ_COLUMN_INDEX)
748
+ rb_ary_push(inspected_flags, rb_str_new2("COLUMN_INDEX"));
749
+ }
750
+
751
+ switch (object->header.type) {
752
+ case GRN_COLUMN_FIX_SIZE:
753
+ case GRN_COLUMN_VAR_SIZE:
754
+ if (flags & GRN_OBJ_COMPRESS_ZLIB)
755
+ rb_ary_push(inspected_flags, rb_str_new2("COMPRESS_ZLIB"));
756
+ if (flags & GRN_OBJ_COMPRESS_LZO)
757
+ rb_ary_push(inspected_flags, rb_str_new2("COMPRESS_LZO"));
758
+ break;
759
+ default:
760
+ break;
761
+ }
762
+
763
+ if (flags & GRN_OBJ_WITH_SECTION)
764
+ rb_ary_push(inspected_flags, rb_str_new2("WITH_SECTION"));
765
+ if (flags & GRN_OBJ_WITH_WEIGHT)
766
+ rb_ary_push(inspected_flags, rb_str_new2("WITH_WEIGHT"));
767
+ if (flags & GRN_OBJ_WITH_POSITION)
768
+ rb_ary_push(inspected_flags, rb_str_new2("WITH_POSITION"));
769
+ if (flags & GRN_OBJ_WITH_BUFFER)
770
+ rb_ary_push(inspected_flags, rb_str_new2("WITH_BUFFER"));
771
+
772
+ if (flags & GRN_OBJ_WITH_SUBREC) {
773
+ rb_ary_push(inspected_flags, rb_str_new2("WITH_SUBREC"));
774
+
775
+ if (flags & GRN_OBJ_UNIT_DOCUMENT_SECTION)
776
+ rb_ary_push(inspected_flags, rb_str_new2("UNIT_DOCUMENT_SECTION"));
777
+ if (flags & GRN_OBJ_UNIT_DOCUMENT_POSITION)
778
+ rb_ary_push(inspected_flags, rb_str_new2("UNIT_DOCUMENT_POSITION"));
779
+
780
+ if (flags & GRN_OBJ_UNIT_SECTION_POSITION)
781
+ rb_ary_push(inspected_flags, rb_str_new2("UNIT_SECTION_POSITION"));
782
+
783
+ if (flags & GRN_OBJ_UNIT_USERDEF_DOCUMENT)
784
+ rb_ary_push(inspected_flags, rb_str_new2("UNIT_USERDEF_DOCUMENT"));
785
+ if (flags & GRN_OBJ_UNIT_USERDEF_SECTION)
786
+ rb_ary_push(inspected_flags, rb_str_new2("UNIT_USERDEF_SECTION"));
787
+ if (flags & GRN_OBJ_UNIT_USERDEF_POSITION)
788
+ rb_ary_push(inspected_flags, rb_str_new2("UNIT_USERDEF_POSITION"));
789
+ }
790
+
791
+ rb_str_cat2(inspected, "<");
792
+ rb_str_concat(inspected, rb_ary_join(inspected_flags, rb_str_new2("|")));
793
+ rb_str_cat2(inspected, ">");
794
+
795
+ return inspected;
796
+ }
797
+
798
+ VALUE
799
+ rb_grn_object_inspect_object_content (VALUE inspected,
800
+ grn_ctx *context, grn_obj *object)
801
+ {
802
+ rb_grn_object_inspect_content_id_with_label(inspected, context, object);
803
+ rb_str_cat2(inspected, ", ");
804
+ rb_grn_object_inspect_content_name_with_label(inspected, context, object);
805
+ rb_str_cat2(inspected, ", ");
806
+ rb_grn_object_inspect_content_path_with_label(inspected, context, object);
807
+ rb_str_cat2(inspected, ", ");
808
+ rb_grn_object_inspect_content_domain_with_label(inspected, context, object);
809
+ rb_str_cat2(inspected, ", ");
810
+ rb_grn_object_inspect_content_range_with_label(inspected, context, object);
811
+ rb_str_cat2(inspected, ", ");
812
+ rb_grn_object_inspect_content_flags_with_label(inspected, context, object);
813
+
814
+ return inspected;
815
+ }
816
+
817
+ VALUE
818
+ rb_grn_object_inspect_content (VALUE self, VALUE inspected)
819
+ {
820
+ RbGrnObject *rb_grn_object;
821
+ grn_ctx *context;
822
+ grn_obj *object;
823
+
824
+ rb_grn_object = SELF(self);
825
+ if (!rb_grn_object)
826
+ return inspected;
827
+
828
+ context = rb_grn_object->context;
829
+ object = rb_grn_object->object;
830
+
831
+ rb_str_cat2(inspected, " ");
832
+ if (object) {
833
+ rb_grn_object_inspect_object_content(inspected, context, object);
834
+ } else {
835
+ rb_str_cat2(inspected, "(closed)");
836
+ }
837
+
838
+ return inspected;
839
+ }
840
+
841
+ VALUE
842
+ rb_grn_object_inspect_footer (VALUE self, VALUE inspected)
843
+ {
844
+ rb_str_cat2(inspected, ">");
845
+
846
+ return inspected;
847
+ }
848
+
849
+ /*
850
+ * Document-method: inspect
851
+ *
852
+ * call-seq:
853
+ * object.inspect -> 詳細情報
854
+ *
855
+ * _object_の詳細を示した文字列を返す。デバッグ用。
856
+ */
857
+ static VALUE
858
+ rb_grn_object_inspect (VALUE self)
859
+ {
860
+ VALUE inspected;
861
+
862
+ inspected = rb_str_new2("");
863
+ rb_grn_object_inspect_header(self, inspected);
864
+ rb_grn_object_inspect_content(self, inspected);
865
+ rb_grn_object_inspect_footer(self, inspected);
866
+
867
+ return inspected;
868
+ }
869
+
870
+ /*
871
+ * Document-method: id
872
+ *
873
+ * call-seq:
874
+ * object.id -> ID/nil
875
+ *
876
+ * _object_のIDを返す。_object_が#closed?なときやIDがない場合
877
+ * は+nil+を返す。
878
+ */
879
+ VALUE
880
+ rb_grn_object_get_id (VALUE self)
881
+ {
882
+ RbGrnObject *rb_grn_object;
883
+ grn_id id;
884
+
885
+ rb_grn_object = SELF(self);
886
+ if (!rb_grn_object->object)
887
+ return Qnil;
888
+
889
+ id = grn_obj_id(rb_grn_object->context, rb_grn_object->object);
890
+ if (id == GRN_ID_NIL)
891
+ return Qnil;
892
+ else
893
+ return UINT2NUM(id);
894
+ }
895
+
896
+ /*
897
+ * Document-method: path
898
+ *
899
+ * call-seq:
900
+ * object.path -> ファイルパス/nil
901
+ *
902
+ * _object_に対応するファイルパスを返す。一時_object_
903
+ * なら+nil+を返す。
904
+ */
905
+ static VALUE
906
+ rb_grn_object_get_path (VALUE self)
907
+ {
908
+ RbGrnObject *rb_grn_object;
909
+ const char *path;
910
+
911
+ rb_grn_object = SELF(self);
912
+ if (!rb_grn_object->object)
913
+ return Qnil;
914
+
915
+ path = grn_obj_path(rb_grn_object->context, rb_grn_object->object);
916
+
917
+ if (!path)
918
+ return Qnil;
919
+ else
920
+ return rb_str_new2(path);
921
+ }
922
+
923
+ /*
924
+ * Document-method: temporary?
925
+ *
926
+ * call-seq:
927
+ * object.temporary? -> true/false
928
+ *
929
+ * _object_が一時オブジェクトなら+true+、永続オブジェクトな
930
+ * ら+false+を返す。
931
+ */
932
+ static VALUE
933
+ rb_grn_object_temporary_p (VALUE self)
934
+ {
935
+ RbGrnObject *rb_grn_object;
936
+
937
+ rb_grn_object = SELF(self);
938
+ if (!rb_grn_object->object)
939
+ return Qnil;
940
+
941
+ return CBOOL2RVAL(!(rb_grn_object->object->header.flags & GRN_OBJ_PERSISTENT));
942
+ }
943
+
944
+ /*
945
+ * Document-method: persistent?
946
+ *
947
+ * call-seq:
948
+ * object.persistent? -> true/false
949
+ *
950
+ * _object_が永続オブジェクトなら+true+、一時オブジェクトな
951
+ * ら+false+を返す。
952
+ */
953
+ static VALUE
954
+ rb_grn_object_persistent_p (VALUE self)
955
+ {
956
+ RbGrnObject *rb_grn_object;
957
+
958
+ rb_grn_object = SELF(self);
959
+ if (!rb_grn_object->object)
960
+ return Qnil;
961
+
962
+ return CBOOL2RVAL(rb_grn_object->object->header.flags & GRN_OBJ_PERSISTENT);
963
+ }
964
+
965
+ /*
966
+ * Document-method: domain
967
+ *
968
+ * call-seq:
969
+ * object.domain -> Groonga::Object/nil
970
+ *
971
+ * _object_の属しているGroonga::Objectを返す。例えば、
972
+ * Groonga::ColumnはGroonga::Tableを返す。属している
973
+ * Groonga::Objectがない場合は+nil+を返す。
974
+ */
975
+ static VALUE
976
+ rb_grn_object_get_domain (VALUE self)
977
+ {
978
+ RbGrnObject *rb_grn_object;
979
+ grn_ctx *context;
980
+ grn_obj *object;
981
+ grn_id domain;
982
+
983
+ rb_grn_object = SELF(self);
984
+ object = rb_grn_object->object;
985
+ if (!object)
986
+ return Qnil;
987
+
988
+ context = rb_grn_object->context;
989
+ domain = object->header.domain;
990
+ if (domain == GRN_ID_NIL) {
991
+ return Qnil;
992
+ } else {
993
+ grn_obj *domain_object;
994
+
995
+ domain_object = grn_ctx_at(context, domain);
996
+ if (domain_object)
997
+ return GRNOBJECT2RVAL(Qnil, context, domain_object, RB_GRN_FALSE);
998
+ else
999
+ return UINT2NUM(domain);
1000
+ }
1001
+ }
1002
+
1003
+ /*
1004
+ * Document-method: name
1005
+ *
1006
+ * call-seq:
1007
+ * object.name -> 名前/nil
1008
+ *
1009
+ * _object_の名前を返す。無名オブジェクトの場合は+nil+を返す。
1010
+ */
1011
+ static VALUE
1012
+ rb_grn_object_get_name (VALUE self)
1013
+ {
1014
+ RbGrnObject *rb_grn_object;
1015
+ VALUE rb_name;
1016
+ char *name;
1017
+ int name_size;
1018
+
1019
+ rb_grn_object = SELF(self);
1020
+ if (!rb_grn_object->object)
1021
+ return Qnil;
1022
+
1023
+ name_size = grn_obj_name(rb_grn_object->context, rb_grn_object->object,
1024
+ NULL, 0);
1025
+ if (name_size == 0)
1026
+ return Qnil;
1027
+
1028
+ name = xmalloc(name_size);
1029
+ grn_obj_name(rb_grn_object->context, rb_grn_object->object,
1030
+ name, name_size);
1031
+ rb_name = rb_str_new(name, name_size);
1032
+ xfree(name);
1033
+
1034
+ return rb_name;
1035
+ }
1036
+
1037
+ /*
1038
+ * Document-method: range
1039
+ *
1040
+ * call-seq:
1041
+ * object.range -> Groonga::Object/nil
1042
+ *
1043
+ * _object_の値がとりうる範囲を示したGroonga::Objectを返す。
1044
+ * 例えば、Groonga::Columnの場合は
1045
+ * Groonga::Table#define_columnで指定されたGroonga::Typeや
1046
+ * Groonga::Tableを返す。
1047
+ * 範囲が指定されていないオブジェクトの場合は+nil+を返す。
1048
+ */
1049
+ static VALUE
1050
+ rb_grn_object_get_range (VALUE self)
1051
+ {
1052
+ RbGrnObject *rb_grn_object;
1053
+ grn_ctx *context;
1054
+ grn_obj *object;
1055
+ grn_id range;
1056
+
1057
+ rb_grn_object = SELF(self);
1058
+ object = rb_grn_object->object;
1059
+ if (!object)
1060
+ return Qnil;
1061
+
1062
+ context = rb_grn_object->context;
1063
+ range = grn_obj_get_range(context, object);
1064
+ if (range == GRN_ID_NIL) {
1065
+ return Qnil;
1066
+ } else {
1067
+ grn_obj *range_object;
1068
+
1069
+ range_object = grn_ctx_at(context, range);
1070
+ if (range_object)
1071
+ return GRNOBJECT2RVAL(Qnil, context, range_object, RB_GRN_FALSE);
1072
+ else
1073
+ return UINT2NUM(range);
1074
+ }
1075
+ }
1076
+
1077
+ /*
1078
+ * Document-method: ==
1079
+ *
1080
+ * call-seq:
1081
+ * object == other -> true/false
1082
+ *
1083
+ * _object_と_other_が同じgroongaのオブジェクトなら+true+を返
1084
+ * し、そうでなければ+false+を返す。
1085
+ */
1086
+ static VALUE
1087
+ rb_grn_object_equal (VALUE self, VALUE other)
1088
+ {
1089
+ RbGrnObject *self_rb_grn_object, *other_rb_grn_object;
1090
+
1091
+ if (self == other)
1092
+ return Qtrue;
1093
+
1094
+ if (!RVAL2CBOOL(rb_funcall(rb_obj_class(self), rb_intern("=="), 1,
1095
+ rb_obj_class(other))))
1096
+ return Qfalse;
1097
+
1098
+ self_rb_grn_object = SELF(self);
1099
+ other_rb_grn_object = SELF(other);
1100
+
1101
+ return self_rb_grn_object->object == other_rb_grn_object->object;
1102
+ }
1103
+
1104
+ /*
1105
+ * Document-method: []
1106
+ *
1107
+ * call-seq:
1108
+ * object[id] -> 値
1109
+ *
1110
+ * _object_の_id_に対応する値を返す。
1111
+ */
1112
+ VALUE
1113
+ rb_grn_object_array_reference (VALUE self, VALUE rb_id)
1114
+ {
1115
+ VALUE exception;
1116
+ RbGrnObject *rb_grn_object;
1117
+ grn_id id, range_id;
1118
+ grn_ctx *context;
1119
+ grn_obj *object;
1120
+ grn_obj *range;
1121
+ unsigned char range_type;
1122
+ grn_obj value;
1123
+ VALUE rb_value = Qnil;
1124
+
1125
+ rb_grn_object = SELF(self);
1126
+ context = rb_grn_object->context;
1127
+ object = rb_grn_object->object;
1128
+ if (!object)
1129
+ return Qnil;
1130
+
1131
+ id = NUM2UINT(rb_id);
1132
+ range_id = grn_obj_get_range(context, object);
1133
+ range = grn_ctx_at(context, range_id);
1134
+ range_type = range ? range->header.type : GRN_VOID;
1135
+ switch (object->header.type) {
1136
+ case GRN_TABLE_HASH_KEY:
1137
+ case GRN_TABLE_PAT_KEY:
1138
+ case GRN_TABLE_NO_KEY:
1139
+ GRN_OBJ_INIT(&value, GRN_BULK, 0, GRN_ID_NIL);
1140
+ break;
1141
+ case GRN_TYPE:
1142
+ case GRN_ACCESSOR: /* FIXME */
1143
+ case GRN_ACCESSOR_VIEW: /* FIXME */
1144
+ GRN_OBJ_INIT(&value, GRN_BULK, 0, range_id);
1145
+ break;
1146
+ case GRN_COLUMN_VAR_SIZE:
1147
+ case GRN_COLUMN_FIX_SIZE:
1148
+ switch (object->header.flags & GRN_OBJ_COLUMN_TYPE_MASK) {
1149
+ case GRN_OBJ_COLUMN_VECTOR:
1150
+ GRN_OBJ_INIT(&value, GRN_VECTOR, 0, range_id);
1151
+ break;
1152
+ case GRN_OBJ_COLUMN_SCALAR:
1153
+ GRN_OBJ_INIT(&value, GRN_BULK, 0, range_id);
1154
+ break;
1155
+ default:
1156
+ rb_raise(rb_eGrnError, "unsupported column type: %u: %s",
1157
+ range_type, rb_grn_inspect(self));
1158
+ break;
1159
+ }
1160
+ break;
1161
+ case GRN_COLUMN_INDEX:
1162
+ GRN_UINT32_INIT(&value, 0);
1163
+ break;
1164
+ default:
1165
+ rb_raise(rb_eGrnError,
1166
+ "unsupported type: %s", rb_grn_inspect(self));
1167
+ break;
1168
+ }
1169
+
1170
+ grn_obj_get_value(context, object, id, &value);
1171
+ exception = rb_grn_context_to_exception(context, self);
1172
+ if (NIL_P(exception))
1173
+ rb_value = GRNVALUE2RVAL(context, &value, range, self);
1174
+ grn_obj_unlink(context, &value);
1175
+ if (!NIL_P(exception))
1176
+ rb_exc_raise(exception);
1177
+
1178
+ return rb_value;
1179
+ }
1180
+
1181
+ static rb_grn_boolean
1182
+ rb_uvector_value_p (RbGrnObject *rb_grn_object, VALUE rb_value)
1183
+ {
1184
+ VALUE first_element;
1185
+
1186
+ switch (rb_grn_object->range->header.type) {
1187
+ case GRN_TYPE:
1188
+ /* TODO: support not sizeof(grn_id) uvector. */
1189
+ /*
1190
+ if (!(rb_grn_object->range->header.flags | GRN_OBJ_KEY_VAR_SIZE)) {
1191
+ return RB_GRN_TRUE;
1192
+ }
1193
+ */
1194
+ break;
1195
+ case GRN_TABLE_HASH_KEY:
1196
+ case GRN_TABLE_PAT_KEY:
1197
+ case GRN_TABLE_NO_KEY:
1198
+ case GRN_TABLE_VIEW:
1199
+ first_element = rb_ary_entry(rb_value, 0);
1200
+ if (RVAL2CBOOL(rb_obj_is_kind_of(first_element, rb_cGrnRecord))) {
1201
+ return RB_GRN_TRUE;
1202
+ }
1203
+ break;
1204
+ default:
1205
+ break;
1206
+ }
1207
+
1208
+ return RB_GRN_FALSE;
1209
+ }
1210
+
1211
+ VALUE
1212
+ rb_grn_object_set_raw (RbGrnObject *rb_grn_object, grn_id id,
1213
+ VALUE rb_value, int flags, VALUE related_object)
1214
+ {
1215
+ grn_ctx *context;
1216
+ grn_obj value;
1217
+ grn_rc rc;
1218
+ VALUE exception;
1219
+
1220
+ context = rb_grn_object->context;
1221
+ if (RVAL2CBOOL(rb_obj_is_kind_of(rb_value, rb_cArray))) {
1222
+ if (rb_uvector_value_p(rb_grn_object, rb_value)) {
1223
+ GRN_OBJ_INIT(&value, GRN_UVECTOR, 0,
1224
+ rb_grn_object->object->header.domain);
1225
+ RVAL2GRNUVECTOR(rb_value, context, &value, related_object);
1226
+ } else {
1227
+ GRN_OBJ_INIT(&value, GRN_VECTOR, 0, GRN_ID_NIL);
1228
+ RVAL2GRNVECTOR(rb_value, context, &value);
1229
+ }
1230
+ } else {
1231
+ if (NIL_P(rb_value)) {
1232
+ GRN_OBJ_INIT(&value, GRN_BULK, 0, GRN_ID_NIL);
1233
+ } else {
1234
+ GRN_OBJ_INIT(&value, GRN_BULK, 0, GRN_ID_NIL);
1235
+ RVAL2GRNBULK(rb_value, context, &value);
1236
+ }
1237
+ }
1238
+ rc = grn_obj_set_value(context, rb_grn_object->object, id,
1239
+ &value, flags);
1240
+ exception = rb_grn_context_to_exception(context, related_object);
1241
+ grn_obj_unlink(context, &value);
1242
+ if (!NIL_P(exception))
1243
+ rb_exc_raise(exception);
1244
+ rb_grn_rc_check(rc, related_object);
1245
+
1246
+ return Qnil;
1247
+ }
1248
+
1249
+ static VALUE
1250
+ rb_grn_object_set (VALUE self, VALUE rb_id, VALUE rb_value, int flags)
1251
+ {
1252
+ RbGrnObject *rb_grn_object;
1253
+ grn_ctx *context;
1254
+ grn_id id;
1255
+
1256
+ rb_grn_object = SELF(self);
1257
+ if (!rb_grn_object->object)
1258
+ return Qnil;
1259
+
1260
+ context = rb_grn_object->context;
1261
+ id = NUM2UINT(rb_id);
1262
+
1263
+ return rb_grn_object_set_raw(rb_grn_object, id, rb_value, flags, self);
1264
+ }
1265
+
1266
+ /*
1267
+ * Document-method: []=
1268
+ *
1269
+ * call-seq:
1270
+ * object[id] = value
1271
+ *
1272
+ * _object_の_id_に対応する値を設定する。既存の値は上書きさ
1273
+ * れる。
1274
+ */
1275
+ static VALUE
1276
+ rb_grn_object_array_set (VALUE self, VALUE rb_id, VALUE rb_value)
1277
+ {
1278
+ return rb_grn_object_set(self, rb_id, rb_value, GRN_OBJ_SET);
1279
+ }
1280
+
1281
+ /*
1282
+ * Document-method: append
1283
+ *
1284
+ * call-seq:
1285
+ * object.append(id, value)
1286
+ *
1287
+ * _object_の_id_に対応する値の最後に_value_を追加する。
1288
+ */
1289
+ static VALUE
1290
+ rb_grn_object_append_value (VALUE self, VALUE rb_id, VALUE rb_value)
1291
+ {
1292
+ return rb_grn_object_set(self, rb_id, rb_value, GRN_OBJ_APPEND);
1293
+ }
1294
+
1295
+ /*
1296
+ * Document-method: prepend
1297
+ *
1298
+ * call-seq:
1299
+ * object.prepend(id, value)
1300
+ *
1301
+ * _object_の_id_に対応する値の最初に_value_を追加する。
1302
+ */
1303
+ static VALUE
1304
+ rb_grn_object_prepend_value (VALUE self, VALUE rb_id, VALUE rb_value)
1305
+ {
1306
+ return rb_grn_object_set(self, rb_id, rb_value, GRN_OBJ_PREPEND);
1307
+ }
1308
+
1309
+ /*
1310
+ * Document-method: remove
1311
+ *
1312
+ * call-seq:
1313
+ * object.remove
1314
+ *
1315
+ * _object_をメモリから解放し、それが永続オブジェクトであっ
1316
+ * た場合は、該当するファイル一式を削除する。
1317
+ */
1318
+ static VALUE
1319
+ rb_grn_object_remove (VALUE self)
1320
+ {
1321
+ RbGrnObject *rb_grn_object;
1322
+ grn_ctx *context;
1323
+ grn_rc rc;
1324
+
1325
+ rb_grn_object = SELF(self);
1326
+ if (!rb_grn_object->object)
1327
+ return Qnil;
1328
+
1329
+ context = rb_grn_object->context;
1330
+ rc = grn_obj_remove(context, rb_grn_object->object);
1331
+ rb_grn_rc_check(rc, self);
1332
+
1333
+ rb_iv_set(self, "@context", Qnil);
1334
+
1335
+ return Qnil;
1336
+ }
1337
+
1338
+ void
1339
+ rb_grn_init_object (VALUE mGrn)
1340
+ {
1341
+ rb_cGrnObject = rb_define_class_under(mGrn, "Object", rb_cObject);
1342
+ rb_define_alloc_func(rb_cGrnObject, rb_grn_object_alloc);
1343
+
1344
+ rb_define_attr(rb_cGrnObject, "context", RB_GRN_TRUE, RB_GRN_FALSE);
1345
+
1346
+ rb_define_method(rb_cGrnObject, "inspect", rb_grn_object_inspect, 0);
1347
+
1348
+ rb_define_method(rb_cGrnObject, "id", rb_grn_object_get_id, 0);
1349
+ rb_define_method(rb_cGrnObject, "domain", rb_grn_object_get_domain, 0);
1350
+ rb_define_method(rb_cGrnObject, "name", rb_grn_object_get_name, 0);
1351
+ rb_define_method(rb_cGrnObject, "range", rb_grn_object_get_range, 0);
1352
+ rb_define_method(rb_cGrnObject, "path", rb_grn_object_get_path, 0);
1353
+
1354
+ rb_define_method(rb_cGrnObject, "temporary?", rb_grn_object_temporary_p, 0);
1355
+ rb_define_method(rb_cGrnObject, "persistent?",
1356
+ rb_grn_object_persistent_p, 0);
1357
+
1358
+ rb_define_method(rb_cGrnObject, "==", rb_grn_object_equal, 1);
1359
+
1360
+ rb_define_method(rb_cGrnObject, "close", rb_grn_object_close, 0);
1361
+ rb_define_method(rb_cGrnObject, "closed?", rb_grn_object_closed_p, 0);
1362
+
1363
+ rb_define_method(rb_cGrnObject, "[]", rb_grn_object_array_reference, 1);
1364
+ rb_define_method(rb_cGrnObject, "[]=", rb_grn_object_array_set, 2);
1365
+ rb_define_method(rb_cGrnObject, "append", rb_grn_object_append_value, 2);
1366
+ rb_define_method(rb_cGrnObject, "prepend", rb_grn_object_prepend_value, 2);
1367
+
1368
+ rb_define_method(rb_cGrnObject, "remove", rb_grn_object_remove, 0);
1369
+ }