groonga 0.0.5 → 0.0.6

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 (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>