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:
Matt Aimonetti 2009-01-28 17:36:36 -08:00
parent e9f7456eab
commit fda5be213a
8 changed files with 185 additions and 108 deletions

View file

@ -3,7 +3,7 @@ require "base64"
module CouchRest module CouchRest
class Database class Database
attr_reader :server, :host, :name, :root attr_reader :server, :host, :name, :root, :uri
attr_accessor :bulk_save_cache_limit attr_accessor :bulk_save_cache_limit
# Create a CouchRest::Database adapter for the supplied CouchRest::Server # Create a CouchRest::Database adapter for the supplied CouchRest::Server
@ -13,11 +13,11 @@ module CouchRest
# server<CouchRest::Server>:: database host # server<CouchRest::Server>:: database host
# name<String>:: database name # name<String>:: database name
# #
def initialize server, name def initialize(server, name)
@name = name @name = name
@server = server @server = server
@host = server.uri @host = server.uri
@root = "#{host}/#{name}" @uri = @root = "#{host}/#{name}"
@streamer = Streamer.new(self) @streamer = Streamer.new(self)
@bulk_save_cache = [] @bulk_save_cache = []
@bulk_save_cache_limit = 50 @bulk_save_cache_limit = 50
@ -25,18 +25,18 @@ module CouchRest
# returns the database's uri # returns the database's uri
def to_s def to_s
@root @uri
end end
# GET the database info from CouchDB # GET the database info from CouchDB
def info def info
CouchRest.get @root CouchRest.get @uri
end end
# Query the <tt>_all_docs</tt> view. Accepts all the same arguments as view. # Query the <tt>_all_docs</tt> view. Accepts all the same arguments as view.
def documents params = {} def documents(params = {})
keys = params.delete(:keys) keys = params.delete(:keys)
url = CouchRest.paramify_url "#{@root}/_all_docs", params url = CouchRest.paramify_url "#{@uri}/_all_docs", params
if keys if keys
CouchRest.post(url, {:keys => keys}) CouchRest.post(url, {:keys => keys})
else else
@ -47,10 +47,10 @@ module CouchRest
# POST a temporary view function to CouchDB for querying. This is not # POST a temporary view function to CouchDB for querying. This is not
# recommended, as you don't get any performance benefit from CouchDB's # recommended, as you don't get any performance benefit from CouchDB's
# materialized views. Can be quite slow on large databases. # materialized views. Can be quite slow on large databases.
def slow_view funcs, params = {} def slow_view(funcs, params = {})
keys = params.delete(:keys) keys = params.delete(:keys)
funcs = funcs.merge({:keys => keys}) if 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'})) JSON.parse(RestClient.post(url, funcs.to_json, {"Content-Type" => 'application/json'}))
end end
@ -59,9 +59,9 @@ module CouchRest
# Query a CouchDB view as defined by a <tt>_design</tt> document. Accepts # Query a CouchDB view as defined by a <tt>_design</tt> document. Accepts
# paramaters as described in http://wiki.apache.org/couchdb/HttpViewApi # paramaters as described in http://wiki.apache.org/couchdb/HttpViewApi
def view name, params = {}, &block def view(name, params = {}, &block)
keys = params.delete(:keys) keys = params.delete(:keys)
url = CouchRest.paramify_url "#{@root}/_view/#{name}", params url = CouchRest.paramify_url "#{@uri}/_view/#{name}", params
if keys if keys
CouchRest.post(url, {:keys => keys}) CouchRest.post(url, {:keys => keys})
else else
@ -74,9 +74,9 @@ module CouchRest
end end
# GET a document from CouchDB, by id. Returns a Ruby Hash. # GET a document from CouchDB, by id. Returns a Ruby Hash.
def get id def get(id)
slug = escape_docid(id) slug = escape_docid(id)
hash = CouchRest.get("#{@root}/#{slug}") hash = CouchRest.get("#{@uri}/#{slug}")
doc = if /^_design/ =~ hash["_id"] doc = if /^_design/ =~ hash["_id"]
Design.new(hash) Design.new(hash)
else else
@ -87,20 +87,20 @@ module CouchRest
end end
# GET an attachment directly from CouchDB # GET an attachment directly from CouchDB
def fetch_attachment docid, name def fetch_attachment(docid, name)
slug = escape_docid(docid) slug = escape_docid(docid)
name = CGI.escape(name) name = CGI.escape(name)
RestClient.get "#{@root}/#{slug}/#{name}" RestClient.get "#{@uri}/#{slug}/#{name}"
end end
# PUT an attachment directly to CouchDB # PUT an attachment directly to CouchDB
def put_attachment doc, name, file, options = {} def put_attachment(doc, name, file, options = {})
docid = escape_docid(doc['_id']) docid = escape_docid(doc['_id'])
name = CGI.escape(name) name = CGI.escape(name)
uri = if doc['_rev'] uri = if doc['_rev']
"#{@root}/#{docid}/#{name}?rev=#{doc['_rev']}" "#{@uri}/#{docid}/#{name}?rev=#{doc['_rev']}"
else else
"#{@root}/#{docid}/#{name}" "#{@uri}/#{docid}/#{name}"
end end
JSON.parse(RestClient.put(uri, file, options)) JSON.parse(RestClient.put(uri, file, options))
@ -115,7 +115,7 @@ module CouchRest
# #
# If <tt>bulk</tt> is true (false by default) the document is cached for bulk-saving later. # 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. # 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'] if doc['_attachments']
doc['_attachments'] = encode_attachments(doc['_attachments']) doc['_attachments'] = encode_attachments(doc['_attachments'])
end end
@ -128,13 +128,13 @@ module CouchRest
end end
result = if doc['_id'] result = if doc['_id']
slug = escape_docid(doc['_id']) slug = escape_docid(doc['_id'])
CouchRest.put "#{@root}/#{slug}", doc CouchRest.put "#{@uri}/#{slug}", doc
else else
begin begin
slug = doc['_id'] = @server.next_uuid slug = doc['_id'] = @server.next_uuid
CouchRest.put "#{@root}/#{slug}", doc CouchRest.put "#{@uri}/#{slug}", doc
rescue #old version of couchdb rescue #old version of couchdb
CouchRest.post @root, doc CouchRest.post @uri, doc
end end
end end
if result['ok'] if result['ok']
@ -145,6 +145,13 @@ module CouchRest
result result
end 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 # POST an array of documents to CouchDB. If any of the documents are
# missing ids, supply one from the uuid cache. # missing ids, supply one from the uuid cache.
# #
@ -162,7 +169,7 @@ module CouchRest
doc['_id'] = nextid if nextid doc['_id'] = nextid if nextid
end end
end end
CouchRest.post "#{@root}/_bulk_docs", {:docs => docs} CouchRest.post "#{@uri}/_bulk_docs", {:docs => docs}
end end
# DELETE the document from CouchDB that has the given <tt>_id</tt> and # DELETE the document from CouchDB that has the given <tt>_id</tt> and
@ -170,7 +177,7 @@ module CouchRest
# #
# If <tt>bulk</tt> is true (false by default) the deletion is recorded for bulk-saving (bulk-deletion :) later. # 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. # 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'] raise ArgumentError, "_id and _rev required for deleting" unless doc['_id'] && doc['_rev']
if bulk if bulk
@bulk_save_cache << { '_id' => doc['_id'], '_rev' => doc['_rev'], '_deleted' => true } @bulk_save_cache << { '_id' => doc['_id'], '_rev' => doc['_rev'], '_deleted' => true }
@ -178,13 +185,19 @@ module CouchRest
return { "ok" => true } # Mimic the non-deferred version return { "ok" => true } # Mimic the non-deferred version
end end
slug = escape_docid(doc['_id']) 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 end
# COPY an existing document to a new id. If the destination id currently exists, a rev must be provided. # 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 # <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 # hash with a '_rev' key
def copy doc, dest def copy_doc(doc, dest)
raise ArgumentError, "_id is required for copying" unless doc['_id'] raise ArgumentError, "_id is required for copying" unless doc['_id']
slug = escape_docid(doc['_id']) slug = escape_docid(doc['_id'])
destination = if dest.respond_to?(:has_key?) && dest['_id'] && dest['_rev'] destination = if dest.respond_to?(:has_key?) && dest['_id'] && dest['_rev']
@ -192,13 +205,19 @@ module CouchRest
else else
dest dest
end 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 end
# MOVE an existing document to a new id. If the destination id currently exists, a rev must be provided. # 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 # <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 # 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'] raise ArgumentError, "_id and _rev are required for moving" unless doc['_id'] && doc['_rev']
slug = escape_docid(doc['_id']) slug = escape_docid(doc['_id'])
destination = if dest.respond_to?(:has_key?) && dest['_id'] && dest['_rev'] destination = if dest.respond_to?(:has_key?) && dest['_id'] && dest['_rev']
@ -206,27 +225,48 @@ module CouchRest
else else
dest dest
end 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 end
# Compact the database, removing old document revisions and optimizing space use. # Compact the database, removing old document revisions and optimizing space use.
def compact! 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 end
# DELETE the database itself. This is not undoable and could be rather # DELETE the database itself. This is not undoable and could be rather
# catastrophic. Use with care! # catastrophic. Use with care!
def delete! def delete!
CouchRest.delete @root CouchRest.delete @uri
end end
private private
def escape_docid id def escape_docid(id)
/^_design\/(.*)/ =~ id ? "_design/#{CGI.escape($1)}" : CGI.escape(id) /^_design\/(.*)/ =~ id ? "_design/#{CGI.escape($1)}" : CGI.escape(id)
end end
def encode_attachments attachments def encode_attachments(attachments)
attachments.each do |k,v| attachments.each do |k,v|
next if v['stub'] next if v['stub']
v['data'] = base64(v['data']) v['data'] = base64(v['data'])
@ -234,7 +274,7 @@ module CouchRest
attachments attachments
end end
def base64 data def base64(data)
Base64.encode64(data).gsub(/\s/,'') Base64.encode64(data).gsub(/\s/,'')
end end
end end

