groonga 0.0.1 → 0.0.2

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 (52) hide show
  1. data/NEWS.ja.rdoc +11 -0
  2. data/NEWS.rdoc +11 -0
  3. data/README.ja.rdoc +4 -3
  4. data/README.rdoc +4 -3
  5. data/Rakefile +1 -1
  6. data/TUTORIAL.ja.rdoc +168 -44
  7. data/benchmark/common.rb +49 -0
  8. data/benchmark/read-write-small-many-items.rb +156 -0
  9. data/benchmark/write-small-many-items.rb +145 -0
  10. data/example/bookmark.rb +68 -20
  11. data/ext/rb-grn-array-cursor.c +8 -0
  12. data/ext/rb-grn-array.c +40 -11
  13. data/ext/rb-grn-column.c +38 -209
  14. data/ext/rb-grn-context.c +203 -56
  15. data/ext/rb-grn-database.c +119 -5
  16. data/ext/rb-grn-encoding-support.c +64 -0
  17. data/ext/rb-grn-encoding.c +58 -1
  18. data/ext/rb-grn-fix-size-column.c +220 -0
  19. data/ext/rb-grn-hash-cursor.c +8 -0
  20. data/ext/rb-grn-hash.c +244 -2
  21. data/ext/rb-grn-index-column.c +474 -0
  22. data/ext/rb-grn-object.c +143 -265
  23. data/ext/rb-grn-patricia-trie.c +148 -2
  24. data/ext/rb-grn-query.c +5 -3
  25. data/ext/rb-grn-record.c +3 -2
  26. data/ext/rb-grn-snippet.c +5 -3
  27. data/ext/rb-grn-table-cursor-key-support.c +3 -3
  28. data/ext/rb-grn-table-cursor.c +106 -112
  29. data/ext/rb-grn-table-key-support.c +220 -118
  30. data/ext/rb-grn-table.c +336 -80
  31. data/ext/rb-grn-type.c +5 -4
  32. data/ext/rb-grn-utils.c +62 -63
  33. data/ext/rb-grn.h +215 -14
  34. data/ext/rb-groonga.c +7 -16
  35. data/extconf.rb +3 -1
  36. data/html/favicon.ico +0 -0
  37. data/html/favicon.xcf +0 -0
  38. data/html/index.html +1 -7
  39. data/lib/groonga/record.rb +6 -1
  40. data/test/groonga-test-utils.rb +1 -0
  41. data/test/test-array.rb +81 -0
  42. data/test/test-column.rb +22 -12
  43. data/test/test-context.rb +1 -29
  44. data/test/test-database.rb +30 -0
  45. data/test/test-hash.rb +194 -0
  46. data/test/test-index-column.rb +57 -0
  47. data/test/test-patricia-trie.rb +82 -0
  48. data/test/test-record.rb +10 -10
  49. data/test/test-table.rb +37 -130
  50. data/test/test-type.rb +4 -3
  51. metadata +15 -4
  52. data/benchmark/small-many-items.rb +0 -175
data/ext/rb-grn-context.c CHANGED
@@ -20,8 +20,29 @@
20
20
 
21
21
  #define SELF(object) (RVAL2GRNCONTEXT(object))
22
22
 
23
+ #define OBJECTS_TABLE_NAME "<ranguba:objects>"
24
+
23
25
  static VALUE cGrnContext;
24
26
 
27
+ /*
28
+ * Document-class: Groonga::Context
29
+ *
30
+ * groonga全体に渡る情報を管理するオブジェクト。通常のアプリ
31
+ * ケーションでは1つのコンテキストを作成し、それを利用する。
32
+ * 複数のコンテキストを利用する必要はない。
33
+ *
34
+ * デフォルトで使用されるコンテキストは
35
+ * Groonga::Context#defaultでアクセスできる。コンテキストを
36
+ * 指定できる箇所でコンテキストの指定を省略したり+nil+を指定
37
+ * した場合はGroonga::Context.defaultが利用される。
38
+ *
39
+ * また、デフォルトのコンテキストは必要になると暗黙のうちに
40
+ * 作成される。そのため、コンテキストを意識することは少ない。
41
+ *
42
+ * 暗黙のうちに作成されるコンテキストにオプションを指定する
43
+ * 場合はGroonga::Context.default_options=を使用する。
44
+ */
45
+
25
46
  grn_ctx *
