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.
@@ -1,14 +1,17 @@
1
+ # -*- coding: utf-8 -*-
1
2
  require 'minitest_helper'
2
3
 
3
4
  class TestGrnMiniHash < MiniTest::Unit::TestCase
4
5
  def test_initialize
5
- Dir.mktmpdir do |dir|
6
- hash = GrnMini::Hash.new(File.join(dir, "test.db"))
6
+ GrnMini::tmpdb do
7
+ hash = GrnMini::Hash.new
7
8
  end
8
9
  end
9
10
 
10
11
  def test_add
11
- GrnMini::Hash.tmpdb do |hash|
12
+ GrnMini::tmpdb do
13
+ hash = GrnMini::Hash.new
14
+
12
15
  hash.add("aaa", text:"aaa", number:1)
13
16
  assert_equal 1, hash.size
14
17
 
@@ -19,12 +22,14 @@ class TestGrnMiniHash < MiniTest::Unit::TestCase
19
22
  end
20
23
 
21
24
  def test_select
22
- GrnMini::Hash.tmpdb do |hash|
25
+ GrnMini::tmpdb do
26
+ hash = GrnMini::Hash.new
27
+
23
28
  hash["a"] = {text:"aaa", number:1}
24
29
  hash["b"] = {text:"bbb", number:2}
25
30
  hash["c"] = {text:"ccc", number:3}
26
31
 
27
- results = hash.select("bb")
32
+ results = hash.select("text:@bb")
28
33
 
29
34
  assert_equal 1, results.size
30
35
  assert_equal "b", results.first.key.key
@@ -33,13 +38,15 @@ class TestGrnMiniHash < MiniTest::Unit::TestCase
33
38
  end
34
39
 
35
40
  def test_select2
36
- GrnMini::Hash.tmpdb do |hash|
41
+ GrnMini::tmpdb do
42
+ hash = GrnMini::Hash.new
43
+
37
44
  hash["a"] = {text:"aaa", number:1}
38
45
  hash["b"] = {text:"bbb", number:2}
39
46
  hash["c"] = {text:"bbb", number:20}
40
47
  hash["d"] = {text:"ccc", number:3}
41
48
 
42
- results = hash.select("bb number:<10")
49
+ results = hash.select("text:@bb number:<10")
43
50
 
44
51
  assert_equal 1, results.size
45
52
  assert_equal "b", results.first.key.key
@@ -49,19 +56,21 @@ class TestGrnMiniHash < MiniTest::Unit::TestCase
49
56
  end
50
57
 
51
58
  def test_size
52
- GrnMini::Hash.tmpdb do |hash|
59
+ GrnMini::tmpdb do
60
+ hash = GrnMini::Hash.new
61
+
53
62
  assert_equal 0, hash.size
54
- assert_equal 0, hash.length
55
63
 
56
64
  hash["a"] = {text:"aaa", number:1}
57
65
  hash["b"] = {text:"bbb", number:2}
58
66
  assert_equal 2, hash.size
59
- assert_equal 2, hash.length
60
67
  end
61
68
  end
62
69
 
63
70
  def test_empty?
64
- GrnMini::Hash.tmpdb do |hash|
71
+ GrnMini::tmpdb do
72
+ hash = GrnMini::Hash.new
73
+
65
74
  assert_equal true, hash.empty?
66
75
 
67
76
  hash["a"] = {text:"aaa", number:1}
@@ -70,7 +79,9 @@ class TestGrnMiniHash < MiniTest::Unit::TestCase
70
79
  end
71
80
 
72
81
  def test_each
73
- GrnMini::Hash.tmpdb do |hash|
82
+ GrnMini::tmpdb do
83
+ hash = GrnMini::Hash.new
84
+
74
85
  hash["c"] = {text:"ccc", number:3}
75
86
  hash["a"] = {text:"aaa", number:1}
76
87
  hash["b"] = {text:"bbb", number:2}
