Module: OceanDynamo::Persistence

Included in:
Table
Defined in:
lib/ocean-dynamo/persistence.rb

Defined Under Namespace

Modules: ClassMethods

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



4
5
6
# File 'lib/ocean-dynamo/persistence.rb', line 4

def self.included(base)
  base.extend(ClassMethods)
end

Instance Method Details

#_setup_from_dynamo(arg) ⇒ Object

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.



269
270
271
272
273
274
275
276
277
278
279
280
281
# File 'lib/ocean-dynamo/persistence.rb', line 269

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 = {}) ⇒ Object



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/ocean-dynamo/persistence.rb', line 169

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 = {}) ⇒ Object



163
164
165
166
# File 'lib/ocean-dynamo/persistence.rb', line 163

def create_or_update(options={})
  result = new_record? ? create(options) : update(options)
  result != false
end

#deleteObject



218
219
220
221
222
223
224
# File 'lib/ocean-dynamo/persistence.rb', line 218

def delete
  if persisted?
    dynamo_delete(lock: lock_attribute)
  end
  freeze
  @destroyed = true
end

#destroyObject



204
205
206
207
208
209
210
# File 'lib/ocean-dynamo/persistence.rb', line 204

def destroy
  run_callbacks :commit do
    run_callbacks :destroy do
      delete
    end
  end
end

#destroy!Object



213
214
215
# File 'lib/ocean-dynamo/persistence.rb', line 213

def destroy!
  destroy || raise(RecordNotDestroyed)
end

#destroyed?Boolean

Returns:

  • (Boolean)


106
107
108
# File 'lib/ocean-dynamo/persistence.rb', line 106

def destroyed?
  @destroyed
end

#initialize(attrs = {}) ⇒ Object


Instance variables and methods



94
95
96
97
98
# File 'lib/ocean-dynamo/persistence.rb', line 94

def initialize(attrs={})
  @destroyed = false
  @new_record = true
  super
end

#new_record?Boolean

Returns:

  • (Boolean)


111
112
113
# File 'lib/ocean-dynamo/persistence.rb', line 111

def new_record?
  @new_record
end

#persisted?Boolean

Returns:

  • (Boolean)


116
117
118
# File 'lib/ocean-dynamo/persistence.rb', line 116

def persisted?
  !(new_record? || destroyed?)
end

#reload(**keywords) ⇒ Object



227
228
229
230
231
# File 'lib/ocean-dynamo/persistence.rb', line 227

def reload(**keywords)
  new_instance = self.class.find(hash_key, range_key, **keywords)
  assign_attributes(new_instance.attributes)
  self
end

#save(options = {}) ⇒ Object



128
129
130
131
132
133
134
135
136
137
138
# File 'lib/ocean-dynamo/persistence.rb', line 128

def save(options={})
  if perform_validations(options)
    begin
      create_or_update
    rescue RecordInvalid
      false
    end
  else
    false
  end
end

#save!(options = {}) ⇒ Object



141
142
143
144
145
146
147
148
# File 'lib/ocean-dynamo/persistence.rb', line 141

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) ⇒ Object

Raises:



234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
# File 'lib/ocean-dynamo/persistence.rb', line 234

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)
      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 = {}) ⇒ Object



190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/ocean-dynamo/persistence.rb', line 190

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 = {}) ⇒ Object



151
152
153
154
# File 'lib/ocean-dynamo/persistence.rb', line 151

def update_attributes(attrs={}, options={})
  assign_attributes(attrs, options)
  save
end

#update_attributes!(attrs = {}, options = {}) ⇒ Object



157
158
159
160
# File 'lib/ocean-dynamo/persistence.rb', line 157

def update_attributes!(attrs={}, options={})
  assign_attributes(attrs, options)
  save!
end

#valid?(context = nil) ⇒ Boolean

Returns:

  • (Boolean)


121
122
123
124
125
# File 'lib/ocean-dynamo/persistence.rb', line 121

def valid?(context = nil)
  context ||= (new_record? ? :create : :update)
  output = super(context)
  errors.empty? && output
end