azure-storage 0.12.3.preview → 0.13.0.preview

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8698a09fa46c65d7407493f269ea6c5446e12d99
4
- data.tar.gz: ef47aa9a97b2391a46a5aed571c91105251609da
3
+ metadata.gz: 2a070f6404238f71f22cb9b6d6cf520710da9d3e
4
+ data.tar.gz: 47aa7276488561d83324937bbd5622c368491ce3
5
5
  SHA512:
6
- metadata.gz: 04ad168a8c0618869c1f93ef570de15191648dcc48e87912c0630547b6843f6b25e2ddd3fcffe6797d8a66d6acb81495fd6072bad8c5f6d62f4b0f596009d75d
7
- data.tar.gz: 8953cd7851fd19f94a7f5d81ed1114ff646a0761a4263c5aba48b3662c57cb0d4763680f0a1fd1dff90e5d2d8ed7d750fdde14ba57353ab237d1d521ca38d8aa
6
+ metadata.gz: 9747b0fee5eed2dfa431cdfcfbf6bbec93b8de3fe2d21397c4638595a547e05b557c28324ee967e80e13a015b9b4fa43c78a2aa8e9cb913e133fa54ff44b3b2a
7
+ data.tar.gz: b2aa8f4ce38f1d1e56aa4408bc73ad7516d5b6577b3bcf914ed16343eb434e0864f577d066b166bfb22cea71e6eaed9c1164d5c4816b8447fd576ad785ec1ea4
@@ -36,7 +36,7 @@ module Azure::Storage
36
36
  attr_accessor :size
37
37
  attr_accessor :type
38
38
  end
39
-
39
+
40
40
  # Public: Creates a new block blob or updates the content of an existing block blob.
41
41
  #
42
42
  # Updating an existing block blob overwrites any existing metadata on the blob
@@ -28,7 +28,7 @@ require 'azure/storage/version'
28
28
  module Azure::Storage
29
29
  module Default
30
30
  # Default REST service (STG) version number
31
- STG_VERSION = '2015-04-05'
31
+ STG_VERSION = '2016-05-31'
32
32
 
33
33
  # The number of default concurrent requests for parallel operation.
34
34
  DEFAULT_PARALLEL_OPERATION_THREAD_COUNT = 1
@@ -47,13 +47,13 @@ module Azure::Storage
47
47
  # Default HTTP port.
48
48
  DEFAULT_HTTP_PORT = 80
49
49
  # Default HTTPS port.
50
- DEFAULT_HTTPS_PORT= 443
50
+ DEFAULT_HTTPS_PORT = 443
51
51
 
52
52
  # Marker for atom metadata.
53
53
  XML_METADATA_MARKER = '$'
54
54
  # Marker for atom value.
55
55
  XML_VALUE_MARKER = '_'
56
-
56
+
57
57
  def os
58
58
  host_os = RbConfig::CONFIG['host_os']
59
59
  case host_os
@@ -69,17 +69,17 @@ module Azure::Storage
69
69
  "Unknown #{host_os}"
70
70
  end
71
71
  end
72
-
72
+
73
73
  module_function :os
74
74
 
75
75
  # Default User Agent header string
76
76
  USER_AGENT = "Azure-Storage/#{Azure::Storage::Version.to_uas} (Ruby #{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}; #{os})".freeze
77
-
77
+
78
78
  class << self
79
79
  def options
80
- Hash[Azure::Storage::Configurable.keys.map{|key| [key, send(key)]}]
80
+ Hash[Azure::Storage::Configurable.keys.map { |key| [key, send(key)] }]
81
81
  end
82
-
82
+
83
83
  # Default storage access key
84
84
  # @return [String]
85
85
  def storage_access_key
@@ -91,7 +91,7 @@ module Azure::Storage
91
91
  def storage_account_name
92
92
  ENV['AZURE_STORAGE_ACCOUNT']
93
93
  end
94
-
94
+
95
95
  # Default storage connection string
96
96
  # @return [String]
97
97
  def storage_connection_string
@@ -121,7 +121,7 @@ module Azure::Storage
121
121
  def storage_queue_host
122
122
  ENV['AZURE_STORAGE_QUEUE_HOST']
123
123
  end
124
-
124
+
125
125
  # Default storage file host
126
126
  # @return [String]
127
127
  def storage_file_host
@@ -405,6 +405,9 @@ module Azure::Storage
405
405
  # Constant representing the type for an entity property.
406
406
  ODATA_TYPE_MARKER = '$'
407
407
 
408
+ # Constant representing the hash key of etag for an entity property in JSON.
409
+ ODATA_ETAG = 'odata.etag'
410
+
408
411
  # The value to set the maximum data service version header.
409
412
  DEFAULT_DATA_SERVICE_VERSION = '3.0;NetFx'
410
413
 
@@ -414,6 +417,12 @@ module Azure::Storage
414
417
  # The name of the special table used to store tables.
415
418
  TABLE_SERVICE_TABLE_NAME = 'Tables'
416
419
 
420
+ # The key of partition key in hash
421
+ PARTITION_KEY = 'PartitionKey'
422
+
423
+ # The key of row key in hash
424
+ ROW_KEY = 'RowKey'
425
+
417
426
  # Operations
418
427
  module Operations
419
428
  RETRIEVE = 'RETRIEVE'
@@ -447,7 +456,7 @@ module Azure::Storage
447
456
  LAST_MODIFIED = 'Last-Modified'
448
457
 
449
458
  # The data service version.
450
- DATA_SERVICE_VERSION = 'dataserviceversion'
459
+ DATA_SERVICE_VERSION = 'DataServiceVersion'
451
460
 
452
461
  # The maximum data service version.
453
462
  MAX_DATA_SERVICE_VERSION = 'maxdataserviceversion'
@@ -555,7 +564,7 @@ module Azure::Storage
555
564
  CONTENT_RANGE = 'cache-range'
556
565
 
557
566
  # The ContentType header.
558
- CONTENT_TYPE = 'content-type'
567
+ CONTENT_TYPE = 'Content-Type'
559
568
 
560
569
  # The header that specifies blob content type.
561
570
  BLOB_CONTENT_TYPE = 'x-ms-blob-content-type'
@@ -594,8 +603,7 @@ module Azure::Storage
594
603
  INCLUDE_SNAPSHOTS_VALUE = 'include'
595
604
 
596
605
  # Specifies that the content-type is JSON.
597
- JSON_CONTENT_TYPE_VALUE = 'application/json;'
598
-
606
+ JSON_CONTENT_TYPE_VALUE = 'application/json'
599
607
 
600
608
  # The header that specifies lease ID.
601
609
  LEASE_ID = 'x-ms-lease-id'
