lotus-dynamodb 0.1.0 → 0.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: 8b6e1c051b76f678f3694e0e0cb8f70871a3dbce
4
- data.tar.gz: d7e164efdaa51814a36a7c803c959ad9c21c3b71
3
+ metadata.gz: 4afda395af46d537deed3ac0619746f3c693f53b
4
+ data.tar.gz: f4c3028928436d9c3d035e48a8ec7a17dab6137c
5
5
  SHA512:
6
- metadata.gz: 5a326db3a7714f0573be6b4ebadd1dc2ad5dc7fea5303be5c61c09bcfdd37435084215ff60837156f9c4481c044f24af96b8b65d504a9b4e25a3f8f5f6069771
7
- data.tar.gz: d1a6068ecc5898cf70ce48ed8b751498ff405fbca62f0a60990f36197d40fe4489e21c0011fff4bd04f215f7642c20763219b624966acaf2578f62be566c308a
6
+ metadata.gz: f35e5aa974d0cb68835e04f6fc6e4b7e77d87f8239ef13a84f5acdf23e6c927d2b1e468d67bf19f82854755cc94e119073b13fb4e16bd0f493668a8eb08395e8
7
+ data.tar.gz: 0d2fea387a98192508cda33c444500374ba1cfe4ff5a2b5b157ecaf1d75e84c4519ec8e8002dffbc84c75a0de6311c0a514f439996f7971173881fcdd3ffdee9
@@ -0,0 +1,14 @@
1
+ v0.1.1
2
+ ------
3
+
4
+ * Bump lotus-model dependency to 0.1.1
5
+ * Switch Lotus::Utils::Kernel.* to Lotus::Model::Mapping::Coercions.*
6
+ * Improve Query#all to return real all entries
7
+ * Improve Query#count to return real count
8
+ * Improve Query#each to iterate over batches of entries
9
+ * Improve DynamodbAdapter#clear to clear even large tables
10
+
11
+ v0.1.0
12
+ ------
13
+
14
+ * Initial version
data/Gemfile CHANGED
@@ -10,7 +10,11 @@ gem 'simplecov', require: false
10
10
  gem 'coveralls', require: false
11
11
 
12
12
  # Benchmarking
13
- gem 'benchmark-ips', '~> 1.2'
13
+ gem 'benchmark-ips', '~> 2.0'
14
14
 
15
15
  # Fixes are not merged yet
16
16
  gem 'fake_dynamo', github: 'krasnoukhov/fake_dynamo'
