dynamodb-api 0.6.2 → 0.9.1
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 +4 -4
- data/.github/workflows/build.yml +28 -0
- data/Appraisals +14 -2
- data/CHANGELOG.md +26 -0
- data/Dockerfile +15 -0
- data/README.md +78 -5
- data/bin/console +1 -1
- data/docker-compose.yml +7 -1
- data/dynamodb-api.gemspec +2 -3
- data/gemfiles/{aws_sdk_2.gemfile → aws_sdk_2_rails_5.gemfile} +1 -0
- data/gemfiles/aws_sdk_2_rails_6.gemfile +9 -0
- data/gemfiles/{aws_sdk_3.gemfile → aws_sdk_3_rails_5.gemfile} +1 -0
- data/gemfiles/aws_sdk_3_rails_6.gemfile +9 -0
- data/lib/dynamodb/api.rb +6 -0
- data/lib/dynamodb/api/base.rb +66 -0
- data/lib/dynamodb/api/config.rb +7 -0
- data/lib/dynamodb/api/delete/item.rb +5 -1
- data/lib/dynamodb/api/delete/tables.rb +1 -0
- data/lib/dynamodb/api/map/operator.rb +15 -12
- data/lib/dynamodb/api/put/item.rb +5 -1
- data/lib/dynamodb/api/query.rb +39 -41
- data/lib/dynamodb/api/relation/from_clause.rb +2 -4
- data/lib/dynamodb/api/relation/query_methods.rb +2 -2
- data/lib/dynamodb/api/relation/where_clause.rb +74 -14
- data/lib/dynamodb/api/scan.rb +42 -0
- data/lib/dynamodb/api/update/base.rb +1 -1
- data/lib/dynamodb/api/version.rb +1 -1
- metadata +20 -30
- data/.travis.yml +0 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1276a3be5e1124f79957caee61c7585e3f59f37da5f12e2fac5d638238727ee8
|
4
|
+
data.tar.gz: c36d86b1087075fd6c154e5491cd08e6effcc0e91ffa0d96595d31fafc33eabc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a3c366b1cd32a307c6756bb4fb50ba43cafa98b5ff69f430ec55d638a5566492ee98f8554531196b27749e83ed2af2f26267cd12d9661feb193bb6ad63d44be9
|
7
|
+
data.tar.gz: 3cac38591e633e466439a2c12eaec0311828138caeb45bdc76f6c420321725a082fba136e2c0f2f826db40ba35c5e8bd5b672ffe2bb43ec10080d4e3f3bdbb31
|
@@ -0,0 +1,28 @@
|
|
1
|
+
name: build
|
2
|
+
on: [push, pull_request]
|
3
|
+
jobs:
|
4
|
+
test:
|
5
|
+
strategy:
|
6
|
+
fail-fast: false
|
7
|
+
matrix:
|
8
|
+
ruby: [2.4, 2.5, 2.6, 2.7]
|
9
|
+
gemfile: [ aws_sdk_2_rails_5, aws_sdk_2_rails_6, aws_sdk_3_rails_5, aws_sdk_3_rails_6 ]
|
10
|
+
exclude:
|
11
|
+
- { ruby: 2.4, gemfile: aws_sdk_2_rails_6 }
|
12
|
+
- { ruby: 2.4, gemfile: aws_sdk_3_rails_6 }
|
13
|
+
runs-on: ubuntu-latest
|
14
|
+
env:
|
15
|
+
BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile
|
16
|
+
TEST_DYNAMODB_ENDPOINT: 'http://0.0.0.0:8000'
|
17
|
+
steps:
|
18
|
+
- uses: actions/checkout@v2
|
19
|
+
- uses: ruby/setup-ruby@v1
|
20
|
+
with:
|
21
|
+
ruby-version: ${{ matrix.ruby }}
|
22
|
+
bundler-cache: true
|
23
|
+
- run: bin/setup
|
24
|
+
- run: docker-compose up -d
|
25
|
+
- run: docker ps
|
26
|
+
- run: bundle exec rubocop --fail-level=C
|
27
|
+
- run: bundle exec rake spec
|
28
|
+
- run: docker-compose down
|
data/Appraisals
CHANGED
@@ -1,7 +1,19 @@
|
|
1
|
-
appraise "aws-sdk-2" do
|
1
|
+
appraise "aws-sdk-2-rails-5" do
|
2
2
|
gem "aws-sdk", "~> 2"
|
3
|
+
gem "activesupport", "~> 5"
|
3
4
|
end
|
4
5
|
|
5
|
-
appraise "aws-sdk-
|
6
|
+
appraise "aws-sdk-2-rails-6" do
|
7
|
+
gem "aws-sdk", "~> 2"
|
8
|
+
gem "activesupport", "~> 6"
|
9
|
+
end
|
10
|
+
|
11
|
+
appraise "aws-sdk-3-rails-5" do
|
12
|
+
gem "aws-sdk", "~> 3"
|
13
|
+
gem "activesupport", "~> 5"
|
14
|
+
end
|
15
|
+
|
16
|
+
appraise "aws-sdk-3-rails-6" do
|
6
17
|
gem "aws-sdk", "~> 3"
|
18
|
+
gem "activesupport", "~> 6"
|
7
19
|
end
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,32 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
---
|
10
|
+
|
11
|
+
## [0.9.1] - 2020-11-21
|
12
|
+
### Security
|
13
|
+
- [#59](https://github.com/walkersumida/dynamodb-api/pull/59) Update rake version
|
14
|
+
|
15
|
+
### Removed
|
16
|
+
- [#57](https://github.com/walkersumida/dynamodb-api/pull/57) Unsupport ruby2.3 and activesupport4
|
17
|
+
|
18
|
+
## [0.9.0] - 2020-02-24
|
19
|
+
### Fixed
|
20
|
+
- [#56](https://github.com/walkersumida/dynamodb-api/pull/56) Make the `begins_with` and `between` available
|
21
|
+
|
22
|
+
## [0.8.1] - 2019-06-03
|
23
|
+
### Fixed
|
24
|
+
- [#49](https://github.com/walkersumida/dynamodb-api/pull/49) not be added table name prefix
|
25
|
+
- [#48](https://github.com/walkersumida/dynamodb-api/pull/48) Improvement DX
|
26
|
+
|
27
|
+
## [0.8.0] - 2019-03-03
|
28
|
+
### Added
|
29
|
+
- [#39](https://github.com/walkersumida/dynamodb-api/pull/39) `next` method
|
30
|
+
|
31
|
+
## [0.7.0] - 2018-12-23
|
32
|
+
### Added
|
33
|
+
- [#34](https://github.com/walkersumida/dynamodb-api/pull/34) `scan` method
|
34
|
+
|
9
35
|
## [0.6.2] - 2018-12-13
|
10
36
|
### Added
|
11
37
|
- [#32](https://github.com/walkersumida/dynamodb-api/pull/32) `remove_attributes` method
|
data/Dockerfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
FROM ruby:2.5.5
|
2
|
+
|
3
|
+
ENV APP_ROOT /app
|
4
|
+
WORKDIR $APP_ROOT
|
5
|
+
|
6
|
+
COPY . $APP_ROOT
|
7
|
+
|
8
|
+
RUN \
|
9
|
+
echo 'gem: --no-document' >> ~/.gemrc && \
|
10
|
+
cp ~/.gemrc /etc/gemrc && \
|
11
|
+
chmod uog+r /etc/gemrc && \
|
12
|
+
bundle config --global build.nokogiri --use-system-libraries && \
|
13
|
+
bundle config --global jobs 4 && \
|
14
|
+
bin/setup && \
|
15
|
+
rm -rf ~/.gem
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Dynamodb::Api
|
2
2
|
|
3
|
-
|
3
|
+

|
4
4
|
[](https://badge.fury.io/rb/dynamodb-api)
|
5
5
|
|
6
6
|
## Installation
|
@@ -57,6 +57,64 @@ cars table.
|
|
57
57
|
|3 |3 |Model S |0.20120601e8 |0 |
|
58
58
|
|4 |1 |S2000 |0.19980101e8 |1 |
|
59
59
|
|
60
|
+
### Scan
|
61
|
+
|
62
|
+
Scan returns items in random order.
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
scan = Dynamodb::Api.scan
|
66
|
+
scan.from('cars')
|
67
|
+
items = scan.all.items
|
68
|
+
```
|
69
|
+
|
70
|
+
| id | maker_id(Partition key) | model | release_date(Sort key) | status |
|
71
|
+
|:---|:---|:---|:---|:---|
|
72
|
+
|1 |1 |Accord |0.19760508e8 |0 |
|
73
|
+
|2 |2 |CROWN |0.19550101e8 |0 |
|
74
|
+
|3 |3 |Model S |0.20120601e8 |0 |
|
75
|
+
|4 |1 |S2000 |0.19980101e8 |1 |
|
76
|
+
|
77
|
+
#### Filter
|
78
|
+
|
79
|
+
```ruby
|
80
|
+
scan = Dynamodb::Api.scan
|
81
|
+
scan.from('cars').
|
82
|
+
filter('model = :model', ':model': 'S2000')
|
83
|
+
items = scan.all.items
|
84
|
+
```
|
85
|
+
|
86
|
+
| id | maker_id(Partition key) | model | release_date(Sort key) | status |
|
87
|
+
|:---|:---|:---|:---|:---|
|
88
|
+
|4 |1 |S2000 |0.19980101e8 |1 |
|
89
|
+
|
90
|
+
#### Limit
|
91
|
+
|
92
|
+
```ruby
|
93
|
+
scan = Dynamodb::Api.scan
|
94
|
+
scan.from('cars').
|
95
|
+
limit(1)
|
96
|
+
items = scan.all.items
|
97
|
+
```
|
98
|
+
|
99
|
+
| id | maker_id(Partition key) | model | release_date(Sort key) | status |
|
100
|
+
|:---|:---|:---|:---|:---|
|
101
|
+
|1 |1 |Accord |0.19760508e8 |0 |
|
102
|
+
|
103
|
+
#### Next(Paging)
|
104
|
+
|
105
|
+
```ruby
|
106
|
+
scan = Dynamodb::Api.scan
|
107
|
+
scan.from('cars').
|
108
|
+
limit(1)
|
109
|
+
_items = scan.all.items
|
110
|
+
items = scan.next.items
|
111
|
+
```
|
112
|
+
|
113
|
+
| id | maker_id(Partition key) | model | release_date(Sort key) | status |
|
114
|
+
|:---|:---|:---|:---|:---|
|
115
|
+
|2 |2 |CROWN |0.19550101e8 |0 |
|
116
|
+
|
117
|
+
|
60
118
|
### Query
|
61
119
|
https://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Client.html#query-instance_method
|
62
120
|
|
@@ -131,6 +189,22 @@ items = query.all.items
|
|
131
189
|
|:---|:---|:---|:---|:---|
|
132
190
|
|1 |1 |Accord |0.19760508e8 |0 |
|
133
191
|
|
192
|
+
#### Next(Paging)
|
193
|
+
|
194
|
+
```ruby
|
195
|
+
query = Dynamodb::Api.query
|
196
|
+
query.from('cars').index('index_maker_id_release_date').
|
197
|
+
where(['maker_id', '=', 1]).
|
198
|
+
order('asc'). # default: 'desc'
|
199
|
+
limit(1)
|
200
|
+
_items = query.all.items
|
201
|
+
items = query.next.items
|
202
|
+
```
|
203
|
+
|
204
|
+
| id | maker_id(Partition key) | model | release_date(Sort key) | status |
|
205
|
+
|:---|:---|:---|:---|:---|
|
206
|
+
|4 |1 |S2000 |0.19980101e8 |1 |
|
207
|
+
|
134
208
|
#### Expression Attribute Names
|
135
209
|
|
136
210
|
Words reserved in DynamoDB can not be used without special processing.
|
@@ -211,11 +285,10 @@ client.create_backup(
|
|
211
285
|
## Development
|
212
286
|
|
213
287
|
- Run `docker-compose up` to run the dynamodb_local.
|
214
|
-
-
|
215
|
-
-
|
216
|
-
- You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
288
|
+
- Run `docker-compose run ruby bundle exec rake spec` to run the tests. Or run `docker-compose run ruby bundle exec appraisal aws-sdk-* rake spec` to run the tests. Replase `*` with aws sdk major version.
|
289
|
+
- You can also run `docker-compose run ruby bin/console` for an interactive prompt that will allow you to experiment.
|
217
290
|
|
218
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
291
|
+
To install this gem onto your local machine, run `docker-compose run ruby bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `docker-compose run ruby bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
219
292
|
|
220
293
|
## Contributing
|
221
294
|
|
data/bin/console
CHANGED
data/docker-compose.yml
CHANGED
data/dynamodb-api.gemspec
CHANGED
@@ -23,10 +23,9 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.require_paths = ['lib']
|
24
24
|
|
25
25
|
spec.add_runtime_dependency 'aws-sdk', '>= 2'
|
26
|
-
spec.add_runtime_dependency('activesupport', '>=
|
26
|
+
spec.add_runtime_dependency('activesupport', '>= 5')
|
27
27
|
|
28
|
-
spec.add_development_dependency '
|
29
|
-
spec.add_development_dependency 'rake', '~> 10.0'
|
28
|
+
spec.add_development_dependency 'rake', '>= 12.3.3'
|
30
29
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
31
30
|
spec.add_development_dependency 'pry'
|
32
31
|
spec.add_development_dependency 'rubocop-airbnb'
|
data/lib/dynamodb/api.rb
CHANGED
@@ -5,7 +5,9 @@ require 'active_support/core_ext'
|
|
5
5
|
require 'dynamodb/api/version'
|
6
6
|
require 'dynamodb/api/config'
|
7
7
|
require 'dynamodb/api/adapter'
|
8
|
+
require 'dynamodb/api/base'
|
8
9
|
require 'dynamodb/api/query'
|
10
|
+
require 'dynamodb/api/scan'
|
9
11
|
require 'dynamodb/api/relation'
|
10
12
|
require 'dynamodb/api/relation/query_methods'
|
11
13
|
require 'dynamodb/api/relation/from_clause'
|
@@ -40,6 +42,10 @@ module Dynamodb
|
|
40
42
|
Delete::Tables.delete_tables
|
41
43
|
end
|
42
44
|
|
45
|
+
def scan
|
46
|
+
Scan.new
|
47
|
+
end
|
48
|
+
|
43
49
|
def query
|
44
50
|
Query.new
|
45
51
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'dynamodb/api/relation'
|
4
|
+
|
5
|
+
module Dynamodb
|
6
|
+
module Api
|
7
|
+
class Base # :nodoc:
|
8
|
+
include Relation
|
9
|
+
attr_accessor :last_evaluated_key
|
10
|
+
|
11
|
+
def all
|
12
|
+
raise NotImplementedError, "You must implement #{self.class}##{__method__}"
|
13
|
+
end
|
14
|
+
|
15
|
+
def next
|
16
|
+
raise NotImplementedError, "You must implement #{self.class}##{__method__}"
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def build_input
|
22
|
+
raise NotImplementedError, "You must implement #{self.class}##{__method__}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def base_params
|
26
|
+
raise NotImplementedError, "You must implement #{self.class}##{__method__}"
|
27
|
+
end
|
28
|
+
|
29
|
+
def order_direct(clause)
|
30
|
+
clause&.direct ? clause.direct : OrderClause.new.direct
|
31
|
+
end
|
32
|
+
|
33
|
+
def select_name(clause)
|
34
|
+
clause&.name ? clause.name : SelectClause.new.name
|
35
|
+
end
|
36
|
+
|
37
|
+
# Build filter clause.
|
38
|
+
# `filter_expression`: e.g. "Artist = :a"
|
39
|
+
# `expression_attribute_values`: e.g. { ":a" => "No One You Know" }
|
40
|
+
#
|
41
|
+
# @param input [Aws::DynamoDB::Types::ScanInput]
|
42
|
+
# @return [Aws::DynamoDB::Types::ScanInput]
|
43
|
+
def build_filter_clause(input)
|
44
|
+
return input if filter_clause&.expression.blank?
|
45
|
+
input[:filter_expression] = filter_clause.expression
|
46
|
+
if filter_clause.values.present?
|
47
|
+
if input[:expression_attribute_values].nil?
|
48
|
+
input[:expression_attribute_values] = {}
|
49
|
+
end
|
50
|
+
input[:expression_attribute_values].
|
51
|
+
merge!(filter_clause.values)
|
52
|
+
end
|
53
|
+
input
|
54
|
+
end
|
55
|
+
|
56
|
+
def build_expression_attribute_names(input)
|
57
|
+
if filter_clause&.reserved_words.present?
|
58
|
+
expression_attribute.add(filter_clause.reserved_words)
|
59
|
+
end
|
60
|
+
if expression_attribute.names.present?
|
61
|
+
input[:expression_attribute_names] = expression_attribute.names
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/lib/dynamodb/api/config.rb
CHANGED
@@ -15,6 +15,13 @@ module Dynamodb
|
|
15
15
|
option :retry_limit, default: 10
|
16
16
|
option :table_name_prefix, default: ''
|
17
17
|
option :index_name_prefix, default: ''
|
18
|
+
|
19
|
+
# @param value [String] the table name
|
20
|
+
# @return [String] the table name
|
21
|
+
def build_table_name(value)
|
22
|
+
return value unless table_name_prefix?
|
23
|
+
"#{table_name_prefix}#{value}"
|
24
|
+
end
|
18
25
|
end
|
19
26
|
end
|
20
27
|
end
|
@@ -3,9 +3,13 @@
|
|
3
3
|
module Dynamodb
|
4
4
|
module Api
|
5
5
|
module Delete
|
6
|
-
class Item
|
6
|
+
class Item
|
7
|
+
# @param key [Hash] the item key
|
8
|
+
# @param table_name [String] the table name
|
7
9
|
def self.delete_item(key, table_name)
|
8
10
|
client = Adapter.client
|
11
|
+
table_name = Dynamodb::Api::Config.build_table_name(table_name)
|
12
|
+
|
9
13
|
client.delete_item(key: key, table_name: table_name)
|
10
14
|
end
|
11
15
|
end
|
@@ -4,21 +4,24 @@ module Dynamodb
|
|
4
4
|
module Api
|
5
5
|
module Map
|
6
6
|
class Operator # :nodoc:
|
7
|
+
# Replace the Dynamodb Operators
|
8
|
+
# @param k [String] The Dynamodb Operator
|
9
|
+
# @return [String]
|
7
10
|
def self.key(k)
|
8
11
|
k = k.gsub(' ', '')
|
9
12
|
case k
|
10
|
-
when '
|
11
|
-
'
|
12
|
-
when '
|
13
|
-
'
|
14
|
-
when '
|
15
|
-
'
|
16
|
-
when '
|
17
|
-
'
|
18
|
-
when '
|
19
|
-
'
|
20
|
-
when '
|
21
|
-
'
|
13
|
+
when 'EQ'
|
14
|
+
'='
|
15
|
+
when 'NE'
|
16
|
+
'!='
|
17
|
+
when 'LE'
|
18
|
+
'<='
|
19
|
+
when 'LT'
|
20
|
+
'<'
|
21
|
+
when 'GE'
|
22
|
+
'>='
|
23
|
+
when 'GT'
|
24
|
+
'>'
|
22
25
|
else
|
23
26
|
k
|
24
27
|
end
|
@@ -3,9 +3,13 @@
|
|
3
3
|
module Dynamodb
|
4
4
|
module Api
|
5
5
|
module Put
|
6
|
-
class Item
|
6
|
+
class Item
|
7
|
+
# @param key [Hash] the item key
|
8
|
+
# @param table_name [String] the table name
|
7
9
|
def self.put_item(item, table_name)
|
8
10
|
client = Adapter.client
|
11
|
+
table_name = Dynamodb::Api::Config.build_table_name(table_name)
|
12
|
+
|
9
13
|
client.put_item(item: item, table_name: table_name)
|
10
14
|
end
|
11
15
|
end
|
data/lib/dynamodb/api/query.rb
CHANGED
@@ -4,55 +4,53 @@ require 'dynamodb/api/relation'
|
|
4
4
|
|
5
5
|
module Dynamodb
|
6
6
|
module Api
|
7
|
-
class Query # :nodoc:
|
8
|
-
include Relation
|
9
|
-
|
7
|
+
class Query < Base # :nodoc:
|
10
8
|
def all
|
11
|
-
Adapter.client.query(
|
12
|
-
|
13
|
-
|
14
|
-
private
|
15
|
-
|
16
|
-
def build_query
|
17
|
-
build_params = base_params.merge(build_filter_clause)
|
18
|
-
build_params[:scan_index_forward] = order_direct(order_clause)
|
19
|
-
build_params[:select] = select_name(select_clause)
|
20
|
-
build_expression_attribute_names(build_params)
|
21
|
-
build_params[:limit] = limit_clause.number if limit_clause&.number
|
22
|
-
build_params
|
9
|
+
result = Adapter.client.query(build_input)
|
10
|
+
@last_evaluated_key = result.last_evaluated_key
|
11
|
+
result
|
23
12
|
end
|
24
13
|
|
25
|
-
def
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
14
|
+
def next
|
15
|
+
return nil if @last_evaluated_key.blank?
|
16
|
+
input = build_input
|
17
|
+
input[:exclusive_start_key] = @last_evaluated_key
|
18
|
+
result = Adapter.client.query(input)
|
19
|
+
@last_evaluated_key = result.last_evaluated_key
|
20
|
+
return nil if result.count.zero?
|
21
|
+
result
|
31
22
|
end
|
32
23
|
|
33
|
-
|
34
|
-
clause&.direct ? clause.direct : OrderClause.new.direct
|
35
|
-
end
|
36
|
-
|
37
|
-
def select_name(clause)
|
38
|
-
clause&.name ? clause.name : SelectClause.new.name
|
39
|
-
end
|
24
|
+
private
|
40
25
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
}
|
26
|
+
# Build options.
|
27
|
+
#
|
28
|
+
# @return [Aws::DynamoDB::Types::ScanInput]
|
29
|
+
def build_input
|
30
|
+
input = Aws::DynamoDB::Types::QueryInput.new
|
31
|
+
input[:expression_attribute_values] = {}
|
32
|
+
input = base_input(input)
|
33
|
+
input = build_filter_clause(input)
|
34
|
+
input[:scan_index_forward] = order_direct(order_clause)
|
35
|
+
input[:select] = select_name(select_clause)
|
36
|
+
build_expression_attribute_names(input)
|
37
|
+
input[:limit] = limit_clause.number if limit_clause&.number
|
38
|
+
input
|
47
39
|
end
|
48
40
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
41
|
+
# Build required options.
|
42
|
+
# `key_condition_expression`: e.g. "Artist = :a"
|
43
|
+
# `expression_attribute_values`: e.g. { ":a" => "No One You Know" }
|
44
|
+
#
|
45
|
+
# @param input [Aws::DynamoDB::Types::ScanInput]
|
46
|
+
# @return [Aws::DynamoDB::Types::ScanInput]
|
47
|
+
def base_input(input)
|
48
|
+
input[:table_name] = from_clause.name
|
49
|
+
input[:index_name] = index_clause.name
|
50
|
+
input[:key_condition_expression] = where_clause.key_condition
|
51
|
+
input[:expression_attribute_values].
|
52
|
+
merge!(where_clause.attribute_values)
|
53
|
+
input
|
56
54
|
end
|
57
55
|
end
|
58
56
|
end
|
@@ -6,11 +6,9 @@ module Dynamodb
|
|
6
6
|
class FromClause # :nodoc:
|
7
7
|
attr_reader :name
|
8
8
|
|
9
|
+
# @param name [String] the table name
|
9
10
|
def initialize(name)
|
10
|
-
|
11
|
-
name = Dynamodb::Api::Config.table_name_prefix + name
|
12
|
-
end
|
13
|
-
@name = name
|
11
|
+
@name = Dynamodb::Api::Config.build_table_name(name)
|
14
12
|
end
|
15
13
|
end
|
16
14
|
end
|
@@ -4,24 +4,89 @@ module Dynamodb
|
|
4
4
|
module Api
|
5
5
|
module Relation
|
6
6
|
class WhereClause # :nodoc:
|
7
|
-
attr_reader :
|
7
|
+
attr_reader :key_condition
|
8
|
+
attr_reader :attribute_values
|
8
9
|
|
9
10
|
KEY = 0
|
10
11
|
VALUE = 2
|
11
12
|
OPERATOR = 1
|
13
|
+
FROM = 0
|
14
|
+
TO = 1
|
12
15
|
|
13
|
-
|
14
|
-
|
16
|
+
# @param conditions [Array]
|
17
|
+
def initialize(conditions)
|
18
|
+
built_conditions = build(conditions)
|
19
|
+
@key_condition = built_conditions[:key_conditions]
|
20
|
+
@attribute_values = built_conditions[:attribute_values]
|
15
21
|
end
|
16
22
|
|
17
23
|
private
|
18
24
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
+
# Build where clause.
|
26
|
+
#
|
27
|
+
# @param conditions [Array]
|
28
|
+
def build(conditions)
|
29
|
+
init = { key_conditions: [], attribute_values: {} }
|
30
|
+
conditions = format_conditions(conditions)
|
31
|
+
built = conditions.each_with_object(init) do |c, h|
|
32
|
+
h[:key_conditions] <<
|
33
|
+
format_key_condition(c[KEY], c[OPERATOR])
|
34
|
+
h[:attribute_values].
|
35
|
+
merge!(format_values(c[KEY], c[OPERATOR], c[VALUE]))
|
36
|
+
end
|
37
|
+
built[:key_conditions] =
|
38
|
+
built[:key_conditions].join(' AND ')
|
39
|
+
built
|
40
|
+
end
|
41
|
+
|
42
|
+
# Format to the `key_condition_expression`.
|
43
|
+
# e.g.
|
44
|
+
# `format_key_condition("Artist", "=")` =>
|
45
|
+
# `"Artist = :Artist"`
|
46
|
+
#
|
47
|
+
# `format_key_condition("Artist", "begins_with")` =>
|
48
|
+
# `"begins_with(Artist, :Artist)"`
|
49
|
+
#
|
50
|
+
# `format_key_condition("Year", "between")` =>
|
51
|
+
# `"Year between :from_Year and :to_Year"`
|
52
|
+
#
|
53
|
+
# @param key [String] a attribute name
|
54
|
+
# @param operator [String] a operator
|
55
|
+
# @return [String] Formatted expression.
|
56
|
+
def format_key_condition(key, operator)
|
57
|
+
case operator.downcase
|
58
|
+
when 'begins_with'
|
59
|
+
"#{operator.downcase}(#{key}, :#{key})"
|
60
|
+
when 'between'
|
61
|
+
"#{key} #{operator.downcase}" \
|
62
|
+
" :from_#{key} AND :to_#{key}"
|
63
|
+
else
|
64
|
+
"#{key} #{Map::Operator.key(operator)} :#{key}"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Format to the `expression_attribute_values`
|
69
|
+
# e.g.
|
70
|
+
# `format_values("Artist", "=", "blue")` =>
|
71
|
+
# `{ ":Artist" => "blue" }`
|
72
|
+
#
|
73
|
+
# `format_values("Year", "between", [1999, 2020])` =>
|
74
|
+
# `{ ":from_Year" => 1999, ":to_Year" => 2020 }`
|
75
|
+
#
|
76
|
+
# @param key [String] a attribute name
|
77
|
+
# @param operator [String] a operator
|
78
|
+
# @param values [Object] values
|
79
|
+
# @return [Hash<Object>] Formatted expression.
|
80
|
+
def format_values(key, operator, values)
|
81
|
+
case operator.downcase
|
82
|
+
when 'between'
|
83
|
+
{
|
84
|
+
":from_#{key}" => values[FROM],
|
85
|
+
":to_#{key}" => values[TO],
|
86
|
+
}
|
87
|
+
else
|
88
|
+
{
|
89
|
+
":#{key}" => values.is_a?(Array) ? values[0] : values,
|
25
90
|
}
|
26
91
|
end
|
27
92
|
end
|
@@ -30,11 +95,6 @@ module Dynamodb
|
|
30
95
|
return [conditions] unless conditions[0].is_a?(Array)
|
31
96
|
conditions
|
32
97
|
end
|
33
|
-
|
34
|
-
def format_value(value)
|
35
|
-
return [value] unless value.is_a?(Array)
|
36
|
-
value
|
37
|
-
end
|
38
98
|
end
|
39
99
|
end
|
40
100
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'dynamodb/api/relation'
|
4
|
+
|
5
|
+
module Dynamodb
|
6
|
+
module Api
|
7
|
+
class Scan < Base # :nodoc:
|
8
|
+
def all
|
9
|
+
result = Adapter.client.scan(build_input)
|
10
|
+
@last_evaluated_key = result.last_evaluated_key
|
11
|
+
result
|
12
|
+
end
|
13
|
+
|
14
|
+
def next
|
15
|
+
return nil if @last_evaluated_key.blank?
|
16
|
+
input = build_input
|
17
|
+
input[:exclusive_start_key] = @last_evaluated_key
|
18
|
+
result = Adapter.client.scan(input)
|
19
|
+
@last_evaluated_key = result.last_evaluated_key
|
20
|
+
result
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def build_input
|
26
|
+
input = Aws::DynamoDB::Types::ScanInput.new
|
27
|
+
input = base_input(input)
|
28
|
+
input = build_filter_clause(input)
|
29
|
+
input[:index_name] = index_clause.name if index_clause&.name
|
30
|
+
input[:select] = select_name(select_clause)
|
31
|
+
build_expression_attribute_names(input)
|
32
|
+
input[:limit] = limit_clause.number if limit_clause&.number
|
33
|
+
input
|
34
|
+
end
|
35
|
+
|
36
|
+
def base_input(input)
|
37
|
+
input[:table_name] = from_clause.name
|
38
|
+
input
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/dynamodb/api/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dynamodb-api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- WalkerSumida
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-06-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk
|
@@ -30,42 +30,28 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '5'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: bundler
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - "~>"
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '1.16'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - "~>"
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '1.16'
|
40
|
+
version: '5'
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
42
|
name: rake
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
58
44
|
requirements:
|
59
|
-
- - "
|
45
|
+
- - ">="
|
60
46
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
47
|
+
version: 12.3.3
|
62
48
|
type: :development
|
63
49
|
prerelease: false
|
64
50
|
version_requirements: !ruby/object:Gem::Requirement
|
65
51
|
requirements:
|
66
|
-
- - "
|
52
|
+
- - ">="
|
67
53
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
54
|
+
version: 12.3.3
|
69
55
|
- !ruby/object:Gem::Dependency
|
70
56
|
name: rspec
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -129,15 +115,16 @@ executables: []
|
|
129
115
|
extensions: []
|
130
116
|
extra_rdoc_files: []
|
131
117
|
files:
|
118
|
+
- ".github/workflows/build.yml"
|
132
119
|
- ".gitignore"
|
133
120
|
- ".pryrc"
|
134
121
|
- ".rspec"
|
135
122
|
- ".rubocop.yml"
|
136
123
|
- ".rubocop_todo.yml"
|
137
|
-
- ".travis.yml"
|
138
124
|
- Appraisals
|
139
125
|
- CHANGELOG.md
|
140
126
|
- CODE_OF_CONDUCT.md
|
127
|
+
- Dockerfile
|
141
128
|
- Gemfile
|
142
129
|
- LICENSE.txt
|
143
130
|
- README.md
|
@@ -146,10 +133,13 @@ files:
|
|
146
133
|
- bin/setup
|
147
134
|
- docker-compose.yml
|
148
135
|
- dynamodb-api.gemspec
|
149
|
-
- gemfiles/
|
150
|
-
- gemfiles/
|
136
|
+
- gemfiles/aws_sdk_2_rails_5.gemfile
|
137
|
+
- gemfiles/aws_sdk_2_rails_6.gemfile
|
138
|
+
- gemfiles/aws_sdk_3_rails_5.gemfile
|
139
|
+
- gemfiles/aws_sdk_3_rails_6.gemfile
|
151
140
|
- lib/dynamodb/api.rb
|
152
141
|
- lib/dynamodb/api/adapter.rb
|
142
|
+
- lib/dynamodb/api/base.rb
|
153
143
|
- lib/dynamodb/api/config.rb
|
154
144
|
- lib/dynamodb/api/config/options.rb
|
155
145
|
- lib/dynamodb/api/delete/item.rb
|
@@ -167,6 +157,7 @@ files:
|
|
167
157
|
- lib/dynamodb/api/relation/query_methods.rb
|
168
158
|
- lib/dynamodb/api/relation/select_clause.rb
|
169
159
|
- lib/dynamodb/api/relation/where_clause.rb
|
160
|
+
- lib/dynamodb/api/scan.rb
|
170
161
|
- lib/dynamodb/api/update/attributes.rb
|
171
162
|
- lib/dynamodb/api/update/base.rb
|
172
163
|
- lib/dynamodb/api/update/item.rb
|
@@ -175,7 +166,7 @@ homepage: https://github.com/walkersumida/dynamodb-api
|
|
175
166
|
licenses:
|
176
167
|
- MIT
|
177
168
|
metadata: {}
|
178
|
-
post_install_message:
|
169
|
+
post_install_message:
|
179
170
|
rdoc_options: []
|
180
171
|
require_paths:
|
181
172
|
- lib
|
@@ -190,9 +181,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
190
181
|
- !ruby/object:Gem::Version
|
191
182
|
version: '0'
|
192
183
|
requirements: []
|
193
|
-
|
194
|
-
|
195
|
-
signing_key:
|
184
|
+
rubygems_version: 3.0.3
|
185
|
+
signing_key:
|
196
186
|
specification_version: 4
|
197
187
|
summary: aws dynamodb api
|
198
188
|
test_files: []
|
data/.travis.yml
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
sudo: false
|
2
|
-
language: ruby
|
3
|
-
rvm:
|
4
|
-
- 2.3
|
5
|
-
- 2.4
|
6
|
-
- 2.5
|
7
|
-
gemfile:
|
8
|
-
- gemfiles/aws_sdk_2.gemfile
|
9
|
-
- gemfiles/aws_sdk_3.gemfile
|
10
|
-
|
11
|
-
before_install: gem install bundler -v 1.16.2
|
12
|
-
|
13
|
-
before_script:
|
14
|
-
- docker-compose up -d
|
15
|
-
|
16
|
-
script: bundle exec rubocop --fail-level=C
|
17
|
-
|
18
|
-
after_script:
|
19
|
-
- docker-compose down
|