groonga 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/NEWS.ja.rdoc +13 -0
  2. data/NEWS.rdoc +13 -0
  3. data/README.ja.rdoc +2 -1
  4. data/README.rdoc +2 -1
  5. data/Rakefile +0 -1
  6. data/TUTORIAL.ja.rdoc +49 -4
  7. data/benchmark/read-write-many-small-items.rb +5 -4
  8. data/benchmark/write-many-small-items.rb +5 -4
  9. data/example/bookmark.rb +30 -1
  10. data/example/index-html.rb +79 -0
  11. data/example/search/config.ru +182 -0
  12. data/example/search/public/css/groonga.css +122 -0
  13. data/ext/rb-grn-array.c +12 -9
  14. data/ext/rb-grn-column.c +13 -8
  15. data/ext/rb-grn-context.c +34 -16
  16. data/ext/rb-grn-database.c +3 -2
  17. data/ext/rb-grn-expression-builder.c +8 -2
  18. data/ext/rb-grn-expression.c +3 -3
  19. data/ext/rb-grn-hash.c +13 -10
  20. data/ext/rb-grn-object.c +127 -19
  21. data/ext/rb-grn-patricia-trie.c +8 -7
  22. data/ext/rb-grn-table-cursor.c +2 -40
  23. data/ext/rb-grn-table.c +154 -42
  24. data/ext/rb-grn-type.c +18 -10
  25. data/ext/rb-grn-utils.c +22 -20
  26. data/ext/rb-grn.h +9 -12
  27. data/extconf.rb +1 -1
  28. data/html/developer.html +1 -1
  29. data/html/index.html +2 -2
  30. data/lib/groonga/expression-builder.rb +133 -63
  31. data/lib/groonga/schema.rb +229 -37
  32. data/test/groonga-test-utils.rb +1 -1
  33. data/test/test-array.rb +1 -0
  34. data/test/test-context.rb +7 -1
  35. data/test/test-database.rb +11 -3
  36. data/test/test-expression-builder.rb +26 -2
  37. data/test/test-fix-size-column.rb +2 -1
  38. data/test/test-hash.rb +6 -1
  39. data/test/test-record.rb +2 -1
  40. data/test/test-schema.rb +85 -10
  41. data/test/test-table.rb +99 -3
  42. data/test/test-type.rb +3 -2
  43. data/test/test-variable-size-column.rb +2 -1
  44. data/test-unit/Rakefile +6 -1
  45. data/test-unit/lib/test/unit/autorunner.rb +26 -3
  46. data/test-unit/lib/test/unit/priority.rb +21 -1
  47. data/test-unit/lib/test/unit/testcase.rb +101 -36
  48. data/test-unit/lib/test/unit/ui/console/testrunner.rb +7 -4
  49. data/test-unit/test/{test_testcase.rb → test-testcase.rb} +30 -1
  50. data/test-unit/test/test_assertions.rb +1 -1
  51. metadata +9 -6
data/ext/rb-grn-table.c CHANGED
@@ -98,6 +98,9 @@ rb_grn_table_mark (void *data)
98
98
  if (!grn_obj_path(context, table))
99
99
  return;
100
100
 
101
+ if (grn_obj_name(context, table, NULL, 0) == 0)
102
+ return;
103
+
101
104
  column_ids = grn_table_create(context, NULL, 0, NULL,
102
105
  GRN_TABLE_HASH_KEY, NULL, 0);
103
106
  n = grn_table_columns(context, table, NULL, 0, column_ids);
@@ -107,7 +110,7 @@ rb_grn_table_mark (void *data)
107
110
  }
108
111
 