View file

@ -38,7 +38,7 @@ module CouchRest
# If <tt>bulk</tt> is <tt>true</tt> (defaults to false) the document is cached for bulk save. # If <tt>bulk</tt> is <tt>true</tt> (defaults to false) the document is cached for bulk save.
def save(bulk = false) def save(bulk = false)
raise ArgumentError, "doc.database required for saving" unless database raise ArgumentError, "doc.database required for saving" unless database
result = database.save self, bulk result = database.save_doc self, bulk
result['ok'] result['ok']
end end
@ -49,7 +49,7 @@ module CouchRest
# actually be deleted from the db until bulk save. # actually be deleted from the db until bulk save.
def destroy(bulk = false) def destroy(bulk = false)
raise ArgumentError, "doc.database required to destroy" unless database raise ArgumentError, "doc.database required to destroy" unless database
result = database.delete(self, bulk) result = database.delete_doc(self, bulk)
if result['ok'] if result['ok']
self['_rev'] = nil self['_rev'] = nil
self['_id'] = nil self['_id'] = nil
@ -59,13 +59,13 @@ module CouchRest
def copy(dest) def copy(dest)
raise ArgumentError, "doc.database required to copy" unless database raise ArgumentError, "doc.database required to copy" unless database
result = database.copy(self, dest) result = database.copy_doc(self, dest)
result['ok'] result['ok']
end end
def move(dest) def move(dest)
raise ArgumentError, "doc.database required to copy" unless database raise ArgumentError, "doc.database required to copy" unless database
result = database.move(self, dest) result = database.move_doc(self, dest)
result['ok'] result['ok']
end end

