Module: Dynamoid::Persistence
- Extended by:
- ActiveSupport::Concern
- Included in:
- Components
- Defined in:
- lib/dynamoid/persistence.rb,
lib/dynamoid/persistence/save.rb,
lib/dynamoid/persistence/import.rb,
lib/dynamoid/persistence/upsert.rb,
lib/dynamoid/persistence/update_fields.rb
Overview
# 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.
Defined Under Namespace
Modules: ClassMethods Classes: Import, Save, UpdateFields, Upsert
Constant Summary collapse
- UNIX_EPOCH_DATE =
Date.new(1970, 1, 1).freeze
Instance Attribute Summary collapse
-
#new_record ⇒ Object
(also: #new_record?)
Returns the value of attribute new_record.
Instance Method Summary collapse
-
#decrement(attribute, by = 1) ⇒ Dynamoid::Document
Change numeric attribute value.
-
#decrement!(attribute, by = 1) ⇒ true|false
Change numeric attribute value and save a model.
-
#delete ⇒ Object
Delete a model.
-
#destroy ⇒ true|false
Delete a model.
-
#destroy! ⇒ Object
Delete a model.
-
#increment(attribute, by = 1) ⇒ Dynamoid::Document
Change numeric attribute value.
-
#increment!(attribute, by = 1) ⇒ true|false
Change numeric attribute value and save a model.
-
#persisted? ⇒ true|false
Is this object persisted in DynamoDB?.
-
#save(options = {}) ⇒ true|false
Create new model or persist changes.
-
#touch(name = nil) ⇒ Object
Update document timestamps.
-
#update(conditions = {}, &block) ⇒ Object
Update a model.
-
#update!(conditions = {}) ⇒ Object
Update a model.
-
#update_attribute(attribute, value) ⇒ Dynamoid::Document
Update a single attribute, saving the object afterwards.
-
#update_attributes(attributes) ⇒ true|false
Update multiple attributes at once, saving the object once the updates are complete.
-
#update_attributes!(attributes) ⇒ Object
Update multiple attributes at once, saving the object once the updates are complete.
Instance Attribute Details
#new_record ⇒ Object Also known as: new_record?
Returns the value of attribute new_record.
19 20 21 |
# File 'lib/dynamoid/persistence.rb', line 19 def new_record @new_record end |
Instance Method Details
#decrement(attribute, by = 1) ⇒ Dynamoid::Document
Change numeric attribute value.
Initializes attribute to zero if nil and subtracts the specified value (by default is 1). Only makes sense for number-based attributes.
user.decrement(:followers_count)
user.decrement(:followers_count, 2)
704 705 706 707 708 |
# File 'lib/dynamoid/persistence.rb', line 704 def decrement(attribute, by = 1) self[attribute] ||= 0 self[attribute] -= by self end |
#decrement!(attribute, by = 1) ⇒ true|false
Change numeric attribute value and save a model.
Initializes attribute to zero if nil and subtracts the specified value (by default is 1). Only makes sense for number-based attributes.
user.decrement!(:followers_count)
user.decrement!(:followers_count, 2)
Returns true if a model was saved and false otherwise.
723 724 725 726 |
# File 'lib/dynamoid/persistence.rb', line 723 def decrement!(attribute, by = 1) decrement(attribute, by) save end |
#delete ⇒ Object
Delete a model.
Supports optimistic locking with the lock_version attribute and doesn’t delete a model if it’s already changed.
Raises Dynamoid::Errors::StaleObjectError exception if cannot delete a model.
771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 |
# File 'lib/dynamoid/persistence.rb', line 771 def delete = range_key ? { range_key: Dumping.dump_field(read_attribute(range_key), self.class.attributes[range_key]) } : {} # Add an optimistic locking check if the lock_version column exists if self.class.attributes[:lock_version] conditions = { if: {} } conditions[:if][:lock_version] = if changes[:lock_version].nil? lock_version else changes[:lock_version][0] end [:conditions] = conditions end @destroyed = true Dynamoid.adapter.delete(self.class.table_name, hash_key, ) rescue Dynamoid::Errors::ConditionalCheckFailedException raise Dynamoid::Errors::StaleObjectError.new(self, 'delete') end |
#destroy ⇒ true|false
Delete a model.
Runs callbacks.
Supports optimistic locking with the lock_version attribute and doesn’t delete a model if it’s already changed.
Returns true if deleted successfully and false otherwise.
739 740 741 742 743 744 745 746 747 |
# File 'lib/dynamoid/persistence.rb', line 739 def destroy ret = run_callbacks(:destroy) do delete end @destroyed = true ret == false ? false : self end |
#destroy! ⇒ Object
Delete a model.
Runs callbacks.
Supports optimistic locking with the lock_version attribute and doesn’t delete a model if it’s already changed.
Raises Dynamoid::Errors::RecordNotDestroyed exception if model deleting failed.
758 759 760 |
# File 'lib/dynamoid/persistence.rb', line 758 def destroy! destroy || (raise Dynamoid::Errors::RecordNotDestroyed, self) end |
#increment(attribute, by = 1) ⇒ Dynamoid::Document
Change numeric attribute value.
Initializes attribute to zero if nil and adds the specified value (by default is 1). Only makes sense for number-based attributes.
user.increment(:followers_count)
user.increment(:followers_count, 2)
669 670 671 672 673 |
# File 'lib/dynamoid/persistence.rb', line 669 def increment(attribute, by = 1) self[attribute] ||= 0 self[attribute] += by self end |
#increment!(attribute, by = 1) ⇒ true|false
Change numeric attribute value and save a model.
Initializes attribute to zero if nil and adds the specified value (by default is 1). Only makes sense for number-based attributes.
user.increment!(:followers_count)
user.increment!(:followers_count, 2)
Returns true if a model was saved and false otherwise.
688 689 690 691 |
# File 'lib/dynamoid/persistence.rb', line 688 def increment!(attribute, by = 1) increment(attribute, by) save end |
#persisted? ⇒ true|false
Is this object persisted in DynamoDB?
user = User.new
user.persisted? # => false
user.save
user.persisted? # => true
418 419 420 |
# File 'lib/dynamoid/persistence.rb', line 418 def persisted? !(new_record? || @destroyed) end |
#save(options = {}) ⇒ true|false
Create new model or persist changes.
Run the validation and callbacks. Returns true if saving is successful and false otherwise.
user = User.new
user.save # => true
user.age = 26
user.save # => true
Validation can be skipped with validate: false option:
user = User.new(age: -1)
user.save(validate: false) # => true
save by default sets timestamps attributes - created_at and updated_at when creates new model and updates updated_at attribute when update already existing one.
Changing updated_at attribute at updating a model can be skipped with touch: false option:
user.save(touch: false)
If a model is new and hash key (id by default) is not assigned yet it was assigned implicitly with random UUID value.
If lock_version attribute is declared it will be incremented. If it’s blank then it will be initialized with 1.
save method call raises Dynamoid::Errors::RecordNotUnique exception if primary key (hash key + optional range key) already exists in a table.
save method call raises Dynamoid::Errors::StaleObjectError exception if there is lock_version attribute and the document in a table was already changed concurrently and lock_version was consequently increased.
When a table is not created yet the first save method call will create a table. It’s useful in test environment to avoid explicit table creation.
470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 |
# File 'lib/dynamoid/persistence.rb', line 470 def save( = {}) self.class.create_table(sync: true) @_touch_record = [:touch] if new_record? run_callbacks(:create) do run_callbacks(:save) do Save.call(self) end end else run_callbacks(:save) do Save.call(self) end end end |
#touch(name = nil) ⇒ Object
Update document timestamps.
Set updated_at attribute to current DateTime.
post.touch
Can update another field in addition with the same timestamp if it’s name passed as argument.
user.touch(:last_login_at)
401 402 403 404 405 406 |
# File 'lib/dynamoid/persistence.rb', line 401 def touch(name = nil) now = DateTime.now self.updated_at = now attributes[name] = now if name save end |
#update(conditions = {}, &block) ⇒ Object
Update a model.
Runs validation and callbacks. Reloads all attribute values.
Accepts mandatory block in order to specify operations which will modify attributes. Supports following operations: add, delete and set.
Operation add just adds a value for numeric attributes and join collections if attribute is a collection (one of array, set or map).
user.update do |t|
t.add(age: 1, followers_count: 5)
t.add(hobbies: ['skying', 'climbing'])
end
Operation delete is applied to collection attribute types and substructs one collection from another.
user.update do |t|
t.delete(hobbies: ['skying'])
end
Operation set just changes an attribute value:
user.update do |t|
t.set(age: 21)
end
All the operations works like ADD, DELETE and PUT actions supported by AttributeUpdates parameter of UpdateItem operation.
Can update a model conditionaly:
user.update(if: { age: 20 }) do |t|
t.add(age: 1)
end
If a document doesn’t meet conditions it just returns false. Otherwise it returns true.
It will increment the lock_version attribute if a table has the column, but will not check it. Thus, a concurrent save call will never cause an update! to fail, but an update! may cause a concurrent save to fail.
651 652 653 654 655 656 |
# File 'lib/dynamoid/persistence.rb', line 651 def update(conditions = {}, &block) update!(conditions, &block) true rescue Dynamoid::Errors::StaleObjectError false end |
#update!(conditions = {}) ⇒ Object
Update a model.
Runs validation and callbacks. Reloads all attribute values.
Accepts mandatory block in order to specify operations which will modify attributes. Supports following operations: add, delete and set.
Operation add just adds a value for numeric attributes and join collections if attribute is a collection (one of array, set or map).
user.update do |t|
t.add(age: 1, followers_count: 5)
t.add(hobbies: ['skying', 'climbing'])
end
Operation delete is applied to collection attribute types and substructs one collection from another.
user.update do |t|
t.delete(hobbies: ['skying'])
end
Operation set just changes an attribute value:
user.update do |t|
t.set(age: 21)
end
All the operations works like ADD, DELETE and PUT actions supported by AttributeUpdates parameter of UpdateItem operation.
Can update a model conditionaly:
user.update(if: { age: 20 }) do |t|
t.add(age: 1)
end
If a document doesn’t meet conditions it raises Dynamoid::Errors::StaleObjectError exception.
It will increment the lock_version attribute if a table has the column, but will not check it. Thus, a concurrent save call will never cause an update! to fail, but an update! may cause a concurrent save to fail.
580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 |
# File 'lib/dynamoid/persistence.rb', line 580 def update!(conditions = {}) run_callbacks(:update) do = range_key ? { range_key: Dumping.dump_field(read_attribute(range_key), self.class.attributes[range_key]) } : {} begin new_attrs = Dynamoid.adapter.update_item(self.class.table_name, hash_key, .merge(conditions: conditions)) do |t| t.add(lock_version: 1) if self.class.attributes[:lock_version] if Dynamoid::Config. time_now = DateTime.now.in_time_zone(Time.zone) time_now_dumped = Dumping.dump_field(time_now, self.class.attributes[:updated_at]) t.set(updated_at: time_now_dumped) end yield t end load(Undumping.undump_attributes(new_attrs, self.class.attributes)) rescue Dynamoid::Errors::ConditionalCheckFailedException raise Dynamoid::Errors::StaleObjectError.new(self, 'update') end end end |
#update_attribute(attribute, value) ⇒ Dynamoid::Document
Update a single attribute, saving the object afterwards.
Returns true if saving is successful and false otherwise.
user.update_attribute(:last_name, 'Tylor')
526 527 528 529 |
# File 'lib/dynamoid/persistence.rb', line 526 def update_attribute(attribute, value) write_attribute(attribute, value) save end |
#update_attributes(attributes) ⇒ true|false
Update multiple attributes at once, saving the object once the updates are complete. Returns true if saving is successful and false otherwise.
user.update_attributes(age: 27, last_name: 'Tylor')
497 498 499 500 |
# File 'lib/dynamoid/persistence.rb', line 497 def update_attributes(attributes) attributes.each { |attribute, value| write_attribute(attribute, value) } save end |
#update_attributes!(attributes) ⇒ Object
Update multiple attributes at once, saving the object once the updates are complete.
user.update_attributes!(age: 27, last_name: 'Tylor')
Raises a Dynamoid::Errors::DocumentNotValid exception if some vaidation fails.
511 512 513 514 |
# File 'lib/dynamoid/persistence.rb', line 511 def update_attributes!(attributes) attributes.each { |attribute, value| write_attribute(attribute, value) } save! end |