dynamoid 0.7.1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +2 -24
- data/README.markdown +89 -73
- data/Rakefile +10 -36
- data/dynamoid.gemspec +56 -191
- data/lib/dynamoid.rb +6 -4
- data/lib/dynamoid/adapter.rb +64 -150
- data/lib/dynamoid/adapter_plugin/aws_sdk_v2.rb +579 -0
- data/lib/dynamoid/components.rb +0 -1
- data/lib/dynamoid/config.rb +2 -5
- data/lib/dynamoid/criteria.rb +1 -1
- data/lib/dynamoid/criteria/chain.rb +27 -140
- data/lib/dynamoid/document.rb +2 -2
- data/lib/dynamoid/errors.rb +30 -9
- data/lib/dynamoid/fields.rb +15 -3
- data/lib/dynamoid/finders.rb +7 -6
- data/lib/dynamoid/identity_map.rb +1 -5
- data/lib/dynamoid/persistence.rb +108 -93
- metadata +56 -229
- data/.document +0 -5
- data/.rspec +0 -1
- data/.travis.yml +0 -7
- data/Gemfile.lock +0 -81
- data/Gemfile_activemodel4 +0 -24
- data/Gemfile_activemodel4.lock +0 -88
- data/VERSION +0 -1
- data/doc/.nojekyll +0 -0
- data/doc/Dynamoid.html +0 -328
- data/doc/Dynamoid/Adapter.html +0 -1872
- data/doc/Dynamoid/Adapter/AwsSdk.html +0 -2101
- data/doc/Dynamoid/Adapter/Local.html +0 -1574
- data/doc/Dynamoid/Associations.html +0 -138
- data/doc/Dynamoid/Associations/Association.html +0 -847
- data/doc/Dynamoid/Associations/BelongsTo.html +0 -161
- data/doc/Dynamoid/Associations/ClassMethods.html +0 -766
- data/doc/Dynamoid/Associations/HasAndBelongsToMany.html +0 -167
- data/doc/Dynamoid/Associations/HasMany.html +0 -167
- data/doc/Dynamoid/Associations/HasOne.html +0 -161
- data/doc/Dynamoid/Associations/ManyAssociation.html +0 -1684
- data/doc/Dynamoid/Associations/SingleAssociation.html +0 -627
- data/doc/Dynamoid/Components.html +0 -242
- data/doc/Dynamoid/Config.html +0 -412
- data/doc/Dynamoid/Config/Options.html +0 -638
- data/doc/Dynamoid/Criteria.html +0 -138
- data/doc/Dynamoid/Criteria/Chain.html +0 -1471
- data/doc/Dynamoid/Criteria/ClassMethods.html +0 -105
- data/doc/Dynamoid/Dirty.html +0 -424
- data/doc/Dynamoid/Dirty/ClassMethods.html +0 -174
- data/doc/Dynamoid/Document.html +0 -1033
- data/doc/Dynamoid/Document/ClassMethods.html +0 -1116
- data/doc/Dynamoid/Errors.html +0 -125
- data/doc/Dynamoid/Errors/ConditionalCheckFailedException.html +0 -141
- data/doc/Dynamoid/Errors/DocumentNotValid.html +0 -221
- data/doc/Dynamoid/Errors/Error.html +0 -137
- data/doc/Dynamoid/Errors/InvalidField.html +0 -141
- data/doc/Dynamoid/Errors/InvalidQuery.html +0 -131
- data/doc/Dynamoid/Errors/MissingRangeKey.html +0 -141
- data/doc/Dynamoid/Fields.html +0 -686
- data/doc/Dynamoid/Fields/ClassMethods.html +0 -438
- data/doc/Dynamoid/Finders.html +0 -135
- data/doc/Dynamoid/Finders/ClassMethods.html +0 -943
- data/doc/Dynamoid/IdentityMap.html +0 -492
- data/doc/Dynamoid/IdentityMap/ClassMethods.html +0 -534
- data/doc/Dynamoid/Indexes.html +0 -321
- data/doc/Dynamoid/Indexes/ClassMethods.html +0 -369
- data/doc/Dynamoid/Indexes/Index.html +0 -1142
- data/doc/Dynamoid/Middleware.html +0 -115
- data/doc/Dynamoid/Middleware/IdentityMap.html +0 -264
- data/doc/Dynamoid/Persistence.html +0 -892
- data/doc/Dynamoid/Persistence/ClassMethods.html +0 -836
- data/doc/Dynamoid/Validations.html +0 -415
- data/doc/_index.html +0 -506
- data/doc/class_list.html +0 -53
- data/doc/css/common.css +0 -1
- data/doc/css/full_list.css +0 -57
- data/doc/css/style.css +0 -338
- data/doc/file.LICENSE.html +0 -73
- data/doc/file.README.html +0 -416
- data/doc/file_list.html +0 -58
- data/doc/frames.html +0 -28
- data/doc/index.html +0 -416
- data/doc/js/app.js +0 -214
- data/doc/js/full_list.js +0 -178
- data/doc/js/jquery.js +0 -4
- data/doc/method_list.html +0 -1144
- data/doc/top-level-namespace.html +0 -112
- data/lib/dynamoid/adapter/aws_sdk.rb +0 -287
- data/lib/dynamoid/indexes.rb +0 -69
- data/lib/dynamoid/indexes/index.rb +0 -103
- data/spec/app/models/address.rb +0 -13
- data/spec/app/models/camel_case.rb +0 -34
- data/spec/app/models/car.rb +0 -6
- data/spec/app/models/magazine.rb +0 -11
- data/spec/app/models/message.rb +0 -9
- data/spec/app/models/nuclear_submarine.rb +0 -5
- data/spec/app/models/sponsor.rb +0 -8
- data/spec/app/models/subscription.rb +0 -12
- data/spec/app/models/tweet.rb +0 -12
- data/spec/app/models/user.rb +0 -26
- data/spec/app/models/vehicle.rb +0 -7
- data/spec/dynamoid/adapter/aws_sdk_spec.rb +0 -376
- data/spec/dynamoid/adapter_spec.rb +0 -155
- data/spec/dynamoid/associations/association_spec.rb +0 -194
- data/spec/dynamoid/associations/belongs_to_spec.rb +0 -71
- data/spec/dynamoid/associations/has_and_belongs_to_many_spec.rb +0 -47
- data/spec/dynamoid/associations/has_many_spec.rb +0 -42
- data/spec/dynamoid/associations/has_one_spec.rb +0 -45
- data/spec/dynamoid/associations_spec.rb +0 -16
- data/spec/dynamoid/config_spec.rb +0 -27
- data/spec/dynamoid/criteria/chain_spec.rb +0 -210
- data/spec/dynamoid/criteria_spec.rb +0 -75
- data/spec/dynamoid/dirty_spec.rb +0 -57
- data/spec/dynamoid/document_spec.rb +0 -180
- data/spec/dynamoid/fields_spec.rb +0 -156
- data/spec/dynamoid/finders_spec.rb +0 -147
- data/spec/dynamoid/identity_map_spec.rb +0 -45
- data/spec/dynamoid/indexes/index_spec.rb +0 -104
- data/spec/dynamoid/indexes_spec.rb +0 -25
- data/spec/dynamoid/persistence_spec.rb +0 -301
- data/spec/dynamoid/validations_spec.rb +0 -36
- data/spec/dynamoid_spec.rb +0 -9
- data/spec/spec_helper.rb +0 -55
- data/spec/support/with_partitioning.rb +0 -15
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9a8130b39add7870e0217be2f31fc55808f02be5
|
4
|
+
data.tar.gz: 73f7caa9ae29e070fcae4deb87461f7a004d0470
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1e73c399b586b8c264f1b19dcb99e121705a82aaea2efcf68b4b250d1b35d30065ddd3c2fa213c6226260063dd8afd3beb6cd78a6ff7c1130fe92486544392ec
|
7
|
+
data.tar.gz: 89d9baede7e7b40c1e15ffa358b84199c8b5cdc9ea8fb855083da2b63651b1f8304b4afe845c0f7b9b1771a9957e0e0a57881663ad40d67542a0aaa9175605d7
|
data/Gemfile
CHANGED
@@ -1,24 +1,2 @@
|
|
1
|
-
source "
|
2
|
-
|
3
|
-
gem 'activemodel'
|
4
|
-
gem 'tzinfo'
|
5
|
-
gem 'aws-sdk'
|
6
|
-
|
7
|
-
# Add dependencies required to use your gem here.
|
8
|
-
# Example:
|
9
|
-
# gem "activesupport", ">= 2.3.5"
|
10
|
-
|
11
|
-
# Add dependencies to develop your gem here.
|
12
|
-
# Include everything needed to run rake, tests, features, etc.
|
13
|
-
group :development do
|
14
|
-
gem "rake"
|
15
|
-
gem "rspec"
|
16
|
-
gem "bundler"
|
17
|
-
gem "jeweler"
|
18
|
-
gem "yard"
|
19
|
-
gem "redcarpet", '1.17.2'
|
20
|
-
gem 'github-markup'
|
21
|
-
gem 'pry'
|
22
|
-
gem 'fake_dynamo', '~>0.1.3'
|
23
|
-
gem "mocha", '0.10.0'
|
24
|
-
end
|
1
|
+
source "http://www.rubygems.org"
|
2
|
+
gemspec
|
data/README.markdown
CHANGED
@@ -15,82 +15,52 @@ But if you want a fast, scalable, simple, easy-to-use database (and a Gem that s
|
|
15
15
|
Installing Dynamoid is pretty simple. First include the Gem in your Gemfile:
|
16
16
|
|
17
17
|
```ruby
|
18
|
-
gem 'dynamoid'
|
18
|
+
gem 'dynamoid', '~> 1'
|
19
19
|
```
|
20
20
|
## Prerequisities
|
21
21
|
|
22
|
-
Dynamoid depends on
|
22
|
+
Dynamoid depends on the aws-sdk, and this is tested on the current version of aws-sdk (~> 2), rails (~> 4).
|
23
23
|
Hence the configuration as needed for aws to work will be dealt with by aws setup.
|
24
24
|
|
25
25
|
Here are the steps to setup aws-sdk.
|
26
26
|
|
27
27
|
```ruby
|
28
|
-
gem 'aws-sdk'
|
28
|
+
gem 'aws-sdk', '~>2'
|
29
29
|
```
|
30
|
-
(or) include the aws-sdk in your Gemfile.
|
31
|
-
|
32
|
-
|
33
|
-
[Refer this link for aws setup](https://github.com/amazonwebservices/aws-sdk-for-ruby)
|
34
30
|
|
35
|
-
|
36
|
-
|
37
|
-
Fill in your AWS Access Key ID and Secret Access Key
|
38
|
-
|
39
|
-
```ruby
|
40
|
-
|
41
|
-
|
42
|
-
development:
|
43
|
-
access_key_id: REPLACE_WITH_ACCESS_KEY_ID
|
44
|
-
secret_access_key: REPLACE_WITH_SECRET_ACCESS_KEY
|
45
|
-
dynamo_db_endpoint: dynamodb.ap-southeast-1.amazonaws.com
|
46
|
-
|
47
|
-
test:
|
48
|
-
<<: *development
|
49
|
-
|
50
|
-
production:
|
51
|
-
<<: *development
|
31
|
+
(or) include the aws-sdk in your Gemfile.
|
52
32
|
|
53
|
-
|
33
|
+
**NOTE:** Dynamoid-1.0 doesn't support aws-sdk Version 1 (Use Dynamoid Major Version 0 for aws-sdk 1)
|
54
34
|
|
55
|
-
|
35
|
+
Configure AWS access:
|
36
|
+
[Reference](https://github.com/aws/aws-sdk-ruby)
|
56
37
|
|
38
|
+
For example, to configure AWS access:
|
57
39
|
|
58
|
-
|
40
|
+
Create config/initializers/aws.rb as follows:
|
59
41
|
|
60
42
|
```ruby
|
61
43
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
AWS.config({
|
67
|
-
:access_key_id => 'REPLACE_WITH_ACCESS_KEY_ID',
|
68
|
-
:secret_access_key => 'REPLACE_WITH_SECRET_ACCESS_KEY',
|
69
|
-
:dynamo_db_endpoint => 'dynamodb.ap-southeast-1.amazonaws.com'
|
44
|
+
Aws.config.update({
|
45
|
+
region: 'us-west-2',
|
46
|
+
credentials: Aws::Credentials.new('REPLACE_WITH_ACCESS_KEY_ID', 'REPLACE_WITH_SECRET_ACCESS_KEY'),
|
70
47
|
})
|
71
48
|
|
72
|
-
|
73
49
|
```
|
74
50
|
|
75
51
|
For a full list of the DDB regions, you can go
|
76
52
|
[here](http://docs.aws.amazon.com/general/latest/gr/rande.html#ddb_region).
|
77
53
|
|
78
|
-
|
79
|
-
Refer to the documentation of the AWS module at the below link for all of the configuration options supported by DynamoDB.
|
80
|
-
|
81
|
-
[Module AWS](http://docs.amazonwebservices.com/AWSRubySDK/latest/frames.html#!http%3A//docs.amazonwebservices.com/AWSRubySDK/latest/AWS.html)
|
82
|
-
|
83
54
|
Then you need to initialize Dynamoid config to get it going. Put code similar to this somewhere (a Rails initializer would be a great place for this if you're using Rails):
|
84
55
|
|
85
56
|
```ruby
|
86
57
|
Dynamoid.configure do |config|
|
87
|
-
config.adapter = '
|
58
|
+
config.adapter = 'aws_sdk_v2' # This adapter establishes a connection to the DynamoDB servers using Amazon's own AWS gem.
|
88
59
|
config.namespace = "dynamoid_app_development" # To namespace tables created by Dynamoid from other tables you might have.
|
89
60
|
config.warn_on_scan = true # Output a warning to the logger when you perform a scan rather than a query on a table.
|
90
|
-
config.partitioning = true # Spread writes randomly across the database. See "partitioning" below for more.
|
91
|
-
config.partition_size = 200 # Determine the key space size that writes are randomly spread across.
|
92
61
|
config.read_capacity = 100 # Read capacity for your tables
|
93
62
|
config.write_capacity = 20 # 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).
|
94
64
|
end
|
95
65
|
|
96
66
|
```
|
@@ -126,7 +96,12 @@ These fields will not change an existing table: so specifying a new read_capacit
|
|
126
96
|
|
127
97
|
You'll have to define all the fields on the model and the data type of each field. Every field on the object must be included here; if you miss any they'll be completely bypassed during DynamoDB's initialization and will not appear on the model objects.
|
128
98
|
|
129
|
-
By default, fields are assumed to be of type ```:string```.
|
99
|
+
By default, fields are assumed to be of type ```:string```. Other built-in types are
|
100
|
+
```:integer```, ```:number```, ```:set```, ```:array```, ```:datetime```, ```:boolean```, and ```:serialized```.
|
101
|
+
If built-in types do not suit you, you can use a custom field type represented by an arbitrary class, provided that the class supports a compatible serialization interface.
|
102
|
+
The primary use case for using a custom field type is to represent your business logic with high-level types, while ensuring portability or backward-compatibility of the serialized representation.
|
103
|
+
|
104
|
+
You get magic columns of id (string), created_at (datetime), and updated_at (datetime) for free.
|
130
105
|
|
131
106
|
```ruby
|
132
107
|
class User
|
@@ -135,32 +110,77 @@ class User
|
|
135
110
|
field :name
|
136
111
|
field :email
|
137
112
|
field :rank, :integer
|
138
|
-
field :number, :
|
113
|
+
field :number, :number
|
139
114
|
field :joined_at, :datetime
|
140
115
|
field :hash, :serialized
|
141
116
|
|
142
117
|
end
|
143
118
|
```
|
144
119
|
|
145
|
-
|
146
|
-
|
147
|
-
You can also define indexes on fields, combinations of fields, and one range field. Yes, only one range field: in DynamoDB tables can have at most one range index, so make good use of it! To make an index, just specify the fields you want it on, either single or in an array. If the entire index is a range, pass ```:range => true```. Otherwise, pass the attribute that will become the range key. The only range attributes you can use right now are integers, floats, and datetimes. If you pass a string as a range key likely DynamoDB will complain a lot.
|
120
|
+
You can optionally set a default value on a field using either a plain value or a lambda:
|
148
121
|
|
149
122
|
```ruby
|
150
|
-
|
151
|
-
|
123
|
+
field :actions_taken, :integer, {default: 0}
|
124
|
+
field :joined_at, :datetime, {default: ->(){Time.now}}
|
125
|
+
```
|
152
126
|
|
153
|
-
|
127
|
+
To use a custom type for a field, suppose you have a `Money` type.
|
154
128
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
129
|
+
```ruby
|
130
|
+
class Money
|
131
|
+
# ... your business logic ...
|
132
|
+
|
133
|
+
def dynamoid_dump
|
134
|
+
"serialized representation as a string"
|
135
|
+
end
|
136
|
+
|
137
|
+
def self.dynamoid_load(serialized_str)
|
138
|
+
# parse serialized representation and return a Money instance
|
139
|
+
Money.new(...)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
class User
|
144
|
+
include Dynamoid::Document
|
145
|
+
|
146
|
+
field :balance, Money
|
147
|
+
end
|
148
|
+
```
|
160
149
|
|
161
|
-
|
150
|
+
If you want to use a third-party class (which does not support `#dynamoid_dump` and `.dynamoid_load`)
|
151
|
+
as your field type, you can use an adapter class providing `.dynamoid_dump` and `.dynamoid_load` class methods
|
152
|
+
for your third-party class. (`.dynamoid_load` can remain the same from the previous example; here we just
|
153
|
+
add a level of indirection for serializing.) Example:
|
154
|
+
|
155
|
+
```ruby
|
156
|
+
# Third-party Money class
|
157
|
+
class Money; end
|
158
|
+
|
159
|
+
class MoneyAdapter
|
160
|
+
def self.dynamoid_load(money_serialized_str)
|
161
|
+
Money.new(...)
|
162
|
+
end
|
163
|
+
|
164
|
+
def self.dynamoid_dump(money_obj)
|
165
|
+
money_obj.value.to_s
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
class User
|
170
|
+
include Dynamoid::Document
|
171
|
+
|
172
|
+
field :balance, MoneyAdapter
|
173
|
+
end
|
162
174
|
```
|
163
175
|
|
176
|
+
Lastly, you can control the data type of your custom-class-backed field at the DynamoDB level.
|
177
|
+
This is especially important if you want to use your custom field as a numeric range or for
|
178
|
+
number-oriented queries. By default custom fields are persisted as a string attribute, but
|
179
|
+
your custom class can override this with a `.dynamoid_field_type` class method, which would
|
180
|
+
return either `:string` or `:number`.
|
181
|
+
(DynamoDB supports some other attribute types, but Dynamoid yet does not.)
|
182
|
+
|
183
|
+
|
164
184
|
### Associations
|
165
185
|
|
166
186
|
Just like in ActiveRecord (or your other favorite ORM), Dynamoid uses associations to create links between models.
|
@@ -245,7 +265,7 @@ Save forces persistence to the datastore: a unique ID is also assigned, but it i
|
|
245
265
|
u.id # => "3a9f7216-4726-4aea-9fbc-8554ae9292cb"
|
246
266
|
```
|
247
267
|
|
248
|
-
|
268
|
+
To use associations, you use association methods very similar to ActiveRecord's:
|
249
269
|
|
250
270
|
```ruby
|
251
271
|
address = u.addresses.create
|
@@ -271,10 +291,10 @@ u.addresses.where(:city => 'Chicago').all
|
|
271
291
|
|
272
292
|
But keep in mind Dynamoid -- and document-based storage systems in general -- are not drop-in replacements for existing relational databases. The above query does not efficiently perform a conditional join, but instead finds all the user's addresses and naively filters them in Ruby. For large associations this is a performance hit compared to relational database engines.
|
273
293
|
|
274
|
-
You can also limit
|
294
|
+
You can also limit the number of evaluated records, or select a record from which to start, to support pagination:
|
275
295
|
|
276
296
|
```ruby
|
277
|
-
Address.
|
297
|
+
Address.eval_limit(5).start(address) # Only 5 addresses.
|
278
298
|
```
|
279
299
|
|
280
300
|
For large queries that return many rows, Dynamoid can use AWS' support for requesting documents in batches:
|
@@ -305,14 +325,6 @@ User.where("created_at.lt" => DateTime.now - 1.day).all
|
|
305
325
|
|
306
326
|
It also supports .gte and .lte. Turning those into symbols and allowing a Rails SQL-style string syntax is in the works. You can only have one range argument per query, because of DynamoDB's inherent limitations, so use it sensibly!
|
307
327
|
|
308
|
-
## Partitioning, Provisioning, and Performance
|
309
|
-
|
310
|
-
DynamoDB achieves much of its speed by relying on a random pattern of writes and reads: internally, hash keys are distributed across servers, and reading from two consecutive servers is much faster than reading from the same server twice. Of course, many of our applications request one key (like a commonly used role, a superuser, or a very popular product) much more frequently than other keys. In DynamoDB, this will result in lowered throughput and slower response times, and is a design pattern we should try to avoid.
|
311
|
-
|
312
|
-
Dynamoid attempts to obviate this problem transparently by employing a partitioning strategy to divide up keys randomly across DynamoDB's servers. Each ID is assigned an additional number (by default 0 to 199, but you can increase the partition size in Dynamoid's configuration) upon save; when read, all 200 hashes are retrieved simultaneously and the most recently updated one is returned to the application. This results in a significant net performance increase, and is usually invisible to the application itself. It does, however, bring up the important issue of provisioning your DynamoDB tables correctly.
|
313
|
-
|
314
|
-
When your read or write throughput exceed your table's allowed provisioning, DynamoDB will wait on connections until throughput is available again. This will appear as very, very slow requests and can be somewhat frustrating. Partitioning significantly increases the amount of throughput tables will experience; though DynamoDB will ignore keys that don't exist, if you have 20 partitioned keys representing one object, all will be retrieved every time the object is requested. Ensure that your tables are set up for this kind of throughput, or turn provisioning off, to make sure that DynamoDB doesn't throttle your requests.
|
315
|
-
|
316
328
|
## Concurrency
|
317
329
|
|
318
330
|
Dynamoid supports basic, ActiveRecord-like optimistic locking on save operations. Simply add a `lock_version` column to your table like so:
|
@@ -327,10 +339,10 @@ class MyTable
|
|
327
339
|
end
|
328
340
|
```
|
329
341
|
|
330
|
-
In this example, all saves to `MyTable` will raise an `
|
331
|
-
|
332
|
-
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.
|
342
|
+
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.
|
333
343
|
|
344
|
+
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
|
+
|
334
346
|
## Credits
|
335
347
|
|
336
348
|
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.
|
@@ -344,10 +356,14 @@ Also, without contributors the project wouldn't be nearly as awesome. So many th
|
|
344
356
|
* [Jason Dew](https://github.com/jasondew)
|
345
357
|
* [Luis Arias](https://github.com/luisantonioa)
|
346
358
|
* [Stefan Neculai](https://github.com/stefanneculai)
|
359
|
+
* [Philip White](https://github.com/philipmw)
|
360
|
+
* [Peeyush Kumar](https://github.com/peeyush1234)
|
347
361
|
|
348
362
|
## Running the tests
|
349
363
|
|
350
|
-
Running the tests is fairly simple. In one window, run `
|
364
|
+
Running the tests is fairly simple. In one window, run `bin/start_dynamodblocal`, and in the other, use `rake`.
|
365
|
+
|
366
|
+
[![Build Status](https://travis-ci.org/Dynamoid/Dynamoid.svg)](https://travis-ci.org/Dynamoid/Dynamoid)
|
351
367
|
|
352
368
|
## Copyright
|
353
369
|
|
data/Rakefile
CHANGED
@@ -11,20 +11,6 @@ rescue Bundler::BundlerError => e
|
|
11
11
|
end
|
12
12
|
require 'rake'
|
13
13
|
|
14
|
-
require 'jeweler'
|
15
|
-
Jeweler::Tasks.new do |gem|
|
16
|
-
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
-
gem.name = "dynamoid"
|
18
|
-
gem.homepage = "http://github.com/Veraticus/Dynamoid"
|
19
|
-
gem.license = "MIT"
|
20
|
-
gem.summary = "Dynamoid is an ORM for Amazon's DynamoDB"
|
21
|
-
gem.description = "Dynamoid is an ORM for Amazon's DynamoDB that supports offline development, associations, querying, and everything else you'd expect from an ActiveRecord-style replacement."
|
22
|
-
gem.email = "josh@joshsymonds.com"
|
23
|
-
gem.authors = ["Josh Symonds"]
|
24
|
-
# dependencies defined in Gemfile
|
25
|
-
end
|
26
|
-
Jeweler::RubygemsDotOrgTasks.new
|
27
|
-
|
28
14
|
require 'rspec/core'
|
29
15
|
require 'rspec/core/rake_task'
|
30
16
|
RSpec::Core::RakeTask.new(:spec) do |spec|
|
@@ -36,31 +22,19 @@ RSpec::Core::RakeTask.new(:rcov) do |spec|
|
|
36
22
|
spec.rcov = true
|
37
23
|
end
|
38
24
|
|
39
|
-
desc "Start
|
25
|
+
desc "Start DynamoDBLocal, run tests, clean up"
|
40
26
|
task :unattended_spec do |t|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
27
|
+
|
28
|
+
if system('bin/start_dynamodblocal')
|
29
|
+
puts 'DynamoDBLocal started; proceeding with specs.'
|
30
|
+
else
|
31
|
+
raise 'Unable to start DynamoDBLocal. Cannot run unattended specs.'
|
32
|
+
end
|
46
33
|
|
47
|
-
#Launch fake_dynamo
|
48
|
-
pid = Process.spawn'fake_dynamo', '-d', data_file, err: '/dev/null', out: '/dev/null'
|
49
34
|
#Cleanup
|
50
|
-
at_exit
|
51
|
-
|
52
|
-
|
53
|
-
}
|
54
|
-
|
55
|
-
#Wait for fake_dynamo to start taking requests
|
56
|
-
40.downto(0) do |count| #Wait up to 2 seconds
|
57
|
-
begin
|
58
|
-
s = TCPSocket.new 'localhost', 4567
|
59
|
-
s.close
|
60
|
-
break
|
61
|
-
rescue Errno::ECONNREFUSED
|
62
|
-
raise if(count == 0)
|
63
|
-
sleep 0.1
|
35
|
+
at_exit do
|
36
|
+
unless system('bin/stop_dynamodblocal')
|
37
|
+
$stderr.puts 'Unable to cleanly stop DynamoDBLocal.'
|
64
38
|
end
|
65
39
|
end
|
66
40
|
|
data/dynamoid.gemspec
CHANGED
@@ -1,208 +1,73 @@
|
|
1
|
-
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
1
|
# -*- encoding: utf-8 -*-
|
5
2
|
|
6
3
|
Gem::Specification.new do |s|
|
7
4
|
s.name = "dynamoid"
|
8
|
-
s.version = "0.
|
5
|
+
s.version = "1.0.0"
|
9
6
|
|
10
|
-
|
11
|
-
s.authors =
|
12
|
-
|
7
|
+
# Keep in sync with README
|
8
|
+
s.authors = %w(
|
9
|
+
Josh Symonds
|
10
|
+
Logan Bowers
|
11
|
+
Craig Heneveld
|
12
|
+
Anatha Kumaran
|
13
|
+
Jason Dew
|
14
|
+
Luis Arias
|
15
|
+
Stefan Neculai
|
16
|
+
Philip White
|
17
|
+
Peeyush Kumar
|
18
|
+
)
|
13
19
|
s.description = "Dynamoid is an ORM for Amazon's DynamoDB that supports offline development, associations, querying, and everything else you'd expect from an ActiveRecord-style replacement."
|
14
|
-
s.email = "josh@joshsymonds.com"
|
15
20
|
s.extra_rdoc_files = [
|
16
21
|
"LICENSE.txt",
|
17
22
|
"README.markdown"
|
18
23
|
]
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
"doc/Dynamoid/Document.html",
|
54
|
-
"doc/Dynamoid/Document/ClassMethods.html",
|
55
|
-
"doc/Dynamoid/Errors.html",
|
56
|
-
"doc/Dynamoid/Errors/ConditionalCheckFailedException.html",
|
57
|
-
"doc/Dynamoid/Errors/DocumentNotValid.html",
|
58
|
-
"doc/Dynamoid/Errors/Error.html",
|
59
|
-
"doc/Dynamoid/Errors/InvalidField.html",
|
60
|
-
"doc/Dynamoid/Errors/InvalidQuery.html",
|
61
|
-
"doc/Dynamoid/Errors/MissingRangeKey.html",
|
62
|
-
"doc/Dynamoid/Fields.html",
|
63
|
-
"doc/Dynamoid/Fields/ClassMethods.html",
|
64
|
-
"doc/Dynamoid/Finders.html",
|
65
|
-
"doc/Dynamoid/Finders/ClassMethods.html",
|
66
|
-
"doc/Dynamoid/IdentityMap.html",
|
67
|
-
"doc/Dynamoid/IdentityMap/ClassMethods.html",
|
68
|
-
"doc/Dynamoid/Indexes.html",
|
69
|
-
"doc/Dynamoid/Indexes/ClassMethods.html",
|
70
|
-
"doc/Dynamoid/Indexes/Index.html",
|
71
|
-
"doc/Dynamoid/Middleware.html",
|
72
|
-
"doc/Dynamoid/Middleware/IdentityMap.html",
|
73
|
-
"doc/Dynamoid/Persistence.html",
|
74
|
-
"doc/Dynamoid/Persistence/ClassMethods.html",
|
75
|
-
"doc/Dynamoid/Validations.html",
|
76
|
-
"doc/_index.html",
|
77
|
-
"doc/class_list.html",
|
78
|
-
"doc/css/common.css",
|
79
|
-
"doc/css/full_list.css",
|
80
|
-
"doc/css/style.css",
|
81
|
-
"doc/file.LICENSE.html",
|
82
|
-
"doc/file.README.html",
|
83
|
-
"doc/file_list.html",
|
84
|
-
"doc/frames.html",
|
85
|
-
"doc/index.html",
|
86
|
-
"doc/js/app.js",
|
87
|
-
"doc/js/full_list.js",
|
88
|
-
"doc/js/jquery.js",
|
89
|
-
"doc/method_list.html",
|
90
|
-
"doc/top-level-namespace.html",
|
91
|
-
"dynamoid.gemspec",
|
92
|
-
"lib/dynamoid.rb",
|
93
|
-
"lib/dynamoid/adapter.rb",
|
94
|
-
"lib/dynamoid/adapter/aws_sdk.rb",
|
95
|
-
"lib/dynamoid/associations.rb",
|
96
|
-
"lib/dynamoid/associations/association.rb",
|
97
|
-
"lib/dynamoid/associations/belongs_to.rb",
|
98
|
-
"lib/dynamoid/associations/has_and_belongs_to_many.rb",
|
99
|
-
"lib/dynamoid/associations/has_many.rb",
|
100
|
-
"lib/dynamoid/associations/has_one.rb",
|
101
|
-
"lib/dynamoid/associations/many_association.rb",
|
102
|
-
"lib/dynamoid/associations/single_association.rb",
|
103
|
-
"lib/dynamoid/components.rb",
|
104
|
-
"lib/dynamoid/config.rb",
|
105
|
-
"lib/dynamoid/config/options.rb",
|
106
|
-
"lib/dynamoid/criteria.rb",
|
107
|
-
"lib/dynamoid/criteria/chain.rb",
|
108
|
-
"lib/dynamoid/dirty.rb",
|
109
|
-
"lib/dynamoid/document.rb",
|
110
|
-
"lib/dynamoid/errors.rb",
|
111
|
-
"lib/dynamoid/fields.rb",
|
112
|
-
"lib/dynamoid/finders.rb",
|
113
|
-
"lib/dynamoid/identity_map.rb",
|
114
|
-
"lib/dynamoid/indexes.rb",
|
115
|
-
"lib/dynamoid/indexes/index.rb",
|
116
|
-
"lib/dynamoid/middleware/identity_map.rb",
|
117
|
-
"lib/dynamoid/persistence.rb",
|
118
|
-
"lib/dynamoid/validations.rb",
|
119
|
-
"spec/app/models/address.rb",
|
120
|
-
"spec/app/models/camel_case.rb",
|
121
|
-
"spec/app/models/car.rb",
|
122
|
-
"spec/app/models/magazine.rb",
|
123
|
-
"spec/app/models/message.rb",
|
124
|
-
"spec/app/models/nuclear_submarine.rb",
|
125
|
-
"spec/app/models/sponsor.rb",
|
126
|
-
"spec/app/models/subscription.rb",
|
127
|
-
"spec/app/models/tweet.rb",
|
128
|
-
"spec/app/models/user.rb",
|
129
|
-
"spec/app/models/vehicle.rb",
|
130
|
-
"spec/dynamoid/adapter/aws_sdk_spec.rb",
|
131
|
-
"spec/dynamoid/adapter_spec.rb",
|
132
|
-
"spec/dynamoid/associations/association_spec.rb",
|
133
|
-
"spec/dynamoid/associations/belongs_to_spec.rb",
|
134
|
-
"spec/dynamoid/associations/has_and_belongs_to_many_spec.rb",
|
135
|
-
"spec/dynamoid/associations/has_many_spec.rb",
|
136
|
-
"spec/dynamoid/associations/has_one_spec.rb",
|
137
|
-
"spec/dynamoid/associations_spec.rb",
|
138
|
-
"spec/dynamoid/config_spec.rb",
|
139
|
-
"spec/dynamoid/criteria/chain_spec.rb",
|
140
|
-
"spec/dynamoid/criteria_spec.rb",
|
141
|
-
"spec/dynamoid/dirty_spec.rb",
|
142
|
-
"spec/dynamoid/document_spec.rb",
|
143
|
-
"spec/dynamoid/fields_spec.rb",
|
144
|
-
"spec/dynamoid/finders_spec.rb",
|
145
|
-
"spec/dynamoid/identity_map_spec.rb",
|
146
|
-
"spec/dynamoid/indexes/index_spec.rb",
|
147
|
-
"spec/dynamoid/indexes_spec.rb",
|
148
|
-
"spec/dynamoid/persistence_spec.rb",
|
149
|
-
"spec/dynamoid/validations_spec.rb",
|
150
|
-
"spec/dynamoid_spec.rb",
|
151
|
-
"spec/spec_helper.rb",
|
152
|
-
"spec/support/with_partitioning.rb"
|
153
|
-
]
|
154
|
-
s.homepage = "http://github.com/Veraticus/Dynamoid"
|
24
|
+
# file list is generated with `git ls-files | grep -v -E -e '^spec/' -e '^\.' -e 'bin/'`
|
25
|
+
s.files = %w(
|
26
|
+
Gemfile
|
27
|
+
LICENSE.txt
|
28
|
+
README.markdown
|
29
|
+
Rakefile
|
30
|
+
dynamoid.gemspec
|
31
|
+
lib/dynamoid.rb
|
32
|
+
lib/dynamoid/adapter.rb
|
33
|
+
lib/dynamoid/adapter_plugin/aws_sdk_v2.rb
|
34
|
+
lib/dynamoid/associations.rb
|
35
|
+
lib/dynamoid/associations/association.rb
|
36
|
+
lib/dynamoid/associations/belongs_to.rb
|
37
|
+
lib/dynamoid/associations/has_and_belongs_to_many.rb
|
38
|
+
lib/dynamoid/associations/has_many.rb
|
39
|
+
lib/dynamoid/associations/has_one.rb
|
40
|
+
lib/dynamoid/associations/many_association.rb
|
41
|
+
lib/dynamoid/associations/single_association.rb
|
42
|
+
lib/dynamoid/components.rb
|
43
|
+
lib/dynamoid/config.rb
|
44
|
+
lib/dynamoid/config/options.rb
|
45
|
+
lib/dynamoid/criteria.rb
|
46
|
+
lib/dynamoid/criteria/chain.rb
|
47
|
+
lib/dynamoid/dirty.rb
|
48
|
+
lib/dynamoid/document.rb
|
49
|
+
lib/dynamoid/errors.rb
|
50
|
+
lib/dynamoid/fields.rb
|
51
|
+
lib/dynamoid/finders.rb
|
52
|
+
lib/dynamoid/identity_map.rb
|
53
|
+
lib/dynamoid/middleware/identity_map.rb
|
54
|
+
lib/dynamoid/persistence.rb
|
55
|
+
lib/dynamoid/validations.rb
|
56
|
+
)
|
57
|
+
s.homepage = "http://github.com/Dynamoid/Dynamoid"
|
155
58
|
s.licenses = ["MIT"]
|
156
59
|
s.require_paths = ["lib"]
|
157
60
|
s.rubygems_version = "1.8.24"
|
158
61
|
s.summary = "Dynamoid is an ORM for Amazon's DynamoDB"
|
159
62
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
s.add_development_dependency(%q<bundler>, [">= 0"])
|
170
|
-
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
171
|
-
s.add_development_dependency(%q<yard>, [">= 0"])
|
172
|
-
s.add_development_dependency(%q<redcarpet>, ["= 1.17.2"])
|
173
|
-
s.add_development_dependency(%q<github-markup>, [">= 0"])
|
174
|
-
s.add_development_dependency(%q<pry>, [">= 0"])
|
175
|
-
s.add_development_dependency(%q<fake_dynamo>, ["~> 0.1.3"])
|
176
|
-
s.add_development_dependency(%q<mocha>, ["= 0.10.0"])
|
177
|
-
else
|
178
|
-
s.add_dependency(%q<activemodel>, [">= 0"])
|
179
|
-
s.add_dependency(%q<tzinfo>, [">= 0"])
|
180
|
-
s.add_dependency(%q<aws-sdk>, [">= 0"])
|
181
|
-
s.add_dependency(%q<rake>, [">= 0"])
|
182
|
-
s.add_dependency(%q<rspec>, [">= 0"])
|
183
|
-
s.add_dependency(%q<bundler>, [">= 0"])
|
184
|
-
s.add_dependency(%q<jeweler>, [">= 0"])
|
185
|
-
s.add_dependency(%q<yard>, [">= 0"])
|
186
|
-
s.add_dependency(%q<redcarpet>, ["= 1.17.2"])
|
187
|
-
s.add_dependency(%q<github-markup>, [">= 0"])
|
188
|
-
s.add_dependency(%q<pry>, [">= 0"])
|
189
|
-
s.add_dependency(%q<fake_dynamo>, ["~> 0.1.3"])
|
190
|
-
s.add_dependency(%q<mocha>, ["= 0.10.0"])
|
191
|
-
end
|
192
|
-
else
|
193
|
-
s.add_dependency(%q<activemodel>, [">= 0"])
|
194
|
-
s.add_dependency(%q<tzinfo>, [">= 0"])
|
195
|
-
s.add_dependency(%q<aws-sdk>, [">= 0"])
|
196
|
-
s.add_dependency(%q<rake>, [">= 0"])
|
197
|
-
s.add_dependency(%q<rspec>, [">= 0"])
|
198
|
-
s.add_dependency(%q<bundler>, [">= 0"])
|
199
|
-
s.add_dependency(%q<jeweler>, [">= 0"])
|
200
|
-
s.add_dependency(%q<yard>, [">= 0"])
|
201
|
-
s.add_dependency(%q<redcarpet>, ["= 1.17.2"])
|
202
|
-
s.add_dependency(%q<github-markup>, [">= 0"])
|
203
|
-
s.add_dependency(%q<pry>, [">= 0"])
|
204
|
-
s.add_dependency(%q<fake_dynamo>, ["~> 0.1.3"])
|
205
|
-
s.add_dependency(%q<mocha>, ["= 0.10.0"])
|
206
|
-
end
|
63
|
+
s.add_runtime_dependency(%q<activemodel>, ["~> 4"])
|
64
|
+
s.add_runtime_dependency(%q<aws-sdk-resources>, ["~> 2"])
|
65
|
+
s.add_runtime_dependency(%q<concurrent-ruby>, ["~> 0.9"])
|
66
|
+
s.add_development_dependency(%q<rake>, [">= 0"])
|
67
|
+
s.add_development_dependency(%q<rspec>, ["~> 3"])
|
68
|
+
s.add_development_dependency(%q<bundler>, [">= 0"])
|
69
|
+
s.add_development_dependency(%q<yard>, [">= 0"])
|
70
|
+
s.add_development_dependency(%q<github-markup>, [">= 0"])
|
71
|
+
s.add_development_dependency(%q<pry>, [">= 0"])
|
207
72
|
end
|
208
73
|
|