View file

@ -365,7 +365,7 @@ module CouchRest
ddocs = all_design_doc_versions ddocs = all_design_doc_versions
ddocs["rows"].each do |row| ddocs["rows"].each do |row|
if (row['id'] != design_doc_id) if (row['id'] != design_doc_id)
database.delete({ database.delete_doc({
"_id" => row['id'], "_id" => row['id'],
"_rev" => row['value']['rev'] "_rev" => row['value']['rev']
}) })
@ -485,9 +485,11 @@ module CouchRest
alias :new_record? :new_document? alias :new_record? :new_document?
# Overridden to set the unique ID. # Overridden to set the unique ID.
# Returns a boolean value
def save bulk = false def save bulk = false
set_unique_id if new_document? && self.respond_to?(:set_unique_id) set_unique_id if new_document? && self.respond_to?(:set_unique_id)
super(bulk) result = database.save_doc(self, bulk)
result["ok"] == true
end end
# Saves the document to the db using create or update. Raises an exception # 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 # Removes the <tt>_id</tt> and <tt>_rev</tt> fields, preparing the
# document to be saved to a new <tt>_id</tt>. # document to be saved to a new <tt>_id</tt>.
def destroy def destroy
result = database.delete self result = database.delete_doc self
if result['ok'] if result['ok']
self['_rev'] = nil self['_rev'] = nil
self['_id'] = nil self['_id'] = nil

View file

