metry 1.2.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. data/History.txt +6 -0
  2. data/Manifest.txt +14 -69
  3. data/TODO +2 -3
  4. data/cucumber.yml +1 -0
  5. data/example/example.rb +1 -1
  6. data/features/psycho/dashboard.feature +17 -0
  7. data/features/psycho/goals.feature +24 -0
  8. data/features/psycho/visitor_tracking.feature +32 -0
  9. data/features/step_definitions/goals.rb +3 -0
  10. data/features/step_definitions/tracking.rb +1 -1
  11. data/features/step_definitions/web.rb +14 -2
  12. data/features/support/env.rb +4 -0
  13. data/lib/metry.rb +4 -6
  14. data/lib/metry/experiment.rb +6 -8
  15. data/lib/metry/psycho.rb +112 -0
  16. data/lib/metry/psycho/dashboard.erb +14 -0
  17. data/lib/metry/psycho/layout.erb +8 -0
  18. data/lib/metry/psycho/new_goal.erb +9 -0
  19. data/lib/metry/psycho/visitor.erb +7 -0
  20. data/lib/metry/rack/tracking.rb +17 -13
  21. data/lib/metry/storage.rb +116 -0
  22. data/radiant/example/features/metry.feature +8 -8
  23. data/radiant/example/features/psycho.feature +13 -0
  24. data/radiant/example/features/step_definitions/experiments.rb +2 -2
  25. data/radiant/example/features/step_definitions/tracking.rb +1 -1
  26. data/radiant/example/features/support/env.rb +3 -0
  27. data/radiant/extension/lib/metry_authenticator.rb +30 -0
  28. data/radiant/extension/lib/metry_tags.rb +2 -1
  29. data/radiant/extension/metry_extension.rb +1 -1
  30. data/test/{test_tokyo.rb → test_storage.rb} +3 -3
  31. metadata +17 -72
  32. data/lib/metry/memory.rb +0 -27
  33. data/lib/metry/tokyo.rb +0 -181
  34. data/vendor/rufus-tokyo/CHANGELOG.txt +0 -112
  35. data/vendor/rufus-tokyo/CREDITS.txt +0 -27
  36. data/vendor/rufus-tokyo/LICENSE.txt +0 -21
  37. data/vendor/rufus-tokyo/README.txt +0 -310
  38. data/vendor/rufus-tokyo/Rakefile +0 -118
  39. data/vendor/rufus-tokyo/TODO.txt +0 -25
  40. data/vendor/rufus-tokyo/doc/decision_table.numbers +0 -0
  41. data/vendor/rufus-tokyo/doc/rdoc-style.css +0 -320
  42. data/vendor/rufus-tokyo/lib/rufus-edo.rb +0 -3
  43. data/vendor/rufus-tokyo/lib/rufus-tokyo.rb +0 -3
  44. data/vendor/rufus-tokyo/lib/rufus/edo.rb +0 -39
  45. data/vendor/rufus-tokyo/lib/rufus/edo/README.txt +0 -106
  46. data/vendor/rufus-tokyo/lib/rufus/edo/cabcore.rb +0 -333
  47. data/vendor/rufus-tokyo/lib/rufus/edo/cabinet/abstract.rb +0 -219
  48. data/vendor/rufus-tokyo/lib/rufus/edo/cabinet/table.rb +0 -159
  49. data/vendor/rufus-tokyo/lib/rufus/edo/error.rb +0 -36
  50. data/vendor/rufus-tokyo/lib/rufus/edo/ntyrant.rb +0 -4
  51. data/vendor/rufus-tokyo/lib/rufus/edo/ntyrant/abstract.rb +0 -137
  52. data/vendor/rufus-tokyo/lib/rufus/edo/ntyrant/table.rb +0 -141
  53. data/vendor/rufus-tokyo/lib/rufus/edo/tabcore.rb +0 -567
  54. data/vendor/rufus-tokyo/lib/rufus/tokyo.rb +0 -58
  55. data/vendor/rufus-tokyo/lib/rufus/tokyo/cabinet/abstract.rb +0 -568
  56. data/vendor/rufus-tokyo/lib/rufus/tokyo/cabinet/lib.rb +0 -230
  57. data/vendor/rufus-tokyo/lib/rufus/tokyo/cabinet/table.rb +0 -753
  58. data/vendor/rufus-tokyo/lib/rufus/tokyo/cabinet/util.rb +0 -425
  59. data/vendor/rufus-tokyo/lib/rufus/tokyo/config.rb +0 -161
  60. data/vendor/rufus-tokyo/lib/rufus/tokyo/dystopia.rb +0 -43
  61. data/vendor/rufus-tokyo/lib/rufus/tokyo/dystopia/lib.rb +0 -65
  62. data/vendor/rufus-tokyo/lib/rufus/tokyo/dystopia/words.rb +0 -71
  63. data/vendor/rufus-tokyo/lib/rufus/tokyo/hmethods.rb +0 -111
  64. data/vendor/rufus-tokyo/lib/rufus/tokyo/query.rb +0 -102
  65. data/vendor/rufus-tokyo/lib/rufus/tokyo/transactions.rb +0 -74
  66. data/vendor/rufus-tokyo/lib/rufus/tokyo/ttcommons.rb +0 -59
  67. data/vendor/rufus-tokyo/lib/rufus/tokyo/tyrant.rb +0 -35
  68. data/vendor/rufus-tokyo/lib/rufus/tokyo/tyrant/abstract.rb +0 -146
  69. data/vendor/rufus-tokyo/lib/rufus/tokyo/tyrant/lib.rb +0 -153
  70. data/vendor/rufus-tokyo/lib/rufus/tokyo/tyrant/table.rb +0 -162
  71. data/vendor/rufus-tokyo/rufus-tokyo.gemspec +0 -25
  72. data/vendor/rufus-tokyo/spec/cabinet_spec.rb +0 -472
  73. data/vendor/rufus-tokyo/spec/cabinetconfig_spec.rb +0 -82
  74. data/vendor/rufus-tokyo/spec/edo_cabinet_spec.rb +0 -447
  75. data/vendor/rufus-tokyo/spec/edo_ntyrant_spec.rb +0 -299
  76. data/vendor/rufus-tokyo/spec/edo_ntyrant_table_spec.rb +0 -462
  77. data/vendor/rufus-tokyo/spec/edo_table_spec.rb +0 -560
  78. data/vendor/rufus-tokyo/spec/hmethods_spec.rb +0 -44
  79. data/vendor/rufus-tokyo/spec/incr.lua +0 -20
  80. data/vendor/rufus-tokyo/spec/spec.rb +0 -9
  81. data/vendor/rufus-tokyo/spec/spec_base.rb +0 -23
  82. data/vendor/rufus-tokyo/spec/start_tyrants.sh +0 -26
  83. data/vendor/rufus-tokyo/spec/stop_tyrants.sh +0 -9
  84. data/vendor/rufus-tokyo/spec/table_spec.rb +0 -567
  85. data/vendor/rufus-tokyo/spec/tyrant_spec.rb +0 -309
  86. data/vendor/rufus-tokyo/spec/tyrant_table_spec.rb +0 -479
  87. data/vendor/rufus-tokyo/spec/util_list_spec.rb +0 -200
  88. data/vendor/rufus-tokyo/spec/util_map_spec.rb +0 -132
  89. data/vendor/rufus-tokyo/tasks/dev.rb +0 -70
  90. data/vendor/rufus-tokyo/test/bm0.rb +0 -353
  91. data/vendor/rufus-tokyo/test/bm1_compression.rb +0 -54
  92. data/vendor/rufus-tokyo/test/con0.rb +0 -30
  93. data/vendor/rufus-tokyo/test/mem.rb +0 -49
  94. data/vendor/rufus-tokyo/test/mem1.rb +0 -44
  95. data/vendor/rufus-tokyo/test/readme0.rb +0 -17
  96. data/vendor/rufus-tokyo/test/readme1.rb +0 -21
  97. data/vendor/rufus-tokyo/test/readme2.rb +0 -15
  98. data/vendor/rufus-tokyo/test/readme3.rb +0 -24
  99. 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,9 +0,0 @@
1
-
2
- #
3
- # specifying rufus-tokyo
4
- #
5
- # Sun Feb 8 13:12:54 JST 2009
6
- #
7
-
8
- Dir["#{File.dirname(__FILE__)}/*_spec.rb"].each { |path| load(path) }
9
-
@@ -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,9 +0,0 @@
1
- #!/bin/bash
2
-
3
- # stopping the spec ttservers
4
-
5
- ruby -e "%w{ tmp/t_spec.pid tmp/tt_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/tt_spec.pid
9
-
@@ -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
-