rroonga 2.0.4 → 2.0.5

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 (90) hide show
  1. data/Rakefile +21 -2
  2. data/bin/grndump +3 -2
  3. data/ext/groonga/extconf.rb +1 -6
  4. data/ext/groonga/rb-grn-array.c +58 -31
  5. data/ext/groonga/rb-grn-column.c +220 -148
  6. data/ext/groonga/rb-grn-context.c +46 -32
  7. data/ext/groonga/rb-grn-database.c +102 -90
  8. data/ext/groonga/rb-grn-double-array-trie.c +205 -163
  9. data/ext/groonga/rb-grn-encoding-support.c +2 -3
  10. data/ext/groonga/rb-grn-encoding.c +13 -8
  11. data/ext/groonga/rb-grn-exception.c +1 -1
  12. data/ext/groonga/rb-grn-expression.c +110 -133
  13. data/ext/groonga/rb-grn-fix-size-column.c +5 -4
  14. data/ext/groonga/rb-grn-geo-point.c +55 -0
  15. data/ext/groonga/rb-grn-hash.c +120 -82
  16. data/ext/groonga/rb-grn-index-column.c +66 -70
  17. data/ext/groonga/rb-grn-index-cursor.c +3 -0
  18. data/ext/groonga/rb-grn-logger.c +33 -51
  19. data/ext/groonga/rb-grn-object.c +2 -0
  20. data/ext/groonga/rb-grn-operator.c +1 -1
  21. data/ext/groonga/rb-grn-patricia-trie.c +287 -232
  22. data/ext/groonga/rb-grn-plugin.c +11 -14
  23. data/ext/groonga/rb-grn-snippet.c +37 -54
  24. data/ext/groonga/rb-grn-table-cursor-key-support.c +3 -3
  25. data/ext/groonga/rb-grn-table-cursor.c +8 -6
  26. data/ext/groonga/rb-grn-table-key-support.c +22 -29
  27. data/ext/groonga/rb-grn-table.c +355 -279
  28. data/ext/groonga/rb-grn-type.c +18 -25
  29. data/ext/groonga/rb-grn-utils.c +77 -7
  30. data/ext/groonga/rb-grn-variable-size-column.c +12 -20
  31. data/ext/groonga/rb-grn-view.c +56 -51
  32. data/ext/groonga/rb-grn.h +28 -1
  33. data/ext/groonga/rb-groonga.c +1 -0
  34. data/lib/groonga.rb +2 -0
  35. data/lib/groonga/command.rb +3 -1
  36. data/lib/groonga/database.rb +27 -0
  37. data/lib/groonga/dumper.rb +96 -17
  38. data/lib/groonga/geo-point.rb +216 -0
  39. data/lib/groonga/schema.rb +29 -46
  40. data/rroonga-build.rb +1 -1
  41. data/rroonga.gemspec +90 -0
  42. data/test/groonga-test-utils.rb +168 -0
  43. data/test/run-test.rb +60 -0
  44. data/test/test-accessor.rb +36 -0
  45. data/test/test-array.rb +146 -0
  46. data/test/test-column.rb +350 -0
  47. data/test/test-command-select.rb +181 -0
  48. data/test/test-context.rb +130 -0
  49. data/test/test-database-dumper.rb +259 -0
  50. data/test/test-database.rb +173 -0
  51. data/test/test-double-array-trie.rb +189 -0
  52. data/test/test-encoding.rb +33 -0
  53. data/test/test-exception.rb +230 -0
  54. data/test/test-expression-builder.rb +602 -0
  55. data/test/test-expression.rb +134 -0
  56. data/test/test-fix-size-column.rb +77 -0
  57. data/test/test-geo-point.rb +190 -0
  58. data/test/test-gqtp.rb +70 -0
  59. data/test/test-hash.rb +367 -0
  60. data/test/test-index-column.rb +180 -0
  61. data/test/test-index-cursor.rb +123 -0
  62. data/test/test-logger.rb +37 -0
  63. data/test/test-pagination.rb +249 -0
  64. data/test/test-patricia-trie.rb +440 -0
  65. data/test/test-plugin.rb +35 -0
  66. data/test/test-procedure.rb +37 -0
  67. data/test/test-query-log.rb +258 -0
  68. data/test/test-record.rb +577 -0
  69. data/test/test-remote.rb +63 -0
  70. data/test/test-schema-create-table.rb +267 -0
  71. data/test/test-schema-dumper.rb +235 -0
  72. data/test/test-schema-type.rb +208 -0
  73. data/test/test-schema-view.rb +90 -0
  74. data/test/test-schema.rb +886 -0
  75. data/test/test-snippet.rb +130 -0
  76. data/test/test-table-dumper.rb +353 -0
  77. data/test/test-table-offset-and-limit.rb +100 -0
  78. data/test/test-table-select-mecab.rb +80 -0
  79. data/test/test-table-select-normalize.rb +57 -0
  80. data/test/test-table-select-weight.rb +123 -0
  81. data/test/test-table-select.rb +191 -0
  82. data/test/test-table-traverse.rb +304 -0
  83. data/test/test-table.rb +711 -0
  84. data/test/test-type.rb +79 -0
  85. data/test/test-variable-size-column.rb +147 -0
  86. data/test/test-variable.rb +28 -0
  87. data/test/test-vector-column.rb +76 -0
  88. data/test/test-version.rb +61 -0
  89. data/test/test-view.rb +72 -0
  90. metadata +330 -202
