groonga 0.0.1

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 (148) hide show
  1. data/AUTHORS +1 -0
  2. data/NEWS.ja.rdoc +5 -0
  3. data/NEWS.rdoc +5 -0
  4. data/README.ja.rdoc +53 -0
  5. data/README.rdoc +54 -0
  6. data/Rakefile +209 -0
  7. data/TUTORIAL.ja.rdoc +160 -0
  8. data/benchmark/small-many-items.rb +175 -0
  9. data/example/bookmark.rb +38 -0
  10. data/ext/.gitignore +2 -0
  11. data/ext/rb-grn-accessor.c +52 -0
  12. data/ext/rb-grn-array-cursor.c +28 -0
  13. data/ext/rb-grn-array.c +168 -0
  14. data/ext/rb-grn-column.c +273 -0
  15. data/ext/rb-grn-context.c +333 -0
  16. data/ext/rb-grn-database.c +128 -0
  17. data/ext/rb-grn-encoding.c +163 -0
  18. data/ext/rb-grn-exception.c +1014 -0
  19. data/ext/rb-grn-hash-cursor.c +30 -0
  20. data/ext/rb-grn-hash.c +40 -0
  21. data/ext/rb-grn-logger.c +277 -0
  22. data/ext/rb-grn-object.c +985 -0
  23. data/ext/rb-grn-patricia-trie-cursor.c +30 -0
  24. data/ext/rb-grn-patricia-trie.c +40 -0
  25. data/ext/rb-grn-procedure.c +52 -0
  26. data/ext/rb-grn-query.c +207 -0
  27. data/ext/rb-grn-record.c +33 -0
  28. data/ext/rb-grn-snippet.c +274 -0
  29. data/ext/rb-grn-table-cursor-key-support.c +55 -0
  30. data/ext/rb-grn-table-cursor.c +294 -0
  31. data/ext/rb-grn-table-key-support.c +299 -0
  32. data/ext/rb-grn-table.c +706 -0
  33. data/ext/rb-grn-type.c +114 -0
  34. data/ext/rb-grn-utils.c +578 -0
  35. data/ext/rb-grn.h +346 -0
  36. data/ext/rb-groonga.c +98 -0
  37. data/extconf.rb +171 -0
  38. data/html/bar.svg +153 -0
  39. data/html/developer.html +121 -0
  40. data/html/developer.svg +469 -0
  41. data/html/download.svg +253 -0
  42. data/html/footer.html.erb +28 -0
  43. data/html/head.html.erb +4 -0
  44. data/html/header.html.erb +17 -0
  45. data/html/index.html +153 -0
  46. data/html/install.svg +636 -0
  47. data/html/logo.xcf +0 -0
  48. data/html/ranguba.css +248 -0
  49. data/html/tutorial.svg +559 -0
  50. data/lib/groonga.rb +50 -0
  51. data/lib/groonga/record.rb +98 -0
  52. data/license/GPL +340 -0
  53. data/license/LGPL +504 -0
  54. data/license/RUBY +59 -0
  55. data/pkg-config.rb +328 -0
  56. data/test-unit/Rakefile +35 -0
  57. data/test-unit/TODO +5 -0
  58. data/test-unit/bin/testrb +5 -0
  59. data/test-unit/html/classic.html +15 -0
  60. data/test-unit/html/index.html +25 -0
  61. data/test-unit/html/index.html.ja +27 -0
  62. data/test-unit/lib/test/unit.rb +342 -0
  63. data/test-unit/lib/test/unit/assertionfailederror.rb +14 -0
  64. data/test-unit/lib/test/unit/assertions.rb +1149 -0
  65. data/test-unit/lib/test/unit/attribute.rb +125 -0
  66. data/test-unit/lib/test/unit/autorunner.rb +306 -0
  67. data/test-unit/lib/test/unit/collector.rb +43 -0
  68. data/test-unit/lib/test/unit/collector/descendant.rb +23 -0
  69. data/test-unit/lib/test/unit/collector/dir.rb +108 -0
  70. data/test-unit/lib/test/unit/collector/load.rb +135 -0
  71. data/test-unit/lib/test/unit/collector/objectspace.rb +34 -0
  72. data/test-unit/lib/test/unit/color-scheme.rb +86 -0
  73. data/test-unit/lib/test/unit/color.rb +96 -0
  74. data/test-unit/lib/test/unit/diff.rb +538 -0
  75. data/test-unit/lib/test/unit/error.rb +124 -0
  76. data/test-unit/lib/test/unit/exceptionhandler.rb +39 -0
  77. data/test-unit/lib/test/unit/failure.rb +110 -0
  78. data/test-unit/lib/test/unit/fixture.rb +176 -0
  79. data/test-unit/lib/test/unit/notification.rb +125 -0
  80. data/test-unit/lib/test/unit/omission.rb +143 -0
  81. data/test-unit/lib/test/unit/pending.rb +146 -0
  82. data/test-unit/lib/test/unit/priority.rb +161 -0
  83. data/test-unit/lib/test/unit/runner/console.rb +52 -0
  84. data/test-unit/lib/test/unit/runner/emacs.rb +8 -0
  85. data/test-unit/lib/test/unit/testcase.rb +360 -0
  86. data/test-unit/lib/test/unit/testresult.rb +89 -0
  87. data/test-unit/lib/test/unit/testsuite.rb +110 -0
  88. data/test-unit/lib/test/unit/ui/console/outputlevel.rb +14 -0
  89. data/test-unit/lib/test/unit/ui/console/testrunner.rb +220 -0
  90. data/test-unit/lib/test/unit/ui/emacs/testrunner.rb +49 -0
  91. data/test-unit/lib/test/unit/ui/testrunner.rb +20 -0
  92. data/test-unit/lib/test/unit/ui/testrunnermediator.rb +77 -0
  93. data/test-unit/lib/test/unit/ui/testrunnerutilities.rb +41 -0
  94. data/test-unit/lib/test/unit/util/backtracefilter.rb +41 -0
  95. data/test-unit/lib/test/unit/util/method-owner-finder.rb +28 -0
  96. data/test-unit/lib/test/unit/util/observable.rb +90 -0
  97. data/test-unit/lib/test/unit/util/procwrapper.rb +48 -0
  98. data/test-unit/lib/test/unit/version.rb +7 -0
  99. data/test-unit/sample/adder.rb +13 -0
  100. data/test-unit/sample/subtracter.rb +12 -0
  101. data/test-unit/sample/tc_adder.rb +18 -0
  102. data/test-unit/sample/tc_subtracter.rb +18 -0
  103. data/test-unit/sample/test_user.rb +22 -0
  104. data/test-unit/sample/ts_examples.rb +7 -0
  105. data/test-unit/test/collector/test-descendant.rb +135 -0
  106. data/test-unit/test/collector/test-load.rb +333 -0
  107. data/test-unit/test/collector/test_dir.rb +406 -0
  108. data/test-unit/test/collector/test_objectspace.rb +98 -0
  109. data/test-unit/test/run-test.rb +13 -0
  110. data/test-unit/test/test-attribute.rb +86 -0
  111. data/test-unit/test/test-color-scheme.rb +56 -0
  112. data/test-unit/test/test-color.rb +47 -0
  113. data/test-unit/test/test-diff.rb +477 -0
  114. data/test-unit/test/test-emacs-runner.rb +60 -0
  115. data/test-unit/test/test-fixture.rb +287 -0
  116. data/test-unit/test/test-notification.rb +33 -0
  117. data/test-unit/test/test-omission.rb +81 -0
  118. data/test-unit/test/test-pending.rb +70 -0
  119. data/test-unit/test/test-priority.rb +119 -0
  120. data/test-unit/test/test_assertions.rb +1082 -0
  121. data/test-unit/test/test_error.rb +26 -0
  122. data/test-unit/test/test_failure.rb +33 -0
  123. data/test-unit/test/test_testcase.rb +478 -0
  124. data/test-unit/test/test_testresult.rb +113 -0
  125. data/test-unit/test/test_testsuite.rb +129 -0
  126. data/test-unit/test/testunit-test-util.rb +14 -0
  127. data/test-unit/test/ui/test_testrunmediator.rb +20 -0
  128. data/test-unit/test/util/test-method-owner-finder.rb +38 -0
  129. data/test-unit/test/util/test_backtracefilter.rb +41 -0
  130. data/test-unit/test/util/test_observable.rb +102 -0
  131. data/test-unit/test/util/test_procwrapper.rb +36 -0
  132. data/test/.gitignore +1 -0
  133. data/test/groonga-test-utils.rb +90 -0
  134. data/test/run-test.rb +54 -0
  135. data/test/test-column.rb +190 -0
  136. data/test/test-context.rb +90 -0
  137. data/test/test-database.rb +62 -0
  138. data/test/test-encoding.rb +33 -0
  139. data/test/test-exception.rb +85 -0
  140. data/test/test-procedure.rb +35 -0
  141. data/test/test-query.rb +22 -0
  142. data/test/test-record.rb +188 -0
  143. data/test/test-snippet.rb +121 -0
  144. data/test/test-table-cursor.rb +51 -0
  145. data/test/test-table.rb +447 -0
  146. data/test/test-type.rb +52 -0
  147. data/test/test-version.rb +31 -0
  148. metadata +213 -0
