rroonga 2.1.2 → 2.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,53 +0,0 @@
1
- /* -*- coding: utf-8; c-file-style: "ruby" -*- */
2
- /*
3
- Copyright (C) 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
- #include "rb-grn.h"
20
-
21
- #define SELF(object) (RVAL2GRNVIEWACCESSOR(object))
22
-
23
- VALUE rb_cGrnViewAccessor;
24
-
25
- grn_obj *
26
- rb_grn_view_accessor_from_ruby_object (VALUE object)
27
- {
28
- if (!RVAL2CBOOL(rb_obj_is_kind_of(object, rb_cGrnViewAccessor))) {
29
- rb_raise(rb_eTypeError, "not a groonga accessor view");
30
- }
31
-
32
- return RVAL2GRNOBJECT(object, NULL);
33
- }
34
-
35
- VALUE
36
- rb_grn_view_accessor_to_ruby_object (grn_ctx *context, grn_obj *table,
37
- grn_bool owner)
38
- {
39
- return GRNOBJECT2RVAL(rb_cGrnViewAccessor, context, table, owner);
40
- }
41
-
42
- /*
43
- * Document-class: Groonga::ViewAccessor < Groonga::Object
44
- *
45
- * キー、値、スコアなど種々の値へのアクセスをカプセル化した
46
- * オブジェクト。 {Groonga::Table#column} で取得できる。
47
- */
48
- void
49
- rb_grn_init_view_accessor (VALUE mGrn)
50
- {
51
- rb_cGrnViewAccessor =
52
- rb_define_class_under(mGrn, "ViewAccessor", rb_cGrnObject);
53
- }
@@ -1,35 +0,0 @@
1
- /* -*- coding: utf-8; c-file-style: "ruby" -*- */
2
- /*
3
- Copyright (C) 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
- #include "rb-grn.h"
20
-
21
- VALUE rb_cGrnViewCursor;
22
-
23
- /*
24
- * Document-class: Groonga::ViewCursor < Groonga::TableCursor
25
- *
26
- * {Groonga::View} からレコードを順番に取り出すためのオブジェク
27
- * ト。利用できるメソッドは {Groonga::TableCursor} を参照。
28
- */
29
-
30
- void
31
- rb_grn_init_view_cursor (VALUE mGrn)
32
- {
33
- rb_cGrnViewCursor =
34
- rb_define_class_under(mGrn, "ViewCursor", rb_cGrnTableCursor);
35
- }
@@ -1,41 +0,0 @@
1
- /* -*- coding: utf-8; c-file-style: "ruby" -*- */
2
- /*
3
- Copyright (C) 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
- #include "rb-grn.h"
20
-
21
- VALUE rb_cGrnViewRecord;
22
-
23
- VALUE
24
- rb_grn_view_record_new (VALUE view, grn_obj *id)
25
- {
26
- return rb_grn_view_record_new_raw(view,
27
- rb_str_new(GRN_TEXT_VALUE(id),
28
- GRN_TEXT_LEN(id)));
29
- }
30
-
31
- VALUE
32
- rb_grn_view_record_new_raw (VALUE view, VALUE rb_id)
33
- {
34
- return rb_funcall(rb_cGrnViewRecord, rb_intern("new"), 2, view, rb_id);
35
- }
36
-
37
- void
38
- rb_grn_init_view_record (VALUE mGrn)
39
- {
40
- rb_cGrnViewRecord = rb_const_get(mGrn, rb_intern("ViewRecord"));
41
- }
@@ -1,414 +0,0 @@
1
- /* -*- coding: utf-8; c-file-style: "ruby" -*- */
2
- /*
3
- Copyright (C) 2010-2011 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
- /* FIXME */
22
- grn_id grn_view_add(grn_ctx *ctx, grn_obj *view, grn_obj *table);
23
- grn_rc grn_table_cursor_next_o(grn_ctx *ctx, grn_table_cursor *tc, grn_obj *id);
24
- grn_obj *grn_obj_get_value_o(grn_ctx *ctx, grn_obj *obj, grn_obj *id, grn_obj *value);
25
-
26
- #define SELF(object) ((RbGrnTable *)DATA_PTR(object))
27
-
28
- VALUE rb_cGrnView;
29
-
30
- /*
31
- * Document-class: Groonga::View < Groonga::Table
32
- *
33
- * 複数のテーブルを1つのテーブルとして扱う仮想的なテーブル
34
- * (ビュー)。
35
- */
36
-
37
- /*
38
- * 複数のテーブルを1つのテーブルとして扱う仮想的なテーブル
39
- * (ビュー)を生成する。ブロックを指定すると、そのブロック
40
- * に生成したテーブルが渡され、ブロックを抜けると自動的にテー
41
- * ブルが破棄される。
42
- *
43
- * ビューにテーブルを追加するときは {#add_table} を
44
- * 使う。
45
- *
46
- * @example 無名一時ビューを生成する。
47
- * Groonga::View.create
48
- *
49
- * @example 無名永続ビューを生成する。
50
- * Groonga::View.create(:path => "/tmp/view.grn")
51
- *
52
- * @example 名前付き永続ビューを生成する。ただし、ファイル名は気にしない。
53
- * Groonga::View.create(:name => "Entries",
54
- * :persistent => true)
55
- *
56
- * @example +Users+ テーブルと +Dogs+ テーブルを横断検索するためのビューを生成する。
57
- * entries = Groonga::View.create(:name => "Entries")
58
- * entries.add_table("Users")
59
- * entries.add_table("Dogs")
60
- *
61
- * @overload create(options={})
62
- * @return [Groonga::View]
63
- * @!macro [new] view.create.options
64
- * @param options [::Hash] The name and value
65
- * pairs. Omitted names are initialized as the default value
66
- * @option options :context (Groonga::Context.default)
67
- * ビューが利用する {Groonga::Context} 。
68
- * @option options :name
69
- * ビューの名前。名前をつけると、 {Groonga::Context#[]} に名
70
- * 前を指定してビューを取得することができる。省略すると
71
- * 無名ビューになり、ビューIDでのみ取得できる。
72
- * @option options :path
73
- * ビューを保存するパス。パスを指定すると永続ビューとな
74
- * り、プロセス終了後もレコードは保持される。次回起動時に
75
- * {Groonga::View.open} で保存されたビューを利用することが
76
- * できる。省略すると一時ビューになり、プロセスが終了する
77
- * とビューは破棄される。
78
- * @option options :persistent
79
- * +true+ を指定すると永続ビューとなる。 +path+ を省略した
80
- * 場合は自動的にパスが付加される。 +:context+ で指定した
81
- * {Groonga::Context} に結びついているデータベースが一時デー
82
- * タベースの場合は例外が発生する。
83
- * @!macro view.create.options
84
- * @overload create(options={})
85
- * @yield [table]
86
- * @!macro view.create.options
87
- */
88
- static VALUE
89
- rb_grn_view_s_create (int argc, VALUE *argv, VALUE klass)
90
- {
91
- grn_ctx *context;
92
- grn_obj *table;
93
- const char *name = NULL, *path = NULL;
94
- unsigned name_size = 0;
95
- grn_obj_flags flags = GRN_TABLE_VIEW;
96
- VALUE rb_table;
97
- VALUE options, rb_context, rb_name, rb_path, rb_persistent;
98
-
99
- rb_scan_args(argc, argv, "01", &options);
100
-
101
- rb_grn_scan_options(options,
102
- "context", &rb_context,
103
- "name", &rb_name,
104
- "path", &rb_path,
105
- "persistent", &rb_persistent,
106
- NULL);
107
-
108
- context = rb_grn_context_ensure(&rb_context);
109
-
110
- if (!NIL_P(rb_name)) {
111
- name = StringValuePtr(rb_name);
112
- name_size = RSTRING_LEN(rb_name);
113
- flags |= GRN_OBJ_PERSISTENT;
114
- }
115
-
116
- if (!NIL_P(rb_path)) {
117
- path = StringValueCStr(rb_path);
118
- flags |= GRN_OBJ_PERSISTENT;
119
- }
120
-
121
- if (RVAL2CBOOL(rb_persistent))
122
- flags |= GRN_OBJ_PERSISTENT;
123
-
124
- table = grn_table_create(context, name, name_size, path, flags, NULL, NULL);
125
- if (!table)
126
- rb_grn_context_check(context, rb_ary_new4(argc, argv));
127
- rb_table = GRNOBJECT2RVAL(klass, context, table, GRN_TRUE);
128
-
129
- if (rb_block_given_p())
130
- return rb_ensure(rb_yield, rb_table, rb_grn_object_close, rb_table);
131
- else
132
- return rb_table;
133
- }
134
-
135
- /*
136
- * _table_ をビューからアクセスできるようにする。
137
- *
138
- * @overload add_table(table)
139
- */
140
- static VALUE
141
- rb_grn_view_add_table (VALUE self, VALUE rb_table)
142
- {
143
- #ifdef WIN32
144
- rb_raise(rb_eNotImpError, "grn_view_add() isn't available on Windows.");
145
- #else
146
- grn_ctx *context = NULL;
147
- grn_obj *view, *table;
148
-
149
- rb_grn_table_deconstruct(SELF(self), &view, &context,
150
- NULL, NULL,
151
- NULL, NULL, NULL,
152
- NULL);
153
- table = RVAL2GRNOBJECT(rb_table, &context);
154
- grn_view_add(context, view, table);
155
- rb_grn_context_check(context, self);
156
- #endif
157
-
158
- return Qnil;
159
- }
160
-
161
- /*
162
- * ビューに登録されているテーブルのレコードを順番にブロック
163
- * に渡す。
164
- *
165
- * @overload each
166
- * @yield [record]
167
- */
168
- static VALUE
169
- rb_grn_view_each (VALUE self)
170
- {
171
- #ifdef WIN32
172
- rb_raise(rb_eNotImpError,
173
- "grn_table_cursor_next_o() isn't available on Windows.");
174
- #else
175
- RbGrnTable *rb_grn_view;
176
- RbGrnObject *rb_grn_object;
177
- grn_ctx *context = NULL;
178
- grn_obj *view;
179
- grn_table_cursor *cursor;
180
- VALUE rb_cursor;
181
- grn_obj id;
182
- grn_rc rc = GRN_SUCCESS;
183
-
184
- rb_grn_view = SELF(self);
185
- rb_grn_table_deconstruct(rb_grn_view, &view, &context,
186
- NULL, NULL,
187
- NULL, NULL, NULL,
188
- NULL);
189
- cursor = grn_table_cursor_open(context, view, NULL, 0, NULL, 0,
190
- 0, -1, GRN_CURSOR_ASCENDING);
191
- rb_cursor = GRNTABLECURSOR2RVAL(Qnil, context, cursor);
192
- rb_grn_object = RB_GRN_OBJECT(rb_grn_view);
193
- GRN_TEXT_INIT(&id, 0);
194
- while (rb_grn_object->object &&
195
- (rc = grn_table_cursor_next_o(context, cursor, &id)) == GRN_SUCCESS) {
196
- rb_yield(rb_grn_view_record_new(self, &id));
197
- }
198
- GRN_OBJ_FIN(context, &id);
199
- rb_grn_object_close(rb_cursor);
200
-
201
- if (!(rc == GRN_SUCCESS || rc == GRN_END_OF_DATA)) {
202
- rb_grn_context_check(context, self);
203
- }
204
- #endif
205
-
206
- return Qnil;
207
- }
208
-
209
- /*
210
- * _view_ の _id_ に対応するカラム _name_ のもつ値を返す。
211
- *
212
- * @overload column_value(id, name)
213
- * @param [String] id _view_ のもつ _id_
214
- * @param [String] name _id_ に対応するカラム名
215
- * @return カラム _name_ のもつ値
216
- */
217
- static VALUE
218
- rb_grn_view_get_column_value (VALUE self, VALUE rb_id, VALUE rb_name)
219
- {
220
- VALUE rb_value = Qnil;
221
- #ifdef WIN32
222
- rb_raise(rb_eNotImpError,
223
- "grn_obj_get_value_o() isn't available on Windows.");
224
- #else
225
- RbGrnTable *rb_view;
226
- grn_ctx *context = NULL;
227
- grn_obj *view, *value, *accessor;
228
- grn_obj id;
229
-
230
- rb_view = SELF(self);
231
- rb_grn_table_deconstruct(rb_view, &view, &context,
232
- NULL, NULL,
233
- &value, NULL, NULL,
234
- NULL);
235
- GRN_BULK_REWIND(value);
236
- GRN_TEXT_INIT(&id, 0);
237
- GRN_TEXT_PUT(context, &id, RSTRING_PTR(rb_id), RSTRING_LEN(rb_id));
238
- accessor = grn_obj_column(context, view,
239
- RSTRING_PTR(rb_name), RSTRING_LEN(rb_name));
240
- grn_obj_get_value_o(context, accessor, &id, value);
241
- grn_obj_unlink(context, accessor);
242
- rb_value = GRNOBJ2RVAL(Qnil, context, value, self);
243
- GRN_OBJ_FIN(context, &id);
244
- #endif
245
-
246
- return rb_value;
247
- }
248
-
249
- /*
250
- * call-seq:
251
- * view.sort(keys, options={}) -> Groonga::ViewRecordの配列
252
- *
253
- * テーブルに登録されているレコードを _keys_ で指定されたルー
254
- * ルに従ってソートしたレコードの配列を返す。
255
- * <pre>
256
- * ==[
257
- * {:key => "カラム名", :order => :asc, :ascending,
258
- * :desc, :descendingのいずれか},
259
- * {:key => "カラム名", :order => :asc, :ascending,
260
- * :desc, :descendingのいずれか},
261
- * ...,
262
- * ]==
263
- * </pre>
264
- * _options_ に指定可能な値は以下の通り。
265
- * @param options [::Hash] The name and value
266
- * pairs. Omitted names are initialized as the default value
267
- * @option options :offset The offset
268
- *
269
- * ソートされたレコードのうち、(0ベースで) _:offset_ 番目
270
- * からレコードを取り出す。
271
- *
272
- * @option options :limit The limit
273
- *
274
- * ソートされたレコードのうち、 _:limit_ 件のみを取り出す。
275
- * 省略された場合または-1が指定された場合は、全件が指定され
276
- * たものとみなす。
277
- */
278
- /* FIXME: DON'T WORK!!! */
279
- static VALUE
280
- rb_grn_view_sort (int argc, VALUE *argv, VALUE self)
281
- {
282
- VALUE rb_result = Qnil;
283
-
284
- #ifdef WIN32
285
- rb_raise(rb_eNotImpError, "grn_view_add() isn't available on Windows.");
286
- #else
287
- grn_ctx *context = NULL;
288
- grn_obj *view;
289
- grn_obj *result;
290
- grn_table_sort_key *keys;
291
- int i, n_keys;
292
- int offset = 0, limit = -1;
293
- VALUE rb_keys, options;
294
- VALUE rb_offset, rb_limit;
295
- VALUE *rb_sort_keys;
296
- grn_table_cursor *cursor;
297
- VALUE exception;
298
- grn_obj id;
299
-
300
- rb_grn_table_deconstruct(SELF(self), &view, &context,
301
- NULL, NULL,
302
- NULL, NULL, NULL,
303
- NULL);
304
-
305
- rb_scan_args(argc, argv, "11", &rb_keys, &options);
306
-
307
- if (!RVAL2CBOOL(rb_obj_is_kind_of(rb_keys, rb_cArray)))
308
- rb_raise(rb_eArgError, "keys should be an array of key: <%s>",
309
- rb_grn_inspect(rb_keys));
310
-
311
- n_keys = RARRAY_LEN(rb_keys);
312
- rb_sort_keys = RARRAY_PTR(rb_keys);
313
- keys = ALLOCA_N(grn_table_sort_key, n_keys);
314
- for (i = 0; i < n_keys; i++) {
315
- VALUE rb_sort_options, rb_key, rb_resolved_key, rb_order;
316
-
317
- if (RVAL2CBOOL(rb_obj_is_kind_of(rb_sort_keys[i], rb_cHash))) {
318
- rb_sort_options = rb_sort_keys[i];
319
- } else if (RVAL2CBOOL(rb_obj_is_kind_of(rb_sort_keys[i], rb_cArray))) {
320
- rb_sort_options = rb_hash_new();
321
- rb_hash_aset(rb_sort_options,
322
- RB_GRN_INTERN("key"),
323
- rb_ary_entry(rb_sort_keys[i], 0));
324
- rb_hash_aset(rb_sort_options,
325
- RB_GRN_INTERN("order"),
326
- rb_ary_entry(rb_sort_keys[i], 1));
327
- } else {
328
- rb_sort_options = rb_hash_new();
329
- rb_hash_aset(rb_sort_options,
330
- RB_GRN_INTERN("key"),
331
- rb_sort_keys[i]);
332
- }
333
- rb_grn_scan_options(rb_sort_options,
334
- "key", &rb_key,
335
- "order", &rb_order,
336
- NULL);
337
- if (RVAL2CBOOL(rb_obj_is_kind_of(rb_key, rb_cString))) {
338
- rb_resolved_key = rb_grn_table_get_column(self, rb_key);
339
- } else {
340
- rb_resolved_key = rb_key;
341
- }
342
- keys[i].key = RVAL2GRNOBJECT(rb_resolved_key, &context);
343
- if (!keys[i].key) {
344
- rb_raise(rb_eGrnNoSuchColumn,
345
- "no such column: <%s>: <%s>",
346
- rb_grn_inspect(rb_key), rb_grn_inspect(self));
347
- }
348
- if (NIL_P(rb_order)) {
349
- keys[i].flags = 0;
350
- } else if (rb_grn_equal_option(rb_order, "desc") ||
351
- rb_grn_equal_option(rb_order, "descending")) {
352
- keys[i].flags = GRN_TABLE_SORT_DESC;
353
- } else if (rb_grn_equal_option(rb_order, "asc") ||
354
- rb_grn_equal_option(rb_order, "ascending")) {
355
- keys[i].flags = GRN_TABLE_SORT_ASC;
356
- } else {
357
- rb_raise(rb_eArgError,
358
- "order should be one of "
359
- "[nil, :desc, :descending, :asc, :ascending]: %s",
360
- rb_grn_inspect(rb_order));
361
- }
362
- }
363
-
364
- rb_grn_scan_options(options,
365
- "offset", &rb_offset,
366
- "limit", &rb_limit,
367
- NULL);
368
-
369
- if (!NIL_P(rb_offset))
370
- offset = NUM2INT(rb_offset);
371
- if (!NIL_P(rb_limit))
372
- limit = NUM2INT(rb_limit);
373
-
374
- result = grn_table_create(context, NULL, 0, NULL, GRN_TABLE_VIEW,
375
- NULL, NULL);
376
- /* use n_records that is return value from
377
- grn_table_sort() when rroonga user become specifying
378
- output table. */
379
- grn_table_sort(context, view, offset, limit, result, keys, n_keys);
380
- exception = rb_grn_context_to_exception(context, self);
381
- if (!NIL_P(exception)) {
382
- grn_obj_unlink(context, result);
383
- rb_exc_raise(exception);
384
- }
385
-
386
- rb_result = rb_ary_new();
387
- cursor = grn_table_cursor_open(context, result, NULL, 0, NULL, 0,
388
- 0, -1, GRN_CURSOR_ASCENDING);
389
- GRN_TEXT_INIT(&id, 0);
390
- while (grn_table_cursor_next_o(context, cursor, &id) == GRN_SUCCESS) {
391
- rb_ary_push(rb_result, rb_grn_view_record_new(self, &id));
392
- }
393
- GRN_OBJ_FIN(context, &id);
394
- grn_table_cursor_close(context, cursor);
395
- grn_obj_unlink(context, result);
396
- #endif
397
-
398
- return rb_result;
399
- }
400
-
401
- void
402
- rb_grn_init_view (VALUE mGrn)
403
- {
404
- rb_cGrnView = rb_define_class_under(mGrn, "View", rb_cGrnTable);
405
-
406
- rb_define_singleton_method(rb_cGrnView, "create",
407
- rb_grn_view_s_create, -1);
408
-
409
- rb_define_method(rb_cGrnView, "add_table", rb_grn_view_add_table, 1);
410
- rb_define_method(rb_cGrnView, "each", rb_grn_view_each, 0);
411
- rb_define_method(rb_cGrnView, "column_value",
412
- rb_grn_view_get_column_value, 2);
413
- rb_define_method(rb_cGrnView, "sort", rb_grn_view_sort, -1);
414
- }