Skip to content

Commit 3799dc7

Browse files
authored
add support for a single design doc (#169)
using a single design doc is more performant because only one doc needs to be kep up-to-date * remove support for lists and lib
1 parent 8c266b7 commit 3799dc7

29 files changed

Lines changed: 294 additions & 550 deletions

.github/workflows/ruby.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,17 @@ jobs:
2424
- ruby: "jruby"
2525
gemfile: "active_support_8_0"
2626
steps:
27-
- uses: actions/checkout@v2
27+
- uses: actions/checkout@v4
2828
- name: Set up CouchDB
29-
uses: cobot/couchdb-action@v4
29+
uses: cobot/couchdb-action@v5
3030
with:
31-
couchdb version: "2.3.1"
31+
couchdb-version: "2.3.1"
3232
- name: Set up Ruby
3333
uses: ruby/setup-ruby@v1
3434
with:
3535
ruby-version: ${{ matrix.ruby }}
3636
bundler-cache: true
3737
- name: Run tests
3838
run: bundle exec rake spec_ci
39+
env:
40+
DATABASE: http://admin:admin@localhost:5984/couch_potato_test

CHANGES.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
## Changes
22

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+
38
# 1.18.0
49

510
- add testing Rails 7.2/8 on CI

README.md

Lines changed: 8 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,12 @@ Another switch allows you to store each CouchDB view in its own design document.
8080
CouchPotato::Config.split_design_documents_per_view = true
8181
```
8282

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+
8389
If you are using more than one database from your app, you can create aliases:
8490

8591
```ruby
@@ -95,6 +101,7 @@ Create a `config/couchdb.yml`:
95101
default: &default
96102
split_design_documents_per_view: true # optional, default is false
97103
digest_view_names: true # optional, default is false
104+
single_design_document: true # optional, default is false
98105
default_language: :erlang # optional, default is javascript
99106
database_host: "http://127.0.0.1:5984"
100107

@@ -299,7 +306,7 @@ user.valid? # => false
299306
user.errors[:name] # => ['can't be blank']
300307
```
301308

302-
#### Finding stuff / views / lists
309+
#### Finding stuff / views
303310

304311
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:
305312

@@ -403,14 +410,6 @@ class User
403410
end
404411
```
405412

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-
414413
If you don't want the results to be converted into models the raw view is your friend:
415414

416415
```ruby
@@ -450,49 +449,6 @@ You can pass in your own view specifications by passing in `:type => MyViewSpecC
450449

451450
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.
452451

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-
496452
#### Associations
497453

498454
Not supported. Not sure if they ever will be. You can implement those yourself using views and custom methods on your models.

lib/couch_potato.rb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@
99
CouchRest.decode_json_objects = true
1010

1111
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,
1313
:split_design_documents_per_view, :default_language, :additional_databases).new
1414
Config.split_design_documents_per_view = false
15+
Config.single_design_document = false
1516
Config.digest_view_names = false
1617
Config.default_language = :javascript
1718
Config.database_host = 'http://127.0.0.1:5984'
@@ -29,6 +30,7 @@ def self.configure(config)
2930
Config.database_host = config['database_host'] if config['database_host']
3031
Config.additional_databases = config['additional_databases'].stringify_keys if config['additional_databases']
3132
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']
3234
Config.digest_view_names = config['digest_view_names'] if config['digest_view_names']
3335
Config.default_language = config['default_language'] if config['default_language']
3436
end
@@ -40,6 +42,12 @@ def self.models
4042
@models
4143
end
4244

45+
# returns all the classes that include the CouchPotato::View::CustomViews module
46+
def self.views
47+
@views ||= []
48+
@views
49+
end
50+
4351
# 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.
4452
def self.database
4553
Thread.current[:__couch_potato_database] ||= Database.new(couchrest_database)

