couchrest 1.0.0.beta2 → 1.0.0.beta3
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +5 -3
- data/couchrest.gemspec +6 -6
- data/history.txt +4 -0
- data/lib/couchrest.rb +7 -4
- data/lib/couchrest/database.rb +5 -5
- data/lib/couchrest/design.rb +1 -1
- data/lib/couchrest/document.rb +6 -1
- data/lib/couchrest/monkeypatches.rb +0 -1
- data/lib/couchrest/rest_api.rb +12 -5
- data/lib/couchrest/server.rb +2 -0
- data/lib/couchrest/support/inheritable_attributes.rb +107 -0
- data/spec/couchrest/couchrest_spec.rb +8 -1
- data/spec/couchrest/database_spec.rb +3 -3
- data/spec/couchrest/design_spec.rb +21 -1
- data/spec/couchrest/document_spec.rb +4 -0
- data/spec/couchrest/server_spec.rb +1 -1
- data/spec/spec_helper.rb +2 -2
- metadata +9 -9
- data/lib/couchrest/support/class.rb +0 -190
data/Rakefile
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'rake'
|
2
2
|
require "rake/rdoctask"
|
3
|
-
|
3
|
+
|
4
|
+
$LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
|
5
|
+
require 'couchrest'
|
4
6
|
|
5
7
|
begin
|
6
8
|
require 'spec/rake/spectask'
|
@@ -25,7 +27,7 @@ begin
|
|
25
27
|
gemspec.files = %w( LICENSE README.md Rakefile THANKS.md history.txt couchrest.gemspec) + Dir["{examples,lib,spec,utils}/**/*"] - Dir["spec/tmp"]
|
26
28
|
gemspec.has_rdoc = true
|
27
29
|
gemspec.add_dependency("rest-client", ">= 1.5.1")
|
28
|
-
gemspec.add_dependency("json", "
|
30
|
+
gemspec.add_dependency("json", "= 1.2.4") # json 1.4.3 has stack overflow issues!
|
29
31
|
# gemspec.add_dependency("couchrest_extended_document", ">= 1.0.0")
|
30
32
|
gemspec.version = CouchRest::VERSION
|
31
33
|
gemspec.date = "2010-07-01"
|
@@ -65,4 +67,4 @@ module Rake
|
|
65
67
|
end
|
66
68
|
|
67
69
|
Rake.remove_task("github:release")
|
68
|
-
Rake.remove_task("release")
|
70
|
+
Rake.remove_task("release")
|
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 = "1.0.0.
|
8
|
+
s.version = "1.0.0.beta3"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") 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-07-
|
12
|
+
s.date = %q{2010-07-25}
|
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 = [
|
@@ -49,7 +49,7 @@ Gem::Specification.new do |s|
|
|
49
49
|
"lib/couchrest/response.rb",
|
50
50
|
"lib/couchrest/rest_api.rb",
|
51
51
|
"lib/couchrest/server.rb",
|
52
|
-
"lib/couchrest/support/
|
52
|
+
"lib/couchrest/support/inheritable_attributes.rb",
|
53
53
|
"spec/couchrest/couchrest_spec.rb",
|
54
54
|
"spec/couchrest/database_spec.rb",
|
55
55
|
"spec/couchrest/design_spec.rb",
|
@@ -95,14 +95,14 @@ Gem::Specification.new do |s|
|
|
95
95
|
|
96
96
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
97
97
|
s.add_runtime_dependency(%q<rest-client>, [">= 1.5.1"])
|
98
|
-
s.add_runtime_dependency(%q<json>, ["
|
98
|
+
s.add_runtime_dependency(%q<json>, ["= 1.2.4"])
|
99
99
|
else
|
100
100
|
s.add_dependency(%q<rest-client>, [">= 1.5.1"])
|
101
|
-
s.add_dependency(%q<json>, ["
|
101
|
+
s.add_dependency(%q<json>, ["= 1.2.4"])
|
102
102
|
end
|
103
103
|
else
|
104
104
|
s.add_dependency(%q<rest-client>, [">= 1.5.1"])
|
105
|
-
s.add_dependency(%q<json>, ["
|
105
|
+
s.add_dependency(%q<json>, ["= 1.2.4"])
|
106
106
|
end
|
107
107
|
end
|
108
108
|
|
data/history.txt
CHANGED
@@ -2,8 +2,12 @@
|
|
2
2
|
|
3
3
|
* Major enhancements
|
4
4
|
* Add create_target option to Database#replicate_to and #replicate_from. http://github.com/couchrest/couchrest/issues/#issue/26 (Alexander Uvarov)
|
5
|
+
* Removing unused core extensions and moving extlib_inhertiable_* methods to use couchrest_inheritable_*
|
6
|
+
to avoid conflicts with Rails. (Geoff Buesing)
|
5
7
|
|
6
8
|
* Minor enhancements
|
9
|
+
* Added Document#id= support (issue detected by Rory Franklin with RSpec model stubs)
|
10
|
+
* Fixing issues with CouchDB 1.0 and RestClient
|
7
11
|
|
8
12
|
== 1.0.0.beta
|
9
13
|
|
data/lib/couchrest.rb
CHANGED
@@ -13,9 +13,11 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
15
|
require 'rubygems'
|
16
|
-
gem 'json', "<= 1.4.2"
|
17
|
-
require 'json'
|
18
16
|
gem 'rest-client', ">= 1.5.1"
|
17
|
+
unless Kernel.const_defined?("JSON")
|
18
|
+
gem 'json', '1.2.4'
|
19
|
+
require 'json'
|
20
|
+
end
|
19
21
|
require 'rest_client'
|
20
22
|
|
21
23
|
# Not sure why this is required, so removed until a reason is found!
|
@@ -25,10 +27,11 @@ $:.unshift File.dirname(__FILE__) unless
|
|
25
27
|
|
26
28
|
require 'couchrest/monkeypatches'
|
27
29
|
require 'couchrest/rest_api'
|
30
|
+
require 'couchrest/support/inheritable_attributes'
|
28
31
|
|
29
32
|
# = CouchDB, close to the metal
|
30
33
|
module CouchRest
|
31
|
-
VERSION = '1.0.0.
|
34
|
+
VERSION = '1.0.0.beta3'
|
32
35
|
|
33
36
|
autoload :Server, 'couchrest/server'
|
34
37
|
autoload :Database, 'couchrest/database'
|
@@ -134,4 +137,4 @@ class CouchRest::ExtendedDocument < CouchRest::Document
|
|
134
137
|
raise "ExtendedDocument is no longer included in CouchRest base driver, see couchrest_extended_document gem"
|
135
138
|
end
|
136
139
|
|
137
|
-
end
|
140
|
+
end
|
data/lib/couchrest/database.rb
CHANGED
@@ -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
|
-
JSON.parse(RestClient.post(url, funcs.to_json,
|
68
|
+
JSON.parse(RestClient.post(url, funcs.to_json, CouchRest.default_headers))
|
69
69
|
end
|
70
70
|
|
71
71
|
# backwards compatibility is a plus
|
@@ -108,14 +108,14 @@ module CouchRest
|
|
108
108
|
# GET an attachment directly from CouchDB
|
109
109
|
def fetch_attachment(doc, name)
|
110
110
|
uri = url_for_attachment(doc, name)
|
111
|
-
RestClient.get uri
|
111
|
+
RestClient.get uri, CouchRest.default_headers
|
112
112
|
end
|
113
113
|
|
114
114
|
# PUT an attachment directly to CouchDB
|
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(RestClient.put(uri, file, options))
|
118
|
+
JSON.parse(RestClient.put(uri, file, CouchRest.default_headers.merge(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
|
data/lib/couchrest/design.rb
CHANGED
@@ -18,7 +18,7 @@ module CouchRest
|
|
18
18
|
doc_keys = keys.collect{|k|"doc['#{k}']"} # this is where :require => 'doc.x == true' would show up
|
19
19
|
key_emit = doc_keys.length == 1 ? "#{doc_keys.first}" : "[#{doc_keys.join(', ')}]"
|
20
20
|
guards = opts.delete(:guards) || []
|
21
|
-
guards.
|
21
|
+
guards += doc_keys.map{|k| "(#{k} != null)"}
|
22
22
|
map_function = <<-JAVASCRIPT
|
23
23
|
function(doc) {
|
24
24
|
if (#{guards.join(' && ')}) {
|
data/lib/couchrest/document.rb
CHANGED
@@ -3,8 +3,9 @@ require 'delegate'
|
|
3
3
|
module CouchRest
|
4
4
|
class Document < Response
|
5
5
|
include CouchRest::Attachments
|
6
|
+
extend CouchRest::InheritableAttributes
|
6
7
|
|
7
|
-
|
8
|
+
couchrest_inheritable_accessor :database
|
8
9
|
attr_accessor :database
|
9
10
|
|
10
11
|
# override the CouchRest::Model-wide default_database
|
@@ -17,6 +18,10 @@ module CouchRest
|
|
17
18
|
def id
|
18
19
|
self['_id']
|
19
20
|
end
|
21
|
+
|
22
|
+
def id=(id)
|
23
|
+
self['_id'] = id
|
24
|
+
end
|
20
25
|
|
21
26
|
def rev
|
22
27
|
self['_rev']
|
data/lib/couchrest/rest_api.rb
CHANGED
@@ -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(RestClient.put(uri, payload))
|
13
|
+
JSON.parse(RestClient.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(RestClient.get(uri), :max_nesting => false)
|
25
|
+
JSON.parse(RestClient.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(RestClient.post(uri, payload))
|
38
|
+
JSON.parse(RestClient.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,13 +46,13 @@ module RestAPI
|
|
39
46
|
end
|
40
47
|
|
41
48
|
def delete(uri)
|
42
|
-
JSON.parse(RestClient.delete(uri))
|
49
|
+
JSON.parse(RestClient.delete(uri, default_headers))
|
43
50
|
end
|
44
51
|
|
45
52
|
def copy(uri, destination)
|
46
53
|
JSON.parse(RestClient::Request.execute( :method => :copy,
|
47
54
|
:url => uri,
|
48
|
-
:headers =>
|
55
|
+
:headers => default_headers.merge('Destination' => destination)
|
49
56
|
).to_s)
|
50
57
|
end
|
51
58
|
|
data/lib/couchrest/server.rb
CHANGED
@@ -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.
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# Copyright (c) 2006-2009 David Heinemeier Hansson
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
# a copy of this software and associated documentation files (the
|
5
|
+
# "Software"), to deal in the Software without restriction, including
|
6
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
# the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be
|
12
|
+
# included in all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
#
|
22
|
+
# Extracted From
|
23
|
+
# http://github.com/rails/rails/commit/971e2438d98326c994ec6d3ef8e37b7e868ed6e2
|
24
|
+
|
25
|
+
module CouchRest
|
26
|
+
module InheritableAttributes
|
27
|
+
|
28
|
+
# Defines class-level inheritable attribute reader. Attributes are available to subclasses,
|
29
|
+
# each subclass has a copy of parent's attribute.
|
30
|
+
#
|
31
|
+
# @param *syms<Array[#to_s]> Array of attributes to define inheritable reader for.
|
32
|
+
# @return <Array[#to_s]> Array of attributes converted into inheritable_readers.
|
33
|
+
#
|
34
|
+
# @api public
|
35
|
+
#
|
36
|
+
# @todo Do we want to block instance_reader via :instance_reader => false
|
37
|
+
# @todo It would be preferable that we do something with a Hash passed in
|
38
|
+
# (error out or do the same as other methods above) instead of silently
|
39
|
+
# moving on). In particular, this makes the return value of this function
|
40
|
+
# less useful.
|
41
|
+
def couchrest_inheritable_reader(*ivars)
|
42
|
+
instance_reader = ivars.pop[:reader] if ivars.last.is_a?(Hash)
|
43
|
+
|
44
|
+
ivars.each do |ivar|
|
45
|
+
self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
46
|
+
def self.#{ivar}
|
47
|
+
return @#{ivar} if self.object_id == #{self.object_id} || defined?(@#{ivar})
|
48
|
+
ivar = superclass.#{ivar}
|
49
|
+
return nil if ivar.nil? && !#{self}.instance_variable_defined?("@#{ivar}")
|
50
|
+
@#{ivar} = ivar && !ivar.is_a?(Module) && !ivar.is_a?(Numeric) && !ivar.is_a?(TrueClass) && !ivar.is_a?(FalseClass) ? ivar.dup : ivar
|
51
|
+
end
|
52
|
+
RUBY
|
53
|
+
unless instance_reader == false
|
54
|
+
self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
55
|
+
def #{ivar}
|
56
|
+
self.class.#{ivar}
|
57
|
+
end
|
58
|
+
RUBY
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Defines class-level inheritable attribute writer. Attributes are available to subclasses,
|
64
|
+
# each subclass has a copy of parent's attribute.
|
65
|
+
#
|
66
|
+
# @param *syms<Array[*#to_s, Hash{:instance_writer => Boolean}]> Array of attributes to
|
67
|
+
# define inheritable writer for.
|
68
|
+
# @option syms :instance_writer<Boolean> if true, instance-level inheritable attribute writer is defined.
|
69
|
+
# @return <Array[#to_s]> An Array of the attributes that were made into inheritable writers.
|
70
|
+
#
|
71
|
+
# @api public
|
72
|
+
#
|
73
|
+
# @todo We need a style for class_eval <<-HEREDOC. I'd like to make it
|
74
|
+
# class_eval(<<-RUBY, __FILE__, __LINE__), but we should codify it somewhere.
|
75
|
+
def couchrest_inheritable_writer(*ivars)
|
76
|
+
instance_writer = ivars.pop[:writer] if ivars.last.is_a?(Hash)
|
77
|
+
ivars.each do |ivar|
|
78
|
+
self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
79
|
+
def self.#{ivar}=(obj)
|
80
|
+
@#{ivar} = obj
|
81
|
+
end
|
82
|
+
RUBY
|
83
|
+
unless instance_writer == false
|
84
|
+
self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
85
|
+
def #{ivar}=(obj) self.class.#{ivar} = obj end
|
86
|
+
RUBY
|
87
|
+
end
|
88
|
+
|
89
|
+
self.send("#{ivar}=", yield) if block_given?
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Defines class-level inheritable attribute accessor. Attributes are available to subclasses,
|
94
|
+
# each subclass has a copy of parent's attribute.
|
95
|
+
#
|
96
|
+
# @param *syms<Array[*#to_s, Hash{:instance_writer => Boolean}]> Array of attributes to
|
97
|
+
# define inheritable accessor for.
|
98
|
+
# @option syms :instance_writer<Boolean> if true, instance-level inheritable attribute writer is defined.
|
99
|
+
# @return <Array[#to_s]> An Array of attributes turned into inheritable accessors.
|
100
|
+
#
|
101
|
+
# @api public
|
102
|
+
def couchrest_inheritable_accessor(*syms, &block)
|
103
|
+
couchrest_inheritable_reader(*syms)
|
104
|
+
couchrest_inheritable_writer(*syms, &block)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -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
|
@@ -137,7 +144,7 @@ describe CouchRest do
|
|
137
144
|
|
138
145
|
describe "ensuring the db exists" do
|
139
146
|
it "should be super easy" do
|
140
|
-
db = CouchRest.database! "
|
147
|
+
db = CouchRest.database! "#{COUCHHOST}/couchrest-test-2"
|
141
148
|
db.name.should == 'couchrest-test-2'
|
142
149
|
db.info["db_name"].should == 'couchrest-test-2'
|
143
150
|
end
|
@@ -180,7 +180,7 @@ describe CouchRest::Database do
|
|
180
180
|
|
181
181
|
docs = [{'key' => 'value'}, {'_id' => 'totally-uniq'}]
|
182
182
|
id_docs = [{'key' => 'value', '_id' => 'asdf6sgadkfhgsdfusdf'}, {'_id' => 'totally-uniq'}]
|
183
|
-
CouchRest.should_receive(:post).with("
|
183
|
+
CouchRest.should_receive(:post).with("#{COUCHHOST}/couchrest-test/_bulk_docs", {:docs => id_docs})
|
184
184
|
|
185
185
|
@db.bulk_save(docs)
|
186
186
|
end
|
@@ -761,14 +761,14 @@ describe CouchRest::Database do
|
|
761
761
|
|
762
762
|
shared_examples_for "continuously replicated" do
|
763
763
|
it "contains the document from the original database" do
|
764
|
-
sleep(1) # Allow some time to replicate
|
764
|
+
sleep(1.5) # Allow some time to replicate
|
765
765
|
doc = @other_db.get('test_doc')
|
766
766
|
doc['some-value'].should == 'foo'
|
767
767
|
end
|
768
768
|
|
769
769
|
it "contains documents saved after replication initiated" do
|
770
770
|
@db.save_doc({'_id' => 'test_doc_after', 'some-value' => 'bar'})
|
771
|
-
sleep(1) # Allow some time to replicate
|
771
|
+
sleep(1.5) # Allow some time to replicate
|
772
772
|
doc = @other_db.get('test_doc_after')
|
773
773
|
doc['some-value'].should == 'bar'
|
774
774
|
end
|
@@ -134,5 +134,25 @@ describe CouchRest::Design do
|
|
134
134
|
res["rows"].first["key"].should == ["a",2]
|
135
135
|
end
|
136
136
|
end
|
137
|
-
|
137
|
+
|
138
|
+
describe "a view with nil and 0 values" do
|
139
|
+
before(:all) do
|
140
|
+
@db = reset_test_db!
|
141
|
+
@des = CouchRest::Design.new
|
142
|
+
@des.name = "test"
|
143
|
+
@des.view_by :code
|
144
|
+
@des.database = @db
|
145
|
+
@des.save
|
146
|
+
@db.bulk_save([{"code" => "a", "age" => 2},
|
147
|
+
{"code" => nil, "age" => 4},{"code" => 0, "age" => 9}])
|
148
|
+
end
|
149
|
+
it "should work" do
|
150
|
+
res = @des.view :by_code
|
151
|
+
res["rows"][0]["key"].should == 0
|
152
|
+
res["rows"][1]["key"].should == "a"
|
153
|
+
res["rows"][2].should be_nil
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
|
138
158
|
end
|
@@ -62,6 +62,10 @@ describe CouchRest::Document do
|
|
62
62
|
@doc.rev.should be_nil
|
63
63
|
@doc.id.should be_nil
|
64
64
|
end
|
65
|
+
it "should be possible to set id" do
|
66
|
+
@doc.id = 1
|
67
|
+
@doc.id.should eql(1)
|
68
|
+
end
|
65
69
|
|
66
70
|
it "should freak out when saving without a database" do
|
67
71
|
lambda{@doc.save}.should raise_error(ArgumentError)
|
data/spec/spec_helper.rb
CHANGED
@@ -8,10 +8,10 @@ unless defined?(FIXTURE_PATH)
|
|
8
8
|
FIXTURE_PATH = File.join(File.dirname(__FILE__), '/fixtures')
|
9
9
|
SCRATCH_PATH = File.join(File.dirname(__FILE__), '/tmp')
|
10
10
|
|
11
|
-
COUCHHOST = "http://127.0.0.1:5984"
|
11
|
+
COUCHHOST = ENV['COUCHHOST'] || "http://127.0.0.1:5984"
|
12
12
|
TESTDB = 'couchrest-test'
|
13
13
|
REPLICATIONDB = 'couchrest-test-replication'
|
14
|
-
TEST_SERVER = CouchRest.new
|
14
|
+
TEST_SERVER = CouchRest.new COUCHHOST
|
15
15
|
TEST_SERVER.default_database = TESTDB
|
16
16
|
DB = TEST_SERVER.database(TESTDB)
|
17
17
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: couchrest
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash: -
|
4
|
+
hash: -1848230053
|
5
5
|
prerelease: true
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 0
|
9
9
|
- 0
|
10
|
-
-
|
11
|
-
version: 1.0.0.
|
10
|
+
- beta3
|
11
|
+
version: 1.0.0.beta3
|
12
12
|
platform: ruby
|
13
13
|
authors:
|
14
14
|
- J. Chris Anderson
|
@@ -19,7 +19,7 @@ autorequire:
|
|
19
19
|
bindir: bin
|
20
20
|
cert_chain: []
|
21
21
|
|
22
|
-
date: 2010-07-
|
22
|
+
date: 2010-07-25 00:00:00 -03:00
|
23
23
|
default_executable:
|
24
24
|
dependencies:
|
25
25
|
- !ruby/object:Gem::Dependency
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirement: &id002 !ruby/object:Gem::Requirement
|
45
45
|
none: false
|
46
46
|
requirements:
|
47
|
-
- -
|
47
|
+
- - "="
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
hash:
|
49
|
+
hash: 23
|
50
50
|
segments:
|
51
51
|
- 1
|
52
|
-
- 4
|
53
52
|
- 2
|
54
|
-
|
53
|
+
- 4
|
54
|
+
version: 1.2.4
|
55
55
|
type: :runtime
|
56
56
|
version_requirements: *id002
|
57
57
|
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.
|
@@ -96,7 +96,7 @@ files:
|
|
96
96
|
- lib/couchrest/response.rb
|
97
97
|
- lib/couchrest/rest_api.rb
|
98
98
|
- lib/couchrest/server.rb
|
99
|
-
- lib/couchrest/support/
|
99
|
+
- lib/couchrest/support/inheritable_attributes.rb
|
100
100
|
- spec/couchrest/couchrest_spec.rb
|
101
101
|
- spec/couchrest/database_spec.rb
|
102
102
|
- spec/couchrest/design_spec.rb
|
@@ -1,190 +0,0 @@
|
|
1
|
-
# Copyright (c) 2006-2009 David Heinemeier Hansson
|
2
|
-
#
|
3
|
-
# Permission is hereby granted, free of charge, to any person obtaining
|
4
|
-
# a copy of this software and associated documentation files (the
|
5
|
-
# "Software"), to deal in the Software without restriction, including
|
6
|
-
# without limitation the rights to use, copy, modify, merge, publish,
|
7
|
-
# distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
-
# permit persons to whom the Software is furnished to do so, subject to
|
9
|
-
# the following conditions:
|
10
|
-
#
|
11
|
-
# The above copyright notice and this permission notice shall be
|
12
|
-
# included in all copies or substantial portions of the Software.
|
13
|
-
#
|
14
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
-
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
-
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
-
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
-
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
-
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
-
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
-
#
|
22
|
-
# Extracted From
|
23
|
-
# http://github.com/rails/rails/commit/971e2438d98326c994ec6d3ef8e37b7e868ed6e2
|
24
|
-
|
25
|
-
# Extends the class object with class and instance accessors for class attributes,
|
26
|
-
# just like the native attr* accessors for instance attributes.
|
27
|
-
#
|
28
|
-
# class Person
|
29
|
-
# cattr_accessor :hair_colors
|
30
|
-
# end
|
31
|
-
#
|
32
|
-
# Person.hair_colors = [:brown, :black, :blonde, :red]
|
33
|
-
class Class
|
34
|
-
def cattr_reader(*syms)
|
35
|
-
syms.flatten.each do |sym|
|
36
|
-
next if sym.is_a?(Hash)
|
37
|
-
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
38
|
-
unless defined? @@#{sym} # unless defined? @@hair_colors
|
39
|
-
@@#{sym} = nil # @@hair_colors = nil
|
40
|
-
end # end
|
41
|
-
#
|
42
|
-
def self.#{sym} # def self.hair_colors
|
43
|
-
@@#{sym} # @@hair_colors
|
44
|
-
end # end
|
45
|
-
#
|
46
|
-
def #{sym} # def hair_colors
|
47
|
-
@@#{sym} # @@hair_colors
|
48
|
-
end # end
|
49
|
-
EOS
|
50
|
-
end
|
51
|
-
end unless Class.respond_to?(:cattr_reader)
|
52
|
-
|
53
|
-
def cattr_writer(*syms)
|
54
|
-
options = syms.extract_options!
|
55
|
-
syms.flatten.each do |sym|
|
56
|
-
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
57
|
-
unless defined? @@#{sym} # unless defined? @@hair_colors
|
58
|
-
@@#{sym} = nil # @@hair_colors = nil
|
59
|
-
end # end
|
60
|
-
#
|
61
|
-
def self.#{sym}=(obj) # def self.hair_colors=(obj)
|
62
|
-
@@#{sym} = obj # @@hair_colors = obj
|
63
|
-
end # end
|
64
|
-
#
|
65
|
-
#{" #
|
66
|
-
def #{sym}=(obj) # def hair_colors=(obj)
|
67
|
-
@@#{sym} = obj # @@hair_colors = obj
|
68
|
-
end # end
|
69
|
-
" unless options[:instance_writer] == false } # # instance writer above is generated unless options[:instance_writer] == false
|
70
|
-
EOS
|
71
|
-
end
|
72
|
-
end unless Class.respond_to?(:cattr_writer)
|
73
|
-
|
74
|
-
def cattr_accessor(*syms)
|
75
|
-
cattr_reader(*syms)
|
76
|
-
cattr_writer(*syms)
|
77
|
-
end unless Class.respond_to?(:cattr_accessor)
|
78
|
-
|
79
|
-
# Defines class-level inheritable attribute reader. Attributes are available to subclasses,
|
80
|
-
# each subclass has a copy of parent's attribute.
|
81
|
-
#
|
82
|
-
# @param *syms<Array[#to_s]> Array of attributes to define inheritable reader for.
|
83
|
-
# @return <Array[#to_s]> Array of attributes converted into inheritable_readers.
|
84
|
-
#
|
85
|
-
# @api public
|
86
|
-
#
|
87
|
-
# @todo Do we want to block instance_reader via :instance_reader => false
|
88
|
-
# @todo It would be preferable that we do something with a Hash passed in
|
89
|
-
# (error out or do the same as other methods above) instead of silently
|
90
|
-
# moving on). In particular, this makes the return value of this function
|
91
|
-
# less useful.
|
92
|
-
def extlib_inheritable_reader(*ivars)
|
93
|
-
instance_reader = ivars.pop[:reader] if ivars.last.is_a?(Hash)
|
94
|
-
|
95
|
-
ivars.each do |ivar|
|
96
|
-
self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
97
|
-
def self.#{ivar}
|
98
|
-
return @#{ivar} if self.object_id == #{self.object_id} || defined?(@#{ivar})
|
99
|
-
ivar = superclass.#{ivar}
|
100
|
-
return nil if ivar.nil? && !#{self}.instance_variable_defined?("@#{ivar}")
|
101
|
-
@#{ivar} = ivar && !ivar.is_a?(Module) && !ivar.is_a?(Numeric) && !ivar.is_a?(TrueClass) && !ivar.is_a?(FalseClass) ? ivar.dup : ivar
|
102
|
-
end
|
103
|
-
RUBY
|
104
|
-
unless instance_reader == false
|
105
|
-
self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
106
|
-
def #{ivar}
|
107
|
-
self.class.#{ivar}
|
108
|
-
end
|
109
|
-
RUBY
|
110
|
-
end
|
111
|
-
end
|
112
|
-
end unless Class.respond_to?(:extlib_inheritable_reader)
|
113
|
-
|
114
|
-
# Defines class-level inheritable attribute writer. Attributes are available to subclasses,
|
115
|
-
# each subclass has a copy of parent's attribute.
|
116
|
-
#
|
117
|
-
# @param *syms<Array[*#to_s, Hash{:instance_writer => Boolean}]> Array of attributes to
|
118
|
-
# define inheritable writer for.
|
119
|
-
# @option syms :instance_writer<Boolean> if true, instance-level inheritable attribute writer is defined.
|
120
|
-
# @return <Array[#to_s]> An Array of the attributes that were made into inheritable writers.
|
121
|
-
#
|
122
|
-
# @api public
|
123
|
-
#
|
124
|
-
# @todo We need a style for class_eval <<-HEREDOC. I'd like to make it
|
125
|
-
# class_eval(<<-RUBY, __FILE__, __LINE__), but we should codify it somewhere.
|
126
|
-
def extlib_inheritable_writer(*ivars)
|
127
|
-
instance_writer = ivars.pop[:writer] if ivars.last.is_a?(Hash)
|
128
|
-
ivars.each do |ivar|
|
129
|
-
self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
130
|
-
def self.#{ivar}=(obj)
|
131
|
-
@#{ivar} = obj
|
132
|
-
end
|
133
|
-
RUBY
|
134
|
-
unless instance_writer == false
|
135
|
-
self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
136
|
-
def #{ivar}=(obj) self.class.#{ivar} = obj end
|
137
|
-
RUBY
|
138
|
-
end
|
139
|
-
|
140
|
-
self.send("#{ivar}=", yield) if block_given?
|
141
|
-
end
|
142
|
-
end unless Class.respond_to?(:extlib_inheritable_writer)
|
143
|
-
|
144
|
-
# Defines class-level inheritable attribute accessor. Attributes are available to subclasses,
|
145
|
-
# each subclass has a copy of parent's attribute.
|
146
|
-
#
|
147
|
-
# @param *syms<Array[*#to_s, Hash{:instance_writer => Boolean}]> Array of attributes to
|
148
|
-
# define inheritable accessor for.
|
149
|
-
# @option syms :instance_writer<Boolean> if true, instance-level inheritable attribute writer is defined.
|
150
|
-
# @return <Array[#to_s]> An Array of attributes turned into inheritable accessors.
|
151
|
-
#
|
152
|
-
# @api public
|
153
|
-
def extlib_inheritable_accessor(*syms, &block)
|
154
|
-
extlib_inheritable_reader(*syms)
|
155
|
-
extlib_inheritable_writer(*syms, &block)
|
156
|
-
end unless Class.respond_to?(:extlib_inheritable_accessor)
|
157
|
-
end
|
158
|
-
|
159
|
-
class Array
|
160
|
-
# Extracts options from a set of arguments. Removes and returns the last
|
161
|
-
# element in the array if it's a hash, otherwise returns a blank hash.
|
162
|
-
#
|
163
|
-
# def options(*args)
|
164
|
-
# args.extract_options!
|
165
|
-
# end
|
166
|
-
#
|
167
|
-
# options(1, 2) # => {}
|
168
|
-
# options(1, 2, :a => :b) # => {:a=>:b}
|
169
|
-
def extract_options!
|
170
|
-
last.is_a?(::Hash) ? pop : {}
|
171
|
-
end unless Array.new.respond_to?(:extract_options!)
|
172
|
-
|
173
|
-
# Wraps the object in an Array unless it's an Array. Converts the
|
174
|
-
# object to an Array using #to_ary if it implements that.
|
175
|
-
def self.wrap(object)
|
176
|
-
case object
|
177
|
-
when nil
|
178
|
-
[]
|
179
|
-
when self
|
180
|
-
object
|
181
|
-
else
|
182
|
-
if object.respond_to?(:to_ary)
|
183
|
-
object.to_ary
|
184
|
-
else
|
185
|
-
[object]
|
186
|
-
end
|
187
|
-
end
|
188
|
-
end unless Array.respond_to?(:wrap)
|
189
|
-
end
|
190
|
-
|