couchrest 1.2.1 → 2.0.0.beta1
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 +4 -4
- data/.rspec +2 -0
- data/.travis.yml +1 -0
- data/README.md +11 -7
- data/VERSION +1 -1
- data/couchrest.gemspec +7 -6
- data/history.txt +8 -0
- data/lib/couchrest.rb +26 -31
- data/lib/couchrest/connection.rb +251 -0
- data/lib/couchrest/database.rb +75 -79
- data/lib/couchrest/design.rb +1 -1
- data/lib/couchrest/exceptions.rb +108 -0
- data/lib/couchrest/helper/pager.rb +3 -1
- data/lib/couchrest/helper/stream_row_parser.rb +93 -0
- data/lib/couchrest/rest_api.rb +33 -134
- data/lib/couchrest/server.rb +34 -47
- data/spec/couchrest/connection_spec.rb +415 -0
- data/spec/couchrest/couchrest_spec.rb +61 -67
- data/spec/couchrest/database_spec.rb +151 -147
- data/spec/couchrest/design_spec.rb +28 -28
- data/spec/couchrest/document_spec.rb +72 -70
- data/spec/couchrest/exceptions_spec.rb +74 -0
- data/spec/couchrest/helpers/pager_spec.rb +22 -22
- data/spec/couchrest/helpers/stream_row_parser_spec.rb +154 -0
- data/spec/couchrest/rest_api_spec.rb +44 -208
- data/spec/couchrest/server_spec.rb +0 -29
- data/spec/spec_helper.rb +11 -6
- metadata +31 -17
- data/lib/couchrest/helper/streamer.rb +0 -63
- data/lib/couchrest/monkeypatches.rb +0 -25
- data/spec/couchrest/helpers/streamer_spec.rb +0 -134
@@ -2,34 +2,5 @@ require File.expand_path("../../spec_helper", __FILE__)
|
|
2
2
|
|
3
3
|
describe CouchRest::Server do
|
4
4
|
|
5
|
-
describe "available databases" do
|
6
|
-
before(:each) do
|
7
|
-
@couch = CouchRest::Server.new COUCHHOST
|
8
|
-
end
|
9
|
-
|
10
|
-
after(:each) do
|
11
|
-
@couch.available_databases.each do |ref, db|
|
12
|
-
db.delete!
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
it "should let you add more databases" do
|
17
|
-
@couch.available_databases.should be_empty
|
18
|
-
@couch.define_available_database(:default, "cr-server-test-db")
|
19
|
-
@couch.available_databases.keys.should include(:default)
|
20
|
-
end
|
21
|
-
|
22
|
-
it "should verify that a database is available" do
|
23
|
-
@couch.define_available_database(:default, "cr-server-test-db")
|
24
|
-
@couch.available_database?(:default).should be_true
|
25
|
-
@couch.available_database?("cr-server-test-db").should be_true
|
26
|
-
@couch.available_database?(:matt).should be_false
|
27
|
-
end
|
28
|
-
|
29
|
-
it "should let you set a default database" do
|
30
|
-
@couch.default_database = 'cr-server-test-default-db'
|
31
|
-
@couch.available_database?(:default).should be_true
|
32
|
-
end
|
33
|
-
end
|
34
5
|
|
35
6
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require "bundler/setup"
|
2
2
|
require "rubygems"
|
3
3
|
require "rspec"
|
4
|
+
require "webmock/rspec"
|
4
5
|
|
5
6
|
require File.join(File.dirname(__FILE__), '..','lib','couchrest')
|
6
7
|
# check the following file to see how to use the spec'd features.
|
@@ -13,17 +14,21 @@ unless defined?(FIXTURE_PATH)
|
|
13
14
|
TESTDB = 'couchrest-test'
|
14
15
|
REPLICATIONDB = 'couchrest-test-replication'
|
15
16
|
TEST_SERVER = CouchRest.new COUCHHOST
|
16
|
-
TEST_SERVER.default_database = TESTDB
|
17
17
|
DB = TEST_SERVER.database(TESTDB)
|
18
18
|
end
|
19
19
|
|
20
|
+
# Allows us to hack Specific request responses
|
21
|
+
WebMock.disable_net_connect!(:allow_localhost => true)
|
22
|
+
|
20
23
|
def reset_test_db!
|
21
24
|
DB.recreate! rescue nil
|
22
25
|
DB
|
23
26
|
end
|
24
27
|
|
25
28
|
RSpec.configure do |config|
|
26
|
-
config.before(:all)
|
29
|
+
config.before(:all) do
|
30
|
+
reset_test_db!
|
31
|
+
end
|
27
32
|
|
28
33
|
config.after(:all) do
|
29
34
|
cr = TEST_SERVER
|
@@ -34,13 +39,13 @@ RSpec.configure do |config|
|
|
34
39
|
end
|
35
40
|
end
|
36
41
|
|
42
|
+
# Check if lucene server is running on port 5985 (not 5984)
|
37
43
|
def couchdb_lucene_available?
|
38
|
-
|
39
|
-
url = URI.parse(lucene_path)
|
44
|
+
url = URI "http://localhost:5985/"
|
40
45
|
req = Net::HTTP::Get.new(url.path)
|
41
|
-
|
46
|
+
Net::HTTP.new(url.host, url.port).start { |http| http.request(req) }
|
42
47
|
true
|
43
|
-
rescue Exception
|
48
|
+
rescue Exception
|
44
49
|
false
|
45
50
|
end
|
46
51
|
|
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:
|
4
|
+
version: 2.0.0.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- J. Chris Anderson
|
@@ -12,22 +12,22 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2015-
|
15
|
+
date: 2015-07-09 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
|
-
name:
|
18
|
+
name: httpclient
|
19
19
|
requirement: !ruby/object:Gem::Requirement
|
20
20
|
requirements:
|
21
21
|
- - "~>"
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version:
|
23
|
+
version: 2.6.0
|
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:
|
30
|
+
version: 2.6.0
|
31
31
|
- !ruby/object:Gem::Dependency
|
32
32
|
name: mime-types
|
33
33
|
requirement: !ruby/object:Gem::Requirement
|
@@ -49,9 +49,6 @@ dependencies:
|
|
49
49
|
- - "~>"
|
50
50
|
- !ruby/object:Gem::Version
|
51
51
|
version: '1.7'
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '1.0'
|
55
52
|
type: :runtime
|
56
53
|
prerelease: false
|
57
54
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -59,9 +56,6 @@ dependencies:
|
|
59
56
|
- - "~>"
|
60
57
|
- !ruby/object:Gem::Version
|
61
58
|
version: '1.7'
|
62
|
-
- - "~>"
|
63
|
-
- !ruby/object:Gem::Version
|
64
|
-
version: '1.0'
|
65
59
|
- !ruby/object:Gem::Dependency
|
66
60
|
name: json
|
67
61
|
requirement: !ruby/object:Gem::Requirement
|
@@ -82,14 +76,14 @@ dependencies:
|
|
82
76
|
requirements:
|
83
77
|
- - "~>"
|
84
78
|
- !ruby/object:Gem::Version
|
85
|
-
version: 2.
|
79
|
+
version: 2.14.1
|
86
80
|
type: :development
|
87
81
|
prerelease: false
|
88
82
|
version_requirements: !ruby/object:Gem::Requirement
|
89
83
|
requirements:
|
90
84
|
- - "~>"
|
91
85
|
- !ruby/object:Gem::Version
|
92
|
-
version: 2.
|
86
|
+
version: 2.14.1
|
93
87
|
- !ruby/object:Gem::Dependency
|
94
88
|
name: rake
|
95
89
|
requirement: !ruby/object:Gem::Requirement
|
@@ -104,6 +98,20 @@ dependencies:
|
|
104
98
|
- - ">="
|
105
99
|
- !ruby/object:Gem::Version
|
106
100
|
version: '0'
|
101
|
+
- !ruby/object:Gem::Dependency
|
102
|
+
name: webmock
|
103
|
+
requirement: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
type: :development
|
109
|
+
prerelease: false
|
110
|
+
version_requirements: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - ">="
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
107
115
|
description: CouchRest provides a simple interface on top of CouchDB's RESTful HTTP
|
108
116
|
API, as well as including some utility scripts for managing views and attachments.
|
109
117
|
email: jchris@apache.org
|
@@ -115,6 +123,7 @@ extra_rdoc_files:
|
|
115
123
|
- THANKS.md
|
116
124
|
files:
|
117
125
|
- ".gitignore"
|
126
|
+
- ".rspec"
|
118
127
|
- ".travis.yml"
|
119
128
|
- Gemfile
|
120
129
|
- LICENSE
|
@@ -139,25 +148,28 @@ files:
|
|
139
148
|
- lib/couchrest/attributes.rb
|
140
149
|
- lib/couchrest/commands/generate.rb
|
141
150
|
- lib/couchrest/commands/push.rb
|
151
|
+
- lib/couchrest/connection.rb
|
142
152
|
- lib/couchrest/database.rb
|
143
153
|
- lib/couchrest/design.rb
|
144
154
|
- lib/couchrest/document.rb
|
155
|
+
- lib/couchrest/exceptions.rb
|
145
156
|
- lib/couchrest/helper/attachments.rb
|
146
157
|
- lib/couchrest/helper/pager.rb
|
147
|
-
- lib/couchrest/helper/
|
158
|
+
- lib/couchrest/helper/stream_row_parser.rb
|
148
159
|
- lib/couchrest/helper/upgrade.rb
|
149
160
|
- lib/couchrest/middlewares/logger.rb
|
150
|
-
- lib/couchrest/monkeypatches.rb
|
151
161
|
- lib/couchrest/rest_api.rb
|
152
162
|
- lib/couchrest/server.rb
|
153
163
|
- lib/couchrest/support/inheritable_attributes.rb
|
154
164
|
- spec/.gitignore
|
165
|
+
- spec/couchrest/connection_spec.rb
|
155
166
|
- spec/couchrest/couchrest_spec.rb
|
156
167
|
- spec/couchrest/database_spec.rb
|
157
168
|
- spec/couchrest/design_spec.rb
|
158
169
|
- spec/couchrest/document_spec.rb
|
170
|
+
- spec/couchrest/exceptions_spec.rb
|
159
171
|
- spec/couchrest/helpers/pager_spec.rb
|
160
|
-
- spec/couchrest/helpers/
|
172
|
+
- spec/couchrest/helpers/stream_row_parser_spec.rb
|
161
173
|
- spec/couchrest/rest_api_spec.rb
|
162
174
|
- spec/couchrest/server_spec.rb
|
163
175
|
- spec/fixtures/attachments/README
|
@@ -198,12 +210,14 @@ signing_key:
|
|
198
210
|
specification_version: 4
|
199
211
|
summary: Lean and RESTful interface to CouchDB.
|
200
212
|
test_files:
|
213
|
+
- spec/couchrest/connection_spec.rb
|
201
214
|
- spec/couchrest/couchrest_spec.rb
|
202
215
|
- spec/couchrest/database_spec.rb
|
203
216
|
- spec/couchrest/design_spec.rb
|
204
217
|
- spec/couchrest/document_spec.rb
|
218
|
+
- spec/couchrest/exceptions_spec.rb
|
205
219
|
- spec/couchrest/helpers/pager_spec.rb
|
206
|
-
- spec/couchrest/helpers/
|
220
|
+
- spec/couchrest/helpers/stream_row_parser_spec.rb
|
207
221
|
- spec/couchrest/rest_api_spec.rb
|
208
222
|
- spec/couchrest/server_spec.rb
|
209
223
|
- spec/fixtures/attachments/README
|
@@ -1,63 +0,0 @@
|
|
1
|
-
module CouchRest
|
2
|
-
class Streamer
|
3
|
-
|
4
|
-
attr_accessor :default_curl_opts
|
5
|
-
|
6
|
-
def initialize
|
7
|
-
self.default_curl_opts = "--silent --no-buffer --tcp-nodelay -H \"Content-Type: application/json\""
|
8
|
-
end
|
9
|
-
|
10
|
-
def view(*args)
|
11
|
-
raise "CouchRest::Streamer#view is deprecated. Please use Database#view with block."
|
12
|
-
end
|
13
|
-
|
14
|
-
def get(url, &block)
|
15
|
-
open_pipe("curl #{default_curl_opts} \"#{url}\"", &block)
|
16
|
-
end
|
17
|
-
|
18
|
-
def post(url, params = {}, &block)
|
19
|
-
open_pipe("curl #{default_curl_opts} -d \"#{escape_quotes(MultiJson.encode(params))}\" \"#{url}\"", &block)
|
20
|
-
end
|
21
|
-
|
22
|
-
protected
|
23
|
-
|
24
|
-
def escape_quotes(data)
|
25
|
-
data.gsub(/"/, '\"')
|
26
|
-
end
|
27
|
-
|
28
|
-
def open_pipe(cmd, &block)
|
29
|
-
first = nil
|
30
|
-
prev = nil
|
31
|
-
IO.popen(cmd) do |f|
|
32
|
-
while line = f.gets
|
33
|
-
row = parse_line(line)
|
34
|
-
if row.nil?
|
35
|
-
first ||= line # save the header for later if we can't parse it.
|
36
|
-
else
|
37
|
-
block.call row
|
38
|
-
end
|
39
|
-
prev = line
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
raise RestClient::ServerBrokeConnection if $? && $?.exitstatus != 0
|
44
|
-
|
45
|
-
parse_first(first, prev)
|
46
|
-
end
|
47
|
-
|
48
|
-
def parse_line line
|
49
|
-
return nil unless line
|
50
|
-
if /(\{.*\}),?/.match(line.chomp)
|
51
|
-
MultiJson.decode($1)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def parse_first first, last
|
56
|
-
return nil unless first
|
57
|
-
header = MultiJson.decode(last ? first + last : first)
|
58
|
-
header.delete("rows")
|
59
|
-
header
|
60
|
-
end
|
61
|
-
|
62
|
-
end
|
63
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
# Monkey patch for faster net/http io
|
2
|
-
if RUBY_VERSION.to_f < 1.9
|
3
|
-
require 'timeout'
|
4
|
-
|
5
|
-
class Net::BufferedIO #:nodoc:
|
6
|
-
alias :old_rbuf_fill :rbuf_fill
|
7
|
-
def rbuf_fill
|
8
|
-
if @io.respond_to?(:read_nonblock)
|
9
|
-
begin
|
10
|
-
@rbuf << @io.read_nonblock(65536)
|
11
|
-
rescue Errno::EWOULDBLOCK
|
12
|
-
if IO.select([@io], nil, nil, @read_timeout)
|
13
|
-
retry
|
14
|
-
else
|
15
|
-
raise Timeout::Error, "IO timeout"
|
16
|
-
end
|
17
|
-
end
|
18
|
-
else
|
19
|
-
timeout(@read_timeout) do
|
20
|
-
@rbuf << @io.sysread(65536)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
@@ -1,134 +0,0 @@
|
|
1
|
-
require File.expand_path("../../../spec_helper", __FILE__)
|
2
|
-
|
3
|
-
describe CouchRest::Streamer do
|
4
|
-
before(:all) do
|
5
|
-
@cr = CouchRest.new(COUCHHOST)
|
6
|
-
@db = @cr.database(TESTDB)
|
7
|
-
@db.delete! rescue nil
|
8
|
-
@db = @cr.create_db(TESTDB) rescue nil
|
9
|
-
@streamer = CouchRest::Streamer.new()
|
10
|
-
@docs = (1..1000).collect{|i| {:integer => i, :string => i.to_s}}
|
11
|
-
@db.bulk_save(@docs)
|
12
|
-
@db.save_doc({
|
13
|
-
"_id" => "_design/first",
|
14
|
-
:views => {
|
15
|
-
:test => {
|
16
|
-
:map => "function(doc){for(var w in doc){ if(!w.match(/^_/))emit(w,doc[w])}}"
|
17
|
-
}
|
18
|
-
}
|
19
|
-
})
|
20
|
-
end
|
21
|
-
|
22
|
-
it "should raise error on #view as deprecated" do
|
23
|
-
lambda { @streamer.view }.should raise_error(/deprecated/)
|
24
|
-
end
|
25
|
-
|
26
|
-
it "should GET each row in a view" do
|
27
|
-
count = 0
|
28
|
-
header = @streamer.get("#{@db.root}/_all_docs") do |row|
|
29
|
-
count += 1
|
30
|
-
end
|
31
|
-
count.should == 1001
|
32
|
-
header.should == {"total_rows" => 1001, "offset" => 0}
|
33
|
-
end
|
34
|
-
|
35
|
-
it "should GET each row in a view with params" do
|
36
|
-
count = 0
|
37
|
-
header = @streamer.get("#{@db.root}/_all_docs?include_docs=true&limit=5") do |row|
|
38
|
-
count += 1
|
39
|
-
end
|
40
|
-
count.should == 5
|
41
|
-
header.should == {"total_rows" => 1001, "offset" => 0}
|
42
|
-
end
|
43
|
-
|
44
|
-
it "should GET no rows in a view with limit=0" do
|
45
|
-
count = 0
|
46
|
-
header = @streamer.get("#{@db.root}/_all_docs?include_docs=true&limit=0") do |row|
|
47
|
-
count += 1
|
48
|
-
end
|
49
|
-
count.should == 0
|
50
|
-
header.should == {"total_rows" => 1001, "offset" => 0}
|
51
|
-
end
|
52
|
-
|
53
|
-
it "should raise an exception if it receives malformed data" do
|
54
|
-
IO.stub(:popen) do |cmd, block|
|
55
|
-
class F
|
56
|
-
def initialize
|
57
|
-
@lines = [
|
58
|
-
'{"total_rows": 123, "offset": "0", "rows": [',
|
59
|
-
'{"foo": 1},',
|
60
|
-
'{"foo": 2},',
|
61
|
-
]
|
62
|
-
end
|
63
|
-
|
64
|
-
def gets
|
65
|
-
@lines.shift
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
f = F.new
|
70
|
-
block.call f
|
71
|
-
|
72
|
-
IO.unstub(:popen)
|
73
|
-
IO.popen 'true' do; end
|
74
|
-
end
|
75
|
-
|
76
|
-
count = 0
|
77
|
-
expect do
|
78
|
-
@streamer.get("#{@db.root}/_all_docs?include_docs=true&limit=0") do |row|
|
79
|
-
count += 1
|
80
|
-
end
|
81
|
-
end.should raise_error(MultiJson::DecodeError)
|
82
|
-
end
|
83
|
-
|
84
|
-
it "should raise an exception if the couch connection fails" do
|
85
|
-
IO.stub(:popen) do |cmd, block|
|
86
|
-
class F
|
87
|
-
def initialize
|
88
|
-
@lines = [
|
89
|
-
'{"total_rows": 123, "offset": "0", "rows": [',
|
90
|
-
'{"foo": 1},',
|
91
|
-
'{"foo": 2},',
|
92
|
-
]
|
93
|
-
end
|
94
|
-
|
95
|
-
def gets
|
96
|
-
@lines.shift
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
block.call F.new
|
101
|
-
|
102
|
-
IO.unstub(:popen)
|
103
|
-
IO.popen 'false' do; end
|
104
|
-
end
|
105
|
-
|
106
|
-
count = 0
|
107
|
-
|
108
|
-
expect do
|
109
|
-
@streamer.get("#{@db.root}/_all_docs?include_docs=true&limit=0") do |row|
|
110
|
-
count += 1
|
111
|
-
end
|
112
|
-
end.should raise_error(RestClient::ServerBrokeConnection)
|
113
|
-
|
114
|
-
count.should == 2
|
115
|
-
end
|
116
|
-
|
117
|
-
it "should POST for each row in a view" do
|
118
|
-
# First grab a pair of IDs
|
119
|
-
ids = []
|
120
|
-
@streamer.get("#{@db.root}/_design/first/_view/test?limit=2") do |row|
|
121
|
-
ids << row['id']
|
122
|
-
end
|
123
|
-
count = 0
|
124
|
-
@streamer.post("#{@db.root}/_all_docs?include_docs=true", :keys => ids) do |row|
|
125
|
-
count += 1
|
126
|
-
end
|
127
|
-
count.should == 2
|
128
|
-
end
|
129
|
-
|
130
|
-
it "should escape quotes" do
|
131
|
-
@streamer.send(:escape_quotes, "keys: [\"sams's test\"]").should eql("keys: [\\\"sams's test\\\"]")
|
132
|
-
end
|
133
|
-
|
134
|
-
end
|