Skip to content
Browse files

Working on migration

  • Loading branch information...
1 parent 1792e7b commit a1328211b04c7574c58497c909fc7889f29ea49a @samlown samlown committed Jun 11, 2012
Showing with 68 additions and 19 deletions.
  1. +68 −19 lib/couchrest/model/designs/design.rb
View
87 lib/couchrest/model/designs/design.rb
@@ -67,45 +67,94 @@ def sync!(db = nil)
# 3. Wait until the view returns a result
# 4. Copy over the original design doc
#
- # A status will be returned according to which method was used in
- # the migration, if at all. The symbols are:
+ # If a block is provided, it will be called with the result of the migration:
#
# * :no_change - Nothing performed as there are no changes.
# * :created - Add a new design doc as non existed
# * :migrated - Migrated the existing design doc.
#
+ # This can be used for progressivly printing the results of the migration.
#
- def migrate!(db = nil)
- doc = load_from_database(db)
+ # After completion, either a "cleanup" Proc object will be provided to finalize
+ # the process and copy the document into place, or simply nil if no cleanup is
+ # required. For example:
+ #
+ # print "Synchronising Cat model designs: "
+ # callback = Cat.design_doc.migrate do |res|
+ # puts res.to_s
+ # end
+ # if callback
+ # puts "Cleaning up."
+ # callback.call
+ # end
+ #
+ def migrate(db = nil, &block)
+ doc = load_from_database(db)
+ cleanup = nil
if !doc
# no need to migrate, just save it
- db.save_doc(to_hash)
- :created
+ new_doc = to_hash.dup
+ db.save_doc(new_doc)
+
+ result = :created
else doc['couchrest-hash'] != checksum
- # Migration required
- doc.merge!(to_hash)
- doc['_id'] = self['_id']+"_#{Time.now.to_i}"
- db.save_doc(doc)
+ id = self['_id'] + "_migration"
+
+ # Delete current migration if there is one
+ old_migration = db.get(id)
+ db.delete_doc(old_migration) if old_migration
+
+ # Save new design doc
+ new_doc = doc.merge(to_hash)
+ new_doc['_id'] = id
+ new_doc.delete('_rev')
+ db.save_doc(new_doc)
+
+ # Proc definition to copy the migration doc over the original
+ cleanup = Proc.new do
+ db.copy_doc(new_doc, doc)
+ db.delete_doc(new_doc)
+ self
+ end
+ result = :migrated
+ else
+ # Already up to date
+ result = :no_change
+ end
+
+ if new_doc && !new_doc['views'].empty?
# Create a view query and send
- name = doc['views'].keys.first
- view = doc['views'][name]
+ name = new_doc['views'].keys.first
+ view = new_doc['views'][name]
params = {:limit => 1}
- params[:reduce => false] if view['reduce']
+ params[:reduce] = false if view['reduce']
db.view(name, params)
+ end
- # When that finishes, copy the design doc back
- db.copy_doc(doc['_id'], self['_id'])
+ # Provide the result in block
+ yield result if block_given?
+
+ cleanup
+ end
- :migrated
+ # Perform a single migration and inmediatly request a cleanup operation:
+ #
+ # print "Synchronising Cat model designs: "
+ # Cat.design_doc.migrate! do |res|
+ # puts res.to_s
+ # end
+ #
+ def migrate!(db = nil, &block)
+ callback = migrate(db, &block)
+ if callback.is_a?(Proc)
+ callback.call
else
- # Already up to date
- :no_change
+ callback
end
end
-
def checksum
sum = self['couchrest-hash']
if sum && (@_original_hash == to_hash)

0 comments on commit a132821

Please sign in to comment.
Something went wrong with that request. Please try again.