rom-dynamo 0.1.4 → 0.14.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 +5 -13
- data/.rspec +1 -0
- data/Gemfile +3 -2
- data/Rakefile +5 -0
- data/lib/rom/dynamo/commands.rb +29 -7
- data/lib/rom/dynamo/relation.rb +113 -71
- data/lib/rom/dynamo/repository.rb +22 -10
- data/lib/rom/dynamo/version.rb +1 -1
- data/lib/rom/dynamo.rb +6 -1
- data/lib/rom-dynamo.rb +1 -0
- data/rom-dynamo.gemspec +6 -4
- metadata +65 -25
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
ZTBlOWU4ZGY1NGZiYjM1MmI3MDg1NjMxYmE0NWE5NjViODUxY2JlNw==
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: bb3d1008f7f0331e2ea2d49690cf9b95388c96143ca86718204e0fc53f3e8c4e
|
4
|
+
data.tar.gz: f45c64b787dab54ea6c821e196c3d3ab4a1aa181065a5338e5892156e606885c
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
ODg1ZDlkYWEwNGEzODg2Mzk2YjFjMjI0MjUyYTAyODRiNTg3YjQyYjIxNWQ0
|
11
|
-
ZGQ1ZjNmNTVhZDkxOWE4ZTk1NGNkMjFmNTE1MmFkYmUzMDliYTM=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
ZGY0ZGRmOThiZDBhYzRiMzA2NjdjMDhhZWM4MzRiMGNhYWEwMzhmYzRiMjhk
|
14
|
-
NDdlZWNhMzE2NjMyOTFkMTY4NWUyMDk4ZmU3YmUxM2I5MWI3NDdjNGU4Mzdk
|
15
|
-
MTIxNjllNjc1ZTU3NjEyODBhZDc5YjljOGFkNzI1NjNlYTk5YzU=
|
6
|
+
metadata.gz: e595872d1620052b010b0b42905ae517d6a2461e1cc9b2a30e78ec661d6f89afa8e3bb4e9f2681b11a44b0372c8e9e6489c02864e768f3091fb539a41f5c0719
|
7
|
+
data.tar.gz: 81ec89f72f4e0b0b5a0be77b828c5db7bb730e6e4b118fca5a52d657d809396bcb63d494d592ebfaabf7d9d0b5ce618e8f323817059f6b537e4826ad1a0382c8
|
data/.rspec
CHANGED
data/Gemfile
CHANGED
data/Rakefile
CHANGED
data/lib/rom/dynamo/commands.rb
CHANGED
@@ -5,21 +5,43 @@ module Rom
|
|
5
5
|
module Commands
|
6
6
|
# DynamoDB create command
|
7
7
|
class Create < ROM::Commands::Create
|
8
|
-
def execute(
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
def execute(tuples)
|
9
|
+
Array([tuples]).flatten.map do |tuple|
|
10
|
+
attributes = input[tuple]
|
11
|
+
dataset.insert(attributes.to_h)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def dataset
|
16
|
+
relation.dataset
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# DynamoDB update command
|
21
|
+
class Update < ROM::Commands::Update
|
22
|
+
def execute(params)
|
23
|
+
attributes = input[params]
|
24
|
+
relation.map do |tuple|
|
25
|
+
dataset.update(tuple, attributes.to_h)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def dataset
|
30
|
+
relation.dataset
|
13
31
|
end
|
14
32
|
end
|
15
33
|
|
16
34
|
# DynamoDB delete command
|
17
35
|
class Delete < ROM::Commands::Delete
|
18
36
|
def execute
|
19
|
-
|
20
|
-
tuples.each { |t|
|
37
|
+
relation.to_a.tap do |tuples|
|
38
|
+
tuples.each { |t| dataset.delete(t) }
|
21
39
|
end
|
22
40
|
end
|
41
|
+
|
42
|
+
def dataset
|
43
|
+
relation.dataset
|
44
|
+
end
|
23
45
|
end
|
24
46
|
end
|
25
47
|
end
|
data/lib/rom/dynamo/relation.rb
CHANGED
@@ -2,84 +2,108 @@ module Rom
|
|
2
2
|
module Dynamo
|
3
3
|
class Relation < ROM::Relation
|
4
4
|
include Enumerable
|
5
|
-
forward :restrict, :index_restrict
|
6
|
-
|
7
|
-
|
8
|
-
dataset.insert(*args)
|
9
|
-
self
|
10
|
-
end
|
11
|
-
|
12
|
-
def delete(*args)
|
13
|
-
dataset.delete(*args)
|
14
|
-
self
|
15
|
-
end
|
5
|
+
forward :restrict, :batch_restrict, :index_restrict
|
6
|
+
forward :limit, :reversed
|
7
|
+
adapter :dynamo
|
16
8
|
end
|
17
9
|
|
18
10
|
class Dataset
|
19
|
-
include
|
20
|
-
|
11
|
+
include Enumerable
|
12
|
+
include Dry::Equalizer(:name, :connection)
|
13
|
+
extend Dry::Initializer[undefined: false]
|
14
|
+
EmptyQuery = { key_conditions: {}.freeze }.freeze
|
15
|
+
|
16
|
+
option :connection
|
17
|
+
option :name, proc(&:to_s)
|
18
|
+
option :table_keys, optional: true, reader: false
|
19
|
+
option :query, default: proc { EmptyQuery }, reader: false
|
21
20
|
alias_method :ddb, :connection
|
22
21
|
|
23
|
-
def initialize(name, ddb, conditions = nil)
|
24
|
-
@name, @connection = name, ddb
|
25
|
-
@conditions = conditions || {}
|
26
|
-
end
|
27
|
-
|
28
22
|
############# READ #############
|
23
|
+
|
29
24
|
def each(&block)
|
30
|
-
|
31
|
-
consistent_read: true
|
32
|
-
|
33
|
-
|
25
|
+
block.nil? ? to_enum : begin
|
26
|
+
result = start_query(consistent_read: true)
|
27
|
+
result.each_page { |p| p[:items].each(&block) }
|
28
|
+
end
|
34
29
|
end
|
35
30
|
|
36
31
|
def restrict(query = nil)
|
37
32
|
return self if query.nil?
|
38
|
-
|
39
|
-
|
40
|
-
|
33
|
+
dup_with_query(Dataset, query)
|
34
|
+
end
|
35
|
+
|
36
|
+
def batch_restrict(keys)
|
37
|
+
dup_as(BatchGetDataset, keys: keys.map do |k|
|
38
|
+
Hash[table_keys.zip(k.is_a?(Array) ? k : [k])]
|
39
|
+
end)
|
41
40
|
end
|
42
41
|
|
43
42
|
def index_restrict(index, query)
|
44
|
-
|
45
|
-
|
46
|
-
|
43
|
+
dup_with_query(GlobalIndexDataset, query, index_name: index.to_s)
|
44
|
+
end
|
45
|
+
|
46
|
+
############# PAGINATION #############
|
47
|
+
|
48
|
+
def limit(limit)
|
49
|
+
dup_with_query(self.class, nil, limit: limit.to_i)
|
50
|
+
end
|
51
|
+
|
52
|
+
def reversed
|
53
|
+
dup_with_query(self.class, nil, scan_index_forward: false)
|
47
54
|
end
|
48
55
|
|
49
56
|
############# WRITE #############
|
50
57
|
def insert(hash)
|
51
|
-
|
52
|
-
|
53
|
-
item: hash
|
54
|
-
})
|
58
|
+
opts = { table_name: name, item: stringify_keys(hash) }
|
59
|
+
connection.put_item(opts).attributes
|
55
60
|
end
|
56
61
|
|
57
62
|
def delete(hash)
|
63
|
+
hash = stringify_keys(hash)
|
58
64
|
connection.delete_item({
|
59
65
|
table_name: name,
|
60
66
|
key: hash_to_key(hash),
|
61
67
|
expected: to_expected(hash),
|
62
|
-
})
|
68
|
+
}).attributes
|
69
|
+
end
|
70
|
+
|
71
|
+
def update(keys, hash)
|
72
|
+
connection.update_item({
|
73
|
+
table_name: name, key: hash_to_key(stringify_keys(keys)),
|
74
|
+
attribute_updates: hash.each_with_object({}) do |(k, v), out|
|
75
|
+
out[k] = { value: dump_value(v), action: 'PUT' } if !keys[k]
|
76
|
+
end
|
77
|
+
}).attributes
|
63
78
|
end
|
64
79
|
|
65
80
|
############# HELPERS #############
|
66
81
|
private
|
67
|
-
def
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
82
|
+
def batch_get_each_item(keys, &block)
|
83
|
+
!keys.empty? && ddb.batch_get_item({
|
84
|
+
request_items: { name => { keys: keys } },
|
85
|
+
}).each_page do |page|
|
86
|
+
out = page[:responses][name]
|
87
|
+
out.each(&block)
|
73
88
|
end
|
74
89
|
end
|
75
90
|
|
76
|
-
def
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
91
|
+
def dup_with_query(klass, key_hash, opts = {})
|
92
|
+
opts = @query.merge(opts)
|
93
|
+
|
94
|
+
if key_hash && !key_hash.empty?
|
95
|
+
conditions = @query[:key_conditions]
|
96
|
+
opts[:key_conditions] = conditions.merge(Hash[
|
97
|
+
key_hash.map do |key, value|
|
98
|
+
[key, {
|
99
|
+
attribute_value_list: [value],
|
100
|
+
comparison_operator: "EQ"
|
101
|
+
}]
|
102
|
+
end
|
103
|
+
]).freeze
|
104
|
+
end
|
105
|
+
|
106
|
+
dup_as(klass, query: opts.freeze)
|
83
107
|
end
|
84
108
|
|
85
109
|
def to_expected(hash)
|
@@ -96,45 +120,63 @@ module Rom
|
|
96
120
|
|
97
121
|
def table_keys
|
98
122
|
@table_keys ||= begin
|
99
|
-
|
100
|
-
|
101
|
-
keys.map(&:attribute_name)
|
123
|
+
r = ddb.describe_table(table_name: name)
|
124
|
+
r[:table][:key_schema].map(&:attribute_name)
|
102
125
|
end
|
103
126
|
end
|
104
127
|
|
128
|
+
def start_query(opts = {}, &block)
|
129
|
+
opts = @query.merge(table_name: name).merge!(opts)
|
130
|
+
puts "Querying DDB: #{opts.inspect}"
|
131
|
+
ddb.query(opts)
|
132
|
+
end
|
133
|
+
|
105
134
|
def dup_as(klass, opts = {})
|
106
135
|
table_keys # To populate keys once at top-level Dataset
|
107
|
-
|
108
|
-
klass.
|
109
|
-
|
110
|
-
|
111
|
-
|
136
|
+
attrs = Dataset.dry_initializer.attributes(self)
|
137
|
+
klass.new(attrs.merge(opts))
|
138
|
+
end
|
139
|
+
|
140
|
+
# String modifiers
|
141
|
+
def stringify_keys(hash)
|
142
|
+
hash.each_with_object({}) { |(k, v), out| out[k.to_s] = v }
|
143
|
+
end
|
144
|
+
|
145
|
+
def dump_value(v)
|
146
|
+
return v.new_offset(0).iso8601(6) if v.is_a?(DateTime)
|
147
|
+
v.is_a?(Time) ? v.utc.iso8601(6) : v
|
112
148
|
end
|
113
149
|
end
|
114
150
|
|
115
|
-
#
|
116
|
-
|
117
|
-
|
151
|
+
# Batch get using an array of key queries
|
152
|
+
# [{ key => val }, { key => val }, ...]
|
153
|
+
class BatchGetDataset < Dataset
|
154
|
+
option :keys
|
118
155
|
|
156
|
+
# Query for records
|
119
157
|
def each(&block)
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
index_name: @index
|
124
|
-
}) { |hash| keys << hash_to_key(hash) }
|
125
|
-
|
126
|
-
# Bail if we have nothing
|
127
|
-
return if keys.empty?
|
158
|
+
batch_get_each_item(@keys, &block)
|
159
|
+
end
|
160
|
+
end
|
128
161
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
162
|
+
# Dataset queried via a Global Secondary Index
|
163
|
+
# Paginate through keys from Global Index and
|
164
|
+
# call BatchGetItem for keys from each page
|
165
|
+
class GlobalIndexDataset < Dataset
|
166
|
+
def each(&block)
|
167
|
+
if @query[:limit]
|
168
|
+
each_item(start_query, &block)
|
169
|
+
else
|
170
|
+
result = start_query(limit: 100)
|
171
|
+
result.each_page { |p| each_item(p, &block) }
|
135
172
|
end
|
136
173
|
end
|
137
174
|
|
175
|
+
private def each_item(result, &block)
|
176
|
+
keys = result[:items].map { |h| hash_to_key(h) }
|
177
|
+
batch_get_each_item(keys, &block)
|
178
|
+
end
|
138
179
|
end
|
180
|
+
|
139
181
|
end
|
140
182
|
end
|
@@ -1,12 +1,19 @@
|
|
1
|
-
require 'uri'
|
2
|
-
require 'rom/
|
1
|
+
require 'addressable/uri'
|
2
|
+
require 'rom/gateway'
|
3
3
|
|
4
4
|
module Rom
|
5
5
|
module Dynamo
|
6
|
-
class
|
6
|
+
class Gateway < ROM::Gateway
|
7
|
+
attr_reader :ddb, :options
|
8
|
+
|
7
9
|
def initialize(uri)
|
8
|
-
uri = URI.parse(uri)
|
9
|
-
|
10
|
+
uri = Addressable::URI.parse(uri)
|
11
|
+
opts = { region: uri.host }
|
12
|
+
opts.merge!(uri.query_values) if uri.query
|
13
|
+
opts.keys.each { |k| opts[k.to_sym] = opts.delete(k) }
|
14
|
+
|
15
|
+
@options = opts
|
16
|
+
@ddb = Aws::DynamoDB::Client.new(@options)
|
10
17
|
@prefix = uri.path.gsub('/', '')
|
11
18
|
@datasets = {}
|
12
19
|
end
|
@@ -17,17 +24,22 @@ module Rom
|
|
17
24
|
|
18
25
|
def dataset(name)
|
19
26
|
name = "#{@prefix}#{name}"
|
20
|
-
@datasets[name] ||= Dataset.new(
|
27
|
+
@datasets[name] ||= _has?(name) && Dataset.new(connection: @ddb, name: name)
|
21
28
|
end
|
22
29
|
|
23
30
|
def dataset?(name)
|
24
|
-
name
|
25
|
-
list = connection.list_tables
|
26
|
-
list[:table_names].include?(name)
|
31
|
+
!!self[name]
|
27
32
|
end
|
28
33
|
|
29
34
|
def [](name)
|
30
|
-
@datasets[name]
|
35
|
+
@datasets["#{@prefix}#{name}"]
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
def _has?(name)
|
40
|
+
@ddb.describe_table(table_name: name)
|
41
|
+
rescue Aws::DynamoDB::Errors::ResourceNotFoundException
|
42
|
+
return false
|
31
43
|
end
|
32
44
|
end
|
33
45
|
end
|
data/lib/rom/dynamo/version.rb
CHANGED
data/lib/rom/dynamo.rb
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
require 'rom'
|
2
|
-
require '
|
2
|
+
require 'date'
|
3
|
+
require 'aws-sdk-dynamodb'
|
3
4
|
require "rom/dynamo/version"
|
4
5
|
require 'rom/dynamo/relation'
|
5
6
|
require 'rom/dynamo/commands'
|
6
7
|
require 'rom/dynamo/repository'
|
7
8
|
|
9
|
+
# jRuby HACK: https://github.com/jruby/jruby/issues/3645#issuecomment-181660161
|
10
|
+
module Aws; const_set(:DynamoDB, Aws::DynamoDB) end
|
11
|
+
|
12
|
+
# Register adapter with ROM-rb
|
8
13
|
ROM.register_adapter(:dynamo, Rom::Dynamo)
|
data/lib/rom-dynamo.rb
CHANGED
data/rom-dynamo.gemspec
CHANGED
@@ -24,10 +24,12 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.require_paths = ["lib"]
|
25
25
|
|
26
26
|
# Runtime
|
27
|
-
spec.add_runtime_dependency "
|
28
|
-
spec.add_runtime_dependency "
|
27
|
+
spec.add_runtime_dependency "addressable", "~> 2.3"
|
28
|
+
spec.add_runtime_dependency "rom", ">= 1.0", "< 6.0"
|
29
|
+
spec.add_runtime_dependency "aws-sdk-dynamodb", "~> 1.0"
|
29
30
|
|
30
31
|
# Development
|
31
|
-
spec.add_development_dependency "
|
32
|
-
spec.add_development_dependency "
|
32
|
+
spec.add_development_dependency "activesupport", ">= 4.0", "< 7.0"
|
33
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
34
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
33
35
|
end
|
metadata
CHANGED
@@ -1,71 +1,111 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rom-dynamo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.14.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Rykov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-05-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: addressable
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.3'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.3'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: rom
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
16
30
|
requirements:
|
17
|
-
- -
|
31
|
+
- - ">="
|
18
32
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0
|
33
|
+
version: '1.0'
|
34
|
+
- - "<"
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '6.0'
|
20
37
|
type: :runtime
|
21
38
|
prerelease: false
|
22
39
|
version_requirements: !ruby/object:Gem::Requirement
|
23
40
|
requirements:
|
24
|
-
- -
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '1.0'
|
44
|
+
- - "<"
|
25
45
|
- !ruby/object:Gem::Version
|
26
|
-
version: '0
|
46
|
+
version: '6.0'
|
27
47
|
- !ruby/object:Gem::Dependency
|
28
|
-
name: aws-sdk-
|
48
|
+
name: aws-sdk-dynamodb
|
29
49
|
requirement: !ruby/object:Gem::Requirement
|
30
50
|
requirements:
|
31
|
-
- -
|
51
|
+
- - "~>"
|
32
52
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
53
|
+
version: '1.0'
|
34
54
|
type: :runtime
|
35
55
|
prerelease: false
|
36
56
|
version_requirements: !ruby/object:Gem::Requirement
|
37
57
|
requirements:
|
38
|
-
- -
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '1.0'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: activesupport
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '4.0'
|
68
|
+
- - "<"
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '7.0'
|
71
|
+
type: :development
|
72
|
+
prerelease: false
|
73
|
+
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '4.0'
|
78
|
+
- - "<"
|
39
79
|
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
80
|
+
version: '7.0'
|
41
81
|
- !ruby/object:Gem::Dependency
|
42
82
|
name: bundler
|
43
83
|
requirement: !ruby/object:Gem::Requirement
|
44
84
|
requirements:
|
45
|
-
- - ~>
|
85
|
+
- - "~>"
|
46
86
|
- !ruby/object:Gem::Version
|
47
|
-
version: '1.
|
87
|
+
version: '1.7'
|
48
88
|
type: :development
|
49
89
|
prerelease: false
|
50
90
|
version_requirements: !ruby/object:Gem::Requirement
|
51
91
|
requirements:
|
52
|
-
- - ~>
|
92
|
+
- - "~>"
|
53
93
|
- !ruby/object:Gem::Version
|
54
|
-
version: '1.
|
94
|
+
version: '1.7'
|
55
95
|
- !ruby/object:Gem::Dependency
|
56
96
|
name: rake
|
57
97
|
requirement: !ruby/object:Gem::Requirement
|
58
98
|
requirements:
|
59
|
-
- - ~>
|
99
|
+
- - "~>"
|
60
100
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
101
|
+
version: '13.0'
|
62
102
|
type: :development
|
63
103
|
prerelease: false
|
64
104
|
version_requirements: !ruby/object:Gem::Requirement
|
65
105
|
requirements:
|
66
|
-
- - ~>
|
106
|
+
- - "~>"
|
67
107
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
108
|
+
version: '13.0'
|
69
109
|
description: DynamoDB adapter for Ruby Object Mapper
|
70
110
|
email:
|
71
111
|
- mrykov@gmail.com
|
@@ -73,9 +113,9 @@ executables: []
|
|
73
113
|
extensions: []
|
74
114
|
extra_rdoc_files: []
|
75
115
|
files:
|
76
|
-
- .gitignore
|
77
|
-
- .rspec
|
78
|
-
- .travis.yml
|
116
|
+
- ".gitignore"
|
117
|
+
- ".rspec"
|
118
|
+
- ".travis.yml"
|
79
119
|
- Gemfile
|
80
120
|
- LICENSE.txt
|
81
121
|
- README.md
|
@@ -99,17 +139,17 @@ require_paths:
|
|
99
139
|
- lib
|
100
140
|
required_ruby_version: !ruby/object:Gem::Requirement
|
101
141
|
requirements:
|
102
|
-
- -
|
142
|
+
- - ">="
|
103
143
|
- !ruby/object:Gem::Version
|
104
144
|
version: '0'
|
105
145
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
106
146
|
requirements:
|
107
|
-
- -
|
147
|
+
- - ">="
|
108
148
|
- !ruby/object:Gem::Version
|
109
149
|
version: '0'
|
110
150
|
requirements: []
|
111
151
|
rubyforge_project:
|
112
|
-
rubygems_version: 2.
|
152
|
+
rubygems_version: 2.7.8
|
113
153
|
signing_key:
|
114
154
|
specification_version: 4
|
115
155
|
summary: DynamoDB adapter for Ruby Object Mapper
|