dpla-couchrest 1.2.1.pre.dpla

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +7 -0
  3. data/.travis.yml +8 -0
  4. data/Gemfile +2 -0
  5. data/LICENSE +176 -0
  6. data/README.md +66 -0
  7. data/Rakefile +23 -0
  8. data/THANKS.md +21 -0
  9. data/VERSION +1 -0
  10. data/couchrest.gemspec +36 -0
  11. data/examples/word_count/markov +38 -0
  12. data/examples/word_count/views/books/chunked-map.js +3 -0
  13. data/examples/word_count/views/books/united-map.js +1 -0
  14. data/examples/word_count/views/markov/chain-map.js +6 -0
  15. data/examples/word_count/views/markov/chain-reduce.js +7 -0
  16. data/examples/word_count/views/word_count/count-map.js +6 -0
  17. data/examples/word_count/views/word_count/count-reduce.js +3 -0
  18. data/examples/word_count/word_count.rb +46 -0
  19. data/examples/word_count/word_count_query.rb +40 -0
  20. data/examples/word_count/word_count_views.rb +26 -0
  21. data/history.txt +214 -0
  22. data/init.rb +1 -0
  23. data/lib/couchrest.rb +146 -0
  24. data/lib/couchrest/attributes.rb +89 -0
  25. data/lib/couchrest/commands/generate.rb +71 -0
  26. data/lib/couchrest/commands/push.rb +103 -0
  27. data/lib/couchrest/database.rb +402 -0
  28. data/lib/couchrest/design.rb +91 -0
  29. data/lib/couchrest/document.rb +105 -0
  30. data/lib/couchrest/helper/attachments.rb +29 -0
  31. data/lib/couchrest/helper/pager.rb +103 -0
  32. data/lib/couchrest/helper/streamer.rb +60 -0
  33. data/lib/couchrest/helper/upgrade.rb +51 -0
  34. data/lib/couchrest/middlewares/logger.rb +263 -0
  35. data/lib/couchrest/monkeypatches.rb +25 -0
  36. data/lib/couchrest/rest_api.rb +166 -0
  37. data/lib/couchrest/server.rb +92 -0
  38. data/lib/couchrest/support/inheritable_attributes.rb +107 -0
  39. data/spec/.gitignore +1 -0
  40. data/spec/couchrest/couchrest_spec.rb +197 -0
  41. data/spec/couchrest/database_spec.rb +914 -0
  42. data/spec/couchrest/design_spec.rb +206 -0
  43. data/spec/couchrest/document_spec.rb +400 -0
  44. data/spec/couchrest/helpers/pager_spec.rb +115 -0
  45. data/spec/couchrest/helpers/streamer_spec.rb +134 -0
  46. data/spec/couchrest/rest_api_spec.rb +241 -0
  47. data/spec/couchrest/server_spec.rb +35 -0
  48. data/spec/fixtures/attachments/README +3 -0
  49. data/spec/fixtures/attachments/couchdb.png +0 -0
  50. data/spec/fixtures/attachments/test.html +11 -0
  51. data/spec/fixtures/views/lib.js +3 -0
  52. data/spec/fixtures/views/test_view/lib.js +3 -0
  53. data/spec/fixtures/views/test_view/only-map.js +4 -0
  54. data/spec/fixtures/views/test_view/test-map.js +3 -0
  55. data/spec/fixtures/views/test_view/test-reduce.js +3 -0
  56. data/spec/spec.opts +5 -0
  57. data/spec/spec_helper.rb +46 -0
  58. data/utils/remap.rb +27 -0
  59. data/utils/subset.rb +30 -0
  60. metadata +212 -0
