groonga 0.0.2 → 0.0.3

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 (54) hide show
  1. data/NEWS.ja.rdoc +18 -3
  2. data/NEWS.rdoc +18 -3
  3. data/README.ja.rdoc +2 -0
  4. data/README.rdoc +2 -0
  5. data/Rakefile +14 -5
  6. data/TUTORIAL.ja.rdoc +82 -16
  7. data/benchmark/{read-write-small-many-items.rb → read-write-many-small-items.rb} +26 -23
  8. data/benchmark/{write-small-many-items.rb → write-many-small-items.rb} +26 -23
  9. data/example/bookmark.rb +49 -5
  10. data/ext/rb-grn-array.c +11 -1
  11. data/ext/rb-grn-column.c +132 -5
  12. data/ext/rb-grn-context.c +85 -80
  13. data/ext/rb-grn-database.c +182 -9
  14. data/ext/rb-grn-expression-builder.c +69 -0
  15. data/ext/rb-grn-expression.c +314 -0
  16. data/ext/rb-grn-fix-size-column.c +68 -89
  17. data/ext/rb-grn-hash.c +14 -5
  18. data/ext/rb-grn-index-column.c +14 -55
  19. data/ext/rb-grn-object.c +206 -75
  20. data/ext/rb-grn-operation.c +92 -0
  21. data/ext/rb-grn-patricia-trie.c +10 -32
  22. data/ext/rb-grn-query.c +9 -9
  23. data/ext/rb-grn-table-cursor.c +19 -80
  24. data/ext/rb-grn-table-key-support.c +33 -39
  25. data/ext/rb-grn-table.c +436 -79
  26. data/ext/rb-grn-type.c +10 -3
  27. data/ext/rb-grn-utils.c +131 -4
  28. data/ext/rb-grn-variable-size-column.c +36 -0
  29. data/ext/rb-grn-variable.c +90 -0
  30. data/ext/rb-grn.h +109 -56
  31. data/ext/rb-groonga.c +4 -0
  32. data/extconf.rb +39 -13
  33. data/html/index.html +2 -2
  34. data/lib/groonga.rb +22 -0
  35. data/lib/groonga/expression-builder.rb +141 -0
  36. data/lib/groonga/record.rb +25 -1
  37. data/lib/groonga/schema.rb +418 -0
  38. data/test/test-column.rb +11 -23
  39. data/test/test-context.rb +1 -1
  40. data/test/test-database.rb +60 -19
  41. data/test/test-expression-builder.rb +114 -0
  42. data/test/test-expression.rb +55 -0
  43. data/test/test-fix-size-column.rb +53 -0
  44. data/test/test-hash.rb +10 -3
  45. data/test/test-index-column.rb +24 -0
  46. data/test/test-patricia-trie.rb +9 -0
  47. data/test/test-procedure.rb +5 -5
  48. data/test/test-record.rb +71 -4
  49. data/test/test-schema.rb +207 -0
  50. data/test/test-table.rb +94 -12
  51. data/test/test-type.rb +18 -11
  52. data/test/test-variable-size-column.rb +53 -0
  53. data/test/test-variable.rb +28 -0
  54. metadata +18 -5
@@ -19,11 +19,11 @@ class ProcedureTest < Test::Unit::TestCase
19
19
  setup :setup_database
20
20
 
21
21
  def test_builtins
22
- assert_equal_procedure("<token:delimit>", Groonga::Procedure::DELIMIT)
23
- assert_equal_procedure("<token:unigram>", Groonga::Procedure::UNIGRAM)
24
- assert_equal_procedure("<token:bigram>", Groonga::Procedure::BIGRAM)
25
- assert_equal_procedure("<token:trigram>", Groonga::Procedure::TRIGRAM)
26
- assert_equal_procedure("<token:mecab>", Groonga::Procedure::MECAB)
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
27
  end
28
28
 
29
29
  private
data/test/test-record.rb CHANGED
@@ -63,6 +63,10 @@ class RecordTest < Test::Unit::TestCase
63
63
  @bookmarks_uri = @bookmarks.define_column("uri", "<shorttext>",
64
64
  :path => @uri_column_path.to_s)
65
65
 
