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,123 @@
1
+ # Copyright (C) 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 IndexCursorTest < Test::Unit::TestCase
17
+ include GroongaTestUtils
18
+
19
+ def setup
20
+ setup_database
21
+ setup_schema
22
+ setup_records
23
+ end
24
+
25
+ def test_open_cursor
26
+ postings = []
27
+ @terms.open_cursor do |table_cursor|
28
+ index_cursor = nil
29
+ @content_index.open_cursor(table_cursor) do |cursor|
30
+ cursor.each do |posting|
31
+ postings << posting.to_hash
32
+ end
33
+ index_cursor = cursor
34
+ end
35
+ assert_predicate(index_cursor, :closed?)
36
+ end
37
+
38
+ assert_equal(expected_postings, postings)
39
+ end
40
+
41
+ def test_enumerable
42
+ opened = false
43
+ @terms.open_cursor do |table_cursor|
44
+ @content_index.open_cursor(table_cursor) do |cursor|
45
+ postings = cursor.collect do |posting|
46
+ posting.to_hash
47
+ end
48
+ assert_equal(expected_postings, postings)
49
+ opened = true
50
+ end
51
+ end
52
+
53
+ assert_true(opened)
54
+ end
55
+
56
+ def test_each_without_block
57
+ opened = false
58
+ @terms.open_cursor do |table_cursor|
59
+ @content_index.open_cursor(table_cursor) do |cursor|
60
+ postings = cursor.each.collect(&:to_hash)
61
+ assert_equal(expected_postings, postings)
62
+ opened = true
63
+ end
64
+ end
65
+
66
+ assert_true(opened)
67
+ end
68
+
69
+ private
70
+ def create_hashes(keys, values)
71
+ hashes = []
72
+ values.each do |value|
73
+ hash = {}
74
+ keys.each_with_index do |key, i|
75
+ hash[key] = value[i]
76
+ end
77
+ hashes << hash
78
+ end
79
+ hashes
80
+ end
81
+
82
+ def setup_schema
83
+ Groonga::Schema.define do |schema|
84
+ schema.create_table("Articles") do |table|
85
+ table.text("content")
86
+ end
87
+
88
+ schema.create_table("Terms",
89
+ :type => :hash,
90
+ :default_tokenizer => :bigram_split_symbol_alpha) do |table|
91
+ table.index("Articles.content")
92
+ end
93
+ end
94
+
95
+ @articles = Groonga["Articles"]
96
+ @terms = Groonga["Terms"]
97
+ @content_index = Groonga["Terms.Articles_content"]
98
+ end
99
+
100
+ def setup_records
101
+ @articles.add(:content => "l")
102
+ @articles.add(:content => "ll")
103
+ @articles.add(:content => "hello")
104
+ end
105
+
106
+ def expected_postings
107
+ parameters = [:record_id, :section_id, :term_id, :position,
108
+ :term_frequency, :weight, :n_rest_postings]
109
+
110
+ expected = [
111
+ [1, 1, 1, 0, 1, 0, 1],
112
+ [2, 1, 1, 0, 1, 0, 1],
113
+ [2, 1, 2, 0, 1, 0, 1],
114
+ [3, 1, 2, 0, 1, 0, 1],
115
+ [3, 1, 3, 0, 1, 0, 0],
116
+ [3, 1, 4, 1, 1, 0, 0],
117
+ [3, 1, 5, 3, 1, 0, 0],
118
+ [3, 1, 6, 4, 1, 0, 0]
119
+ ]
120
+
121
+ create_hashes(parameters, expected)
122
+ end
123
+ end
@@ -0,0 +1,37 @@
1
+ # Copyright (C) 2010 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 LoggerTest < Test::Unit::TestCase
17
+ include GroongaTestUtils
18
+
19
+ def setup
20
+ @default_log_path = Groonga::Logger.log_path
21
+ @default_query_log_path = Groonga::Logger.query_log_path
22
+ end
23
+
24
+ def teardown
25
+ Groonga::Logger.log_path = @default_log_path
26
+ Groonga::Logger.query_log_path = @default_query_log_path
27
+ end
28
+
29
+ def test_reopen
30
+ if File.exist?(@default_log_path)
31
+ FileUtils.mv(@default_log_path, "#{@default_log_path}.old")
32
+ end
33
+ assert_false(File.exist?(@default_log_path))
34
+ Groonga::Logger.reopen
35
+ assert_true(File.exist?(@default_log_path))
36
+ end
37
+ end
@@ -0,0 +1,249 @@
1
+ # Copyright (C) 2010 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 PaginationTest < Test::Unit::TestCase
17
+ include GroongaTestUtils
18
+
19
+ setup :setup_database
20
+
21
+ setup
22
+ def setup_data
23
+ Groonga::Schema.define do |schema|
24
+ schema.create_table("Users",
25
+ :type => :hash,
26
+ :key_type => "ShortText") do |table|
27
+ table.uint32(:number)
28
+ end
29
+ end
30
+ @users = context["Users"]
31
+ 150.times do |i|
32
+ @users.add("user#{i + 1}", :number => i + 1)
33
+ end
34
+ end
35
+
36
+ def test_default
37
+ assert_paginate({
38
+ :current_page => 1,
39
+ :page_size => 10,
40
+ :n_pages => 15,
41
+ :n_records => 150,
42
+ :start_offset => 1,
43
+ :end_offset => 10,
44
+ :have_previous_page? => false,
45
+ :previous_page => nil,
46
+ :have_next_page? => true,
47
+ :next_page => 2,
48
+ :first_page? => true,
49
+ :last_page? => false,
50
+ :have_pages? => true,
51
+ })
52
+ end
53
+
54
+ def test_no_entries
55
+ @users.each do |user|
56
+ user.delete
57
+ end
58
+ assert_paginate({
59
+ :current_page => 1,
60
+ :page_size => 10,
61
+ :n_pages => 1,
62
+ :n_records => 0,
63
+ :start_offset => nil,
64
+ :end_offset => nil,
65
+ :have_previous_page? => false,
66
+ :previous_page => nil,
67
+ :have_next_page? => false,
68
+ :next_page => nil,
69
+ :first_page? => true,
70
+ :last_page? => true,
71
+ :have_pages? => false,
72
+ :keys => [],
73
+ })
74
+ end
75
+
76
+ def test_page
77
+ assert_paginate({
78
+ :current_page => 6,
79
+ :page_size => 10,
80
+ :n_pages => 15,
81
+ :n_records => 150,
82
+ :start_offset => 51,
83
+ :end_offset => 60,
84
+ :have_previous_page? => true,
85
+ :previous_page => 5,
86
+ :have_next_page? => true,
87
+ :next_page => 7,
88
+ :first_page? => false,
89
+ :last_page? => false,
90
+ :have_pages? => true,
91
+ },
92
+ :page => 6)
93
+ end
94
+
95
+ def test_max_page
96
+ assert_paginate({
97
+ :current_page => 15,
98
+ :page_size => 10,
99
+ :n_pages => 15,
100
+ :n_records => 150,
101
+ :start_offset => 141,
102
+ :end_offset => 150,
103
+ :have_previous_page? => true,
104
+ :previous_page => 14,
105
+ :have_next_page? => false,
106
+ :next_page => nil,
107
+ :first_page? => false,
108
+ :last_page? => true,
109
+ :have_pages? => true,
110
+ },
111
+ :page => 15)
112
+ end
113
+
114
+ def test_too_large_page
115
+ assert_raise(Groonga::TooLargePage) do
116
+ assert_paginate({},
117
+ :page => 16)
118
+ end
119
+ end
120
+
121
+ def test_zero_page
122
+ assert_raise(Groonga::TooSmallPage) do
123
+ assert_paginate({},
124
+ :page => 0)
125
+ end
126
+ end
127
+
128
+ def test_negative_page
129
+ assert_raise(Groonga::TooSmallPage) do
130
+ assert_paginate({},
131
+ :page => -1)
132
+ end
133
+ end
134
+
135
+ def test_size
136
+ assert_paginate({
137
+ :current_page => 1,
138
+ :page_size => 7,
139
+ :n_pages => 22,
140
+ :n_records => 150,
141
+ :start_offset => 1,
142
+ :end_offset => 7,
143
+ :have_previous_page? => false,
144
+ :previous_page => nil,
145
+ :have_next_page? => true,
146
+ :next_page => 2,
147
+ :first_page? => true,
148
+ :last_page? => false,
149
+ :have_pages? => true,
150
+ },
151
+ :size => 7)
152
+ end
153
+
154
+ def test_max_size
155
+ assert_paginate({
156
+ :current_page => 1,
157
+ :page_size => 150,
158
+ :n_pages => 1,
159
+ :n_records => 150,
160
+ :start_offset => 1,
161
+ :end_offset => 150,
162
+ :have_previous_page? => false,
163
+ :previous_page => nil,
164
+ :have_next_page? => false,
165
+ :next_page => nil,
166
+ :first_page? => true,
167
+ :last_page? => true,
168
+ :have_pages? => false,
169
+ },
170
+ :size => 150)
171
+ end
172
+
173
+ def test_too_large_size
174
+ assert_paginate({
175
+ :current_page => 1,
176
+ :page_size => 151,
177
+ :n_pages => 1,
178
+ :n_records => 150,
179
+ :start_offset => 1,
180
+ :end_offset => 150,
181
+ :have_previous_page? => false,
182
+ :previous_page => nil,
183
+ :have_next_page? => false,
184
+ :next_page => nil,
185
+ :first_page? => true,
186
+ :last_page? => true,
187
+ :have_pages? => false,
188
+ },
189
+ :size => 151)
190
+ end
191
+
192
+ def test_zero_size
193
+ assert_raise(Groonga::TooSmallPageSize) do
194
+ assert_paginate({},
195
+ :size => 0)
196
+ end
197
+ end
198
+
199
+ def test_negative_size
200
+ assert_raise(Groonga::TooSmallPageSize) do
201
+ assert_paginate({},
202
+ :size => -1)
203
+ end
204
+ end
205
+
206
+ def test_full
207
+ assert_paginate({
208
+ :current_page => 2,
209
+ :page_size => 50,
210
+ :n_pages => 3,
211
+ :n_records => 150,
212
+ :start_offset => 51,
213
+ :end_offset => 100,
214
+ :have_previous_page? => true,
215
+ :previous_page => 1,
216
+ :have_next_page? => true,
217
+ :next_page => 3,
218
+ :first_page? => false,
219
+ :last_page? => false,
220
+ :have_pages? => true,
221
+ },
222
+ :page => 2,
223
+ :size => 50)
224
+ end
225
+
226
+ private
227
+ def assert_paginate(expected, options={})
228
+ users = @users.paginate([["number"]], options)
229
+ if expected[:keys].nil?
230
+ range = (expected[:start_offset]..expected[:end_offset])
231
+ expected[:keys] = range.collect {|i| "user#{i}"}
232
+ end
233
+ assert_equal(expected,
234
+ :current_page => users.current_page,
235
+ :page_size => users.page_size,
236
+ :n_pages => users.n_pages,
237
+ :n_records => users.n_records,
238
+ :start_offset => users.start_offset,
239
+ :end_offset => users.end_offset,
240
+ :previous_page => users.previous_page,
241
+ :have_previous_page? => users.have_previous_page?,
242
+ :next_page => users.next_page,
243
+ :have_next_page? => users.have_next_page?,
244
+ :first_page? => users.first_page?,
245
+ :last_page? => users.last_page?,
246
+ :have_pages? => users.have_pages?,
247
+ :keys => users.collect(&:key))
248
+ end
249
+ end
@@ -0,0 +1,440 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2009-2012 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
+ class PatriciaTrieTest < Test::Unit::TestCase
19
+ include GroongaTestUtils
20
+ include ERB::Util
21
+
22
+ setup :setup_database
23
+
24
+ def test_support_key?
25
+ assert_predicate(Groonga::PatriciaTrie.create(:name => "Users",
26
+ :key_type => "ShortText"),
27
+ :support_key?)
28
+ end
29
+
30
+ def test_encoding
31
+ assert_equal(Groonga::Encoding.default,
32
+ Groonga::PatriciaTrie.create.encoding)
33
+ end
34
+
35
+ def test_tokenizer
36
+ trie = Groonga::PatriciaTrie.create
37
+ assert_nil(trie.default_tokenizer)
38
+ trie.default_tokenizer = "TokenTrigram"
39
+ assert_equal(Groonga::Context.default["TokenTrigram"],
40
+ trie.default_tokenizer)
41
+ end
42
+
43
+ def test_search
44
+ users = Groonga::Array.create(:name => "Users")
45
+ users.define_column("name", "ShortText")
46
+
47
+ bookmarks = Groonga::PatriciaTrie.create(:name => "Bookmarks",
48
+ :key_type => "ShortText")
49
+ bookmarks.define_column("user_id", users)
50
+
51
+ daijiro = users.add
52
+ daijiro["name"] = "daijiro"
53
+ gunyarakun = users.add
54
+ gunyarakun["name"] = "gunyarakun"
55
+
56
+ groonga = bookmarks.add("http://groonga.org/")
57
+ groonga["user_id"] = daijiro
58
+
59
+ records = bookmarks.search("http://groonga.org/")
60
+ assert_equal(["daijiro"],
61
+ records.records.collect {|record| record[".user_id.name"]})
62
+ end
63
+
64
+ def test_add
65
+ users = Groonga::PatriciaTrie.create(:name => "Users")
66
+ users.define_column("address", "Text")
67
+ me = users.add("me", :address => "me@example.com")
68
+ assert_equal("me@example.com", me[:address])
69
+ end
70
+
71
+ def test_default_tokenizer_on_create
72
+ terms = Groonga::PatriciaTrie.create(:name => "Terms",
73
+ :default_tokenizer => "TokenUnigram")
74
+ assert_equal(context[Groonga::Type::UNIGRAM],
75
+ terms.default_tokenizer)
76
+ end
77
+
78
+ def test_duplicated_name
79
+ Groonga::PatriciaTrie.create(:name => "Users")
80
+ assert_raise(Groonga::InvalidArgument) do
81
+ Groonga::PatriciaTrie.create(:name => "Users")
82
+ end
83
+ end
84
+
85
+ def test_has_key?
86
+ users = Groonga::PatriciaTrie.create(:name => "Users")
87
+ assert_false(users.has_key?("morita"))
88
+ users.add("morita")
89
+ assert_true(users.has_key?("morita"))
90
+ end
91
+
92
+ def test_scan
93
+ Groonga::Context.default_options = {:encoding => "utf-8"}
94
+ words = Groonga::PatriciaTrie.create(:key_type => "ShortText",
95
+ :key_normalize => true)
96
+ words.add("リンク")
97
+ arupaka = words.add("アルパカ")
98
+ words.add("アルパカ(生物)")
99
+ adventure_of_link = words.add('リンクの冒険')
100
+ words.add('冒険')
101
+ gaxtu = words.add('ガッ')
102
+ muteki = words.add('MUTEKI')
103
+ assert_equal([[muteki, "muTEki", 0, 6],
104
+ [adventure_of_link, "リンクの冒険", 7, 18],
105
+ [arupaka, "アルパカ", 42, 12],
106
+ [gaxtu, "ガッ", 55, 6]],
107
+ words.scan('muTEki リンクの冒険 ミリバール アルパカ ガッ'))
108
+ end
109
+
110
+ def test_tag_keys
111
+ Groonga::Context.default_options = {:encoding => "utf-8"}
112
+ words = Groonga::PatriciaTrie.create(:key_type => "ShortText",
113
+ :key_normalize => true)
114
+ words.add('リンク')
115
+ words.add('リンクの冒険')
116
+ words.add('冒険')
117
+ words.add('㍊')
118
+ words.add('ガッ')
119
+ words.add('MUTEKI')
120
+
121
+ text = 'muTEki リンクの冒険 マッチしない ミリバール ガッ おわり'
122
+ actual = words.tag_keys(text) do |record, word|
123
+ "<#{word}(#{record.key})>"
124
+ end
125
+ assert_equal("<muTEki(muteki)> " +
126
+ "<リンクの冒険(リンクの冒険)> " +
127
+ "マッチしない " +
128
+ "<ミリバール(ミリバール)> " +
129
+ "<ガッ(ガッ)> " +
130
+ "おわり",
131
+ actual)
132
+ end
133
+
134
+ def test_tag_keys_other_text_handler
135
+ Groonga::Context.default_options = {:encoding => "utf-8"}
136
+ words = Groonga::PatriciaTrie.create(:key_type => "ShortText",
137
+ :key_normalize => true)
138
+ words.add('ガッ')
139
+ words.add('MUTEKI')
140
+
141
+ text = 'muTEki マッチしない <> ガッ'
142
+ other_text_handler = Proc.new do |string|
143
+ h(string)
144
+ end
145
+ options = {:other_text_handler => other_text_handler}
146
+ actual = words.tag_keys(text, options) do |record, word|
147
+ "<span class=\"keyword\">#{h(word)}(#{h(record.key)})</span>\n"
148
+ end
149
+ assert_equal("<span class=\"keyword\">muTEki(muteki)</span>\n" +
150
+ " マッチしない &lt;&gt; " +
151
+ "<span class=\"keyword\">ガッ(ガッ)</span>\n",
152
+ actual)
153
+ end
154
+
155
+ def test_tag_keys_with_last_match
156
+ Groonga::Context.default_options = {:encoding => "utf-8"}
157
+ words = Groonga::PatriciaTrie.create(:key_type => "ShortText",
158
+ :key_normalize => true)
159
+ words.add('ガッ')
160
+ words.add('MUTEKI')
161
+
162
+ text = 'muTEki マッチしない ガッ'
163
+ actual = words.tag_keys(text) do |record, word|
164
+ "<#{word}(#{record.key})>"
165
+ end
166
+ assert_equal("<muTEki(muteki)> " +
167
+ "マッチしない " +
168
+ "<ガッ(ガッ)>",
169
+ actual)
170
+ end
171
+
172
+ def test_tag_keys_with_no_match
173
+ Groonga::Context.default_options = {:encoding => "utf-8"}
174
+ words = Groonga::PatriciaTrie.create(:key_type => "ShortText",
175
+ :key_normalize => true)
176
+
177
+ words.add('無敵')
178
+ words.add('BOUKEN')
179
+
180
+ text = 'muTEki リンクの冒険'
181
+ actual = words.tag_keys(text) do |record, word|
182
+ "<#{word}(#{record.key})>"
183
+ end
184
+ assert_equal(text, actual)
185
+ end
186
+
187
+ def test_prefix_search
188
+ paths = Groonga::PatriciaTrie.create(:name => "Paths",
189
+ :key_type => 'ShortText')
190
+ paths.add('/')
191
+ paths.add('/tmp')
192
+ paths.add('/usr/bin')
193
+ paths.add('/usr/local/bin')
194
+
195
+ records = paths.prefix_search('/')
196
+ assert_equal(["/usr/local/bin", "/usr/bin", "/tmp", "/"],
197
+ records.records.collect {|record| record["._key"]})
198
+
199
+ records = paths.prefix_search('/usr')
200
+ assert_equal(["/usr/local/bin", "/usr/bin"],
201
+ records.records.collect {|record| record["._key"]})
202
+
203
+ records = paths.prefix_search('/usr/local')
204
+ assert_equal(["/usr/local/bin"],
205
+ records.records.collect {|record| record["._key"]})
206
+
207
+ records = paths.prefix_search('nonexistent')
208
+ assert_equal([],
209
+ records.records.collect {|record| record["._key"]})
210
+ end
211
+
212
+
213
+ def test_prefix_cursor
214
+ paths = Groonga::PatriciaTrie.create(:name => "Paths",
215
+ :key_type => 'ShortText')
216
+ paths.add('/')
217
+ paths.add('/tmp')
218
+ paths.add('/usr/bin')
219
+ paths.add('/usr/local/bin')
220
+
221
+ assert_prefix_cursor(["/usr/local/bin", "/usr/bin", "/tmp", "/"],
222
+ paths, "/", {:order => :desc})
223
+ assert_prefix_cursor(["/", "/tmp", "/usr/bin", "/usr/local/bin"],
224
+ paths, "/")
225
+ assert_prefix_cursor(["/usr/local/bin", "/usr/bin"],
226
+ paths, "/usr/local",
227
+ {:key_bytes => "/usr".size, :order => :desc})
228
+ assert_prefix_cursor(["/tmp", "/usr/bin"],
229
+ paths, "/",
230
+ {:offset => 1, :limit => 2})
231
+ end
232
+
233
+ def assert_prefix_cursor(expected, tables, prefix, options={})
234
+ actual = []
235
+ tables.open_prefix_cursor(prefix, options) do |cursor|
236
+ cursor.each do |record|
237
+ actual << record.key
238
+ end
239
+ end
240
+ assert_equal(expected, actual)
241
+ end
242
+
243
+ def test_rk_cursor
244
+ terms = Groonga::PatriciaTrie.create(:name => "Terms",
245
+ :key_type => 'ShortText')
246
+ ["インデックス",
247
+ "エヌグラム",
248
+ "エンジン",
249
+ "カネソナエタ",
250
+ "カノウ",
251
+ "キノウ",
252
+ "キョウカ",
253
+ "クミコミ",
254
+ "クミコム",
255
+ "グルンガ",
256
+ "ケンサク",
257
+ "ケンサクヨウキュウ",
258
+ "ゲンゴ",
259
+ "コウセイド",
260
+ "コウソク",
261
+ "コンパクト",
262
+ "サクセイ",
263
+ "ショリ",
264
+ "ショリケイ",
265
+ "ジッソウ",
266
+ "ジュンスイ",
267
+ "スクリプト",
268
+ "セッケイ",
269
+ "ゼンブン",
270
+ "タイプ",
271
+ "タンゴ",
272
+ "ダイキボ",
273
+ "テンチ",
274
+ "ディービーエムエス",
275
+ "トウ",
276
+ "トクチョウ",
277
+ "ブンショリョウ",
278
+ "ヨウキュウ"].each do |term|
279
+ terms.add(term)
280
+ end
281
+
282
+ assert_rk_cursor(["カネソナエタ",
283
+ "カノウ",
284
+ "キノウ",
285
+ "キョウカ",
286
+ "クミコミ",
287
+ "クミコム",
288
+ "ケンサク",
289
+ "ケンサクヨウキュウ",
290
+ "コウセイド",
291
+ "コウソク",
292
+ "コンパクト"],
293
+ terms, "k")
294
+ end
295
+
296
+ def assert_rk_cursor(expected, tables, prefix, options={})
297
+ actual = []
298
+ tables.open_rk_cursor(prefix, options) do |cursor|
299
+ cursor.each do |record|
300
+ actual << record.key
301
+ end
302
+ end
303
+ assert_equal(expected, actual.sort)
304
+ end
305
+
306
+ def test_near_cursor
307
+ points = Groonga::PatriciaTrie.create(:name => "Points",
308
+ :key_type => 'WGS84GeoPoint')
309
+ ["130322053x504985073",
310
+ "130285021x504715091",
311
+ "130117012x504390088",
312
+ "130335016x504662007",
313
+ "130308044x504536008",
314
+ "130306053x504530043",
315
+ "130205016x505331054",
316
+ "130222054x505270050",
317
+ "130255017x504266011",
318
+ "130239038x504251015",
319
+ "129885039x503653023",
320
+ "129809022x504597055",
321
+ "130015001x504266057",
322
+ "130089012x505045070",
323
+ "130208017x504315098",
324
+ "130347036x504325073",
325
+ "130380061x505202034",
326
+ "129903045x504648034",
327
+ "130094061x505025099",
328
+ "130133052x505120058",
329
+ "130329069x505188046",
330
+ "130226001x503769013",
331
+ "129866001x504328017",
332
+ "129786048x504792049",
333
+ "129845056x504853081",
334
+ "130055008x504968095",
335
+ "130086003x504480071",
336
+ "129680021x504441006",
337
+ "129855010x504452003",
338
+ "130280013x505208029",
339
+ "129721099x504685024",
340
+ "129690039x504418033",
341
+ "130019020x505027021",
342
+ "130046026x505082073",
343
+ "130038025x505066028",
344
+ "129917001x504675017"].each do |point|
345
+ points.add(point)
346
+ end
347
+
348
+ assert_near_cursor(["129885039x503653023",
349
+ "129866001x504328017",
350
+ "130015001x504266057",
351
+ "129690039x504418033",
352
+ "129680021x504441006",
353
+ "129721099x504685024",
354
+ "129855010x504452003",
355
+ "129809022x504597055",
356
+ "129786048x504792049",
357
+ "129845056x504853081"],
358
+ points,
359
+ "129786048x504792049",
360
+ {:limit => 10})
361
+ end
362
+
363
+ def assert_near_cursor(expected, tables, prefix, options={})
364
+ actual = []
365
+ tables.open_near_cursor(prefix, options) do |cursor|
366
+ cursor.each do |record|
367
+ actual << record.key.to_s
368
+ end
369
+ end
370
+ assert_equal(expected, actual)
371
+ end
372
+
373
+ def test_add_uint_key
374
+ numbers = Groonga::PatriciaTrie.create(:name => "Numbers",
375
+ :key_type => "UInt32")
376
+ numbers.add(1)
377
+ numbers.add(2)
378
+ numbers.add(5)
379
+ numbers.add(7)
380
+ assert_equal([1, 2, 5, 7], numbers.collect {|number| number.key})
381
+ end
382
+
383
+ def test_added?
384
+ users = Groonga::PatriciaTrie.create(:name => "Users",
385
+ :key_type => "ShortText")
386
+ bob = users.add("bob")
387
+ assert_predicate(bob, :added?)
388
+ bob_again = users.add("bob")
389
+ assert_not_predicate(bob_again, :added?)
390
+ end
391
+
392
+ def test_defrag
393
+ users = Groonga::PatriciaTrie.create(:name => "Users",
394
+ :key_type => "ShortText")
395
+ users.define_column("name", "ShortText")
396
+ users.define_column("address", "ShortText")
397
+ 1000.times do |i|
398
+ users.add("user #{i}",
399
+ :name => "user #{i}" * 1000,
400
+ :address => "address #{i}" * 1000)
401
+ end
402
+ assert_equal(7, users.defrag)
403
+ end
404
+
405
+ def test_rename
406
+ users = Groonga::PatriciaTrie.create(:name => "Users",
407
+ :key_type => "ShortText")
408
+ name = users.define_column("name", "ShortText")
409
+ address = users.define_column("address", "ShortText")
410
+
411
+ users.rename("People")
412
+ assert_equal(["People", "People.name", "People.address"],
413
+ [users.name, name.name, address.name])
414
+ end
415
+
416
+ def test_each
417
+ users = Groonga::PatriciaTrie.create(:name => "Users",
418
+ :key_type => "ShortText")
419
+ users.add("Alice")
420
+ users.add("Bob")
421
+ users.add("Carl")
422
+
423
+ user_names = []
424
+ users.each do |user|
425
+ user_names << user.key
426
+ end
427
+ assert_equal(["Alice", "Bob", "Carl"], user_names)
428
+ end
429
+
430
+ def test_each_without_block
431
+ users = Groonga::PatriciaTrie.create(:name => "Users",
432
+ :key_type => "ShortText")
433
+ users.add("Alice")
434
+ users.add("Bob")
435
+ users.add("Carl")
436
+
437
+ user_names = users.each.collect(&:key)
438
+ assert_equal(["Alice", "Bob", "Carl"], user_names)
439
+ end
440
+ end