grn_mini 0.2.0 → 0.3.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/README.md +19 -0
- data/lib/grn_mini.rb +1 -0
- data/lib/grn_mini/hash.rb +95 -0
- data/lib/grn_mini/version.rb +1 -1
- data/sample/mini-directory-search.rb +2 -2
- data/test/test_grn_mini_array.rb +4 -3
- data/test/test_grn_mini_hash.rb +260 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 954b7ebeb13d40913ed6022a6b96d972193b73ea
|
4
|
+
data.tar.gz: c64cf4de87e4cf59b172fb1b4d5c64d7f8f17e12
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0406c079b5f1fac34c4f35de6e0ca59b1236df413b285ec28d529c054e1e08f1558f03712b24c37d2dba53f843e219db3ecc37e3d3ea33143faf4121c50b6fb1
|
7
|
+
data.tar.gz: 747fe7c71d88f786229ad7461639b9ff4de8cee0bc73e27aff73ce3301c98659311173517434b98b857b91bbbace9aabb084ee3900c968fd828bad8531d43af3
|
data/README.md
CHANGED
@@ -52,6 +52,25 @@ end
|
|
52
52
|
# Delete temporary database
|
53
53
|
```
|
54
54
|
|
55
|
+
## Create Hash
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
require 'grn_mini'
|
59
|
+
|
60
|
+
hash = GrnMini::Hash.new("test.db")
|
61
|
+
|
62
|
+
# Add
|
63
|
+
hash["a"] = {text:"aaa", number:1}
|
64
|
+
hash["b"] = {text:"bbb", number:2}
|
65
|
+
hash["c"] = {text:"ccc", number:3}
|
66
|
+
|
67
|
+
# Read
|
68
|
+
hash["b"].text #=> "bbb"
|
69
|
+
|
70
|
+
# Write
|
71
|
+
hash["b"].text = "BBB"
|
72
|
+
```
|
73
|
+
|
55
74
|
## Data Type
|
56
75
|
|
57
76
|
```ruby
|
data/lib/grn_mini.rb
CHANGED
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'grn_mini/util'
|
2
|
+
require 'groonga'
|
3
|
+
require 'tmpdir'
|
4
|
+
|
5
|
+
module GrnMini
|
6
|
+
class Hash
|
7
|
+
attr_accessor :grn
|
8
|
+
include Enumerable
|
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")
|
26
|
+
end
|
27
|
+
|
28
|
+
def add(key, values)
|
29
|
+
if @grn.empty?
|
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
|
+
|
47
|
+
@grn.add(key, values)
|
48
|
+
end
|
49
|
+
|
50
|
+
def [](key)
|
51
|
+
@grn[key]
|
52
|
+
end
|
53
|
+
|
54
|
+
def []=(key, value)
|
55
|
+
add(key, value)
|
56
|
+
end
|
57
|
+
|
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
|
+
def delete(id = nil, &block)
|
79
|
+
if block_given?
|
80
|
+
@grn.delete(&block)
|
81
|
+
else
|
82
|
+
raise IdIsGreaterThanZero if id == 0
|
83
|
+
@grn.delete(id)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
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
|
+
end
|
95
|
+
end
|
data/lib/grn_mini/version.rb
CHANGED
@@ -15,7 +15,7 @@ module Input
|
|
15
15
|
|
16
16
|
if File.file? filename
|
17
17
|
next if ignore_file?(filename)
|
18
|
-
array << {filename: filename, text: read_file(filename), timestamp: File.stat(filename).mtime, suffix: File.extname(filename).sub('.', "")
|
18
|
+
array << {filename: filename, text: read_file(filename), timestamp: File.stat(filename).mtime, suffix: File.extname(filename).sub('.', "")}
|
19
19
|
index += 1
|
20
20
|
end
|
21
21
|
end
|
@@ -61,7 +61,7 @@ class Search
|
|
61
61
|
elements = []
|
62
62
|
|
63
63
|
page_entries.each do |record|
|
64
|
-
element = "<hr>\n<a href=\"/#{record.
|
64
|
+
element = "<hr>\n<a href=\"/#{record.value.key.id}\">#{record.filename}</a>\n"
|
65
65
|
|
66
66
|
snippet.execute(record.text).each do |segment|
|
67
67
|
element += "<pre style=\"border:1px solid #bbb;\">#{segment}</pre>\n"
|
data/test/test_grn_mini_array.rb
CHANGED
@@ -41,6 +41,7 @@ class TestGrnMiniArray < MiniTest::Unit::TestCase
|
|
41
41
|
results = array.select("bb number:<10")
|
42
42
|
|
43
43
|
assert_equal 1, results.size
|
44
|
+
assert_equal 2, results.first.key.id
|
44
45
|
assert_equal "bbb", results.first.text
|
45
46
|
assert_equal 2, results.first.number
|
46
47
|
end
|
@@ -325,8 +326,8 @@ EOF
|
|
325
326
|
record = results.first
|
326
327
|
segments = snippet.execute(record.text)
|
327
328
|
assert_equal 2, segments.size
|
328
|
-
assert_match /\[1\]
|
329
|
-
assert_match /\[2\]
|
329
|
+
assert_match /\[1\]<< This>> is a<< pen>> pep pea pek pet./, segments[0]
|
330
|
+
assert_match /\[2\]<< This>> is a<< pen>> pep pea pek pet./, segments[1]
|
330
331
|
end
|
331
332
|
end
|
332
333
|
|
@@ -344,7 +345,7 @@ EOF
|
|
344
345
|
record = results.first
|
345
346
|
segments = snippet.execute(record.text)
|
346
347
|
assert_equal 1, segments.size
|
347
|
-
assert_equal "<html>\n <div><strong>This</strong> is a
|
348
|
+
assert_equal "<html>\n <div><strong>This</strong> is a<strong> pen</strong> pep pea pek pet.</div>\n</html>\n", segments.first
|
348
349
|
end
|
349
350
|
end
|
350
351
|
|
@@ -0,0 +1,260 @@
|
|
1
|
+
require 'minitest_helper'
|
2
|
+
|
3
|
+
class TestGrnMiniHash < MiniTest::Unit::TestCase
|
4
|
+
def test_initialize
|
5
|
+
Dir.mktmpdir do |dir|
|
6
|
+
hash = GrnMini::Hash.new(File.join(dir, "test.db"))
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_add
|
11
|
+
GrnMini::Hash.tmpdb do |hash|
|
12
|
+
hash.add("aaa", text:"aaa", number:1)
|
13
|
+
assert_equal 1, hash.size
|
14
|
+
|
15
|
+
# alias []=
|
16
|
+
hash["bbb"] = {text:"bbb", number:2}
|
17
|
+
assert_equal 2, hash.size
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_select
|
22
|
+
GrnMini::Hash.tmpdb do |hash|
|
23
|
+
hash["a"] = {text:"aaa", number:1}
|
24
|
+
hash["b"] = {text:"bbb", number:2}
|
25
|
+
hash["c"] = {text:"ccc", number:3}
|
26
|
+
|
27
|
+
results = hash.select("bb")
|
28
|
+
|
29
|
+
assert_equal 1, results.size
|
30
|
+
assert_equal "b", results.first.key.key
|
31
|
+
assert_equal "bbb", results.first.text
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_select2
|
36
|
+
GrnMini::Hash.tmpdb do |hash|
|
37
|
+
hash["a"] = {text:"aaa", number:1}
|
38
|
+
hash["b"] = {text:"bbb", number:2}
|
39
|
+
hash["c"] = {text:"bbb", number:20}
|
40
|
+
hash["d"] = {text:"ccc", number:3}
|
41
|
+
|
42
|
+
results = hash.select("bb number:<10")
|
43
|
+
|
44
|
+
assert_equal 1, results.size
|
45
|
+
assert_equal "b", results.first.key.key
|
46
|
+
assert_equal "bbb", results.first.text
|
47
|
+
assert_equal 2, results.first.number
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_size
|
52
|
+
GrnMini::Hash.tmpdb do |hash|
|
53
|
+
assert_equal 0, hash.size
|
54
|
+
assert_equal 0, hash.length
|
55
|
+
|
56
|
+
hash["a"] = {text:"aaa", number:1}
|
57
|
+
hash["b"] = {text:"bbb", number:2}
|
58
|
+
assert_equal 2, hash.size
|
59
|
+
assert_equal 2, hash.length
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_empty?
|
64
|
+
GrnMini::Hash.tmpdb do |hash|
|
65
|
+
assert_equal true, hash.empty?
|
66
|
+
|
67
|
+
hash["a"] = {text:"aaa", number:1}
|
68
|
+
assert_equal false, hash.empty?
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_each
|
73
|
+
GrnMini::Hash.tmpdb do |hash|
|
74
|
+
hash["c"] = {text:"ccc", number:3}
|
75
|
+
hash["a"] = {text:"aaa", number:1}
|
76
|
+
hash["b"] = {text:"bbb", number:2}
|
77
|
+
|
78
|
+
total = 0
|
79
|
+
|
80
|
+
hash.each do |v|
|
81
|
+
total += v.number
|
82
|
+
end
|
83
|
+
|
84
|
+
assert_equal 6, total
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_read_by_key
|
89
|
+
GrnMini::Hash.tmpdb do |hash|
|
90
|
+
hash["a"] = {text:"aaa", number:1}
|
91
|
+
hash["b"] = {text:"bbb", number:2}
|
92
|
+
hash["c"] = {text:"ccc", number:3}
|
93
|
+
|
94
|
+
assert_equal nil, hash["not found"]
|
95
|
+
assert_equal "aaa", hash["a"].text
|
96
|
+
assert_equal "bbb", hash["b"].text
|
97
|
+
assert_equal "ccc", hash["c"].text
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_write_by_key
|
102
|
+
GrnMini::Hash.tmpdb do |hash|
|
103
|
+
hash["a"] = {text:"aaa", number:1}
|
104
|
+
hash["b"] = {text:"bbb", number:2}
|
105
|
+
hash["c"] = {text:"ccc", number:3}
|
106
|
+
|
107
|
+
assert_equal "bbb", hash["b"].text
|
108
|
+
assert_equal 2, hash["b"].number
|
109
|
+
|
110
|
+
hash["b"].text = "BBB"
|
111
|
+
hash["b"].number = 22
|
112
|
+
|
113
|
+
assert_equal "BBB", hash["b"].text
|
114
|
+
assert_equal 22, hash["b"].number
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_delete_by_id
|
119
|
+
GrnMini::Hash.tmpdb do |hash|
|
120
|
+
hash["a"] = {text:"aaa", number:1}
|
121
|
+
hash["b"] = {text:"bbb", number:2}
|
122
|
+
hash["c"] = {text:"ccc", number:3}
|
123
|
+
|
124
|
+
# Delete from key
|
125
|
+
assert_equal 3, hash.size
|
126
|
+
assert_equal 2, hash["b"].number
|
127
|
+
|
128
|
+
hash.delete("b")
|
129
|
+
|
130
|
+
assert_equal 2, hash.size
|
131
|
+
assert_nil hash["b"]
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def test_delete_by_block
|
136
|
+
GrnMini::Hash.tmpdb do |hash|
|
137
|
+
hash["a"] = {text:"aaa", number:1}
|
138
|
+
hash["b"] = {text:"bbb", number:2}
|
139
|
+
hash["c"] = {text:"ccc", number:3}
|
140
|
+
|
141
|
+
hash.delete do |record|
|
142
|
+
record.number >= 2
|
143
|
+
end
|
144
|
+
|
145
|
+
assert_equal 1, hash.size
|
146
|
+
assert_equal "aaa", hash.first.text
|
147
|
+
assert_equal 1, hash.first.number
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_float_column
|
152
|
+
GrnMini::Hash.tmpdb do |hash|
|
153
|
+
hash["a"] = {text:"aaaa", float: 1.5}
|
154
|
+
hash["b"] = {text:"bbbb", float: 2.5}
|
155
|
+
hash["c"] = {text:"cccc", float: 3.5}
|
156
|
+
|
157
|
+
assert_equal 2.5, hash["b"].float
|
158
|
+
|
159
|
+
results = hash.select("float:>2.6")
|
160
|
+
assert_equal 3.5, results.first.float
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def test_time_column
|
165
|
+
GrnMini::Hash.tmpdb do |hash|
|
166
|
+
hash["a"] = {text:"aaaa", timestamp: Time.new(2013)} # 2013-01-01
|
167
|
+
hash["b"] = {text:"bbbb", timestamp: Time.new(2014)} # 2014-01-01
|
168
|
+
hash["c"] = {text:"cccc", timestamp: Time.new(2015)} # 2015-01-01
|
169
|
+
|
170
|
+
assert_equal Time.new(2014), hash["b"].timestamp
|
171
|
+
|
172
|
+
results = hash.select("timestamp:<=#{Time.new(2013,12).to_i}")
|
173
|
+
assert_equal 1, results.size
|
174
|
+
assert_equal Time.new(2013), results.first.timestamp
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def test_record_attributes
|
179
|
+
GrnMini::Hash.tmpdb do |hash|
|
180
|
+
hash["a"] = {text:"aaaa", int: 1}
|
181
|
+
hash["b"] = {text:"bbbb", int: 2}
|
182
|
+
hash["c"] = {text:"cccc", int: 3}
|
183
|
+
|
184
|
+
assert_equal({"_id"=>1, "_key"=>"a", "int"=>1, "text"=>"aaaa"}, hash["a"].attributes)
|
185
|
+
assert_equal({"_id"=>2, "_key"=>"b", "int"=>2, "text"=>"bbbb"}, hash["b"].attributes)
|
186
|
+
assert_equal({"_id"=>3, "_key"=>"c", "int"=>3, "text"=>"cccc"}, hash["c"].attributes)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def test_assign_long_text_to_short_text
|
191
|
+
GrnMini::Hash.tmpdb do |hash|
|
192
|
+
hash["a"] = {filename:"a.txt"}
|
193
|
+
hash["b"] = {filename:"a"*4095 + ".txt" } # Over 4095 byte (ShortText limit)
|
194
|
+
|
195
|
+
results = hash.select("txt", default_column: "filename")
|
196
|
+
assert_equal 2, results.size
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def test_grn_object
|
201
|
+
GrnMini::Hash.tmpdb do |hash|
|
202
|
+
hash["a"] = {text: "aaaa", filename:"a.txt", int: 1, float: 1.5, time: Time.at(2001)}
|
203
|
+
|
204
|
+
raw = hash.grn
|
205
|
+
|
206
|
+
assert_equal true, raw.have_column?("filename")
|
207
|
+
assert_equal true, raw.have_column?("int")
|
208
|
+
assert_equal true, raw.have_column?("float")
|
209
|
+
assert_equal true, raw.have_column?("time")
|
210
|
+
assert_equal false, raw.have_column?("timeee")
|
211
|
+
|
212
|
+
assert_equal "ShortText", raw.column("text").range.name
|
213
|
+
assert_equal "ShortText", raw.column("filename").range.name
|
214
|
+
assert_equal "Int32" , raw.column("int").range.name
|
215
|
+
assert_equal "Float" , raw.column("float").range.name
|
216
|
+
assert_equal "Time" , raw.column("time").range.name
|
217
|
+
|
218
|
+
assert_equal true, raw.support_key? # GrnMini::Array is false
|
219
|
+
assert_equal false, raw.support_sub_records?
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
def test_sort
|
224
|
+
GrnMini::Hash.tmpdb do |hash|
|
225
|
+
hash["a"] = {name:"Tanaka", age: 11, height: 162.5}
|
226
|
+
hash["b"] = {name:"Suzuki", age: 31, height: 170.0}
|
227
|
+
hash["c"] = {name:"Hayashi", age: 21, height: 175.4}
|
228
|
+
hash["d"] = {name:"Suzuki", age: 5, height: 110.0}
|
229
|
+
|
230
|
+
sorted_by_age = hash.sort(["age"])
|
231
|
+
sorted_array = sorted_by_age.map {|r| {name: r.name, age: r.age}}
|
232
|
+
assert_equal [{:name=>"Suzuki", :age=>5},
|
233
|
+
{:name=>"Tanaka", :age=>11},
|
234
|
+
{:name=>"Hayashi", :age=>21},
|
235
|
+
{:name=>"Suzuki", :age=>31}], sorted_array
|
236
|
+
|
237
|
+
sorted_by_combination = hash.sort([{key: "name", order: :ascending},
|
238
|
+
{key: "age" , order: :descending}])
|
239
|
+
sorted_array = sorted_by_combination.map {|r| {name: r.name, age: r.age}}
|
240
|
+
assert_equal [{:name=>"Hayashi", :age=>21},
|
241
|
+
{:name=>"Suzuki", :age=>31},
|
242
|
+
{:name=>"Suzuki", :age=>5},
|
243
|
+
{:name=>"Tanaka", :age=>11}], sorted_array
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
def test_group_from_hash
|
248
|
+
GrnMini::Hash.tmpdb do |hash|
|
249
|
+
hash["a"] = {text:"aaaa.txt", suffix:"txt", type:1}
|
250
|
+
hash["b"] = {text:"aaaa.doc", suffix:"doc", type:2}
|
251
|
+
hash["c"] = {text:"aabb.txt", suffix:"txt", type:2}
|
252
|
+
|
253
|
+
groups = GrnMini::Util::group_with_sort(hash, "suffix")
|
254
|
+
|
255
|
+
assert_equal 2, groups.size
|
256
|
+
assert_equal ["txt", 2], [groups[0].key, groups[0].n_sub_records]
|
257
|
+
assert_equal ["doc", 1], [groups[1].key, groups[1].n_sub_records]
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: grn_mini
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ongaeshi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-01-
|
11
|
+
date: 2014-01-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -85,12 +85,14 @@ files:
|
|
85
85
|
- grn_mini.gemspec
|
86
86
|
- lib/grn_mini.rb
|
87
87
|
- lib/grn_mini/array.rb
|
88
|
+
- lib/grn_mini/hash.rb
|
88
89
|
- lib/grn_mini/util.rb
|
89
90
|
- lib/grn_mini/version.rb
|
90
91
|
- sample/mini-directory-search.rb
|
91
92
|
- test/minitest_helper.rb
|
92
93
|
- test/test_grn_mini.rb
|
93
94
|
- test/test_grn_mini_array.rb
|
95
|
+
- test/test_grn_mini_hash.rb
|
94
96
|
homepage: ''
|
95
97
|
licenses:
|
96
98
|
- MIT
|
@@ -119,3 +121,4 @@ test_files:
|
|
119
121
|
- test/minitest_helper.rb
|
120
122
|
- test/test_grn_mini.rb
|
121
123
|
- test/test_grn_mini_array.rb
|
124
|
+
- test/test_grn_mini_hash.rb
|