rufus-jig 0.1.23 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +1 -0
- data/CHANGELOG.txt +8 -0
- data/README.rdoc +41 -11
- data/Rakefile +37 -12
- data/TODO.txt +6 -3
- data/lib/rufus/jig/adapters/em.rb +21 -24
- data/lib/rufus/jig/adapters/net.rb +3 -4
- data/lib/rufus/jig/adapters/net_persistent.rb +26 -7
- data/lib/rufus/jig/adapters/patron.rb +25 -10
- data/lib/rufus/jig/couch.rb +199 -36
- data/lib/rufus/jig/http.rb +183 -90
- data/lib/rufus/jig/path.rb +4 -4
- data/lib/rufus/jig/version.rb +1 -1
- data/rufus-jig.gemspec +55 -34
- data/spec/couch/attachements_spec.rb +113 -0
- data/spec/couch/basic_auth_spec.rb +75 -0
- data/spec/couch/conditional_spec.rb +178 -0
- data/spec/couch/continuous.rb +97 -0
- data/spec/couch/couch_spec.rb +64 -0
- data/spec/couch/db_spec.rb +366 -0
- data/{test → spec/couch}/tweet.png +0 -0
- data/spec/couch/views_spec.rb +326 -0
- data/spec/couch_url.txt +2 -0
- data/spec/jig/basic_auth_spec.rb +51 -0
- data/spec/jig/conditional_spec.rb +76 -0
- data/spec/jig/delete_spec.rb +32 -0
- data/spec/jig/get_spec.rb +116 -0
- data/spec/jig/misc_spec.rb +120 -0
- data/spec/jig/new_spec.rb +95 -0
- data/spec/jig/parse_uri_spec.rb +139 -0
- data/spec/jig/post_spec.rb +79 -0
- data/spec/jig/prefix_spec.rb +51 -0
- data/spec/jig/put_spec.rb +68 -0
- data/spec/jig/timeout_spec.rb +94 -0
- data/{test → spec}/server.rb +14 -4
- data/spec/spec_helper.rb +61 -0
- data/spec/support/couch_helper.rb +14 -0
- data/spec/support/server_helper.rb +32 -0
- metadata +98 -43
- data/lib/rufus/jig/adapters/net_response.rb +0 -42
- data/test/base.rb +0 -53
- data/test/bm/bm0.rb +0 -49
- data/test/bm/bm1.rb +0 -43
- data/test/conc/put_vs_delete.rb +0 -28
- data/test/couch_base.rb +0 -52
- data/test/couch_url.txt +0 -1
- data/test/ct_0_couch.rb +0 -64
- data/test/ct_1_couchdb.rb +0 -204
- data/test/ct_2_couchdb_options.rb +0 -50
- data/test/ct_3_couchdb_views.rb +0 -106
- data/test/ct_4_attachments.rb +0 -126
- data/test/ct_5_couchdb_continuous.rb +0 -92
- data/test/cut_0_auth_couch.rb +0 -62
- data/test/test.rb +0 -28
- data/test/to.sh +0 -25
- data/test/tt_0_get_timeout.rb +0 -92
- data/test/ut_0_http_get.rb +0 -191
- data/test/ut_1_http_post.rb +0 -81
- data/test/ut_2_http_delete.rb +0 -42
- data/test/ut_3_http_put.rb +0 -105
- data/test/ut_4_http_prefix.rb +0 -50
- data/test/ut_5_http_misc.rb +0 -65
- data/test/ut_6_args.rb +0 -98
- data/test/ut_7_parse_uri.rb +0 -79
- data/test/ut_8_auth.rb +0 -37
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour --format documentation
|
data/CHANGELOG.txt
CHANGED
@@ -2,6 +2,14 @@
|
|
2
2
|
= rufus-jig CHANGELOG.txt
|
3
3
|
|
4
4
|
|
5
|
+
== rufus-jig - 1.0.0 released 2010/12/08
|
6
|
+
|
7
|
+
- Couch #all, #query, #query_for_docs, #bulk_put and #bulk_delete
|
8
|
+
- Rufus::Jig.parse_uri now identifies the #fragment
|
9
|
+
- conditional GET on by default
|
10
|
+
- switched from test/unit to rspec
|
11
|
+
|
12
|
+
|
5
13
|
== rufus-jig - 0.1.23 released 2010/10/01
|
6
14
|
|
7
15
|
- net-http-persistent 1.4 which contains the shutdown_in_all_threads patch
|
data/README.rdoc
CHANGED
@@ -74,8 +74,6 @@ posting...
|
|
74
74
|
For the real thing : http://github.com/couchrest/couchrest
|
75
75
|
There is also the excellent : http://github.com/langalex/couch_potato
|
76
76
|
|
77
|
-
Warning : rufus-jig >= 0.1.18 is meant for CouchDB >= 0.11.
|
78
|
-
|
79
77
|
The class Rufus::Jig::Couch provides a get/put/delete trio that is couch-oriented. Json encoding/decoding is automatically handled as well as
|
80
78
|
|
81
79
|
put and delete return nil in case of success and true (conflict) or and exception else.
|
@@ -111,8 +109,32 @@ put and delete return nil in case of success and true (conflict) or and exceptio
|
|
111
109
|
|
112
110
|
c.detach('coffee0', '1-x-newrevision-whatever', 'picture')
|
113
111
|
|
112
|
+
there is also
|
113
|
+
|
114
|
+
c.all(:skip => 100, :limit => 100)
|
115
|
+
c.all(:keys => %w[ doc0 doc1 doc3 ])
|
116
|
+
# grabbing multiple docs in one go
|
117
|
+
|
118
|
+
c.query('_design/my_design_doc/_view/my_view')
|
119
|
+
c.query('my_design_doc:my_view')
|
120
|
+
# 'querying' a view
|
121
|
+
|
122
|
+
c.query_for_docs('my_design_doc:my_view')
|
123
|
+
# querying for documents
|
124
|
+
|
125
|
+
bulk operations
|
126
|
+
|
127
|
+
docs = c.all(:keys => %w[ doc0 doc1 doc3 ])
|
128
|
+
c.bulk_delete(docs)
|
129
|
+
# deleting in one go
|
114
130
|
|
115
|
-
|
131
|
+
docs = c.all(:keys => %w[ doc0 doc1 doc3 ])
|
132
|
+
docs.each { |doc| doc['status'] = 'copied' }
|
133
|
+
c.bulk_put(docs)
|
134
|
+
# updating in one go
|
135
|
+
|
136
|
+
|
137
|
+
=== Couch on_change
|
116
138
|
|
117
139
|
Continuous feed with a 20s heartbeat :
|
118
140
|
|
@@ -137,22 +159,29 @@ http://rufus.rubyforge.org/rufus-jig/
|
|
137
159
|
|
138
160
|
== testing
|
139
161
|
|
140
|
-
|
162
|
+
rake
|
163
|
+
|
164
|
+
or
|
165
|
+
|
166
|
+
rspec spec/
|
167
|
+
|
168
|
+
tests all (plain jig and CouchDB).
|
141
169
|
|
142
|
-
|
170
|
+
rspec spec/jig
|
143
171
|
|
144
|
-
|
172
|
+
only tests the plain jig stuff.
|
145
173
|
|
146
|
-
|
174
|
+
rspec spec/couch
|
147
175
|
|
176
|
+
only tests the CouchDB stuff.
|
148
177
|
|
149
|
-
|
178
|
+
By default net/http is used. To test with another HTTP lib :
|
150
179
|
|
151
|
-
|
180
|
+
JIG_LIB=patron rspec spec/
|
152
181
|
|
153
|
-
|
182
|
+
You can specify patron, em, netp or net. Netp corresponds to http://seattlerb.rubyforge.org/net-http-persistent/
|
154
183
|
|
155
|
-
|
184
|
+
The specs require the json and sinatra gems. You can spot issues in the file server.log (created when running specs).
|
156
185
|
|
157
186
|
|
158
187
|
== known issues
|
@@ -186,6 +215,7 @@ http://rufus.rubyforge.org
|
|
186
215
|
|
187
216
|
* John Mettraux, http://jmettraux.wordpress.com/
|
188
217
|
* Kenneth Kalmer, http://www.opensourcery.co.za/
|
218
|
+
* Torsten Schoenebaum, http://github.com/tosch/
|
189
219
|
|
190
220
|
|
191
221
|
== license
|
data/Rakefile
CHANGED
@@ -1,19 +1,11 @@
|
|
1
1
|
|
2
|
-
|
2
|
+
$:.unshift('.')
|
3
3
|
require 'lib/rufus/jig/version.rb'
|
4
4
|
|
5
5
|
require 'rubygems'
|
6
6
|
require 'rake'
|
7
7
|
|
8
8
|
|
9
|
-
#
|
10
|
-
# CLEAN
|
11
|
-
|
12
|
-
require 'rake/clean'
|
13
|
-
CLEAN.include('pkg', 'tmp', 'html', 'rdoc')
|
14
|
-
task :default => [ :clean ]
|
15
|
-
|
16
|
-
|
17
9
|
#
|
18
10
|
# GEM
|
19
11
|
|
@@ -30,18 +22,18 @@ Jeweler::Tasks.new do |gem|
|
|
30
22
|
|
31
23
|
An HTTP client, greedy with JSON content, GETting conditionally.
|
32
24
|
|
33
|
-
Uses
|
25
|
+
Uses Yajl-ruby whenever possible.
|
34
26
|
}
|
35
27
|
gem.email = 'jmettraux@gmail.com'
|
36
28
|
gem.homepage = 'http://github.com/jmettraux/rufus-jig/'
|
37
29
|
gem.authors = [ 'John Mettraux', 'Kenneth Kalmer' ]
|
38
30
|
gem.rubyforge_project = 'rufus'
|
39
31
|
|
40
|
-
gem.test_file = 'test/test.rb'
|
41
|
-
|
42
32
|
gem.add_dependency 'rufus-lru'
|
43
33
|
gem.add_dependency 'rufus-json', '>= 0.2.5'
|
34
|
+
|
44
35
|
gem.add_development_dependency 'rake'
|
36
|
+
gem.add_development_dependency 'rspec', '~> 2.2.0'
|
45
37
|
gem.add_development_dependency 'yard'
|
46
38
|
gem.add_development_dependency 'jeweler'
|
47
39
|
gem.add_development_dependency 'patron'
|
@@ -53,6 +45,39 @@ end
|
|
53
45
|
Jeweler::GemcutterTasks.new
|
54
46
|
|
55
47
|
|
48
|
+
#
|
49
|
+
# CLEAN
|
50
|
+
|
51
|
+
require 'rake/clean'
|
52
|
+
CLEAN.include('pkg', 'tmp', 'html', 'rdoc', 'server.log')
|
53
|
+
|
54
|
+
#
|
55
|
+
# SPEC / TEST
|
56
|
+
|
57
|
+
#task :spec => :check_dependencies do
|
58
|
+
task :spec do
|
59
|
+
sh 'rspec spec/'
|
60
|
+
end
|
61
|
+
task :test => :spec
|
62
|
+
|
63
|
+
task :default => :spec
|
64
|
+
|
65
|
+
desc %{
|
66
|
+
runs the specs against net, netp, patron and em
|
67
|
+
}
|
68
|
+
task :specs do
|
69
|
+
puts; puts "-" * 80; puts
|
70
|
+
sh 'export JIG_LIB=net; rspec -f p spec/; exit 0'
|
71
|
+
puts; puts "-" * 80; puts
|
72
|
+
sh 'export JIG_LIB=netp; rspec -f p spec/; exit 0'
|
73
|
+
puts; puts "-" * 80; puts
|
74
|
+
sh 'export JIG_LIB=patron; rspec -f p spec/; exit 0'
|
75
|
+
puts; puts "-" * 80; puts
|
76
|
+
sh 'export JIG_LIB=em; rspec -f p spec/; exit 0'
|
77
|
+
puts; puts "-" * 80; puts
|
78
|
+
end
|
79
|
+
|
80
|
+
|
56
81
|
#
|
57
82
|
# DOC
|
58
83
|
|
data/TODO.txt
CHANGED
@@ -19,14 +19,17 @@
|
|
19
19
|
http://seattlerb.rubyforge.org/net-http-persistent/Net/HTTP/Persistent.html
|
20
20
|
[o] HttpResponse : DRY net and netp
|
21
21
|
[x] patron : http can steal each other's patron session (inside the same thread)
|
22
|
+
[o] why not a :force_json ?
|
23
|
+
[o] netp : close() impl
|
24
|
+
[o] views : couch#query(view, opts) ?
|
22
25
|
|
23
26
|
[ ] HEAD
|
27
|
+
[ ] OPTIONS
|
24
28
|
[ ] redirections ? (Patron seem to understand them)
|
25
|
-
[ ] why not a :force_json ?
|
26
29
|
|
27
30
|
[ ] make HttpCore detect do_request
|
28
|
-
|
29
31
|
[ ] timeout per request ?
|
32
|
+
[ ] caching
|
30
33
|
|
31
|
-
[ ]
|
34
|
+
[ ] digest auth (as for rufus-verbs) ?
|
32
35
|
|
@@ -25,20 +25,20 @@
|
|
25
25
|
|
26
26
|
class Rufus::Jig::HttpResponse
|
27
27
|
|
28
|
-
def initialize(
|
28
|
+
def initialize(em_client)
|
29
29
|
|
30
30
|
@original = [ em_client, em_client.response ]
|
31
31
|
|
32
32
|
@status = em_client.response_header.status
|
33
|
-
@headers = response_headers(
|
33
|
+
@headers = response_headers(em_client.response_header)
|
34
34
|
@body = em_client.response
|
35
35
|
end
|
36
36
|
|
37
37
|
protected
|
38
38
|
|
39
|
-
def response_headers(
|
39
|
+
def response_headers(hash)
|
40
40
|
|
41
|
-
hash.inject({}) do |headers, (
|
41
|
+
hash.inject({}) do |headers, (key, value)|
|
42
42
|
key = key.downcase.split('_').map { |c| c.capitalize }.join( '-' )
|
43
43
|
headers[ key ] = value
|
44
44
|
headers
|
@@ -50,9 +50,9 @@ class Rufus::Jig::Http < Rufus::Jig::HttpCore
|
|
50
50
|
|
51
51
|
require 'uri'
|
52
52
|
|
53
|
-
def initialize(
|
53
|
+
def initialize(*args)
|
54
54
|
|
55
|
-
super(
|
55
|
+
super(*args)
|
56
56
|
|
57
57
|
@options[:user_agent] ||= "#{self.class} #{Rufus::Jig::VERSION} (em)"
|
58
58
|
end
|
@@ -68,11 +68,11 @@ class Rufus::Jig::Http < Rufus::Jig::HttpCore
|
|
68
68
|
|
69
69
|
protected
|
70
70
|
|
71
|
-
def do_request(
|
71
|
+
def do_request(method, path, data, opts)
|
72
72
|
|
73
73
|
args = {}
|
74
74
|
|
75
|
-
args[:head] = request_headers(
|
75
|
+
args[:head] = request_headers(opts)
|
76
76
|
args[:body] = data if data
|
77
77
|
|
78
78
|
if to = (opts[:timeout] || @options[:timeout])
|
@@ -83,26 +83,23 @@ class Rufus::Jig::Http < Rufus::Jig::HttpCore
|
|
83
83
|
end
|
84
84
|
|
85
85
|
if auth = @options[:basic_auth]
|
86
|
-
args[:head].merge!(
|
86
|
+
args[:head].merge!('authorization' => auth)
|
87
87
|
end
|
88
88
|
|
89
|
-
em_response(
|
89
|
+
em_response(em_request(path).send(method, args))
|
90
90
|
end
|
91
91
|
|
92
|
-
def em_request(
|
92
|
+
def em_request(uri='/')
|
93
93
|
|
94
|
-
uri = Rufus::Jig.parse_uri(
|
95
|
-
uri
|
96
|
-
|
97
|
-
|
98
|
-
:path => uri.path,
|
99
|
-
:query => uri.query
|
100
|
-
)
|
94
|
+
uri = Rufus::Jig.parse_uri(uri)
|
95
|
+
uri.scheme ||= (@port == 443 ? 'https' : 'http')
|
96
|
+
uri.host ||= @host
|
97
|
+
uri.port ||= @port
|
101
98
|
|
102
|
-
EventMachine::HttpRequest.new(
|
99
|
+
EventMachine::HttpRequest.new(uri.to_s)
|
103
100
|
end
|
104
101
|
|
105
|
-
def em_response(
|
102
|
+
def em_response(em_client)
|
106
103
|
|
107
104
|
th = Thread.current
|
108
105
|
|
@@ -110,7 +107,7 @@ class Rufus::Jig::Http < Rufus::Jig::HttpCore
|
|
110
107
|
|
111
108
|
em_client.errback {
|
112
109
|
|
113
|
-
#th.raise(
|
110
|
+
#th.raise(Rufus::Jig::TimeoutError.new)
|
114
111
|
# works with ruby < 1.9.x
|
115
112
|
th.wakeup
|
116
113
|
}
|
@@ -125,15 +122,15 @@ class Rufus::Jig::Http < Rufus::Jig::HttpCore
|
|
125
122
|
|
126
123
|
raise Rufus::Jig::TimeoutError if em_client.response_header.status == 0
|
127
124
|
|
128
|
-
Rufus::Jig::HttpResponse.new(
|
125
|
+
Rufus::Jig::HttpResponse.new(em_client)
|
129
126
|
end
|
130
127
|
|
131
|
-
def request_headers(
|
128
|
+
def request_headers(options)
|
132
129
|
|
133
130
|
headers = { 'user-agent' => @options[:user_agent] }
|
134
131
|
|
135
132
|
%w[ Accept If-None-Match Content-Type ].each do |k|
|
136
|
-
headers[k] = options[k] if options.has_key?(
|
133
|
+
headers[k] = options[k] if options.has_key?(k)
|
137
134
|
end
|
138
135
|
|
139
136
|
headers
|
@@ -23,12 +23,11 @@
|
|
23
23
|
#++
|
24
24
|
|
25
25
|
require 'net/http'
|
26
|
-
require 'rufus/jig/adapters/net_response'
|
27
26
|
|
28
27
|
|
29
28
|
class Rufus::Jig::Http < Rufus::Jig::HttpCore
|
30
29
|
|
31
|
-
def initialize
|
30
|
+
def initialize(*args)
|
32
31
|
|
33
32
|
super(*args)
|
34
33
|
|
@@ -45,7 +44,7 @@ class Rufus::Jig::Http < Rufus::Jig::HttpCore
|
|
45
44
|
|
46
45
|
protected
|
47
46
|
|
48
|
-
def get_http
|
47
|
+
def get_http(opts)
|
49
48
|
|
50
49
|
http = Net::HTTP.new(@host, @port)
|
51
50
|
|
@@ -62,7 +61,7 @@ class Rufus::Jig::Http < Rufus::Jig::HttpCore
|
|
62
61
|
http
|
63
62
|
end
|
64
63
|
|
65
|
-
def do_request
|
64
|
+
def do_request(method, path, data, opts)
|
66
65
|
|
67
66
|
path = '/' if path == ''
|
68
67
|
|
@@ -23,12 +23,9 @@
|
|
23
23
|
#++
|
24
24
|
|
25
25
|
|
26
|
-
require 'rufus/jig/adapters/net_response'
|
27
|
-
|
28
|
-
|
29
26
|
class Rufus::Jig::Http < Rufus::Jig::HttpCore
|
30
27
|
|
31
|
-
def initialize
|
28
|
+
def initialize(*args)
|
32
29
|
|
33
30
|
super(*args)
|
34
31
|
|
@@ -38,6 +35,14 @@ class Rufus::Jig::Http < Rufus::Jig::HttpCore
|
|
38
35
|
name = [ 'jig', @host, @port.to_s ].join('|')
|
39
36
|
|
40
37
|
@http = Net::HTTP::Persistent.new(name)
|
38
|
+
|
39
|
+
@http.open_timeout = 5
|
40
|
+
# connection timeout
|
41
|
+
|
42
|
+
@timeout = @options[:timeout]
|
43
|
+
@timeout = @timeout.to_i if @timeout
|
44
|
+
|
45
|
+
reset_timeout
|
41
46
|
end
|
42
47
|
|
43
48
|
def variant
|
@@ -54,7 +59,7 @@ class Rufus::Jig::Http < Rufus::Jig::HttpCore
|
|
54
59
|
|
55
60
|
protected
|
56
61
|
|
57
|
-
def do_request
|
62
|
+
def do_request(method, path, data, opts)
|
58
63
|
|
59
64
|
path = '/' if path == ''
|
60
65
|
|
@@ -66,13 +71,27 @@ class Rufus::Jig::Http < Rufus::Jig::HttpCore
|
|
66
71
|
if auth = @options[:basic_auth]
|
67
72
|
req.basic_auth(*auth)
|
68
73
|
end
|
74
|
+
if to = opts[:timeout]
|
75
|
+
@http.read_timeout = to
|
76
|
+
end
|
69
77
|
|
70
78
|
req.body = data ? data : ''
|
71
79
|
|
72
80
|
begin
|
73
81
|
Rufus::Jig::HttpResponse.new(@http.request(uri, req))
|
74
|
-
rescue
|
75
|
-
raise Rufus::Jig::TimeoutError
|
82
|
+
rescue Net::HTTP::Persistent::Error => nhpe
|
83
|
+
raise Rufus::Jig::TimeoutError if nhpe.message.match(/Timeout::Error/)
|
84
|
+
ensure
|
85
|
+
reset_timeout
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def reset_timeout
|
90
|
+
|
91
|
+
if @timeout
|
92
|
+
@http.read_timeout = (@timeout < 1) ? nil : @timeout
|
93
|
+
else
|
94
|
+
@http.read_timeout = 5 # like Patron
|
76
95
|
end
|
77
96
|
end
|
78
97
|
end
|
@@ -23,20 +23,31 @@
|
|
23
23
|
#++
|
24
24
|
|
25
25
|
|
26
|
+
#
|
27
|
+
# Re-opening to adapt to Patron
|
28
|
+
#
|
26
29
|
class Rufus::Jig::HttpResponse
|
27
30
|
|
28
|
-
|
31
|
+
NHR = /^Net::HTTP/
|
32
|
+
|
33
|
+
def initialize(res)
|
29
34
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
35
|
+
if NHR.match(res.class.name)
|
36
|
+
# for the couch#attach workaround :-( ...
|
37
|
+
net_http_init(res)
|
38
|
+
return
|
39
|
+
end
|
40
|
+
|
41
|
+
@original = res
|
42
|
+
@status = res.status
|
43
|
+
@headers = res.headers
|
44
|
+
@body = res.body
|
34
45
|
end
|
35
46
|
end
|
36
47
|
|
37
48
|
class Rufus::Jig::Http < Rufus::Jig::HttpCore
|
38
49
|
|
39
|
-
def initialize
|
50
|
+
def initialize(*args)
|
40
51
|
|
41
52
|
super(*args)
|
42
53
|
|
@@ -54,11 +65,15 @@ class Rufus::Jig::Http < Rufus::Jig::HttpCore
|
|
54
65
|
|
55
66
|
protected
|
56
67
|
|
57
|
-
def get_patron
|
68
|
+
def get_patron(opts)
|
58
69
|
|
59
70
|
to = (opts[:timeout] || @options[:timeout])
|
60
71
|
to = to.to_i if to
|
61
|
-
to =
|
72
|
+
to = if to
|
73
|
+
to < 1 ? nil : to
|
74
|
+
else
|
75
|
+
5
|
76
|
+
end
|
62
77
|
|
63
78
|
patron = Patron::Session.new
|
64
79
|
patron.base_url = "#{@host}:#{@port}"
|
@@ -80,7 +95,7 @@ class Rufus::Jig::Http < Rufus::Jig::HttpCore
|
|
80
95
|
patron
|
81
96
|
end
|
82
97
|
|
83
|
-
def do_request
|
98
|
+
def do_request(method, path, data, opts)
|
84
99
|
|
85
100
|
opts['Expect'] = '' if (method == :put) && ( ! @options[:expect])
|
86
101
|
|
@@ -90,7 +105,7 @@ class Rufus::Jig::Http < Rufus::Jig::HttpCore
|
|
90
105
|
end
|
91
106
|
|
92
107
|
begin
|
93
|
-
get_patron(opts).send(method, *args)
|
108
|
+
Rufus::Jig::HttpResponse.new(get_patron(opts).send(method, *args))
|
94
109
|
rescue Patron::TimeoutError => te
|
95
110
|
raise Rufus::Jig::TimeoutError
|
96
111
|
end
|