109
112
  cursor = grn_table_cursor_open(context, column_ids, NULL, 0, NULL, 0,
110
- GRN_CURSOR_ASCENDING);
113
+ 0, 0, GRN_CURSOR_ASCENDING);
111
114
  while (grn_table_cursor_next(context, cursor) != GRN_ID_NIL) {
112
115
  void *key;
113
116
  grn_id *column_id;
@@ -136,14 +139,14 @@ rb_grn_table_s_create (int argc, VALUE *argv, VALUE klass,
136
139
  grn_obj_flags key_store)
137
140
  {
138
141
  grn_ctx *context;
139
- grn_obj *key_type = NULL, *table;
142
+ grn_obj *key_type = NULL, *value_type = NULL, *table;
140
143
  const char *name = NULL, *path = NULL;
141
- unsigned name_size = 0, value_size = 0;
144
+ unsigned name_size = 0;
142
145
  grn_obj_flags flags = key_store;
143
146
  VALUE rb_table;
144
147
  VALUE options, rb_context, rb_name, rb_path, rb_persistent;
145
148
  VALUE rb_key_normalize, rb_key_with_sis, rb_key_type;
146
- VALUE rb_value_size;
149
+ VALUE rb_value_type;
147
150
 
148
151
  rb_scan_args(argc, argv, "01", &options);
149
152
 
@@ -155,7 +158,7 @@ rb_grn_table_s_create (int argc, VALUE *argv, VALUE klass,
155
158
  "key_normalize", &rb_key_normalize,
156
159
  "key_with_sis", &rb_key_with_sis,
157
160
  "key_type", &rb_key_type,
158
- "value_size", &rb_value_size,
161
+ "value_type", &rb_value_type,
159
162
  NULL);
160
163
 
161
164
  context = rb_grn_context_ensure(&rb_context);
@@ -186,11 +189,11 @@ rb_grn_table_s_create (int argc, VALUE *argv, VALUE klass,
186
189
  key_type = RVAL2GRNOBJECT(rb_key_type, &context);
187
190
  }
188
191
 
189
- if (!NIL_P(rb_value_size))
190
- value_size = NUM2UINT(rb_value_size);
192
+ if (!NIL_P(rb_value_type))
193
+ value_type = RVAL2GRNOBJECT(rb_value_type, &context);
191
194
 
192
195
  table = grn_table_create(context, name, name_size, path,
193
- flags, key_type, value_size);
196
+ flags, key_type, value_type);
194
197
  rb_table = rb_grn_object_alloc(klass);
195
198
  rb_grn_table_assign(rb_table, rb_context, context, table, RB_GRN_TRUE);
196
199
  rb_grn_context_check(context, rb_table);
@@ -362,7 +365,7 @@ rb_grn_table_define_column (int argc, VALUE *argv, VALUE self)
362
365
  unsigned name_size = 0;
363
366
  grn_obj_flags flags = 0;
364
367
  VALUE rb_name, rb_value_type;
365
- VALUE options, rb_path, rb_persistent, rb_type;
368
+ VALUE options, rb_path, rb_persistent, rb_compress, rb_type;
366
369
 
367
370
  rb_grn_table_deconstruct(SELF(self), &table, &context,
368
371
  NULL, NULL,
@@ -377,6 +380,7 @@ rb_grn_table_define_column (int argc, VALUE *argv, VALUE self)
377
380
  "path", &rb_path,
378
381
  "persistent", &rb_persistent,
379
382
  "type", &rb_type,
383
+ "compress", &rb_compress,
380
384
  NULL);
381
385
 
382
386
  value_type = RVAL2GRNOBJECT(rb_value_type, &context);
@@ -401,6 +405,18 @@ rb_grn_table_define_column (int argc, VALUE *argv, VALUE self)
401
405
  rb_grn_inspect(rb_type));
402
406
  }
403
407
 
408
+ if (NIL_P(rb_compress)) {
409
+ } else if (rb_grn_equal_option(rb_compress, "zlib")) {
410
+ flags |= GRN_OBJ_COMPRESS_ZLIB;
411
+ } else if (rb_grn_equal_option(rb_compress, "lzo")) {
412
+ flags |= GRN_OBJ_COMPRESS_LZO;
413
+ } else {
414
+ rb_raise(rb_eArgError,
415
+ "invalid compress type: %s: "
416
+ "available types: [:zlib, :lzo, nil]",
417
+ rb_grn_inspect(rb_compress));
418
+ }
419
+
404
420
  column = grn_column_create(context, table, name, name_size,
405
421
  path, flags, value_type);
406
422
  rb_grn_context_check(context, self);
@@ -419,7 +435,7 @@ rb_grn_table_define_index_column (int argc, VALUE *argv, VALUE self)
419
435
  grn_obj_flags flags = GRN_OBJ_COLUMN_INDEX;
420
436
  VALUE rb_name, rb_value_type;
421
437
  VALUE options, rb_path, rb_persistent;
422
- VALUE rb_compress, rb_with_section, rb_with_weight, rb_with_position;
438
+ VALUE rb_with_section, rb_with_weight, rb_with_position;
423
439
  VALUE rb_column, rb_source, rb_sources;
424
440
 