26
47
  rb_grn_context_from_ruby_object (VALUE object)
27
48
  {
@@ -37,13 +58,90 @@ rb_grn_context_from_ruby_object (VALUE object)
37
58
  return context;
38
59
  }
39
60
 
61
+ void
62
+ rb_grn_context_register (grn_ctx *context, RbGrnObject *object)
63
+ {
64
+ grn_obj *objects;
65
+
66
+ if (!grn_ctx_db(context))
67
+ return;
68
+
69
+ objects = grn_ctx_get(context,
70
+ OBJECTS_TABLE_NAME,
71
+ strlen(OBJECTS_TABLE_NAME));
72
+ if (!objects)
73
+ objects = grn_table_create(context,
74
+ OBJECTS_TABLE_NAME,
75
+ strlen(OBJECTS_TABLE_NAME),
76
+ NULL,
77
+ GRN_OBJ_TABLE_HASH_KEY,
78
+ grn_ctx_at(context, GRN_DB_UINT64),
79
+ 0);
80
+
81
+ grn_table_add(context, objects,
82
+ &object, sizeof(RbGrnObject *),
83
+ NULL);
84
+ }
85
+
86
+ void
87
+ rb_grn_context_unregister (grn_ctx *context, RbGrnObject *object)
88
+ {
89
+ grn_obj *objects;
90
+
91
+ if (!grn_ctx_db(context))
92
+ return;
93
+
94
+ objects = grn_ctx_get(context,
95
+ OBJECTS_TABLE_NAME,
96
+ strlen(OBJECTS_TABLE_NAME));
97
+ if (!objects)
98
+ return;
99
+
100
+ grn_table_delete(context, objects, &object, sizeof(RbGrnObject *));
101
+ }
102
+
103
+ void
104
+ rb_grn_context_unbind (grn_ctx *context)
105
+ {
106
+ grn_obj *database;
107
+ grn_obj *objects;
108
+
109
+ database = grn_ctx_db(context);
110
+ if (!database)
111
+ return;
112
+
113
+ objects = grn_ctx_get(context,
114
+ OBJECTS_TABLE_NAME,
115
+ strlen(OBJECTS_TABLE_NAME));
116
+ if (objects) {
117
+ grn_table_cursor *cursor;
118
+
119
+ cursor = grn_table_cursor_open(context, objects, NULL, 0, NULL, 0, 0);
120
+ while (grn_table_cursor_next(context, cursor) != GRN_ID_NIL) {
121
+ void *value;
122
+ RbGrnObject *object = NULL;
123
+ grn_table_cursor_get_key(context, cursor, &value);
124
+ memcpy(&object, value, sizeof(RbGrnObject *));
125
+ object->object = NULL;
126
+ object->unbind(object);
127
+ }
128
+ grn_table_cursor_close(context, cursor);
129
+ grn_obj_close(context, objects);
130
+ }
131
+
132
+ grn_obj_close(context, database);
133
+ grn_ctx_use(context, NULL);
134
+ }
135
+
40
136
  static void
41
137
  rb_grn_context_free (void *pointer)
42
138
  {
43
139
  grn_ctx *context = pointer;
44
140
 
45
- if (context->stat != GRN_CTX_FIN)
141
+ if (context->stat != GRN_CTX_FIN) {
142
+ rb_grn_context_unbind (context);
46
143
  grn_ctx_fin(context);
144
+ }
47
145
  xfree(context);
48
146
  }
49
147
 
@@ -66,21 +164,21 @@ rb_grn_context_to_exception (grn_ctx *context, VALUE related_object)
66
164
  exception_class = rb_grn_rc_to_exception(context->rc);