data/ext/rb-grn-type.c ADDED
@@ -0,0 +1,114 @@
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) (RVAL2GRNTYPE(object))
22
+
23
+ VALUE rb_cGrnType;
24
+
25
+ grn_obj *
26
+ rb_grn_type_from_ruby_object (VALUE object)
27
+ {
28
+ if (!RVAL2CBOOL(rb_obj_is_kind_of(object, rb_cGrnType))) {
29
+ rb_raise(rb_eTypeError, "not a groonga type");
30
+ }
31
+
32
+ return RVAL2GRNOBJECT(object, NULL);
33
+ }
34
+
35
+ VALUE
36
+ rb_grn_type_to_ruby_object (grn_ctx *context, grn_obj *type,
37
+ rb_grn_boolean owner)
38
+ {
39
+ return GRNOBJECT2RVAL(rb_cGrnType, context, type, owner);
40
+ }
41
+
42
+ static VALUE
43
+ rb_grn_type_initialize (int argc, VALUE *argv, VALUE self)
44
+ {
45
+ grn_ctx *context;
46
+ grn_obj *type;
47
+ const char *name = NULL;
48
+ unsigned name_size, size = sizeof(grn_id);
49
+ grn_obj_flags flags = 0;
50
+ VALUE rb_name, options, rb_context, rb_key_type, rb_size;
51
+
52
+ rb_scan_args(argc, argv, "11", &rb_name, &options);
53
+
54
+ rb_grn_scan_options(options,
55
+ "context", &rb_context,
56
+ "type", &rb_key_type,
57
+ "size", &rb_size,
58
+ NULL);
59
+
60
+ name = StringValuePtr(rb_name);
61
+ name_size = RSTRING_LEN(rb_name);
62
+
63
+ context = rb_grn_context_ensure(rb_context);
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")) {
69
+ flags = GRN_OBJ_KEY_INT;
70
+ size = sizeof(int);
71
+ } else if (rb_grn_equal_option(rb_key_type, "uint")) {
72
+ flags = GRN_OBJ_KEY_UINT;
73
+ size = sizeof(unsigned int);
74
+ } else if (rb_grn_equal_option(rb_key_type, "float")) {
75
+ flags = GRN_OBJ_KEY_FLOAT;
76
+ size = sizeof(double);
77
+ }
78
+
79
+ if (NIL_P(rb_size)) {
80
+ if (flags == GRN_OBJ_KEY_VAR_SIZE)
81
+ rb_raise(rb_eArgError, "size is missing: %s",
82
+ rb_grn_inspect(options));
83
+ } else {
84
+ size = NUM2UINT(rb_size);
85
+ }
86
+
87
+ type = grn_type_create(context, name, name_size, flags, size);
88
+ rb_grn_object_initialize(self, context, type);
89
+ rb_grn_context_check(context, rb_ary_new4(argc, argv));
90
+
91
+ return Qnil;
92
+ }
93
+
94
+ void
95
+ rb_grn_init_type (VALUE mGrn)
96
+ {
97
+ rb_cGrnType = rb_define_class_under(mGrn, "Type", rb_cGrnObject);
98
+
99
+ rb_define_method(rb_cGrnType, "initialize", rb_grn_type_initialize, -1);
100
+
101
+ rb_define_const(rb_cGrnType, "INT", INT2NUM(GRN_DB_INT));
102
+ rb_define_const(rb_cGrnType, "UINT", INT2NUM(GRN_DB_UINT));
103
+ rb_define_const(rb_cGrnType, "INT64", INT2NUM(GRN_DB_INT64));
104
+ rb_define_const(rb_cGrnType, "FLOAT", INT2NUM(GRN_DB_FLOAT));
105
+ rb_define_const(rb_cGrnType, "TIME", INT2NUM(GRN_DB_TIME));
106
+ rb_define_const(rb_cGrnType, "SHORT_TEXT", INT2NUM(GRN_DB_SHORTTEXT));
107
+ rb_define_const(rb_cGrnType, "TEXT", INT2NUM(GRN_DB_TEXT));
108
+ rb_define_const(rb_cGrnType, "LONG_TEXT", INT2NUM(GRN_DB_LONGTEXT));
109
+ rb_define_const(rb_cGrnType, "DELIMIT", INT2NUM(GRN_DB_DELIMIT));
110
+ rb_define_const(rb_cGrnType, "UNIGRAM", INT2NUM(GRN_DB_UNIGRAM));
111
+ rb_define_const(rb_cGrnType, "BIGRAM", INT2NUM(GRN_DB_BIGRAM));
112
+ rb_define_const(rb_cGrnType, "TRIGRAM", INT2NUM(GRN_DB_TRIGRAM));
113
+ rb_define_const(rb_cGrnType, "MECAB", INT2NUM(GRN_DB_MECAB));
114
+ }
@@ -0,0 +1,578 @@
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
+ #include <stdarg.h>
22
+
23
+ const char *
24
+ rb_grn_inspect (VALUE object)
25
+ {
26
+ VALUE inspected;
27
+
28
+ inspected = rb_funcall(object, rb_intern("inspect"), 0);
29
+ return StringValueCStr(inspected);
30
+ }
31
+
32
+ void
33
+ rb_grn_scan_options (VALUE options, ...)
34
+ {
35
+ VALUE available_keys;
36
+ const char *key;
37
+ VALUE *value;
38
+ va_list args;
39
+
40
+ if (NIL_P(options))
41
+ options = rb_hash_new();
42
+ else
43
+ options = rb_funcall(options, rb_intern("dup"), 0);
44
+
45
+ Check_Type(options, T_HASH);
46
+
47
+ available_keys = rb_ary_new();
48
+ va_start(args, options);
49
+ key = va_arg(args, const char *);
50
+ while (key) {
51
+ VALUE rb_key;
52
+ value = va_arg(args, VALUE *);
53
+
54
+ rb_key = RB_GRN_INTERN(key);
55
+ rb_ary_push(available_keys, rb_key);
56
+ *value = rb_funcall(options, rb_intern("delete"), 1, rb_key);
57
+
58
+ key = va_arg(args, const char *);
59
+ }
60
+ va_end(args);
61
+
62
+ if (RVAL2CBOOL(rb_funcall(options, rb_intern("empty?"), 0)))
63
+ return;
64
+
65
+ rb_raise(rb_eArgError,
66
+ "unexpected key(s) exist: %s: available keys: %s",
67
+ rb_grn_inspect(rb_funcall(options, rb_intern("keys"), 0)),
68
+ rb_grn_inspect(available_keys));
69
+ }
70
+
71
+ rb_grn_boolean
72
+ rb_grn_equal_option (VALUE option, const char *key)
73
+ {
74
+ VALUE key_string, key_symbol;
75
+
76
+ key_string = rb_str_new2(key);
77
+ if (RVAL2CBOOL(rb_funcall(option, rb_intern("=="), 1, key_string)))
78
+ return RB_GRN_TRUE;
79
+
80
+ key_symbol = rb_str_intern(key_string);
81
+ if (RVAL2CBOOL(rb_funcall(option, rb_intern("=="), 1, key_symbol)))
82
+ return RB_GRN_TRUE;
83
+
84
+ return RB_GRN_FALSE;
85
+ }
86
+
87
+ static VALUE
88
+ rb_grn_bulk_to_ruby_object_by_range_id (grn_ctx *context, grn_obj *bulk,
89
+ grn_obj *range, grn_id range_id,
90
+ VALUE rb_range,
91
+ VALUE related_object, VALUE *rb_value)
92
+ {
93
+ rb_grn_boolean success = RB_GRN_TRUE;
94
+
95
+ switch (range_id) {
96
+ case GRN_DB_VOID:
97
+ *rb_value = rb_str_new(GRN_BULK_HEAD(bulk), GRN_BULK_VSIZE(bulk));
98
+ break;
99
+ case GRN_DB_INT:
100
+ *rb_value = INT2NUM(*((int *)GRN_BULK_HEAD(bulk)));
101
+ break;
102
+ case GRN_DB_UINT:
103
+ *rb_value = UINT2NUM(*((int *)GRN_BULK_HEAD(bulk)));
104
+ break;
105
+ case GRN_DB_INT64:
106
+ *rb_value = LL2NUM(*((long long *)GRN_BULK_HEAD(bulk)));
107
+ break;
108
+ case GRN_DB_FLOAT:
109
+ *rb_value = rb_float_new(*((double *)GRN_BULK_HEAD(bulk)));
110
+ break;
111
+ case GRN_DB_TIME:
112
+ {
113
+ grn_timeval *time_value = (grn_timeval *)GRN_BULK_HEAD(bulk);
114
+ *rb_value = rb_funcall(rb_cTime, rb_intern("at"), 2,
115
+ INT2NUM(time_value->tv_sec),
116
+ INT2NUM(time_value->tv_usec));
117
+ }
118
+ break;
119
+ case GRN_DB_SHORTTEXT:
120
+ case GRN_DB_TEXT:
121
+ case GRN_DB_LONGTEXT:
122
+ *rb_value = rb_str_new(GRN_BULK_HEAD(bulk), GRN_BULK_VSIZE(bulk));
123
+ break;
124
+ default:
125
+ success = RB_GRN_FALSE;
126
+ break;
127
+ }
128
+
129
+ return success;
130
+ }
131
+
132
+ static VALUE
133
+ rb_grn_bulk_to_ruby_object_by_range_type (grn_ctx *context, grn_obj *bulk,
134
+ grn_obj *range, grn_id range_id,
135
+ VALUE rb_range,
136
+ VALUE related_object, VALUE *rb_value)
137
+ {
138
+ rb_grn_boolean success = RB_GRN_TRUE;
139
+
140
+ switch (range->header.type) {
141
+ case GRN_TABLE_HASH_KEY:
142
+ case GRN_TABLE_PAT_KEY:
143
+ case GRN_TABLE_NO_KEY:
144
+ {
145
+ grn_id id;
146
+
147
+ id = *((grn_id *)GRN_BULK_HEAD(bulk));
148
+ if (id == GRN_ID_NIL)
149
+ *rb_value = Qnil;
150
+ else
151
+ *rb_value = rb_grn_record_new(rb_range, id);
152
+ }
153
+ break;
154
+ default:
155
+ success = RB_GRN_FALSE;
156
+ break;
157
+ }
158
+
159
+ return success;
160
+ }
161
+
162
+ VALUE
163
+ rb_grn_bulk_to_ruby_object (grn_ctx *context, grn_obj *bulk,
164
+ VALUE related_object)
165
+ {
166
+ grn_id range_id;
167
+ grn_obj *range;
168
+ VALUE rb_range;
169
+ VALUE rb_value = Qnil;
170
+
171
+ if (GRN_BULK_EMPTYP(bulk))
172
+ return Qnil;
173
+
174
+ range_id = bulk->header.domain;
175
+ range = grn_ctx_get(context, range_id);
176
+ rb_range = GRNOBJECT2RVAL(Qnil, context, range, RB_GRN_FALSE);
177
+
178
+ if (rb_grn_bulk_to_ruby_object_by_range_id(context, bulk,
179
+ range, range_id, rb_range,
180
+ related_object, &rb_value))
181
+ return rb_value;
182
+
183
+ if (rb_grn_bulk_to_ruby_object_by_range_type(context, bulk,
184
+ range, range_id, rb_range,
185
+ related_object, &rb_value))
186
+ return rb_value;
187
+
188
+ return rb_str_new(GRN_BULK_HEAD(bulk), GRN_BULK_VSIZE(bulk));
189
+ }
190
+
191
+ grn_obj *
192
+ rb_grn_bulk_from_ruby_object (VALUE object, grn_ctx *context, grn_obj *bulk)
193
+ {
194
+ const char *string;
195
+ unsigned int size;
196
+ int32_t int32_value;
197
+ int64_t int64_value;
198
+ grn_timeval time_value;
199
+ double double_value;
200
+ grn_id id_value;
201
+ grn_obj_flags flags = 0;
202
+
203
+ if (NIL_P(object)) {
204
+ string = NULL;
205
+ size = 0;
206
+ } else if (RVAL2CBOOL(rb_obj_is_kind_of(object, rb_cString))) {
207
+ string = RSTRING_PTR(object);
208
+ size = RSTRING_LEN(object);
209
+ flags |= GRN_OBJ_DO_SHALLOW_COPY;
210
+ } else if (FIXNUM_P(object)) {
211
+ int32_value = NUM2INT(object);
212
+ string = (const char *)&int32_value;
213
+ size = sizeof(int32_value);
214
+ } else if (RVAL2CBOOL(rb_obj_is_kind_of(object, rb_cBignum))) {
215
+ int64_value = NUM2LL(object);
216
+ string = (const char *)&int64_value;
217
+ size = sizeof(int64_value);
218
+ } else if (RVAL2CBOOL(rb_obj_is_kind_of(object, rb_cFloat))) {
219
+ double_value = NUM2DBL(object);
220
+ string = (const char *)&double_value;
221
+ size = sizeof(double_value);
222
+ } else if (RVAL2CBOOL(rb_obj_is_kind_of(object, rb_cTime))) {
223
+ time_value.tv_sec = NUM2INT(rb_funcall(object, rb_intern("to_i"), 0));
224
+ time_value.tv_usec = NUM2INT(rb_funcall(object, rb_intern("usec"), 0));
225
+ string = (const char *)&time_value;
226
+ size = sizeof(time_value);
227
+ } else if (RVAL2CBOOL(rb_obj_is_kind_of(object, rb_cGrnObject))) {
228
+ grn_obj *grn_object;
229
+
230
+ grn_object = RVAL2GRNOBJECT(object, &context);
231
+ id_value = grn_obj_id(context, grn_object);
232
+ string = (const char *)&id_value;
233
+ size = sizeof(id_value);
234
+ } else if (RVAL2CBOOL(rb_obj_is_kind_of(object, rb_cGrnRecord))) {
235
+ id_value = NUM2UINT(rb_funcall(object, rb_intern("id"), 0));
236
+ string = (const char *)&id_value;
237
+ size = sizeof(id_value);
238
+ } else if (RVAL2CBOOL(rb_obj_is_kind_of(object, rb_cGrnRecord))) {
239
+ id_value = NUM2UINT(rb_funcall(object, rb_intern("id"), 0));
240
+ string = (const char *)&id_value;
241
+ size = sizeof(id_value);
242
+ } else {
243
+ rb_raise(rb_eTypeError,
244
+ "bulked object should be one of "
245
+ "[nil, String, Integer, Float, Time, Groonga::Object]: %s",
246
+ rb_grn_inspect(object));
247
+ }
248
+
249
+ if (bulk) {
250
+ GRN_OBJ_INIT(bulk, GRN_BULK, flags);
251
+ } else {
252
+ bulk = grn_obj_open(context, GRN_BULK, 0, flags);
253
+ rb_grn_context_check(context, object);
254
+ }
255
+ GRN_BULK_SET(context, bulk, string, size);
256
+
257
+ return bulk;
258
+ }
259
+
260
+ grn_obj *
261
+ rb_grn_bulk_from_ruby_object_with_type (VALUE object, grn_ctx *context,
262
+ grn_obj *bulk, grn_id type)
263
+ {
264
+ const char *string;
265
+ unsigned int size;
266
+ int32_t int32_value;
267
+ uint32_t uint32_value;
268
+ int64_t int64_value;
269
+ grn_timeval time_value;
270
+ double double_value;
271
+ grn_id range;
272
+ VALUE rb_type;
273
+ grn_obj_flags flags = 0;
274
+ grn_obj *type_object;
275
+
276
+ switch (type) {
277
+ case GRN_DB_INT:
278
+ int32_value = NUM2INT(object);
279
+ string = (const char *)&int32_value;
280
+ size = sizeof(int32_value);
281
+ break;
282
+ case GRN_DB_UINT:
283
+ uint32_value = NUM2UINT(object);
284
+ string = (const char *)&uint32_value;
285
+ size = sizeof(uint32_value);
286
+ break;
287
+ case GRN_DB_INT64:
288
+ int64_value = NUM2LL(object);
289
+ string = (const char *)&int64_value;
290
+ size = sizeof(int64_value);
291
+ break;
292
+ case GRN_DB_FLOAT:
293
+ double_value = NUM2DBL(object);
294
+ string = (const char *)&double_value;
295
+ size = sizeof(double_value);
296
+ break;
297
+ case GRN_DB_TIME:
298
+ time_value.tv_sec = NUM2INT(rb_funcall(object, rb_intern("tv_sec"), 0));
299
+ time_value.tv_usec = NUM2INT(rb_funcall(object, rb_intern("tv_usec"), 0));
300
+ string = (const char *)&time_value;
301
+ size = sizeof(time_value);
302
+ break;
303
+ case GRN_DB_SHORTTEXT:
304
+ case GRN_DB_TEXT:
305
+ case GRN_DB_LONGTEXT:
306
+ string = StringValuePtr(object);
307
+ size = RSTRING_LEN(object);
308
+ range = grn_obj_get_range(context, grn_ctx_get(context, type));
309
+ if (size > range)
310
+ rb_raise(rb_eArgError,
311
+ "string is too large: expected: %u <= %u",
312
+ size, range);
313
+ flags |= GRN_OBJ_DO_SHALLOW_COPY;
314
+ break;
315
+ case GRN_DB_VOID:
316
+ case GRN_DB_DELIMIT:
317
+ case GRN_DB_UNIGRAM:
318
+ case GRN_DB_BIGRAM:
319
+ case GRN_DB_TRIGRAM:
320
+ case GRN_DB_MECAB:
321
+ type_object = grn_ctx_get(context, type);
322
+ rb_type = GRNOBJECT2RVAL(Qnil, context, type_object, RB_GRN_FALSE);
323
+ rb_raise(rb_eArgError,
324
+ "unbulkable type: %s",
325
+ rb_grn_inspect(rb_type));
326
+ break;
327
+ default:
328
+ return RVAL2GRNBULK(object, context, bulk);
329
+ break;
330
+ }
331
+
332
+ if (bulk) {
333
+ GRN_OBJ_INIT(bulk, GRN_BULK, flags);
334
+ } else {
335
+ bulk = grn_obj_open(context, GRN_BULK, flags, GRN_ID_NIL);
336
+ rb_grn_context_check(context, object);
337
+ }
338
+ GRN_BULK_SET(context, bulk, string, size);
339
+
340
+ return bulk;
341
+ }
342
+
343
+
344
+ /* FIXME: maybe not work */
345
+ VALUE
346
+ rb_grn_vector_to_ruby_object (grn_ctx *context, grn_obj *vector)
347
+ {
348
+ VALUE array;
349
+ unsigned int i, n;
350
+
351
+ if (!vector)
352
+ return Qnil;
353
+
354
+ n = grn_vector_size(context, vector);
355
+ array = rb_ary_new2(n);
356
+ for (i = 0; i < n; i++) {
357
+ const char *value;
358
+ unsigned int weight, length;
359
+ grn_id domain;
360
+
361
+ length = grn_vector_get_element(context, vector, i,
362
+ &value, &weight, &domain);
363
+ rb_ary_push(array,
364
+ rb_ary_new3(2,
365
+ rb_str_new(value, length), /* FIXME */
366
+ UINT2NUM(weight)));
367
+ }
368
+
369
+ return array;
370
+ }
371
+
372
+ grn_obj *
373
+ rb_grn_vector_from_ruby_object (VALUE object, grn_ctx *context, grn_obj *vector)
374
+ {
375
+ VALUE *values;
376
+ int i, n;
377
+
378
+ if (vector)
379
+ GRN_OBJ_INIT(vector, GRN_VECTOR, 0);
380
+ else
381
+ vector = grn_obj_open(context, GRN_VECTOR, 0, 0);
382
+
383
+ if (NIL_P(object))
384
+ return vector;
385
+
386
+ n = RARRAY_LEN(object);
387
+ values = RARRAY_PTR(object);
388
+ for (i = 0; i < n; i++) {
389
+ VALUE rb_value;
390
+ grn_id id;
391
+ void *grn_value;
392
+
393
+ rb_value = values[i];
394
+ id = NUM2UINT(rb_value);
395
+ grn_value = &id;
396
+ grn_vector_add_element(context, vector, grn_value, sizeof(id),
397
+ 0, GRN_ID_NIL);
398
+ }
399
+
400
+ return vector;
401
+ }
402
+
403
+ VALUE
404
+ rb_grn_uvector_to_ruby_object (grn_ctx *context, grn_obj *uvector)
405
+ {
406
+ VALUE array;
407
+ grn_id *current, *end;
408
+
409
+ if (!uvector)
410
+ return Qnil;
411
+
412
+ array = rb_ary_new();
413
+ current = (grn_id *)GRN_BULK_HEAD(uvector);
414
+ end = (grn_id *)GRN_BULK_CURR(uvector);
415
+ while (current < end) {
416
+ rb_ary_push(array, UINT2NUM(*current));
417
+ current++;
418
+ }
419
+
420
+ return array;
421
+ }
422
+
423
+ grn_obj *
424
+ rb_grn_uvector_from_ruby_object (VALUE object, grn_ctx *context,
425
+ grn_obj *uvector)
426
+ {
427
+ VALUE *values;
428
+ int i, n;
429
+
430
+ if (uvector)
431
+ GRN_OBJ_INIT(uvector, GRN_UVECTOR, 0);
432
+ else
433
+ uvector = grn_obj_open(context, GRN_UVECTOR, 0, 0);
434
+
435
+ if (NIL_P(object))
436
+ return uvector;
437
+
438
+ n = RARRAY_LEN(object);
439
+ values = RARRAY_PTR(object);
440
+ for (i = 0; i < n; i++) {
441
+ VALUE value;
442
+ grn_id id;
443
+ void *grn_value;
444
+
445
+ value = values[i];
446
+ id = NUM2UINT(value);
447
+ grn_value = &id;
448
+ grn_bulk_write(context, uvector, grn_value, sizeof(id));
449
+ }
450
+
451
+ return uvector;
452
+ }
453
+
454
+ VALUE
455
+ rb_grn_value_to_ruby_object (grn_ctx *context,
456
+ grn_obj *value,
457
+ grn_obj *range,
458
+ VALUE related_object)
459
+ {
460
+ if (!value)
461
+ return Qnil;
462
+
463
+ switch (value->header.type) {
464
+ case GRN_VOID:
465
+ return Qnil;
466
+ break;
467
+ case GRN_BULK:
468
+ if (GRN_BULK_EMPTYP(value))
469
+ return Qnil;
470
+ if (value->header.domain == GRN_ID_NIL && range)
471
+ value->header.domain = grn_obj_id(context, range);
472
+ return GRNBULK2RVAL(context, value, related_object);
473
+ break;
474
+ default:
475
+ rb_raise(rb_eGrnError,
476
+ "unsupported value type: 0x%0x: %s",
477
+ value->header.type, rb_grn_inspect(related_object));
478
+ break;
479
+ }
480
+
481
+ if (!range)
482
+ return GRNOBJECT2RVAL(Qnil, context, value, RB_GRN_FALSE);
483
+
484
+ return Qnil;
485
+ }
486
+
487
+ grn_id
488
+ rb_grn_id_from_ruby_object (VALUE object, grn_ctx *context, grn_obj *table,
489
+ VALUE related_object)
490
+ {
491
+ VALUE rb_id;
492
+
493
+ if (NIL_P(object))
494
+ return Qnil;
495
+
496
+ if (RVAL2CBOOL(rb_obj_is_kind_of(object, rb_cGrnRecord))) {
497
+ VALUE rb_table;
498
+ rb_table = rb_funcall(object, rb_intern("table"), 0);
499
+ if (table && RVAL2GRNOBJECT(rb_table, &context) != table) {
500
+ VALUE rb_expected_table;
501
+
502
+ rb_expected_table =
503
+ GRNOBJECT2RVAL(Qnil, context, table, RB_GRN_FALSE);
504
+ rb_raise(rb_eGrnError,
505
+ "wrong table: expected <%s>: actual <%s>",
506
+ rb_grn_inspect(rb_expected_table),
507
+ rb_grn_inspect(rb_table));
508
+ }
509
+ rb_id = rb_funcall(object, rb_intern("id"), 0);
510
+ } else {
511
+ rb_id = object;
512
+ }
513
+
514
+ if (!RVAL2CBOOL(rb_obj_is_kind_of(rb_id, rb_cInteger)))
515
+ rb_raise(rb_eGrnError,
516
+ "should be unsigned integer or Groogna::Record: <%s>: <%s>",
517
+ rb_grn_inspect(object),
518
+ rb_grn_inspect(related_object));
519
+
520
+ return NUM2UINT(rb_id);
521
+ }
522
+
523
+ VALUE
524
+ rb_grn_key_to_ruby_object (grn_ctx *context, const void *key, int key_size,
525
+ grn_obj *table, VALUE related_object)
526
+ {
527
+ grn_obj bulk;
528
+
529
+ GRN_OBJ_INIT(&bulk, GRN_BULK, GRN_OBJ_DO_SHALLOW_COPY);
530
+ GRN_BULK_SET(context, &bulk, key, key_size);
531
+ bulk.header.domain = table->header.domain;
532
+
533
+ return GRNBULK2RVAL(context, &bulk, related_object);
534
+ }
535
+
536
+ grn_obj *
537
+ rb_grn_key_from_ruby_object (VALUE rb_key, grn_ctx *context,
538
+ grn_obj *key, grn_id domain_id,
539
+ VALUE related_object)
540
+ {
541
+ grn_obj *domain = NULL;
542
+ grn_id id;
543
+
544
+ if (domain_id != GRN_ID_NIL)
545
+ domain = grn_ctx_get(context, domain_id);
546
+
547
+ if (!domain)
548
+ return RVAL2GRNBULK(rb_key, context, key);
549
+
550
+ switch (domain->header.type) {
551
+ case GRN_TYPE:
552
+ return RVAL2GRNBULK_WITH_TYPE(rb_key, context, key, domain_id);
553
+ break;
554
+ case GRN_TABLE_HASH_KEY:
555
+ case GRN_TABLE_PAT_KEY:
556
+ case GRN_TABLE_NO_KEY:
557
+ id = RVAL2GRNID(rb_key, context, domain, related_object);
558
+ break;
559
+ default:
560
+ if (!RVAL2CBOOL(rb_obj_is_kind_of(rb_key, rb_cInteger)))
561
+ rb_raise(rb_eGrnError,
562
+ "should be unsigned integer: <%s>: <%s>",
563
+ rb_grn_inspect(rb_key),
564
+ rb_grn_inspect(related_object));
565
+
566
+ id = NUM2UINT(rb_key);
567
+ break;
568
+ }
569
+
570
+ GRN_OBJ_INIT(key, GRN_BULK, 0);
571
+ GRN_BULK_SET(context, key, &id, sizeof(id));
572
+ return key;
573
+ }
574
+
575
+ void
576
+ rb_grn_init_utils (VALUE mGrn)
577
+ {
578
+ }