@@ -86,7 +97,9 @@ class TestGrnMiniHash < MiniTest::Unit::TestCase
86
97
  end
87
98
 
88
99
  def test_read_by_key
89
- GrnMini::Hash.tmpdb do |hash|
100
+ GrnMini::tmpdb do
101
+ hash = GrnMini::Hash.new
102
+
90
103
  hash["a"] = {text:"aaa", number:1}
91
104
  hash["b"] = {text:"bbb", number:2}
92
105
  hash["c"] = {text:"ccc", number:3}
@@ -99,7 +112,9 @@ class TestGrnMiniHash < MiniTest::Unit::TestCase
99
112
  end
100
113
 
101
114
  def test_write_by_key
102
- GrnMini::Hash.tmpdb do |hash|
115
+ GrnMini::tmpdb do
116
+ hash = GrnMini::Hash.new
117
+
103
118
  hash["a"] = {text:"aaa", number:1}
104
119
  hash["b"] = {text:"bbb", number:2}
105
120
  hash["c"] = {text:"ccc", number:3}
@@ -116,7 +131,9 @@ class TestGrnMiniHash < MiniTest::Unit::TestCase
116
131
  end
117
132
 
118
133
  def test_delete_by_id
119
- GrnMini::Hash.tmpdb do |hash|
134
+ GrnMini::tmpdb do
135
+ hash = GrnMini::Hash.new
136
+
120
137
  hash["a"] = {text:"aaa", number:1}
121
138
  hash["b"] = {text:"bbb", number:2}
122
139
  hash["c"] = {text:"ccc", number:3}
@@ -133,7 +150,9 @@ class TestGrnMiniHash < MiniTest::Unit::TestCase
133
150
  end
134
151
 
135
152
  def test_delete_by_block
136
- GrnMini::Hash.tmpdb do |hash|
153
+ GrnMini::tmpdb do
154
+ hash = GrnMini::Hash.new
155
+
137
156
  hash["a"] = {text:"aaa", number:1}
138
157
  hash["b"] = {text:"bbb", number:2}
139
158
  hash["c"] = {text:"ccc", number:3}
@@ -149,7 +168,9 @@ class TestGrnMiniHash < MiniTest::Unit::TestCase
149
168
  end
150
169
 
151
170
  def test_float_column
152
- GrnMini::Hash.tmpdb do |hash|
171
+ GrnMini::tmpdb do
172
+ hash = GrnMini::Hash.new
173
+
153
174
  hash["a"] = {text:"aaaa", float: 1.5}
154
175
  hash["b"] = {text:"bbbb", float: 2.5}
155
176
  hash["c"] = {text:"cccc", float: 3.5}
@@ -162,7 +183,9 @@ class TestGrnMiniHash < MiniTest::Unit::TestCase
162
183
  end
163
184
 
164
185
  def test_time_column
165
- GrnMini::Hash.tmpdb do |hash|
186
+ GrnMini::tmpdb do
187
+ hash = GrnMini::Hash.new
188
+
166
189
  hash["a"] = {text:"aaaa", timestamp: Time.new(2013)} # 2013-01-01
167
190
  hash["b"] = {text:"bbbb", timestamp: Time.new(2014)} # 2014-01-01
168
191
  hash["c"] = {text:"cccc", timestamp: Time.new(2015)} # 2015-01-01
@@ -176,7 +199,9 @@ class TestGrnMiniHash < MiniTest::Unit::TestCase
176
199
  end
177
200
 
178
201
  def test_record_attributes
179
- GrnMini::Hash.tmpdb do |hash|
202
+ GrnMini::tmpdb do
203
+ hash = GrnMini::Hash.new
204
+
180
205
  hash["a"] = {text:"aaaa", int: 1}
181
206
  hash["b"] = {text:"bbbb", int: 2}
182
207
  hash["c"] = {text:"cccc", int: 3}