66
+ @rate_column_path = @columns_dir + "rate"
67
+ @bookmarks_rate = @bookmarks.define_column("rate", "<int>",
68
+ :path => @rate_column_path.to_s)
69
+
66
70
  @comment_column_path = @columns_dir + "comment"
67
71
  @bookmarks_comment =
68
72
  @bookmarks.define_column("comment", "<text>",
@@ -80,11 +84,11 @@ class RecordTest < Test::Unit::TestCase
80
84
  @bookmarks_index =
81
85
  Groonga::PatriciaTrie.create(:name => "bookmarks-index",
82
86
  :path => @bookmarks_index_path.to_s)
83
- @bookmarks_index.default_tokenizer = "<token:bigram>"
87
+ @bookmarks_index.default_tokenizer = "TokenBigram"
84
88
 
85
89
  @content_index_column_path = @columns_dir + "content-index"
86
90
  @bookmarks_content_index =
87
- @bookmarks_index.define_index_column("<index:content>", @bookmarks,
91
+ @bookmarks_index.define_index_column("content", @bookmarks,
88
92
  :with_section => true,
89
93
  :with_weight => true,
90
94
  :with_position => true,
@@ -93,7 +97,7 @@ class RecordTest < Test::Unit::TestCase
93
97
 
94
98
  @uri_index_column_path = @columns_dir + "uri-index"
95
99
  @bookmarks_uri_index =
96
- @bookmarks_index.define_index_column("<index:uri>", @bookmarks,
100
+ @bookmarks_index.define_index_column("uri", @bookmarks,
97
101
  :with_position => true,
98
102
  :path => @uri_index_column_path.to_s)
99
103
  @bookmarks_uri_index.source = @bookmarks_uri
@@ -117,7 +121,9 @@ class RecordTest < Test::Unit::TestCase
117
121
 
118
122
  def test_get_nonexistent_column
119
123
  groonga = @bookmarks.add
120
- assert_nil(groonga["nonexistent"])
124
+ assert_raise(Groonga::Error) do
125
+ groonga["nonexistent"]
126
+ end
121
127
  end
122
128
 
123
129
  def test_set_nonexistent_column
@@ -185,4 +191,65 @@ class RecordTest < Test::Unit::TestCase
185
191
  [record.id, record.score]
186
192
  end)
187
193
  end
194
+
195
+ def test_increment!
196
+ groonga = @bookmarks.add
197
+ assert_equal(0, groonga["rate"])
198
+ groonga.increment!("rate")
199
+ assert_equal(1, groonga["rate"])
200
+ groonga.increment!("rate", 2)
201
+ assert_equal(3, groonga["rate"])
202
+ groonga.increment!("rate", -2)
203
+ assert_equal(1, groonga["rate"])
204
+ end
205
+
206
+ def test_decrement!
207
+ groonga = @bookmarks.add
208
+ assert_equal(0, groonga["rate"])
209
+ groonga.decrement!("rate")
210
+ assert_equal(-1, groonga["rate"])
211
+ groonga.decrement!("rate", 2)
212
+ assert_equal(-3, groonga["rate"])
213
+ groonga.decrement!("rate", -2)
214
+ assert_equal(-1, groonga["rate"])
215
+ end
216
+
217
+ def test_lock
218
+ groonga = @bookmarks.add
219
+
220
+ assert_not_predicate(groonga, :locked?)
221
+ groonga.lock
222
+ assert_predicate(groonga, :locked?)
223
+ groonga.unlock
224
+ assert_not_predicate(groonga, :locked?)
225
+ end
226
+
227
+ def test_lock_failed
228
+ groonga = @bookmarks.add
229
+
230
+ groonga.lock
231
+ assert_raise(Groonga::ResourceDeadlockAvoided) do
232
+ groonga.lock
233
+ end
234
+ end
235
+
236
+ def test_lock_block
237
+ groonga = @bookmarks.add
238
+
239
+ assert_not_predicate(groonga, :locked?)
240
+ groonga.lock do
241
+ assert_predicate(groonga, :locked?)
242
+ end
243
+ assert_not_predicate(groonga, :locked?)
244
+ end
245
+
246
+ def test_clear_lock
247
+ groonga = @bookmarks.add
248
+
249
+ assert_not_predicate(groonga, :locked?)
250
+ groonga.lock
251
+ assert_predicate(groonga, :locked?)
252
+ groonga.clear_lock
253
+ assert_not_predicate(groonga, :locked?)
254
+ end
188
255
  end
@@ -0,0 +1,207 @@
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 SchemaTest < Test::Unit::TestCase
17
+ include GroongaTestUtils
18
+
19
+ setup :setup_database
20
+
21
+ def test_create_table
22
+ assert_nil(context["<posts>"])
23
+ Groonga::Schema.create_table("<posts>") do |table|
24
+ end
25
+ assert_not_nil(context["<posts>"])
26
+ end
27
+
28
+ def test_define_hash
29
+ Groonga::Schema.create_table("<posts>", :type => :hash) do |table|
30
+ end
31
+ assert_kind_of(Groonga::Hash, context["<posts>"])
32
+ end
33
+
34
+ def test_define_hash_with_full_option
35
+ path = @tmp_dir + "hash.groonga"
36
+ tokenizer = context["<token:trigram>"]
37
+ Groonga::Schema.create_table("<posts>",
38
+ :type => :hash,
39
+ :key_type => "integer",
40
+ :path => path.to_s,
41
+ :value_size => 29,
42
+ :default_tokenizer => tokenizer) do |table|
43
+ end
44
+ table = context["<posts>"]
45
+ assert_equal("#<Groonga::Hash " +
46
+ "id: <#{table.id}>, " +
47
+ "name: <<posts>>, " +
48
+ "path: <#{path}>, " +
49
+ "domain: <#{context['<int>'].inspect}>, " +
50
+ "range: <nil>, " +
51
+ "encoding: <#{Groonga::Encoding.default.inspect}>, " +
52
+ "size: <0>>",
53
+ table.inspect)
54
+ assert_equal(tokenizer, table.default_tokenizer)
55
+ end
56
+
57
+ def test_define_patricia_trie
58
+ Groonga::Schema.create_table("<posts>", :type => :patricia_trie) do |table|
59
+ end
60
+ assert_kind_of(Groonga::PatriciaTrie, context["<posts>"])
61
+ end
62
+
63
+ def test_define_patricia_trie_with_full_option
64
+ path = @tmp_dir + "patricia-trie.groonga"
65
+ Groonga::Schema.create_table("<posts>",
66
+ :type => :patricia_trie,
67
+ :key_type => "integer",
68
+ :path => path.to_s,
69
+ :value_size => 29,
70
+ :default_tokenizer => "<token:bigram>",
71
+ :key_normalize => true,
72
+ :key_with_sis => true) do |table|
73
+ end
74
+ table = context["<posts>"]
75
+ assert_equal("#<Groonga::PatriciaTrie " +
76
+ "id: <#{table.id}>, " +
77
+ "name: <<posts>>, " +
78
+ "path: <#{path}>, " +
79
+ "domain: <#{context['<int>'].inspect}>, " +
80
+ "range: <nil>, " +
81
+ "encoding: <#{Groonga::Encoding.default.inspect}>, " +
82
+ "size: <0>>",
83
+ table.inspect)
84
+ assert_equal(context["<token:bigram>"], table.default_tokenizer)
85
+ end
86
+
87
+ def test_define_array
88
+ Groonga::Schema.create_table("<posts>", :type => :array) do |table|
89
+ end
90
+ assert_kind_of(Groonga::Array, context["<posts>"])
91
+ end
92
+
93
+ def test_define_array_with_full_option
94
+ path = @tmp_dir + "array.groonga"
95
+ Groonga::Schema.create_table("<posts>",
96
+ :type => :array,
97
+ :path => path.to_s,
98
+ :value_size => 29) do |table|
99
+ end
100
+ table = context["<posts>"]
101
+ assert_equal("#<Groonga::Array " +
102
+ "id: <#{table.id}>, " +
103
+ "name: <<posts>>, " +
104
+ "path: <#{path}>, " +
105
+ "domain: <nil>, " +
106
+ "range: <nil>, " +
107
+ "size: <0>>",
108
+ table.inspect)
109
+ end
110
+
111
+ def test_integer32_column
112
+ assert_nil(context["<posts>.rate"])
113
+ Groonga::Schema.create_table("<posts>") do |table|
114
+ table.integer32 :rate
115
+ end
116
+ assert_equal(context["<int>"], context["<posts>.rate"].range)
117
+ end
118
+
119
+ def test_integer64_column
120
+ assert_nil(context["<posts>.rate"])
121
+ Groonga::Schema.create_table("<posts>") do |table|
122
+ table.integer64 :rate
123
+ end
124
+ assert_equal(context["<int64>"], context["<posts>.rate"].range)
125
+ end
126
+
127
+ def test_unsigned_integer32_column
128
+ assert_nil(context["<posts>.n_viewed"])
129
+ Groonga::Schema.create_table("<posts>") do |table|
130
+ table.unsigned_integer32 :n_viewed
131
+ end
132
+ assert_equal(context["<uint>"], context["<posts>.n_viewed"].range)
133
+ end
134
+
135
+ def test_unsigned_integer64_column
136
+ assert_nil(context["<posts>.n_viewed"])
137
+ Groonga::Schema.create_table("<posts>") do |table|
138
+ table.unsigned_integer64 :n_viewed
139
+ end
140
+ assert_equal(context["<uint64>"], context["<posts>.n_viewed"].range)
141
+ end
142
+
143
+ def test_float_column
144
+ assert_nil(context["<posts>.rate"])
145
+ Groonga::Schema.create_table("<posts>") do |table|
146
+ table.float :rate
147
+ end
148
+ assert_equal(context["<float>"], context["<posts>.rate"].range)
149
+ end
150
+
151
+ def test_time_column
152
+ assert_nil(context["<posts>.last_modified"])
153
+ Groonga::Schema.create_table("<posts>") do |table|
154
+ table.time :last_modified
155
+ end
156
+ assert_equal(context["<time>"], context["<posts>.last_modified"].range)
157
+ end
158
+
159
+ def test_short_text_column
160
+ assert_nil(context["<posts>.title"])
161
+ Groonga::Schema.create_table("<posts>") do |table|
162
+ table.short_text :title
163
+ end
164
+ assert_equal(context["<shorttext>"], context["<posts>.title"].range)
165
+ end
166
+
167
+ def test_text_column
168
+ assert_nil(context["<posts>.comment"])
169
+ Groonga::Schema.create_table("<posts>") do |table|
170
+ table.text :comment
171
+ end
172
+ assert_equal(context["<text>"], context["<posts>.comment"].range)
173
+ end
174
+
175
+ def test_long_text_column
176
+ assert_nil(context["<posts>.content"])
177
+ Groonga::Schema.create_table("<posts>") do |table|
178
+ table.long_text :content
179
+ end
180
+ assert_equal(context["<longtext>"], context["<posts>.content"].range)
181
+ end
182
+
183
+ def test_index
184
+ assert_nil(context["<terms>.content"])
185
+ Groonga::Schema.create_table("<posts>") do |table|
186
+ table.long_text :content
187
+ end
188
+ Groonga::Schema.create_table("<terms>") do |table|
189
+ table.index :posts_content, "<posts>.content"
190
+ end
191
+ assert_equal([context["<posts>.content"]],
192
+ context["<terms>.posts_content"].sources)
193
+ end
194
+
195
+ def test_dump
196
+ Groonga::Schema.define do |schema|
197
+ schema.create_table("<posts>") do |table|
198
+ table.short_text :title
199
+ end
200
+ end
201
+ assert_equal(<<-EOS, Groonga::Schema.dump)
202
+ create_table("<posts>") do |table|
203
+ table.short_text("title")
204
+ end
205
+ EOS
206
+ end
207
+ end
data/test/test-table.rb CHANGED
@@ -326,10 +326,21 @@ class TableTest < Test::Unit::TestCase
326
326
  },
327
327
  ],
328
328
  :limit => 20)
