mara 0.1.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.
- checksums.yaml +7 -0
- data/README.md +3 -0
- data/Rakefile +26 -0
- data/lib/mara.rb +13 -0
- data/lib/mara/attribute_formatter.rb +161 -0
- data/lib/mara/batch.rb +223 -0
- data/lib/mara/client.rb +43 -0
- data/lib/mara/configure.rb +100 -0
- data/lib/mara/dynamo_helpers.rb +34 -0
- data/lib/mara/error.rb +8 -0
- data/lib/mara/instrument.rb +16 -0
- data/lib/mara/model.rb +13 -0
- data/lib/mara/model/attributes.rb +166 -0
- data/lib/mara/model/base.rb +225 -0
- data/lib/mara/model/dsl.rb +208 -0
- data/lib/mara/model/persistence.rb +120 -0
- data/lib/mara/model/query.rb +97 -0
- data/lib/mara/null_value.rb +13 -0
- data/lib/mara/persistence.rb +204 -0
- data/lib/mara/primary_key.rb +117 -0
- data/lib/mara/query.rb +90 -0
- data/lib/mara/table.rb +141 -0
- data/lib/mara/version.rb +5 -0
- metadata +195 -0
@@ -0,0 +1,208 @@
|
|
1
|
+
require_relative '../error'
|
2
|
+
|
3
|
+
module Mara
|
4
|
+
module Model
|
5
|
+
##
|
6
|
+
# An error raised if the index requested in
|
7
|
+
# {Dsl::ClassMethods.global_secondary_index} or
|
8
|
+
# {Dsl::ClassMethods.global_secondary_index} are not found.
|
9
|
+
#
|
10
|
+
# @author Maddie Schipper
|
11
|
+
# @since 1.0.0
|
12
|
+
class IndexError < Mara::Error; end
|
13
|
+
|
14
|
+
##
|
15
|
+
# Represents a DynamoDB Local Secondary Index.
|
16
|
+
#
|
17
|
+
# @see Mara::Model::Dsl::ClassMethods#add_lsi
|
18
|
+
#
|
19
|
+
# @!attribute [rw] name
|
20
|
+
# The name of the index.
|
21
|
+
#
|
22
|
+
# @return [String]
|
23
|
+
#
|
24
|
+
# @!attribute [rw] key_name
|
25
|
+
# The name of the LSI sort_key.
|
26
|
+
#
|
27
|
+
# @return [String]
|
28
|
+
LocalSecondaryIndex = Struct.new(:name, :key_name)
|
29
|
+
|
30
|
+
##
|
31
|
+
# Represents a DynamoDB Global Secondary Index.
|
32
|
+
#
|
33
|
+
# @see Mara::Model::Dsl::ClassMethods#add_gsi
|
34
|
+
#
|
35
|
+
# @!attribute [rw] name
|
36
|
+
# The name of the index.
|
37
|
+
#
|
38
|
+
# @return [String]
|
39
|
+
#
|
40
|
+
# @!attribute [rw] partition_key
|
41
|
+
# The name of the GSI partion key.
|
42
|
+
#
|
43
|
+
# @return [String]
|
44
|
+
#
|
45
|
+
# @!attribute [rw] sort_key
|
46
|
+
# The name of the GSI sort_key.
|
47
|
+
#
|
48
|
+
# @return [String, nil]
|
49
|
+
GlobalSecondaryIndex = Struct.new(:name, :partition_key, :sort_key)
|
50
|
+
|
51
|
+
##
|
52
|
+
# Helper DSL methods for Base class.
|
53
|
+
#
|
54
|
+
# @author Maddie Schipper
|
55
|
+
# @since 1.0.0
|
56
|
+
module Dsl
|
57
|
+
##
|
58
|
+
# @private
|
59
|
+
def self.included(klass)
|
60
|
+
klass.extend(ClassMethods)
|
61
|
+
end
|
62
|
+
|
63
|
+
##
|
64
|
+
# Helper method added at the class level.
|
65
|
+
#
|
66
|
+
# @author Maddie Schipper
|
67
|
+
# @since 1.0.0
|
68
|
+
module ClassMethods
|
69
|
+
##
|
70
|
+
# Set a partion_key and sort_key for a model.
|
71
|
+
#
|
72
|
+
# @see #partition_key
|
73
|
+
#
|
74
|
+
# @see #sort_key
|
75
|
+
#
|
76
|
+
# @example Setting the partition_key & sort_key
|
77
|
+
# class Person < Mara::Model::Base
|
78
|
+
# primary_key('PartionKeyName', 'SortKeyName')
|
79
|
+
# # ...
|
80
|
+
#
|
81
|
+
# @param partition_key [#to_s] The name of the DynamoDB table's partion
|
82
|
+
# key.
|
83
|
+
#
|
84
|
+
# @param sort_key [#to_s, nil] The name of the DynamoDB table's sort
|
85
|
+
# key.
|
86
|
+
#
|
87
|
+
# @return [void]
|
88
|
+
def primary_key(partition_key, sort_key = nil)
|
89
|
+
partition_key(partition_key)
|
90
|
+
sort_key(sort_key)
|
91
|
+
end
|
92
|
+
|
93
|
+
##
|
94
|
+
# Set the partion key name for the model. This value is required.
|
95
|
+
#
|
96
|
+
# @param partition_key [#to_s] The name of the partion key.
|
97
|
+
#
|
98
|
+
# @return [String]
|
99
|
+
def partition_key(partition_key = nil)
|
100
|
+
unless partition_key.nil?
|
101
|
+
@partition_key = partition_key.to_s
|
102
|
+
validates_presence_of :partition_key
|
103
|
+
end
|
104
|
+
@partition_key
|
105
|
+
end
|
106
|
+
|
107
|
+
##
|
108
|
+
# Set the sort key name for the model.
|
109
|
+
#
|
110
|
+
# @param sort_key [#to_s] The name of the sort key.
|
111
|
+
#
|
112
|
+
# @return [String]
|
113
|
+
def sort_key(sort_key = nil)
|
114
|
+
unless sort_key.nil?
|
115
|
+
@sort_key = sort_key.to_s
|
116
|
+
validates_presence_of :sort_key
|
117
|
+
end
|
118
|
+
|
119
|
+
@sort_key
|
120
|
+
end
|
121
|
+
|
122
|
+
##
|
123
|
+
# Add a local secondary index definition.
|
124
|
+
#
|
125
|
+
# @note This is only required for querying.
|
126
|
+
#
|
127
|
+
# @param name [String] The name of the index.
|
128
|
+
#
|
129
|
+
# @param key_name [String] The name of the LSI sort key.
|
130
|
+
#
|
131
|
+
# @return [void]
|
132
|
+
def add_lsi(name, key_name)
|
133
|
+
local_secondary_indices[name.to_s] = LocalSecondaryIndex.new(name.to_s, key_name.to_s)
|
134
|
+
end
|
135
|
+
|
136
|
+
##
|
137
|
+
# @private
|
138
|
+
#
|
139
|
+
# All registered local secondary indices
|
140
|
+
#
|
141
|
+
# @return [Hash<String, LocalSecondaryIndex>]
|
142
|
+
def local_secondary_indices
|
143
|
+
@local_secondary_indices ||= {}
|
144
|
+
end
|
145
|
+
|
146
|
+
##
|
147
|
+
# Get a defined local secondary index by name.
|
148
|
+
#
|
149
|
+
# @param name [#to_s] The name of the LSI to get.
|
150
|
+
#
|
151
|
+
# @raise [IndexError] The index is not registered on the model.
|
152
|
+
#
|
153
|
+
# @return [LocalSecondaryIndex]
|
154
|
+
def local_secondary_index(name)
|
155
|
+
index = local_secondary_indices[name.to_s]
|
156
|
+
if index.nil?
|
157
|
+
raise Mara::Model::IndexError, "Can't find a LSI with the name `#{name}`"
|
158
|
+
end
|
159
|
+
|
160
|
+
index
|
161
|
+
end
|
162
|
+
|
163
|
+
##
|
164
|
+
# Add a global secondary index definition.
|
165
|
+
#
|
166
|
+
# @note This is only required for querying.
|
167
|
+
#
|
168
|
+
# @param name [#to_s] The name of the index.
|
169
|
+
#
|
170
|
+
# @param partition_key [#to_s] The name of the GSI partition key.
|
171
|
+
#
|
172
|
+
# @param sort_key [String, nil] The name of the GSI sort key.
|
173
|
+
#
|
174
|
+
# @return [void]
|
175
|
+
def add_gsi(name, partition_key, sort_key = nil)
|
176
|
+
global_secondary_indices[name.to_s] = GlobalSecondaryIndex.new(name.to_s, partition_key.to_s, sort_key)
|
177
|
+
end
|
178
|
+
|
179
|
+
##
|
180
|
+
# @private
|
181
|
+
#
|
182
|
+
# All registered global secondary indices
|
183
|
+
#
|
184
|
+
# @return [Hash<String, GlobalSecondaryIndex>]
|
185
|
+
def global_secondary_indices
|
186
|
+
@global_secondary_indices ||= {}
|
187
|
+
end
|
188
|
+
|
189
|
+
##
|
190
|
+
# Get a defined global secondary index by name.
|
191
|
+
#
|
192
|
+
# @param name [#to_s] The name of the GSI to get.
|
193
|
+
#
|
194
|
+
# @raise [IndexError] The index is not registered on the model.
|
195
|
+
#
|
196
|
+
# @return [GlobalSecondaryIndex]
|
197
|
+
def global_secondary_index(name)
|
198
|
+
index = global_secondary_indices[name.to_s]
|
199
|
+
if index.nil?
|
200
|
+
raise Mara::Model::IndexError, "Can't find a GSI with the name `#{name}`"
|
201
|
+
end
|
202
|
+
|
203
|
+
index
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require_relative '../attribute_formatter'
|
2
|
+
require_relative '../batch'
|
3
|
+
require_relative '../instrument'
|
4
|
+
|
5
|
+
module Mara
|
6
|
+
module Model
|
7
|
+
##
|
8
|
+
# Methods that save/update/delete a model.
|
9
|
+
#
|
10
|
+
# @author Maddie Schipper
|
11
|
+
# @since 1.0.0
|
12
|
+
module Persistence
|
13
|
+
##
|
14
|
+
# @private
|
15
|
+
def self.included(klass)
|
16
|
+
klass.extend(ClassMethods)
|
17
|
+
end
|
18
|
+
|
19
|
+
##
|
20
|
+
# Helper method added at the class level.
|
21
|
+
#
|
22
|
+
# @author Maddie Schipper
|
23
|
+
# @since 1.0.0
|
24
|
+
module ClassMethods
|
25
|
+
end
|
26
|
+
|
27
|
+
##
|
28
|
+
# @private
|
29
|
+
#
|
30
|
+
# Converts the attributes into a DynamoDB compatable hash.
|
31
|
+
#
|
32
|
+
# @return [Hash]
|
33
|
+
def to_dynamo
|
34
|
+
{}.tap do |formatted|
|
35
|
+
attributes.each do |key, value|
|
36
|
+
formatted[key] = Mara::AttributeFormatter.format(value)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
##
|
42
|
+
# @private
|
43
|
+
#
|
44
|
+
# Get a primary key attribute for the item.
|
45
|
+
#
|
46
|
+
# @return [Hash]
|
47
|
+
def primary_key
|
48
|
+
{}.tap do |base|
|
49
|
+
base[self.class.partition_key] = Mara::AttributeFormatter.format(partition_key)
|
50
|
+
|
51
|
+
unless self.class.sort_key.blank?
|
52
|
+
base[self.class.sort_key] = Mara::AttributeFormatter.format(sort_key)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
##
|
58
|
+
# @private
|
59
|
+
#
|
60
|
+
# Create a DynamoDB representation of the model.
|
61
|
+
#
|
62
|
+
# @return [Hash]
|
63
|
+
def to_item
|
64
|
+
to_dynamo.merge(primary_key)
|
65
|
+
end
|
66
|
+
|
67
|
+
##
|
68
|
+
# Perform validation and save the model.
|
69
|
+
#
|
70
|
+
# @return [true, false]
|
71
|
+
def save
|
72
|
+
Mara.instrument('model.save', model: self) do
|
73
|
+
next false unless valid?
|
74
|
+
|
75
|
+
Mara::Batch.save_model(to_item)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
##
|
80
|
+
# Perform validation and save the model.
|
81
|
+
#
|
82
|
+
# @see #save
|
83
|
+
#
|
84
|
+
# @note Same as {#save} but will raise an error on validation faiure and
|
85
|
+
# save failure
|
86
|
+
#
|
87
|
+
# @return [void]
|
88
|
+
def save!
|
89
|
+
Mara.instrument('model.save', model: self) do
|
90
|
+
validate!
|
91
|
+
Mara::Batch.save_model!(to_item)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
##
|
96
|
+
# Perform a destroy on the model.
|
97
|
+
#
|
98
|
+
# @return [true, false]
|
99
|
+
def destroy
|
100
|
+
Mara.instrument('model.destroy', model: self) do
|
101
|
+
Mara::Batch.delete_model(primary_key)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
##
|
106
|
+
# Perform a destroy on the model.
|
107
|
+
#
|
108
|
+
# @see #destroy
|
109
|
+
#
|
110
|
+
# @note Same as {#destroy} but will raise an error on delete failure.
|
111
|
+
#
|
112
|
+
# @return [void]
|
113
|
+
def destroy!
|
114
|
+
Mara.instrument('model.destroy', model: self) do
|
115
|
+
Mara::Batch.delete_model!(primary_key)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require_relative '../error'
|
2
|
+
require_relative '../query'
|
3
|
+
require_relative '../attribute_formatter'
|
4
|
+
require_relative '../instrument'
|
5
|
+
|
6
|
+
module Mara
|
7
|
+
module Model
|
8
|
+
##
|
9
|
+
# Error raised when a find method fails to find the requested object.
|
10
|
+
#
|
11
|
+
# @author Maddie Schipper
|
12
|
+
# @since 1.0.0
|
13
|
+
class NotFoundError < Error; end
|
14
|
+
|
15
|
+
##
|
16
|
+
# Methods to query for a model.
|
17
|
+
#
|
18
|
+
# @author Maddie Schipper
|
19
|
+
# @since 1.0.0
|
20
|
+
module Query
|
21
|
+
##
|
22
|
+
# @private
|
23
|
+
def self.included(klass)
|
24
|
+
klass.extend(ClassMethods)
|
25
|
+
end
|
26
|
+
|
27
|
+
##
|
28
|
+
# Helper methods defined on the class.
|
29
|
+
#
|
30
|
+
# @author Maddie Schipper
|
31
|
+
# @since 1.0.0
|
32
|
+
module ClassMethods
|
33
|
+
##
|
34
|
+
# Find a single object with the matching partition_key and sort key.
|
35
|
+
#
|
36
|
+
# @param partition_key [#to_s] The value for the partition key.
|
37
|
+
#
|
38
|
+
# @param sort_key [#to_s, nil] The value for the sort key.
|
39
|
+
#
|
40
|
+
# @raise [NotFoundError] If the object doesn't exist in the table for
|
41
|
+
# the requested primary key.
|
42
|
+
#
|
43
|
+
# @raise [ArgumentError] If the +partition_key+ is blank, or the
|
44
|
+
# +sort_key+ is blank and the class defines a sort_key name.
|
45
|
+
#
|
46
|
+
# @return [ Mara::Model::Base]
|
47
|
+
def find(partition_key, sort_key = nil)
|
48
|
+
Mara.instrument('model.find', class_name: name, partition_key: partition_key, sort_key: sort_key) do
|
49
|
+
_find(partition_key, sort_key)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
##
|
54
|
+
# @private
|
55
|
+
#
|
56
|
+
# @see #find
|
57
|
+
def _find(partition_key, sort_key = nil)
|
58
|
+
if partition_key.blank?
|
59
|
+
raise ArgumentError, 'Must specify a valid partition key value'
|
60
|
+
end
|
61
|
+
|
62
|
+
if sort_key.nil? && !self.sort_key.blank?
|
63
|
+
raise ArgumentError, "#{self.class.name} specifies a sort key, but no sort key value was given."
|
64
|
+
end
|
65
|
+
|
66
|
+
key_params = {}
|
67
|
+
key_params[self.partition_key] = Mara::AttributeFormatter.format(partition_key)
|
68
|
+
if self.sort_key.present?
|
69
|
+
key_params[self.sort_key] = Mara::AttributeFormatter.format(sort_key)
|
70
|
+
end
|
71
|
+
|
72
|
+
response = Mara::Query.get_item(key: key_params)
|
73
|
+
|
74
|
+
if response.nil? || response.items.empty?
|
75
|
+
raise NotFoundError, "Can't find item with pk=#{partition_key} sk=#{sort_key}"
|
76
|
+
end
|
77
|
+
|
78
|
+
item = response.items[0]
|
79
|
+
|
80
|
+
construct(item)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
##
|
85
|
+
# Checks if a the model exists in the table?
|
86
|
+
#
|
87
|
+
# @return [true, false]
|
88
|
+
def exist?
|
89
|
+
pk = partition_key
|
90
|
+
sk = conditional_sort_key
|
91
|
+
self.class.find(pk, sk).present?
|
92
|
+
rescue Mara::Model::NotFoundError
|
93
|
+
false
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,204 @@
|
|
1
|
+
require_relative 'error'
|
2
|
+
require_relative 'client'
|
3
|
+
require_relative 'configure'
|
4
|
+
require_relative 'instrument'
|
5
|
+
require_relative 'dynamo_helpers'
|
6
|
+
|
7
|
+
module Mara
|
8
|
+
##
|
9
|
+
# @private
|
10
|
+
#
|
11
|
+
# Perform calls to DynamoDB for saving/updating/deleting
|
12
|
+
#
|
13
|
+
# @author Maddie Schipper
|
14
|
+
# @since 1.0.0
|
15
|
+
class Persistence
|
16
|
+
include DynamoHelpers
|
17
|
+
|
18
|
+
##
|
19
|
+
# @private
|
20
|
+
#
|
21
|
+
# A wrapper for a create request.
|
22
|
+
#
|
23
|
+
# @!attribute [rw] record
|
24
|
+
# The record hash to be created.
|
25
|
+
#
|
26
|
+
# @return [Hash]
|
27
|
+
#
|
28
|
+
# @author Maddie Schipper
|
29
|
+
# @since 1.0.0
|
30
|
+
CreateRequest = Struct.new(:record) do
|
31
|
+
##
|
32
|
+
# Converts the CreateRequest to JSON
|
33
|
+
#
|
34
|
+
# @return [Hash]
|
35
|
+
def as_json
|
36
|
+
{
|
37
|
+
put_request: {
|
38
|
+
item: record
|
39
|
+
}
|
40
|
+
}
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
##
|
45
|
+
# @private
|
46
|
+
#
|
47
|
+
# A wrapper for a destroy request.
|
48
|
+
#
|
49
|
+
# @!attribute [rw] record
|
50
|
+
# The record hash to be destroyed.
|
51
|
+
#
|
52
|
+
# @return [Hash]
|
53
|
+
#
|
54
|
+
# @author Maddie Schipper
|
55
|
+
# @since 1.0.0
|
56
|
+
DestroyRequest = Struct.new(:record) do
|
57
|
+
##
|
58
|
+
# Converts the DestroyRequest to JSON
|
59
|
+
#
|
60
|
+
# @return [Hash]
|
61
|
+
def as_json
|
62
|
+
{
|
63
|
+
delete_request: {
|
64
|
+
key: record
|
65
|
+
}
|
66
|
+
}
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
##
|
71
|
+
# @private The response for a save operation.
|
72
|
+
#
|
73
|
+
# @!attribute [r] consumed_capacity
|
74
|
+
# The total consumed capacity for the request.
|
75
|
+
#
|
76
|
+
# @return [Float]
|
77
|
+
#
|
78
|
+
# @!attribute [r] operation_count
|
79
|
+
# The total number of API calls required to perform the operation.
|
80
|
+
#
|
81
|
+
# @return [Integer]
|
82
|
+
#
|
83
|
+
# @author Maddie Schipper
|
84
|
+
# @since 1.0.0
|
85
|
+
Response = Struct.new(:consumed_capacity, :operation_count)
|
86
|
+
|
87
|
+
##
|
88
|
+
# @private
|
89
|
+
#
|
90
|
+
# Error thrown by Persistence calls.
|
91
|
+
#
|
92
|
+
# @author Maddie Schipper
|
93
|
+
# @since 1.0.0
|
94
|
+
class Error < Mara::Error; end
|
95
|
+
|
96
|
+
class << self
|
97
|
+
##
|
98
|
+
# Perform a save on a item.
|
99
|
+
#
|
100
|
+
# @param item [Hash] The item to be saved.
|
101
|
+
#
|
102
|
+
# @return [true, false]
|
103
|
+
def save_model(item)
|
104
|
+
create = CreateRequest.new(item)
|
105
|
+
response = perform_requests(
|
106
|
+
Mara::Client.shared,
|
107
|
+
Mara.config.dynamodb.table_name,
|
108
|
+
[create]
|
109
|
+
)
|
110
|
+
!response.nil?
|
111
|
+
end
|
112
|
+
|
113
|
+
##
|
114
|
+
# Perform a save on the a item.
|
115
|
+
#
|
116
|
+
# @see .save_model
|
117
|
+
#
|
118
|
+
# @param item [Hash] The item to be saved.
|
119
|
+
#
|
120
|
+
# @raise Error If the save operation fails.
|
121
|
+
#
|
122
|
+
# @return [void]
|
123
|
+
def save_model!(item)
|
124
|
+
return if save_model(item)
|
125
|
+
|
126
|
+
raise Error, 'Failed to save!'
|
127
|
+
end
|
128
|
+
|
129
|
+
##
|
130
|
+
# Delete an item.
|
131
|
+
#
|
132
|
+
# @param item [Hash] The item to be deleted.
|
133
|
+
#
|
134
|
+
# @return [true, false]
|
135
|
+
def delete_model(item)
|
136
|
+
delete = DestroyRequest.new(item)
|
137
|
+
response = perform_requests(
|
138
|
+
Mara::Client.shared,
|
139
|
+
Mara.config.dynamodb.table_name,
|
140
|
+
[delete]
|
141
|
+
)
|
142
|
+
!response.nil?
|
143
|
+
end
|
144
|
+
|
145
|
+
##
|
146
|
+
# Delete an item.
|
147
|
+
#
|
148
|
+
# @see .delete_model
|
149
|
+
#
|
150
|
+
# @param item [Hash] The item to be deleted.
|
151
|
+
#
|
152
|
+
# @raise Error If the delete operation fails.
|
153
|
+
#
|
154
|
+
# @return [void]
|
155
|
+
def delete_model!(item)
|
156
|
+
return if delete_model(item)
|
157
|
+
|
158
|
+
raise Error, 'Failed to delete!'
|
159
|
+
end
|
160
|
+
|
161
|
+
##
|
162
|
+
# Perform a batch of save requests.
|
163
|
+
def perform_requests(client, table_name, requests, group_size = 10)
|
164
|
+
results = Mara.instrument('save_batch_records', requests: requests, table_name: table_name) do
|
165
|
+
requests.each_slice(group_size).map do |sub_requests|
|
166
|
+
_perform_requests(client, table_name, sub_requests)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
Response.new(
|
170
|
+
results.map(&:consumed_capacity).sum,
|
171
|
+
results.map(&:operation_count).sum
|
172
|
+
)
|
173
|
+
end
|
174
|
+
|
175
|
+
private
|
176
|
+
|
177
|
+
def _base_batch_write_item_params(table_name)
|
178
|
+
params = {
|
179
|
+
return_consumed_capacity: 'TOTAL',
|
180
|
+
return_item_collection_metrics: 'SIZE',
|
181
|
+
request_items: {}
|
182
|
+
}
|
183
|
+
if block_given?
|
184
|
+
params[:request_items][table_name] = yield
|
185
|
+
end
|
186
|
+
params
|
187
|
+
end
|
188
|
+
|
189
|
+
def _perform_requests(client, table_name, requests)
|
190
|
+
params = _base_batch_write_item_params(table_name) { requests.map(&:as_json) }
|
191
|
+
response = Mara.instrument('save_batch_record_operation', requests: requests, table_name: table_name) do
|
192
|
+
client.batch_write_item(params)
|
193
|
+
end
|
194
|
+
|
195
|
+
cc = calculate_consumed_capacity(response.consumed_capacity, table_name)
|
196
|
+
|
197
|
+
Response.new(
|
198
|
+
cc,
|
199
|
+
1
|
200
|
+
)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|