couchrest 2.0.0.rc3 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 47b17f1a8431dbf297df05649b3e3ef50da87ec5
4
- data.tar.gz: d6c33fc6dfd9651d3cafb18d75a91a363542026f
3
+ metadata.gz: 35f90529f40322cb4c79feff70763d46e7feb0b0
4
+ data.tar.gz: 9cb8ed603d0898f37d1ebafeb23fa00204eaea62
5
5
  SHA512:
6
- metadata.gz: c690201c7ca0cde422405fc26e1399e18d0b98c435cfb6ca37e38fb2dd194351f06188930ebe805fd7201fb5f089dbde9df1fea1f12913c8ecf0be8f602ef4c9
7
- data.tar.gz: 0d012252eb5d4a89302d2f069d76b855763aba3e65d6a17dbfe6f78b2d129ff381211ed96d08250ae6bef6edea8224983a03245db5bf06b0851af8a777bb5d35
6
+ metadata.gz: e927060a2d0c42fd94f761b7f4f161c6627738c92c51de6bf483b9ebbce3527ab165420eb54a3a1c0e9f447d8f1cfc3323b70a05e87a761bac387472bd8c3b3e
7
+ data.tar.gz: 431046aa57a718f9c2d9a1c966cf060b1123f49dff147ccd8a272b39ab1df5c59d8c038dc41c8d5f9cb6f84783c21e8c6abd380fbcca00b6999d5bee8754b460
data/.gitignore CHANGED
@@ -5,3 +5,4 @@ pkg
5
5
  *.gem
6
6
  Gemfile.lock
7
7
  *.rvmrc
8
+ .bundle
data/.travis.yml CHANGED
@@ -3,9 +3,10 @@ rvm:
3
3
  - 2.2.0
4
4
  - 2.1.0
5
5
  - 2.0.0
6
- - 1.9.3
7
6
  - jruby
8
7
  - rbx
9
8
  services: couchdb
10
9
  before_install:
11
10
  - gem install bundler
11
+ env:
12
+ - JRUBY_OPTS=--2.0
data/Rakefile CHANGED
@@ -1,7 +1,5 @@
1
- # encoding: utf-8
2
- require 'bundler'
3
- Bundler::GemHelper.install_tasks
4
1
 
2
+ require 'bundler/gem_tasks'
5
3
  require 'rspec/core/rake_task'
6
4
 
7
5
  desc 'Default: run unit tests.'
@@ -12,12 +10,3 @@ RSpec::Core::RakeTask.new do |t|
12
10
  t.pattern = 'spec/**/*_spec.rb'
13
11
  t.rspec_opts = ["-c", "-f progress"]
14
12
  end
15
-
16
- module Rake
17
- def self.remove_task(task_name)
18
- Rake.application.instance_variable_get('@tasks').delete(task_name.to_s)
19
- end
20
- end
21
-
22
- Rake.remove_task("github:release")
23
- Rake.remove_task("release")
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.0.0.rc3
1
+ 2.0.0
data/couchrest.gemspec CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
9
9
  s.authors = ["J. Chris Anderson", "Matt Aimonetti", "Marcos Tapajos", "Will Leinweber", "Sam Lown"]
10
10
  s.date = File.mtime('VERSION')
11
11
  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.}
12
- s.email = %q{jchris@apache.org}
12
+ s.email = %q{me@samlown.com}
13
13
 
14
14
  s.files = `git ls-files`.split("\n")
15
15
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -21,18 +21,19 @@ Gem::Specification.new do |s|
21
21
  "README.md",
22
22
  "THANKS.md"
23
23
  ]
