rom-dynamo 0.1.4 → 0.16.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 CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- MzVjNmE0OWM2ODc1N2ZkNDM4ZDAzYjliNWYzODE0MDZmZWUxYzFkOA==
5
- data.tar.gz: !binary |-
6
- ZTBlOWU4ZGY1NGZiYjM1MmI3MDg1NjMxYmE0NWE5NjViODUxY2JlNw==
2
+ SHA256:
3
+ metadata.gz: 7bbcf8f8498ca2b84b9542512884cc138dc251fc334dfac08412eeff71f9d1fa
4
+ data.tar.gz: eb0a7649d78caea174c0e6aea7ae5545bffd21fa1c6ae6e71ca0a79140dfc2fb
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- MDBkZmMwNzcyM2VlODE1NzQ1Y2ExOTgzNDUwMjhkNDA3ZmYzMGM4YzYxYWFl
10
- ODg1ZDlkYWEwNGEzODg2Mzk2YjFjMjI0MjUyYTAyODRiNTg3YjQyYjIxNWQ0
11
- ZGQ1ZjNmNTVhZDkxOWE4ZTk1NGNkMjFmNTE1MmFkYmUzMDliYTM=
12
- data.tar.gz: !binary |-
13
- ZGY0ZGRmOThiZDBhYzRiMzA2NjdjMDhhZWM4MzRiMGNhYWEwMzhmYzRiMjhk
14
- NDdlZWNhMzE2NjMyOTFkMTY4NWUyMDk4ZmU3YmUxM2I5MWI3NDdjNGU4Mzdk
15
- MTIxNjllNjc1ZTU3NjEyODBhZDc5YjljOGFkNzI1NjNlYTk5YzU=
6
+ metadata.gz: 6ca7ae3a668dd4938a1261916e6404f8a618bf8c0e35cab0e856911111bcef397cedb303c371b3aa13cf83d2f876fccbbf4c3a7e8f0d8710767bcb585b1be2a5
7
+ data.tar.gz: 4361cf505fe065176038d2639c63328efef862e52df9631cf6fcf32910261e33ad4380c3aeb995a2bd6af849de8fe71645f7626e1ff9d49786f53e085f89fb1c
@@ -0,0 +1,31 @@
1
+ name: specs
2
+
3
+ on:
4
+ push:
5
+ branches: [ master ]
6
+ pull_request:
7
+ branches: [ master ]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ fail-fast: true
14
+ matrix:
15
+ ruby: [2.4, 2.5, 2.6, 2.7, 3.0, 4.0, head, jruby]
16
+ steps:
17
+ - uses: actions/checkout@v6
18
+ - name: Set up Ruby & run Bundler
19
+ uses: ruby/setup-ruby@v1
20
+ with:
21
+ ruby-version: ${{ matrix.ruby }}
22
+ bundler-cache: true
23
+ - name: Setup DynamoDB Local
24
+ uses: rrainn/dynamodb-action@v2.0.0
25
+ with:
26
+ port: 8000
27
+ - name: Run specs
28
+ run: bundle exec rake spec
29
+ env:
30
+ AWS_ACCESS_KEY_ID: DEADBEEF
31
+ AWS_SECRET_ACCESS_KEY: FORAWSSDK
data/.rspec CHANGED
@@ -1,2 +1,3 @@
1
1
  --format documentation
2
+ --require spec_helper
2
3
  --color
data/Gemfile CHANGED
@@ -4,6 +4,8 @@ source 'https://rubygems.org'
4
4
  gemspec
5
5
 
6
6
  # For development/testing
7
+ gem 'nokogiri'
7
8
  gem 'dotenv'
8
- gem 'rom', :github => 'rom-rb/rom'
9
- gem 'virtus'
9
+ gem 'rom'
10
+ gem 'virtus'
11
+ gem 'rspec'
data/README.md CHANGED
@@ -4,6 +4,7 @@
4
4
  # Rom::Dynamo
