metry 1.2.0 → 2.0.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/History.txt +6 -0
- data/Manifest.txt +14 -69
- data/TODO +2 -3
- data/cucumber.yml +1 -0
- data/example/example.rb +1 -1
- data/features/psycho/dashboard.feature +17 -0
- data/features/psycho/goals.feature +24 -0
- data/features/psycho/visitor_tracking.feature +32 -0
- data/features/step_definitions/goals.rb +3 -0
- data/features/step_definitions/tracking.rb +1 -1
- data/features/step_definitions/web.rb +14 -2
- data/features/support/env.rb +4 -0
- data/lib/metry.rb +4 -6
- data/lib/metry/experiment.rb +6 -8
- data/lib/metry/psycho.rb +112 -0
- data/lib/metry/psycho/dashboard.erb +14 -0
- data/lib/metry/psycho/layout.erb +8 -0
- data/lib/metry/psycho/new_goal.erb +9 -0
- data/lib/metry/psycho/visitor.erb +7 -0
- data/lib/metry/rack/tracking.rb +17 -13
- data/lib/metry/storage.rb +116 -0
- data/radiant/example/features/metry.feature +8 -8
- data/radiant/example/features/psycho.feature +13 -0
- data/radiant/example/features/step_definitions/experiments.rb +2 -2
- data/radiant/example/features/step_definitions/tracking.rb +1 -1
- data/radiant/example/features/support/env.rb +3 -0
- data/radiant/extension/lib/metry_authenticator.rb +30 -0
- data/radiant/extension/lib/metry_tags.rb +2 -1
- data/radiant/extension/metry_extension.rb +1 -1
- data/test/{test_tokyo.rb → test_storage.rb} +3 -3
- metadata +17 -72
- data/lib/metry/memory.rb +0 -27
- data/lib/metry/tokyo.rb +0 -181
- data/vendor/rufus-tokyo/CHANGELOG.txt +0 -112
- data/vendor/rufus-tokyo/CREDITS.txt +0 -27
- data/vendor/rufus-tokyo/LICENSE.txt +0 -21
- data/vendor/rufus-tokyo/README.txt +0 -310
- data/vendor/rufus-tokyo/Rakefile +0 -118
- data/vendor/rufus-tokyo/TODO.txt +0 -25
- data/vendor/rufus-tokyo/doc/decision_table.numbers +0 -0
- data/vendor/rufus-tokyo/doc/rdoc-style.css +0 -320
- data/vendor/rufus-tokyo/lib/rufus-edo.rb +0 -3
- data/vendor/rufus-tokyo/lib/rufus-tokyo.rb +0 -3
- data/vendor/rufus-tokyo/lib/rufus/edo.rb +0 -39
- data/vendor/rufus-tokyo/lib/rufus/edo/README.txt +0 -106
- data/vendor/rufus-tokyo/lib/rufus/edo/cabcore.rb +0 -333
- data/vendor/rufus-tokyo/lib/rufus/edo/cabinet/abstract.rb +0 -219
- data/vendor/rufus-tokyo/lib/rufus/edo/cabinet/table.rb +0 -159
- data/vendor/rufus-tokyo/lib/rufus/edo/error.rb +0 -36
- data/vendor/rufus-tokyo/lib/rufus/edo/ntyrant.rb +0 -4
- data/vendor/rufus-tokyo/lib/rufus/edo/ntyrant/abstract.rb +0 -137
- data/vendor/rufus-tokyo/lib/rufus/edo/ntyrant/table.rb +0 -141
- data/vendor/rufus-tokyo/lib/rufus/edo/tabcore.rb +0 -567
- data/vendor/rufus-tokyo/lib/rufus/tokyo.rb +0 -58
- data/vendor/rufus-tokyo/lib/rufus/tokyo/cabinet/abstract.rb +0 -568
- data/vendor/rufus-tokyo/lib/rufus/tokyo/cabinet/lib.rb +0 -230
- data/vendor/rufus-tokyo/lib/rufus/tokyo/cabinet/table.rb +0 -753
- data/vendor/rufus-tokyo/lib/rufus/tokyo/cabinet/util.rb +0 -425
- data/vendor/rufus-tokyo/lib/rufus/tokyo/config.rb +0 -161
- data/vendor/rufus-tokyo/lib/rufus/tokyo/dystopia.rb +0 -43
- data/vendor/rufus-tokyo/lib/rufus/tokyo/dystopia/lib.rb +0 -65
- data/vendor/rufus-tokyo/lib/rufus/tokyo/dystopia/words.rb +0 -71
- data/vendor/rufus-tokyo/lib/rufus/tokyo/hmethods.rb +0 -111
- data/vendor/rufus-tokyo/lib/rufus/tokyo/query.rb +0 -102
- data/vendor/rufus-tokyo/lib/rufus/tokyo/transactions.rb +0 -74
- data/vendor/rufus-tokyo/lib/rufus/tokyo/ttcommons.rb +0 -59
- data/vendor/rufus-tokyo/lib/rufus/tokyo/tyrant.rb +0 -35
- data/vendor/rufus-tokyo/lib/rufus/tokyo/tyrant/abstract.rb +0 -146
- data/vendor/rufus-tokyo/lib/rufus/tokyo/tyrant/lib.rb +0 -153
- data/vendor/rufus-tokyo/lib/rufus/tokyo/tyrant/table.rb +0 -162
- data/vendor/rufus-tokyo/rufus-tokyo.gemspec +0 -25
- data/vendor/rufus-tokyo/spec/cabinet_spec.rb +0 -472
- data/vendor/rufus-tokyo/spec/cabinetconfig_spec.rb +0 -82
- data/vendor/rufus-tokyo/spec/edo_cabinet_spec.rb +0 -447
- data/vendor/rufus-tokyo/spec/edo_ntyrant_spec.rb +0 -299
- data/vendor/rufus-tokyo/spec/edo_ntyrant_table_spec.rb +0 -462
- data/vendor/rufus-tokyo/spec/edo_table_spec.rb +0 -560
- data/vendor/rufus-tokyo/spec/hmethods_spec.rb +0 -44
- data/vendor/rufus-tokyo/spec/incr.lua +0 -20
- data/vendor/rufus-tokyo/spec/spec.rb +0 -9
- data/vendor/rufus-tokyo/spec/spec_base.rb +0 -23
- data/vendor/rufus-tokyo/spec/start_tyrants.sh +0 -26
- data/vendor/rufus-tokyo/spec/stop_tyrants.sh +0 -9
- data/vendor/rufus-tokyo/spec/table_spec.rb +0 -567
- data/vendor/rufus-tokyo/spec/tyrant_spec.rb +0 -309
- data/vendor/rufus-tokyo/spec/tyrant_table_spec.rb +0 -479
- data/vendor/rufus-tokyo/spec/util_list_spec.rb +0 -200
- data/vendor/rufus-tokyo/spec/util_map_spec.rb +0 -132
- data/vendor/rufus-tokyo/tasks/dev.rb +0 -70
- data/vendor/rufus-tokyo/test/bm0.rb +0 -353
- data/vendor/rufus-tokyo/test/bm1_compression.rb +0 -54
- data/vendor/rufus-tokyo/test/con0.rb +0 -30
- data/vendor/rufus-tokyo/test/mem.rb +0 -49
- data/vendor/rufus-tokyo/test/mem1.rb +0 -44
- data/vendor/rufus-tokyo/test/readme0.rb +0 -17
- data/vendor/rufus-tokyo/test/readme1.rb +0 -21
- data/vendor/rufus-tokyo/test/readme2.rb +0 -15
- data/vendor/rufus-tokyo/test/readme3.rb +0 -24
- data/vendor/rufus-tokyo/test/readmes_test.sh +0 -17
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
#
|
|
3
|
-
# Specifying rufus-tokyo
|
|
4
|
-
#
|
|
5
|
-
# Sun Feb 8 14:15:31 JST 2009
|
|
6
|
-
#
|
|
7
|
-
|
|
8
|
-
require File.dirname(__FILE__) + '/spec_base'
|
|
9
|
-
|
|
10
|
-
require 'rufus/tokyo/hmethods'
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class MyHash
|
|
14
|
-
include Rufus::Tokyo::HashMethods
|
|
15
|
-
attr_accessor :default_proc
|
|
16
|
-
def get (k)
|
|
17
|
-
k.to_i % 2 == 0 ? k : nil
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
describe 'an instance that include HashMethods' do
|
|
22
|
-
|
|
23
|
-
before do
|
|
24
|
-
@h = MyHash.new
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
it 'should be ready for testing' do # :(
|
|
28
|
-
@h[1].should.be.nil
|
|
29
|
-
@h[2].should.equal(2)
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
it 'should accept a default value' do
|
|
33
|
-
@h.default = :default
|
|
34
|
-
@h.default.should.equal(:default)
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
it 'should accept a default_proc' do
|
|
38
|
-
@h.default_proc = lambda { |h, k| k * 2 }
|
|
39
|
-
@h[1].should.equal(2)
|
|
40
|
-
@h[2].should.equal(2)
|
|
41
|
-
@h[3].should.equal(6)
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
--
|
|
3
|
-
-- Taken from http://tokyocabinet.sourceforge.net/tyrantdoc/#luaext
|
|
4
|
-
--
|
|
5
|
-
|
|
6
|
-
function incr (key, value)
|
|
7
|
-
value = tonumber(value)
|
|
8
|
-
if not value then
|
|
9
|
-
return nil
|
|
10
|
-
end
|
|
11
|
-
local old = tonumber(_get(key))
|
|
12
|
-
if old then
|
|
13
|
-
value = value + old
|
|
14
|
-
end
|
|
15
|
-
if not _put(key, value) then
|
|
16
|
-
return nil
|
|
17
|
-
end
|
|
18
|
-
return value
|
|
19
|
-
end
|
|
20
|
-
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
#
|
|
3
|
-
# Specifying rufus-tokyo
|
|
4
|
-
#
|
|
5
|
-
# Sun Feb 8 13:15:08 JST 2009
|
|
6
|
-
#
|
|
7
|
-
|
|
8
|
-
#
|
|
9
|
-
# bacon
|
|
10
|
-
|
|
11
|
-
$:.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')))
|
|
12
|
-
|
|
13
|
-
require 'rubygems'
|
|
14
|
-
require 'fileutils'
|
|
15
|
-
|
|
16
|
-
$:.unshift(File.expand_path('~/tmp/bacon/lib')) # my own bacon for a while
|
|
17
|
-
|
|
18
|
-
require 'bacon'
|
|
19
|
-
|
|
20
|
-
puts
|
|
21
|
-
|
|
22
|
-
Bacon.summary_on_exit
|
|
23
|
-
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
#
|
|
4
|
-
# starting the tt servers (standard + table)
|
|
5
|
-
#
|
|
6
|
-
|
|
7
|
-
TMP=`pwd`/tmp
|
|
8
|
-
# so that tt doesn't complain about relative paths...
|
|
9
|
-
|
|
10
|
-
[ -d $TMP ] || mkdir $TMP
|
|
11
|
-
|
|
12
|
-
ttserver \
|
|
13
|
-
-dmn \
|
|
14
|
-
-ext `pwd`/spec/incr.lua \
|
|
15
|
-
-port 45000 \
|
|
16
|
-
-pid $TMP/t_spec.pid -rts $TMP/t_spec.rts \
|
|
17
|
-
-log $TMP/t.log \
|
|
18
|
-
$TMP/tyrant.tch
|
|
19
|
-
|
|
20
|
-
ttserver \
|
|
21
|
-
-dmn \
|
|
22
|
-
-port 45001 \
|
|
23
|
-
-pid $TMP/tt_spec.pid -rts $TMP/tt_spec.rts \
|
|
24
|
-
-log $TMP/tt.log \
|
|
25
|
-
$TMP/tyrant_table.tct
|
|
26
|
-
|
|
@@ -1,567 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
#
|
|
3
|
-
# Specifying rufus-tokyo
|
|
4
|
-
#
|
|
5
|
-
# Sun Feb 8 16:07:16 JST 2009
|
|
6
|
-
#
|
|
7
|
-
|
|
8
|
-
require File.dirname(__FILE__) + '/spec_base'
|
|
9
|
-
|
|
10
|
-
require 'rufus/tokyo'
|
|
11
|
-
|
|
12
|
-
FileUtils.mkdir('tmp') rescue nil
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
describe 'Rufus::Tokyo::Table' do
|
|
16
|
-
|
|
17
|
-
it 'should open in write/create mode by default' do
|
|
18
|
-
|
|
19
|
-
t = Rufus::Tokyo::Table.new('tmp/default.tct')
|
|
20
|
-
t.close
|
|
21
|
-
File.exist?('tmp/default.tct').should.equal(true)
|
|
22
|
-
FileUtils.rm('tmp/default.tct')
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
it 'should raise an error when file is missing' do
|
|
26
|
-
|
|
27
|
-
lambda {
|
|
28
|
-
Rufus::Tokyo::Table.new('tmp/missing.tct', :mode => 'r')
|
|
29
|
-
}.should.raise(
|
|
30
|
-
Rufus::Tokyo::TokyoError).message.should.equal('(err 3) file not found')
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
describe 'Rufus::Tokyo::Table' do
|
|
35
|
-
|
|
36
|
-
before do
|
|
37
|
-
@t = Rufus::Tokyo::Table.new('tmp/table.tct')
|
|
38
|
-
@t.clear
|
|
39
|
-
end
|
|
40
|
-
after do
|
|
41
|
-
@t.close
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
it 'should return its path' do
|
|
45
|
-
|
|
46
|
-
@t.path.should.equal('tmp/table.tct')
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
it 'should generate unique ids' do
|
|
50
|
-
|
|
51
|
-
@t.genuid.should.satisfy { |i| i > 0 }
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
it 'should return nil for missing keys' do
|
|
55
|
-
|
|
56
|
-
@t['missing'].should.be.nil
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
it 'should accept Array and Hash input' do
|
|
60
|
-
|
|
61
|
-
@t.size.should.equal(0)
|
|
62
|
-
|
|
63
|
-
@t['pk0'] = [ 'name', 'toto', 'age', '30' ]
|
|
64
|
-
@t['pk1'] = { 'name' => 'fred', 'age' => '22' }
|
|
65
|
-
|
|
66
|
-
@t.size.should.equal(2)
|
|
67
|
-
@t['pk0'].should.equal({ 'name' => 'toto', 'age' => '30' })
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
it 'should return nil when deleting inexistent entries' do
|
|
71
|
-
|
|
72
|
-
@t.delete('I_do_not_exist').should.equal(nil)
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
it 'should delete the entry and return the value' do
|
|
76
|
-
|
|
77
|
-
@t['pk0'] = [ 'name', 'toto', 'age', '30' ]
|
|
78
|
-
@t.delete('pk0').should.equal({ 'name' => 'toto', 'age' => '30' })
|
|
79
|
-
@t.size.should.equal(0)
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
it 'should raise an ArgumentError on non map or hash input' do
|
|
83
|
-
|
|
84
|
-
lambda {
|
|
85
|
-
@t['pk0'] = 'bad thing here'
|
|
86
|
-
}.should.raise(ArgumentError)
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
unless defined?(JRUBY_VERSION)
|
|
90
|
-
it 'should raise an ArgumentError on non-string column name' do
|
|
91
|
-
|
|
92
|
-
lambda {
|
|
93
|
-
@t['pk0'] = [ 1, 2 ]
|
|
94
|
-
}.should.raise(ArgumentError)
|
|
95
|
-
lambda {
|
|
96
|
-
@t['pk0'] = { 1 => 2 }
|
|
97
|
-
}.should.raise(ArgumentError)
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
it 'should raise an ArgumentError on non-string column value' do
|
|
101
|
-
|
|
102
|
-
lambda {
|
|
103
|
-
@t['pk0'] = { 'a' => 2 }
|
|
104
|
-
}.should.raise(ArgumentError)
|
|
105
|
-
end
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
it 'should correctly abort transactions' do
|
|
109
|
-
|
|
110
|
-
@t.transaction {
|
|
111
|
-
@t['pk0'] = { 'a' => 'A' }
|
|
112
|
-
@t.abort
|
|
113
|
-
}
|
|
114
|
-
@t.size.should.be.zero
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
it 'should rollback transactions with errors' do
|
|
118
|
-
|
|
119
|
-
@t.transaction {
|
|
120
|
-
@t['pk0'] = { 'a' => 'A' }
|
|
121
|
-
raise 'something goes wrong'
|
|
122
|
-
}
|
|
123
|
-
@t.size.should.be.zero
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
it 'should commit successful transactions' do
|
|
127
|
-
|
|
128
|
-
@t.transaction do
|
|
129
|
-
@t['pk0'] = { 'a' => 'A' }
|
|
130
|
-
end
|
|
131
|
-
@t['pk0'].should.equal({ 'a' => 'A' })
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
it 'should abort low level transactions' do
|
|
135
|
-
|
|
136
|
-
@t.tranbegin
|
|
137
|
-
@t['pk0'] = { 'a' => 'A' }
|
|
138
|
-
@t.tranabort
|
|
139
|
-
@t.size.should.be.zero
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
it 'should commit low level transactions' do
|
|
143
|
-
|
|
144
|
-
@t.tranbegin
|
|
145
|
-
@t['pk0'] = { 'a' => 'A' }
|
|
146
|
-
@t.trancommit
|
|
147
|
-
@t['pk0'].should.equal({ 'a' => 'A' })
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
it 'should store binary data \0' do
|
|
151
|
-
s = "toto#{0.chr}nada"
|
|
152
|
-
@t[s] = { s => s }
|
|
153
|
-
@t[s].should.equal({ s => s })
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
describe 'Rufus::Tokyo::Table #keys' do
|
|
160
|
-
|
|
161
|
-
before do
|
|
162
|
-
@n = 50
|
|
163
|
-
@tab = Rufus::Tokyo::Table.new('tmp/test_new.tct')
|
|
164
|
-
@tab.clear
|
|
165
|
-
@n.times { |i| @tab["person#{i}"] = { 'name' => 'whoever' } }
|
|
166
|
-
@n.times { |i| @tab["animal#{i}"] = { 'name' => 'whichever' } }
|
|
167
|
-
@tab["toto#{0.chr}5"] = { 'name' => 'toto' }
|
|
168
|
-
end
|
|
169
|
-
after do
|
|
170
|
-
@tab.close
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
it 'should return a Ruby Array by default' do
|
|
174
|
-
|
|
175
|
-
@tab.keys.class.should.equal(::Array)
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
it 'should return a Cabinet List when :native => true' do
|
|
179
|
-
|
|
180
|
-
l = @tab.keys(:native => true)
|
|
181
|
-
l.class.should.equal(Rufus::Tokyo::List)
|
|
182
|
-
l.size.should.equal(2 * @n + 1)
|
|
183
|
-
l.free
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
it 'should retrieve forward matching keys when :prefix => "prefix-"' do
|
|
187
|
-
|
|
188
|
-
@tab.keys(:prefix => 'person').size.should.equal(@n)
|
|
189
|
-
|
|
190
|
-
l = @tab.keys(:prefix => 'animal', :native => true)
|
|
191
|
-
l.size.should.equal(@n)
|
|
192
|
-
l.free
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
it 'should retrieve keys that contain \0' do
|
|
196
|
-
|
|
197
|
-
@tab.keys.include?("toto#{0.chr}5").should.be.true
|
|
198
|
-
end
|
|
199
|
-
|
|
200
|
-
it 'should retrieve forward matching keys when key contains \0' do
|
|
201
|
-
|
|
202
|
-
@tab.keys(:prefix => 'toto').should.equal([ "toto#{0.chr}5" ])
|
|
203
|
-
end
|
|
204
|
-
|
|
205
|
-
it 'should return a limited number of keys when :limit is set' do
|
|
206
|
-
|
|
207
|
-
@tab.keys(:limit => 20).size.should.equal(20)
|
|
208
|
-
end
|
|
209
|
-
|
|
210
|
-
it 'should delete_keys_with_prefix' do
|
|
211
|
-
|
|
212
|
-
@tab.delete_keys_with_prefix('animal')
|
|
213
|
-
@tab.size.should.equal(@n + 1)
|
|
214
|
-
@tab.keys(:prefix => 'animal').size.should.equal(0)
|
|
215
|
-
end
|
|
216
|
-
end
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
def prepare_table_with_data
|
|
220
|
-
|
|
221
|
-
t = Rufus::Tokyo::Table.new('tmp/test_new.tct')
|
|
222
|
-
t.clear
|
|
223
|
-
t['pk0'] = { 'name' => 'jim', 'age' => '25', 'lang' => 'ja,en' }
|
|
224
|
-
t['pk1'] = { 'name' => 'jeff', 'age' => '32', 'lang' => 'en,es' }
|
|
225
|
-
t['pk2'] = { 'name' => 'jack', 'age' => '44', 'lang' => 'en' }
|
|
226
|
-
t['pk3'] = { 'name' => 'jake', 'age' => '45', 'lang' => 'en,li' }
|
|
227
|
-
t
|
|
228
|
-
end
|
|
229
|
-
|
|
230
|
-
describe 'Rufus::Tokyo::Table' do
|
|
231
|
-
|
|
232
|
-
before do
|
|
233
|
-
@t = prepare_table_with_data
|
|
234
|
-
end
|
|
235
|
-
after do
|
|
236
|
-
@t.close
|
|
237
|
-
end
|
|
238
|
-
|
|
239
|
-
it 'should accept lexical indexes' do
|
|
240
|
-
@t.set_index('name', :lexical).should.equal(true)
|
|
241
|
-
end
|
|
242
|
-
|
|
243
|
-
it 'should accept decimal indexes' do
|
|
244
|
-
@t.set_index('age', :decimal).should.equal(true)
|
|
245
|
-
end
|
|
246
|
-
|
|
247
|
-
it 'should accept removal of indexes' do
|
|
248
|
-
@t.set_index('age', :decimal)
|
|
249
|
-
@t.set_index('age', :remove).should.equal(true)
|
|
250
|
-
end
|
|
251
|
-
|
|
252
|
-
it 'should accept indexes on the primary key (well...)' do
|
|
253
|
-
@t.set_index(:pk, :lexical).should.equal(true)
|
|
254
|
-
@t.set_index('', :lexical).should.equal(true)
|
|
255
|
-
end
|
|
256
|
-
end
|
|
257
|
-
|
|
258
|
-
describe 'Rufus::Tokyo::Table#lget' do
|
|
259
|
-
|
|
260
|
-
before do
|
|
261
|
-
@t = prepare_table_with_data
|
|
262
|
-
end
|
|
263
|
-
after do
|
|
264
|
-
@t.close
|
|
265
|
-
end
|
|
266
|
-
|
|
267
|
-
it 'should return an empty hash for missing keys' do
|
|
268
|
-
@t.lget(%w{ pk97 pk98 }).should.equal({})
|
|
269
|
-
end
|
|
270
|
-
|
|
271
|
-
it 'should return multiple records' do
|
|
272
|
-
@t.lget(%w{ pk0 pk1 }).should.equal({
|
|
273
|
-
'pk0' => { 'name' => 'jim', 'age' => '25', 'lang' => 'ja,en' },
|
|
274
|
-
'pk1' => { 'name' => 'jeff', 'age' => '32', 'lang' => 'en,es' }
|
|
275
|
-
})
|
|
276
|
-
end
|
|
277
|
-
end
|
|
278
|
-
|
|
279
|
-
describe 'Rufus::Tokyo::Table, like a Ruby Hash' do
|
|
280
|
-
|
|
281
|
-
before do
|
|
282
|
-
@t = prepare_table_with_data
|
|
283
|
-
end
|
|
284
|
-
after do
|
|
285
|
-
@t.close
|
|
286
|
-
end
|
|
287
|
-
|
|
288
|
-
it 'should respond to #keys' do
|
|
289
|
-
|
|
290
|
-
@t.keys.should.equal([ 'pk0', 'pk1', 'pk2', 'pk3' ])
|
|
291
|
-
end
|
|
292
|
-
|
|
293
|
-
it 'should respond to #values' do
|
|
294
|
-
|
|
295
|
-
@t.values.should.equal([
|
|
296
|
-
{ 'name' => 'jim', 'age' => '25', 'lang' => 'ja,en' },
|
|
297
|
-
{ 'name' => 'jeff', 'age' => '32', 'lang' => 'en,es' },
|
|
298
|
-
{ 'name' => 'jack', 'age' => '44', 'lang' => 'en' },
|
|
299
|
-
{ 'name' => 'jake', 'age' => '45', 'lang' => 'en,li' }])
|
|
300
|
-
end
|
|
301
|
-
|
|
302
|
-
it 'should benefit from Enumerable' do
|
|
303
|
-
|
|
304
|
-
@t.find { |k, v|
|
|
305
|
-
v['name'] == 'jeff'
|
|
306
|
-
}.should.equal([
|
|
307
|
-
'pk1', { 'name' => 'jeff', 'age' => '32', 'lang' => 'en,es' }])
|
|
308
|
-
end
|
|
309
|
-
end
|
|
310
|
-
|
|
311
|
-
describe 'queries on Rufus::Tokyo::Table' do
|
|
312
|
-
|
|
313
|
-
before do
|
|
314
|
-
@t = prepare_table_with_data
|
|
315
|
-
end
|
|
316
|
-
after do
|
|
317
|
-
@t.close
|
|
318
|
-
end
|
|
319
|
-
|
|
320
|
-
it 'can be executed' do
|
|
321
|
-
|
|
322
|
-
@t.query { |q|
|
|
323
|
-
q.add 'lang', :includes, 'en'
|
|
324
|
-
}.size.should.equal(4)
|
|
325
|
-
end
|
|
326
|
-
|
|
327
|
-
it 'can be prepared' do
|
|
328
|
-
|
|
329
|
-
@t.prepare_query { |q|
|
|
330
|
-
q.add 'lang', :includes, 'en'
|
|
331
|
-
}.should.satisfy { |q| q.class == Rufus::Tokyo::TableQuery }
|
|
332
|
-
end
|
|
333
|
-
|
|
334
|
-
it 'can be counted' do
|
|
335
|
-
|
|
336
|
-
q = @t.prepare_query { |q|
|
|
337
|
-
q.add 'lang', :includes, 'en'
|
|
338
|
-
}
|
|
339
|
-
q.run
|
|
340
|
-
q.count.should.equal(4)
|
|
341
|
-
end
|
|
342
|
-
|
|
343
|
-
it 'can be limited' do
|
|
344
|
-
|
|
345
|
-
@t.query { |q|
|
|
346
|
-
q.add 'lang', :includes, 'en'
|
|
347
|
-
q.limit 2
|
|
348
|
-
}.size.should.equal(2)
|
|
349
|
-
end
|
|
350
|
-
|
|
351
|
-
it 'can leverage regex matches' do
|
|
352
|
-
|
|
353
|
-
@t.query { |q|
|
|
354
|
-
q.add 'name', :matches, '^j.+k'
|
|
355
|
-
}.to_a.should.equal([
|
|
356
|
-
{:pk => 'pk2', "name"=>"jack", "lang"=>"en", "age"=>"44"},
|
|
357
|
-
{:pk => 'pk3', "name"=>"jake", "lang"=>"en,li", "age"=>"45"}])
|
|
358
|
-
end
|
|
359
|
-
|
|
360
|
-
it 'can leverage numerical comparison (gt)' do
|
|
361
|
-
|
|
362
|
-
@t.query { |q|
|
|
363
|
-
q.add 'age', :gt, '40'
|
|
364
|
-
q.pk_only
|
|
365
|
-
}.to_a.should.equal([ 'pk2', 'pk3' ])
|
|
366
|
-
end
|
|
367
|
-
|
|
368
|
-
it 'can have negated conditions' do
|
|
369
|
-
|
|
370
|
-
@t.query { |q|
|
|
371
|
-
q.add 'age', :gt, '40', false
|
|
372
|
-
q.pk_only
|
|
373
|
-
}.to_a.should.equal([ 'pk0', 'pk1' ])
|
|
374
|
-
end
|
|
375
|
-
|
|
376
|
-
if Rufus::Tokyo::CabinetLib.respond_to?(:qry_setlimit)
|
|
377
|
-
|
|
378
|
-
it 'can be limited and have an offset' do
|
|
379
|
-
|
|
380
|
-
@t.query { |q|
|
|
381
|
-
q.add 'lang', :includes, 'en'
|
|
382
|
-
q.order_by 'name', :desc
|
|
383
|
-
q.limit 2, 0
|
|
384
|
-
}.collect { |e| e['name'] }.should.equal(%w{ jim jeff })
|
|
385
|
-
@t.query { |q|
|
|
386
|
-
q.add 'lang', :includes, 'en'
|
|
387
|
-
q.order_by 'name', :desc
|
|
388
|
-
q.limit 2, 2
|
|
389
|
-
}.collect { |e| e['name'] }.should.equal(%w{ jake jack })
|
|
390
|
-
end
|
|
391
|
-
end
|
|
392
|
-
|
|
393
|
-
it 'can be deleted (searchout : query#delete)' do
|
|
394
|
-
|
|
395
|
-
@t.prepare_query { |q|
|
|
396
|
-
q.add 'lang', :includes, 'es'
|
|
397
|
-
}.delete
|
|
398
|
-
|
|
399
|
-
@t.size.should.equal(3)
|
|
400
|
-
end
|
|
401
|
-
|
|
402
|
-
it 'can be deleted immediately (searchout table#query_delete)' do
|
|
403
|
-
|
|
404
|
-
@t.query_delete { |q|
|
|
405
|
-
q.add 'lang', :includes, 'es'
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
@t.size.should.equal(3)
|
|
409
|
-
end
|
|
410
|
-
|
|
411
|
-
end
|
|
412
|
-
|
|
413
|
-
describe 'Rufus::Tokyo::TableQuery#process' do
|
|
414
|
-
|
|
415
|
-
before do
|
|
416
|
-
@t = prepare_table_with_data
|
|
417
|
-
end
|
|
418
|
-
after do
|
|
419
|
-
@t.close
|
|
420
|
-
end
|
|
421
|
-
|
|
422
|
-
it 'can iterate over the matching records' do
|
|
423
|
-
|
|
424
|
-
keys, values = [], []
|
|
425
|
-
|
|
426
|
-
@t.prepare_query { |q|
|
|
427
|
-
q.add 'lang', :includes, 'en'
|
|
428
|
-
}.process { |k, v|
|
|
429
|
-
keys << k
|
|
430
|
-
values << v
|
|
431
|
-
}.free
|
|
432
|
-
|
|
433
|
-
keys.should.equal(%w[ pk0 pk1 pk2 pk3 ])
|
|
434
|
-
values.first.keys.sort.should.equal(%w[ age lang name ])
|
|
435
|
-
end
|
|
436
|
-
|
|
437
|
-
it 'can stop while iterating' do
|
|
438
|
-
|
|
439
|
-
seen = 0
|
|
440
|
-
|
|
441
|
-
@t.prepare_query { |q|
|
|
442
|
-
q.add 'lang', :includes, 'en'
|
|
443
|
-
}.process { |k, v|
|
|
444
|
-
seen = seen + 1
|
|
445
|
-
:stop
|
|
446
|
-
}.free
|
|
447
|
-
|
|
448
|
-
seen.should.equal(1)
|
|
449
|
-
end
|
|
450
|
-
|
|
451
|
-
it 'can delete while iterating' do
|
|
452
|
-
|
|
453
|
-
@t.prepare_query { |q|
|
|
454
|
-
q.add 'lang', :includes, 'en'
|
|
455
|
-
}.process { |k, v|
|
|
456
|
-
v['name'].match(/^ja/) ? :delete : nil
|
|
457
|
-
}.free
|
|
458
|
-
|
|
459
|
-
@t.keys.sort.should.equal(%w[ pk0 pk1 ])
|
|
460
|
-
end
|
|
461
|
-
|
|
462
|
-
it 'can update while iterating' do
|
|
463
|
-
|
|
464
|
-
@t.prepare_query { |q|
|
|
465
|
-
q.add 'lang', :includes, 'en'
|
|
466
|
-
}.process { |k, v|
|
|
467
|
-
v['name'].match(/^ja/) ? v.merge('special' => 'seen') : nil
|
|
468
|
-
}.free
|
|
469
|
-
|
|
470
|
-
@t.size.should.equal(4)
|
|
471
|
-
|
|
472
|
-
@t['pk2'].should.equal(
|
|
473
|
-
{'name'=>'jack', 'age'=>'44', 'lang'=>'en', 'special'=>'seen'})
|
|
474
|
-
@t['pk3'].should.equal(
|
|
475
|
-
{'name'=>'jake', 'age'=>'45', 'lang'=>'en,li', 'special'=>'seen'})
|
|
476
|
-
end
|
|
477
|
-
|
|
478
|
-
it 'can update, delete and stop' do
|
|
479
|
-
|
|
480
|
-
seen = []
|
|
481
|
-
|
|
482
|
-
@t.prepare_query { |q|
|
|
483
|
-
q.add 'lang', :includes, 'en'
|
|
484
|
-
q.order_by 'name', :desc
|
|
485
|
-
}.process { |k, v|
|
|
486
|
-
seen << v['name']
|
|
487
|
-
case v['name']
|
|
488
|
-
when 'jim' then nil
|
|
489
|
-
when 'jeff' then :delete
|
|
490
|
-
when 'jake' then [ :stop, v.merge('special' => 'nada') ]
|
|
491
|
-
end
|
|
492
|
-
}.free
|
|
493
|
-
|
|
494
|
-
seen.include?('jack').should.be.false
|
|
495
|
-
|
|
496
|
-
@t.size.should.equal(3)
|
|
497
|
-
|
|
498
|
-
@t['pk3'].should.equal(
|
|
499
|
-
{'name'=>'jake', 'age'=>'45', 'lang'=>'en,li', 'special'=>'nada'})
|
|
500
|
-
@t['pk1'].should.be.nil
|
|
501
|
-
end
|
|
502
|
-
end
|
|
503
|
-
|
|
504
|
-
describe 'results from queries on Rufus::Tokyo::Table' do
|
|
505
|
-
|
|
506
|
-
before do
|
|
507
|
-
@t = prepare_table_with_data
|
|
508
|
-
end
|
|
509
|
-
after do
|
|
510
|
-
@t.close
|
|
511
|
-
end
|
|
512
|
-
|
|
513
|
-
it 'can come ordered (strdesc)' do
|
|
514
|
-
|
|
515
|
-
@t.query { |q|
|
|
516
|
-
q.add 'lang', :includes, 'en'
|
|
517
|
-
q.order_by 'name', :desc
|
|
518
|
-
q.limit 2
|
|
519
|
-
}.to_a.should.equal([
|
|
520
|
-
{:pk => 'pk0', "name"=>"jim", "lang"=>"ja,en", "age"=>"25"},
|
|
521
|
-
{:pk => 'pk1', "name"=>"jeff", "lang"=>"en,es", "age"=>"32"}])
|
|
522
|
-
end
|
|
523
|
-
|
|
524
|
-
it 'can come ordered (strasc)' do
|
|
525
|
-
|
|
526
|
-
@t.query { |q|
|
|
527
|
-
q.add 'lang', :includes, 'en'
|
|
528
|
-
q.order_by 'name', :asc
|
|
529
|
-
}.to_a.should.equal([
|
|
530
|
-
{:pk => 'pk2', "name"=>"jack", "lang"=>"en", "age"=>"44"},
|
|
531
|
-
{:pk => 'pk3', "name"=>"jake", "lang"=>"en,li", "age"=>"45"},
|
|
532
|
-
{:pk => 'pk1', "name"=>"jeff", "lang"=>"en,es", "age"=>"32"},
|
|
533
|
-
{:pk => 'pk0', "name"=>"jim", "lang"=>"ja,en", "age"=>"25"}])
|
|
534
|
-
end
|
|
535
|
-
|
|
536
|
-
it 'can come ordered (numasc)' do
|
|
537
|
-
|
|
538
|
-
@t.query { |q|
|
|
539
|
-
q.add 'lang', :includes, 'en'
|
|
540
|
-
q.order_by 'age', :numasc
|
|
541
|
-
}.to_a.should.equal([
|
|
542
|
-
{:pk => 'pk0', "name"=>"jim", "lang"=>"ja,en", "age"=>"25"},
|
|
543
|
-
{:pk => 'pk1', "name"=>"jeff", "lang"=>"en,es", "age"=>"32"},
|
|
544
|
-
{:pk => 'pk2', "name"=>"jack", "lang"=>"en", "age"=>"44"},
|
|
545
|
-
{:pk => 'pk3', "name"=>"jake", "lang"=>"en,li", "age"=>"45"}])
|
|
546
|
-
end
|
|
547
|
-
|
|
548
|
-
it 'can come without the primary keys (no_pk)' do
|
|
549
|
-
|
|
550
|
-
@t.query { |q|
|
|
551
|
-
q.add 'name', :matches, '^j.+k'
|
|
552
|
-
q.no_pk
|
|
553
|
-
}.to_a.should.equal([
|
|
554
|
-
{"name"=>"jack", "lang"=>"en", "age"=>"44"},
|
|
555
|
-
{"name"=>"jake", "lang"=>"en,li", "age"=>"45"}])
|
|
556
|
-
end
|
|
557
|
-
|
|
558
|
-
it 'can consist only of the primary keys (pk_only)' do
|
|
559
|
-
|
|
560
|
-
@t.query { |q|
|
|
561
|
-
q.add 'name', :matches, '^j.+k'
|
|
562
|
-
q.pk_only
|
|
563
|
-
}.to_a.should.equal(["pk2", "pk3"])
|
|
564
|
-
end
|
|
565
|
-
|
|
566
|
-
end
|
|
567
|
-
|