Skip to content

Commit 4a743a7

Browse files
committed
Implement Document.delete() method
1 parent ff2342f commit 4a743a7

File tree

2 files changed

+81
-44
lines changed

2 files changed

+81
-44
lines changed

lib/dynamoid/persistence.rb

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -458,52 +458,49 @@ def inc(hash_key_value, range_key_value = nil, counters)
458458

459459
# Delete a model.
460460
#
461-
# Delete a model by given partition key:
461+
# Raises +Dynamoid::Errors::MissingHashKey+ if a partition key has value
462+
# +nil+ and raises +Dynamoid::Errors::MissingRangeKey+ if a sort key is
463+
# required but has value +nil+ or is missing.
462464
#
463-
# User.delete(user_id)
465+
# @param ids [String|Array] primary key or an array of primary keys
466+
# @return nil
464467
#
465-
# Delete a model by given partition and sort keys:
468+
# @example Delete a model by given partition key:
469+
# User.delete(user_id)
466470
#
471+
# @example Delete a model by given partition and sort keys:
467472
# User.delete(user_id, sort_key)
468473
#
469-
# Delete multiple models by given partition keys:
470-
#
474+
# @example Delete multiple models by given partition keys:
471475
# User.delete([id1, id2, id3])
472476
#
473-
# Delete multiple models by given partition and sort keys:
474-
#
477+
# @example Delete multiple models by given partition and sort keys:
475478
# User.delete([[id1, sk1], [id2, sk2], [id3, sk3]])
476-
#
477-
# Raises +Dynamoid::Errors::MissingHashKey+ if a partition key has value
478-
# +nil+ and raises +Dynamoid::Errors::MissingRangeKey+ if a sort key is
479-
# required but has value +nil+ or is missing.
480-
#
481-
# @return nil
482-
def delete(*args)
483-
if args.empty?
479+
480+
def delete(*ids)
481+
if ids.empty?
484482
raise Dynamoid::Errors::MissingHashKey
485483
end
486484

487-
# TODO: warn if passed excessive arguments
488-
# TODO: handle a case when sort key isn't declared but given in arguments
489-
if args[0].is_a?(Array)
490-
# given multiple keys:
491-
keys = args[0] # ignore other arguments
485+
if ids[0].is_a?(Array)
486+
# given multiple keys
487+
# Model.delete([id1, id2, id3])
488+
keys = ids[0] # ignore other arguments
492489

493-
494-
if keys[0].is_a?(Array)
490+
if self.range_key
495491
# compound primary key
492+
# expect [hash key, range key] pairs
496493

497494
ids = []
498495
range_key = []
499496

500497
# assume all elements are pairs, that's arrays
501498
keys.each do |pk, sk|
502499
raise Dynamoid::Errors::MissingHashKey if pk.nil?
503-
raise Dynamoid::Errors::MissingRangeKey if self.range_key? && sk.nil?
500+
raise Dynamoid::Errors::MissingRangeKey if self.range_key && sk.nil?
504501

505-
partition_key_dumped = Dumping.dump_field(pk, self.attributes[self.hash_key])
506-
sort_key_dumped = Dumping.dump_field(sk, self.attributes[self.range_key])
502+
partition_key_dumped = cast_and_dump(self.hash_key, pk)
503+
sort_key_dumped = cast_and_dump(self.range_key, sk)
507504

508505
ids << partition_key_dumped
509506
range_key << sort_key_dumped
@@ -517,22 +514,25 @@ def delete(*args)
517514
keys.each do |pk|
518515
raise Dynamoid::Errors::MissingHashKey if pk.nil?
519516

520-
partition_key_dumped = Dumping.dump_field(pk, self.attributes[self.hash_key])
517+
partition_key_dumped = cast_and_dump(self.hash_key, pk)
521518
ids << partition_key_dumped
522519
end
523520
end
524521

525522
options = range_key ? { range_key: range_key } : {}
526523
Dynamoid.adapter.delete(self.table_name, ids, options)
527524
else
528-
# Model.delete(partition_key, sort_key)
529-
partition_key, sort_key = args
525+
# given single primary key:
526+
# Model.delete(partition_key)
527+
# Model.delete(partition_key, sort_key)
528+
529+
partition_key, sort_key = ids
530530

531531
raise Dynamoid::Errors::MissingHashKey if partition_key.nil?
532532
raise Dynamoid::Errors::MissingRangeKey if self.range_key? && sort_key.nil?
533533

534-
options = sort_key ? { range_key: Dumping.dump_field(sort_key, self.attributes[self.range_key]) } : {}
535-
partition_key_dumped = Dumping.dump_field(partition_key, self.attributes[self.hash_key])
534+
options = sort_key ? { range_key: cast_and_dump(self.range_key, sort_key) } : {}
535+
partition_key_dumped = cast_and_dump(self.hash_key, partition_key)
536536

537537
Dynamoid.adapter.delete(self.table_name, partition_key_dumped, options)
538538
end

spec/dynamoid/persistence/delete_spec.rb

Lines changed: 51 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,22 @@
2424
obj1 = klass.create!
2525
obj2 = klass.create!
2626