@@ -188,7 +213,9 @@ class TestGrnMiniHash < MiniTest::Unit::TestCase
188
213
  end
189
214
 
190
215
  def test_assign_long_text_to_short_text
191
- GrnMini::Hash.tmpdb do |hash|
216
+ GrnMini::tmpdb do
217
+ hash = GrnMini::Hash.new
218
+
192
219
  hash["a"] = {filename:"a.txt"}
193
220
  hash["b"] = {filename:"a"*4095 + ".txt" } # Over 4095 byte (ShortText limit)
194
221
 
@@ -198,7 +225,9 @@ class TestGrnMiniHash < MiniTest::Unit::TestCase
198
225
  end
199
226
 
200
227
  def test_grn_object
201
- GrnMini::Hash.tmpdb do |hash|
228
+ GrnMini::tmpdb do
229
+ hash = GrnMini::Hash.new
230
+
202
231
  hash["a"] = {text: "aaaa", filename:"a.txt", int: 1, float: 1.5, time: Time.at(2001)}
203
232
 
204
233
  raw = hash.grn
@@ -221,7 +250,9 @@ class TestGrnMiniHash < MiniTest::Unit::TestCase
221
250
  end
222
251
 
223
252
  def test_sort
224
- GrnMini::Hash.tmpdb do |hash|
253
+ GrnMini::tmpdb do
254
+ hash = GrnMini::Hash.new
255
+
225
256
  hash["a"] = {name:"Tanaka", age: 11, height: 162.5}
226
257
  hash["b"] = {name:"Suzuki", age: 31, height: 170.0}
227
258
  hash["c"] = {name:"Hayashi", age: 21, height: 175.4}
@@ -245,7 +276,9 @@ class TestGrnMiniHash < MiniTest::Unit::TestCase
245
276
  end
246
277
 
247
278
  def test_group_from_hash
248
- GrnMini::Hash.tmpdb do |hash|
279
+ GrnMini::tmpdb do
280
+ hash = GrnMini::Hash.new
281
+
249
282
  hash["a"] = {text:"aaaa.txt", suffix:"txt", type:1}
250
283
  hash["b"] = {text:"aaaa.doc", suffix:"doc", type:2}
251
284
  hash["c"] = {text:"aabb.txt", suffix:"txt", type:2}
@@ -257,4 +290,90 @@ class TestGrnMiniHash < MiniTest::Unit::TestCase
257
290
  assert_equal ["doc", 1], [groups[1].key, groups[1].n_sub_records]
258
291
  end
259
292
  end