@@ -715,7 +723,7 @@ module Azure::Storage
715
723
  LEASE_ACTION = 'x-ms-lease-action'
716
724
 
717
725
  # The accept header.
718
- ACCEPT = 'accept'
726
+ ACCEPT = 'Accept'
719
727
 
720
728
  # The accept charset header.
721
729
  ACCEPT_CHARSET = 'Accept-Charset'
@@ -743,10 +751,18 @@ module Azure::Storage
743
751
 
744
752
  # The append blob committed block header.
745
753
  BLOB_COMMITTED_BLOCK_COUNT = 'x-ms-blob-committed-block-count'
754
+
755
+ # The returned response payload should be with no metadata.
756
+ ODATA_NO_META = 'application/json;odata=nometadata'
757
+
758
+ # The returned response payload should be with minimal metadata.
759
+ ODATA_MIN_META = 'application/json;odata=minimalmetadata'
760
+
761
+ # The returned response payload should be with full metadata.
762
+ ODATA_FULL_META = 'application/json;odata=fullmetadata'
746
763
  end
747
764
 
748
765
  module QueryStringConstants
749
-
750
766
  # Query component for SAS API version.
751
767
  API_VERSION = 'api-version'
752
768
 
@@ -872,6 +888,9 @@ module Azure::Storage
872
888
 
873
889
  # The ending Partition Key for tableSAS URI's.
874
890
  ENDRK = 'erk'
891
+
892
+ # ACL
893
+ ACL = 'acl'
875
894
  end
876
895
 
877
896
  module StorageServiceClientConstants
@@ -49,7 +49,7 @@ module Azure::Storage
49
49
  super(signer, account_name, options)
50
50
  end
51
51
 
52
- def call(method, uri, body=nil, headers={}, options={})
52
+ def call(method, uri, body=nil, headers={}, options = {})
53
53
  super(method, uri, body, StorageService.common_headers(options).merge(headers))
54
54
  end
55
55
 
@@ -106,12 +106,15 @@ module Azure::Storage
106
106
  end
107
107
 
108
108
  protected
109
- def add_operation(method, uri, body=nil, headers=nil)
109
+ def add_operation(method, uri, body = nil, headers = nil)
110
110
  op = {
111
- :method => method,
112
- :uri => uri,
113
- :body => body,
114
- :headers => headers
111
+ method: method,
112
+ uri: uri,
113
+ body: body,
114
+ headers: headers.merge(
115
+ HeaderConstants::CONTENT_TYPE => HeaderConstants::JSON_CONTENT_TYPE_VALUE,
116
+ HeaderConstants::DATA_SERVICE_VERSION => TableConstants::DEFAULT_DATA_SERVICE_VERSION
117
+ )
115
118
  }
116
119
  operations.push op
117
120
  end
@@ -141,13 +144,9 @@ module Azure::Storage
141
144
  case operation[:method]
142
145
  when :post
143
146
  # entity from body
144
- result = Azure::Storage::Table::Serialization.hash_from_entry_xml(response[:body])
147
+ entity = Azure::Storage::Table::Serialization.entity_from_json(response[:body])
145
148
 
146
- entity = Azure::Storage::Table::Entity.new
147
- entity.table = table
148
- entity.updated = result[:updated]
149
- entity.etag = response[:headers]["etag"] || result[:etag]
150
- entity.properties = result[:properties]
149
+ entity.etag = response[:headers]["etag"] if entity.etag.nil?
151
150
 
152
151
  new_responses.push entity
153
152
  when :put, :merge
@@ -172,31 +171,27 @@ module Azure::Storage
172
171
  body.add_line "Content-Type: multipart/mixed; boundary=#{changeset_id}"
173
172
  body.add_line ""
174
173
 
