couchrest 2.0.0.rc3 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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.