67
165
  message = rb_grn_rc_to_message(context->rc);
68
166
 
69
- grn_bulk_init(context, &bulk, 0);
70
- GRN_BULK_PUTS(context, &bulk, message);
71
- GRN_BULK_PUTS(context, &bulk, ": ");
72
- GRN_BULK_PUTS(context, &bulk, context->errbuf);
167
+ GRN_OBJ_INIT(&bulk, GRN_BULK, 0, GRN_ID_NIL);
168
+ GRN_TEXT_PUTS(context, &bulk, message);
169
+ GRN_TEXT_PUTS(context, &bulk, ": ");
170
+ GRN_TEXT_PUTS(context, &bulk, context->errbuf);
73
171
  if (!NIL_P(related_object)) {
74
- GRN_BULK_PUTS(context, &bulk, ": ");
75
- GRN_BULK_PUTS(context, &bulk, rb_grn_inspect(related_object));
172
+ GRN_TEXT_PUTS(context, &bulk, ": ");
173
+ GRN_TEXT_PUTS(context, &bulk, rb_grn_inspect(related_object));
76
174
  }
77
- GRN_BULK_PUTS(context, &bulk, "\n");
78
- GRN_BULK_PUTS(context, &bulk, context->errfile);
79
- GRN_BULK_PUTS(context, &bulk, ":");
80
- grn_bulk_itoa(context, &bulk, context->errline);
81
- GRN_BULK_PUTS(context, &bulk, ": ");
82
- GRN_BULK_PUTS(context, &bulk, context->errfunc);
83
- GRN_BULK_PUTS(context, &bulk, "()");
175
+ GRN_TEXT_PUTS(context, &bulk, "\n");
176
+ GRN_TEXT_PUTS(context, &bulk, context->errfile);
177
+ GRN_TEXT_PUTS(context, &bulk, ":");
178
+ grn_text_itoa(context, &bulk, context->errline);
179
+ GRN_TEXT_PUTS(context, &bulk, ": ");
180
+ GRN_TEXT_PUTS(context, &bulk, context->errfunc);
181
+ GRN_TEXT_PUTS(context, &bulk, "()");
84
182
  exception = rb_funcall(exception_class, rb_intern("new"), 1,
85
183
  rb_str_new(GRN_BULK_HEAD(&bulk),
86
184
  GRN_BULK_VSIZE(&bulk)));
@@ -102,13 +200,24 @@ rb_grn_context_check (grn_ctx *context, VALUE related_object)
102
200
  }
103
201
 
104
202
  grn_ctx *
105
- rb_grn_context_ensure (VALUE context)
203
+ rb_grn_context_ensure (VALUE *context)
106
204
  {
107
- if (NIL_P(context))
108
- context = rb_grn_context_get_default();
109
- return SELF(context);
205
+ if (NIL_P(*context))
206
+ *context = rb_grn_context_get_default();
207
+ return SELF(*context);
110
208
  }
111
209
 
210
+ /*
211
+ * call-seq:
212
+ * Groonga::Context.default -> Groonga::Context
213
+ *
214
+ * デフォルトのコンテキストを返す。デフォルトのコンテキスト
215
+ * が作成されていない場合は暗黙のうちに作成し、それを返す。
216
+ *
217
+ * 暗黙のうちにコンテキストを作成する場合は、
218
+ * Groonga::Context.default_optionsに設定されているオプショ
219
+ * ンを利用する。
220
+ */
112
221
  static VALUE
113
222
  rb_grn_context_s_get_default (VALUE self)
114
223
  {
@@ -128,6 +237,15 @@ rb_grn_context_get_default (void)
128
237
  return rb_grn_context_s_get_default(cGrnContext);
129
238
  }
130
239
 
240
+ /*
241
+ * call-seq:
242
+ * Groonga::Context.default=(context)
243
+ *
244
+ * デフォルトのコンテキストを設定する。+nil+を指定すると、デ
245
+ * フォルトのコンテキストをリセットする。リセットすると、次
246
+ * 回Groonga::Context.defaultを呼び出したときに新しくコンテ
247
+ * キストが作成される。
248
+ */
131
249
  static VALUE
