groonga 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,30 @@
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
+ VALUE rb_cGrnHashCursor;
22
+
23
+ void
24
+ rb_grn_init_hash_cursor (VALUE mGrn)
25
+ {
26
+ rb_cGrnHashCursor =
27
+ rb_define_class_under(mGrn, "HashCursor", rb_cGrnTableCursor);
28
+
29
+ rb_include_module(rb_cGrnHashCursor, rb_mGrnTableCursorKeySupport);
30
+ }
data/ext/rb-grn-hash.c ADDED
@@ -0,0 +1,40 @@
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) (RVAL2GRNTABLE(object))
22
+
23
+ VALUE rb_cGrnHash;
24
+
25
+ static VALUE
26
+ rb_grn_hash_s_create (int argc, VALUE *argv, VALUE self)
27
+ {
28
+ return rb_grn_table_s_create(argc, argv, self, GRN_TABLE_HASH_KEY);
29
+ }
30
+
31
+ void
32
+ rb_grn_init_hash (VALUE mGrn)
33
+ {
34
+ rb_cGrnHash = rb_define_class_under(mGrn, "Hash", rb_cGrnTable);
35
+
36
+ rb_include_module(rb_cGrnHash, rb_mGrnTableKeySupport);
37
+
38
+ rb_define_singleton_method(rb_cGrnHash, "create",
39
+ rb_grn_hash_s_create, -1);
40
+ }
@@ -0,0 +1,277 @@
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 RVAL2GRNWRAPPER(object) (rb_grn_logger_info_wrapper_from_ruby_object(object))
22
+ #define RVAL2GRNLOGLEVEL(object) (rb_grn_log_level_from_ruby_object(object))
23
+ #define GRNLOGLEVEL2RVAL(level) (rb_grn_log_level_to_ruby_object(level))
24
+
25
+ VALUE cGrnLogger;
26
+
27
+ typedef struct _rb_grn_logger_info_wrapper
28
+ {
29
+ grn_logger_info *logger;
30
+ VALUE handler;
31
+ } rb_grn_logger_info_wrapper;
32
+
33
+ static rb_grn_logger_info_wrapper *
34
+ rb_grn_logger_info_wrapper_from_ruby_object (VALUE object)
35
+ {
36
+ rb_grn_logger_info_wrapper *wrapper;
37
+
38
+ if (NIL_P(object))
39
+ return NULL;
40
+
41
+ if (!RVAL2CBOOL(rb_obj_is_kind_of(object, cGrnLogger))) {
42
+ rb_raise(rb_eTypeError, "not a groonga logger");
43
+ }
44
+
45
+ Data_Get_Struct(object, rb_grn_logger_info_wrapper, wrapper);
46
+ if (!wrapper)
47
+ rb_raise(rb_eTypeError, "groonga logger is NULL");
48
+
49
+ return wrapper;
50
+ }
51
+
52
+ grn_logger_info *
53
+ rb_grn_logger_from_ruby_object (VALUE object)
54
+ {
55
+ rb_grn_logger_info_wrapper *wrapper;
56
+
57
+ wrapper = RVAL2GRNWRAPPER(object);
58
+ if (!wrapper)
59
+ return NULL;
60
+
61
+ return wrapper->logger;
62
+ }
63
+
64
+ static void
65
+ rb_grn_logger_free (void *object)
66
+ {
67
+ rb_grn_logger_info_wrapper *wrapper = object;
68
+
69
+ xfree(wrapper->logger);
70
+ xfree(wrapper);
71
+ }
72
+
73
+ static VALUE
74
+ rb_grn_logger_alloc (VALUE klass)
75
+ {
76
+ return Data_Wrap_Struct(klass, NULL, rb_grn_logger_free, NULL);
77
+ }
78
+
79
+ static grn_log_level
80
+ rb_grn_log_level_from_ruby_object (VALUE rb_level)
81
+ {
82
+ grn_log_level level = GRN_LOG_NONE;
83
+
84
+ if (NIL_P(rb_level)) {
85
+ level = GRN_LOG_DEFAULT_LEVEL;
86
+ } else if (rb_grn_equal_option(rb_level, "none")) {
87
+ level = GRN_LOG_NONE;
88
+ } else if (rb_grn_equal_option(rb_level, "emergency")) {
89
+ level = GRN_LOG_EMERG;
90
+ } else if (rb_grn_equal_option(rb_level, "alert")) {
91
+ level = GRN_LOG_ALERT;
92
+ } else if (rb_grn_equal_option(rb_level, "critical")) {
93
+ level = GRN_LOG_CRIT;
94
+ } else if (rb_grn_equal_option(rb_level, "error")) {
95
+ level = GRN_LOG_ERROR;
96
+ } else if (rb_grn_equal_option(rb_level, "warning")) {
97
+ level = GRN_LOG_WARNING;
98
+ } else if (rb_grn_equal_option(rb_level, "notice")) {
99
+ level = GRN_LOG_NOTICE;
100
+ } else if (rb_grn_equal_option(rb_level, "info")) {
101
+ level = GRN_LOG_INFO;
102
+ } else if (rb_grn_equal_option(rb_level, "debug")) {
103
+ level = GRN_LOG_DEBUG;
104
+ } else if (rb_grn_equal_option(rb_level, "dump")) {
105
+ level = GRN_LOG_DUMP;
106
+ } else {
107
+ rb_raise(rb_eArgError,
108
+ "log level should be one of "
109
+ "[nil, :none, :emergency, :alert, :critical, :error, "
110
+ ":warning, :notice, :info, :debug, :dump]: %s",
111
+ rb_grn_inspect(rb_level));
112
+ }
113
+
114
+ return level;
115
+ }
116
+
117
+ static VALUE
118
+ rb_grn_log_level_to_ruby_object (grn_log_level level)
119
+ {
120
+ VALUE rb_level = Qnil;
121
+
122
+ switch (level) {
123
+ case GRN_LOG_NONE:
124
+ rb_level = RB_GRN_INTERN("none");
125
+ break;
126
+ case GRN_LOG_EMERG:
127
+ rb_level = RB_GRN_INTERN("emergency");
128
+ break;
129
+ case GRN_LOG_ALERT:
130
+ rb_level = RB_GRN_INTERN("alert");
131
+ break;
132
+ case GRN_LOG_CRIT:
133
+ rb_level = RB_GRN_INTERN("critical");
134
+ break;
135
+ case GRN_LOG_ERROR:
136
+ rb_level = RB_GRN_INTERN("error");
137
+ break;
138
+ case GRN_LOG_WARNING:
139
+ rb_level = RB_GRN_INTERN("warning");
140
+ break;
141
+ case GRN_LOG_NOTICE:
142
+ rb_level = RB_GRN_INTERN("notice");
143
+ break;
144
+ case GRN_LOG_INFO:
145
+ rb_level = RB_GRN_INTERN("info");
146
+ break;
147
+ case GRN_LOG_DEBUG:
148
+ rb_level = RB_GRN_INTERN("debug");
149
+ break;
150
+ case GRN_LOG_DUMP:
151
+ rb_level = RB_GRN_INTERN("dump");
152
+ break;
153
+ default:
154
+ rb_level = INT2NUM(level);
155
+ break;
156
+ }
157
+
158
+ return rb_level;
159
+ }
160
+
161
+ static void
162
+ rb_grn_log (int level, const char *time, const char *title,
163
+ const char *message, const char *location, void *func_arg)
164
+ {
165
+ rb_grn_logger_info_wrapper *wrapper = func_arg;
166
+
167
+ rb_funcall(wrapper->handler, rb_intern("call"), 5,
168
+ GRNLOGLEVEL2RVAL(level),
169
+ rb_str_new2(time),
170
+ rb_str_new2(title),
171
+ rb_str_new2(message),
172
+ rb_str_new2(location));
173
+ }
174
+
175
+ static void
176
+ rb_grn_logger_set_handler (VALUE self, VALUE rb_handler)
177
+ {
178
+ rb_grn_logger_info_wrapper *wrapper;
179
+ grn_logger_info *logger;
180
+
181
+ wrapper = RVAL2GRNWRAPPER(self);
182
+ wrapper->handler = rb_handler;
183
+ rb_iv_set(self, "@handler", rb_handler);
184
+
185
+ logger = wrapper->logger;
186
+ if (NIL_P(rb_handler)) {
187
+ logger->func = NULL;
188
+ logger->func_arg = NULL;
189
+ } else {
190
+ logger->func = rb_grn_log;
191
+ logger->func_arg = wrapper;
192
+ }
193
+ }
194
+
195
+ static VALUE
196
+ rb_grn_logger_initialize (int argc, VALUE *argv, VALUE self)
197
+ {
198
+ rb_grn_logger_info_wrapper *wrapper;
199
+ grn_logger_info *logger;
200
+ grn_log_level level;
201
+ int flags = 0;
202
+ VALUE options, rb_level, rb_time, rb_title, rb_message, rb_location;
203
+ VALUE rb_handler;
204
+
205
+ rb_scan_args(argc, argv, "01&", &options, &rb_handler);
206
+
207
+ rb_grn_scan_options(options,
208
+ "level", &rb_level,
209
+ "time", &rb_time,
210
+ "title", &rb_title,
211
+ "message", &rb_message,
212
+ "location", &rb_location,
213
+ NULL);
214
+
215
+ level = RVAL2GRNLOGLEVEL(rb_level);
216
+
217
+ if (NIL_P(rb_time) || RVAL2CBOOL(rb_time))
218
+ flags |= GRN_LOG_TIME;
219
+ if (NIL_P(rb_title) || RVAL2CBOOL(rb_title))
220
+ flags |= GRN_LOG_TITLE;
221
+ if (NIL_P(rb_message) || RVAL2CBOOL(rb_message))
222
+ flags |= GRN_LOG_MESSAGE;
223
+ if (NIL_P(rb_location) || RVAL2CBOOL(rb_location))
224
+ flags |= GRN_LOG_LOCATION;
225
+
226
+ wrapper = ALLOC(rb_grn_logger_info_wrapper);
227
+ logger = ALLOC(grn_logger_info);
228
+ wrapper->logger = logger;
229
+ DATA_PTR(self) = wrapper;
230
+
231
+ logger->max_level = level;
232
+ logger->flags = flags;
233
+ rb_grn_logger_set_handler(self, rb_handler);
234
+
235
+ return Qnil;
236
+ }
237
+
238
+ static VALUE
239
+ rb_grn_logger_s_register (int argc, VALUE *argv, VALUE klass)
240
+ {
241
+ VALUE logger;
242
+ grn_rc rc;
243
+
244
+ logger = rb_funcall2(klass, rb_intern("new"), argc, argv);
245
+ rb_grn_logger_set_handler(logger, rb_block_proc());
246
+ rc = grn_logger_info_set(NULL, RVAL2GRNLOGGER(logger));
247
+ rb_grn_rc_check(rc, logger);
248
+ rb_cv_set(klass, "@@current_logger", logger);
249
+
250
+ return Qnil;
251
+ }
252
+
253
+ static void
254
+ rb_grn_logger_reset (VALUE klass)
255
+ {
256
+ VALUE current_logger;
257
+
258
+ current_logger = rb_cv_get(klass, "@@current_logger");
259
+ if (NIL_P(current_logger))
260
+ return;
261
+
262
+ grn_logger_info_set(NULL, NULL);
263
+ }
264
+
265
+ void
266
+ rb_grn_init_logger (VALUE mGrn)
267
+ {
268
+ cGrnLogger = rb_define_class_under(mGrn, "Logger", rb_cObject);
269
+ rb_define_alloc_func(cGrnLogger, rb_grn_logger_alloc);
270
+
271
+ rb_cv_set(cGrnLogger, "@@current_logger", Qnil);
272
+ rb_define_singleton_method(cGrnLogger, "register",
273
+ rb_grn_logger_s_register, -1);
274
+ rb_set_end_proc(rb_grn_logger_reset, cGrnLogger);
275
+
276
+ rb_define_method(cGrnLogger, "initialize", rb_grn_logger_initialize, -1);
277
+ }
@@ -0,0 +1,985 @@
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
+ /*
20
+ * Document-class: Groonga::Object
21
+ *
22
+ * Ruby/groongaが提供するクラスのベースとなるクラス。
23
+ * Groonga::ContextとGroonga::Logger以外はGroonga::Objectを継
24
+ * 承している。
25
+ */
26
+
27
+ #include "rb-grn.h"
28
+
29
+ #define SELF(object) ((RbGrnObject *)DATA_PTR(object))
30
+
31
+ VALUE rb_cGrnObject;
32
+
33
+ typedef struct _RbGrnObject RbGrnObject;
34
+ struct _RbGrnObject
35
+ {
36
+ grn_ctx *context;
37
+ grn_obj *object;
38
+ rb_grn_boolean owner;
39
+ };
40
+
41
+ grn_obj *
42
+ rb_grn_object_from_ruby_object (VALUE object, grn_ctx **context)
43
+ {
44
+ RbGrnObject *rb_grn_object;
45
+
46
+ if (NIL_P(object))
47
+ return NULL;
48
+
49
+ if (context && *context) {
50
+ grn_obj *grn_object;
51
+ if (RVAL2CBOOL(rb_obj_is_kind_of(object, rb_cString))) {
52
+ grn_object = grn_ctx_lookup(*context,
53
+ StringValuePtr(object),
54
+ RSTRING_LEN(object));
55
+ if (!grn_object)
56
+ rb_raise(rb_eArgError,
57
+ "unregistered groonga object: name: <%s>",
58
+ rb_grn_inspect(object));
59
+ return grn_object;
60
+ } else if (RVAL2CBOOL(rb_obj_is_kind_of(object, rb_cInteger))) {
61
+ grn_object = grn_ctx_get(*context, NUM2UINT(object));
62
+ if (!grn_object)
63
+ rb_raise(rb_eArgError,
64
+ "unregistered groonga object: ID: <%s>",
65
+ rb_grn_inspect(object));
66
+ return grn_object;
67
+ }
68
+ }
69
+
70
+ if (!RVAL2CBOOL(rb_obj_is_kind_of(object, rb_cGrnObject))) {
71
+ rb_raise(rb_eTypeError, "not a groonga object");
72
+ }
73
+
74
+ Data_Get_Struct(object, RbGrnObject, rb_grn_object);
75
+ if (!rb_grn_object)
76
+ rb_raise(rb_eGrnError, "groonga object is NULL");
77
+
78
+ if (context && !*context)
79
+ *context = rb_grn_object->context;
80
+
81
+ return rb_grn_object->object;
82
+ }
83
+
84
+ static void
85
+ rb_rb_grn_object_free (void *object)
86
+ {
87
+ RbGrnObject *rb_grn_object = object;
88
+
89
+ if (rb_grn_object->context && rb_grn_object->object &&
90
+ rb_grn_object->owner) {
91
+ /* FIXME */
92
+ /* grn_obj_close(rb_grn_object->context, rb_grn_object->object); */
93
+ }
94
+
95
+ xfree(rb_grn_object);
96
+ }
97
+
98
+ VALUE
99
+ rb_grn_object_to_ruby_class (grn_obj *object)
100
+ {
101
+ VALUE klass = Qnil;
102
+
103
+ switch (object->header.type) {
104
+ case GRN_DB:
105
+ klass = rb_cGrnDatabase;
106
+ break;
107
+ case GRN_TABLE_HASH_KEY:
108
+ klass = rb_cGrnHash;
109
+ break;
110
+ case GRN_TABLE_PAT_KEY:
111
+ klass = rb_cGrnPatriciaTrie;
112
+ break;
113
+ case GRN_TABLE_NO_KEY:
114
+ klass = rb_cGrnArray;
115
+ break;
116
+ case GRN_TYPE:
117
+ klass = rb_cGrnType;
118
+ break;
119
+ case GRN_ACCESSOR:
120
+ klass = rb_cGrnAccessor;
121
+ break;
122
+ case GRN_PROC:
123
+ klass = rb_cGrnProcedure;
124
+ break;
125
+ case GRN_COLUMN_FIX_SIZE:
126
+ klass = rb_cGrnFixSizeColumn;
127
+ break;
128
+ case GRN_COLUMN_VAR_SIZE:
129
+ klass = rb_cGrnVarSizeColumn;
130
+ break;
131
+ case GRN_COLUMN_INDEX:
132
+ klass = rb_cGrnIndexColumn;
133
+ break;
134
+ default:
135
+ rb_raise(rb_eTypeError,
136
+ "unsupported groonga object type: %d",
137
+ object->header.type);
138
+ break;
139
+ }
140
+
141
+ return klass;
142
+ }
143
+
144
+ VALUE
145
+ rb_grn_object_to_ruby_object (VALUE klass, grn_ctx *context, grn_obj *object,
146
+ rb_grn_boolean owner)
147
+ {
148
+ RbGrnObject *rb_grn_object;
149
+
150
+ if (!object)
151
+ return Qnil;
152
+
153
+ rb_grn_object = ALLOC(RbGrnObject);
154
+ rb_grn_object->context = context;
155
+ rb_grn_object->object = object;
156
+ rb_grn_object->owner = owner;
157
+
158
+ if (NIL_P(klass))
159
+ klass = GRNOBJECT2RCLASS(object);
160
+
161
+ return Data_Wrap_Struct(klass, NULL, rb_rb_grn_object_free, rb_grn_object);
162
+ }
163
+
164
+ VALUE
165
+ rb_grn_object_alloc (VALUE klass)
166
+ {
167
+ return Data_Wrap_Struct(klass, NULL, rb_rb_grn_object_free, NULL);
168
+ }
169
+
170
+ void
171
+ rb_grn_object_initialize (VALUE self, grn_ctx *context, grn_obj *object)
172
+ {
173
+ RbGrnObject *rb_grn_object;
174
+
175
+ rb_grn_object = ALLOC(RbGrnObject);
176
+ DATA_PTR(self) = rb_grn_object;
177
+ rb_grn_object->context = context;
178
+ rb_grn_object->object = object;
179
+ rb_grn_object->owner = RB_GRN_TRUE;
180
+ }
181
+
182
+ /*
183
+ * Document-method: close
184
+ *
185
+ * call-seq:
186
+ * object.close
187
+ *
188
+ * _object_が使用しているリソースを開放する。これ以降_object_を
189
+ * 使うことはできない。
190
+ */
191
+ VALUE
192
+ rb_grn_object_close (VALUE self)
193
+ {
194
+ RbGrnObject *rb_grn_object;
195
+
196
+ rb_grn_object = SELF(self);
197
+ if (rb_grn_object->context && rb_grn_object->object) {
198
+ if (rb_grn_object->owner)
199
+ grn_obj_close(rb_grn_object->context, rb_grn_object->object);
200
+ rb_grn_object->context = NULL;
201
+ rb_grn_object->object = NULL;
202
+ rb_grn_object->owner = RB_GRN_FALSE;
203
+ }
204
+ return Qnil;
205
+ }
206
+
207
+ /*
208
+ * Document-method: closed?
209
+ *
210
+ * call-seq:
211
+ * object.closed? -> true/false
212
+ *
213
+ * _object_が開放済みの場合は+true+を返し、そうでない場合は
214
+ * +false+を返す。
215
+ */
216
+ static VALUE
217
+ rb_grn_object_closed_p (VALUE self)
218
+ {
219
+ RbGrnObject *rb_grn_object;
220
+
221
+ rb_grn_object = SELF(self);
222
+ if (rb_grn_object->context && rb_grn_object->object)
223
+ return Qfalse;
224
+ else
225
+ return Qtrue;
226
+ }
227
+
228
+ VALUE
229
+ rb_grn_object_inspect_object (VALUE inspected, grn_ctx *context, grn_obj *object)
230
+ {
231
+ VALUE rb_object;
232
+
233
+ rb_object = GRNOBJECT2RVAL(Qnil, context, object, RB_GRN_FALSE);
234
+ rb_str_concat(inspected, rb_inspect(rb_object));
235
+
236
+ return inspected;
237
+ }
238
+
239
+ VALUE
240
+ rb_grn_object_inspect_header (VALUE self, VALUE inspected)
241
+ {
242
+ rb_str_cat2(inspected, "#<");
243
+ rb_str_concat(inspected, rb_inspect(rb_obj_class(self)));
244
+ rb_str_cat2(inspected, " ");
245
+
246
+ return inspected;
247
+ }
248
+
249
+ static VALUE
250
+ rb_grn_object_inspect_content_id (VALUE inspected,
251
+ grn_ctx *context, grn_obj *object)
252
+ {
253
+ grn_id id;
254
+
255
+ rb_str_cat2(inspected, "id: <");
256
+ id = grn_obj_id(context, object);
257
+ if (id == GRN_ID_NIL)
258
+ rb_str_cat2(inspected, "nil");
259
+ else
260
+ rb_str_concat(inspected, rb_obj_as_string(UINT2NUM(id)));
261
+ rb_str_cat2(inspected, ">");
262
+
263
+ return inspected;
264
+ }
265
+
266
+ static VALUE
267
+ rb_grn_object_inspect_content_name (VALUE inspected,
268
+ grn_ctx *context, grn_obj *object)
269
+ {
270
+ int name_size;
271
+
272
+ rb_str_cat2(inspected, "name: ");
273
+ name_size = grn_obj_name(context, object, NULL, 0);
274
+ if (name_size == 0) {
275
+ rb_str_cat2(inspected, "(anonymous)");
276
+ } else {
277
+ grn_obj name;
278
+
279
+ GRN_OBJ_INIT(&name, GRN_BULK, 0);
280
+ grn_bulk_space(context, &name, name_size);
281
+ grn_obj_name(context, object, GRN_BULK_HEAD(&name), name_size);
282
+ GRN_BULK_PUTC(context, &name, '\0');
283
+ rb_str_cat2(inspected, "<");
284
+ rb_str_cat2(inspected, GRN_BULK_HEAD(&name));
285
+ rb_str_cat2(inspected, ">");
286
+ }
287
+
288
+ return inspected;
289
+ }
290
+
291
+ static VALUE
292
+ rb_grn_object_inspect_content_path (VALUE inspected,
293
+ grn_ctx *context, grn_obj *object)
294
+ {
295
+ const char *path;
296
+
297
+ rb_str_cat2(inspected, "path: ");
298
+ path = grn_obj_path(context, object);
299
+ if (path) {
300
+ rb_str_cat2(inspected, "<");
301
+ rb_str_cat2(inspected, path);
302
+ rb_str_cat2(inspected, ">");
303
+ } else {
304
+ rb_str_cat2(inspected, "(temporary)");
305
+ }
306
+
307
+ return inspected;
308
+ }
309
+
310
+ static VALUE
311
+ rb_grn_object_inspect_content_domain (VALUE inspected,
312
+ grn_ctx *context, grn_obj *object)
313
+ {
314
+ grn_id domain;
315
+
316
+ rb_str_cat2(inspected, "domain: ");
317
+ domain = object->header.domain;
318
+ rb_str_cat2(inspected, "<");
319
+ if (domain == GRN_ID_NIL) {
320
+ rb_str_cat2(inspected, "nil");
321
+ } else {
322
+ grn_obj *domain_object;
323
+
324
+ domain_object = grn_ctx_get(context, domain);
325
+ if (domain_object) {
326
+ rb_grn_object_inspect_object(inspected, context, domain_object);
327
+ } else {
328
+ rb_str_concat(inspected, rb_obj_as_string(UINT2NUM(domain)));
329
+ }
330
+ }
331
+ rb_str_cat2(inspected, ">");
332
+
333
+ return inspected;
334
+ }
335
+
336
+ static VALUE
337
+ rb_grn_object_inspect_content_range (VALUE inspected,
338
+ grn_ctx *context, grn_obj *object)
339
+ {
340
+ grn_id range;
341
+
342
+ rb_str_cat2(inspected, "range: ");
343
+
344
+ range = grn_obj_get_range(context, object);
345
+ rb_str_cat2(inspected, "<");
346
+ switch (object->header.type) {
347
+ case GRN_TYPE:
348
+ rb_str_concat(inspected, rb_inspect(UINT2NUM(range)));
349
+ break;
350
+ default:
351
+ if (range == GRN_ID_NIL) {
352
+ rb_str_cat2(inspected, "nil");
353
+ } else {
354
+ grn_obj *range_object;
355
+
356
+ range_object = grn_ctx_get(context, range);
357
+ if (range_object) {
358
+ rb_grn_object_inspect_object(inspected, context, range_object);
359
+ } else {
360
+ rb_str_concat(inspected, rb_obj_as_string(UINT2NUM(range)));
361
+ }
362
+ }
363
+ }
364
+ rb_str_cat2(inspected, ">");
365
+
366
+ return inspected;
367
+ }
368
+
369
+ VALUE
370
+ rb_grn_object_inspect_object_content (VALUE inspected,
371
+ grn_ctx *context, grn_obj *object)
372
+ {
373
+ rb_grn_object_inspect_content_id(inspected, context, object);
374
+ rb_str_cat2(inspected, ", ");
375
+ rb_grn_object_inspect_content_name(inspected, context, object);
376
+ rb_str_cat2(inspected, ", ");
377
+ rb_grn_object_inspect_content_path(inspected, context, object);
378
+ rb_str_cat2(inspected, ", ");
379
+ rb_grn_object_inspect_content_domain(inspected, context, object);
380
+ rb_str_cat2(inspected, ", ");
381
+ rb_grn_object_inspect_content_range(inspected, context, object);
382
+
383
+ return inspected;
384
+ }
385
+
386
+ VALUE
387
+ rb_grn_object_inspect_content (VALUE self, VALUE inspected)
388
+ {
389
+ RbGrnObject *rb_grn_object;
390
+ grn_ctx *context;
391
+ grn_obj *object;
392
+
393
+ rb_grn_object = SELF(self);
394
+ context = rb_grn_object->context;
395
+ object = rb_grn_object->object;
396
+
397
+ if (!object)
398
+ return inspected;
399
+
400
+ rb_grn_object_inspect_object_content(inspected, context, object);
401
+
402
+ return inspected;
403
+ }
404
+
405
+ VALUE
406
+ rb_grn_object_inspect_footer (VALUE self, VALUE inspected)
407
+ {
408
+ rb_str_cat2(inspected, ">");
409
+
410
+ return inspected;
411
+ }
412
+
413
+ /*
414
+ * Document-method: inspect
415
+ *
416
+ * call-seq:
417
+ * object.inspect -> 詳細情報
418
+ *
419
+ * _object_の詳細を示した文字列を返す。デバッグ用。
420
+ */
421
+ static VALUE
422
+ rb_grn_object_inspect (VALUE self)
423
+ {
424
+ VALUE inspected;
425
+
426
+ inspected = rb_str_new2("");
427
+ rb_grn_object_inspect_header(self, inspected);
428
+ rb_grn_object_inspect_content(self, inspected);
429
+ rb_grn_object_inspect_footer(self, inspected);
430
+
431
+ return inspected;
432
+ }
433
+
434
+ /*
435
+ * Document-method: id
436
+ *
437
+ * call-seq:
438
+ * object.id -> ID/nil
439
+ *
440
+ * _object_のIDを返す。_object_が#closed?なときやIDがない場合
441
+ * は+nil+を返す。
442
+ */
443
+ static VALUE
444
+ rb_grn_object_get_id (VALUE self)
445
+ {
446
+ RbGrnObject *rb_grn_object;
447
+ grn_id id;
448
+
449
+ rb_grn_object = SELF(self);
450
+ if (!rb_grn_object->object)
451
+ return Qnil;
452
+
453
+ id = grn_obj_id(rb_grn_object->context, rb_grn_object->object);
454
+ if (id == GRN_ID_NIL)
455
+ return Qnil;
456
+ else
457
+ return UINT2NUM(id);
458
+ }
459
+
460
+ /*
461
+ * Document-method: domain
462
+ *
463
+ * call-seq:
464
+ * object.domain -> Groonga::Object/nil
465
+ *
466
+ * _object_の属しているGroonga::Objectを返す。例えば、
467
+ * Groonga::ColumnはGroonga::Tableを返す。属している
468
+ * Groonga::Objectがない場合は+nil+を返す。
469
+ */
470
+ static VALUE
471
+ rb_grn_object_get_domain (VALUE self)
472
+ {
473
+ RbGrnObject *rb_grn_object;
474
+ grn_ctx *context;
475
+ grn_obj *object;
476
+ grn_id domain;
477
+
478
+ rb_grn_object = SELF(self);
479
+ object = rb_grn_object->object;
480
+ if (!object)
481
+ return Qnil;
482
+
483
+ context = rb_grn_object->context;
484
+ domain = object->header.domain;
485
+ if (domain == GRN_ID_NIL) {
486
+ return Qnil;
487
+ } else {
488
+ grn_obj *domain_object;
489
+
490
+ domain_object = grn_ctx_get(context, domain);
491
+ if (domain_object)
492
+ return GRNOBJECT2RVAL(Qnil, context, domain_object, RB_GRN_FALSE);
493
+ else
494
+ return UINT2NUM(domain);
495
+ }
496
+ }
497
+
498
+ /*
499
+ * Document-method: name
500
+ *
501
+ * call-seq:
502
+ * object.name -> 名前/nil
503
+ *
504
+ * _object_の名前を返す。無名オブジェクトの場合は+nil+を返す。
505
+ */
506
+ static VALUE
507
+ rb_grn_object_get_name (VALUE self)
508
+ {
509
+ RbGrnObject *rb_grn_object;
510
+ VALUE rb_name;
511
+ int name_size;
512
+
513
+ rb_grn_object = SELF(self);
514
+ if (!rb_grn_object->object)
515
+ return Qnil;
516
+
517
+ name_size = grn_obj_name(rb_grn_object->context, rb_grn_object->object,
518
+ NULL, 0);
519
+ if (name_size == 0)
520
+ return Qnil;
521
+
522
+ rb_name = rb_str_buf_new(name_size);
523
+ rb_str_set_len(rb_name, name_size);
524
+ grn_obj_name(rb_grn_object->context, rb_grn_object->object,
525
+ RSTRING_PTR(rb_name), name_size);
526
+ return rb_name;
527
+ }
528
+
529
+ /*
530
+ * Document-method: range
531
+ *
532
+ * call-seq:
533
+ * object.range -> Groonga::Object/nil
534
+ *
535
+ * _object_の値がとりうる範囲を示したGroonga::Objectを返す。
536
+ * 例えば、Groonga::Columnの場合は
537
+ * Groonga::Table#define_columnで指定されたGroonga::Typeや
538
+ * Groonga::Tableを返す。
539
+ * 範囲が指定されていないオブジェクトの場合は+nil+を返す。
540
+ */
541
+ static VALUE
542
+ rb_grn_object_get_range (VALUE self)
543
+ {
544
+ RbGrnObject *rb_grn_object;
545
+ grn_ctx *context;
546
+ grn_obj *object;
547
+ grn_id range;
548
+
549
+ rb_grn_object = SELF(self);
550
+ object = rb_grn_object->object;
551
+ if (!object)
552
+ return Qnil;
553
+
554
+ context = rb_grn_object->context;
555
+ range = grn_obj_get_range(context, object);
556
+ if (range == GRN_ID_NIL) {
557
+ return Qnil;
558
+ } else {
559
+ grn_obj *range_object;
560
+
561
+ range_object = grn_ctx_get(context, range);
562
+ if (range_object)
563
+ return GRNOBJECT2RVAL(Qnil, context, range_object, RB_GRN_FALSE);
564
+ else
565
+ return UINT2NUM(range);
566
+ }
567
+ }
568
+
569
+ /*
570
+ * Document-method: ==
571
+ *
572
+ * call-seq:
573
+ * object == other -> true/false
574
+ *
575
+ * _object_と_other_が同じgroongaのオブジェクトなら+true+を返
576
+ * し、そうでなければ+false+を返す。
577
+ */
578
+ static VALUE
579
+ rb_grn_object_equal (VALUE self, VALUE other)
580
+ {
581
+ RbGrnObject *self_rb_grn_object, *other_rb_grn_object;
582
+
583
+ if (self == other)
584
+ return Qtrue;
585
+
586
+ if (!RVAL2CBOOL(rb_funcall(rb_obj_class(self), rb_intern("=="), 1,
587
+ rb_obj_class(other))))
588
+ return Qfalse;
589
+
590
+ self_rb_grn_object = SELF(self);
591
+ other_rb_grn_object = SELF(other);
592
+
593
+ return self_rb_grn_object->object == other_rb_grn_object->object;
594
+ }
595
+
596
+ /*
597
+ * Document-method: []
598
+ *
599
+ * call-seq:
600
+ * object[id] -> 値
601
+ *
602
+ * _object_の_id_に対応する値を返す。
603
+ */
604
+ VALUE
605
+ rb_grn_object_array_reference (VALUE self, VALUE rb_id)
606
+ {
607
+ VALUE exception;
608
+ RbGrnObject *rb_grn_object;
609
+ grn_id id, range_id;
610
+ grn_ctx *context;
611
+ grn_obj *object;
612
+ grn_obj *range;
613
+ unsigned char range_type;
614
+ grn_obj value;
615
+ VALUE rb_value = Qnil;
616
+
617
+ rb_grn_object = SELF(self);
618
+ context = rb_grn_object->context;
619
+ object = rb_grn_object->object;
620
+ if (!object)
621
+ return Qnil;
622
+
623
+ id = NUM2UINT(rb_id);
624
+ range_id = grn_obj_get_range(context, object);
625
+ range = grn_ctx_get(context, range_id);
626
+ range_type = range ? range->header.type : GRN_VOID;
627
+ switch (object->header.type) {
628
+ case GRN_TABLE_HASH_KEY:
629
+ case GRN_TABLE_PAT_KEY:
630
+ case GRN_TABLE_NO_KEY:
631
+ GRN_OBJ_INIT(&value, GRN_BULK, 0);
632
+ break;
633
+ case GRN_TYPE:
634
+ case GRN_ACCESSOR: /* FIXME */
635
+ GRN_OBJ_INIT(&value, GRN_BULK, 0);
636
+ value.header.domain = range_id;
637
+ break;
638
+ case GRN_COLUMN_VAR_SIZE:
639
+ case GRN_COLUMN_FIX_SIZE:
640
+ switch (object->header.flags & GRN_OBJ_COLUMN_TYPE_MASK) {
641
+ case GRN_OBJ_COLUMN_VECTOR:
642
+ GRN_OBJ_INIT(&value, GRN_VECTOR, 0);
643
+ value.header.domain = range_id;
644
+ break;
645
+ case GRN_OBJ_COLUMN_INDEX:
646
+ case GRN_OBJ_COLUMN_SCALAR:
647
+ GRN_OBJ_INIT(&value, GRN_BULK, 0);
648
+ value.header.domain = range_id;
649
+ break;
650
+ default:
651
+ rb_raise(rb_eGrnError, "unsupported column type: %u: %s",
652
+ range_type, rb_grn_inspect(self));
653
+ break;
654
+ }
655
+ break;
656
+ default:
657
+ rb_raise(rb_eGrnError,
658
+ "unsupported type: %s", rb_grn_inspect(self));
659
+ break;
660
+ }
661
+
662
+ grn_obj_get_value(context, object, id, &value);
663
+ exception = rb_grn_context_to_exception(context, self);
664
+ if (NIL_P(exception))
665
+ rb_value = GRNVALUE2RVAL(context, &value, range, self);
666
+ grn_obj_close(context, &value);
667
+ if (!NIL_P(exception))
668
+ rb_exc_raise(exception);
669
+
670
+ return rb_value;
671
+ }
672
+
673
+ static VALUE
674
+ rb_grn_object_set (VALUE self, VALUE rb_id, VALUE rb_value, int flags)
675
+ {
676
+ RbGrnObject *rb_grn_object;
677
+ grn_ctx *context;
678
+ grn_id id;
679
+ grn_obj value;
680
+ grn_rc rc;
681
+ VALUE exception;
682
+
683
+ rb_grn_object = SELF(self);
684
+ if (!rb_grn_object->object)
685
+ return Qnil;
686
+
687
+ context = rb_grn_object->context;
688
+ id = NUM2UINT(rb_id);
689
+ if (RVAL2CBOOL(rb_obj_is_kind_of(rb_value, rb_cArray))) {
690
+ RVAL2GRNVECTOR(rb_value, context, &value);
691
+ } else {
692
+ RVAL2GRNBULK(rb_value, context, &value);
693
+ }
694
+ rc = grn_obj_set_value(context, rb_grn_object->object, id,
695
+ &value, flags);
696
+ exception = rb_grn_context_to_exception(context, self);
697
+ grn_obj_close(context, &value);
698
+ if (!NIL_P(exception))
699
+ rb_exc_raise(exception);
700
+ rb_grn_rc_check(rc, self);
701
+
702
+ return Qnil;
703
+ }
704
+
705
+ /*
706
+ * Document-method: []=
707
+ *
708
+ * call-seq:
709
+ * object[id] = value
710
+ *
711
+ * _object_の_id_に対応する値を設定する。既存の値は上書きさ
712
+ * れる。
713
+ */
714
+ static VALUE
715
+ rb_grn_object_array_set (VALUE self, VALUE rb_id, VALUE rb_value)
716
+ {
717
+ return rb_grn_object_set(self, rb_id, rb_value, GRN_OBJ_SET);
718
+ }
719
+
720
+ /*
721
+ * Document-method: append
722
+ *
723
+ * call-seq:
724
+ * object.append(id, value)
725
+ *
726
+ * _object_の_id_に対応する値に_value_を追加する。
727
+ */
728
+ static VALUE
729
+ rb_grn_object_append_value (VALUE self, VALUE rb_id, VALUE rb_value)
730
+ {
731
+ return rb_grn_object_set(self, rb_id, rb_value, GRN_OBJ_APPEND);
732
+ }
733
+
734
+ /*
735
+ * Document-method: search
736
+ *
737
+ * call-seq:
738
+ * object.search(query, options={}) -> Groonga::Table
739
+ *
740
+ * _object_から_query_に対応するオブジェクトを検索し、見つかっ
741
+ * たオブジェクトのIDがキーになっているGroonga::Tableを返す。
742
+ *
743
+ * 利用可能なオプションは以下の通り。
744
+ *
745
+ * [_:result_]
746
+ * 結果を格納するGroonga::Hash。指定しない場合は新しく
747
+ * Groonga::Hashを生成し、それに結果を格納して返す。
748
+ * [_:operator_]
749
+ * 以下のどれかの値を指定する。+nil+, <tt>"or"</tt>, <tt>"||"</tt>,
750
+ * <tt>"and"</tt>, <tt>"+"</tt>, <tt>"&&"</tt>, <tt>"but"</tt>,
751
+ * <tt>"not"</tt>, <tt>"-"</tt>, <tt>"adjust"</tt>, <tt>">"</tt>。
752
+ * それぞれ以下のようになる。(FIXME: 「以下」)
753
+ * [_:exact_]
754
+ * +true+を指定すると完全一致で検索する
755
+ * [_:longest_common_prefix_]
756
+ * +true+を指定すると_query_と同じ接頭辞をもつエントリのう
757
+ * ち、もっとも長いエントリを検索する
758
+ * [_:suffix_]
759
+ * +true+を指定すると_query_が後方一致するエントリを検索す
760
+ * る
761
+ * [_:prefix_]
762
+ * +true+を指定すると_query_が前方一致するレコードを検索す
763
+ * る
764
+ * [_:near_]
765
+ * +true+を指定すると_query_に指定した複数の語が近傍に含ま
766
+ * れるレコードを検索する
767
+ * [...]
768
+ * ...
769
+ */
770
+ static VALUE
771
+ rb_grn_object_search (int argc, VALUE *argv, VALUE self)
772
+ {
773
+ RbGrnObject *rb_grn_object;
774
+ grn_ctx *context;
775
+ grn_obj *object;
776
+ grn_obj *query;
777
+ grn_obj *result;
778
+ grn_sel_operator operator;
779
+ grn_search_optarg search_options;
780
+ rb_grn_boolean search_options_is_set = RB_GRN_FALSE;
781
+ rb_grn_boolean query_is_created = RB_GRN_FALSE;
782
+ grn_rc rc;
783
+ VALUE rb_query, options, rb_result, rb_operator;
784
+ VALUE rb_exact, rb_longest_common_prefix, rb_suffix, rb_prefix, rb_partial;
785
+ VALUE rb_near, rb_near2, rb_similar, rb_term_extract;
786
+ VALUE rb_similarity_threshold, rb_max_interval, rb_weight_vector;
787
+ VALUE rb_procedure, rb_max_size;
788
+
789
+ rb_grn_object = SELF(self);
790
+ if (!rb_grn_object->object)
791
+ return Qnil;
792
+
793
+ context = rb_grn_object->context;
794
+ object = rb_grn_object->object;
795
+
796
+ rb_scan_args(argc, argv, "11", &rb_query, &options);
797
+
798
+ if (CBOOL2RVAL(rb_obj_is_kind_of(rb_query, rb_cGrnQuery))) {
799
+ grn_query *_query;
800
+ _query = RVAL2GRNQUERY(rb_query);
801
+ query = (grn_obj *)_query;
802
+ } else {
803
+ query_is_created = RB_GRN_TRUE;
804
+ query = RVAL2GRNBULK(rb_query, context, NULL);
805
+ }
806
+
807
+ rb_grn_scan_options(options,
808
+ "result", &rb_result,
809
+ "operator", &rb_operator,
810
+ "exact", &rb_exact,
811
+ "longest_common_prefix", &rb_longest_common_prefix,
812
+ "suffix", &rb_suffix,
813
+ "prefix", &rb_prefix,
814
+ "partial", &rb_partial,
815
+ "near", &rb_near,
816
+ "near2", &rb_near2,
817
+ "similar", &rb_similar,
818
+ "term_extract", &rb_term_extract,
819
+ "similarity_threshold", &rb_similarity_threshold,
820
+ "max_interval", &rb_max_interval,
821
+ "weight_vector", &rb_weight_vector,
822
+ "procedure", &rb_procedure,
823
+ "max_size", &rb_max_size,
824
+ NULL);
825
+
826
+ if (NIL_P(rb_result)) {
827
+ grn_obj *domain = NULL;
828
+
829
+ switch (object->header.type) {
830
+ case GRN_TABLE_PAT_KEY:
831
+ case GRN_TABLE_HASH_KEY:
832
+ domain = object;
833
+ break;
834
+ default:
835
+ domain = grn_ctx_get(context, grn_obj_get_range(context, object));
836
+ break;
837
+ }
838
+ result = grn_table_create(context, NULL, 0, NULL,
839
+ GRN_OBJ_TABLE_HASH_KEY | GRN_OBJ_WITH_SUBREC,
840
+ domain, 0);
841
+ rb_grn_context_check(context, self);
842
+ } else {
843
+ result = RVAL2GRNOBJECT(rb_result, &context);
844
+ }
845
+
846
+ operator = RVAL2GRNSELECTOPERATOR(rb_operator);
847
+
848
+ search_options.flags = 0;
849
+ if (!NIL_P(rb_exact)) {
850
+ search_options_is_set = RB_GRN_TRUE;
851
+ if (RVAL2CBOOL(rb_exact))
852
+ search_options.flags |= GRN_SEARCH_EXACT;
853
+ }
854
+ if (!NIL_P(rb_longest_common_prefix)) {
855
+ search_options_is_set = RB_GRN_TRUE;
856
+ if (RVAL2CBOOL(rb_longest_common_prefix))
857
+ search_options.flags |= GRN_SEARCH_LCP;
858
+ }
859
+ if (!NIL_P(rb_suffix)) {
860
+ search_options_is_set = RB_GRN_TRUE;
861
+ if (RVAL2CBOOL(rb_suffix))
862
+ search_options.flags |= GRN_SEARCH_SUFFIX;
863
+ }
864
+ if (!NIL_P(rb_prefix)) {
865
+ search_options_is_set = RB_GRN_TRUE;
866
+ if (RVAL2CBOOL(rb_prefix))
867
+ search_options.flags |= GRN_SEARCH_PREFIX;
868
+ }
869
+ if (!NIL_P(rb_partial)) {
870
+ search_options_is_set = RB_GRN_TRUE;
871
+ if (RVAL2CBOOL(rb_partial))
872
+ search_options.flags |= GRN_SEARCH_PARTIAL;
873
+ }
874
+ if (!NIL_P(rb_near)) {
875
+ search_options_is_set = RB_GRN_TRUE;
876
+ if (RVAL2CBOOL(rb_near))
877
+ search_options.flags |= GRN_SEARCH_NEAR;
878
+ }
879
+ if (!NIL_P(rb_near2)) {
880
+ search_options_is_set = RB_GRN_TRUE;
881
+ if (RVAL2CBOOL(rb_near2))
882
+ search_options.flags |= GRN_SEARCH_NEAR2;
883
+ }
884
+ if (!NIL_P(rb_similar)) {
885
+ search_options_is_set = RB_GRN_TRUE;
886
+ if (RVAL2CBOOL(rb_similar))
887
+ search_options.flags |= GRN_SEARCH_SIMILAR;
888
+ }
889
+ if (!NIL_P(rb_term_extract)) {
890
+ search_options_is_set = RB_GRN_TRUE;
891
+ if (RVAL2CBOOL(rb_term_extract))
892
+ search_options.flags |= GRN_SEARCH_TERM_EXTRACT;
893
+ }
894
+
895
+ search_options.similarity_threshold = 30; /* FIXME */
896
+ if (!NIL_P(rb_similarity_threshold)) {
897
+ search_options_is_set = RB_GRN_TRUE;
898
+ search_options.similarity_threshold = NUM2INT(rb_similarity_threshold);
899
+ }
900
+
901
+ search_options.max_interval = 5; /* FIXME */
902
+ if (!NIL_P(rb_max_interval)) {
903
+ search_options_is_set = RB_GRN_TRUE;
904
+ search_options.max_interval = NUM2INT(rb_max_interval);
905
+ }
906
+
907
+ search_options.weight_vector = NULL; /* FIXME */
908
+ if (!NIL_P(rb_weight_vector)) {
909
+ search_options_is_set = RB_GRN_TRUE;
910
+ /* FIXME */
911
+ /* search_options.weight_vector = RVAL2INTVECTOR(rb_weight_vector); */
912
+ }
913
+
914
+ search_options.proc = NULL;
915
+ if (!NIL_P(rb_procedure)) {
916
+ search_options_is_set = RB_GRN_TRUE;
917
+ search_options.proc = RVAL2GRNOBJECT(rb_procedure, &context);
918
+ }
919
+
920
+ search_options.max_size = 100; /* FIXME */
921
+ if (!NIL_P(rb_max_size)) {
922
+ search_options_is_set = RB_GRN_TRUE;
923
+ search_options.max_size = INT2NUM(rb_max_size);
924
+ }
925
+
926
+ rc = grn_obj_search(context,
927
+ object,
928
+ query,
929
+ result,
930
+ operator,
931
+ search_options_is_set ? &search_options : NULL);
932
+ if (query_is_created)
933
+ grn_obj_close(context, query);
934
+ rb_grn_rc_check(rc, self);
935
+
936
+ if (NIL_P(rb_result))
937
+ return GRNOBJECT2RVAL(Qnil, context, result, RB_GRN_TRUE);
938
+ else
939
+ return rb_result;
940
+ }
941
+
942
+ static VALUE
943
+ rb_grn_object_remove (VALUE self)
944
+ {
945
+ RbGrnObject *rb_grn_object;
946
+ grn_ctx *context;
947
+ grn_rc rc;
948
+
949
+ rb_grn_object = SELF(self);
950
+ if (!rb_grn_object->object)
951
+ return Qnil;
952
+
953
+ context = rb_grn_object->context;
954
+ rc = grn_obj_remove(context, rb_grn_object->object);
955
+ rb_grn_rc_check(rc, self);
956
+
957
+ return Qnil;
958
+ }
959
+
960
+ void
961
+ rb_grn_init_object (VALUE mGrn)
962
+ {
963
+ rb_cGrnObject = rb_define_class_under(mGrn, "Object", rb_cObject);
964
+ rb_define_alloc_func(rb_cGrnObject, rb_grn_object_alloc);
965
+
966
+ rb_define_method(rb_cGrnObject, "inspect", rb_grn_object_inspect, 0);
967
+
968
+ rb_define_method(rb_cGrnObject, "id", rb_grn_object_get_id, 0);
969
+ rb_define_method(rb_cGrnObject, "domain", rb_grn_object_get_domain, 0);
970
+ rb_define_method(rb_cGrnObject, "name", rb_grn_object_get_name, 0);
971
+ rb_define_method(rb_cGrnObject, "range", rb_grn_object_get_range, 0);
972
+
973
+ rb_define_method(rb_cGrnObject, "==", rb_grn_object_equal, 1);
974
+
975
+ rb_define_method(rb_cGrnObject, "close", rb_grn_object_close, 0);
976
+ rb_define_method(rb_cGrnObject, "closed?", rb_grn_object_closed_p, 0);
977
+
978
+ rb_define_method(rb_cGrnObject, "[]", rb_grn_object_array_reference, 1);
979
+ rb_define_method(rb_cGrnObject, "[]=", rb_grn_object_array_set, 2);
980
+ rb_define_method(rb_cGrnObject, "append", rb_grn_object_append_value, 2);
981
+
982
+ rb_define_method(rb_cGrnObject, "search", rb_grn_object_search, -1);
983
+
984
+ rb_define_method(rb_cGrnObject, "remove", rb_grn_object_remove, 0);
985
+ }