lib/couch_potato/database.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,8 +273,6 @@ def raw_view(spec)
273273
map: spec.map_function,
274274
reduce: spec.reduce_function
275275
} },
276-
({ spec.list_name => spec.list_function } unless spec.list_name.nil?),
277-
spec.lib,
278276
spec.language
279277
).query_view!(spec.view_parameters)
280278
end

lib/couch_potato/persistence.rb

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,20 @@
1212
require File.dirname(__FILE__) + '/persistence/revisions'
1313
require File.dirname(__FILE__) + '/forbidden_attributes_protection'
1414
require File.dirname(__FILE__) + '/view/custom_views'
15-
require File.dirname(__FILE__) + '/view/lists'
1615
require File.dirname(__FILE__) + '/view/view_query'
1716

1817

1918
module CouchPotato
2019
module Persistence
20+
module TrackModels
21+
def inherited(child)
22+
super
23+
CouchPotato.models << child
24+
end
25+
end
2126

2227
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
2529
base.send :include, DirtyAttributes, GhostAttributes, Attachments
2630
base.send :include, MagicTimestamps, ActiveModelCompliance,
2731
ForbiddenAttributesProtection, Revisions
@@ -31,9 +35,8 @@ def self.included(base) #:nodoc:
3135
alias_method :id, :_id
3236
alias_method :id=, :_id=
3337

34-
def self.inherited(child)
35-
super
36-
CouchPotato.models << child
38+
class << self
39+
prepend TrackModels
3740
end
3841
end
3942

lib/couch_potato/rspec/matchers.rb

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
require 'couch_potato/rspec/matchers/map_to_matcher'
44
require 'couch_potato/rspec/matchers/reduce_to_matcher'
55
require 'couch_potato/rspec/matchers/map_reduce_to_matcher'
6-
require 'couch_potato/rspec/matchers/list_as_matcher'
76

87
module RSpec
98
module Matchers
@@ -19,10 +18,6 @@ def rereduce(keys, values)
1918
CouchPotato::RSpec::ReduceToProxy.new(keys, values, true)
2019
end
2120

22-
def list(results)
23-
CouchPotato::RSpec::ListAsProxy.new(results)
24-
end
25-
2621
def map_reduce(*docs)
2722
CouchPotato::RSpec::MapReduceToProxy.new(docs)
2823
end

lib/couch_potato/rspec/matchers/list_as_matcher.rb

Lines changed: 0 additions & 54 deletions
This file was deleted.

lib/couch_potato/rspec/matchers/map_reduce_to_matcher.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,14 @@ def matches?(view_spec)
7272
var options = #{@options.to_json};
7373
var map = #{view_spec.map_function};
7474
var reduce = #{view_spec.reduce_function};
75-
var lib = #{view_spec.respond_to?(:lib) && view_spec.lib.to_json};
7675
var collate = (function() { var module = {exports: {}}; var exports = module.exports; eval(#{File.read(File.expand_path(File.dirname(__FILE__) + '/../../../../vendor/pouchdb-collate/pouchdb-collate.js')).to_json}); return module.exports.collate;})();
7776
7877
// Map the input docs
7978
var require = function(modulePath) {
8079
var module = {exports: {}};
8180
var exports = module.exports;
8281
var pathArray = modulePath.split("/").slice(2);
83-
var result = lib;
82+
var result = {};
8483
for (var i in pathArray) {
8584
result = result[pathArray[i]];
8685
}

lib/couch_potato/rspec/matchers/map_to_matcher.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,12 @@ def matches?(view_spec)
2626
(function() {
2727
var doc = #{@input_ruby.to_json};
2828
var map = #{view_spec.map_function};
29-
var lib = #{view_spec.respond_to?(:lib) && view_spec.lib.to_json};
3029
var result = [];
3130
var require = function(modulePath) {
3231
var module = {exports: {}};
3332
var exports = module.exports;
3433
var pathArray = modulePath.split("/").slice(2);
35-
var result = lib;
34+
var result = {};
3635
for (var i in pathArray) {
3736
result = result[pathArray[i]];
3837
}

0 commit comments

Comments
 (0)