425
441
  rb_grn_table_deconstruct(SELF(self), &table, &context,
@@ -434,7 +450,6 @@ rb_grn_table_define_index_column (int argc, VALUE *argv, VALUE self)
434
450
  rb_grn_scan_options(options,
435
451
  "path", &rb_path,
436
452
  "persistent", &rb_persistent,
437
- "compress", &rb_compress,
438
453
  "with_section", &rb_with_section,
439
454
  "with_weight", &rb_with_weight,
440
455
  "with_position", &rb_with_position,
@@ -452,18 +467,6 @@ rb_grn_table_define_index_column (int argc, VALUE *argv, VALUE self)
452
467
  if (RVAL2CBOOL(rb_persistent))
453
468
  flags |= GRN_OBJ_PERSISTENT;
454
469
 
455
- if (NIL_P(rb_compress)) {
456
- } else if (rb_grn_equal_option(rb_compress, "zlib")) {
457
- flags |= GRN_OBJ_COMPRESS_ZLIB;
458
- } else if (rb_grn_equal_option(rb_compress, "lzo")) {
459
- flags |= GRN_OBJ_COMPRESS_LZO;
460
- } else {
461
- rb_raise(rb_eArgError,
462
- "invalid compress type: %s: "
463
- "available types: [:zlib, :lzo, nil]",
464
- rb_grn_inspect(rb_compress));
465
- }
466
-
467
470
  if (RVAL2CBOOL(rb_with_section))
468
471
  flags |= GRN_OBJ_WITH_SECTION;
469
472
 
@@ -551,6 +554,18 @@ rb_grn_table_get_column (VALUE self, VALUE rb_name)
551
554
  NULL, NULL,
552
555
  NULL, NULL, NULL);
553
556
 
557
+ switch (TYPE(rb_name)) {
558
+ case T_SYMBOL:
559
+ rb_name = rb_str_new2(rb_id2name(SYM2ID(rb_name)));
560
+ break;
561
+ case T_STRING:
562
+ break;
563
+ default:
564
+ rb_raise(rb_eArgError,
565
+ "column name should be String or Symbol: %s",
566
+ rb_grn_inspect(rb_name));
567
+ break;
568
+ }
554
569
  name = StringValuePtr(rb_name);
555
570
  name_size = RSTRING_LEN(rb_name);
556
571
 
@@ -598,7 +613,7 @@ rb_grn_table_get_columns (int argc, VALUE *argv, VALUE self)
598
613
  return rb_columns;
599
614
 
600
615
  cursor = grn_table_cursor_open(context, columns, NULL, 0, NULL, 0,
601
- GRN_CURSOR_ASCENDING);
616
+ 0, 0, GRN_CURSOR_ASCENDING);
602
617
  rb_grn_context_check(context, self);
603
618
  while (grn_table_cursor_next(context, cursor) != GRN_ID_NIL) {
604
619
  void *key;
@@ -674,10 +689,11 @@ rb_grn_table_open_grn_cursor (int argc, VALUE *argv, VALUE self,
674
689
  if (RVAL2CBOOL(rb_less_than))
675
690
  flags |= GRN_CURSOR_LT;
676
691
 
692
+ /* FIXME: should support offset and limit */
677
693
  cursor = grn_table_cursor_open(*context, table,
678
694
  min_key, min_key_size,
679
695
  max_key, max_key_size,
680
- flags);
696
+ 0, 0, flags);
681
697
  rb_grn_context_check(*context, self);
682
698
 
683
699
  return cursor;
@@ -694,8 +710,7 @@ rb_grn_table_open_cursor (int argc, VALUE *argv, VALUE self)
694
710
  rb_cursor = GRNTABLECURSOR2RVAL(Qnil, context, cursor);
695
711
  rb_iv_set(rb_cursor, "@table", self); /* FIXME: cursor should mark table */
696
712
  if (rb_block_given_p())
697
- return rb_ensure(rb_yield, rb_cursor,
698
- rb_grn_table_cursor_close, rb_cursor);
713
+ return rb_ensure(rb_yield, rb_cursor, rb_grn_object_close, rb_cursor);
699
714
  else
700
715
  return rb_cursor;
701
716
  }
@@ -760,14 +775,13 @@ rb_grn_table_each (VALUE self)
760
775
  rb_grn_table_deconstruct(SELF(self), &table, &context,
761
776
  NULL, NULL,
762
777
  NULL, NULL, NULL);
763
- cursor = grn_table_cursor_open(context, table, NULL, 0, NULL, 0, 0);
778
+ cursor = grn_table_cursor_open(context, table, NULL, 0, NULL, 0,
779
+ 0, 0, GRN_CURSOR_ASCENDING);
764
780
  rb_cursor = GRNTABLECURSOR2RVAL(Qnil, context, cursor);
765
- rb_iv_set(self, "cursor", rb_cursor);
766
781
  while ((id = grn_table_cursor_next(context, cursor)) != GRN_ID_NIL) {
767
782
  rb_yield(rb_grn_record_new(self, id, Qnil));
768
783
  }
769
- rb_grn_table_cursor_close(rb_cursor);
770
- rb_iv_set(self, "cursor", Qnil);
784
+ rb_grn_object_close(rb_cursor);
771
785
 
772
786
  return Qnil;
773
787
  }
@@ -824,6 +838,14 @@ rb_grn_table_sort (int argc, VALUE *argv, VALUE self)
824
838
 