132
250
  rb_grn_context_s_set_default (VALUE self, VALUE context)
133
251
  {
@@ -135,12 +253,27 @@ rb_grn_context_s_set_default (VALUE self, VALUE context)
135
253
  return Qnil;
136
254
  }
137
255
 
256
+ /*
257
+ * call-seq:
258
+ * Groonga::Context.default_options -> Hash or nil
259
+ *
260
+ * コンテキストを作成する時に利用するデフォルトのオプション
261
+ * を返す。
262
+ */
138
263
  static VALUE
139
264
  rb_grn_context_s_get_default_options (VALUE self)
140
265
  {
141
266
  return rb_cv_get(self, "@@default_options");
142
267
  }
143
268
 
269
+ /*
270
+ * call-seq:
271
+ * Groonga::Context.default_options=(options)
272
+ *
273
+ * コンテキストを作成する時に利用するデフォルトのオプション
274
+ * を設定する。利用可能なオプションは
275
+ * Groonga::Context.newを参照。
276
+ */
144
277
  static VALUE
145
278
  rb_grn_context_s_set_default_options (VALUE self, VALUE options)
146
279
  {
@@ -148,6 +281,17 @@ rb_grn_context_s_set_default_options (VALUE self, VALUE options)
148
281
  return Qnil;
149
282
  }
150
283
 
284
+ /*
285
+ * call-seq:
286
+ * Groonga::Context.new(options=nil)
287
+ *
288
+ * コンテキストを作成する。_options_に指定可能な値は以下の通
289
+ * り。
290
+ *
291
+ * [+:encoding+]
292
+ * エンコーディングを指定する。エンコーディングの指定方法
293
+ * はGroonga::Encodingを参照。
294
+ */
151
295
  static VALUE
152
296
  rb_grn_context_initialize (int argc, VALUE *argv, VALUE self)
153
297
  {
@@ -155,7 +299,7 @@ rb_grn_context_initialize (int argc, VALUE *argv, VALUE self)
155
299
  int flags = 0;
156
300
  grn_rc rc;
157
301
  VALUE options, default_options;
158
- VALUE use_ql, batch_mode, rb_encoding;
302
+ VALUE rb_encoding;
159
303
 
160
304
  rb_scan_args(argc, argv, "01", &options);
161
305
  default_options = rb_grn_context_s_get_default_options(rb_obj_class(self));
@@ -167,16 +311,9 @@ rb_grn_context_initialize (int argc, VALUE *argv, VALUE self)
167
311
  options = rb_funcall(default_options, rb_intern("merge"), 1, options);
168
312
 
169
313
  rb_grn_scan_options(options,
170
- "use_ql", &use_ql,
171
- "batch_mode", &batch_mode,
172
314
  "encoding", &rb_encoding,
173
315
  NULL);
174
316
 
175
- if (RVAL2CBOOL(use_ql))
176
- flags |= GRN_CTX_USE_QL;
177
- if (RVAL2CBOOL(batch_mode))
178
- flags |= GRN_CTX_BATCH_MODE;
179
-
180
317
  context = ALLOC(grn_ctx);
181
318
  DATA_PTR(self) = context;
182
319
  rc = grn_ctx_init(context, flags);
@@ -192,6 +329,12 @@ rb_grn_context_initialize (int argc, VALUE *argv, VALUE self)
192
329
  return Qnil;
193
330
  }
194
331
 
332
+ /*
333
+ * call-seq:
334
+ * context.inspect -> String
335
+ *
336
+ * コンテキストの中身を人に見やすい文字列で返す。
337
+ */
195
338
  static VALUE
196
339
  rb_grn_context_inspect (VALUE self)