17
+
18
+ # Upstream
19
+ gem 'lotus-utils', github: 'lotus/utils'
20
+ gem 'lotus-model', github: 'lotus/model'
data/README.md CHANGED
@@ -16,12 +16,12 @@ It is built using ```AWS::DynamoDB::Client```, which is a part of ```aws-sdk```
16
16
  [![Build Status](https://secure.travis-ci.org/krasnoukhov/lotus-dynamodb.svg?branch=master)](http://travis-ci.org/krasnoukhov/lotus-dynamodb?branch=master)
17
17
  [![Coverage Status](https://img.shields.io/coveralls/krasnoukhov/lotus-dynamodb.svg)](https://coveralls.io/r/krasnoukhov/lotus-dynamodb?branch=master)
18
18
  [![Code Climate](https://img.shields.io/codeclimate/github/krasnoukhov/lotus-dynamodb.svg)](https://codeclimate.com/github/krasnoukhov/lotus-dynamodb)
19
- [![Inline docs](http://inch-pages.github.io/github/krasnoukhov/lotus-dynamodb.svg)](http://inch-pages.github.io/github/krasnoukhov/lotus-dynamodb)
19
+ [![Inline docs](http://inch-ci.org/github/krasnoukhov/lotus-dynamodb.svg)](http://inch-ci.org/github/krasnoukhov/lotus-dynamodb)
20
20
  [![Dependencies](https://gemnasium.com/krasnoukhov/lotus-dynamodb.svg)](https://gemnasium.com/krasnoukhov/lotus-dynamodb)
21
21
 
22
22
  ## Links
23
23
 
24
- * API Doc: [http://rdoc.info/github/krasnoukhov/lotus-dynamodb](http://rdoc.info/github/krasnoukhov/lotus-dynamodb)
24
+ * API Doc: [http://rdoc.info/gems/lotus-dynamodb](http://rdoc.info/gems/lotus-dynamodb)
25
25
  * Bugs/Issues: [https://github.com/krasnoukhov/lotus-dynamodb/issues](https://github.com/krasnoukhov/lotus-dynamodb/issues)
26
26
 
27
27
  ## Installation
@@ -73,31 +73,31 @@ Following methods are not supported since it's incompatible with DynamoDB:
73
73
 
74
74
  Generic methods supported by DynamoDB adapter:
75
75
 
76
- * [all](http://rdoc.info/github/krasnoukhov/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#all-instance_method)
77
- * [where](http://rdoc.info/github/krasnoukhov/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#where-instance_method) (aliases: ```eq```, ```in```, ```between```)
78
- * [or](http://rdoc.info/github/krasnoukhov/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#or-instance_method)
79
- * [exclude](http://rdoc.info/github/krasnoukhov/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#exclude-instance_method) (aliases: ```not```, ```ne```)
80
- * [select](http://rdoc.info/github/krasnoukhov/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#select-instance_method)
81
- * [order](http://rdoc.info/github/krasnoukhov/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#order-instance_method) (alias: ```asc```)
82
- * [desc](http://rdoc.info/github/krasnoukhov/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#desc-instance_method)
83
- * [limit](http://rdoc.info/github/krasnoukhov/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#limit-instance_method)
84
- * [exists?](http://rdoc.info/github/krasnoukhov/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#exist%3F-instance_method) (alias: ```exist?```)
85
- * [count](http://rdoc.info/github/krasnoukhov/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#count-instance_method)
76
+ * [all](http://rdoc.info/gems/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#all-instance_method)
77
+ * [where](http://rdoc.info/gems/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#where-instance_method) (aliases: ```eq```, ```in```, ```between```)
78
+ * [or](http://rdoc.info/gems/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#or-instance_method)
79
+ * [exclude](http://rdoc.info/gems/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#exclude-instance_method) (aliases: ```not```, ```ne```)
80
+ * [select](http://rdoc.info/gems/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#select-instance_method)
81
+ * [order](http://rdoc.info/gems/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#order-instance_method) (alias: ```asc```)
82
+ * [desc](http://rdoc.info/gems/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#desc-instance_method)
83
+ * [limit](http://rdoc.info/gems/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#limit-instance_method)
84
+ * [exists?](http://rdoc.info/gems/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#exist%3F-instance_method) (alias: ```exist?```)
85
+ * [count](http://rdoc.info/gems/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#count-instance_method)
86
86
 
87
87
  DynamoDB-specific methods:
88
88
 
89
- * [query](http://rdoc.info/github/krasnoukhov/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#query-instance_method) – ensure ```query``` operation is performed instead of ```scan```
90
- * [consistent](http://rdoc.info/github/krasnoukhov/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#consistent-instance_method) – require consistent read for query
91
- * [index](http://rdoc.info/github/krasnoukhov/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#index-instance_method) – perform query on specific index
92
- * [le](http://rdoc.info/github/krasnoukhov/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#le-instance_method)
93
- * [lt](http://rdoc.info/github/krasnoukhov/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#lt-instance_method)
94
- * [ge](http://rdoc.info/github/krasnoukhov/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#ge-instance_method)
95
- * [gt](http://rdoc.info/github/krasnoukhov/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#gt-instance_method)
96
- * [contains](http://rdoc.info/github/krasnoukhov/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#contains-instance_method)
97
- * [not_contains](http://rdoc.info/github/krasnoukhov/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#not_contains-instance_method)
98
- * [begins_with](http://rdoc.info/github/krasnoukhov/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#begins_with-instance_method)
99
- * [null](http://rdoc.info/github/krasnoukhov/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#null-instance_method)
100
- * [not_null](http://rdoc.info/github/krasnoukhov/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#not_null-instance_method)
89
+ * [query](http://rdoc.info/gems/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#query-instance_method) – ensure ```query``` operation is performed instead of ```scan```
90
+ * [consistent](http://rdoc.info/gems/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#consistent-instance_method) – require consistent read for query
91
+ * [index](http://rdoc.info/gems/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#index-instance_method) – perform query on specific index
92
+ * [le](http://rdoc.info/gems/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#le-instance_method)
93
+ * [lt](http://rdoc.info/gems/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#lt-instance_method)
94
+ * [ge](http://rdoc.info/gems/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#ge-instance_method)
95
+ * [gt](http://rdoc.info/gems/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#gt-instance_method)
96
+ * [contains](http://rdoc.info/gems/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#contains-instance_method)
97
+ * [not_contains](http://rdoc.info/gems/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#not_contains-instance_method)
98
+ * [begins_with](http://rdoc.info/gems/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#begins_with-instance_method)
99
+ * [null](http://rdoc.info/gems/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#null-instance_method)
100
+ * [not_null](http://rdoc.info/gems/lotus-dynamodb/Lotus/Model/Adapters/Dynamodb/Query#not_null-instance_method)
101
101
 
102
102
  ### Example
103
103
 
@@ -18,34 +18,27 @@ class Project
18
18
  :attr5, :attr6, :attr7, :attr8, :attr9
19
19
  end
20
20
 
21
- default_collection = Lotus::Model::Mapping::Collection.new(:projects, Lotus::Model::Mapping::Coercer) do
22
- entity Project
21
+ spec = ->(c) {
22
+ c.entity Project
23
+
24
+ c.attribute :id, Integer
25
+ c.attribute :attr1, String
26
+ c.attribute :attr2, String
27
+ c.attribute :attr3, String
28
+ c.attribute :attr4, String
29
+ c.attribute :attr5, String
30
+ c.attribute :attr6, String
31
+ c.attribute :attr7, String
32
+ c.attribute :attr8, String
33
+ c.attribute :attr9, String
34
+ }
23
35
 
24
- attribute :id, Integer
25
- attribute :attr1, String
26
- attribute :attr2, String
27
- attribute :attr3, String
28
- attribute :attr4, String
29
- attribute :attr5, String
30
- attribute :attr6, String
31
- attribute :attr7, String
32
- attribute :attr8, String
33
- attribute :attr9, String
36
+ default_collection = Lotus::Model::Mapping::Collection.new(:projects, Lotus::Model::Mapping::Coercer) do
37
+ spec.call(self)
34
38
  end
35
39
 
36
40
  dynamodb_collection = Lotus::Model::Mapping::Collection.new(:projects, Lotus::Model::Adapters::Dynamodb::Coercer) do
37
- entity Project
38
-
39
- attribute :id, Integer
40
- attribute :attr1, String
41
- attribute :attr2, String
42
- attribute :attr3, String
43
- attribute :attr4, String
44
- attribute :attr5, String
45
- attribute :attr6, String
46
- attribute :attr7, String
47
- attribute :attr8, String
48
- attribute :attr9, String
41
+ spec.call(self)
49
42
  end
50
43
 
51
44
  record = Hash[id: '23', attr1: 'attr1', attr2: 'attr2',
@@ -3,6 +3,6 @@ module Lotus
3
3
  # Defines the version
4
4
  #
5
5
  # @since 0.1.0
6
- VERSION = '0.1.0'
6
+ VERSION = '0.1.1'
7
7
  end
8
8
  end
@@ -1,4 +1,4 @@
1
- require 'lotus/utils/kernel'
1
+ require 'lotus/model/mapping/coercions'
2
2
  require 'multi_json'
3
3
 
4
4
  module Lotus
@@ -126,6 +126,16 @@ module Lotus
126
126
  # @api private
127
127
  # @since 0.1.0
128
128
  def _compile!
129
+ _compile_skipped!
130
+ _compile_record!
131
+ _compile_serialization!
132
+ end
133
+
134
+ # Compile skipped klasses methods.
135
+ #
136
+ # @api private
137
+ # @since 0.1.1
138
+ def _compile_skipped!
129
139
  instance_eval(SKIPPED_KLASSES.map do |klass|
130
140
  %{
131
141
  def from_#{_method_name(klass)}(value)
@@ -137,19 +147,13 @@ module Lotus
137
147
  end
138
148
  }
139
149
  end.join("\n"))
150
+ end
140
151
 
141
- code = @collection.attributes.map do |_,(klass,mapped)|
142
- %{
143
- def deserialize_#{ mapped }(value)
144
- #{kernel_wrap(klass) { "from_#{_method_name(klass)}(value)" }}
145
- end
146
-
147
- def serialize_#{ mapped }(value)
148
- from_#{_method_name(klass)}(value)
149
- end
150
- }
151
- end.join("\n")
152
-
152
+ # Compile record methods.
153
+ #
154
+ # @api private
155
+ # @since 0.1.1
156
+ def _compile_record!
153
157
  instance_eval %{
154
158
  def to_record(entity)
155
159
  if entity.id
@@ -161,23 +165,39 @@ module Lotus
161
165
 
162
166
  def from_record(record)
163
167
  #{ @collection.entity }.new(
164
- Hash[*[#{ @collection.attributes.map{|name,(klass,mapped)| ":#{name},#{kernel_wrap(klass) { "to_#{_method_name(klass)}(record[:#{mapped}])" }}"}.join(',') }]]
168
+ Hash[*[#{ @collection.attributes.map{|name,(klass,mapped)| ":#{name},#{coercions_wrap(klass) { "to_#{_method_name(klass)}(record[:#{mapped}])" }}"}.join(',') }]]
165
169
  )
166
170
  end
167
-
168
- #{ code }
169
171
  }
170
172
  end
171
173
 
172
- # Wraps string in Lotus::Utils::Kernel call if needed.
174
+ # Compile deserialise/serialize methods.
175
+ #
176
+ # @api private
177
+ # @since 0.1.1
178
+ def _compile_serialization!
179
+ instance_eval(@collection.attributes.map do |_,(klass,mapped)|
180
+ %{
181
+ def deserialize_#{ mapped }(value)
182
+ #{coercions_wrap(klass) { "from_#{_method_name(klass)}(value)" }}
183
+ end
184
+
185
+ def serialize_#{ mapped }(value)
186
+ from_#{_method_name(klass)}(value)
187
+ end
188
+ }
189
+ end.join("\n"))
190
+ end
191
+
192
+ # Wraps string in Lotus::Model::Mapping::Coercions call if needed.
173
193
  #
174
194
  # @api private
175
195
  # @since 0.1.0
176
- def kernel_wrap(klass)
196
+ def coercions_wrap(klass)
177
197
  if klass.to_s.include?("::")
178
198
  yield
179
199
  else
180
- "Lotus::Utils::Kernel.#{klass}(#{yield})"
200
+ "Lotus::Model::Mapping::Coercions.#{klass}(#{yield})"
181
201
  end
182
202
  end
183
203
 
@@ -18,10 +18,11 @@ module Lotus
18
18
  # @api private
19
19
  # @since 0.1.0
20
20
  class Response
21
- attr_accessor :count, :entities
21
+ attr_accessor :count, :entities, :last_evaluated_key
22
22
 
23
- def initialize(count, entities = nil)
24
- @count, @entities = count, entities
23
+ def initialize
24
+ @count = 0
25
+ @entities = []
25
26
  end
26
27
  end
27
28
 
@@ -136,6 +137,7 @@ module Lotus
136
137
  # Performs DynamoDB query operation.
137
138
  #
138
139
  # @param options [Hash] AWS::DynamoDB::Client options
140
+ # @param previous_response [Response] deserialized response from a previous operation
139
141
  #
140
142
  # @see http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/DynamoDB/Client/V20120810.html#query-instance_method
141
143
  #
@@ -143,14 +145,15 @@ module Lotus
143
145
  #
144
146
  # @api private
145
147
  # @since 0.1.0
146
- def query(options = {})
148
+ def query(options = {}, previous_response = nil)
147
149
  response = @client.query(options.merge(table_name: name))
148
- deserialize_response(response)
150
+ deserialize_response(response, previous_response)
149
151
  end
150
152
 
151
153
  # Performs DynamoDB scan operation.
152
154
  #
153
155
  # @param options [Hash] AWS::DynamoDB::Client options
156
+ # @param previous_response [Response] deserialized response from a previous operation
154
157
  #
155
158
  # @see http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/DynamoDB/Client/V20120810.html#scan-instance_method
156
159
  #
@@ -158,9 +161,9 @@ module Lotus
158
161
  #
159
162
  # @api private
160
163
  # @since 0.1.0
161
- def scan(options = {})
164
+ def scan(options = {}, previous_response = nil)
162
165
  response = @client.scan(options.merge(table_name: name))
163
- deserialize_response(response)
166
+ deserialize_response(response, previous_response)
164
167
  end
165
168
 
166
169
  # Fetches DynamoDB table schema.
@@ -286,19 +289,22 @@ module Lotus
286
289
  # Deserialize DynamoDB scan/query response.
287
290
  #
288
291
  # @param response [Hash] the serialized response
292
+ # @param previous_response [Response] deserialized response from a previous operation
289
293
  #
290
- # @return [Hash] the deserialized response
294
+ # @return [Response] the deserialized response
291
295
  #
292
296
  # @api private
293
297
  # @since 0.1.0
294
- def deserialize_response(response)
295
- result = Response.new(response[:count])
298
+ def deserialize_response(response, previous_response = nil)
299
+ current_response = previous_response || Response.new
300
+ current_response.count += response[:count]
296
301
 
297
- result.entities = response[:member].map do |item|
302
+ current_response.entities += response[:member].map do |item|
298
303
  deserialize_item(item)
299
304
  end if response[:member]
300
305
 
301
- result
306
+ current_response.last_evaluated_key = response[:last_evaluated_key]
307
+ current_response
302
308
  end
303
309
 
304
310
  # Deserialize item from DynamoDB response.
@@ -84,19 +84,6 @@ module Lotus
84
84
  ).first
85
85
  end
86
86
 
87
- # Deletes all the records from the table.
88
- #
89
- # @see Lotus::Model::Adapters::Dynamodb::Collection#scan
90
- # @see Lotus::Model::Mapping::Collection
91
- #
92
- # @api private
93
- # @since 0.1.0
94
- def clear
95
- @collection.deserialize(@dataset.scan.entities).each do |entity|
96
- delete(entity)
97
- end
98
- end
99
-
100
87
  private
101
88
  # Serialize the given entity before to persist in the database.
102
89
  #
@@ -41,7 +41,7 @@ module Lotus
41
41
  include Enumerable
42
42
  extend Forwardable
43
43
 
44
- def_delegators :all, :each, :to_s, :empty?
44
+ def_delegators :all, :to_s, :empty?
45
45
 
46
46
  # @attr_reader operation [Symbol] operation to perform
47
47
  #
@@ -81,7 +81,36 @@ module Lotus
81
81
  #
82
82
  # @since 0.1.0
83
83
  def all
84
- @collection.deserialize(run.entities)
84
+ response = run
85
+ while !@options[:limit] && response.last_evaluated_key
86
+ @options[:exclusive_start_key] = response.last_evaluated_key
87
+ response = run(response)
88
+ end
89
+
90
+ @collection.deserialize(response.entities)
91
+ end
92
+
93
+ # Iterates over fetched records.
94
+ #
95
+ # @return [Integer] total count of records
96
+ #
97
+ # @since 0.1.1
98
+ def each
99
+ response = run
100
+ entities = @collection.deserialize(response.entities)
101
+ entities.each { |x| yield(x) }
102
+
103
+ while !@options[:limit] && response.last_evaluated_key
104
+ response.entities = []
105
+
106
+ @options[:exclusive_start_key] = response.last_evaluated_key
107
+ response = run(response)
108
+
109
+ entities = @collection.deserialize(response.entities)
110
+ entities.each { |x| yield(x) }
111
+ end
112
+
113
+ response.count
85
114
  end
86
115
 
87
116
  # Set operation to be query instead of scan.
@@ -443,7 +472,14 @@ module Lotus
443
472
  @options[:select] = "COUNT"
444
473
  @options.delete(:attributes_to_get)
445
474
 
446
- run.count
475
+ response = run
476
+
477
+ while !@options[:limit] && response.last_evaluated_key
478
+ @options[:exclusive_start_key] = response.last_evaluated_key
479
+ response = run(response)
480
+ end
481
+
482
+ response.count
447
483
  end
448
484
 
449
485
  # This method is not implemented.
@@ -545,12 +581,14 @@ module Lotus
545
581
 
546
582
  # Apply all the options and return a filtered collection.
547
583
  #
584
+ # @param previous_response [Response] deserialized response from a previous operation
585
+ #
548
586
  # @return [Array]
549
587
  #
550
588
  # @api private
551
589
  # @since 0.1.0
552
- def run
553
- @dataset.public_send(operation, @options)
590
+ def run(previous_response = nil)
591
+ @dataset.public_send(operation, @options, previous_response)
554
592
  end
555
593
  end
556
594
  end
@@ -88,7 +88,8 @@ module Lotus
88
88
  # @api private
89
89
  # @since 0.1.0
90
90
  def clear(collection)
91
- command(collection).clear
91
+ blk = Proc.new {}
92
+ query(collection, blk).each { |entity| delete(collection, entity) }
92
93
  end
93
94
 
94
95
  # Returns an unique record from the given collection, with the given
@@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
17
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
18
  spec.require_paths = ['lib']
19
19
 
20
- spec.add_runtime_dependency 'lotus-model', '~> 0.1'
20
+ spec.add_runtime_dependency 'lotus-model', '~> 0.1', '>= 0.1.1'
21
21
  spec.add_runtime_dependency 'aws-sdk', '~> 1.0'
22
22
  spec.add_runtime_dependency 'multi_json', '~> 1.10'
23
23
 
@@ -10,8 +10,8 @@ begin
10
10
  { attribute_name: "id", key_type: "HASH" },
11
11
  ],
12
12
  provisioned_throughput: {
13
- read_capacity_units: 10,
14
- write_capacity_units: 10,
13
+ read_capacity_units: 50,
14
+ write_capacity_units: 50,
15
15
  },
16
16
  )
17
17
 
@@ -26,8 +26,8 @@ begin
26
26
  { attribute_name: "created_at", key_type: "RANGE" },
27
27
  ],
28
28
  provisioned_throughput: {
29
- read_capacity_units: 10,
30
- write_capacity_units: 10,
29
+ read_capacity_units: 50,
30
+ write_capacity_units: 50,
31
31
  },
32
32
  )
33
33
 
@@ -62,13 +62,13 @@ begin
62
62
  projection_type: "ALL",
63
63
  },
64
64
  provisioned_throughput: {
65
- read_capacity_units: 10,
66
- write_capacity_units: 10,
65
+ read_capacity_units: 50,
66
+ write_capacity_units: 50,
67
67
  },
68
68
  }],
69
69
  provisioned_throughput: {
70
- read_capacity_units: 10,
71
- write_capacity_units: 10,
70
+ read_capacity_units: 50,
71
+ write_capacity_units: 50,
72
72
  },
73
73
  )
74
74
  rescue AWS::DynamoDB::Errors::ResourceInUseException
@@ -2,7 +2,7 @@ require 'test_helper'
2
2
 
3
3
  describe Lotus::Model::Adapters::Dynamodb::Query do
4
4
  before do
5
- MockResponse = Struct.new(:entities)
5
+ MockResponse = Struct.new(:entities, :last_evaluated_key)
6
6
 
7
7
  class MockDataset
8
8
  include AWS::DynamoDB::Types
@@ -15,11 +15,11 @@ describe Lotus::Model::Adapters::Dynamodb::Query do
15
15
  @records = MockResponse.new(entities)
16
16
  end
17
17
 
18
- def query(options = {})
18
+ def query(options = {}, previous_response = nil)
19
19
  records
20
20
  end
21
21
 
22
- def scan(options = {})
22
+ def scan(options = {}, previous_response = nil)
23
23
  records
24
24
  end
25
25
 
@@ -59,18 +59,6 @@ describe Lotus::Model::Adapters::DynamodbAdapter do
59
59
 
60
60
  let(:collection) { :test_users }
61
61
 
62
- describe '#first' do
63
- it 'raises an error' do
64
- -> { @adapter.first(collection) }.must_raise NotImplementedError
65
- end
66
- end
67
-
68
- describe '#last' do
69
- it 'raises an error' do
70
- -> { @adapter.last(collection) }.must_raise NotImplementedError
71
- end
72
- end
73
-
74
62
  describe 'multiple collections' do
75
63
  it 'create records' do
76
64
  user = TestUser.new
@@ -87,6 +75,18 @@ describe Lotus::Model::Adapters::DynamodbAdapter do
87
75
  end
88
76
  end
89
77
 
78
+ describe '#first' do
79
+ it 'raises an error' do
80
+ -> { @adapter.first(collection) }.must_raise NotImplementedError
81
+ end
82
+ end
83
+
84
+ describe '#last' do
85
+ it 'raises an error' do
86
+ -> { @adapter.last(collection) }.must_raise NotImplementedError
87
+ end
88
+ end
89
+
90
90
  describe '#persist' do
91
91
  describe 'when the given entity is not persisted' do
92
92
  let(:entity) { TestUser.new }
@@ -179,6 +179,64 @@ describe Lotus::Model::Adapters::DynamodbAdapter do
179
179
  @adapter.all(collection).must_equal [entity]
180
180
  end
181
181
  end
182
+
183
+ describe 'when large records set is persisted' do
184
+ before do
185
+ entities.each do |entity|
186
+ @adapter.create(collection, entity)
187
+ end
188
+ end
189
+
190
+ let(:entities) { 25.times.map { TestUser.new(name: 'A'*50_000) } }
191
+
192
+ it 'returns all of them' do
193
+ @adapter.all(collection).count.must_equal entities.count
194
+ end
195
+ end
196
+ end
197
+
198
+ describe '#each' do
199
+ describe 'when no records are persisted' do
200
+ it 'returns an empty collection' do
201
+ query = Proc.new {}
202
+ counter = 0
203
+ @adapter.query(collection, &query).each { |x| counter += 1 }
204
+ counter.must_equal 0
205
+ end
206
+ end
207
+
208
+ describe 'when some records are persisted' do
209
+ before do
210
+ @adapter.create(collection, entity)
211
+ end
212
+
213
+ let(:entity) { TestUser.new }
214
+
215
+ it 'returns all of them' do
216
+ query = Proc.new {}
217
+ counter = 0
218
+ @adapter.query(collection, &query).each { |x| counter += 1 }
219
+ counter.must_equal 1
220
+ end
221
+ end
222
+
223
+ describe 'when large records set is persisted' do
224
+ before do
225
+ entities.each do |entity|
226
+ @adapter.create(collection, entity)
227
+ end
228
+ end
229
+
230
+ let(:entities) { 25.times.map { TestUser.new(name: 'A'*50_000) } }
231
+
232
+ it 'returns all of them' do
233
+ query = Proc.new {}
234
+ counter = 0
235
+ count = @adapter.query(collection, &query).each { |x| counter += 1 }
236
+ counter.must_equal entities.count
237
+ count.must_equal entities.count
238
+ end
239
+ end
182
240
  end
183
241
 
184
242
  describe '#find' do
@@ -866,6 +924,33 @@ describe Lotus::Model::Adapters::DynamodbAdapter do
866
924
  result.must_equal 2
867
925
  end
868
926
  end
927
+
928
+ describe 'with large records set' do
929
+ before do
930
+ purchases.each do |entity|
931
+ @adapter.create(collection, entity)
932
+ end
933
+ end
934
+
935
+ let(:purchases) do
936
+ 25.times.map do |i|
937
+ TestPurchase.new(
938
+ region: 'europe',
939
+ content: ('A'..'Z').to_a[i]*50_000,
940
+ created_at: Time.new,
941
+ )
942
+ end
943
+ end
944
+
945
+ it 'returns all of them' do
946
+ query = Proc.new {
947
+ where(region: 'europe')
948
+ }
949
+
950
+ result = @adapter.query(collection, &query).count
951
+ result.must_equal purchases.count
952
+ end
953
+ end
869
954
  end
870
955
 
871
956
  describe 'consistent' do
@@ -22,6 +22,8 @@ require 'lotus-dynamodb'
22
22
 
23
23
  if ENV['AWS']
24
24
  AWS.config(
25
+ # logger: Logger.new($stdout),
26
+ # log_level: :debug,
25
27
  access_key_id: ENV['AWS_KEY'],
26
28
  secret_access_key: ENV['AWS_SECRET'],
27
29
  )
@@ -2,6 +2,6 @@ require 'test_helper'
2
2
 
3
3
  describe Lotus::Dynamodb::VERSION do
4
4
  it 'returns current version' do
5
- Lotus::Dynamodb::VERSION.must_equal '0.1.0'
5
+ Lotus::Dynamodb::VERSION.must_equal '0.1.1'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lotus-dynamodb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dmitry Krasnoukhov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-20 00:00:00.000000000 Z
11
+ date: 2014-06-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: lotus-model
@@ -17,6 +17,9 @@ dependencies:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0.1'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 0.1.1
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -24,6 +27,9 @@ dependencies:
24
27
  - - "~>"
25
28
  - !ruby/object:Gem::Version
26
29
  version: '0.1'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 0.1.1
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: aws-sdk
29
35
  requirement: !ruby/object:Gem::Requirement
@@ -146,6 +152,7 @@ files:
146
152
  - ".gitignore"
147
153
  - ".travis.yml"
148
154
  - ".yardopts"
155
+ - CHANGELOG.md
149
156
  - Gemfile
150
157
  - LICENSE.md
151
158
  - Procfile