Object
A class wrapping an instance of Rufus::Jig::Http and providing CouchDB-oriented http verbs.
Attaches a file to a couch document.
couch.attach(
doc['_id'], doc['_rev'], 'my_picture', data,
:content_type => 'image/jpeg')
or
couch.attach(
doc, 'my_picture', data,
:content_type => 'image/jpeg')
# File lib/rufus/jig/couch.rb, line 162
162: def attach (doc_id, doc_rev, attachment_name, data, opts=nil)
163:
164: if opts.nil?
165: opts = data
166: data = attachment_name
167: attachment_name = doc_rev
168: doc_rev = doc_id['_rev']
169: doc_id = doc_id['_id']
170: end
171:
172: attachment_name = attachment_name.gsub(/\//, '%2F')
173:
174: ct = opts[:content_type]
175:
176: raise(ArgumentError.new(
177: ":content_type option must be specified"
178: )) unless ct
179:
180: opts[:cache] = false
181:
182: path = adjust("#{doc_id}/#{attachment_name}?rev=#{doc_rev}")
183:
184: if @http.variant == :patron
185: #
186: # patron, as of 0.4.5 has difficulties when PUTting attachements
187: # this is a fallback to net/http
188: #
189: require 'net/http'
190: http = Net::HTTP.new(@http.host, @http.port)
191: req = Net::HTTP::Put.new(path)
192: req['User-Agent'] =
193: "rufus-jig #{Rufus::Jig::VERSION} (patron 0.4.5 fallback to net/http)"
194: req['Content-Type'] =
195: opts[:content_type]
196: req.body = data
197: res = http.start { |h| h.request(req) }
198: status = res.code.to_i
199: raise Rufus::Jig::HttpError.new(status, res.body) unless [ 200, 201 ].include?(status)
200: return nil
201: end
202:
203: @http.put(path, data, opts)
204: end
# File lib/rufus/jig/couch.rb, line 52
52: def close
53:
54: @http.close
55: end
# File lib/rufus/jig/couch.rb, line 98
98: def delete (doc_or_path, rev=nil)
99:
100: doc, path = if rev
101: [ { '_id' => doc_or_path, '_rev' => rev }, doc_or_path ]
102: elsif doc_or_path.is_a?(String)
103: [ nil, doc_or_path ]
104: else
105: [ doc_or_path, doc_or_path['_id'] ]
106: end
107:
108: path = adjust(path)
109:
110: r = if doc
111:
112: raise(
113: ArgumentError.new("cannot delete document without _rev")
114: ) unless doc['_rev']
115:
116: rpath = Rufus::Jig::Path.add_params(path, :rev => doc['_rev'])
117:
118: @http.delete(rpath)
119:
120: else
121:
122: @http.delete(path)
123: end
124:
125: if r == true # conflict
126:
127: doc = @http.get(path)
128: doc ? doc : true
129: # returns the doc if present or true if the doc is gone
130:
131: else # delete is successful
132:
133: nil
134: end
135: end
Detaches a file from a couch document.
couch.detach(doc['_id'], doc['_rev'], 'my_picture')
or
couch.detach(doc, 'my_picture')
# File lib/rufus/jig/couch.rb, line 215
215: def detach (doc_id, doc_rev, attachment_name=nil)
216:
217: if attachment_name.nil?
218: attachment_name = doc_rev
219: doc_rev = doc_id['_rev']
220: doc_id = doc_id['_id']
221: end
222:
223: attachment_name = attachment_name.gsub(/\//, '%2F')
224:
225: path = adjust("#{doc_id}/#{attachment_name}?rev=#{doc_rev}")
226:
227: @http.delete(path)
228: end
# File lib/rufus/jig/couch.rb, line 86
86: def get (doc_or_path, opts={})
87:
88: path = doc_or_path.is_a?(Hash) ? doc_or_path['_id'] : doc_or_path
89: path = adjust(path)
90:
91: if et = etag(path)
92: opts[:etag] = et
93: end
94:
95: @http.get(path, opts)
96: end
# File lib/rufus/jig/couch.rb, line 47
47: def name
48:
49: path
50: end
A development method. Removes all the design documents in this couch database.
Used in tests setup or teardown, when views are subject to frequent changes (rufus-doric and co).
# File lib/rufus/jig/couch.rb, line 279
279: def nuke_design_documents
280:
281: docs = get('_all_docs')['rows']
282:
283: views = docs.select { |d| d['id'] && d['id'].match(/^\_design\//) }
284:
285: views.each { |v| delete(v['id'], v['value']['rev']) }
286: end
Watches the database for changes.
db.on_change do |doc_id, deleted|
puts "doc #{doc_id} has been #{deleted ? 'deleted' : 'changed'}"
end
db.on_change do |doc_id, deleted, doc|
puts "doc #{doc_id} has been #{deleted ? 'deleted' : 'changed'}"
p doc
end
This is a blocking method. One might want to wrap it inside of a Thread.
Note : doc inclusion (third parameter to the block) only works with CouchDB >= 0.11.
# File lib/rufus/jig/couch.rb, line 246
246: def on_change (opts={}, &block)
247:
248: query = {
249: 'feed' => 'continuous',
250: 'heartbeat' => opts[:heartbeat] || 20_000 }
251: query['include_docs'] = true if block.arity > 2
252: query = query.map { |k, v| "#{k}=#{v}" }.join('&')
253:
254: socket = TCPSocket.open(@http.host, @http.port)
255:
256: socket.print("GET /#{path}/_changes?#{query} HTTP/1.1\r\n")
257: socket.print("User-Agent: rufus-jig #{Rufus::Jig::VERSION}\r\n")
258: socket.print("\r\n")
259:
260: loop do
261: data = socket.gets
262: break if data.nil?
263: data = (Rufus::Json.decode(data) rescue nil)
264: next unless data.is_a?(Hash)
265: args = [ data['id'], (data['deleted'] == true) ]
266: args << data['doc'] if block.arity > 2
267: block.call(*args)
268: end
269:
270: on_change(opts, &block) if opts[:reconnect]
271: end
# File lib/rufus/jig/couch.rb, line 137
137: def post (path, doc)
138:
139: path = adjust(path)
140:
141: opts = { :content_type => :json }
142:
143: if et = etag(path)
144: opts[:etag] = et
145: end
146:
147: @http.post(path, doc, opts)
148: end
# File lib/rufus/jig/couch.rb, line 57
57: def put (doc_or_path, opts={})
58:
59: path, payload = if doc_or_path.is_a?(String)
60: [ doc_or_path, '' ]
61: else
62: [ doc_or_path['_id'], doc_or_path ]
63: end
64:
65: pa = adjust(path)
66:
67: #if @opts[:re_put_ok] == false && payload['_rev']
68: # rr = delete(path, payload['_rev'])
69: # return rr unless rr.nil?
70: #end
71:
72: r = @http.put(pa, payload, :content_type => :json, :cache => false)
73:
74: return @http.get(pa) || true if r == true
75: #
76: # conflict : returns the current version of the doc
77: # (or true if there is no document (probably 404 for the database))
78:
79: if opts[:update_rev] && doc_or_path.is_a?(Hash)
80: doc_or_path['_rev'] = r['rev']
81: end
82:
83: nil
84: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.