Class: Cushion::Database
- Inherits:
-
Object
- Object
- Cushion::Database
- Defined in:
- lib/cushion/database.rb
Instance Attribute Summary collapse
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#server ⇒ Object
readonly
Returns the value of attribute server.
-
#use_tempfiles ⇒ Object
Returns the value of attribute use_tempfiles.
Instance Method Summary collapse
-
#all(options = {}) ⇒ Object
Convenience method for querying the all_docs view.
-
#attach(id, filename, data, options = {}) ⇒ Object
Save a file attachment under an existing document, or create a new document containing an attachment.
-
#bulk(docs, options = {}) ⇒ Object
Creates, updates and deletes multiple documents in this database according to the supplied
docsarray. -
#compact(headers = {}) ⇒ Object
Compacts this database.
-
#copy(source, destination, options = {}) ⇒ Object
Copies the document at
sourceto a new or existing location atdestination. -
#copy_attachment(id, old_filename, new_filename, options = {}) ⇒ Object
Copies an attachment to a new location.
-
#create(headers = {}) ⇒ Object
Creates this database on the server.
-
#delete(path, headers = {}) ⇒ Object
Issues a DELETE request to this database.
-
#destroy(*args) ⇒ Object
Deletes a single document or attachment by key.
-
#doc(id, options = {}) ⇒ Object
(also: #document)
Retrieves a single document by
idand returns aCushion::Documentlinked to this database. -
#drop(headers = {}) ⇒ Object
Deletes this database from the server.
-
#external(verb, process_path, params = {}) ⇒ Object
Issues a request to the CouchDB external server identified by
process. -
#fetch(*args) ⇒ Object
Retrieves a single document or attachment by key.
-
#get(path, headers = {}) ⇒ Object
Issues a GET request to this database.
-
#head(path, headers = {}) ⇒ Object
Issues a HEAD request to this database.
-
#info(headers = {}) ⇒ Object
Retrieves information about this database.
-
#initialize(name, options = {}) ⇒ Database
constructor
Initializes a Cushion::Database instance.
-
#key?(*args) ⇒ Boolean
(also: #has_key?)
Returns true if a document key exists in this database.
-
#list(design, list_template, view, options = {}) ⇒ Object
Query the list template identified by
design,list_templateandview. -
#move(source, destination, options = {}) ⇒ Object
Moves the document at
sourceto a new or existing location atdestination. -
#move_attachment(id, old_filename, new_filename, options = {}) ⇒ Object
(also: #rename_attachment)
Moves an attachment to a new location.
-
#post(path, body, headers = {}) ⇒ Object
Issues a POST request to this database.
-
#purge(doc_revs, options = {}) ⇒ Object
Completely purges the supplied document revisions from the database.
-
#put(path, body, headers = {}) ⇒ Object
Issues a PUT request to this database.
-
#recreate ⇒ Object
Deletes and recreates this database.
-
#request(verb, path, params) ⇒ Object
Issues a generic request to this database.
-
#show(design, show_template, id, options = {}) ⇒ Object
Query the show template identified by
design,show_templateandid. -
#store(doc, options = {}) ⇒ Object
Stores a document to the database.
-
#temp(funcs, options = {}) ⇒ Object
Convenience method for querying temporary views.
-
#view(name, options = {}) ⇒ Object
Query a named view.
Constructor Details
#initialize(name, options = {}) ⇒ Database
Initializes a Cushion::Database instance.
10 11 12 13 14 15 16 17 18 19 20 21 |
# File 'lib/cushion/database.rb', line 10 def initialize(name, = {}) unless [:server] raise ArgumentError, "server option must be provided" end unless name raise ArgumentError, "name must be provided" end # TODO: CouchDB has strict db naming requirements. Should validate. @name = CGI.escape(name.to_s) @server = [:server] @use_tempfiles = [:use_tempfiles] end |
Instance Attribute Details
#name ⇒ Object (readonly)
Returns the value of attribute name.
6 7 8 |
# File 'lib/cushion/database.rb', line 6 def name @name end |
#server ⇒ Object (readonly)
Returns the value of attribute server.
6 7 8 |
# File 'lib/cushion/database.rb', line 6 def server @server end |
#use_tempfiles ⇒ Object
Returns the value of attribute use_tempfiles.
7 8 9 |
# File 'lib/cushion/database.rb', line 7 def use_tempfiles @use_tempfiles end |
Instance Method Details
#all(options = {}) ⇒ Object
Convenience method for querying the all_docs view. See #view for more information.
324 325 326 |
# File 'lib/cushion/database.rb', line 324 def all( = {}) view(:all, ) end |
#attach(id, filename, data, options = {}) ⇒ Object
Save a file attachment under an existing document, or create a new document containing an attachment. id is the document id. filename is the name of the attachment (extensions may be omitted). Set the rev option to store the attachment under an existing document. Example:
db.attach("docid", "foo.txt", somedata, :rev => "1234")
#=> Stores an attachment under docid
db.attach("anotherid", "bar.jpg", :content_type => "image/jpeg")
#=> Creates a new document containing the attachment. Also sets the
content type.
+data+ may be a <tt>String</tt>, or any object that responds to read.
Content type defaults to ‘application/octet-stream’.
140 141 142 143 144 145 146 147 148 |
# File 'lib/cushion/database.rb', line 140 def attach(id, filename, data, = {}) headers = .delete(:headers) || {} headers[:content_type] = .delete(:content_type) || "application/octet-stream" rev = .delete(:rev) slug = Cushion.escape_key(id, filename) rev_slug = "?rev=#{rev}" if rev data = data.respond_to?(:read) ? data.read : data put("#{slug}#{rev_slug}", data, headers) end |
#bulk(docs, options = {}) ⇒ Object
Creates, updates and deletes multiple documents in this database according to the supplied docs array. Set the _deleted attribute to true to delete an individual doc. Set the _rev attribute to update an individual doc. Leave out the _rev attribute to create a new doc. Example:
docs = [
{ "_id" => "0", "_rev" => "123456", "_deleted" => true }, #=> Delete this doc
{ "_id" => "1", "_rev" => "32486671", "foo" => "bar" }, #=> Update this doc
{ "_id" => "2", "baz" => "bat" } #=> Create this doc
]
db.bulk(docs)
bulk returns a hash of updated doc ids and revs, as follows:
{
"ok" => true,
"new_revs" => [
{ "id" => "0", "rev" => "3682408536" },
{ "id" => "1", "rev" => "3206753266" },
{ "id" => "2", "rev" => "426742535" }
]
}
Set the use_uuids option to generate UUIDs from the server cache before saving. Set the headers option to pass custom request headers.
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/cushion/database.rb', line 187 def bulk(docs, = {}) delete_all = .delete(:delete) headers = .delete(:headers) || {} use_uuids = .delete(:use_uuids) || true if delete_all updates = docs.map { |doc| { '_id' => doc['_id'], '_rev' => doc['_rev'], '_deleted' => true } } else updates = docs end if (use_uuids) ids, noids = docs.partition{|d|d['_id']} uuid_count = [noids.length, server.uuid_batch_count].max noids.each do |doc| nextid = server.next_uuid(uuid_count) rescue nil doc['_id'] = nextid if nextid end end post("_bulk_docs", {:docs => updates}, headers) end |
#compact(headers = {}) ⇒ Object
Compacts this database.
363 364 365 |
# File 'lib/cushion/database.rb', line 363 def compact(headers = {}) post("_compact", nil, headers) end |
#copy(source, destination, options = {}) ⇒ Object
Copies the document at source to a new or existing location at destination. Set the dest_rev option to overwrite an existing document. Set the headers option to pass custom request headers. Example:
db.copy("doc1", "doc2")
#=> Copies to a new location
db.copy("doc1", "doc3", :dest_rev => "4567")
#=> Overwrites an existing doc
217 218 219 220 221 222 223 224 225 226 227 |
# File 'lib/cushion/database.rb', line 217 def copy(source, destination, = {}) headers = .delete(:headers) || {} dest_rev = .delete(:dest_rev) slug = Cushion.escape_key(source) dest = if dest_rev "#{destination}?rev=#{dest_rev}" else destination end server.copy("#{@name}/#{slug}", dest, headers) end |
#copy_attachment(id, old_filename, new_filename, options = {}) ⇒ Object
Copies an attachment to a new location. This is presently experimental.
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
# File 'lib/cushion/database.rb', line 230 def (id, old_filename, new_filename, = {}) headers = .delete(:headers) || {} src = fetch(id, old_filename) headers[:content_type] = src.headers[:content_type] dest_id = [:dest_id] || id opts = [:dest_rev] ? { :rev => [:dest_rev] } : {} if opts.empty? && (id == dest_id) opts = { :rev => src.headers[:etag] } end res = attach(dest_id, new_filename, src, { :headers => headers }.merge(opts)) if id == dest_id res.merge("src_rev" => res["rev"]) else res.merge("src_rev" => src.headers[:etag]) end end |
#create(headers = {}) ⇒ Object
Creates this database on the server.
368 369 370 |
# File 'lib/cushion/database.rb', line 368 def create(headers = {}) server.put(@name, nil, headers) end |
#delete(path, headers = {}) ⇒ Object
Issues a DELETE request to this database. See Cushion::Server#delete.
433 434 435 |
# File 'lib/cushion/database.rb', line 433 def delete(path, headers = {}) server.delete("#{@name}/#{path}", headers) end |
#destroy(*args) ⇒ Object
Deletes a single document or attachment by key. The rev option must be provided.
152 153 154 155 156 157 158 |
# File 'lib/cushion/database.rb', line 152 def destroy(*args) = args.last.is_a?(Hash) ? args.pop : {} headers = .delete(:headers) || {} id, file = args slug = Cushion.escape_key(id, file) delete("#{slug}?rev=#{[:rev]}", headers) end |
#doc(id, options = {}) ⇒ Object Also known as: document
Retrieves a single document by id and returns a Cushion::Document linked to this database.
78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/cushion/database.rb', line 78 def doc(id, = {}) result = fetch(id.to_s, ) ndoc = if /^_design/ =~ result["_id"] Design.new(result) else Document.new(result) end ndoc.database = self ndoc end |
#drop(headers = {}) ⇒ Object
Deletes this database from the server.
373 374 375 |
# File 'lib/cushion/database.rb', line 373 def drop(headers = {}) server.delete(@name, headers) end |
#external(verb, process_path, params = {}) ⇒ Object
Issues a request to the CouchDB external server identified by process. Calls to external must include a request verb. Set the headers option to pass custom request headers.
407 408 409 410 |
# File 'lib/cushion/database.rb', line 407 def external(verb, process_path, params = {}) path = Cushion.paramify_url("_#{process_path}", params[:query]) request(verb, path, :body => params[:body], :headers => params[:headers]) end |
#fetch(*args) ⇒ Object
Retrieves a single document or attachment by key. Returns attachments as an OpenURI IO object if the use_tempfiles database option has been set. Set the headers option to pass custom request headers. Examples:
db.fetch("mydoc")
db.fetch("my/doc") # Forward slashes are automatically escaped...
db.fetch("_design/foo") # ...except in the case of design docs
Attachments can be fetched by supplying the id and filename as follows:
db.fetch("mydoc", "foo.txt")
db.fetch("mydoc", "path/to/foo.txt") # Virtual file path
Cushion requests “application/json” by default, and response bodies will automatically be parsed as such. To request data from CouchDB in another (unparsed) format, simply set the accept header:
db.fetch("mydoc", :headers => { :accept => "text/plain" })
Set :head => true to return the headers rather than the content body. Set :etag => some_value to perform a simple if-none-match conditional GET.
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/cushion/database.rb', line 47 def fetch(*args) = args.last.is_a?(Hash) ? args.pop : {} id, file = args slug = Cushion.escape_key(id, file) headers = .delete(:headers) || {} if etag = .delete(:etag) headers.merge!(:if_none_match => "\"#{etag}\"") end head = .delete(:head) path = Cushion.paramify_url("#{slug}", ) if head return head(path, headers) elsif file && @use_tempfiles return server.("#{@name}/#{path}") end get(path, headers) end |
#get(path, headers = {}) ⇒ Object
Issues a GET request to this database. See Cushion::Server#get.
418 419 420 |
# File 'lib/cushion/database.rb', line 418 def get(path, headers = {}) server.get("#{@name}/#{path}", headers) end |
#head(path, headers = {}) ⇒ Object
Issues a HEAD request to this database. See Cushion::Server#head.
413 414 415 |
# File 'lib/cushion/database.rb', line 413 def head(path, headers = {}) server.head("#{@name}/#{path}", headers) end |
#info(headers = {}) ⇒ Object
Retrieves information about this database.
358 359 360 |
# File 'lib/cushion/database.rb', line 358 def info(headers = {}) server.get(@name, headers) end |
#key?(*args) ⇒ Boolean Also known as: has_key?
Returns true if a document key exists in this database. See #fetch.
66 67 68 69 70 71 72 |
# File 'lib/cushion/database.rb', line 66 def key?(*args) = args.last.is_a?(Hash) ? args.pop : {} id, file = args !!fetch(id, file, .merge(:head => true)) rescue RestClient::ResourceNotFound false end |
#list(design, list_template, view, options = {}) ⇒ Object
Query the list template identified by design, list_template and view. The results are not parsed by default. Set the headers option to pass custom request headers.
350 351 352 353 354 355 |
# File 'lib/cushion/database.rb', line 350 def list(design, list_template, view, = {}) defaults = { :accept => "text/html;text/plain;*/*" } headers = .delete(:headers) || {} path = Cushion.paramify_url("_list/#{design}/#{list_template}/#{view}", ) get(path, defaults.merge(headers)) end |
#move(source, destination, options = {}) ⇒ Object
Moves the document at source to a new or existing location at destination. Set the dest_rev option to overwrite an existing document. Set the headers option to pass custom request headers. Example:
db.move("doc1", "doc2", :rev => "1234")
#=> Moves to a new location
db.copy("doc1", "doc3", :rev => "1234", :dest_rev => "4567")
#=> Overwrites an existing doc
256 257 258 259 260 261 262 263 264 265 266 267 |
# File 'lib/cushion/database.rb', line 256 def move(source, destination, = {}) headers = .delete(:headers) || {} dest_rev = .delete(:dest_rev) slug = Cushion.escape_key(source) path = Cushion.paramify_url("#{slug}", ) dest = if dest_rev "#{destination}?rev=#{dest_rev}" else destination end server.move("#{@name}/#{path}", dest, headers) end |
#move_attachment(id, old_filename, new_filename, options = {}) ⇒ Object Also known as: rename_attachment
Moves an attachment to a new location. This is presently experimental.
270 271 272 273 274 275 276 277 |
# File 'lib/cushion/database.rb', line 270 def (id, old_filename, new_filename, = {}) res = (id, old_filename, new_filename, ) if res["ok"] destroy(id, old_filename, :rev => res["src_rev"]) else res end end |
#post(path, body, headers = {}) ⇒ Object
Issues a POST request to this database. See Cushion::Server#post.
423 424 425 |
# File 'lib/cushion/database.rb', line 423 def post(path, body, headers = {}) server.post("#{@name}/#{path}", body, headers) end |
#purge(doc_revs, options = {}) ⇒ Object
Completely purges the supplied document revisions from the database. doc_revs is a hash of document ids, each containing an array of revisions to be deleted. Example:
doc_revs = {
"1" => ["12345", "42836"],
"2" => ["572654"],
"3" => ["34462"]
}
db.purge(doc_revs)
399 400 401 |
# File 'lib/cushion/database.rb', line 399 def purge(doc_revs, = {}) post("_purge", doc_revs, ) end |
#put(path, body, headers = {}) ⇒ Object
Issues a PUT request to this database. See Cushion::Server#put.
428 429 430 |
# File 'lib/cushion/database.rb', line 428 def put(path, body, headers = {}) server.put("#{@name}/#{path}", body, headers) end |
#recreate ⇒ Object
Deletes and recreates this database.
378 379 380 381 382 383 384 385 |
# File 'lib/cushion/database.rb', line 378 def recreate begin drop rescue RestClient::ResourceNotFound nil end create end |
#request(verb, path, params) ⇒ Object
Issues a generic request to this database. See Cushion::Server#request.
438 439 440 |
# File 'lib/cushion/database.rb', line 438 def request(verb, path, params) server.request(verb, "#{@name}/#{path}", params) end |
#show(design, show_template, id, options = {}) ⇒ Object
Query the show template identified by design, show_template and id. The results are not parsed by default. Set the headers option to pass custom request headers.
338 339 340 341 342 343 344 |
# File 'lib/cushion/database.rb', line 338 def show(design, show_template, id, = {}) defaults = { :accept => "text/html;text/plain;*/*" } headers = .delete(:headers) || {} slug = Cushion.escape_key(id) path = Cushion.paramify_url("_show/#{design}/#{show_template}/#{slug}", ) get(path, defaults.merge(headers)) end |
#store(doc, options = {}) ⇒ Object
Stores a document to the database. Pass a hash with the desired attributes. If an _id attribute is not provided one will be generated automatically from the server UUID cache. Examples:
db.store("foo" => "bar") #=> Creates a doc with an auto-generated key
db.store("_id" => "def") #=> Creates a doc with key "def"
To update a document, set the _rev attribute on the document hash:
db.store("_id" => "ghi", "_rev" => "1234")
Inline attachments are automatically encoded within the document.
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/cushion/database.rb', line 105 def store(doc, = {}) headers = .delete(:headers) || {} if doc['_attachments'] doc['_attachments'] = Cushion.(doc['_attachments']) end res = if doc['_id'] slug = Cushion.escape_key(doc['_id']) put("#{slug}", doc, headers) else slug = doc['_id'] = server.next_uuid put("#{slug}", doc, headers) end if res['ok'] doc['_id'] = res['id'] doc['_rev'] = res['rev'] end res end |
#temp(funcs, options = {}) ⇒ Object
Convenience method for querying temporary views. See #view for more information.
330 331 332 |
# File 'lib/cushion/database.rb', line 330 def temp(funcs, = {}) view(:temp, .merge(:funcs => funcs)) end |
#view(name, options = {}) ⇒ Object
Query a named view. Set name to :all to query CouchDB’s all_docs view. Set name to :temp to query a temp_view. Set the keys option to perform a key-based multi-document fetch against any view. Examples
temp_view = { :map => "function(doc){emit(doc.status,null)}" }
db.view(:temp, :funcs => temp_view, :key => "verified")
db.view("people/by_first_name", :key => "gomer")
db.view("foo/bar", :keys => ["a", "b", "c"])
db.view(:all)
Set the headers option to pass custom request headers. Set :etag => some_value to perform a simple if-none-match conditional GET.
Temp view queries are slow, so they should only be used as a convenience during development. Whenever possible you should query against saved views.
298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 |
# File 'lib/cushion/database.rb', line 298 def view(name, = {}) keys = .delete(:keys) headers = .delete(:headers) || {} if etag = .delete(:etag) headers.merge!(:if_none_match => "\"#{etag}\"".squeeze("\"")) end body = keys ? {:keys => keys} : {} if name == :all slug = "_all_docs" elsif name == :temp slug = "_temp_view" body.merge!(.delete(:funcs)) else slug = "_view/#{name}" end path = Cushion.paramify_url(slug, ) if body.any? post(path, body, headers) else get(path, headers) end end |