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, consistent: false) ⇒ Object

Sets the dynamo_item and deserialises and assigns all its defined attributes. Skips undeclared attributes.

The arg may be either an Item or an ItemData. If Item, a request will be made for the attributes from DynamoDB. If ItemData, no DB access will be made and the existing data will be used.

The :consistent keyword may only be used when the arg is an Item.



243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
# File 'lib/ocean-dynamo/persistence.rb', line 243

def _setup_from_dynamo(arg, consistent: false)
  case arg
  when AWS::DynamoDB::Item
    item = arg
    item_data = nil
  when AWS::DynamoDB::ItemData
    item = arg.item
    item_data = arg
    raise ArgumentError, ":consistent may not be specified when passing an ItemData" if consistent
  else
    raise ArgumentError, "arg must be an AWS::DynamoDB::Item or an AWS::DynamoDB::ItemData"
  end
  
  @dynamo_item = item

  if !item_data
    raw_attrs = item.attributes.to_hash(consistent_read: consistent)
  else
    raw_attrs = item_data.attributes
  end

  dynamo_deserialize_attributes(raw_attrs)
  @new_record = false
  self
end

#create(options = {}) ⇒ Object



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/ocean-dynamo/persistence.rb', line 150

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



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

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

#deleteObject



199
200
201
202
203
204
205
# File 'lib/ocean-dynamo/persistence.rb', line 199

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

#destroyObject



185
186
187
188
189
190
191
# File 'lib/ocean-dynamo/persistence.rb', line 185

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

#destroy!Object



194
195
196
# File 'lib/ocean-dynamo/persistence.rb', line 194

def destroy!
  destroy || raise(RecordNotDestroyed)
end

#destroyed?Boolean

Returns:

  • (Boolean)


87
88
89
# File 'lib/ocean-dynamo/persistence.rb', line 87

def destroyed?
  @destroyed
end

#initialize(attrs = {}) ⇒ Object


Instance variables and methods



75
76
77
78
79
# File 'lib/ocean-dynamo/persistence.rb', line 75

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

#new_record?Boolean

Returns:

  • (Boolean)


92
93
94
# File 'lib/ocean-dynamo/persistence.rb', line 92

def new_record?
  @new_record
end

#persisted?Boolean

Returns:

  • (Boolean)


97
98
99
# File 'lib/ocean-dynamo/persistence.rb', line 97

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

#reload(**keywords) ⇒ Object



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

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

#save(options = {}) ⇒ Object



109
110
111
112
113
114
115
116
117
118
119
# File 'lib/ocean-dynamo/persistence.rb', line 109

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

#save!(options = {}) ⇒ Object



122
123
124
125
126
127
128
129
# File 'lib/ocean-dynamo/persistence.rb', line 122

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:



215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/ocean-dynamo/persistence.rb', line 215

def touch(name=nil)
  raise DynamoError, "can not touch on a new record object" unless persisted?
  _late_connect?
  run_callbacks :touch do
    begin
      dynamo_item.attributes.update(_handle_locking) do |u|
        set_timestamps(name).each do |k|
          u.set(k => serialize_attribute(k, read_attribute(k)))
        end
      end
    rescue AWS::DynamoDB::Errors::ConditionalCheckFailedException
      raise OceanDynamo::StaleObjectError.new(self)
    end
    self
  end
end

#update(options = {}) ⇒ Object



171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/ocean-dynamo/persistence.rb', line 171

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



132
133
134
135
# File 'lib/ocean-dynamo/persistence.rb', line 132

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

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



138
139
140
141
# File 'lib/ocean-dynamo/persistence.rb', line 138

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

#valid?(context = nil) ⇒ Boolean

Returns:

  • (Boolean)


102
103
104
105
106
# File 'lib/ocean-dynamo/persistence.rb', line 102

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