329
- results = results.records(:order => :ascending).collect do |record|
330
- id_column[record.value.unpack("i")[0]]
329
+ assert_equal((180..199).to_a.reverse,
330
+ results.collect {|record| record["id"]})
331
+ end
332
+
333
+ def test_sort_simple
334
+ bookmarks = Groonga::Array.create(:name => "<bookmarks>")
335
+ id_column = bookmarks.define_column("id", "<int>")
336
+ 100.times do |i|
337
+ bookmark = bookmarks.add
338
+ bookmark["id"] = i + 100
331
339
  end
332
- assert_equal((180..199).to_a.reverse, results)
340
+
341
+ results = bookmarks.sort(["id"], :limit => 20)
342
+ assert_equal((100..119).to_a,
343
+ results.collect {|record| record["id"]})
333
344
  end
334
345
 
335
346
  def test_sort_without_limit
@@ -340,15 +351,86 @@ class TableTest < Test::Unit::TestCase
340
351
  bookmark["id"] = i + 100
341
352
  end
342
353
 
343
- results = bookmarks.sort([
344
- {
345
- :key => "id",
346
- :order => :descending,
347
- },
348
- ])
349
- results = results.records(:order => :ascending).collect do |record|
350
- id_column[record.value.unpack("i")[0]]
354
+ results = bookmarks.sort([{:key => "id", :order => :descending}])
355
+ assert_equal((100..199).to_a.reverse,
356
+ results.collect {|record| record["id"]})
357
+ end
358
+
359
+ def test_group
360
+ bookmarks = Groonga::Hash.create(:name => "<bookmarks>")
361
+ bookmarks.define_column("title", "<text>")
362
+ comments = Groonga::Array.create(:name => "<comments>")
363
+ comments.define_column("bookmark", bookmarks)
364
+ comments.define_column("content", "Text")
365
+ comments.define_column("issued", "Int32")
366
+
367
+ groonga = bookmarks.add("http://groonga.org/", :title => "groonga")
368
+ ruby = bookmarks.add("http://ruby-lang.org/", :title => "Ruby")
369
+
370
+ now = Time.now.to_i
371
+ comments.add(:bookmark => groonga,
372
+ :content => "full-text search",
373
+ :issued => now)
374
+ comments.add(:bookmark => groonga,
375
+ :content => "column store",
376
+ :issued => now)
377
+ comments.add(:bookmark => ruby,
378
+ :content => "object oriented script language",
379
+ :issued => now)
380
+
381
+ records = comments.select do |record|
382
+ record["issued"] > 0
383
+ end
384
+ assert_equal([[2, "groonga", "http://groonga.org/"],
385
+ [1, "Ruby", "http://ruby-lang.org/"]],
386
+ records.group([".bookmark"]).collect do |record|
387
+ bookmark = record.key
388
+ [record[".:nsubrecs"],
389
+ bookmark["title"],
390
+ bookmark.key]
391
+ end)
392
+ end
393
+
394
+ def test_lock
395
+ bookmarks = Groonga::Array.create(:name => "<bookmarks>")
396
+ bookmark = bookmarks.add
397
+
398
+ assert_not_predicate(bookmarks, :locked?)
399
+ bookmarks.lock
400
+ assert_predicate(bookmarks, :locked?)
401
+ bookmarks.unlock
402
+ assert_not_predicate(bookmarks, :locked?)
403
+ end
404
+
405
+ def test_lock_failed
406
+ bookmarks = Groonga::Array.create(:name => "<bookmarks>")
407
+ bookmark = bookmarks.add
408
+
409
+ bookmarks.lock
410
+ assert_raise(Groonga::ResourceDeadlockAvoided) do
411
+ bookmarks.lock
351
412
  end
352
- assert_equal((100..199).to_a.reverse, results)
413
+ end
414
+
415
+ def test_lock_block
416
+ bookmarks = Groonga::Array.create(:name => "<bookmarks>")
417
+ bookmark = bookmarks.add
418
+
419
+ assert_not_predicate(bookmarks, :locked?)
420
+ bookmarks.lock do
421
+ assert_predicate(bookmarks, :locked?)
422
+ end
423
+ assert_not_predicate(bookmarks, :locked?)
424
+ end
425
+
426
+ def test_clear_lock
427
+ bookmarks = Groonga::Array.create(:name => "<bookmarks>")
428
+ bookmark = bookmarks.add
429
+
430
+ assert_not_predicate(bookmarks, :locked?)
431
+ bookmarks.lock
432
+ assert_predicate(bookmarks, :locked?)
433
+ bookmarks.clear_lock
434
+ assert_not_predicate(bookmarks, :locked?)
353
435
  end
354
436
  end