couchrest 0.33 → 0.34
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +8 -127
- data/Rakefile +20 -36
- data/THANKS.md +2 -1
- data/history.txt +25 -0
- data/lib/couchrest.rb +5 -4
- data/lib/couchrest/core/database.rb +26 -21
- data/lib/couchrest/core/document.rb +4 -3
- data/lib/couchrest/helper/streamer.rb +11 -4
- data/lib/couchrest/mixins/attribute_protection.rb +74 -0
- data/lib/couchrest/mixins/callbacks.rb +187 -138
- data/lib/couchrest/mixins/collection.rb +3 -16
- data/lib/couchrest/mixins/extended_attachments.rb +1 -1
- data/lib/couchrest/mixins/extended_document_mixins.rb +1 -0
- data/lib/couchrest/mixins/properties.rb +71 -44
- data/lib/couchrest/mixins/validation.rb +18 -29
- data/lib/couchrest/more/casted_model.rb +29 -1
- data/lib/couchrest/more/extended_document.rb +73 -25
- data/lib/couchrest/more/property.rb +20 -1
- data/lib/couchrest/support/class.rb +81 -67
- data/lib/couchrest/support/rails.rb +12 -5
- data/lib/couchrest/validation/auto_validate.rb +5 -9
- data/lib/couchrest/validation/validators/confirmation_validator.rb +11 -3
- data/lib/couchrest/validation/validators/format_validator.rb +8 -3
- data/lib/couchrest/validation/validators/length_validator.rb +10 -5
- data/lib/couchrest/validation/validators/numeric_validator.rb +6 -1
- data/lib/couchrest/validation/validators/required_field_validator.rb +8 -3
- data/spec/couchrest/core/couchrest_spec.rb +48 -2
- data/spec/couchrest/core/database_spec.rb +22 -10
- data/spec/couchrest/core/document_spec.rb +9 -1
- data/spec/couchrest/helpers/streamer_spec.rb +31 -2
- data/spec/couchrest/more/attribute_protection_spec.rb +94 -0
- data/spec/couchrest/more/casted_extended_doc_spec.rb +2 -4
- data/spec/couchrest/more/casted_model_spec.rb +230 -1
- data/spec/couchrest/more/extended_doc_attachment_spec.rb +2 -2
- data/spec/couchrest/more/extended_doc_spec.rb +173 -15
- data/spec/couchrest/more/extended_doc_view_spec.rb +17 -10
- data/spec/couchrest/more/property_spec.rb +97 -3
- data/spec/fixtures/more/article.rb +4 -3
- data/spec/fixtures/more/card.rb +1 -1
- data/spec/fixtures/more/cat.rb +5 -3
- data/spec/fixtures/more/event.rb +4 -1
- data/spec/fixtures/more/invoice.rb +2 -2
- data/spec/fixtures/more/person.rb +1 -0
- data/spec/fixtures/more/user.rb +22 -0
- metadata +46 -13
data/README.md
CHANGED
@@ -14,11 +14,6 @@ Note: CouchRest only support CouchDB 0.9.0 or newer.
|
|
14
14
|
|
15
15
|
$ sudo gem install couchrest
|
16
16
|
|
17
|
-
Alternatively, you can install from Github:
|
18
|
-
|
19
|
-
$ gem sources -a http://gems.github.com (you only have to do this once)
|
20
|
-
$ sudo gem install couchrest-couchrest
|
21
|
-
|
22
17
|
### Relax, it's RESTful
|
23
18
|
|
24
19
|
CouchRest rests on top of a HTTP abstraction layer using by default Heroku’s excellent REST Client Ruby HTTP wrapper.
|
@@ -30,136 +25,22 @@ The most complete documentation is the spec/ directory. To validate your
|
|
30
25
|
CouchRest install, from the project root directory run `rake`, or `autotest`
|
31
26
|
(requires RSpec and optionally ZenTest for autotest support).
|
32
27
|
|
33
|
-
##
|
34
|
-
|
35
|
-
Quick Start:
|
36
|
-
|
37
|
-
# with !, it creates the database if it doesn't already exist
|
38
|
-
@db = CouchRest.database!("http://127.0.0.1:5984/couchrest-test")
|
39
|
-
response = @db.save_doc({:key => 'value', 'another key' => 'another value'})
|
40
|
-
doc = @db.get(response['id'])
|
41
|
-
puts doc.inspect
|
42
|
-
|
43
|
-
Bulk Save:
|
44
|
-
|
45
|
-
@db.bulk_save([
|
46
|
-
{"wild" => "and random"},
|
47
|
-
{"mild" => "yet local"},
|
48
|
-
{"another" => ["set","of","keys"]}
|
49
|
-
])
|
50
|
-
# returns ids and revs of the current docs
|
51
|
-
puts @db.documents.inspect
|
52
|
-
|
53
|
-
Creating and Querying Views:
|
54
|
-
|
55
|
-
@db.save_doc({
|
56
|
-
"_id" => "_design/first",
|
57
|
-
:views => {
|
58
|
-
:test => {
|
59
|
-
:map => "function(doc){for(var w in doc){ if(!w.match(/^_/))emit(w,doc[w])}}"
|
60
|
-
}
|
61
|
-
}
|
62
|
-
})
|
63
|
-
puts @db.view('first/test')['rows'].inspect
|
64
|
-
|
65
|
-
|
66
|
-
## CouchRest::ExtendedDocument
|
67
|
-
|
68
|
-
CouchRest::ExtendedDocument is a DSL/ORM for CouchDB. Basically, ExtendedDocument seats on top of CouchRest Core to add the concept of Model.
|
69
|
-
ExtendedDocument offers a lot of the usual ORM tools such as optional yet defined schema, validation, callbacks, pagination, casting and much more.
|
70
|
-
|
71
|
-
### Model example
|
72
|
-
|
73
|
-
Check spec/couchrest/more and spec/fixtures/more for more examples
|
74
|
-
|
75
|
-
class Article < CouchRest::ExtendedDocument
|
76
|
-
use_database DB
|
77
|
-
unique_id :slug
|
78
|
-
|
79
|
-
view_by :date, :descending => true
|
80
|
-
view_by :user_id, :date
|
81
|
-
|
82
|
-
view_by :tags,
|
83
|
-
:map =>
|
84
|
-
"function(doc) {
|
85
|
-
if (doc['couchrest-type'] == 'Article' && doc.tags) {
|
86
|
-
doc.tags.forEach(function(tag){
|
87
|
-
emit(tag, 1);
|
88
|
-
});
|
89
|
-
}
|
90
|
-
}",
|
91
|
-
:reduce =>
|
92
|
-
"function(keys, values, rereduce) {
|
93
|
-
return sum(values);
|
94
|
-
}"
|
28
|
+
## Docs
|
95
29
|
|
96
|
-
|
97
|
-
property :slug, :read_only => true
|
98
|
-
property :title
|
99
|
-
property :tags, :cast_as => ['String']
|
30
|
+
API: [http://rdoc.info/projects/couchrest/couchrest](http://rdoc.info/projects/couchrest/couchrest)
|
100
31
|
|
101
|
-
|
32
|
+
Check the wiki for documentation and examples [http://wiki.github.com/couchrest/couchrest](http://wiki.github.com/couchrest/couchrest)
|
102
33
|
|
103
|
-
|
34
|
+
## Contact
|
104
35
|
|
105
|
-
|
106
|
-
self['slug'] = title.downcase.gsub(/[^a-z0-9]/,'-').squeeze('-').gsub(/^\-|\-$/,'') if new_document?
|
107
|
-
end
|
108
|
-
end
|
36
|
+
Please post bugs, suggestions and patches to the bug tracker at <http://jchris.lighthouseapp.com/projects/17807-couchrest/overview>.
|
109
37
|
|
110
|
-
|
38
|
+
Follow us on Twitter: http://twitter.com/couchrest
|
111
39
|
|
112
|
-
|
113
|
-
`create_callback`, `save_callback`, `update_callback` and `destroy_callback`
|
114
|
-
|
115
|
-
In your document inherits from `CouchRest::ExtendedDocument`, define your callback as follows:
|
116
|
-
|
117
|
-
save_callback :before, :generate_slug_from_name
|
118
|
-
|
119
|
-
CouchRest uses a mixin you can find in lib/mixins/callbacks which is extracted from Rails 3, here are some simple usage examples:
|
120
|
-
|
121
|
-
save_callback :before, :before_method
|
122
|
-
save_callback :after, :after_method, :if => :condition
|
123
|
-
save_callback :around {|r| stuff; yield; stuff }
|
124
|
-
|
125
|
-
Check the mixin or the ExtendedDocument class to see how to implement your own callbacks.
|
126
|
-
|
127
|
-
### Casting
|
128
|
-
|
129
|
-
Often, you will want to store multiple objects within a document, to be able to retrieve your objects when you load the document,
|
130
|
-
you can define some casting rules.
|
131
|
-
|
132
|
-
property :casted_attribute, :cast_as => 'WithCastedModelMixin'
|
133
|
-
property :keywords, :cast_as => ["String"]
|
134
|
-
|
135
|
-
If you want to cast an array of instances from a specific Class, use the trick shown above ["ClassName"]
|
136
|
-
|
137
|
-
### Pagination
|
138
|
-
|
139
|
-
Pagination is available in any ExtendedDocument classes. Here are some usage examples:
|
140
|
-
|
141
|
-
basic usage:
|
142
|
-
|
143
|
-
Article.all.paginate(:page => 1, :per_page => 5)
|
144
|
-
|
145
|
-
note: the above query will look like: `GET /db/_design/Article/_view/all?include_docs=true&skip=0&limit=5&reduce=false` and only fetch 5 documents.
|
146
|
-
|
147
|
-
Slightly more advance usage:
|
148
|
-
|
149
|
-
Article.by_name(:startkey => 'a', :endkey => {}).paginate(:page => 1, :per_page => 5)
|
150
|
-
|
151
|
-
note: the above query will look like: `GET /db/_design/Article/_view/by_name?startkey=%22a%22&limit=5&skip=0&endkey=%7B%7D&include_docs=true`
|
152
|
-
Basically, you can paginate through the articles starting by the letter a, 5 articles at a time.
|
153
|
-
|
154
|
-
|
155
|
-
Low level usage:
|
156
|
-
|
157
|
-
Article.paginate(:design_doc => 'Article', :view_name => 'by_date',
|
158
|
-
:per_page => 3, :page => 2, :descending => true, :key => Date.today, :include_docs => true)
|
159
|
-
|
40
|
+
Also, check http://twitter.com/#search?q=%23couchrest
|
160
41
|
|
161
42
|
## Ruby on Rails
|
162
43
|
|
163
44
|
CouchRest is compatible with rails and can even be used a Rails plugin.
|
164
45
|
However, you might be interested in the CouchRest companion rails project:
|
165
|
-
[http://github.com/hpoydar/couchrest-rails](http://github.com/hpoydar/couchrest-rails)
|
46
|
+
[http://github.com/hpoydar/couchrest-rails](http://github.com/hpoydar/couchrest-rails)
|
data/Rakefile
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
require 'rake'
|
2
2
|
require "rake/rdoctask"
|
3
|
-
require 'rake/gempackagetask'
|
4
3
|
require File.join(File.expand_path(File.dirname(__FILE__)),'lib','couchrest')
|
5
4
|
|
6
|
-
|
7
5
|
begin
|
8
6
|
require 'spec/rake/spectask'
|
9
7
|
rescue LoadError
|
@@ -14,45 +12,31 @@ EOS
|
|
14
12
|
exit(0)
|
15
13
|
end
|
16
14
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
35
|
-
|
36
|
-
|
37
|
-
desc "Create .gemspec file (useful for github)"
|
38
|
-
task :gemspec do
|
39
|
-
filename = "#{spec.name}.gemspec"
|
40
|
-
File.open(filename, "w") do |f|
|
41
|
-
f.puts spec.to_ruby
|
15
|
+
begin
|
16
|
+
require 'jeweler'
|
17
|
+
Jeweler::Tasks.new do |gemspec|
|
18
|
+
gemspec.name = "couchrest"
|
19
|
+
gemspec.summary = "Lean and RESTful interface to CouchDB."
|
20
|
+
gemspec.description = "CouchRest provides a simple interface on top of CouchDB's RESTful HTTP API, as well as including some utility scripts for managing views and attachments."
|
21
|
+
gemspec.email = "jchris@apache.org"
|
22
|
+
gemspec.homepage = "http://github.com/couchrest/couchrest"
|
23
|
+
gemspec.authors = ["J. Chris Anderson", "Matt Aimonetti", "Marcos Tapajos"]
|
24
|
+
gemspec.extra_rdoc_files = %w( README.md LICENSE THANKS.md )
|
25
|
+
gemspec.files = %w( LICENSE README.md Rakefile THANKS.md history.txt) + Dir["{examples,lib,spec,utils}/**/*"] - Dir["spec/tmp"]
|
26
|
+
gemspec.has_rdoc = true
|
27
|
+
gemspec.add_dependency("rest-client", ">= 0.5")
|
28
|
+
gemspec.add_dependency("mime-types", ">= 1.15")
|
29
|
+
gemspec.version = CouchRest::VERSION
|
30
|
+
gemspec.date = "2008-11-22"
|
31
|
+
gemspec.require_path = "lib"
|
42
32
|
end
|
43
|
-
|
44
|
-
|
45
|
-
Rake::GemPackageTask.new(spec) do |pkg|
|
46
|
-
pkg.gem_spec = spec
|
47
|
-
end
|
48
|
-
|
49
|
-
desc "Install the gem locally"
|
50
|
-
task :install => [:package] do
|
51
|
-
sh %{sudo gem install pkg/couchrest-#{CouchRest::VERSION}}
|
33
|
+
rescue LoadError
|
34
|
+
puts "Jeweler not available. Install it with: gem install jeweler"
|
52
35
|
end
|
53
36
|
|
54
37
|
desc "Run all specs"
|
55
38
|
Spec::Rake::SpecTask.new('spec') do |t|
|
39
|
+
t.spec_opts = ["--color"]
|
56
40
|
t.spec_files = FileList['spec/**/*_spec.rb']
|
57
41
|
end
|
58
42
|
|
data/THANKS.md
CHANGED
@@ -12,7 +12,8 @@ changes. A list of these people is included below.
|
|
12
12
|
* [Jonathan S. Katz](http://github.com/jkatz)
|
13
13
|
* [Matt Lyon](http://mattly.tumblr.com/)
|
14
14
|
* Simon Rozet (simon /at/ rozet /dot/ name)
|
15
|
+
* [Marcos Tapajós](http://tapajos.me)
|
15
16
|
|
16
|
-
Patches are welcome. The primary source for this software project is [on Github](http://github.com/
|
17
|
+
Patches are welcome. The primary source for this software project is [on Github](http://github.com/couchrest/couchrest)
|
17
18
|
|
18
19
|
A lot of people have active forks - thank you all - even the patches I don't end up using are helpful.
|
data/history.txt
CHANGED
@@ -1,3 +1,28 @@
|
|
1
|
+
== 0.34
|
2
|
+
|
3
|
+
* Major enhancements
|
4
|
+
|
5
|
+
* Added support for https database URIs. (Mathias Meyer)
|
6
|
+
* Changing some validations to be compatible with activemodel. (Marcos Tapajós)
|
7
|
+
* Adds attribute protection to properties. (Will Leinweber)
|
8
|
+
* Improved CouchRest::Database#save_doc, added "batch" mode to significantly speed up saves at cost of lower durability gurantees. (Igal Koshevoy)
|
9
|
+
* Added CouchRest::Database#bulk_save_doc and #batch_save_doc as human-friendlier wrappers around #save_doc. (Igal Koshevoy)
|
10
|
+
|
11
|
+
* Minor enhancements
|
12
|
+
|
13
|
+
* Fix content_type handling for attachments
|
14
|
+
* Fixed a bug in the pagination code that caused it to paginate over records outside of the scope of the view parameters.(John Wood)
|
15
|
+
* Removed amount_pages calculation for the pagination collection, since it cannot be reliably calculated without a view.(John Wood)
|
16
|
+
* Bug fix: http://github.com/couchrest/couchrest/issues/#issue/2 (Luke Burton)
|
17
|
+
* Bug fix: http://github.com/couchrest/couchrest/issues/#issue/1 (Marcos Tapajós)
|
18
|
+
* Removed the Database class deprecation notices (Matt Aimonetti)
|
19
|
+
* Adding support to :cast_as => 'Date'. (Marcos Tapajós)
|
20
|
+
* Improve documentation (Marcos Tapajós)
|
21
|
+
* Streamer fixes (Julien Sanchez)
|
22
|
+
* Fix Save on Document & ExtendedDocument crashed if bulk (Julien Sanchez)
|
23
|
+
* Fix Initialization of ExtendentDocument model shouldn't failed on a nil value in argument (deepj)
|
24
|
+
* Change to use Jeweler and Gemcutter (Marcos Tapajós)
|
25
|
+
|
1
26
|
== 0.33
|
2
27
|
|
3
28
|
* Major enhancements
|
data/lib/couchrest.rb
CHANGED
@@ -28,7 +28,7 @@ require 'couchrest/monkeypatches'
|
|
28
28
|
|
29
29
|
# = CouchDB, close to the metal
|
30
30
|
module CouchRest
|
31
|
-
VERSION = '0.
|
31
|
+
VERSION = '0.34' unless self.const_defined?("VERSION")
|
32
32
|
|
33
33
|
autoload :Server, 'couchrest/core/server'
|
34
34
|
autoload :Database, 'couchrest/core/database'
|
@@ -48,6 +48,7 @@ module CouchRest
|
|
48
48
|
require File.join(File.dirname(__FILE__), 'couchrest', 'core', 'rest_api')
|
49
49
|
require File.join(File.dirname(__FILE__), 'couchrest', 'core', 'http_abstraction')
|
50
50
|
require File.join(File.dirname(__FILE__), 'couchrest', 'mixins')
|
51
|
+
require File.join(File.dirname(__FILE__), 'couchrest', 'support', 'rails') if defined?(Rails)
|
51
52
|
|
52
53
|
# we extend CouchRest with the RestAPI module which gives us acess to
|
53
54
|
# the get, post, put, delete and copy
|
@@ -95,14 +96,14 @@ module CouchRest
|
|
95
96
|
|
96
97
|
def parse url
|
97
98
|
case url
|
98
|
-
when /^
|
99
|
+
when /^https?:\/\/(.*)\/(.*)\/(.*)/
|
99
100
|
host = $1
|
100
101
|
db = $2
|
101
102
|
docid = $3
|
102
|
-
when /^
|
103
|
+
when /^https?:\/\/(.*)\/(.*)/
|
103
104
|
host = $1
|
104
105
|
db = $2
|
105
|
-
when /^
|
106
|
+
when /^https?:\/\/(.*)/
|
106
107
|
host = $1
|
107
108
|
when /(.*)\/(.*)\/(.*)/
|
108
109
|
host = $1
|
@@ -129,7 +129,7 @@ module CouchRest
|
|
129
129
|
end
|
130
130
|
end
|
131
131
|
end
|
132
|
-
|
132
|
+
|
133
133
|
# Save a document to CouchDB. This will use the <tt>_id</tt> field from
|
134
134
|
# the document as the id for PUT, or request a new UUID from CouchDB, if
|
135
135
|
# no <tt>_id</tt> is present on the document. IDs are attached to
|
@@ -139,13 +139,25 @@ module CouchRest
|
|
139
139
|
#
|
140
140
|
# If <tt>bulk</tt> is true (false by default) the document is cached for bulk-saving later.
|
141
141
|
# Bulk saving happens automatically when #bulk_save_cache limit is exceded, or on the next non bulk save.
|
142
|
-
|
142
|
+
#
|
143
|
+
# If <tt>batch</tt> is true (false by default) the document is saved in
|
144
|
+
# batch mode, "used to achieve higher throughput at the cost of lower
|
145
|
+
# guarantees. When [...] sent using this option, it is not immediately
|
146
|
+
# written to disk. Instead it is stored in memory on a per-user basis for a
|
147
|
+
# second or so (or the number of docs in memory reaches a certain point).
|
148
|
+
# After the threshold has passed, the docs are committed to disk. Instead
|
149
|
+
# of waiting for the doc to be written to disk before responding, CouchDB
|
150
|
+
# sends an HTTP 202 Accepted response immediately. batch=ok is not suitable
|
151
|
+
# for crucial data, but it ideal for applications like logging which can
|
152
|
+
# accept the risk that a small proportion of updates could be lost due to a
|
153
|
+
# crash."
|
154
|
+
def save_doc(doc, bulk = false, batch = false)
|
143
155
|
if doc['_attachments']
|
144
156
|
doc['_attachments'] = encode_attachments(doc['_attachments'])
|
145
157
|
end
|
146
158
|
if bulk
|
147
159
|
@bulk_save_cache << doc
|
148
|
-
|
160
|
+
bulk_save if @bulk_save_cache.length >= @bulk_save_cache_limit
|
149
161
|
return {"ok" => true} # Compatibility with Document#save
|
150
162
|
elsif !bulk && @bulk_save_cache.length > 0
|
151
163
|
bulk_save
|
@@ -153,7 +165,9 @@ module CouchRest
|
|
153
165
|
result = if doc['_id']
|
154
166
|
slug = escape_docid(doc['_id'])
|
155
167
|
begin
|
156
|
-
|
168
|
+
uri = "#{@root}/#{slug}"
|
169
|
+
uri << "?batch=ok" if batch
|
170
|
+
CouchRest.put uri, doc
|
157
171
|
rescue HttpAbstraction::ResourceNotFound
|
158
172
|
p "resource not found when saving even tho an id was passed"
|
159
173
|
slug = doc['_id'] = @server.next_uuid
|
@@ -175,12 +189,15 @@ module CouchRest
|
|
175
189
|
result
|
176
190
|
end
|
177
191
|
|
178
|
-
|
179
|
-
def
|
180
|
-
|
181
|
-
|
192
|
+
# Save a document to CouchDB in bulk mode. See #save_doc's +bulk+ argument.
|
193
|
+
def bulk_save_doc(doc)
|
194
|
+
save_doc(doc, true)
|
195
|
+
end
|
196
|
+
|
197
|
+
# Save a document to CouchDB in batch mode. See #save_doc's +batch+ argument.
|
198
|
+
def batch_save_doc(doc)
|
199
|
+
save_doc(doc, false, true)
|
182
200
|
end
|
183
|
-
|
184
201
|
|
185
202
|
# POST an array of documents to CouchDB. If any of the documents are
|
186
203
|
# missing ids, supply one from the uuid cache.
|
@@ -219,12 +236,6 @@ module CouchRest
|
|
219
236
|
CouchRest.delete "#{@root}/#{slug}?rev=#{doc['_rev']}"
|
220
237
|
end
|
221
238
|
|
222
|
-
### DEPRECATION NOTICE
|
223
|
-
def delete(doc, bulk=false)
|
224
|
-
puts "CouchRest::Database's delete method is being deprecated, please use delete_doc instead"
|
225
|
-
delete_doc(doc, bulk)
|
226
|
-
end
|
227
|
-
|
228
239
|
# COPY an existing document to a new id. If the destination id currently exists, a rev must be provided.
|
229
240
|
# <tt>dest</tt> can take one of two forms if overwriting: "id_to_overwrite?rev=revision" or the actual doc
|
230
241
|
# hash with a '_rev' key
|
@@ -239,12 +250,6 @@ module CouchRest
|
|
239
250
|
CouchRest.copy "#{@root}/#{slug}", destination
|
240
251
|
end
|
241
252
|
|
242
|
-
### DEPRECATION NOTICE
|
243
|
-
def copy(doc, dest)
|
244
|
-
puts "CouchRest::Database's copy method is being deprecated, please use copy_doc instead"
|
245
|
-
copy_doc(doc, dest)
|
246
|
-
end
|
247
|
-
|
248
253
|
# Compact the database, removing old document revisions and optimizing space use.
|
249
254
|
def compact!
|
250
255
|
CouchRest.post "#{@root}/_compact"
|
@@ -23,9 +23,10 @@ module CouchRest
|
|
23
23
|
end
|
24
24
|
|
25
25
|
# returns true if the document has never been saved
|
26
|
-
def
|
26
|
+
def new?
|
27
27
|
!rev
|
28
28
|
end
|
29
|
+
alias :new_document? :new?
|
29
30
|
|
30
31
|
# Saves the document to the db using create or update. Also runs the :save
|
31
32
|
# callbacks. Sets the <tt>_id</tt> and <tt>_rev</tt> fields based on
|
@@ -63,8 +64,8 @@ module CouchRest
|
|
63
64
|
|
64
65
|
# Returns the CouchDB uri for the document
|
65
66
|
def uri(append_rev = false)
|
66
|
-
return nil if
|
67
|
-
couch_uri = "
|
67
|
+
return nil if new?
|
68
|
+
couch_uri = "#{database.root}/#{CGI.escape(id)}"
|
68
69
|
if append_rev == true
|
69
70
|
couch_uri << "?rev=#{rev}"
|
70
71
|
elsif append_rev.kind_of?(Integer)
|
@@ -7,15 +7,22 @@ module CouchRest
|
|
7
7
|
|
8
8
|
# Stream a view, yielding one row at a time. Shells out to <tt>curl</tt> to keep RAM usage low when you have millions of rows.
|
9
9
|
def view name, params = nil, &block
|
10
|
-
urlst = /^_/.match(name)
|
10
|
+
urlst = if /^_/.match(name) then
|
11
|
+
"#{@db.root}/#{name}"
|
12
|
+
else
|
13
|
+
name = name.split('/')
|
14
|
+
dname = name.shift
|
15
|
+
vname = name.join('/')
|
16
|
+
"#{@db.root}/_design/#{dname}/_view/#{vname}"
|
17
|
+
end
|
11
18
|
url = CouchRest.paramify_url urlst, params
|
12
19
|
# puts "stream #{url}"
|
13
20
|
first = nil
|
14
|
-
IO.popen("curl --silent #{url}") do |view|
|
21
|
+
IO.popen("curl --silent \"#{url}\"") do |view|
|
15
22
|
first = view.gets # discard header
|
16
23
|
while line = view.gets
|
17
24
|
row = parse_line(line)
|
18
|
-
block.call row
|
25
|
+
block.call row unless row.nil? # last line "}]" discarded
|
19
26
|
end
|
20
27
|
end
|
21
28
|
parse_first(first)
|
@@ -41,4 +48,4 @@ module CouchRest
|
|
41
48
|
end
|
42
49
|
|
43
50
|
end
|
44
|
-
end
|
51
|
+
end
|