couchmodel 0.1.0.beta3 → 0.1.0.beta4
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/README.rdoc +22 -7
- data/lib/core_extension/array.rb +18 -2
- data/lib/core_extension/string.rb +12 -2
- data/lib/couch_model/active_model.rb +31 -8
- data/lib/couch_model/base/accessor.rb +8 -5
- data/lib/couch_model/base/association.rb +36 -15
- data/lib/couch_model/base/finder.rb +1 -0
- data/lib/couch_model/base/setup.rb +6 -1
- data/lib/couch_model/base.rb +55 -17
- data/lib/couch_model/collection.rb +41 -21
- data/lib/couch_model/configuration.rb +42 -46
- data/lib/couch_model/database.rb +2 -2
- data/lib/couch_model/design.rb +18 -14
- data/lib/couch_model/row.rb +34 -0
- data/lib/couch_model/server.rb +2 -2
- data/lib/couch_model/transport.rb +55 -34
- data/lib/couch_model/view.rb +9 -5
- data/spec/fake_transport.yml +84 -29
- data/spec/fake_transport_helper.rb +5 -3
- data/spec/integration/basic_spec.rb +26 -12
- data/spec/integration/design/membership.design +1 -1
- data/spec/integration/design/user.design +12 -0
- data/spec/lib/core_extension/array_spec.rb +24 -0
- data/spec/lib/couch_model/active_model_spec.rb +51 -0
- data/spec/lib/couch_model/base_spec.rb +30 -1
- data/spec/lib/couch_model/collection_spec.rb +31 -7
- data/spec/lib/couch_model/configuration_spec.rb +2 -2
- data/spec/lib/couch_model/core/accessor_spec.rb +11 -3
- data/spec/lib/couch_model/core/association_spec.rb +26 -0
- data/spec/lib/couch_model/core/setup_spec.rb +8 -0
- data/spec/lib/couch_model/design_spec.rb +1 -5
- data/spec/lib/couch_model/row_spec.rb +71 -0
- data/spec/lib/couch_model/transport_spec.rb +18 -1
- data/spec/lib/couch_model/view_spec.rb +2 -2
- data/spec/spec_helper.rb +1 -1
- metadata +6 -3
data/README.rdoc
CHANGED
@@ -36,6 +36,7 @@ To define a model, it's necessary to create a subclass of <tt>CouchModel::Base</
|
|
36
36
|
|
37
37
|
key_accessor :name
|
38
38
|
key_accessor :email
|
39
|
+
key_accessor :language, :default => "en"
|
39
40
|
|
40
41
|
end
|
41
42
|
|
@@ -49,7 +50,8 @@ manually by calling <tt>CouchModel::Configuration.setup_databases</tt> and
|
|
49
50
|
<tt>CouchModel::Configuration.setup_designs</tt>.
|
50
51
|
|
51
52
|
The method <tt>key_accessor</tt> defined access methods to the given keys of the CouchDB document. It's also possible
|
52
|
-
to use <tt>key_reader</tt> and <tt>key_writer</tt> here.
|
53
|
+
to use <tt>key_reader</tt> and <tt>key_writer</tt> here. If the <tt>:default</tt> option is passed, the key will get
|
54
|
+
a default value assigned during initialization of the class.
|
53
55
|
|
54
56
|
== Design documents
|
55
57
|
|
@@ -67,7 +69,7 @@ A design document should look like this
|
|
67
69
|
:id: "test_design"
|
68
70
|
:language: "javascript"
|
69
71
|
:views:
|
70
|
-
|
72
|
+
:view_name_1:
|
71
73
|
:map:
|
72
74
|
function(document) {
|
73
75
|
...
|
@@ -76,7 +78,7 @@ A design document should look like this
|
|
76
78
|
function(key, values, rereduce) {
|
77
79
|
...
|
78
80
|
};
|
79
|
-
|
81
|
+
:view_name_2:
|
80
82
|
:keys: [ "key_one", "key_two" ]
|
81
83
|
...
|
82
84
|
|
@@ -113,12 +115,25 @@ generates getters and setters for the session object itself (<tt>session</tt> an
|
|
113
115
|
|
114
116
|
The <tt>has_many</tt> acts as a wrapper for the specified view. The previously defined view
|
115
117
|
<tt>by_user_id_and_created_at</tt> emits membership-documents by thier <tt>user_id</tt> and the <tt>created_at</tt>
|
116
|
-
date.
|
117
|
-
method can be passed
|
118
|
+
date.
|
119
|
+
Basically, the association can be accessed by a reader method. Options for querying the view can be passed by a hash.
|
118
120
|
|
119
|
-
user.membership(
|
121
|
+
user.membership(:startkey => [ ... ], :endkey => [ ... ], :descending => false)
|
120
122
|
|
121
|
-
The
|
123
|
+
The possible keys for that query hash can be taken from http://wiki.apache.org/couchdb/HTTP_view_API (Section Querying
|
124
|
+
Options).
|
125
|
+
|
126
|
+
If a <tt>:query</tt> option is defined (like in the example above), the given method is used to generate this query
|
127
|
+
hash. When querying a view, the first arguments will be passed to that method and the result of the generator-method
|
128
|
+
will be merged with the additionally given query hash.
|
129
|
+
|
130
|
+
user.membership(created_at, :returns => :rows)
|
131
|
+
|
132
|
+
The <tt>:returns</tt> option extends the possible keys defined by CouchDB. If not given or specified as
|
133
|
+
<tt>:models</tt>, CouchModel will try to cast the returned rows into model classes. It also automatically passes the
|
134
|
+
<tt>:include_docs</tt> option to CouchDB. If this option is specified as <tt>:rows</tt>, a collection of
|
135
|
+
<tt>CouchModel::Row</tt> objects is returned that wraps the CouchDB result rows. That's maybe useful for views with a
|
136
|
+
reduce function.
|
122
137
|
|
123
138
|
== Rails integration
|
124
139
|
|
data/lib/core_extension/array.rb
CHANGED
@@ -1,13 +1,29 @@
|
|
1
1
|
|
2
|
+
# Extention of ruby's standard array.
|
2
3
|
class Array
|
3
4
|
|
5
|
+
def resize(length, element = nil)
|
6
|
+
case size <=> length
|
7
|
+
when 1
|
8
|
+
slice 0, length
|
9
|
+
when -1
|
10
|
+
result = self.dup
|
11
|
+
result << element while result.size < length
|
12
|
+
result
|
13
|
+
when 0
|
14
|
+
self
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# This wrap method is taken from ActiveSupport and simply
|
19
|
+
# wraps an object into an array.
|
4
20
|
def self.wrap(object)
|
5
21
|
if object.nil?
|
6
|
-
[]
|
22
|
+
[ ]
|
7
23
|
elsif object.respond_to?(:to_ary)
|
8
24
|
object.to_ary
|
9
25
|
else
|
10
|
-
[object]
|
26
|
+
[ object ]
|
11
27
|
end
|
12
28
|
end
|
13
29
|
|
@@ -1,12 +1,22 @@
|
|
1
1
|
|
2
|
-
class String
|
2
|
+
class String # :nodoc:
|
3
3
|
|
4
|
+
# This method converts a CamelCaseString into an underscore_string.
|
4
5
|
def underscore
|
5
6
|
self.gsub(/([a-z][A-Z])/){ |match| "#{match[0]}_#{match[1]}" }.downcase
|
6
7
|
end
|
7
8
|
|
9
|
+
# This method converts an underscore_string into a CamelCaseString.
|
8
10
|
def camelize
|
9
|
-
self.
|
11
|
+
self.camelize_path.camelize_name
|
12
|
+
end
|
13
|
+
|
14
|
+
def camelize_path
|
15
|
+
self.gsub(/\/(.?)/) { "::#{$1.upcase}" }
|
16
|
+
end
|
17
|
+
|
18
|
+
def camelize_name
|
19
|
+
self.gsub(/(?:^|_)(.)/) { $1.upcase }
|
10
20
|
end
|
11
21
|
|
12
22
|
end
|
@@ -5,6 +5,7 @@ require 'active_model'
|
|
5
5
|
|
6
6
|
module CouchModel
|
7
7
|
|
8
|
+
# Extension of class Base to implement the ActiveModel interface.
|
8
9
|
class Base
|
9
10
|
extend ::ActiveModel::Naming
|
10
11
|
extend ::ActiveModel::Callbacks
|
@@ -15,13 +16,16 @@ module CouchModel
|
|
15
16
|
include ::ActiveModel::Serializers::JSON
|
16
17
|
include ::ActiveModel::Serializers::Xml
|
17
18
|
|
19
|
+
# The InvalidModelError is raised, e. g. if the save! method is called on an invalid model.
|
20
|
+
class InvalidModelError < StandardError; end
|
21
|
+
|
18
22
|
CALLBACKS = [ :initialize, :save, :create, :update, :destroy ].freeze unless defined?(CALLBACKS)
|
19
23
|
|
20
24
|
define_model_callbacks *CALLBACKS
|
21
25
|
|
22
26
|
CALLBACKS.each do |method_name|
|
23
27
|
|
24
|
-
|
28
|
+
alias_method :"#{method_name}_without_callbacks", :"#{method_name}"
|
25
29
|
|
26
30
|
define_method :"#{method_name}" do |*arguments|
|
27
31
|
send :"_run_#{method_name}_callbacks" do
|
@@ -35,6 +39,10 @@ module CouchModel
|
|
35
39
|
|
36
40
|
alias destroyed? new?
|
37
41
|
|
42
|
+
def to_param
|
43
|
+
id
|
44
|
+
end
|
45
|
+
|
38
46
|
alias save_without_active_model save
|
39
47
|
|
40
48
|
def save
|
@@ -44,6 +52,12 @@ module CouchModel
|
|
44
52
|
result
|
45
53
|
end
|
46
54
|
|
55
|
+
def save!
|
56
|
+
raise InvalidModelError, "errors: #{errors.full_messages.join(' / ')}" unless valid?
|
57
|
+
raise StandardError, "unknown error while saving model" unless save
|
58
|
+
true
|
59
|
+
end
|
60
|
+
|
47
61
|
private
|
48
62
|
|
49
63
|
def discard_changes!
|
@@ -55,17 +69,18 @@ module CouchModel
|
|
55
69
|
|
56
70
|
alias key_accessor_without_dirty key_accessor
|
57
71
|
|
58
|
-
def key_accessor(key)
|
72
|
+
def key_accessor(key, options = { })
|
59
73
|
add_key key
|
60
74
|
redefine_attribute_methods
|
61
75
|
|
62
|
-
key_accessor_without_dirty key
|
76
|
+
key_accessor_without_dirty key, options
|
77
|
+
redefine_key_writer key
|
78
|
+
end
|
63
79
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
end
|
80
|
+
def create!(*arguments)
|
81
|
+
model = new *arguments
|
82
|
+
model.save!
|
83
|
+
model
|
69
84
|
end
|
70
85
|
|
71
86
|
private
|
@@ -80,6 +95,14 @@ module CouchModel
|
|
80
95
|
define_attribute_methods @keys
|
81
96
|
end
|
82
97
|
|
98
|
+
def redefine_key_writer(key)
|
99
|
+
alias_method :"#{key}_without_dirty=", :"#{key}="
|
100
|
+
define_method :"#{key}=" do |value|
|
101
|
+
send :"#{key}_will_change!"
|
102
|
+
send :"#{key}_without_dirty=", value
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
83
106
|
end
|
84
107
|
|
85
108
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
|
2
2
|
module CouchModel
|
3
3
|
|
4
|
+
# This should extend the Base class to provide key_accessor methods.
|
4
5
|
class Base
|
5
6
|
|
6
7
|
module Accessor
|
@@ -13,21 +14,23 @@ module CouchModel
|
|
13
14
|
|
14
15
|
module ClassMethods
|
15
16
|
|
16
|
-
def key_reader(key)
|
17
|
+
def key_reader(key, options = { })
|
18
|
+
set_default key, options[:default] if options.has_key?(:default)
|
17
19
|
define_method :"#{key}" do
|
18
20
|
@attributes[key.to_s]
|
19
21
|
end
|
20
22
|
end
|
21
23
|
|
22
|
-
def key_writer(key)
|
24
|
+
def key_writer(key, options = { })
|
25
|
+
set_default key, options[:default] if options.has_key?(:default)
|
23
26
|
define_method :"#{key}=" do |value|
|
24
27
|
@attributes[key.to_s] = value
|
25
28
|
end
|
26
29
|
end
|
27
30
|
|
28
|
-
def key_accessor(
|
29
|
-
key_reader
|
30
|
-
key_writer
|
31
|
+
def key_accessor(*arguments)
|
32
|
+
key_reader *arguments
|
33
|
+
key_writer *arguments
|
31
34
|
end
|
32
35
|
|
33
36
|
end
|
@@ -1,6 +1,8 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "core_extension", "array"))
|
1
2
|
|
2
3
|
module CouchModel
|
3
4
|
|
5
|
+
# This should extend the Base class to provide association methods.
|
4
6
|
class Base
|
5
7
|
|
6
8
|
module Association
|
@@ -18,13 +20,30 @@ module CouchModel
|
|
18
20
|
key = options[:key] || "#{name}_id"
|
19
21
|
|
20
22
|
key_accessor key
|
23
|
+
define_belongs_to_reader name, class_name, key
|
24
|
+
define_belongs_to_writer name, class_name, key
|
25
|
+
end
|
26
|
+
|
27
|
+
def has_many(name, options = { })
|
28
|
+
class_name = options[:class_name] || name.to_s.camelize
|
29
|
+
view_name = options[:view_name] || raise(ArgumentError, "no view_name is given")
|
30
|
+
query = options[:query]
|
31
|
+
|
32
|
+
define_has_many_query name, query
|
33
|
+
define_has_many_reader name, class_name, view_name
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
21
37
|
|
22
|
-
|
38
|
+
def define_belongs_to_reader(reader_name, class_name, key)
|
39
|
+
define_method :"#{reader_name}" do
|
23
40
|
klass = Object.const_get class_name
|
24
41
|
klass.find self.send(key)
|
25
|
-
end
|
42
|
+
end
|
43
|
+
end
|
26
44
|
|
27
|
-
|
45
|
+
def define_belongs_to_writer(writer_name, class_name, key)
|
46
|
+
define_method :"#{writer_name}=" do |value|
|
28
47
|
klass = Object.const_get class_name
|
29
48
|
if value
|
30
49
|
raise ArgumentError, "only objects of class #{klass} are accepted" unless value.is_a?(klass)
|
@@ -35,22 +54,24 @@ module CouchModel
|
|
35
54
|
end
|
36
55
|
end
|
37
56
|
|
38
|
-
def
|
39
|
-
|
40
|
-
|
41
|
-
query = options[:query]
|
57
|
+
def define_has_many_query(query_name, query)
|
58
|
+
define_method :"#{query_name}_query", &query if query.is_a?(Proc)
|
59
|
+
end
|
42
60
|
|
43
|
-
|
61
|
+
def define_has_many_reader(reader_name, class_name, view_name)
|
62
|
+
define_method :"#{reader_name}" do |*arguments|
|
63
|
+
last_argument = arguments.last
|
64
|
+
hash_argument = last_argument.is_a?(Hash) && last_argument
|
44
65
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
self.send :"#{name}_query", *arguments
|
66
|
+
arity = 0
|
67
|
+
query = if self.respond_to?(:"#{reader_name}_query")
|
68
|
+
arity = self.method(:"#{reader_name}_query").arity
|
69
|
+
self.send :"#{reader_name}_query", *arguments.resize(arity)
|
50
70
|
else
|
51
|
-
{ :key =>
|
71
|
+
hash_argument || { :key => self.id }
|
52
72
|
end
|
53
|
-
|
73
|
+
query.merge! hash_argument if hash_argument && arity < arguments.size
|
74
|
+
Object.const_get(class_name).send :"#{view_name}", query
|
54
75
|
end
|
55
76
|
end
|
56
77
|
|
@@ -1,6 +1,7 @@
|
|
1
1
|
|
2
2
|
module CouchModel
|
3
3
|
|
4
|
+
# This should extend the Base class to provide setup methods.
|
4
5
|
class Base
|
5
6
|
|
6
7
|
module Setup
|
@@ -37,12 +38,16 @@ module CouchModel
|
|
37
38
|
@design || raise(StandardError, "no database defined!")
|
38
39
|
end
|
39
40
|
|
41
|
+
def count
|
42
|
+
all.total_count
|
43
|
+
end
|
44
|
+
|
40
45
|
def method_missing(method_name, *arguments, &block)
|
41
46
|
view = find_view method_name
|
42
47
|
view ? view.collection(*arguments) : super
|
43
48
|
end
|
44
49
|
|
45
|
-
def respond_to?(method_name)
|
50
|
+
def respond_to?(method_name, *arguments)
|
46
51
|
view = find_view method_name
|
47
52
|
view ? true : super
|
48
53
|
end
|
data/lib/couch_model/base.rb
CHANGED
@@ -12,20 +12,28 @@ require 'uri'
|
|
12
12
|
|
13
13
|
module CouchModel
|
14
14
|
|
15
|
+
# Base is the main super class of all models that should be stored in CouchDB.
|
16
|
+
# See the README file for more informations.
|
15
17
|
class Base
|
16
18
|
include CouchModel::Base::Setup
|
17
19
|
include CouchModel::Base::Accessor
|
18
20
|
include CouchModel::Base::Finder
|
19
21
|
include CouchModel::Base::Association
|
20
22
|
|
21
|
-
|
23
|
+
# The NotFoundError will be raised if an operation is tried on a document that
|
24
|
+
# dosen't exists.
|
22
25
|
class NotFoundError < StandardError; end
|
23
26
|
|
24
27
|
attr_reader :attributes
|
25
28
|
|
26
29
|
def initialize(attributes = { })
|
27
|
-
|
30
|
+
klass = self.class
|
31
|
+
@attributes = { Configuration::CLASS_KEY => klass.to_s }
|
28
32
|
self.attributes = attributes
|
33
|
+
|
34
|
+
klass.defaults.each do |key, value|
|
35
|
+
@attributes[key] = value unless @attributes.has_key?(key)
|
36
|
+
end
|
29
37
|
end
|
30
38
|
|
31
39
|
def attributes=(attributes)
|
@@ -55,29 +63,25 @@ module CouchModel
|
|
55
63
|
end
|
56
64
|
|
57
65
|
def load
|
58
|
-
|
59
|
-
|
60
|
-
self.rev = response["_rev"]
|
61
|
-
[ "_id", "_rev", Configuration::CLASS_KEY ].each { |key| response.delete key }
|
62
|
-
self.attributes = response
|
66
|
+
load_response Transport.request(:get, url, :expected_status_code => 200)
|
63
67
|
true
|
64
|
-
rescue Transport::UnexpectedStatusCodeError =>
|
65
|
-
|
66
|
-
raise e
|
68
|
+
rescue Transport::UnexpectedStatusCodeError => error
|
69
|
+
upgrade_unexpected_status_error error
|
67
70
|
end
|
68
71
|
|
72
|
+
alias reload load
|
73
|
+
|
69
74
|
def save
|
70
75
|
new? ? create : update
|
71
76
|
end
|
72
77
|
|
73
78
|
def destroy
|
74
79
|
return false if new?
|
75
|
-
Transport.request :delete, self.url, :
|
76
|
-
|
80
|
+
Transport.request :delete, self.url, :headers => { "If-Match" => self.rev }, :expected_status_code => 200
|
81
|
+
clear_rev
|
77
82
|
true
|
78
|
-
rescue Transport::UnexpectedStatusCodeError =>
|
79
|
-
|
80
|
-
raise e
|
83
|
+
rescue Transport::UnexpectedStatusCodeError => error
|
84
|
+
upgrade_unexpected_status_error error
|
81
85
|
end
|
82
86
|
|
83
87
|
def url
|
@@ -95,8 +99,13 @@ module CouchModel
|
|
95
99
|
@attributes["_rev"] = value
|
96
100
|
end
|
97
101
|
|
102
|
+
def load_response(response)
|
103
|
+
self.rev = response["_rev"]
|
104
|
+
self.attributes = response
|
105
|
+
end
|
106
|
+
|
98
107
|
def create
|
99
|
-
response = Transport.request :post, self.database.url, :
|
108
|
+
response = Transport.request :post, self.database.url, :body => self.attributes, :expected_status_code => 201
|
100
109
|
self.id = response["id"]
|
101
110
|
self.rev = response["rev"]
|
102
111
|
true
|
@@ -105,13 +114,42 @@ module CouchModel
|
|
105
114
|
end
|
106
115
|
|
107
116
|
def update
|
108
|
-
response = Transport.request :put, self.url, :
|
117
|
+
response = Transport.request :put, self.url, :body => self.attributes, :expected_status_code => 201
|
109
118
|
self.rev = response["rev"]
|
110
119
|
true
|
111
120
|
rescue Transport::UnexpectedStatusCodeError
|
112
121
|
false
|
113
122
|
end
|
114
123
|
|
124
|
+
def clear_rev
|
125
|
+
self.rev = nil
|
126
|
+
end
|
127
|
+
|
128
|
+
def upgrade_unexpected_status_error(error)
|
129
|
+
raise NotFoundError if error.status_code == 404
|
130
|
+
raise error
|
131
|
+
end
|
132
|
+
|
133
|
+
def self.set_default(key, value)
|
134
|
+
@defaults ||= { }
|
135
|
+
@defaults[key.to_s] = value
|
136
|
+
end
|
137
|
+
|
138
|
+
def self.defaults
|
139
|
+
@defaults || { }
|
140
|
+
end
|
141
|
+
|
142
|
+
def self.create(*arguments)
|
143
|
+
model = new *arguments
|
144
|
+
model.save ? model : nil
|
145
|
+
end
|
146
|
+
|
147
|
+
def self.destroy_all
|
148
|
+
all.each do |model|
|
149
|
+
model.destroy
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
115
153
|
end
|
116
154
|
|
117
155
|
end
|
@@ -1,9 +1,11 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), "configuration")
|
2
1
|
require File.join(File.dirname(__FILE__), "transport")
|
3
|
-
require
|
2
|
+
require File.join(File.dirname(__FILE__), "row")
|
4
3
|
|
5
4
|
module CouchModel
|
6
5
|
|
6
|
+
# Collection is a proxy class for the resultset of a CouchDB view. It provides
|
7
|
+
# all read-only methods of an array. The loading of content is lazy and
|
8
|
+
# will be triggerd on the first request.
|
7
9
|
class Collection
|
8
10
|
|
9
11
|
REQUEST_PARAMETER_KEYS = [
|
@@ -25,10 +27,11 @@ module CouchModel
|
|
25
27
|
|
26
28
|
def initialize(url, options = { })
|
27
29
|
@url, @options = url, options
|
30
|
+
@options[:returns] ||= :models
|
28
31
|
end
|
29
32
|
|
30
33
|
def total_count
|
31
|
-
|
34
|
+
fetch_meta unless @total_count
|
32
35
|
@total_count
|
33
36
|
end
|
34
37
|
|
@@ -47,38 +50,55 @@ module CouchModel
|
|
47
50
|
|
48
51
|
private
|
49
52
|
|
50
|
-
def fetch
|
51
|
-
|
53
|
+
def fetch
|
54
|
+
fetch_response
|
55
|
+
evaluate_total_count
|
56
|
+
evaluate_entries
|
57
|
+
true
|
58
|
+
end
|
52
59
|
|
53
|
-
|
60
|
+
def fetch_meta
|
61
|
+
fetch_meta_response
|
62
|
+
evaluate_total_count
|
63
|
+
true
|
64
|
+
end
|
65
|
+
|
66
|
+
def fetch_response
|
67
|
+
@response = Transport.request(
|
54
68
|
:get, url,
|
55
|
-
:parameters => request_parameters
|
69
|
+
:parameters => request_parameters,
|
56
70
|
:expected_status_code => 200
|
57
71
|
)
|
58
|
-
|
59
|
-
true
|
60
72
|
end
|
61
73
|
|
62
|
-
def
|
63
|
-
@
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
model = model_class.new
|
69
|
-
model.instance_variable_set :@attributes, row["doc"]
|
70
|
-
model
|
71
|
-
end
|
74
|
+
def fetch_meta_response
|
75
|
+
@response = Transport.request(
|
76
|
+
:get, url,
|
77
|
+
:parameters => request_parameters.merge(:limit => 0),
|
78
|
+
:expected_status_code => 200
|
79
|
+
)
|
72
80
|
end
|
73
81
|
|
74
82
|
def request_parameters
|
75
|
-
parameters = {
|
83
|
+
parameters = @options[:returns] == :models ? { :include_docs => true } : { }
|
76
84
|
REQUEST_PARAMETER_KEYS.each do |key|
|
77
|
-
parameters[ key
|
85
|
+
parameters[ key ] = @options[key] if @options.has_key?(key)
|
78
86
|
end
|
79
87
|
parameters
|
80
88
|
end
|
81
89
|
|
90
|
+
def evaluate_total_count
|
91
|
+
@total_count = @response["total_rows"]
|
92
|
+
end
|
93
|
+
|
94
|
+
def evaluate_entries
|
95
|
+
returns = @options[:returns]
|
96
|
+
@entries = @response["rows"].map do |row_hash|
|
97
|
+
row = CouchModel::Row.new row_hash
|
98
|
+
returns == :models ? row.model : row
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
82
102
|
end
|
83
103
|
|
84
104
|
end
|