mara 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|