Skip to content

Commit

Permalink
Working on migration
Browse files Browse the repository at this point in the history
  • Loading branch information
samlown committed Jun 11, 2012
1 parent 1792e7b commit a132821
Showing 1 changed file with 68 additions and 19 deletions.
87 changes: 68 additions & 19 deletions lib/couchrest/model/designs/design.rb
Expand Up @@ -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)
Expand Down

0 comments on commit a132821

Please sign in to comment.