couch_potato 0.2.20 → 0.2.21
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/CHANGES.md +6 -0
- data/VERSION.yml +2 -1
- data/lib/couch_potato/database.rb +21 -4
- data/lib/couch_potato/persistence.rb +1 -1
- data/lib/couch_potato/persistence/attachments.rb +1 -1
- data/lib/couch_potato/persistence/callbacks.rb +1 -1
- data/lib/couch_potato/persistence/dirty_attributes.rb +1 -1
- data/lib/couch_potato/persistence/ghost_attributes.rb +1 -1
- data/lib/couch_potato/persistence/json.rb +1 -1
- data/lib/couch_potato/persistence/properties.rb +2 -2
- data/lib/couch_potato/persistence/type_caster.rb +1 -1
- data/lib/couch_potato/persistence/validation.rb +1 -1
- data/lib/couch_potato/view/base_view_spec.rb +38 -1
- data/lib/couch_potato/view/custom_views.rb +7 -7
- data/rails/reload_classes.rb +10 -26
- data/spec/rails_spec.rb +1 -3
- data/spec/unit/base_view_spec_spec.rb +46 -0
- data/spec/unit/database_spec.rb +29 -0
- data/spec/unit/model_view_spec_spec.rb +1 -1
- metadata +4 -2
data/CHANGES.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
## Changes
|
2
2
|
|
3
|
+
### 0.2.21
|
4
|
+
* automatically set a database instance on results of CouchPotato::Database#view (langalex)
|
5
|
+
* improved auto loading of unloaded constants - can now load constants that have never been loaded before (langalex)
|
6
|
+
* raise exception on invalid parameters passed to a couchdb view query (langalex)
|
7
|
+
* when querying a view: pass in ranges as key instead of startkey/endkey, pass in plain value instead of hash with key (langalex)
|
8
|
+
|
3
9
|
### 0.2.20
|
4
10
|
* support for :boolean properties (jweiss)
|
5
11
|
* return the total_rows when querying a view (langalex)
|
data/VERSION.yml
CHANGED
@@ -13,25 +13,42 @@ module CouchPotato
|
|
13
13
|
end
|
14
14
|
|
15
15
|
# executes a view and return the results. you pass in a view spec
|
16
|
-
# which is usually a result of a SomePersistentClass.
|
16
|
+
# which is usually a result of a SomePersistentClass.some_view call.
|
17
17
|
# also return the total_rows returned by CouchDB as an accessor on the results.
|
18
18
|
#
|
19
19
|
# Example:
|
20
20
|
#
|
21
21
|
# class User
|
22
22
|
# include CouchPotato::Persistence
|
23
|
-
#
|
23
|
+
# property :age
|
24
|
+
# view :all, key: :age
|
24
25
|
# end
|
26
|
+
# db = CouchPotato.database
|
25
27
|
#
|
26
|
-
#
|
27
|
-
#
|
28
|
+
# db.view(User.all) # => [user1, user2]
|
29
|
+
# db.view(User.all).total_rows # => 2
|
28
30
|
#
|
31
|
+
# You can pass the usual parameters you can pass to a couchdb view to the view:
|
32
|
+
#
|
33
|
+
# db.view(User.all(limit: 5, startkey: 2, reduce: false))
|
34
|
+
#
|
35
|
+
# For your convenience when passing a has with only a key parameter you can just pass in the value
|
36
|
+
#
|
37
|
+
# db.view(User.all(key: 1)) == db.view(User.all(1))
|
38
|
+
#
|
39
|
+
# Instead of passing a startkey and endkey you can pass in a key with a range:
|
40
|
+
#
|
41
|
+
# db.view(User.all(key: 1..20)) == db.view(startkey: 1, endkey: 20) == db.view(User.all(1..20))
|
42
|
+
#
|
29
43
|
def view(spec)
|
30
44
|
results = CouchPotato::View::ViewQuery.new(database,
|
31
45
|
spec.design_document, spec.view_name, spec.map_function,
|
32
46
|
spec.reduce_function).query_view!(spec.view_parameters)
|
33
47
|
processed_results = spec.process_results results
|
34
48
|
processed_results.instance_eval "def total_rows; #{results['total_rows']}; end" if results['total_rows']
|
49
|
+
processed_results.each do |document|
|
50
|
+
document.database = self if document.respond_to?(:database=)
|
51
|
+
end if processed_results.respond_to?(:each)
|
35
52
|
processed_results
|
36
53
|
end
|
37
54
|
|
@@ -16,7 +16,7 @@ require File.dirname(__FILE__) + '/view/view_query'
|
|
16
16
|
module CouchPotato
|
17
17
|
module Persistence
|
18
18
|
|
19
|
-
def self.included(base)
|
19
|
+
def self.included(base) #:nodoc:
|
20
20
|
base.send :include, Properties, Callbacks, Validation, Json, CouchPotato::View::CustomViews
|
21
21
|
base.send :include, DirtyAttributes, GhostAttributes, Attachments
|
22
22
|
base.send :include, MagicTimestamps
|
@@ -32,7 +32,7 @@ module CouchPotato
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
-
def self.included(base)
|
35
|
+
def self.included(base) #:nodoc:
|
36
36
|
base.extend ClassMethods
|
37
37
|
base.class_eval do
|
38
38
|
def self.properties
|
@@ -42,7 +42,7 @@ module CouchPotato
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
-
def type_caster
|
45
|
+
def type_caster #:nodoc:
|
46
46
|
@type_caster ||= TypeCaster.new
|
47
47
|
end
|
48
48
|
|
@@ -3,7 +3,7 @@ require 'validatable'
|
|
3
3
|
module CouchPotato
|
4
4
|
module Persistence
|
5
5
|
module Validation
|
6
|
-
def self.included(base)
|
6
|
+
def self.included(base) #:nodoc:
|
7
7
|
base.send :include, Validatable
|
8
8
|
base.class_eval do
|
9
9
|
# Override the validate method to first run before_validation callback
|
@@ -5,6 +5,8 @@ module CouchPotato
|
|
5
5
|
private :klass, :options
|
6
6
|
|
7
7
|
def initialize(klass, view_name, options, view_parameters)
|
8
|
+
normalized_view_parameters = normalize_view_parameters view_parameters
|
9
|
+
assert_valid_view_parameters normalized_view_parameters
|
8
10
|
@klass = klass
|
9
11
|
@design_document = klass.to_s.underscore
|
10
12
|
@view_name = view_name
|
@@ -13,12 +15,47 @@ module CouchPotato
|
|
13
15
|
[:group, :include_docs, :descending, :group_level, :limit].each do |key|
|
14
16
|
@view_parameters[key] = options[key] if options.include?(key)
|
15
17
|
end
|
16
|
-
@view_parameters.merge!(
|
18
|
+
@view_parameters.merge!(normalized_view_parameters)
|
17
19
|
end
|
18
20
|
|
19
21
|
def process_results(results)
|
20
22
|
results
|
21
23
|
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def normalize_view_parameters(params)
|
28
|
+
normalized_params = params.dup
|
29
|
+
hash = wrap_in_hash params
|
30
|
+
replace_range_key hash
|
31
|
+
end
|
32
|
+
|
33
|
+
def wrap_in_hash(params)
|
34
|
+
if params.is_a?(Hash)
|
35
|
+
params
|
36
|
+
else
|
37
|
+
{:key => params}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def replace_range_key(params)
|
42
|
+
if((key = params[:key]).is_a?(Range))
|
43
|
+
params.delete :key
|
44
|
+
params[:startkey] = key.first
|
45
|
+
params[:endkey] = key.last
|
46
|
+
end
|
47
|
+
params
|
48
|
+
end
|
49
|
+
|
50
|
+
def assert_valid_view_parameters(params)
|
51
|
+
params.keys.each do |key|
|
52
|
+
raise ArgumentError.new("invalid view parameter: #{key}") unless valid_view_parameters.include?(key.to_s)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def valid_view_parameters
|
57
|
+
%w(key startkey startkey_docid endkey endkey_docid limit stale descending skip group group_level reduce include_docs inclusive_end)
|
58
|
+
end
|
22
59
|
end
|
23
60
|
end
|
24
61
|
end
|
@@ -9,13 +9,12 @@ module CouchPotato
|
|
9
9
|
module View
|
10
10
|
module CustomViews
|
11
11
|
|
12
|
-
def self.included(base)
|
12
|
+
def self.included(base) #:nodoc:
|
13
13
|
base.extend ClassMethods
|
14
14
|
end
|
15
15
|
|
16
16
|
module ClassMethods
|
17
|
-
|
18
|
-
def views(view_name = nil)
|
17
|
+
def views(view_name = nil) #:nodoc:
|
19
18
|
if view_name
|
20
19
|
_find_view(view_name)
|
21
20
|
else
|
@@ -23,10 +22,11 @@ module CouchPotato
|
|
23
22
|
end
|
24
23
|
end
|
25
24
|
|
26
|
-
def execute_view(view_name, view_parameters)
|
25
|
+
def execute_view(view_name, view_parameters) #:nodoc:
|
27
26
|
view_spec_class(views(view_name)[:type]).new(self, view_name, views(view_name), view_parameters)
|
28
27
|
end
|
29
|
-
|
28
|
+
|
29
|
+
# Declare a CouchDB view, for examples on how to use see the *ViewSpec classes in CouchPotato::View
|
30
30
|
def view(view_name, options)
|
31
31
|
view_name = view_name.to_s
|
32
32
|
views[view_name] = options
|
@@ -34,7 +34,7 @@ module CouchPotato
|
|
34
34
|
self.instance_eval(method_str)
|
35
35
|
end
|
36
36
|
|
37
|
-
def view_spec_class(type)
|
37
|
+
def view_spec_class(type) #:nodoc:
|
38
38
|
if type && type.is_a?(Class)
|
39
39
|
type
|
40
40
|
else
|
@@ -43,7 +43,7 @@ module CouchPotato
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
-
def _find_view(view)
|
46
|
+
def _find_view(view) #:nodoc:
|
47
47
|
return @views[view] if @views && @views[view]
|
48
48
|
superclass._find_view(view) if superclass && superclass.respond_to?(:_find_view)
|
49
49
|
end
|
data/rails/reload_classes.rb
CHANGED
@@ -1,32 +1,16 @@
|
|
1
1
|
module CouchPotato
|
2
|
-
module Persistence
|
3
|
-
|
4
|
-
def self.persistent_classes #:nodoc:
|
5
|
-
@persistent_classes ||= []
|
6
|
-
end
|
7
|
-
|
8
|
-
def self.reload_persistent_classes #:nodoc:
|
9
|
-
persistent_classes.each do |clazz|
|
10
|
-
eval clazz.name
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
|
15
|
-
def self.included_with_class_reloading(base) #:nodoc:
|
16
|
-
persistent_classes << base
|
17
|
-
included_without_class_reloading(base)
|
18
|
-
end
|
19
|
-
|
20
|
-
class << self
|
21
|
-
alias_method :included_without_class_reloading, :included
|
22
|
-
alias_method :included, :included_with_class_reloading
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
2
|
Database.class_eval do
|
27
3
|
def load_document_with_class_reloading(id)
|
28
|
-
|
29
|
-
|
4
|
+
begin
|
5
|
+
load_document_without_class_reloading id
|
6
|
+
rescue ArgumentError => e
|
7
|
+
if(name = e.message.scan(/(can't find const|undefined class\/module) ([\w\:]+)/).first[1])
|
8
|
+
eval name
|
9
|
+
retry
|
10
|
+
else
|
11
|
+
raise e
|
12
|
+
end
|
13
|
+
end
|
30
14
|
end
|
31
15
|
|
32
16
|
alias_method :load_document_without_class_reloading, :load_document
|
data/spec/rails_spec.rb
CHANGED
@@ -10,9 +10,7 @@ end
|
|
10
10
|
|
11
11
|
describe CouchPotato::Database, 'rails specific behavior' do
|
12
12
|
|
13
|
-
it "should load
|
14
|
-
Autoloader::Uninitialized
|
15
|
-
Autoloader.send :remove_const, 'Uninitialized'
|
13
|
+
it "should load models whose constants are currently uninitialized (like with rails in development mode)" do
|
16
14
|
recreate_db
|
17
15
|
CouchPotato.couchrest_database.save_doc(JSON.create_id => 'Autoloader::Uninitialized', '_id' => '1')
|
18
16
|
CouchPotato.database.load('1').class.name.should == 'Autoloader::Uninitialized'
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe CouchPotato::View::BaseViewSpec, 'initialize' do
|
4
|
+
describe "view parameters" do
|
5
|
+
it "should raise an error when passing invalid view parameters" do
|
6
|
+
lambda {
|
7
|
+
CouchPotato::View::BaseViewSpec.new Object, 'all', {}, {:start_key => '1'}
|
8
|
+
}.should raise_error(ArgumentError, "invalid view parameter: start_key")
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should not raise an error when passing valid view parameters" do
|
12
|
+
lambda {
|
13
|
+
CouchPotato::View::BaseViewSpec.new Object, 'all', {}, {
|
14
|
+
:key => 'keyvalue',
|
15
|
+
:startkey => 'keyvalue',
|
16
|
+
:startkey_docid => 'docid',
|
17
|
+
:endkey => 'keyvalue',
|
18
|
+
:endkey_docid => 'docid',
|
19
|
+
:limit => 3,
|
20
|
+
:stale => 'ok',
|
21
|
+
:descending => true,
|
22
|
+
:skip => 1,
|
23
|
+
:group => true,
|
24
|
+
:group_level => 1,
|
25
|
+
:reduce => false,
|
26
|
+
:include_docs => true,
|
27
|
+
:inclusive_end => true
|
28
|
+
}
|
29
|
+
}.should_not raise_error
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should convert a range passed as key into startkey and endkey" do
|
33
|
+
spec = CouchPotato::View::BaseViewSpec.new Object, 'all', {}, {:key => '1'..'2'}
|
34
|
+
spec.view_parameters.should == {:startkey => '1', :endkey => '2'}
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should convert a plain value to a hash with a key" do
|
38
|
+
spec = CouchPotato::View::BaseViewSpec.new Object, 'all', {}, '2'
|
39
|
+
spec.view_parameters.should == {:key => '2'}
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
|
data/spec/unit/database_spec.rb
CHANGED
@@ -205,3 +205,32 @@ describe CouchPotato::Database, 'save_document' do
|
|
205
205
|
|
206
206
|
end
|
207
207
|
end
|
208
|
+
|
209
|
+
describe CouchPotato::Database, 'view' do
|
210
|
+
before(:each) do
|
211
|
+
@db = CouchPotato::Database.new(stub('couchrest db').as_null_object)
|
212
|
+
@result = stub('result')
|
213
|
+
@spec = stub('view spec', :process_results => [@result]).as_null_object
|
214
|
+
CouchPotato::View::ViewQuery.stub(:new => stub('view query', :query_view! => {'rows' => [@result]}))
|
215
|
+
end
|
216
|
+
|
217
|
+
it "should set itself on returned results that have an accessor" do
|
218
|
+
@result.stub(:respond_to?).with(:database=).and_return(true)
|
219
|
+
@result.should_receive(:database=).with(@db)
|
220
|
+
@db.view(@spec)
|
221
|
+
end
|
222
|
+
|
223
|
+
it "should not set itself on returned results that don't have an accessor" do
|
224
|
+
@result.stub(:respond_to?).with(:database=).and_return(false)
|
225
|
+
@result.should_not_receive(:database=).with(@db)
|
226
|
+
@db.view(@spec)
|
227
|
+
end
|
228
|
+
|
229
|
+
it "should not try to set itself on result sets that are not collections" do
|
230
|
+
lambda {
|
231
|
+
@spec.stub(:process_results => 1)
|
232
|
+
}.should_not raise_error
|
233
|
+
|
234
|
+
@db.view(@spec)
|
235
|
+
end
|
236
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: couch_potato
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.21
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexander Lang
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-01-
|
12
|
+
date: 2010-01-13 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -100,6 +100,7 @@ files:
|
|
100
100
|
- spec/spec.opts
|
101
101
|
- spec/spec_helper.rb
|
102
102
|
- spec/unit/attributes_spec.rb
|
103
|
+
- spec/unit/base_view_spec_spec.rb
|
103
104
|
- spec/unit/callbacks_spec.rb
|
104
105
|
- spec/unit/couch_potato_spec.rb
|
105
106
|
- spec/unit/create_spec.rb
|
@@ -153,6 +154,7 @@ test_files:
|
|
153
154
|
- spec/rails_spec.rb
|
154
155
|
- spec/spec_helper.rb
|
155
156
|
- spec/unit/attributes_spec.rb
|
157
|
+
- spec/unit/base_view_spec_spec.rb
|
156
158
|
- spec/unit/callbacks_spec.rb
|
157
159
|
- spec/unit/couch_potato_spec.rb
|
158
160
|
- spec/unit/create_spec.rb
|