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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d9be0f31417b188293408482f8661646b207c587e62f19b252cba0beecb9f7a7
4
- data.tar.gz: e449872d243d29819b761edf6503f5931cd838436eabb2584bd7ea238125573f
3
+ metadata.gz: 1276a3be5e1124f79957caee61c7585e3f59f37da5f12e2fac5d638238727ee8
4
+ data.tar.gz: c36d86b1087075fd6c154e5491cd08e6effcc0e91ffa0d96595d31fafc33eabc
5
5
  SHA512:
6
- metadata.gz: 43976f0890badbe08057345c9576d6cb48cd623ac97b1363bab6cc9dfaa245cded0cba11dc694a6d4213e0b08ab30ac8436f86b249553859220cb03224068ffa
7
- data.tar.gz: 66be89216803aeb7644a12a5107894cc1531eb14c9ca70bae8dc304fdeffd985d1ba4ac83d8ff07eaa381138e51e4b90c8aa22f056c4e62e55ec21fce12a43fc
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-3" do
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
- [![Build Status](https://travis-ci.org/walkersumida/dynamodb-api.svg?branch=master)](https://travis-ci.org/walkersumida/dynamodb-api)
3
+ ![Build Status](https://github.com/walkersumida/dynamodb-api/workflows/build/badge.svg?branch=master)
4
4
  [![Gem Version](https://badge.fury.io/rb/dynamodb-api.svg)](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
- - After checking out the repo, run `bin/setup` to install dependencies.
215
- - Run `bundle exec rake spec` to run the tests. Or run `bundle exec appraisal aws-sdk-* rake spec` to run the tests. Replase `*` with aws sdk major version.
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
@@ -21,7 +21,7 @@ Aws.config.update(
21
21
  )
22
22
 
23
23
  Dynamodb::Api.config do |config|
24
- config.endpoint = 'http://0.0.0.0:8000'
24
+ config.endpoint = 'http://dynamodb:8000'
25
25
  end
26
26
 
27
27
  IRB.start(__FILE__)
data/docker-compose.yml CHANGED
@@ -1,6 +1,12 @@
1
1
  version: '3'
2
2
  services:
3
+ ruby:
4
+ build:
5
+ context: .
6
+ dockerfile: Dockerfile
7
+ volumes:
8
+ - .:/app
3
9
  dynamodb:
4
- image: cnadiminti/dynamodb-local:2018-04-11
10
+ image: amazon/dynamodb-local
5
11
  ports:
6
12
  - 8000:8000
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', '>= 4')
26
+ spec.add_runtime_dependency('activesupport', '>= 5')
27
27
 
28
- spec.add_development_dependency 'bundler', '~> 1.16'
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'
@@ -4,5 +4,6 @@ source "https://rubygems.org"
4
4
 
5
5
  gem "pry-byebug", platforms: :ruby
6
6
  gem "aws-sdk", "~> 2"
7
+ gem "activesupport", "~> 5"
7
8
 
8
9
  gemspec path: "../"
@@ -0,0 +1,9 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "pry-byebug", platforms: :ruby
6
+ gem "aws-sdk", "~> 2"
7
+ gem "activesupport", "~> 6"
8
+
9
+ gemspec path: "../"
@@ -4,5 +4,6 @@ source "https://rubygems.org"
4
4
 
5
5
  gem "pry-byebug", platforms: :ruby
6
6
  gem "aws-sdk", "~> 3"
7
+ gem "activesupport", "~> 5"
7
8
 
8
9
  gemspec path: "../"
@@ -0,0 +1,9 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "pry-byebug", platforms: :ruby
6
+ gem "aws-sdk", "~> 3"
7
+ gem "activesupport", "~> 6"
8
+
9
+ gemspec path: "../"
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
@@ -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 # :nodoc:
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,6 +4,7 @@ module Dynamodb
4
4
  module Api
5
5
  module Delete
6
6
  class Tables # :nodoc:
7
+ # TODO: add rspec
7
8
  def self.delete_tables
8
9
  client = Adapter.client
9
10
  table_names = client.list_tables[:table_names]
@@ -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
- 'EQ'
12
- when '!='
13
- 'NE'
14
- when '<='
15
- 'LE'
16
- when '<'
17
- 'LT'
18
- when '>='
19
- 'GE'
20
- when '>'
21
- 'GT'
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 # :nodoc:
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
@@ -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(build_query)
12
- end
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 base_params
26
- {
27
- table_name: from_clause.name,
28
- index_name: index_clause.name,
29
- key_conditions: where_clause.key_conditions,
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
- def order_direct(clause)
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
- def build_filter_clause
42
- return {} if filter_clause&.expression.blank?
43
- {
44
- filter_expression: filter_clause.expression,
45
- expression_attribute_values: filter_clause.values,
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
- def build_expression_attribute_names(params)
50
- if filter_clause&.reserved_words.present?
51
- expression_attribute.add(filter_clause.reserved_words)
52
- end
53
- if expression_attribute.names.present?
54
- params[:expression_attribute_names] = expression_attribute.names
55
- end
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
- if Dynamodb::Api::Config.table_name_prefix?
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
@@ -24,8 +24,8 @@ module Dynamodb
24
24
  self
25
25
  end
26
26
 
27
- def where(key_conditions)
28
- self.where_clause = Relation::WhereClause.new(key_conditions)
27
+ def where(expression)
28
+ self.where_clause = Relation::WhereClause.new(expression)
29
29
  self
30
30
  end
31
31
 
@@ -4,24 +4,89 @@ module Dynamodb
4
4
  module Api
5
5
  module Relation
6
6
  class WhereClause # :nodoc:
7
- attr_reader :key_conditions
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
- def initialize(key_conditions)
14
- @key_conditions = build(key_conditions)
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
- def build(key_conditions)
20
- conditions = format_conditions(key_conditions)
21
- conditions.each_with_object({}) do |c, h|
22
- h[c[KEY]] = {
23
- attribute_value_list: format_value(c[VALUE]),
24
- comparison_operator: Map::Operator.key(c[OPERATOR]),
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
@@ -7,7 +7,7 @@ module Dynamodb
7
7
  def update_item(key, cols, table_name)
8
8
  @key = key
9
9
  @cols = cols
10
- @table_name = table_name
10
+ @table_name = Dynamodb::Api::Config.build_table_name(table_name)
11
11
 
12
12
  client = Adapter.client
13
13
  client.update_item(build_update_clause)
@@ -1,5 +1,5 @@
1
1
  module Dynamodb
2
2
  module Api
3
- VERSION = '0.6.2'.freeze
3
+ VERSION = '0.9.1'.freeze
4
4
  end
5
5
  end
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.6.2
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: 2018-12-15 00:00:00.000000000 Z
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: '4'
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: '4'
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: '10.0'
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: '10.0'
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/aws_sdk_2.gemfile
150
- - gemfiles/aws_sdk_3.gemfile
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
- rubyforge_project:
194
- rubygems_version: 2.7.6
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