Merge branch 'master' of git://github.com/thewordnerd/couchrest

* 'master' of git://github.com/thewordnerd/couchrest:
  Removed model create/update callbacks and integrated with new bulk save infrastructure.
  Make bulk saving more flexible.
  Add support for database compaction.
This commit is contained in:
Matt Lyon 2008-12-19 02:15:02 -08:00
commit efae804920
6 changed files with 122 additions and 41 deletions

View file

@ -4,6 +4,7 @@ require "base64"
module CouchRest
class Database
attr_reader :server, :host, :name, :root
attr_accessor :bulk_save_cache_limit
# Create a CouchRest::Database adapter for the supplied CouchRest::Server
# and database name.
@ -18,6 +19,8 @@ module CouchRest
@host = server.uri
@root = "#{host}/#{name}"
@streamer = Streamer.new(self)
@bulk_save_cache = []
@bulk_save_cache_limit = 50
end
# returns the database's uri
@ -106,10 +109,20 @@ module CouchRest
# documents on the client side because POST has the curious property of
# being automatically retried by proxies in the event of network
# segmentation and lost responses.
def save doc
#
# 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)
if doc['_attachments']
doc['_attachments'] = encode_attachments(doc['_attachments'])
end
if bulk
@bulk_save_cache << doc
return bulk_save if @bulk_save_cache.length >= @bulk_save_cache_limit
return {"ok" => true} # Compatibility with Document#save
elsif !bulk && @bulk_save_cache.length > 0
bulk_save
end
result = if doc['_id']
slug = CGI.escape(doc['_id'])
CouchRest.put "#{@root}/#{slug}", doc
@ -131,7 +144,13 @@ module CouchRest
# POST an array of documents to CouchDB. If any of the documents are
# missing ids, supply one from the uuid cache.
def bulk_save docs
#
# If called with no arguments, bulk saves the cache of documents to be bulk saved.
def bulk_save (docs = nil)
if docs.nil?
docs = @bulk_save_cache
@bulk_save_cache = []
end
ids, noids = docs.partition{|d|d['_id']}
uuid_count = [noids.length, @server.uuid_batch_count].max
noids.each do |doc|
@ -149,7 +168,12 @@ module CouchRest
slug = CGI.escape(doc['_id'])
CouchRest.delete "#{@root}/#{slug}?rev=#{doc['_rev']}"
end
# Compact the database, removing old document revisions and optimizing space use.
def compact!
CouchRest.post "#{@root}/_compact"
end
# DELETE the database itself. This is not undoable and could be rather
# catastrophic. Use with care!
def delete!

View file

@ -35,9 +35,10 @@ module CouchRest
# Saves the document to the db using create or update. Also runs the :save
# callbacks. Sets the <tt>_id</tt> and <tt>_rev</tt> fields based on
# CouchDB's response.
def save
# 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
result = database.save self, bulk
result['ok']
end
@ -57,4 +58,4 @@ module CouchRest
end
end
end

View file

@ -215,8 +215,9 @@ module CouchRest
# on the document whenever saving occurs. CouchRest uses a pretty
# decent time format by default. See Time#to_json
def timestamps!
before(:create) do
self['updated_at'] = self['created_at'] = Time.now
before(:save) do
self['updated_at'] = Time.now
self['created_at'] = self['updated_at'] if new_document?
end
before(:update) do
self['updated_at'] = Time.now
@ -478,19 +479,10 @@ module CouchRest
# for compatibility with old-school frameworks
alias :new_record? :new_document?
# We override this to create the create and update callback opportunities.
# I think we should drop those and just have save. If you care, in your callback,
# check new_document?
def save actually=false
if actually
super()
else
if new_document?
create
else
update
end
end
# Overridden to set the unique ID.
def save bulk = false
set_unique_id if self.respond_to?(:set_unique_id)
super(bulk)
end
# Saves the document to the db using create or update. Raises an exception
@ -498,10 +490,6 @@ module CouchRest
def save!
raise "#{self.inspect} failed to save" unless self.save
end
def update
save :actually
end
# Deletes the document from the database. Runs the :delete callbacks.
# Removes the <tt>_id</tt> and <tt>_rev</tt> fields, preparing the
@ -515,12 +503,6 @@ module CouchRest
result['ok']
end
def create
# can we use the callbacks for this?
set_unique_id if self.respond_to?(:set_unique_id)
save :actually
end
private
def apply_defaults
@ -553,9 +535,7 @@ module CouchRest
end
include ::Extlib::Hook
# todo: drop create and update hooks...
# (use new_record? in callbacks if you care)
register_instance_hooks :save, :create, :update, :destroy
register_instance_hooks :save, :destroy
end # class Model
end # module CouchRest
end # module CouchRest