27-
klass.delete([obj1.id, obj2.id])
28-
29-
expect(klass.exists?(obj1.id)).to eql(false)
30-
expect(klass.exists?(obj2.id)).to eql(false)
27+
expect {
28+
expect {
29+
klass.delete([obj1.id, obj2.id])
30+
}.to change { klass.where(id: obj1.id).first }.to(nil)
31+
}.to change { klass.where(id: obj2.id).first }.to(nil)
3132
end
3233

3334
it 'deletes multiple items when given multiple partition and sort keys' do
3435
obj1 = klass_with_composite_key.create!(age: 1)
3536
obj2 = klass_with_composite_key.create!(age: 2)
3637

37-
klass_with_composite_key.delete([[obj1.id, obj1.age], [obj2.id, obj2.age]])
38-
39-
expect(klass_with_composite_key.exists?([[obj1.id, obj1.age]])).to eql(false)
40-
expect(klass_with_composite_key.exists?([[obj2.id, obj2.age]])).to eql(false)
38+
expect {
39+
expect {
40+
klass_with_composite_key.delete([[obj1.id, obj1.age], [obj2.id, obj2.age]])
41+
}.to change { klass_with_composite_key.where(id: obj1.id, age: obj1.age).first }.to(nil)
42+
}.to change { klass_with_composite_key.where(id: obj2.id, age: obj2.age).first }.to(nil)
4143
end
4244

4345
it 'uses dumped value of partition key to delete item' do
@@ -47,9 +49,20 @@
4749

4850
expect {
4951
klass.delete(obj.published_on)
50-
}.to change {
51-
klass.where(published_on: obj.published_on).first
52-
}.to(nil)
52+
}.to change { klass.where(published_on: obj.published_on).first }.to(nil)
53+
end
54+
55+
it 'uses dumped value of partition key to delete item when given multiple primary keys' do
56+
klass = new_class(partition_key: { name: :published_on, type: :date })
57+
58+
obj1 = klass.create!(published_on: '2018-10-07'.to_date)
59+
obj2 = klass.create!(published_on: '2018-10-13'.to_date)
60+
61+
expect {
62+
expect {
63+
klass.delete([obj1.published_on, obj2.published_on])
64+
}.to change { klass.where(published_on: obj1.published_on).first }.to(nil)
65+
}.to change { klass.where(published_on: obj2.published_on).first }.to(nil)
5366
end
5467

5568
it 'uses dumped value of sort key to delete item' do
@@ -61,11 +74,25 @@
6174

6275
expect {
6376
klass.delete(obj.id, obj.activated_on)
64-
}.to change {
65-
klass.where(id: obj.id, activated_on: obj.activated_on).first
66-
}.to(nil)
77+
}.to change { klass.where(id: obj.id, activated_on: obj.activated_on).first }.to(nil)
6778
end
6879

80+
it 'uses dumped value of sort key to delete item when given multiple primary keys' do
81+
klass = new_class do
82+
range :activated_on, :date
83+
end
84+
85+
obj1 = klass.create!(activated_on: Date.today)
86+
obj2 = klass.create!(activated_on: Date.tomorrow)
87+
88+
expect {
89+
expect {
90+
klass.delete([[obj1.id, obj1.activated_on], [obj2.id, obj2.activated_on]])
91+
}.to change { klass.where(id: obj1.id, activated_on: obj1.activated_on).first }.to(nil)
92+
}.to change { klass.where(id: obj2.id, activated_on: obj2.activated_on).first }.to(nil)
93+
end
94+
95+
6996
it 'does not raise exception when model was concurrently deleted' do
7097
klass = new_class
7198
klass.create_table
@@ -78,6 +105,7 @@
78105
it 'requires partition key to be specified' do
79106
klass = new_class
80107
expect { klass.delete(nil) }.to raise_exception(Dynamoid::Errors::MissingHashKey)
108+
expect { klass.delete() }.to raise_exception(Dynamoid::Errors::MissingHashKey)
81109
end
82110
end
83111

@@ -86,10 +114,19 @@
86114
expect { klass_with_composite_key.delete(nil, 1) }.to raise_exception(Dynamoid::Errors::MissingHashKey)
87115
end
88116

117+
it 'requires partition key to be specified when given multiple primary keys' do
118+
expect { klass_with_composite_key.delete([nil]) }.to raise_exception(Dynamoid::Errors::MissingHashKey)
119+
end
120+
89121
it 'requires sort key to be specified' do
90122
expect { klass_with_composite_key.delete("abc", nil) }.to raise_exception(Dynamoid::Errors::MissingRangeKey)
91123
expect { klass_with_composite_key.delete("abc") }.to raise_exception(Dynamoid::Errors::MissingRangeKey)
92124
end
125+
126+
it 'requires sort key to be specified when given multiple primary keys' do
127+
expect { klass_with_composite_key.delete([["abc", nil]]) }.to raise_exception(Dynamoid::Errors::MissingRangeKey)
128+
expect { klass_with_composite_key.delete([["abc"]]) }.to raise_exception(Dynamoid::Errors::MissingRangeKey)
129+
end
93130
end
94131
end
95132

0 commit comments

Comments
 (0)