analysand 1.0.1 → 1.1.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/CHANGELOG +16 -0
- data/README +3 -2
- data/analysand.gemspec +4 -1
- data/bin/analysand +2 -3
- data/lib/analysand.rb +3 -5
- data/lib/analysand/change_watcher.rb +3 -1
- data/lib/analysand/connection_testing.rb +7 -1
- data/lib/analysand/database.rb +38 -147
- data/lib/analysand/errors.rb +3 -0
- data/lib/analysand/reading.rb +26 -0
- data/lib/analysand/streaming_view_response.rb +100 -0
- data/lib/analysand/version.rb +1 -1
- data/lib/analysand/view_streaming/builder.rb +142 -0
- data/lib/analysand/viewing.rb +95 -0
- data/lib/analysand/writing.rb +71 -0
- data/spec/analysand/a_response.rb +19 -0
- data/spec/analysand/change_watcher_spec.rb +18 -0
- data/spec/analysand/database_spec.rb +7 -0
- data/spec/analysand/response_spec.rb +9 -5
- data/spec/analysand/view_response_spec.rb +17 -6
- data/spec/analysand/view_streaming/builder_spec.rb +73 -0
- data/spec/analysand/view_streaming_spec.rb +122 -0
- data/spec/fixtures/vcr_cassettes/view.yml +40 -0
- data/spec/support/database_access.rb +2 -2
- metadata +90 -63
@@ -0,0 +1,122 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'analysand/database'
|
4
|
+
require 'benchmark'
|
5
|
+
|
6
|
+
require File.expand_path('../a_response', __FILE__)
|
7
|
+
|
8
|
+
module Analysand
|
9
|
+
describe Database do
|
10
|
+
let(:db) { Database.new(database_uri) }
|
11
|
+
let(:row_count) { 10000 }
|
12
|
+
|
13
|
+
before(:all) do
|
14
|
+
WebMock.disable!
|
15
|
+
end
|
16
|
+
|
17
|
+
after(:all) do
|
18
|
+
WebMock.enable!
|
19
|
+
end
|
20
|
+
|
21
|
+
before(:all) do
|
22
|
+
clean_databases!
|
23
|
+
|
24
|
+
doc = {
|
25
|
+
'views' => {
|
26
|
+
'a_view' => {
|
27
|
+
'map' => %Q{
|
28
|
+
function (doc) {
|
29
|
+
var i;
|
30
|
+
|
31
|
+
for(i = 0; i < #{row_count}; i++) {
|
32
|
+
emit(doc['_id'], i);
|
33
|
+
}
|
34
|
+
}
|
35
|
+
}
|
36
|
+
}
|
37
|
+
}
|
38
|
+
}
|
39
|
+
|
40
|
+
db.put!('_design/doc', doc, admin_credentials)
|
41
|
+
db.put!('abc123', {}, admin_credentials)
|
42
|
+
end
|
43
|
+
|
44
|
+
shared_examples_for 'a view streamer' do
|
45
|
+
def get_view(options = {})
|
46
|
+
db.send(method, 'doc/a_view', options)
|
47
|
+
end
|
48
|
+
|
49
|
+
describe 'response' do
|
50
|
+
it_should_behave_like 'a response' do
|
51
|
+
let(:response) { get_view(:stream => true) }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'returns all rows in order' do
|
56
|
+
resp = get_view(:stream => true)
|
57
|
+
|
58
|
+
resp.rows.map { |r| r['value'] }.should == (0...row_count).to_a
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'yields docs' do
|
62
|
+
resp = get_view(:include_docs => true, :stream => true)
|
63
|
+
|
64
|
+
resp.docs.take(10).all? { |d| d.has_key?('_id') }.should be_true
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'returns rows as soon as possible' do
|
68
|
+
# first, make sure the view's built
|
69
|
+
db.head('_design/doc/_view/a_view', admin_credentials)
|
70
|
+
|
71
|
+
streamed = Benchmark.realtime do
|
72
|
+
resp = get_view(:stream => true)
|
73
|
+
resp.rows.take(10)
|
74
|
+
end
|
75
|
+
|
76
|
+
read_everything = Benchmark.realtime do
|
77
|
+
resp = get_view
|
78
|
+
resp.rows.take(10)
|
79
|
+
end
|
80
|
+
|
81
|
+
streamed.should_not be_within(0.5).of(read_everything)
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'returns view metadata' do
|
85
|
+
resp = get_view(:stream => true)
|
86
|
+
|
87
|
+
resp.total_rows.should == row_count
|
88
|
+
resp.offset.should == 0
|
89
|
+
end
|
90
|
+
|
91
|
+
describe '#each' do
|
92
|
+
it 'returns an Enumerator if no block is given' do
|
93
|
+
resp = get_view(:stream => true)
|
94
|
+
|
95
|
+
resp.rows.each.should be_instance_of(Enumerator)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe '#view in streaming mode' do
|
101
|
+
it_should_behave_like 'a view streamer' do
|
102
|
+
let(:method) { :view }
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'returns error codes from failures' do
|
106
|
+
resp = db.view('doc/nonexistent', :stream => true)
|
107
|
+
|
108
|
+
resp.code.should == '404'
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe '#view! in streaming mode' do
|
113
|
+
it_should_behave_like 'a view streamer' do
|
114
|
+
let(:method) { :view! }
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'raises CannotAccessView on failure' do
|
118
|
+
lambda { db.view!('doc/nonexistent', :stream => true) }.should raise_error(CannotAccessView)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: http://localhost:5984/analysand_test/_design/doc/_view/a_view
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
Accept:
|
11
|
+
- ! '*/*'
|
12
|
+
User-Agent:
|
13
|
+
- Ruby
|
14
|
+
Connection:
|
15
|
+
- keep-alive
|
16
|
+
Keep-Alive:
|
17
|
+
- 30
|
18
|
+
response:
|
19
|
+
status:
|
20
|
+
code: 200
|
21
|
+
message: OK
|
22
|
+
headers:
|
23
|
+
Transfer-Encoding:
|
24
|
+
- chunked
|
25
|
+
Server:
|
26
|
+
- CouchDB/1.2.0 (Erlang OTP/R15B)
|
27
|
+
Etag:
|
28
|
+
- ! '"D4N5T8QITOHPR5PN1FFNNQ9JA"'
|
29
|
+
Date:
|
30
|
+
- Fri, 02 Nov 2012 14:33:24 GMT
|
31
|
+
Content-Type:
|
32
|
+
- text/plain; charset=utf-8
|
33
|
+
Cache-Control:
|
34
|
+
- must-revalidate
|
35
|
+
body:
|
36
|
+
encoding: US-ASCII
|
37
|
+
string: ! "{\"total_rows\":1,\"offset\":0,\"rows\":[\r\n{\"id\":\"abc123\",\"key\":\"abc123\",\"value\":1}\r\n]}\n"
|
38
|
+
http_version:
|
39
|
+
recorded_at: Fri, 02 Nov 2012 14:33:24 GMT
|
40
|
+
recorded_with: VCR 2.3.0
|
@@ -32,8 +32,8 @@ module DatabaseAccess
|
|
32
32
|
##
|
33
33
|
# Resets member and admin lists for the test database to [].
|
34
34
|
def clear_security
|
35
|
-
set_security({ '
|
36
|
-
{ '
|
35
|
+
set_security({ 'names' => [], 'roles' => [] },
|
36
|
+
{ 'names' => [], 'roles' => [] })
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
metadata
CHANGED
@@ -1,192 +1,208 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: analysand
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.1.0
|
4
5
|
prerelease:
|
5
|
-
version: 1.0.1
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- David Yip
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-11-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
prerelease: false
|
16
15
|
name: celluloid
|
17
|
-
|
18
|
-
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
19
18
|
requirements:
|
20
19
|
- - ! '>='
|
21
20
|
- !ruby/object:Gem::Version
|
22
21
|
version: '0.12'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
25
|
none: false
|
24
|
-
requirement: !ruby/object:Gem::Requirement
|
25
26
|
requirements:
|
26
27
|
- - ! '>='
|
27
28
|
- !ruby/object:Gem::Version
|
28
29
|
version: '0.12'
|
29
|
-
none: false
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
|
-
prerelease: false
|
32
31
|
name: celluloid-io
|
33
|
-
|
34
|
-
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
35
34
|
requirements:
|
36
35
|
- - ! '>='
|
37
36
|
- !ruby/object:Gem::Version
|
38
37
|
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
39
41
|
none: false
|
40
|
-
requirement: !ruby/object:Gem::Requirement
|
41
42
|
requirements:
|
42
43
|
- - ! '>='
|
43
44
|
- !ruby/object:Gem::Version
|
44
45
|
version: '0'
|
45
|
-
none: false
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
|
-
prerelease: false
|
48
47
|
name: http_parser.rb
|
49
|
-
|
50
|
-
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
51
50
|
requirements:
|
52
51
|
- - ! '>='
|
53
52
|
- !ruby/object:Gem::Version
|
54
53
|
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
55
57
|
none: false
|
56
|
-
requirement: !ruby/object:Gem::Requirement
|
57
58
|
requirements:
|
58
59
|
- - ! '>='
|
59
60
|
- !ruby/object:Gem::Version
|
60
61
|
version: '0'
|
61
|
-
none: false
|
62
62
|
- !ruby/object:Gem::Dependency
|
63
|
-
prerelease: false
|
64
63
|
name: json
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
65
70
|
type: :runtime
|
71
|
+
prerelease: false
|
66
72
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
67
74
|
requirements:
|
68
75
|
- - ! '>='
|
69
76
|
- !ruby/object:Gem::Version
|
70
77
|
version: '0'
|
71
|
-
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: json-stream
|
72
80
|
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
73
82
|
requirements:
|
74
83
|
- - ! '>='
|
75
84
|
- !ruby/object:Gem::Version
|
76
85
|
version: '0'
|
77
|
-
none: false
|
78
|
-
- !ruby/object:Gem::Dependency
|
79
|
-
prerelease: false
|
80
|
-
name: net-http-persistent
|
81
86
|
type: :runtime
|
87
|
+
prerelease: false
|
82
88
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
83
90
|
requirements:
|
84
91
|
- - ! '>='
|
85
92
|
- !ruby/object:Gem::Version
|
86
93
|
version: '0'
|
87
|
-
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: net-http-persistent
|
88
96
|
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
89
98
|
requirements:
|
90
99
|
- - ! '>='
|
91
100
|
- !ruby/object:Gem::Version
|
92
101
|
version: '0'
|
93
|
-
none: false
|
94
|
-
- !ruby/object:Gem::Dependency
|
95
|
-
prerelease: false
|
96
|
-
name: rack
|
97
102
|
type: :runtime
|
103
|
+
prerelease: false
|
98
104
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
99
106
|
requirements:
|
100
107
|
- - ! '>='
|
101
108
|
- !ruby/object:Gem::Version
|
102
109
|
version: '0'
|
103
|
-
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: rack
|
104
112
|
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
105
114
|
requirements:
|
106
115
|
- - ! '>='
|
107
116
|
- !ruby/object:Gem::Version
|
108
117
|
version: '0'
|
109
|
-
none: false
|
110
|
-
- !ruby/object:Gem::Dependency
|
111
|
-
prerelease: false
|
112
|
-
name: yajl-ruby
|
113
118
|
type: :runtime
|
119
|
+
prerelease: false
|
114
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
115
122
|
requirements:
|
116
123
|
- - ! '>='
|
117
124
|
- !ruby/object:Gem::Version
|
118
125
|
version: '0'
|
119
|
-
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: yajl-ruby
|
120
128
|
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
121
130
|
requirements:
|
122
131
|
- - ! '>='
|
123
132
|
- !ruby/object:Gem::Version
|
124
133
|
version: '0'
|
125
|
-
|
126
|
-
- !ruby/object:Gem::Dependency
|
134
|
+
type: :runtime
|
127
135
|
prerelease: false
|
128
|
-
name: rake
|
129
|
-
type: :development
|
130
136
|
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
131
138
|
requirements:
|
132
139
|
- - ! '>='
|
133
140
|
- !ruby/object:Gem::Version
|
134
141
|
version: '0'
|
135
|
-
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: rake
|
136
144
|
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
137
146
|
requirements:
|
138
147
|
- - ! '>='
|
139
148
|
- !ruby/object:Gem::Version
|
140
149
|
version: '0'
|
141
|
-
none: false
|
142
|
-
- !ruby/object:Gem::Dependency
|
143
|
-
prerelease: false
|
144
|
-
name: rspec
|
145
150
|
type: :development
|
151
|
+
prerelease: false
|
146
152
|
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
147
154
|
requirements:
|
148
155
|
- - ! '>='
|
149
156
|
- !ruby/object:Gem::Version
|
150
157
|
version: '0'
|
151
|
-
|
158
|
+
- !ruby/object:Gem::Dependency
|
159
|
+
name: rspec
|
152
160
|
requirement: !ruby/object:Gem::Requirement
|
161
|
+
none: false
|
153
162
|
requirements:
|
154
163
|
- - ! '>='
|
155
164
|
- !ruby/object:Gem::Version
|
156
165
|
version: '0'
|
157
|
-
none: false
|
158
|
-
- !ruby/object:Gem::Dependency
|
159
|
-
prerelease: false
|
160
|
-
name: vcr
|
161
166
|
type: :development
|
167
|
+
prerelease: false
|
162
168
|
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
none: false
|
163
170
|
requirements:
|
164
171
|
- - ! '>='
|
165
172
|
- !ruby/object:Gem::Version
|
166
173
|
version: '0'
|
167
|
-
|
174
|
+
- !ruby/object:Gem::Dependency
|
175
|
+
name: vcr
|
168
176
|
requirement: !ruby/object:Gem::Requirement
|
177
|
+
none: false
|
169
178
|
requirements:
|
170
179
|
- - ! '>='
|
171
180
|
- !ruby/object:Gem::Version
|
172
181
|
version: '0'
|
173
|
-
none: false
|
174
|
-
- !ruby/object:Gem::Dependency
|
175
|
-
prerelease: false
|
176
|
-
name: webmock
|
177
182
|
type: :development
|
183
|
+
prerelease: false
|
178
184
|
version_requirements: !ruby/object:Gem::Requirement
|
185
|
+
none: false
|
179
186
|
requirements:
|
180
187
|
- - ! '>='
|
181
188
|
- !ruby/object:Gem::Version
|
182
189
|
version: '0'
|
183
|
-
|
190
|
+
- !ruby/object:Gem::Dependency
|
191
|
+
name: webmock
|
184
192
|
requirement: !ruby/object:Gem::Requirement
|
193
|
+
none: false
|
185
194
|
requirements:
|
186
195
|
- - ! '>='
|
187
196
|
- !ruby/object:Gem::Version
|
188
197
|
version: '0'
|
198
|
+
type: :development
|
199
|
+
prerelease: false
|
200
|
+
version_requirements: !ruby/object:Gem::Requirement
|
189
201
|
none: false
|
202
|
+
requirements:
|
203
|
+
- - ! '>='
|
204
|
+
- !ruby/object:Gem::Version
|
205
|
+
version: '0'
|
190
206
|
description: A terrible burden for a couch
|
191
207
|
email:
|
192
208
|
- yipdw@member.fsf.org
|
@@ -198,6 +214,7 @@ files:
|
|
198
214
|
- .gitignore
|
199
215
|
- .rspec
|
200
216
|
- .travis.yml
|
217
|
+
- CHANGELOG
|
201
218
|
- Gemfile
|
202
219
|
- LICENSE
|
203
220
|
- README
|
@@ -211,10 +228,16 @@ files:
|
|
211
228
|
- lib/analysand/database.rb
|
212
229
|
- lib/analysand/errors.rb
|
213
230
|
- lib/analysand/instance.rb
|
231
|
+
- lib/analysand/reading.rb
|
214
232
|
- lib/analysand/response.rb
|
233
|
+
- lib/analysand/streaming_view_response.rb
|
215
234
|
- lib/analysand/version.rb
|
216
235
|
- lib/analysand/view_response.rb
|
236
|
+
- lib/analysand/view_streaming/builder.rb
|
237
|
+
- lib/analysand/viewing.rb
|
238
|
+
- lib/analysand/writing.rb
|
217
239
|
- script/setup_database.rb
|
240
|
+
- spec/analysand/a_response.rb
|
218
241
|
- spec/analysand/a_session_grantor.rb
|
219
242
|
- spec/analysand/change_watcher_spec.rb
|
220
243
|
- spec/analysand/database_spec.rb
|
@@ -222,37 +245,37 @@ files:
|
|
222
245
|
- spec/analysand/instance_spec.rb
|
223
246
|
- spec/analysand/response_spec.rb
|
224
247
|
- spec/analysand/view_response_spec.rb
|
248
|
+
- spec/analysand/view_streaming/builder_spec.rb
|
249
|
+
- spec/analysand/view_streaming_spec.rb
|
225
250
|
- spec/fixtures/vcr_cassettes/get_session_does_not_refresh_cookie.yml
|
226
251
|
- spec/fixtures/vcr_cassettes/get_session_refreshes_cookie.yml
|
227
252
|
- spec/fixtures/vcr_cassettes/head_request_with_etag.yml
|
253
|
+
- spec/fixtures/vcr_cassettes/view.yml
|
228
254
|
- spec/spec_helper.rb
|
229
255
|
- spec/support/database_access.rb
|
230
256
|
- spec/support/example_isolation.rb
|
231
257
|
- spec/support/test_parameters.rb
|
232
|
-
homepage:
|
258
|
+
homepage: https://github.com/yipdw/analysand
|
233
259
|
licenses: []
|
234
260
|
post_install_message:
|
235
261
|
rdoc_options: []
|
236
262
|
require_paths:
|
237
263
|
- lib
|
238
264
|
required_ruby_version: !ruby/object:Gem::Requirement
|
265
|
+
none: false
|
239
266
|
requirements:
|
240
267
|
- - ! '>='
|
241
268
|
- !ruby/object:Gem::Version
|
242
|
-
|
243
|
-
- 0
|
244
|
-
version: '0'
|
245
|
-
hash: 2002549777813010636
|
246
|
-
none: false
|
269
|
+
version: '1.9'
|
247
270
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
271
|
+
none: false
|
248
272
|
requirements:
|
249
273
|
- - ! '>='
|
250
274
|
- !ruby/object:Gem::Version
|
275
|
+
version: '0'
|
251
276
|
segments:
|
252
277
|
- 0
|
253
|
-
|
254
|
-
hash: 2002549777813010636
|
255
|
-
none: false
|
278
|
+
hash: 1636075710604712169
|
256
279
|
requirements: []
|
257
280
|
rubyforge_project:
|
258
281
|
rubygems_version: 1.8.24
|
@@ -260,6 +283,7 @@ signing_key:
|
|
260
283
|
specification_version: 3
|
261
284
|
summary: A CouchDB client of dubious worth
|
262
285
|
test_files:
|
286
|
+
- spec/analysand/a_response.rb
|
263
287
|
- spec/analysand/a_session_grantor.rb
|
264
288
|
- spec/analysand/change_watcher_spec.rb
|
265
289
|
- spec/analysand/database_spec.rb
|
@@ -267,9 +291,12 @@ test_files:
|
|
267
291
|
- spec/analysand/instance_spec.rb
|
268
292
|
- spec/analysand/response_spec.rb
|
269
293
|
- spec/analysand/view_response_spec.rb
|
294
|
+
- spec/analysand/view_streaming/builder_spec.rb
|
295
|
+
- spec/analysand/view_streaming_spec.rb
|
270
296
|
- spec/fixtures/vcr_cassettes/get_session_does_not_refresh_cookie.yml
|
271
297
|
- spec/fixtures/vcr_cassettes/get_session_refreshes_cookie.yml
|
272
298
|
- spec/fixtures/vcr_cassettes/head_request_with_etag.yml
|
299
|
+
- spec/fixtures/vcr_cassettes/view.yml
|
273
300
|
- spec/spec_helper.rb
|
274
301
|
- spec/support/database_access.rb
|
275
302
|
- spec/support/example_isolation.rb
|