Module: CouchRest::Model::Designs::Migrations

Included in:
CouchRest::Model::Design
Defined in:
lib/couchrest/model/designs/migrations.rb

Overview

Design Document Migrations Support

A series of methods used inside design documents in order to perform migrations.

Instance Method Summary collapse

Instance Method Details

#migrate(db = nil) {|result| ... } ⇒ Object

Migrate the design document preventing downtime on a production system. Typically this will be used when auto updates are disabled.

Steps taken are:

1. Compare the checksum with the current version
2. If different, create a new design doc with timestamp
3. Wait until the view returns a result
4. Copy over the original design doc

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.

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

Yields:

  • (result)


42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/couchrest/model/designs/migrations.rb', line 42

def migrate(db = nil, &block)
  db    ||= database
  doc     = load_from_database(db)
  cleanup = nil
  id      = self['_id']

  if !doc
    # no need to migrate, just save it
    new_doc = to_hash.dup
    db.save_doc(new_doc)

    result = :created
  elsif doc['couchrest-hash'] != checksum
    id += "_migration"

    # Delete current migration if there is one
    old_migration = load_from_database(db, 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

  wait_for_view_update_completion(db, new_doc)

  yield result if block_given?

  cleanup
end

#migrate!(db = nil, &block) ⇒ Object

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


94
95
96
97
98
99
100
101
# File 'lib/couchrest/model/designs/migrations.rb', line 94

def migrate!(db = nil, &block)
  callback = migrate(db, &block)
  if callback.is_a?(Proc)
    callback.call
  else
    callback
  end
end