825
839
  if (RVAL2CBOOL(rb_obj_is_kind_of(rb_sort_keys[i], rb_cHash))) {
826
840
  rb_sort_options = rb_sort_keys[i];
841
+ } else if (RVAL2CBOOL(rb_obj_is_kind_of(rb_sort_keys[i], rb_cArray))) {
842
+ rb_sort_options = rb_hash_new();
843
+ rb_hash_aset(rb_sort_options,
844
+ RB_GRN_INTERN("key"),
845
+ rb_ary_entry(rb_sort_keys[i], 0));
846
+ rb_hash_aset(rb_sort_options,
847
+ RB_GRN_INTERN("order"),
848
+ rb_ary_entry(rb_sort_keys[i], 1));
827
849
  } else {
828
850
  rb_sort_options = rb_hash_new();
829
851
  rb_hash_aset(rb_sort_options,
@@ -842,9 +864,14 @@ rb_grn_table_sort (int argc, VALUE *argv, VALUE self)
842
864
  } else if (rb_grn_equal_option(rb_order, "desc") ||
843
865
  rb_grn_equal_option(rb_order, "descending")) {
844
866
  keys[i].flags = GRN_TABLE_SORT_DESC;
845
- } else {
846
- /* FIXME: validation */
867
+ } else if (rb_grn_equal_option(rb_order, "asc") ||
868
+ rb_grn_equal_option(rb_order, "ascending")) {
847
869
  keys[i].flags = GRN_TABLE_SORT_ASC;
870
+ } else {
871
+ rb_raise(rb_eArgError,
872
+ "order should be one of "
873
+ "[nil, :desc, :descending, :asc, :ascending]: %s",
874
+ rb_grn_inspect(rb_order));
848
875
  }
849
876
  }
850
877
 
@@ -856,12 +883,12 @@ rb_grn_table_sort (int argc, VALUE *argv, VALUE self)
856
883
  limit = NUM2INT(rb_limit);
857
884
 
858
885
  result = grn_table_create(context, NULL, 0, NULL, GRN_TABLE_NO_KEY,
859
- table, sizeof(grn_id));
886
+ NULL, table);
860
887
  n_records = grn_table_sort(context, table, limit, result, keys, n_keys);
861
888
 
862
889
  rb_result = rb_ary_new();
863
890
  cursor = grn_table_cursor_open(context, result, NULL, 0, NULL, 0,
864
- GRN_CURSOR_ASCENDING);
891
+ 0, 0, GRN_CURSOR_ASCENDING);
865
892
  while (grn_table_cursor_next(context, cursor) != GRN_ID_NIL) {
866
893
  void *value;
867
894
  grn_id *id;
@@ -1220,16 +1247,32 @@ rb_grn_table_select (int argc, VALUE *argv, VALUE self)
1220
1247
  grn_obj *table, *result, *expression;
1221
1248
  grn_operator operator = GRN_OP_OR;
1222
1249
  grn_rc rc;
1223
- VALUE options;
1250
+ VALUE rb_query = Qnil, query_or_options, options;
1224
1251
  VALUE rb_name, rb_operator, rb_result;
1225
1252
  VALUE rb_expression, builder;
1226
1253
 
1227
- rb_scan_args(argc, argv, "01", &options);
1254
+ rb_scan_args(argc, argv, "02", &query_or_options, &options);
1228
1255
 
1229
1256
  rb_grn_table_deconstruct(SELF(self), &table, &context,
1230
1257
  NULL, NULL,
1231
1258
  NULL, NULL, NULL);
1232
1259
 
1260
+ if (RVAL2CBOOL(rb_obj_is_kind_of(query_or_options, rb_cString))) {
1261
+ if (rb_block_given_p())
1262
+ rb_raise(rb_eArgError,
1263
+ "should not specify both of query string and "
1264
+ "expression block: %s",
1265
+ rb_grn_inspect(rb_ary_new4(argc, argv)));
1266
+ rb_query = query_or_options;
1267
+ } else {
1268
+ if (!NIL_P(options))
1269
+ rb_raise(rb_eArgError,
1270
+ "should be [query_string, option_hash] "
1271
+ "or [option_hash]: %s",
1272
+ rb_grn_inspect(rb_ary_new4(argc, argv)));
1273
+ options = query_or_options;
1274
+ }
1275
+
1233
1276
  rb_grn_scan_options(options,
1234
1277
  "operator", &rb_operator,
1235
1278
  "result", &rb_result,
@@ -1249,12 +1292,27 @@ rb_grn_table_select (int argc, VALUE *argv, VALUE self)
1249
1292
  result = RVAL2GRNTABLE(rb_result, &context);
1250
1293
  }
1251
1294
 
1252
- builder = rb_grn_record_expression_builder_new(self, rb_name);
1253
- rb_expression = rb_grn_record_expression_builder_build(builder);
1295
+ if (NIL_P(rb_query)) {
1296
+ builder = rb_grn_record_expression_builder_new(self, rb_name);
1297
+ rb_expression = rb_grn_record_expression_builder_build(builder);
1298
+ rb_grn_object_deconstruct(RB_GRN_OBJECT(DATA_PTR(rb_expression)),
1299
+ &expression, NULL,
1300
+ NULL, NULL, NULL, NULL);
1301
+ } else {
1302
+ const char *name = NULL, *query;
1303
+ unsigned name_size = 0, query_size;
1304
+
1305
+ query = StringValueCStr(rb_query);
1306
+ query_size = RSTRING_LEN(rb_query);
1307
+ if (!NIL_P(rb_name)) {
1308
+ name = StringValueCStr(rb_name);
1309
+ name_size = RSTRING_LEN(rb_name);
1310
+ }
1311
+ expression = grn_expr_create_from_str(context, name, name_size,
1312
+ query, query_size,
1313
+ table, NULL);
1314
+ }
1254
1315
 
1255
- rb_grn_object_deconstruct(RB_GRN_OBJECT(DATA_PTR(rb_expression)),
1256
- &expression, NULL,
1257
- NULL, NULL, NULL, NULL);
1258
1316
 
1259
1317
  rc = grn_table_select(context, table, expression, result, operator);
1260
1318
  rb_grn_context_check(context, self);
@@ -1263,6 +1321,52 @@ rb_grn_table_select (int argc, VALUE *argv, VALUE self)
1263
1321
  return rb_result;
1264
1322
  }
