couch_potato 1.10.0 → 1.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +9 -3
- data/CHANGES.md +8 -0
- data/couch_potato.gemspec +1 -1
- data/lib/couch_potato/database.rb +47 -23
- data/lib/couch_potato/version.rb +1 -1
- data/spec/railtie_spec.rb +1 -1
- data/spec/unit/database_spec.rb +32 -9
- data/spec/unit/view_query_spec.rb +12 -7
- data/spec/views_spec.rb +11 -0
- metadata +8 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fc65386f8f391b222c93733fbf83cb00050bc37b2fa1787be8d73e4847b2fa43
|
4
|
+
data.tar.gz: a2c6fe4017c646b3bceaa9baaa236044ffe286fd3380095296a602034511d817
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5f7c933270982e090183aacdb7fdd52e76e2739476e7e4d87cbcad1239c62b4973f31ce62278f181c33612bc6c2dc8ee7abbc2ffca0bef4560b919b8a37359c8
|
7
|
+
data.tar.gz: 7f79c9a6b3c31f5f1fc0eea3f4a16da6e7cb6ace5a68232a9a127d7d056b5144d88714e12e128a64eba34a9377e073311408077958c14b818c0f4037853a59a5
|
data/.github/workflows/ruby.yml
CHANGED
@@ -16,7 +16,7 @@ jobs:
|
|
16
16
|
strategy:
|
17
17
|
fail-fast: false
|
18
18
|
matrix:
|
19
|
-
ruby: [2.
|
19
|
+
ruby: [2.7, '3.0', "jruby"]
|
20
20
|
gemfile:
|
21
21
|
- "active_support_5_0"
|
22
22
|
- "active_support_5_1"
|
@@ -25,10 +25,16 @@ jobs:
|
|
25
25
|
- "active_support_6_1"
|
26
26
|
- "active_support_7_0"
|
27
27
|
exclude:
|
28
|
-
- ruby: 2.6
|
29
|
-
gemfile: "active_support_7_0"
|
30
28
|
- ruby: "jruby"
|
31
29
|
gemfile: "active_support_7_0"
|
30
|
+
- ruby: "3.0"
|
31
|
+
gemfile: "active_support_5_0"
|
32
|
+
- ruby: "3.0"
|
33
|
+
gemfile: "active_support_5_1"
|
34
|
+
- ruby: "3.0"
|
35
|
+
gemfile: "active_support_5_2"
|
36
|
+
- ruby: "3.0"
|
37
|
+
gemfile: "active_support_6_0"
|
32
38
|
steps:
|
33
39
|
- uses: actions/checkout@v2
|
34
40
|
- name: Set up CouchDB
|
data/CHANGES.md
CHANGED
data/couch_potato.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.add_dependency 'json', '~> 2.3'
|
19
19
|
|
20
20
|
s.add_development_dependency 'rake', '~>12.0'
|
21
|
-
s.add_development_dependency 'rspec', '~>3.
|
21
|
+
s.add_development_dependency 'rspec', '~>3.10.0'
|
22
22
|
s.add_development_dependency 'timecop'
|
23
23
|
s.add_development_dependency 'tzinfo'
|
24
24
|
|
@@ -65,12 +65,27 @@ module CouchPotato
|
|
65
65
|
# to a given block in batches of the given size, making multiple
|
66
66
|
# requests with according skip/limit params sent to CouchDB.
|
67
67
|
def view_in_batches(spec, batch_size: default_batch_size)
|
68
|
+
rows = nil
|
68
69
|
batch = 0
|
69
70
|
loop do
|
70
|
-
spec.view_parameters = spec
|
71
|
-
|
72
|
-
|
73
|
-
|
71
|
+
spec.view_parameters = spec
|
72
|
+
.view_parameters
|
73
|
+
.merge({limit: batch_size})
|
74
|
+
.merge(
|
75
|
+
if rows
|
76
|
+
{
|
77
|
+
startkey: rows&.last&.dig('key'),
|
78
|
+
startkey_docid: rows&.last&.dig('id'),
|
79
|
+
skip: 1
|
80
|
+
}
|
81
|
+
else
|
82
|
+
{}
|
83
|
+
end
|
84
|
+
)
|
85
|
+
result = raw_view(spec)
|
86
|
+
rows = result['rows']
|
87
|
+
yield process_view_results(result, spec)
|
88
|
+
break if rows.size < batch_size
|
74
89
|
|
75
90
|
batch += 1
|
76
91
|
end
|
@@ -198,27 +213,34 @@ module CouchPotato
|
|
198
213
|
|
199
214
|
def view_without_caching(spec)
|
200
215
|
ActiveSupport::Notifications.instrument('couch_potato.view', name: "#{spec.design_document}/#{spec.view_name}") do
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
processed_results = spec.process_results results
|
213
|
-
if processed_results.respond_to?(:database=)
|
214
|
-
processed_results.database = self
|
215
|
-
elsif processed_results.respond_to?(:each)
|
216
|
-
processed_results.each do |document|
|
217
|
-
document.database = self if document.respond_to?(:database=)
|
218
|
-
end
|
216
|
+
process_view_results(raw_view(spec), spec)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
def process_view_results(results, spec)
|
221
|
+
processed_results = spec.process_results results
|
222
|
+
if processed_results.respond_to?(:database=)
|
223
|
+
processed_results.database = self
|
224
|
+
elsif processed_results.respond_to?(:each)
|
225
|
+
processed_results.each do |document|
|
226
|
+
document.database = self if document.respond_to?(:database=)
|
219
227
|
end
|
220
|
-
processed_results
|
221
228
|
end
|
229
|
+
processed_results
|
230
|
+
end
|
231
|
+
|
232
|
+
def raw_view(spec)
|
233
|
+
CouchPotato::View::ViewQuery.new(
|
234
|
+
couchrest_database,
|
235
|
+
spec.design_document,
|
236
|
+
{ spec.view_name => {
|
237
|
+
map: spec.map_function,
|
238
|
+
reduce: spec.reduce_function
|
239
|
+
} },
|
240
|
+
({ spec.list_name => spec.list_function } unless spec.list_name.nil?),
|
241
|
+
spec.lib,
|
242
|
+
spec.language
|
243
|
+
).query_view!(spec.view_parameters)
|
222
244
|
end
|
223
245
|
|
224
246
|
def load_document_without_caching(id)
|
@@ -269,6 +291,8 @@ module CouchPotato
|
|
269
291
|
end
|
270
292
|
|
271
293
|
def bulk_load(ids)
|
294
|
+
return [] if ids.empty?
|
295
|
+
|
272
296
|
response = couchrest_database.bulk_load ids
|
273
297
|
docs = response['rows'].map { |row| row['doc'] }.compact
|
274
298
|
docs.each do |doc|
|
data/lib/couch_potato/version.rb
CHANGED
data/spec/railtie_spec.rb
CHANGED
@@ -87,7 +87,7 @@ describe "railtie" do
|
|
87
87
|
it 'assigns additional_databases to config' do
|
88
88
|
allow(File).to receive_messages(:read => "test:\n database: test\n additional_databases:\n db2: test2")
|
89
89
|
|
90
|
-
expect(CouchPotato::Config).to receive(:additional_databases=).with('db2' => 'test2')
|
90
|
+
expect(CouchPotato::Config).to receive(:additional_databases=).with({'db2' => 'test2'})
|
91
91
|
|
92
92
|
CouchPotato.rails_init
|
93
93
|
end
|
data/spec/unit/database_spec.rb
CHANGED
@@ -98,6 +98,10 @@ describe CouchPotato::Database, 'load' do
|
|
98
98
|
|
99
99
|
db.load(['1'])
|
100
100
|
end
|
101
|
+
|
102
|
+
it 'returns an empty array when passing an empty array' do
|
103
|
+
expect(db.load([])).to eq([])
|
104
|
+
end
|
101
105
|
end
|
102
106
|
end
|
103
107
|
|
@@ -426,11 +430,11 @@ describe CouchPotato::Database, '#view_in_batches' do
|
|
426
430
|
let(:view_query) do
|
427
431
|
instance_double(
|
428
432
|
CouchPotato::View::ViewQuery,
|
429
|
-
query_view!: { 'rows' => [
|
433
|
+
query_view!: { 'rows' => [] }
|
430
434
|
)
|
431
435
|
end
|
432
|
-
let(:
|
433
|
-
let(:spec) { double('view spec', process_results:
|
436
|
+
let(:processed_result) { double(:processed_result) }
|
437
|
+
let(:spec) { double('view spec', process_results: processed_result).as_null_object }
|
434
438
|
let(:couchrest_db) { double('couchrest db').as_null_object }
|
435
439
|
let(:db) { CouchPotato::Database.new(couchrest_db) }
|
436
440
|
|
@@ -439,22 +443,41 @@ describe CouchPotato::Database, '#view_in_batches' do
|
|
439
443
|
.to receive_messages(new: view_query)
|
440
444
|
end
|
441
445
|
|
442
|
-
it 'sets skip/
|
443
|
-
allow(spec).to receive(:process_results).and_return([result, result], [result]) # run twice
|
446
|
+
it 'sets no skip/startkey/startkey_docid for the first batch' do
|
444
447
|
allow(spec).to receive(:view_parameters) { { key: 'x' } }
|
445
448
|
|
446
449
|
expect(spec).to receive(:view_parameters=)
|
447
|
-
.with(key: 'x',
|
450
|
+
.with({key: 'x', limit: 2})
|
451
|
+
|
452
|
+
db.view_in_batches(spec, batch_size: 2) { |results| }
|
453
|
+
end
|
454
|
+
|
455
|
+
it 'sets skip/startkey/startkey_docid for each other batch' do
|
456
|
+
allow(spec).to receive(:view_parameters) { { key: 'x' } }
|
457
|
+
allow(view_query).to receive(:query_view!)
|
458
|
+
.and_return({'rows' => [{}, {'key' => 'k1', 'id' => 'id1'}]}, {'rows' => [{}]})
|
459
|
+
allow(spec).to receive(:view_parameters=)
|
460
|
+
|
448
461
|
expect(spec).to receive(:view_parameters=)
|
449
|
-
.with(key: 'x',
|
462
|
+
.with({key: 'x', limit: 2, startkey: 'k1', startkey_docid: 'id1', skip: 1})
|
450
463
|
|
451
464
|
db.view_in_batches(spec, batch_size: 2) { |results| }
|
452
465
|
end
|
453
466
|
|
467
|
+
it 'yields processed results to the block' do
|
468
|
+
allow(view_query).to receive(:query_view!)
|
469
|
+
.and_return({'rows' => [{'key' => 'k1', 'id' => 'id1'}]})
|
470
|
+
allow(spec).to receive(:view_parameters=)
|
471
|
+
|
472
|
+
expect { |x| db.view_in_batches(spec, batch_size: 2, &x) }.to yield_with_args(processed_result)
|
473
|
+
end
|
474
|
+
|
454
475
|
it 'yields batches until running out of data' do
|
455
|
-
allow(
|
476
|
+
allow(view_query).to receive(:query_view!)
|
477
|
+
.and_return({'rows' => [{}, {}]}, {'rows' => [{}]})
|
478
|
+
allow(spec).to receive(:process_results).and_return([processed_result, processed_result], [processed_result])
|
456
479
|
|
457
|
-
expect { |b| db.view_in_batches(spec, batch_size: 2, &b) }.to yield_successive_args([
|
480
|
+
expect { |b| db.view_in_batches(spec, batch_size: 2, &b) }.to yield_successive_args([processed_result, processed_result], [processed_result])
|
458
481
|
end
|
459
482
|
end
|
460
483
|
|
@@ -15,10 +15,12 @@ describe CouchPotato::View::ViewQuery, 'query_view!' do
|
|
15
15
|
|
16
16
|
it 'updates a view if it does not exist' do
|
17
17
|
expect(db).to receive(:save_doc).with(
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
{
|
19
|
+
'views' => {'view' => {'map' => '<map_code>', 'reduce' => '<reduce_code>'}, 'lib' => {'test' => '<lib_code>'}},
|
20
|
+
'lists' => {},
|
21
|
+
"_id" => "_design/design",
|
22
|
+
"language" => "javascript"
|
23
|
+
}
|
22
24
|
)
|
23
25
|
|
24
26
|
CouchPotato::View::ViewQuery.new(db, 'design', {:view => {:map => '<map_code>', :reduce => '<reduce_code>'}}, nil, {'test' => "<lib_code>"}).query_view!
|
@@ -46,8 +48,11 @@ describe CouchPotato::View::ViewQuery, 'query_view!' do
|
|
46
48
|
|
47
49
|
it 'updates a view in erlang if it does not exist' do
|
48
50
|
expect(db).to receive(:save_doc).with(
|
49
|
-
|
50
|
-
|
51
|
+
{
|
52
|
+
'views' => {'view' => {'map' => '<map_code>', 'reduce' => '<reduce_code>'}},
|
53
|
+
'lists' => {}, "_id" => "_design/design", "language" => "erlang"
|
54
|
+
}
|
55
|
+
)
|
51
56
|
|
52
57
|
CouchPotato::View::ViewQuery.new(db, 'design',
|
53
58
|
{:view => {:map => '<map_code>', :reduce => '<reduce_code>'}},
|
@@ -120,7 +125,7 @@ describe CouchPotato::View::ViewQuery, 'query_view!' do
|
|
120
125
|
|
121
126
|
it 'does not pass in reduce or lib keys if there is no lib or reduce object' do
|
122
127
|
allow(db).to receive(:get).and_return({'views' => {}})
|
123
|
-
expect(db).to receive(:save_doc).with('views' => {'view7' => {'map' => '<map code>'}})
|
128
|
+
expect(db).to receive(:save_doc).with({'views' => {'view7' => {'map' => '<map code>'}}})
|
124
129
|
CouchPotato::View::ViewQuery.new(db, 'design', :view7 => {:map => '<map code>', :reduce => nil}).query_view!
|
125
130
|
end
|
126
131
|
|
data/spec/views_spec.rb
CHANGED
@@ -405,4 +405,15 @@ describe 'views' do
|
|
405
405
|
expect(@db.view(Build.timeline(stale: 'ok'))).to be_empty
|
406
406
|
end
|
407
407
|
end
|
408
|
+
|
409
|
+
describe 'view_in_batches' do
|
410
|
+
it 'yields docs in batches until all gone' do
|
411
|
+
build1 = Build.new(time: 1).tap {|b| @db.save!(b) }
|
412
|
+
build2 = Build.new(time: 2).tap {|b| @db.save!(b) }
|
413
|
+
build3 = Build.new(time: 3).tap {|b| @db.save!(b) }
|
414
|
+
|
415
|
+
expect {|block| @db.view_in_batches(Build.timeline, batch_size: 2, &block)}
|
416
|
+
.to yield_successive_args([build1, build2], [build3])
|
417
|
+
end
|
418
|
+
end
|
408
419
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: couch_potato
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexander Lang
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-10-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -78,14 +78,14 @@ dependencies:
|
|
78
78
|
requirements:
|
79
79
|
- - "~>"
|
80
80
|
- !ruby/object:Gem::Version
|
81
|
-
version: 3.
|
81
|
+
version: 3.10.0
|
82
82
|
type: :development
|
83
83
|
prerelease: false
|
84
84
|
version_requirements: !ruby/object:Gem::Requirement
|
85
85
|
requirements:
|
86
86
|
- - "~>"
|
87
87
|
- !ruby/object:Gem::Version
|
88
|
-
version: 3.
|
88
|
+
version: 3.10.0
|
89
89
|
- !ruby/object:Gem::Dependency
|
90
90
|
name: timecop
|
91
91
|
requirement: !ruby/object:Gem::Requirement
|
@@ -219,7 +219,7 @@ files:
|
|
219
219
|
homepage: http://github.com/langalex/couch_potato
|
220
220
|
licenses: []
|
221
221
|
metadata: {}
|
222
|
-
post_install_message:
|
222
|
+
post_install_message:
|
223
223
|
rdoc_options: []
|
224
224
|
require_paths:
|
225
225
|
- lib
|
@@ -234,8 +234,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
234
234
|
- !ruby/object:Gem::Version
|
235
235
|
version: '0'
|
236
236
|
requirements: []
|
237
|
-
rubygems_version: 3.
|
238
|
-
signing_key:
|
237
|
+
rubygems_version: 3.2.32
|
238
|
+
signing_key:
|
239
239
|
specification_version: 4
|
240
240
|
summary: Ruby persistence layer for CouchDB
|
241
241
|
test_files:
|