@ -61,7 +61,7 @@ describe CouchRest::Database do
emit(doc.word,null); emit(doc.word,null);
} }
}'}} }'}}
@db.save({ @db.save_doc({
"_id" => "_design/test", "_id" => "_design/test",
:views => @view :views => @view
}) })
@ -80,7 +80,7 @@ describe CouchRest::Database do
describe "select from an existing view" do describe "select from an existing view" do
before(:each) do before(:each) do
r = @db.save({ r = @db.save_doc({
"_id" => "_design/first", "_id" => "_design/first",
:views => { :views => {
:test => { :test => {
@ -129,9 +129,9 @@ describe CouchRest::Database do
describe "GET (document by id) when the doc exists" do describe "GET (document by id) when the doc exists" do
before(:each) do before(:each) do
@r = @db.save({'lemons' => 'from texas', 'and' => 'spain'}) @r = @db.save_doc({'lemons' => 'from texas', 'and' => 'spain'})
@docid = "http://example.com/stuff.cgi?things=and%20stuff" @docid = "http://example.com/stuff.cgi?things=and%20stuff"
@db.save({'_id' => @docid, 'will-exist' => 'here'}) @db.save_doc({'_id' => @docid, 'will-exist' => 'here'})
end end
it "should get the document" do it "should get the document" do
doc = @db.get(@r['id']) doc = @db.get(@r['id'])
@ -176,7 +176,7 @@ describe CouchRest::Database do
end end
it "in the case of an id conflict should not insert anything" do it "in the case of an id conflict should not insert anything" do
@r = @db.save({'lemons' => 'from texas', 'and' => 'how', "_id" => "oneB"}) @r = @db.save_doc({'lemons' => 'from texas', 'and' => 'how', "_id" => "oneB"})
lambda do lambda do
rs = @db.bulk_save([ rs = @db.bulk_save([
@ -192,7 +192,7 @@ describe CouchRest::Database do
end end
it "should empty the bulk save cache if no documents are given" do it "should empty the bulk save cache if no documents are given" do
@db.save({"_id" => "bulk_cache_1", "val" => "test"}, true) @db.save_doc({"_id" => "bulk_cache_1", "val" => "test"}, true)
lambda do lambda do
@db.get('bulk_cache_1') @db.get('bulk_cache_1')
end.should raise_error(RestClient::ResourceNotFound) end.should raise_error(RestClient::ResourceNotFound)
@ -201,7 +201,7 @@ describe CouchRest::Database do
end end
it "should raise an error that is useful for recovery" do it "should raise an error that is useful for recovery" do
@r = @db.save({"_id" => "taken", "field" => "stuff"}) @r = @db.save_doc({"_id" => "taken", "field" => "stuff"})
begin begin
rs = @db.bulk_save([ rs = @db.bulk_save([
{"_id" => "taken", "wild" => "and random"}, {"_id" => "taken", "wild" => "and random"},
@ -220,13 +220,13 @@ describe CouchRest::Database do
@db.documents["total_rows"].should == 0 @db.documents["total_rows"].should == 0
end end
it "should create the document and return the id" do it "should create the document and return the id" do
r = @db.save({'lemons' => 'from texas', 'and' => 'spain'}) r = @db.save_doc({'lemons' => 'from texas', 'and' => 'spain'})
r2 = @db.get(r['id']) r2 = @db.get(r['id'])
r2["lemons"].should == "from texas" r2["lemons"].should == "from texas"
end end
it "should use PUT with UUIDs" do it "should use PUT with UUIDs" do
CouchRest.should_receive(:put).and_return({"ok" => true, "id" => "100", "rev" => "55"}) CouchRest.should_receive(:put).and_return({"ok" => true, "id" => "100", "rev" => "55"})
r = @db.save({'just' => ['another document']}) r = @db.save_doc({'just' => ['another document']})
end end
end end
@ -260,7 +260,7 @@ describe CouchRest::Database do
} }
} }
} }
@db.save(@doc) @db.save_doc(@doc)
end end
it "should save and be indicated" do it "should save and be indicated" do
doc = @db.get("mydocwithattachment") doc = @db.get("mydocwithattachment")
@ -284,10 +284,10 @@ describe CouchRest::Database do
} }
} }
} }
@db.save(doc) @db.save_doc(doc)
doc = @db.get('mydocwithattachment') doc = @db.get('mydocwithattachment')
doc['field'] << 'another value' doc['field'] << 'another value'
@db.save(doc) @db.save_doc(doc)
end end
it 'should be there' do it 'should be there' do
@ -314,7 +314,7 @@ describe CouchRest::Database do
} }
} }
} }
@db.save(@doc) @db.save_doc(@doc)
end end
it "should save and be indicated" do it "should save and be indicated" do
doc = @db.get("mydocwithattachment") doc = @db.get("mydocwithattachment")
@ -343,7 +343,7 @@ describe CouchRest::Database do
} }
} }
} }
@docid = @db.save(@doc)['id'] @docid = @db.save_doc(@doc)['id']
end end
it "should save and be indicated" do it "should save and be indicated" do
doc = @db.get(@docid) doc = @db.get(@docid)
@ -358,15 +358,15 @@ describe CouchRest::Database do
describe "PUT (new document with url id)" do describe "PUT (new document with url id)" do
it "should create the document" do it "should create the document" do
@docid = "http://example.com/stuff.cgi?things=and%20stuff" @docid = "http://example.com/stuff.cgi?things=and%20stuff"
@db.save({'_id' => @docid, 'will-exist' => 'here'}) @db.save_doc({'_id' => @docid, 'will-exist' => 'here'})
lambda{@db.save({'_id' => @docid})}.should raise_error(RestClient::Request::RequestFailed) lambda{@db.save_doc({'_id' => @docid})}.should raise_error(RestClient::Request::RequestFailed)
@db.get(@docid)['will-exist'].should == 'here' @db.get(@docid)['will-exist'].should == 'here'
end end
end end
describe "PUT (new document with id)" do describe "PUT (new document with id)" do
it "should start without the document" do it "should start without the document" do
# r = @db.save({'lemons' => 'from texas', 'and' => 'spain'}) # r = @db.save_doc({'lemons' => 'from texas', 'and' => 'spain'})
@db.documents['rows'].each do |doc| @db.documents['rows'].each do |doc|
doc['id'].should_not == 'my-doc' doc['id'].should_not == 'my-doc'
end end
@ -375,17 +375,17 @@ describe CouchRest::Database do
# or instead make it return something with a fancy <=> method # or instead make it return something with a fancy <=> method
end end
it "should create the document" do it "should create the document" do
@db.save({'_id' => 'my-doc', 'will-exist' => 'here'}) @db.save_doc({'_id' => 'my-doc', 'will-exist' => 'here'})
lambda{@db.save({'_id' => 'my-doc'})}.should raise_error(RestClient::Request::RequestFailed) lambda{@db.save_doc({'_id' => 'my-doc'})}.should raise_error(RestClient::Request::RequestFailed)
end end
end end
describe "PUT (existing document with rev)" do describe "PUT (existing document with rev)" do
before(:each) do before(:each) do
@db.save({'_id' => 'my-doc', 'will-exist' => 'here'}) @db.save_doc({'_id' => 'my-doc', 'will-exist' => 'here'})
@doc = @db.get('my-doc') @doc = @db.get('my-doc')
@docid = "http://example.com/stuff.cgi?things=and%20stuff" @docid = "http://example.com/stuff.cgi?things=and%20stuff"
@db.save({'_id' => @docid, 'now' => 'save'}) @db.save_doc({'_id' => @docid, 'now' => 'save'})
end end
it "should start with the document" do it "should start with the document" do
@doc['will-exist'].should == 'here' @doc['will-exist'].should == 'here'
@ -394,18 +394,18 @@ describe CouchRest::Database do
it "should save with url id" do it "should save with url id" do
doc = @db.get(@docid) doc = @db.get(@docid)
doc['yaml'] = ['json', 'word.'] doc['yaml'] = ['json', 'word.']
@db.save doc @db.save_doc doc
@db.get(@docid)['yaml'].should == ['json', 'word.'] @db.get(@docid)['yaml'].should == ['json', 'word.']
end end
it "should fail to resave without the rev" do it "should fail to resave without the rev" do
@doc['them-keys'] = 'huge' @doc['them-keys'] = 'huge'
@doc['_rev'] = 'wrong' @doc['_rev'] = 'wrong'
# @db.save(@doc) # @db.save_doc(@doc)
lambda {@db.save(@doc)}.should raise_error lambda {@db.save_doc(@doc)}.should raise_error
end end
it "should update the document" do it "should update the document" do
@doc['them-keys'] = 'huge' @doc['them-keys'] = 'huge'
@db.save(@doc) @db.save_doc(@doc)
now = @db.get('my-doc') now = @db.get('my-doc')
now['them-keys'].should == 'huge' now['them-keys'].should == 'huge'
end end
@ -414,7 +414,7 @@ describe CouchRest::Database do
describe "cached bulk save" do describe "cached bulk save" do
it "stores documents in a database-specific cache" do it "stores documents in a database-specific cache" do
td = {"_id" => "btd1", "val" => "test"} td = {"_id" => "btd1", "val" => "test"}
@db.save(td, true) @db.save_doc(td, true)
@db.instance_variable_get("@bulk_save_cache").should == [td] @db.instance_variable_get("@bulk_save_cache").should == [td]
end end
@ -423,8 +423,8 @@ describe CouchRest::Database do
@db.bulk_save_cache_limit = 3 @db.bulk_save_cache_limit = 3
td1 = {"_id" => "td1", "val" => true} td1 = {"_id" => "td1", "val" => true}
td2 = {"_id" => "td2", "val" => 4} td2 = {"_id" => "td2", "val" => 4}
@db.save(td1, true) @db.save_doc(td1, true)
@db.save(td2, true) @db.save_doc(td2, true)
lambda do lambda do
@db.get(td1["_id"]) @db.get(td1["_id"])
end.should raise_error(RestClient::ResourceNotFound) end.should raise_error(RestClient::ResourceNotFound)
@ -432,7 +432,7 @@ describe CouchRest::Database do
@db.get(td2["_id"]) @db.get(td2["_id"])
end.should raise_error(RestClient::ResourceNotFound) end.should raise_error(RestClient::ResourceNotFound)
td3 = {"_id" => "td3", "val" => "foo"} td3 = {"_id" => "td3", "val" => "foo"}
@db.save(td3, true) @db.save_doc(td3, true)
@db.get(td1["_id"])["val"].should == td1["val"] @db.get(td1["_id"])["val"].should == td1["val"]
@db.get(td2["_id"])["val"].should == td2["val"] @db.get(td2["_id"])["val"].should == td2["val"]
@db.get(td3["_id"])["val"].should == td3["val"] @db.get(td3["_id"])["val"].should == td3["val"]
@ -442,11 +442,11 @@ describe CouchRest::Database do
td1 = {"_id" => "blah", "val" => true} td1 = {"_id" => "blah", "val" => true}
td2 = {"_id" => "steve", "val" => 3} td2 = {"_id" => "steve", "val" => 3}
@db.bulk_save_cache_limit = 50 @db.bulk_save_cache_limit = 50
@db.save(td1, true) @db.save_doc(td1, true)
lambda do lambda do
@db.get(td1["_id"]) @db.get(td1["_id"])
end.should raise_error(RestClient::ResourceNotFound) end.should raise_error(RestClient::ResourceNotFound)
@db.save(td2) @db.save_doc(td2)
@db.get(td1["_id"])["val"].should == td1["val"] @db.get(td1["_id"])["val"].should == td1["val"]
@db.get(td2["_id"])["val"].should == td2["val"] @db.get(td2["_id"])["val"].should == td2["val"]
end end
@ -454,27 +454,27 @@ describe CouchRest::Database do
describe "DELETE existing document" do describe "DELETE existing document" do
before(:each) do before(:each) do
@r = @db.save({'lemons' => 'from texas', 'and' => 'spain'}) @r = @db.save_doc({'lemons' => 'from texas', 'and' => 'spain'})
@docid = "http://example.com/stuff.cgi?things=and%20stuff" @docid = "http://example.com/stuff.cgi?things=and%20stuff"
@db.save({'_id' => @docid, 'will-exist' => 'here'}) @db.save_doc({'_id' => @docid, 'will-exist' => 'here'})
end end
it "should work" do it "should work" do
doc = @db.get(@r['id']) doc = @db.get(@r['id'])
doc['and'].should == 'spain' doc['and'].should == 'spain'
@db.delete doc @db.delete_doc doc
lambda{@db.get @r['id']}.should raise_error lambda{@db.get @r['id']}.should raise_error
end end
it "should work with uri id" do it "should work with uri id" do
doc = @db.get(@docid) doc = @db.get(@docid)
@db.delete doc @db.delete_doc doc
lambda{@db.get @docid}.should raise_error lambda{@db.get @docid}.should raise_error
end end
it "should fail without an _id" do it "should fail without an _id" do
lambda{@db.delete({"not"=>"a real doc"})}.should raise_error(ArgumentError) lambda{@db.delete_doc({"not"=>"a real doc"})}.should raise_error(ArgumentError)
end end
it "should defer actual deletion when using bulk save" do it "should defer actual deletion when using bulk save" do
doc = @db.get(@docid) doc = @db.get(@docid)
@db.delete doc, true @db.delete_doc doc, true
lambda{@db.get @docid}.should_not raise_error lambda{@db.get @docid}.should_not raise_error
@db.bulk_save @db.bulk_save
lambda{@db.get @docid}.should raise_error lambda{@db.get @docid}.should raise_error
@ -484,13 +484,13 @@ describe CouchRest::Database do
describe "COPY existing document" do describe "COPY existing document" do
before :each do before :each do
@r = @db.save({'artist' => 'Zappa', 'title' => 'Muffin Man'}) @r = @db.save_doc({'artist' => 'Zappa', 'title' => 'Muffin Man'})
@docid = 'tracks/zappa/muffin-man' @docid = 'tracks/zappa/muffin-man'
@doc = @db.get(@r['id']) @doc = @db.get(@r['id'])
end end
describe "to a new location" do describe "to a new location" do
it "should work" do it "should work" do
@db.copy @doc, @docid @db.copy_doc @doc, @docid
newdoc = @db.get(@docid) newdoc = @db.get(@docid)
newdoc['artist'].should == 'Zappa' newdoc['artist'].should == 'Zappa'
end end
@ -500,20 +500,20 @@ describe CouchRest::Database do
end end
describe "to an existing location" do describe "to an existing location" do
before :each do before :each do
@db.save({'_id' => @docid, 'will-exist' => 'here'}) @db.save_doc({'_id' => @docid, 'will-exist' => 'here'})
end end
it "should fail without a rev" do it "should fail without a rev" do
lambda{@db.copy @doc, @docid}.should raise_error(RestClient::RequestFailed) lambda{@db.copy_doc @doc, @docid}.should raise_error(RestClient::RequestFailed)
end end
it "should succeed with a rev" do it "should succeed with a rev" do
@to_be_overwritten = @db.get(@docid) @to_be_overwritten = @db.get(@docid)
@db.copy @doc, "#{@docid}?rev=#{@to_be_overwritten['_rev']}" @db.copy_doc @doc, "#{@docid}?rev=#{@to_be_overwritten['_rev']}"
newdoc = @db.get(@docid) newdoc = @db.get(@docid)
newdoc['artist'].should == 'Zappa' newdoc['artist'].should == 'Zappa'
end end
it "should succeed given the doc to overwrite" do it "should succeed given the doc to overwrite" do
@to_be_overwritten = @db.get(@docid) @to_be_overwritten = @db.get(@docid)
@db.copy @doc, @to_be_overwritten @db.copy_doc @doc, @to_be_overwritten
newdoc = @db.get(@docid) newdoc = @db.get(@docid)
newdoc['artist'].should == 'Zappa' newdoc['artist'].should == 'Zappa'
end end
@ -522,13 +522,13 @@ describe CouchRest::Database do
describe "MOVE existing document" do describe "MOVE existing document" do
before :each do before :each do
@r = @db.save({'artist' => 'Zappa', 'title' => 'Muffin Man'}) @r = @db.save_doc({'artist' => 'Zappa', 'title' => 'Muffin Man'})
@docid = 'tracks/zappa/muffin-man' @docid = 'tracks/zappa/muffin-man'
@doc = @db.get(@r['id']) @doc = @db.get(@r['id'])
end end
describe "to a new location" do describe "to a new location" do
it "should work" do it "should work" do
@db.move @doc, @docid @db.move_doc @doc, @docid
newdoc = @db.get(@docid) newdoc = @db.get(@docid)
newdoc['artist'].should == 'Zappa' newdoc['artist'].should == 'Zappa'
lambda {@db.get(@r['id'])}.should raise_error(RestClient::ResourceNotFound) lambda {@db.get(@r['id'])}.should raise_error(RestClient::ResourceNotFound)
@ -540,22 +540,22 @@ describe CouchRest::Database do
end end
describe "to an existing location" do describe "to an existing location" do
before :each do before :each do
@db.save({'_id' => @docid, 'will-exist' => 'here'}) @db.save_doc({'_id' => @docid, 'will-exist' => 'here'})
end end
it "should fail without a rev" do it "should fail without a rev" do
lambda{@db.move @doc, @docid}.should raise_error(RestClient::RequestFailed) lambda{@db.move_doc @doc, @docid}.should raise_error(RestClient::RequestFailed)
lambda{@db.get(@r['id'])}.should_not raise_error lambda{@db.get(@r['id'])}.should_not raise_error
end end
it "should succeed with a rev" do it "should succeed with a rev" do
@to_be_overwritten = @db.get(@docid) @to_be_overwritten = @db.get(@docid)
@db.move @doc, "#{@docid}?rev=#{@to_be_overwritten['_rev']}" @db.move_doc @doc, "#{@docid}?rev=#{@to_be_overwritten['_rev']}"
newdoc = @db.get(@docid) newdoc = @db.get(@docid)
newdoc['artist'].should == 'Zappa' newdoc['artist'].should == 'Zappa'
lambda {@db.get(@r['id'])}.should raise_error(RestClient::ResourceNotFound) lambda {@db.get(@r['id'])}.should raise_error(RestClient::ResourceNotFound)
end end
it "should succeed given the doc to overwrite" do it "should succeed given the doc to overwrite" do
@to_be_overwritten = @db.get(@docid) @to_be_overwritten = @db.get(@docid)
@db.move @doc, @to_be_overwritten @db.move_doc @doc, @to_be_overwritten
newdoc = @db.get(@docid) newdoc = @db.get(@docid)
newdoc['artist'].should == 'Zappa' newdoc['artist'].should == 'Zappa'
lambda {@db.get(@r['id'])}.should raise_error(RestClient::ResourceNotFound) lambda {@db.get(@r['id'])}.should raise_error(RestClient::ResourceNotFound)
@ -566,7 +566,7 @@ describe CouchRest::Database do
it "should list documents" do it "should list documents" do
5.times do 5.times do
@db.save({'another' => 'doc', 'will-exist' => 'anywhere'}) @db.save_doc({'another' => 'doc', 'will-exist' => 'anywhere'})
end end
ds = @db.documents ds = @db.documents
ds['rows'].should be_an_instance_of(Array) ds['rows'].should be_an_instance_of(Array)
@ -577,7 +577,7 @@ describe CouchRest::Database do
describe "documents / _all_docs" do describe "documents / _all_docs" do
before(:each) do before(:each) do
9.times do |i| 9.times do |i|
@db.save({'_id' => "doc#{i}",'another' => 'doc', 'will-exist' => 'here'}) @db.save_doc({'_id' => "doc#{i}",'another' => 'doc', 'will-exist' => 'here'})
end end
end end
it "should list documents with keys and such" do it "should list documents with keys and such" do
@ -625,5 +625,40 @@ describe CouchRest::Database do
end end
end end
describe "creating a database" do
before(:each) do
@db = @cr.database('couchrest-test-db_to_create')
@db.delete!
end
it "should just work fine" do
@cr.databases.should_not include('couchrest-test-db_to_create')
@db.create!
@cr.databases.should include('couchrest-test-db_to_create')
end
end
describe "recreating a database" do
before(:each) do
@db = @cr.database('couchrest-test-db_to_create')
@db2 = @cr.database('couchrest-test-db_to_recreate')
@cr.databases.include?(@db.name) ? nil : @db.create!
@cr.databases.include?(@db2.name) ? @db2.delete! : nil
end
it "should drop and recreate a database" do
@cr.databases.should include(@db.name)
@db.recreate!
@cr.databases.should include(@db.name)
end
it "should recreate a db even tho it doesn't exist" do
@cr.databases.should_not include(@db2.name)
@db2.recreate!
@cr.databases.should include(@db2.name)
end
end
end end

