azure-storage-table 1.0.1 → 2.0.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
- SHA1:
3
- metadata.gz: 9d6b032a68dc79dd98665bcc15d46421f1491d34
4
- data.tar.gz: ce386074b44d0badb2c563d08397be6d0acf6ce7
2
+ SHA256:
3
+ metadata.gz: 354d8ebc7d0f9b9f9face790c7cc29283a161defed051dc723ac9cc893b97cca
4
+ data.tar.gz: 7704f0ccba3f01dd17c0232eaae9c415f3e45de7d3156f3a26edd7f6da7dfb66
5
5
  SHA512:
6
- metadata.gz: a975813a24aa07e98dee4b6b3d15a530265b89c9a64a472d11765de7bbd7cd4eadeeba07c0a2e2eb246c8fdb4f7b5df1eadb4aa9705c7616e0f7d72f55e333a7
7
- data.tar.gz: bbfc1e19e733994310ad337cdae1dedf6f43952fccf1c4c3e2ba5f222fc6800537ee3fe41d85e1cc4835b3e5043acd7f7b268c091f2b2aa4d4c3da3cee2043a3
6
+ metadata.gz: c037a7ffcdfcfa49e4b0751c8d7643def8cfe30f97385727d41378cdecd028676f23743c746cc444805da2bfaf5b2c54aabb8b4a2a9f60e422b0c12f8cc09b7d
7
+ data.tar.gz: a7569980bd48f52b05a8d2e2d0cb2976d8ce15c2b1fbc6776a92b6ea299731671a86dfbe983f9553e7a2bf1c3b4e8a2fbc7c24422a331f7f5109202b3f2247b3
@@ -1,26 +1,26 @@
1
- # frozen_string_literal: true
2
-
3
- #-------------------------------------------------------------------------
4
- # # Copyright (c) Microsoft and contributors. All rights reserved.
5
- #
6
- # The MIT License(MIT)
7
-
8
- # Permission is hereby granted, free of charge, to any person obtaining a copy
9
- # of this software and associated documentation files(the "Software"), to deal
10
- # in the Software without restriction, including without limitation the rights
11
- # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
12
- # copies of the Software, and to permit persons to whom the Software is
13
- # furnished to do so, subject to the following conditions :
14
-
15
- # The above copyright notice and this permission notice shall be included in
16
- # all copies or substantial portions of the Software.
17
-
18
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
21
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
- # THE SOFTWARE.
25
- #--------------------------------------------------------------------------
26
- require "azure/storage/table/autoload"
1
+ # frozen_string_literal: true
2
+
3
+ #-------------------------------------------------------------------------
4
+ # # Copyright (c) Microsoft and contributors. All rights reserved.
5
+ #
6
+ # The MIT License(MIT)
7
+
8
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ # of this software and associated documentation files(the "Software"), to deal
10
+ # in the Software without restriction, including without limitation the rights
11
+ # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
12
+ # copies of the Software, and to permit persons to whom the Software is
13
+ # furnished to do so, subject to the following conditions :
14
+
15
+ # The above copyright notice and this permission notice shall be included in
16
+ # all copies or substantial portions of the Software.
17
+
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
21
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ # THE SOFTWARE.
25
+ #--------------------------------------------------------------------------
26
+ require "azure/storage/table/autoload"
@@ -1,69 +1,69 @@
1
- # frozen_string_literal: true
2
-
3
- #-------------------------------------------------------------------------
4
- # # Copyright (c) Microsoft and contributors. All rights reserved.
5
- #
6
- # The MIT License(MIT)
7
-
8
- # Permission is hereby granted, free of charge, to any person obtaining a copy
9
- # of this software and associated documentation files(the "Software"), to deal
10
- # in the Software without restriction, including without limitation the rights
11
- # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
12
- # copies of the Software, and to permit persons to whom the Software is
13
- # furnished to do so, subject to the following conditions :
14
-
15
- # The above copyright notice and this permission notice shall be included in
16
- # all copies or substantial portions of the Software.
17
-
18
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
21
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
- # THE SOFTWARE.
25
- #--------------------------------------------------------------------------
26
- require "cgi"
27
- require "azure/storage/common/core/auth/shared_key"
28
-
29
- module Azure::Storage
30
- module Table
31
- module Auth
32
- class SharedKey < Azure::Storage::Common::Core::Auth::SharedKey
33
- # The account name
34
- attr :account_name
35
-
36
- # Generate the string to sign.
37
- #
38
- # @param method [Symbol] The HTTP request method.
39
- # @param uri [URI] The URI of the request we're signing.
40
- # @param headers [Hash] The HTTP request headers.
41
- #
42
- # Returns a plain text string.
43
- def signable_string(method, uri, headers)
44
- [
45
- method.to_s.upcase,
46
- headers.fetch("Content-MD5", ""),
47
- headers.fetch("Content-Type", ""),
48
- headers.fetch("Date") { headers.fetch("x-ms-date") },
49
- canonicalized_resource(uri)
50
- ].join("\n")
51
- end
52
-
53
- # Calculate the Canonicalized Resource string for a request.
54
- #
55
- # @param uri [URI] The request's URI.
56
- #
57
- # @return [String] with the canonicalized resource.
58
- def canonicalized_resource(uri)
59
- resource = "/#{account_name}#{uri.path}"
60
-
61
- comp = CGI.parse(uri.query.to_s).fetch("comp", nil)
62
- resource = [resource, "comp=" + comp[0]].join("?") if comp
63
-
64
- resource
65
- end
66
- end
67
- end
68
- end
69
- end
1
+ # frozen_string_literal: true
2
+
3
+ #-------------------------------------------------------------------------
4
+ # # Copyright (c) Microsoft and contributors. All rights reserved.
5
+ #
6
+ # The MIT License(MIT)
7
+
8
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ # of this software and associated documentation files(the "Software"), to deal
10
+ # in the Software without restriction, including without limitation the rights
11
+ # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
12
+ # copies of the Software, and to permit persons to whom the Software is
13
+ # furnished to do so, subject to the following conditions :
14
+
15
+ # The above copyright notice and this permission notice shall be included in
16
+ # all copies or substantial portions of the Software.
17
+
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
21
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ # THE SOFTWARE.
25
+ #--------------------------------------------------------------------------
26
+ require "cgi"
27
+ require "azure/storage/common/core/auth/shared_key"
28
+
29
+ module Azure::Storage
30
+ module Table
31
+ module Auth
32
+ class SharedKey < Azure::Storage::Common::Core::Auth::SharedKey
33
+ # The account name
34
+ attr :account_name
35
+
36
+ # Generate the string to sign.
37
+ #
38
+ # @param method [Symbol] The HTTP request method.
39
+ # @param uri [URI] The URI of the request we're signing.
40
+ # @param headers [Hash] The HTTP request headers.
41
+ #
42
+ # Returns a plain text string.
43
+ def signable_string(method, uri, headers)
44
+ [
45
+ method.to_s.upcase,
46
+ headers.fetch("Content-MD5", ""),
47
+ headers.fetch("Content-Type", ""),
48
+ headers.fetch("Date") { headers.fetch("x-ms-date") },
49
+ canonicalized_resource(uri)
50
+ ].join("\n")
51
+ end
52
+
53
+ # Calculate the Canonicalized Resource string for a request.
54
+ #
55
+ # @param uri [URI] The request's URI.
56
+ #
57
+ # @return [String] with the canonicalized resource.
58
+ def canonicalized_resource(uri)
59
+ resource = "/#{account_name}#{uri.path}"
60
+
61
+ comp = CGI.parse(uri.query.to_s).fetch("comp", nil)
62
+ resource = [resource, "comp=" + comp[0]].join("?") if comp
63
+
64
+ resource
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -1,48 +1,48 @@
1
- # frozen_string_literal: true
2
-
3
- #-------------------------------------------------------------------------
4
- # # Copyright (c) Microsoft and contributors. All rights reserved.
5
- #
6
- # The MIT License(MIT)
7
-
8
- # Permission is hereby granted, free of charge, to any person obtaining a copy
9
- # of this software and associated documentation files(the "Software"), to deal
10
- # in the Software without restriction, including without limitation the rights
11
- # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
12
- # copies of the Software, and to permit persons to whom the Software is
13
- # furnished to do so, subject to the following conditions :
14
-
15
- # The above copyright notice and this permission notice shall be included in
16
- # all copies or substantial portions of the Software.
17
-
18
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
21
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
- # THE SOFTWARE.
25
- #--------------------------------------------------------------------------
26
- require "rubygems"
27
- require "nokogiri"
28
- require "base64"
29
-
30
- require "azure/storage/common"
31
-
32
- module Azure
33
- module Storage
34
- module Table
35
- autoload :Default, "azure/storage/table/default"
36
- autoload :TableConstants, "azure/storage/table/default"
37
- autoload :Version, "azure/storage/table/version"
38
- autoload :Serialization, "azure/storage/table/serialization"
39
- autoload :TableService, "azure/storage/table/table_service"
40
- autoload :Batch, "azure/storage/table/batch"
41
- autoload :Query, "azure/storage/table/query"
42
- autoload :BatchResponse, "azure/storage/table/batch_response"
43
- autoload :EdmType, "azure/storage/table/edmtype"
44
- autoload :Entity, "azure/storage/table/entity"
45
- autoload :GUID, "azure/storage/table/guid"
46
- end
47
- end
48
- end
1
+ # frozen_string_literal: true
2
+
3
+ #-------------------------------------------------------------------------
4
+ # # Copyright (c) Microsoft and contributors. All rights reserved.
5
+ #
6
+ # The MIT License(MIT)
7
+
8
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ # of this software and associated documentation files(the "Software"), to deal
10
+ # in the Software without restriction, including without limitation the rights
11
+ # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
12
+ # copies of the Software, and to permit persons to whom the Software is
13
+ # furnished to do so, subject to the following conditions :
14
+
15
+ # The above copyright notice and this permission notice shall be included in
16
+ # all copies or substantial portions of the Software.
17
+
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
21
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ # THE SOFTWARE.
25
+ #--------------------------------------------------------------------------
26
+ require "rubygems"
27
+ require "nokogiri"
28
+ require "base64"
29
+
30
+ require "azure/storage/common"
31
+
32
+ module Azure
33
+ module Storage
34
+ module Table
35
+ autoload :Default, "azure/storage/table/default"
36
+ autoload :TableConstants, "azure/storage/table/default"
37
+ autoload :Version, "azure/storage/table/version"
38
+ autoload :Serialization, "azure/storage/table/serialization"
39
+ autoload :TableService, "azure/storage/table/table_service"
40
+ autoload :Batch, "azure/storage/table/batch"
41
+ autoload :Query, "azure/storage/table/query"
42
+ autoload :BatchResponse, "azure/storage/table/batch_response"
43
+ autoload :EdmType, "azure/storage/table/edmtype"
44
+ autoload :Entity, "azure/storage/table/entity"
45
+ autoload :GUID, "azure/storage/table/guid"
46
+ end
47
+ end
48
+ end
@@ -1,366 +1,366 @@
1
- #-------------------------------------------------------------------------
2
- # # Copyright (c) Microsoft and contributors. All rights reserved.
3
- #
4
- # The MIT License(MIT)
5
-
6
- # Permission is hereby granted, free of charge, to any person obtaining a copy
7
- # of this software and associated documentation files(the "Software"), to deal
8
- # in the Software without restriction, including without limitation the rights
9
- # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
10
- # copies of the Software, and to permit persons to whom the Software is
11
- # furnished to do so, subject to the following conditions :
12
-
13
- # The above copyright notice and this permission notice shall be included in
14
- # all copies or substantial portions of the Software.
15
-
16
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
19
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
- # THE SOFTWARE.
23
- #--------------------------------------------------------------------------
24
- require "securerandom"
25
- require "azure/core/http/http_error"
26
-
27
- module Azure::Storage
28
- module Table
29
- # Represents a batch of table operations.
30
- #
31
- # Example usage:
32
- #
33
- # svc = TableSerice.new
34
- #
35
- # batch = Batch.new "table", "partition"
36
- # batch.insert "row1", {"meta"=>"data"}
37
- # batch.insert "row2", {"meta"=>"data"}
38
- #
39
- # results = svc.execute_batch batch
40
- #
41
- class Batch
42
- def initialize(table, partition, &block)
43
- @table = table
44
- @partition = partition
45
- @operations = []
46
- @entity_keys = []
47
- @batch_id = "batch_" + SecureRandom.uuid
48
- @changeset_id = "changeset_" + SecureRandom.uuid
49
-
50
- self.instance_eval(&block) if block_given?
51
- end
52
-
53
- private
54
- attr_reader :table
55
- attr_reader :partition
56
-
57
- attr_accessor :operations
58
- attr_accessor :entity_keys
59
- attr_accessor :changeset_id
60
-
61
- public
62
- attr_accessor :batch_id
63
-
64
- protected
65
- class ResponseWrapper
66
- def initialize(hash)
67
- @hash = hash
68
- end
69
-
70
- def uri
71
- @hash[:uri]
72
- end
73
-
74
- def status_code
75
- @hash[:status_code].to_i
76
- end
77
-
78
- def body
79
- @hash[:body]
80
- end
81
- end
82
-
83
- protected
84
- def add_operation(method, row_key = nil, body = nil, headers = nil)
85
- raise Azure::Storage::Common::Core::StorageError.new("Get operation should be the only operation in the batch.") if operations.length > 0 && (method == :get || operations[0][:method] == :get)
86
- op = {
87
- method: method,
88
- row_key: row_key,
89
- body: body,
90
- headers: headers.merge(
91
- Azure::Storage::Common::HeaderConstants::CONTENT_TYPE => Azure::Storage::Common::HeaderConstants::JSON_CONTENT_TYPE_VALUE,
92
- Azure::Storage::Common::HeaderConstants::DATA_SERVICE_VERSION => TableConstants::DEFAULT_DATA_SERVICE_VERSION
93
- )
94
- }
95
- operations.push op
96
- end
97
-
98
- protected
99
- def check_entity_key(key)
100
- raise ArgumentError, "Only allowed to perform a single operation per entity, and there is already a operation registered in this batch for the key: #{key}." if entity_keys.include? key
101
- entity_keys.push key
102
- end
103
-
104
- public
105
- def parse_response(response)
106
- responses = BatchResponse.parse response.body, (!operations.empty? && operations[0][:method] == :get)
107
- new_responses = []
108
-
109
- (0..responses.length - 1).each { |index|
110
- operation = operations[index]
111
- response = responses[index]
112
-
113
- if response[:status_code].to_i > 299
114
- # failed
115
- error = Azure::Core::Http::HTTPError.new(ResponseWrapper.new(response.merge(uri: operation[:uri])))
116
- error.description = response[:message] if (error.description || "").strip == ""
117
- raise error
118
- else
119
- # success
120
- case operation[:method]
121
- when :post, :get
122
- # entity from body
123
- entity = Serialization.entity_from_json(response[:body])
124
-
125
- entity.etag = response[:headers]["etag"] if entity.etag.nil?
126
-
127
- new_responses.push entity
128
- when :put, :merge
129
- # etag from headers
130
- new_responses.push response[:headers]["etag"]
131
- when :delete
132
- # true
133
- new_responses.push nil
134
- end
135
- end
136
- }
137
-
138
- new_responses
139
- end
140
-
141
- public
142
- def to_body(table_service)
143
- body = ""
144
- body.define_singleton_method(:add_line) do |a| self << (a || nil) + "\n" end
145
-
146
- is_get = true if !operations.empty? && operations[0][:method] == :get
147
-
148
- body.add_line "--#{batch_id}"
149
- body.add_line "Content-Type: multipart/mixed; boundary=#{changeset_id}" unless is_get
150
- body.add_line "" unless is_get
151
-
152
- operations.each { |op|
153
- uri = table_service.entities_uri(@table, @partition, op[:row_key])
154
- body.add_line "--#{changeset_id}" unless is_get
155
- body.add_line "Content-Type: application/http"
156
- body.add_line "Content-Transfer-Encoding: binary"
157
- body.add_line ""
158
- body.add_line "#{op[:method].to_s.upcase} #{uri} HTTP/1.1"
159
-
160
- if op[:headers]
161
- op[:headers].each { |k, v|
162
- body.add_line "#{k}: #{v}"
163
- }
164
- end
165
-
166
- if op[:body]
167
- body.add_line "Content-Length: #{op[:body].bytesize}"
168
- body.add_line ""
169
- body.add_line op[:body]
170
- else
171
- body.add_line ""
172
- end
173
-
174
- }
175
- body.add_line "--#{changeset_id}--" unless is_get
176
- body.add_line "--#{batch_id}--"
177
- end
178
-
179
- # Public: Inserts new entity to the table.
180
- #
181
- # ==== Attributes
182
- #
183
- # * +row_key+ - String. The row key
184
- # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
185
- # * +options+ - Hash. Optional parameters.
186
- #
187
- # ==== Options
188
- #
189
- # Accepted key/value pairs in options parameter are:
190
- # * +:accept+ - String. Specifies the accepted content-type of the response payload. Possible values are:
191
- # :no_meta
192
- # :min_meta
193
- # :full_meta
194
- # * +:prefer+ - String. Specifies whether the response should include the inserted entity in the payload. Possible values are:
195
- # Azure::Storage::Common::HeaderConstants::PREFER_CONTENT
196
- # Azure::Storage::Common::HeaderConstants::PREFER_NO_CONTENT
197
- #
198
- # See http://msdn.microsoft.com/en-us/library/azure/dd179433
199
- public
200
- def insert(row_key, entity_values, options = {})
201
- check_entity_key(row_key)
202
-
203
- headers = { Azure::Storage::Common::HeaderConstants::ACCEPT => Serialization.get_accept_string(options[:accept]) }
204
- headers[Azure::Storage::Common::HeaderConstants::PREFER] = options[:prefer] unless options[:prefer].nil?
205
-
206
- body = Serialization.hash_to_json({
207
- "PartitionKey" => partition,
208
- "RowKey" => row_key
209
- }.merge(entity_values)
210
- )
211
-
212
- add_operation(:post, nil, body, headers)
213
- self
214
- end
215
-
216
- # Public: Gets entity from the table.
217
- #
218
- # ==== Attributes
219
- #
220
- # * +row_key+ - String. The row key
221
- # * +options+ - Hash. Optional parameters.
222
- #
223
- # ==== Options
224
- #
225
- # Accepted key/value pairs in options parameter are:
226
- # * +:accept+ - String. Specifies the accepted content-type of the response payload. Possible values are:
227
- # :no_meta
228
- # :min_meta
229
- # :full_meta
230
- #
231
- # See http://msdn.microsoft.com/en-us/library/azure/dd179433
232
- public
233
- def get(row_key, options = {})
234
- check_entity_key(row_key)
235
-
236
- headers = { Azure::Storage::Common::HeaderConstants::ACCEPT => Serialization.get_accept_string(options[:accept]) }
237
-
238
- add_operation(:get, row_key, nil, headers)
239
- self
240
- end
241
-
242
- # Public: Updates an existing entity in a table. The Update Entity operation replaces
243
- # the entire entity and can be used to remove properties.
244
- #
245
- # ==== Attributes
246
- #
247
- # * +row_key+ - String. The row key
248
- # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
249
- # * +options+ - Hash. Optional parameters.
250
- #
251
- # ==== Options
252
- #
253
- # Accepted key/value pairs in options parameter are:
254
- # * :if_match - String. A matching condition which is required for update (optional, Default="*")
255
- # * :create_if_not_exists - Boolean. If true, and partition_key and row_key do not reference and existing entity,
256
- # that entity will be inserted. If false, the operation will fail. (optional, Default=false)
257
- # * +:accept+ - String. Specifies the accepted content-type of the response payload. Possible values are:
258
- # :no_meta
259
- # :min_meta
260
- # :full_meta
261
- #
262
- # See http://msdn.microsoft.com/en-us/library/azure/dd179427
263
- public
264
- def update(row_key, entity_values, options = {})
265
- check_entity_key(row_key)
266
-
267
- headers = { Azure::Storage::Common::HeaderConstants::ACCEPT => Serialization.get_accept_string(options[:accept]) }
268
- headers["If-Match"] = options[:if_match] || "*" unless options[:create_if_not_exists]
269
-
270
- body = Serialization.hash_to_json(entity_values)
271
-
272
- add_operation(:put, row_key, body, headers)
273
- self
274
- end
275
-
276
- # Public: Updates an existing entity by updating the entity's properties. This operation
277
- # does not replace the existing entity, as the update_entity operation does.
278
- #
279
- # ==== Attributes
280
- #
281
- # * +row_key+ - String. The row key
282
- # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
283
- # * +options+ - Hash. Optional parameters.
284
- #
285
- # ==== Options
286
- #
287
- # Accepted key/value pairs in options parameter are:
288
- # * +if_match+ - String. A matching condition which is required for update (optional, Default="*")
289
- # * +create_if_not_exists+ - Boolean. If true, and partition_key and row_key do not reference and existing entity,
290
- # that entity will be inserted. If false, the operation will fail. (optional, Default=false)
291
- # * +:accept+ - String. Specifies the accepted content-type of the response payload. Possible values are:
292
- # :no_meta
293
- # :min_meta
294
- # :full_meta
295
- #
296
- # See http://msdn.microsoft.com/en-us/library/azure/dd179392
297
- public
298
- def merge(row_key, entity_values, options = {})
299
- check_entity_key(row_key)
300
-
301
- headers = { Azure::Storage::Common::HeaderConstants::ACCEPT => Serialization.get_accept_string(options[:accept]) }
302
- headers["If-Match"] = options[:if_match] || "*" unless options[:create_if_not_exists]
303
-
304
- body = Serialization.hash_to_json(entity_values)
305
-
306
- add_operation(:merge, row_key, body, headers)
307
- self
308
- end
309
-
310
- # Public: Inserts or updates an existing entity within a table by merging new property values into the entity.
311
- #
312
- # ==== Attributes
313
- #
314
- # * +row_key+ - String. The row key
315
- # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
316
- #
317
- # See http://msdn.microsoft.com/en-us/library/azure/hh452241
318
- public
319
- def insert_or_merge(row_key, entity_values)
320
- merge(row_key, entity_values, create_if_not_exists: true)
321
- self
322
- end
323
-
324
- # Public: Inserts or updates a new entity into a table.
325
- #
326
- # ==== Attributes
327
- #
328
- # * +row_key+ - String. The row key
329
- # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
330
- #
331
- # See http://msdn.microsoft.com/en-us/library/azure/hh452242
332
- public
333
- def insert_or_replace(row_key, entity_values)
334
- update(row_key, entity_values, create_if_not_exists: true)
335
- self
336
- end
337
-
338
- # Public: Deletes an existing entity in the table.
339
- #
340
- # ==== Attributes
341
- #
342
- # * +row_key+ - String. The row key
343
- # * +options+ - Hash. Optional parameters.
344
- #
345
- # ==== Options
346
- #
347
- # Accepted key/value pairs in options parameter are:
348
- # * +if_match+ - String. A matching condition which is required for update (optional, Default="*")
349
- # * +:accept+ - String. Specifies the accepted content-type of the response payload. Possible values are:
350
- # :no_meta
351
- # :min_meta
352
- # :full_meta
353
- #
354
- # See http://msdn.microsoft.com/en-us/library/azure/dd135727
355
- public
356
- def delete(row_key, options = {})
357
- headers = {
358
- Azure::Storage::Common::HeaderConstants::ACCEPT => Serialization.get_accept_string(options[:accept]),
359
- "If-Match" => options[:if_match] || "*"
360
- }
361
- add_operation(:delete, row_key, nil, headers)
362
- self
363
- end
364
- end
365
- end
366
- end
1
+ #-------------------------------------------------------------------------
2
+ # # Copyright (c) Microsoft and contributors. All rights reserved.
3
+ #
4
+ # The MIT License(MIT)
5
+
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # of this software and associated documentation files(the "Software"), to deal
8
+ # in the Software without restriction, including without limitation the rights
9
+ # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
10
+ # copies of the Software, and to permit persons to whom the Software is
11
+ # furnished to do so, subject to the following conditions :
12
+
13
+ # The above copyright notice and this permission notice shall be included in
14
+ # all copies or substantial portions of the Software.
15
+
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
19
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ # THE SOFTWARE.
23
+ #--------------------------------------------------------------------------
24
+ require "securerandom"
25
+ require "azure/core/http/http_error"
26
+
27
+ module Azure::Storage
28
+ module Table
29
+ # Represents a batch of table operations.
30
+ #
31
+ # Example usage:
32
+ #
33
+ # svc = TableSerice.new
34
+ #
35
+ # batch = Batch.new "table", "partition"
36
+ # batch.insert "row1", {"meta"=>"data"}
37
+ # batch.insert "row2", {"meta"=>"data"}
38
+ #
39
+ # results = svc.execute_batch batch
40
+ #
41
+ class Batch
42
+ def initialize(table, partition, &block)
43
+ @table = table
44
+ @partition = partition
45
+ @operations = []
46
+ @entity_keys = []
47
+ @batch_id = "batch_" + SecureRandom.uuid
48
+ @changeset_id = "changeset_" + SecureRandom.uuid
49
+
50
+ self.instance_eval(&block) if block_given?
51
+ end
52
+
53
+ private
54
+ attr_reader :table
55
+ attr_reader :partition
56
+
57
+ attr_accessor :operations
58
+ attr_accessor :entity_keys
59
+ attr_accessor :changeset_id
60
+
61
+ public
62
+ attr_accessor :batch_id
63
+
64
+ protected
65
+ class ResponseWrapper
66
+ def initialize(hash)
67
+ @hash = hash
68
+ end
69
+
70
+ def uri
71
+ @hash[:uri]
72
+ end
73
+
74
+ def status_code
75
+ @hash[:status_code].to_i
76
+ end
77
+
78
+ def body
79
+ @hash[:body]
80
+ end
81
+ end
82
+
83
+ protected
84
+ def add_operation(method, row_key = nil, body = nil, headers = nil)
85
+ raise Azure::Storage::Common::Core::StorageError.new("Get operation should be the only operation in the batch.") if operations.length > 0 && (method == :get || operations[0][:method] == :get)
86
+ op = {
87
+ method: method,
88
+ row_key: row_key,
89
+ body: body,
90
+ headers: headers.merge(
91
+ Azure::Storage::Common::HeaderConstants::CONTENT_TYPE => Azure::Storage::Common::HeaderConstants::JSON_CONTENT_TYPE_VALUE,
92
+ Azure::Storage::Common::HeaderConstants::DATA_SERVICE_VERSION => TableConstants::DEFAULT_DATA_SERVICE_VERSION
93
+ )
94
+ }
95
+ operations.push op
96
+ end
97
+
98
+ protected
99
+ def check_entity_key(key)
100
+ raise ArgumentError, "Only allowed to perform a single operation per entity, and there is already a operation registered in this batch for the key: #{key}." if entity_keys.include? key
101
+ entity_keys.push key
102
+ end
103
+
104
+ public
105
+ def parse_response(response)
106
+ responses = BatchResponse.parse response.body, (!operations.empty? && operations[0][:method] == :get)
107
+ new_responses = []
108
+
109
+ (0..responses.length - 1).each { |index|
110
+ operation = operations[index]
111
+ response = responses[index]
112
+
113
+ if response[:status_code].to_i > 299
114
+ # failed
115
+ error = Azure::Core::Http::HTTPError.new(ResponseWrapper.new(response.merge(uri: operation[:uri])))
116
+ error.description = response[:message] if (error.description || "").strip == ""
117
+ raise error
118
+ else
119
+ # success
120
+ case operation[:method]
121
+ when :post, :get
122
+ # entity from body
123
+ entity = Serialization.entity_from_json(response[:body])
124
+
125
+ entity.etag = response[:headers]["etag"] if entity.etag.nil?
126
+
127
+ new_responses.push entity
128
+ when :put, :merge
129
+ # etag from headers
130
+ new_responses.push response[:headers]["etag"]
131
+ when :delete
132
+ # true
133
+ new_responses.push nil
134
+ end
135
+ end
136
+ }
137
+
138
+ new_responses
139
+ end
140
+
141
+ public
142
+ def to_body(table_service)
143
+ body = ""
144
+ body.define_singleton_method(:add_line) do |a| self << (a || nil) + "\n" end
145
+
146
+ is_get = true if !operations.empty? && operations[0][:method] == :get
147
+
148
+ body.add_line "--#{batch_id}"
149
+ body.add_line "Content-Type: multipart/mixed; boundary=#{changeset_id}" unless is_get
150
+ body.add_line "" unless is_get
151
+
152
+ operations.each { |op|
153
+ uri = table_service.entities_uri(@table, @partition, op[:row_key])
154
+ body.add_line "--#{changeset_id}" unless is_get
155
+ body.add_line "Content-Type: application/http"
156
+ body.add_line "Content-Transfer-Encoding: binary"
157
+ body.add_line ""
158
+ body.add_line "#{op[:method].to_s.upcase} #{uri} HTTP/1.1"
159
+
160
+ if op[:headers]
161
+ op[:headers].each { |k, v|
162
+ body.add_line "#{k}: #{v}"
163
+ }
164
+ end
165
+
166
+ if op[:body]
167
+ body.add_line "Content-Length: #{op[:body].bytesize}"
168
+ body.add_line ""
169
+ body.add_line op[:body]
170
+ else
171
+ body.add_line ""
172
+ end
173
+
174
+ }
175
+ body.add_line "--#{changeset_id}--" unless is_get
176
+ body.add_line "--#{batch_id}--"
177
+ end
178
+
179
+ # Public: Inserts new entity to the table.
180
+ #
181
+ # ==== Attributes
182
+ #
183
+ # * +row_key+ - String. The row key
184
+ # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
185
+ # * +options+ - Hash. Optional parameters.
186
+ #
187
+ # ==== Options
188
+ #
189
+ # Accepted key/value pairs in options parameter are:
190
+ # * +:accept+ - String. Specifies the accepted content-type of the response payload. Possible values are:
191
+ # :no_meta
192
+ # :min_meta
193
+ # :full_meta
194
+ # * +:prefer+ - String. Specifies whether the response should include the inserted entity in the payload. Possible values are:
195
+ # Azure::Storage::Common::HeaderConstants::PREFER_CONTENT
196
+ # Azure::Storage::Common::HeaderConstants::PREFER_NO_CONTENT
197
+ #
198
+ # See http://msdn.microsoft.com/en-us/library/azure/dd179433
199
+ public
200
+ def insert(row_key, entity_values, options = {})
201
+ check_entity_key(row_key)
202
+
203
+ headers = { Azure::Storage::Common::HeaderConstants::ACCEPT => Serialization.get_accept_string(options[:accept]) }
204
+ headers[Azure::Storage::Common::HeaderConstants::PREFER] = options[:prefer] unless options[:prefer].nil?
205
+
206
+ body = Serialization.hash_to_json({
207
+ "PartitionKey" => partition,
208
+ "RowKey" => row_key
209
+ }.merge(entity_values)
210
+ )
211
+
212
+ add_operation(:post, nil, body, headers)
213
+ self
214
+ end
215
+
216
+ # Public: Gets entity from the table.
217
+ #
218
+ # ==== Attributes
219
+ #
220
+ # * +row_key+ - String. The row key
221
+ # * +options+ - Hash. Optional parameters.
222
+ #
223
+ # ==== Options
224
+ #
225
+ # Accepted key/value pairs in options parameter are:
226
+ # * +:accept+ - String. Specifies the accepted content-type of the response payload. Possible values are:
227
+ # :no_meta
228
+ # :min_meta
229
+ # :full_meta
230
+ #
231
+ # See http://msdn.microsoft.com/en-us/library/azure/dd179433
232
+ public
233
+ def get(row_key, options = {})
234
+ check_entity_key(row_key)
235
+
236
+ headers = { Azure::Storage::Common::HeaderConstants::ACCEPT => Serialization.get_accept_string(options[:accept]) }
237
+
238
+ add_operation(:get, row_key, nil, headers)
239
+ self
240
+ end
241
+
242
+ # Public: Updates an existing entity in a table. The Update Entity operation replaces
243
+ # the entire entity and can be used to remove properties.
244
+ #
245
+ # ==== Attributes
246
+ #
247
+ # * +row_key+ - String. The row key
248
+ # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
249
+ # * +options+ - Hash. Optional parameters.
250
+ #
251
+ # ==== Options
252
+ #
253
+ # Accepted key/value pairs in options parameter are:
254
+ # * :if_match - String. A matching condition which is required for update (optional, Default="*")
255
+ # * :create_if_not_exists - Boolean. If true, and partition_key and row_key do not reference and existing entity,
256
+ # that entity will be inserted. If false, the operation will fail. (optional, Default=false)
257
+ # * +:accept+ - String. Specifies the accepted content-type of the response payload. Possible values are:
258
+ # :no_meta
259
+ # :min_meta
260
+ # :full_meta
261
+ #
262
+ # See http://msdn.microsoft.com/en-us/library/azure/dd179427
263
+ public
264
+ def update(row_key, entity_values, options = {})
265
+ check_entity_key(row_key)
266
+
267
+ headers = { Azure::Storage::Common::HeaderConstants::ACCEPT => Serialization.get_accept_string(options[:accept]) }
268
+ headers["If-Match"] = options[:if_match] || "*" unless options[:create_if_not_exists]
269
+
270
+ body = Serialization.hash_to_json(entity_values)
271
+
272
+ add_operation(:put, row_key, body, headers)
273
+ self
274
+ end
275
+
276
+ # Public: Updates an existing entity by updating the entity's properties. This operation
277
+ # does not replace the existing entity, as the update_entity operation does.
278
+ #
279
+ # ==== Attributes
280
+ #
281
+ # * +row_key+ - String. The row key
282
+ # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
283
+ # * +options+ - Hash. Optional parameters.
284
+ #
285
+ # ==== Options
286
+ #
287
+ # Accepted key/value pairs in options parameter are:
288
+ # * +if_match+ - String. A matching condition which is required for update (optional, Default="*")
289
+ # * +create_if_not_exists+ - Boolean. If true, and partition_key and row_key do not reference and existing entity,
290
+ # that entity will be inserted. If false, the operation will fail. (optional, Default=false)
291
+ # * +:accept+ - String. Specifies the accepted content-type of the response payload. Possible values are:
292
+ # :no_meta
293
+ # :min_meta
294
+ # :full_meta
295
+ #
296
+ # See http://msdn.microsoft.com/en-us/library/azure/dd179392
297
+ public
298
+ def merge(row_key, entity_values, options = {})
299
+ check_entity_key(row_key)
300
+
301
+ headers = { Azure::Storage::Common::HeaderConstants::ACCEPT => Serialization.get_accept_string(options[:accept]) }
302
+ headers["If-Match"] = options[:if_match] || "*" unless options[:create_if_not_exists]
303
+
304
+ body = Serialization.hash_to_json(entity_values)
305
+
306
+ add_operation(:merge, row_key, body, headers)
307
+ self
308
+ end
309
+
310
+ # Public: Inserts or updates an existing entity within a table by merging new property values into the entity.
311
+ #
312
+ # ==== Attributes
313
+ #
314
+ # * +row_key+ - String. The row key
315
+ # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
316
+ #
317
+ # See http://msdn.microsoft.com/en-us/library/azure/hh452241
318
+ public
319
+ def insert_or_merge(row_key, entity_values)
320
+ merge(row_key, entity_values, create_if_not_exists: true)
321
+ self
322
+ end
323
+
324
+ # Public: Inserts or updates a new entity into a table.
325
+ #
326
+ # ==== Attributes
327
+ #
328
+ # * +row_key+ - String. The row key
329
+ # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
330
+ #
331
+ # See http://msdn.microsoft.com/en-us/library/azure/hh452242
332
+ public
333
+ def insert_or_replace(row_key, entity_values)
334
+ update(row_key, entity_values, create_if_not_exists: true)
335
+ self
336
+ end
337
+
338
+ # Public: Deletes an existing entity in the table.
339
+ #
340
+ # ==== Attributes
341
+ #
342
+ # * +row_key+ - String. The row key
343
+ # * +options+ - Hash. Optional parameters.
344
+ #
345
+ # ==== Options
346
+ #
347
+ # Accepted key/value pairs in options parameter are:
348
+ # * +if_match+ - String. A matching condition which is required for update (optional, Default="*")
349
+ # * +:accept+ - String. Specifies the accepted content-type of the response payload. Possible values are:
350
+ # :no_meta
351
+ # :min_meta
352
+ # :full_meta
353
+ #
354
+ # See http://msdn.microsoft.com/en-us/library/azure/dd135727
355
+ public
356
+ def delete(row_key, options = {})
357
+ headers = {
358
+ Azure::Storage::Common::HeaderConstants::ACCEPT => Serialization.get_accept_string(options[:accept]),
359
+ "If-Match" => options[:if_match] || "*"
360
+ }
361
+ add_operation(:delete, row_key, nil, headers)
362
+ self
363
+ end
364
+ end
365
+ end
366
+ end