197
340
  {
@@ -206,20 +349,6 @@ rb_grn_context_inspect (VALUE self)
206
349
  rb_str_concat(inspected, rb_inspect(rb_obj_class(self)));
207
350
  rb_str_cat2(inspected, " ");
208
351
 
209
- rb_str_cat2(inspected, "use_ql: <");
210
- if (context->flags & GRN_CTX_USE_QL)
211
- rb_str_cat2(inspected, "true");
212
- else
213
- rb_str_cat2(inspected, "false");
214
- rb_str_cat2(inspected, ">, ");
215
-
216
- rb_str_cat2(inspected, "batch_mode: <");
217
- if (context->flags & GRN_CTX_BATCH_MODE)
218
- rb_str_cat2(inspected, "true");
219
- else
220
- rb_str_cat2(inspected, "false");
221
- rb_str_cat2(inspected, ">, ");
222
-
223
352
  rb_str_cat2(inspected, "encoding: <");
224
353
  rb_str_concat(inspected, rb_inspect(GRNENCODING2RVAL(context->encoding)));
225
354
  rb_str_cat2(inspected, ">, ");
@@ -234,24 +363,25 @@ rb_grn_context_inspect (VALUE self)
234
363
  return inspected;
235
364
  }
236
365
 
237
- static VALUE
238
- rb_grn_context_use_ql_p (VALUE self)
239
- {
240
- return CBOOL2RVAL(SELF(self)->flags & GRN_CTX_USE_QL);
241
- }
242
-
243
- static VALUE
244
- rb_grn_context_batch_mode_p (VALUE self)
245
- {
246
- return CBOOL2RVAL(SELF(self)->flags & GRN_CTX_BATCH_MODE);
247
- }
248
-
366
+ /*
367
+ * call-seq:
368
+ * context.encoding -> Groonga::Encoding
369
+ *
370
+ * コンテキストが使うエンコーディングを返す。
371
+ */
249
372
  static VALUE
250
373
  rb_grn_context_get_encoding (VALUE self)
251
374
  {
252
375
  return GRNENCODING2RVAL(GRN_CTX_GET_ENCODING(SELF(self)));
253
376
  }
254
377
 
378
+ /*
379
+ * call-seq:
380
+ * context.encoding=(encoding)
381
+ *
382
+ * コンテキストが使うエンコーディングを設定する。エンコーディ
383
+ * ングの指定のしかたはGroonga::Encodingを参照。
384
+ */
255
385
  static VALUE
256
386
  rb_grn_context_set_encoding (VALUE self, VALUE rb_encoding)
257
387
  {
@@ -265,6 +395,12 @@ rb_grn_context_set_encoding (VALUE self, VALUE rb_encoding)
265
395
  return rb_encoding;
266
396
  }
267
397
 
398
+ /*
399
+ * call-seq:
400
+ * context.database -> Groonga::Database
401
+ *
402
+ * コンテキストが使うデータベースを返す。
403
+ */
268
404
  static VALUE
269
405
  rb_grn_context_get_database (VALUE self)
270
406
  {
@@ -274,6 +410,19 @@ rb_grn_context_get_database (VALUE self)
274
410
  return GRNDB2RVAL(context, grn_ctx_db(context), RB_GRN_FALSE);
275
411
  }
276
412
 
413
+ /*
414
+ * call-seq:
415
+ * context[name] -> Groonga::Object or nil
416
+ * context[id] -> Groonga::Object or nil
417
+ *
418
+ * コンテキスト管理下にあるオブジェクトを返す。
419
+ *
420
+ * _name_として文字列を指定した場合はオブジェクト名でオブジェ
421
+ * クトを検索する。
422
+ *
423
+ * _id_として数値を指定した場合はオブジェクトIDでオブジェク
424
+ * トを検索する。
425
+ */
277
426
  static VALUE
278
427
  rb_grn_context_array_reference (VALUE self, VALUE name_or_id)