1265
1323
 
1324
+ static VALUE
1325
+ rb_grn_table_set_operation_bang (VALUE self, VALUE rb_other,
1326
+ grn_operator operator)
1327
+ {
1328
+ grn_ctx *context;
1329
+ grn_obj *table, *other;
1330
+ grn_rc rc;
1331
+
1332
+ rb_grn_table_deconstruct(SELF(self), &table, &context,
1333
+ NULL, NULL,
1334
+ NULL, NULL, NULL);
1335
+ rb_grn_table_deconstruct(SELF(rb_other), &other, NULL,
1336
+ NULL, NULL,
1337
+ NULL, NULL, NULL);
1338
+
1339
+ rc = grn_table_setoperation(context, table, other, table, operator);
1340
+ rb_grn_context_check(context, self);
1341
+ rb_grn_rc_check(rc, self);
1342
+
1343
+ return self;
1344
+ }
1345
+
1346
+ static VALUE
1347
+ rb_grn_table_union_bang (VALUE self, VALUE rb_other)
1348
+ {
1349
+ return rb_grn_table_set_operation_bang(self ,rb_other, GRN_OP_OR);
1350
+ }
1351
+
1352
+ static VALUE
1353
+ rb_grn_table_intersection_bang (VALUE self, VALUE rb_other)
1354
+ {
1355
+ return rb_grn_table_set_operation_bang(self ,rb_other, GRN_OP_AND);
1356
+ }
1357
+
1358
+ static VALUE
1359
+ rb_grn_table_difference_bang (VALUE self, VALUE rb_other)
1360
+ {
1361
+ return rb_grn_table_set_operation_bang(self ,rb_other, GRN_OP_BUT);
1362
+ }
1363
+
1364
+ static VALUE
1365
+ rb_grn_table_merge_bang (VALUE self, VALUE rb_other)
1366
+ {
1367
+ return rb_grn_table_set_operation_bang(self ,rb_other, GRN_OP_ADJUST);
1368
+ }
1369
+
1266
1370
  void
1267
1371
  rb_grn_init_table (VALUE mGrn)