@@ -0,0 +1,35 @@
1
+ # Copyright (C) 2011 Kouhei Sutou <kou@clear-code.com>
2
+ #
3
+ # This library is free software; you can redistribute it and/or
4
+ # modify it under the terms of the GNU Lesser General Public
5
+ # License version 2.1 as published by the Free Software Foundation.
6
+ #
7
+ # This library is distributed in the hope that it will be useful,
8
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10
+ # Lesser General Public License for more details.
11
+ #
12
+ # You should have received a copy of the GNU Lesser General Public
13
+ # License along with this library; if not, write to the Free Software
14
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
+
16
+ class PluginTest < Test::Unit::TestCase
17
+ include GroongaTestUtils
18
+
19
+ setup :setup_sandbox
20
+ setup :setup_database
21
+ teardown :teardown_sandbox
22
+
23
+ def test_register
24
+ context = Groonga::Context.default
25
+ assert_nil(context["suggest"])
26
+ context.register_plugin("suggest/suggest")
27
+ assert_not_nil(context["suggest"])
28
+ end
29
+
30
+ def test_system_plugins_dir
31
+ suggest_plugin_path = "#{Groonga::Plugin.system_plugins_dir}/"
32
+ suggest_plugin_path << "suggest/suggest#{Groonga::Plugin.suffix}"
33
+ assert_send([File, :exist?, suggest_plugin_path])
34
+ end
35
+ end
@@ -0,0 +1,37 @@
1
+ # Copyright (C) 2009 Kouhei Sutou <kou@clear-code.com>
2
+ #
3
+ # This library is free software; you can redistribute it and/or
4
+ # modify it under the terms of the GNU Lesser General Public
5
+ # License version 2.1 as published by the Free Software Foundation.
6
+ #
7
+ # This library is distributed in the hope that it will be useful,
8
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10
+ # Lesser General Public License for more details.
11
+ #
12
+ # You should have received a copy of the GNU Lesser General Public
13
+ # License along with this library; if not, write to the Free Software
14
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
+
16
+ class ProcedureTest < Test::Unit::TestCase
17
+ include GroongaTestUtils
18
+
19
+ setup :setup_database
20
+
21
+ def test_builtins
22
+ assert_equal_procedure("TokenDelimit", Groonga::Procedure::DELIMIT)
23
+ assert_equal_procedure("TokenUnigram", Groonga::Procedure::UNIGRAM)
24
+ assert_equal_procedure("TokenBigram", Groonga::Procedure::BIGRAM)
25
+ assert_equal_procedure("TokenTrigram", Groonga::Procedure::TRIGRAM)
26
+ assert_equal_procedure("TokenMecab", Groonga::Procedure::MECAB,
27
+ :accept_nil => true)
28
+ end
29
+
30
+ private
31
+ def assert_equal_procedure(expected_name, id, options={})
32
+ procedure = Groonga::Context.default[id]
33
+ expected_name = nil if procedure.nil? and options[:accept_nil]
34
+ assert_equal(expected_name,
35
+ procedure ? procedure.name : procedure)
36
+ end
37
+ end
@@ -0,0 +1,258 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (C) 2011 Kouhei Sutou <kou@clear-code.com>
3
+ #
4
+ # This library is free software; you can redistribute it and/or
5
+ # modify it under the terms of the GNU Lesser General Public
6
+ # License version 2.1 as published by the Free Software Foundation.
7
+ #
8
+ # This library is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
+ # Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public
14
+ # License along with this library; if not, write to the Free Software
15
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
+
17
+ require "cgi"
18
+
19
+ module QueryLogTest
20
+ module CommandParseTestUtils
21
+ private
22
+ def command(name, parameters)
23
+ Groonga::QueryLog::Command.new(name, parameters)
24
+ end
25
+
26
+ def parse_http_path(command, parameters)
27
+ path = "/d/#{command}.json"
28
+ unless parameters.empty?
29
+ uri_parameters = parameters.collect do |key, value|
30
+ [CGI.escape(key.to_s), CGI.escape(value.to_s)].join("=")
31
+ end
32
+ path << "?"
33
+ path << uri_parameters.join("&")
34
+ end
35
+ Groonga::QueryLog::Command.parse(path)
36
+ end
37
+
38
+ def parse_command_line(command, parameters)
39
+ command_line = "#{command} --output_type json"
40
+ parameters.each do |key, value|
41
+ if /"| / =~ value
42
+ escaped_value = '"' + value.gsub(/"/, '\"') + '"'
43
+ else
44
+ escaped_value = value
45
+ end
46
+ command_line << " --#{key} #{escaped_value}"
47
+ end
48
+ Groonga::QueryLog::Command.parse(command_line)
49
+ end
50
+ end
51
+
52
+ module HTTPCommandParseTestUtils
53
+ private
54
+ def parse(command, parameters={})
55
+ parse_http_path(command, parameters)
56
+ end
57
+ end
58
+
59
+ module CommandLineCommandParseTestUtils
60
+ private
61
+ def parse(command, parameters={})
62
+ parse_command_line(command, parameters)
63
+ end
64
+ end
65
+
66
+ module SelectCommandParseTests
67
+ include CommandParseTestUtils
68
+
69
+ def test_parameters
70
+ select = parse("select",
71
+ :table => "Users",
72
+ :filter => "age<=30")
73
+ assert_equal(command("select",
74
+ "table" => "Users",
75
+ "filter" => "age<=30",
76
+ "output_type" => "json"),
77
+ select)
78
+ end
79
+
80
+ def test_scorer
81
+ select = parse("select",
82
+ :table => "Users",
83
+ :filter => "age<=30",
84
+ :scorer => "_score = random()")
85
+ assert_equal("_score = random()", select.scorer)
86
+ end
87
+
88
+ def test_to_uri_format
89
+ select = parse("select",
90
+ :table => "Users",
91
+ :filter => "age<=30")
92
+ assert_equal("/d/select.json?filter=age%3C%3D30&table=Users",
93
+ select.to_uri_format)
94
+ end
95
+
96
+ def test_to_command_format
97
+ select = parse("select",
98
+ :table => "Users",
99
+ :filter => "age<=30")
100
+ assert_equal("select --filter \"age<=30\" " +
101
+ "--output_type \"json\" --table \"Users\"",
102
+ select.to_command_format)
103
+ end
104
+ end
105
+
106
+ module SelectCommandParseFilterTests
107
+ include CommandParseTestUtils
108
+
109
+ def test_parenthesis
110
+ filter = 'geo_in_rectangle(location,' +
111
+ '"35.73360x139.7394","62614x139.7714") && ' +
112
+ '((type == "たいやき" || type == "和菓子")) && ' +
113
+ 'keyword @ "たいやき" &! keyword @ "白" &! keyword @ "養殖"'
114
+ select = parse("select",
115
+ :table => "Users",
116
+ :filter => filter)
117
+ assert_equal(['geo_in_rectangle(location,' +
118
+ '"35.73360x139.7394","62614x139.7714")',
119
+ 'type == "たいやき"',
120
+ 'type == "和菓子"',
121
+ 'keyword @ "たいやき"',
122
+ 'keyword @ "白"',
123
+ 'keyword @ "養殖"'],
124
+ select.conditions)
125
+ end
126
+
127
+ def test_to_uri_format
128
+ filter = 'geo_in_rectangle(location,' +
129
+ '"35.73360x139.7394","62614x139.7714") && ' +
130
+ '((type == "たいやき" || type == "和菓子")) && ' +
131
+ 'keyword @ "たいやき" &! keyword @ "白" &! keyword @ "養殖"'
132
+ select = parse("select",
133
+ :table => "Users",
134
+ :filter => filter)
135
+ assert_equal("/d/select.json?filter=geo_in_rectangle%28location%2C" +
136
+ "%2235.73360x139.7394%22%2C%2262614x139.7714%22%29+" +
137
+ "%26%26+%28%28type+" +
138
+ "%3D%3D+%22%E3%81%9F%E3%81%84%E3%82%84%E3%81%8D%22+" +
139
+ "%7C%7C+type+%3D%3D+" +
140
+ "%22%E5%92%8C%E8%8F%93%E5%AD%90%22%29%29+" +
141
+ "%26%26+keyword+%40+" +
142
+ "%22%E3%81%9F%E3%81%84%E3%82%84%E3%81%8D%22+%26%21+" +
143
+ "keyword+%40+%22%E7%99%BD%22+%26%21+" +
144
+ "keyword+%40+%22%E9%A4%8A%E6%AE%96%22&table=Users",
145
+ select.to_uri_format)
146
+ end
147
+
148
+ def test_to_command_format
149
+ filter = 'geo_in_rectangle(location,' +
150
+ '"35.73360x139.7394","62614x139.7714") && ' +
151
+ '((type == "たいやき" || type == "和菓子")) && ' +
152
+ 'keyword @ "たいやき" &! keyword @ "白" &! keyword @ "養殖"'
153
+ select = parse("select",
154
+ :table => "Users",
155
+ :filter => filter)
156
+ assert_equal("select " +
157
+ "--filter " +
158
+ "\"geo_in_rectangle(location," +
159
+ "\\\"35.73360x139.7394\\\",\\\"62614x139.7714\\\") && " +
160
+ "((type == \\\"たいやき\\\" || " +
161
+ "type == \\\"和菓子\\\")) && " +
162
+ "keyword @ \\\"たいやき\\\" &! keyword @ \\\"白\\\" &! " +
163
+ "keyword @ \\\"養殖\\\"\" " +
164
+ "--output_type \"json\" --table \"Users\"",
165
+ select.to_command_format)
166
+ end
167
+ end
168
+
169
+ class HTTPSelectCommandParseTest < Test::Unit::TestCase
170
+ include SelectCommandParseTests
171
+ include SelectCommandParseFilterTests
172
+ include HTTPCommandParseTestUtils
173
+
174
+ def test_uri_format?
175
+ command = parse("status")
176
+ assert_predicate(command, :uri_format?)
177
+ end
178
+
179
+ def test_command_format?
180
+ command = parse("status")
181
+ assert_not_predicate(command, :command_format?)
182
+ end
183
+ end
184
+
185
+ class CommandLineSelecCommandParseTest < Test::Unit::TestCase
186
+ include SelectCommandParseTests
187
+ include SelectCommandParseFilterTests
188
+ include CommandLineCommandParseTestUtils
189
+
190
+ def test_uri_format?
191
+ command = parse("status")
192
+ assert_not_predicate(command, :uri_format?)
193
+ end
194
+
195
+ def test_command_format?
196
+ command = parse("status")
197
+ assert_predicate(command, :command_format?)
198
+ end
199
+ end
200
+
201
+ class StatisticOperationParseTest < Test::Unit::TestCase
202
+ def test_context
203
+ operations = statistics.first.operations.collect do |operation|
204
+ [operation[:name], operation[:context]]
205
+ end
206
+ expected = [
207
+ ["filter", "local_name @ \"gsub\""],
208
+ ["filter", "description @ \"string\""],
209
+ ["select", nil],
210
+ ["sort", "_score"],
211
+ ["output", "_key"],
212
+ ["drilldown", "name"],
213
+ ["drilldown", "class"],
214
+ ]
215
+ assert_equal(expected, operations)
216
+ end
217
+
218
+ def test_n_records
219
+ operations = statistics.first.operations.collect do |operation|
220
+ [operation[:name], operation[:n_records]]
221
+ end
222
+ expected = [
223
+ ["filter", 15],
224
+ ["filter", 13],
225
+ ["select", 13],
226
+ ["sort", 10],
227
+ ["output", 10],
228
+ ["drilldown", 3],
229
+ ["drilldown", 2],
230
+ ]
231
+ assert_equal(expected, operations)
232
+ end
233
+
234
+ private
235
+ def log
236
+ <<-EOL
237
+ 2011-06-02 16:27:04.731685|5091e5c0|>/d/select.join?table=Entries&filter=local_name+%40+%22gsub%22+%26%26+description+%40+%22string%22&sortby=_score&output_columns=_key&drilldown=name,class
238
+ 2011-06-02 16:27:04.733539|5091e5c0|:000000001849451 filter(15)
239
+ 2011-06-02 16:27:04.734978|5091e5c0|:000000003293459 filter(13)
240
+ 2011-06-02 16:27:04.735012|5091e5c0|:000000003327415 select(13)
241
+ 2011-06-02 16:27:04.735096|5091e5c0|:000000003411824 sort(10)
242
+ 2011-06-02 16:27:04.735232|5091e5c0|:000000003547265 output(10)
243
+ 2011-06-02 16:27:04.735606|5091e5c0|:000000003921419 drilldown(3)
244
+ 2011-06-02 16:27:04.735762|5091e5c0|:000000004077552 drilldown(2)
245
+ 2011-06-02 16:27:04.735808|5091e5c0|<000000004123726 rc=0
246
+ EOL
247
+ end
248
+
249
+ def statistics
250
+ statistics = []
251
+ parser = Groonga::QueryLog::Parser.new
252
+ parser.parse(StringIO.new(log)) do |statistic|
253
+ statistics << statistic
254
+ end
255
+ statistics
256
+ end
257
+ end
258
+ end
@@ -0,0 +1,577 @@
1
+ # Copyright (C) 2009-2012 Kouhei Sutou <kou@clear-code.com>
2
+ #
3
+ # This library is free software; you can redistribute it and/or
4
+ # modify it under the terms of the GNU Lesser General Public
5
+ # License version 2.1 as published by the Free Software Foundation.
6
+ #
7
+ # This library is distributed in the hope that it will be useful,
8
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10
+ # Lesser General Public License for more details.
11
+ #
12
+ # You should have received a copy of the GNU Lesser General Public
13
+ # License along with this library; if not, write to the Free Software
14
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
+
16
+ class RecordTest < Test::Unit::TestCase
17
+ include GroongaTestUtils
18
+
19
+ def setup
20
+ setup_database
21
+
22
+ setup_addresses_table
23
+ setup_users_table
24
+ setup_bookmarks_table
25
+ setup_indexes
26
+ end
27
+
28
+ def setup_addresses_table
29
+ @addresses = Groonga::Array.create(:name => "Addresses")
30
+ @addresses.define_column("mail", "ShortText")
31
+ end
32
+
33
+ def setup_users_table
34
+ @users = Groonga::Hash.create(:name => "Users",
35
+ :key_type => "ShortText")
36
+ @users.define_column("addresses", @addresses, :type => "vector")
37
+ end
38
+
39
+ def setup_bookmarks_table
40
+ @bookmarks = Groonga::Array.create(:name => "Bookmarks",
41
+ :value_type => "Int32")
42
+ @bookmarks.define_column("uri", "ShortText")
43
+ @bookmarks.define_column("rate", "Int32")
44
+ @bookmarks.define_column("comment", "Text")
45
+ @bookmarks.define_column("content", "LongText")
46
+ @bookmarks.define_column("user", @users)
47
+ end
48
+
49
+ def setup_indexes
50
+ @bookmarks_index = Groonga::PatriciaTrie.create(:name => "BookmarksIndex")
51
+ @bookmarks_index.default_tokenizer = "TokenBigram"
52
+
53
+ @bookmarks_content_index =
54
+ @bookmarks_index.define_index_column("content", @bookmarks,
55
+ :with_section => true,
56
+ :with_weight => true,
57
+ :with_position => true,
58
+ :source => "Bookmarks.content")
59
+ @bookmarks_index.define_index_column("uri", @bookmarks,
60
+ :with_position => true,
61
+ :source => "Bookmarks.uri")
62
+ end
63
+
64
+ def test_column_accessor
65
+ groonga = @bookmarks.add
66
+
67
+ groonga["uri"] = "http://groonga.org/"
68
+ assert_equal("http://groonga.org/", groonga["uri"])
69
+
70
+ groonga["comment"] = "fulltext search engine"
71
+ assert_equal("fulltext search engine", groonga["comment"])
72
+ end
73
+
74
+ def test_have_column?
75
+ groonga = @bookmarks.add
76
+ assert_true(groonga.have_column?(:uri))
77
+ assert_false(groonga.have_column?(:nonexistent))
78
+ end
79
+
80
+ def test_have_column_id
81
+ groonga = @bookmarks.add
82
+ assert_true(groonga.have_column?(:_id))
83
+ end
84
+
85
+ def test_have_column_key_hash
86
+ mori = @users.add("mori")
87
+ assert_true(mori.have_column?(:_key))
88
+ end
89
+
90
+ def test_have_column_key_array_with_value_type
91
+ groonga = @bookmarks.add
92
+ assert_true(groonga.have_column?(:_key))
93
+ end
94
+
95
+ def test_have_column_key_array_without_value_type
96
+ groonga_ml = @addresses.add
97
+ assert_false(groonga_ml.have_column?(:_key))
98
+ end
99
+
100
+ def test_have_column_nsubrecs_existent
101
+ @users.add("mori")
102
+ bookmarks = @users.select do |record|
103
+ record.key == "mori"
104
+ end
105
+ assert_true(bookmarks.to_a.first.have_column?(:_nsubrecs))
106
+ end
107
+
108
+ def test_have_column_nsubrecs_nonexistent
109
+ groonga = @bookmarks.add
110
+ assert_false(groonga.have_column?(:_nsubrecs))
111
+ end
112
+
113
+ def test_get_nonexistent_column
114
+ groonga = @bookmarks.add
115
+ assert_raise(Groonga::NoSuchColumn) do
116
+ groonga["nonexistent"]
117
+ end
118
+ end
119
+
120
+ def test_set_nonexistent_column
121
+ groonga = @bookmarks.add
122
+ assert_raise(Groonga::NoSuchColumn) do
123
+ groonga["nonexistent"] = "value"
124
+ end
125
+ end
126
+
127
+ def test_set_object_id
128
+ groonga = @bookmarks.add
129
+ daijiro = @users.add("daijiro")
130
+ assert_nil(groonga["user"])
131
+ groonga["user"] = daijiro
132
+ assert_equal(daijiro, groonga["user"])
133
+ end
134
+
135
+ def test_set_nil
136
+ groonga = @bookmarks.add(:content => "groonga")
137
+ assert_equal("groonga", groonga["content"])
138
+ groonga["content"] = nil
139
+ assert_nil(groonga["content"])
140
+ end
141
+
142
+ def test_set_empty_string
143
+ groonga = @bookmarks.add(:content => "groonga")
144
+ assert_equal("groonga", groonga["content"])
145
+ groonga["content"] = ""
146
+ assert_nil(groonga["content"])
147
+ end
148
+
149
+ def test_set_nil_reference
150
+ groonga = @bookmarks.add(:user => "daijiro",
151
+ :uri => "http://groonga.org/")
152
+ groonga.user = nil
153
+ assert_nil(groonga.user)
154
+ end
155
+
156
+ def test_set_empty_key_reference
157
+ groonga = @bookmarks.add(:user => "daijiro",
158
+ :uri => "http://groonga.org/")
159
+ assert_equal(@users["daijiro"], groonga.user)
160
+ groonga["user"] = ""
161
+ assert_nil(groonga.user)
162
+ end
163
+
164
+ def test_set_string_to_integer_column
165
+ groonga = @bookmarks.add(:content => "groonga")
166
+ groonga.rate = "100"
167
+ assert_equal(100, groonga.rate)
168
+ end
169
+
170
+ def test_delete
171
+ bookmark_records = []
172
+ bookmark_records << @bookmarks.add
173
+ bookmark_records << @bookmarks.add
174
+ bookmark_records << @bookmarks.add
175
+
176
+ assert_equal(3, @bookmarks.size)
177
+ bookmark_records[1].delete
178
+ assert_equal(2, @bookmarks.size)
179
+ end
180
+
181
+ def test_key
182
+ documents = Groonga::PatriciaTrie.create(:name => "Documents",
183
+ :key_type => "ShortText")
184
+ reference = documents.add("reference")
185
+ assert_equal("reference", reference.key)
186
+ end
187
+
188
+ def test_value
189
+ bookmark = @bookmarks.add
190
+ assert_equal(0, bookmark.value)
191
+ bookmark.value = 100
192
+ assert_equal(100, bookmark.value)
193
+ end
194
+
195
+ def test_reference_column?
196
+ bookmark = @bookmarks.add
197
+ assert_false(bookmark.reference_column?("uri"))
198
+ assert_true(bookmark.reference_column?("user"))
199
+ end
200
+
201
+ def test_index_column?
202
+ bookmark = @bookmarks.add
203
+ assert_false(bookmark.index_column?("uri"))
204
+ index = @bookmarks_index.add("token")
205
+ assert_true(index.index_column?("content"))
206
+ end
207
+
208
+ def test_vector_column?
209
+ bookmark = @bookmarks.add
210
+ assert_false(bookmark.vector_column?("uri"))
211
+ morita = @users.add("morita")
212
+ assert_true(morita.vector_column?("addresses"))
213
+ end
214
+
215
+ def test_scalar_column?
216
+ bookmark = @bookmarks.add
217
+ assert_true(bookmark.scalar_column?("uri"))
218
+ morita = @users.add("morita")
219
+ assert_false(morita.scalar_column?("addresses"))
220
+ end
221
+
222
+ def test_score
223
+ groonga = @bookmarks.add
224
+ groonga["content"] = "full text search search search engine."
225
+
226
+ google = @bookmarks.add
227
+ google["content"] = "Web search engine."
228
+
229
+ results = @bookmarks_content_index.search("search")
230
+ assert_equal([[groonga.id, 3], [google.id, 1]],
231
+ results.collect do |record|
232
+ [record.id, record.score]
233
+ end)
234
+ end
235
+
236
+ def test_score=
237
+ groonga = @bookmarks.add
238
+ groonga["content"] = "full text search search search engine."
239
+
240
+ google = @bookmarks.add
241
+ google["content"] = "Web search engine."
242
+
243
+ results = @bookmarks_content_index.search("search")
244
+ results.each do |record|
245
+ record.score *= 10
246
+ end
247
+ assert_equal([[groonga.id, 30], [google.id, 10]],
248
+ results.collect do |record|
249
+ [record.id, record.score]
250
+ end)
251
+ end
252
+
253
+ def test_increment!
254
+ groonga = @bookmarks.add
255
+ assert_equal(0, groonga["rate"])
256
+ groonga.increment!("rate")
257
+ assert_equal(1, groonga["rate"])
258
+ groonga.increment!("rate", 2)
259
+ assert_equal(3, groonga["rate"])
260
+ groonga.increment!("rate", -2)
261
+ assert_equal(1, groonga["rate"])
262
+ end
263
+
264
+ def test_decrement!
265
+ groonga = @bookmarks.add
266
+ assert_equal(0, groonga["rate"])
267
+ groonga.decrement!("rate")
268
+ assert_equal(-1, groonga["rate"])
269
+ groonga.decrement!("rate", 2)
270
+ assert_equal(-3, groonga["rate"])
271
+ groonga.decrement!("rate", -2)
272
+ assert_equal(-1, groonga["rate"])
273
+ end
274
+
275
+ def test_lock
276
+ groonga = @bookmarks.add
277
+
278
+ assert_not_predicate(groonga, :locked?)
279
+ groonga.lock
280
+ assert_predicate(groonga, :locked?)
281
+ groonga.unlock
282
+ assert_not_predicate(groonga, :locked?)
283
+ end
284
+
285
+ def test_lock_failed
286
+ groonga = @bookmarks.add
287
+
288
+ groonga.lock
289
+ assert_raise(Groonga::ResourceDeadlockAvoided) do
290
+ groonga.lock
291
+ end
292
+ end
293
+
294
+ def test_lock_block
295
+ groonga = @bookmarks.add
296
+
297
+ assert_not_predicate(groonga, :locked?)
298
+ groonga.lock do
299
+ assert_predicate(groonga, :locked?)
300
+ end
301
+ assert_not_predicate(groonga, :locked?)
302
+ end
303
+
304
+ def test_clear_lock
305
+ groonga = @bookmarks.add
306
+
307
+ assert_not_predicate(groonga, :locked?)
308
+ groonga.lock
309
+ assert_predicate(groonga, :locked?)
310
+ groonga.clear_lock
311
+ assert_not_predicate(groonga, :locked?)
312
+ end
313
+
314
+ def test_attributes
315
+ values = {
316
+ "uri" => "http://groonga.org/",
317
+ "rate" => 5,
318
+ "comment" => "Great!"
319
+ }
320
+ groonga = @bookmarks.add(values)
321
+ assert_equal(values.merge("_id" => groonga.id,
322
+ "content" => nil,
323
+ "user" => nil),
324
+ groonga.attributes)
325
+ end
326
+
327
+ def test_recursive_attributes
328
+ need_self_recursive_equal
329
+
330
+ @bookmarks.define_column("next", @bookmarks)
331
+
332
+ top_page_record = @bookmarks.add(top_page)
333
+ doc_page_record = @bookmarks.add(doc_page)
334
+
335
+ top_page_record["next"] = doc_page_record
336
+ doc_page_record["next"] = top_page_record
337
+
338
+ expected = {
339
+ "_id" => 1,
340
+ "user" => nil,
341
+ "uri" => "http://groonga.org/",
342
+ "rate" => 5,
343
+ "next" => {
344
+ "_id" => 2,
345
+ "user" => nil,
346
+ "uri" => "http://groonga.org/document.html",
347
+ "rate" => 8,
348
+ "content" => nil,
349
+ "comment" => "Informative"
350
+ },
351
+ "content" => nil,
352
+ "comment" => "Great!"
353
+ }
354
+ expected["next"]["next"] = expected
355
+
356
+ assert_equal(expected, top_page_record.attributes)
357
+ end
358
+
359
+ def test_duplicate_records_attributes
360
+ need_self_recursive_equal
361
+
362
+ @bookmarks.define_column("next1", @bookmarks)
363
+ @bookmarks.define_column("next2", @bookmarks)
364
+
365
+ top_page_record = @bookmarks.add(top_page)
366
+ doc_page_record = @bookmarks.add(doc_page)
367
+
368
+ top_page_record["next1"] = doc_page_record
369
+ top_page_record["next2"] = doc_page_record
370
+ doc_page_record["next1"] = top_page_record
371
+
372
+ doc_page_attributes = {
373
+ "_id" => 2,
374
+ "user" => nil,
375
+ "uri" => "http://groonga.org/document.html",
376
+ "rate" => 8,
377
+ "content" => nil,
378
+ "comment" => "Informative",
379
+ "next2" => nil
380
+ }
381
+ top_page_attributes = {
382
+ "_id" => 1,
383
+ "user" => nil,
384
+ "uri" => "http://groonga.org/",
385
+ "rate" => 5,
386
+ "next1" => doc_page_attributes,
387
+ "next2" => doc_page_attributes,
388
+ "content" => nil,
389
+ "comment" => "Great!"
390
+ }
391
+ doc_page_attributes["next1"] = top_page_attributes
392
+
393
+ actual_records = top_page_record.attributes
394
+ assert_equal(top_page_attributes, actual_records)
395
+ assert_equal(actual_records["next1"].object_id,
396
+ actual_records["next2"].object_id)
397
+ end
398
+
399
+ def test_select_result_attributes
400
+ @bookmarks.add(top_page)
401
+ select_result = @bookmarks.select
402
+ select_result_result = select_result.first
403
+
404
+ expected_attributes = {
405
+ "_id" => 1,
406
+ "_key" => {
407
+ "comment" => "Great!",
408
+ "content" => nil,
409
+ "_id" => 1,
410
+ "rate" => 5,
411
+ "uri" => "http://groonga.org/",
412
+ "user" => nil
413
+ },
414
+ "_nsubrecs" => 1,
415
+ "_score" => 1,
416
+ }
417
+
418
+ assert_equal(expected_attributes, select_result_result.attributes)
419
+ end
420
+
421
+ def test_self_referencing_attributes
422
+ need_self_recursive_equal
423
+
424
+ @bookmarks.define_column("next", @bookmarks)
425
+
426
+ top_page_record = @bookmarks.add(top_page)
427
+ top_page_record["next"] = top_page_record
428
+
429
+ expected = {
430
+ "_id" => 1,
431
+ "user" => nil,
432
+ "uri" => "http://groonga.org/",
433
+ "rate" => 5,
434
+ "content" => nil,
435
+ "comment" => "Great!"
436
+ }
437
+ expected["next"] = expected
438
+
439
+ assert_equal(expected, top_page_record.attributes)
440
+ end
441
+
442
+ def test_vector_attributes
443
+ @bookmarks.define_column("related_bookmarks", @bookmarks, :type => :vector)
444
+
445
+ top_page_record = @bookmarks.add(top_page)
446
+ doc_page_record = @bookmarks.add(doc_page)
447
+ top_page_record["related_bookmarks"] = [doc_page_record]
448
+
449
+ expected = {
450
+ "_id" => 1,
451
+ "user" => nil,
452
+ "uri" => "http://groonga.org/",
453
+ "rate" => 5,
454
+ "related_bookmarks" => [
455
+ {
456
+ "_id" => 2,
457
+ "comment" => "Informative",
458
+ "content" => nil,
459
+ "rate" => 8,
460
+ "related_bookmarks" => [],
461
+ "uri" => "http://groonga.org/document.html",
462
+ "user" => nil,
463
+ }
464
+ ],
465
+ "content" => nil,
466
+ "comment" => "Great!"
467
+ }
468
+
469
+ assert_equal(expected, top_page_record.attributes)
470
+ end
471
+
472
+ def test_self_referencing_vector_attributes
473
+ need_self_recursive_equal
474
+
475
+ @bookmarks.define_column("related_bookmarks", @bookmarks, :type => :vector)
476
+
477
+ top_page_record = @bookmarks.add(top_page)
478
+ doc_page_record = @bookmarks.add(doc_page)
479
+ top_page_record["related_bookmarks"] = [
480
+ top_page_record,
481
+ doc_page_record
482
+ ]
483
+
484
+ top_page_attributes = {
485
+ "_id" => 1,
486
+ "user" => nil,
487
+ "uri" => "http://groonga.org/",
488
+ "rate" => 5,
489
+ "content" => nil,
490
+ "comment" => "Great!"
491
+ }
492
+ doc_page_attributes = {
493
+ "_id" => 2,
494
+ "comment" => "Informative",
495
+ "content" => nil,
496
+ "rate" => 8,
497
+ "related_bookmarks" => [],
498
+ "uri" => "http://groonga.org/document.html",
499
+ "user" => nil,
500
+ }
501
+ top_page_attributes["related_bookmarks"] = [
502
+ top_page_attributes,
503
+ doc_page_attributes
504
+ ]
505
+ assert_equal(top_page_attributes, top_page_record.attributes)
506
+ end
507
+
508
+ def test_dynamic_accessor
509
+ groonga = @bookmarks.add
510
+ assert_equal([],
511
+ ["uri", "uri="] - groonga.methods.collect {|name| name.to_s})
512
+ assert_equal([true, true],
513
+ [groonga.respond_to?(:uri),
514
+ groonga.respond_to?(:uri=)])
515
+ groonga.uri = "http://groonga.org/"
516
+ assert_equal("http://groonga.org/", groonga.uri)
517
+ end
518
+
519
+ def test_method_chain
520
+ morita = @users.add("morita")
521
+ groonga = @bookmarks.add(:user => morita, :uri => "http://groonga.org")
522
+ assert_equal("morita", groonga.user.key)
523
+ end
524
+
525
+ def test_support_sub_records
526
+ morita = @users.add("morita")
527
+ assert_not_predicate(morita, :support_sub_records?)
528
+ users = @users.select {|record| record.key == "morita"}
529
+ assert_predicate(users.to_a[0], :support_sub_records?)
530
+ end
531
+
532
+ def test_set_record_like_object
533
+ kou_at_clear_code = @addresses.add(:mail => "kou@clear-code.com")
534
+ record_like_class = Class.new do
535
+ attr_reader :record_raw_id
536
+ def initialize(record_raw_id)
537
+ @record_raw_id = record_raw_id
538
+ end
539
+ end
540
+ record_like_object = record_like_class.new(kou_at_clear_code.record_raw_id)
541
+ kou = @users.add("kou")
542
+ kou.addresses = [record_like_object]
543
+ end
544
+
545
+ def test_set_array_like_records
546
+ kou_at_clear_code = @addresses.add(:mail => "kou@clear-code.com")
547
+ array_like_class = Class.new do
548
+ def initialize(records)
549
+ @records = records
550
+ end
551
+
552
+ def to_ary
553
+ @records
554
+ end
555
+ end
556
+ array_like_object = array_like_class.new([kou_at_clear_code])
557
+ kou = @users.add("kou")
558
+ kou.addresses = array_like_object
559
+ end
560
+
561
+ private
562
+ def top_page
563
+ {
564
+ "uri" => "http://groonga.org/",
565
+ "rate" => 5,
566
+ "comment" => "Great!",
567
+ }
568
+ end
569
+
570
+ def doc_page
571
+ {
572
+ "uri" => "http://groonga.org/document.html",
573
+ "rate" => 8,
574
+ "comment" => "Informative"
575
+ }
576
+ end
577
+ end