1/* -*- c-basic-offset: 2 -*- */
2/*
3 Copyright(C) 2014-2015 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
21#ifdef GRN_WITH_MRUBY
22#include <mruby.h>
23#include <mruby/class.h>
24#include <mruby/data.h>
25
26#include "mrb_ctx.h"
27#include "mrb_database.h"
28#include "mrb_converter.h"
29
30static struct mrb_data_type mrb_grn_database_type = {
31 "Groonga::Database",
32 NULL
33};
34
35static mrb_value
36mrb_grn_database_initialize(mrb_state *mrb, mrb_value self)
37{
38 mrb_value mrb_database_ptr;
39
40 mrb_get_args(mrb, "o", &mrb_database_ptr);
41 DATA_TYPE(self) = &mrb_grn_database_type;
42 DATA_PTR(self) = mrb_cptr(mrb_database_ptr);
43 return self;
44}
45
46static mrb_value
47mrb_grn_database_class_open(mrb_state *mrb, mrb_value klass)
48{
49 grn_ctx *ctx = (grn_ctx *)mrb->ud;
50 grn_obj *database;
51 char *path;
52
53 mrb_get_args(mrb, "z", &path);
54
55 database = grn_db_open(ctx, path);
56 grn_mrb_ctx_check(mrb);
57
58 return mrb_funcall(mrb, klass, "new", 1, mrb_cptr_value(mrb, database));
59}
60
61static mrb_value
62mrb_grn_database_class_create(mrb_state *mrb, mrb_value klass)
63{
64 grn_ctx *ctx = (grn_ctx *)mrb->ud;
65 grn_obj *database;
66 char *path;
67
68 mrb_get_args(mrb, "z", &path);
69
70 database = grn_db_create(ctx, path, NULL);
71 grn_mrb_ctx_check(mrb);
72
73 return mrb_funcall(mrb, klass, "new", 1, mrb_cptr_value(mrb, database));
74}
75
76static mrb_value
77mrb_grn_database_recover(mrb_state *mrb, mrb_value self)
78{
79 grn_ctx *ctx = (grn_ctx *)mrb->ud;
80
81 grn_db_recover(ctx, DATA_PTR(self));
82 grn_mrb_ctx_check(mrb);
83
84 return mrb_nil_value();
85}
86
87static mrb_value
88mrb_grn_database_is_locked(mrb_state *mrb, mrb_value self)
89{
90 grn_ctx *ctx = (grn_ctx *)mrb->ud;
91 unsigned int is_locked;
92
93 is_locked = grn_obj_is_locked(ctx, DATA_PTR(self));
94 grn_mrb_ctx_check(mrb);
95
96 return mrb_bool_value(is_locked != 0);
97}
98
99static mrb_value
100mrb_grn_database_get_last_modified(mrb_state *mrb, mrb_value self)
101{
102 grn_ctx *ctx = (grn_ctx *)mrb->ud;
103 uint32_t last_modified;
104 struct RClass *time_class;
105
106 last_modified = grn_db_get_last_modified(ctx, DATA_PTR(self));
107
108 time_class = mrb_class_get(mrb, "Time");
109 return mrb_funcall(mrb,
110 mrb_obj_value(time_class),
111 "at",
112 1,
113 mrb_float_value(mrb, last_modified));
114}
115
116static mrb_value
117mrb_grn_database_is_dirty(mrb_state *mrb, mrb_value self)
118{
119 grn_ctx *ctx = (grn_ctx *)mrb->ud;
120 grn_bool is_dirty;
121
122 is_dirty = grn_db_is_dirty(ctx, DATA_PTR(self));
123
124 return mrb_bool_value(is_dirty);
125}
126
127static mrb_value
128mrb_grn_database_array_reference(mrb_state *mrb, mrb_value self)
129{
130 grn_ctx *ctx = (grn_ctx *)mrb->ud;
131 grn_obj *database;
132 mrb_value mrb_id_or_key;
133
134 mrb_get_args(mrb, "o", &mrb_id_or_key);
135
136 database = DATA_PTR(self);
137
138 if (mrb_fixnum_p(mrb_id_or_key)) {
139 char name[GRN_TABLE_MAX_KEY_SIZE];
140 int name_size;
141
142 name_size = grn_table_get_key(ctx,
143 grn_ctx_db(ctx),
144 mrb_fixnum(mrb_id_or_key),
145 name,
146 GRN_TABLE_MAX_KEY_SIZE);
147 if (name_size == 0) {
148 return mrb_nil_value();
149 } else {
150 return mrb_str_new(mrb, name, name_size);
151 }
152 } else {
153 grn_id name_domain_id = GRN_DB_SHORT_TEXT;
154 grn_id id;
155 grn_mrb_value_to_raw_data_buffer buffer;
156 void *name;
157 unsigned int name_size;
158
159 grn_mrb_value_to_raw_data_buffer_init(mrb, &buffer);
160 grn_mrb_value_to_raw_data(mrb, "name", mrb_id_or_key,
161 name_domain_id, &buffer,
162 &name, &name_size);
163 id = grn_table_get(ctx, database, name, name_size);
164 grn_mrb_value_to_raw_data_buffer_fin(mrb, &buffer);
165
166 if (id == GRN_ID_NIL) {
167 return mrb_nil_value();
168 } else {
169 return mrb_fixnum_value(id);
170 }
171 }
172}
173
174void
175grn_mrb_database_init(grn_ctx *ctx)
176{
177 grn_mrb_data *data = &(ctx->impl->mrb);
178 mrb_state *mrb = data->state;
179 struct RClass *module = data->module;
180 struct RClass *object_class = data->object_class;
181 struct RClass *klass;
182
183 klass = mrb_define_class_under(mrb, module, "Database", object_class);
184 MRB_SET_INSTANCE_TT(klass, MRB_TT_DATA);
185
186 mrb_define_class_method(mrb, klass, "open",
187 mrb_grn_database_class_open,
188 MRB_ARGS_REQ(1));
189 mrb_define_class_method(mrb, klass, "create",
190 mrb_grn_database_class_create,
191 MRB_ARGS_REQ(1));
192
193 mrb_define_method(mrb, klass, "initialize",
194 mrb_grn_database_initialize, MRB_ARGS_REQ(1));
195 mrb_define_method(mrb, klass, "recover",
196 mrb_grn_database_recover, MRB_ARGS_NONE());
197 mrb_define_method(mrb, klass, "locked?",
198 mrb_grn_database_is_locked, MRB_ARGS_NONE());
199 mrb_define_method(mrb, klass, "last_modified",
200 mrb_grn_database_get_last_modified, MRB_ARGS_NONE());
201 mrb_define_method(mrb, klass, "dirty?",
202 mrb_grn_database_is_dirty, MRB_ARGS_NONE());
203 mrb_define_method(mrb, klass, "[]",
204 mrb_grn_database_array_reference, MRB_ARGS_REQ(1));
205}
206#endif
207