1268
1372
  {
@@ -1312,6 +1416,14 @@ rb_grn_init_table (VALUE mGrn)
1312
1416
 
1313
1417
  rb_define_method(rb_cGrnTable, "select", rb_grn_table_select, -1);
1314
1418
 
1419
+ rb_define_method(rb_cGrnTable, "union!", rb_grn_table_union_bang, 1);
1420
+ rb_define_method(rb_cGrnTable, "intersection!",
1421
+ rb_grn_table_intersection_bang, 1);
1422
+ rb_define_method(rb_cGrnTable, "difference!",
1423
+ rb_grn_table_difference_bang, 1);
1424
+ rb_define_method(rb_cGrnTable, "merge!",
1425
+ rb_grn_table_merge_bang, 1);
1426
+
1315
1427
  rb_grn_init_table_key_support(mGrn);
1316
1428
  rb_grn_init_array(mGrn);
1317
1429
  rb_grn_init_hash(mGrn);
data/ext/rb-grn-type.c CHANGED
@@ -45,15 +45,15 @@ rb_grn_type_initialize (int argc, VALUE *argv, VALUE self)
45
45
  grn_ctx *context;
46
46
  grn_obj *type;
47
47
  const char *name = NULL;
48
- unsigned name_size, size = sizeof(grn_id);
48
+ unsigned name_size, size = 0;
49
49
  grn_obj_flags flags = 0;
50
- VALUE rb_name, options, rb_context, rb_key_type, rb_size;
50
+ VALUE rb_name, options, rb_context, rb_option, rb_size;
51
51
 
52
52
  rb_scan_args(argc, argv, "11", &rb_name, &options);
53
53
 
54
54
  rb_grn_scan_options(options,
55
55
  "context", &rb_context,
56
- "type", &rb_key_type,
56
+ "option", &rb_option,
57
57
  "size", &rb_size,
58
58
  NULL);
59
59
 
@@ -62,22 +62,30 @@ rb_grn_type_initialize (int argc, VALUE *argv, VALUE self)
62
62
 
63
63
  context = rb_grn_context_ensure(&rb_context);
64
64
 
65
- if (NIL_P(rb_key_type)) {
66
- flags = GRN_OBJ_KEY_VAR_SIZE;
67
- } else if (rb_grn_equal_option(rb_key_type, "integer") ||
68
- rb_grn_equal_option(rb_key_type, "int")) {
65
+ if (NIL_P(rb_option)) {
66
+ } else if (rb_grn_equal_option(rb_option, "integer") ||
67
+ rb_grn_equal_option(rb_option, "int")) {
69
68
  flags = GRN_OBJ_KEY_INT;
70
69
  size = sizeof(int);
71
- } else if (rb_grn_equal_option(rb_key_type, "uint")) {
70
+ } else if (rb_grn_equal_option(rb_option, "unsigned_integer") ||
71
+ rb_grn_equal_option(rb_option, "uint")) {
72
72
  flags = GRN_OBJ_KEY_UINT;
73
73
  size = sizeof(unsigned int);
74
- } else if (rb_grn_equal_option(rb_key_type, "float")) {
74
+ } else if (rb_grn_equal_option(rb_option, "float")) {
75
75
  flags = GRN_OBJ_KEY_FLOAT;
76
76
  size = sizeof(double);
77
+ } else if (rb_grn_equal_option(rb_option, "variable")) {
78
+ flags = GRN_OBJ_KEY_VAR_SIZE;
79
+ } else {
80
+ rb_raise(rb_eArgError,
81
+ ":option should be one of "
82
+ "[:int, :integer, :uint, :unsigned_integer, "
83
+ ":float, :variable]: %s",
84
+ rb_grn_inspect(options));
77
85
  }
78
86
 
79
87
  if (NIL_P(rb_size)) {
80
- if (flags == GRN_OBJ_KEY_VAR_SIZE)
88
+ if (size == 0)
81
89
  rb_raise(rb_eArgError, "size is missing: %s",
82
90
  rb_grn_inspect(options));
83
91
  } else {
data/ext/rb-grn-utils.c CHANGED
@@ -110,10 +110,10 @@ rb_grn_bulk_to_ruby_object_by_range_id (grn_ctx *context, grn_obj *bulk,
110
110
  break;
111
111
  case GRN_DB_TIME:
112
112
  {
113
- grn_timeval *time_value = (grn_timeval *)GRN_BULK_HEAD(bulk);
113
+ int64_t time_value = GRN_TIME_VALUE(bulk);
114
114
  *rb_value = rb_funcall(rb_cTime, rb_intern("at"), 2,
115
- INT2NUM(time_value->tv_sec),
116
- INT2NUM(time_value->tv_usec));
115
+ LL2NUM(time_value / RB_GRN_USEC_PER_SEC),
116
+ LL2NUM(time_value % RB_GRN_USEC_PER_SEC));
117
117
  }
118
118
  break;
119
119
  case GRN_DB_SHORT_TEXT:
@@ -195,7 +195,7 @@ rb_grn_bulk_from_ruby_object (VALUE object, grn_ctx *context, grn_obj *bulk)
195
195
  unsigned int size;
196
196
  int32_t int32_value;
197
197
  int64_t int64_value;
198
- grn_timeval time_value;
198
+ int64_t time_value;
199
199
  double double_value;
200
200
  grn_id id_value;
201
201
  grn_obj_flags flags = 0;
@@ -231,8 +231,7 @@ rb_grn_bulk_from_ruby_object (VALUE object, grn_ctx *context, grn_obj *bulk)
231
231
 
232
232
  sec = rb_funcall(object, rb_intern("to_i"), 0);
233
233
  usec = rb_funcall(object, rb_intern("usec"), 0);
234
- time_value.tv_sec = NUM2INT(sec);
235
- time_value.tv_usec = NUM2INT(usec);
234
+ time_value = NUM2LL(sec) * RB_GRN_USEC_PER_SEC + NUM2LL(usec);
236
235
  string = (const char *)&time_value;
237
236
  size = sizeof(time_value);
238
237
  } else if (RVAL2CBOOL(rb_obj_is_kind_of(object, rb_cGrnObject))) {
@@ -274,7 +273,7 @@ rb_grn_bulk_from_ruby_object_with_type (VALUE object, grn_ctx *context,
274
273
  int32_t int32_value;
275
274
  uint32_t uint32_value;
276
275
  int64_t int64_value;
277
- grn_timeval time_value;
276
+ int64_t time_value;
278
277
  double double_value;
279
278
  grn_id range;
280
279
  VALUE rb_type;
@@ -302,8 +301,13 @@ rb_grn_bulk_from_ruby_object_with_type (VALUE object, grn_ctx *context,
302
301
  size = sizeof(double_value);
303
302
  break;
304
303
  case GRN_DB_TIME:
305
- time_value.tv_sec = NUM2INT(rb_funcall(object, rb_intern("tv_sec"), 0));
306
- time_value.tv_usec = NUM2INT(rb_funcall(object, rb_intern("tv_usec"), 0));
304
+ {
305
+ VALUE sec, usec;
306
+
307
+ sec = rb_funcall(object, rb_intern("to_i"), 0);
308
+ usec = rb_funcall(object, rb_intern("usec"), 0);
309
+ time_value = NUM2LL(sec) * RB_GRN_USEC_PER_SEC + NUM2LL(usec);
310
+ }
307
311
  string = (const char *)&time_value;
308
312
  size = sizeof(time_value);
309
313
  break;
@@ -586,36 +590,34 @@ rb_grn_obj_from_ruby_object (VALUE rb_object, grn_ctx *context, grn_obj **_obj)
586
590
 
587
591
  switch (TYPE(rb_object)) {
588
592
  case T_NIL:
589
- GRN_VOID_INIT(obj);
593
+ grn_obj_reinit(context, obj, GRN_DB_VOID, 0);
590
594
  break;
591
595
  case T_STRING:
592
- GRN_TEXT_INIT(obj, 0);
596
+ grn_obj_reinit(context, obj, GRN_DB_TEXT, 0);
593
597
  GRN_TEXT_SET(context, obj,
594
598
  RSTRING_PTR(rb_object), RSTRING_LEN(rb_object));
595
599
  break;
596
600
  case T_FIXNUM:
597
- GRN_INT32_INIT(obj, 0);
601
+ grn_obj_reinit(context, obj, GRN_DB_INT32, 0);
598
602
  GRN_INT32_SET(context, obj, NUM2INT(rb_object));
599
603
  break;
600
604
  case T_BIGNUM:
601
- GRN_INT64_INIT(obj, 0);
605
+ grn_obj_reinit(context, obj, GRN_DB_INT64, 0);
602
606
  GRN_INT64_SET(context, obj, NUM2LL(rb_object));
603
607
  break;
604
608
  case T_FLOAT:
605
- GRN_FLOAT_INIT(obj, 0);
609
+ grn_obj_reinit(context, obj, GRN_DB_FLOAT, 0);
606
610
  GRN_FLOAT_SET(context, obj, NUM2DBL(rb_object));
607
611
  break;
608
612
  default:
609
613
  if (RVAL2CBOOL(rb_obj_is_kind_of(rb_object, rb_cTime))) {
610
614
  VALUE sec, usec;
611
- unsigned long long time_value;
615
+ int64_t time_value;
612
616
 
613
617
  sec = rb_funcall(rb_object, rb_intern("to_i"), 0);
614
618
  usec = rb_funcall(rb_object, rb_intern("usec"), 0);
615
- time_value = NUM2INT(sec);
616
- time_value <<= 32;
617
- time_value += NUM2INT(usec);
618
- GRN_TIME_INIT(obj, 0);
619
+ time_value = NUM2LL(sec) * RB_GRN_USEC_PER_SEC + NUM2LL(usec);
620
+ grn_obj_reinit(context, obj, GRN_DB_TIME, 0);
619
621
  GRN_TIME_SET(context, obj, time_value);
620
622
  } else if (RVAL2CBOOL(rb_obj_is_kind_of(rb_object, rb_cGrnObject))) {
621
623
  grn_obj_close(context, obj); /* TODO: reduce memory allocation */
@@ -632,7 +634,7 @@ rb_grn_obj_from_ruby_object (VALUE rb_object, grn_ctx *context, grn_obj **_obj)
632
634
  &table, NULL,
633
635
  NULL, NULL, NULL, NULL, NULL);
634
636
  table_id = grn_obj_id(context, table);
635
- GRN_RECORD_INIT(obj, 0, table_id);
637
+ grn_obj_reinit(context, obj, table_id, 0);
636
638
  GRN_RECORD_SET(context, obj, id);
637
639
  } else {
638
640
  rb_raise(rb_eTypeError,
data/ext/rb-grn.h CHANGED
@@ -65,7 +65,7 @@ RB_GRN_BEGIN_DECLS
65
65
 
66
66
  #define RB_GRN_MAJOR_VERSION 0
67
67
  #define RB_GRN_MINOR_VERSION 0
68
- #define RB_GRN_MICRO_VERSION 5
68
+ #define RB_GRN_MICRO_VERSION 6
69
69
 
70
70
  typedef int rb_grn_boolean;
71
71
  #define RB_GRN_FALSE (0)
@@ -75,10 +75,7 @@ typedef int rb_grn_boolean;
75
75
 
76
76
  #include <stdint.h>
77
77
 
78
- typedef struct {
79
- int32_t tv_sec;
80
- int32_t tv_usec;
81
- } grn_timeval;
78
+ #define RB_GRN_USEC_PER_SEC 1000000
82
79
 
83
80
  #define RB_GRN_OBJECT(object) ((RbGrnObject *)(object))
84
81
  #define RB_GRN_TABLE(object) ((RbGrnTable *)(object))
@@ -91,6 +88,12 @@ typedef struct {
91
88
 
92
89
  typedef void (*RbGrnUnbindFunction) (void *object);
93
90
 
91
+ typedef struct _RbGrnContext RbGrnContext;
92
+ struct _RbGrnContext
93
+ {
94
+ grn_ctx context;
95
+ };
96
+
94
97
  typedef struct _RbGrnObject RbGrnObject;
95
98
  struct _RbGrnObject
96
99
  {
@@ -222,12 +225,6 @@ const char *rb_grn_rc_to_message (grn_rc rc);
222
225
  void rb_grn_rc_check (grn_rc rc,
223
226
  VALUE related_object);
224
227
 
225
- void rb_grn_context_register (grn_ctx *context,
226
- RbGrnObject *object);
227
- void rb_grn_context_unregister (grn_ctx *context,
228
- RbGrnObject *object);
229
- void rb_grn_context_unbind (grn_ctx *context);
230
-
231
228
  grn_ctx *rb_grn_context_ensure (VALUE *context);
232
229
  VALUE rb_grn_context_get_default (void);
233
230
  VALUE rb_grn_context_to_exception (grn_ctx *context,
@@ -268,6 +265,7 @@ void rb_grn_object_deconstruct (RbGrnObject *rb_grn_object,
268
265
  VALUE rb_grn_object_array_reference (VALUE object,
269
266
  VALUE rb_id);
270
267
  VALUE rb_grn_object_close (VALUE object);
268
+ VALUE rb_grn_object_closed_p (VALUE object);
271
269
  VALUE rb_grn_object_inspect_object (VALUE inspected,
272
270
  grn_ctx *context,
273
271
  grn_obj *object);
@@ -320,7 +318,6 @@ VALUE rb_grn_table_array_set (VALUE self,
320
318
 
321
319
  grn_ctx *rb_grn_table_cursor_ensure_context (VALUE cursor,
322
320
  VALUE *rb_context);
323
- VALUE rb_grn_table_cursor_close (VALUE object);
324
321
 
325
322
  void rb_grn_table_key_support_bind (RbGrnTableKeySupport *rb_grn_table_key_support,
326
323
  grn_ctx *context,
data/extconf.rb CHANGED
@@ -36,7 +36,7 @@ package_name = "groonga"
36
36
  module_name = "groonga"
37
37
  ext_dir_name = "ext"
38
38
  src_dir = File.join(File.expand_path(File.dirname(__FILE__)), ext_dir_name)
39
- major, minor, micro = 0, 1, 0
39
+ major, minor, micro = 0, 1, 1
40
40
 
41
41
  def local_groonga_base_dir
42
42
  File.join(File.dirname(__FILE__), "vendor")
data/html/developer.html CHANGED
@@ -51,7 +51,7 @@
51
51
  Ruby/groongaおよびActiveGroongaを利用したサンプルプログラムもリポジトリにあります。
52
52
  サンプルプログラムは以下のようにチェックアウトできます。
53
53
  </p>
54
- <pre class="command">% svn co http://groonga.rubyforge.org/svn/examples/trunk groonga-examples</pre>
54
+ <pre class="command">% svn co http://groonga.rubyforge.org/svn/examples groonga-examples</pre>
55
55
 
56
56
  <h2>バグ報告・メーリングリスト</h2>
57
57
  <p>
data/html/index.html CHANGED
@@ -42,7 +42,7 @@
42
42
 
43
43
  <h3>Ruby/groongaの最新リリース</h3>
44
44
  <p>
45
- 2009-07-19にリリースされた0.0.5が最新です。
45
+ 2009-07-31にリリースされた0.0.6が最新です。
46
46
  </p>
47
47
 
48
48
  <h3 id="install-ruby-groonga">Ruby/groongaのインストール</h3>
@@ -79,7 +79,7 @@
79
79
 
80
80
  <h3>ActiveGroongaの最新リリース</h3>
81
81
  <p>
82
- 2009-06-05にリリースされた0.0.2が最新です。
82
+ 2009-07-31にリリースされた0.0.6が最新です。
83
83
  </p>
84
84
 
85
85
  <h3 id="install-active-groonga">ActiveGroongaのインストール</h3>