dynamini 2.0.1 → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7670b7c7034d305b27556e8308071bce377fb070
4
- data.tar.gz: b390eaed2526efccbfa2abefcf304980999c2201
3
+ metadata.gz: 375aefa0350dd33fcd702b47d06896ffad78b986
4
+ data.tar.gz: b8159e0743eb229c6c93e5ea27e2cb45ef3147c0
5
5
  SHA512:
6
- metadata.gz: f2b7b0109bb0ad3b278719c886d5c97122a6dd2551a25fab863746bd20930b102206ba3b88bf9a2f1db79ab4ce4a3a2186982d1d4f6143ad694601043d37be48
7
- data.tar.gz: b9adb969dd713d8cb86254e23b245c16ac1b2bbf27da03af0bdbebe57a03cc4b486d7b974b39990db8f403c4e13af1197295d8fb637ffa1e8e7ce14208106ca7
6
+ metadata.gz: b3c7ac2347cafdcdad0e67d54c3cfaac1fbc94a34324b9dc43e9dcc83831e13b2c0423af95f01c434db677600f5ecb81547968845efed78288243675c24193ab
7
+ data.tar.gz: 4bba1206df754d28ceddae3e7fe09214561a6368bd52c07d21da40628c36c9b90732a4bdc6c2b5c3836451c11f03abe1d7965f9f10f71ad7ea01d0b3bc91e5b9
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dynamini (2.0.1)
4
+ dynamini (2.1.1)
5
5
  activemodel (>= 3, < 5.0)
6
6
  aws-sdk (~> 2)
7
7
 
@@ -99,6 +99,3 @@ DEPENDENCIES
99
99
  guard-shell
100
100
  pry (~> 0)
101
101
  rspec (~> 3)
102
-
103
- BUNDLED WITH
104
- 1.11.2
data/README.md CHANGED
@@ -175,13 +175,13 @@ Vehicle.find('H3LLO').stuff
175
175
  ```
176
176
 
177
177
  ## Testing
178
- There's a test client included with this gem, meaning you don't have to connect to a real Dynamo instance when testing.
179
- You could also use this in development if you dont have a real Dynamo instance yet, but the data saved to it won't persist through a server restart.
180
- To activate this feature, just do:
178
+ We've included an optional in-memory test client, so you don't necessarily have to connect to a real Dynamo instance when running tests. You could also use this in your development environment if you don't have a real Dynamo instance yet, but the data saved to it won't persist through a server restart.
179
+
180
+ To activate this feature, just require the testing module:
181
181
  ```ruby
182
182
  require 'dynamini/testing'
183
183
  ```
184
- After which any internal API calls will be replaced with calls to Dynamini::TestClient.
184
+ This module replaces all API calls Dynamini makes to AWS DynamoDB with calls to Dynamini::TestClient.
185
185
 
186
186
  The test client will not reset its database unless you tell it to, like so:
187
187
  ```ruby
