module MongoidVersionedAtomic::VAtomic

Public Class Methods

included(base) click to toggle source
# File lib/mongoid_versioned_atomic/v_atomic.rb, line 31
def self.included(base)
    base.extend(ClassMethods)
end

Public Instance Methods

filter_fields() click to toggle source
removes "version" and "op_success" fields from the document before save or update, this ensures that these fields can only be persisted by the versioned_create and versioned_update methods.
prevents inadvertent persistence of these fields.

return attributes : the document as a set of key-value fields.

# File lib/mongoid_versioned_atomic/v_atomic.rb, line 166
def filter_fields

   remove_attribute(:version)
   remove_attribute(:op_success)
   attributes

   
end
versioned_create(query={},log=false) click to toggle source

after_persist sets the fields in the persisted document on the instance.

# File lib/mongoid_versioned_atomic/v_atomic.rb, line 226
def versioned_create(query={},log=false)
              

              self.send("op_success=",false)
              update = {}
              options = {}
              id_query = {"_id" => as_document["_id"]}
      
              query = query.empty? ? id_query : query


                if version == 0
                        
                                update["$setOnInsert"] = {}
                             options[:upsert] = true
                                
                             expected_version = 1

                             
                                        prepare_insert(options) do
                                                
                                                as_document.keys.each do |k|
                                                   if (k != "version" && k != "op_success")
                                                           update["$setOnInsert"][k] = self.send(k.to_sym)
                                                   end
                                           end

                                           update["$setOnInsert"]["version"] = 1

                                                options,update = self.class.before_persist(options,update,true)

                                                self.class.log_opts(query,update,options,"create",log)
                                                
                                                write_result = collection.update_one(query,update,options)


                                                        
                                                self.matched_count = write_result.matched_count
                                                self.modified_count = write_result.modified_count
                                                self.upserted_id = write_result.upserted_id
                                                
                                                ##as long as it matched a document, or it inserted a document
                                                if self.upserted_id
                                                                self.send("op_success=",true)
                                                                self.version = 1
                                                else
                                                                self.send("op_success=",false)
                                                end
                                                
                                                        
                                                                
                                        end
                                
                        
                end         

                

                return query,update,options  
                                
end
versioned_update(dirty_fields={},bypass_versioning=false,optional_update_hash={},log=false) click to toggle source

finally call after_persist to set all the changed fields on the document. this becomes relevant especially in case where you pass in an optional update hash with an “$inc” for some field. The incremented value is not there on the instance, since the instance has the older value and this must be set if the op is successfull on the instance.

# File lib/mongoid_versioned_atomic/v_atomic.rb, line 316
def versioned_update(dirty_fields={},bypass_versioning=false,optional_update_hash={},log=false)
        self.send("op_success=",false)
        query = {}
        options = {}
        update = {}
        curr_doc = as_document
        
        

        ##if the dirty fields are empty then it becomes equal to a hash whose keys are the document attributes, and whose values for each key are nil,
        ##otherwise dirty_fields stays as it is.
        dirty_fields = dirty_fields.empty? ? Hash[curr_doc.keys.zip([])] : dirty_fields
        
        if curr_doc["version"] > 0
                
                if !bypass_versioning
                        query["version"] = curr_doc["version"]
                end
                query["_id"] = curr_doc["_id"]
                update["$set"] = {} 
                options[:upsert] = false
                expected_version = curr_doc["version"] + 1

                ##what happens is that we send the update["$set"][k] to whatever was stored in the dirty_fields.
                
                prepare_update(options) do
                        
                        dirty_fields.keys.each do |k|
                                if (k != "version" && k != "_id" && k != "op_success")
                                        update["$set"][k] = self.send(k.to_sym)
                                end
                        end


                        update = optional_update_hash.empty? ? update : optional_update_hash

                        options,update = self.class.before_persist(options,update,bypass_versioning)

                        #puts "-----------------------------------"
                        #puts "called update"
                        #puts "-----------------------------------"

                        self.class.log_opts(query,update,options,"update",log)

                        write_result = collection.update_one(query,update,options)
                        
                        if write_result.modified_count == 1
                                self.send("op_success=",true)
                                persisted_doc = self.class.to_s.constantize.find(self.to_param)
                                persisted_doc = persisted_doc.attributes
                                self.class.after_persist(persisted_doc,self)
                        else
                                self.send("op_success=",false)
                        end

                end
                
                
        end

        return query,update,options  

end