Parent

Rufus::Jig::Couch

A class wrapping an instance of Rufus::Jig::Http and providing CouchDB-oriented http verbs.

Attributes

path[R]
http[R]

Public Class Methods

new(*args) click to toggle source
    # File lib/rufus/jig/couch.rb, line 40
40:     def initialize (*args)
41: 
42:       @http, @path, payload, @opts = Rufus::Jig::Http.extract_http(false, *args)
43: 
44:       @path ||= '/'
45:     end

Public Instance Methods

attach(doc_id, doc_rev, attachment_name, data, opts=nil) click to toggle source

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
close() click to toggle source
    # File lib/rufus/jig/couch.rb, line 52
52:     def close
53: 
54:       @http.close
55:     end
delete(doc_or_path, rev=nil) click to toggle source
     # 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
detach(doc_id, doc_rev, attachment_name=nil) click to toggle source

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
get(doc_or_path, opts={}) click to toggle source
    # 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
name() click to toggle source
    # File lib/rufus/jig/couch.rb, line 47
47:     def name
48: 
49:       path
50:     end
nuke_design_documents() click to toggle source

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
on_change(opts={}, &block) click to toggle source

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
post(path, doc) click to toggle source
     # 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
put(doc_or_path, opts={}) click to toggle source
    # 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

Protected Instance Methods

adjust(path) click to toggle source
     # File lib/rufus/jig/couch.rb, line 290
290:     def adjust (path)
291: 
292:       case path
293:         when '.' then @path
294:         when /^\// then path
295:         else Rufus::Jig::Path.join(@path, path)
296:       end
297:     end
etag(path) click to toggle source

Fetches etag from http cache

     # File lib/rufus/jig/couch.rb, line 301
301:     def etag (path)
302: 
303:       r = @http.cache[path]
304: 
305:       r ? r.first : nil
306:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.