Permalink
Browse files

Working on doc migration support

  • Loading branch information...
1 parent d76b887 commit 1792e7b49199e22229453a434844f3d313feecca @samlown samlown committed Jun 10, 2012
Showing with 50 additions and 2 deletions.
  1. +1 −1 history.md
  2. +48 −0 lib/couchrest/model/designs/design.rb
  3. +1 −1 spec/unit/designs/design_spec.rb
View
@@ -4,7 +4,7 @@
* Completely refactored Design Document handling.
* Removed old `view` and `view_by` methods.
- * CouchRest::Model::Base.respond_to_missing? and respond_to? (Kim Burgestrand)
+ * CouchRest::Model::Base.respond_to_missing? and respond_to? (Kim Burgestrand) (later removed)
* Time#as_json now insists on using xmlschema with 3 fraction digits by default.
* Added time_fraction_digits configuration object
@@ -57,6 +57,54 @@ def sync!(db = nil)
self
end
+ # 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
+ #
+ # A status will be returned according to which method was used in
+ # the migration, if at all. The symbols are:
+ #
+ # * :no_change - Nothing performed as there are no changes.
+ # * :created - Add a new design doc as non existed
+ # * :migrated - Migrated the existing design doc.
+ #
+ #
+ def migrate!(db = nil)
+ doc = load_from_database(db)
+
+ if !doc
+ # no need to migrate, just save it
+ db.save_doc(to_hash)
+ :created
+ else doc['couchrest-hash'] != checksum
+ # Migration required
+ doc.merge!(to_hash)
+ doc['_id'] = self['_id']+"_#{Time.now.to_i}"
+ db.save_doc(doc)
+
+ # Create a view query and send
+ name = doc['views'].keys.first
+ view = doc['views'][name]
+ params = {:limit => 1}
+ params[:reduce => false] if view['reduce']
+ db.view(name, params)
+
+ # When that finishes, copy the design doc back
+ db.copy_doc(doc['_id'], self['_id'])
+
+ :migrated
+ else
+ # Already up to date
+ :no_change
+ end
+ end
+
def checksum
sum = self['couchrest-hash']
@@ -173,7 +173,7 @@ class DesignSampleModel < CouchRest::Model::Base
it "should provide same checksum without refresh on re-request" do
chk = @doc.checksum
- @doc.should_not_receive(:chaecksum!)
+ @doc.should_not_receive(:checksum!)
@doc.checksum.should eql(chk)
end

0 comments on commit 1792e7b

Please sign in to comment.