293
+
294
+ def test_select_table_element
295
+ GrnMini::tmpdb do
296
+ links = GrnMini::Hash.new("Links")
297
+ links.setup_columns(next: links)
298
+
299
+ links["aaa"] = {}
300
+ links["bbb"] = {}
301
+ links["ccc"] = {}
302
+
303
+ links["aaa"].next = links["bbb"]
304
+ links["bbb"].next = links["ccc"]
305
+ links["ccc"].next = links["aaa"]
306
+
307
+ assert_equal links["bbb"], links["aaa"].next
308
+
309
+ assert_equal links["ccc"], links.select("next: aaa").first.key
310
+ end
311
+ end
312
+
313
+ def test_nodes_table
314
+ GrnMini::tmpdb do
315
+ nodes = GrnMini::Hash.new("Nodes")
316
+ nodes.setup_columns(childs: [nodes], numbers: [0])
317
+
318
+ nodes["aaa"] = {}
319
+ nodes["bbb"] = {}
320
+ nodes["ccc"] = {}
321
+ nodes["ddd"] = {}
322
+ nodes["eee"] = {}
323
+
324
+ nodes["aaa"].childs = ["bbb", "ccc"]
325
+ # nodes["bbb"].childs = nodes["bbb"].childs + [nodes["ddd"]]
326
+ nodes["bbb"].childs += [nodes["ddd"]]
327
+ nodes["bbb"].childs += [nodes["eee"]]
328
+
329
+ assert_equal 2, nodes["aaa"].childs.size
330
+ assert_equal 2, nodes["bbb"].childs.size
331
+
332
+ assert_equal nodes["aaa"], nodes.select("childs: bbb").first.key
333
+ assert_equal 0, nodes.select("childs: aaa").size
334
+ end
335
+ end
336
+
337
+ def test_users_and_articles
338
+ GrnMini::tmpdb do
339
+ users = GrnMini::Hash.new("Users")
340
+ articles = GrnMini::Hash.new("Articles")
341
+
342
+ users.setup_columns(name: "", favorites: [articles])
343
+ articles.setup_columns(author: users, text: "")
344
+
345
+ users["aaa"] = {name: "Mr.A"}
346
+ users["bbb"] = {name: "Mr.B"}
347
+ users["ccc"] = {name: "Mr.C"}
348
+
349
+ articles["aaa:1"] = {author: "aaa", text: "111"}
350
+ articles["aaa:2"] = {author: "aaa", text: "222"}
351
+ articles["aaa:3"] = {author: "aaa", text: "333"}
352
+ articles["bbb:1"] = {author: "bbb", text: "111"}
353
+ articles["bbb:2"] = {author: "bbb", text: "222"}
354
+ articles["ccc:1"] = {author: "ccc", text: "111"}
355
+
356
+ users["aaa"].favorites = ["aaa:1", "bbb:2"]
357
+ users["bbb"].favorites = ["aaa:2"]
358
+ users["ccc"].favorites = ["aaa:1", "bbb:1", "ccc:1"]
359
+
360
+ assert_equal ["aaa", "ccc"], select_keys(users) { |record| record.favorites == "aaa:1" }
361
+ assert_equal ["bbb"], select_keys(users) { |record| record.favorites == "aaa:2" }
362
+ assert_equal [], select_keys(users) { |record| record.favorites == "aaa:3" }
363
+
364
+ assert_equal ["aaa", "ccc"], select_keys(users) { |record| record.favorites.text =~ "111" }
365
+ assert_equal ["aaa", "bbb"], select_keys(users) { |record| record.favorites.text =~ "222" }
366
+ assert_equal [], select_keys(users) { |record| record.favorites.text =~ "333" }
367
+
368
+ # assert_equal ["aaa", "ccc"], select_keys(users) { |record| record.favorites.text == "111" } # TODO ==だと動かない
369
+ # assert_equal ["aaa", "ccc"], select_keys(users) { |record| record.favorites.author == "bbb" } # TODO 正しく動かない
370
+ end
371
+ end
372
+
373
+ def select_keys(table)
374
+ table.select { |record|
375
+ yield record
376
+ }.map { |record| record._key }.sort
377
+ end
378
+
260
379
  end
