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.
@@ -0,0 +1,36 @@
1
+ #!/bin/bash
2
+
3
+ #
4
+ # starting the tt servers (standard + table)
5
+ #
6
+
7
+ TMP=`pwd`/tmp
8
+ SPEC=`pwd`/spec
9
+ # so that tt doesn't complain about relative paths...
10
+
11
+ [ -d $TMP ] || mkdir $TMP
12
+
13
+ ttserver \
14
+ -dmn \
15
+ -port 45000 \
16
+ -pid $TMP/t_spec.pid -rts $TMP/t_spec.rts \
17
+ -log $TMP/t.log \
18
+ -ext $SPEC/ext.lua \
19
+ $TMP/tyrant.tch
20
+
21
+ ttserver \
22
+ -dmn \
23
+ -port 45001 \
24
+ -pid $TMP/tt1_spec.pid -rts $TMP/tt1_spec.rts \
25
+ -log $TMP/tt1.log \
26
+ -ext $SPEC/ext.lua \
27
+ $TMP/tyrant_table1.tct
28
+
29
+ ttserver \
30
+ -dmn \
31
+ -port 45002 \
32
+ -pid $TMP/tt2_spec.pid -rts $TMP/tt2_spec.rts \
33
+ -log $TMP/tt2.log \
34
+ -ext $SPEC/ext.lua \
35
+ $TMP/tyrant_table2.tct
36
+
@@ -0,0 +1,9 @@
1
+ #!/bin/bash
2
+
3
+ # stopping the spec ttservers
4
+
5
+ ruby -e "%w{ tmp/t_spec.pid tmp/tt1_spec.pid tmp/tt2_spec.pid }.each { |pf| File.exist?(pf) && Process.kill(9, File.read(pf).strip.to_i) }"
6
+
7
+ rm tmp/t_spec.pid
8
+ rm tmp/tt1_spec.pid
9
+ rm tmp/tt2_spec.pid
@@ -0,0 +1,159 @@
1
+ require 'pathname'
2
+ require Pathname(__FILE__).dirname.join('spec_base') unless $root
3
+
4
+ describe TokyoTyrant::Query, "with an open database" do
5
+ before do
6
+ @db = TokyoTyrant::Table.new('127.0.0.1', 45001)
7
+ @db.clear
8
+ load('spec/plu_db.rb') unless $codes
9
+ @db.mput($codes)
10
+ end
11
+
12
+ it "should get a query object" do
13
+ @db.query.class.should == TokyoTyrant::Query
14
+ end
15
+
16
+ it "should get keys for search conditions" do
17
+ q = @db.query
18
+ q.addcond('type', :streq, 'Spinach')
19
+ q.search.sort.should == %w[3332 34173]
20
+ end
21
+
22
+ it "should get keys for negated search conditions" do
23
+ q = @db.query
24
+ q.addcond('type', '!streq', 'Spinach')
25
+ res = q.search
26
+ %w[3332 34173].each do |k|
27
+ res.should.not.include?(k)
28
+ end
29
+ end
30
+
31
+ it "should get ordered keys for search conditions with default order" do
32
+ q = @db.query
33
+ q.addcond('type', :streq, 'Spinach')
34
+ q.setorder('variety')
35
+ q.search.should == ["3332", "34173"]
36
+ end
37
+
38
+ it "should get ordered keys for search conditions with ascending order" do
39
+ q = @db.query
40
+ q.addcond('type', :streq, 'Spinach')
41
+ q.setorder('variety', :strasc)
42
+ q.search.should == ["3332", "34173"]
43
+ end
44
+
45
+ it "should get ordered keys for search conditions with decending order" do
46
+ q = @db.query
47
+ q.addcond('type', :streq, 'Spinach')
48
+ q.order_by('variety', :StrDesc)
49
+ q.search.should == ["34173", "3332"]
50
+ end
51
+
52
+ it "should get limited keys for search conditions with limit" do
53
+ q = @db.query{ |q|
54
+ q.addcond('type', :streq, 'Apple')
55
+ q.order_by('variety', :strdesc)
56
+ q.setlimit(10)
57
+ }.should == ["4860", "3011", "3271", "3382", "4182", "3353", "4176", "3272", "3297", "3009"]
58
+ end
59
+
60
+ it "should get limited keys for search conditions with limit and offset" do
61
+ q = @db.query{ |q|
62
+ q.addcond('type', :streq, 'Apple')
63
+ q.order_by('variety', :strdesc)
64
+ q.setlimit(10, 10)
65
+ }.should == ["3008", "3352", "3077", "3349", "3076", "3073", "3348", "3007", "3078", "3347"]
66
+ end
67
+
68
+ it "should get records for search conditions" do
69
+ q = @db.query
70
+ q.addcond('type', :streq, 'Garlic')
71
+ res = q.get.sort{ |x,y| x['variety'] <=> y['variety'] }
72
+ res.should == [{ '__id' => "4609", 'variety' => "Elephant", 'code' => "4609", 'type' => "Garlic" },
73
+ { '__id' => "3401", 'variety' => "One-clove types", 'code' => "3401", 'type' => "Garlic" },
74
+ { '__id' => "3052", 'variety' => "String", 'code' => "3052", 'type' => "Garlic" }]
75
+ end
76
+
77
+ it "should remove records for conditions" do
78
+ q = @db.query
79
+ q.addcond('type', :streq, 'Orange')
80
+ q.search.size.should == 11
81
+ q.searchout.should.be.true
82
+ q.search.size.should == 0
83
+ end
84
+
85
+ it "should chain search options" do
86
+ res = @db.query.condition('type', :streq, 'Cucumber').order_by('variety', :strdesc).limit(3).search
87
+ res.should == ["4596", "4595", "4594"]
88
+ end
89
+
90
+ it "should query with a block" do
91
+ res = @db.query do |q|
92
+ q.condition('type', :streq, 'Cucumber')
93
+ q.order_by('variety', :strdesc)
94
+ q.limit(3)
95
+ end
96
+ res.should == ["4596", "4595", "4594"]
97
+ end
98
+
99
+ it "should find with a block" do
100
+ res = @db.find do |q|
101
+ q.condition('type', :streq, 'Cucumber')
102
+ q.order_by('variety', :strdesc)
103
+ q.limit(3)
104
+ end
105
+ res.should == [{'type'=>"Cucumber", 'variety'=>"Pickling / Gherkin", '__id'=>"4596", 'code'=>"4596"},
106
+ {'type'=>"Cucumber", 'variety'=>"Lemon", '__id'=>"4595", 'code'=>"4595"},
107
+ {'type'=>"Cucumber", 'variety'=>"Japanese / White", '__id'=>"4594", 'code'=>"4594"}]
108
+ end
109
+
110
+ it "should show query count" do
111
+ res = @db.prepare_query{ |q| q.condition('type', :streq, 'Cucumber') }.count
112
+ res.should == 5
113
+ end
114
+
115
+ it "should allow a custom pkey for a result set" do
116
+ q = @db.query
117
+ q.condition('type', :streq, 'Cucumber')
118
+ q.set_pkey(:pk)
119
+ q.get.should == [{'type'=>"Cucumber", 'code'=>"4592", :pk=>"4592", 'variety'=>"Armenian"},
120
+ {'type'=>"Cucumber", 'code'=>"4593", :pk=>"4593", 'variety'=>"English / Hot House / Long Seedless / Telegraph / Continental"},
121
+ {'type'=>"Cucumber", 'code'=>"4594", :pk=>"4594", 'variety'=>"Japanese / White"},
122
+ {'type'=>"Cucumber", 'code'=>"4595", :pk=>"4595", 'variety'=>"Lemon"},
123
+ {'type'=>"Cucumber", 'code'=>"4596", :pk=>"4596", 'variety'=>"Pickling / Gherkin"}]
124
+ end
125
+
126
+ it "should return a query hint" do
127
+ @db.set_index(:type, :lexical)
128
+ q = @db.query
129
+ q.condition(:type, :streq, 'Cucumber')
130
+ q.order_by(:code)
131
+ q.limit(3)
132
+ q.run
133
+ q.hint.should == "\nusing an index: \"type\" asc (STREQ)\nresult set size: 5\nsorting the result set: \"code\"\n"
134
+ end
135
+
136
+ it "should query multiple servers" do
137
+ servers = { 1 => TokyoTyrant::Table.new('127.0.0.1', 45001),
138
+ 2 => TokyoTyrant::Table.new('127.0.0.1', 45002) }
139
+
140
+ # dummy data
141
+ servers.each do |account_id, server|
142
+ server.clear
143
+ server["#{account_id}/1"] = {
144
+ :name => "Test 1 (#{account_id})",
145
+ :id => 1,
146
+ }
147
+ server["#{account_id}/2"] = {
148
+ :name => "Test 2 (#{account_id})",
149
+ :id => 2,
150
+ }
151
+ end
152
+ ones = proc{ |q| q.add_condition :id, :numeq, 1 }
153
+ queries = servers.collect{ |account_id,server| server.prepare_query(&ones) }
154
+ results = TokyoTyrant::Query.parallel_search(*queries)
155
+ expected = [{ "" => "1/1", "name" => "Test 1 (1)", "id" => "1" },
156
+ { "" => "2/1", "name" => "Test 1 (2)", "id" => "1" }]
157
+ results.should == expected
158
+ end
159
+ end
@@ -0,0 +1,254 @@
1
+ require 'pathname'
2
+ require Pathname(__FILE__).dirname.join('spec_base') unless $root
3
+
4
+ describe TokyoTyrant::DB, "with an open database" do
5
+
6
+ before do
7
+ @db = TokyoTyrant::DB.new('127.0.0.1', 45000)
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:45000'
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
+ @db[:salad] = 'bacon bits'
34
+ @db[:salad].should == 'bacon bits'
35
+ end
36
+
37
+ it "should return a value" do
38
+ @db[:salad] = 'bacon bits'
39
+ @db[:salad].should == 'bacon bits'
40
+ end
41
+
42
+ it "should accept binary data" do
43
+ s = "mango#{0.chr}salsa"
44
+ @db.put(s, s).should.be.true
45
+ @db[s].should.equal(s)
46
+ end
47
+
48
+ it "should save multiple values" do
49
+ h = { 'pizza' => 'old forge style',
50
+ 'sandwich' => 'peanut butter jelly',
51
+ 'yogurt' => 'greek',
52
+ 'coffee' => 'black' }
53
+ @db.mput(h).should.be.empty
54
+ h.each_pair do |k,v|
55
+ @db[k].should == v
56
+ end
57
+ end
58
+
59
+ it "should delete multiple values" do
60
+ h = { 'pizza' => 'old forge style',
61
+ 'sandwich' => 'peanut butter jelly',
62
+ 'yogurt' => 'greek',
63
+ 'coffee' => 'black' }
64
+ @db.mput(h)
65
+ @db.outlist('coffee', 'yogurt').should.be.empty
66
+ @db.keys.sort.should == ['pizza','sandwich']
67
+ end
68
+
69
+ it "should get multiple values" do
70
+ h = { 'pizza' => 'old forge style',
71
+ 'sandwich' => 'peanut butter jelly',
72
+ 'yogurt' => 'greek',
73
+ 'coffee' => 'black' }
74
+ @db.mput(h)
75
+ @db.mget(h.keys).should == h
76
+ end
77
+
78
+ it "should out a value" do
79
+ k = :tomato
80
+ @db[k] = 'green'
81
+ @db.out(k).should.be.true
82
+ @db[k].should.be.nil
83
+ @db.out(k).should.be.false
84
+ end
85
+
86
+ it "should get a value size" do
87
+ k = :cereal
88
+ v = 'granola'
89
+ @db[k] = v
90
+ @db.vsiz(k).should == v.size
91
+ end
92
+
93
+ it "should check a key" do
94
+ k = :fruit
95
+ @db[k] = 'banana'
96
+ @db.check(k).should.be.true
97
+ @db.out(k)
98
+ @db.check(k).should.be.false
99
+ end
100
+
101
+ it "should iterate" do
102
+ @db[:cheese] = 'gouda'
103
+ @db[:grapes] = 'green'
104
+ @db[:oranges] = 'florida'
105
+ @db[:crackers] = 'triscuit'
106
+
107
+ @db.iterinit.should.be.true
108
+ @db.iternext.should == 'cheese'
109
+ @db.iternext.should == 'grapes'
110
+ @db.iternext.should == 'oranges'
111
+ @db.iternext.should == 'crackers'
112
+ @db.iternext.should == nil
113
+ end
114
+
115
+ it "should get forward matching keys" do
116
+ @db['apples/royalgala'] = '4173'
117
+ @db['apples/grannysmith'] = '4139'
118
+ @db['bananas/yellow'] = '4011'
119
+ @db['oranges/shamouti'] = '3027'
120
+ @db['grapefruit/deepred'] = '4288'
121
+ @db.fwmkeys('apples').sort.should == ["apples/grannysmith", "apples/royalgala"]
122
+ end
123
+
124
+ it "should delete forward matching keys" do
125
+ @db['apples/royalgala'] = '4173'
126
+ @db['apples/grannysmith'] = '4139'
127
+ @db['bananas/yellow'] = '4011'
128
+ @db['oranges/shamouti'] = '3027'
129
+ @db['grapefruit/deepred'] = '4288'
130
+ @db.delete_keys_with_prefix('apples').should == nil
131
+ @db.fwmkeys('apples').should.be.empty
132
+ @db.keys.sort.should == ['bananas/yellow', 'grapefruit/deepred', 'oranges/shamouti']
133
+ end
134
+
135
+ it "should get all keys" do
136
+ keys = %w[appetizers entree dessert]
137
+ values = %w[chips chicken\ caeser\ salad ice\ cream]
138
+ keys.each_with_index do |k,i|
139
+ @db[k] = values[i]
140
+ end
141
+ @db.keys.should == keys
142
+ end
143
+
144
+ it "should get all values" do
145
+ keys = %w[appetizers entree dessert]
146
+ values = %w[chips chicken\ caeser\ salad ice\ cream]
147
+ keys.each_with_index do |k,i|
148
+ @db[k] = values[i]
149
+ end
150
+ @db.values.should == values
151
+ end
152
+
153
+ it "should vanish all records" do
154
+ @db['chocolate'] = 'dark'
155
+ @db['tea'] = 'earl grey'
156
+ @db.empty?.should.be.false
157
+ @db.vanish.should.be.true
158
+ @db.empty?.should.be.true
159
+ end
160
+
161
+ it "should count records" do
162
+ @db['hummus'] = 'chickpeas'
163
+ @db['falafel'] = 'chickpeas'
164
+ @db.rnum.should == 2
165
+ end
166
+
167
+ it "should report db size" do
168
+ @db['rootbeer'] = 'virgils'
169
+ @db.db_size.should.not == 0
170
+ end
171
+
172
+ it "should fetch a record" do
173
+ @db.out('beer')
174
+ @db.fetch('beer'){ 'heineken' }.should == 'heineken'
175
+ @db['beer'].should == 'heineken'
176
+ @db.fetch('beer'){ 'becks' }.should == 'heineken'
177
+ end
178
+
179
+ it "should iterate through records" do
180
+ keys = %w[grapejuice tacoshells rice]
181
+ values = %w[Kedem Ortega Uncle\ Ben]
182
+ keys.each_with_index{ |k,i| @db[k] = values[i] }
183
+
184
+ i = 0
185
+ @db.each do |k,v|
186
+ k.should == keys[i]
187
+ v.should == values[i]
188
+ i = i += 1
189
+ end
190
+ end
191
+
192
+ it "should iterate through keys" do
193
+ keys = %w[burritos fajitas tacos tostas enchiladas]
194
+ values = Array.new(keys.size, 'yum')
195
+ keys.each_with_index{ |k,i| @db[k] = values[i] }
196
+
197
+ i = 0
198
+ @db.each_key do |k|
199
+ k.should == keys[i]
200
+ i = i += 1
201
+ end
202
+ end
203
+
204
+ it "should iterate through values" do
205
+ keys = %w[falafel humus couscous tabbouleh tzatziki]
206
+ values = %w[chickpeas chickpeas semolina bulgar yogurt]
207
+ keys.each_with_index{ |k,i| @db[k] = values[i] }
208
+
209
+ i = 0
210
+ @db.each_value do |v|
211
+ v.should == values[i]
212
+ i = i += 1
213
+ end
214
+ end
215
+
216
+ it "should add serialized integer values" do
217
+ key = 'counter'
218
+ @db.out(key)
219
+ @db.add_int(key, 1).should == 1
220
+ @db.add_int(key, 1).should == 2
221
+ @db.get_int(key).should == 2
222
+ end
223
+
224
+ it "should increment integer values" do
225
+ key = 'counter'
226
+ @db.out(key)
227
+ @db.increment(key).should == 1
228
+ @db.increment(key, 2).should == 3
229
+ @db.get_int(key).should == 3
230
+ end
231
+
232
+ it "should add serialized double values" do
233
+ key = 'counter'
234
+ @db.out(key)
235
+ @db.add_double(key, 1.0).should.be.close?(1.0, 0.005)
236
+ @db.add_double(key, 1.0).should.be.close?(2.0, 0.005)
237
+ @db.get_double(key).should.be.close?(2.0, 0.005)
238
+ end
239
+
240
+ it "should run lua extensions" do
241
+ @db.ext('echo', 'hello', 'world').should == "hello\tworld"
242
+ end
243
+
244
+ it "should serialize objects that respond to to_tokyo_tyrant" do
245
+ class Thing
246
+ def to_tokyo_tyrant
247
+ "success"
248
+ end
249
+ end
250
+
251
+ @db["to_tokyo_tyrant"] = Thing.new
252
+ @db["to_tokyo_tyrant"].should == "success"
253
+ end
254
+ end