rroonga 0.9.2-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (199) hide show
  1. data/AUTHORS +5 -0
  2. data/NEWS.ja.rdoc +114 -0
  3. data/NEWS.rdoc +116 -0
  4. data/README.ja.rdoc +65 -0
  5. data/README.rdoc +66 -0
  6. data/Rakefile +206 -0
  7. data/benchmark/common.rb +49 -0
  8. data/benchmark/read-write-many-small-items.rb +144 -0
  9. data/benchmark/write-many-small-items.rb +135 -0
  10. data/example/bookmark.rb +161 -0
  11. data/example/index-html.rb +89 -0
  12. data/example/search/config.ru +230 -0
  13. data/example/search/public/css/groonga.css +122 -0
  14. data/ext/.gitignore +2 -0
  15. data/ext/groonga/extconf.rb +93 -0
  16. data/ext/groonga/rb-grn-accessor.c +52 -0
  17. data/ext/groonga/rb-grn-array-cursor.c +36 -0
  18. data/ext/groonga/rb-grn-array.c +210 -0
  19. data/ext/groonga/rb-grn-column.c +573 -0
  20. data/ext/groonga/rb-grn-context.c +662 -0
  21. data/ext/groonga/rb-grn-database.c +472 -0
  22. data/ext/groonga/rb-grn-encoding-support.c +64 -0
  23. data/ext/groonga/rb-grn-encoding.c +257 -0
  24. data/ext/groonga/rb-grn-exception.c +1110 -0
  25. data/ext/groonga/rb-grn-expression-builder.c +75 -0
  26. data/ext/groonga/rb-grn-expression.c +731 -0
  27. data/ext/groonga/rb-grn-fix-size-column.c +166 -0
  28. data/ext/groonga/rb-grn-hash-cursor.c +38 -0
  29. data/ext/groonga/rb-grn-hash.c +294 -0
  30. data/ext/groonga/rb-grn-index-column.c +488 -0
  31. data/ext/groonga/rb-grn-logger.c +504 -0
  32. data/ext/groonga/rb-grn-object.c +1369 -0
  33. data/ext/groonga/rb-grn-operation.c +198 -0
  34. data/ext/groonga/rb-grn-patricia-trie-cursor.c +39 -0
  35. data/ext/groonga/rb-grn-patricia-trie.c +488 -0
  36. data/ext/groonga/rb-grn-procedure.c +52 -0
  37. data/ext/groonga/rb-grn-query.c +260 -0
  38. data/ext/groonga/rb-grn-record.c +40 -0
  39. data/ext/groonga/rb-grn-snippet.c +334 -0
  40. data/ext/groonga/rb-grn-table-cursor-key-support.c +69 -0
  41. data/ext/groonga/rb-grn-table-cursor.c +247 -0
  42. data/ext/groonga/rb-grn-table-key-support.c +714 -0
  43. data/ext/groonga/rb-grn-table.c +1977 -0
  44. data/ext/groonga/rb-grn-type.c +181 -0
  45. data/ext/groonga/rb-grn-utils.c +769 -0
  46. data/ext/groonga/rb-grn-variable-size-column.c +36 -0
  47. data/ext/groonga/rb-grn-variable.c +108 -0
  48. data/ext/groonga/rb-grn-view-accessor.c +53 -0
  49. data/ext/groonga/rb-grn-view-cursor.c +35 -0
  50. data/ext/groonga/rb-grn-view-record.c +41 -0
  51. data/ext/groonga/rb-grn-view.c +421 -0
  52. data/ext/groonga/rb-grn.h +698 -0
  53. data/ext/groonga/rb-groonga.c +107 -0
  54. data/extconf.rb +130 -0
  55. data/html/bar.svg +153 -0
  56. data/html/developer.html +117 -0
  57. data/html/developer.svg +469 -0
  58. data/html/download.svg +253 -0
  59. data/html/favicon.ico +0 -0
  60. data/html/favicon.xcf +0 -0
  61. data/html/footer.html.erb +28 -0
  62. data/html/head.html.erb +4 -0
  63. data/html/header.html.erb +17 -0
  64. data/html/index.html +147 -0
  65. data/html/install.svg +636 -0
  66. data/html/logo.xcf +0 -0
  67. data/html/ranguba.css +250 -0
  68. data/html/tutorial.svg +559 -0
  69. data/lib/1.8/groonga.so +0 -0
  70. data/lib/1.9/groonga.so +0 -0
  71. data/lib/groonga.rb +90 -0
  72. data/lib/groonga/context.rb +184 -0
  73. data/lib/groonga/expression-builder.rb +324 -0
  74. data/lib/groonga/patricia-trie.rb +85 -0
  75. data/lib/groonga/record.rb +311 -0
  76. data/lib/groonga/schema.rb +1191 -0
  77. data/lib/groonga/view-record.rb +56 -0
  78. data/license/GPL +340 -0
  79. data/license/LGPL +504 -0
  80. data/license/RUBY +59 -0
  81. data/misc/grnop2ruby.rb +49 -0
  82. data/pkg-config.rb +333 -0
  83. data/rroonga-build.rb +57 -0
  84. data/test-unit/Rakefile +40 -0
  85. data/test-unit/TODO +5 -0
  86. data/test-unit/bin/testrb +5 -0
  87. data/test-unit/html/classic.html +15 -0
  88. data/test-unit/html/index.html +25 -0
  89. data/test-unit/html/index.html.ja +27 -0
  90. data/test-unit/lib/test/unit.rb +323 -0
  91. data/test-unit/lib/test/unit/assertionfailederror.rb +25 -0
  92. data/test-unit/lib/test/unit/assertions.rb +1230 -0
  93. data/test-unit/lib/test/unit/attribute.rb +125 -0
  94. data/test-unit/lib/test/unit/autorunner.rb +360 -0
  95. data/test-unit/lib/test/unit/collector.rb +36 -0
  96. data/test-unit/lib/test/unit/collector/descendant.rb +23 -0
  97. data/test-unit/lib/test/unit/collector/dir.rb +108 -0
  98. data/test-unit/lib/test/unit/collector/load.rb +144 -0
  99. data/test-unit/lib/test/unit/collector/objectspace.rb +34 -0
  100. data/test-unit/lib/test/unit/color-scheme.rb +102 -0
  101. data/test-unit/lib/test/unit/color.rb +96 -0
  102. data/test-unit/lib/test/unit/diff.rb +724 -0
  103. data/test-unit/lib/test/unit/error.rb +130 -0
  104. data/test-unit/lib/test/unit/exceptionhandler.rb +39 -0
  105. data/test-unit/lib/test/unit/failure.rb +136 -0
  106. data/test-unit/lib/test/unit/fixture.rb +176 -0
  107. data/test-unit/lib/test/unit/notification.rb +129 -0
  108. data/test-unit/lib/test/unit/omission.rb +191 -0
  109. data/test-unit/lib/test/unit/pending.rb +150 -0
  110. data/test-unit/lib/test/unit/priority.rb +180 -0
  111. data/test-unit/lib/test/unit/runner/console.rb +52 -0
  112. data/test-unit/lib/test/unit/runner/emacs.rb +8 -0
  113. data/test-unit/lib/test/unit/runner/tap.rb +8 -0
  114. data/test-unit/lib/test/unit/testcase.rb +476 -0
  115. data/test-unit/lib/test/unit/testresult.rb +89 -0
  116. data/test-unit/lib/test/unit/testsuite.rb +110 -0
  117. data/test-unit/lib/test/unit/ui/console/outputlevel.rb +14 -0
  118. data/test-unit/lib/test/unit/ui/console/testrunner.rb +466 -0
  119. data/test-unit/lib/test/unit/ui/emacs/testrunner.rb +63 -0
  120. data/test-unit/lib/test/unit/ui/tap/testrunner.rb +92 -0
  121. data/test-unit/lib/test/unit/ui/testrunner.rb +28 -0
  122. data/test-unit/lib/test/unit/ui/testrunnermediator.rb +77 -0
  123. data/test-unit/lib/test/unit/ui/testrunnerutilities.rb +41 -0
  124. data/test-unit/lib/test/unit/util/backtracefilter.rb +41 -0
  125. data/test-unit/lib/test/unit/util/method-owner-finder.rb +28 -0
  126. data/test-unit/lib/test/unit/util/observable.rb +90 -0
  127. data/test-unit/lib/test/unit/util/procwrapper.rb +48 -0
  128. data/test-unit/lib/test/unit/version.rb +7 -0
  129. data/test-unit/sample/adder.rb +13 -0
  130. data/test-unit/sample/subtracter.rb +12 -0
  131. data/test-unit/sample/test_adder.rb +20 -0
  132. data/test-unit/sample/test_subtracter.rb +20 -0
  133. data/test-unit/sample/test_user.rb +23 -0
  134. data/test-unit/test/collector/test-descendant.rb +133 -0
  135. data/test-unit/test/collector/test-load.rb +442 -0
  136. data/test-unit/test/collector/test_dir.rb +406 -0
  137. data/test-unit/test/collector/test_objectspace.rb +100 -0
  138. data/test-unit/test/run-test.rb +15 -0
  139. data/test-unit/test/test-attribute.rb +86 -0
  140. data/test-unit/test/test-color-scheme.rb +67 -0
  141. data/test-unit/test/test-color.rb +47 -0
  142. data/test-unit/test/test-diff.rb +518 -0
  143. data/test-unit/test/test-emacs-runner.rb +60 -0
  144. data/test-unit/test/test-fixture.rb +287 -0
  145. data/test-unit/test/test-notification.rb +33 -0
  146. data/test-unit/test/test-omission.rb +81 -0
  147. data/test-unit/test/test-pending.rb +70 -0
  148. data/test-unit/test/test-priority.rb +119 -0
  149. data/test-unit/test/test-testcase.rb +544 -0
  150. data/test-unit/test/test_assertions.rb +1151 -0
  151. data/test-unit/test/test_error.rb +26 -0
  152. data/test-unit/test/test_failure.rb +33 -0
  153. data/test-unit/test/test_testresult.rb +113 -0
  154. data/test-unit/test/test_testsuite.rb +129 -0
  155. data/test-unit/test/testunit-test-util.rb +14 -0
  156. data/test-unit/test/ui/test_testrunmediator.rb +20 -0
  157. data/test-unit/test/util/test-method-owner-finder.rb +38 -0
  158. data/test-unit/test/util/test_backtracefilter.rb +41 -0
  159. data/test-unit/test/util/test_observable.rb +102 -0
  160. data/test-unit/test/util/test_procwrapper.rb +36 -0
  161. data/test/.gitignore +1 -0
  162. data/test/groonga-test-utils.rb +134 -0
  163. data/test/run-test.rb +58 -0
  164. data/test/test-array.rb +90 -0
  165. data/test/test-column.rb +316 -0
  166. data/test/test-context-select.rb +93 -0
  167. data/test/test-context.rb +73 -0
  168. data/test/test-database.rb +113 -0
  169. data/test/test-encoding.rb +33 -0
  170. data/test/test-exception.rb +93 -0
  171. data/test/test-expression-builder.rb +217 -0
  172. data/test/test-expression.rb +134 -0
  173. data/test/test-fix-size-column.rb +65 -0
  174. data/test/test-gqtp.rb +72 -0
  175. data/test/test-hash.rb +305 -0
  176. data/test/test-index-column.rb +81 -0
  177. data/test/test-logger.rb +37 -0
  178. data/test/test-patricia-trie.rb +205 -0
  179. data/test/test-procedure.rb +37 -0
  180. data/test/test-query.rb +22 -0
  181. data/test/test-record.rb +243 -0
  182. data/test/test-remote.rb +54 -0
  183. data/test/test-schema-view.rb +90 -0
  184. data/test/test-schema.rb +459 -0
  185. data/test/test-snippet.rb +130 -0
  186. data/test/test-table-cursor.rb +153 -0
  187. data/test/test-table-offset-and-limit.rb +102 -0
  188. data/test/test-table-select-normalize.rb +53 -0
  189. data/test/test-table-select.rb +150 -0
  190. data/test/test-table.rb +594 -0
  191. data/test/test-type.rb +71 -0
  192. data/test/test-variable-size-column.rb +98 -0
  193. data/test/test-variable.rb +28 -0
  194. data/test/test-vector-column.rb +76 -0
  195. data/test/test-version.rb +31 -0
  196. data/test/test-view.rb +72 -0
  197. data/text/TUTORIAL.ja.rdoc +392 -0
  198. data/text/expression.rdoc +284 -0
  199. metadata +276 -0
