1/* -*- c-basic-offset: 2 -*- */
2/*
3 Copyright(C) 2013-2016 Brazil
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17*/
18
19#include "../grn_ctx_impl.h"
20#include "../grn_util.h"
21
22#ifdef GRN_WITH_MRUBY
23#include <mruby.h>
24#include <mruby/string.h>
25#include <mruby/class.h>
26#include <mruby/data.h>
27
28#include "../grn_mrb.h"
29#include "mrb_ctx.h"
30#include "mrb_object.h"
31#include "mrb_operator.h"
32#include "mrb_options.h"
33#include "mrb_converter.h"
34
35static mrb_value
36object_remove_force(mrb_state *mrb, mrb_value self)
37{
38 grn_ctx *ctx = (grn_ctx *)mrb->ud;
39 char *name;
40 mrb_int name_size;
41
42 mrb_get_args(mrb, "s", &name, &name_size);
43 grn_obj_remove_force(ctx, name, name_size);
44 grn_mrb_ctx_check(mrb);
45
46 return mrb_nil_value();
47}
48
49mrb_value
50grn_mrb_object_inspect(mrb_state *mrb, mrb_value self)
51{
52 grn_ctx *ctx = (grn_ctx *)mrb->ud;
53 grn_obj *object;
54 mrb_value inspected;
55
56 object = DATA_PTR(self);
57 inspected = mrb_str_buf_new(mrb, 48);
58
59 mrb_str_cat_lit(mrb, inspected, "#<");
60 mrb_str_cat_cstr(mrb, inspected, mrb_obj_classname(mrb, self));
61 mrb_str_cat_lit(mrb, inspected, ":");
62 mrb_str_concat(mrb, inspected, mrb_ptr_to_str(mrb, mrb_cptr(self)));
63 if (object) {
64 grn_obj buffer;
65 GRN_TEXT_INIT(&buffer, 0);
66 grn_inspect(ctx, &buffer, object);
67 mrb_str_cat_lit(mrb, inspected, " ");
68 mrb_str_cat(mrb, inspected, GRN_TEXT_VALUE(&buffer), GRN_TEXT_LEN(&buffer));
69 GRN_OBJ_FIN(ctx, &buffer);
70 } else {
71 mrb_str_cat_lit(mrb, inspected, " (closed)");
72 }
73 mrb_str_cat_lit(mrb, inspected, ">");
74
75 return inspected;
76}
77
78static mrb_value
79object_get_id(mrb_state *mrb, mrb_value self)
80{
81 grn_ctx *ctx = (grn_ctx *)mrb->ud;
82 grn_id id;
83
84 id = grn_obj_id(ctx, DATA_PTR(self));
85
86 return mrb_fixnum_value(id);
87}
88
89static mrb_value
90object_get_name(mrb_state *mrb, mrb_value self)
91{
92 grn_ctx *ctx = (grn_ctx *)mrb->ud;
93 grn_obj *object;
94 char name[GRN_TABLE_MAX_KEY_SIZE];
95 int name_length;
96
97 object = DATA_PTR(self);
98 name_length = grn_obj_name(ctx, object, name, GRN_TABLE_MAX_KEY_SIZE);
99
100 if (name_length == 0) {
101 return mrb_nil_value();
102 } else {
103 return mrb_str_new(mrb, name, name_length);
104 }
105}
106
107static mrb_value
108object_get_path(mrb_state *mrb, mrb_value self)
109{
110 grn_ctx *ctx = (grn_ctx *)mrb->ud;
111 grn_obj *object;
112 const char *path;
113
114 object = DATA_PTR(self);
115 path = grn_obj_path(ctx, object);
116
117 if (path) {
118 return mrb_str_new_cstr(mrb, path);
119 } else {
120 return mrb_nil_value();
121 }
122}
123
124static mrb_value
125object_grn_inspect(mrb_state *mrb, mrb_value self)
126{
127 grn_ctx *ctx = (grn_ctx *)mrb->ud;
128 grn_obj buffer;
129 mrb_value inspected;
130
131 GRN_TEXT_INIT(&buffer, 0);
132 grn_inspect(ctx, &buffer, DATA_PTR(self));
133 inspected = mrb_str_new(mrb, GRN_TEXT_VALUE(&buffer), GRN_TEXT_LEN(&buffer));
134 GRN_OBJ_FIN(ctx, &buffer);
135
136 return inspected;
137}
138
139static mrb_value
140object_equal(mrb_state *mrb, mrb_value self)
141{
142 grn_obj *object, *other_object;
143 mrb_value mrb_other;
144
145 mrb_get_args(mrb, "o", &mrb_other);
146 if (!mrb_obj_is_kind_of(mrb, mrb_other, mrb_obj_class(mrb, self))) {
147 return mrb_false_value();
148 }
149
150 object = DATA_PTR(self);
151 other_object = DATA_PTR(mrb_other);
152 return mrb_bool_value(object == other_object);
153}
154
155static mrb_value
156object_hash(mrb_state *mrb, mrb_value self)
157{
158 grn_obj *object;
159
160 object = DATA_PTR(self);
161 return mrb_fixnum_value((mrb_int)((uint64_t)object));
162}
163
164static mrb_value
165object_close(mrb_state *mrb, mrb_value self)
166{
167 grn_ctx *ctx = (grn_ctx *)mrb->ud;
168 grn_obj *object;
169
170 object = DATA_PTR(self);
171 if (!object) {
172 mrb_raise(mrb, E_ARGUMENT_ERROR, "already closed object");
173 }
174
175 grn_obj_close(ctx, object);
176 DATA_PTR(self) = NULL;
177
178 return mrb_nil_value();
179}
180
181static mrb_value
182object_remove(mrb_state *mrb, mrb_value self)
183{
184 grn_ctx *ctx = (grn_ctx *)mrb->ud;
185 mrb_value mrb_options = mrb_nil_value();
186 grn_bool dependent = GRN_FALSE;
187 grn_obj *object;
188
189 mrb_get_args(mrb, "|H", &mrb_options);
190 if (!mrb_nil_p(mrb_options)) {
191 mrb_value mrb_dependent;
192 mrb_dependent = grn_mrb_options_get_lit(mrb, mrb_options, "dependent");
193 dependent = mrb_test(mrb_dependent);
194 }
195
196 object = DATA_PTR(self);
197 if (dependent) {
198 grn_obj_remove_dependent(ctx, object);
199 } else {
200 grn_obj_remove(ctx, object);
201 }
202 grn_mrb_ctx_check(mrb);
203
204 DATA_PTR(self) = NULL;
205
206 return mrb_nil_value();
207}
208
209static mrb_value
210object_is_closed(mrb_state *mrb, mrb_value self)
211{
212 grn_obj *object;
213
214 object = DATA_PTR(self);
215 return mrb_bool_value(object == NULL);
216}
217
218static mrb_value
219object_get_domain_id(mrb_state *mrb, mrb_value self)
220{
221 grn_obj *object;
222 grn_id domain_id;
223
224 object = DATA_PTR(self);
225 domain_id = object->header.domain;
226
227 if (domain_id == GRN_ID_NIL) {
228 return mrb_nil_value();
229 } else {
230 return mrb_fixnum_value(domain_id);
231 }
232}
233
234static mrb_value
235object_get_range_id(mrb_state *mrb, mrb_value self)
236{
237 grn_ctx *ctx = (grn_ctx *)mrb->ud;
238 grn_obj *object;
239 grn_id range_id;
240
241 object = DATA_PTR(self);
242 range_id = grn_obj_get_range(ctx, object);
243
244 if (range_id == GRN_ID_NIL) {
245 return mrb_nil_value();
246 } else {
247 return mrb_fixnum_value(range_id);
248 }
249}
250
251static mrb_value
252object_is_temporary(mrb_state *mrb, mrb_value self)
253{
254 grn_obj *object;
255 grn_obj_flags flags;
256
257 object = DATA_PTR(self);
258 flags = object->header.flags;
259 return mrb_bool_value((flags & GRN_OBJ_PERSISTENT) != GRN_OBJ_PERSISTENT);
260}
261
262static mrb_value
263object_is_persistent(mrb_state *mrb, mrb_value self)
264{
265 grn_obj *object;
266 grn_obj_flags flags;
267
268 object = DATA_PTR(self);
269 flags = object->header.flags;
270 return mrb_bool_value((flags & GRN_OBJ_PERSISTENT) == GRN_OBJ_PERSISTENT);
271}
272
273static mrb_value
274object_is_true(mrb_state *mrb, mrb_value self)
275{
276 grn_ctx *ctx = (grn_ctx *)mrb->ud;
277 grn_obj *object;
278
279 object = DATA_PTR(self);
280 return mrb_bool_value(grn_obj_is_true(ctx, object));
281}
282
283static mrb_value
284object_check_corrupt(mrb_state *mrb, mrb_value self)
285{
286 grn_ctx *ctx = (grn_ctx *)mrb->ud;
287 grn_obj *object;
288 grn_bool is_corrupt;
289
290 object = DATA_PTR(self);
291 is_corrupt = grn_obj_is_corrupt(ctx, object);
292 grn_mrb_ctx_check(mrb);
293 return mrb_bool_value(is_corrupt);
294}
295
296void
297grn_mrb_object_init(grn_ctx *ctx)
298{
299 grn_mrb_data *data = &(ctx->impl->mrb);
300 mrb_state *mrb = data->state;
301 struct RClass *module = data->module;
302 struct RClass *klass;
303
304 klass = mrb_define_class_under(mrb, module, "Object", mrb->object_class);
305 MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
306 data->object_class = klass;
307
308 mrb_define_class_method(mrb,
309 klass,
310 "remove_force",
311 object_remove_force,
312 MRB_ARGS_REQ(1));
313
314 mrb_define_method(mrb, klass, "inspect",
315 grn_mrb_object_inspect, MRB_ARGS_NONE());
316
317 mrb_define_method(mrb, klass, "id", object_get_id, MRB_ARGS_NONE());
318 mrb_define_method(mrb, klass, "name", object_get_name, MRB_ARGS_NONE());
319 mrb_define_method(mrb, klass, "path", object_get_path, MRB_ARGS_NONE());
320 mrb_define_method(mrb, klass, "grn_inspect",
321 object_grn_inspect, MRB_ARGS_NONE());
322 mrb_define_method(mrb, klass, "==", object_equal, MRB_ARGS_REQ(1));
323 mrb_define_method(mrb, klass, "eql?", object_equal, MRB_ARGS_REQ(1));
324 mrb_define_method(mrb, klass, "hash", object_hash, MRB_ARGS_NONE());
325 mrb_define_method(mrb, klass, "close", object_close, MRB_ARGS_NONE());
326 mrb_define_method(mrb, klass, "remove", object_remove, MRB_ARGS_OPT(1));
327 mrb_define_method(mrb, klass, "closed?", object_is_closed, MRB_ARGS_NONE());
328
329 mrb_define_method(mrb, klass, "domain_id", object_get_domain_id,
330 MRB_ARGS_NONE());
331 mrb_define_method(mrb, klass, "range_id", object_get_range_id,
332 MRB_ARGS_NONE());
333
334 mrb_define_method(mrb, klass, "temporary?", object_is_temporary,
335 MRB_ARGS_NONE());
336 mrb_define_method(mrb, klass, "persistent?", object_is_persistent,
337 MRB_ARGS_NONE());
338
339 mrb_define_method(mrb, klass, "true?", object_is_true, MRB_ARGS_NONE());
340
341 mrb_define_method(mrb, klass, "check_corrupt", object_check_corrupt,
342 MRB_ARGS_NONE());
343
344 grn_mrb_load(ctx, "index_info.rb");
345}
346#endif
347