@@ -0,0 +1,67 @@
1
+ require 'minitest_helper'
2
+
3
+ class TestMicroBlog < MiniTest::Unit::TestCase
4
+ def test_micro_blog
5
+ GrnMini::tmpdb do
6
+ engine = MicroBlog.new
7
+
8
+ # Add user
9
+ engine.add_user("aaa", "Mr. A", "Hello.")
10
+ engine.add_user("bbb", "Mr. B", "Good Afternoon.")
11
+ engine.add_user("ccc", "Mr. C", "Hi.")
12
+
13
+ # Follow
14
+ engine.follow("bbb", "aaa")
15
+ engine.follow("ccc", "aaa")
16
+ engine.follow("ccc", "bbb")
17
+
18
+ users = engine.users
19
+ assert_equal 0, users["aaa"].follower.size
20
+ assert_equal 1, users["bbb"].follower.size
21
+ assert_equal 2, users["ccc"].follower.size
22
+
23
+ # Followee
24
+ assert_equal 2, engine.followee("aaa").size
25
+ assert_equal 1, engine.followee("bbb").size
26
+ assert_equal 0, engine.followee("ccc").size
27
+ end
28
+ end
29
+
30
+ class MicroBlog
31
+ attr_reader :users
32
+ attr_reader :comments
33
+ attr_reader :hash_tags
34
+
35
+ def initialize
36
+ @users = GrnMini::Hash.new("Users")
37
+ @comments = GrnMini::Hash.new("Comments")
38
+ @hash_tags = GrnMini::Hash.new("HashTags")
39
+
40
+ @users.setup_columns(name: "User Name",
41
+ follower: [users],
42
+ favorites: [comments],
43
+ description: ""
44
+ )
45
+
46
+ @comments.setup_columns(comment: "",
47
+ last_modified: Time.new,
48
+ replied_to: [comments],
49
+ replied_users: [users],
50
+ hash_tags: [hash_tags],
51
+ posted_by: users
52
+ )
53
+ end
54
+
55
+ def add_user(id, name, description)
56
+ @users[id] = {name: name, description: description }
57
+ end
58
+
59
+ def follow(user_id, follow_id)
60
+ @users[user_id].follower += [@users[follow_id]]
61
+ end
62
+
63
+ def followee(user_id)
64
+ @users.select("follower:#{user_id}")
65
+ end
66
+ end
67
+ 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.3.0
4
+ version: 0.4.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-09 00:00:00.000000000 Z
11
+ date: 2014-01-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -79,6 +79,7 @@ files:
79
79
  - .gitignore
80
80
  - .travis.yml
81
81
  - Gemfile
82
+ - HISTORY.md
82
83
  - LICENSE.txt
83
84
  - README.md
84
85
  - Rakefile
@@ -86,13 +87,14 @@ files:
86
87
  - lib/grn_mini.rb
87
88
  - lib/grn_mini/array.rb
88
89
  - lib/grn_mini/hash.rb
90
+ - lib/grn_mini/table.rb
89
91
  - lib/grn_mini/util.rb
90
92
  - lib/grn_mini/version.rb
91
- - sample/mini-directory-search.rb
92
93
  - test/minitest_helper.rb
93
94
  - test/test_grn_mini.rb
94
95
  - test/test_grn_mini_array.rb
95
96
  - test/test_grn_mini_hash.rb
97
+ - test/test_micro_blog.rb
96
98
  homepage: ''
97
99
  licenses:
98
100
  - MIT
@@ -122,3 +124,4 @@ test_files:
122
124
  - test/test_grn_mini.rb
123
125
  - test/test_grn_mini_array.rb
124
126
  - test/test_grn_mini_hash.rb
