1/* -*- c-basic-offset: 2 -*- */
2/*
3 Copyright(C) 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/data.h>
24#include <mruby/hash.h>
25#include <mruby/string.h>
26
27#include "../grn_mrb.h"
28#include "../grn_output.h"
29#include "mrb_ctx.h"
30#include "mrb_writer.h"
31#include "mrb_options.h"
32
33static mrb_value
34writer_write(mrb_state *mrb, mrb_value self)
35{
36 grn_ctx *ctx = (grn_ctx *)mrb->ud;
37 mrb_value target;
38
39 mrb_get_args(mrb, "o", &target);
40
41 switch (mrb_type(target)) {
42 case MRB_TT_FALSE :
43 if (mrb_nil_p(target)) {
44 GRN_OUTPUT_NULL();
45 } else {
46 GRN_OUTPUT_BOOL(GRN_FALSE);
47 }
48 break;
49 case MRB_TT_TRUE :
50 GRN_OUTPUT_BOOL(GRN_TRUE);
51 break;
52 case MRB_TT_FIXNUM :
53 GRN_OUTPUT_INT32(mrb_fixnum(target));
54 break;
55 case MRB_TT_FLOAT :
56 GRN_OUTPUT_FLOAT(mrb_float(target));
57 break;
58 case MRB_TT_SYMBOL :
59 {
60 const char *name;
61 mrb_int name_length;
62
63 name = mrb_sym2name_len(mrb, mrb_symbol(target), &name_length);
64 GRN_OUTPUT_STR(name, name_length);
65 }
66 break;
67 case MRB_TT_STRING :
68 GRN_OUTPUT_STR(RSTRING_PTR(target), RSTRING_LEN(target));
69 break;
70 default :
71 mrb_raisef(mrb, E_ARGUMENT_ERROR,
72 "must be nil, true, false, number, float, symbol or string: "
73 "%S",
74 target);
75 break;
76 }
77
78 return mrb_nil_value();
79}
80
81static mrb_value
82writer_open_array(mrb_state *mrb, mrb_value self)
83{
84 grn_ctx *ctx = (grn_ctx *)mrb->ud;
85 char *name;
86 mrb_int n_elements;
87
88 mrb_get_args(mrb, "zi", &name, &n_elements);
89 GRN_OUTPUT_ARRAY_OPEN(name, n_elements);
90
91 return mrb_nil_value();
92}
93
94static mrb_value
95writer_close_array(mrb_state *mrb, mrb_value self)
96{
97 grn_ctx *ctx = (grn_ctx *)mrb->ud;
98
99 GRN_OUTPUT_ARRAY_CLOSE();
100
101 return mrb_nil_value();
102}
103
104static mrb_value
105writer_open_map(mrb_state *mrb, mrb_value self)
106{
107 grn_ctx *ctx = (grn_ctx *)mrb->ud;
108 char *name;
109 mrb_int n_elements;
110
111 mrb_get_args(mrb, "zi", &name, &n_elements);
112 GRN_OUTPUT_MAP_OPEN(name, n_elements);
113
114 return mrb_nil_value();
115}
116
117static mrb_value
118writer_close_map(mrb_state *mrb, mrb_value self)
119{
120 grn_ctx *ctx = (grn_ctx *)mrb->ud;
121
122 GRN_OUTPUT_MAP_CLOSE();
123
124 return mrb_nil_value();
125}
126
127static mrb_value
128writer_write_table_columns(mrb_state *mrb, mrb_value self)
129{
130 grn_ctx *ctx = (grn_ctx *)mrb->ud;
131 mrb_value mrb_table;
132 char *columns;
133 mrb_int columns_size;
134 grn_obj *table;
135 grn_obj_format format;
136 int n_hits = 0;
137 int offset = 0;
138 int limit = 0;
139 int hits_offset = 0;
140
141 mrb_get_args(mrb, "os", &mrb_table, &columns, &columns_size);
142
143 table = DATA_PTR(mrb_table);
144 GRN_OBJ_FORMAT_INIT(&format, n_hits, offset, limit, hits_offset);
145 format.flags |= GRN_OBJ_FORMAT_WITH_COLUMN_NAMES;
146 {
147 grn_rc rc;
148 rc = grn_output_format_set_columns(ctx, &format,
149 table, columns, columns_size);
150 if (rc != GRN_SUCCESS) {
151 GRN_OBJ_FORMAT_FIN(ctx, &format);
152 grn_mrb_ctx_check(mrb);
153 }
154 }
155 GRN_OUTPUT_TABLE_COLUMNS(table, &format);
156 GRN_OBJ_FORMAT_FIN(ctx, &format);
157
158 return mrb_nil_value();
159}
160
161static mrb_value
162writer_write_table_records(mrb_state *mrb, mrb_value self)
163{
164 grn_ctx *ctx = (grn_ctx *)mrb->ud;
165 mrb_value mrb_table;
166 mrb_value mrb_options = mrb_nil_value();
167 char *columns;
168 mrb_int columns_size;
169 grn_obj *table;
170 grn_obj_format format;
171 int n_hits = 0;
172 int offset = 0;
173 int limit = -1;
174 int hits_offset = 0;
175
176 mrb_get_args(mrb, "os|H", &mrb_table, &columns, &columns_size, &mrb_options);
177
178 table = DATA_PTR(mrb_table);
179 if (!mrb_nil_p(mrb_options)) {
180 mrb_value mrb_offset;
181 mrb_value mrb_limit;
182
183 mrb_offset = grn_mrb_options_get_lit(mrb, mrb_options, "offset");
184 if (!mrb_nil_p(mrb_offset)) {
185 offset = mrb_fixnum(mrb_offset);
186 }
187
188 mrb_limit = grn_mrb_options_get_lit(mrb, mrb_options, "limit");
189 if (!mrb_nil_p(mrb_limit)) {
190 limit = mrb_fixnum(mrb_limit);
191 }
192 }
193 if (limit < 0) {
194 limit = grn_table_size(ctx, table) + limit + 1;
195 }
196 GRN_OBJ_FORMAT_INIT(&format, n_hits, offset, limit, hits_offset);
197 {
198 grn_rc rc;
199 rc = grn_output_format_set_columns(ctx, &format,
200 table, columns, columns_size);
201 if (rc != GRN_SUCCESS) {
202 GRN_OBJ_FORMAT_FIN(ctx, &format);
203 grn_mrb_ctx_check(mrb);
204 }
205 }
206 GRN_OUTPUT_TABLE_RECORDS(table, &format);
207 GRN_OBJ_FORMAT_FIN(ctx, &format);
208
209 return mrb_nil_value();
210}
211
212static mrb_value
213writer_set_content_type(mrb_state *mrb, mrb_value self)
214{
215 grn_ctx *ctx = (grn_ctx *)mrb->ud;
216 mrb_int content_type;
217
218 mrb_get_args(mrb, "i", &content_type);
219
220 grn_ctx_set_output_type(ctx, content_type);
221
222 return mrb_nil_value();
223}
224
225void
226grn_mrb_writer_init(grn_ctx *ctx)
227{
228 grn_mrb_data *data = &(ctx->impl->mrb);
229 mrb_state *mrb = data->state;
230 struct RClass *module = data->module;
231 struct RClass *klass;
232
233 klass = mrb_define_class_under(mrb, module, "Writer", mrb->object_class);
234
235 mrb_define_method(mrb, klass, "write", writer_write, MRB_ARGS_REQ(1));
236 mrb_define_method(mrb, klass, "open_array",
237 writer_open_array, MRB_ARGS_REQ(2));
238 mrb_define_method(mrb, klass, "close_array",
239 writer_close_array, MRB_ARGS_NONE());
240 mrb_define_method(mrb, klass, "open_map",
241 writer_open_map, MRB_ARGS_REQ(2));
242 mrb_define_method(mrb, klass, "close_map",
243 writer_close_map, MRB_ARGS_NONE());
244
245 mrb_define_method(mrb, klass, "write_table_columns",
246 writer_write_table_columns, MRB_ARGS_REQ(2));
247 mrb_define_method(mrb, klass, "write_table_records",
248 writer_write_table_records, MRB_ARGS_ARG(2, 1));
249
250 mrb_define_method(mrb, klass, "content_type=",
251 writer_set_content_type, MRB_ARGS_REQ(1));
252}
253#endif
254