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.



275
276
277
278
279
280
281
282
283
284
285
286
287
# 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 = {}) ⇒ Object



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# 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 = {}) ⇒ Object



168
169
170
171
# File 'lib/ocean-dynamo/persistence.rb', line 168

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

#deleteObject



223
224
225
226
227
228
229
# File 'lib/ocean-dynamo/persistence.rb', line 223

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

#destroyObject



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

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

#destroy!Object



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

def destroy!
  destroy || raise(RecordNotDestroyed)
end

#destroyed?Boolean

Returns:

  • (Boolean)


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

def destroyed?
  @destroyed
end

#initialize(attrs = {}) ⇒ Object


Instance variables and methods



99
100
101
102
103
# File 'lib/ocean-dynamo/persistence.rb', line 99

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

#new_record?Boolean

Returns:

  • (Boolean)


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

def new_record?
  @new_record
end

#persisted?Boolean

Returns:

  • (Boolean)


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

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

#reload(**keywords) ⇒ Object



232
233
234
235
236
# 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 = {}) ⇒ Object



133
134
135
136
137
138
139
140
141
142
143
# 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 = {}) ⇒ Object



146
147
148
149
150
151
152
153
# 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) ⇒ Object

Raises:



239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
# 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 = {}) ⇒ Object



195
196
197
198
199
200
201
202
203
204
205
206
# 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 = {}) ⇒ Object



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

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

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



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

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

#valid?(context = nil) ⇒ Boolean

Returns:

  • (Boolean)


126
127
128
129
130
# File 'lib/ocean-dynamo/persistence.rb', line 126

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