175
- content_id = 1
176
174
  operations.each { |op|
177
175
  body.add_line "--#{changeset_id}"
178
176
  body.add_line "Content-Type: application/http"
179
177
  body.add_line "Content-Transfer-Encoding: binary"
180
178
  body.add_line ""
181
179
  body.add_line "#{op[:method].to_s.upcase} #{op[:uri]} HTTP/1.1"
182
- body.add_line "Content-ID: #{content_id}"
183
180
 
184
181
  if op[:headers]
185
- op[:headers].each { |k,v|
186
- body.add_line "#{k}: #{v}"
182
+ op[:headers].each { |k, v|
183
+ body.add_line "#{k}: #{v}"
187
184
  }
188
185
  end
189
-
186
+
190
187
  if op[:body]
191
- body.add_line "Content-Type: application/atom+xml;type=entry"
192
188
  body.add_line "Content-Length: #{op[:body].bytesize}"
193
189
  body.add_line ""
194
190
  body.add_line op[:body]
195
191
  else
196
192
  body.add_line ""
197
- end
193
+ end
198
194
 
199
- content_id += 1
200
195
  }
201
196
  body.add_line "--#{changeset_id}--"
202
197
  body.add_line "--#{batch_id}--"
@@ -207,81 +202,105 @@ module Azure::Storage
207
202
  # ==== Attributes
208
203
  #
209
204
  # * +row_key+ - String. The row key
210
- # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
205
+ # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
206
+ # * +options+ - Hash. Optional parameters.
207
+ #
208
+ # ==== Options
209
+ #
210
+ # Accepted key/value pairs in options parameter are:
211
+ # * +:accept+ - String. Specifies the accepted content-type of the response payload. Possible values are:
212
+ # :no_meta
213
+ # :min_meta
214
+ # :full_meta
215
+ # * +:prefer+ - String. Specifies whether the response should include the inserted entity in the payload. Possible values are:
216
+ # HeaderConstants::PREFER_CONTENT
217
+ # HeaderConstants::PREFER_NO_CONTENT
211
218
  #
212
219
  # See http://msdn.microsoft.com/en-us/library/azure/dd179433
213
220
  public
214
- def insert(row_key, entity_values)
221
+ def insert(row_key, entity_values, options = {})
215
222
  check_entity_key(row_key)
216
223
 
217
- body = Azure::Storage::Table::Serialization.hash_to_entry_xml({
218
- "PartitionKey" => partition,
224
+ headers = { HeaderConstants::ACCEPT => Table::Serialization.get_accept_string(options[:accept]) }
225
+ headers[HeaderConstants::PREFER] = options[:prefer] unless options[:prefer].nil?
226
+
227
+ body = Azure::Storage::Table::Serialization.hash_to_json({
228
+ "PartitionKey" => partition,
219
229
  "RowKey" => row_key
220
- }.merge(entity_values) ).to_xml
230
+ }.merge(entity_values)
231
+ )
221
232
 
222
- add_operation(:post, @table_service.entities_uri(table), body)
233
+ add_operation(:post, @table_service.entities_uri(table), body, headers)
223
234
  self
224
235
  end
225
236
 
226
- # Public: Updates an existing entity in a table. The Update Entity operation replaces
237
+ # Public: Updates an existing entity in a table. The Update Entity operation replaces
227
238
  # the entire entity and can be used to remove properties.
228
239
  #
229
240
  # ==== Attributes
230
241
  #
231
242
  # * +row_key+ - String. The row key
232
- # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
233
- # * +options+ - Hash. Optional parameters.
243
+ # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
244
+ # * +options+ - Hash. Optional parameters.
234
245
  #
235
246
  # ==== Options
236
247
  #
237
248
  # Accepted key/value pairs in options parameter are:
238
249
  # * :if_match - String. A matching condition which is required for update (optional, Default="*")
239
- # * :create_if_not_exists - Boolean. If true, and partition_key and row_key do not reference and existing entity,
250
+ # * :create_if_not_exists - Boolean. If true, and partition_key and row_key do not reference and existing entity,
240
251
  # that entity will be inserted. If false, the operation will fail. (optional, Default=false)
252
+ # * +:accept+ - String. Specifies the accepted content-type of the response payload. Possible values are:
253
+ # :no_meta
254
+ # :min_meta
255
+ # :full_meta
241
256
  #
242
257
  # See http://msdn.microsoft.com/en-us/library/azure/dd179427
243
258
  public
244
- def update(row_key, entity_values, options={})
259
+ def update(row_key, entity_values, options = {})
245
260
  check_entity_key(row_key)
246
261
 
247
262
  uri = @table_service.entities_uri(table, partition, row_key)
248
263
 
249
- headers = {}
264
+ headers = { HeaderConstants::ACCEPT => Table::Serialization.get_accept_string(options[:accept]) }
250
265
  headers["If-Match"] = options[:if_match] || "*" unless options[:create_if_not_exists]
251
266
 
252
- body = Azure::Storage::Table::Serialization.hash_to_entry_xml(entity_values).to_xml
267
+ body = Azure::Storage::Table::Serialization.hash_to_json(entity_values)
253
268
 
254
269
  add_operation(:put, uri, body, headers)
255
270
  self
256
271
  end
257
-
272
+
258
273
  # Public: Updates an existing entity by updating the entity's properties. This operation
259
274
  # does not replace the existing entity, as the update_entity operation does.
260
275
  #
261
276
  # ==== Attributes
262
277
  #
263
278
  # * +row_key+ - String. The row key
264
- # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
265
- # * +options+ - Hash. Optional parameters.
279
+ # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
280
+ # * +options+ - Hash. Optional parameters.
266
281
  #
267
282
  # ==== Options
268
283
  #
269
284
  # Accepted key/value pairs in options parameter are:
270
285
  # * +if_match+ - String. A matching condition which is required for update (optional, Default="*")
271
- # * +create_if_not_exists+ - Boolean. If true, and partition_key and row_key do not reference and existing entity,
286
+ # * +create_if_not_exists+ - Boolean. If true, and partition_key and row_key do not reference and existing entity,
272
287
  # that entity will be inserted. If false, the operation will fail. (optional, Default=false)
273
- #
288
+ # * +:accept+ - String. Specifies the accepted content-type of the response payload. Possible values are:
289
+ # :no_meta
290
+ # :min_meta
291
+ # :full_meta
292
+ #
274
293
  # See http://msdn.microsoft.com/en-us/library/azure/dd179392
275
294
  public
276
- def merge(row_key, entity_values, options={})
295
+ def merge(row_key, entity_values, options = {})
277
296
  check_entity_key(row_key)
278
297
 
279
298
  uri = @table_service.entities_uri(table, partition, row_key)
280
299
 
281
- headers = {}
300
+ headers = { HeaderConstants::ACCEPT => Table::Serialization.get_accept_string(options[:accept]) }
282
301
  headers["If-Match"] = options[:if_match] || "*" unless options[:create_if_not_exists]
283
302
 
284
- body = Azure::Storage::Table::Serialization.hash_to_entry_xml(entity_values).to_xml
303
+ body = Azure::Storage::Table::Serialization.hash_to_json(entity_values)
285
304
 
286
305
  add_operation(:merge, uri, body, headers)
287
306
  self
@@ -293,11 +312,11 @@ module Azure::Storage
293
312
  #
294
313
  # * +row_key+ - String. The row key
295
314
  # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
296
- #
315
+ #
297
316
  # See http://msdn.microsoft.com/en-us/library/azure/hh452241
298
317
  public
299
318
  def insert_or_merge(row_key, entity_values)
300
- merge(row_key, entity_values, { :create_if_not_exists => true })
319
+ merge(row_key, entity_values, create_if_not_exists: true)
301
320
  self
302
321
  end
303
322
 
@@ -306,12 +325,12 @@ module Azure::Storage
306
325
  # ==== Attributes
307
326
  #
308
327
  # * +row_key+ - String. The row key
309
- # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
310
- #
328
+ # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
329
+ #
311
330
  # See http://msdn.microsoft.com/en-us/library/azure/hh452242
312
331
  public
313
332
  def insert_or_replace(row_key, entity_values)
314
- update(row_key, entity_values, { :create_if_not_exists => true })
333
+ update(row_key, entity_values, create_if_not_exists: true)
315
334
  self
316
335
  end
317
336
 
@@ -320,19 +339,27 @@ module Azure::Storage
320
339
  # ==== Attributes
321
340
  #
322
341
  # * +row_key+ - String. The row key
323
- # * +options+ - Hash. Optional parameters.
342
+ # * +options+ - Hash. Optional parameters.
324
343
  #
325
344
  # ==== Options
326
345
  #
327
346
  # Accepted key/value pairs in options parameter are:
328
347
  # * +if_match+ - String. A matching condition which is required for update (optional, Default="*")
348
+ # * +:accept+ - String. Specifies the accepted content-type of the response payload. Possible values are:
349
+ # :no_meta
350
+ # :min_meta
351
+ # :full_meta
329
352
  #
330
353
  # See http://msdn.microsoft.com/en-us/library/azure/dd135727
331
354
  public
332
- def delete(row_key, options={})
333
- add_operation(:delete, @table_service.entities_uri(table, partition, row_key), nil, {"If-Match"=> options[:if_match] || "*"})
355
+ def delete(row_key, options = {})
356
+ headers = {
357
+ HeaderConstants::ACCEPT => Table::Serialization.get_accept_string(options[:accept]),
358
+ "If-Match" => options[:if_match] || "*"
359
+ }
360
+ add_operation(:delete, @table_service.entities_uri(table, partition, row_key), nil, headers)
334
361
  self
335
362
  end
336
363
  end
337
364
  end
338
- end
365
+ end
@@ -68,13 +68,7 @@ module Azure::Storage
68
68
  when "Edm.Binary"
69
69
  Base64.encode64(value.to_s).chomp("\n")
70
70
  when "Edm.DateTime"
71
- value.xmlschema(7)
72
- when "Edm.Boolean"
73
- if value.nil?
74
- ''
75
- else
76
- value == true ? '1' : '0'
77
- end
71
+ to_edm_time(value)
78
72
  else
79
73
  value.to_s
80
74
  end
@@ -113,7 +107,7 @@ module Azure::Storage
113
107
  # type - String. The Edm datatype
114
108
  #
115
109
  # Returns an typed object
116
- def self.unserialize_query_value(value, type)
110
+ def self.deserialize_value(value, type)
117
111
  case type
118
112
  when "Edm.DateTime"
119
113
  Time.parse(value)
@@ -122,15 +116,20 @@ module Azure::Storage
122
116
  when "Edm.Int32", "Edm.Int64"
123
117
  Integer(value)
124
118
  when "Edm.Boolean"
125
- /true/i === value
119
+ value == true || value == 'true' ? true : false
126
120
  when "Edm.Guid"
127
121
  GUID.new(value.to_s)
128
122
  when "Edm.Binary"
129
123
  Base64.decode64(value.to_s).force_encoding("BINARY")
130
124
  else
131
- value.to_s
125
+ value == '' ? nil : value.to_s
132
126
  end
133
127
  end
128
+
129
+ def self.to_edm_time(value)
130
+ date = value.is_a?(Time) ? value : Time.parse(value)
131
+ date.utc.strftime('%Y-%m-%dT%H:%M:%S.%6N0Z')
132
+ end
134
133
  end
135
134
  end
136
135
  end
@@ -31,8 +31,6 @@ module Azure::Storage
31
31
  yield self if block_given?
32
32
  end
33
33
 
34
- attr_accessor :table
35
- attr_accessor :updated
36
34
  attr_accessor :etag
37
35
  attr_accessor :properties
38
36
  end
@@ -25,93 +25,95 @@ require 'azure/storage/service/serialization'
25
25
 
26
26
  require 'azure/storage/table/guid'
27
27
  require 'azure/storage/table/edmtype'
28
+ require 'azure/storage/table/entity'
28
29
 
29
30
  require 'time'
30
31
  require 'date'
31
-
32
- module Azure::Storage
33
- module Table
34
- module Serialization
35
- include Azure::Storage::Service::Serialization
36
-
37
- def self.hash_to_entry_xml(hash, id=nil, xml=Nokogiri::XML::Builder.new(:encoding => 'UTF-8'))
38
- entry_namespaces = {
39
- 'xmlns' => 'http://www.w3.org/2005/Atom',
40
- 'xmlns:m' => 'http://schemas.microsoft.com/ado/2007/08/dataservices/metadata',
41
- 'xmlns:d' => 'http://schemas.microsoft.com/ado/2007/08/dataservices'
42
- }
43
-
44
- xml.entry entry_namespaces do |entry|
45
- id ? entry.id(id): entry.id
46
- entry.updated Time.now.xmlschema
47
- entry.title
48
- entry.author do |author|
49
- author.name
50
- end
51
- hash_to_content_xml(hash, entry)
32
+ require 'json'
33
+
34
+ module Azure
35
+ module Storage
36
+ module Table
37
+ # This is a class that serializes the request/response body for table
38
+ # service.
39
+ module Serialization
40
+ include Azure::Storage::Service::Serialization
41
+
42
+ def self.hash_to_json(h)
43
+ newhash = {}
44
+ h.map do |key, val|
45
+ type = Table::EdmType.property_type(val)
46
+ type_key = key.is_a?(Symbol) ? key.to_s + TableConstants::ODATA_TYPE_SUFFIX : key + TableConstants::ODATA_TYPE_SUFFIX
47
+ newhash[key] = EdmType::serialize_value(type, val)
48
+ newhash[type_key] = type unless type.nil? || type.empty? || h.key?(type_key)
49
+ end
50
+ JSON newhash
52
51
  end
53
52
 
54
- xml
55
- end
56
-
57
- def self.hash_to_content_xml(hash, xml=Nokogiri::XML::Builder.new(:encoding => 'UTF-8'))
58
- xml.send('content', :type => 'application/xml') do |content|
59
- content.send('m:properties') do |properties|
60
- hash.each do |key, val|
61
- key = key.encode('UTF-8') if key.is_a? String and !key.encoding.names.include?('BINARY')
62
- val = val.encode('UTF-8') if val.is_a? String and !val.encoding.names.include?('BINARY')
53
+ def self.table_entries_from_json(json)
54
+ table_entries_from_hash(hash_from_json(json))
55
+ end
63
56
 
64
- type = Azure::Storage::Table::EdmType.property_type(val)
65
- attributes = {}
66
- attributes['m:type'] = type unless type.nil? || type.empty?
57
+ def self.hash_from_json(json)
58
+ JSON.parse(json)
59
+ end
67
60
 
68
- if val.nil?
69
- attributes['m:null'] = 'true'
70
- properties.send("d:#{key}", attributes)
71
- else
72
- properties.send("d:#{key}", Azure::Storage::Table::EdmType.serialize_value(type, val), attributes)
73
- end
61
+ def self.table_entries_from_hash(h)
62
+ values = []
63
+ if h['value']
64
+ h['value'].each do |name|
65
+ values.push(name)
74
66
  end
67
+ elsif h['TableName']
68
+ values = h
75
69
  end
70
+ values
76
71
  end
77
72
 
78
- xml
79
- end
73
+ def self.entity_from_json(json)
74
+ entity_from_hash(hash_from_json(json))
75
+ end
80
76
 
81
- def self.entries_from_feed_xml(xml)
82
- xml = slopify(xml)
83
- expect_node('feed', xml)
77
+ def self.entities_from_json(json)
78
+ entities_hash = hash_from_json(json)
79
+ entities_hash['value'].nil? ? [entity_from_hash(entities_hash)] : entities_from_hash(entities_hash)
80
+ end
84
81
 
85
- return nil unless (xml > 'entry').any?
86
-
87
- results = []
88
-
89
- if (xml > 'entry').count == 0
90
- results.push hash_from_entry_xml((xml > 'entry'))
91
- else
92
- (xml > 'entry').each do |entry|
93
- results.push hash_from_entry_xml(entry)
94
- end
82
+ def self.entities_from_hash(h)
83
+ entities = []
84
+ h['value'].each { |entity_hash|
85
+ entities.push(entity_from_hash(entity_hash))
86
+ }
87
+ entities
95
88
  end
96
89
 
97
- results
98
- end
90
+ def self.entity_from_hash(h)
91
+ Entity.new do |entity|
92
+ entity.etag = h.delete(TableConstants::ODATA_ETAG)
93
+ properties = {}
94
+ h.each do |k, v|
95
+ type = h[k + TableConstants::ODATA_TYPE_SUFFIX]
96
+ properties[k] = EdmType::deserialize_value(v, type.nil? ? EdmType::property_type(v) : type)
97
+ end
98
+ entity.properties = properties
99
+ end
100
+ end
99
101
 
100
- def self.hash_from_entry_xml(xml)
101
- xml = slopify(xml)
102
- expect_node('entry', xml)
103
- result = {}
104
- result[:etag] = xml['etag']
105
- result[:updated] = Time.parse((xml > 'updated').text) if (xml > 'updated').any?
106
- properties = {}
107
- if (xml > 'content').any?
108
- (xml > 'content').first.first_element_child.element_children.each do |prop|
109
- properties[prop.name] = prop.text != '' ? Azure::Storage::Table::EdmType.unserialize_query_value(prop.text, prop['m:type']) : prop['null'] ? nil : ''
102
+ def self.get_accept_string(accept_type = :min_meta)
103
+ case accept_type
104
+ when :no_meta
105
+ HeaderConstants::ODATA_NO_META
106
+ when :min_meta
107
+ HeaderConstants::ODATA_MIN_META
108
+ when :full_meta
109
+ HeaderConstants::ODATA_FULL_META
110
+ when nil
111
+ HeaderConstants::ODATA_MIN_META
112
+ else
113
+ accept_type
110
114
  end
111
115
  end
112
- result[:properties] = properties
113
- result
114
116
  end
115
117
  end
116
118
  end
117
- end
119
+ end
@@ -52,16 +52,26 @@ module Azure::Storage
52
52
  # * +:timeout+ - Integer. A timeout in seconds.
53
53
  # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
54
54
  # in the analytics logs when storage analytics logging is enabled.
55
+ # * +:accept+ - String. Specifies the accepted content-type of the response payload. Possible values are:
56
+ # :no_meta
57
+ # :min_meta
58
+ # :full_meta
59
+ # * +:prefer+ - String. Specifies whether the response should include the inserted entity in the payload. Possible values are:
60
+ # HeaderConstants::PREFER_CONTENT
61
+ # HeaderConstants::PREFER_NO_CONTENT
55
62
  #
56
63
  # See http://msdn.microsoft.com/en-us/library/azure/dd135729
57
64
  #
58
65
  # @return [nil] on success
59
66
  def create_table(table_name, options={})
60
- query = { }
61
- query['timeout'] = options[:timeout].to_s if options[:timeout]
62
67
 
63
- body = Table::Serialization.hash_to_entry_xml({"TableName" => table_name}).to_xml
64
- call(:post, collection_uri(query), body, {}, options)
68
+ headers = {
69
+ HeaderConstants::ACCEPT => Table::Serialization.get_accept_string(options[:accept]),
70
+ }
71
+ headers[HeaderConstants::PREFER] = options[:prefer] unless options[:prefer].nil?
72
+ body = Serialization.hash_to_json({"TableName" => table_name})
73
+
74
+ call(:post, collection_uri(new_query(options)), body, headers, options)
65
75
  nil
66
76
  end
67
77
 
@@ -83,10 +93,8 @@ module Azure::Storage
83
93
  #
84
94
  # Returns nil on success
85
95
  def delete_table(table_name, options={})
86
- query = { }
87
- query["timeout"] = options[:timeout].to_s if options[:timeout]
88
96
 
89
- call(:delete, table_uri(table_name, query), nil, {}, options)
97
+ call(:delete, table_uri(table_name, new_query(options)), nil, {}, options)
90
98
  nil
91
99
  end
92
100
 
@@ -106,12 +114,11 @@ module Azure::Storage
106
114
  #
107
115
  # Returns the last updated time for the table
108
116
  def get_table(table_name, options={})
109
- query = { }
110
- query["timeout"] = options[:timeout].to_s if options[:timeout]
111
-
112
- response = call(:get, table_uri(table_name, query), nil, {}, options)
113
- results = Table::Serialization.hash_from_entry_xml(response.body)
114
- results[:updated]
117
+ headers = {
118
+ HeaderConstants::ACCEPT => Table::Serialization.get_accept_string(:full_meta),
119
+ }
120
+ response = call(:get, table_uri(table_name, new_query(options)), nil, headers, options)
121
+ results = Table::Serialization.table_entries_from_json(response.body)
115
122
  rescue => e
116
123
  raise_with_response(e, response)
117
124
  end
@@ -130,21 +137,27 @@ module Azure::Storage
130
137
  # * +:timeout+ - Integer. A timeout in seconds.
131
138
  # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
132
139
  # in the analytics logs when storage analytics logging is enabled.
140
+ # * +:accept+ - String. Specifies the accepted content-type of the response payload. Possible values are:
141
+ # :no_meta
142
+ # :min_meta
143
+ # :full_meta
133
144
  #
134
145
  # See http://msdn.microsoft.com/en-us/library/azure/dd179405
135
146
  #
136
147
  # Returns an array with an extra continuation_token property on success
137
148
  def query_tables(options={})
138
- query = { }
139
- query["NextTableName"] = options[:next_table_token] if options[:next_table_token]
140
- query["timeout"] = options[:timeout].to_s if options[:timeout]
149
+ query = new_query(options)
150
+ query[TableConstants::NEXT_TABLE_NAME] = options[:next_table_token] if options[:next_table_token]
141
151
  uri = collection_uri(query)
142
152
 
143
- response = call(:get, uri, nil, {}, options)
144
- entries = Table::Serialization.entries_from_feed_xml(response.body) || []
153
+ headers = {
154
+ HeaderConstants::ACCEPT => Table::Serialization.get_accept_string(options[:accept]),
155
+ }
145
156
 
157
+ response = call(:get, uri, nil, headers, options)
158
+ entries = Table::Serialization.table_entries_from_json(response.body) || []
146
159
  values = Azure::Service::EnumerationResults.new(entries)
147
- values.continuation_token = response.headers["x-ms-continuation-NextTableName"]
160
+ values.continuation_token = response.headers[TableConstants::CONTINUATION_NEXT_TABLE_NAME]
148
161
  values
149
162
  rescue => e
150
163
  raise_with_response(e, response)
@@ -168,13 +181,13 @@ module Azure::Storage
168
181
  #
169
182
  # Returns a list of Azure::Storage::Entity::SignedIdentifier instances
170
183
  def get_table_acl(table_name, options={})
171
- query = { 'comp' => 'acl'}
172
- query['timeout'] = options[:timeout].to_s if options[:timeout]
184
+ query = new_query(options)
185
+ query[QueryStringConstants::COMP] = QueryStringConstants::ACL
173
186
 
174
187
  response = call(:get, generate_uri(table_name, query), nil, {'x-ms-version' => '2012-02-12'}, options)
175
188
 
176
189
  signed_identifiers = []
177
- signed_identifiers = Table::Serialization.signed_identifiers_from_xml response.body unless response.body == nil or response.body.length < 1
190
+ signed_identifiers = Table::Serialization.signed_identifiers_from_xml response.body unless response.body == nil || response.body.length < 1
178
191
  signed_identifiers
179
192
  rescue => e
180
193
  raise_with_response(e, response)
@@ -199,8 +212,8 @@ module Azure::Storage
199
212
  #
200
213
  # Returns nil on success
201
214
  def set_table_acl(table_name, options={})
202
- query = { 'comp' => 'acl'}
203
- query['timeout'] = options[:timeout].to_s if options[:timeout]
215
+ query = new_query(options)
216
+ query[QueryStringConstants::COMP] = QueryStringConstants::ACL
204
217
 
205
218
  uri = generate_uri(table_name, query)
206
219
  body = nil
@@ -223,27 +236,26 @@ module Azure::Storage
223
236
  #
224
237
  # Accepted key/value pairs in options parameter are:
225
238
  # * +:timeout+ - Integer. A timeout in seconds.
226
- # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
239
+ # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
227
240
  # in the analytics logs when storage analytics logging is enabled.
241
+ # * +:accept+ - String. Specifies the accepted content-type of the response payload. Possible values are:
242
+ # :no_meta
243
+ # :min_meta
244
+ # :full_meta
228
245
  #
229
246
  # See http://msdn.microsoft.com/en-us/library/azure/dd179433
230
247
  #
231
248
  # Returns a Azure::Storage::Entity::Table::Entity
232
- def insert_entity(table_name, entity_values, options={})
233
- body = Table::Serialization.hash_to_entry_xml(entity_values).to_xml
234
-
235
- query = { }
236
- query['timeout'] = options[:timeout].to_s if options[:timeout]
237
-
238
- response = call(:post, entities_uri(table_name, nil, nil, query), body, {}, options)
239
- result = Table::Serialization.hash_from_entry_xml(response.body)
240
-
241
- Entity.new do |entity|
242
- entity.table = table_name
243
- entity.updated = result[:updated]
244
- entity.etag = response.headers['etag'] || result[:etag]
245
- entity.properties = result[:properties]
246
- end
249
+ def insert_entity(table_name, entity_values, options = {})
250
+ body = Table::Serialization.hash_to_json(entity_values)
251
+ time = EdmType::to_edm_time(Time.now)
252
+ headers = {
253
+ HeaderConstants::ACCEPT => Table::Serialization.get_accept_string(options[:accept])
254
+ }
255
+ response = call(:post, entities_uri(table_name, nil, nil, new_query(options)), body, headers, options)
256
+ result = Table::Serialization.entity_from_json(response.body)
257
+ result.etag = response.headers[HeaderConstants::ETAG] if result.etag.nil?
258
+ result
247
259
  rescue => e
248
260
  raise_with_response(e, response)
249
261
  end
@@ -265,86 +277,79 @@ module Azure::Storage
265
277
  # * +:top+ - Integer. A limit for the number of results returned (optional)
266
278
  # * +:continuation_token+ - Hash. The continuation token.
267
279
  # * +:timeout+ - Integer. A timeout in seconds.
268
- # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
280
+ # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
269
281
  # in the analytics logs when storage analytics logging is enabled.
282
+ # * +:accept+ - String. Specifies the accepted content-type of the response payload. Possible values are:
283
+ # :no_meta
284
+ # :min_meta
285
+ # :full_meta
270
286
  #
271
287
  # See http://msdn.microsoft.com/en-us/library/azure/dd179421
272
288
  #
273
289
  # Returns an array with an extra continuation_token property on success
274
- def query_entities(table_name, options={})
275
- query ={}
276
- query["$select"] = options[:select].join ',' if options[:select]
277
- query["$filter"] = options[:filter] if options[:filter]
278
- query["$top"] = options[:top].to_s if options[:top] unless options[:partition_key] and options[:row_key]
279
- query["NextPartitionKey"] = options[:continuation_token][:next_partition_key] if options[:continuation_token] and options[:continuation_token][:next_partition_key]
280
- query["NextRowKey"] = options[:continuation_token][:next_row_key] if options[:continuation_token] and options[:continuation_token][:next_row_key]
281
- query["timeout"] = options[:timeout].to_s if options[:timeout]
290
+ def query_entities(table_name, options = {})
291
+ query = new_query(options)
292
+ query[QueryStringConstants::SELECT] = options[:select].join ',' if options[:select]
293
+ query[QueryStringConstants::FILTER] = options[:filter] if options[:filter]
294
+ query[QueryStringConstants::TOP] = options[:top].to_s if options[:top] unless options[:partition_key] && options[:row_key]
295
+ query[QueryStringConstants::NEXT_PARTITION_KEY] = options[:continuation_token][:next_partition_key] if options[:continuation_token] && options[:continuation_token][:next_partition_key]
296
+ query[QueryStringConstants::NEXT_ROW_KEY] = options[:continuation_token][:next_row_key] if options[:continuation_token] && options[:continuation_token][:next_row_key]
282
297
 
283
298
  uri = entities_uri(table_name, options[:partition_key], options[:row_key], query)
284
- response = call(:get, uri, nil, {"DataServiceVersion" => "2.0;NetFx"}, options)
285
-
286
- entities = Azure::Service::EnumerationResults.new
287
-
288
- results = (options[:partition_key] and options[:row_key]) ? [Table::Serialization.hash_from_entry_xml(response.body)] : Table::Serialization.entries_from_feed_xml(response.body)
289
-
290
- results.each do |result|
291
- entity = Entity.new do |e|
292
- e.table = table_name
293
- e.updated = result[:updated]
294
- e.etag = response.headers["etag"] || result[:etag]
295
- e.properties = result[:properties]
296
- end
297
- entities.push entity
298
- end if results
299
+
300
+ headers = {
301
+ HeaderConstants::ACCEPT => Table::Serialization.get_accept_string(options[:accept])
302
+ }
303
+
304
+ response = call(:get, uri, nil, headers, options)
305
+
306
+ entities = Azure::Service::EnumerationResults.new.push(*Table::Serialization.entities_from_json(response.body))
299
307
 
300
308
  entities.continuation_token = nil
301
- entities.continuation_token = {
302
- :next_partition_key=> response.headers["x-ms-continuation-NextPartitionKey"],
303
- :next_row_key => response.headers["x-ms-continuation-NextRowKey"]
304
- } if response.headers["x-ms-continuation-NextPartitionKey"]
309
+ entities.continuation_token = {
310
+ next_partition_key: response.headers[TableConstants::CONTINUATION_NEXT_PARTITION_KEY],
311
+ next_row_key: response.headers[TableConstants::CONTINUATION_NEXT_ROW_KEY]
312
+ } if response.headers[TableConstants::CONTINUATION_NEXT_PARTITION_KEY]
305
313
 
306
314
  entities
307
315
  rescue => e
308
316
  raise_with_response(e, response)
309
317
  end
310
318
 
311
- # Public: Updates an existing entity in a table. The Update Entity operation replaces
319
+ # Public: Updates an existing entity in a table. The Update Entity operation replaces
312
320
  # the entire entity and can be used to remove properties.
313
321
  #
314
322
  # ==== Attributes
315
323
  #
316
324
  # * +table_name+ - String. The table name
317
325
  # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
318
- # * +options+ - Hash. Optional parameters.
326
+ # * +options+ - Hash. Optional parameters.
319
327
  #
320
328
  # ==== Options
321
329
  #
322
330
  # Accepted key/value pairs in options parameter are:
323
331
  # * +:if_match+ - String. A matching condition which is required for update (optional, Default="*")
324
- # * +:create_if_not_exists+ - Boolean. If true, and partition_key and row_key do not reference and existing entity,
332
+ # * +:create_if_not_exists+ - Boolean. If true, and partition_key and row_key do not reference and existing entity,
325
333
  # that entity will be inserted. If false, the operation will fail. (optional, Default=false)
326
334
  # * +:timeout+ - Integer. A timeout in seconds.
327
- # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
335
+ # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
328
336
  # in the analytics logs when storage analytics logging is enabled.
329
337
  #
330
338
  # See http://msdn.microsoft.com/en-us/library/azure/dd179427
331
339
  #
332
- # Returns the ETag for the entity on success
333
- def update_entity(table_name, entity_values, options={})
340
+ # Returns the ETag for the entity on success
341
+ def update_entity(table_name, entity_values, options = {})
334
342
  if_match = "*"
335
343
  if_match = options[:if_match] if options[:if_match]
336
344
 
337
- query = { }
338
- query["timeout"] = options[:timeout].to_s if options[:timeout]
339
-
340
- uri = entities_uri(table_name,
345
+ uri = entities_uri(table_name,
341
346
  entity_values[:PartitionKey] || entity_values['PartitionKey'],
342
- entity_values[:RowKey] || entity_values["RowKey"], query)
347
+ entity_values[:RowKey] || entity_values["RowKey"], new_query(options))
343
348
 
344
349
  headers = {}
345
350
  headers["If-Match"] = if_match || "*" unless options[:create_if_not_exists]
346
351
 
347
- body = Table::Serialization.hash_to_entry_xml(entity_values).to_xml
352
+ body = Table::Serialization.hash_to_json(entity_values)
348
353
 
349
354
  response = call(:put, uri, body, headers, options)
350
355
  response.headers["etag"]
@@ -359,36 +364,33 @@ module Azure::Storage
359
364
  #
360
365
  # * +table_name+ - String. The table name
361
366
  # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
362
- # * +options+ - Hash. Optional parameters.
367
+ # * +options+ - Hash. Optional parameters.
363
368
  #
364
369
  # ==== Options
365
370
  #
366
371
  # Accepted key/value pairs in options parameter are:
367
372
  # * +:if_match+ - String. A matching condition which is required for update (optional, Default="*")
368
- # * +:create_if_not_exists+ - Boolean. If true, and partition_key and row_key do not reference and existing entity,
373
+ # * +:create_if_not_exists+ - Boolean. If true, and partition_key and row_key do not reference and existing entity,
369
374
  # that entity will be inserted. If false, the operation will fail. (optional, Default=false)
370
375
  # * +:timeout+ - Integer. A timeout in seconds.
371
- # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
376
+ # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
372
377
  # in the analytics logs when storage analytics logging is enabled.
373
- #
378
+ #
374
379
  # See http://msdn.microsoft.com/en-us/library/azure/dd179392
375
- #
376
- # Returns the ETag for the entity on success
377
- def merge_entity(table_name, entity_values, options={})
380
+ #
381
+ # Returns the ETag for the entity on success
382
+ def merge_entity(table_name, entity_values, options = {})
378
383
  if_match = "*"
379
384
  if_match = options[:if_match] if options[:if_match]
380
385
 
381
- query = { }
382
- query["timeout"] = options[:timeout].to_s if options[:timeout]
383
-
384
- uri = entities_uri(table_name,
386
+ uri = entities_uri(table_name,
385
387
  entity_values[:PartitionKey] || entity_values['PartitionKey'],
386
- entity_values[:RowKey] || entity_values['RowKey'], query)
388
+ entity_values[:RowKey] || entity_values['RowKey'], new_query(options))
387
389
 
388
- headers = { "X-HTTP-Method"=> "MERGE" }
390
+ headers = { "X-HTTP-Method" => "MERGE" }
389
391
  headers["If-Match"] = if_match || "*" unless options[:create_if_not_exists]
390
392
 
391
- body = Table::Serialization.hash_to_entry_xml(entity_values).to_xml
393
+ body = Table::Serialization.hash_to_json(entity_values)
392
394
 
393
395
  response = call(:post, uri, body, headers, options)
394
396
  response.headers["etag"]
@@ -402,19 +404,19 @@ module Azure::Storage
402
404
  #
403
405
  # * +table_name+ - String. The table name
404
406
  # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
405
- # * +options+ - Hash. Optional parameters.
407
+ # * +options+ - Hash. Optional parameters.
406
408
  #
407
409
  # ==== Options
408
410
  #
409
411
  # Accepted key/value pairs in options parameter are:
410
412
  # * +:timeout+ - Integer. A timeout in seconds.
411
- # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
413
+ # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
412
414
  # in the analytics logs when storage analytics logging is enabled.
413
- #
415
+ #
414
416
  # See http://msdn.microsoft.com/en-us/library/azure/hh452241
415
- #
416
- # Returns the ETag for the entity on success
417
- def insert_or_merge_entity(table_name, entity_values, options={})
417
+ #
418
+ # Returns the ETag for the entity on success
419
+ def insert_or_merge_entity(table_name, entity_values, options = {})
418
420
  options[:create_if_not_exists] = true
419
421
  merge_entity(table_name, entity_values, options)
420
422
  end
@@ -425,19 +427,19 @@ module Azure::Storage
425
427
  #
426
428
  # * +table_name+ - String. The table name
427
429
  # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
428
- # * +options+ - Hash. Optional parameters.
430
+ # * +options+ - Hash. Optional parameters.
429
431
  #
430
432
  # ==== Options
431
433
  #
432
434
  # Accepted key/value pairs in options parameter are:
433
435
  # * +:timeout+ - Integer. A timeout in seconds.
434
- # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
436
+ # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
435
437
  # in the analytics logs when storage analytics logging is enabled.
436
- #
438
+ #
437
439
  # See http://msdn.microsoft.com/en-us/library/azure/hh452242
438
440
  #
439
- # Returns the ETag for the entity on success
440
- def insert_or_replace_entity(table_name, entity_values, options={})
441
+ # Returns the ETag for the entity on success
442
+ def insert_or_replace_entity(table_name, entity_values, options = {})
441
443
  options[:create_if_not_exists] = true
442
444
  update_entity(table_name, entity_values, options)
443
445
  end
@@ -456,19 +458,17 @@ module Azure::Storage
456
458
  # Accepted key/value pairs in options parameter are:
457
459
  # * +:if_match+ - String. A matching condition which is required for update (optional, Default="*")
458
460
  # * +:timeout+ - Integer. A timeout in seconds.
459
- # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
461
+ # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
460
462
  # in the analytics logs when storage analytics logging is enabled.
461
463
  #
462
464
  # See http://msdn.microsoft.com/en-us/library/azure/dd135727
463
465
  #
464
466
  # Returns nil on success
465
- def delete_entity(table_name, partition_key, row_key, options={})
467
+ def delete_entity(table_name, partition_key, row_key, options = {})
466
468
  if_match = "*"
467
469
  if_match = options[:if_match] if options[:if_match]
468
470
 
469
- query = { }
470
- query["timeout"] = options[:timeout].to_s if options[:timeout]
471
- call(:delete, entities_uri(table_name, partition_key, row_key, query), nil, { "If-Match"=> if_match }, options)
471
+ call(:delete, entities_uri(table_name, partition_key, row_key, new_query(options)), nil, { "If-Match" => if_match }, options)
472
472
  nil
473
473
  end
474
474
 
@@ -491,16 +491,13 @@ module Azure::Storage
491
491
  # Returns an array of results, one for each operation in the batch
492
492
  def execute_batch(batch, options={})
493
493
  headers = {
494
- 'Content-Type' => "multipart/mixed; boundary=#{batch.batch_id}",
495
- 'Accept' => 'application/atom+xml,application/xml',
496
- 'Accept-Charset'=> 'UTF-8'
494
+ HeaderConstants::CONTENT_TYPE => "multipart/mixed; boundary=#{batch.batch_id}",
495
+ HeaderConstants::ACCEPT => Table::Serialization.get_accept_string(options[:accept]),
496
+ 'Accept-Charset' => 'UTF-8'
497
497
  }
498
498
 
499
- query = { }
500
- query["timeout"] = options[:timeout].to_s if options[:timeout]
501
-
502
499
  body = batch.to_body
503
- response = call(:post, generate_uri('/$batch', query), body, headers, options)
500
+ response = call(:post, generate_uri('/$batch', new_query(options)), body, headers, options, true)
504
501
  batch.parse_response(response)
505
502
  rescue => e
506
503
  raise_with_response(e, response)
@@ -523,7 +520,7 @@ module Azure::Storage
523
520
  # in the analytics logs when storage analytics logging is enabled.
524
521
  #
525
522
  # Returns an Azure::Storage::Table::Entity instance on success
526
- def get_entity(table_name, partition_key, row_key, options={})
523
+ def get_entity(table_name, partition_key, row_key, options = {})
527
524
  options[:partition_key] = partition_key
528
525
  options[:row_key] = row_key
529
526
  results = query_entities(table_name, options)
@@ -563,7 +560,7 @@ module Azure::Storage
563
560
  #
564
561
  # Returns a URI
565
562
  public
566
- def entities_uri(table_name, partition_key=nil, row_key=nil, query={})
563
+ def entities_uri(table_name, partition_key = nil, row_key = nil, query = {})
567
564
  return table_name if table_name.kind_of? ::URI
568
565
 
569
566
  path = if partition_key && row_key
@@ -618,6 +615,19 @@ module Azure::Storage
618
615
  raise e if response.nil?
619
616
  raise "Response header: #{response.headers.inspect}\nResponse body: #{response.body.inspect}\n#{e.inspect}\n#{e.backtrace.join("\n")}"
620
617
  end
618
+
619
+ protected
620
+ def call(method, uri, body = nil, headers = {}, options = {}, is_batch = false)
621
+ # Add JSON Content-Type header if is_batch is false because default is Atom.
622
+ headers[HeaderConstants::CONTENT_TYPE] = HeaderConstants::JSON_CONTENT_TYPE_VALUE unless is_batch
623
+ headers[HeaderConstants::DATA_SERVICE_VERSION] = TableConstants::DEFAULT_DATA_SERVICE_VERSION
624
+ super(method, uri, body, headers, options)
625
+ end
626
+
627
+ protected
628
+ def new_query(options = {})
629
+ options[:timeout].nil? ? {} : { QueryStringConstants::TIMEOUT => options[:timeout].to_s }
630
+ end
621
631
  end
622
632
  end
623
633
  end
@@ -27,8 +27,8 @@ module Azure
27
27
  class Version
28
28
  # Fields represent the parts defined in http://semver.org/
29
29
  MAJOR = 0 unless defined? MAJOR
30
- MINOR = 12 unless defined? MINOR
31
- UPDATE = 3 unless defined? UPDATE
30
+ MINOR = 13 unless defined? MINOR
31
+ UPDATE = 0 unless defined? UPDATE
32
32
  PRE = 'preview' unless defined? PRE
33
33
 
34
34
  class << self
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: azure-storage
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.3.preview
4
+ version: 0.13.0.preview
5
5
  platform: ruby
6
6
  authors:
7
7
  - Microsoft Corporation
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-08-11 00:00:00.000000000 Z
11
+ date: 2017-09-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: azure-core
@@ -52,6 +52,26 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0.10'
55
+ - !ruby/object:Gem::Dependency
56
+ name: nokogiri
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.6'
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: 1.6.8
65
+ type: :runtime
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - "~>"
70
+ - !ruby/object:Gem::Version
71
+ version: '1.6'
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: 1.6.8
55
75
  - !ruby/object:Gem::Dependency
56
76
  name: dotenv
57
77
  requirement: !ruby/object:Gem::Requirement