dynamoid 3.4.0 → 3.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +94 -3
- data/README.md +52 -26
- data/lib/dynamoid.rb +1 -0
- data/lib/dynamoid/adapter.rb +15 -6
- data/lib/dynamoid/adapter_plugin/aws_sdk_v3.rb +48 -36
- data/lib/dynamoid/adapter_plugin/aws_sdk_v3/batch_get_item.rb +13 -1
- data/lib/dynamoid/adapter_plugin/aws_sdk_v3/create_table.rb +9 -8
- data/lib/dynamoid/adapter_plugin/aws_sdk_v3/item_updater.rb +5 -4
- data/lib/dynamoid/adapter_plugin/aws_sdk_v3/middleware/backoff.rb +2 -2
- data/lib/dynamoid/adapter_plugin/aws_sdk_v3/middleware/limit.rb +2 -3
- data/lib/dynamoid/adapter_plugin/aws_sdk_v3/middleware/start_key.rb +2 -2
- data/lib/dynamoid/adapter_plugin/aws_sdk_v3/query.rb +4 -2
- data/lib/dynamoid/adapter_plugin/aws_sdk_v3/scan.rb +6 -3
- data/lib/dynamoid/adapter_plugin/aws_sdk_v3/table.rb +1 -0
- data/lib/dynamoid/adapter_plugin/aws_sdk_v3/until_past_table_status.rb +2 -1
- data/lib/dynamoid/application_time_zone.rb +1 -0
- data/lib/dynamoid/associations.rb +182 -19
- data/lib/dynamoid/associations/association.rb +10 -2
- data/lib/dynamoid/associations/belongs_to.rb +2 -1
- data/lib/dynamoid/associations/has_and_belongs_to_many.rb +2 -1
- data/lib/dynamoid/associations/has_many.rb +2 -1
- data/lib/dynamoid/associations/has_one.rb +2 -1
- data/lib/dynamoid/associations/many_association.rb +68 -23
- data/lib/dynamoid/associations/single_association.rb +31 -4
- data/lib/dynamoid/components.rb +1 -0
- data/lib/dynamoid/config.rb +5 -5
- data/lib/dynamoid/config/backoff_strategies/constant_backoff.rb +1 -0
- data/lib/dynamoid/config/backoff_strategies/exponential_backoff.rb +1 -0
- data/lib/dynamoid/config/options.rb +1 -0
- data/lib/dynamoid/criteria.rb +9 -1
- data/lib/dynamoid/criteria/chain.rb +422 -46
- data/lib/dynamoid/criteria/ignored_conditions_detector.rb +3 -3
- data/lib/dynamoid/criteria/key_fields_detector.rb +32 -11
- data/lib/dynamoid/criteria/nonexistent_fields_detector.rb +3 -2
- data/lib/dynamoid/criteria/overwritten_conditions_detector.rb +1 -1
- data/lib/dynamoid/dirty.rb +119 -64
- data/lib/dynamoid/document.rb +125 -43
- data/lib/dynamoid/dumping.rb +9 -0
- data/lib/dynamoid/dynamodb_time_zone.rb +1 -0
- data/lib/dynamoid/errors.rb +2 -0
- data/lib/dynamoid/fields.rb +217 -36
- data/lib/dynamoid/fields/declare.rb +86 -0
- data/lib/dynamoid/finders.rb +69 -32
- data/lib/dynamoid/identity_map.rb +6 -0
- data/lib/dynamoid/indexes.rb +86 -17
- data/lib/dynamoid/loadable.rb +2 -2
- data/lib/dynamoid/log/formatter.rb +26 -0
- data/lib/dynamoid/middleware/identity_map.rb +1 -0
- data/lib/dynamoid/persistence.rb +496 -104
- data/lib/dynamoid/persistence/import.rb +1 -0
- data/lib/dynamoid/persistence/save.rb +1 -0
- data/lib/dynamoid/persistence/update_fields.rb +5 -2
- data/lib/dynamoid/persistence/update_validations.rb +18 -0
- data/lib/dynamoid/persistence/upsert.rb +5 -3
- data/lib/dynamoid/primary_key_type_mapping.rb +1 -0
- data/lib/dynamoid/railtie.rb +1 -0
- data/lib/dynamoid/tasks.rb +3 -1
- data/lib/dynamoid/tasks/database.rb +1 -0
- data/lib/dynamoid/type_casting.rb +12 -2
- data/lib/dynamoid/undumping.rb +8 -0
- data/lib/dynamoid/validations.rb +6 -1
- data/lib/dynamoid/version.rb +1 -1
- metadata +48 -74
- data/.coveralls.yml +0 -1
- data/.document +0 -5
- data/.gitignore +0 -74
- data/.rspec +0 -2
- data/.rubocop.yml +0 -71
- data/.rubocop_todo.yml +0 -55
- data/.travis.yml +0 -44
- data/Appraisals +0 -22
- data/Gemfile +0 -8
- data/Rakefile +0 -46
- data/Vagrantfile +0 -29
- data/docker-compose.yml +0 -7
- data/dynamoid.gemspec +0 -57
- data/gemfiles/rails_4_2.gemfile +0 -9
- data/gemfiles/rails_5_0.gemfile +0 -8
- data/gemfiles/rails_5_1.gemfile +0 -8
- data/gemfiles/rails_5_2.gemfile +0 -8
- data/gemfiles/rails_6_0.gemfile +0 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bc5c35cc32f9e77598030b980baff43156095b9480be6984d67e2cb5116fae47
|
|
4
|
+
data.tar.gz: 7b8ff766d64bf83096bf641f7ca641ab15974f451481a215cf63b69597cf4126
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0f4ac62013723a6880583471808d823cdbd4b84944357249a4dbad7b4087cf32bffc53880ec599c2f5fd61b07136ce7f7be05677fdc0aedf80ae3cf3c2b7b0ee
|
|
7
|
+
data.tar.gz: 3da0f1ffa1225c5233032330d6d1b9c5e2da60979770b42faecbd8141fd8bd5b9520767c2cc01beb5cee8a7979996cdaa53c3a03c49815c3b01dd23c8dabbb37
|
data/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,103 @@
|
|
|
1
1
|
# HEAD
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# 3.7.1 / 2021-06-30
|
|
8
|
+
|
|
9
|
+
## Fixes
|
|
10
|
+
|
|
11
|
+
* [#484](https://github.com/Dynamoid/dynamoid/pull/484) Fix model deletion - update cached foreign keys in associated models when delete a model
|
|
12
|
+
* [#492](https://github.com/Dynamoid/dynamoid/pull/492) Fix using `:date` field as an index hash/range key (@yoshida-eth0)
|
|
13
|
+
* [#503](https://github.com/Dynamoid/dynamoid/pull/503) Fix explicit forcing index with `#with_index` method when perform Scan operation (@bmalinconico)
|
|
14
|
+
* [#511](https://github.com/Dynamoid/dynamoid/pull/511) Fix `BatchGetItem` operation when partial result returned (so there are unprocessed keys) and table has a range key. The fix affects `.find_all` method only (@Bajena)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# 3.7.0 / 2021-02-02
|
|
19
|
+
|
|
4
20
|
|
|
5
21
|
## Features
|
|
6
22
|
|
|
23
|
+
* [#476](https://github.com/Dynamoid/dynamoid/pull/476) Added `#with_index` method to force an index in query (@bmalinconico)
|
|
24
|
+
* [#481](https://github.com/Dynamoid/dynamoid/pull/481) Added `alias` option to the `field` method to declare a field alias and use more conventional name to set and get value
|
|
25
|
+
|
|
7
26
|
## Improvements
|
|
8
27
|
|
|
28
|
+
* [#482](https://github.com/Dynamoid/dynamoid/pull/482) Support Ruby 3.0 and Rails 6.1
|
|
29
|
+
* [#461](https://github.com/Dynamoid/dynamoid/pull/461) Allow to delete item attribute with `#update` method (@jkirsteins)
|
|
30
|
+
* [#463](https://github.com/Dynamoid/dynamoid/pull/463) Raise `UnknownAttribute` exception when specified not declared attribute name (@AlexGascon)
|
|
31
|
+
|
|
32
|
+
## Fixes
|
|
33
|
+
|
|
34
|
+
* [#480](https://github.com/Dynamoid/dynamoid/pull/480) Repair `.consistent`/`.delete_all`/`.destroy_all` calls directly on a model class
|
|
35
|
+
* [#484](https://github.com/Dynamoid/dynamoid/pull/484) Fix broken foreign keys after model deleting (@kkan)
|
|
36
|
+
* Fixes in Readme.md: [#470](https://github.com/Dynamoid/dynamoid/pull/470) (@rromanchuk), [#473](https://github.com/Dynamoid/dynamoid/pull/473) (@Rulikkk)
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
# 3.6.0 / 2020-07-13
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
## Features
|
|
46
|
+
|
|
47
|
+
* [#458](https://github.com/Dynamoid/dynamoid/pull/458) Added `binary` field type
|
|
48
|
+
* [#459](https://github.com/Dynamoid/dynamoid/pull/459) Added `log_formatter` config option and changed default logging format
|
|
49
|
+
|
|
50
|
+
## Improvements
|
|
51
|
+
|
|
52
|
+
* [#423](https://github.com/Dynamoid/dynamoid/pull/423) Added warning when generated for a field methods override existing ones
|
|
53
|
+
* [#429](https://github.com/Dynamoid/dynamoid/pull/429) Added `raise_error` option for `find` method
|
|
54
|
+
* [#440](https://github.com/Dynamoid/dynamoid/pull/440) Optimized performance of `first` method when there are only conditions on key attribute in a query (@mrkamel)
|
|
55
|
+
* [#445](https://github.com/Dynamoid/dynamoid/pull/445) Support `limit` parameter in `first` method (@mrkamel)
|
|
56
|
+
* [#450](https://github.com/Dynamoid/dynamoid/pull/450) Got rid of `null-logger` gem to make Dynamoid dependencies license suitable for commercial use (@yakjuly)
|
|
57
|
+
* [#454](https://github.com/Dynamoid/dynamoid/pull/454) Added block argument to `create`/`create!` methods
|
|
58
|
+
* [#456](https://github.com/Dynamoid/dynamoid/pull/456) Detect when `find` method requires a range key argument and raise `Dynamoid::Errors::MissingRangeKey` exception if it's missing
|
|
59
|
+
* YARD documentation:
|
|
60
|
+
* added missing documentation so now all the public methods are documented
|
|
61
|
+
* hid all the private methods and classes
|
|
62
|
+
|
|
63
|
+
## Fixes
|
|
64
|
+
|
|
65
|
+
* [#425](https://github.com/Dynamoid/dynamoid/pull/425) Fixed typos in the README.md file (@omarsotillo)
|
|
66
|
+
* [#432](https://github.com/Dynamoid/dynamoid/pull/432) Support tables that use "hash_key" as their partition key name (@remomueller)
|
|
67
|
+
* [#434](https://github.com/Dynamoid/dynamoid/pull/434) Support tables that have attribute with name "range_value"
|
|
68
|
+
* [#453](https://github.com/Dynamoid/dynamoid/pull/453) Fixed issue with using `type` attribute as a GSI hash key
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
# 3.5.0 / 2020-04-04
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
## Features
|
|
78
|
+
* Feature: [#405](https://github.com/Dynamoid/dynamoid/pull/405) Added `update!` class method (@UrsaDK)
|
|
79
|
+
* Feature: [#408](https://github.com/Dynamoid/dynamoid/pull/408) Added `ActiveSupport` load hook on `Dynamoid` load (@aaronmallen)
|
|
80
|
+
* Feature: [#422](https://github.com/Dynamoid/dynamoid/pull/422) Added `.pluck` method
|
|
81
|
+
|
|
82
|
+
## Fixes:
|
|
83
|
+
* Fix: [#410](https://github.com/Dynamoid/dynamoid/pull/410) Fixed creating GSI when table uses on-demand capacity provisioning (@icy-arctic-fox)
|
|
84
|
+
* Fix: [#414](https://github.com/Dynamoid/dynamoid/pull/414) Fixed lazy table creation
|
|
85
|
+
* Fix: [#415](https://github.com/Dynamoid/dynamoid/pull/415) Fixed RubyDoc comment (@walkersumida)
|
|
86
|
+
* Fix: [#420](https://github.com/Dynamoid/dynamoid/pull/420) Fixed `#persisted?` for deleted/destroyed models
|
|
87
|
+
|
|
88
|
+
## Improvements:
|
|
89
|
+
* Improvement: [#416](https://github.com/Dynamoid/dynamoid/pull/416) Improved speed of Adapter's `truncate` method. It now uses `#batch_delete_item` method (@TheSmartnik)
|
|
90
|
+
* Improvement: [#421](https://github.com/Dynamoid/dynamoid/pull/421) Added `touch: false` option of the #save method
|
|
91
|
+
* Improvement: [#423](https://github.com/Dynamoid/dynamoid/pull/423) Added warning when generated for a field methods override existing ones
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
# 3.4.1
|
|
98
|
+
|
|
9
99
|
## Fixes
|
|
100
|
+
* Fix: [#398](https://github.com/Dynamoid/dynamoid/pull/398) Fix broken configuration
|
|
10
101
|
|
|
11
102
|
---
|
|
12
103
|
|
|
@@ -28,8 +119,8 @@
|
|
|
28
119
|
|
|
29
120
|
## Fixes
|
|
30
121
|
|
|
31
|
-
Fix: [#382](https://github.com/Dynamoid/dynamoid/pull/382) Fixed deprecation warning about `Module#parent_name` in Rails 6 (@tmandke)
|
|
32
|
-
Fix: Typos in Readme.md (@romeuhcf)
|
|
122
|
+
* Fix: [#382](https://github.com/Dynamoid/dynamoid/pull/382) Fixed deprecation warning about `Module#parent_name` in Rails 6 (@tmandke)
|
|
123
|
+
* Fix: Typos in Readme.md (@romeuhcf)
|
|
33
124
|
|
|
34
125
|
---
|
|
35
126
|
|
data/README.md
CHANGED
|
@@ -126,8 +126,8 @@ end
|
|
|
126
126
|
Dynamoid supports Ruby >= 2.3 and Rails >= 4.2.
|
|
127
127
|
|
|
128
128
|
Its compatibility is tested against following Ruby versions: 2.3, 2.4,
|
|
129
|
-
2.5
|
|
130
|
-
5.2 and 6.
|
|
129
|
+
2.5, 2.6, 2.7 and 3.0, JRuby 9.2.x and against Rails versions: 4.2, 5.0, 5.1,
|
|
130
|
+
5.2, 6.0 and 6.1.
|
|
131
131
|
|
|
132
132
|
## Setup
|
|
133
133
|
|
|
@@ -212,16 +212,17 @@ each field. Every field on the object must be included here; if you miss
|
|
|
212
212
|
any they'll be completely bypassed during DynamoDB's initialization and
|
|
213
213
|
will not appear on the model objects.
|
|
214
214
|
|
|
215
|
-
By default, fields are assumed to be of type
|
|
216
|
-
types are
|
|
217
|
-
`date`,
|
|
218
|
-
List and Map DynamoDB types respectively. `raw` type means
|
|
219
|
-
Ruby Array, Hash, String and numbers. If built-in types do
|
|
220
|
-
you can use a custom field type represented by an
|
|
221
|
-
provided that the class supports a compatible
|
|
222
|
-
The primary use case for using a custom field
|
|
223
|
-
business logic with high-level types, while
|
|
224
|
-
backward-compatibility of the serialized
|
|
215
|
+
By default, fields are assumed to be of type `string`. Other built-in
|
|
216
|
+
types are `integer`, `number`, `set`, `array`, `map`, `datetime`,
|
|
217
|
+
`date`, `boolean`, `binary`, `raw` and `serialized`. `array` and
|
|
218
|
+
`map` match List and Map DynamoDB types respectively. `raw` type means
|
|
219
|
+
you can store Ruby Array, Hash, String and numbers. If built-in types do
|
|
220
|
+
not suit you, you can use a custom field type represented by an
|
|
221
|
+
arbitrary class, provided that the class supports a compatible
|
|
222
|
+
serialization interface. The primary use case for using a custom field
|
|
223
|
+
type is to represent your business logic with high-level types, while
|
|
224
|
+
ensuring portability or backward-compatibility of the serialized
|
|
225
|
+
representation.
|
|
225
226
|
|
|
226
227
|
#### Note on boolean type
|
|
227
228
|
|
|
@@ -232,7 +233,7 @@ easily achieve this with `store_as_native_boolean` field option:
|
|
|
232
233
|
|
|
233
234
|
```ruby
|
|
234
235
|
class Document
|
|
235
|
-
include
|
|
236
|
+
include Dynamoid::Document
|
|
236
237
|
|
|
237
238
|
field :active, :boolean, store_as_native_boolean: false
|
|
238
239
|
end
|
|
@@ -246,7 +247,7 @@ strings instead then set `store_as_string` to `true`
|
|
|
246
247
|
|
|
247
248
|
```ruby
|
|
248
249
|
class Document
|
|
249
|
-
include
|
|
250
|
+
include Dynamoid::Document
|
|
250
251
|
|
|
251
252
|
field :sent_on, :date, store_as_string: true
|
|
252
253
|
end
|
|
@@ -261,7 +262,7 @@ as ISO-8601 formatted strings instead then set `store_as_string` to
|
|
|
261
262
|
|
|
262
263
|
```ruby
|
|
263
264
|
class Document
|
|
264
|
-
include
|
|
265
|
+
include Dynamoid::Document
|
|
265
266
|
|
|
266
267
|
field :sent_at, :datetime, store_as_string: true
|
|
267
268
|
end
|
|
@@ -293,7 +294,7 @@ types.
|
|
|
293
294
|
|
|
294
295
|
```ruby
|
|
295
296
|
class Document
|
|
296
|
-
include
|
|
297
|
+
include Dynamoid::Document
|
|
297
298
|
|
|
298
299
|
field :tags, :set, of: :integer
|
|
299
300
|
end
|
|
@@ -305,7 +306,7 @@ elements type:
|
|
|
305
306
|
|
|
306
307
|
```ruby
|
|
307
308
|
class Document
|
|
308
|
-
include
|
|
309
|
+
include Dynamoid::Document
|
|
309
310
|
|
|
310
311
|
field :values, :set, of: { serialized: { serializer: JSON } }
|
|
311
312
|
field :dates, :set, of: { date: { store_as_string: true } }
|
|
@@ -329,7 +330,7 @@ natively, you should specify element type with `of` option:
|
|
|
329
330
|
|
|
330
331
|
```ruby
|
|
331
332
|
class Document
|
|
332
|
-
include
|
|
333
|
+
include Dynamoid::Document
|
|
333
334
|
|
|
334
335
|
field :dates, :array, of: :date
|
|
335
336
|
end
|
|
@@ -364,6 +365,26 @@ field :actions_taken, :integer, default: 0
|
|
|
364
365
|
field :joined_at, :datetime, default: -> { Time.now }
|
|
365
366
|
```
|
|
366
367
|
|
|
368
|
+
#### Aliases
|
|
369
|
+
|
|
370
|
+
It might be helpful to define an alias for already existing field when
|
|
371
|
+
naming convention used for a table differs from conventions common in
|
|
372
|
+
Ruby:
|
|
373
|
+
|
|
374
|
+
```ruby
|
|
375
|
+
field firstName, :string, alias: :first_name
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
This way there will be generated
|
|
379
|
+
setters/getters/`<name>?`/`<name>_before_type_cast` methods for both
|
|
380
|
+
original field name (`firstName`) and an alias (`first_name`).
|
|
381
|
+
|
|
382
|
+
```ruby
|
|
383
|
+
user = User.new(first_name: 'Michael')
|
|
384
|
+
user.first_name # => 'Michael'
|
|
385
|
+
user.firstName # => 'Michael'
|
|
386
|
+
```
|
|
387
|
+
|
|
367
388
|
#### Custom Types
|
|
368
389
|
|
|
369
390
|
To use a custom type for a field, suppose you have a `Money` type.
|
|
@@ -575,7 +596,7 @@ c.my_new_type
|
|
|
575
596
|
|
|
576
597
|
### Type casting
|
|
577
598
|
|
|
578
|
-
|
|
599
|
+
Dynamoid supports type casting and tries to do it in the most convenient
|
|
579
600
|
way. Values for all fields (except custom type) are coerced to declared
|
|
580
601
|
field types.
|
|
581
602
|
|
|
@@ -613,7 +634,7 @@ well.
|
|
|
613
634
|
|
|
614
635
|
### Dirty API
|
|
615
636
|
|
|
616
|
-
Dynamoid supports Dirty API which
|
|
637
|
+
Dynamoid supports Dirty API which is equivalent to [Rails 5.2
|
|
617
638
|
`ActiveModel::Dirty`](https://api.rubyonrails.org/v5.2/classes/ActiveModel/Dirty.html).
|
|
618
639
|
There is only one limitation - change in place of field isn't detected
|
|
619
640
|
automatically.
|
|
@@ -631,7 +652,7 @@ u.email = 'josh@joshsymonds.com'
|
|
|
631
652
|
u.save
|
|
632
653
|
```
|
|
633
654
|
|
|
634
|
-
Save forces persistence to the
|
|
655
|
+
Save forces persistence to the data store: a unique ID is also assigned,
|
|
635
656
|
but it is a string and not an auto-incrementing number.
|
|
636
657
|
|
|
637
658
|
```ruby
|
|
@@ -762,7 +783,7 @@ for requesting documents in batches:
|
|
|
762
783
|
|
|
763
784
|
```ruby
|
|
764
785
|
# Do some maintenance on the entire table without flooding DynamoDB
|
|
765
|
-
Address.
|
|
786
|
+
Address.batch(100).each { |address| address.do_some_work; sleep(0.01) }
|
|
766
787
|
Address.record_limit(10_000).batch(100).each { … } # Batch specified as part of a chain
|
|
767
788
|
```
|
|
768
789
|
|
|
@@ -1068,7 +1089,7 @@ Listed below are all configuration options.
|
|
|
1068
1089
|
* `models_dir` - `dynamoid:create_tables` rake task loads DynamoDb
|
|
1069
1090
|
models from this directory. Default is `./app/models`.
|
|
1070
1091
|
* `application_timezone` - Dynamoid converts all `datetime` fields to
|
|
1071
|
-
|
|
1092
|
+
specified time zone when loads data from the storage.
|
|
1072
1093
|
Acceptable values - `:utc`, `:local` (to use system time zone) and
|
|
1073
1094
|
time zone name e.g. `Eastern Time (US & Canada)`. Default is `utc`
|
|
1074
1095
|
* `dynamodb_timezone` - When a datetime field is stored in string format
|
|
@@ -1088,6 +1109,11 @@ Listed below are all configuration options.
|
|
|
1088
1109
|
`nil`
|
|
1089
1110
|
* `backoff_strategies`: is a hash and contains all available strategies.
|
|
1090
1111
|
Default is { constant: ..., exponential: ...}
|
|
1112
|
+
* `log_formatter`: overrides default AWS SDK formatter. There are
|
|
1113
|
+
several canned formatters: `Aws::Log::Formatter.default`,
|
|
1114
|
+
`Aws::Log::Formatter.colored` and `Aws::Log::Formatter.short`. Please
|
|
1115
|
+
look into `Aws::Log::Formatter` AWS SDK documentation in order to
|
|
1116
|
+
provide own formatter.
|
|
1091
1117
|
* `http_continue_timeout`: The number of seconds to wait for a
|
|
1092
1118
|
100-continue HTTP response before sending the request body. Default
|
|
1093
1119
|
option value is `nil`. If not specified effected value is `1`
|
|
@@ -1261,7 +1287,7 @@ class User
|
|
|
1261
1287
|
end
|
|
1262
1288
|
|
|
1263
1289
|
Dynamoid.config.logger.level = :debug
|
|
1264
|
-
Dynamoid.config.endpoint = 'localhost:8000'
|
|
1290
|
+
Dynamoid.config.endpoint = 'http://localhost:8000'
|
|
1265
1291
|
|
|
1266
1292
|
User.create(name: 'Alex')
|
|
1267
1293
|
|
|
@@ -1336,12 +1362,12 @@ environment.
|
|
|
1336
1362
|
|
|
1337
1363
|
If you want to run all the specs that travis runs, use `bundle exec
|
|
1338
1364
|
wwtd`, but first you will need to setup all the rubies, for each of `%w(
|
|
1339
|
-
2.
|
|
1365
|
+
2.3.8 2.4.6 2.5.5 2.6.3 2.7.0 3.0.0 9.2.14.0)`. When you run
|
|
1340
1366
|
`bundle exec wwtd` it will take care of starting and stopping the local
|
|
1341
1367
|
dynamodb instance.
|
|
1342
1368
|
|
|
1343
1369
|
```shell
|
|
1344
|
-
rvm use
|
|
1370
|
+
rvm use 3.0.0
|
|
1345
1371
|
gem install rubygems-update
|
|
1346
1372
|
gem install bundler
|
|
1347
1373
|
bundle install
|
data/lib/dynamoid.rb
CHANGED
data/lib/dynamoid/adapter.rb
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
# require only 'concurrent/atom' once this issue is resolved:
|
|
4
4
|
# https://github.com/ruby-concurrency/concurrent-ruby/pull/377
|
|
5
5
|
require 'concurrent'
|
|
6
|
-
require
|
|
6
|
+
require 'dynamoid/adapter_plugin/aws_sdk_v3'
|
|
7
7
|
|
|
8
8
|
# encoding: utf-8
|
|
9
9
|
module Dynamoid
|
|
@@ -11,6 +11,7 @@ module Dynamoid
|
|
|
11
11
|
# 1) For the rest of Dynamoid, the gateway to DynamoDB.
|
|
12
12
|
# 2) Allows switching `config.adapter` to ease development of a new adapter.
|
|
13
13
|
# 3) Caches the list of tables Dynamoid knows about.
|
|
14
|
+
# @private
|
|
14
15
|
class Adapter
|
|
15
16
|
def initialize
|
|
16
17
|
@adapter_ = Concurrent::Atom.new(nil)
|
|
@@ -78,8 +79,8 @@ module Dynamoid
|
|
|
78
79
|
#
|
|
79
80
|
# @param [String] table the name of the table to write the object to
|
|
80
81
|
# @param [Array] ids to fetch, can also be a string of just one id
|
|
81
|
-
# @param [Hash] options
|
|
82
|
-
#
|
|
82
|
+
# @param [Hash] options Passed to the underlying query. The :range_key option is required whenever the table has a range key,
|
|
83
|
+
# unless multiple ids are passed in.
|
|
83
84
|
#
|
|
84
85
|
# @since 0.2.0
|
|
85
86
|
def read(table, ids, options = {}, &blk)
|
|
@@ -94,7 +95,9 @@ module Dynamoid
|
|
|
94
95
|
#
|
|
95
96
|
# @param [String] table the name of the table to write the object to
|
|
96
97
|
# @param [Array] ids to delete, can also be a string of just one id
|
|
97
|
-
# @param [
|
|
98
|
+
# @param [Hash] options allowed only +range_key+ - range key or array of
|
|
99
|
+
# range keys of the record to delete, can also be
|
|
100
|
+
# a string of just one range_key, and +conditions+
|
|
98
101
|
#
|
|
99
102
|
def delete(table, ids, options = {})
|
|
100
103
|
range_key = options[:range_key] # array of range keys that matches the ids passed in
|
|
@@ -115,7 +118,7 @@ module Dynamoid
|
|
|
115
118
|
# Scans a table. Generally quite slow; try to avoid using scan if at all possible.
|
|
116
119
|
#
|
|
117
120
|
# @param [String] table the name of the table to write the object to
|
|
118
|
-
# @param [Hash]
|
|
121
|
+
# @param [Hash] query a hash of attributes: matching records will be returned by the scan
|
|
119
122
|
#
|
|
120
123
|
# @since 0.2.0
|
|
121
124
|
def scan(table, query = {}, opts = {})
|
|
@@ -155,8 +158,14 @@ module Dynamoid
|
|
|
155
158
|
#
|
|
156
159
|
# @since 0.2.0
|
|
157
160
|
def method_missing(method, *args, &block)
|
|
158
|
-
|
|
161
|
+
# Don't use keywork arguments delegating (with **kw). It works in
|
|
162
|
+
# different way in different Ruby versions: <= 2.6, 2.7, 3.0 and in some
|
|
163
|
+
# future 3.x versions. Providing that there are no downstream methods
|
|
164
|
+
# with keyword arguments in adapter.
|
|
165
|
+
#
|
|
166
|
+
# https://eregon.me/blog/2019/11/10/the-delegation-challenge-of-ruby27.html
|
|
159
167
|
|
|
168
|
+
return benchmark(method, *args) { adapter.send(method, *args, &block) } if adapter.respond_to?(method)
|
|
160
169
|
super
|
|
161
170
|
end
|
|
162
171
|
|
|
@@ -9,8 +9,18 @@ require_relative 'aws_sdk_v3/table'
|
|
|
9
9
|
require_relative 'aws_sdk_v3/until_past_table_status'
|
|
10
10
|
|
|
11
11
|
module Dynamoid
|
|
12
|
+
# @private
|
|
12
13
|
module AdapterPlugin
|
|
13
14
|
# The AwsSdkV3 adapter provides support for the aws-sdk version 2 for ruby.
|
|
15
|
+
|
|
16
|
+
# Note: Don't use keyword arguments in public methods as far as method
|
|
17
|
+
# calls on adapter are delegated to the plugin.
|
|
18
|
+
#
|
|
19
|
+
# There are breaking changes in Ruby related to delegating keyword
|
|
20
|
+
# arguments so we have decided just to avoid them when use delegation.
|
|
21
|
+
#
|
|
22
|
+
# https://eregon.me/blog/2019/11/10/the-delegation-challenge-of-ruby27.html
|
|
23
|
+
|
|
14
24
|
class AwsSdkV3
|
|
15
25
|
EQ = 'EQ'
|
|
16
26
|
RANGE_MAP = {
|
|
@@ -61,6 +71,25 @@ module Dynamoid
|
|
|
61
71
|
|
|
62
72
|
attr_reader :table_cache
|
|
63
73
|
|
|
74
|
+
# Build an array of values for Condition
|
|
75
|
+
# Is used in ScanFilter and QueryFilter
|
|
76
|
+
# https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Condition.html
|
|
77
|
+
# @param [String] operator value of RANGE_MAP or FIELD_MAP hash, e.g. "EQ", "LT" etc
|
|
78
|
+
# @param [Object] value scalar value or array/set
|
|
79
|
+
def self.attribute_value_list(operator, value)
|
|
80
|
+
# For BETWEEN and IN operators we should keep value as is (it should be already an array)
|
|
81
|
+
# NULL and NOT_NULL require absence of attribute list
|
|
82
|
+
# For all the other operators we wrap the value with array
|
|
83
|
+
# https://docs.aws.amazon.com/en_us/amazondynamodb/latest/developerguide/LegacyConditionalParameters.Conditions.html
|
|
84
|
+
if %w[BETWEEN IN].include?(operator)
|
|
85
|
+
[value].flatten
|
|
86
|
+
elsif %w[NULL NOT_NULL].include?(operator)
|
|
87
|
+
nil
|
|
88
|
+
else
|
|
89
|
+
[value]
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
64
93
|
# Establish the connection to DynamoDB.
|
|
65
94
|
#
|
|
66
95
|
# @return [Aws::DynamoDB::Client] the DynamoDB connection
|
|
@@ -78,23 +107,25 @@ module Dynamoid
|
|
|
78
107
|
|
|
79
108
|
# if credentials are passed, they already contain access key & secret key
|
|
80
109
|
if Dynamoid::Config.credentials?
|
|
81
|
-
connection_hash[:credentials] = Dynamoid::Config.credentials
|
|
110
|
+
@connection_hash[:credentials] = Dynamoid::Config.credentials
|
|
82
111
|
else
|
|
83
112
|
# otherwise, pass access key & secret key for credentials creation
|
|
84
113
|
if Dynamoid::Config.access_key?
|
|
85
|
-
connection_hash[:access_key_id] = Dynamoid::Config.access_key
|
|
114
|
+
@connection_hash[:access_key_id] = Dynamoid::Config.access_key
|
|
86
115
|
end
|
|
87
116
|
if Dynamoid::Config.secret_key?
|
|
88
|
-
connection_hash[:secret_access_key] = Dynamoid::Config.secret_key
|
|
117
|
+
@connection_hash[:secret_access_key] = Dynamoid::Config.secret_key
|
|
89
118
|
end
|
|
90
119
|
end
|
|
91
120
|
|
|
92
|
-
# https://github.com/aws/aws-sdk-ruby/blob/master/gems/aws-sdk-core/lib/aws-sdk-core/plugins/logging.rb
|
|
93
|
-
# https://github.com/aws/aws-sdk-ruby/blob/master/gems/aws-sdk-core/lib/aws-sdk-core/log/formatter.rb
|
|
94
|
-
formatter = Aws::Log::Formatter.new(':operation | Request :http_request_body | Response :http_response_body')
|
|
95
121
|
@connection_hash[:logger] = Dynamoid::Config.logger
|
|
96
122
|
@connection_hash[:log_level] = :debug
|
|
97
|
-
|
|
123
|
+
|
|
124
|
+
# https://github.com/aws/aws-sdk-ruby/blob/master/gems/aws-sdk-core/lib/aws-sdk-core/plugins/logging.rb
|
|
125
|
+
# https://github.com/aws/aws-sdk-ruby/blob/master/gems/aws-sdk-core/lib/aws-sdk-core/log/formatter.rb
|
|
126
|
+
if Dynamoid::Config.log_formatter
|
|
127
|
+
@connection_hash[:log_formatter] = Dynamoid::Config.log_formatter
|
|
128
|
+
end
|
|
98
129
|
|
|
99
130
|
@connection_hash
|
|
100
131
|
end
|
|
@@ -122,9 +153,9 @@ module Dynamoid
|
|
|
122
153
|
# end
|
|
123
154
|
#
|
|
124
155
|
# @param [String] table_name the name of the table
|
|
125
|
-
# @param [Array]
|
|
126
|
-
# @param [Hash] additional options
|
|
127
|
-
# @
|
|
156
|
+
# @param [Array] objects to be processed
|
|
157
|
+
# @param [Hash] options additional options
|
|
158
|
+
# @yield [true|false] invokes an optional block with argument - whether there are unprocessed items
|
|
128
159
|
#
|
|
129
160
|
# See:
|
|
130
161
|
# * http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchWriteItem.html
|
|
@@ -179,9 +210,9 @@ module Dynamoid
|
|
|
179
210
|
# end
|
|
180
211
|
# end
|
|
181
212
|
#
|
|
182
|
-
# @param [Hash]
|
|
213
|
+
# @param [Hash] table_names_with_ids the hash of tables and IDs to retrieve
|
|
183
214
|
# @param [Hash] options to be passed to underlying BatchGet call
|
|
184
|
-
# @param [Proc] optional block can be passed to handle each batch of items
|
|
215
|
+
# @param [Proc] block optional block can be passed to handle each batch of items
|
|
185
216
|
#
|
|
186
217
|
# @return [Hash] a hash where keys are the table names and the values are the retrieved items
|
|
187
218
|
#
|
|
@@ -259,7 +290,7 @@ module Dynamoid
|
|
|
259
290
|
false
|
|
260
291
|
end
|
|
261
292
|
|
|
262
|
-
def update_time_to_live(table_name
|
|
293
|
+
def update_time_to_live(table_name, attribute)
|
|
263
294
|
request = {
|
|
264
295
|
table_name: table_name,
|
|
265
296
|
time_to_live_specification: {
|
|
@@ -525,11 +556,11 @@ module Dynamoid
|
|
|
525
556
|
hk = table.hash_key
|
|
526
557
|
rk = table.range_key
|
|
527
558
|
|
|
528
|
-
scan(table_name, {}, {}).flat_map{ |i| i }.
|
|
529
|
-
|
|
530
|
-
opts[:range_key] = attributes[rk.to_sym] if rk
|
|
531
|
-
delete_item(table_name, attributes[hk], opts)
|
|
559
|
+
ids = scan(table_name, {}, {}).flat_map { |i| i }.map do |attributes|
|
|
560
|
+
rk ? [attributes[hk], attributes[rk.to_sym]] : attributes[hk]
|
|
532
561
|
end
|
|
562
|
+
|
|
563
|
+
batch_delete_item(table_name => ids)
|
|
533
564
|
end
|
|
534
565
|
|
|
535
566
|
def count(table_name)
|
|
@@ -587,25 +618,6 @@ module Dynamoid
|
|
|
587
618
|
end
|
|
588
619
|
end
|
|
589
620
|
|
|
590
|
-
# Build an array of values for Condition
|
|
591
|
-
# Is used in ScanFilter and QueryFilter
|
|
592
|
-
# https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Condition.html
|
|
593
|
-
# @params [String] operator: value of RANGE_MAP or FIELD_MAP hash, e.g. "EQ", "LT" etc
|
|
594
|
-
# @params [Object] value: scalar value or array/set
|
|
595
|
-
def self.attribute_value_list(operator, value)
|
|
596
|
-
# For BETWEEN and IN operators we should keep value as is (it should be already an array)
|
|
597
|
-
# NULL and NOT_NULL require absence of attribute list
|
|
598
|
-
# For all the other operators we wrap the value with array
|
|
599
|
-
# https://docs.aws.amazon.com/en_us/amazondynamodb/latest/developerguide/LegacyConditionalParameters.Conditions.html
|
|
600
|
-
if %w[BETWEEN IN].include?(operator)
|
|
601
|
-
[value].flatten
|
|
602
|
-
elsif %w[NULL NOT_NULL].include?(operator)
|
|
603
|
-
nil
|
|
604
|
-
else
|
|
605
|
-
[value]
|
|
606
|
-
end
|
|
607
|
-
end
|
|
608
|
-
|
|
609
621
|
def sanitize_item(attributes)
|
|
610
622
|
config_value = Dynamoid.config.store_attribute_with_nil_value
|
|
611
623
|
store_attribute_with_nil_value = config_value.nil? ? false : !!config_value
|