module Dynamoid::Persistence
Persistence
is responsible for dumping objects to and marshalling objects from the datastore. It tries to reserialize values to be of the same type as when they were passed in, based on the fields in the class.
Attributes
Public Instance Methods
Delete this object from the datastore and all indexes.
@since 0.2.0
# File lib/dynamoid/persistence.rb, line 211 def delete delete_indexes options = range_key ? {:range_key => dump_field(self.read_attribute(range_key), self.class.attributes[range_key])} : {} Dynamoid::Adapter.delete(self.class.table_name, self.hash_key, options) end
Delete this object, but only after running callbacks for it.
@since 0.2.0
# File lib/dynamoid/persistence.rb, line 201 def destroy run_callbacks(:destroy) do self.delete end self end
Dump this object’s attributes into hash form, fit to be persisted into the datastore.
@since 0.2.0
# File lib/dynamoid/persistence.rb, line 220 def dump Hash.new.tap do |hash| self.class.attributes.each do |attribute, options| hash[attribute] = dump_field(self.read_attribute(attribute), options) end end end
Is this object persisted in the datastore? Required for some ActiveModel integration stuff.
@since 0.2.0
# File lib/dynamoid/persistence.rb, line 149 def persisted? !new_record? end
Run the callbacks and then persist this object in the datastore.
@since 0.2.0
# File lib/dynamoid/persistence.rb, line 156 def save(options = {}) self.class.create_table if new_record? conditions = { :unless_exists => [self.class.hash_key]} conditions[:unless_exists] << range_key if(range_key) run_callbacks(:create) { persist(conditions) } else persist end self end
Set updated_at and any passed in field to current DateTime. Useful for things like last_login_at, etc.
# File lib/dynamoid/persistence.rb, line 139 def touch(name = nil) now = DateTime.now self.updated_at = now attributes[name] = now if name save end
# File lib/dynamoid/persistence.rb, line 191 def update(conditions = {}, &block) update!(conditions, &block) true rescue Dynamoid::Errors::ConditionalCheckFailedException false end
update!() will increment the lock_version if the table has the column, but will not check it. Thus, a concurrent save will never cause an update! to fail, but an update! may cause a concurrent save to fail.
# File lib/dynamoid/persistence.rb, line 176 def update!(conditions = {}, &block) run_callbacks(:update) do options = range_key ? {:range_key => dump_field(self.read_attribute(range_key), self.class.attributes[range_key])} : {} new_attrs = Dynamoid::Adapter.update_item(self.class.table_name, self.hash_key, options.merge(:conditions => conditions)) do |t| if(self.class.attributes[:lock_version]) raise "Optimistic locking cannot be used with Partitioning" if(Dynamoid::Config.partitioning) t.add(lock_version: 1) end yield t end load(new_attrs) end end
Private Instance Methods
Determine how to dump this field. Given a value, it’ll determine how to turn it into a value that can be persisted into the datastore.
@since 0.2.0
# File lib/dynamoid/persistence.rb, line 234 def dump_field(value, options) return if value.nil? || (value.respond_to?(:empty?) && value.empty?) case options[:type] when :string value.to_s when :integer value.to_i when :float value.to_f when :set, :array if value.is_a?(Set) || value.is_a?(Array) value else Set[value] end when :datetime value.to_time.to_f when :serialized options[:serializer] ? options[:serializer].dump(value) : value.to_yaml when :boolean value.to_s[0] else raise ArgumentError, "Unknown type #{options[:type]}" end end
Persist the object into the datastore. Assign it an id first if it doesn’t have one; then afterwards, save its indexes.
@since 0.2.0
# File lib/dynamoid/persistence.rb, line 265 def persist(conditions = nil) run_callbacks(:save) do self.hash_key = SecureRandom.uuid if self.hash_key.nil? || self.hash_key.blank? # Add an exists check to prevent overwriting existing records with new ones if(new_record?) conditions ||= {} (conditions[:unless_exists] ||= []) << self.class.hash_key end # Add an optimistic locking check if the lock_version column exists if(self.class.attributes[:lock_version]) conditions ||= {} raise "Optimistic locking cannot be used with Partitioning" if(Dynamoid::Config.partitioning) self.lock_version = (lock_version || 0) + 1 #Uses the original lock_version value from ActiveModel::Dirty in case user changed lock_version manually (conditions[:if] ||= {})[:lock_version] = changes[:lock_version][0] if(changes[:lock_version][0]) end Dynamoid::Adapter.write(self.class.table_name, self.dump, conditions) save_indexes @new_record = false true end end