couch_potato 1.17.0 → 1.19.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.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +9 -7
- data/CHANGES.md +11 -0
- data/README.md +8 -52
- data/Rakefile +1 -1
- data/couch_potato.gemspec +1 -1
- data/gemfiles/{active_support_7_0 → active_support_7_2} +1 -1
- data/gemfiles/{active_support_7_1 → active_support_8_0} +1 -1
- data/lib/couch_potato/database.rb +0 -2
- data/lib/couch_potato/persistence.rb +9 -6
- data/lib/couch_potato/version.rb +2 -2
- data/lib/couch_potato/view/base_view_spec.rb +21 -12
- data/lib/couch_potato/view/custom_view_spec.rb +0 -4
- data/lib/couch_potato/view/custom_views.rb +12 -0
- data/lib/couch_potato/view/flex_view_spec.rb +1 -1
- data/lib/couch_potato/view/raw_view_spec.rb +2 -6
- data/lib/couch_potato/view/view_query.rb +26 -28
- data/lib/couch_potato.rb +9 -1
- data/spec/property_spec.rb +1 -1
- data/spec/single_design_document_spec.rb +63 -0
- data/spec/unit/attributes_spec.rb +1 -1
- data/spec/unit/base_view_spec_spec.rb +62 -68
- data/spec/unit/couch_potato_spec.rb +3 -0
- data/spec/unit/database_spec.rb +1 -53
- data/spec/unit/rspec_matchers_spec.rb +2 -66
- data/spec/unit/view_query_spec.rb +5 -99
- data/spec/view_updates_spec.rb +53 -5
- data/spec/views_spec.rb +1 -34
- metadata +10 -11
- data/lib/couch_potato/view/lists.rb +0 -23
- data/spec/unit/lists_spec.rb +0 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 46b162f592d8c1c7dada2e150793fbfc5f8c76c1e9bb8a3364f8f2895505335b
|
4
|
+
data.tar.gz: eca37db69c74f6f58ec6bb518028a100e9b74ce1bfbe7edce16b899c5caa7406
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c4f8edddc5e9a667bb09cb1fa9c5ee5bbb6f374088f27d039bfedd21ce59f13be2a963803bb40be0677916ab9d1d3543eb325849dd5f05010089092ceb0ce891
|
7
|
+
data.tar.gz: 4952e15f37cce9db1e07032f8588a24d28d990cba4e657b657cd4621cf8786a08af9289daadcc1c65a1f6d7f55ea4aef447f7e7e409c488bb706e6ea39e61c4f
|
data/.github/workflows/ruby.yml
CHANGED
@@ -16,19 +16,19 @@ jobs:
|
|
16
16
|
strategy:
|
17
17
|
fail-fast: false
|
18
18
|
matrix:
|
19
|
-
ruby: ["3.
|
19
|
+
ruby: ["3.2", "3.3", "jruby"]
|
20
20
|
gemfile:
|
21
|
-
- "
|
22
|
-
- "
|
21
|
+
- "active_support_7_2"
|
22
|
+
- "active_support_8_0"
|
23
23
|
exclude:
|
24
24
|
- ruby: "jruby"
|
25
|
-
gemfile: "
|
25
|
+
gemfile: "active_support_8_0"
|
26
26
|
steps:
|
27
|
-
- uses: actions/checkout@
|
27
|
+
- uses: actions/checkout@v4
|
28
28
|
- name: Set up CouchDB
|
29
|
-
uses: cobot/couchdb-action@
|
29
|
+
uses: cobot/couchdb-action@v5
|
30
30
|
with:
|
31
|
-
couchdb
|
31
|
+
couchdb-version: "2.3.1"
|
32
32
|
- name: Set up Ruby
|
33
33
|
uses: ruby/setup-ruby@v1
|
34
34
|
with:
|
@@ -36,3 +36,5 @@ jobs:
|
|
36
36
|
bundler-cache: true
|
37
37
|
- name: Run tests
|
38
38
|
run: bundle exec rake spec_ci
|
39
|
+
env:
|
40
|
+
DATABASE: http://admin:admin@localhost:5984/couch_potato_test
|
data/CHANGES.md
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
## Changes
|
2
2
|
|
3
|
+
# 1.19.0 / rspec-matchers 4.2.0
|
4
|
+
|
5
|
+
- add `single_design_document` config option
|
6
|
+
- remove support for lists and lib
|
7
|
+
|
8
|
+
# 1.18.0
|
9
|
+
|
10
|
+
- add testing Rails 7.2/8 on CI
|
11
|
+
- change gemspec to allow for Rails 8
|
12
|
+
- remove support for Rails < 7.2
|
13
|
+
|
3
14
|
# 1.17.0
|
4
15
|
|
5
16
|
- filter out nil ids for loading multiple documents
|
data/README.md
CHANGED
@@ -80,6 +80,12 @@ Another switch allows you to store each CouchDB view in its own design document.
|
|
80
80
|
CouchPotato::Config.split_design_documents_per_view = true
|
81
81
|
```
|
82
82
|
|
83
|
+
With the following switch, couch potato only creates a single design document for all views:
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
CouchPotato::Config.single_design_document = true
|
87
|
+
```
|
88
|
+
|
83
89
|
If you are using more than one database from your app, you can create aliases:
|
84
90
|
|
85
91
|
```ruby
|
@@ -95,6 +101,7 @@ Create a `config/couchdb.yml`:
|
|
95
101
|
default: &default
|
96
102
|
split_design_documents_per_view: true # optional, default is false
|
97
103
|
digest_view_names: true # optional, default is false
|
104
|
+
single_design_document: true # optional, default is false
|
98
105
|
default_language: :erlang # optional, default is javascript
|
99
106
|
database_host: "http://127.0.0.1:5984"
|
100
107
|
|
@@ -299,7 +306,7 @@ user.valid? # => false
|
|
299
306
|
user.errors[:name] # => ['can't be blank']
|
300
307
|
```
|
301
308
|
|
302
|
-
#### Finding stuff / views
|
309
|
+
#### Finding stuff / views
|
303
310
|
|
304
311
|
In order to find data in your CouchDB you have to create a [view](http://books.couchdb.org/relax/design-documents/views) first. Couch Potato offers you to create and manage those views for you. All you have to do is declare them in your classes:
|
305
312
|
|
@@ -403,14 +410,6 @@ class User
|
|
403
410
|
end
|
404
411
|
```
|
405
412
|
|
406
|
-
commonJS modules can also be used in custom views:
|
407
|
-
|
408
|
-
```ruby
|
409
|
-
class User
|
410
|
-
view :all, :map => "function(doc) { emit(null, require("views/lib/test").test)}", :lib => {:test => "exports.test = 'test'"}, :include_docs => true, :type => :custom
|
411
|
-
end
|
412
|
-
```
|
413
|
-
|
414
413
|
If you don't want the results to be converted into models the raw view is your friend:
|
415
414
|
|
416
415
|
```ruby
|
@@ -450,49 +449,6 @@ You can pass in your own view specifications by passing in `:type => MyViewSpecC
|
|
450
449
|
|
451
450
|
If turned on, Couch Potato will append an MD5 digest of the map function to each view name. This makes sure (together with split_design_documents_per_view) that no views/design documents are ever updated. Instead, new ones are created. Since reindexing can take a long time once your database is larger, you want to avoid blocking your app while CouchDB is busy. Instead, you create a new view, warm it up, and only then start using it.
|
452
451
|
|
453
|
-
##### Lists
|
454
|
-
|
455
|
-
CouchPotato also supports [CouchDB lists](http://books.couchdb.org/relax/design-documents/lists). With lists you can process the result of a view query with another JavaScript function. This can be useful for example if you want to filter your results, or add some data to each document.
|
456
|
-
|
457
|
-
Defining a list works similarly to views:
|
458
|
-
|
459
|
-
```ruby
|
460
|
-
class User
|
461
|
-
include CouchPotato::Persistence
|
462
|
-
|
463
|
-
property :first_name
|
464
|
-
view :with_full_name, key: first_namne, list: :add_last_name
|
465
|
-
view :all, key: :first_name
|
466
|
-
|
467
|
-
list :add_last_name, <<-JS
|
468
|
-
function(head, req) {
|
469
|
-
var row;
|
470
|
-
send('{"rows": [');
|
471
|
-
while(row = getRow()) {
|
472
|
-
row.doc.name = row.doc.first_name + ' doe';
|
473
|
-
send(JSON.stringify(row));
|
474
|
-
};
|
475
|
-
send(']}');
|
476
|
-
}
|
477
|
-
JS
|
478
|
-
end
|
479
|
-
|
480
|
-
CouchPotato.database.save User.new(first_name: 'joe')
|
481
|
-
CouchPotato.database.view(User.with_full_name).first.name # => 'joe doe'
|
482
|
-
```
|
483
|
-
|
484
|
-
You can also pass in the list at query time:
|
485
|
-
|
486
|
-
```ruby
|
487
|
-
CouchPotato.database.view(User.all(list: :add_last_name))
|
488
|
-
```
|
489
|
-
|
490
|
-
And you can pass parameters to the list:
|
491
|
-
|
492
|
-
```ruby
|
493
|
-
CouchPotato.database.view(User.all(list: :add_last_name, list_params: {filter: '*'}))
|
494
|
-
```
|
495
|
-
|
496
452
|
#### Associations
|
497
453
|
|
498
454
|
Not supported. Not sure if they ever will be. You can implement those yourself using views and custom methods on your models.
|
data/Rakefile
CHANGED
@@ -26,7 +26,7 @@ end
|
|
26
26
|
|
27
27
|
desc 'Run all specs for all gemfiles'
|
28
28
|
task :spec do
|
29
|
-
%w(
|
29
|
+
%w(7_2 8_0).each do |version|
|
30
30
|
Bundler.with_original_env do
|
31
31
|
puts "Running tests with ActiveSupport #{version.sub('_', '.')}"
|
32
32
|
sh "env BUNDLE_GEMFILE=gemfiles/active_support_#{version} bundle install"
|
data/couch_potato.gemspec
CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.version = CouchPotato::VERSION
|
14
14
|
s.platform = Gem::Platform::RUBY
|
15
15
|
|
16
|
-
s.add_dependency 'activemodel', ['>=
|
16
|
+
s.add_dependency 'activemodel', ['>= 7.2', '< 8.1']
|
17
17
|
s.add_dependency 'couchrest', '~>2.0.0'
|
18
18
|
s.add_dependency 'json', '~> 2.3'
|
19
19
|
|
@@ -12,16 +12,20 @@ require File.dirname(__FILE__) + '/persistence/type_caster'
|
|
12
12
|
require File.dirname(__FILE__) + '/persistence/revisions'
|
13
13
|
require File.dirname(__FILE__) + '/forbidden_attributes_protection'
|
14
14
|
require File.dirname(__FILE__) + '/view/custom_views'
|
15
|
-
require File.dirname(__FILE__) + '/view/lists'
|
16
15
|
require File.dirname(__FILE__) + '/view/view_query'
|
17
16
|
|
18
17
|
|
19
18
|
module CouchPotato
|
20
19
|
module Persistence
|
20
|
+
module TrackModels
|
21
|
+
def inherited(child)
|
22
|
+
super
|
23
|
+
CouchPotato.models << child
|
24
|
+
end
|
25
|
+
end
|
21
26
|
|
22
27
|
def self.included(base) #:nodoc:
|
23
|
-
base.send :include, Properties, Callbacks, Json, CouchPotato::View::CustomViews
|
24
|
-
CouchPotato::View::Lists
|
28
|
+
base.send :include, Properties, Callbacks, Json, CouchPotato::View::CustomViews
|
25
29
|
base.send :include, DirtyAttributes, GhostAttributes, Attachments
|
26
30
|
base.send :include, MagicTimestamps, ActiveModelCompliance,
|
27
31
|
ForbiddenAttributesProtection, Revisions
|
@@ -31,9 +35,8 @@ module CouchPotato
|
|
31
35
|
alias_method :id, :_id
|
32
36
|
alias_method :id=, :_id=
|
33
37
|
|
34
|
-
|
35
|
-
|
36
|
-
CouchPotato.models << child
|
38
|
+
class << self
|
39
|
+
prepend TrackModels
|
37
40
|
end
|
38
41
|
end
|
39
42
|
|
data/lib/couch_potato/version.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
module CouchPotato
|
4
4
|
module View
|
5
5
|
class BaseViewSpec
|
6
|
-
attr_reader :reduce_function, :
|
6
|
+
attr_reader :reduce_function, :design_document, :view_name, :klass, :options, :language
|
7
7
|
attr_accessor :view_parameters
|
8
8
|
|
9
9
|
private :klass, :options
|
@@ -11,7 +11,7 @@ module CouchPotato
|
|
11
11
|
def initialize(klass, view_name, options, view_parameters)
|
12
12
|
normalized_view_parameters = ViewParameters.normalize_view_parameters view_parameters
|
13
13
|
|
14
|
-
|
14
|
+
|
15
15
|
@language = options[:language] || Config.default_language
|
16
16
|
|
17
17
|
assert_valid_view_parameters normalized_view_parameters
|
@@ -19,16 +19,12 @@ module CouchPotato
|
|
19
19
|
@options = options
|
20
20
|
@view_name = compute_view_name(view_name,
|
21
21
|
options.key?(:digest_view_name) ? options[:digest_view_name] : Config.digest_view_names)
|
22
|
-
@design_document =
|
23
|
-
@list_params = normalized_view_parameters.delete :list_params
|
24
|
-
|
25
|
-
@list_function = klass.lists(@list_name) if @list_name
|
22
|
+
@design_document = design_doc_name
|
26
23
|
@view_parameters = {}
|
27
24
|
%i[group include_docs descending group_level limit].each do |key|
|
28
25
|
@view_parameters[key] = options[key] if options.include?(key)
|
29
26
|
end
|
30
27
|
@view_parameters.merge!(normalized_view_parameters)
|
31
|
-
@view_parameters.merge!(@list_params) if @list_params
|
32
28
|
end
|
33
29
|
|
34
30
|
def process_results(results)
|
@@ -42,10 +38,16 @@ module CouchPotato
|
|
42
38
|
private
|
43
39
|
|
44
40
|
def compute_view_name(view_name, digest)
|
41
|
+
name = if CouchPotato::Config.single_design_document
|
42
|
+
"#{translate_to_design_doc_name(klass.to_s, view_name)}-#{view_name}"
|
43
|
+
else
|
44
|
+
view_name
|
45
|
+
end
|
46
|
+
|
45
47
|
if digest
|
46
|
-
"#{
|
48
|
+
"#{name}-#{Digest::MD5.hexdigest(map_function + reduce_function.to_s)}"
|
47
49
|
else
|
48
|
-
|
50
|
+
name
|
49
51
|
end
|
50
52
|
end
|
51
53
|
|
@@ -56,10 +58,18 @@ module CouchPotato
|
|
56
58
|
end
|
57
59
|
|
58
60
|
def valid_view_parameters
|
59
|
-
%w[
|
61
|
+
%w[key keys startkey startkey_docid endkey endkey_docid limit stale descending skip group group_level reduce include_docs inclusive_end]
|
62
|
+
end
|
63
|
+
|
64
|
+
def design_doc_name
|
65
|
+
if CouchPotato::Config.single_design_document
|
66
|
+
'couch_potato'
|
67
|
+
else
|
68
|
+
translate_to_design_doc_name(klass.to_s, view_name)
|
69
|
+
end
|
60
70
|
end
|
61
71
|
|
62
|
-
def translate_to_design_doc_name(klass_name, view_name
|
72
|
+
def translate_to_design_doc_name(klass_name, view_name)
|
63
73
|
klass_name = klass_name.dup
|
64
74
|
klass_name.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
65
75
|
klass_name.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
@@ -68,7 +78,6 @@ module CouchPotato
|
|
68
78
|
|
69
79
|
if CouchPotato::Config.split_design_documents_per_view
|
70
80
|
doc_name += "_view_#{view_name}" if view_name.present?
|
71
|
-
doc_name += "_list_#{list_name}" if list_name.present?
|
72
81
|
end
|
73
82
|
doc_name
|
74
83
|
end
|
@@ -9,9 +9,21 @@ require 'couch_potato/view/view_parameters'
|
|
9
9
|
module CouchPotato
|
10
10
|
module View
|
11
11
|
module CustomViews
|
12
|
+
module TrackViews
|
13
|
+
def inherited(child)
|
14
|
+
super
|
15
|
+
CouchPotato.views << child
|
16
|
+
end
|
17
|
+
end
|
12
18
|
|
13
19
|
def self.included(base) #:nodoc:
|
14
20
|
base.extend ClassMethods
|
21
|
+
CouchPotato.views << base
|
22
|
+
base.class_eval do
|
23
|
+
class << self
|
24
|
+
prepend TrackViews
|
25
|
+
end
|
26
|
+
end
|
15
27
|
end
|
16
28
|
|
17
29
|
module ClassMethods
|
@@ -96,7 +96,7 @@ module CouchPotato
|
|
96
96
|
end
|
97
97
|
|
98
98
|
delegate :view_name, :view_parameters, :design_document, :map_function,
|
99
|
-
:reduce_function, :
|
99
|
+
:reduce_function, :language, to: :view_spec_delegate
|
100
100
|
|
101
101
|
def process_results(results)
|
102
102
|
results = Results.new(results)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module CouchPotato
|
2
2
|
module View
|
3
|
-
# A view for custom map/reduce functions that returns the raw data
|
3
|
+
# A view for custom map/reduce functions that returns the raw data from couchdb
|
4
4
|
#
|
5
5
|
# example:
|
6
6
|
# view :my_custom_view, :map => "function(doc) { emit(doc._id, null); }", :type => :raw, :reduce => nil
|
@@ -10,7 +10,7 @@ module CouchPotato
|
|
10
10
|
# view :my_custom_view, :map => "function(doc) { emit(doc._id, null); }", :type => :raw, :results_filter => lambda{|results| results['rows].map{|row| row['value']}}
|
11
11
|
#
|
12
12
|
# example:
|
13
|
-
# view :my_custom_view, :map => "function(doc) { emit(doc._id, null); }", :type => :raw
|
13
|
+
# view :my_custom_view, :map => "function(doc) { emit(doc._id, null); }", :type => :raw"
|
14
14
|
class RawViewSpec < BaseViewSpec
|
15
15
|
def map_function
|
16
16
|
options[:map]
|
@@ -19,10 +19,6 @@ module CouchPotato
|
|
19
19
|
def reduce_function
|
20
20
|
options[:reduce]
|
21
21
|
end
|
22
|
-
|
23
|
-
def lib
|
24
|
-
options[:lib]
|
25
|
-
end
|
26
22
|
end
|
27
23
|
end
|
28
24
|
end
|
@@ -2,18 +2,13 @@ module CouchPotato
|
|
2
2
|
module View
|
3
3
|
# Used to query views (and create them if they don't exist). Usually you won't have to use this class directly. Instead it is used internally by the CouchPotato::Database.view method.
|
4
4
|
class ViewQuery
|
5
|
-
def initialize(couchrest_database, design_document_name, view,
|
5
|
+
def initialize(couchrest_database, design_document_name, view, language = :javascript)
|
6
6
|
@database = couchrest_database
|
7
7
|
@design_document_name = design_document_name
|
8
8
|
@view_name = view.keys[0]
|
9
9
|
@map_function = view.values[0][:map]
|
10
10
|
@reduce_function = view.values[0][:reduce]
|
11
|
-
@lib = lib
|
12
11
|
@language = language
|
13
|
-
if list
|
14
|
-
@list_function = list.values[0]
|
15
|
-
@list_name = list.keys[0]
|
16
|
-
end
|
17
12
|
end
|
18
13
|
|
19
14
|
def query_view!(parameters = {})
|
@@ -42,34 +37,41 @@ module CouchPotato
|
|
42
37
|
def update_view
|
43
38
|
design_doc = @database.get "_design/#{@design_document_name}" rescue nil
|
44
39
|
original_views = design_doc && design_doc['views'].dup
|
45
|
-
|
46
|
-
view_updated unless design_doc.nil?
|
40
|
+
view_updated
|
47
41
|
design_doc ||= empty_design_document
|
48
|
-
|
49
|
-
|
50
|
-
|
42
|
+
if CouchPotato::Config.single_design_document
|
43
|
+
design_doc['views'] = all_views
|
44
|
+
else
|
45
|
+
design_doc['views'][@view_name.to_s] = view_functions
|
51
46
|
end
|
52
|
-
if
|
53
|
-
design_doc
|
54
|
-
design_doc['lists'][@list_name.to_s] = @list_function
|
47
|
+
if original_views != design_doc['views']
|
48
|
+
@database.save_doc(design_doc)
|
55
49
|
end
|
56
|
-
@database.save_doc(design_doc) if original_views != design_doc['views'] || original_lists != design_doc['lists']
|
57
50
|
end
|
58
51
|
|
59
|
-
def
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
52
|
+
def all_views
|
53
|
+
CouchPotato.views.flat_map do |klass|
|
54
|
+
specs = klass.views.map { |view_name, view| klass.execute_view(view_name, {}) }
|
55
|
+
specs.map do |klass_spec|
|
56
|
+
{ klass_spec.view_name => view_functions(klass_spec.map_function, klass_spec.reduce_function) }
|
57
|
+
end
|
58
|
+
end.inject(&:merge)
|
59
|
+
end
|
60
|
+
|
61
|
+
def view_functions(map_function = @map_function, reduce_function = @reduce_function)
|
62
|
+
{'map' => map_function, 'reduce' => reduce_function}.compact
|
65
63
|
end
|
66
64
|
|
67
65
|
def empty_design_document
|
68
|
-
{'views' => {},
|
66
|
+
{'views' => {}, "_id" => "_design/#{@design_document_name}", "language" => @language.to_s}
|
69
67
|
end
|
70
68
|
|
71
69
|
def view_has_been_updated?
|
72
|
-
|
70
|
+
if CouchPotato::Config.single_design_document
|
71
|
+
updated_views.any?
|
72
|
+
else
|
73
|
+
updated_views[[@design_document_name, @view_name]]
|
74
|
+
end
|
73
75
|
end
|
74
76
|
|
75
77
|
def view_updated
|
@@ -81,11 +83,7 @@ module CouchPotato
|
|
81
83
|
end
|
82
84
|
|
83
85
|
def query_view(parameters)
|
84
|
-
|
85
|
-
@database.connection.get CouchRest.paramify_url("/#{@database.name}/_design/#{@design_document_name}/_list/#{@list_name}/#{@view_name}", parameters)
|
86
|
-
else
|
87
|
-
@database.view view_url, parameters
|
88
|
-
end
|
86
|
+
@database.view view_url, parameters
|
89
87
|
end
|
90
88
|
|
91
89
|
def view_url
|
data/lib/couch_potato.rb
CHANGED
@@ -9,9 +9,10 @@ JSON.create_id = 'ruby_class'
|
|
9
9
|
CouchRest.decode_json_objects = true
|
10
10
|
|
11
11
|
module CouchPotato
|
12
|
-
Config = Struct.new(:database_host, :database_name, :digest_view_names,
|
12
|
+
Config = Struct.new(:database_host, :database_name, :digest_view_names, :single_design_document,
|
13
13
|
:split_design_documents_per_view, :default_language, :additional_databases).new
|
14
14
|
Config.split_design_documents_per_view = false
|
15
|
+
Config.single_design_document = false
|
15
16
|
Config.digest_view_names = false
|
16
17
|
Config.default_language = :javascript
|
17
18
|
Config.database_host = 'http://127.0.0.1:5984'
|
@@ -29,6 +30,7 @@ module CouchPotato
|
|
29
30
|
Config.database_host = config['database_host'] if config['database_host']
|
30
31
|
Config.additional_databases = config['additional_databases'].stringify_keys if config['additional_databases']
|
31
32
|
Config.split_design_documents_per_view = config['split_design_documents_per_view'] if config['split_design_documents_per_view']
|
33
|
+
Config.single_design_document = config['single_design_document'] if config['single_design_document']
|
32
34
|
Config.digest_view_names = config['digest_view_names'] if config['digest_view_names']
|
33
35
|
Config.default_language = config['default_language'] if config['default_language']
|
34
36
|
end
|
@@ -40,6 +42,12 @@ module CouchPotato
|
|
40
42
|
@models
|
41
43
|
end
|
42
44
|
|
45
|
+
# returns all the classes that include the CouchPotato::View::CustomViews module
|
46
|
+
def self.views
|
47
|
+
@views ||= []
|
48
|
+
@views
|
49
|
+
end
|
50
|
+
|
43
51
|
# Returns a database instance which you can then use to create objects and query views. You have to set the CouchPotato::Config.database_name before this works.
|
44
52
|
def self.database
|
45
53
|
Thread.current[:__couch_potato_database] ||= Database.new(couchrest_database)
|
data/spec/property_spec.rb
CHANGED
@@ -418,7 +418,7 @@ describe 'properties' do
|
|
418
418
|
|
419
419
|
it "should include complex datatypes fully inspected" do
|
420
420
|
comment.title = {'en' => 'Blog post'}
|
421
|
-
expect(comment.inspect).to
|
421
|
+
expect(comment.inspect).to match(/title: {"en"\s*=>\s*"Blog post"}/)
|
422
422
|
|
423
423
|
comment.title = nil
|
424
424
|
expect(comment.inspect).to include('title: nil')
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'single design document' do
|
4
|
+
let(:db) { CouchPotato.database }
|
5
|
+
let(:couchrest_db) { db.couchrest_database }
|
6
|
+
|
7
|
+
class Thing1
|
8
|
+
include CouchPotato::Persistence
|
9
|
+
|
10
|
+
property :title
|
11
|
+
|
12
|
+
view :all, key: :title
|
13
|
+
end
|
14
|
+
|
15
|
+
class Thing2
|
16
|
+
include CouchPotato::Persistence
|
17
|
+
|
18
|
+
property :name
|
19
|
+
|
20
|
+
view :all, key: :name
|
21
|
+
end
|
22
|
+
|
23
|
+
class Thing3 < Thing1 # should work with inheritance
|
24
|
+
property :tag
|
25
|
+
|
26
|
+
view :by_tag, key: :tag
|
27
|
+
end
|
28
|
+
|
29
|
+
before(:each) do
|
30
|
+
recreate_db
|
31
|
+
CouchPotato::Config.single_design_document = true
|
32
|
+
CouchPotato.views.select! { |v| [Thing1, Thing2, Thing3].include?(v) } # clear classes from other specs
|
33
|
+
end
|
34
|
+
|
35
|
+
after(:each) do
|
36
|
+
CouchPotato::Config.single_design_document = false
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'creates a single design document for all views' do
|
40
|
+
thing1 = Thing1.new title: 't1'
|
41
|
+
db.save! thing1
|
42
|
+
thing2 = Thing2.new name: 'n2'
|
43
|
+
db.save! thing2
|
44
|
+
|
45
|
+
db.view(Thing1.all) # create all views when querying the first one
|
46
|
+
|
47
|
+
expect(couchrest_db.get('_design/couch_potato')['views'].keys)
|
48
|
+
.to(eq(['thing1-all', 'thing2-all', 'thing3-by_tag']))
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'returns the correct models' do
|
52
|
+
thing1 = Thing1.new title: 't1'
|
53
|
+
db.save! thing1
|
54
|
+
thing2 = Thing2.new name: 'n2'
|
55
|
+
db.save! thing2
|
56
|
+
thing3 = Thing3.new tag: 'tag1'
|
57
|
+
db.save! thing3
|
58
|
+
|
59
|
+
expect(db.view(Thing1.all('t1'))).to eq([thing1])
|
60
|
+
expect(db.view(Thing2.all('n2'))).to eq([thing2])
|
61
|
+
expect(db.view(Thing3.by_tag('tag1'))).to eq([thing3])
|
62
|
+
end
|
63
|
+
end
|