azure-storage-table 1.0.0 → 2.0.3

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.
@@ -1,775 +1,778 @@
1
- # frozen_string_literal: true
2
-
3
- #-------------------------------------------------------------------------
4
- # # Copyright (c) Microsoft and contributors. All rights reserved.
5
- #
6
- # The MIT License(MIT)
7
-
8
- # Permission is hereby granted, free of charge, to any person obtaining a copy
9
- # of this software and associated documentation files(the "Software"), to deal
10
- # in the Software without restriction, including without limitation the rights
11
- # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
12
- # copies of the Software, and to permit persons to whom the Software is
13
- # furnished to do so, subject to the following conditions :
14
-
15
- # The above copyright notice and this permission notice shall be included in
16
- # all copies or substantial portions of the Software.
17
-
18
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
21
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
- # THE SOFTWARE.
25
- #--------------------------------------------------------------------------
26
- require "azure/storage/table/auth/shared_key"
27
-
28
- module Azure::Storage
29
- include Azure::Storage::Common::Service
30
- StorageService = Azure::Storage::Common::Service::StorageService
31
-
32
- module Table
33
- class TableService < StorageService
34
- class << self
35
- # Public: Creates an instance of [Azure::Storage::Table::TableService]
36
- #
37
- # ==== Attributes
38
- #
39
- # * +options+ - Hash. Optional parameters.
40
- #
41
- # ==== Options
42
- #
43
- # Accepted key/value pairs in options parameter are:
44
- #
45
- # * +:use_development_storage+ - TrueClass|FalseClass. Whether to use storage emulator.
46
- # * +:development_storage_proxy_uri+ - String. Used with +:use_development_storage+ if emulator is hosted other than localhost.
47
- # * +:storage_account_name+ - String. The name of the storage account.
48
- # * +:storage_access_key+ - Base64 String. The access key of the storage account.
49
- # * +:storage_sas_token+ - String. The signed access signature for the storage account or one of its service.
50
- # * +:storage_table_host+ - String. Specified Table service endpoint or hostname
51
- # * +:storage_dns_suffix+ - String. The suffix of a regional Storage Service, to
52
- # * +:default_endpoints_protocol+ - String. http or https
53
- # * +:use_path_style_uri+ - String. Whether use path style URI for specified endpoints
54
- # * +:ca_file+ - String. File path of the CA file if having issue with SSL
55
- # * +:user_agent_prefix+ - String. The user agent prefix that can identify the application calls the library
56
- #
57
- # The valid set of options include:
58
- # * Storage Emulator: +:use_development_storage+ required, +:development_storage_proxy_uri+ optionally
59
- # * Storage account name and key: +:storage_account_name+ and +:storage_access_key+ required, set +:storage_dns_suffix+ necessarily
60
- # * Storage account name and SAS token: +:storage_account_name+ and +:storage_sas_token+ required, set +:storage_dns_suffix+ necessarily
61
- # * Specified hosts and SAS token: At least one of the service host and SAS token. It's up to user to ensure the SAS token is suitable for the serivce
62
- # * Anonymous Table: only +:storage_table_host+, if it is to only access tables within a container
63
- #
64
- # Additional notes:
65
- # * Specified hosts can be set when use account name with access key or sas token
66
- # * +:default_endpoints_protocol+ can be set if the scheme is not specified in hosts
67
- # * Storage emulator always use path style URI
68
- # * +:ca_file+ is independent.
69
- #
70
- # When empty options are given, it will try to read settings from Environment Variables. Refer to [Azure::Storage::Common::ClientOptions.env_vars_mapping] for the mapping relationship
71
- #
72
- # @return [Azure::Storage::Table::TableService]
73
- def create(options = {}, &block)
74
- service_options = { client: Azure::Storage::Common::Client::create(options, &block), api_version: Azure::Storage::Table::Default::STG_VERSION }
75
- service_options[:user_agent_prefix] = options[:user_agent_prefix] if options[:user_agent_prefix]
76
- Azure::Storage::Table::TableService.new(service_options, &block)
77
- end
78
-
79
- # Public: Creates an instance of [Azure::Storage::Table::TableService] with Storage Emulator
80
- #
81
- # ==== Attributes
82
- #
83
- # * +proxy_uri+ - String. Used with +:use_development_storage+ if emulator is hosted other than localhost.
84
- #
85
- # @return [Azure::Storage::Table::TableService]
86
- def create_development(proxy_uri = nil, &block)
87
- service_options = { client: Azure::Storage::Common::Client::create_development(proxy_uri, &block), api_version: Azure::Storage::Table::Default::STG_VERSION }
88
- Azure::Storage::Table::TableService.new(service_options, &block)
89
- end
90
-
91
- # Public: Creates an instance of [Azure::Storage::Table::TableService] from Environment Variables
92
- #
93
- # @return [Azure::Storage::Table::TableService]
94
- def create_from_env(&block)
95
- service_options = { client: Azure::Storage::Common::Client::create_from_env(&block), api_version: Azure::Storage::Table::Default::STG_VERSION }
96
- Azure::Storage::Table::TableService.new(service_options, &block)
97
- end
98
-
99
- # Public: Creates an instance of [Azure::Storage::Table::TableService] from Environment Variables
100
- #
101
- # ==== Attributes
102
- #
103
- # * +connection_string+ - String. Please refer to https://azure.microsoft.com/en-us/documentation/articles/storage-configure-connection-string/.
104
- #
105
- # @return [Azure::Storage::Table::TableService]
106
- def create_from_connection_string(connection_string, &block)
107
- service_options = { client: Azure::Storage::Common::Client::create_from_connection_string(connection_string, &block), api_version: Azure::Storage::Table::Default::STG_VERSION }
108
- Azure::Storage::Table::TableService.new(service_options, &block)
109
- end
110
- end
111
-
112
- # Public: Initializes an instance of [Azure::Storage::Table::TableService]
113
- #
114
- # ==== Attributes
115
- #
116
- # * +options+ - Hash. Optional parameters.
117
- #
118
- # ==== Options
119
- #
120
- # Accepted key/value pairs in options parameter are:
121
- #
122
- # * +:use_development_storage+ - TrueClass|FalseClass. Whether to use storage emulator.
123
- # * +:development_storage_proxy_uri+ - String. Used with +:use_development_storage+ if emulator is hosted other than localhost.
124
- # * +:storage_connection_string+ - String. The storage connection string.
125
- # * +:storage_account_name+ - String. The name of the storage account.
126
- # * +:storage_access_key+ - Base64 String. The access key of the storage account.
127
- # * +:storage_sas_token+ - String. The signed access signature for the storage account or one of its service.
128
- # * +:storage_table_host+ - String. Specified Table serivce endpoint or hostname
129
- # * +:storage_dns_suffix+ - String. The suffix of a regional Storage Serivce, to
130
- # * +:default_endpoints_protocol+ - String. http or https
131
- # * +:use_path_style_uri+ - String. Whether use path style URI for specified endpoints
132
- # * +:ca_file+ - String. File path of the CA file if having issue with SSL
133
- # * +:user_agent_prefix+ - String. The user agent prefix that can identify the application calls the library
134
- # * +:client+ - Azure::Storage::Common::Client. The common client used to initalize the service.
135
- #
136
- # The valid set of options include:
137
- # * Storage Emulator: +:use_development_storage+ required, +:development_storage_proxy_uri+ optionally
138
- # * Storage account name and key: +:storage_account_name+ and +:storage_access_key+ required, set +:storage_dns_suffix+ necessarily
139
- # * Storage account name and SAS token: +:storage_account_name+ and +:storage_sas_token+ required, set +:storage_dns_suffix+ necessarily
140
- # * Specified hosts and SAS token: At least one of the service host and SAS token. It's up to user to ensure the SAS token is suitable for the serivce
141
- # * Azure::Storage::Common::Client: The common client used to initalize the service. This client can be initalized and used repeatedly.
142
- # * Anonymous Table: only +:storage_table_host+, if it is to only access tables within a container
143
- #
144
- # Additional notes:
145
- # * Specified hosts can be set when use account name with access key or sas token
146
- # * +:default_endpoints_protocol+ can be set if the scheme is not specified in hosts
147
- # * Storage emulator always use path style URI
148
- # * +:ca_file+ is independent.
149
- #
150
- # When empty options are given, it will try to read settings from Environment Variables. Refer to [Azure::Storage::Common::ClientOptions.env_vars_mapping] for the mapping relationship
151
- def initialize(options = {}, &block)
152
- service_options = options.clone
153
- client_config = service_options[:client] ||= Azure::Storage::Common::Client::create(service_options, &block)
154
- @user_agent_prefix = service_options[:user_agent_prefix] if service_options[:user_agent_prefix]
155
- @api_version = service_options[:api_version] || Azure::Storage::Table::Default::STG_VERSION
156
- signer = service_options[:signer] || client_config.signer || Auth::SharedKey.new(client_config.storage_account_name, client_config.storage_access_key)
157
- signer.api_ver = @api_version if signer.is_a? Azure::Storage::Common::Core::Auth::SharedAccessSignatureSigner
158
- super(signer, client_config.storage_account_name, service_options, &block)
159
- @storage_service_host[:primary] = client.storage_table_host
160
- @storage_service_host[:secondary] = client.storage_table_host true
161
- end
162
-
163
- # Public: Creates new table in the storage account
164
- #
165
- # ==== Attributes
166
- #
167
- # * +table_name+ - String. The table name
168
- # * +options+ - Hash. Optional parameters.
169
- #
170
- # ==== Options
171
- #
172
- # Accepted key/value pairs in options parameter are:
173
- #
174
- # * +:timeout+ - Integer. A timeout in seconds.
175
- # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
176
- # in the analytics logs when storage analytics logging is enabled.
177
- # * +:accept+ - String. Specifies the accepted content-type of the response payload. Possible values are:
178
- # :no_meta
179
- # :min_meta
180
- # :full_meta
181
- # * +:prefer+ - String. Specifies whether the response should include the inserted entity in the payload. Possible values are:
182
- # Azure::Storage::Common::HeaderConstants::PREFER_CONTENT
183
- # Azure::Storage::Common::HeaderConstants::PREFER_NO_CONTENT
184
- #
185
- # See http://msdn.microsoft.com/en-us/library/azure/dd135729
186
- #
187
- # @return [nil] on success
188
- def create_table(table_name, options = {})
189
- headers = {
190
- Azure::Storage::Common::HeaderConstants::ACCEPT => Serialization.get_accept_string(options[:accept]),
191
- }
192
- headers[Azure::Storage::Common::HeaderConstants::PREFER] = options[:prefer] unless options[:prefer].nil?
193
- body = Serialization.hash_to_json("TableName" => table_name)
194
-
195
- call(:post, collection_uri(new_query(options)), body, headers, options)
196
- nil
197
- end
198
-
199
- # Public: Deletes the specified table and any data it contains.
200
- #
201
- # ==== Attributes
202
- #
203
- # * +table_name+ - String. The table name
204
- # * +options+ - Hash. Optional parameters.
205
- #
206
- # ==== Options
207
- #
208
- # Accepted key/value pairs in options parameter are:
209
- # * +:timeout+ - Integer. A timeout in seconds.
210
- # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
211
- # in the analytics logs when storage analytics logging is enabled.
212
- #
213
- # See http://msdn.microsoft.com/en-us/library/azure/dd179387
214
- #
215
- # Returns nil on success
216
- def delete_table(table_name, options = {})
217
- call(:delete, table_uri(table_name, new_query(options)), nil, {}, options)
218
- nil
219
- end
220
-
221
- # Public: Gets the table.
222
- #
223
- # ==== Attributes
224
- #
225
- # * +table_name+ - String. The table name
226
- # * +options+ - Hash. Optional parameters.
227
- #
228
- # ==== Options
229
- #
230
- # Accepted key/value pairs in options parameter are:
231
- # * +:timeout+ - Integer. A timeout in seconds.
232
- # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
233
- # in the analytics logs when storage analytics logging is enabled.
234
- # * +:location_mode+ - LocationMode. Specifies the location mode used to decide
235
- # which location the request should be sent to.
236
- #
237
- # Returns the last updated time for the table
238
- def get_table(table_name, options = {})
239
- headers = {
240
- Azure::Storage::Common::HeaderConstants::ACCEPT => Serialization.get_accept_string(:full_meta),
241
- }
242
- options[:request_location_mode] = Azure::Storage::Common::RequestLocationMode::PRIMARY_OR_SECONDARY
243
- response = call(:get, table_uri(table_name, new_query(options), options), nil, headers, options)
244
- Serialization.table_entries_from_json(response.body)
245
- rescue => e
246
- raise_with_response(e, response)
247
- end
248
-
249
- # Public: Gets a list of all tables on the account.
250
- #
251
- # ==== Attributes
252
- #
253
- # * +options+ - Hash. Optional parameters.
254
- #
255
- # ==== Options
256
- #
257
- # Accepted key/value pairs in options parameter are:
258
- # * +:next_table_token+ - String. A token used to enumerate the next page of results, when the list of tables is
259
- # larger than a single operation can return at once. (optional)
260
- # * +:timeout+ - Integer. A timeout in seconds.
261
- # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
262
- # in the analytics logs when storage analytics logging is enabled.
263
- # * +:location_mode+ - LocationMode. Specifies the location mode used to decide
264
- # which location the request should be sent to.
265
- # * +:accept+ - String. Specifies the accepted content-type of the response payload. Possible values are:
266
- # :no_meta
267
- # :min_meta
268
- # :full_meta
269
- #
270
- # See http://msdn.microsoft.com/en-us/library/azure/dd179405
271
- #
272
- # Returns an array with an extra continuation_token property on success
273
- def query_tables(options = {})
274
- query = new_query(options)
275
- query[TableConstants::NEXT_TABLE_NAME] = options[:next_table_token] if options[:next_table_token]
276
-
277
- options[:request_location_mode] = Azure::Storage::Common::RequestLocationMode::PRIMARY_OR_SECONDARY
278
- uri = collection_uri(query, options)
279
-
280
- headers = {
281
- Azure::Storage::Common::HeaderConstants::ACCEPT => Serialization.get_accept_string(options[:accept]),
282
- }
283
-
284
- response = call(:get, uri, nil, headers, options)
285
- entries = Serialization.table_entries_from_json(response.body) || []
286
- values = Azure::Storage::Common::Service::EnumerationResults.new(entries)
287
- values.continuation_token = response.headers[TableConstants::CONTINUATION_NEXT_TABLE_NAME]
288
- values
289
- rescue => e
290
- raise_with_response(e, response)
291
- end
292
-
293
- # Public: Gets the access control list (ACL) for the table.
294
- #
295
- # ==== Attributes
296
- #
297
- # * +table_name+ - String. The table name
298
- # * +options+ - Hash. Optional parameters.
299
- #
300
- # ==== Options
301
- #
302
- # Accepted key/value pairs in options parameter are:
303
- # * +:timeout+ - Integer. A timeout in seconds.
304
- # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
305
- # in the analytics logs when storage analytics logging is enabled.
306
- # * +:location_mode+ - LocationMode. Specifies the location mode used to decide
307
- # which location the request should be sent to.
308
- #
309
- # See http://msdn.microsoft.com/en-us/library/azure/jj159100
310
- #
311
- # Returns a list of Azure::Storage::Entity::SignedIdentifier instances
312
- def get_table_acl(table_name, options = {})
313
- query = new_query(options)
314
- query[Azure::Storage::Common::QueryStringConstants::COMP] = Azure::Storage::Common::QueryStringConstants::ACL
315
-
316
- options[:request_location_mode] = Azure::Storage::Common::RequestLocationMode::PRIMARY_OR_SECONDARY
317
- response = call(:get, generate_uri(table_name, query, options), nil, { "x-ms-version" => "2012-02-12" }, options)
318
-
319
- signed_identifiers = []
320
- signed_identifiers = Serialization.signed_identifiers_from_xml response.body unless response.body == nil || response.body.length < 1
321
- signed_identifiers
322
- rescue => e
323
- raise_with_response(e, response)
324
- end
325
-
326
- # Public: Sets the access control list (ACL) for the table.
327
- #
328
- # ==== Attributes
329
- #
330
- # * +table_name+ - String. The table name
331
- # * +options+ - Hash. Optional parameters.
332
- #
333
- # ==== Options
334
- #
335
- # Accepted key/value pairs in options parameter are:
336
- # * +:signed_identifiers+ - Array. A list of Azure::Storage::Entity::SignedIdentifier instances
337
- # * +:timeout+ - Integer. A timeout in seconds.
338
- # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
339
- # in the analytics logs when storage analytics logging is enabled.
340
- #
341
- # See http://msdn.microsoft.com/en-us/library/azure/jj159102
342
- #
343
- # Returns nil on success
344
- def set_table_acl(table_name, options = {})
345
- query = new_query(options)
346
- query[Azure::Storage::Common::QueryStringConstants::COMP] = Azure::Storage::Common::QueryStringConstants::ACL
347
-
348
- uri = generate_uri(table_name, query)
349
- body = nil
350
- body = Serialization.signed_identifiers_to_xml options[:signed_identifiers] if options[:signed_identifiers] && options[:signed_identifiers].length > 0
351
-
352
- call(:put, uri, body, { "x-ms-version" => "2012-02-12" }, options)
353
- nil
354
- end
355
-
356
- # Public: Inserts new entity to the table.
357
- #
358
- #
359
- # ==== Attributes
360
- #
361
- # * +table_name+ - String. The table name
362
- # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
363
- # * +options+ - Hash. Optional parameters.
364
- #
365
- # ==== Options
366
- #
367
- # Accepted key/value pairs in options parameter are:
368
- # * +:timeout+ - Integer. A timeout in seconds.
369
- # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
370
- # in the analytics logs when storage analytics logging is enabled.
371
- # * +:accept+ - String. Specifies the accepted content-type of the response payload. Possible values are:
372
- # :no_meta
373
- # :min_meta
374
- # :full_meta
375
- #
376
- # See http://msdn.microsoft.com/en-us/library/azure/dd179433
377
- #
378
- # Returns a Azure::Storage::Entity::Table::Entity
379
- def insert_entity(table_name, entity_values, options = {})
380
- body = Serialization.hash_to_json(entity_values)
381
- #time = EdmType::to_edm_time(Time.now)
382
- headers = {
383
- Azure::Storage::Common::HeaderConstants::ACCEPT => Serialization.get_accept_string(options[:accept])
384
- }
385
- response = call(:post, entities_uri(table_name, nil, nil, new_query(options)), body, headers, options)
386
- result = Serialization.entity_from_json(response.body)
387
- result.etag = response.headers[Azure::Storage::Common::HeaderConstants::ETAG] if result.etag.nil?
388
- result
389
- rescue => e
390
- raise_with_response(e, response)
391
- end
392
-
393
- # Public: Queries entities for the given table name
394
- #
395
- # ==== Attributes
396
- #
397
- # * +table_name+ - String. The table name
398
- # * +options+ - Hash. Optional parameters.
399
- #
400
- # ==== Options
401
- #
402
- # Accepted key/value pairs in options parameter are:
403
- # * +:partition_key+ - String. The partition key (optional)
404
- # * +:row_key+ - String. The row key (optional)
405
- # * +:select+ - Array. An array of property names to return (optional)
406
- # * +:filter+ - String. A filter expression (optional)
407
- # * +:top+ - Integer. A limit for the number of results returned (optional)
408
- # * +:continuation_token+ - Hash. The continuation token.
409
- # * +:timeout+ - Integer. A timeout in seconds.
410
- # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
411
- # in the analytics logs when storage analytics logging is enabled.
412
- # * +:location_mode+ - LocationMode. Specifies the location mode used to decide
413
- # which location the request should be sent to.
414
- # * +:accept+ - String. Specifies the accepted content-type of the response payload. Possible values are:
415
- # :no_meta
416
- # :min_meta
417
- # :full_meta
418
- #
419
- # See http://msdn.microsoft.com/en-us/library/azure/dd179421
420
- #
421
- # Returns an array with an extra continuation_token property on success
422
- def query_entities(table_name, options = {})
423
- query = new_query(options)
424
- query[Azure::Storage::Common::QueryStringConstants::SELECT] = options[:select].join "," if options[:select]
425
- query[Azure::Storage::Common::QueryStringConstants::FILTER] = options[:filter] if options[:filter]
426
- query[Azure::Storage::Common::QueryStringConstants::TOP] = options[:top].to_s if options[:top] unless options[:partition_key] && options[:row_key]
427
- query[Azure::Storage::Common::QueryStringConstants::NEXT_PARTITION_KEY] = options[:continuation_token][:next_partition_key] if options[:continuation_token] && options[:continuation_token][:next_partition_key]
428
- query[Azure::Storage::Common::QueryStringConstants::NEXT_ROW_KEY] = options[:continuation_token][:next_row_key] if options[:continuation_token] && options[:continuation_token][:next_row_key]
429
-
430
- options[:request_location_mode] = Azure::Storage::Common::RequestLocationMode::PRIMARY_OR_SECONDARY
431
- uri = entities_uri(table_name, options[:partition_key], options[:row_key], query, options)
432
-
433
- headers = {
434
- Azure::Storage::Common::HeaderConstants::ACCEPT => Serialization.get_accept_string(options[:accept])
435
- }
436
-
437
- response = call(:get, uri, nil, headers, options)
438
-
439
- entities = Azure::Storage::Common::Service::EnumerationResults.new.push(*Serialization.entities_from_json(response.body))
440
-
441
- entities.continuation_token = nil
442
- entities.continuation_token = {
443
- next_partition_key: response.headers[TableConstants::CONTINUATION_NEXT_PARTITION_KEY],
444
- next_row_key: response.headers[TableConstants::CONTINUATION_NEXT_ROW_KEY]
445
- } if response.headers[TableConstants::CONTINUATION_NEXT_PARTITION_KEY]
446
-
447
- entities
448
- rescue => e
449
- raise_with_response(e, response)
450
- end
451
-
452
- # Public: Updates an existing entity in a table. The Update Entity operation replaces
453
- # the entire entity and can be used to remove properties.
454
- #
455
- # ==== Attributes
456
- #
457
- # * +table_name+ - String. The table name
458
- # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
459
- # * +options+ - Hash. Optional parameters.
460
- #
461
- # ==== Options
462
- #
463
- # Accepted key/value pairs in options parameter are:
464
- # * +:if_match+ - String. A matching condition which is required for update (optional, Default="*")
465
- # * +:create_if_not_exists+ - Boolean. If true, and partition_key and row_key do not reference and existing entity,
466
- # that entity will be inserted. If false, the operation will fail. (optional, Default=false)
467
- # * +:timeout+ - Integer. A timeout in seconds.
468
- # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
469
- # in the analytics logs when storage analytics logging is enabled.
470
- #
471
- # See http://msdn.microsoft.com/en-us/library/azure/dd179427
472
- #
473
- # Returns the ETag for the entity on success
474
- def update_entity(table_name, entity_values, options = {})
475
- if_match = "*"
476
- if_match = options[:if_match] if options[:if_match]
477
-
478
- uri = entities_uri(table_name,
479
- entity_values[:PartitionKey] || entity_values["PartitionKey"],
480
- entity_values[:RowKey] || entity_values["RowKey"], new_query(options))
481
-
482
- headers = {}
483
- headers["If-Match"] = if_match || "*" unless options[:create_if_not_exists]
484
-
485
- body = Serialization.hash_to_json(entity_values)
486
-
487
- response = call(:put, uri, body, headers, options)
488
- response.headers["etag"]
489
- rescue => e
490
- raise_with_response(e, response)
491
- end
492
-
493
- # Public: Updates an existing entity by updating the entity's properties. This operation
494
- # does not replace the existing entity, as the update_entity operation does.
495
- #
496
- # ==== Attributes
497
- #
498
- # * +table_name+ - String. The table name
499
- # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
500
- # * +options+ - Hash. Optional parameters.
501
- #
502
- # ==== Options
503
- #
504
- # Accepted key/value pairs in options parameter are:
505
- # * +:if_match+ - String. A matching condition which is required for update (optional, Default="*")
506
- # * +:create_if_not_exists+ - Boolean. If true, and partition_key and row_key do not reference and existing entity,
507
- # that entity will be inserted. If false, the operation will fail. (optional, Default=false)
508
- # * +:timeout+ - Integer. A timeout in seconds.
509
- # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
510
- # in the analytics logs when storage analytics logging is enabled.
511
- #
512
- # See http://msdn.microsoft.com/en-us/library/azure/dd179392
513
- #
514
- # Returns the ETag for the entity on success
515
- def merge_entity(table_name, entity_values, options = {})
516
- if_match = "*"
517
- if_match = options[:if_match] if options[:if_match]
518
-
519
- uri = entities_uri(table_name,
520
- entity_values[:PartitionKey] || entity_values["PartitionKey"],
521
- entity_values[:RowKey] || entity_values["RowKey"], new_query(options))
522
-
523
- headers = { "X-HTTP-Method" => "MERGE" }
524
- headers["If-Match"] = if_match || "*" unless options[:create_if_not_exists]
525
-
526
- body = Serialization.hash_to_json(entity_values)
527
-
528
- response = call(:post, uri, body, headers, options)
529
- response.headers["etag"]
530
- rescue => e
531
- raise_with_response(e, response)
532
- end
533
-
534
- # Public: Inserts or updates an existing entity within a table by merging new property values into the entity.
535
- #
536
- # ==== Attributes
537
- #
538
- # * +table_name+ - String. The table name
539
- # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
540
- # * +options+ - Hash. Optional parameters.
541
- #
542
- # ==== Options
543
- #
544
- # Accepted key/value pairs in options parameter are:
545
- # * +:timeout+ - Integer. A timeout in seconds.
546
- # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
547
- # in the analytics logs when storage analytics logging is enabled.
548
- #
549
- # See http://msdn.microsoft.com/en-us/library/azure/hh452241
550
- #
551
- # Returns the ETag for the entity on success
552
- def insert_or_merge_entity(table_name, entity_values, options = {})
553
- options[:create_if_not_exists] = true
554
- merge_entity(table_name, entity_values, options)
555
- end
556
-
557
- # Public: Inserts or updates a new entity into a table.
558
- #
559
- # ==== Attributes
560
- #
561
- # * +table_name+ - String. The table name
562
- # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
563
- # * +options+ - Hash. Optional parameters.
564
- #
565
- # ==== Options
566
- #
567
- # Accepted key/value pairs in options parameter are:
568
- # * +:timeout+ - Integer. A timeout in seconds.
569
- # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
570
- # in the analytics logs when storage analytics logging is enabled.
571
- #
572
- # See http://msdn.microsoft.com/en-us/library/azure/hh452242
573
- #
574
- # Returns the ETag for the entity on success
575
- def insert_or_replace_entity(table_name, entity_values, options = {})
576
- options[:create_if_not_exists] = true
577
- update_entity(table_name, entity_values, options)
578
- end
579
-
580
- # Public: Deletes an existing entity in the table.
581
- #
582
- # ==== Attributes
583
- #
584
- # * +table_name+ - String. The table name
585
- # * +partition_key+ - String. The partition key
586
- # * +row_key+ - String. The row key
587
- # * +options+ - Hash. Optional parameters.
588
- #
589
- # ==== Options
590
- #
591
- # Accepted key/value pairs in options parameter are:
592
- # * +:if_match+ - String. A matching condition which is required for update (optional, Default="*")
593
- # * +:timeout+ - Integer. A timeout in seconds.
594
- # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
595
- # in the analytics logs when storage analytics logging is enabled.
596
- #
597
- # See http://msdn.microsoft.com/en-us/library/azure/dd135727
598
- #
599
- # Returns nil on success
600
- def delete_entity(table_name, partition_key, row_key, options = {})
601
- if_match = "*"
602
- if_match = options[:if_match] if options[:if_match]
603
-
604
- call(:delete, entities_uri(table_name, partition_key, row_key, new_query(options)), nil, { "If-Match" => if_match }, options)
605
- nil
606
- end
607
-
608
- # Public: Executes a batch of operations.
609
- #
610
- # ==== Attributes
611
- #
612
- # * +batch+ - The Azure::Storage::Table::Batch instance to execute.
613
- # * +options+ - Hash. Optional parameters.
614
- #
615
- # ==== Options
616
- #
617
- # Accepted key/value pairs in options parameter are:
618
- # * +:timeout+ - Integer. A timeout in seconds.
619
- # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
620
- # in the analytics logs when storage analytics logging is enabled.
621
- # * +:location_mode+ - LocationMode. Specifies the location mode used to decide
622
- # which location the request should be sent to.
623
- #
624
- # See http://msdn.microsoft.com/en-us/library/azure/dd894038
625
- #
626
- # Returns an array of results, one for each operation in the batch
627
- def execute_batch(batch, options = {})
628
- headers = {
629
- Azure::Storage::Common::HeaderConstants::CONTENT_TYPE => "multipart/mixed; boundary=#{batch.batch_id}",
630
- Azure::Storage::Common::HeaderConstants::ACCEPT => Serialization.get_accept_string(options[:accept]),
631
- "Accept-Charset" => "UTF-8"
632
- }
633
-
634
- body = batch.to_body(self)
635
- options[:request_location_mode] = Azure::Storage::Common::RequestLocationMode::PRIMARY_OR_SECONDARY
636
- response = call(:post, generate_uri("/$batch", new_query(options), options), body, headers, options, true)
637
- batch.parse_response(response)
638
- rescue => e
639
- raise_with_response(e, response)
640
- end
641
-
642
- # Public: Gets an existing entity in the table.
643
- #
644
- # ==== Attributes
645
- #
646
- # * +table_name+ - String. The table name
647
- # * +partition_key+ - String. The partition key
648
- # * +row_key+ - String. The row key
649
- # * +options+ - Hash. Optional parameters.
650
- #
651
- # ==== Options
652
- #
653
- # Accepted key/value pairs in options parameter are:
654
- # * +:timeout+ - Integer. A timeout in seconds.
655
- # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
656
- # in the analytics logs when storage analytics logging is enabled.
657
- # * +:location_mode+ - LocationMode. Specifies the location mode used to decide
658
- # which location the request should be sent to.
659
- #
660
- # Returns an Azure::Storage::Table::Entity instance on success
661
- def get_entity(table_name, partition_key, row_key, options = {})
662
- options[:partition_key] = partition_key
663
- options[:row_key] = row_key
664
- results = query_entities(table_name, options)
665
- results.length > 0 ? results[0] : nil
666
- end
667
-
668
- # Protected: Generate the URI for the collection of tables.
669
- #
670
- # Returns a URI
671
- protected
672
- def collection_uri(query = {}, options = {})
673
- generate_uri("Tables", query, options)
674
- end
675
-
676
- # Public: Generate the URI for a specific table.
677
- #
678
- # ==== Attributes
679
- #
680
- # * +name+ - The table name. If this is a URI, we just return this
681
- #
682
- # Returns a URI
683
- public
684
- def table_uri(name, query = {}, options = {})
685
- return name if name.kind_of? ::URI
686
- generate_uri("Tables('#{name}')", query, options)
687
- end
688
-
689
- # Public: Generate the URI for an entity or group of entities in a table.
690
- # If both the 'partition_key' and 'row_key' are specified, then the URI
691
- # will match the entity under those specific keys.
692
- #
693
- # ==== Attributes
694
- #
695
- # * +table_name+ - The table name
696
- # * +partition_key+ - The desired partition key (optional)
697
- # * +row_key+ - The desired row key (optional)
698
- #
699
- # Returns a URI
700
- public
701
- def entities_uri(table_name, partition_key = nil, row_key = nil, query = {}, options = {})
702
- return table_name if table_name.kind_of? ::URI
703
-
704
- path = if partition_key && row_key
705
- "%s(PartitionKey='%s',RowKey='%s')" % [
706
- table_name.encode("UTF-8"), encodeODataUriValue(partition_key.encode("UTF-8")), encodeODataUriValue(row_key.encode("UTF-8"))
707
- ]
708
- else
709
- "%s()" % table_name.encode("UTF-8")
710
- end
711
-
712
- uri = generate_uri(path, query, options)
713
- qs = []
714
- if query
715
- query.each do | key, val |
716
- key = key.encode("UTF-8")
717
- val = val.encode("UTF-8")
718
-
719
- if key[0] == "$"
720
- qs.push "#{key}#{::URI.encode_www_form("" => val)}"
721
- else
722
- qs.push ::URI.encode_www_form(key => val)
723
- end
724
- end
725
- end
726
- uri.query = qs.join "&" if qs.length > 0
727
- uri
728
- end
729
-
730
- protected
731
- def encodeODataUriValues(values)
732
- new_values = []
733
- values.each do |value|
734
- new_values.push encodeODataUriValue(value)
735
- end
736
- new_values
737
- end
738
-
739
- protected
740
- def encodeODataUriValue(value)
741
- # Replace each single quote (') with double single quotes ('') not double
742
- # quotes (")
743
- value = value.gsub("'", "''")
744
-
745
- # Encode the special URL characters
746
- value = URI.escape(value)
747
-
748
- value
749
- end
750
-
751
- protected
752
- def raise_with_response(e, response)
753
- raise e if response.nil?
754
- raise "Response header: #{response.headers.inspect}\nResponse body: #{response.body.inspect}\n#{e.inspect}\n#{e.backtrace.join("\n")}"
755
- end
756
-
757
- protected
758
- def call(method, uri, body = nil, headers = {}, options = {}, is_batch = false)
759
- headers["x-ms-version"] = @api_version ? @api_version : Default::STG_VERSION unless headers["x-ms-version"]
760
- headers["User-Agent"] = @user_agent_prefix ? "#{@user_agent_prefix}; #{Default::USER_AGENT}" : Default::USER_AGENT
761
- # Add JSON Content-Type header if is_batch is false because default is Atom.
762
- headers[Azure::Storage::Common::HeaderConstants::CONTENT_TYPE] = Azure::Storage::Common::HeaderConstants::JSON_CONTENT_TYPE_VALUE unless is_batch
763
- headers[Azure::Storage::Common::HeaderConstants::DATA_SERVICE_VERSION] = TableConstants::DEFAULT_DATA_SERVICE_VERSION
764
- super(method, uri, body, headers, options)
765
- end
766
-
767
- protected
768
- def new_query(options = {})
769
- options[:timeout].nil? ? {} : { Azure::Storage::Common::QueryStringConstants::TIMEOUT => options[:timeout].to_s }
770
- end
771
- end
772
- end
773
- end
774
-
775
- Azure::Storage::TableService = Azure::Storage::Table::TableService
1
+ # frozen_string_literal: true
2
+
3
+ #-------------------------------------------------------------------------
4
+ # # Copyright (c) Microsoft and contributors. All rights reserved.
5
+ #
6
+ # The MIT License(MIT)
7
+
8
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ # of this software and associated documentation files(the "Software"), to deal
10
+ # in the Software without restriction, including without limitation the rights
11
+ # to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
12
+ # copies of the Software, and to permit persons to whom the Software is
13
+ # furnished to do so, subject to the following conditions :
14
+
15
+ # The above copyright notice and this permission notice shall be included in
16
+ # all copies or substantial portions of the Software.
17
+
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
21
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ # THE SOFTWARE.
25
+ #--------------------------------------------------------------------------
26
+ require "azure/storage/table/auth/shared_key"
27
+
28
+ module Azure::Storage
29
+ include Azure::Storage::Common::Service
30
+ StorageService = Azure::Storage::Common::Service::StorageService
31
+
32
+ module Table
33
+ class TableService < StorageService
34
+ class << self
35
+ # Public: Creates an instance of [Azure::Storage::Table::TableService]
36
+ #
37
+ # ==== Attributes
38
+ #
39
+ # * +options+ - Hash. Optional parameters.
40
+ #
41
+ # ==== Options
42
+ #
43
+ # Accepted key/value pairs in options parameter are:
44
+ #
45
+ # * +:use_development_storage+ - TrueClass|FalseClass. Whether to use storage emulator.
46
+ # * +:development_storage_proxy_uri+ - String. Used with +:use_development_storage+ if emulator is hosted other than localhost.
47
+ # * +:storage_account_name+ - String. The name of the storage account.
48
+ # * +:storage_access_key+ - Base64 String. The access key of the storage account.
49
+ # * +:storage_sas_token+ - String. The signed access signature for the storage account or one of its service.
50
+ # * +:storage_table_host+ - String. Specified Table service endpoint or hostname
51
+ # * +:storage_dns_suffix+ - String. The suffix of a regional Storage Service, to
52
+ # * +:default_endpoints_protocol+ - String. http or https
53
+ # * +:use_path_style_uri+ - String. Whether use path style URI for specified endpoints
54
+ # * +:ca_file+ - String. File path of the CA file if having issue with SSL
55
+ # * +:ssl_version+ - Symbol. The ssl version to be used, sample: :TLSv1_1, :TLSv1_2, for the details, see https://github.com/ruby/openssl/blob/master/lib/openssl/ssl.rb
56
+ # * +:ssl_min_version+ - Symbol. The min ssl version supported, only supported in Ruby 2.5+
57
+ # * +:ssl_max_version+ - Symbol. The max ssl version supported, only supported in Ruby 2.5+
58
+ # * +:user_agent_prefix+ - String. The user agent prefix that can identify the application calls the library
59
+ #
60
+ # The valid set of options include:
61
+ # * Storage Emulator: +:use_development_storage+ required, +:development_storage_proxy_uri+ optionally
62
+ # * Storage account name and key: +:storage_account_name+ and +:storage_access_key+ required, set +:storage_dns_suffix+ necessarily
63
+ # * Storage account name and SAS token: +:storage_account_name+ and +:storage_sas_token+ required, set +:storage_dns_suffix+ necessarily
64
+ # * Specified hosts and SAS token: At least one of the service host and SAS token. It's up to user to ensure the SAS token is suitable for the serivce
65
+ # * Anonymous Table: only +:storage_table_host+, if it is to only access tables within a container
66
+ #
67
+ # Additional notes:
68
+ # * Specified hosts can be set when use account name with access key or sas token
69
+ # * +:default_endpoints_protocol+ can be set if the scheme is not specified in hosts
70
+ # * Storage emulator always use path style URI
71
+ # * +:ca_file+ is independent.
72
+ #
73
+ # When empty options are given, it will try to read settings from Environment Variables. Refer to [Azure::Storage::Common::ClientOptions.env_vars_mapping] for the mapping relationship
74
+ #
75
+ # @return [Azure::Storage::Table::TableService]
76
+ def create(options = {}, &block)
77
+ service_options = { client: Azure::Storage::Common::Client::create(options, &block), api_version: Azure::Storage::Table::Default::STG_VERSION }
78
+ service_options[:user_agent_prefix] = options[:user_agent_prefix] if options[:user_agent_prefix]
79
+ Azure::Storage::Table::TableService.new(service_options, &block)
80
+ end
81
+
82
+ # Public: Creates an instance of [Azure::Storage::Table::TableService] with Storage Emulator
83
+ #
84
+ # ==== Attributes
85
+ #
86
+ # * +proxy_uri+ - String. Used with +:use_development_storage+ if emulator is hosted other than localhost.
87
+ #
88
+ # @return [Azure::Storage::Table::TableService]
89
+ def create_development(proxy_uri = nil, &block)
90
+ service_options = { client: Azure::Storage::Common::Client::create_development(proxy_uri, &block), api_version: Azure::Storage::Table::Default::STG_VERSION }
91
+ Azure::Storage::Table::TableService.new(service_options, &block)
92
+ end
93
+
94
+ # Public: Creates an instance of [Azure::Storage::Table::TableService] from Environment Variables
95
+ #
96
+ # @return [Azure::Storage::Table::TableService]
97
+ def create_from_env(&block)
98
+ service_options = { client: Azure::Storage::Common::Client::create_from_env(&block), api_version: Azure::Storage::Table::Default::STG_VERSION }
99
+ Azure::Storage::Table::TableService.new(service_options, &block)
100
+ end
101
+
102
+ # Public: Creates an instance of [Azure::Storage::Table::TableService] from Environment Variables
103
+ #
104
+ # ==== Attributes
105
+ #
106
+ # * +connection_string+ - String. Please refer to https://azure.microsoft.com/en-us/documentation/articles/storage-configure-connection-string/.
107
+ #
108
+ # @return [Azure::Storage::Table::TableService]
109
+ def create_from_connection_string(connection_string, &block)
110
+ service_options = { client: Azure::Storage::Common::Client::create_from_connection_string(connection_string, &block), api_version: Azure::Storage::Table::Default::STG_VERSION }
111
+ Azure::Storage::Table::TableService.new(service_options, &block)
112
+ end
113
+ end
114
+
115
+ # Public: Initializes an instance of [Azure::Storage::Table::TableService]
116
+ #
117
+ # ==== Attributes
118
+ #
119
+ # * +options+ - Hash. Optional parameters.
120
+ #
121
+ # ==== Options
122
+ #
123
+ # Accepted key/value pairs in options parameter are:
124
+ #
125
+ # * +:use_development_storage+ - TrueClass|FalseClass. Whether to use storage emulator.
126
+ # * +:development_storage_proxy_uri+ - String. Used with +:use_development_storage+ if emulator is hosted other than localhost.
127
+ # * +:storage_connection_string+ - String. The storage connection string.
128
+ # * +:storage_account_name+ - String. The name of the storage account.
129
+ # * +:storage_access_key+ - Base64 String. The access key of the storage account.
130
+ # * +:storage_sas_token+ - String. The signed access signature for the storage account or one of its service.
131
+ # * +:storage_table_host+ - String. Specified Table serivce endpoint or hostname
132
+ # * +:storage_dns_suffix+ - String. The suffix of a regional Storage Serivce, to
133
+ # * +:default_endpoints_protocol+ - String. http or https
134
+ # * +:use_path_style_uri+ - String. Whether use path style URI for specified endpoints
135
+ # * +:ca_file+ - String. File path of the CA file if having issue with SSL
136
+ # * +:user_agent_prefix+ - String. The user agent prefix that can identify the application calls the library
137
+ # * +:client+ - Azure::Storage::Common::Client. The common client used to initalize the service.
138
+ #
139
+ # The valid set of options include:
140
+ # * Storage Emulator: +:use_development_storage+ required, +:development_storage_proxy_uri+ optionally
141
+ # * Storage account name and key: +:storage_account_name+ and +:storage_access_key+ required, set +:storage_dns_suffix+ necessarily
142
+ # * Storage account name and SAS token: +:storage_account_name+ and +:storage_sas_token+ required, set +:storage_dns_suffix+ necessarily
143
+ # * Specified hosts and SAS token: At least one of the service host and SAS token. It's up to user to ensure the SAS token is suitable for the serivce
144
+ # * Azure::Storage::Common::Client: The common client used to initalize the service. This client can be initalized and used repeatedly.
145
+ # * Anonymous Table: only +:storage_table_host+, if it is to only access tables within a container
146
+ #
147
+ # Additional notes:
148
+ # * Specified hosts can be set when use account name with access key or sas token
149
+ # * +:default_endpoints_protocol+ can be set if the scheme is not specified in hosts
150
+ # * Storage emulator always use path style URI
151
+ # * +:ca_file+ is independent.
152
+ #
153
+ # When empty options are given, it will try to read settings from Environment Variables. Refer to [Azure::Storage::Common::ClientOptions.env_vars_mapping] for the mapping relationship
154
+ def initialize(options = {}, &block)
155
+ service_options = options.clone
156
+ client_config = service_options[:client] ||= Azure::Storage::Common::Client::create(service_options, &block)
157
+ @user_agent_prefix = service_options[:user_agent_prefix] if service_options[:user_agent_prefix]
158
+ @api_version = service_options[:api_version] || Azure::Storage::Table::Default::STG_VERSION
159
+ signer = service_options[:signer] || client_config.signer || Auth::SharedKey.new(client_config.storage_account_name, client_config.storage_access_key)
160
+ signer.api_ver = @api_version if signer.is_a? Azure::Storage::Common::Core::Auth::SharedAccessSignatureSigner
161
+ super(signer, client_config.storage_account_name, service_options, &block)
162
+ @storage_service_host[:primary] = client.storage_table_host
163
+ @storage_service_host[:secondary] = client.storage_table_host true
164
+ end
165
+
166
+ # Public: Creates new table in the storage account
167
+ #
168
+ # ==== Attributes
169
+ #
170
+ # * +table_name+ - String. The table name
171
+ # * +options+ - Hash. Optional parameters.
172
+ #
173
+ # ==== Options
174
+ #
175
+ # Accepted key/value pairs in options parameter are:
176
+ #
177
+ # * +:timeout+ - Integer. A timeout in seconds.
178
+ # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
179
+ # in the analytics logs when storage analytics logging is enabled.
180
+ # * +:accept+ - String. Specifies the accepted content-type of the response payload. Possible values are:
181
+ # :no_meta
182
+ # :min_meta
183
+ # :full_meta
184
+ # * +:prefer+ - String. Specifies whether the response should include the inserted entity in the payload. Possible values are:
185
+ # Azure::Storage::Common::HeaderConstants::PREFER_CONTENT
186
+ # Azure::Storage::Common::HeaderConstants::PREFER_NO_CONTENT
187
+ #
188
+ # See http://msdn.microsoft.com/en-us/library/azure/dd135729
189
+ #
190
+ # @return [nil] on success
191
+ def create_table(table_name, options = {})
192
+ headers = {
193
+ Azure::Storage::Common::HeaderConstants::ACCEPT => Serialization.get_accept_string(options[:accept]),
194
+ }
195
+ headers[Azure::Storage::Common::HeaderConstants::PREFER] = options[:prefer] unless options[:prefer].nil?
196
+ body = Serialization.hash_to_json("TableName" => table_name)
197
+
198
+ call(:post, collection_uri(new_query(options)), body, headers, options)
199
+ nil
200
+ end
201
+
202
+ # Public: Deletes the specified table and any data it contains.
203
+ #
204
+ # ==== Attributes
205
+ #
206
+ # * +table_name+ - String. The table name
207
+ # * +options+ - Hash. Optional parameters.
208
+ #
209
+ # ==== Options
210
+ #
211
+ # Accepted key/value pairs in options parameter are:
212
+ # * +:timeout+ - Integer. A timeout in seconds.
213
+ # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
214
+ # in the analytics logs when storage analytics logging is enabled.
215
+ #
216
+ # See http://msdn.microsoft.com/en-us/library/azure/dd179387
217
+ #
218
+ # Returns nil on success
219
+ def delete_table(table_name, options = {})
220
+ call(:delete, table_uri(table_name, new_query(options)), nil, {}, options)
221
+ nil
222
+ end
223
+
224
+ # Public: Gets the table.
225
+ #
226
+ # ==== Attributes
227
+ #
228
+ # * +table_name+ - String. The table name
229
+ # * +options+ - Hash. Optional parameters.
230
+ #
231
+ # ==== Options
232
+ #
233
+ # Accepted key/value pairs in options parameter are:
234
+ # * +:timeout+ - Integer. A timeout in seconds.
235
+ # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
236
+ # in the analytics logs when storage analytics logging is enabled.
237
+ # * +:location_mode+ - LocationMode. Specifies the location mode used to decide
238
+ # which location the request should be sent to.
239
+ #
240
+ # Returns the last updated time for the table
241
+ def get_table(table_name, options = {})
242
+ headers = {
243
+ Azure::Storage::Common::HeaderConstants::ACCEPT => Serialization.get_accept_string(:full_meta),
244
+ }
245
+ options[:request_location_mode] = Azure::Storage::Common::RequestLocationMode::PRIMARY_OR_SECONDARY
246
+ response = call(:get, table_uri(table_name, new_query(options), options), nil, headers, options)
247
+ Serialization.table_entries_from_json(response.body)
248
+ rescue => e
249
+ raise_with_response(e, response)
250
+ end
251
+
252
+ # Public: Gets a list of all tables on the account.
253
+ #
254
+ # ==== Attributes
255
+ #
256
+ # * +options+ - Hash. Optional parameters.
257
+ #
258
+ # ==== Options
259
+ #
260
+ # Accepted key/value pairs in options parameter are:
261
+ # * +:next_table_token+ - String. A token used to enumerate the next page of results, when the list of tables is
262
+ # larger than a single operation can return at once. (optional)
263
+ # * +:timeout+ - Integer. A timeout in seconds.
264
+ # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
265
+ # in the analytics logs when storage analytics logging is enabled.
266
+ # * +:location_mode+ - LocationMode. Specifies the location mode used to decide
267
+ # which location the request should be sent to.
268
+ # * +:accept+ - String. Specifies the accepted content-type of the response payload. Possible values are:
269
+ # :no_meta
270
+ # :min_meta
271
+ # :full_meta
272
+ #
273
+ # See http://msdn.microsoft.com/en-us/library/azure/dd179405
274
+ #
275
+ # Returns an array with an extra continuation_token property on success
276
+ def query_tables(options = {})
277
+ query = new_query(options)
278
+ query[TableConstants::NEXT_TABLE_NAME] = options[:next_table_token] if options[:next_table_token]
279
+
280
+ options[:request_location_mode] = Azure::Storage::Common::RequestLocationMode::PRIMARY_OR_SECONDARY
281
+ uri = collection_uri(query, options)
282
+
283
+ headers = {
284
+ Azure::Storage::Common::HeaderConstants::ACCEPT => Serialization.get_accept_string(options[:accept]),
285
+ }
286
+
287
+ response = call(:get, uri, nil, headers, options)
288
+ entries = Serialization.table_entries_from_json(response.body) || []
289
+ values = Azure::Storage::Common::Service::EnumerationResults.new(entries)
290
+ values.continuation_token = response.headers[TableConstants::CONTINUATION_NEXT_TABLE_NAME]
291
+ values
292
+ rescue => e
293
+ raise_with_response(e, response)
294
+ end
295
+
296
+ # Public: Gets the access control list (ACL) for the table.
297
+ #
298
+ # ==== Attributes
299
+ #
300
+ # * +table_name+ - String. The table name
301
+ # * +options+ - Hash. Optional parameters.
302
+ #
303
+ # ==== Options
304
+ #
305
+ # Accepted key/value pairs in options parameter are:
306
+ # * +:timeout+ - Integer. A timeout in seconds.
307
+ # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
308
+ # in the analytics logs when storage analytics logging is enabled.
309
+ # * +:location_mode+ - LocationMode. Specifies the location mode used to decide
310
+ # which location the request should be sent to.
311
+ #
312
+ # See http://msdn.microsoft.com/en-us/library/azure/jj159100
313
+ #
314
+ # Returns a list of Azure::Storage::Entity::SignedIdentifier instances
315
+ def get_table_acl(table_name, options = {})
316
+ query = new_query(options)
317
+ query[Azure::Storage::Common::QueryStringConstants::COMP] = Azure::Storage::Common::QueryStringConstants::ACL
318
+
319
+ options[:request_location_mode] = Azure::Storage::Common::RequestLocationMode::PRIMARY_OR_SECONDARY
320
+ response = call(:get, generate_uri(table_name, query, options), nil, { "x-ms-version" => "2012-02-12" }, options)
321
+
322
+ signed_identifiers = []
323
+ signed_identifiers = Serialization.signed_identifiers_from_xml response.body unless response.body == nil || response.body.length < 1
324
+ signed_identifiers
325
+ rescue => e
326
+ raise_with_response(e, response)
327
+ end
328
+
329
+ # Public: Sets the access control list (ACL) for the table.
330
+ #
331
+ # ==== Attributes
332
+ #
333
+ # * +table_name+ - String. The table name
334
+ # * +options+ - Hash. Optional parameters.
335
+ #
336
+ # ==== Options
337
+ #
338
+ # Accepted key/value pairs in options parameter are:
339
+ # * +:signed_identifiers+ - Array. A list of Azure::Storage::Entity::SignedIdentifier instances
340
+ # * +:timeout+ - Integer. A timeout in seconds.
341
+ # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
342
+ # in the analytics logs when storage analytics logging is enabled.
343
+ #
344
+ # See http://msdn.microsoft.com/en-us/library/azure/jj159102
345
+ #
346
+ # Returns nil on success
347
+ def set_table_acl(table_name, options = {})
348
+ query = new_query(options)
349
+ query[Azure::Storage::Common::QueryStringConstants::COMP] = Azure::Storage::Common::QueryStringConstants::ACL
350
+
351
+ uri = generate_uri(table_name, query)
352
+ body = nil
353
+ body = Serialization.signed_identifiers_to_xml options[:signed_identifiers] if options[:signed_identifiers] && options[:signed_identifiers].length > 0
354
+
355
+ call(:put, uri, body, { "x-ms-version" => "2012-02-12" }, options)
356
+ nil
357
+ end
358
+
359
+ # Public: Inserts new entity to the table.
360
+ #
361
+ #
362
+ # ==== Attributes
363
+ #
364
+ # * +table_name+ - String. The table name
365
+ # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
366
+ # * +options+ - Hash. Optional parameters.
367
+ #
368
+ # ==== Options
369
+ #
370
+ # Accepted key/value pairs in options parameter are:
371
+ # * +:timeout+ - Integer. A timeout in seconds.
372
+ # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
373
+ # in the analytics logs when storage analytics logging is enabled.
374
+ # * +:accept+ - String. Specifies the accepted content-type of the response payload. Possible values are:
375
+ # :no_meta
376
+ # :min_meta
377
+ # :full_meta
378
+ #
379
+ # See http://msdn.microsoft.com/en-us/library/azure/dd179433
380
+ #
381
+ # Returns a Azure::Storage::Entity::Table::Entity
382
+ def insert_entity(table_name, entity_values, options = {})
383
+ body = Serialization.hash_to_json(entity_values)
384
+ #time = EdmType::to_edm_time(Time.now)
385
+ headers = {
386
+ Azure::Storage::Common::HeaderConstants::ACCEPT => Serialization.get_accept_string(options[:accept])
387
+ }
388
+ response = call(:post, entities_uri(table_name, nil, nil, new_query(options)), body, headers, options)
389
+ result = Serialization.entity_from_json(response.body)
390
+ result.etag = response.headers[Azure::Storage::Common::HeaderConstants::ETAG] if result.etag.nil?
391
+ result
392
+ rescue => e
393
+ raise_with_response(e, response)
394
+ end
395
+
396
+ # Public: Queries entities for the given table name
397
+ #
398
+ # ==== Attributes
399
+ #
400
+ # * +table_name+ - String. The table name
401
+ # * +options+ - Hash. Optional parameters.
402
+ #
403
+ # ==== Options
404
+ #
405
+ # Accepted key/value pairs in options parameter are:
406
+ # * +:partition_key+ - String. The partition key (optional)
407
+ # * +:row_key+ - String. The row key (optional)
408
+ # * +:select+ - Array. An array of property names to return (optional)
409
+ # * +:filter+ - String. A filter expression (optional)
410
+ # * +:top+ - Integer. A limit for the number of results returned (optional)
411
+ # * +:continuation_token+ - Hash. The continuation token.
412
+ # * +:timeout+ - Integer. A timeout in seconds.
413
+ # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
414
+ # in the analytics logs when storage analytics logging is enabled.
415
+ # * +:location_mode+ - LocationMode. Specifies the location mode used to decide
416
+ # which location the request should be sent to.
417
+ # * +:accept+ - String. Specifies the accepted content-type of the response payload. Possible values are:
418
+ # :no_meta
419
+ # :min_meta
420
+ # :full_meta
421
+ #
422
+ # See http://msdn.microsoft.com/en-us/library/azure/dd179421
423
+ #
424
+ # Returns an array with an extra continuation_token property on success
425
+ def query_entities(table_name, options = {})
426
+ query = new_query(options)
427
+ query[Azure::Storage::Common::QueryStringConstants::SELECT] = options[:select].join "," if options[:select]
428
+ query[Azure::Storage::Common::QueryStringConstants::FILTER] = options[:filter] if options[:filter]
429
+ query[Azure::Storage::Common::QueryStringConstants::TOP] = options[:top].to_s if options[:top] unless options[:partition_key] && options[:row_key]
430
+ query[Azure::Storage::Common::QueryStringConstants::NEXT_PARTITION_KEY] = options[:continuation_token][:next_partition_key] if options[:continuation_token] && options[:continuation_token][:next_partition_key]
431
+ query[Azure::Storage::Common::QueryStringConstants::NEXT_ROW_KEY] = options[:continuation_token][:next_row_key] if options[:continuation_token] && options[:continuation_token][:next_row_key]
432
+
433
+ options[:request_location_mode] = Azure::Storage::Common::RequestLocationMode::PRIMARY_OR_SECONDARY
434
+ uri = entities_uri(table_name, options[:partition_key], options[:row_key], query, options)
435
+
436
+ headers = {
437
+ Azure::Storage::Common::HeaderConstants::ACCEPT => Serialization.get_accept_string(options[:accept])
438
+ }
439
+
440
+ response = call(:get, uri, nil, headers, options)
441
+
442
+ entities = Azure::Storage::Common::Service::EnumerationResults.new.push(*Serialization.entities_from_json(response.body))
443
+
444
+ entities.continuation_token = nil
445
+ entities.continuation_token = {
446
+ next_partition_key: response.headers[TableConstants::CONTINUATION_NEXT_PARTITION_KEY],
447
+ next_row_key: response.headers[TableConstants::CONTINUATION_NEXT_ROW_KEY]
448
+ } if response.headers[TableConstants::CONTINUATION_NEXT_PARTITION_KEY]
449
+
450
+ entities
451
+ rescue => e
452
+ raise_with_response(e, response)
453
+ end
454
+
455
+ # Public: Updates an existing entity in a table. The Update Entity operation replaces
456
+ # the entire entity and can be used to remove properties.
457
+ #
458
+ # ==== Attributes
459
+ #
460
+ # * +table_name+ - String. The table name
461
+ # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
462
+ # * +options+ - Hash. Optional parameters.
463
+ #
464
+ # ==== Options
465
+ #
466
+ # Accepted key/value pairs in options parameter are:
467
+ # * +:if_match+ - String. A matching condition which is required for update (optional, Default="*")
468
+ # * +:create_if_not_exists+ - Boolean. If true, and partition_key and row_key do not reference and existing entity,
469
+ # that entity will be inserted. If false, the operation will fail. (optional, Default=false)
470
+ # * +:timeout+ - Integer. A timeout in seconds.
471
+ # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
472
+ # in the analytics logs when storage analytics logging is enabled.
473
+ #
474
+ # See http://msdn.microsoft.com/en-us/library/azure/dd179427
475
+ #
476
+ # Returns the ETag for the entity on success
477
+ def update_entity(table_name, entity_values, options = {})
478
+ if_match = "*"
479
+ if_match = options[:if_match] if options[:if_match]
480
+
481
+ uri = entities_uri(table_name,
482
+ entity_values[:PartitionKey] || entity_values["PartitionKey"],
483
+ entity_values[:RowKey] || entity_values["RowKey"], new_query(options))
484
+
485
+ headers = {}
486
+ headers["If-Match"] = if_match || "*" unless options[:create_if_not_exists]
487
+
488
+ body = Serialization.hash_to_json(entity_values)
489
+
490
+ response = call(:put, uri, body, headers, options)
491
+ response.headers["etag"]
492
+ rescue => e
493
+ raise_with_response(e, response)
494
+ end
495
+
496
+ # Public: Updates an existing entity by updating the entity's properties. This operation
497
+ # does not replace the existing entity, as the update_entity operation does.
498
+ #
499
+ # ==== Attributes
500
+ #
501
+ # * +table_name+ - String. The table name
502
+ # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
503
+ # * +options+ - Hash. Optional parameters.
504
+ #
505
+ # ==== Options
506
+ #
507
+ # Accepted key/value pairs in options parameter are:
508
+ # * +:if_match+ - String. A matching condition which is required for update (optional, Default="*")
509
+ # * +:create_if_not_exists+ - Boolean. If true, and partition_key and row_key do not reference and existing entity,
510
+ # that entity will be inserted. If false, the operation will fail. (optional, Default=false)
511
+ # * +:timeout+ - Integer. A timeout in seconds.
512
+ # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
513
+ # in the analytics logs when storage analytics logging is enabled.
514
+ #
515
+ # See http://msdn.microsoft.com/en-us/library/azure/dd179392
516
+ #
517
+ # Returns the ETag for the entity on success
518
+ def merge_entity(table_name, entity_values, options = {})
519
+ if_match = "*"
520
+ if_match = options[:if_match] if options[:if_match]
521
+
522
+ uri = entities_uri(table_name,
523
+ entity_values[:PartitionKey] || entity_values["PartitionKey"],
524
+ entity_values[:RowKey] || entity_values["RowKey"], new_query(options))
525
+
526
+ headers = { "X-HTTP-Method" => "MERGE" }
527
+ headers["If-Match"] = if_match || "*" unless options[:create_if_not_exists]
528
+
529
+ body = Serialization.hash_to_json(entity_values)
530
+
531
+ response = call(:post, uri, body, headers, options)
532
+ response.headers["etag"]
533
+ rescue => e
534
+ raise_with_response(e, response)
535
+ end
536
+
537
+ # Public: Inserts or updates an existing entity within a table by merging new property values into the entity.
538
+ #
539
+ # ==== Attributes
540
+ #
541
+ # * +table_name+ - String. The table name
542
+ # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
543
+ # * +options+ - Hash. Optional parameters.
544
+ #
545
+ # ==== Options
546
+ #
547
+ # Accepted key/value pairs in options parameter are:
548
+ # * +:timeout+ - Integer. A timeout in seconds.
549
+ # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
550
+ # in the analytics logs when storage analytics logging is enabled.
551
+ #
552
+ # See http://msdn.microsoft.com/en-us/library/azure/hh452241
553
+ #
554
+ # Returns the ETag for the entity on success
555
+ def insert_or_merge_entity(table_name, entity_values, options = {})
556
+ options[:create_if_not_exists] = true
557
+ merge_entity(table_name, entity_values, options)
558
+ end
559
+
560
+ # Public: Inserts or updates a new entity into a table.
561
+ #
562
+ # ==== Attributes
563
+ #
564
+ # * +table_name+ - String. The table name
565
+ # * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
566
+ # * +options+ - Hash. Optional parameters.
567
+ #
568
+ # ==== Options
569
+ #
570
+ # Accepted key/value pairs in options parameter are:
571
+ # * +:timeout+ - Integer. A timeout in seconds.
572
+ # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
573
+ # in the analytics logs when storage analytics logging is enabled.
574
+ #
575
+ # See http://msdn.microsoft.com/en-us/library/azure/hh452242
576
+ #
577
+ # Returns the ETag for the entity on success
578
+ def insert_or_replace_entity(table_name, entity_values, options = {})
579
+ options[:create_if_not_exists] = true
580
+ update_entity(table_name, entity_values, options)
581
+ end
582
+
583
+ # Public: Deletes an existing entity in the table.
584
+ #
585
+ # ==== Attributes
586
+ #
587
+ # * +table_name+ - String. The table name
588
+ # * +partition_key+ - String. The partition key
589
+ # * +row_key+ - String. The row key
590
+ # * +options+ - Hash. Optional parameters.
591
+ #
592
+ # ==== Options
593
+ #
594
+ # Accepted key/value pairs in options parameter are:
595
+ # * +:if_match+ - String. A matching condition which is required for update (optional, Default="*")
596
+ # * +:timeout+ - Integer. A timeout in seconds.
597
+ # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
598
+ # in the analytics logs when storage analytics logging is enabled.
599
+ #
600
+ # See http://msdn.microsoft.com/en-us/library/azure/dd135727
601
+ #
602
+ # Returns nil on success
603
+ def delete_entity(table_name, partition_key, row_key, options = {})
604
+ if_match = "*"
605
+ if_match = options[:if_match] if options[:if_match]
606
+
607
+ call(:delete, entities_uri(table_name, partition_key, row_key, new_query(options)), nil, { "If-Match" => if_match }, options)
608
+ nil
609
+ end
610
+
611
+ # Public: Executes a batch of operations.
612
+ #
613
+ # ==== Attributes
614
+ #
615
+ # * +batch+ - The Azure::Storage::Table::Batch instance to execute.
616
+ # * +options+ - Hash. Optional parameters.
617
+ #
618
+ # ==== Options
619
+ #
620
+ # Accepted key/value pairs in options parameter are:
621
+ # * +:timeout+ - Integer. A timeout in seconds.
622
+ # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
623
+ # in the analytics logs when storage analytics logging is enabled.
624
+ # * +:location_mode+ - LocationMode. Specifies the location mode used to decide
625
+ # which location the request should be sent to.
626
+ #
627
+ # See http://msdn.microsoft.com/en-us/library/azure/dd894038
628
+ #
629
+ # Returns an array of results, one for each operation in the batch
630
+ def execute_batch(batch, options = {})
631
+ headers = {
632
+ Azure::Storage::Common::HeaderConstants::CONTENT_TYPE => "multipart/mixed; boundary=#{batch.batch_id}",
633
+ Azure::Storage::Common::HeaderConstants::ACCEPT => Serialization.get_accept_string(options[:accept]),
634
+ "Accept-Charset" => "UTF-8"
635
+ }
636
+
637
+ body = batch.to_body(self)
638
+ options[:request_location_mode] = Azure::Storage::Common::RequestLocationMode::PRIMARY_OR_SECONDARY
639
+ response = call(:post, generate_uri("/$batch", new_query(options), options), body, headers, options, true)
640
+ batch.parse_response(response)
641
+ rescue => e
642
+ raise_with_response(e, response)
643
+ end
644
+
645
+ # Public: Gets an existing entity in the table.
646
+ #
647
+ # ==== Attributes
648
+ #
649
+ # * +table_name+ - String. The table name
650
+ # * +partition_key+ - String. The partition key
651
+ # * +row_key+ - String. The row key
652
+ # * +options+ - Hash. Optional parameters.
653
+ #
654
+ # ==== Options
655
+ #
656
+ # Accepted key/value pairs in options parameter are:
657
+ # * +:timeout+ - Integer. A timeout in seconds.
658
+ # * +:request_id+ - String. Provides a client-generated, opaque value with a 1 KB character limit that is recorded
659
+ # in the analytics logs when storage analytics logging is enabled.
660
+ # * +:location_mode+ - LocationMode. Specifies the location mode used to decide
661
+ # which location the request should be sent to.
662
+ #
663
+ # Returns an Azure::Storage::Table::Entity instance on success
664
+ def get_entity(table_name, partition_key, row_key, options = {})
665
+ options[:partition_key] = partition_key
666
+ options[:row_key] = row_key
667
+ results = query_entities(table_name, options)
668
+ results.length > 0 ? results[0] : nil
669
+ end
670
+
671
+ # Protected: Generate the URI for the collection of tables.
672
+ #
673
+ # Returns a URI
674
+ protected
675
+ def collection_uri(query = {}, options = {})
676
+ generate_uri("Tables", query, options)
677
+ end
678
+
679
+ # Public: Generate the URI for a specific table.
680
+ #
681
+ # ==== Attributes
682
+ #
683
+ # * +name+ - The table name. If this is a URI, we just return this
684
+ #
685
+ # Returns a URI
686
+ public
687
+ def table_uri(name, query = {}, options = {})
688
+ return name if name.kind_of? ::URI
689
+ generate_uri("Tables('#{name}')", query, options)
690
+ end
691
+
692
+ # Public: Generate the URI for an entity or group of entities in a table.
693
+ # If both the 'partition_key' and 'row_key' are specified, then the URI
694
+ # will match the entity under those specific keys.
695
+ #
696
+ # ==== Attributes
697
+ #
698
+ # * +table_name+ - The table name
699
+ # * +partition_key+ - The desired partition key (optional)
700
+ # * +row_key+ - The desired row key (optional)
701
+ #
702
+ # Returns a URI
703
+ public
704
+ def entities_uri(table_name, partition_key = nil, row_key = nil, query = {}, options = {})
705
+ return table_name if table_name.kind_of? ::URI
706
+
707
+ path = if partition_key && row_key
708
+ "%s(PartitionKey='%s',RowKey='%s')" % [
709
+ table_name.encode("UTF-8"), encodeODataUriValue(partition_key.encode("UTF-8")), encodeODataUriValue(row_key.encode("UTF-8"))
710
+ ]
711
+ else
712
+ "%s()" % table_name.encode("UTF-8")
713
+ end
714
+
715
+ uri = generate_uri(path, query, options)
716
+ qs = []
717
+ if query
718
+ query.each do | key, val |
719
+ key = key.encode("UTF-8")
720
+ val = val.encode("UTF-8")
721
+
722
+ if key[0] == "$"
723
+ qs.push "#{key}#{::URI.encode_www_form("" => val)}"
724
+ else
725
+ qs.push ::URI.encode_www_form(key => val)
726
+ end
727
+ end
728
+ end
729
+ uri.query = qs.join "&" if qs.length > 0
730
+ uri
731
+ end
732
+
733
+ protected
734
+ def encodeODataUriValues(values)
735
+ new_values = []
736
+ values.each do |value|
737
+ new_values.push encodeODataUriValue(value)
738
+ end
739
+ new_values
740
+ end
741
+
742
+ protected
743
+ def encodeODataUriValue(value)
744
+ # Replace each single quote (') with double single quotes ('') not double
745
+ # quotes (")
746
+ value = value.gsub("'", "''")
747
+
748
+ # Encode the special URL characters
749
+ value = URI.escape(value)
750
+
751
+ value
752
+ end
753
+
754
+ protected
755
+ def raise_with_response(e, response)
756
+ raise e if response.nil?
757
+ raise "Response header: #{response.headers.inspect}\nResponse body: #{response.body.inspect}\n#{e.inspect}\n#{e.backtrace.join("\n")}"
758
+ end
759
+
760
+ protected
761
+ def call(method, uri, body = nil, headers = {}, options = {}, is_batch = false)
762
+ headers["x-ms-version"] = @api_version ? @api_version : Default::STG_VERSION unless headers["x-ms-version"]
763
+ headers["User-Agent"] = @user_agent_prefix ? "#{@user_agent_prefix}; #{Default::USER_AGENT}" : Default::USER_AGENT
764
+ # Add JSON Content-Type header if is_batch is false because default is Atom.
765
+ headers[Azure::Storage::Common::HeaderConstants::CONTENT_TYPE] = Azure::Storage::Common::HeaderConstants::JSON_CONTENT_TYPE_VALUE unless is_batch
766
+ headers[Azure::Storage::Common::HeaderConstants::DATA_SERVICE_VERSION] = TableConstants::DEFAULT_DATA_SERVICE_VERSION
767
+ super(method, uri, body, headers, options)
768
+ end
769
+
770
+ protected
771
+ def new_query(options = {})
772
+ options[:timeout].nil? ? {} : { Azure::Storage::Common::QueryStringConstants::TIMEOUT => options[:timeout].to_s }
773
+ end
774
+ end
775
+ end
776
+ end
777
+
778
+ Azure::Storage::TableService = Azure::Storage::Table::TableService