279
428
  {
@@ -287,11 +436,11 @@ rb_grn_context_array_reference (VALUE self, VALUE name_or_id)
287
436
 
288
437
  name = StringValuePtr(name_or_id);
289
438
  name_size = RSTRING_LEN(name_or_id);
290
- object = grn_ctx_lookup(context, name, name_size);
439
+ object = grn_ctx_get(context, name, name_size);
291
440
  } else if (RVAL2CBOOL(rb_obj_is_kind_of(name_or_id, rb_cInteger))) {
292
441
  unsigned id;
293
442
  id = NUM2UINT(name_or_id);
294
- object = grn_ctx_get(context, id);
443
+ object = grn_ctx_at(context, id);
295
444
  } else {
296
445
  rb_raise(rb_eArgError, "should be string or unsigned integer: %s",
297
446
  rb_grn_inspect(name_or_id));
@@ -322,8 +471,6 @@ rb_grn_init_context (VALUE mGrn)
322
471
 
323
472
  rb_define_method(cGrnContext, "inspect", rb_grn_context_inspect, 0);
324
473
 
325
- rb_define_method(cGrnContext, "use_ql?", rb_grn_context_use_ql_p, 0);
326
- rb_define_method(cGrnContext, "batch_mode?", rb_grn_context_batch_mode_p, 0);
327
474
  rb_define_method(cGrnContext, "encoding", rb_grn_context_get_encoding, 0);
328
475
  rb_define_method(cGrnContext, "encoding=", rb_grn_context_set_encoding, 1);
329
476
 
@@ -18,10 +18,21 @@
18
18
 
19
19
  #include "rb-grn.h"
20
20
 
21
- #define SELF(object) (RVAL2GRNDB(object))
21
+ #define SELF(object) ((RbGrnObject *)DATA_PTR(object))
22
22
 
23
23
  VALUE rb_cGrnDatabase;
24
24
 
25
+ /*
26
+ * Document-class: Groonga::Database
27
+ *
28
+ * テーブルの集合を管理するためのオブジェクト。
29
+ *
30
+ * コンテキストに結びつけて使用する。通常、アプリケーション
31
+ * 毎に1つのコンテキストを利用するので、データベースも1つだ
32
+ * け利用する。コンテキストと違い、データベースは暗黙のうち
33
+ * に作成されないので明示的に作成する必要がある。
34
+ */
35
+
25
36
  grn_obj *
26
37
  rb_grn_database_from_ruby_object (VALUE object)
27
38
  {
@@ -39,6 +50,31 @@ rb_grn_database_to_ruby_object (grn_ctx *context, grn_obj *database,
39
50
  return GRNOBJECT2RVAL(rb_cGrnDatabase, context, database, owner);
40
51
  }
41
52
 
53
+ /*
54
+ * call-seq:
55
+ * Groonga::Database.create(options=nil) -> Groonga::Database
56
+ *
57
+ * 新しくデータベースを作成する。
58
+ *
59
+ * _options_にはハッシュでオプションを指定する。指定できるオ
60
+ * プションは以下の通り。
61
+ *
62
+ * [+:path+]
63
+ * データベースを保存するパス。省略すると一時データベース
64
+ * となる。
65
+ *
66
+ * [+:context+]
67
+ * データベースを結びつけるコンテキスト。省略すると
68
+ * Groonga::Context.defaultを利用する。
69
+ *
70
+ * 使用例は以下の通り。
71
+ *
72
+ * 一時データベースを作成:
73
+ * Groonga::Database.create
74
+ *
75
+ * 永続データベースを作成:
76
+ * Groonga::Database.create(:path => "/tmp/db.groonga")
77
+ */
42
78
  static VALUE
43
79
  rb_grn_database_s_create (int argc, VALUE *argv, VALUE klass)
44
80
  {
@@ -59,14 +95,17 @@ rb_grn_database_s_create (int argc, VALUE *argv, VALUE klass)
59
95
 
60
96
  if (!NIL_P(rb_path))
61
97
  path = StringValuePtr(rb_path);
62
- context = rb_grn_context_ensure(rb_context);
98
+ context = rb_grn_context_ensure(&rb_context);
63
99
 
64
100
  create_args.builtin_type_names = NULL;
65
101
  create_args.n_builtin_type_names = 0;
66
102
 
67
103
  database = grn_db_create(context, path, &create_args);
68
104
  rb_grn_context_check(context, rb_ary_new4(argc, argv));
69
- rb_database = GRNOBJECT2RVAL(klass, context, database, RB_GRN_FALSE);
105
+ rb_database = rb_grn_object_alloc(klass);
106
+ rb_grn_object_assign(rb_database, rb_context, context,
107
+ database, RB_GRN_TRUE);
108
+ rb_iv_set(rb_database, "context", rb_context);
70
109
  rb_grn_context_check(context, rb_ary_new4(argc, argv));
71
110
 
72
111
  if (rb_block_given_p())
@@ -76,6 +115,22 @@ rb_grn_database_s_create (int argc, VALUE *argv, VALUE klass)
76
115
  return rb_database;
77
116
  }
78
117
 
118
+ /*
119
+ * call-seq:
120
+ * Groonga::Database.new(path, options=nil) -> Groonga::Database
121
+ * Groonga::Database.new(path, options=nil) {|database| ...}
122
+ *
123
+ * 既存のデータベースを開く。ブロックを指定した場合はブロッ
124
+ * クに開いたデータベースを渡し、ブロックを抜けるときに閉じ
125
+ * る。
126
+ *
127
+ * _options_にはハッシュでオプションを指定する。指定できるオ
128
+ * プションは以下の通り。
129
+ *
130
+ * [+:context+]
131
+ * データベースを結びつけるコンテキスト。省略すると
132
+ * Groonga::Context.defaultを利用する。
133
+ */
79
134
  static VALUE
80
135
  rb_grn_database_initialize (int argc, VALUE *argv, VALUE self)
81
136
  {
@@ -91,15 +146,31 @@ rb_grn_database_initialize (int argc, VALUE *argv, VALUE self)
91
146
  "context", &rb_context,
92
147
  NULL);
93
148
 
94
- context = rb_grn_context_ensure(rb_context);
149
+ context = rb_grn_context_ensure(&rb_context);
95
150
 
96
151
  database = grn_db_open(context, path);
97
- rb_grn_object_initialize(self, context, database);
152
+ rb_grn_object_assign(self, rb_context, context, database, RB_GRN_TRUE);
98
153
  rb_grn_context_check(context, self);
99
154
 
100
155
  return Qnil;
101
156
  }
102
157
 
158
+ /*
159
+ * call-seq:
160
+ * Groonga::Database.open(path, options=nil) -> Groonga::Database
161
+ * Groonga::Database.open(path, options=nil) {|database| ...}
162
+ *
163
+ * 既存のデータベースを開く。ブロックを指定した場合はブロッ
164
+ * クに開いたデータベースを渡し、ブロックを抜けるときに閉じ
165
+ * る。
166
+ *
167
+ * _options_にはハッシュでオプションを指定する。指定できるオ
168
+ * プションは以下の通り。
169
+ *
170
+ * [+:context+]
171
+ * データベースを結びつけるコンテキスト。省略すると
172
+ * Groonga::Context.defaultを利用する。
173
+ */
103
174
  static VALUE
104
175
  rb_grn_database_s_open (int argc, VALUE *argv, VALUE klass)
105
176
  {
@@ -113,10 +184,50 @@ rb_grn_database_s_open (int argc, VALUE *argv, VALUE klass)
113
184
  return database;
114
185
  }
115
186
 
187
+ /*
188
+ * call-seq:
189
+ * database.each {|object| ...}
190
+ *
191
+ * データベース内のオブジェクトを順番にブロックに渡す。
192
+ *
193
+ * すべてのオブジェクトの名前を表示する:
194
+ * database.each do |object|
195
+ * p object.name
196
+ * end
197
+ */
198
+ static VALUE
199
+ rb_grn_database_each (VALUE self)
200
+ {
201
+ grn_ctx *context = NULL;
202
+ grn_obj *database;
203
+ grn_table_cursor *cursor;
204
+ VALUE rb_cursor;
205
+ grn_id id;
206
+
207
+ rb_grn_object_deconstruct((RbGrnObject *)SELF(self), &database, &context,
208
+ NULL, NULL, NULL, NULL);
209
+ cursor = grn_table_cursor_open(context, database, NULL, 0, NULL, 0, 0);
210
+ rb_cursor = GRNTABLECURSOR2RVAL(Qnil, context, cursor);
211
+ rb_iv_set(self, "cursor", rb_cursor);
212
+ while ((id = grn_table_cursor_next(context, cursor)) != GRN_ID_NIL) {
213
+ grn_obj *object;
214
+
215
+ object = grn_ctx_at(context, id);
216
+ if (object)
217
+ rb_yield(GRNOBJECT2RVAL(Qnil, context, object, RB_GRN_FALSE));
218
+ }
219
+ rb_grn_table_cursor_close(rb_cursor);
220
+ rb_iv_set(self, "cursor", Qnil);
221
+
222
+ return Qnil;
223
+ }
224
+
116
225
  void
117
226
  rb_grn_init_database (VALUE mGrn)
118
227
  {
119
228
  rb_cGrnDatabase = rb_define_class_under(mGrn, "Database", rb_cGrnObject);
229
+ rb_include_module(rb_cGrnDatabase, rb_mEnumerable);
230
+ rb_include_module(rb_cGrnDatabase, rb_mGrnEncodingSupport);
120
231
 
121
232
  rb_define_singleton_method(rb_cGrnDatabase, "create",
122
233
  rb_grn_database_s_create, -1);
@@ -125,4 +236,7 @@ rb_grn_init_database (VALUE mGrn)
125
236
 
126
237
  rb_define_method(rb_cGrnDatabase, "initialize",
127
238
  rb_grn_database_initialize, -1);
239
+
240
+ rb_define_method(rb_cGrnDatabase, "each",
241
+ rb_grn_database_each, 0);
128
242
  }
@@ -0,0 +1,64 @@
1
+ /* -*- c-file-style: "ruby" -*- */
2
+ /*
3
+ Copyright (C) 2009 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) (RB_GRN_OBJECT(DATA_PTR(object)))
22
+
23
+ VALUE rb_mGrnEncodingSupport;
24
+
25
+ /*
26
+ * Document-module: Groonga::EncodingSupport
27
+ *
28
+ * オブジェクトにエンコーディング関連の機能を提供するモジュー
29
+ * ル。
30
+ */
31
+
32
+ /*
33
+ * call-seq:
34
+ * object.encoding -> エンコーディング
35
+ *
36
+ * オブジェクトのエンコーディングを返す。
37
+ */
38
+ static VALUE
39
+ rb_grn_encoding_support_get_encoding (VALUE self)
40
+ {
41
+ grn_ctx *context = NULL;
42
+ grn_obj *object = NULL;
43
+ grn_obj *encoding_value;
44
+ grn_encoding encoding;
45
+
46
+ rb_grn_object_deconstruct(SELF(self), &object, &context,
47
+ NULL, NULL, NULL, NULL);
48
+ encoding_value = grn_obj_get_info(context, object, GRN_INFO_ENCODING, NULL);
49
+ rb_grn_context_check(context, self);
50
+
51
+ memcpy(&encoding, GRN_BULK_HEAD(encoding_value), sizeof(encoding));
52
+ grn_obj_close(context, encoding_value);
53
+
54
+ return GRNENCODING2RVAL(encoding);
55
+ }
56
+
57
+ void
58
+ rb_grn_init_encoding_support (VALUE mGrn)
59
+ {
60
+ rb_mGrnEncodingSupport = rb_define_module_under(mGrn, "EncodingSupport");
61
+
62
+ rb_define_method(rb_mGrnEncodingSupport, "encoding",
63
+ rb_grn_encoding_support_get_encoding, 0);
64
+ }