couchrest 0.37 → 0.38
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +4 -4
- data/Rakefile +2 -1
- data/couchrest.gemspec +7 -4
- data/history.txt +8 -0
- data/lib/couchrest.rb +2 -2
- data/lib/couchrest/core/database.rb +12 -12
- data/lib/couchrest/core/rest_api.rb +13 -6
- data/lib/couchrest/core/server.rb +2 -0
- data/spec/couchrest/core/couchrest_spec.rb +8 -1
- data/spec/couchrest/core/database_spec.rb +73 -43
- metadata +23 -4
data/README.md
CHANGED
@@ -8,7 +8,7 @@ to CouchDB's API endpoints so you don't have to.
|
|
8
8
|
|
9
9
|
CouchRest is designed to make a simple base for application and framework-specific object oriented APIs. CouchRest is Object-Mapper agnostic, the parsed JSON it returns from CouchDB shows up as subclasses of Ruby's Hash. Naked JSON, just as it was mean to be.
|
10
10
|
|
11
|
-
Note: CouchRest only support CouchDB 0.9.0 or newer.
|
11
|
+
**Note: CouchRest only support CouchDB 0.9.0 or newer. Some features requires CouchDB 0.10.0 or newer.**
|
12
12
|
|
13
13
|
## Easy Install
|
14
14
|
|
@@ -33,11 +33,11 @@ Check the wiki for documentation and examples [http://wiki.github.com/couchrest/
|
|
33
33
|
|
34
34
|
## Contact
|
35
35
|
|
36
|
-
Please post bugs, suggestions and patches to the bug tracker at
|
36
|
+
Please post bugs, suggestions and patches to the bug tracker at [http://github.com/couchrest/couchrest/issues](http://github.com/couchrest/couchrest/issues).
|
37
37
|
|
38
|
-
Follow us on Twitter: http://twitter.com/couchrest
|
38
|
+
Follow us on Twitter: [http://twitter.com/couchrest](http://twitter.com/couchrest)
|
39
39
|
|
40
|
-
Also, check http://twitter.com/#search?q=%23couchrest
|
40
|
+
Also, check [http://twitter.com/#search?q=%23couchrest](http://twitter.com/#search?q=%23couchrest)
|
41
41
|
|
42
42
|
## Ruby on Rails
|
43
43
|
|
data/Rakefile
CHANGED
@@ -26,8 +26,9 @@ begin
|
|
26
26
|
gemspec.has_rdoc = true
|
27
27
|
gemspec.add_dependency("rest-client", ">= 0.5")
|
28
28
|
gemspec.add_dependency("mime-types", ">= 1.15")
|
29
|
+
gemspec.add_dependency("json", "1.2.4")
|
29
30
|
gemspec.version = CouchRest::VERSION
|
30
|
-
gemspec.date = "
|
31
|
+
gemspec.date = Time.now.strftime("%Y-%m-%d")
|
31
32
|
gemspec.require_path = "lib"
|
32
33
|
end
|
33
34
|
rescue LoadError
|
data/couchrest.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{couchrest}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.38"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["J. Chris Anderson", "Matt Aimonetti", "Marcos Tapajos", "Will Leinweber"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-07-28}
|
13
13
|
s.description = %q{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.}
|
14
14
|
s.email = %q{jchris@apache.org}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -127,7 +127,7 @@ Gem::Specification.new do |s|
|
|
127
127
|
s.homepage = %q{http://github.com/couchrest/couchrest}
|
128
128
|
s.rdoc_options = ["--charset=UTF-8"]
|
129
129
|
s.require_paths = ["lib"]
|
130
|
-
s.rubygems_version = %q{1.3.
|
130
|
+
s.rubygems_version = %q{1.3.7}
|
131
131
|
s.summary = %q{Lean and RESTful interface to CouchDB.}
|
132
132
|
s.test_files = [
|
133
133
|
"spec/couchrest/core/couchrest_spec.rb",
|
@@ -167,16 +167,19 @@ Gem::Specification.new do |s|
|
|
167
167
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
168
168
|
s.specification_version = 3
|
169
169
|
|
170
|
-
if Gem::Version.new(Gem::
|
170
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
171
171
|
s.add_runtime_dependency(%q<rest-client>, [">= 0.5"])
|
172
172
|
s.add_runtime_dependency(%q<mime-types>, [">= 1.15"])
|
173
|
+
s.add_runtime_dependency(%q<json>, ["= 1.2.4"])
|
173
174
|
else
|
174
175
|
s.add_dependency(%q<rest-client>, [">= 0.5"])
|
175
176
|
s.add_dependency(%q<mime-types>, [">= 1.15"])
|
177
|
+
s.add_dependency(%q<json>, ["= 1.2.4"])
|
176
178
|
end
|
177
179
|
else
|
178
180
|
s.add_dependency(%q<rest-client>, [">= 0.5"])
|
179
181
|
s.add_dependency(%q<mime-types>, [">= 1.15"])
|
182
|
+
s.add_dependency(%q<json>, ["= 1.2.4"])
|
180
183
|
end
|
181
184
|
end
|
182
185
|
|
data/history.txt
CHANGED
@@ -4,6 +4,14 @@
|
|
4
4
|
|
5
5
|
* Minor enhancements
|
6
6
|
|
7
|
+
== 0.38
|
8
|
+
|
9
|
+
* Major enhancements
|
10
|
+
* Add create_target option to Database#replicate_to and #replicate_from. http://github.com/couchrest/couchrest/issues/#issue/26 (Alexander Uvarov)
|
11
|
+
|
12
|
+
* Minor enhancements
|
13
|
+
* Support for CouchDB 1.0
|
14
|
+
|
7
15
|
== 0.37
|
8
16
|
|
9
17
|
* Minor 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.38' unless self.const_defined?("VERSION")
|
32
32
|
|
33
33
|
autoload :Server, 'couchrest/core/server'
|
34
34
|
autoload :Database, 'couchrest/core/database'
|
@@ -159,4 +159,4 @@ module CouchRest
|
|
159
159
|
url
|
160
160
|
end
|
161
161
|
end # class << self
|
162
|
-
end
|
162
|
+
end
|
@@ -65,7 +65,7 @@ module CouchRest
|
|
65
65
|
keys = params.delete(:keys)
|
66
66
|
funcs = funcs.merge({:keys => keys}) if keys
|
67
67
|
url = CouchRest.paramify_url "#{@root}/_temp_view", params
|
68
|
-
|
68
|
+
CouchRest.post(url, funcs)
|
69
69
|
end
|
70
70
|
|
71
71
|
# backwards compatibility is a plus
|
@@ -115,7 +115,7 @@ module CouchRest
|
|
115
115
|
def put_attachment(doc, name, file, options = {})
|
116
116
|
docid = escape_docid(doc['_id'])
|
117
117
|
uri = url_for_attachment(doc, name)
|
118
|
-
JSON.parse(HttpAbstraction.put(uri, file, options))
|
118
|
+
JSON.parse(HttpAbstraction.put(uri, file, CouchRest.default_headers.update(options)))
|
119
119
|
end
|
120
120
|
|
121
121
|
# DELETE an attachment directly from CouchDB
|
@@ -123,13 +123,13 @@ module CouchRest
|
|
123
123
|
uri = url_for_attachment(doc, name)
|
124
124
|
# this needs a rev
|
125
125
|
begin
|
126
|
-
|
126
|
+
CouchRest.delete(uri)
|
127
127
|
rescue Exception => error
|
128
128
|
if force
|
129
129
|
# get over a 409
|
130
130
|
doc = get(doc['_id'])
|
131
131
|
uri = url_for_attachment(doc, name)
|
132
|
-
|
132
|
+
CouchRest.delete(uri)
|
133
133
|
else
|
134
134
|
error
|
135
135
|
end
|
@@ -302,17 +302,17 @@ module CouchRest
|
|
302
302
|
ensure
|
303
303
|
create!
|
304
304
|
end
|
305
|
-
|
305
|
+
|
306
306
|
# Replicates via "pulling" from another database to this database. Makes no attempt to deal with conflicts.
|
307
|
-
def replicate_from
|
308
|
-
replicate
|
307
|
+
def replicate_from(other_db, continuous = false, create_target = false)
|
308
|
+
replicate(other_db, continuous, :target => name, :create_target => create_target)
|
309
309
|
end
|
310
|
-
|
310
|
+
|
311
311
|
# Replicates via "pushing" to another database. Makes no attempt to deal with conflicts.
|
312
|
-
def replicate_to
|
313
|
-
replicate
|
312
|
+
def replicate_to(other_db, continuous = false, create_target = false)
|
313
|
+
replicate(other_db, continuous, :source => name, :create_target => create_target)
|
314
314
|
end
|
315
|
-
|
315
|
+
|
316
316
|
# DELETE the database itself. This is not undoable and could be rather
|
317
317
|
# catastrophic. Use with care!
|
318
318
|
def delete!
|
@@ -322,7 +322,7 @@ module CouchRest
|
|
322
322
|
|
323
323
|
private
|
324
324
|
|
325
|
-
def replicate
|
325
|
+
def replicate(other_db, continuous, options)
|
326
326
|
raise ArgumentError, "must provide a CouchReset::Database" unless other_db.kind_of?(CouchRest::Database)
|
327
327
|
raise ArgumentError, "must provide a target or source option" unless (options.key?(:target) || options.key?(:source))
|
328
328
|
payload = options
|
@@ -1,9 +1,16 @@
|
|
1
1
|
module RestAPI
|
2
2
|
|
3
|
+
def default_headers
|
4
|
+
{
|
5
|
+
:content_type => :json,
|
6
|
+
:accept => :json
|
7
|
+
}
|
8
|
+
end
|
9
|
+
|
3
10
|
def put(uri, doc = nil)
|
4
11
|
payload = doc.to_json if doc
|
5
12
|
begin
|
6
|
-
JSON.parse(HttpAbstraction.put(uri, payload))
|
13
|
+
JSON.parse(HttpAbstraction.put(uri, payload, default_headers))
|
7
14
|
rescue Exception => e
|
8
15
|
if $DEBUG
|
9
16
|
raise "Error while sending a PUT request #{uri}\npayload: #{payload.inspect}\n#{e}"
|
@@ -15,7 +22,7 @@ module RestAPI
|
|
15
22
|
|
16
23
|
def get(uri)
|
17
24
|
begin
|
18
|
-
JSON.parse(HttpAbstraction.get(uri), :max_nesting => false)
|
25
|
+
JSON.parse(HttpAbstraction.get(uri, default_headers), :max_nesting => false)
|
19
26
|
rescue => e
|
20
27
|
if $DEBUG
|
21
28
|
raise "Error while sending a GET request #{uri}\n: #{e}"
|
@@ -28,7 +35,7 @@ module RestAPI
|
|
28
35
|
def post(uri, doc = nil)
|
29
36
|
payload = doc.to_json if doc
|
30
37
|
begin
|
31
|
-
JSON.parse(HttpAbstraction.post(uri, payload))
|
38
|
+
JSON.parse(HttpAbstraction.post(uri, payload, default_headers))
|
32
39
|
rescue Exception => e
|
33
40
|
if $DEBUG
|
34
41
|
raise "Error while sending a POST request #{uri}\npayload: #{payload.inspect}\n#{e}"
|
@@ -39,11 +46,11 @@ module RestAPI
|
|
39
46
|
end
|
40
47
|
|
41
48
|
def delete(uri)
|
42
|
-
JSON.parse(HttpAbstraction.delete(uri))
|
49
|
+
JSON.parse(HttpAbstraction.delete(uri, default_headers))
|
43
50
|
end
|
44
51
|
|
45
52
|
def copy(uri, destination)
|
46
|
-
JSON.parse(HttpAbstraction.copy(uri,
|
53
|
+
JSON.parse(HttpAbstraction.copy(uri, default_headers.merge('Destination' => destination)))
|
47
54
|
end
|
48
55
|
|
49
|
-
end
|
56
|
+
end
|
@@ -73,6 +73,8 @@ module CouchRest
|
|
73
73
|
# Restart the CouchDB instance
|
74
74
|
def restart!
|
75
75
|
CouchRest.post "#{@uri}/_restart"
|
76
|
+
rescue RestClient::ServerBrokeConnection
|
77
|
+
# Shouldn't really happen, but does in CouchDB 1.0.0
|
76
78
|
end
|
77
79
|
|
78
80
|
# Retrive an unused UUID from CouchDB. Server instances manage caching a list of unused UUIDs.
|
@@ -28,6 +28,13 @@ describe CouchRest do
|
|
28
28
|
|
29
29
|
it "should restart" do
|
30
30
|
@cr.restart!
|
31
|
+
begin
|
32
|
+
@cr.info
|
33
|
+
rescue
|
34
|
+
# Give the couchdb time to restart
|
35
|
+
sleep 0.2
|
36
|
+
retry
|
37
|
+
end
|
31
38
|
end
|
32
39
|
|
33
40
|
it "should provide one-time access to uuids" do
|
@@ -181,4 +188,4 @@ describe CouchRest do
|
|
181
188
|
end
|
182
189
|
end
|
183
190
|
|
184
|
-
end
|
191
|
+
end
|
@@ -702,81 +702,111 @@ describe CouchRest::Database do
|
|
702
702
|
@cr.databases.should_not include('couchrest-test')
|
703
703
|
end
|
704
704
|
end
|
705
|
-
|
705
|
+
|
706
706
|
describe "simply replicating a database" do
|
707
|
-
before do
|
707
|
+
before(:each) do
|
708
708
|
@db.save_doc({'_id' => 'test_doc', 'some-value' => 'foo'})
|
709
|
-
@other_db = @cr.database
|
710
|
-
@other_db.delete! rescue nil
|
711
|
-
@other_db = @cr.create_db REPLICATIONDB
|
709
|
+
@other_db = @cr.database(REPLICATIONDB)
|
712
710
|
end
|
713
711
|
|
714
|
-
|
715
|
-
before do
|
716
|
-
@other_db.replicate_from @db
|
717
|
-
end
|
718
|
-
|
712
|
+
shared_examples_for "simply replicated" do
|
719
713
|
it "contains the document from the original database" do
|
720
714
|
doc = @other_db.get('test_doc')
|
721
715
|
doc['some-value'].should == 'foo'
|
722
716
|
end
|
723
717
|
end
|
724
|
-
|
718
|
+
|
719
|
+
describe "via pulling" do
|
720
|
+
before(:each) do
|
721
|
+
@other_db.recreate!
|
722
|
+
@other_db.replicate_from @db
|
723
|
+
end
|
724
|
+
|
725
|
+
it_should_behave_like "simply replicated"
|
726
|
+
end
|
727
|
+
|
725
728
|
describe "via pushing" do
|
726
|
-
before do
|
729
|
+
before(:each) do
|
730
|
+
@other_db.recreate!
|
727
731
|
@db.replicate_to @other_db
|
728
732
|
end
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
+
|
734
|
+
it_should_behave_like "simply replicated"
|
735
|
+
end
|
736
|
+
|
737
|
+
describe "implicitly creating target" do
|
738
|
+
describe "via pulling" do
|
739
|
+
before(:each) do
|
740
|
+
@other_db.replicate_from(@db, false, true)
|
741
|
+
end
|
742
|
+
|
743
|
+
it_should_behave_like "simply replicated"
|
744
|
+
end
|
745
|
+
|
746
|
+
describe "via pushing" do
|
747
|
+
before(:each) do
|
748
|
+
@db.replicate_to(@other_db, false, true)
|
749
|
+
end
|
750
|
+
|
751
|
+
it_should_behave_like "simply replicated"
|
733
752
|
end
|
734
753
|
end
|
735
754
|
end
|
736
|
-
|
755
|
+
|
737
756
|
describe "continuously replicating a database" do
|
738
|
-
before do
|
757
|
+
before(:each) do
|
739
758
|
@db.save_doc({'_id' => 'test_doc', 'some-value' => 'foo'})
|
740
|
-
@other_db = @cr.database
|
741
|
-
@other_db.delete! rescue nil
|
742
|
-
@other_db = @cr.create_db REPLICATIONDB
|
759
|
+
@other_db = @cr.database(REPLICATIONDB)
|
743
760
|
end
|
744
761
|
|
745
|
-
|
746
|
-
before do
|
747
|
-
@other_db.replicate_from @db, true
|
748
|
-
end
|
749
|
-
|
762
|
+
shared_examples_for "continuously replicated" do
|
750
763
|
it "contains the document from the original database" do
|
751
|
-
sleep(1) # Allow some time to replicate
|
764
|
+
sleep(1.5) # Allow some time to replicate
|
752
765
|
doc = @other_db.get('test_doc')
|
753
766
|
doc['some-value'].should == 'foo'
|
754
767
|
end
|
755
|
-
|
768
|
+
|
756
769
|
it "contains documents saved after replication initiated" do
|
757
770
|
@db.save_doc({'_id' => 'test_doc_after', 'some-value' => 'bar'})
|
758
|
-
sleep(1) # Allow some time to replicate
|
771
|
+
sleep(1.5) # Allow some time to replicate
|
759
772
|
doc = @other_db.get('test_doc_after')
|
760
773
|
doc['some-value'].should == 'bar'
|
761
774
|
end
|
762
775
|
end
|
763
|
-
|
776
|
+
|
777
|
+
describe "via pulling" do
|
778
|
+
before(:each) do
|
779
|
+
@other_db.recreate!
|
780
|
+
@other_db.replicate_from(@db, true)
|
781
|
+
end
|
782
|
+
|
783
|
+
it_should_behave_like "continuously replicated"
|
784
|
+
end
|
785
|
+
|
764
786
|
describe "via pushing" do
|
765
|
-
before do
|
766
|
-
@
|
787
|
+
before(:each) do
|
788
|
+
@other_db.recreate!
|
789
|
+
@db.replicate_to(@other_db, true)
|
767
790
|
end
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
791
|
+
|
792
|
+
it_should_behave_like "continuously replicated"
|
793
|
+
end
|
794
|
+
|
795
|
+
describe "implicitly creating target" do
|
796
|
+
before(:each) do
|
797
|
+
@other_db.replicate_from(@db, true, true)
|
773
798
|
end
|
774
|
-
|
775
|
-
|
776
|
-
@
|
777
|
-
|
778
|
-
|
779
|
-
|
799
|
+
|
800
|
+
after(:each) do
|
801
|
+
@other_db.delete!
|
802
|
+
end
|
803
|
+
|
804
|
+
describe "via pulling" do
|
805
|
+
it_should_behave_like "continuously replicated"
|
806
|
+
end
|
807
|
+
|
808
|
+
describe "via pushing" do
|
809
|
+
it_should_behave_like "continuously replicated"
|
780
810
|
end
|
781
811
|
end
|
782
812
|
end
|
metadata
CHANGED
@@ -4,8 +4,8 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
version: "0.
|
7
|
+
- 38
|
8
|
+
version: "0.38"
|
9
9
|
platform: ruby
|
10
10
|
authors:
|
11
11
|
- J. Chris Anderson
|
@@ -16,13 +16,14 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2010-
|
19
|
+
date: 2010-07-28 00:00:00 -03:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
23
23
|
name: rest-client
|
24
24
|
prerelease: false
|
25
25
|
requirement: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
26
27
|
requirements:
|
27
28
|
- - ">="
|
28
29
|
- !ruby/object:Gem::Version
|
@@ -36,6 +37,7 @@ dependencies:
|
|
36
37
|
name: mime-types
|
37
38
|
prerelease: false
|
38
39
|
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
39
41
|
requirements:
|
40
42
|
- - ">="
|
41
43
|
- !ruby/object:Gem::Version
|
@@ -45,6 +47,21 @@ dependencies:
|
|
45
47
|
version: "1.15"
|
46
48
|
type: :runtime
|
47
49
|
version_requirements: *id002
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
name: json
|
52
|
+
prerelease: false
|
53
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - "="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
segments:
|
59
|
+
- 1
|
60
|
+
- 2
|
61
|
+
- 4
|
62
|
+
version: 1.2.4
|
63
|
+
type: :runtime
|
64
|
+
version_requirements: *id003
|
48
65
|
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.
|
49
66
|
email: jchris@apache.org
|
50
67
|
executables: []
|
@@ -171,6 +188,7 @@ rdoc_options:
|
|
171
188
|
require_paths:
|
172
189
|
- lib
|
173
190
|
required_ruby_version: !ruby/object:Gem::Requirement
|
191
|
+
none: false
|
174
192
|
requirements:
|
175
193
|
- - ">="
|
176
194
|
- !ruby/object:Gem::Version
|
@@ -178,6 +196,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
178
196
|
- 0
|
179
197
|
version: "0"
|
180
198
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
199
|
+
none: false
|
181
200
|
requirements:
|
182
201
|
- - ">="
|
183
202
|
- !ruby/object:Gem::Version
|
@@ -187,7 +206,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
187
206
|
requirements: []
|
188
207
|
|
189
208
|
rubyforge_project:
|
190
|
-
rubygems_version: 1.3.
|
209
|
+
rubygems_version: 1.3.7
|
191
210
|
signing_key:
|
192
211
|
specification_version: 3
|
193
212
|
summary: Lean and RESTful interface to CouchDB.
|