dynamoid 1.2.1 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/README.md +71 -19
- data/dynamoid.gemspec +6 -1
- data/lib/dynamoid/adapter_plugin/aws_sdk_v2.rb +53 -27
- data/lib/dynamoid/associations/belongs_to.rb +2 -2
- data/lib/dynamoid/associations/has_and_belongs_to_many.rb +2 -2
- data/lib/dynamoid/associations/has_many.rb +1 -1
- data/lib/dynamoid/associations/has_one.rb +1 -1
- data/lib/dynamoid/associations/many_association.rb +2 -2
- data/lib/dynamoid/associations/single_association.rb +7 -1
- data/lib/dynamoid/components.rb +1 -1
- data/lib/dynamoid/config.rb +5 -2
- data/lib/dynamoid/errors.rb +3 -0
- data/lib/dynamoid/persistence.rb +34 -7
- data/lib/dynamoid/version.rb +1 -1
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 66d793bb4519ccd94ce9e8dd46550c02db75390e
|
4
|
+
data.tar.gz: 55f4da7a601691112e2eac068a81f3194b893fa5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f26bf8ba08816cffae591a78e2b9148abed5423bd8a84c556888bba9c9e35dd24e971b9425e2729ae71be6ec0ee015eab274e321bcfe99fe18243339e13e2e2b
|
7
|
+
data.tar.gz: c2f267ed34a44de9c940416ebbbc950ab6588aa1e75de85d016171d881466613966223c24d59b669fea09919f1b5a47d8fc1005c68692f9b8c4003dd89a0a045
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,19 @@
|
|
1
|
+
# HEAD
|
2
|
+
|
3
|
+
# 1.3.0
|
4
|
+
|
5
|
+
* Fixed specs (@AlexNisnevich & @pboling)
|
6
|
+
* Fix `blank?` and `present?` behavior for single associations (#110, @AlexNisnevich & @bayesimpact)
|
7
|
+
* Support BatchGet for more than 100 items (#80, @getninjas)
|
8
|
+
* Add ability to specify connection settings specific to Dynamoid (#116, @NielsKSchjoedt)
|
9
|
+
* Adds Support for Rails 5! (#109, @gastzars)
|
10
|
+
* Table Namespace Fix (#79, @alexperto)
|
11
|
+
* Improve Testing Docs (#103, @tadast)
|
12
|
+
* Query All Items by Looping (#102, @richardhsu)
|
13
|
+
* Store document in DocumentNotValid error for easier debugging (#98, holyketzer)
|
14
|
+
* Better support for raw datatype (#104, @OpenGov)
|
15
|
+
* Fix associative tables with non-id primary keys (#86, @everett-wetchler)
|
16
|
+
|
1
17
|
# 1.2.1
|
2
18
|
|
3
19
|
* Remove accidental Gemfile.lock; fix .gitignore (#95, @pboling)
|
data/README.md
CHANGED
@@ -30,7 +30,7 @@ gem 'aws-sdk', '~>2'
|
|
30
30
|
|
31
31
|
(or) include the aws-sdk in your Gemfile.
|
32
32
|
|
33
|
-
**NOTE:** Dynamoid-1.0 doesn't support aws-sdk Version 1 (Use Dynamoid Major Version 0 for aws-sdk 1)
|
33
|
+
**NOTE:** Dynamoid-1.0 doesn't support aws-sdk Version 1 (Use Dynamoid Major Version 0 for aws-sdk 1)
|
34
34
|
|
35
35
|
Configure AWS access:
|
36
36
|
[Reference](https://github.com/aws/aws-sdk-ruby)
|
@@ -48,6 +48,16 @@ Create config/initializers/aws.rb as follows:
|
|
48
48
|
|
49
49
|
```
|
50
50
|
|
51
|
+
Alternatively, if you don't want Aws connection settings to be overwritten for you entire project, you can specify connection settings for Dynamoid only, by setting those in the `Dynamoid.configure` clause:
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
Dynamoid.configure do |config|
|
55
|
+
config.access_key = 'REPLACE_WITH_ACCESS_KEY_ID'
|
56
|
+
config.secret_key = 'REPLACE_WITH_SECRET_ACCESS_KEY'
|
57
|
+
config.region = 'us-west-2'
|
58
|
+
end
|
59
|
+
```
|
60
|
+
|
51
61
|
For a full list of the DDB regions, you can go
|
52
62
|
[here](http://docs.aws.amazon.com/general/latest/gr/rande.html#ddb_region).
|
53
63
|
|
@@ -60,7 +70,7 @@ Then you need to initialize Dynamoid config to get it going. Put code similar to
|
|
60
70
|
config.warn_on_scan = true # Output a warning to the logger when you perform a scan rather than a query on a table.
|
61
71
|
config.read_capacity = 5 # Read capacity for your tables
|
62
72
|
config.write_capacity = 5 # Write capacity for your tables
|
63
|
-
config.endpoint = 'http://localhost:3000' # [Optional]. If provided, it communicates with the DB listening at the endpoint. This is useful for testing with [Amazon Local DB] (http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Tools.DynamoDBLocal.html).
|
73
|
+
config.endpoint = 'http://localhost:3000' # [Optional]. If provided, it communicates with the DB listening at the endpoint. This is useful for testing with [Amazon Local DB] (http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Tools.DynamoDBLocal.html).
|
64
74
|
end
|
65
75
|
|
66
76
|
```
|
@@ -129,20 +139,20 @@ To use a custom type for a field, suppose you have a `Money` type.
|
|
129
139
|
```ruby
|
130
140
|
class Money
|
131
141
|
# ... your business logic ...
|
132
|
-
|
142
|
+
|
133
143
|
def dynamoid_dump
|
134
144
|
"serialized representation as a string"
|
135
145
|
end
|
136
|
-
|
146
|
+
|
137
147
|
def self.dynamoid_load(serialized_str)
|
138
148
|
# parse serialized representation and return a Money instance
|
139
149
|
Money.new(...)
|
140
150
|
end
|
141
151
|
end
|
142
|
-
|
152
|
+
|
143
153
|
class User
|
144
154
|
include Dynamoid::Document
|
145
|
-
|
155
|
+
|
146
156
|
field :balance, Money
|
147
157
|
end
|
148
158
|
```
|
@@ -155,20 +165,20 @@ add a level of indirection for serializing.) Example:
|
|
155
165
|
```ruby
|
156
166
|
# Third-party Money class
|
157
167
|
class Money; end
|
158
|
-
|
168
|
+
|
159
169
|
class MoneyAdapter
|
160
170
|
def self.dynamoid_load(money_serialized_str)
|
161
171
|
Money.new(...)
|
162
172
|
end
|
163
|
-
|
173
|
+
|
164
174
|
def self.dynamoid_dump(money_obj)
|
165
175
|
money_obj.value.to_s
|
166
176
|
end
|
167
177
|
end
|
168
|
-
|
178
|
+
|
169
179
|
class User
|
170
180
|
include Dynamoid::Document
|
171
|
-
|
181
|
+
|
172
182
|
field :balance, MoneyAdapter
|
173
183
|
end
|
174
184
|
```
|
@@ -207,12 +217,12 @@ class Address
|
|
207
217
|
|
208
218
|
...
|
209
219
|
|
210
|
-
belongs_to :
|
220
|
+
belongs_to :user # Automatically links up with the user model
|
211
221
|
|
212
222
|
end
|
213
223
|
```
|
214
224
|
|
215
|
-
Contrary to what you'd expect, association information is always contained on the object specifying the association, even if it seems like the association has a foreign key. This is a side effect of DynamoDB's structure: it's very difficult to find foreign keys without an index. Usually you won't find this to be a problem, but it does mean that association methods that build new models will not work correctly -- for example, ```user.addresses.new``` returns an address that is not associated to the user. We'll be correcting this soon.
|
225
|
+
Contrary to what you'd expect, association information is always contained on the object specifying the association, even if it seems like the association has a foreign key. This is a side effect of DynamoDB's structure: it's very difficult to find foreign keys without an index. Usually you won't find this to be a problem, but it does mean that association methods that build new models will not work correctly -- for example, ```user.addresses.new``` returns an address that is not associated to the user. We'll be correcting this ~soon~ maybe someday, if we get a pull request.
|
216
226
|
|
217
227
|
### Validations
|
218
228
|
|
@@ -327,14 +337,14 @@ It also supports .gte and .lte. Turning those into symbols and allowing a Rails
|
|
327
337
|
|
328
338
|
## Concurrency
|
329
339
|
|
330
|
-
Dynamoid supports basic, ActiveRecord-like optimistic locking on save operations. Simply add a `lock_version` column to your table like so:
|
340
|
+
Dynamoid supports basic, ActiveRecord-like optimistic locking on save operations. Simply add a `lock_version` column to your table like so:
|
331
341
|
|
332
342
|
```ruby
|
333
343
|
class MyTable
|
334
344
|
...
|
335
|
-
|
345
|
+
|
336
346
|
field :lock_version, :integer
|
337
|
-
|
347
|
+
|
338
348
|
...
|
339
349
|
end
|
340
350
|
```
|
@@ -342,7 +352,49 @@ end
|
|
342
352
|
In this example, all saves to `MyTable` will raise an `Dynamoid::Errors::StaleObjectError` if a concurrent process loaded, edited, and saved the same row. Your code should trap this exception, reload the row (so that it will pick up the newest values), and try the save again.
|
343
353
|
|
344
354
|
Calls to `update` and `update!` also increment the `lock_version`, however they do not check the existing value. This guarantees that a update operation will raise an exception in a concurrent save operation, however a save operation will never cause an update to fail. Thus, `update` is useful & safe only for doing atomic operations (e.g. increment a value, add/remove from a set, etc), but should not be used in a read-modify-write pattern.
|
345
|
-
|
355
|
+
|
356
|
+
## Test Environment
|
357
|
+
|
358
|
+
In test environment you will most likely want to clean the database between test runs to keep tests completely isolated. This can be achieved like so
|
359
|
+
|
360
|
+
```ruby
|
361
|
+
module DynamoidReset
|
362
|
+
def self.all
|
363
|
+
Dynamoid.adapter.list_tables.each do |table|
|
364
|
+
# Only delete tables in our namespace
|
365
|
+
if table =~ /^#{Dynamoid::Config.namespace}/
|
366
|
+
Dynamoid.adapter.delete_table(table)
|
367
|
+
end
|
368
|
+
end
|
369
|
+
Dynamoid.adapter.tables.clear
|
370
|
+
# Recreate all tables to avoid unexpected errors
|
371
|
+
Dynamoid.included_models.each(&:create_table)
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
# Reduce noise in test output
|
376
|
+
Dynamoid.logger.level = Logger::FATAL
|
377
|
+
```
|
378
|
+
|
379
|
+
If you're using RSpec you can invoke the above like so:
|
380
|
+
|
381
|
+
```ruby
|
382
|
+
RSpec.configure do |config|
|
383
|
+
config.before(:each) do
|
384
|
+
DynamoidReset.all
|
385
|
+
end
|
386
|
+
end
|
387
|
+
```
|
388
|
+
|
389
|
+
In Rails, you may also want to ensure you do not delete non-test data accidentally by adding the following to your test environment setup:
|
390
|
+
|
391
|
+
```ruby
|
392
|
+
raise "Tests should be run in 'test' environment only" if Rails.env != 'test'
|
393
|
+
Dynamoid.configure do |config|
|
394
|
+
config.namespace = "#{Rails.application.railtie_name}_#{Rails.env}"
|
395
|
+
end
|
396
|
+
```
|
397
|
+
|
346
398
|
## Credits
|
347
399
|
|
348
400
|
Dynamoid borrows code, structure, and even its name very liberally from the truly amazing [Mongoid](https://github.com/mongoid/mongoid). Without Mongoid to crib from none of this would have been possible, and I hope they don't mind me reusing their very awesome ideas to make DynamoDB just as accessible to the Ruby world as MongoDB.
|
@@ -363,7 +415,7 @@ Also, without contributors the project wouldn't be nearly as awesome. So many th
|
|
363
415
|
* [Brian Glusman](https://github.com/bglusman) *
|
364
416
|
* [Peter Boling](https://github.com/pboling) *
|
365
417
|
|
366
|
-
\* Current
|
418
|
+
\* Current Maintainers
|
367
419
|
|
368
420
|
## Running the tests
|
369
421
|
|
@@ -380,9 +432,9 @@ Running the tests is fairly simple. You should have an instance of DynamoDB runn
|
|
380
432
|
```shell
|
381
433
|
bin/start_dynamodblocal
|
382
434
|
```
|
383
|
-
|
435
|
+
|
384
436
|
* and lastly, use `rake` to run the tests.
|
385
|
-
|
437
|
+
|
386
438
|
```shell
|
387
439
|
rake
|
388
440
|
```
|
data/dynamoid.gemspec
CHANGED
@@ -38,7 +38,11 @@ Gem::Specification.new do |spec|
|
|
38
38
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
39
39
|
spec.require_paths = ["lib"]
|
40
40
|
|
41
|
-
|
41
|
+
if Gem::Version.new(RUBY_VERSION) > Gem::Version.new("2.2.2")
|
42
|
+
spec.add_runtime_dependency(%q<activemodel>, [">= 4"])
|
43
|
+
else
|
44
|
+
spec.add_runtime_dependency(%q<activemodel>, ["~> 4"])
|
45
|
+
end
|
42
46
|
spec.add_runtime_dependency(%q<aws-sdk-resources>, ["~> 2"])
|
43
47
|
spec.add_runtime_dependency(%q<concurrent-ruby>, [">= 1.0"])
|
44
48
|
spec.add_development_dependency(%q<rake>, [">= 10"])
|
@@ -49,4 +53,5 @@ Gem::Specification.new do |spec|
|
|
49
53
|
spec.add_development_dependency(%q<pry>, [">= 0"])
|
50
54
|
spec.add_development_dependency(%q<coveralls>, [">= 0"])
|
51
55
|
spec.add_development_dependency(%q<rspec-retry>, [">= 0"])
|
56
|
+
spec.add_development_dependency(%q<activesupport>, ["~> 4"])
|
52
57
|
end
|
@@ -36,14 +36,29 @@ module Dynamoid
|
|
36
36
|
#
|
37
37
|
# @return [Aws::DynamoDB::Client] the DynamoDB connection
|
38
38
|
def connect!
|
39
|
-
@client =
|
40
|
-
Aws::DynamoDB::Client.new(endpoint: Dynamoid::Config.endpoint)
|
41
|
-
else
|
42
|
-
Aws::DynamoDB::Client.new
|
43
|
-
end
|
39
|
+
@client = Aws::DynamoDB::Client.new(connection_config)
|
44
40
|
@table_cache = {}
|
45
41
|
end
|
46
42
|
|
43
|
+
def connection_config
|
44
|
+
@connection_hash = {}
|
45
|
+
|
46
|
+
if Dynamoid::Config.endpoint?
|
47
|
+
@connection_hash[:endpoint] = Dynamoid::Config.endpoint
|
48
|
+
end
|
49
|
+
if Dynamoid::Config.access_key?
|
50
|
+
@connection_hash[:access_key_id] = Dynamoid::Config.access_key
|
51
|
+
end
|
52
|
+
if Dynamoid::Config.secret_key?
|
53
|
+
@connection_hash[:secret_access_key] = Dynamoid::Config.secret_key
|
54
|
+
end
|
55
|
+
if Dynamoid::Config.region?
|
56
|
+
@connection_hash[:region] = Dynamoid::Config.region
|
57
|
+
end
|
58
|
+
|
59
|
+
@connection_hash
|
60
|
+
end
|
61
|
+
|
47
62
|
# Return the client object.
|
48
63
|
#
|
49
64
|
# @since 1.0.0
|
@@ -97,35 +112,41 @@ module Dynamoid
|
|
97
112
|
request_items = Hash.new{|h, k| h[k] = []}
|
98
113
|
return request_items if table_ids.all?{|k, v| v.empty?}
|
99
114
|
|
115
|
+
ret = Hash.new([].freeze) # Default for tables where no rows are returned
|
116
|
+
|
100
117
|
table_ids.each do |t, ids|
|
101
118
|
next if ids.empty?
|
102
119
|
tbl = describe_table(t)
|
103
120
|
hk = tbl.hash_key.to_s
|
104
121
|
rng = tbl.range_key.to_s
|
105
122
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
123
|
+
Array(ids).each_slice(Dynamoid::Config.batch_size) do |ids|
|
124
|
+
request_items = Hash.new{|h, k| h[k] = []}
|
125
|
+
|
126
|
+
keys = if rng.present?
|
127
|
+
Array(ids).map do |h,r|
|
128
|
+
{ hk => h, rng => r }
|
129
|
+
end
|
130
|
+
else
|
131
|
+
Array(ids).map do |id|
|
132
|
+
{ hk => id }
|
133
|
+
end
|
113
134
|
end
|
114
|
-
end
|
115
135
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
end
|
136
|
+
request_items[t] = {
|
137
|
+
keys: keys
|
138
|
+
}
|
120
139
|
|
121
|
-
|
122
|
-
|
123
|
-
|
140
|
+
results = client.batch_get_item(
|
141
|
+
request_items: request_items
|
142
|
+
)
|
124
143
|
|
125
|
-
|
126
|
-
|
127
|
-
|
144
|
+
results.data[:responses].each do |table, rows|
|
145
|
+
ret[table] += rows.collect { |r| result_item_to_hash(r) }
|
146
|
+
end
|
147
|
+
end
|
128
148
|
end
|
149
|
+
|
129
150
|
ret
|
130
151
|
end
|
131
152
|
|
@@ -447,11 +468,16 @@ module Dynamoid
|
|
447
468
|
q[:key_conditions] = key_conditions
|
448
469
|
|
449
470
|
Enumerator.new { |y|
|
450
|
-
|
471
|
+
loop do
|
472
|
+
results = client.query(q)
|
473
|
+
results.items.each { |row| y << result_item_to_hash(row) }
|
451
474
|
|
452
|
-
|
453
|
-
|
454
|
-
|
475
|
+
if(lk = results.last_evaluated_key)
|
476
|
+
q[:exclusive_start_key] = lk
|
477
|
+
else
|
478
|
+
break
|
479
|
+
end
|
480
|
+
end
|
455
481
|
}
|
456
482
|
end
|
457
483
|
|
@@ -29,14 +29,14 @@ module Dynamoid #:nodoc:
|
|
29
29
|
#
|
30
30
|
# @since 0.2.0
|
31
31
|
def associate_target(object)
|
32
|
-
object.update_attribute(target_attribute, target_ids.merge(Array(source.
|
32
|
+
object.update_attribute(target_attribute, target_ids.merge(Array(source.hash_key)))
|
33
33
|
end
|
34
34
|
|
35
35
|
# Disassociate a source object from this association.
|
36
36
|
#
|
37
37
|
# @since 0.2.0
|
38
38
|
def disassociate_target(object)
|
39
|
-
source.update_attribute(source_attribute, target_ids - Array(source.
|
39
|
+
source.update_attribute(source_attribute, target_ids - Array(source.hash_key))
|
40
40
|
end
|
41
41
|
end
|
42
42
|
end
|
@@ -24,7 +24,7 @@ module Dynamoid #:nodoc:
|
|
24
24
|
# @since 0.2.0
|
25
25
|
def associate_target(object)
|
26
26
|
ids = object.send(target_attribute) || Set.new
|
27
|
-
object.update_attribute(target_attribute, ids.merge(Array(source.
|
27
|
+
object.update_attribute(target_attribute, ids.merge(Array(source.hash_key)))
|
28
28
|
end
|
29
29
|
|
30
30
|
# Disassociate a source object from this association.
|
@@ -32,7 +32,7 @@ module Dynamoid #:nodoc:
|
|
32
32
|
# @since 0.2.0
|
33
33
|
def disassociate_target(object)
|
34
34
|
ids = object.send(target_attribute) || Set.new
|
35
|
-
object.update_attribute(target_attribute, ids - Array(source.
|
35
|
+
object.update_attribute(target_attribute, ids - Array(source.hash_key))
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
@@ -23,7 +23,7 @@ module Dynamoid #:nodoc:
|
|
23
23
|
#
|
24
24
|
# @since 0.2.0
|
25
25
|
def associate_target(object)
|
26
|
-
object.update_attribute(target_attribute, Set[source.
|
26
|
+
object.update_attribute(target_attribute, Set[source.hash_key])
|
27
27
|
end
|
28
28
|
|
29
29
|
# Disassociate a source object from this association.
|
@@ -24,7 +24,7 @@ module Dynamoid #:nodoc:
|
|
24
24
|
#
|
25
25
|
# @since 0.2.0
|
26
26
|
def associate_target(object)
|
27
|
-
object.update_attribute(target_attribute, Set[source.
|
27
|
+
object.update_attribute(target_attribute, Set[source.hash_key])
|
28
28
|
end
|
29
29
|
|
30
30
|
# Disassociate a source object from this association.
|
@@ -52,7 +52,7 @@ module Dynamoid #:nodoc:
|
|
52
52
|
#
|
53
53
|
# @since 0.2.0
|
54
54
|
def delete(object)
|
55
|
-
source.update_attribute(source_attribute, source_ids - Array(object).collect(&:
|
55
|
+
source.update_attribute(source_attribute, source_ids - Array(object).collect(&:hash_key))
|
56
56
|
Array(object).each {|o| self.send(:disassociate_target, o)} if target_association
|
57
57
|
object
|
58
58
|
end
|
@@ -67,7 +67,7 @@ module Dynamoid #:nodoc:
|
|
67
67
|
#
|
68
68
|
# @since 0.2.0
|
69
69
|
def <<(object)
|
70
|
-
source.update_attribute(source_attribute, source_ids.merge(Array(object).collect(&:
|
70
|
+
source.update_attribute(source_attribute, source_ids.merge(Array(object).collect(&:hash_key)))
|
71
71
|
Array(object).each {|o| self.send(:associate_target, o)} if target_association
|
72
72
|
object
|
73
73
|
end
|
@@ -9,7 +9,7 @@ module Dynamoid #:nodoc:
|
|
9
9
|
|
10
10
|
def setter(object)
|
11
11
|
delete
|
12
|
-
source.update_attribute(source_attribute, Set[object.
|
12
|
+
source.update_attribute(source_attribute, Set[object.hash_key])
|
13
13
|
self.send(:associate_target, object) if target_association
|
14
14
|
object
|
15
15
|
end
|
@@ -53,6 +53,12 @@ module Dynamoid #:nodoc:
|
|
53
53
|
target.nil?
|
54
54
|
end
|
55
55
|
|
56
|
+
def empty?
|
57
|
+
# This is needed to that ActiveSupport's #blank? and #present?
|
58
|
+
# methods work as expected for SingleAssociations.
|
59
|
+
target.nil?
|
60
|
+
end
|
61
|
+
|
56
62
|
private
|
57
63
|
|
58
64
|
# Find the target of the has_one association.
|
data/lib/dynamoid/components.rb
CHANGED
@@ -23,7 +23,7 @@ module Dynamoid
|
|
23
23
|
include ActiveModel::Naming
|
24
24
|
include ActiveModel::Observing if defined?(ActiveModel::Observing)
|
25
25
|
include ActiveModel::Serializers::JSON
|
26
|
-
include ActiveModel::Serializers::Xml
|
26
|
+
include ActiveModel::Serializers::Xml if defined?(ActiveModel::Serializers::Xml)
|
27
27
|
include Dynamoid::Fields
|
28
28
|
include Dynamoid::Indexes
|
29
29
|
include Dynamoid::Persistence
|
data/lib/dynamoid/config.rb
CHANGED
@@ -14,8 +14,10 @@ module Dynamoid
|
|
14
14
|
option :adapter, :default => 'aws_sdk_v2'
|
15
15
|
option :namespace, :default => defined?(Rails) ? "dynamoid_#{Rails.application.class.parent_name}_#{Rails.env}" : "dynamoid"
|
16
16
|
option :logger, :default => defined?(Rails)
|
17
|
-
option :access_key
|
18
|
-
option :secret_key
|
17
|
+
option :access_key, :default => nil
|
18
|
+
option :secret_key, :default => nil
|
19
|
+
option :region, :default => nil
|
20
|
+
option :batch_size, :default => 100
|
19
21
|
option :read_capacity, :default => 100
|
20
22
|
option :write_capacity, :default => 20
|
21
23
|
option :warn_on_scan, :default => true
|
@@ -26,6 +28,7 @@ module Dynamoid
|
|
26
28
|
option :timestamps, :default => true
|
27
29
|
option :sync_retry_max_times, :default => 60 # a bit over 2 minutes
|
28
30
|
option :sync_retry_wait_seconds, :default => 2
|
31
|
+
option :convert_big_decimal, :default => false
|
29
32
|
|
30
33
|
# The default logger for Dynamoid: either the Rails logger or just stdout.
|
31
34
|
#
|
data/lib/dynamoid/errors.rb
CHANGED
data/lib/dynamoid/persistence.rb
CHANGED
@@ -18,13 +18,8 @@ module Dynamoid
|
|
18
18
|
def table_name
|
19
19
|
table_base_name = options[:name] || base_class.name.split('::').last
|
20
20
|
.downcase.pluralize
|
21
|
-
table_prefix = if Dynamoid::Config.namespace.nil? then
|
22
|
-
''
|
23
|
-
else
|
24
|
-
"#{Dynamoid::Config.namespace}_"
|
25
|
-
end
|
26
21
|
|
27
|
-
@table_name ||=
|
22
|
+
@table_name ||= [Dynamoid::Config.namespace.to_s,table_base_name].reject(&:empty?).join("_")
|
28
23
|
end
|
29
24
|
|
30
25
|
# Creates a table.
|
@@ -96,7 +91,7 @@ module Dynamoid
|
|
96
91
|
value = default_value.respond_to?(:call) ? default_value.call : default_value
|
97
92
|
end
|
98
93
|
|
99
|
-
|
94
|
+
unless value.nil?
|
100
95
|
case options[:type]
|
101
96
|
when :string
|
102
97
|
value.to_s
|
@@ -106,6 +101,12 @@ module Dynamoid
|
|
106
101
|
BigDecimal.new(value.to_s)
|
107
102
|
when :array
|
108
103
|
value.to_a
|
104
|
+
when :raw
|
105
|
+
if value.is_a?(Hash)
|
106
|
+
undump_hash(value)
|
107
|
+
else
|
108
|
+
value
|
109
|
+
end
|
109
110
|
when :set
|
110
111
|
Set.new(value)
|
111
112
|
when :datetime
|
@@ -145,6 +146,30 @@ module Dynamoid
|
|
145
146
|
end
|
146
147
|
end
|
147
148
|
|
149
|
+
private
|
150
|
+
|
151
|
+
def undump_hash(hash)
|
152
|
+
{}.tap do |h|
|
153
|
+
hash.each { |key, value| h[key.to_sym] = undump_hash_value(value) }
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def undump_hash_value(val)
|
158
|
+
case val
|
159
|
+
when BigDecimal
|
160
|
+
if Dynamoid::Config.convert_big_decimal
|
161
|
+
val.to_f
|
162
|
+
else
|
163
|
+
val
|
164
|
+
end
|
165
|
+
when Hash
|
166
|
+
undump_hash(val)
|
167
|
+
when Array
|
168
|
+
val.map { |v| undump_hash_value(v) }
|
169
|
+
else
|
170
|
+
val
|
171
|
+
end
|
172
|
+
end
|
148
173
|
end
|
149
174
|
|
150
175
|
# Set updated_at and any passed in field to current DateTime. Useful for things like last_login_at, etc.
|
@@ -286,6 +311,8 @@ module Dynamoid
|
|
286
311
|
!value.nil? ? value.to_time.to_f : nil
|
287
312
|
when :serialized
|
288
313
|
options[:serializer] ? options[:serializer].dump(value) : value.to_yaml
|
314
|
+
when :raw
|
315
|
+
!value.nil? ? value : nil
|
289
316
|
when :boolean
|
290
317
|
!value.nil? ? value.to_s[0] : nil
|
291
318
|
else
|
data/lib/dynamoid/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dynamoid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josh Symonds
|
@@ -20,7 +20,7 @@ authors:
|
|
20
20
|
autorequire:
|
21
21
|
bindir: exe
|
22
22
|
cert_chain: []
|
23
|
-
date: 2016-
|
23
|
+
date: 2016-12-13 00:00:00.000000000 Z
|
24
24
|
dependencies:
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: activemodel
|
@@ -176,6 +176,20 @@ dependencies:
|
|
176
176
|
- - ">="
|
177
177
|
- !ruby/object:Gem::Version
|
178
178
|
version: '0'
|
179
|
+
- !ruby/object:Gem::Dependency
|
180
|
+
name: activesupport
|
181
|
+
requirement: !ruby/object:Gem::Requirement
|
182
|
+
requirements:
|
183
|
+
- - "~>"
|
184
|
+
- !ruby/object:Gem::Version
|
185
|
+
version: '4'
|
186
|
+
type: :development
|
187
|
+
prerelease: false
|
188
|
+
version_requirements: !ruby/object:Gem::Requirement
|
189
|
+
requirements:
|
190
|
+
- - "~>"
|
191
|
+
- !ruby/object:Gem::Version
|
192
|
+
version: '4'
|
179
193
|
description: Dynamoid is an ORM for Amazon's DynamoDB that supports offline development,
|
180
194
|
associations, querying, and everything else you'd expect from an ActiveRecord-style
|
181
195
|
replacement.
|