@@ -0,0 +1,40 @@
1
+ require 'rubygems'
2
+ require 'couchrest'
3
+
4
+ couch = CouchRest.new("http://127.0.0.1:5984")
5
+ db = couch.database('word-count-example')
6
+
7
+ puts "Now that we've parsed all those books into CouchDB, the queries we can run are incredibly flexible."
8
+ puts "\nThe simplest query we can run is the total word count for all words in all documents:"
9
+ puts "this will take a few minutes the first time. if it times out, just rerun this script in a few few minutes."
10
+ puts db.view('word_count/words').inspect
11
+
12
+ puts "\nWe can also narrow the query down to just one word, across all documents. Here is the count for 'flight' in all three books:"
13
+
14
+ word = 'flight'
15
+ params = {
16
+ :startkey => [word],
17
+ :endkey => [word,{}]
18
+ }
19
+
20
+ puts db.view('word_count/words',params).inspect
21
+
22
+ puts "\nWe scope the query using startkey and endkey params to take advantage of CouchDB's collation ordering. Here are the params for the last query:"
23
+ puts params.inspect
24
+
25
+ puts "\nWe can also count words on a per-title basis."
26
+
27
+ title = 'da-vinci'
28
+ params = {
29
+ :key => [word, title]
30
+ }
31
+
32
+ puts db.view('word_count/words',params).inspect
33
+
34
+
35
+ puts "\nHere are the params for 'flight' in the da-vinci book:"
36
+ puts params.inspect
37
+ puts
38
+ puts 'The url looks like this:'
39
+ puts 'http://127.0.0.1:5984/word-count-example/_view/word_count/count?key=["flight","da-vinci"]'
40
+ puts "\nTry dropping that in your browser..."
@@ -0,0 +1,26 @@
1
+ require 'rubygems'
2
+ require 'couchrest'
3
+
4
+ couch = CouchRest.new("http://127.0.0.1:5984")
5
+ db = couch.database('word-count-example')
6
+
7
+ word_count = {
8
+ :map => 'function(doc){
9
+ var words = doc.text.split(/\W/);
10
+ words.forEach(function(word){
11
+ if (word.length > 0) emit([word,doc.title],1);
12
+ });
13
+ }',
14
+ :reduce => 'function(key,combine){
15
+ return sum(combine);
16
+ }'
17
+ }
18
+
19
+ db.delete_doc db.get("_design/word_count") rescue nil
20
+
21
+ db.save_doc({
22
+ "_id" => "_design/word_count",
23
+ :views => {
24
+ :words => word_count
25
+ }
26
+ })
data/history.txt ADDED
@@ -0,0 +1,214 @@
1
+ == 1.2.0 - 2013-05-25
2
+
3
+ * Changes
4
+ * Added clobal configuration option to decode JSON objects (@langalex)
5
+ * Changing specs to test parameters as apposed to CouchDB for replication and restart
6
+ * Spec updates (@tapajos)
7
+ * Spec typos (@frasertweedale, @m1foley)
8
+
9
+ == 1.1.3 - 2012-07-31
10
+
11
+ * Minor changes
12
+ * Add support for HTTP HEAD requests (Tim Anglade)
13
+ * Make CouchRest#database! check if a db exists before creating it (Tim Anglade)
14
+ * Use _doc suffix in examples for delete and save (Mickael Riga)
15
+ * Database#view should not modify the params (@krishan)
16
+ * Fix replication with couchdb >= 1.1.0 (@erickt)
17
+ * Streamer protection against bad responses improved (@erickt)
18
+ * Support atomic bulk save requests with all_or_nothing CouchDB parameter (@matthiasjakel)
19
+ * Update multi_json dependency so we can use any 1.x version (@dgraham)
20
+
21
+ == 1.1.2 - 2011-07-18
22
+
23
+ * Minor changes
24
+ * Added `as_couch_json` method. If available, will be called before sending document to JSON encoder.
25
+
26
+ == 1.1.1 - 2011-07-04
27
+
28
+ * Urgent change
29
+ * Ensuring attributes hash initalized on use to avoid issues when initializer is overwritten.
30
+
31
+ == 1.1.0 - 2011-06-25
32
+
33
+ * Minor changes
34
+ * Refactored basic CouchRest API (get, post, etc.) to pass-through RestClient and MultiJSON options, including headers.
35
+ * CouchRest::Attributes module created to make attribute related methods independent.
36
+
37
+ == 1.1.0.pre3 - 2011-06-06
38
+
39
+ * Major changes
40
+ * CouchRest::Response removed
41
+ * CouchRest::Document now forwards key Hash methods (instead of inheritance) (thanks @karmi for prompting the discussion: https://github.com/crx/tire/commit/abf491d0035843a0a7395c8c32b9b7c2120071f9)
42
+ * Support multiple JSON gems with multi_json (thanks chrisdurtschi)
43
+
44
+ == 1.1.0.pre2 - 2011-04-08
45
+
46
+ * Major changes
47
+ * Time#to_json monkey patch removed! Standard JSON methods now used instead.
48
+
49
+ * Minor alterations
50
+ * Named doc replication (thanks @ahamid)
51
+ * Database#update_doc no longer requires document to be returned from block (thanks @ferrous26)
52
+ * Streamer now available for all queries that return multiple documents (thanks @pcapr for pointer)
53
+ * Streamer#view method removed, use Database.view with block
54
+ * Database#changes method added (with streamer option)
55
+ * Added :allow_nil option when creating views
56
+ * Bug fix: only symbols can be passed as view options (helps fix auto :reduce option)
57
+
58
+ WARNING: If you depend on ordering by Time, this release may cause issues on old databases!
59
+ Either update your documents to use the new format (JSON standard), or use Javascript's Date.parse
60
+ method in your views. Also, use Time#utc to ensure universal ordering regardless of time
61
+ zone. (CouchRest Model does this automatically.)
62
+
63
+ == 1.0.2
64
+
65
+ * Minor enhancements
66
+ * Bundler
67
+ * Dependency versions upgrade
68
+ * Removed reduce option from view's defaults. Now detected according to presence of reduce function.
69
+ * Design#has_view? and Design#can_reduce_view? now available publically
70
+
71
+ == 1.0.1
72
+
73
+ * Minor enhancements
74
+ * rest-client version mismatch between couchrest.rb & gemspec
75
+ * json 1.4.X series re-enabled as tests now pass with v.1.4.6
76
+
77
+ == 1.0.0
78
+
79
+ * Major enhancements
80
+ * Moved ExtendedDocument and friends into own library, couchrest_extended_document. (Sam Lown)
81
+ * Removed HttpAbstraction component for direct interface with RestClient. (Sam Lown)
82
+ * Changed version to more conventional format starting from 1.0.0 to avoid ambiguity issues with order. (Sam Lown)
83
+
84
+ == 0.38
85
+
86
+ * Major enhancements
87
+ * Add create_target option to Database#replicate_to and #replicate_from. http://github.com/couchrest/couchrest/issues/#issue/26 (Alexander Uvarov)
88
+ * Removing unused core extensions and moving extlib_inhertiable_* methods to use couchrest_inheritable_*
89
+ to avoid conflicts with Rails. (Geoff Buesing)
90
+
91
+ * Minor enhancements
92
+ * Support for CouchDB 1.0
93
+ * Added Document#id= support (issue detected by Rory Franklin with RSpec model stubs)
94
+ * Fixing issues with CouchDB 1.0 and RestClient
95
+
96
+ == 0.37
97
+
98
+ * Minor enhancements
99
+ * Added gemspec (needed for Bundler install) (Tapajós)
100
+
101
+ == 0.36
102
+
103
+ * Major enhancements
104
+ * Adds support for continuous replication (sauy7)
105
+ * Automatic Type Casting (Alexander Uvarov, Sam Lown, Tim Heighes, Will Leinweber)
106
+ * Added a search method to CouchRest:Database to search the documents in a given database. (Dave Farkas, Arnaud Berthomier, John Wood)
107
+
108
+ * Minor enhancements
109
+ * Provide a description of the timeout error (John Wood)
110
+
111
+ == 0.35
112
+
113
+ * Major enhancements
114
+ * CouchRest::ExtendedDocument allow chaining the inherit class callback (Kenneth Kalmer) - http://github.com/couchrest/couchrest/issues#issue/8
115
+
116
+ * Minor enhancements
117
+ * Fix attachment bug (Johannes Jörg Schmidt)
118
+ * Fix create database exception bug (Damien Mathieu)
119
+ * Compatible with restclient >= 1.4.0 new responses (Julien Kirch)
120
+ * Bug fix: Attribute protection no longer strips attributes coming from the database (Will Leinweber)
121
+ * Bug fix: Remove double CGI escape when PUTting an attachment (nzoschke)
122
+ * Bug fix: Changing Class proxy to set database on result sets (Peter Gumeson)
123
+ * Bug fix: Updated time regexp (Nolan Darilek)
124
+ * Added an update_doc method to database to handle conflicts during atomic updates. (Pierre Larochelle)
125
+ * Bug fix: http://github.com/couchrest/couchrest/issues/#issue/2 (Luke Burton)
126
+
127
+ == 0.34
128
+
129
+ * Major enhancements
130
+
131
+ * Added support for https database URIs. (Mathias Meyer)
132
+ * Changing some validations to be compatible with activemodel. (Marcos Tapajós)
133
+ * Adds attribute protection to properties. (Will Leinweber)
134
+ * Improved CouchRest::Database#save_doc, added "batch" mode to significantly speed up saves at cost of lower durability gurantees. (Igal Koshevoy)
135
+ * Added CouchRest::Database#bulk_save_doc and #batch_save_doc as human-friendlier wrappers around #save_doc. (Igal Koshevoy)
136
+
137
+ * Minor enhancements
138
+
139
+ * Fix content_type handling for attachments
140
+ * Fixed a bug in the pagination code that caused it to paginate over records outside of the scope of the view parameters.(John Wood)
141
+ * Removed amount_pages calculation for the pagination collection, since it cannot be reliably calculated without a view.(John Wood)
142
+ * Bug fix: http://github.com/couchrest/couchrest/issues/#issue/2 (Luke Burton)
143
+ * Bug fix: http://github.com/couchrest/couchrest/issues/#issue/1 (Marcos Tapajós)
144
+ * Removed the Database class deprecation notices (Matt Aimonetti)
145
+ * Adding support to :cast_as => 'Date'. (Marcos Tapajós)
146
+ * Improve documentation (Marcos Tapajós)
147
+ * Streamer fixes (Julien Sanchez)
148
+ * Fix Save on Document & ExtendedDocument crashed if bulk (Julien Sanchez)
149
+ * Fix Initialization of ExtendentDocument model shouldn't failed on a nil value in argument (deepj)
150
+ * Change to use Jeweler and Gemcutter (Marcos Tapajós)
151
+
152
+ == 0.33
153
+
154
+ * Major enhancements
155
+
156
+ * Added a new Rack logger middleware letting you log/save requests/queries (Matt Aimonetti)
157
+
158
+ * Minor enhancements
159
+
160
+ * Added #amount_pages to a paginated result array (Matt Aimonetti)
161
+ * Ruby 1.9.2 compatible (Matt Aimonetti)
162
+ * Added a property? method for property cast as :boolean (John Wood)
163
+ * Added an option to force the deletion of a attachments (bypass 409s) (Matt Aimonetti)
164
+ * Created a new abstraction layer for the REST API (Matt Aimonetti)
165
+ * Bug fix: made ExtendedDocument#all compatible with Couch 0.10 (tc)
166
+
167
+ == 0.32
168
+
169
+ * Major enhancements
170
+
171
+ * ExtendedDocument.get doesn't raise an exception anymore. If no documents are found nil is returned.
172
+ * ExtendedDocument.get! works the say #get used to work and will raise an exception if a document isn't found.
173
+
174
+ * Minor enhancements
175
+
176
+ * Bug fix: Model.all(:keys => [1,2]) was not working (Matt Aimonetti)
177
+ * Added ValidationErrors#count in order to play nicely with Rails (Peter Wagenet)
178
+ * Bug fix: class proxy design doc refresh (Daniel Kirsh)
179
+ * Bug fix: the count method on the proxy collection was missing (Daniel Kirsch)
180
+ * Added #amount_pages to a paginated collection. (Matt Aimonetti)
181
+
182
+ == 0.31
183
+
184
+ * Major enhancements
185
+
186
+ * Created an abstraction HTTP layer to support different http adapters (Matt Aimonetti)
187
+ * Added ExtendedDocument.create({}) and #create!({}) so you don't have to do Model.new.create (Matt Aimonetti)
188
+
189
+ * Minor enhancements
190
+
191
+ * Added an init.rb file for easy usage as a Rails plugin (Aaron Quint)
192
+ * Bug fix: pagination shouldn't die on empty results (Arnaud Berthomier)
193
+ * Optimized ExtendedDocument.count to run about 3x faster (Matt Aimonetti)
194
+ * Added Float casting (Ryan Felton & Matt Aimonetti)
195
+
196
+ == 0.30
197
+
198
+ * Major enhancements
199
+
200
+ * Added support for pagination (John Wood)
201
+ * Improved performance when initializing documents with timestamps (Matt Aimonetti)
202
+
203
+ * Minor enhancements
204
+
205
+ * Extended the API to retrieve an attachment URI (Matt Aimonetti)
206
+ * Bug fix: default value should be able to be set as false (Alexander Uvarov)
207
+ * Bug fix: validates_is_numeric should be able to properly validate a Float instance (Rob Kaufman)
208
+ * Bug fix: fixed the Timeout implementation (Seth Falcon)
209
+
210
+
211
+ ---
212
+
213
+ Unfortunately, before 0.30 we did not keep a track of the modifications made to CouchRest.
214
+ You can see the full commit history on GitHub: http://github.com/couchrest/couchrest/commits/master/
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require File.join(File.dirname(__FILE__),'lib', 'couchrest.rb')
data/lib/couchrest.rb ADDED
@@ -0,0 +1,146 @@
1
+ # Copyright 2008 J. Chris Anderson
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'rest_client'
16
+ require 'multi_json'
17
+
18
+ # Not sure why this is required, so removed until a reason is found!
19
+ $:.unshift File.dirname(__FILE__) unless
20
+ $:.include?(File.dirname(__FILE__)) ||
21
+ $:.include?(File.expand_path(File.dirname(__FILE__)))
22
+
23
+ require 'couchrest/monkeypatches'
24
+ require 'couchrest/rest_api'
25
+ require 'couchrest/support/inheritable_attributes'
26
+
27
+ require 'forwardable'
28
+
29
+ # = CouchDB, close to the metal
30
+ module CouchRest
31
+ autoload :Attributes, 'couchrest/attributes'
32
+ autoload :Server, 'couchrest/server'
33
+ autoload :Database, 'couchrest/database'
34
+ autoload :Document, 'couchrest/document'
35
+ autoload :Design, 'couchrest/design'
36
+ autoload :Model, 'couchrest/model'
37
+ autoload :Pager, 'couchrest/helper/pager'
38
+ autoload :Streamer, 'couchrest/helper/streamer'
39
+ autoload :Attachments, 'couchrest/helper/attachments'
40
+ autoload :Upgrade, 'couchrest/helper/upgrade'
41
+
42
+ # we extend CouchRest with the RestAPI module which gives us acess to
43
+ # the get, post, put, delete and copy
44
+ CouchRest.extend(::CouchRest::RestAPI)
45
+
46
+ # The CouchRest module methods handle the basic JSON serialization
47
+ # and deserialization, as well as query parameters. The module also includes
48
+ # some helpers for tasks like instantiating a new Database or Server instance.
49
+ class << self
50
+
51
+ # todo, make this parse the url and instantiate a Server or Database instance
52
+ # depending on the specificity.
53
+ def new(*opts)
54
+ Server.new(*opts)
55
+ end
56
+
57
+ def parse url
58
+ case url
59
+ when /^(https?:\/\/)(.*)\/(.*)\/(.*)/
60
+ scheme = $1
61
+ host = $2
62
+ db = $3
63
+ docid = $4
64
+ when /^(https?:\/\/)(.*)\/(.*)/
65
+ scheme = $1
66
+ host = $2
67
+ db = $3
68
+ when /^(https?:\/\/)(.*)/
69
+ scheme = $1
70
+ host = $2
71
+ when /(.*)\/(.*)\/(.*)/
72
+ host = $1
73
+ db = $2
74
+ docid = $3
75
+ when /(.*)\/(.*)/
76
+ host = $1
77
+ db = $2
78
+ else
79
+ db = url
80
+ end
81
+
82
+ db = nil if db && db.empty?
83
+
84
+ {
85
+ :host => (scheme || "http://") + (host || "127.0.0.1:5984"),
86
+ :database => db,
87
+ :doc => docid
88
+ }
89
+ end
90
+
91
+ # set proxy to use
92
+ def proxy url
93
+ RestClient.proxy = url
94
+ end
95
+
96
+ # ensure that a database exists
97
+ # creates it if it isn't already there
98
+ # returns it after it's been created
99
+ def database! url
100
+ parsed = parse url
101
+ cr = CouchRest.new(parsed[:host])
102
+ cr.database!(parsed[:database])
103
+ end
104
+
105
+ def database url
106
+ parsed = parse url
107
+ cr = CouchRest.new(parsed[:host])
108
+ cr.database(parsed[:database])
109
+ end
110
+
111
+ def paramify_url url, params = {}
112
+ if params && !params.empty?
113
+ query = params.collect do |k,v|
114
+ v = MultiJson.encode(v) if %w{key startkey endkey}.include?(k.to_s)
115
+ "#{k}=#{CGI.escape(v.to_s)}"
116
+ end.join("&")
117
+ url = "#{url}?#{query}"
118
+ end
119
+ url
120
+ end
121
+
122
+ @@decode_json_objects = false
123
+
124
+ def decode_json_objects=(value)
125
+ @@decode_json_objects = value
126
+ end
127
+
128
+ # When set to true, CouchRest.get tries to decode the JSON returned
129
+ # from CouchDB into a Ruby object. Default: false.
130
+ def decode_json_objects
131
+ @@decode_json_objects
132
+ end
133
+ end # class << self
134
+ end
135
+ # For the sake of backwards compatability, generate a dummy ExtendedDocument class
136
+ # which should be replaced by real library: couchrest_extended_document.
137
+ #
138
+ # Added 2010-05-10 by Sam Lown. Please remove at some point in the future.
139
+ #
140
+ class CouchRest::ExtendedDocument < CouchRest::Document
141
+
142
+ def self.inherited(subclass)
143
+ raise "ExtendedDocument is no longer included in CouchRest base driver, see couchrest_extended_document gem"
144
+ end
145
+
146
+ end
@@ -0,0 +1,89 @@
1
+ #
2
+ # CouchRest::Attributes
3
+ #
4
+ # When included, provide the owner with an attributes hash and
5
+ # accessors that forward calls to it.
6
+ #
7
+ # Provides the basic functionality of Hash without actually being
8
+ # a Hash using Ruby's standard Forwardable module.
9
+ #
10
+ module CouchRest
11
+
12
+ module Attributes
13
+ extend Forwardable
14
+
15
+ # Initialize a new CouchRest Document and prepare
16
+ # a hidden attributes hash.
17
+ #
18
+ # When inherting a Document, it is essential that the
19
+ # super method is called before you own changes to ensure
20
+ # that the attributes hash has been initialized before
21
+ # you attempt to use it.
22
+ def initialize(attrs = nil)
23
+ attrs.each{|k,v| self[k] = v} unless attrs.nil?
24
+ end
25
+
26
+ # Hash equivilent methods to access the attributes
27
+ def_delegators :_attributes, :to_a, :==, :eql?, :keys, :values, :each,
28
+ :reject, :reject!, :empty?, :clear, :merge, :merge!,
29
+ :encode_json, :as_json, :to_json, :frozen?
30
+
31
+ def []=(key, value)
32
+ _attributes[key.to_s] = value
33
+ end
34
+ def [](key)
35
+ _attributes[key.to_s]
36
+ end
37
+ def has_key?(key)
38
+ _attributes.has_key?(key.to_s)
39
+ end
40
+ def delete(key)
41
+ _attributes.delete(key.to_s)
42
+ end
43
+ def dup
44
+ new = super
45
+ @_attributes = @_attributes.dup
46
+ new
47
+ end
48
+ def clone
49
+ new = super
50
+ @_attributes = @_attributes.dup
51
+ new
52
+ end
53
+ def to_hash
54
+ _attributes
55
+ end
56
+
57
+ # Provide JSON data hash that can be stored in the database.
58
+ # Will go through each attribute value and request the `as_couch_json` method
59
+ # on each if available, or return the value as-is.
60
+ def as_couch_json
61
+ _attributes.inject({}) {|h, (k,v)| h[k] = v.respond_to?(:as_couch_json) ? v.as_couch_json : v; h}
62
+ end
63
+
64
+ # Freeze the object's attributes instead of the actual document.
65
+ # This prevents further modifications to stored data, but does allow access
66
+ # to local variables useful for callbacks or cached data.
67
+ def freeze
68
+ _attributes.freeze; self
69
+ end
70
+
71
+ # Provide details of the current keys in the reponse. Based on ActiveRecord::Base.
72
+ def inspect
73
+ attributes_as_nice_string = self.keys.collect { |key|
74
+ "#{key}: #{self[key].inspect}"
75
+ }.compact.join(", ")
76
+ "#<#{self.class} #{attributes_as_nice_string}>"
77
+ end
78
+
79
+ protected
80
+
81
+ # Define accessor for _attributes hash that will instantiate the
82
+ # model if this has not already been done.
83
+ def _attributes
84
+ @_attributes ||= {}
85
+ end
86
+
87
+ end
88
+
89
+ end