module OceanDynamo::Persistence
Public Class Methods
included(base)
click to toggle source
# File lib/ocean-dynamo/persistence.rb, line 4 def self.included(base) base.extend(ClassMethods) end
new(attrs={})
click to toggle source
Instance variables and methods
Calls superclass method
# File lib/ocean-dynamo/persistence.rb, line 99 def initialize(attrs={}) @destroyed = false @new_record = true super end
Public Instance Methods
_setup_from_dynamo(arg)
click to toggle source
Deserialises and assigns all defined attributes. Skips undeclared attributes. Unlike its predecessor, this version never reads anything from DynamoDB, it just processes the results from such reads. Thus, the implementation of consistent
reads is up to the caller of this method.
# File lib/ocean-dynamo/persistence.rb, line 275 def _setup_from_dynamo(arg) case arg when Aws::DynamoDB::Types::GetItemOutput raw_attrs = arg.item when Hash raw_attrs = arg else raise ArgumentError, "arg must be an Aws::DynamoDB::Types::GetItemOutput or a Hash (was #{arg.class})" end dynamo_deserialize_attributes(raw_attrs) @new_record = false self end
create(options={})
click to toggle source
# File lib/ocean-dynamo/persistence.rb, line 174 def create(options={}) return false if options[:validate] != false && !valid?(:create) run_callbacks :commit do run_callbacks :save do run_callbacks :create do # Default the correct hash key to a UUID if self.class.has_belongs_to? write_attribute(table_range_key, SecureRandom.uuid) if range_key.blank? else write_attribute(table_hash_key, SecureRandom.uuid) if hash_key.blank? end set_timestamps dynamo_persist true end end end end
create_or_update(options={})
click to toggle source
# File lib/ocean-dynamo/persistence.rb, line 168 def create_or_update(options={}) result = new_record? ? create(options) : update(options) result != false end
delete()
click to toggle source
# File lib/ocean-dynamo/persistence.rb, line 223 def delete if persisted? dynamo_delete(lock: lock_attribute) end freeze @destroyed = true end
destroy()
click to toggle source
# File lib/ocean-dynamo/persistence.rb, line 209 def destroy run_callbacks :commit do run_callbacks :destroy do delete end end end
destroy!()
click to toggle source
# File lib/ocean-dynamo/persistence.rb, line 218 def destroy! destroy || raise(RecordNotDestroyed) end
destroyed?()
click to toggle source
def dynamo_schema(*)
super
end
# File lib/ocean-dynamo/persistence.rb, line 111 def destroyed? @destroyed end
new_record?()
click to toggle source
# File lib/ocean-dynamo/persistence.rb, line 116 def new_record? @new_record end
persisted?()
click to toggle source
# File lib/ocean-dynamo/persistence.rb, line 121 def persisted? !(new_record? || destroyed?) end
reload(**keywords)
click to toggle source
# File lib/ocean-dynamo/persistence.rb, line 232 def reload(**keywords) new_instance = self.class.find(hash_key, range_key, **keywords) assign_attributes(new_instance.attributes) self end
save(options={})
click to toggle source
# File lib/ocean-dynamo/persistence.rb, line 133 def save(options={}) if perform_validations(options) begin create_or_update rescue RecordInvalid false end else false end end
save!(options={})
click to toggle source
# File lib/ocean-dynamo/persistence.rb, line 146 def save!(options={}) if perform_validations(options) options[:validate] = false create_or_update(options) || raise(RecordNotSaved) else raise RecordInvalid.new(self) end end
touch(name=nil)
click to toggle source
# File lib/ocean-dynamo/persistence.rb, line 239 def touch(name=nil) raise DynamoError, "can not touch on a new record object" unless persisted? _late_connect? run_callbacks :touch do begin timestamps = set_timestamps(name) return self if timestamps.blank? update_expression = [] expression_attribute_values = {} timestamps.each_with_index do |ts, i| nomen = ":ts#{i}" expression_attribute_values[nomen] = serialize_attribute(ts, read_attribute(ts)) update_expression << "#{ts} = #{nomen}" end update_expression = "SET " + update_expression.join(", ") options = { key: serialized_key_attributes, update_expression: update_expression }.merge(_handle_locking) options[:expression_attribute_values] = (options[:expression_attribute_values] || {}).merge(expression_attribute_values) dynamo_table.update_item(options) rescue Aws::DynamoDB::Errors::ConditionalCheckFailedException write_attribute(lock_attribute, read_attribute(lock_attribute)-1) unless frozen? raise OceanDynamo::StaleObjectError.new(self) end self end end
update(options={})
click to toggle source
# File lib/ocean-dynamo/persistence.rb, line 195 def update(options={}) return false if options[:validate] != false && !valid?(:update) run_callbacks :commit do run_callbacks :save do run_callbacks :update do set_timestamps dynamo_persist(lock: lock_attribute) true end end end end
update_attributes(attrs={}, options={})
click to toggle source
# File lib/ocean-dynamo/persistence.rb, line 156 def update_attributes(attrs={}, options={}) assign_attributes(attrs, options) save end
update_attributes!(attrs={}, options={})
click to toggle source
# File lib/ocean-dynamo/persistence.rb, line 162 def update_attributes!(attrs={}, options={}) assign_attributes(attrs, options) save! end
valid?(context = nil)
click to toggle source
Calls superclass method
# File lib/ocean-dynamo/persistence.rb, line 126 def valid?(context = nil) context ||= (new_record? ? :create : :update) output = super(context) errors.empty? && output end
Protected Instance Methods
deserialize_attribute(value, metadata, type: metadata[:type])
click to toggle source
# File lib/ocean-dynamo/persistence.rb, line 395 def deserialize_attribute(value, metadata, type: metadata[:type]) case type when :reference return value when :string return "" if value == nil value.is_a?(Set) ? value.to_a : value when :integer return nil if value == nil value.is_a?(Set) || value.is_a?(Array) ? value.collect(&:to_i) : value.to_i when :float return nil if value == nil value.is_a?(Set) || value.is_a?(Array) ? value.collect(&:to_f) : value.to_f when :boolean case value when "true" true when "false" false else nil end when :datetime return nil if value == nil Time.zone.at(value.to_i) when :serialized return nil if value == nil JSON.parse(value) else raise UnsupportedType.new(type.to_s) end end
serialize_attribute(attribute, value, metadata=fields[attribute], target_class: metadata['target_class'], type: metadata['type'])
click to toggle source
# File lib/ocean-dynamo/persistence.rb, line 359 def serialize_attribute(attribute, value, metadata=fields[attribute], target_class: metadata['target_class'], # Remove? type: metadata['type']) return nil if value == nil case type when :reference value when :string return nil if ["", []].include?(value) value when :integer value == [] ? nil : value when :float value == [] ? nil : value when :boolean value ? "true" : "false" when :datetime value.to_i when :serialized value.to_json else raise UnsupportedType.new(type.to_s) end end
serialized_attributes()
click to toggle source
# File lib/ocean-dynamo/persistence.rb, line 329 def serialized_attributes result = Hash.new fields.each do |attribute, metadata| serialized = serialize_attribute(attribute, read_attribute(attribute), metadata) result[attribute] = serialized unless serialized == nil end result end
serialized_key_attributes()
click to toggle source
# File lib/ocean-dynamo/persistence.rb, line 339 def serialized_key_attributes result = Hash.new # First the hash key attribute = table_hash_key metadata = fields[attribute] serialized = serialize_attribute(attribute, read_attribute(attribute), metadata) raise "Hash key may not be null" if serialized == nil result[attribute] = serialized # Then the range key, if any if table_range_key attribute = table_range_key metadata = fields[attribute] serialized = serialize_attribute(attribute, read_attribute(attribute), metadata) raise "Range key may not be null" if serialized == nil result[attribute] = serialized end result end