127
+ - test/test_micro_blog.rb
@@ -1,153 +0,0 @@
1
- require 'grn_mini'
2
- require 'find'
3
- require 'kconv'
4
- require 'sinatra'
5
- require "sinatra/reloader" if ENV['SINATRA_RELOADER']
6
-
7
- module Input
8
- module_function
9
-
10
- def from_dir(array, dir = ".")
11
- index = 1
12
- puts "Create database .."
13
- Find.find(File.expand_path(dir)) do |filename|
14
- Find.prune if ignore_dir?(filename)
15
-
16
- if File.file? filename
17
- next if ignore_file?(filename)
18
- array << {filename: filename, text: read_file(filename), timestamp: File.stat(filename).mtime, suffix: File.extname(filename).sub('.', "")}
19
- index += 1
20
- end
21
- end
22
- puts "Input complete : #{array.size} files"
23
- end
24
-
25
- def read_file(filename)
26
- text = File.read(filename)
27
- Kconv.kconv(text, Kconv::UTF8).gsub("\r\n", "\n")
28
- end
29
-
30
- def ignore_dir?(filename)
31
- basename = File.basename(filename)
32
- /(\A\.svn\Z)|(\A\.git\Z)|(\ACVS\Z)/.match(basename)
33
- end
34
-
35
- def ignore_file?(filename)
36
- (s = File.read(filename, 1024)) && s.index("\x00")
37
- end
38
- end
39
-
40
- class Search
41
- def initialize(array, params)
42
- @array = array
43
- @params = params
44
- @page = @params[:page] ? @params[:page].to_i : 1
45
- end
46
-
47
- def has_query?
48
- @params[:query] && !@params[:query].empty?
49
- end
50
-
51
- def parse
52
- unless has_query?
53
- @header = "<span>#{@array.size} files.</span>"
54
- @content = ""
55
- @pagination = ""
56
- else
57
- results = @array.select(@params[:query])
58
-
59
- page_entries = results.paginate([["_score", :desc]], :page => @page, :size => 20)
60
- snippet = GrnMini::Util::html_snippet_from_selection_results(results, "<strong style=\"background-color: #FFEE55\">", "</strong>")
61
- elements = []
62
-
63
- page_entries.each do |record|
64
- element = "<hr>\n<a href=\"/#{record.value.key.id}\">#{record.filename}</a>\n"
65
-
66
- snippet.execute(record.text).each do |segment|
67
- element += "<pre style=\"border:1px solid #bbb;\">#{segment}</pre>\n"
68
- end
69
-
70
- elements << element
71
- end
72
-
73
- @header = "<span>#{page_entries.n_records} hit. (#{page_entries.start_offset} - #{page_entries.end_offset})</span>"
74
- @content = elements.join("\n")
75
-
76
- if page_entries.n_pages > 1
77
- @pagination += page_link(@page - 1, "&lt;-") + "&nbsp;" if @page > 1
78
-
79
- @pagination += page_range(page_entries).map {|v|
80
- if (v == @page)
81
- "<strong>#{v.to_s}</strong>"
82
- else
83
- page_link(v, v.to_s)
84
- end
85
- }.join("&nbsp;")
86
-
87
- @pagination += "&nbsp;" + page_link(@page + 1, "-&gt;") if @page < page_entries.n_pages
88
- end
89
- end
90
- end
91
-
92
- def page_range(page_entries)
93
- first_diff = [5 - (@page - 1), 0].max
94
- last_diff = [5 - (page_entries.n_pages - @page), 0].max
95
- [@page - 5 - last_diff, 1].max .. [@page + 5 + first_diff, page_entries.n_pages].min
96
- end
97
-
98
- def page_link(page, msg)
99
- "<a href=\"/?query=#{@params[:query]}&page=#{page}\">#{msg}</a>"
100
- end
101
-
102
- def html
103
- <<EOF
104
- #{@header}
105
- <div class="form">
106
- <form method="post" action="/search">
107
- <input type="text" style="width: 419px;" name="query" value="#{@params[:query]}">
108
- <input type="submit" value="Search">
109
- </form>
110
- </div>
111
- <div class="content">
112
- #{@content}
113
- </div>
114
- <div class="pagination">
115
- #{@pagination}
116
- </div>
117
- EOF
118
- end
119
- end
120
-
121
- ### main ###
122
- configure do
123
- $array = GrnMini::Array.new("mini-directory-search.db")
124
- Input.from_dir($array) if $array.empty?
125
- end
126
-
127
- get '/' do
128
- search = Search.new($array, params)
129
- search.parse
130
- search.html
131
- end
132
-
133
- get '/:id' do
134
- record = $array[params[:id].to_i]
135
-
136
- <<EOF
137
- <span>#{record.filename} (#{record.timestamp})</span>
138
- <div class="form">
139
- <form method="post" action="/search">
140
- <input type="text" style="width: 419px;" name="query" value="#{@params[:query]}">
141
- <input type="submit" value="Search">
142
- </form>
143
- </div>
144
- <div class="content">
145
- <hr>
146
- <pre>#{CGI.escapeHTML(record.text)}</pre>
147
- </div>
148
- EOF
149
- end
150
-
151
- post '/search' do
152
- redirect "/?query=#{escape(params[:query])}"
153
- end