azure-storage 0.12.3.preview → 0.13.0.preview

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
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