slight change of API, CR::Document now uses <action>_doc instead of <action>, also added #create! and #recreate! to Document instances
This commit is contained in:
parent
a4a2b202ae
commit
84e2bf94e4
8 changed files with 190 additions and 107 deletions
|
@ -3,7 +3,7 @@ require "base64"
|
|||
|
||||
module CouchRest
|
||||
class Database
|
||||
attr_reader :server, :host, :name, :root
|
||||
attr_reader :server, :host, :name, :root, :uri
|
||||
attr_accessor :bulk_save_cache_limit
|
||||
|
||||
# Create a CouchRest::Database adapter for the supplied CouchRest::Server
|
||||
|
@ -13,11 +13,11 @@ module CouchRest
|
|||
# server<CouchRest::Server>:: database host
|
||||
# name<String>:: database name
|
||||
#
|
||||
def initialize server, name
|
||||
def initialize(server, name)
|
||||
@name = name
|
||||
@server = server
|
||||
@host = server.uri
|
||||
@root = "#{host}/#{name}"
|
||||
@uri = @root = "#{host}/#{name}"
|
||||
@streamer = Streamer.new(self)
|
||||
@bulk_save_cache = []
|
||||
@bulk_save_cache_limit = 50
|
||||
|
@ -25,18 +25,18 @@ module CouchRest
|
|||
|
||||
# returns the database's uri
|
||||
def to_s
|
||||
@root
|
||||
@uri
|
||||
end
|
||||
|
||||
# GET the database info from CouchDB
|
||||
def info
|
||||
CouchRest.get @root
|
||||
CouchRest.get @uri
|
||||
end
|
||||
|
||||
# Query the <tt>_all_docs</tt> view. Accepts all the same arguments as view.
|
||||
def documents params = {}
|
||||
def documents(params = {})
|
||||
keys = params.delete(:keys)
|
||||
url = CouchRest.paramify_url "#{@root}/_all_docs", params
|
||||
url = CouchRest.paramify_url "#{@uri}/_all_docs", params
|
||||
if keys
|
||||
CouchRest.post(url, {:keys => keys})
|
||||
else
|
||||
|
@ -47,10 +47,10 @@ module CouchRest
|
|||
# POST a temporary view function to CouchDB for querying. This is not
|
||||
# recommended, as you don't get any performance benefit from CouchDB's
|
||||
# materialized views. Can be quite slow on large databases.
|
||||
def slow_view funcs, params = {}
|
||||
def slow_view(funcs, params = {})
|
||||
keys = params.delete(:keys)
|
||||
funcs = funcs.merge({:keys => keys}) if keys
|
||||
url = CouchRest.paramify_url "#{@root}/_temp_view", params
|
||||
url = CouchRest.paramify_url "#{@uri}/_temp_view", params
|
||||
JSON.parse(RestClient.post(url, funcs.to_json, {"Content-Type" => 'application/json'}))
|
||||
end
|
||||
|
||||
|
@ -59,9 +59,9 @@ module CouchRest
|
|||
|
||||
# Query a CouchDB view as defined by a <tt>_design</tt> document. Accepts
|
||||
# paramaters as described in http://wiki.apache.org/couchdb/HttpViewApi
|
||||
def view name, params = {}, &block
|
||||
def view(name, params = {}, &block)
|
||||
keys = params.delete(:keys)
|
||||
url = CouchRest.paramify_url "#{@root}/_view/#{name}", params
|
||||
url = CouchRest.paramify_url "#{@uri}/_view/#{name}", params
|
||||
if keys
|
||||
CouchRest.post(url, {:keys => keys})
|
||||
else
|
||||
|
@ -74,9 +74,9 @@ module CouchRest
|
|||
end
|
||||
|
||||
# GET a document from CouchDB, by id. Returns a Ruby Hash.
|
||||
def get id
|
||||
def get(id)
|
||||
slug = escape_docid(id)
|
||||
hash = CouchRest.get("#{@root}/#{slug}")
|
||||
hash = CouchRest.get("#{@uri}/#{slug}")
|
||||
doc = if /^_design/ =~ hash["_id"]
|
||||
Design.new(hash)
|
||||
else
|
||||
|
@ -87,14 +87,21 @@ module CouchRest
|
|||
end
|
||||
|
||||
# GET an attachment directly from CouchDB
|
||||
def fetch_attachment doc, name
|
||||
docid = doc.respond_to?(:has_key?) ? doc['_id'] : doc
|
||||
RestClient.get uri_for_attachment({'_id' => docid}, name)
|
||||
def fetch_attachment(docid, name)
|
||||
slug = escape_docid(docid)
|
||||
name = CGI.escape(name)
|
||||
RestClient.get "#{@uri}/#{slug}/#{name}"
|
||||
end
|
||||
|
||||
# PUT an attachment directly to CouchDB
|
||||
def put_attachment doc, name, file, options = {}
|
||||
uri = uri_for_attachment(doc, name)
|
||||
def put_attachment(doc, name, file, options = {})
|
||||
docid = escape_docid(doc['_id'])
|
||||
name = CGI.escape(name)
|
||||
uri = if doc['_rev']
|
||||
"#{@uri}/#{docid}/#{name}?rev=#{doc['_rev']}"
|
||||
else
|
||||
"#{@uri}/#{docid}/#{name}"
|
||||
end
|
||||
JSON.parse(RestClient.put(uri, file, options))
|
||||
end
|
||||
|
||||
|
@ -113,7 +120,7 @@ module CouchRest
|
|||
#
|
||||
# If <tt>bulk</tt> is true (false by default) the document is cached for bulk-saving later.
|
||||
# Bulk saving happens automatically when #bulk_save_cache limit is exceded, or on the next non bulk save.
|
||||
def save (doc, bulk = false)
|
||||
def save_doc(doc, bulk = false)
|
||||
if doc['_attachments']
|
||||
doc['_attachments'] = encode_attachments(doc['_attachments'])
|
||||
end
|
||||
|
@ -126,13 +133,13 @@ module CouchRest
|
|||
end
|
||||
result = if doc['_id']
|
||||
slug = escape_docid(doc['_id'])
|
||||
CouchRest.put "#{@root}/#{slug}", doc
|
||||
CouchRest.put "#{@uri}/#{slug}", doc
|
||||
else
|
||||
begin
|
||||
slug = doc['_id'] = @server.next_uuid
|
||||
CouchRest.put "#{@root}/#{slug}", doc
|
||||
CouchRest.put "#{@uri}/#{slug}", doc
|
||||
rescue #old version of couchdb
|
||||
CouchRest.post @root, doc
|
||||
CouchRest.post @uri, doc
|
||||
end
|
||||
end
|
||||
if result['ok']
|
||||
|
@ -143,6 +150,13 @@ module CouchRest
|
|||
result
|
||||
end
|
||||
|
||||
### DEPRECATION NOTICE
|
||||
def save(doc, bulk=false)
|
||||
puts "CouchRest::Database's save method is being deprecated, please use save_doc instead"
|
||||
save_doc(doc, bulk)
|
||||
end
|
||||
|
||||
|
||||
# POST an array of documents to CouchDB. If any of the documents are
|
||||
# missing ids, supply one from the uuid cache.
|
||||
#
|
||||
|
@ -160,7 +174,7 @@ module CouchRest
|
|||
doc['_id'] = nextid if nextid
|
||||
end
|
||||
end
|
||||
CouchRest.post "#{@root}/_bulk_docs", {:docs => docs}
|
||||
CouchRest.post "#{@uri}/_bulk_docs", {:docs => docs}
|
||||
end
|
||||
|
||||
# DELETE the document from CouchDB that has the given <tt>_id</tt> and
|
||||
|
@ -168,7 +182,7 @@ module CouchRest
|
|||
#
|
||||
# If <tt>bulk</tt> is true (false by default) the deletion is recorded for bulk-saving (bulk-deletion :) later.
|
||||
# Bulk saving happens automatically when #bulk_save_cache limit is exceded, or on the next non bulk save.
|
||||
def delete (doc, bulk = false)
|
||||
def delete_doc(doc, bulk = false)
|
||||
raise ArgumentError, "_id and _rev required for deleting" unless doc['_id'] && doc['_rev']
|
||||
if bulk
|
||||
@bulk_save_cache << { '_id' => doc['_id'], '_rev' => doc['_rev'], '_deleted' => true }
|
||||
|
@ -176,13 +190,19 @@ module CouchRest
|
|||
return { "ok" => true } # Mimic the non-deferred version
|
||||
end
|
||||
slug = escape_docid(doc['_id'])
|
||||
CouchRest.delete "#{@root}/#{slug}?rev=#{doc['_rev']}"
|
||||
CouchRest.delete "#{@uri}/#{slug}?rev=#{doc['_rev']}"
|
||||
end
|
||||
|
||||
### DEPRECATION NOTICE
|
||||
def delete(doc, bulk=false)
|
||||
puts "CouchRest::Database's delete method is being deprecated, please use delete_doc instead"
|
||||
delete_doc(doc, bulk)
|
||||
end
|
||||
|
||||
# COPY an existing document to a new id. If the destination id currently exists, a rev must be provided.
|
||||
# <tt>dest</tt> can take one of two forms if overwriting: "id_to_overwrite?rev=revision" or the actual doc
|
||||
# hash with a '_rev' key
|
||||
def copy doc, dest
|
||||
def copy_doc(doc, dest)
|
||||
raise ArgumentError, "_id is required for copying" unless doc['_id']
|
||||
slug = escape_docid(doc['_id'])
|
||||
destination = if dest.respond_to?(:has_key?) && dest['_id'] && dest['_rev']
|
||||
|
@ -190,13 +210,19 @@ module CouchRest
|
|||
else
|
||||
dest
|
||||
end
|
||||
CouchRest.copy "#{@root}/#{slug}", destination
|
||||
CouchRest.copy "#{@uri}/#{slug}", destination
|
||||
end
|
||||
|
||||
### DEPRECATION NOTICE
|
||||
def copy(doc, dest)
|
||||
puts "CouchRest::Database's copy method is being deprecated, please use copy_doc instead"
|
||||
copy_doc(doc, dest)
|
||||
end
|
||||
|
||||
# MOVE an existing document to a new id. If the destination id currently exists, a rev must be provided.
|
||||
# <tt>dest</tt> can take one of two forms if overwriting: "id_to_overwrite?rev=revision" or the actual doc
|
||||
# hash with a '_rev' key
|
||||
def move doc, dest
|
||||
def move_doc(doc, dest)
|
||||
raise ArgumentError, "_id and _rev are required for moving" unless doc['_id'] && doc['_rev']
|
||||
slug = escape_docid(doc['_id'])
|
||||
destination = if dest.respond_to?(:has_key?) && dest['_id'] && dest['_rev']
|
||||
|
@ -204,12 +230,33 @@ module CouchRest
|
|||
else
|
||||
dest
|
||||
end
|
||||
CouchRest.move "#{@root}/#{slug}?rev=#{doc['_rev']}", destination
|
||||
CouchRest.move "#{@uri}/#{slug}?rev=#{doc['_rev']}", destination
|
||||
end
|
||||
|
||||
### DEPRECATION NOTICE
|
||||
def move(doc, dest)
|
||||
puts "CouchRest::Database's move method is being deprecated, please use move_doc instead"
|
||||
move_doc(doc, dest)
|
||||
end
|
||||
|
||||
# Compact the database, removing old document revisions and optimizing space use.
|
||||
def compact!
|
||||
CouchRest.post "#{@root}/_compact"
|
||||
CouchRest.post "#{@uri}/_compact"
|
||||
end
|
||||
|
||||
# Create the database
|
||||
def create!
|
||||
bool = server.create_db(@name) rescue false
|
||||
bool && true
|
||||
end
|
||||
|
||||
# Delete and re create the database
|
||||
def recreate!
|
||||
delete!
|
||||
create!
|
||||
rescue RestClient::ResourceNotFound
|
||||
ensure
|
||||
create!
|
||||
end
|
||||
|
||||
# Replicates via "pulling" from another database to this database. Makes no attempt to deal with conflicts.
|
||||
|
@ -227,7 +274,7 @@ module CouchRest
|
|||
# DELETE the database itself. This is not undoable and could be rather
|
||||
# catastrophic. Use with care!
|
||||
def delete!
|
||||
CouchRest.delete @root
|
||||
CouchRest.delete @uri
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -243,7 +290,7 @@ module CouchRest
|
|||
/^_design\/(.*)/ =~ id ? "_design/#{CGI.escape($1)}" : CGI.escape(id)
|
||||
end
|
||||
|
||||
def encode_attachments attachments
|
||||
def encode_attachments(attachments)
|
||||
attachments.each do |k,v|
|
||||
next if v['stub']
|
||||
v['data'] = base64(v['data'])
|
||||
|
@ -251,7 +298,7 @@ module CouchRest
|
|||
attachments
|
||||
end
|
||||
|
||||
def base64 data
|
||||
def base64(data)
|
||||
Base64.encode64(data).gsub(/\s/,'')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -38,7 +38,7 @@ module CouchRest
|
|||
# If <tt>bulk</tt> is <tt>true</tt> (defaults to false) the document is cached for bulk save.
|
||||
def save(bulk = false)
|
||||
raise ArgumentError, "doc.database required for saving" unless database
|
||||
result = database.save self, bulk
|
||||
result = database.save_doc self, bulk
|
||||
result['ok']
|
||||
end
|
||||
|
||||
|
@ -49,7 +49,7 @@ module CouchRest
|
|||
# actually be deleted from the db until bulk save.
|
||||
def destroy(bulk = false)
|
||||
raise ArgumentError, "doc.database required to destroy" unless database
|
||||
result = database.delete(self, bulk)
|
||||
result = database.delete_doc(self, bulk)
|
||||
if result['ok']
|
||||
self['_rev'] = nil
|
||||
self['_id'] = nil
|
||||
|
@ -62,7 +62,7 @@ module CouchRest
|
|||
# hash with a '_rev' key
|
||||
def copy(dest)
|
||||
raise ArgumentError, "doc.database required to copy" unless database
|
||||
result = database.copy(self, dest)
|
||||
result = database.copy_doc(self, dest)
|
||||
result['ok']
|
||||
end
|
||||
|
||||
|
@ -71,7 +71,7 @@ module CouchRest
|
|||
# hash with a '_rev' key
|
||||
def move(dest)
|
||||
raise ArgumentError, "doc.database required to copy" unless database
|
||||
result = database.move(self, dest)
|
||||
result = database.move_doc(self, dest)
|
||||
result['ok']
|
||||
end
|
||||
|
||||
|
|
|
@ -365,7 +365,7 @@ module CouchRest
|
|||
ddocs = all_design_doc_versions
|
||||
ddocs["rows"].each do |row|
|
||||
if (row['id'] != design_doc_id)
|
||||
database.delete({
|
||||
database.delete_doc({
|
||||
"_id" => row['id'],
|
||||
"_rev" => row['value']['rev']
|
||||
})
|
||||
|
@ -485,9 +485,11 @@ module CouchRest
|
|||
alias :new_record? :new_document?
|
||||
|
||||
# Overridden to set the unique ID.
|
||||
# Returns a boolean value
|
||||
def save bulk = false
|
||||
set_unique_id if new_document? && self.respond_to?(:set_unique_id)
|
||||
super(bulk)
|
||||
result = database.save_doc(self, bulk)
|
||||
result["ok"] == true
|
||||
end
|
||||
|
||||
# Saves the document to the db using create or update. Raises an exception
|
||||
|
@ -500,7 +502,7 @@ module CouchRest
|
|||
# Removes the <tt>_id</tt> and <tt>_rev</tt> fields, preparing the
|
||||
# document to be saved to a new <tt>_id</tt>.
|
||||
def destroy
|
||||
result = database.delete self
|
||||
result = database.delete_doc self
|
||||
if result['ok']
|
||||
self['_rev'] = nil
|
||||
self['_id'] = nil
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue