dynamoid-edge 1.1.0
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 +7 -0
- data/CHANGELOG.md +21 -0
- data/Gemfile +2 -0
- data/LICENSE.txt +20 -0
- data/README.markdown +377 -0
- data/Rakefile +67 -0
- data/dynamoid-edge.gemspec +74 -0
- data/lib/dynamoid/adapter.rb +181 -0
- data/lib/dynamoid/adapter_plugin/aws_sdk_v2.rb +761 -0
- data/lib/dynamoid/associations/association.rb +105 -0
- data/lib/dynamoid/associations/belongs_to.rb +44 -0
- data/lib/dynamoid/associations/has_and_belongs_to_many.rb +40 -0
- data/lib/dynamoid/associations/has_many.rb +39 -0
- data/lib/dynamoid/associations/has_one.rb +39 -0
- data/lib/dynamoid/associations/many_association.rb +191 -0
- data/lib/dynamoid/associations/single_association.rb +69 -0
- data/lib/dynamoid/associations.rb +106 -0
- data/lib/dynamoid/components.rb +37 -0
- data/lib/dynamoid/config/options.rb +78 -0
- data/lib/dynamoid/config.rb +54 -0
- data/lib/dynamoid/criteria/chain.rb +212 -0
- data/lib/dynamoid/criteria.rb +29 -0
- data/lib/dynamoid/dirty.rb +47 -0
- data/lib/dynamoid/document.rb +201 -0
- data/lib/dynamoid/errors.rb +63 -0
- data/lib/dynamoid/fields.rb +156 -0
- data/lib/dynamoid/finders.rb +197 -0
- data/lib/dynamoid/identity_map.rb +92 -0
- data/lib/dynamoid/middleware/identity_map.rb +16 -0
- data/lib/dynamoid/persistence.rb +324 -0
- data/lib/dynamoid/validations.rb +36 -0
- data/lib/dynamoid.rb +50 -0
- metadata +226 -0
@@ -0,0 +1,324 @@
|
|
1
|
+
require 'bigdecimal'
|
2
|
+
require 'securerandom'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
# encoding: utf-8
|
6
|
+
module Dynamoid
|
7
|
+
|
8
|
+
# Persistence is responsible for dumping objects to and marshalling objects from the datastore. It tries to reserialize
|
9
|
+
# values to be of the same type as when they were passed in, based on the fields in the class.
|
10
|
+
module Persistence
|
11
|
+
extend ActiveSupport::Concern
|
12
|
+
|
13
|
+
attr_accessor :new_record
|
14
|
+
alias :new_record? :new_record
|
15
|
+
|
16
|
+
module ClassMethods
|
17
|
+
|
18
|
+
def table_name
|
19
|
+
@table_name ||= "#{Dynamoid::Config.namespace}_#{options[:name] || base_class.name.split('::').last.downcase.pluralize}"
|
20
|
+
end
|
21
|
+
|
22
|
+
# Creates a table.
|
23
|
+
#
|
24
|
+
# @param [Hash] options options to pass for table creation
|
25
|
+
# @option options [Symbol] :id the id field for the table
|
26
|
+
# @option options [Symbol] :table_name the actual name for the table
|
27
|
+
# @option options [Integer] :read_capacity set the read capacity for the table; does not work on existing tables
|
28
|
+
# @option options [Integer] :write_capacity set the write capacity for the table; does not work on existing tables
|
29
|
+
# @option options [Hash] {range_key => :type} a hash of the name of the range key and a symbol of its type
|
30
|
+
# @option options [Symbol] :hash_key_type the dynamo type of the hash key (:string or :number)
|
31
|
+
# @since 0.4.0
|
32
|
+
def create_table(options = {})
|
33
|
+
if self.range_key
|
34
|
+
range_key_hash = { range_key => dynamo_type(attributes[range_key][:type]) }
|
35
|
+
else
|
36
|
+
range_key_hash = nil
|
37
|
+
end
|
38
|
+
options = {
|
39
|
+
:id => self.hash_key,
|
40
|
+
:table_name => self.table_name,
|
41
|
+
:write_capacity => self.write_capacity,
|
42
|
+
:read_capacity => self.read_capacity,
|
43
|
+
:range_key => range_key_hash,
|
44
|
+
:hash_key_type => dynamo_type(attributes[self.hash_key][:type]),
|
45
|
+
:local_secondary_indexes => self.local_secondary_indexes.values,
|
46
|
+
:global_secondary_indexes => self.global_secondary_indexes.values
|
47
|
+
}.merge(options)
|
48
|
+
|
49
|
+
Dynamoid.adapter.create_table(options[:table_name], options[:id], options)
|
50
|
+
end
|
51
|
+
|
52
|
+
def from_database(attrs = {})
|
53
|
+
clazz = attrs[:type] ? obj = attrs[:type].constantize : self
|
54
|
+
clazz.new(attrs).tap { |r| r.new_record = false }
|
55
|
+
end
|
56
|
+
|
57
|
+
# Undump an object into a hash, converting each type from a string representation of itself into the type specified by the field.
|
58
|
+
#
|
59
|
+
# @since 0.2.0
|
60
|
+
def undump(incoming = nil)
|
61
|
+
incoming = (incoming || {}).symbolize_keys
|
62
|
+
Hash.new.tap do |hash|
|
63
|
+
self.attributes.each do |attribute, options|
|
64
|
+
hash[attribute] = undump_field(incoming[attribute], options)
|
65
|
+
end
|
66
|
+
incoming.each {|attribute, value| hash[attribute] = value unless hash.has_key? attribute }
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Undump a string value for a given type.
|
71
|
+
#
|
72
|
+
# @since 0.2.0
|
73
|
+
def undump_field(value, options)
|
74
|
+
if (field_class = options[:type]).is_a?(Class)
|
75
|
+
raise 'Dynamoid class-type fields do not support default values' if options[:default]
|
76
|
+
|
77
|
+
if field_class.respond_to?(:dynamoid_load)
|
78
|
+
field_class.dynamoid_load(value)
|
79
|
+
end
|
80
|
+
elsif options[:type] == :serialized
|
81
|
+
if value.is_a?(String)
|
82
|
+
options[:serializer] ? options[:serializer].load(value) : YAML.load(value)
|
83
|
+
else
|
84
|
+
value
|
85
|
+
end
|
86
|
+
else
|
87
|
+
if value.nil? && (default_value = options[:default])
|
88
|
+
value = default_value.respond_to?(:call) ? default_value.call : default_value
|
89
|
+
end
|
90
|
+
|
91
|
+
if !value.nil?
|
92
|
+
case options[:type]
|
93
|
+
when :string
|
94
|
+
value.to_s
|
95
|
+
when :integer
|
96
|
+
Integer(value)
|
97
|
+
when :number
|
98
|
+
BigDecimal.new(value.to_s)
|
99
|
+
when :array
|
100
|
+
value.to_a
|
101
|
+
when :set
|
102
|
+
Set.new(value)
|
103
|
+
when :datetime
|
104
|
+
if value.is_a?(Date) || value.is_a?(DateTime) || value.is_a?(Time)
|
105
|
+
value
|
106
|
+
else
|
107
|
+
Time.at(value).to_datetime
|
108
|
+
end
|
109
|
+
when :boolean
|
110
|
+
# persisted as 't', but because undump is called during initialize it can come in as true
|
111
|
+
if value == 't' || value == true
|
112
|
+
true
|
113
|
+
elsif value == 'f' || value == false
|
114
|
+
false
|
115
|
+
else
|
116
|
+
raise ArgumentError, "Boolean column neither true nor false"
|
117
|
+
end
|
118
|
+
else
|
119
|
+
raise ArgumentError, "Unknown type #{options[:type]}"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def dynamo_type(type)
|
126
|
+
if type.is_a?(Class)
|
127
|
+
type.respond_to?(:dynamoid_field_type) ? type.dynamoid_field_type : :string
|
128
|
+
else
|
129
|
+
case type
|
130
|
+
when :integer, :number, :datetime
|
131
|
+
:number
|
132
|
+
when :string, :serialized
|
133
|
+
:string
|
134
|
+
else
|
135
|
+
raise 'unknown type'
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
141
|
+
|
142
|
+
# Set updated_at and any passed in field to current DateTime. Useful for things like last_login_at, etc.
|
143
|
+
#
|
144
|
+
def touch(name = nil)
|
145
|
+
now = DateTime.now
|
146
|
+
self.updated_at = now
|
147
|
+
attributes[name] = now if name
|
148
|
+
save
|
149
|
+
end
|
150
|
+
|
151
|
+
# Is this object persisted in the datastore? Required for some ActiveModel integration stuff.
|
152
|
+
#
|
153
|
+
# @since 0.2.0
|
154
|
+
def persisted?
|
155
|
+
!new_record?
|
156
|
+
end
|
157
|
+
|
158
|
+
# Run the callbacks and then persist this object in the datastore.
|
159
|
+
#
|
160
|
+
# @since 0.2.0
|
161
|
+
def save(options = {})
|
162
|
+
self.class.create_table
|
163
|
+
|
164
|
+
if new_record?
|
165
|
+
conditions = { :unless_exists => [self.class.hash_key]}
|
166
|
+
conditions[:unless_exists] << range_key if(range_key)
|
167
|
+
|
168
|
+
run_callbacks(:create) { persist(conditions) }
|
169
|
+
else
|
170
|
+
persist
|
171
|
+
end
|
172
|
+
|
173
|
+
self
|
174
|
+
end
|
175
|
+
|
176
|
+
#
|
177
|
+
# update!() will increment the lock_version if the table has the column, but will not check it. Thus, a concurrent save will
|
178
|
+
# never cause an update! to fail, but an update! may cause a concurrent save to fail.
|
179
|
+
#
|
180
|
+
#
|
181
|
+
def update!(conditions = {}, &block)
|
182
|
+
run_callbacks(:update) do
|
183
|
+
options = range_key ? {:range_key => dump_field(self.read_attribute(range_key), self.class.attributes[range_key])} : {}
|
184
|
+
|
185
|
+
begin
|
186
|
+
new_attrs = Dynamoid.adapter.update_item(self.class.table_name, self.hash_key, options.merge(:conditions => conditions)) do |t|
|
187
|
+
if(self.class.attributes[:lock_version])
|
188
|
+
t.add(lock_version: 1)
|
189
|
+
end
|
190
|
+
|
191
|
+
yield t
|
192
|
+
end
|
193
|
+
load(new_attrs)
|
194
|
+
rescue Dynamoid::Errors::ConditionalCheckFailedException
|
195
|
+
raise Dynamoid::Errors::StaleObjectError.new(self, 'update')
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def update(conditions = {}, &block)
|
201
|
+
update!(conditions, &block)
|
202
|
+
true
|
203
|
+
rescue Dynamoid::Errors::StaleObjectError
|
204
|
+
false
|
205
|
+
end
|
206
|
+
|
207
|
+
# Delete this object, but only after running callbacks for it.
|
208
|
+
#
|
209
|
+
# @since 0.2.0
|
210
|
+
def destroy
|
211
|
+
run_callbacks(:destroy) do
|
212
|
+
self.delete
|
213
|
+
end
|
214
|
+
self
|
215
|
+
end
|
216
|
+
|
217
|
+
# Delete this object from the datastore.
|
218
|
+
#
|
219
|
+
# @since 0.2.0
|
220
|
+
def delete
|
221
|
+
options = range_key ? {:range_key => dump_field(self.read_attribute(range_key), self.class.attributes[range_key])} : {}
|
222
|
+
|
223
|
+
# Add an optimistic locking check if the lock_version column exists
|
224
|
+
if(self.class.attributes[:lock_version])
|
225
|
+
conditions = {:if => {}}
|
226
|
+
conditions[:if][:lock_version] =
|
227
|
+
if changes[:lock_version].nil?
|
228
|
+
self.lock_version
|
229
|
+
else
|
230
|
+
changes[:lock_version][0]
|
231
|
+
end
|
232
|
+
options[:conditions] = conditions
|
233
|
+
end
|
234
|
+
Dynamoid.adapter.delete(self.class.table_name, self.hash_key, options)
|
235
|
+
rescue Dynamoid::Errors::ConditionalCheckFailedException
|
236
|
+
raise Dynamoid::Errors::StaleObjectError.new(self, 'delete')
|
237
|
+
end
|
238
|
+
|
239
|
+
# Dump this object's attributes into hash form, fit to be persisted into the datastore.
|
240
|
+
#
|
241
|
+
# @since 0.2.0
|
242
|
+
def dump
|
243
|
+
Hash.new.tap do |hash|
|
244
|
+
self.class.attributes.each do |attribute, options|
|
245
|
+
hash[attribute] = dump_field(self.read_attribute(attribute), options)
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
private
|
251
|
+
|
252
|
+
# Determine how to dump this field. Given a value, it'll determine how to turn it into a value that can be
|
253
|
+
# persisted into the datastore.
|
254
|
+
#
|
255
|
+
# @since 0.2.0
|
256
|
+
def dump_field(value, options)
|
257
|
+
if (field_class = options[:type]).is_a?(Class)
|
258
|
+
if value.respond_to?(:dynamoid_dump)
|
259
|
+
value.dynamoid_dump
|
260
|
+
elsif field_class.respond_to?(:dynamoid_dump)
|
261
|
+
field_class.dynamoid_dump(value)
|
262
|
+
else
|
263
|
+
raise ArgumentError, "Neither #{field_class} nor #{value} support serialization for Dynamoid."
|
264
|
+
end
|
265
|
+
else
|
266
|
+
case options[:type]
|
267
|
+
when :string
|
268
|
+
!value.nil? ? value.to_s : nil
|
269
|
+
when :integer
|
270
|
+
!value.nil? ? Integer(value) : nil
|
271
|
+
when :number
|
272
|
+
!value.nil? ? value : nil
|
273
|
+
when :set
|
274
|
+
!value.nil? ? Set.new(value) : nil
|
275
|
+
when :array
|
276
|
+
!value.nil? ? value : nil
|
277
|
+
when :datetime
|
278
|
+
!value.nil? ? value.to_time.to_f : nil
|
279
|
+
when :serialized
|
280
|
+
options[:serializer] ? options[:serializer].dump(value) : value.to_yaml
|
281
|
+
when :boolean
|
282
|
+
!value.nil? ? value.to_s[0] : nil
|
283
|
+
else
|
284
|
+
raise ArgumentError, "Unknown type #{options[:type]}"
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
# Persist the object into the datastore. Assign it an id first if it doesn't have one.
|
290
|
+
#
|
291
|
+
# @since 0.2.0
|
292
|
+
def persist(conditions = nil)
|
293
|
+
run_callbacks(:save) do
|
294
|
+
self.hash_key = SecureRandom.uuid if self.hash_key.nil? || self.hash_key.blank?
|
295
|
+
|
296
|
+
# Add an exists check to prevent overwriting existing records with new ones
|
297
|
+
if(new_record?)
|
298
|
+
conditions ||= {}
|
299
|
+
(conditions[:unless_exists] ||= []) << self.class.hash_key
|
300
|
+
end
|
301
|
+
|
302
|
+
# Add an optimistic locking check if the lock_version column exists
|
303
|
+
if(self.class.attributes[:lock_version])
|
304
|
+
conditions ||= {}
|
305
|
+
self.lock_version = (lock_version || 0) + 1
|
306
|
+
#Uses the original lock_version value from ActiveModel::Dirty in case user changed lock_version manually
|
307
|
+
(conditions[:if] ||= {})[:lock_version] = changes[:lock_version][0] if(changes[:lock_version][0])
|
308
|
+
end
|
309
|
+
|
310
|
+
begin
|
311
|
+
Dynamoid.adapter.write(self.class.table_name, self.dump, conditions)
|
312
|
+
@new_record = false
|
313
|
+
true
|
314
|
+
rescue Dynamoid::Errors::ConditionalCheckFailedException => e
|
315
|
+
if new_record?
|
316
|
+
raise Dynamoid::Errors::RecordNotUnique.new(e, self)
|
317
|
+
else
|
318
|
+
raise Dynamoid::Errors::StaleObjectError.new(self, 'persist')
|
319
|
+
end
|
320
|
+
end
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
324
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Dynamoid
|
3
|
+
|
4
|
+
# Provide ActiveModel validations to Dynamoid documents.
|
5
|
+
module Validations
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
include ActiveModel::Validations
|
9
|
+
include ActiveModel::Validations::Callbacks
|
10
|
+
|
11
|
+
# Override save to provide validation support.
|
12
|
+
#
|
13
|
+
# @since 0.2.0
|
14
|
+
def save(options = {})
|
15
|
+
options.reverse_merge!(:validate => true)
|
16
|
+
return false if options[:validate] and (not valid?)
|
17
|
+
super
|
18
|
+
end
|
19
|
+
|
20
|
+
# Is this object valid?
|
21
|
+
#
|
22
|
+
# @since 0.2.0
|
23
|
+
def valid?(context = nil)
|
24
|
+
context ||= (new_record? ? :create : :update)
|
25
|
+
super(context)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Raise an error unless this object is valid.
|
29
|
+
#
|
30
|
+
# @since 0.2.0
|
31
|
+
def save!
|
32
|
+
raise Dynamoid::Errors::DocumentNotValid.new(self) unless valid?
|
33
|
+
save(:validate => false)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/dynamoid.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require "delegate"
|
2
|
+
require "time"
|
3
|
+
require "securerandom"
|
4
|
+
require "active_support"
|
5
|
+
require "active_support/core_ext"
|
6
|
+
require 'active_support/json'
|
7
|
+
require "active_support/inflector"
|
8
|
+
require "active_support/lazy_load_hooks"
|
9
|
+
require "active_support/time_with_zone"
|
10
|
+
require "active_model"
|
11
|
+
|
12
|
+
require 'dynamoid/errors'
|
13
|
+
require 'dynamoid/fields'
|
14
|
+
require 'dynamoid/indexes'
|
15
|
+
require 'dynamoid/associations'
|
16
|
+
require 'dynamoid/persistence'
|
17
|
+
require 'dynamoid/dirty'
|
18
|
+
require 'dynamoid/validations'
|
19
|
+
require 'dynamoid/criteria'
|
20
|
+
require 'dynamoid/finders'
|
21
|
+
require 'dynamoid/identity_map'
|
22
|
+
require 'dynamoid/config'
|
23
|
+
require 'dynamoid/components'
|
24
|
+
require 'dynamoid/document'
|
25
|
+
require 'dynamoid/adapter'
|
26
|
+
|
27
|
+
require 'dynamoid/middleware/identity_map'
|
28
|
+
|
29
|
+
module Dynamoid
|
30
|
+
extend self
|
31
|
+
|
32
|
+
MAX_ITEM_SIZE = 65_536
|
33
|
+
|
34
|
+
def configure
|
35
|
+
block_given? ? yield(Dynamoid::Config) : Dynamoid::Config
|
36
|
+
end
|
37
|
+
alias :config :configure
|
38
|
+
|
39
|
+
def logger
|
40
|
+
Dynamoid::Config.logger
|
41
|
+
end
|
42
|
+
|
43
|
+
def included_models
|
44
|
+
@included_models ||= []
|
45
|
+
end
|
46
|
+
|
47
|
+
def adapter
|
48
|
+
@adapter ||= Adapter.new
|
49
|
+
end
|
50
|
+
end
|
metadata
ADDED
@@ -0,0 +1,226 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dynamoid-edge
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Josh Symonds
|
8
|
+
- Logan Bowers
|
9
|
+
- Craig Heneveld
|
10
|
+
- Anatha Kumaran
|
11
|
+
- Jason Dew
|
12
|
+
- Luis Arias
|
13
|
+
- Stefan Neculai
|
14
|
+
- Philip White
|
15
|
+
- Peeyush Kumar
|
16
|
+
autorequire:
|
17
|
+
bindir: bin
|
18
|
+
cert_chain: []
|
19
|
+
date: 2016-03-10 00:00:00.000000000 Z
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: activemodel
|
23
|
+
requirement: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '4'
|
28
|
+
type: :runtime
|
29
|
+
prerelease: false
|
30
|
+
version_requirements: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '4'
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: aws-sdk-resources
|
37
|
+
requirement: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '2'
|
42
|
+
type: :runtime
|
43
|
+
prerelease: false
|
44
|
+
version_requirements: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '2'
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: concurrent-ruby
|
51
|
+
requirement: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '1.0'
|
56
|
+
type: :runtime
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '1.0'
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: rake
|
65
|
+
requirement: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
- !ruby/object:Gem::Dependency
|
78
|
+
name: rspec
|
79
|
+
requirement: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - "~>"
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '3'
|
84
|
+
type: :development
|
85
|
+
prerelease: false
|
86
|
+
version_requirements: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - "~>"
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '3'
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: bundler
|
93
|
+
requirement: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
type: :development
|
99
|
+
prerelease: false
|
100
|
+
version_requirements: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
- !ruby/object:Gem::Dependency
|
106
|
+
name: yard
|
107
|
+
requirement: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
type: :development
|
113
|
+
prerelease: false
|
114
|
+
version_requirements: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
- !ruby/object:Gem::Dependency
|
120
|
+
name: github-markup
|
121
|
+
requirement: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
type: :development
|
127
|
+
prerelease: false
|
128
|
+
version_requirements: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0'
|
133
|
+
- !ruby/object:Gem::Dependency
|
134
|
+
name: pry
|
135
|
+
requirement: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '0'
|
140
|
+
type: :development
|
141
|
+
prerelease: false
|
142
|
+
version_requirements: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
- !ruby/object:Gem::Dependency
|
148
|
+
name: coveralls
|
149
|
+
requirement: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - ">="
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0'
|
154
|
+
type: :development
|
155
|
+
prerelease: false
|
156
|
+
version_requirements: !ruby/object:Gem::Requirement
|
157
|
+
requirements:
|
158
|
+
- - ">="
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
version: '0'
|
161
|
+
description: Dynamoid is an ORM for Amazon's DynamoDB that supports offline development,
|
162
|
+
associations, querying, and everything else you'd expect from an ActiveRecord-style
|
163
|
+
replacement.
|
164
|
+
email:
|
165
|
+
executables: []
|
166
|
+
extensions: []
|
167
|
+
extra_rdoc_files:
|
168
|
+
- LICENSE.txt
|
169
|
+
- README.markdown
|
170
|
+
files:
|
171
|
+
- CHANGELOG.md
|
172
|
+
- Gemfile
|
173
|
+
- LICENSE.txt
|
174
|
+
- README.markdown
|
175
|
+
- Rakefile
|
176
|
+
- dynamoid-edge.gemspec
|
177
|
+
- lib/dynamoid.rb
|
178
|
+
- lib/dynamoid/adapter.rb
|
179
|
+
- lib/dynamoid/adapter_plugin/aws_sdk_v2.rb
|
180
|
+
- lib/dynamoid/associations.rb
|
181
|
+
- lib/dynamoid/associations/association.rb
|
182
|
+
- lib/dynamoid/associations/belongs_to.rb
|
183
|
+
- lib/dynamoid/associations/has_and_belongs_to_many.rb
|
184
|
+
- lib/dynamoid/associations/has_many.rb
|
185
|
+
- lib/dynamoid/associations/has_one.rb
|
186
|
+
- lib/dynamoid/associations/many_association.rb
|
187
|
+
- lib/dynamoid/associations/single_association.rb
|
188
|
+
- lib/dynamoid/components.rb
|
189
|
+
- lib/dynamoid/config.rb
|
190
|
+
- lib/dynamoid/config/options.rb
|
191
|
+
- lib/dynamoid/criteria.rb
|
192
|
+
- lib/dynamoid/criteria/chain.rb
|
193
|
+
- lib/dynamoid/dirty.rb
|
194
|
+
- lib/dynamoid/document.rb
|
195
|
+
- lib/dynamoid/errors.rb
|
196
|
+
- lib/dynamoid/fields.rb
|
197
|
+
- lib/dynamoid/finders.rb
|
198
|
+
- lib/dynamoid/identity_map.rb
|
199
|
+
- lib/dynamoid/middleware/identity_map.rb
|
200
|
+
- lib/dynamoid/persistence.rb
|
201
|
+
- lib/dynamoid/validations.rb
|
202
|
+
homepage: http://github.com/Dynamoid/Dynamoid
|
203
|
+
licenses:
|
204
|
+
- MIT
|
205
|
+
metadata: {}
|
206
|
+
post_install_message:
|
207
|
+
rdoc_options: []
|
208
|
+
require_paths:
|
209
|
+
- lib
|
210
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
211
|
+
requirements:
|
212
|
+
- - ">="
|
213
|
+
- !ruby/object:Gem::Version
|
214
|
+
version: '0'
|
215
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
216
|
+
requirements:
|
217
|
+
- - ">="
|
218
|
+
- !ruby/object:Gem::Version
|
219
|
+
version: '0'
|
220
|
+
requirements: []
|
221
|
+
rubyforge_project:
|
222
|
+
rubygems_version: 2.4.5.1
|
223
|
+
signing_key:
|
224
|
+
specification_version: 4
|
225
|
+
summary: Dynamoid is an ORM for Amazon's DynamoDB
|
226
|
+
test_files: []
|