5
5
 
6
6
  [![Gem Version](https://badge.fury.io/rb/rom-dynamo.svg)][gem]
7
+ [![Build Status](https://github.com/rykov/rom-dynamo/actions/workflows/specs.yml/badge.svg)](https://github.com/rykov/rom-dynamo/actions/workflows/specs.yml)
7
8
 
8
9
  AWS DynamoDB support for [Ruby Object Mapper](https://github.com/rom-rb/rom).
9
10
 
data/Rakefile CHANGED
@@ -1,2 +1,7 @@
1
+ #!/usr/bin/env rake
1
2
  require "bundler/gem_tasks"
3
+ require 'rspec/core'
4
+ require 'rspec/core/rake_task'
2
5
 
6
+ task :default => :spec
7
+ RSpec::Core::RakeTask.new
@@ -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(tuple)
9
- attributes = input[tuple]
10
- validator.call(attributes)
11
- relation.insert(attributes.to_h)
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
- target.to_a.tap do |tuples|
20
- tuples.each { |t| relation.delete(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
@@ -0,0 +1,196 @@
1
+ module Rom
2
+ module Dynamo
3
+ class Dataset
4
+ include Enumerable
5
+ include Dry::Equalizer(:name, :connection)
6
+ extend Dry::Initializer[undefined: false]
7
+ EmptyQuery = { key_conditions: {}.freeze }.freeze
8
+
9
+ option :connection
10
+ option :name, proc(&:to_s)
11
+ option :logger, optional: true
12
+ option :table_keys, optional: true, reader: false
13
+ option :query, default: proc { EmptyQuery }, reader: false
14
+ alias_method :ddb, :connection
15
+
16
+ ######### ENUMERATE ###########
17
+
18
+ def each(&block)
19
+ return enum_for(:each) if block.nil?
20
+ each_page { |p| p.items.each(&block) }
21
+ end
22
+
23
+ def each_page(&block)
24
+ return enum_for(:each_page) if block.nil?
25
+ result = start_query(consistent_read: true)
26
+ result.each_page(&block)
27
+ end
28
+
29
+ ############# QUERY #############
30
+
31
+ def restrict(query = nil)
32
+ return self if query.nil?
33
+ dup_with_query(self.class, 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)
40
+ end
41
+
42
+ def index_restrict(index, query)
43
+ dup_with_query(GlobalIndexDataset, query, index_name: index.to_s)
44
+ end
45
+
46
+ ############# PAGINATE #############
47
+
48
+ def limit(limit)
49
+ opts = limit.nil? ? {} : { limit: limit.to_i }
50
+ dup_with_query(self.class, nil, opts)
51
+ end
52
+
53
+ def offset(key)
54
+ opts = key.nil? ? {} : { exclusive_start_key: key }
55
+ dup_with_query(self.class, nil, opts)
56
+ end
57
+
58
+ def reversed
59
+ dup_with_query(self.class, nil, scan_index_forward: false)
60
+ end
61
+
62
+ ############# WRITE #############
63
+ def insert(hash)
64
+ opts = { table_name: name, item: stringify_keys(hash) }
65
+ connection.put_item(opts).attributes
66
+ end
67
+
68
+ def delete(hash)
69
+ hash = stringify_keys(hash)
70
+ connection.delete_item({
71
+ table_name: name,
72
+ key: hash_to_key(hash),
73
+ expected: to_expected(hash),
74
+ }).attributes
75
+ end
76
+
77
+ def update(keys, hash)
78
+ connection.update_item({
79
+ table_name: name, key: hash_to_key(stringify_keys(keys)),
80
+ attribute_updates: hash.each_with_object({}) do |(k, v), out|
81
+ out[k] = { value: dump_value(v), action: 'PUT' } if !keys[k]
82
+ end
83
+ }).attributes
84
+ end
85
+
86
+ ############# HELPERS #############
87
+ private
88
+ def batch_get_each_page(keys, &block)
89
+ !keys.empty? && ddb.batch_get_item({
90
+ request_items: { name => { keys: keys } },
91
+ }).each_page do |page|
92
+ block.call(page[:responses][name])
93
+ end
94
+ end
95
+
96
+ def dup_with_query(klass, key_hash, opts = {})
97
+ opts = @query.merge(opts)
98
+
99
+ if key_hash && !key_hash.empty?
100
+ conditions = @query[:key_conditions]
101
+ opts[:key_conditions] = conditions.merge(Hash[
102
+ key_hash.map do |key, value|
103
+ [key, {
104
+ attribute_value_list: [value],
105
+ comparison_operator: "EQ"
106
+ }]
107
+ end
108
+ ]).freeze
109
+ end
110
+
111
+ dup_as(klass, query: opts.freeze)
112
+ end
113
+
114
+ def to_expected(hash)
115
+ hash && Hash[hash.map do |k, v|
116
+ [k, { value: v }]
117
+ end]
118
+ end
119
+
120
+ def hash_to_key(hash)
121
+ table_keys.each_with_object({}) do |k, out|
122
+ out[k] = hash[k] if hash.has_key?(k)
123
+ end
124
+ end
125
+
126
+ def table_keys
127
+ @table_keys ||= begin
128
+ r = ddb.describe_table(table_name: name)
129
+ r[:table][:key_schema].map(&:attribute_name)
130
+ end
131
+ end
132
+
133
+ def start_query(opts = {}, &block)
134
+ opts = @query.merge(table_name: name).merge!(opts)
135
+ logger&.debug("Querying DDB: #{opts.inspect}")
136
+ ddb.query(opts)
137
+ end
138
+
139
+ def dup_as(klass, opts = {})
140
+ table_keys # To populate keys once at top-level Dataset
141
+ attrs = Dataset.dry_initializer.attributes(self)
142
+ klass.new(**attrs.merge(opts))
143
+ end
144
+
145
+ # String modifiers
146
+ def stringify_keys(hash)
147
+ hash.each_with_object({}) { |(k, v), out| out[k.to_s] = v }
148
+ end
149
+
150
+ def dump_value(v)
151
+ return v.new_offset(0).iso8601(6) if v.is_a?(DateTime)
152
+ v.is_a?(Time) ? v.utc.iso8601(6) : v
153
+ end
154
+ end
155
+
156
+ # Batch get using an array of key queries
157
+ # [{ key => val }, { key => val }, ...]
158
+ class BatchGetDataset < Dataset
159
+ option :keys
160
+
161
+ # Query for records
162
+ def each_page(&block)
163
+ return enum_for(:each_page) if block.nil?
164
+ batch_get_each_page(@keys) do |items|
165
+ klass = Aws::DynamoDB::Types::QueryOutput
166
+ block.call(klass.new(items: items, count: items.size))
167
+ end
168
+ end
169
+ end
170
+
171
+ # Dataset queried via a Global Secondary Index
172
+ # Paginate through keys from Global Index and
173
+ # call BatchGetItem for keys from each page
174
+ class GlobalIndexDataset < Dataset
175
+ def each_page(&block)
176
+ return enum_for(:each_page) if block.nil?
177
+ if @query[:limit]
178
+ block.call(populated_results(start_query))
179
+ else
180
+ start_query(limit: 100).each_page do |p|
181
+ block.call(populated_results(p))
182
+ end
183
+ end
184
+ end
185
+
186
+ private def populated_results(result, &block)
187
+ klass = Aws::DynamoDB::Types::QueryOutput
188
+ keys = result.items.map { |h| hash_to_key(h) }
189
+ klass.new(result.to_hash.merge(items: [].tap do |out|
190
+ batch_get_each_page(keys) { |i| out.concat(i) }
191
+ end))
192
+ end
193
+
194
+ end
195
+ end
196
+ end
@@ -0,0 +1,46 @@
1
+ require 'addressable/uri'
2
+ require 'rom/gateway'
3
+
4
+ module Rom
5
+ module Dynamo
6
+ class Gateway < ROM::Gateway
7
+ attr_reader :ddb, :options, :logger
8
+
9
+ def initialize(uri)
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)
17
+ @prefix = uri.path.gsub('/', '')
18
+ @datasets = {}
19
+ end
20
+
21
+ def use_logger(logger)
22
+ @logger = logger
23
+ end
24
+
25
+ def dataset(name)
26
+ name = "#{@prefix}#{name}"
27
+ @datasets[name] ||= _has?(name) && Dataset.new(connection: @ddb, name: name, logger: @logger)
28
+ end
29
+
30
+ def dataset?(name)
31
+ !!self[name]
32
+ end
33
+
34
+ def [](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
43
+ end
44
+ end
45
+ end
46
+ end
@@ -2,139 +2,20 @@ module Rom
2
2
  module Dynamo
3
3
  class Relation < ROM::Relation
4
4
  include Enumerable
5
- forward :restrict, :index_restrict
6
-
7
- def insert(*args)
8
- dataset.insert(*args)
9
- self
10
- end
11
-
12
- def delete(*args)
13
- dataset.delete(*args)
14
- self
15
- end
16
- end
17
-
18
- class Dataset
19
- include Equalizer.new(:name, :connection)
20
- attr_reader :name, :connection
21
- alias_method :ddb, :connection
22
-
23
- def initialize(name, ddb, conditions = nil)
24
- @name, @connection = name, ddb
25
- @conditions = conditions || {}
26
- end
27
-
28
- ############# READ #############
29
- def each(&block)
30
- each_item({
31
- consistent_read: true,
32
- key_conditions: @conditions
33
- }, &block)
34
- end
35
-
36
- def restrict(query = nil)
37
- return self if query.nil?
38
- conds = query_to_conditions(query)
39
- conds = @conditions.merge(conds)
40
- dup_as(Dataset, conditions: conds)
41
- end
42
-
43
- def index_restrict(index, query)
44
- conds = query_to_conditions(query)
45
- conds = @conditions.merge(conds)
46
- dup_as(GlobalIndexDataset, index: index, conditions: conds)
47
- end
48
-
49
- ############# WRITE #############
50
- def insert(hash)
51
- connection.put_item({
52
- table_name: name,
53
- item: hash
54
- })
55
- end
56
-
57
- def delete(hash)
58
- connection.delete_item({
59
- table_name: name,
60
- key: hash_to_key(hash),
61
- expected: to_expected(hash),
62
- })
63
- end
64
-
65
- ############# HELPERS #############
66
- private
67
- def each_item(options, &block)
68
- puts "Querying #{name} ...\nWith: #{options.inspect}"
69
- connection.query(options.merge({
70
- table_name: name
71
- })).each_page do |page|
72
- page[:items].each(&block)
73
- end
74
- end
75
-
76
- def query_to_conditions(query)
77
- Hash[query.map do |key, value|
78
- [key, {
79
- attribute_value_list: [value],
80
- comparison_operator: "EQ"
81
- }]
82
- end]
83
- end
84
-
85
- def to_expected(hash)
86
- hash && Hash[hash.map do |k, v|
87
- [k, { value: v }]
88
- end]
89
- end
90
-
91
- def hash_to_key(hash)
92
- table_keys.each_with_object({}) do |k, out|
93
- out[k] = hash[k] if hash.has_key?(k)
94
- end
95
- end
96
-
97
- def table_keys
98
- @table_keys ||= begin
99
- resp = ddb.describe_table(table_name: name)
100
- keys = resp.first[:table][:key_schema]
101
- keys.map(&:attribute_name)
102
- end
103
- end
104
-
105
- def dup_as(klass, opts = {})
106
- table_keys # To populate keys once at top-level Dataset
107
- vars = [:@name, :@connection, :@conditions, :@table_keys]
108
- klass.allocate.tap do |out|
109
- vars.each { |k| out.instance_variable_set(k, instance_variable_get(k)) }
110
- opts.each { |k, v| out.instance_variable_set("@#{k}", v) }
111
- end
112
- end
113
- end
114
-
115
- # Dataset queried via a Global Index
116
- class GlobalIndexDataset < Dataset
117
- attr_accessor :index
118
-
119
- def each(&block)
120
- # Pull record IDs from Global Index
121
- keys = []; each_item({
122
- key_conditions: @conditions,
123
- index_name: @index
124
- }) { |hash| keys << hash_to_key(hash) }
125
-
126
- # Bail if we have nothing
127
- return if keys.empty?
128
-
129
- # Query for the actual records
130
- ddb.batch_get_item({
131
- request_items: { name => { keys: keys } },
132
- }).each_page do |page|
133
- out = page[:responses][name]
134
- out.each(&block)
5
+ forward :restrict, :batch_restrict, :index_restrict
6
+ forward :limit, :reversed, :offset
7
+ adapter :dynamo
8
+
9
+ def each_page(&block)
10
+ return enum_for(:each_page) if block.nil?
11
+ dataset.each_page do |page|
12
+ items = page[:items].map { |t| output_schema[t] }
13
+ items = mapper.(items).to_a if auto_map?
14
+ hash = page.to_hash.merge(items: items)
15
+ hash[:last_evaluated_key] ||= nil
16
+ block.call(ROM::OpenStruct.new(hash))
135
17
  end
136
18
  end
137
-
138
19
  end
139
20
  end
140
21
  end
@@ -1,5 +1,5 @@
1
1
  module Rom
2
2
  module Dynamo
3
- VERSION = "0.1.4"
3
+ VERSION = "0.16.0"
4
4
  end
5
5
  end
data/lib/rom/dynamo.rb CHANGED
@@ -1,8 +1,16 @@
1
1
  require 'rom'
2
- require 'aws-sdk-core'
3
- require "rom/dynamo/version"
2
+ require 'date'
3
+ require 'aws-sdk-dynamodb'
4
+ require 'rom/dynamo/version'
5
+ require 'rom/dynamo/dataset'
4
6
  require 'rom/dynamo/relation'
5
7
  require 'rom/dynamo/commands'
6
- require 'rom/dynamo/repository'
8
+ require 'rom/dynamo/gateway'
7
9
 
10
+ # jRuby HACK: https://github.com/jruby/jruby/issues/3645#issuecomment-181660161
11
+ if RUBY_ENGINE == 'jruby'
12
+ module Aws; const_set(:DynamoDB, Aws::DynamoDB) end
13
+ end
14
+
15
+ # Register adapter with ROM-rb
8
16
  ROM.register_adapter(:dynamo, Rom::Dynamo)
data/lib/rom-dynamo.rb CHANGED
@@ -1 +1,2 @@
1
1
  require 'rom/dynamo'
2
+ ROM::Dynamo = Rom::Dynamo
data/rom-dynamo.gemspec CHANGED
@@ -23,11 +23,16 @@ Gem::Specification.new do |spec|
23
23
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
24
  spec.require_paths = ["lib"]
25
25
 
26
+ # Ruby 2.0 and above
27
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.4.0')
28
+
26
29
  # Runtime
27
- spec.add_runtime_dependency "rom", "~> 0.5"
28
- spec.add_runtime_dependency "aws-sdk-core"
30
+ spec.add_runtime_dependency "addressable", "~> 2.3"
31
+ spec.add_runtime_dependency "rom", ">= 1.0", "< 6.0"
32
+ spec.add_runtime_dependency "aws-sdk-dynamodb", "~> 1.0"
29
33
 
30
34
  # Development
31
- spec.add_development_dependency "bundler", "~> 1.8"
32
- spec.add_development_dependency "rake", "~> 10.0"
35
+ spec.add_development_dependency "activesupport", ">= 4.0", "< 9.0"
36
+ spec.add_development_dependency "bundler", ">= 1.7"
37
+ spec.add_development_dependency "rake", "~> 13.0"
33
38
  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.1.4
4
+ version: 0.16.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: 2015-02-19 00:00:00.000000000 Z
11
+ date: 2026-04-01 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.5'
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.5'
46
+ version: '6.0'
27
47
  - !ruby/object:Gem::Dependency
28
- name: aws-sdk-core
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
+ - - "~>"
39
59
  - !ruby/object:Gem::Version
40
- version: '0'
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: '9.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
+ - - "<"
79
+ - !ruby/object:Gem::Version
80
+ version: '9.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.8'
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.8'
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: '10.0'
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: '10.0'
108
+ version: '13.0'
69
109
  description: DynamoDB adapter for Ruby Object Mapper
70
110
  email:
71
111
  - mrykov@gmail.com
@@ -73,9 +113,10 @@ executables: []
73
113
  extensions: []
74
114
  extra_rdoc_files: []
75
115
  files:
76
- - .gitignore
77
- - .rspec
78
- - .travis.yml
116
+ - ".github/workflows/specs.yml"
117
+ - ".gitignore"
118
+ - ".rspec"
119
+ - ".travis.yml"
79
120
  - Gemfile
80
121
  - LICENSE.txt
81
122
  - README.md
@@ -85,8 +126,9 @@ files:
85
126
  - lib/rom-dynamo.rb
86
127
  - lib/rom/dynamo.rb
87
128
  - lib/rom/dynamo/commands.rb
129
+ - lib/rom/dynamo/dataset.rb
130
+ - lib/rom/dynamo/gateway.rb
88
131
  - lib/rom/dynamo/relation.rb
89
- - lib/rom/dynamo/repository.rb
90
132
  - lib/rom/dynamo/version.rb
91
133
  - rom-dynamo.gemspec
92
134
  homepage: https://github.com/rykov/rom-dynamo
@@ -99,17 +141,17 @@ require_paths:
99
141
  - lib
100
142
  required_ruby_version: !ruby/object:Gem::Requirement
101
143
  requirements:
102
- - - ! '>='
144
+ - - ">="
103
145
  - !ruby/object:Gem::Version
104
- version: '0'
146
+ version: 2.4.0
105
147
  required_rubygems_version: !ruby/object:Gem::Requirement
106
148
  requirements:
107
- - - ! '>='
149
+ - - ">="
108
150
  - !ruby/object:Gem::Version
109
151
  version: '0'
110
152
  requirements: []
111
153
  rubyforge_project:
112
- rubygems_version: 2.4.5
154
+ rubygems_version: 2.7.8
113
155
  signing_key:
114
156
  specification_version: 4
115
157
  summary: DynamoDB adapter for Ruby Object Mapper
@@ -1,34 +0,0 @@
1
- require 'uri'
2
- require 'rom/repository'
3
-
4
- module Rom
5
- module Dynamo
6
- class Repository < ROM::Repository
7
- def initialize(uri)
8
- uri = URI.parse(uri)
9
- @connection = Aws::DynamoDB::Client.new(region: uri.host)
10
- @prefix = uri.path.gsub('/', '')
11
- @datasets = {}
12
- end
13
-
14
- def use_logger(logger)
15
- @logger = logger
16
- end
17
-
18
- def dataset(name)
19
- name = "#{@prefix}#{name}"
20
- @datasets[name] ||= Dataset.new(name, @connection)
21
- end
22
-
23
- def dataset?(name)
24
- name = "#{@prefix}#{name}"
25
- list = connection.list_tables
26
- list[:table_names].include?(name)
27
- end
28
-
29
- def [](name)
30
- @datasets[name]
31
- end
32
- end
33
- end
34
- end