grn_mini 0.3.0 → 0.4.0
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.
- checksums.yaml +4 -4
- data/HISTORY.md +45 -0
- data/README.md +141 -30
- data/lib/grn_mini.rb +18 -1
- data/lib/grn_mini/array.rb +8 -74
- data/lib/grn_mini/hash.rb +6 -69
- data/lib/grn_mini/table.rb +91 -0
- data/lib/grn_mini/version.rb +1 -1
- data/test/test_grn_mini_array.rb +261 -31
- data/test/test_grn_mini_hash.rb +142 -23
- data/test/test_micro_blog.rb +67 -0
- metadata +6 -3
- data/sample/mini-directory-search.rb +0 -153
data/lib/grn_mini/hash.rb
CHANGED
@@ -1,49 +1,14 @@
|
|
1
|
-
require 'grn_mini/
|
2
|
-
require 'groonga'
|
3
|
-
require 'tmpdir'
|
1
|
+
require 'grn_mini/table'
|
4
2
|
|
5
3
|
module GrnMini
|
6
|
-
class Hash
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
def self.tmpdb
|
11
|
-
Dir.mktmpdir do |dir|
|
12
|
-
# p dir
|
13
|
-
yield self.new(File.join(dir, "tmp.db"))
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def initialize(path)
|
18
|
-
unless File.exist?(path)
|
19
|
-
Groonga::Database.create(path: path)
|
20
|
-
else
|
21
|
-
Groonga::Database.open(path)
|
22
|
-
end
|
23
|
-
|
24
|
-
@grn = Groonga["Hash"] || Groonga::Hash.create(name: "Hash", persistent: true)
|
25
|
-
@terms = Groonga["Terms"] || Groonga::PatriciaTrie.create(name: "Terms", key_normalize: true, default_tokenizer: "TokenBigramSplitSymbolAlphaDigit")
|
4
|
+
class Hash < Table
|
5
|
+
def initialize(name = "Hash")
|
6
|
+
super(name,
|
7
|
+
Groonga[name] || Groonga::Hash.create(name: name, persistent: true))
|
26
8
|
end
|
27
9
|
|
28
10
|
def add(key, values)
|
29
|
-
|
30
|
-
values.each do |key, value|
|
31
|
-
column = key.to_s
|
32
|
-
|
33
|
-
# @todo Need define_index_column ?
|
34
|
-
if value.is_a?(Time)
|
35
|
-
@grn.define_column(column, "Time")
|
36
|
-
elsif value.is_a?(Float)
|
37
|
-
@grn.define_column(column, "Float")
|
38
|
-
elsif value.is_a?(Numeric)
|
39
|
-
@grn.define_column(column, "Int32")
|
40
|
-
else
|
41
|
-
@grn.define_column(column, "ShortText")
|
42
|
-
@terms.define_index_column("array_#{column}", @grn, source: "Hash.#{column}", with_position: true)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
11
|
+
setup_columns(values) unless @setup_columns_once
|
47
12
|
@grn.add(key, values)
|
48
13
|
end
|
49
14
|
|
@@ -55,41 +20,13 @@ module GrnMini
|
|
55
20
|
add(key, value)
|
56
21
|
end
|
57
22
|
|
58
|
-
def select(query, options = {default_column: "text"})
|
59
|
-
@grn.select(query, options)
|
60
|
-
end
|
61
|
-
|
62
|
-
def size
|
63
|
-
@grn.size
|
64
|
-
end
|
65
|
-
|
66
|
-
alias length size
|
67
|
-
|
68
|
-
def empty?
|
69
|
-
size == 0
|
70
|
-
end
|
71
|
-
|
72
|
-
def each
|
73
|
-
@grn.each do |record|
|
74
|
-
yield record
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
23
|
def delete(id = nil, &block)
|
79
24
|
if block_given?
|
80
25
|
@grn.delete(&block)
|
81
26
|
else
|
82
|
-
raise IdIsGreaterThanZero if id == 0
|
83
27
|
@grn.delete(id)
|
84
28
|
end
|
85
29
|
end
|
86
30
|
|
87
|
-
def sort(keys, options = {})
|
88
|
-
@grn.sort(keys, options)
|
89
|
-
end
|
90
|
-
|
91
|
-
def group(key, options = {})
|
92
|
-
@grn.group(key, options)
|
93
|
-
end
|
94
31
|
end
|
95
32
|
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'grn_mini/util'
|
2
|
+
require 'groonga'
|
3
|
+
|
4
|
+
module GrnMini
|
5
|
+
class NotSupportColumnType < RuntimeError; end
|
6
|
+
|
7
|
+
class Table
|
8
|
+
attr_accessor :grn
|
9
|
+
include Enumerable
|
10
|
+
|
11
|
+
def initialize(name, grn)
|
12
|
+
@name = name
|
13
|
+
@grn = grn
|
14
|
+
@terms = Groonga["Terms"] || Groonga::PatriciaTrie.create(name: "Terms", key_normalize: true, default_tokenizer: "TokenBigramSplitSymbolAlphaDigit")
|
15
|
+
@setup_columns_once = false
|
16
|
+
end
|
17
|
+
|
18
|
+
def setup_columns(hash)
|
19
|
+
hash.each do |key, value|
|
20
|
+
column = key.to_s
|
21
|
+
|
22
|
+
if value.is_a?(String)
|
23
|
+
@grn.define_column(column, value_type(value))
|
24
|
+
@terms.define_index_column("#{@name}_#{column}", @grn, source: "#{@name}.#{column}", with_position: true)
|
25
|
+
elsif value.is_a?(::Array)
|
26
|
+
@grn.define_column(column, value_type(value), type: :vector)
|
27
|
+
|
28
|
+
elem = value.first
|
29
|
+
|
30
|
+
if elem.is_a?(GrnMini::Table)
|
31
|
+
elem.grn.define_index_column("index_#{column}", @grn, source: "#{@grn.name}.#{column}")
|
32
|
+
elsif elem.is_a?(Groonga::Table)
|
33
|
+
elem.define_index_column("index_#{column}", @grn, source: "#{@grn.name}.#{column}")
|
34
|
+
end
|
35
|
+
else
|
36
|
+
@grn.define_column(column, value_type(value))
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
@setup_columns_once = true
|
41
|
+
end
|
42
|
+
|
43
|
+
def value_type(value)
|
44
|
+
if value.is_a?(TrueClass) || value.is_a?(FalseClass)
|
45
|
+
"Bool"
|
46
|
+
elsif value.is_a?(Integer)
|
47
|
+
"Int32"
|
48
|
+
elsif value.is_a?(Float)
|
49
|
+
"Float"
|
50
|
+
elsif value.is_a?(Time)
|
51
|
+
"Time"
|
52
|
+
elsif value.is_a?(String)
|
53
|
+
"ShortText"
|
54
|
+
elsif value.is_a?(GrnMini::Table)
|
55
|
+
value.grn.name
|
56
|
+
elsif value.is_a?(Groonga::Table)
|
57
|
+
value.name
|
58
|
+
elsif value.is_a?(::Array)
|
59
|
+
value_type(value.first)
|
60
|
+
else
|
61
|
+
raise NotSupportColumnType, value
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def select(*args, &block)
|
66
|
+
@grn.select(*args, &block)
|
67
|
+
end
|
68
|
+
|
69
|
+
def size
|
70
|
+
@grn.size
|
71
|
+
end
|
72
|
+
|
73
|
+
def empty?
|
74
|
+
size == 0
|
75
|
+
end
|
76
|
+
|
77
|
+
def each
|
78
|
+
@grn.each do |record|
|
79
|
+
yield record
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def sort(keys, options = {})
|
84
|
+
@grn.sort(keys, options)
|
85
|
+
end
|
86
|
+
|
87
|
+
def group(key, options = {})
|
88
|
+
@grn.group(key, options)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
data/lib/grn_mini/version.rb
CHANGED
data/test/test_grn_mini_array.rb
CHANGED
@@ -2,13 +2,15 @@ require 'minitest_helper'
|
|
2
2
|
|
3
3
|
class TestGrnMiniArray < MiniTest::Unit::TestCase
|
4
4
|
def test_initialize
|
5
|
-
|
6
|
-
array = GrnMini::Array.new
|
5
|
+
GrnMini::tmpdb do
|
6
|
+
array = GrnMini::Array.new
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
10
|
def test_add
|
11
|
-
GrnMini::
|
11
|
+
GrnMini::tmpdb do
|
12
|
+
array = GrnMini::Array.new
|
13
|
+
|
12
14
|
array.add(text:"aaa", number:1)
|
13
15
|
assert_equal 1, array.size
|
14
16
|
|
@@ -19,12 +21,14 @@ class TestGrnMiniArray < MiniTest::Unit::TestCase
|
|
19
21
|
end
|
20
22
|
|
21
23
|
def test_select
|
22
|
-
GrnMini::
|
24
|
+
GrnMini::tmpdb do
|
25
|
+
array = GrnMini::Array.new
|
26
|
+
|
23
27
|
array << {text:"aaa", number:1}
|
24
28
|
array << {text:"bbb", number:2}
|
25
29
|
array << {text:"ccc", number:3}
|
26
30
|
|
27
|
-
results = array.select("bb")
|
31
|
+
results = array.select("text:@bb")
|
28
32
|
|
29
33
|
assert_equal 1, results.size
|
30
34
|
assert_equal "bbb", results.first.text
|
@@ -32,13 +36,15 @@ class TestGrnMiniArray < MiniTest::Unit::TestCase
|
|
32
36
|
end
|
33
37
|
|
34
38
|
def test_select2
|
35
|
-
GrnMini::
|
39
|
+
GrnMini::tmpdb do
|
40
|
+
array = GrnMini::Array.new
|
41
|
+
|
36
42
|
array << {text:"aaa", number:1}
|
37
43
|
array << {text:"bbb", number:2}
|
38
44
|
array << {text:"bbb", number:20}
|
39
45
|
array << {text:"ccc", number:3}
|
40
46
|
|
41
|
-
results = array.select("bb number:<10")
|
47
|
+
results = array.select("text:@bb number:<10")
|
42
48
|
|
43
49
|
assert_equal 1, results.size
|
44
50
|
assert_equal 2, results.first.key.id
|
@@ -48,19 +54,21 @@ class TestGrnMiniArray < MiniTest::Unit::TestCase
|
|
48
54
|
end
|
49
55
|
|
50
56
|
def test_size
|
51
|
-
GrnMini::
|
57
|
+
GrnMini::tmpdb do
|
58
|
+
array = GrnMini::Array.new
|
59
|
+
|
52
60
|
assert_equal 0, array.size
|
53
|
-
assert_equal 0, array.length
|
54
61
|
|
55
62
|
array << {text:"aaa", number:1}
|
56
63
|
array << {text:"bbb", number:2}
|
57
64
|
assert_equal 2, array.size
|
58
|
-
assert_equal 2, array.length
|
59
65
|
end
|
60
66
|
end
|
61
67
|
|
62
68
|
def test_empty?
|
63
|
-
GrnMini::
|
69
|
+
GrnMini::tmpdb do
|
70
|
+
array = GrnMini::Array.new
|
71
|
+
|
64
72
|
assert_equal true, array.empty?
|
65
73
|
|
66
74
|
array << {text:"aaa", number:1}
|
@@ -69,7 +77,9 @@ class TestGrnMiniArray < MiniTest::Unit::TestCase
|
|
69
77
|
end
|
70
78
|
|
71
79
|
def test_each
|
72
|
-
GrnMini::
|
80
|
+
GrnMini::tmpdb do
|
81
|
+
array = GrnMini::Array.new
|
82
|
+
|
73
83
|
array << {text:"aaa", number:1}
|
74
84
|
array << {text:"bbb", number:2}
|
75
85
|
array << {text:"ccc", number:3}
|
@@ -91,7 +101,9 @@ class TestGrnMiniArray < MiniTest::Unit::TestCase
|
|
91
101
|
end
|
92
102
|
|
93
103
|
def test_read_by_id
|
94
|
-
GrnMini::
|
104
|
+
GrnMini::tmpdb do
|
105
|
+
array = GrnMini::Array.new
|
106
|
+
|
95
107
|
array << {text:"aaa", number:1}
|
96
108
|
array << {text:"bbb", number:2}
|
97
109
|
array << {text:"ccc", number:3}
|
@@ -111,7 +123,9 @@ class TestGrnMiniArray < MiniTest::Unit::TestCase
|
|
111
123
|
end
|
112
124
|
|
113
125
|
def test_write_by_id
|
114
|
-
GrnMini::
|
126
|
+
GrnMini::tmpdb do
|
127
|
+
array = GrnMini::Array.new
|
128
|
+
|
115
129
|
array << {text:"aaa", number:1}
|
116
130
|
array << {text:"bbb", number:2}
|
117
131
|
array << {text:"ccc", number:3}
|
@@ -128,7 +142,9 @@ class TestGrnMiniArray < MiniTest::Unit::TestCase
|
|
128
142
|
end
|
129
143
|
|
130
144
|
def test_delete_by_id
|
131
|
-
GrnMini::
|
145
|
+
GrnMini::tmpdb do
|
146
|
+
array = GrnMini::Array.new
|
147
|
+
|
132
148
|
array << {text:"aaa", number:1}
|
133
149
|
array << {text:"bbb", number:2}
|
134
150
|
array << {text:"ccc", number:3}
|
@@ -163,7 +179,9 @@ class TestGrnMiniArray < MiniTest::Unit::TestCase
|
|
163
179
|
end
|
164
180
|
|
165
181
|
def test_delete_by_block
|
166
|
-
GrnMini::
|
182
|
+
GrnMini::tmpdb do
|
183
|
+
array = GrnMini::Array.new
|
184
|
+
|
167
185
|
array << {text:"bbb", number:2}
|
168
186
|
array << {text:"ccc", number:3}
|
169
187
|
array << {text:"aaa", number:1}
|
@@ -179,7 +197,9 @@ class TestGrnMiniArray < MiniTest::Unit::TestCase
|
|
179
197
|
end
|
180
198
|
|
181
199
|
def test_float_column
|
182
|
-
GrnMini::
|
200
|
+
GrnMini::tmpdb do
|
201
|
+
array = GrnMini::Array.new
|
202
|
+
|
183
203
|
array << {text:"aaaa", float: 1.5}
|
184
204
|
array << {text:"bbbb", float: 2.5}
|
185
205
|
array << {text:"cccc", float: 3.5}
|
@@ -192,7 +212,9 @@ class TestGrnMiniArray < MiniTest::Unit::TestCase
|
|
192
212
|
end
|
193
213
|
|
194
214
|
def test_time_column
|
195
|
-
GrnMini::
|
215
|
+
GrnMini::tmpdb do
|
216
|
+
array = GrnMini::Array.new
|
217
|
+
|
196
218
|
array << {text:"aaaa", timestamp: Time.new(2013)} # 2013-01-01
|
197
219
|
array << {text:"bbbb", timestamp: Time.new(2014)} # 2014-01-01
|
198
220
|
array << {text:"cccc", timestamp: Time.new(2015)} # 2015-01-01
|
@@ -205,8 +227,29 @@ class TestGrnMiniArray < MiniTest::Unit::TestCase
|
|
205
227
|
end
|
206
228
|
end
|
207
229
|
|
230
|
+
def test_bool_column
|
231
|
+
GrnMini::tmpdb do
|
232
|
+
array = GrnMini::Array.new
|
233
|
+
|
234
|
+
array << {bool: true}
|
235
|
+
array << {bool: false}
|
236
|
+
array << {bool: false}
|
237
|
+
|
238
|
+
assert_equal true, array[1].bool
|
239
|
+
assert_equal false, array[2].bool
|
240
|
+
|
241
|
+
results = array.select { |r| r.bool == true }
|
242
|
+
assert_equal 1, results.size
|
243
|
+
|
244
|
+
results = array.select { |r| r.bool == false }
|
245
|
+
assert_equal 2, results.size
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
208
249
|
def test_record_attributes
|
209
|
-
GrnMini::
|
250
|
+
GrnMini::tmpdb do
|
251
|
+
array = GrnMini::Array.new
|
252
|
+
|
210
253
|
array << {text:"aaaa", int: 1}
|
211
254
|
array << {text:"bbbb", int: 2}
|
212
255
|
array << {text:"cccc", int: 3}
|
@@ -218,7 +261,9 @@ class TestGrnMiniArray < MiniTest::Unit::TestCase
|
|
218
261
|
end
|
219
262
|
|
220
263
|
def test_assign_long_text_to_short_text
|
221
|
-
GrnMini::
|
264
|
+
GrnMini::tmpdb do
|
265
|
+
array = GrnMini::Array.new
|
266
|
+
|
222
267
|
array << {filename:"a.txt"}
|
223
268
|
array << {filename:"a"*4095 + ".txt" } # Over 4095 byte (ShortText limit)
|
224
269
|
|
@@ -228,7 +273,9 @@ class TestGrnMiniArray < MiniTest::Unit::TestCase
|
|
228
273
|
end
|
229
274
|
|
230
275
|
def test_grn_object
|
231
|
-
GrnMini::
|
276
|
+
GrnMini::tmpdb do
|
277
|
+
array = GrnMini::Array.new
|
278
|
+
|
232
279
|
array << {text: "aaaa", filename:"a.txt", int: 1, float: 1.5, time: Time.at(2001)}
|
233
280
|
|
234
281
|
raw = array.grn
|
@@ -251,7 +298,9 @@ class TestGrnMiniArray < MiniTest::Unit::TestCase
|
|
251
298
|
end
|
252
299
|
|
253
300
|
def test_sort
|
254
|
-
GrnMini::
|
301
|
+
GrnMini::tmpdb do
|
302
|
+
array = GrnMini::Array.new
|
303
|
+
|
255
304
|
array << {name:"Tanaka", age: 11, height: 162.5}
|
256
305
|
array << {name:"Suzuki", age: 31, height: 170.0}
|
257
306
|
array << {name:"Hayashi", age: 21, height: 175.4}
|
@@ -275,7 +324,9 @@ class TestGrnMiniArray < MiniTest::Unit::TestCase
|
|
275
324
|
end
|
276
325
|
|
277
326
|
def test_group_from_array
|
278
|
-
GrnMini::
|
327
|
+
GrnMini::tmpdb do
|
328
|
+
array = GrnMini::Array.new
|
329
|
+
|
279
330
|
array << {text:"aaaa.txt", suffix:"txt", type:1}
|
280
331
|
array << {text:"aaaa.doc", suffix:"doc", type:2}
|
281
332
|
array << {text:"aabb.txt", suffix:"txt", type:2}
|
@@ -289,13 +340,15 @@ class TestGrnMiniArray < MiniTest::Unit::TestCase
|
|
289
340
|
end
|
290
341
|
|
291
342
|
def test_group_from_selection_results
|
292
|
-
GrnMini::
|
343
|
+
GrnMini::tmpdb do
|
344
|
+
array = GrnMini::Array.new
|
345
|
+
|
293
346
|
array << {text:"aaaa", suffix:"txt"}
|
294
347
|
array << {text:"aaaa", suffix:"doc"}
|
295
348
|
array << {text:"aaaa", suffix:"txt"}
|
296
349
|
array << {text:"cccc", suffix:"txt"}
|
297
350
|
|
298
|
-
results = array.select("aa")
|
351
|
+
results = array.select("text:@aa")
|
299
352
|
groups = GrnMini::Util::group_with_sort(results, "suffix")
|
300
353
|
|
301
354
|
assert_equal 2, groups.size
|
@@ -305,7 +358,9 @@ class TestGrnMiniArray < MiniTest::Unit::TestCase
|
|
305
358
|
end
|
306
359
|
|
307
360
|
def test_text_snippet_from_selection_results
|
308
|
-
GrnMini::
|
361
|
+
GrnMini::tmpdb do
|
362
|
+
array = GrnMini::Array.new
|
363
|
+
|
309
364
|
array << {text: <<EOF, filename: "aaa.txt"}
|
310
365
|
[1] This is a pen pep pea pek pet.
|
311
366
|
------------------------------
|
@@ -320,7 +375,7 @@ class TestGrnMiniArray < MiniTest::Unit::TestCase
|
|
320
375
|
------------------------------
|
321
376
|
EOF
|
322
377
|
|
323
|
-
results = array.select("This pen")
|
378
|
+
results = array.select("This pen", default_column: "text")
|
324
379
|
snippet = GrnMini::Util::text_snippet_from_selection_results(results)
|
325
380
|
|
326
381
|
record = results.first
|
@@ -332,14 +387,16 @@ EOF
|
|
332
387
|
end
|
333
388
|
|
334
389
|
def test_html_snippet_from_selection_results
|
335
|
-
GrnMini::
|
390
|
+
GrnMini::tmpdb do
|
391
|
+
array = GrnMini::Array.new
|
392
|
+
|
336
393
|
array << {text: <<EOF, filename: "aaa.txt"}
|
337
394
|
<html>
|
338
395
|
<div>This is a pen pep pea pek pet.</div>
|
339
396
|
</html>
|
340
397
|
EOF
|
341
398
|
|
342
|
-
results = array.select("This pen")
|
399
|
+
results = array.select("text:@This text:@pen")
|
343
400
|
snippet = GrnMini::Util::html_snippet_from_selection_results(results)
|
344
401
|
|
345
402
|
record = results.first
|
@@ -350,7 +407,9 @@ EOF
|
|
350
407
|
end
|
351
408
|
|
352
409
|
def test_paginate
|
353
|
-
GrnMini::
|
410
|
+
GrnMini::tmpdb do
|
411
|
+
array = GrnMini::Array.new
|
412
|
+
|
354
413
|
array << {text: "aaaa", filename: "1.txt"}
|
355
414
|
array << {text: "aaaa aaaa", filename: "2a.txt"}
|
356
415
|
array << {text: "aaaa aaaa aaaa", filename: "3.txt"}
|
@@ -358,7 +417,7 @@ EOF
|
|
358
417
|
array << {text: "aaaa aaaa", filename: "2c.txt"}
|
359
418
|
array << {text: "aaaa aaaa", filename: "2d.txt"}
|
360
419
|
|
361
|
-
results = array.select
|
420
|
+
results = array.select { |r| r.text =~ "aaaa" }
|
362
421
|
|
363
422
|
# page1
|
364
423
|
page_entries = results.paginate([["_score", :desc]], :page => 1, :size => 5)
|
@@ -375,4 +434,175 @@ EOF
|
|
375
434
|
assert_equal "1.txt", page_entries.first.filename
|
376
435
|
end
|
377
436
|
end
|
437
|
+
|
438
|
+
def test_multi_table
|
439
|
+
Dir.mktmpdir do |dir|
|
440
|
+
GrnMini::create_or_open(File.join(dir, "test.db"))
|
441
|
+
|
442
|
+
users = GrnMini::Array.new("Users")
|
443
|
+
users << {name: "aaa", age: 10}
|
444
|
+
users << {name: "bbb", age: 20}
|
445
|
+
users << {name: "ccc", age: 30}
|
446
|
+
|
447
|
+
articles = GrnMini::Array.new("Articles")
|
448
|
+
articles << {title: "Hello", text: "hello everyone."}
|
449
|
+
|
450
|
+
assert Groonga["Users"]
|
451
|
+
assert_equal 3, users.size
|
452
|
+
|
453
|
+
assert Groonga["Articles"]
|
454
|
+
assert_equal 1, articles.size
|
455
|
+
end
|
456
|
+
end
|
457
|
+
|
458
|
+
def test_multi_table_select
|
459
|
+
GrnMini::tmpdb do
|
460
|
+
users = GrnMini::Array.new("Users")
|
461
|
+
users << {name: "aaa", age: 10, text: ""}
|
462
|
+
users << {name: "bbb", age: 20}
|
463
|
+
users << {name: "ccc", age: 30}
|
464
|
+
|
465
|
+
articles = GrnMini::Array.new("Articles")
|
466
|
+
articles << {title: "1", text: "111 aaa"}
|
467
|
+
articles << {title: "2", text: "222 bbb"}
|
468
|
+
articles << {title: "3", text: "333 ccc"}
|
469
|
+
|
470
|
+
results = users.select("222 OR ccc", default_column: "text")
|
471
|
+
assert_equal 0, results.size
|
472
|
+
|
473
|
+
results = articles.select("222 OR ccc", default_column: "text")
|
474
|
+
assert_equal 2, results.size
|
475
|
+
assert_equal "2", results.first.title
|
476
|
+
end
|
477
|
+
end
|
478
|
+
|
479
|
+
def test_setup_columns
|
480
|
+
GrnMini::tmpdb do
|
481
|
+
array = GrnMini::Array.new
|
482
|
+
|
483
|
+
array.setup_columns(
|
484
|
+
name: "",
|
485
|
+
age: 0,
|
486
|
+
)
|
487
|
+
|
488
|
+
array << {name: "bbb", age: 20 }
|
489
|
+
assert_raises(Groonga::NoSuchColumn) { array << {name: "aaa", age: 10, text: ""} }
|
490
|
+
assert_equal 2, array.size
|
491
|
+
end
|
492
|
+
end
|
493
|
+
|
494
|
+
def test_setup_columns_groonga_table
|
495
|
+
GrnMini::tmpdb do
|
496
|
+
users = GrnMini::Array.new("Users")
|
497
|
+
|
498
|
+
users.setup_columns(
|
499
|
+
parent: users,
|
500
|
+
)
|
501
|
+
|
502
|
+
users << {}
|
503
|
+
users << { parent: users[1] }
|
504
|
+
users << { parent: users[2] }
|
505
|
+
|
506
|
+
# No error ..
|
507
|
+
# users << { parent: 123456 }
|
508
|
+
# users << { parent: 1.5 }
|
509
|
+
# users << { parent: Time.now }
|
510
|
+
|
511
|
+
assert_equal nil, users[1].parent
|
512
|
+
assert_equal users[1], users[2].parent
|
513
|
+
assert_equal users[1], users[3].parent.parent
|
514
|
+
end
|
515
|
+
end
|
516
|
+
|
517
|
+
def test_setup_columns_vector
|
518
|
+
GrnMini::tmpdb do
|
519
|
+
array = GrnMini::Array.new
|
520
|
+
array.setup_columns(links:[""])
|
521
|
+
|
522
|
+
array << {}
|
523
|
+
assert_equal [], array[1].links
|
524
|
+
|
525
|
+
# Nothing happens ..
|
526
|
+
array[1].links << "http://ongaeshi.me"
|
527
|
+
assert_equal 0, array[1].links.size
|
528
|
+
|
529
|
+
# Use links=
|
530
|
+
array[1].links = ["http://ongaeshi.me", "http://yahoo.co.jp"]
|
531
|
+
assert_equal 2, array[1].links.size
|
532
|
+
|
533
|
+
array << { links: ["aaa", "bbb", "ccc"]}
|
534
|
+
array << { links: ["AAA"]}
|
535
|
+
|
536
|
+
# array.each do |record|
|
537
|
+
# p record.attributes
|
538
|
+
# end
|
539
|
+
|
540
|
+
assert_equal 3, array.size
|
541
|
+
assert_equal 3, array[2].links.size
|
542
|
+
end
|
543
|
+
end
|
544
|
+
|
545
|
+
def test_setup_columns_vector2
|
546
|
+
GrnMini::tmpdb do
|
547
|
+
array = GrnMini::Array.new
|
548
|
+
array.setup_columns(strs: [""],
|
549
|
+
numbers: [0],
|
550
|
+
floats: [0.1],
|
551
|
+
times: [Time.new],
|
552
|
+
arrays: [array]
|
553
|
+
)
|
554
|
+
|
555
|
+
array.add(strs: ["AAA", "BBB"],
|
556
|
+
numbers: [1, 2, 3],
|
557
|
+
floats: [0.1, 0.2, 0.3],
|
558
|
+
times: [Time.at(0), Time.at(1), Time.at(3)],
|
559
|
+
arrays: []
|
560
|
+
)
|
561
|
+
array.add(arrays: [array[1]])
|
562
|
+
array.add(arrays: [array[1], array[2]])
|
563
|
+
|
564
|
+
# First element is [1..N], Second and subsequent elements is [0..N-1].
|
565
|
+
assert_equal 0.2, array[3].arrays[1].arrays[0].floats[1]
|
566
|
+
end
|
567
|
+
end
|
568
|
+
|
569
|
+
def test_tweet
|
570
|
+
GrnMini::tmpdb do
|
571
|
+
users = GrnMini::Array.new("Users")
|
572
|
+
tweets = GrnMini::Array.new("Tweets")
|
573
|
+
|
574
|
+
users.setup_columns(name: "A Name"
|
575
|
+
)
|
576
|
+
tweets.setup_columns(user: users,
|
577
|
+
time: Time.new,
|
578
|
+
text: "A Tweet.",
|
579
|
+
replies: [tweets]
|
580
|
+
)
|
581
|
+
|
582
|
+
users << { name: "AAA" }
|
583
|
+
users << { name: "BBB" }
|
584
|
+
|
585
|
+
tweets << { user: users[1], time: Time.at(1), text: "AAA Tweet 1" }
|
586
|
+
tweets << { user: users[2], time: Time.at(2), text: "BBB Tweet 1" }
|
587
|
+
tweets << { user: users[1], time: Time.at(3), text: "AAA Tweet 2" }
|
588
|
+
tweets << { user: users[1], time: Time.at(4), text: "Re: BBB Tweet 1" }
|
589
|
+
tweets << { user: users[2], time: Time.at(5), text: "Re: Re: BBB Tweet 1" }
|
590
|
+
tweets[3].replies = [tweets[4], tweets[5]]
|
591
|
+
|
592
|
+
# tweets.each do |record|
|
593
|
+
# p record.attributes
|
594
|
+
# end
|
595
|
+
|
596
|
+
assert_equal 3, tweets.select("user:1").size
|
597
|
+
assert_equal "AAA Tweet 2", tweets.select("user:1 text:@Tweet text:@2").first.text
|
598
|
+
assert_equal 2, tweets.select("user:2").size
|
599
|
+
end
|
600
|
+
end
|
601
|
+
|
602
|
+
def test_not_support_column_type
|
603
|
+
GrnMini::tmpdb do
|
604
|
+
array = GrnMini::Array.new
|
605
|
+
assert_raises(GrnMini::NotSupportColumnType) { array.setup_columns(error: Hash) }
|
606
|
+
end
|
607
|
+
end
|
378
608
|
end
|