dynamoid 0.6.1 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.travis.yml +4 -0
- data/Gemfile +3 -2
- data/Gemfile.lock +40 -45
- data/README.markdown +55 -25
- data/Rakefile +31 -0
- data/VERSION +1 -1
- data/doc/Dynamoid.html +58 -42
- data/doc/Dynamoid/Adapter.html +666 -179
- data/doc/Dynamoid/Adapter/AwsSdk.html +752 -236
- data/doc/Dynamoid/Associations.html +28 -21
- data/doc/Dynamoid/Associations/Association.html +102 -49
- data/doc/Dynamoid/Associations/BelongsTo.html +28 -25
- data/doc/Dynamoid/Associations/ClassMethods.html +95 -52
- data/doc/Dynamoid/Associations/HasAndBelongsToMany.html +28 -25
- data/doc/Dynamoid/Associations/HasMany.html +28 -25
- data/doc/Dynamoid/Associations/HasOne.html +28 -25
- data/doc/Dynamoid/Associations/ManyAssociation.html +138 -94
- data/doc/Dynamoid/Associations/SingleAssociation.html +67 -38
- data/doc/Dynamoid/Components.html +60 -22
- data/doc/Dynamoid/Config.html +61 -44
- data/doc/Dynamoid/Config/Options.html +90 -61
- data/doc/Dynamoid/Criteria.html +28 -21
- data/doc/Dynamoid/Criteria/Chain.html +508 -100
- data/doc/Dynamoid/Criteria/ClassMethods.html +26 -19
- data/doc/Dynamoid/Dirty.html +424 -0
- data/doc/Dynamoid/Dirty/ClassMethods.html +174 -0
- data/doc/Dynamoid/Document.html +451 -84
- data/doc/Dynamoid/Document/ClassMethods.html +281 -102
- data/doc/Dynamoid/Errors.html +29 -22
- data/doc/Dynamoid/Errors/ConditionalCheckFailedException.html +141 -0
- data/doc/Dynamoid/Errors/DocumentNotValid.html +36 -25
- data/doc/Dynamoid/Errors/Error.html +27 -20
- data/doc/Dynamoid/Errors/InvalidField.html +27 -19
- data/doc/Dynamoid/Errors/InvalidQuery.html +131 -0
- data/doc/Dynamoid/Errors/MissingRangeKey.html +27 -19
- data/doc/Dynamoid/Fields.html +94 -77
- data/doc/Dynamoid/Fields/ClassMethods.html +166 -37
- data/doc/Dynamoid/Finders.html +28 -21
- data/doc/Dynamoid/Finders/ClassMethods.html +505 -78
- data/doc/Dynamoid/IdentityMap.html +492 -0
- data/doc/Dynamoid/IdentityMap/ClassMethods.html +534 -0
- data/doc/Dynamoid/Indexes.html +41 -28
- data/doc/Dynamoid/Indexes/ClassMethods.html +45 -29
- data/doc/Dynamoid/Indexes/Index.html +100 -62
- data/doc/Dynamoid/Middleware.html +115 -0
- data/doc/Dynamoid/Middleware/IdentityMap.html +264 -0
- data/doc/Dynamoid/Persistence.html +326 -85
- data/doc/Dynamoid/Persistence/ClassMethods.html +275 -109
- data/doc/Dynamoid/Validations.html +47 -31
- data/doc/_index.html +116 -71
- data/doc/class_list.html +13 -7
- data/doc/css/full_list.css +4 -2
- data/doc/css/style.css +60 -44
- data/doc/file.LICENSE.html +26 -19
- data/doc/file.README.html +152 -48
- data/doc/file_list.html +14 -8
- data/doc/frames.html +20 -5
- data/doc/index.html +152 -48
- data/doc/js/app.js +52 -43
- data/doc/js/full_list.js +14 -9
- data/doc/js/jquery.js +4 -16
- data/doc/method_list.html +446 -540
- data/doc/top-level-namespace.html +27 -20
- data/{Dynamoid.gemspec → dynamoid.gemspec} +21 -8
- data/lib/dynamoid/adapter.rb +11 -10
- data/lib/dynamoid/adapter/aws_sdk.rb +40 -19
- data/lib/dynamoid/components.rb +2 -1
- data/lib/dynamoid/criteria/chain.rb +29 -11
- data/lib/dynamoid/dirty.rb +6 -0
- data/lib/dynamoid/document.rb +34 -19
- data/lib/dynamoid/fields.rb +36 -30
- data/lib/dynamoid/finders.rb +7 -5
- data/lib/dynamoid/persistence.rb +37 -10
- data/spec/app/models/address.rb +2 -0
- data/spec/app/models/camel_case.rb +10 -0
- data/spec/app/models/car.rb +6 -0
- data/spec/app/models/nuclear_submarine.rb +5 -0
- data/spec/app/models/subscription.rb +2 -2
- data/spec/app/models/vehicle.rb +7 -0
- data/spec/dynamoid/adapter/aws_sdk_spec.rb +20 -11
- data/spec/dynamoid/adapter_spec.rb +67 -82
- data/spec/dynamoid/associations/association_spec.rb +30 -30
- data/spec/dynamoid/criteria/chain_spec.rb +56 -9
- data/spec/dynamoid/criteria_spec.rb +3 -0
- data/spec/dynamoid/dirty_spec.rb +8 -0
- data/spec/dynamoid/document_spec.rb +109 -47
- data/spec/dynamoid/fields_spec.rb +32 -3
- data/spec/dynamoid/finders_spec.rb +12 -0
- data/spec/dynamoid/persistence_spec.rb +73 -8
- data/spec/spec_helper.rb +1 -0
- data/spec/support/with_partitioning.rb +15 -0
- metadata +22 -9
|
@@ -6,19 +6,21 @@
|
|
|
6
6
|
<title>
|
|
7
7
|
Top Level Namespace
|
|
8
8
|
|
|
9
|
-
— Documentation by YARD 0.
|
|
9
|
+
— Documentation by YARD 0.8.6.1
|
|
10
10
|
|
|
11
11
|
</title>
|
|
12
12
|
|
|
13
|
-
<link rel="stylesheet" href="css/style.css" type="text/css"
|
|
13
|
+
<link rel="stylesheet" href="css/style.css" type="text/css" charset="utf-8" />
|
|
14
14
|
|
|
15
|
-
<link rel="stylesheet" href="css/common.css" type="text/css"
|
|
15
|
+
<link rel="stylesheet" href="css/common.css" type="text/css" charset="utf-8" />
|
|
16
16
|
|
|
17
17
|
<script type="text/javascript" charset="utf-8">
|
|
18
|
+
hasFrames = window.top.frames.main ? true : false;
|
|
18
19
|
relpath = '';
|
|
19
|
-
|
|
20
|
+
framesUrl = "frames.html#!" + escape(window.location.href);
|
|
20
21
|
</script>
|
|
21
22
|
|
|
23
|
+
|
|
22
24
|
<script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
|
|
23
25
|
|
|
24
26
|
<script type="text/javascript" charset="utf-8" src="js/app.js"></script>
|
|
@@ -26,36 +28,41 @@
|
|
|
26
28
|
|
|
27
29
|
</head>
|
|
28
30
|
<body>
|
|
29
|
-
<script type="text/javascript" charset="utf-8">
|
|
30
|
-
if (window.top.frames.main) document.body.className = 'frames';
|
|
31
|
-
</script>
|
|
32
|
-
|
|
33
31
|
<div id="header">
|
|
34
32
|
<div id="menu">
|
|
35
33
|
|
|
36
|
-
<a href="_index.html">Index</a> »
|
|
34
|
+
<a href="_index.html">Index</a> »
|
|
37
35
|
|
|
38
36
|
|
|
39
37
|
<span class="title">Top Level Namespace</span>
|
|
40
38
|
|
|
41
|
-
|
|
39
|
+
|
|
42
40
|
<div class="noframes"><span class="title">(</span><a href="." target="_top">no frames</a><span class="title">)</span></div>
|
|
43
41
|
</div>
|
|
44
42
|
|
|
45
43
|
<div id="search">
|
|
46
44
|
|
|
47
|
-
<a
|
|
45
|
+
<a class="full_list_link" id="class_list_link"
|
|
46
|
+
href="class_list.html">
|
|
47
|
+
Class List
|
|
48
|
+
</a>
|
|
48
49
|
|
|
49
|
-
<a
|
|
50
|
+
<a class="full_list_link" id="method_list_link"
|
|
51
|
+
href="method_list.html">
|
|
52
|
+
Method List
|
|
53
|
+
</a>
|
|
50
54
|
|
|
51
|
-
<a
|
|
55
|
+
<a class="full_list_link" id="file_list_link"
|
|
56
|
+
href="file_list.html">
|
|
57
|
+
File List
|
|
58
|
+
</a>
|
|
52
59
|
|
|
53
60
|
</div>
|
|
54
61
|
<div class="clear"></div>
|
|
55
62
|
</div>
|
|
56
|
-
|
|
63
|
+
|
|
57
64
|
<iframe id="search_frame"></iframe>
|
|
58
|
-
|
|
65
|
+
|
|
59
66
|
<div id="content"><h1>Top Level Namespace
|
|
60
67
|
|
|
61
68
|
|
|
@@ -76,11 +83,11 @@
|
|
|
76
83
|
|
|
77
84
|
<h2>Defined Under Namespace</h2>
|
|
78
85
|
<p class="children">
|
|
79
|
-
|
|
86
|
+
|
|
80
87
|
|
|
81
88
|
<strong class="modules">Modules:</strong> <span class='object_link'><a href="Dynamoid.html" title="Dynamoid (module)">Dynamoid</a></span>
|
|
82
89
|
|
|
83
|
-
|
|
90
|
+
|
|
84
91
|
|
|
85
92
|
|
|
86
93
|
</p>
|
|
@@ -94,11 +101,11 @@
|
|
|
94
101
|
|
|
95
102
|
|
|
96
103
|
</div>
|
|
97
|
-
|
|
104
|
+
|
|
98
105
|
<div id="footer">
|
|
99
|
-
Generated on Thu
|
|
106
|
+
Generated on Thu Jun 27 21:59:09 2013 by
|
|
100
107
|
<a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
|
|
101
|
-
0.
|
|
108
|
+
0.8.6.1 (ruby-1.9.3).
|
|
102
109
|
</div>
|
|
103
110
|
|
|
104
111
|
</body>
|
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
|
|
6
6
|
Gem::Specification.new do |s|
|
|
7
7
|
s.name = "dynamoid"
|
|
8
|
-
s.version = "0.
|
|
8
|
+
s.version = "0.7.0"
|
|
9
9
|
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
11
11
|
s.authors = ["Josh Symonds"]
|
|
12
|
-
s.date = "2013-
|
|
12
|
+
s.date = "2013-06-28"
|
|
13
13
|
s.description = "Dynamoid is an ORM for Amazon's DynamoDB that supports offline development, associations, querying, and everything else you'd expect from an ActiveRecord-style replacement."
|
|
14
14
|
s.email = "josh@joshsymonds.com"
|
|
15
15
|
s.extra_rdoc_files = [
|
|
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
|
|
|
19
19
|
s.files = [
|
|
20
20
|
".document",
|
|
21
21
|
".rspec",
|
|
22
|
-
"
|
|
22
|
+
".travis.yml",
|
|
23
23
|
"Gemfile",
|
|
24
24
|
"Gemfile.lock",
|
|
25
25
|
"LICENSE.txt",
|
|
@@ -46,20 +46,28 @@ Gem::Specification.new do |s|
|
|
|
46
46
|
"doc/Dynamoid/Criteria.html",
|
|
47
47
|
"doc/Dynamoid/Criteria/Chain.html",
|
|
48
48
|
"doc/Dynamoid/Criteria/ClassMethods.html",
|
|
49
|
+
"doc/Dynamoid/Dirty.html",
|
|
50
|
+
"doc/Dynamoid/Dirty/ClassMethods.html",
|
|
49
51
|
"doc/Dynamoid/Document.html",
|
|
50
52
|
"doc/Dynamoid/Document/ClassMethods.html",
|
|
51
53
|
"doc/Dynamoid/Errors.html",
|
|
54
|
+
"doc/Dynamoid/Errors/ConditionalCheckFailedException.html",
|
|
52
55
|
"doc/Dynamoid/Errors/DocumentNotValid.html",
|
|
53
56
|
"doc/Dynamoid/Errors/Error.html",
|
|
54
57
|
"doc/Dynamoid/Errors/InvalidField.html",
|
|
58
|
+
"doc/Dynamoid/Errors/InvalidQuery.html",
|
|
55
59
|
"doc/Dynamoid/Errors/MissingRangeKey.html",
|
|
56
60
|
"doc/Dynamoid/Fields.html",
|
|
57
61
|
"doc/Dynamoid/Fields/ClassMethods.html",
|
|
58
62
|
"doc/Dynamoid/Finders.html",
|
|
59
63
|
"doc/Dynamoid/Finders/ClassMethods.html",
|
|
64
|
+
"doc/Dynamoid/IdentityMap.html",
|
|
65
|
+
"doc/Dynamoid/IdentityMap/ClassMethods.html",
|
|
60
66
|
"doc/Dynamoid/Indexes.html",
|
|
61
67
|
"doc/Dynamoid/Indexes/ClassMethods.html",
|
|
62
68
|
"doc/Dynamoid/Indexes/Index.html",
|
|
69
|
+
"doc/Dynamoid/Middleware.html",
|
|
70
|
+
"doc/Dynamoid/Middleware/IdentityMap.html",
|
|
63
71
|
"doc/Dynamoid/Persistence.html",
|
|
64
72
|
"doc/Dynamoid/Persistence/ClassMethods.html",
|
|
65
73
|
"doc/Dynamoid/Validations.html",
|
|
@@ -78,6 +86,7 @@ Gem::Specification.new do |s|
|
|
|
78
86
|
"doc/js/jquery.js",
|
|
79
87
|
"doc/method_list.html",
|
|
80
88
|
"doc/top-level-namespace.html",
|
|
89
|
+
"dynamoid.gemspec",
|
|
81
90
|
"lib/dynamoid.rb",
|
|
82
91
|
"lib/dynamoid/adapter.rb",
|
|
83
92
|
"lib/dynamoid/adapter/aws_sdk.rb",
|
|
@@ -107,12 +116,15 @@ Gem::Specification.new do |s|
|
|
|
107
116
|
"lib/dynamoid/validations.rb",
|
|
108
117
|
"spec/app/models/address.rb",
|
|
109
118
|
"spec/app/models/camel_case.rb",
|
|
119
|
+
"spec/app/models/car.rb",
|
|
110
120
|
"spec/app/models/magazine.rb",
|
|
111
121
|
"spec/app/models/message.rb",
|
|
122
|
+
"spec/app/models/nuclear_submarine.rb",
|
|
112
123
|
"spec/app/models/sponsor.rb",
|
|
113
124
|
"spec/app/models/subscription.rb",
|
|
114
125
|
"spec/app/models/tweet.rb",
|
|
115
126
|
"spec/app/models/user.rb",
|
|
127
|
+
"spec/app/models/vehicle.rb",
|
|
116
128
|
"spec/dynamoid/adapter/aws_sdk_spec.rb",
|
|
117
129
|
"spec/dynamoid/adapter_spec.rb",
|
|
118
130
|
"spec/dynamoid/associations/association_spec.rb",
|
|
@@ -134,12 +146,13 @@ Gem::Specification.new do |s|
|
|
|
134
146
|
"spec/dynamoid/persistence_spec.rb",
|
|
135
147
|
"spec/dynamoid/validations_spec.rb",
|
|
136
148
|
"spec/dynamoid_spec.rb",
|
|
137
|
-
"spec/spec_helper.rb"
|
|
149
|
+
"spec/spec_helper.rb",
|
|
150
|
+
"spec/support/with_partitioning.rb"
|
|
138
151
|
]
|
|
139
152
|
s.homepage = "http://github.com/Veraticus/Dynamoid"
|
|
140
153
|
s.licenses = ["MIT"]
|
|
141
154
|
s.require_paths = ["lib"]
|
|
142
|
-
s.rubygems_version = "1.8.
|
|
155
|
+
s.rubygems_version = "1.8.25"
|
|
143
156
|
s.summary = "Dynamoid is an ORM for Amazon's DynamoDB"
|
|
144
157
|
|
|
145
158
|
if s.respond_to? :specification_version then
|
|
@@ -157,7 +170,7 @@ Gem::Specification.new do |s|
|
|
|
157
170
|
s.add_development_dependency(%q<redcarpet>, ["= 1.17.2"])
|
|
158
171
|
s.add_development_dependency(%q<github-markup>, [">= 0"])
|
|
159
172
|
s.add_development_dependency(%q<pry>, [">= 0"])
|
|
160
|
-
s.add_development_dependency(%q<fake_dynamo>, ["
|
|
173
|
+
s.add_development_dependency(%q<fake_dynamo>, ["~> 0.1.3"])
|
|
161
174
|
s.add_development_dependency(%q<mocha>, ["= 0.10.0"])
|
|
162
175
|
else
|
|
163
176
|
s.add_dependency(%q<activemodel>, [">= 0"])
|
|
@@ -171,7 +184,7 @@ Gem::Specification.new do |s|
|
|
|
171
184
|
s.add_dependency(%q<redcarpet>, ["= 1.17.2"])
|
|
172
185
|
s.add_dependency(%q<github-markup>, [">= 0"])
|
|
173
186
|
s.add_dependency(%q<pry>, [">= 0"])
|
|
174
|
-
s.add_dependency(%q<fake_dynamo>, ["
|
|
187
|
+
s.add_dependency(%q<fake_dynamo>, ["~> 0.1.3"])
|
|
175
188
|
s.add_dependency(%q<mocha>, ["= 0.10.0"])
|
|
176
189
|
end
|
|
177
190
|
else
|
|
@@ -186,7 +199,7 @@ Gem::Specification.new do |s|
|
|
|
186
199
|
s.add_dependency(%q<redcarpet>, ["= 1.17.2"])
|
|
187
200
|
s.add_dependency(%q<github-markup>, [">= 0"])
|
|
188
201
|
s.add_dependency(%q<pry>, [">= 0"])
|
|
189
|
-
s.add_dependency(%q<fake_dynamo>, ["
|
|
202
|
+
s.add_dependency(%q<fake_dynamo>, ["~> 0.1.3"])
|
|
190
203
|
s.add_dependency(%q<mocha>, ["= 0.10.0"])
|
|
191
204
|
end
|
|
192
205
|
end
|
data/lib/dynamoid/adapter.rb
CHANGED
|
@@ -65,25 +65,28 @@ module Dynamoid
|
|
|
65
65
|
#
|
|
66
66
|
# @param [String] table the name of the table to write the object to
|
|
67
67
|
# @param [Array] ids to fetch, can also be a string of just one id
|
|
68
|
-
# @param [
|
|
68
|
+
# @param [Hash] options: Passed to the underlying query. The :range_key option is required whenever the table has a range key,
|
|
69
|
+
# unless multiple ids are passed in and Dynamoid::Config.partitioning? is turned off.
|
|
69
70
|
#
|
|
70
71
|
# @since 0.2.0
|
|
71
72
|
def read(table, ids, options = {})
|
|
72
|
-
range_key = options
|
|
73
|
+
range_key = options.delete(:range_key)
|
|
74
|
+
|
|
73
75
|
if ids.respond_to?(:each)
|
|
74
76
|
ids = ids.collect{|id| range_key ? [id, range_key] : id}
|
|
75
77
|
if Dynamoid::Config.partitioning?
|
|
76
|
-
results = batch_get_item(table => id_with_partitions(ids))
|
|
78
|
+
results = batch_get_item({table => id_with_partitions(ids)}, options)
|
|
77
79
|
{table => result_for_partition(results[table],table)}
|
|
78
80
|
else
|
|
79
|
-
batch_get_item(table => ids)
|
|
81
|
+
batch_get_item({table => ids}, options)
|
|
80
82
|
end
|
|
81
83
|
else
|
|
82
84
|
if Dynamoid::Config.partitioning?
|
|
83
85
|
ids = range_key ? [[ids, range_key]] : ids
|
|
84
|
-
results = batch_get_item(table => id_with_partitions(ids))
|
|
86
|
+
results = batch_get_item({table => id_with_partitions(ids)}, options)
|
|
85
87
|
result_for_partition(results[table],table).first
|
|
86
88
|
else
|
|
89
|
+
options[:range_key] = range_key if range_key
|
|
87
90
|
get_item(table, ids, options)
|
|
88
91
|
end
|
|
89
92
|
end
|
|
@@ -185,7 +188,7 @@ module Dynamoid
|
|
|
185
188
|
range_key_name = table.range_key.name.to_sym
|
|
186
189
|
|
|
187
190
|
final_hash = {}
|
|
188
|
-
|
|
191
|
+
|
|
189
192
|
results.each do |record|
|
|
190
193
|
test_record = final_hash[record[range_key_name]]
|
|
191
194
|
|
|
@@ -254,11 +257,9 @@ module Dynamoid
|
|
|
254
257
|
modified_options[:hash_value] = id
|
|
255
258
|
|
|
256
259
|
query_result = Dynamoid::Adapter::AwsSdk.query(table_name, modified_options)
|
|
257
|
-
query_result
|
|
258
|
-
|
|
259
|
-
results = results + query_result unless query_result.nil?
|
|
260
|
+
results += query_result.inject([]){|array, result| array += [result]} if query_result.any?
|
|
260
261
|
end
|
|
261
|
-
|
|
262
|
+
|
|
262
263
|
result_for_partition results, table_name
|
|
263
264
|
end
|
|
264
265
|
end
|
|
@@ -53,20 +53,21 @@ module Dynamoid
|
|
|
53
53
|
# Get many items at once from DynamoDB. More efficient than getting each item individually.
|
|
54
54
|
#
|
|
55
55
|
# @example Retrieve IDs 1 and 2 from the table testtable
|
|
56
|
-
# Dynamoid::Adapter::AwsSdk.batch_get_item('table1' => ['1', '2'])
|
|
56
|
+
# Dynamoid::Adapter::AwsSdk.batch_get_item({'table1' => ['1', '2']}, :consistent_read => true)
|
|
57
57
|
#
|
|
58
|
-
# @param [Hash]
|
|
58
|
+
# @param [Hash] table_ids the hash of tables and IDs to retrieve
|
|
59
|
+
# @param [Hash] options to be passed to underlying BatchGet call
|
|
59
60
|
#
|
|
60
61
|
# @return [Hash] a hash where keys are the table names and the values are the retrieved items
|
|
61
62
|
#
|
|
62
63
|
# @since 0.2.0
|
|
63
|
-
def batch_get_item(options)
|
|
64
|
+
def batch_get_item(table_ids, options = {})
|
|
64
65
|
hash = Hash.new{|h, k| h[k] = []}
|
|
65
|
-
return hash if
|
|
66
|
-
|
|
66
|
+
return hash if table_ids.all?{|k, v| v.empty?}
|
|
67
|
+
table_ids.each do |t, ids|
|
|
67
68
|
Array(ids).in_groups_of(100, false) do |group|
|
|
68
69
|
batch = AWS::DynamoDB::BatchGet.new(:config => @@connection.config)
|
|
69
|
-
batch.table(t, :all, Array(group)) unless group.nil? || group.empty?
|
|
70
|
+
batch.table(t, :all, Array(group), options) unless group.nil? || group.empty?
|
|
70
71
|
batch.each do |table_name, attributes|
|
|
71
72
|
hash[table_name] << attributes.symbolize_keys!
|
|
72
73
|
end
|
|
@@ -196,6 +197,8 @@ module Dynamoid
|
|
|
196
197
|
object.delete_if{|k, v| v.nil? || (v.respond_to?(:empty?) && v.empty?)},
|
|
197
198
|
options || {}
|
|
198
199
|
)
|
|
200
|
+
rescue AWS::DynamoDB::Errors::ConditionalCheckFailedException => e
|
|
201
|
+
raise Dynamoid::Errors::ConditionalCheckFailedException
|
|
199
202
|
end
|
|
200
203
|
|
|
201
204
|
# Query the DynamoDB table. This employs DynamoDB's indexes so is generally faster than scanning, but is
|
|
@@ -211,19 +214,25 @@ module Dynamoid
|
|
|
211
214
|
# @option opts [Number] :range_gte find range keys greater than or equal to this
|
|
212
215
|
# @option opts [Number] :range_lte find range keys less than or equal to this
|
|
213
216
|
#
|
|
214
|
-
# @return [
|
|
217
|
+
# @return [Enumerator] an iterator of all matching items
|
|
215
218
|
#
|
|
216
219
|
# @since 0.2.0
|
|
217
220
|
def query(table_name, opts = {})
|
|
218
221
|
table = get_table(table_name)
|
|
219
222
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
223
|
+
Enumerator.new do |yielder|
|
|
224
|
+
consistent_opts = { :consistent_read => opts[:consistent_read] || false }
|
|
225
|
+
if table.composite_key?
|
|
226
|
+
table.items.query(opts).each do |data|
|
|
227
|
+
if opts.has_key? :select
|
|
228
|
+
yielder.yield data.attributes.symbolize_keys!
|
|
229
|
+
else
|
|
230
|
+
yielder.yield data.attributes.to_h(consistent_opts).symbolize_keys!
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
else
|
|
234
|
+
yielder.yield get_item(table_name, opts[:hash_value])
|
|
235
|
+
end
|
|
227
236
|
end
|
|
228
237
|
end
|
|
229
238
|
|
|
@@ -233,16 +242,16 @@ module Dynamoid
|
|
|
233
242
|
# @param [String] table_name the name of the table
|
|
234
243
|
# @param [Hash] scan_hash a hash of attributes: matching records will be returned by the scan
|
|
235
244
|
#
|
|
236
|
-
# @return [
|
|
245
|
+
# @return [Enumerator] an iterator of all matching items
|
|
237
246
|
#
|
|
238
247
|
# @since 0.2.0
|
|
239
248
|
def scan(table_name, scan_hash, select_opts)
|
|
240
249
|
table = get_table(table_name)
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
250
|
+
Enumerator.new do |yielder|
|
|
251
|
+
table.items.where(scan_hash).select(select_opts).each do |data|
|
|
252
|
+
yielder.yield data.attributes.symbolize_keys!
|
|
253
|
+
end
|
|
244
254
|
end
|
|
245
|
-
results
|
|
246
255
|
end
|
|
247
256
|
|
|
248
257
|
# @todo Add an UpdateItem method.
|
|
@@ -261,6 +270,18 @@ module Dynamoid
|
|
|
261
270
|
def table_cache
|
|
262
271
|
@table_cache ||= {}
|
|
263
272
|
end
|
|
273
|
+
|
|
274
|
+
# Number of items from a table
|
|
275
|
+
#
|
|
276
|
+
# @param [String] table_name the name of the table
|
|
277
|
+
#
|
|
278
|
+
# @return [Integer] the number of items from a table
|
|
279
|
+
#
|
|
280
|
+
# @since 0.6.1
|
|
281
|
+
def count(table_name)
|
|
282
|
+
table = get_table(table_name)
|
|
283
|
+
table.items.count
|
|
284
|
+
end
|
|
264
285
|
end
|
|
265
286
|
end
|
|
266
287
|
end
|
data/lib/dynamoid/components.rb
CHANGED
|
@@ -10,10 +10,11 @@ module Dynamoid
|
|
|
10
10
|
extend ActiveModel::Translation
|
|
11
11
|
extend ActiveModel::Callbacks
|
|
12
12
|
|
|
13
|
-
define_model_callbacks :create, :save, :destroy, :initialize
|
|
13
|
+
define_model_callbacks :create, :save, :destroy, :initialize, :update
|
|
14
14
|
|
|
15
15
|
before_create :set_created_at
|
|
16
16
|
before_save :set_updated_at
|
|
17
|
+
after_initialize :set_type
|
|
17
18
|
end
|
|
18
19
|
|
|
19
20
|
include ActiveModel::AttributeMethods
|
|
@@ -31,7 +31,7 @@ module Dynamoid #:nodoc:
|
|
|
31
31
|
#
|
|
32
32
|
# @since 0.2.0
|
|
33
33
|
def where(args)
|
|
34
|
-
args.each {|k, v| query[k] = v}
|
|
34
|
+
args.each {|k, v| query[k.to_sym] = v}
|
|
35
35
|
self
|
|
36
36
|
end
|
|
37
37
|
|
|
@@ -43,7 +43,8 @@ module Dynamoid #:nodoc:
|
|
|
43
43
|
# Returns all the records matching the criteria.
|
|
44
44
|
#
|
|
45
45
|
# @since 0.2.0
|
|
46
|
-
def all
|
|
46
|
+
def all(opts = {})
|
|
47
|
+
batch opts[:batch_size] if opts.has_key? :batch_size
|
|
47
48
|
records
|
|
48
49
|
end
|
|
49
50
|
|
|
@@ -116,6 +117,12 @@ module Dynamoid #:nodoc:
|
|
|
116
117
|
records
|
|
117
118
|
end
|
|
118
119
|
|
|
120
|
+
def batch(batch_size)
|
|
121
|
+
raise 'Cannot batch calls when using partitioning' if Dynamoid::Config.partitioning?
|
|
122
|
+
@batch_size = batch_size
|
|
123
|
+
self
|
|
124
|
+
end
|
|
125
|
+
|
|
119
126
|
def start(start)
|
|
120
127
|
@start = start
|
|
121
128
|
self
|
|
@@ -141,28 +148,29 @@ module Dynamoid #:nodoc:
|
|
|
141
148
|
|
|
142
149
|
# The actual records referenced by the association.
|
|
143
150
|
#
|
|
144
|
-
# @return [
|
|
151
|
+
# @return [Enumerator] an iterator of the found records.
|
|
145
152
|
#
|
|
146
153
|
# @since 0.2.0
|
|
147
154
|
def records
|
|
148
|
-
if range?
|
|
155
|
+
results = if range?
|
|
149
156
|
records_with_range
|
|
150
157
|
elsif index
|
|
151
158
|
records_with_index
|
|
152
159
|
else
|
|
153
160
|
records_without_index
|
|
154
161
|
end
|
|
162
|
+
@batch_size ? results : Array(results)
|
|
155
163
|
end
|
|
156
164
|
|
|
157
165
|
# If the query matches an index on the associated class, then this method will retrieve results from the index table.
|
|
158
166
|
#
|
|
159
|
-
# @return [
|
|
167
|
+
# @return [Enumerator] an iterator of the found records.
|
|
160
168
|
#
|
|
161
169
|
# @since 0.2.0
|
|
162
170
|
def records_with_index
|
|
163
171
|
ids = ids_from_index
|
|
164
172
|
if ids.nil? || ids.empty?
|
|
165
|
-
[]
|
|
173
|
+
Enumerator.new []
|
|
166
174
|
else
|
|
167
175
|
ids = ids.to_a
|
|
168
176
|
|
|
@@ -171,7 +179,7 @@ module Dynamoid #:nodoc:
|
|
|
171
179
|
end
|
|
172
180
|
|
|
173
181
|
ids = ids.take(@limit) if @limit
|
|
174
|
-
|
|
182
|
+
source.find(ids, consistent_opts)
|
|
175
183
|
end
|
|
176
184
|
end
|
|
177
185
|
|
|
@@ -190,12 +198,16 @@ module Dynamoid #:nodoc:
|
|
|
190
198
|
end
|
|
191
199
|
|
|
192
200
|
def records_with_range
|
|
193
|
-
|
|
201
|
+
Enumerator.new do |yielder|
|
|
202
|
+
Dynamoid::Adapter.query(source.table_name, range_query).each do |hash|
|
|
203
|
+
yielder.yield source.from_database(hash)
|
|
204
|
+
end
|
|
205
|
+
end
|
|
194
206
|
end
|
|
195
207
|
|
|
196
208
|
# If the query does not match an index, we'll manually scan the associated table to find results.
|
|
197
209
|
#
|
|
198
|
-
# @return [
|
|
210
|
+
# @return [Enumerator] an iterator of the found records.
|
|
199
211
|
#
|
|
200
212
|
# @since 0.2.0
|
|
201
213
|
def records_without_index
|
|
@@ -208,7 +220,11 @@ module Dynamoid #:nodoc:
|
|
|
208
220
|
raise Dynamoid::Errors::InvalidQuery, 'Consistent read is not supported by SCAN operation'
|
|
209
221
|
end
|
|
210
222
|
|
|
211
|
-
|
|
223
|
+
Enumerator.new do |yielder|
|
|
224
|
+
Dynamoid::Adapter.scan(source.table_name, query, scan_opts).each do |hash|
|
|
225
|
+
yielder.yield source.from_database(hash)
|
|
226
|
+
end
|
|
227
|
+
end
|
|
212
228
|
end
|
|
213
229
|
|
|
214
230
|
# Format the provided query so that it can be used to query results from DynamoDB.
|
|
@@ -271,8 +287,9 @@ module Dynamoid #:nodoc:
|
|
|
271
287
|
query.keys.collect{|k| k.to_s.split('.').first}
|
|
272
288
|
end
|
|
273
289
|
|
|
290
|
+
# Use range query only when [hash_key] or [hash_key, range_key] is specified in query keys.
|
|
274
291
|
def range?
|
|
275
|
-
return false unless source.range_key
|
|
292
|
+
return false unless query_keys.include?(source.hash_key.to_s) or query_keys.include?(source.range_key.to_s)
|
|
276
293
|
query_keys == [source.hash_key.to_s] || (query_keys.to_set == [source.hash_key.to_s, source.range_key.to_s].to_set)
|
|
277
294
|
end
|
|
278
295
|
|
|
@@ -298,6 +315,7 @@ module Dynamoid #:nodoc:
|
|
|
298
315
|
opts = {}
|
|
299
316
|
opts[:limit] = @limit if @limit
|
|
300
317
|
opts[:next_token] = start_key if @start
|
|
318
|
+
opts[:batch_size] = @batch_size if @batch_size
|
|
301
319
|
opts
|
|
302
320
|
end
|
|
303
321
|
end
|