openlogic-couchrest_model 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +11 -0
- data/.rspec +4 -0
- data/Gemfile +4 -0
- data/LICENSE +176 -0
- data/README.md +137 -0
- data/Rakefile +38 -0
- data/THANKS.md +21 -0
- data/VERSION +1 -0
- data/benchmarks/dirty.rb +118 -0
- data/couchrest_model.gemspec +36 -0
- data/history.md +309 -0
- data/init.rb +1 -0
- data/lib/couchrest/model.rb +10 -0
- data/lib/couchrest/model/associations.rb +231 -0
- data/lib/couchrest/model/base.rb +129 -0
- data/lib/couchrest/model/callbacks.rb +28 -0
- data/lib/couchrest/model/casted_array.rb +83 -0
- data/lib/couchrest/model/casted_by.rb +33 -0
- data/lib/couchrest/model/casted_hash.rb +84 -0
- data/lib/couchrest/model/class_proxy.rb +135 -0
- data/lib/couchrest/model/collection.rb +273 -0
- data/lib/couchrest/model/configuration.rb +67 -0
- data/lib/couchrest/model/connection.rb +70 -0
- data/lib/couchrest/model/core_extensions/hash.rb +9 -0
- data/lib/couchrest/model/core_extensions/time_parsing.rb +66 -0
- data/lib/couchrest/model/design_doc.rb +128 -0
- data/lib/couchrest/model/designs.rb +91 -0
- data/lib/couchrest/model/designs/view.rb +513 -0
- data/lib/couchrest/model/dirty.rb +39 -0
- data/lib/couchrest/model/document_queries.rb +99 -0
- data/lib/couchrest/model/embeddable.rb +78 -0
- data/lib/couchrest/model/errors.rb +25 -0
- data/lib/couchrest/model/extended_attachments.rb +83 -0
- data/lib/couchrest/model/persistence.rb +178 -0
- data/lib/couchrest/model/properties.rb +228 -0
- data/lib/couchrest/model/property.rb +114 -0
- data/lib/couchrest/model/property_protection.rb +71 -0
- data/lib/couchrest/model/proxyable.rb +183 -0
- data/lib/couchrest/model/support/couchrest_database.rb +13 -0
- data/lib/couchrest/model/support/couchrest_design.rb +33 -0
- data/lib/couchrest/model/typecast.rb +154 -0
- data/lib/couchrest/model/validations.rb +80 -0
- data/lib/couchrest/model/validations/casted_model.rb +16 -0
- data/lib/couchrest/model/validations/locale/en.yml +5 -0
- data/lib/couchrest/model/validations/uniqueness.rb +69 -0
- data/lib/couchrest/model/views.rb +151 -0
- data/lib/couchrest/railtie.rb +24 -0
- data/lib/couchrest_model.rb +66 -0
- data/lib/rails/generators/couchrest_model.rb +16 -0
- data/lib/rails/generators/couchrest_model/config/config_generator.rb +18 -0
- data/lib/rails/generators/couchrest_model/config/templates/couchdb.yml +21 -0
- data/lib/rails/generators/couchrest_model/model/model_generator.rb +27 -0
- data/lib/rails/generators/couchrest_model/model/templates/model.rb +2 -0
- data/spec/.gitignore +1 -0
- data/spec/fixtures/attachments/README +3 -0
- data/spec/fixtures/attachments/couchdb.png +0 -0
- data/spec/fixtures/attachments/test.html +11 -0
- data/spec/fixtures/config/couchdb.yml +10 -0
- data/spec/fixtures/models/article.rb +36 -0
- data/spec/fixtures/models/base.rb +164 -0
- data/spec/fixtures/models/card.rb +19 -0
- data/spec/fixtures/models/cat.rb +23 -0
- data/spec/fixtures/models/client.rb +6 -0
- data/spec/fixtures/models/course.rb +27 -0
- data/spec/fixtures/models/event.rb +8 -0
- data/spec/fixtures/models/invoice.rb +14 -0
- data/spec/fixtures/models/key_chain.rb +5 -0
- data/spec/fixtures/models/membership.rb +4 -0
- data/spec/fixtures/models/person.rb +11 -0
- data/spec/fixtures/models/project.rb +6 -0
- data/spec/fixtures/models/question.rb +7 -0
- data/spec/fixtures/models/sale_entry.rb +9 -0
- data/spec/fixtures/models/sale_invoice.rb +14 -0
- data/spec/fixtures/models/service.rb +10 -0
- data/spec/fixtures/models/user.rb +22 -0
- data/spec/fixtures/views/lib.js +3 -0
- data/spec/fixtures/views/test_view/lib.js +3 -0
- data/spec/fixtures/views/test_view/only-map.js +4 -0
- data/spec/fixtures/views/test_view/test-map.js +3 -0
- data/spec/fixtures/views/test_view/test-reduce.js +3 -0
- data/spec/functional/validations_spec.rb +8 -0
- data/spec/spec_helper.rb +60 -0
- data/spec/unit/active_model_lint_spec.rb +30 -0
- data/spec/unit/assocations_spec.rb +242 -0
- data/spec/unit/attachment_spec.rb +176 -0
- data/spec/unit/base_spec.rb +537 -0
- data/spec/unit/casted_spec.rb +72 -0
- data/spec/unit/class_proxy_spec.rb +167 -0
- data/spec/unit/collection_spec.rb +86 -0
- data/spec/unit/configuration_spec.rb +77 -0
- data/spec/unit/connection_spec.rb +148 -0
- data/spec/unit/core_extensions/time_parsing.rb +77 -0
- data/spec/unit/design_doc_spec.rb +241 -0
- data/spec/unit/designs/view_spec.rb +831 -0
- data/spec/unit/designs_spec.rb +134 -0
- data/spec/unit/dirty_spec.rb +436 -0
- data/spec/unit/embeddable_spec.rb +498 -0
- data/spec/unit/inherited_spec.rb +33 -0
- data/spec/unit/persistence_spec.rb +481 -0
- data/spec/unit/property_protection_spec.rb +192 -0
- data/spec/unit/property_spec.rb +481 -0
- data/spec/unit/proxyable_spec.rb +376 -0
- data/spec/unit/subclass_spec.rb +85 -0
- data/spec/unit/typecast_spec.rb +521 -0
- data/spec/unit/validations_spec.rb +140 -0
- data/spec/unit/view_spec.rb +367 -0
- metadata +301 -0
@@ -0,0 +1,129 @@
|
|
1
|
+
module CouchRest
|
2
|
+
module Model
|
3
|
+
class Base < CouchRest::Document
|
4
|
+
|
5
|
+
extend ActiveModel::Naming
|
6
|
+
|
7
|
+
include CouchRest::Model::Configuration
|
8
|
+
include CouchRest::Model::Connection
|
9
|
+
include CouchRest::Model::Persistence
|
10
|
+
include CouchRest::Model::DocumentQueries
|
11
|
+
include CouchRest::Model::Views
|
12
|
+
include CouchRest::Model::DesignDoc
|
13
|
+
include CouchRest::Model::ExtendedAttachments
|
14
|
+
include CouchRest::Model::ClassProxy
|
15
|
+
include CouchRest::Model::Proxyable
|
16
|
+
include CouchRest::Model::Collection
|
17
|
+
include CouchRest::Model::PropertyProtection
|
18
|
+
include CouchRest::Model::Associations
|
19
|
+
include CouchRest::Model::Validations
|
20
|
+
include CouchRest::Model::Callbacks
|
21
|
+
include CouchRest::Model::Designs
|
22
|
+
include CouchRest::Model::CastedBy
|
23
|
+
include CouchRest::Model::Dirty
|
24
|
+
include CouchRest::Model::Callbacks
|
25
|
+
|
26
|
+
def self.subclasses
|
27
|
+
@subclasses ||= []
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.inherited(subklass)
|
31
|
+
super
|
32
|
+
subklass.send(:include, CouchRest::Model::Properties)
|
33
|
+
|
34
|
+
subklass.class_eval <<-EOS, __FILE__, __LINE__ + 1
|
35
|
+
def self.inherited(subklass)
|
36
|
+
super
|
37
|
+
subklass.properties = self.properties.dup
|
38
|
+
# This is nasty:
|
39
|
+
subklass._validators = self._validators.dup
|
40
|
+
end
|
41
|
+
EOS
|
42
|
+
subclasses << subklass
|
43
|
+
end
|
44
|
+
|
45
|
+
# Instantiate a new CouchRest::Model::Base by preparing all properties
|
46
|
+
# using the provided document hash.
|
47
|
+
#
|
48
|
+
# Options supported:
|
49
|
+
#
|
50
|
+
# * :directly_set_attributes, true when data comes directly from database
|
51
|
+
# * :database, provide an alternative database
|
52
|
+
#
|
53
|
+
# If a block is provided the new model will be passed into the
|
54
|
+
# block so that it can be populated.
|
55
|
+
def initialize(attributes = {}, options = {})
|
56
|
+
super()
|
57
|
+
prepare_all_attributes(attributes, options)
|
58
|
+
# set the instance's database, if provided
|
59
|
+
self.database = options[:database] unless options[:database].nil?
|
60
|
+
unless self['_id'] && self['_rev']
|
61
|
+
self[self.model_type_key] = self.class.to_s
|
62
|
+
end
|
63
|
+
|
64
|
+
yield self if block_given?
|
65
|
+
|
66
|
+
after_initialize if respond_to?(:after_initialize)
|
67
|
+
run_callbacks(:initialize) { self }
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
# Temp solution to make the view_by methods available
|
72
|
+
def self.method_missing(m, *args, &block)
|
73
|
+
if has_view?(m)
|
74
|
+
query = args.shift || {}
|
75
|
+
return view(m, query, *args, &block)
|
76
|
+
elsif m.to_s =~ /^find_(by_.+)/
|
77
|
+
view_name = $1
|
78
|
+
if has_view?(view_name)
|
79
|
+
return first_from_view(view_name, *args)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
super
|
83
|
+
end
|
84
|
+
|
85
|
+
# compatbility for 1.8, it does not use respond_to_missing?
|
86
|
+
# thing is, when using it like this only, doing method(:find_by_view)
|
87
|
+
# will throw an error
|
88
|
+
def self.respond_to?(m, include_private = false)
|
89
|
+
super || respond_to_missing?(m, include_private)
|
90
|
+
end
|
91
|
+
|
92
|
+
# ruby 1.9 feature
|
93
|
+
# this allows ruby to know that the method is defined using
|
94
|
+
# method_missing, and as such, method(:find_by_view) will actually
|
95
|
+
# give a Method back, and not throw an error like in 1.8!
|
96
|
+
def self.respond_to_missing?(m, include_private = false)
|
97
|
+
has_view?(m) || has_view?(m.to_s[/^find_(by_.+)/, 1])
|
98
|
+
end
|
99
|
+
|
100
|
+
def to_key
|
101
|
+
new? ? nil : [id]
|
102
|
+
end
|
103
|
+
|
104
|
+
alias :to_param :id
|
105
|
+
alias :new_record? :new?
|
106
|
+
alias :new_document? :new?
|
107
|
+
|
108
|
+
# Compare this model with another by confirming to see
|
109
|
+
# if the IDs and their databases match!
|
110
|
+
#
|
111
|
+
# Camparison of the database is required in case the
|
112
|
+
# model has been proxied or loaded elsewhere.
|
113
|
+
#
|
114
|
+
# A Basic CouchRest document will only ever compare using
|
115
|
+
# a Hash comparison on the attributes.
|
116
|
+
def == other
|
117
|
+
return false unless other.is_a?(Base)
|
118
|
+
if id.nil? && other.id.nil?
|
119
|
+
# no ids? assume comparing nested and revert to hash comparison
|
120
|
+
to_hash == other.to_hash
|
121
|
+
else
|
122
|
+
database == other.database && id == other.id
|
123
|
+
end
|
124
|
+
end
|
125
|
+
alias :eql? :==
|
126
|
+
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module CouchRest #:nodoc:
|
4
|
+
module Model #:nodoc:
|
5
|
+
|
6
|
+
module Callbacks
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
CALLBACKS = [
|
10
|
+
:before_validation, :after_validation,
|
11
|
+
:after_initialize,
|
12
|
+
:before_create, :around_create, :after_create,
|
13
|
+
:before_destroy, :around_destroy, :after_destroy,
|
14
|
+
:before_save, :around_save, :after_save,
|
15
|
+
:before_update, :around_update, :after_update,
|
16
|
+
]
|
17
|
+
|
18
|
+
included do
|
19
|
+
extend ActiveModel::Callbacks
|
20
|
+
include ActiveModel::Validations::Callbacks
|
21
|
+
|
22
|
+
define_model_callbacks :initialize, :only => :after
|
23
|
+
define_model_callbacks :create, :destroy, :save, :update
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
#
|
2
|
+
# Wrapper around Array so that the casted_by attribute is set in all
|
3
|
+
# elements of the array.
|
4
|
+
#
|
5
|
+
|
6
|
+
module CouchRest::Model
|
7
|
+
class CastedArray < Array
|
8
|
+
include CouchRest::Model::CastedBy
|
9
|
+
include CouchRest::Model::Dirty
|
10
|
+
attr_accessor :casted_by_property
|
11
|
+
|
12
|
+
def initialize(array, property, parent = nil)
|
13
|
+
self.casted_by_property = property
|
14
|
+
self.casted_by = parent unless parent.nil?
|
15
|
+
super(array)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Adding new entries
|
19
|
+
|
20
|
+
def << obj
|
21
|
+
super(instantiate_and_cast(obj))
|
22
|
+
end
|
23
|
+
|
24
|
+
def push(obj)
|
25
|
+
super(instantiate_and_cast(obj))
|
26
|
+
end
|
27
|
+
|
28
|
+
def unshift(obj)
|
29
|
+
super(instantiate_and_cast(obj))
|
30
|
+
end
|
31
|
+
|
32
|
+
def []= index, obj
|
33
|
+
value = instantiate_and_cast(obj, false)
|
34
|
+
couchrest_parent_will_change! if use_dirty? && value != self[index]
|
35
|
+
super(index, value)
|
36
|
+
end
|
37
|
+
|
38
|
+
def pop
|
39
|
+
couchrest_parent_will_change! if use_dirty? && self.length > 0
|
40
|
+
super
|
41
|
+
end
|
42
|
+
|
43
|
+
def shift
|
44
|
+
couchrest_parent_will_change! if use_dirty? && self.length > 0
|
45
|
+
super
|
46
|
+
end
|
47
|
+
|
48
|
+
def clear
|
49
|
+
couchrest_parent_will_change! if use_dirty? && self.length > 0
|
50
|
+
super
|
51
|
+
end
|
52
|
+
|
53
|
+
def delete(obj)
|
54
|
+
couchrest_parent_will_change! if use_dirty? && self.length > 0
|
55
|
+
super(obj)
|
56
|
+
end
|
57
|
+
|
58
|
+
def delete_at(index)
|
59
|
+
couchrest_parent_will_change! if use_dirty? && self.length > 0
|
60
|
+
super(index)
|
61
|
+
end
|
62
|
+
|
63
|
+
def build(*args)
|
64
|
+
obj = casted_by_property.build(*args)
|
65
|
+
self.push(obj)
|
66
|
+
obj
|
67
|
+
end
|
68
|
+
|
69
|
+
protected
|
70
|
+
|
71
|
+
def instantiate_and_cast(obj, change = true)
|
72
|
+
property = casted_by_property
|
73
|
+
couchrest_parent_will_change! if change && use_dirty?
|
74
|
+
if casted_by && property && obj.class != property.type_class
|
75
|
+
property.cast_value(casted_by, obj)
|
76
|
+
else
|
77
|
+
obj.casted_by = casted_by if obj.respond_to?(:casted_by)
|
78
|
+
obj.casted_by_property = casted_by_property if obj.respond_to?(:casted_by_property)
|
79
|
+
obj
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
|
2
|
+
module CouchRest::Model
|
3
|
+
module CastedBy
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
included do
|
6
|
+
self.send(:attr_accessor, :casted_by)
|
7
|
+
self.send(:attr_accessor, :casted_by_property)
|
8
|
+
end
|
9
|
+
|
10
|
+
# Gets a reference to the actual document in the DB
|
11
|
+
# Calls up to the next document if there is one,
|
12
|
+
# Otherwise we're at the top and we return self
|
13
|
+
def base_doc
|
14
|
+
return self if base_doc?
|
15
|
+
casted_by ? casted_by.base_doc : nil
|
16
|
+
end
|
17
|
+
|
18
|
+
# Checks if we're the top document
|
19
|
+
def base_doc?
|
20
|
+
!casted_by
|
21
|
+
end
|
22
|
+
|
23
|
+
# Provide the property this casted model instance has been
|
24
|
+
# used by. If it has not been set, search through the
|
25
|
+
# casted_by objects properties to try and find it.
|
26
|
+
#def casted_by_property
|
27
|
+
# return nil unless casted_by
|
28
|
+
# attrs = casted_by.attributes
|
29
|
+
# @casted_by_property ||= casted_by.properties.detect{ |k| attrs[k.to_s] === self }
|
30
|
+
#end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
#
|
2
|
+
# Wrapper around Hash so that the casted_by attribute is set.
|
3
|
+
|
4
|
+
module CouchRest::Model
|
5
|
+
class CastedHash < Hash
|
6
|
+
include CouchRest::Model::CastedBy
|
7
|
+
include CouchRest::Model::Dirty
|
8
|
+
attr_accessor :casted_by_property
|
9
|
+
|
10
|
+
def self.[](hash, property, parent = nil)
|
11
|
+
obj = super(hash)
|
12
|
+
obj.casted_by_property = property
|
13
|
+
obj.casted_by = parent unless parent.nil?
|
14
|
+
obj
|
15
|
+
end
|
16
|
+
|
17
|
+
# needed for dirty
|
18
|
+
def attributes
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def []= key, obj
|
23
|
+
couchrest_attribute_will_change!(key) if use_dirty? && obj != self[key]
|
24
|
+
super(key, obj)
|
25
|
+
end
|
26
|
+
|
27
|
+
def delete(key)
|
28
|
+
couchrest_attribute_will_change!(key) if use_dirty? && include?(key)
|
29
|
+
super(key)
|
30
|
+
end
|
31
|
+
|
32
|
+
def merge!(other_hash)
|
33
|
+
if use_dirty? && other_hash && other_hash.kind_of?(Hash)
|
34
|
+
other_hash.keys.each do |key|
|
35
|
+
if self[key] != other_hash[key] || !include?(key)
|
36
|
+
couchrest_attribute_will_change!(key)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
super(other_hash)
|
41
|
+
end
|
42
|
+
|
43
|
+
def replace(other_hash)
|
44
|
+
if use_dirty? && other_hash && other_hash.kind_of?(Hash)
|
45
|
+
# new keys and changed keys
|
46
|
+
other_hash.keys.each do |key|
|
47
|
+
if self[key] != other_hash[key] || !include?(key)
|
48
|
+
couchrest_attribute_will_change!(key)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
# old keys
|
52
|
+
old_keys = self.keys.reject { |key| other_hash.include?(key) }
|
53
|
+
old_keys.each { |key| couchrest_attribute_will_change!(key) }
|
54
|
+
end
|
55
|
+
|
56
|
+
super(other_hash)
|
57
|
+
end
|
58
|
+
|
59
|
+
def clear
|
60
|
+
self.keys.each { |key| couchrest_attribute_will_change!(key) } if use_dirty?
|
61
|
+
super
|
62
|
+
end
|
63
|
+
|
64
|
+
def delete_if
|
65
|
+
if use_dirty? && block_given?
|
66
|
+
self.keys.each do |key|
|
67
|
+
couchrest_attribute_will_change!(key) if yield key, self[key]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
super
|
71
|
+
end
|
72
|
+
|
73
|
+
# ruby 1.9
|
74
|
+
def keep_if
|
75
|
+
if use_dirty? && block_given?
|
76
|
+
self.keys.each do |key|
|
77
|
+
couchrest_attribute_will_change!(key) if !yield key, self[key]
|
78
|
+
end
|
79
|
+
end
|
80
|
+
super
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
module CouchRest
|
2
|
+
module Model
|
3
|
+
module ClassProxy
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
base.extend(ClassMethods)
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
|
11
|
+
# Return a proxy object which represents a model class on a
|
12
|
+
# chosen database instance. This allows you to DRY operations
|
13
|
+
# where a database is chosen dynamically.
|
14
|
+
#
|
15
|
+
# ==== Example:
|
16
|
+
#
|
17
|
+
# db = CouchRest::Database.new(...)
|
18
|
+
# articles = Article.on(db)
|
19
|
+
#
|
20
|
+
# articles.all { ... }
|
21
|
+
# articles.by_title { ... }
|
22
|
+
#
|
23
|
+
# u = articles.get("someid")
|
24
|
+
#
|
25
|
+
# u = articles.new(:title => "I like plankton")
|
26
|
+
# u.save # saved on the correct database
|
27
|
+
|
28
|
+
def on(database)
|
29
|
+
Proxy.new(self, database)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class Proxy #:nodoc:
|
34
|
+
def initialize(klass, database)
|
35
|
+
@klass = klass
|
36
|
+
@database = database
|
37
|
+
end
|
38
|
+
|
39
|
+
# Base
|
40
|
+
|
41
|
+
def new(*args)
|
42
|
+
doc = @klass.new(*args)
|
43
|
+
doc.database = @database
|
44
|
+
doc
|
45
|
+
end
|
46
|
+
|
47
|
+
def method_missing(m, *args, &block)
|
48
|
+
if has_view?(m)
|
49
|
+
query = args.shift || {}
|
50
|
+
return view(m, query, *args, &block)
|
51
|
+
elsif m.to_s =~ /^find_(by_.+)/
|
52
|
+
view_name = $1
|
53
|
+
if has_view?(view_name)
|
54
|
+
return first_from_view(view_name, *args)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
super
|
58
|
+
end
|
59
|
+
|
60
|
+
# DocumentQueries
|
61
|
+
|
62
|
+
def all(opts = {}, &block)
|
63
|
+
docs = @klass.all({:database => @database}.merge(opts), &block)
|
64
|
+
docs.each { |doc| doc.database = @database if doc.respond_to?(:database) } if docs
|
65
|
+
docs
|
66
|
+
end
|
67
|
+
|
68
|
+
def count(opts = {}, &block)
|
69
|
+
@klass.all({:database => @database, :raw => true, :limit => 0}.merge(opts), &block)['total_rows']
|
70
|
+
end
|
71
|
+
|
72
|
+
def first(opts = {})
|
73
|
+
doc = @klass.first({:database => @database}.merge(opts))
|
74
|
+
doc.database = @database if doc && doc.respond_to?(:database)
|
75
|
+
doc
|
76
|
+
end
|
77
|
+
|
78
|
+
def last(opts = {})
|
79
|
+
doc = @klass.last({:database => @database}.merge(opts))
|
80
|
+
doc.database = @database if doc && doc.respond_to?(:database)
|
81
|
+
doc
|
82
|
+
end
|
83
|
+
|
84
|
+
def get(id)
|
85
|
+
doc = @klass.get(id, @database)
|
86
|
+
doc.database = @database if doc && doc.respond_to?(:database)
|
87
|
+
doc
|
88
|
+
end
|
89
|
+
alias :find :get
|
90
|
+
|
91
|
+
def get!(id)
|
92
|
+
doc = @klass.get!(id, @database)
|
93
|
+
doc.database = @database if doc && doc.respond_to?(:database)
|
94
|
+
doc
|
95
|
+
end
|
96
|
+
alias :find! :get!
|
97
|
+
|
98
|
+
# Views
|
99
|
+
|
100
|
+
def has_view?(view)
|
101
|
+
@klass.has_view?(view)
|
102
|
+
end
|
103
|
+
|
104
|
+
def view(name, query={}, &block)
|
105
|
+
docs = @klass.view(name, {:database => @database}.merge(query), &block)
|
106
|
+
docs.each { |doc| doc.database = @database if doc.respond_to?(:database) } if docs
|
107
|
+
docs
|
108
|
+
end
|
109
|
+
|
110
|
+
def first_from_view(name, *args)
|
111
|
+
# add to first hash available, or add to end
|
112
|
+
(args.last.is_a?(Hash) ? args.last : (args << {}).last)[:database] = @database
|
113
|
+
doc = @klass.first_from_view(name, *args)
|
114
|
+
doc.database = @database if doc && doc.respond_to?(:database)
|
115
|
+
doc
|
116
|
+
end
|
117
|
+
|
118
|
+
# DesignDoc
|
119
|
+
|
120
|
+
def design_doc
|
121
|
+
@klass.design_doc
|
122
|
+
end
|
123
|
+
|
124
|
+
def refresh_design_doc
|
125
|
+
@klass.refresh_design_doc(@database)
|
126
|
+
end
|
127
|
+
|
128
|
+
def save_design_doc
|
129
|
+
@klass.save_design_doc(@database)
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|