ruby-tokyotyrant 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.
- data/COPYING +504 -0
- data/README.rdoc +204 -0
- data/Rakefile +68 -0
- data/benchmarks/bulk_db.rb +74 -0
- data/benchmarks/bulk_table.rb +87 -0
- data/benchmarks/db.rb +114 -0
- data/benchmarks/table.rb +161 -0
- data/ext/extconf.rb +39 -0
- data/ext/tokyo_tyrant.c +147 -0
- data/ext/tokyo_tyrant.h +48 -0
- data/ext/tokyo_tyrant_db.c +227 -0
- data/ext/tokyo_tyrant_db.h +8 -0
- data/ext/tokyo_tyrant_module.c +453 -0
- data/ext/tokyo_tyrant_module.h +10 -0
- data/ext/tokyo_tyrant_query.c +226 -0
- data/ext/tokyo_tyrant_query.h +9 -0
- data/ext/tokyo_tyrant_table.c +319 -0
- data/ext/tokyo_tyrant_table.h +8 -0
- data/spec/ext.lua +4 -0
- data/spec/plu_db.rb +538 -0
- data/spec/spec.rb +1 -0
- data/spec/spec_base.rb +16 -0
- data/spec/start_tyrants.sh +36 -0
- data/spec/stop_tyrants.sh +9 -0
- data/spec/tokyo_tyrant_query_spec.rb +159 -0
- data/spec/tokyo_tyrant_spec.rb +254 -0
- data/spec/tokyo_tyrant_table_spec.rb +301 -0
- metadata +80 -0
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
require 'pathname'
|
|
2
|
+
require Pathname(__FILE__).dirname.join('spec_base') unless $root
|
|
3
|
+
|
|
4
|
+
describe TokyoTyrant::Table, "with an open database" do
|
|
5
|
+
|
|
6
|
+
before do
|
|
7
|
+
@db = TokyoTyrant::Table.new('127.0.0.1', 45001)
|
|
8
|
+
@db.clear
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "should not be nil" do
|
|
12
|
+
@db.should.not.be.nil
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "should close" do
|
|
16
|
+
@db.close.should.be.true
|
|
17
|
+
begin
|
|
18
|
+
@db.close
|
|
19
|
+
rescue => e
|
|
20
|
+
e.message.should == 'close error: invalid operation'
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "should return a server expression" do
|
|
25
|
+
@db.server.should == '127.0.0.1:45001'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "should optimize" do
|
|
29
|
+
@db.optimize.should.be.true
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "should save a value" do
|
|
33
|
+
value = { 'lettuce' => 'Red Leaf', 'dressing' => 'ranch', 'extra' => 'bacon bits' }
|
|
34
|
+
@db[:salad] = value
|
|
35
|
+
@db[:salad].should == value
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "should return a value" do
|
|
39
|
+
value = { 'lettuce' => 'Red Leaf', 'dressing' => 'ranch', 'extra' => 'bacon bits' }
|
|
40
|
+
@db[:salad] = value
|
|
41
|
+
@db[:salad].should == value
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "should accept binary data" do
|
|
45
|
+
s = "mango#{0.chr}salsa"
|
|
46
|
+
h = { s => s }
|
|
47
|
+
@db.put(s, h).should.be.true
|
|
48
|
+
@db[s].should.equal(h)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "should save multiple values" do
|
|
52
|
+
h = { 'pizza' => { 'best' => 'old forge style', 'ok' => 'new york style', 'worst' => 'chicago style' },
|
|
53
|
+
'sandwich' => { 'best' => 'peanut butter jelly', 'ok' => 'turkey', 'worst' => 'olive loaf' },
|
|
54
|
+
'yogurt' => { 'best' => 'greek', 'ok' => 'organic', 'worst' => '+hfcs' },
|
|
55
|
+
'coffee' => { 'best' => 'black', 'ok' => 'espresso', 'worst' => 'latte' } }
|
|
56
|
+
|
|
57
|
+
@db.mput(h).should.be.empty
|
|
58
|
+
h.each_pair do |k,v|
|
|
59
|
+
@db[k].should == v
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "should delete multiple values" do
|
|
64
|
+
h = { 'pizza' => { 'best' => 'old forge style', 'ok' => 'new york style', 'worst' => 'chicago style' },
|
|
65
|
+
'sandwich' => { 'best' => 'peanut butter jelly', 'ok' => 'turkey', 'worst' => 'olive loaf' },
|
|
66
|
+
'yogurt' => { 'best' => 'greek', 'ok' => 'organic', 'worst' => '+hfcs' },
|
|
67
|
+
'coffee' => { 'best' => 'black', 'ok' => 'espresso', 'worst' => 'latte' } }
|
|
68
|
+
|
|
69
|
+
@db.mput(h)
|
|
70
|
+
@db.outlist('coffee', 'yogurt').should.be.empty
|
|
71
|
+
@db.keys.sort.should == ['pizza','sandwich']
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it "should get multiple values" do
|
|
75
|
+
h = { 'pizza' => { 'best' => 'old forge style', 'ok' => 'new york style', 'worst' => 'chicago style' },
|
|
76
|
+
'sandwich' => { 'best' => 'peanut butter jelly', 'ok' => 'turkey', 'worst' => 'olive loaf' },
|
|
77
|
+
'yogurt' => { 'best' => 'greek', 'ok' => 'organic', 'worst' => '+hfcs' },
|
|
78
|
+
'coffee' => { 'best' => 'black', 'ok' => 'espresso', 'worst' => 'latte' } }
|
|
79
|
+
|
|
80
|
+
@db.mput(h)
|
|
81
|
+
@db.mget(h.keys).should == h
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
it "should out a value" do
|
|
85
|
+
k = :tomato
|
|
86
|
+
@db[k] = { 'color' => 'red', 'variety' => 'beefy' }
|
|
87
|
+
@db.out(k).should.be.true
|
|
88
|
+
@db[k].should.be.nil
|
|
89
|
+
@db.out(k).should.be.false
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it "should check a key" do
|
|
93
|
+
k = :fruit
|
|
94
|
+
@db[k] = { 'name' => 'banana', 'code' => '4011' }
|
|
95
|
+
@db.check(k).should.be.true
|
|
96
|
+
@db.out(k)
|
|
97
|
+
@db.check(k).should.be.false
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
it "should iterate" do
|
|
101
|
+
@db[:cheese] = { 'melty' => 'gouda', 'sharp' => 'cheddar', 'stringy' => 'mozerella' }
|
|
102
|
+
@db[:grapes] = { 'sour' => 'green', 'big' => 'red', 'wine' => 'purple' }
|
|
103
|
+
@db[:oranges] = { 'juicy' => 'florida', 'yellow' => 'california' }
|
|
104
|
+
@db[:crackers] = { 'wheat' => 'triscuit', 'snack' => 'ritz', 'soup' => 'saltine' }
|
|
105
|
+
|
|
106
|
+
@db.iterinit.should.be.true
|
|
107
|
+
@db.iternext.should == 'cheese'
|
|
108
|
+
@db.iternext.should == 'grapes'
|
|
109
|
+
@db.iternext.should == 'oranges'
|
|
110
|
+
@db.iternext.should == 'crackers'
|
|
111
|
+
@db.iternext.should == nil
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it "should get forward matching keys" do
|
|
115
|
+
@db['apples/royalgala'] = { 'code' => '4173', 'color' => 'red-yellow' }
|
|
116
|
+
@db['apples/grannysmith'] = { 'code' => '4139', 'color' => 'green' }
|
|
117
|
+
@db['bananas/yellow'] = { 'code' => '4011', 'color' => 'yellow' }
|
|
118
|
+
@db['oranges/shamouti'] = { 'code' => '3027', 'color' => 'orange' }
|
|
119
|
+
@db['grapefruit/deepred'] = { 'code' => '4288', 'color' => 'yellow/pink' }
|
|
120
|
+
@db.fwmkeys('apples').sort.should == ["apples/grannysmith", "apples/royalgala"]
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "should delete forward matching keys" do
|
|
124
|
+
@db['apples/royalgala'] = { 'code' => '4173', 'color' => 'red-yellow' }
|
|
125
|
+
@db['apples/grannysmith'] = { 'code' => '4139', 'color' => 'green' }
|
|
126
|
+
@db['bananas/yellow'] = { 'code' => '4011', 'color' => 'yellow' }
|
|
127
|
+
@db['oranges/shamouti'] = { 'code' => '3027', 'color' => 'orange' }
|
|
128
|
+
@db['grapefruit/deepred'] = { 'code' => '4288', 'color' => 'yellow/pink' }
|
|
129
|
+
@db.delete_keys_with_prefix('apples').should == nil
|
|
130
|
+
@db.fwmkeys('apples').should.be.empty
|
|
131
|
+
@db.keys.sort.should == ['bananas/yellow', 'grapefruit/deepred', 'oranges/shamouti']
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it "should get all keys" do
|
|
135
|
+
keys = %w[appetizers entree dessert]
|
|
136
|
+
values = [{ 'cheap' => 'chips', 'expensive' => 'sample everything platter' },
|
|
137
|
+
{ 'cheap' => 'hoagie', 'expensive' => 'steak' },
|
|
138
|
+
{ 'cheap' => 'water ice', 'expensive' => 'cheesecake' }]
|
|
139
|
+
|
|
140
|
+
keys.each_with_index do |k,i|
|
|
141
|
+
@db[k] = values[i]
|
|
142
|
+
end
|
|
143
|
+
@db.keys.should == keys
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
it "should get all values" do
|
|
147
|
+
keys = %w[appetizers entree dessert]
|
|
148
|
+
values = [{ 'cheap' => 'chips', 'expensive' => 'sample everything platter' },
|
|
149
|
+
{ 'cheap' => 'hoagie', 'expensive' => 'steak' },
|
|
150
|
+
{ 'cheap' => 'water ice', 'expensive' => 'cheesecake' }]
|
|
151
|
+
|
|
152
|
+
keys.each_with_index do |k,i|
|
|
153
|
+
@db[k] = values[i]
|
|
154
|
+
end
|
|
155
|
+
@db.values.should == values
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
it "should vanish all records" do
|
|
159
|
+
@db['chocolate'] = { 'type' => 'dark' }
|
|
160
|
+
@db['tea'] = { 'type' => 'earl grey' }
|
|
161
|
+
@db.empty?.should.be.false
|
|
162
|
+
@db.vanish.should.be.true
|
|
163
|
+
@db.empty?.should.be.true
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
it "should count records" do
|
|
167
|
+
@db['hummus'] = { 'ingredients' => 'chickpeas,garlic' }
|
|
168
|
+
@db['falafel'] = { 'ingredients' => 'chickpeas,herbs' }
|
|
169
|
+
@db.rnum.should == 2
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
it "should report db size" do
|
|
173
|
+
@db['rootbeer'] = { 'gourmet' => 'Virgils', 'natural' => 'Hansens' }
|
|
174
|
+
@db.db_size.should.not == 0
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
it "should fetch a record" do
|
|
178
|
+
@db.out('beer')
|
|
179
|
+
@db.fetch('beer'){{ 'import' => 'heineken' }}.should == { 'import' => 'heineken' }
|
|
180
|
+
@db['beer'].should == { 'import' => 'heineken' }
|
|
181
|
+
@db.fetch('beer'){{ 'import' => 'becks' }}.should == { 'import' => 'heineken' }
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
it "should iterate through records" do
|
|
185
|
+
keys = %w[grapejuice tacoshells rice]
|
|
186
|
+
values = [{ 'purple' => 'Kedem', 'green' => 'Juicy Juice' },
|
|
187
|
+
{ 'crunchy' => 'Ortega', 'soft' => 'Taco Bell' },
|
|
188
|
+
{ 'brown' => 'Instant', 'white' => 'Uncle Ben' }]
|
|
189
|
+
keys.each_with_index{ |k,i| @db[k] = values[i] }
|
|
190
|
+
|
|
191
|
+
i = 0
|
|
192
|
+
@db.each do |k,v|
|
|
193
|
+
k.should == keys[i]
|
|
194
|
+
v.should == values[i]
|
|
195
|
+
i = i += 1
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
it "should iterate through keys" do
|
|
200
|
+
keys = %w[burritos fajitas tacos tostas enchiladas]
|
|
201
|
+
values = Array.new(keys.size, { 'tasty' => 'yes' })
|
|
202
|
+
keys.each_with_index{ |k,i| @db[k] = values[i] }
|
|
203
|
+
|
|
204
|
+
i = 0
|
|
205
|
+
@db.each_key do |k|
|
|
206
|
+
k.should == keys[i]
|
|
207
|
+
i = i += 1
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
it "should iterate through values" do
|
|
212
|
+
keys = %w[falafel humus couscous tabbouleh tzatziki]
|
|
213
|
+
values = [{ 'ingredient' => 'chickpeas' },
|
|
214
|
+
{ 'ingredient' => 'chickpeas' },
|
|
215
|
+
{ 'ingredient' => 'semolina' },
|
|
216
|
+
{ 'ingredient' => 'bulgar' },
|
|
217
|
+
{ 'ingredient' => 'yogurt' }]
|
|
218
|
+
|
|
219
|
+
keys.each_with_index{ |k,i| @db[k] = values[i] }
|
|
220
|
+
|
|
221
|
+
i = 0
|
|
222
|
+
@db.each_value do |v|
|
|
223
|
+
v.should == values[i]
|
|
224
|
+
i = i += 1
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
it "should add serialized integer values" do
|
|
229
|
+
key = 'counter'
|
|
230
|
+
@db.out(key)
|
|
231
|
+
@db[key] = { 'title' => 'Bean Counter' }
|
|
232
|
+
@db.add_int(key, 1).should == 1
|
|
233
|
+
@db.add_int(key, 1).should == 2
|
|
234
|
+
@db.get_int(key).should == 2
|
|
235
|
+
@db[key].should == { 'title' => 'Bean Counter', '_num' => "2" }
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
it "should increment integer values" do
|
|
239
|
+
key = 'counter'
|
|
240
|
+
@db.out(key)
|
|
241
|
+
@db[key] = { 'title' => 'Bean Counter' }
|
|
242
|
+
@db.increment(key).should == 1
|
|
243
|
+
@db.increment(key, 2).should == 3
|
|
244
|
+
@db.get_int(key).should == 3
|
|
245
|
+
@db[key].should == { 'title' => 'Bean Counter', '_num' => "3" }
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
it "should add serialized double values" do
|
|
249
|
+
key = 'counter'
|
|
250
|
+
@db.out(key)
|
|
251
|
+
@db[key] = { 'title' => 'Bean Counter' }
|
|
252
|
+
@db.add_double(key, 1.0).should.be.close?(1.0, 0.005)
|
|
253
|
+
@db.add_double(key, 1.0).should.be.close?(2.0, 0.005)
|
|
254
|
+
@db.get_double(key).should.be.close?(2.0, 0.005)
|
|
255
|
+
@db[key].should == { 'title' => 'Bean Counter', '_num' => "2" }
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
it "should set an index" do
|
|
259
|
+
key = 'counter'
|
|
260
|
+
50.times do |i|
|
|
261
|
+
@db["key#{i}"] = { 'title' => %w{rice beans corn}.sort_by{rand}.first,
|
|
262
|
+
'description' => 'a whole protein' }
|
|
263
|
+
end
|
|
264
|
+
@db.set_index('title', :lexical).should.be.true
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
it "should run lua extensions" do
|
|
268
|
+
@db.ext('echo', 'hello', 'world').should == "hello\tworld"
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
it "should perform meta search with multiple query objects" do
|
|
272
|
+
keys = %w[falafel humus couscous tabbouleh tzatziki peanutbutter]
|
|
273
|
+
values = [{ 'ingredient' => 'chickpeas' },
|
|
274
|
+
{ 'ingredient' => 'chickpeas' },
|
|
275
|
+
{ 'ingredient' => 'semolina' },
|
|
276
|
+
{ 'ingredient' => 'bulgar' },
|
|
277
|
+
{ 'ingredient' => 'yogurt' },
|
|
278
|
+
{ 'ingredient' => 'peanuts'}]
|
|
279
|
+
|
|
280
|
+
keys.each_with_index{ |k,i| @db[k] = values[i] }
|
|
281
|
+
|
|
282
|
+
query1 = @db.prepare_query{ |q| q.condition('ingredient', :streq, 'yogurt').order_by('ingredient') }
|
|
283
|
+
query2 = @db.prepare_query{ |q| q.condition('ingredient', :streq, 'chickpeas').order_by('ingredient') }
|
|
284
|
+
query3 = @db.prepare_query{ |q| q.condition('ingredient', :ftsex, 'pea').order_by('ingredient') }
|
|
285
|
+
|
|
286
|
+
@db.search(:union, query1, query2).should == ["falafel", "humus", "tzatziki"]
|
|
287
|
+
@db.search(:diff, query1, query2).should == ["tzatziki"]
|
|
288
|
+
@db.search(:intersection, query2, query3).should == ["falafel", "humus"]
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
it "should serialize objects that respond to to_tokyo_tyrant" do
|
|
292
|
+
class Thing
|
|
293
|
+
def to_tokyo_tyrant
|
|
294
|
+
"success"
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
@db["to_tokyo_tyrant"] = { "thing" => Thing.new }
|
|
299
|
+
@db["to_tokyo_tyrant"].should == { "thing" => "success" }
|
|
300
|
+
end
|
|
301
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: ruby-tokyotyrant
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.3.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Flinn
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
|
|
12
|
+
date: 2009-10-17 00:00:00 -04:00
|
|
13
|
+
default_executable:
|
|
14
|
+
dependencies: []
|
|
15
|
+
|
|
16
|
+
description:
|
|
17
|
+
email: flinn@actsasflinn.com
|
|
18
|
+
executables: []
|
|
19
|
+
|
|
20
|
+
extensions:
|
|
21
|
+
- ext/extconf.rb
|
|
22
|
+
extra_rdoc_files:
|
|
23
|
+
- README.rdoc
|
|
24
|
+
files:
|
|
25
|
+
- COPYING
|
|
26
|
+
- Rakefile
|
|
27
|
+
- README.rdoc
|
|
28
|
+
- ext/tokyo_tyrant.c
|
|
29
|
+
- ext/tokyo_tyrant.h
|
|
30
|
+
- ext/tokyo_tyrant_db.c
|
|
31
|
+
- ext/tokyo_tyrant_db.h
|
|
32
|
+
- ext/tokyo_tyrant_module.c
|
|
33
|
+
- ext/tokyo_tyrant_module.h
|
|
34
|
+
- ext/tokyo_tyrant_query.c
|
|
35
|
+
- ext/tokyo_tyrant_query.h
|
|
36
|
+
- ext/tokyo_tyrant_table.c
|
|
37
|
+
- ext/tokyo_tyrant_table.h
|
|
38
|
+
- spec/ext.lua
|
|
39
|
+
- spec/plu_db.rb
|
|
40
|
+
- spec/spec.rb
|
|
41
|
+
- spec/spec_base.rb
|
|
42
|
+
- spec/start_tyrants.sh
|
|
43
|
+
- spec/stop_tyrants.sh
|
|
44
|
+
- spec/tokyo_tyrant_query_spec.rb
|
|
45
|
+
- spec/tokyo_tyrant_spec.rb
|
|
46
|
+
- spec/tokyo_tyrant_table_spec.rb
|
|
47
|
+
- benchmarks/bulk_db.rb
|
|
48
|
+
- benchmarks/bulk_table.rb
|
|
49
|
+
- benchmarks/db.rb
|
|
50
|
+
- benchmarks/table.rb
|
|
51
|
+
has_rdoc: true
|
|
52
|
+
homepage: http://github.com/actsasflinn/ruby-tokyotyrant/
|
|
53
|
+
licenses: []
|
|
54
|
+
|
|
55
|
+
post_install_message:
|
|
56
|
+
rdoc_options: []
|
|
57
|
+
|
|
58
|
+
require_paths:
|
|
59
|
+
- ext
|
|
60
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
61
|
+
requirements:
|
|
62
|
+
- - ">="
|
|
63
|
+
- !ruby/object:Gem::Version
|
|
64
|
+
version: "0"
|
|
65
|
+
version:
|
|
66
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
67
|
+
requirements:
|
|
68
|
+
- - ">="
|
|
69
|
+
- !ruby/object:Gem::Version
|
|
70
|
+
version: "0"
|
|
71
|
+
version:
|
|
72
|
+
requirements: []
|
|
73
|
+
|
|
74
|
+
rubyforge_project:
|
|
75
|
+
rubygems_version: 1.3.5
|
|
76
|
+
signing_key:
|
|
77
|
+
specification_version: 3
|
|
78
|
+
summary: A C based TokyoTyrant Ruby binding
|
|
79
|
+
test_files:
|
|
80
|
+
- spec/spec.rb
|