Skip to content

Commit

Permalink
Merge 464f115 into aa790f1
Browse files Browse the repository at this point in the history
  • Loading branch information
andrykonchin committed May 27, 2023
2 parents aa790f1 + 464f115 commit 8ca0e64
Show file tree
Hide file tree
Showing 6 changed files with 275 additions and 71 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -963,7 +963,7 @@ To idempotently create-but-not-update a record, apply the `unless_exists` condit
to its keys when you upsert.

```ruby
Address.upsert(id, { city: 'Chicago' }, if: { unless_exists: [:id] })
Address.upsert(id, { city: 'Chicago' }, { unless_exists: [:id] })
```

### Deleting
Expand Down
5 changes: 1 addition & 4 deletions lib/dynamoid/adapter_plugin/aws_sdk_v3.rb
Original file line number Diff line number Diff line change
Expand Up @@ -631,10 +631,7 @@ def expected_stanza(conditions = nil)
conditions.delete(:unless_exists).try(:each) do |col|
expected[col.to_s][:exists] = false
end
conditions.delete(:if_exists).try(:each) do |col, val|
expected[col.to_s][:exists] = true
expected[col.to_s][:value] = val
end

conditions.delete(:if).try(:each) do |col, val|
expected[col.to_s][:value] = val
end
Expand Down
36 changes: 34 additions & 2 deletions lib/dynamoid/persistence.rb
Original file line number Diff line number Diff line change
Expand Up @@ -271,14 +271,21 @@ def update!(hash_key, range_key_value = nil, attrs)
# meets the specified conditions. Conditions can be specified as a +Hash+
# with +:if+ key:
#
# User.update_fields('1', { age: 26 }, if: { version: 1 })
# User.update_fields('1', { age: 26 }, { if: { version: 1 } })
#
# Here +User+ model has an integer +version+ field and the document will
# be updated only if the +version+ attribute currently has value 1.
#
# If a document with specified hash and range keys doesn't exist or
# conditions were specified and failed the method call returns +nil+.
#
# To check if some attribute (or attributes) isn't stored in a DynamoDB
# item (e.g. it wasn't set explicitly) there is another condition -
# +unless_exists+:
#
# user = User.create(name: 'Tylor')
# User.update_fields(user.id, { age: 18 }, { unless_exists: [:age] })
#
# +update_fields+ uses the +UpdateItem+ operation so it saves changes and
# loads an updated document back with one HTTP request.
#
Expand Down Expand Up @@ -323,11 +330,18 @@ def update_fields(hash_key_value, range_key_value = nil, attrs = {}, conditions
# meets the specified conditions. Conditions can be specified as a +Hash+
# with +:if+ key:
#
# User.upsert('1', { age: 26 }, if: { version: 1 })
# User.upsert('1', { age: 26 }, { if: { version: 1 } })
#
# Here +User+ model has an integer +version+ field and the document will
# be updated only if the +version+ attribute currently has value 1.
#
# To check if some attribute (or attributes) isn't stored in a DynamoDB
# item (e.g. it wasn't set explicitly) there is another condition -
# +unless_exists+:
#
# user = User.create(name: 'Tylor')
# User.upsert(user.id, { age: 18 }, { unless_exists: [:age] })
#
# If conditions were specified and failed the method call returns +nil+.
#
# +upsert+ uses the +UpdateItem+ operation so it saves changes and loads
Expand Down Expand Up @@ -621,6 +635,15 @@ def update_attribute(attribute, value)
# t.add(age: 1)
# end
#
# To check if some attribute (or attributes) isn't stored in a DynamoDB
# item (e.g. it wasn't set explicitly) there is another condition -
# +unless_exists+:
#
# user = User.create(name: 'Tylor')
# user.update!(unless_exists: [:age]) do |t|
# t.set(age: 18)
# end
#
# If a document doesn't meet conditions it raises
# +Dynamoid::Errors::StaleObjectError+ exception.
#
Expand Down Expand Up @@ -717,6 +740,15 @@ def update!(conditions = {})
# t.add(age: 1)
# end
#
# To check if some attribute (or attributes) isn't stored in a DynamoDB
# item (e.g. it wasn't set explicitly) there is another condition -
# +unless_exists+:
#
# user = User.create(name: 'Tylor')
# user.update(unless_exists: [:age]) do |t|
# t.set(age: 18)
# 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,
Expand Down
4 changes: 2 additions & 2 deletions lib/dynamoid/persistence/save.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ def options_to_update_item
end

conditions = {}
conditions[:if_exists] ||= {}
conditions[:if_exists][@model.class.hash_key] = @model.hash_key
conditions[:if] ||= {}
conditions[:if][@model.class.hash_key] = @model.hash_key

# Add an optimistic locking check if the lock_version column exists
if @model.class.attributes[:lock_version]
Expand Down
4 changes: 2 additions & 2 deletions lib/dynamoid/persistence/update_fields.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ def options_to_update_item
end

conditions = @conditions.deep_dup
conditions[:if_exists] ||= {}
conditions[:if_exists][@model_class.hash_key] = @partition_key
conditions[:if] ||= {}
conditions[:if][@model_class.hash_key] = @partition_key
options[:conditions] = conditions

options
Expand Down

0 comments on commit 8ca0e64

Please sign in to comment.