@@ -205,9 +205,6 @@ config.after(:each) {
205
205
  * If you use non-numeric strings for your primary key, remember to change your foreign key columns on related objects to be string type.
206
206
  * You might want to conditionally set the table name for your model based on the Rails.env, enabling separate tables for development and production.
207
207
 
208
- ## Coming Soon
209
- * Conditional updates ( http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.SpecifyingConditions.html )
210
-
211
208
  ## Contributing
212
209
 
213
210
  If you'd like to contribute, pull requests are welcome!
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'dynamini'
3
- s.version = '2.0.1'
3
+ s.version = '2.1.1'
4
4
  s.summary = 'DynamoDB interface'
5
5
  s.description = 'Lightweight DynamoDB interface gem designed as
6
6
  a drop-in replacement for ActiveRecord.
@@ -1,5 +1,6 @@
1
1
  module Dynamini
2
2
  module Querying
3
+ OPTIONAL_QUERY_PARAMS = [:limit, :scan_index_forward]
3
4
 
4
5
  def find(hash_value, range_value = nil)
5
6
  fail 'Range key cannot be blank.' if range_key && range_value.nil?
@@ -51,11 +52,13 @@ module Dynamini
51
52
  expression_attribute_values = build_expression_attribute_values(args)
52
53
  key_condition_expression = build_key_condition_expression(args)
53
54
 
54
- client.query(
55
- table_name: table_name,
56
- key_condition_expression: key_condition_expression,
57
- expression_attribute_values: expression_attribute_values
58
- )
55
+ client.query(set_extra_parameters(
56
+ {
57
+ table_name: table_name,
58
+ key_condition_expression: key_condition_expression,
59
+ expression_attribute_values: expression_attribute_values
60
+ },
61
+ args))
59
62
  end
60
63
 
61
64
  def build_expression_attribute_values(args)
@@ -78,6 +81,11 @@ module Dynamini
78
81
  expression
79
82
  end
80
83
 
84
+ def set_extra_parameters(hash, args)
85
+ extras = args.select { |k, v| OPTIONAL_QUERY_PARAMS.include? k }
86
+ hash.merge!(extras)
87
+ end
88
+
81
89
  def validate_query_values(hash_value, range_value)
82
90
  fail 'Key cannot be blank.' if (hash_value.nil? || hash_value == '')
83
91
  fail 'Range key cannot be blank.' if range_key && range_value.nil?
@@ -124,6 +124,8 @@ module Dynamini
124
124
  selected = parent.values
125
125
  selected = selected.select{ |item| item[@range_key_attr] >= start_val.to_f } if start_val
126
126
  selected = selected.select{ |item| item[@range_key_attr] <= end_val.to_f } if end_val
127
+ selected = selected.sort! { |a,b| b[@range_key_attr] <=> a[@range_key_attr] } if args[:scan_index_forward] == false
128
+ selected = selected[0...args[:limit]] if args[:limit]
127
129
 
128
130
  OpenStruct.new(items: selected)
129
131
  end
@@ -4,10 +4,10 @@ describe Dynamini::Querying do
4
4
 
5
5
  let(:model_attributes) {
6
6
  {
7
- name: 'Widget',
8
- price: 9.99,
9
- id: 'abcd1234',
10
- hash_key: '009'
7
+ name: 'Widget',
8
+ price: 9.99,
9
+ id: 'abcd1234',
10
+ hash_key: '009'
11
11
  }
12
12
  }
13
13
 
@@ -104,6 +104,31 @@ describe Dynamini::Querying do
104
104
  expect(TestClassWithRange.query(hash_key: 'non-existent key')).to eq([])
105
105
  end
106
106
  end
107
+
108
+ context 'when :limit is provided' do
109
+ it 'should return only the first two records' do
110
+ records = TestClassWithRange.query(hash_key: 'foo', limit: 2)
111
+ expect(records.length).to eq 2
112
+ expect(records.first.bar).to eq 1
113
+ expect(records.last.bar).to eq 2
114
+ end
115
+ end
116
+
117
+ context 'when :scan_index_forward is provided' do
118
+ it 'should return records in order when given true' do
119
+ records = TestClassWithRange.query(hash_key: 'foo', scan_index_forward: true)
120
+ expect(records.length).to eq 4
121
+ expect(records.first.bar).to eq 1
122
+ expect(records.last.bar).to eq 4
123
+ end
124
+
125
+ it 'should return records in reverse order when given false' do
126
+ records = TestClassWithRange.query(hash_key: 'foo', scan_index_forward: false)
127
+ expect(records.length).to eq 4
128
+ expect(records.first.bar).to eq 4
129
+ expect(records.last.bar).to eq 1
130
+ end
131
+ end
107
132
  end
108
133
 
109
134
  describe '.exists?' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dynamini
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Greg Ward
@@ -15,110 +15,110 @@ authors:
15
15
  autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
- date: 2016-02-09 00:00:00.000000000 Z
18
+ date: 2016-02-29 00:00:00.000000000 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: activemodel
22
22
  requirement: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: '3'
27
- - - "<"
27
+ - - <
28
28
  - !ruby/object:Gem::Version
29
29
  version: '5.0'
30
30
  type: :runtime
31
31
  prerelease: false
32
32
  version_requirements: !ruby/object:Gem::Requirement
33
33
  requirements:
34
- - - ">="
34
+ - - '>='
35
35
  - !ruby/object:Gem::Version
36
36
  version: '3'
37
- - - "<"
37
+ - - <
38
38
  - !ruby/object:Gem::Version
39
39
  version: '5.0'
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: aws-sdk
42
42
  requirement: !ruby/object:Gem::Requirement
43
43
  requirements:
44
- - - "~>"
44
+ - - ~>
45
45
  - !ruby/object:Gem::Version
46
46
  version: '2'
47
47
  type: :runtime
48
48
  prerelease: false
49
49
  version_requirements: !ruby/object:Gem::Requirement
50
50
  requirements:
51
- - - "~>"
51
+ - - ~>
52
52
  - !ruby/object:Gem::Version
53
53
  version: '2'
54
54
  - !ruby/object:Gem::Dependency
55
55
  name: rspec
56
56
  requirement: !ruby/object:Gem::Requirement
57
57
  requirements:
58
- - - "~>"
58
+ - - ~>
59
59
  - !ruby/object:Gem::Version
60
60
  version: '3'
61
61
  type: :development
62
62
  prerelease: false
63
63
  version_requirements: !ruby/object:Gem::Requirement
64
64
  requirements:
65
- - - "~>"
65
+ - - ~>
66
66
  - !ruby/object:Gem::Version
67
67
  version: '3'
68
68
  - !ruby/object:Gem::Dependency
69
69
  name: pry
70
70
  requirement: !ruby/object:Gem::Requirement
71
71
  requirements:
72
- - - "~>"
72
+ - - ~>
73
73
  - !ruby/object:Gem::Version
74
74
  version: '0'
75
75
  type: :development
76
76
  prerelease: false
77
77
  version_requirements: !ruby/object:Gem::Requirement
78
78
  requirements:
79
- - - "~>"
79
+ - - ~>
80
80
  - !ruby/object:Gem::Version
81
81
  version: '0'
82
82
  - !ruby/object:Gem::Dependency
83
83
  name: fuubar
84
84
  requirement: !ruby/object:Gem::Requirement
85
85
  requirements:
86
- - - "~>"
86
+ - - ~>
87
87
  - !ruby/object:Gem::Version
88
88
  version: '2'
89
89
  type: :development
90
90
  prerelease: false
91
91
  version_requirements: !ruby/object:Gem::Requirement
92
92
  requirements:
93
- - - "~>"
93
+ - - ~>
94
94
  - !ruby/object:Gem::Version
95
95
  version: '2'
96
96
  - !ruby/object:Gem::Dependency
97
97
  name: guard-rspec
98
98
  requirement: !ruby/object:Gem::Requirement
99
99
  requirements:
100
- - - ">="
100
+ - - '>='
101
101
  - !ruby/object:Gem::Version
102
102
  version: '0'
103
103
  type: :development
104
104
  prerelease: false
105
105
  version_requirements: !ruby/object:Gem::Requirement
106
106
  requirements:
107
- - - ">="
107
+ - - '>='
108
108
  - !ruby/object:Gem::Version
109
109
  version: '0'
110
110
  - !ruby/object:Gem::Dependency
111
111
  name: guard-shell
112
112
  requirement: !ruby/object:Gem::Requirement
113
113
  requirements:
114
- - - ">="
114
+ - - '>='
115
115
  - !ruby/object:Gem::Version
116
116
  version: '0'
117
117
  type: :development
118
118
  prerelease: false
119
119
  version_requirements: !ruby/object:Gem::Requirement
120
120
  requirements:
121
- - - ">="
121
+ - - '>='
122
122
  - !ruby/object:Gem::Version
123
123
  version: '0'
124
124
  description: |-
@@ -130,9 +130,9 @@ executables: []
130
130
  extensions: []
131
131
  extra_rdoc_files: []
132
132
  files:
133
- - ".gitignore"
134
- - ".rspec"
135
- - ".travis.yml"
133
+ - .gitignore
134
+ - .rspec
135
+ - .travis.yml
136
136
  - Gemfile
137
137
  - Gemfile.lock
138
138
  - Guardfile
@@ -170,17 +170,17 @@ require_paths:
170
170
  - lib
171
171
  required_ruby_version: !ruby/object:Gem::Requirement
172
172
  requirements:
173
- - - ">="
173
+ - - '>='
174
174
  - !ruby/object:Gem::Version
175
175
  version: '0'
176
176
  required_rubygems_version: !ruby/object:Gem::Requirement
177
177
  requirements:
178
- - - ">="
178
+ - - '>='
179
179
  - !ruby/object:Gem::Version
180
180
  version: '0'
181
181
  requirements: []
182
182
  rubyforge_project:
183
- rubygems_version: 2.5.1
183
+ rubygems_version: 2.2.2
184
184
  signing_key:
185
185
  specification_version: 4
186
186
  summary: DynamoDB interface