View file

@ -62,7 +62,7 @@ describe CouchRest::Design do
describe "from a saved document" do describe "from a saved document" do
before(:each) do before(:each) do
@db = reset_test_db! @db = reset_test_db!
@db.save({ @db.save_doc({
"_id" => "_design/test", "_id" => "_design/test",
"views" => { "views" => {
"by_name" => { "by_name" => {

View file

@ -42,7 +42,7 @@ describe CouchRest::Document, "saving using a database" do
before(:all) do before(:all) do
@doc = CouchRest::Document.new("key" => [1,2,3], :more => "values") @doc = CouchRest::Document.new("key" => [1,2,3], :more => "values")
@db = reset_test_db! @db = reset_test_db!
@resp = @db.save(@doc) @resp = @db.save_doc(@doc)
end end
it "should apply the database" do it "should apply the database" do
@doc.database.should == @db @doc.database.should == @db
@ -71,7 +71,7 @@ end
describe "getting from a database" do describe "getting from a database" do
before(:all) do before(:all) do
@db = reset_test_db! @db = reset_test_db!
@resp = @db.save({ @resp = @db.save_doc({
"key" => "value" "key" => "value"
}) })
@doc = @db.get @resp['id'] @doc = @db.get @resp['id']
@ -95,7 +95,7 @@ end
describe "destroying a document from a db" do describe "destroying a document from a db" do
before(:all) do before(:all) do
@db = reset_test_db! @db = reset_test_db!
@resp = @db.save({ @resp = @db.save_doc({
"key" => "value" "key" => "value"
}) })
@doc = @db.get @resp['id'] @doc = @db.get @resp['id']
@ -114,7 +114,7 @@ end
describe "destroying a document from a db using bulk save" do describe "destroying a document from a db using bulk save" do
before(:all) do before(:all) do
@db = reset_test_db! @db = reset_test_db!
@resp = @db.save({ @resp = @db.save_doc({
"key" => "value" "key" => "value"
}) })
@doc = @db.get @resp['id'] @doc = @db.get @resp['id']
@ -132,7 +132,7 @@ end
describe "copying a document" do describe "copying a document" do
before :each do before :each do
@db = reset_test_db! @db = reset_test_db!
@resp = @db.save({'key' => 'value'}) @resp = @db.save_doc({'key' => 'value'})
@docid = 'new-location' @docid = 'new-location'
@doc = @db.get(@resp['id']) @doc = @db.get(@resp['id'])
end end
@ -148,7 +148,7 @@ describe "copying a document" do
end end
describe "to an existing location" do describe "to an existing location" do
before :each do before :each do
@db.save({'_id' => @docid, 'will-exist' => 'here'}) @db.save_doc({'_id' => @docid, 'will-exist' => 'here'})
end end
it "should fail without a rev" do it "should fail without a rev" do
lambda{@doc.copy @docid}.should raise_error(RestClient::RequestFailed) lambda{@doc.copy @docid}.should raise_error(RestClient::RequestFailed)
@ -171,7 +171,7 @@ end
describe "MOVE existing document" do describe "MOVE existing document" do
before :each do before :each do
@db = reset_test_db! @db = reset_test_db!
@resp = @db.save({'key' => 'value'}) @resp = @db.save_doc({'key' => 'value'})
@docid = 'new-location' @docid = 'new-location'
@doc = @db.get(@resp['id']) @doc = @db.get(@resp['id'])
end end
@ -189,7 +189,7 @@ describe "MOVE existing document" do
end end
describe "to an existing location" do describe "to an existing location" do
before :each do before :each do
@db.save({'_id' => @docid, 'will-exist' => 'here'}) @db.save_doc({'_id' => @docid, 'will-exist' => 'here'})
end end
it "should fail without a rev" do it "should fail without a rev" do
lambda{@doc.move @docid}.should raise_error(RestClient::RequestFailed) lambda{@doc.move @docid}.should raise_error(RestClient::RequestFailed)

View file

@ -275,7 +275,7 @@ describe CouchRest::Model do
} }
] ]
} }
r = Course.database.save course_doc r = Course.database.save_doc course_doc
@course = Course.get r['id'] @course = Course.get r['id']
end end
it "should load the course" do it "should load the course" do
@ -336,7 +336,7 @@ describe CouchRest::Model do
}, },
"final_test_at" => "2008/12/19 13:00:00 +0800" "final_test_at" => "2008/12/19 13:00:00 +0800"
} }
r = Course.database.save course_doc r = Course.database.save_doc course_doc
@course = Course.get r['id'] @course = Course.get r['id']
end end
it "should load the course" do it "should load the course" do
@ -353,7 +353,7 @@ describe CouchRest::Model do
describe "cast keys to any type" do describe "cast keys to any type" do
before(:all) do before(:all) do
event_doc = { :subject => "Some event", :occurs_at => Time.now } event_doc = { :subject => "Some event", :occurs_at => Time.now }
e = Event.database.save event_doc e = Event.database.save_doc event_doc
@event = Event.get e['id'] @event = Event.get e['id']
end end
@ -408,7 +408,7 @@ describe CouchRest::Model do
before(:each) do before(:each) do
@art = Article.new @art = Article.new
@old = Article.database.get('this-is-the-title') rescue nil @old = Article.database.get('this-is-the-title') rescue nil
Article.database.delete(@old) if @old Article.database.delete_doc(@old) if @old
end end
it "should be a new document" do it "should be a new document" do
@ -538,7 +538,7 @@ describe CouchRest::Model do
end end
it "should not include non-Articles" do it "should not include non-Articles" do
Article.database.save({"date" => 1}) Article.database.save_doc({"date" => 1})
view = Article.by_date :raw => true view = Article.by_date :raw => true
view['rows'].length.should == 4 view['rows'].length.should == 4
end end
@ -591,7 +591,7 @@ describe CouchRest::Model do
describe "a ducktype view" do describe "a ducktype view" do
before(:all) do before(:all) do
@id = @db.save({:dept => true})['id'] @id = @db.save_doc({:dept => true})['id']
end end
it "should setup" do it "should setup" do
duck = Course.get(@id) # from a different db duck = Course.get(@id) # from a different db

View file

@ -60,7 +60,7 @@ describe CouchRest::Pager do
@docs << ({:number => (i % 10)}) @docs << ({:number => (i % 10)})
end end
@db.bulk_save(@docs) @db.bulk_save(@docs)
@db.save({ @db.save_doc({
'_id' => '_design/magic', '_id' => '_design/magic',
'views' => { 'views' => {
'number' => { 'number' => {