@@ -0,0 +1,52 @@
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) (RVAL2GRNACCESSOR(object))
22
+
23
+ VALUE rb_cGrnAccessor;
24
+
25
+ grn_obj *
26
+ rb_grn_accessor_from_ruby_object (VALUE object)
27
+ {
28
+ if (!RVAL2CBOOL(rb_obj_is_kind_of(object, rb_cGrnAccessor))) {
29
+ rb_raise(rb_eTypeError, "not a groonga accessor");
30
+ }
31
+
32
+ return RVAL2GRNOBJECT(object, NULL);
33
+ }
34
+
35
+ VALUE
36
+ rb_grn_accessor_to_ruby_object (grn_ctx *context, grn_obj *table,
37
+ rb_grn_boolean owner)
38
+ {
39
+ return GRNOBJECT2RVAL(rb_cGrnAccessor, context, table, owner);
40
+ }
41
+
42
+ /*
43
+ * Document-class: Groonga::Accessor < Groonga::Object
44
+ *
45
+ * キー、値、スコアなど種々の値へのアクセスをカプセル化した
46
+ * オブジェクト。Groonga::Table#columnで取得できる。
47
+ */
48
+ void
49
+ rb_grn_init_accessor (VALUE mGrn)
50
+ {
51
+ rb_cGrnAccessor = rb_define_class_under(mGrn, "Accessor", rb_cGrnObject);
52
+ }
@@ -0,0 +1,36 @@
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_cGrnArrayCursor;
22
+
23
+ /*
24
+ * Document-class: Groonga::ArrayCursor < Groonga::TableCursor
25
+ *
26
+ * Groonga::Arrayに登録されているレコードを順番に取り出すため
27
+ * のオブジェクト。利用できるメソッドはGroonga::TableCursorを
28
+ * 参照。
29
+ */
30
+
31
+ void
32
+ rb_grn_init_array_cursor (VALUE mGrn)
33
+ {
34
+ rb_cGrnArrayCursor =
35
+ rb_define_class_under(mGrn, "ArrayCursor", rb_cGrnTableCursor);
36
+ }
@@ -0,0 +1,210 @@
1
+ /* -*- c-file-style: "ruby" -*- */
2
+ /*
3
+ Copyright (C) 2009-2010 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, context) (RVAL2GRNTABLE(object, context))
22
+
23
+ VALUE rb_cGrnArray;
24
+
25
+ /*
26
+ * Document-class: Groonga::Array < Groonga::Table
27
+ *
28
+ * 各レコードがキーに関連付けられていないテーブル。レコードは
29
+ * IDで識別する。
30
+ */
31
+
32
+ /*
33
+ * call-seq:
34
+ * Groonga::Array.create(options={}) -> Groonga::Array
35
+ * Groonga::Array.create(options={}) {|table| ... }
36
+ *
37
+ * キーのないテーブルを生成する。ブロックを指定すると、そのブ
38
+ * ロックに生成したテーブルが渡され、ブロックを抜けると自動的
39
+ * にテーブルが破棄される。
40
+ *
41
+ * _options_に指定可能な値は以下の通り。
42
+ *
43
+ * [+:context+]
44
+ * テーブルが利用するGroonga::Context。省略すると
45
+ * Groonga::Context.defaultを用いる。
46
+ *
47
+ * [+:name+]
48
+ * テーブルの名前。名前をつけると、Groonga::Context#[]に名
49
+ * 前を指定してテーブルを取得することができる。省略すると
50
+ * 無名テーブルになり、テーブルIDでのみ取得できる。
51
+ *
52
+ * [+:path+]
53
+ * テーブルを保存するパス。パスを指定すると永続テーブルとな
54
+ * り、プロセス終了後もレコードは保持される。次回起動時に
55
+ * Groonga::Context#[]で保存されたレコードを利用することが
56
+ * できる。省略すると一時テーブルになり、プロセスが終了する
57
+ * とレコードは破棄される。
58
+ *
59
+ * [+:persistent+]
60
+ * +true+を指定すると永続テーブルとなる。+path+を省略した
61
+ * 場合は自動的にパスが付加される。+:context+で指定した
62
+ * Groonga::Contextに結びついているデータベースが一時デー
63
+ * タベースの場合は例外が発生する。
64
+ *
65
+ * [+:value_type+]
66
+ * 値の型を指定する。省略すると値のための領域を確保しない。
67
+ * 値を保存したい場合は必ず指定すること。
68
+ *
69
+ * 参考: Groonga::Type.new
70
+ *
71
+ * [+:sub_records+]
72
+ * +true+を指定すると#groupでグループ化したときに、
73
+ * Groonga::Record#n_sub_recordsでグループに含まれるレコー
74
+ * ドの件数を取得できる。
75
+ *
76
+ * 使用例:
77
+ *
78
+ * 無名一時テーブルを生成する。
79
+ * Groonga::Array.create
80
+ *
81
+ * 無名永続テーブルを生成する。
82
+ * Groonga::Array.create(:path => "/tmp/array.grn")
83
+ *
84
+ * 名前付き永続テーブルを生成する。ただし、ファイル名は気に
85
+ * しない。
86
+ * Groonga::Array.create(:name => "<bookmarks>",
87
+ * :persistent => true)
88
+ *
89
+ * それぞれのレコードに512バイトの値を格納できる無名一時テー
90
+ * ブルを生成する。
91
+ * Groonga::Array.create(:value => 512)
92
+ */
93
+ static VALUE
94
+ rb_grn_array_s_create (int argc, VALUE *argv, VALUE klass)
95
+ {
96
+ grn_ctx *context = NULL;
97
+ grn_obj *value_type = NULL, *table;
98
+ const char *name = NULL, *path = NULL;
99
+ unsigned name_size = 0;
100
+ grn_obj_flags flags = GRN_TABLE_NO_KEY;
101
+ VALUE rb_table;
102
+ VALUE options, rb_context, rb_name, rb_path, rb_persistent;
103
+ VALUE rb_value_type, rb_sub_records;
104
+
105
+ rb_scan_args(argc, argv, "01", &options);
106
+
107
+ rb_grn_scan_options(options,
108
+ "context", &rb_context,
109
+ "name", &rb_name,
110
+ "path", &rb_path,
111
+ "persistent", &rb_persistent,
112
+ "value_type", &rb_value_type,
113
+ "sub_records", &rb_sub_records,
114
+ NULL);
115
+
116
+ context = rb_grn_context_ensure(&rb_context);
117
+
118
+ if (!NIL_P(rb_name)) {
119
+ name = StringValuePtr(rb_name);
120
+ name_size = RSTRING_LEN(rb_name);
121
+ flags |= GRN_OBJ_PERSISTENT;
122
+ }
123
+
124
+ if (!NIL_P(rb_path)) {
125
+ path = StringValueCStr(rb_path);
126
+ flags |= GRN_OBJ_PERSISTENT;
127
+ }
128
+
129
+ if (RVAL2CBOOL(rb_persistent))
130
+ flags |= GRN_OBJ_PERSISTENT;
131
+
132
+ if (!NIL_P(rb_value_type))
133
+ value_type = RVAL2GRNOBJECT(rb_value_type, &context);
134
+
135
+ if (RVAL2CBOOL(rb_sub_records))
136
+ flags |= GRN_OBJ_WITH_SUBREC;
137
+
138
+ table = grn_table_create(context, name, name_size, path,
139
+ flags, NULL, value_type);
140
+ if (!table)
141
+ rb_grn_context_check(context, rb_ary_new4(argc, argv));
142
+ rb_table = GRNOBJECT2RVAL(klass, context, table, RB_GRN_TRUE);
143
+ rb_grn_context_check(context, rb_table);
144
+ rb_iv_set(rb_table, "@context", rb_context);
145
+
146
+ if (rb_block_given_p())
147
+ return rb_ensure(rb_yield, rb_table, rb_grn_object_close, rb_table);
148
+ else
149
+ return rb_table;
150
+ }
151
+
152
+ /*
153
+ * call-seq:
154
+ * array.add(values=nil) -> Groonga::Recordまたはnil
155
+ *
156
+ * レコード追加し、追加したレコードを返す。レコードの追加に失
157
+ * 敗した場合は+nil+を返す。
158
+ *
159
+ * _values_にはレコードのカラムに設定する値を指定する。省略
160
+ * した場合または+nil+を指定した場合はカラムは設定しない。カ
161
+ * ラムの値は<tt>{:カラム名1 => 値1, :カラム名2 => 値2,
162
+ * ...}</tt>と指定する。
163
+ *
164
+ * 使用例では、以下のようなユーザを格納するGroonga::Arrayが
165
+ * 定義されているものとする。
166
+ * users = Groonga::Array.create(:name => "Users")
167
+ * users.define_column("name", "ShortText")
168
+ * users.define_column("uri", "ShortText")
169
+ *
170
+ * ユーザを追加する。
171
+ * user = users.add
172
+ *
173
+ * daijiroユーザを追加する。
174
+ * daijiro = users.add(:name => "daijiro")
175
+ *
176
+ * gunyara-kunユーザを追加する。
177
+ * gunyara_kun = users.add(:name => "gunyara-kun",
178
+ * :uri => "http://d.hatena.ne.jp/tasukuchan/")
179
+ */
180
+ static VALUE
181
+ rb_grn_array_add (int argc, VALUE *argv, VALUE self)
182
+ {
183
+ grn_ctx *context = NULL;
184
+ grn_obj *table;
185
+ grn_id id;
186
+ VALUE values;
187
+
188
+ rb_scan_args(argc, argv, "01", &values);
189
+
190
+ table = SELF(self, &context);
191
+
192
+ id = grn_table_add(context, table, NULL, 0, NULL);
193
+ rb_grn_context_check(context, self);
194
+
195
+ if (GRN_ID_NIL == id)
196
+ return Qnil;
197
+ else
198
+ return rb_grn_record_new(self, id, values);
199
+ }
200
+
201
+ void
202
+ rb_grn_init_array (VALUE mGrn)
203
+ {
204
+ rb_cGrnArray = rb_define_class_under(mGrn, "Array", rb_cGrnTable);
205
+
206
+ rb_define_singleton_method(rb_cGrnArray, "create",
207
+ rb_grn_array_s_create, -1);
208
+
209
+ rb_define_method(rb_cGrnArray, "add", rb_grn_array_add, -1);
210
+ }
@@ -0,0 +1,573 @@
1
+ /* -*- c-file-style: "ruby" -*- */
2
+ /* vim: set sts=4 sw=4 ts=8 noet: */
3
+ /*
4
+ Copyright (C) 2009-2010 Kouhei Sutou <kou@clear-code.com>
5
+
6
+ This library is free software; you can redistribute it and/or
7
+ modify it under the terms of the GNU Lesser General Public
8
+ License version 2.1 as published by the Free Software Foundation.
9
+
10
+ This library is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ Lesser General Public License for more details.
14
+
15
+ You should have received a copy of the GNU Lesser General Public
16
+ License along with this library; if not, write to the Free Software
17
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
+ */
19
+
20
+ #include "rb-grn.h"
21
+
22
+ #define SELF(object) ((RbGrnColumn *)DATA_PTR(object))
23
+
24
+ VALUE rb_cGrnColumn;
25
+
26
+ /*
27
+ * Document-class: Groonga::Column < Groonga::Object
28
+ *
29
+ * テーブルに情報を付加するためのオブジェクト。テーブルに複
30
+ * 数のカラムを定義することによりレコード毎に複数の情報を付
31
+ * 加することができる。
32
+ *
33
+ * カラムには大きく分けて3種類ある。
34
+ * [Groonga::FixSizeColumn]
35
+ * 固定長のデータを格納するカラム。
36
+ * [Groonga::VariableSizeColumn]
37
+ * 可変長のデータを格納するカラム。
38
+ * [Groonga::IndexColumn]
39
+ * 転置インデックスを格納するカラム。全文検索や参照元レコー
40
+ * ドの検索を行う場合はこのカラムを使用する。
41
+ *
42
+ * 固定長データ用カラム・可変長データ用カラムは1つのデータだ
43
+ * けを格納するか複数のデータを格納するかを選ぶことができる。
44
+ * 1つのデータの場合はスカラ値、複数のデータの場合はスカラー
45
+ * 値を格納するという。
46
+ *
47
+ * カラムは名前を持ち、1つのテーブルでは同じカラム名を持つカ
48
+ * ラムを複数定義することはできない。
49
+ */
50
+
51
+ grn_obj *
52
+ rb_grn_column_from_ruby_object (VALUE object, grn_ctx **context)
53
+ {
54
+ if (!RVAL2CBOOL(rb_obj_is_kind_of(object, rb_cGrnColumn))) {
55
+ rb_raise(rb_eTypeError, "not a groonga column");
56
+ }
57
+
58
+ return RVAL2GRNOBJECT(object, context);
59
+ }
60
+
61
+ VALUE
62
+ rb_grn_column_to_ruby_object (VALUE klass, grn_ctx *context, grn_obj *column,
63
+ rb_grn_boolean owner)
64
+ {
65
+ return GRNOBJECT2RVAL(klass, context, column, owner);
66
+ }
67
+
68
+ void
69
+ rb_grn_column_bind (RbGrnColumn *rb_column,
70
+ grn_ctx *context, grn_obj *column)
71
+ {
72
+ RbGrnObject *rb_grn_object;
73
+
74
+ rb_grn_object = RB_GRN_OBJECT(rb_column);
75
+ rb_grn_named_object_bind(RB_GRN_NAMED_OBJECT(rb_column), context, column);
76
+ rb_column->value = grn_obj_open(context, GRN_BULK, 0,
77
+ rb_grn_object->range_id);
78
+ }
79
+
80
+ void
81
+ rb_grn_column_finalizer (grn_ctx *context, grn_obj *grn_object,
82
+ RbGrnColumn *rb_column)
83
+ {
84
+ rb_grn_named_object_finalizer(context, grn_object,
85
+ RB_GRN_NAMED_OBJECT(rb_column));
86
+ if (context && rb_column->value)
87
+ grn_obj_unlink(context, rb_column->value);
88
+ rb_column->value = NULL;
89
+ }
90
+
91
+ void
92
+ rb_grn_column_deconstruct (RbGrnColumn *rb_column,
93
+ grn_obj **column,
94
+ grn_ctx **context,
95
+ grn_id *domain_id,
96
+ grn_obj **domain,
97
+ grn_obj **value,
98
+ grn_id *range_id,
99
+ grn_obj **range)
100
+ {
101
+ RbGrnObject *rb_grn_object;
102
+
103
+ rb_grn_object = RB_GRN_OBJECT(rb_column);
104
+ rb_grn_object_deconstruct(rb_grn_object, column, context,
105
+ domain_id, domain,
106
+ range_id, range);
107
+
108
+ if (value)
109
+ *value = rb_column->value;
110
+ }
111
+
112
+ /*
113
+ * call-seq:
114
+ * column.table -> Groonga::Table
115
+ *
116
+ * カラムが所属するテーブルを返す。
117
+ */
118
+ static VALUE
119
+ rb_grn_column_get_table (VALUE self)
120
+ {
121
+ grn_ctx *context = NULL;
122
+ grn_obj *column;
123
+ grn_obj *table;
124
+
125
+ rb_grn_object_deconstruct((RbGrnObject *)(SELF(self)), &column, &context,
126
+ NULL, NULL,
127
+ NULL, NULL);
128
+ table = grn_column_table(context, column);
129
+ rb_grn_context_check(context, self);
130
+
131
+ return GRNOBJECT2RVAL(Qnil, context, table, RB_GRN_FALSE);
132
+ }
133
+
134
+ /*
135
+ * call-seq:
136
+ * column.local_name
137
+ *
138
+ * テーブル名を除いたカラム名を返す。
139
+ *
140
+ * items = Groonga::Array.create(:name => "Items")
141
+ * title = items.define_column("title", "ShortText")
142
+ * title.name # => "Items.title"
143
+ * title.local_name # => "title"
144
+ */
145
+ static VALUE
146
+ rb_grn_column_get_local_name (VALUE self)
147
+ {
148
+ RbGrnColumn *rb_grn_column;
149
+ grn_ctx *context = NULL;
150
+ grn_obj *column;
151
+ VALUE rb_name;
152
+ char *name;
153
+ int name_size;
154
+
155
+ rb_grn_column = SELF(self);
156
+ rb_grn_object_deconstruct(RB_GRN_OBJECT(rb_grn_column), &column, &context,
157
+ NULL, NULL,
158
+ NULL, NULL);
159
+ name_size = grn_column_name(context, column, NULL, 0);
160
+ if (name_size == 0)
161
+ return Qnil;
162
+
163
+ name = xmalloc(name_size);
164
+ grn_column_name(context, column, name, name_size);
165
+ rb_name = rb_str_new(name, name_size);
166
+ xfree(name);
167
+
168
+ return rb_name;
169
+ }
170
+
171
+ /*
172
+ * call-seq:
173
+ * column.select(options) {|record| ...} -> Groonga::Hash
174
+ * column.select(query, options) -> Groonga::Hash
175
+ * column.select(expression, options) -> Groonga::Hash
176
+ *
177
+ * カラムが所属するテーブルからブロックまたは文字列で指定し
178
+ * た条件にマッチするレコードを返す。返されたテーブルには
179
+ * +expression+という特異メソッドがあり、指定した条件を表し
180
+ * ているGroonga::Expressionを取得できる。
181
+ * Groonga::Expression#snippetを使うことにより、指定した条件
182
+ * 用のスニペットを簡単に生成できる。
183
+ *
184
+ * results = description_column.select do |column|
185
+ * column =~ "groonga"
186
+ * end
187
+ * snippet = results.expression.snippet([["<em>", "</em>"]])
188
+ * results.each do |record|
189
+ * puts "#{record['name']}の説明文の中で「groonga」が含まれる部分"
190
+ * snippet.execute(record["description"].each do |snippet|
191
+ * puts "---"
192
+ * puts "#{snippet}..."
193
+ * puts "---"
194
+ * end
195
+ * end
196
+ *
197
+ * 出力例
198
+ * Ruby/groongaの説明文の中で「groonga」が含まれる部分
199
+ * ---
200
+ * Ruby/<em>groonga</em>は<em>groonga</em>のいわゆるDB-APIの層の...
201
+ * ---
202
+ *
203
+ * _query_には「[カラム名]:[演算子][値]」という書式で条件を
204
+ * 指定する。演算子は以下の通り。
205
+ *
206
+ * [なし]
207
+ * [カラム値] == [値]
208
+ * [<tt>!</tt>]
209
+ * [カラム値] != [値]
210
+ * [<tt><</tt>]
211
+ * [カラム値] < [値]
212
+ * [<tt>></tt>]
213
+ * [カラム値] > [値]
214
+ * [<tt><=</tt>]
215
+ * [カラム値] <= [値]
216
+ * [<tt>>=</tt>]
217
+ * [カラム値] >= [値]
218
+ * [<tt>@</tt>]
219
+ * [カラム値]が[値]を含んでいるかどうか
220
+ *
221
+ * 例:
222
+ * "groonga" # _column_カラムの値が"groonga"のレコードにマッチ
223
+ * "name:daijiro" # _column_カラムが属しているテーブルの
224
+ * # "name"カラムの値が"daijiro"のレコードにマッチ
225
+ * "description:@groonga" # _column_カラムが属しているテーブルの
226
+ * # "description"カラムが
227
+ * # "groonga"を含んでいるレコードにマッチ
228
+ *
229
+ * _expression_には既に作成済みのGroonga::Expressionを渡す
230
+ *
231
+ * ブロックで条件を指定する場合は
232
+ * Groonga::ColumnExpressionBuilderを参照。
233
+ *
234
+ * _options_に指定可能な値は以下の通り。
235
+ *
236
+ * [+:operator+]
237
+ * マッチしたレコードをどのように扱うか。指定可能な値は以
238
+ * 下の通り。省略した場合はGroonga::Operation::OR。
239
+ *
240
+ * [Groonga::Operation::OR]
241
+ * マッチしたレコードを追加。すでにレコードが追加され
242
+ * ている場合は何もしない。
243
+ * [Groonga::Operation::AND]
244
+ * マッチしたレコードのスコアを増加。マッチしなかった
245
+ * レコードを削除。
246
+ * [Groonga::Operation::BUT]
247
+ * マッチしたレコードを削除。
248
+ * [Groonga::Operation::ADJUST]
249
+ * マッチしたレコードのスコアを増加。
250
+ *
251
+ * [+:result+]
252
+ * 検索結果を格納するテーブル。マッチしたレコードが追加さ
253
+ * れていく。省略した場合は新しくテーブルを作成して返す。
254
+ *
255
+ * [+:name+]
256
+ * 条件の名前。省略した場合は名前を付けない。
257
+ *
258
+ * [+:syntax+]
259
+ * _query_の構文。省略した場合は+:query+。
260
+ *
261
+ * 参考: Groonga::Expression#parse.
262
+ *
263
+ * [+:allow_pragma+]
264
+ * query構文時にプラグマを利用するかどうか。省略した場合は
265
+ * 利用する。
266
+ *
267
+ * 参考: Groonga::Expression#parse.
268
+ *
269
+ * [+:allow_column+]
270
+ * query構文時にカラム指定を利用するかどうか。省略した場合
271
+ * は利用する。
272
+ *
273
+ * 参考: Groonga::Expression#parse.
274
+ *
275
+ * [+:allow_update+]
276
+ * script構文時に更新操作を利用するかどうか。省略した場合
277
+ * は利用する。
278
+ *
279
+ * 参考: Groonga::Expression#parse.
280
+ */
281
+ static VALUE
282
+ rb_grn_column_select (int argc, VALUE *argv, VALUE self)
283
+ {
284
+ grn_ctx *context;
285
+ grn_obj *table, *column, *result, *expression;
286
+ grn_operator operator = GRN_OP_OR;
287
+ VALUE options;
288
+ VALUE rb_query, condition_or_options;
289
+ VALUE rb_name, rb_operator, rb_result, rb_syntax;
290
+ VALUE rb_allow_pragma, rb_allow_column, rb_allow_update;
291
+ VALUE builder;
292
+ VALUE rb_expression = Qnil;
293
+
294
+ rb_query = Qnil;
295
+
296
+ rb_scan_args(argc, argv, "02", &condition_or_options, &options);
297
+
298
+ rb_grn_column_deconstruct(SELF(self), &column, &context,
299
+ NULL, NULL,
300
+ NULL, NULL, NULL);
301
+ table = grn_column_table(context, column);
302
+
303
+ if (RVAL2CBOOL(rb_obj_is_kind_of(condition_or_options, rb_cString))) {
304
+ rb_query = condition_or_options;
305
+ } else if (RVAL2CBOOL(rb_obj_is_kind_of(condition_or_options,
306
+ rb_cGrnExpression))) {
307
+ rb_expression = condition_or_options;
308
+ } else {
309
+ if (!NIL_P(options))
310
+ rb_raise(rb_eArgError,
311
+ "should be [query_string, option_hash], "
312
+ "[expression, option_hash] "
313
+ "or [option_hash]: %s",
314
+ rb_grn_inspect(rb_ary_new4(argc, argv)));
315
+ options = condition_or_options;
316
+ }
317
+
318
+ rb_grn_scan_options(options,
319
+ "operator", &rb_operator,
320
+ "result", &rb_result,
321
+ "name", &rb_name,
322
+ "syntax", &rb_syntax,
323
+ "allow_pragma", &rb_allow_pragma,
324
+ "allow_column", &rb_allow_column,
325
+ "allow_update", &rb_allow_update,
326
+ NULL);
327
+
328
+ if (!NIL_P(rb_operator))
329
+ operator = NUM2INT(rb_operator);
330
+
331
+ if (NIL_P(rb_result)) {
332
+ result = grn_table_create(context, NULL, 0, NULL,
333
+ GRN_TABLE_HASH_KEY | GRN_OBJ_WITH_SUBREC,
334
+ table,
335
+ 0);
336
+ rb_result = GRNTABLE2RVAL(context, result, RB_GRN_TRUE);
337
+ } else {
338
+ result = RVAL2GRNTABLE(rb_result, &context);
339
+ }
340
+
341
+ if (NIL_P(rb_expression)) {
342
+ builder = rb_grn_column_expression_builder_new(self, rb_name, rb_query);
343
+ rb_funcall(builder, rb_intern("syntax="), 1, rb_syntax);
344
+ rb_funcall(builder, rb_intern("allow_pragma="), 1, rb_allow_pragma);
345
+ rb_funcall(builder, rb_intern("allow_column="), 1, rb_allow_column);
346
+ rb_funcall(builder, rb_intern("allow_update="), 1, rb_allow_update);
347
+ rb_expression = rb_grn_column_expression_builder_build(builder);
348
+ }
349
+ rb_grn_object_deconstruct(RB_GRN_OBJECT(DATA_PTR(rb_expression)),
350
+ &expression, NULL,
351
+ NULL, NULL, NULL, NULL);
352
+
353
+ grn_table_select(context, table, expression, result, operator);
354
+ rb_grn_context_check(context, self);
355
+
356
+ rb_attr(rb_singleton_class(rb_result),
357
+ rb_intern("expression"),
358
+ RB_GRN_TRUE, RB_GRN_FALSE, RB_GRN_FALSE);
359
+ rb_iv_set(rb_result, "@expression", rb_expression);
360
+
361
+ return rb_result;
362
+ }
363
+
364
+ /*
365
+ * Document-method: unlock
366
+ *
367
+ * call-seq:
368
+ * column.unlock(options={})
369
+ *
370
+ * _column_のロックを解除する。
371
+ *
372
+ * 利用可能なオプションは以下の通り。
373
+ *
374
+ * [_:id_]
375
+ * _:id_で指定したレコードのロックを解除する。(注:
376
+ * groonga側が未実装のため、現在は無視される)
377
+ */
378
+ static VALUE
379
+ rb_grn_column_unlock (int argc, VALUE *argv, VALUE self)
380
+ {
381
+ grn_id id = GRN_ID_NIL;
382
+ grn_ctx *context;
383
+ grn_obj *column;
384
+ grn_rc rc;
385
+ VALUE options, rb_id;
386
+
387
+ rb_scan_args(argc, argv, "01", &options);
388
+
389
+ rb_grn_column_deconstruct(SELF(self), &column, &context,
390
+ NULL, NULL,
391
+ NULL, NULL, NULL);
392
+
393
+ rb_grn_scan_options(options,
394
+ "id", &rb_id,
395
+ NULL);
396
+
397
+ if (!NIL_P(rb_id))
398
+ id = NUM2UINT(rb_id);
399
+
400
+ rc = grn_obj_unlock(context, column, id);
401
+ rb_grn_context_check(context, self);
402
+ rb_grn_rc_check(rc, self);
403
+
404
+ return Qnil;
405
+ }
406
+
407
+ static VALUE
408
+ rb_grn_column_unlock_ensure (VALUE self)
409
+ {
410
+ return rb_grn_column_unlock(0, NULL, self);
411
+ }
412
+
413
+ /*
414
+ * Document-method: lock
415
+ *
416
+ * call-seq:
417
+ * column.lock(options={})
418
+ * column.lock(options={}) {...}
419
+ *
420
+ * _column_をロックする。ロックに失敗した場合は
421
+ * Groonga::ResourceDeadlockAvoided例外が発生する。
422
+ *
423
+ * ブロックを指定した場合はブロックを抜けたときにunlockする。
424
+ *
425
+ * 利用可能なオプションは以下の通り。
426
+ *
427
+ * [_:timeout_]
428
+ * ロックを獲得できなかった場合は_:timeout_秒間ロックの獲
429
+ * 得を試みる。_:timeout_秒以内にロックを獲得できなかった
430
+ * 場合は例外が発生する。
431
+ * [_:id_]
432
+ * _:id_で指定したレコードをロックする。(注: groonga側が
433
+ * 未実装のため、現在は無視される)
434
+ */
435
+ static VALUE
436
+ rb_grn_column_lock (int argc, VALUE *argv, VALUE self)
437
+ {
438
+ grn_id id = GRN_ID_NIL;
439
+ grn_ctx *context;
440
+ grn_obj *column;
441
+ int timeout = 0;
442
+ grn_rc rc;
443
+ VALUE options, rb_timeout, rb_id;
444
+
445
+ rb_scan_args(argc, argv, "01", &options);
446
+
447
+ rb_grn_column_deconstruct(SELF(self), &column, &context,
448
+ NULL, NULL,
449
+ NULL, NULL, NULL);
450
+
451
+ rb_grn_scan_options(options,
452
+ "timeout", &rb_timeout,
453
+ "id", &rb_id,
454
+ NULL);
455
+
456
+ if (!NIL_P(rb_timeout))
457
+ timeout = NUM2UINT(rb_timeout);
458
+
459
+ if (!NIL_P(rb_id))
460
+ id = NUM2UINT(rb_id);
461
+
462
+ rc = grn_obj_lock(context, column, id, timeout);
463
+ rb_grn_context_check(context, self);
464
+ rb_grn_rc_check(rc, self);
465
+
466
+ if (rb_block_given_p()) {
467
+ return rb_ensure(rb_yield, Qnil, rb_grn_column_unlock_ensure, self);
468
+ } else {
469
+ return Qnil;
470
+ }
471
+ }
472
+
473
+ /*
474
+ * Document-method: clear_lock
475
+ *
476
+ * call-seq:
477
+ * column.clear_lock(options={})
478
+ *
479
+ * _column_のロックを強制的に解除する。
480
+ *
481
+ * 利用可能なオプションは以下の通り。
482
+ *
483
+ * [_:id_]
484
+ * _:id_で指定したレコードのロックを強制的に解除する。
485
+ * (注: groonga側が未実装のため、現在は無視される。実装さ
486
+ * れるのではないかと思っているが、実装されないかもしれな
487
+ * い。)
488
+ */
489
+ static VALUE
490
+ rb_grn_column_clear_lock (int argc, VALUE *argv, VALUE self)
491
+ {
492
+ grn_id id = GRN_ID_NIL;
493
+ grn_ctx *context;
494
+ grn_obj *column;
495
+ VALUE options, rb_id;
496
+
497
+ rb_scan_args(argc, argv, "01", &options);
498
+
499
+ rb_grn_column_deconstruct(SELF(self), &column, &context,
500
+ NULL, NULL,
501
+ NULL, NULL, NULL);
502
+
503
+ rb_grn_scan_options(options,
504
+ "id", &rb_id,
505
+ NULL);
506
+
507
+ if (!NIL_P(rb_id))
508
+ id = NUM2UINT(rb_id);
509
+
510
+ grn_obj_clear_lock(context, column);
511
+
512
+ return Qnil;
513
+ }
514
+
515
+ /*
516
+ * Document-method: locked?
517
+ *
518
+ * call-seq:
519
+ * column.locked?(options={})
520
+ *
521
+ * _column_がロックされていれば+true+を返す。
522
+ *
523
+ * 利用可能なオプションは以下の通り。
524
+ *
525
+ * [_:id_]
526
+ * _:id_で指定したレコードがロックされていれば+true+を返す。
527
+ * (注: groonga側が未実装のため、現在は無視される。実装さ
528
+ * れるのではないかと思っているが、実装されないかもしれな
529
+ * い。)
530
+ */
531
+ static VALUE
532
+ rb_grn_column_is_locked (int argc, VALUE *argv, VALUE self)
533
+ {
534
+ grn_id id = GRN_ID_NIL;
535
+ grn_ctx *context;
536
+ grn_obj *column;
537
+ VALUE options, rb_id;
538
+
539
+ rb_scan_args(argc, argv, "01", &options);
540
+
541
+ rb_grn_column_deconstruct(SELF(self), &column, &context,
542
+ NULL, NULL,
543
+ NULL, NULL, NULL);
544
+
545
+ rb_grn_scan_options(options,
546
+ "id", &rb_id,
547
+ NULL);
548
+
549
+ if (!NIL_P(rb_id))
550
+ id = NUM2UINT(rb_id);
551
+
552
+ return CBOOL2RVAL(grn_obj_is_locked(context, column));
553
+ }
554
+
555
+ void
556
+ rb_grn_init_column (VALUE mGrn)
557
+ {
558
+ rb_cGrnColumn = rb_define_class_under(mGrn, "Column", rb_cGrnObject);
559
+
560
+ rb_define_method(rb_cGrnColumn, "table", rb_grn_column_get_table, 0);
561
+ rb_define_method(rb_cGrnColumn, "local_name",
562
+ rb_grn_column_get_local_name, 0);
563
+
564
+ rb_define_method(rb_cGrnColumn, "select", rb_grn_column_select, -1);
565
+ rb_define_method(rb_cGrnColumn, "lock", rb_grn_column_lock, -1);
566
+ rb_define_method(rb_cGrnColumn, "unlock", rb_grn_column_unlock, -1);
567
+ rb_define_method(rb_cGrnColumn, "clear_lock", rb_grn_column_clear_lock, -1);
568
+ rb_define_method(rb_cGrnColumn, "locked?", rb_grn_column_is_locked, -1);
569
+
570
+ rb_grn_init_fix_size_column(mGrn);
571
+ rb_grn_init_variable_size_column(mGrn);
572
+ rb_grn_init_index_column(mGrn);
573
+ }