24
+
24
25
  s.homepage = %q{http://github.com/couchrest/couchrest}
25
26
  s.rdoc_options = ["--charset=UTF-8"]
26
27
  s.require_paths = ["lib"]
27
- s.rubygems_version = %q{1.3.7}
28
28
  s.summary = %q{Lean and RESTful interface to CouchDB.}
29
29
 
30
- s.add_dependency("httpclient", ["~> 2.7"])
31
- s.add_dependency("mime-types", [">= 1.15"])
32
- s.add_dependency("multi_json", ["~> 1.7"])
33
- s.add_development_dependency("json", [">= 1.7.0"])
34
- s.add_development_dependency("rspec", "~> 2.14.1")
35
- s.add_development_dependency("rake")
36
- s.add_development_dependency("webmock")
37
- s.add_development_dependency("mime-types", "2.6.2") # Avoid Errors with 3.0 series
30
+ s.add_dependency "httpclient", ["~> 2.8"]
31
+ s.add_dependency "multi_json", ["~> 1.7"]
32
+ s.add_dependency "mime-types", [">= 1.15"]
33
+
34
+ s.add_development_dependency "bundler", "~> 1.3"
35
+ # s.add_development_dependency "json", ">= 2.0.1"
36
+ s.add_development_dependency "rspec", "~> 2.14.1"
37
+ s.add_development_dependency "rake"
38
+ s.add_development_dependency "webmock"
38
39
  end
data/history.txt CHANGED
@@ -1,4 +1,14 @@
1
- == 2.0.0.rc3
1
+ == 2.0.0 - 2016-07-06
2
+
3
+ * Minor changes
4
+ * Update the revisions when bulk saving (@ellneal)
5
+ * Pass connection options via Server, with improved connection caching (@samlown)
6
+ * Support for disabling persistent connections (@samlown)
7
+ * Escaping database names (@samlown)
8
+ * Upgrading to HTTPClient 2.8 series (@samlown)
9
+ * Removing Ruby < 2.0 support (@samlown)
10
+
11
+ == 2.0.0.rc3 - 2016-01-08
2
12
 
3
13
  * Major Changes
4
14
  * At the risk of causing chaos, `Database#get` now returns nil for 404 (@samlown)
@@ -12,10 +12,10 @@ module CouchRest
12
12
  module Attributes
13
13
  extend Forwardable
14
14
 
15
- # Initialize a new CouchRest Document and prepare
15
+ # Initialize a new CouchRest Document and prepare
16
16
  # a hidden attributes hash.
17
17
  #
18
- # When inherting a Document, it is essential that the
18
+ # When inherting a Document, it is essential that the
19
19
  # super method is called before you own changes to ensure
20
20
  # that the attributes hash has been initialized before
21
21
  # you attempt to use it.
@@ -34,9 +34,15 @@ module CouchRest
34
34
  def [](key)
35
35
  _attributes[key.to_s]
36
36
  end
37
- def has_key?(key)
37
+ # key? is preferred over has_key?
38
+ def key?(key)
38
39
  _attributes.has_key?(key.to_s)
39
40
  end
41
+ # has_key? is deprecated for Hash, key? replaces it
42
+ # https://github.com/bbatsov/ruby-style-guide#hash-key
43
+ def has_key?(key)
44
+ key?(key)
45
+ end
40
46
  def delete(key)
41
47
  _attributes.delete(key.to_s)
42
48
  end
@@ -5,30 +5,30 @@ module CouchRest
5
5
  # Handle connections to the CouchDB server and provide a set of HTTP based methods to
6
6
  # perform requests.
7
7
  #
8
- # All connection are persistent. A connection cannot be re-used to connect to other servers.
8
+ # All connections are persistent, unless configured otherwise. A connection cannot be re-used to connect to other servers.
9
9
  #
10
10
  # Six types of REST requests are supported: get, put, post, delete, copy and head.
11
11
  #
12
- # Requests that do not have a payload, get, delete and copy, accept the URI and options parameters,
13
- # where as put and post both expect a document as the second parameter.
12
+ # Requests that do not have a payload like GET, DELETE and COPY, accept the URI and options parameters.
13
+ # PUT and POST both expect a document as the second parameter.
14
14
  #
15
- # The API will share the options between the Net::HTTP connection and JSON parser.
15
+ # The API will share the options between the HTTP connection and JSON parser.
16
16
  #
17
- # The following options will be recognised as header options and automatically added
18
- # to the header hash:
17
+ # When initializing a connection, the following options are available:
19
18
  #
20
- # * `:content_type`, type of content to be sent, especially useful when sending files as this will set the file type. The default is :json.
21
- # * `:accept`, the content type to accept in the response. This should pretty much always be `:json`.
22
- #
23
- # The following request options are supported:
24
- #
25
- # * `:payload` override the document or data sent in the message body (only PUT or POST).
26
- # * `:headers` any additional headers (overrides :content_type and :accept)
19
+ # * `:persistent` true by default, forces the HTTP connection to be persistent to ensure each request attempts to use the same TCP socket, especially important for SSL connections.
27
20
  # * `:timeout` (or `:read_timeout`) and `:open_timeout` the time in miliseconds to wait for the request, see the [Net HTTP Persistent documentation](http://docs.seattlerb.org/net-http-persistent/Net/HTTP/Persistent.html#attribute-i-read_timeout) for more details.
28
21
  # * `:verify_ssl` verify ssl certificates (or not)
29
22
  # * `:ssl_client_cert`, `:ssl_client_key` parameters controlling ssl client certificate authentication
30
23
  # * `:ssl_ca_file` load additional CA certificates from a file (or directory)
31
24
  #
25
+ # The following request options are supported:
26
+ #
27
+ # * `:content_type`, type of content to be sent, especially useful when sending files as this will set the file type. The default is :json.
28
+ # * `:accept`, the content type to accept in the response. This should pretty much always be `:json`.
29
+ # * `:payload` override the document or data sent in the message body (only PUT or POST).
30
+ # * `:headers` any additional headers (overrides :content_type and :accept if provided).
31
+ #
32
32
  # When :raw is true in PUT and POST requests, no attempt will be made to convert the document payload to JSON. This is
33
33
  # not normally necessary as IO and Tempfile objects will not be parsed anyway. The result of the request will
34
34
  # *always* be parsed.
@@ -54,12 +54,13 @@ module CouchRest
54
54
 
55
55
  SUCCESS_RESPONSE_CODES = [200, 201, 202, 204]
56
56
 
57
- attr_reader :uri, :http, :last_response
57
+ attr_reader :uri, :last_response, :options
58
58
 
59
59
  def initialize(uri, options = {})
60
60
  raise "CouchRest::Connection.new requires URI::HTTP(S) parameter" unless uri.is_a?(URI::HTTP)
61
61
  @uri = clean_uri(uri)
62
- prepare_http_connection(options)
62
+ @options = options.dup
63
+ @options[:persistent] = true if @options[:persistent].nil?
63
64
  end
64
65
 
65
66
  # Send a GET request.
@@ -96,6 +97,12 @@ module CouchRest
96
97
  execute('HEAD', path, options)
97
98
  end
98
99
 
100
+ # Special accessor that will either return the last used http
101
+ # connection or prepare a new one if none available.
102
+ def http
103
+ @http || prepare_http_connection
104
+ end
105
+
99
106
  protected
100
107
 
101
108
  # Duplicate and remove excess baggage from the provided URI
@@ -108,33 +115,42 @@ module CouchRest
108
115
  end
109
116
 
110
117
  # Take a look at the options povided and try to apply them to the HTTP conneciton.
111
- # We try to maintain RestClient compatability as this is what we used before.
112
- def prepare_http_connection(opts)
113
- @http = HTTPClient.new(opts[:proxy] || self.class.proxy)
118
+ def prepare_http_connection
119
+ conn = @http
120
+ if conn.nil? || !options[:persistent]
121
+ conn = HTTPClient.new(options[:proxy] || self.class.proxy)
122
+ set_http_connection_options(conn, options)
123
+ @http = conn # Always set to last used connection
124
+ end
125
+ conn
126
+ end
114
127
 
128
+ # Prepare the http connection options for HTTPClient.
129
+ # We try to maintain RestClient compatability in option names as this is what we used before.
130
+ def set_http_connection_options(conn, opts)
115
131
  # Authentication
116
132
  unless uri.user.to_s.empty?
117
- http.force_basic_auth = true
118
- http.set_auth(uri.to_s, uri.user, uri.password)
133
+ conn.force_basic_auth = true
134
+ conn.set_auth(uri.to_s, uri.user, uri.password)
119
135
  end
120
136
 
121
137
  # SSL Certificate option mapping
122
138
  if opts.include?(:verify_ssl)
123
- http.ssl_config.verify_mode = opts[:verify_ssl] ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
139
+ conn.ssl_config.verify_mode = opts[:verify_ssl] ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
124
140
  end
125
- http.ssl_config.client_cert = opts[:ssl_client_cert] if opts.include?(:ssl_client_cert)
126
- http.ssl_config.client_key = opts[:ssl_client_key] if opts.include?(:ssl_client_key)
127
- http.ssl_config.set_trust_ca(opts[:ssl_ca_file]) if opts.include?(:ssl_ca_file)
141
+ conn.ssl_config.client_cert = opts[:ssl_client_cert] if opts.include?(:ssl_client_cert)
142
+ conn.ssl_config.client_key = opts[:ssl_client_key] if opts.include?(:ssl_client_key)
143
+ conn.ssl_config.set_trust_ca(opts[:ssl_ca_file]) if opts.include?(:ssl_ca_file)
128
144
 
129
145
  # Timeout options
130
- http.receive_timeout = opts[:timeout] if opts.include?(:timeout)
131
- http.connect_timeout = opts[:open_timeout] if opts.include?(:open_timeout)
132
- http.send_timeout = opts[:read_timeout] if opts.include?(:read_timeout)
133
-
134
- http
146
+ conn.receive_timeout = opts[:timeout] if opts.include?(:timeout)
147
+ conn.connect_timeout = opts[:open_timeout] if opts.include?(:open_timeout)
148
+ conn.send_timeout = opts[:read_timeout] if opts.include?(:read_timeout)
135
149
  end
136
150
 
137
151
  def execute(method, path, options, payload = nil, &block)
152
+ conn = prepare_http_connection
153
+
138
154
  req = {
139
155
  :method => method,
140
156
  :uri => uri + path
@@ -151,29 +167,29 @@ module CouchRest
151
167
  req[:body] = payload_from_doc(req, payload, options)
152
168
  end
153
169
 
154
- send_and_parse_response(req, options, &block)
170
+ send_and_parse_response(conn, req, options, &block)
155
171
  end
156
172
 
157
- def send_and_parse_response(req, options, &block)
173
+ def send_and_parse_response(conn, req, opts, &block)
158
174
  if block_given?
159
- parser = CouchRest::StreamRowParser.new(options[:continuous] ? :feed : :array)
160
- response = send_request(req) do |chunk|
175
+ parser = CouchRest::StreamRowParser.new(opts[:continuous] ? :feed : :array)
176
+ response = send_request(conn, req) do |chunk|
161
177
  parser.parse(chunk) do |doc|
162
- block.call(parse_body(doc, options))
178
+ block.call(parse_body(doc, opts))
163
179
  end
164
180
  end
165
181
  handle_response_code(response)
166
- parse_body(parser.header, options)
182
+ parse_body(parser.header, opts)
167
183
  else
168
- response = send_request(req)
184
+ response = send_request(conn, req)
169
185
  handle_response_code(response)
170
- parse_response(response, options)
186
+ parse_response(response, opts)
171
187
  end
172
188
  end
173
189
 
174
190
  # Send request, and leave a reference to the response for debugging purposes
175
- def send_request(req, &block)
176
- @last_response = http.request(req.delete(:method), req.delete(:uri), req, &block)
191
+ def send_request(conn, req, &block)
192
+ @last_response = conn.request(req.delete(:method), req.delete(:uri), req, &block)
177
193
  end
178
194
 
179
195
  def handle_response_code(response)
@@ -26,7 +26,7 @@ module CouchRest
26
26
  def initialize(server, name)
27
27
  @name = name
28
28
  @server = server
29
- @path = "/#{name.gsub('/','%2F')}"
29
+ @path = "/#{CGI.escape(name)}"
30
30
  @bulk_save_cache = []
31
31
  @bulk_save_cache_limit = 500 # must be smaller than the uuid count
32
32
  end
@@ -202,7 +202,10 @@ module CouchRest
202
202
  if opts[:all_or_nothing]
203
203
  request_body[:all_or_nothing] = true
204
204
  end
205
- connection.post "#{path}/_bulk_docs", request_body
205
+ results = connection.post "#{path}/_bulk_docs", request_body
206
+ docs_by_id = Hash[docs.map { |doc| [doc['_id'], doc] }] unless docs.nil?
207
+ results.each { |r| docs_by_id[r['id']]['_rev'] = r['rev'] if r['ok'] } unless results.nil?
208
+ results
206
209
  end
207
210
  alias :bulk_delete :bulk_save
208
211
 
@@ -12,15 +12,27 @@ module CouchRest
12
12
  # saving new documents. See also #next_uuid.
13
13
  attr_reader :uuids
14
14
 
15
- def initialize(server = 'http://127.0.0.1:5984', uuid_batch_count = 1000)
15
+ # The connection options we should use to connect with
16
+ attr_reader :connection_options
17
+
18
+ def initialize(server = 'http://127.0.0.1:5984', opts = {})
16
19
  @uri = prepare_uri(server).freeze
17
- @uuid_batch_count = uuid_batch_count
20
+ if opts.is_a?(Integer)
21
+ # Backwards compatibility
22
+ @uuid_batch_count = opts
23
+ @connection_options = {}
24
+ else
25
+ @uuid_batch_count = opts.delete(:uuid_batch_count)
26
+ @connection_options = opts
27
+ end
28
+ @uuid_batch_count ||= 1000
18
29
  end
19
30
 
20
31
  # Lazy load the connection for the current thread
21
32
  def connection
22
33
  conns = (Thread.current['couchrest.connections'] ||= {})
23
- conns[uri.to_s] ||= Connection.new(uri)
34
+ key = "#{uri.to_s}##{connection_options.hash}"
35
+ conns[key] ||= Connection.new(uri, connection_options)
24
36
  end
25
37
 
26
38
  # Lists all databases on the server
@@ -157,8 +157,11 @@ describe CouchRest::Connection do
157
157
  let :conn do
158
158
  CouchRest::Connection.new(uri)
159
159
  end
160
+ let :mock_uri do
161
+ URI "http://mock/db/test-doc"
162
+ end
160
163
  let :mock_conn do
161
- CouchRest::Connection.new(URI "http://mock")
164
+ CouchRest::Connection.new(mock_uri)
162
165
  end
163
166
 
164
167
  describe :get do
@@ -169,6 +172,29 @@ describe CouchRest::Connection do
169
172
  expect(res['name']).to eql(doc['name'])
170
173
  end
171
174
 
175
+ context "persistency" do
176
+ before :each do
177
+ stub_request(:get, "http://mock/db/test-doc")
178
+ .to_return(:body => doc.to_json)
179
+ end
180
+
181
+ it "should have persistency enabled by default" do
182
+ conn = CouchRest::Connection.new(mock_uri)
183
+ expect(conn.options[:persistent]).to be_true
184
+ http1 = conn.http
185
+ conn.get(mock_uri.path)
186
+ expect(conn.http.object_id).to eql(http1.object_id)
187
+ end
188
+
189
+ it "should disable persistency" do
190
+ conn = CouchRest::Connection.new(mock_uri, :persistent => false)
191
+ expect(conn.options[:persistent]).to be_false
192
+ http1 = conn.http
193
+ conn.get(mock_uri.path)
194
+ expect(conn.http.object_id).to_not eql(http1.object_id)
195
+ end
196
+ end
197
+
172
198
  it "should raise exception if document missing" do
173
199
  uri = URI(DB.to_s + "/missingdoc")
174
200
  conn = CouchRest::Connection.new(uri)
@@ -11,12 +11,12 @@ describe CouchRest::Database do
11
11
  describe "#initialize" do
12
12
  describe "database name including slash" do
13
13
  it "should escape the name in the URI" do
14
- db = @cr.database("foo/bar")
15
- expect(db.name).to eq "foo/bar"
16
- expect(db.root).to eq URI("#{COUCHHOST}/foo%2Fbar")
17
- expect(db.uri).to eq URI("#{COUCHHOST}/foo%2Fbar")
18
- expect(db.to_s).to eq "#{COUCHHOST}/foo%2Fbar"
19
- expect(db.path).to eq "/foo%2Fbar"
14
+ db = @cr.database("foo/bar some")
15
+ expect(db.name).to eq "foo/bar some"
16
+ expect(db.root).to eq URI("#{COUCHHOST}/foo%2Fbar+some")
17
+ expect(db.uri).to eq URI("#{COUCHHOST}/foo%2Fbar+some")
18
+ expect(db.to_s).to eq "#{COUCHHOST}/foo%2Fbar+some"
19
+ expect(db.path).to eq "/foo%2Fbar+some"
20
20
  end
21
21
  end
22
22
  end
@@ -3,7 +3,7 @@ require File.expand_path("../../spec_helper", __FILE__)
3
3
  class Video < CouchRest::Document; end
4
4
 
5
5
  describe CouchRest::Document do
6
-
6
+
7
7
  before(:all) do
8
8
  @couch = CouchRest.new
9
9
  @db = @couch.database!(TESTDB)
@@ -73,18 +73,26 @@ describe CouchRest::Document do
73
73
  end
74
74
  end
75
75
 
76
- describe "#has_key?" do
76
+ describe "#key?" do
77
77
  before :each do
78
78
  @doc = CouchRest::Document.new
79
79
  end
80
80
  it "should confirm existance of key" do
81
81
  @doc[:test] = 'example'
82
- expect(@doc.has_key?('test')).to be_true
83
- expect(@doc.has_key?(:test)).to be_true
82
+ expect(@doc.key?('test')).to be_true
83
+ expect(@doc.key?(:test)).to be_true
84
84
  end
85
85
  it "should deny existance of key" do
86
- expect(@doc.has_key?(:bardom)).to be_false
87
- expect(@doc.has_key?('bardom')).to be_false
86
+ expect(@doc.key?(:bardom)).to be_false
87
+ expect(@doc.key?('bardom')).to be_false
88
+ end
89
+ end
90
+
91
+ describe "#has_key?" do
92
+ it 'calls #key?' do
93
+ @doc = CouchRest::Document.new
94
+ expect(@doc).to receive(:key?).with(:test)
95
+ @doc.has_key? :test
88
96
  end
89
97
  end
90
98
 
@@ -160,7 +168,7 @@ describe CouchRest::Document do
160
168
  expect(Video.new.database).to eql @db
161
169
  Video.use_database nil
162
170
  end
163
-
171
+
164
172
  it "should be overwritten by instance" do
165
173
  db = @couch.database('test')
166
174
  article = Video.new
@@ -173,7 +181,7 @@ describe CouchRest::Document do
173
181
 
174
182
  describe "new" do
175
183
  before(:each) do
176
- @doc = CouchRest::Document.new("key" => [1,2,3], :more => "values")
184
+ @doc = CouchRest::Document.new("key" => [1,2,3], :more => "values")
177
185
  end
178
186
  it "should create itself from a Hash" do
179
187
  expect(@doc["key"]).to eql [1,2,3]
@@ -187,22 +195,22 @@ describe CouchRest::Document do
187
195
  @doc.id = 1
188
196
  expect(@doc.id).to eql(1)
189
197
  end
190
-
198
+
191
199
  it "should freak out when saving without a database" do
192
200
  expect(lambda{@doc.save}).to raise_error(ArgumentError)
193
201
  end
194
-
202
+
195
203
  end
196
204
 
197
205
  # move to database spec
198
206
  describe "saving using a database" do
199
207
  before(:all) do
200
- @doc = CouchRest::Document.new("key" => [1,2,3], :more => "values")
201
- @db = reset_test_db!
208
+ @doc = CouchRest::Document.new("key" => [1,2,3], :more => "values")
209
+ @db = reset_test_db!
202
210
  @resp = @db.save_doc(@doc)
203
211
  end
204
212
  it "should apply the database" do
205
- expect(@doc.database).to eql @db
213
+ expect(@doc.database).to eql @db
206
214
  end
207
215
  it "should get id and rev" do
208
216
  expect(@doc.id).to eql @resp["id"]
@@ -231,6 +239,25 @@ describe CouchRest::Document do
231
239
  doc.database.bulk_save
232
240
  expect(doc.database.get(doc["_id"])["val"]).to eql doc["val"]
233
241
  end
242
+
243
+ it "should update the revisions of the saved documents" do
244
+ doc = CouchRest::Document.new({"_id" => "bulkdoc1", "val" => 3})
245
+ doc.database = @db
246
+ doc.save(true)
247
+ doc.database.bulk_save
248
+ expect(doc.database.get(doc["_id"])["_rev"]).to eql doc["_rev"]
249
+ end
250
+
251
+ it "should not update the revisions of documents that aren't saved successfully" do
252
+ doc1 = CouchRest::Document.new({"_id" => "bulkdoc", "val" => 3})
253
+ doc2 = CouchRest::Document.new({"_id" => "bulkdoc2", "val" => 3})
254
+ doc1.database = @db
255
+ doc2.database = @db
256
+ doc1.save(true)
257
+ doc2.save(true)
258
+ @db.bulk_save
259
+ expect(doc1["_rev"]).to be_nil
260
+ end
234
261
  end
235
262
 
236
263
  describe "getting from a database" do
@@ -251,7 +278,7 @@ describe CouchRest::Document do
251
278
  @doc["more"] = "keys"
252
279
  @doc.save
253
280
  expect(@db.get(@resp['id'])["more"]).to eql "keys"
254
- @doc["more"] = "these keys"
281
+ @doc["more"] = "these keys"
255
282
  @doc.save
256
283
  expect(@db.get(@resp['id'])["more"]).to eql "these keys"
257
284
  end
@@ -270,7 +297,7 @@ describe CouchRest::Document do
270
297
  expect(@db.get @resp['id']).to be_nil
271
298
  end
272
299
  it "should error when there's no db" do
273
- @doc = CouchRest::Document.new("key" => [1,2,3], :more => "values")
300
+ @doc = CouchRest::Document.new("key" => [1,2,3], :more => "values")
274
301
  expect(lambda{@doc.destroy}).to raise_error(ArgumentError)
275
302
  end
276
303
  end
@@ -6,8 +6,12 @@ describe CouchRest::Server do
6
6
  CouchRest::Server.new(COUCHHOST)
7
7
  end
8
8
 
9
+ let :mock_url do
10
+ "http://mock"
11
+ end
12
+
9
13
  let :mock_server do
10
- CouchRest::Server.new("http://mock")
14
+ CouchRest::Server.new(mock_url)
11
15
  end
12
16
 
13
17
  describe "#initialize" do
@@ -21,6 +25,24 @@ describe CouchRest::Server do
21
25
  server = CouchRest::Server.new(COUCHHOST + "/some/path?q=1#fragment")
22
26
  expect(server.uri.to_s).to eql(COUCHHOST)
23
27
  end
28
+
29
+ it "should set default uuid batch count" do
30
+ expect(server.uuid_batch_count).to eql(1000)
31
+ end
32
+
33
+ it "should set uuid batch count" do
34
+ server = CouchRest::Server.new(mock_url, 1234)
35
+ expect(server.uuid_batch_count).to eql(1234)
36
+ server = CouchRest::Server.new(mock_url, :uuid_batch_count => 1235)
37
+ expect(server.uuid_batch_count).to eql(1235)
38
+ end
39
+
40
+ it "should set connection options" do
41
+ server = CouchRest::Server.new(mock_url)
42
+ expect(server.connection_options).to be_empty
43
+ server = CouchRest::Server.new(mock_url, :persistent => false)
44
+ expect(server.connection_options[:persistent]).to be_false
45
+ end
24
46
  end
25
47
 
26
48
  describe :connection do
@@ -32,7 +54,32 @@ describe CouchRest::Server do
32
54
  it "should cache connection in current thread" do
33
55
  server.connection # instantiate
34
56
  conns = Thread.current['couchrest.connections']
35
- expect(server.connection).to eql(conns[COUCHHOST])
57
+ expect(server.connection).to eql(conns[COUCHHOST + "##{{}.hash}"])
58
+ end
59
+
60
+ it "should cache connection in current thread with options" do
61
+ Thread.current['couchrest.connections'] = {}
62
+ srv = CouchRest::Server.new(mock_url, :persistent => false)
63
+ srv.connection # instantiate
64
+ conns = Thread.current['couchrest.connections']
65
+ expect(srv.connection.object_id).to eql(conns[conns.keys.last].object_id)
66
+ expect(conns.length).to eql(1)
67
+ end
68
+
69
+ it "should not cache connection in current thread with different options" do
70
+ conns = Thread.current['couchrest.connections'] = {}
71
+ srv = CouchRest::Server.new(mock_url, :persistent => true)
72
+ srv.connection # init
73
+ srv2 = CouchRest::Server.new(mock_url, :persistent => false)
74
+ srv2.connection # init
75
+ expect(conns.length).to eql(2)
76
+ expect(srv.connection.object_id).to_not eql(srv2.connection.object_id)
77
+ end
78
+
79
+ it "should pass configuration options to the connection" do
80
+ expect(mock_server.connection.options[:persistent]).to be_true
81
+ srv = CouchRest::Server.new(mock_url, :persistent => false)
82
+ expect(srv.connection.options[:persistent]).to be_false
36
83
  end
37
84
 
38
85
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: couchrest
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.rc3
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - J. Chris Anderson
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2016-01-08 00:00:00.000000000 Z
15
+ date: 2016-07-06 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: httpclient
@@ -20,56 +20,56 @@ dependencies:
20
20
  requirements:
21
21
  - - "~>"
22
22
  - !ruby/object:Gem::Version
23
- version: '2.7'
23
+ version: '2.8'
24
24
  type: :runtime
25
25
  prerelease: false
26
26
  version_requirements: !ruby/object:Gem::Requirement
27
27
  requirements:
28
28
  - - "~>"
29
29
  - !ruby/object:Gem::Version
30
- version: '2.7'
30
+ version: '2.8'
31
31
  - !ruby/object:Gem::Dependency
32
- name: mime-types
32
+ name: multi_json
33
33
  requirement: !ruby/object:Gem::Requirement
34
34
  requirements:
35
- - - ">="
35
+ - - "~>"
36
36
  - !ruby/object:Gem::Version
37
- version: '1.15'
37
+ version: '1.7'
38
38
  type: :runtime
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
41
41
  requirements:
42
- - - ">="
42
+ - - "~>"
43
43
  - !ruby/object:Gem::Version
44
- version: '1.15'
44
+ version: '1.7'
45
45
  - !ruby/object:Gem::Dependency
46
- name: multi_json
46
+ name: mime-types
47
47
  requirement: !ruby/object:Gem::Requirement
48
48
  requirements:
49
- - - "~>"
49
+ - - ">="
50
50
  - !ruby/object:Gem::Version
51
- version: '1.7'
51
+ version: '1.15'
52
52
  type: :runtime
53
53
  prerelease: false
54
54
  version_requirements: !ruby/object:Gem::Requirement
55
55
  requirements:
56
- - - "~>"
56
+ - - ">="
57
57
  - !ruby/object:Gem::Version
58
- version: '1.7'
58
+ version: '1.15'
59
59
  - !ruby/object:Gem::Dependency
60
- name: json
60
+ name: bundler
61
61
  requirement: !ruby/object:Gem::Requirement
62
62
  requirements:
63
- - - ">="
63
+ - - "~>"
64
64
  - !ruby/object:Gem::Version
65
- version: 1.7.0
65
+ version: '1.3'
66
66
  type: :development
67
67
  prerelease: false
68
68
  version_requirements: !ruby/object:Gem::Requirement
69
69
  requirements:
70
- - - ">="
70
+ - - "~>"
71
71
  - !ruby/object:Gem::Version
72
- version: 1.7.0
72
+ version: '1.3'
73
73
  - !ruby/object:Gem::Dependency
74
74
  name: rspec
75
75
  requirement: !ruby/object:Gem::Requirement
@@ -112,23 +112,9 @@ dependencies:
112
112
  - - ">="
113
113
  - !ruby/object:Gem::Version
114
114
  version: '0'
115
- - !ruby/object:Gem::Dependency
116
- name: mime-types
117
- requirement: !ruby/object:Gem::Requirement
118
- requirements:
119
- - - '='
120
- - !ruby/object:Gem::Version
121
- version: 2.6.2
122
- type: :development
123
- prerelease: false
124
- version_requirements: !ruby/object:Gem::Requirement
125
- requirements:
126
- - - '='
127
- - !ruby/object:Gem::Version
128
- version: 2.6.2
129
115
  description: CouchRest provides a simple interface on top of CouchDB's RESTful HTTP
130
116
  API, as well as including some utility scripts for managing views and attachments.
131
- email: jchris@apache.org
117
+ email: me@samlown.com
132
118
  executables: []
133
119
  extensions: []
134
120
  extra_rdoc_files:
@@ -220,7 +206,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
220
206
  version: 1.3.1
221
207
  requirements: []
222
208
  rubyforge_project:
223
- rubygems_version: 2.5.1
209
+ rubygems_version: 2.4.6
224
210
  signing_key:
225
211
  specification_version: 4
226
212
  summary: Lean and RESTful interface to CouchDB.