stuartpreston-azure-sdk-for-ruby 0.7.1 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +11 -11
- data/.travis.yml +10 -10
- data/ChangeLog.txt +70 -68
- data/Gemfile +15 -15
- data/README.md +618 -618
- data/Rakefile +133 -133
- data/azure.gemspec +44 -44
- data/lib/azure.rb +52 -52
- data/lib/azure/base_management/affinity_group.rb +32 -32
- data/lib/azure/base_management/base_management_service.rb +304 -304
- data/lib/azure/base_management/location.rb +27 -27
- data/lib/azure/base_management/management_http_request.rb +171 -171
- data/lib/azure/base_management/serialization.rb +129 -129
- data/lib/azure/base_management/sql_management_http_request.rb +45 -45
- data/lib/azure/blob/blob.rb +31 -31
- data/lib/azure/blob/blob_service.rb +1423 -1423
- data/lib/azure/blob/block.rb +30 -30
- data/lib/azure/blob/container.rb +31 -31
- data/lib/azure/blob/serialization.rb +284 -284
- data/lib/azure/cloud_service_management/cloud_service.rb +38 -38
- data/lib/azure/cloud_service_management/cloud_service_management_service.rb +140 -140
- data/lib/azure/cloud_service_management/serialization.rb +117 -117
- data/lib/azure/core.rb +39 -39
- data/lib/azure/core/auth/authorizer.rb +36 -36
- data/lib/azure/core/auth/shared_key.rb +110 -110
- data/lib/azure/core/auth/shared_key_lite.rb +48 -48
- data/lib/azure/core/auth/signer.rb +48 -48
- data/lib/azure/core/configuration.rb +211 -211
- data/lib/azure/core/error.rb +22 -22
- data/lib/azure/core/filtered_service.rb +43 -43
- data/lib/azure/core/http/debug_filter.rb +35 -35
- data/lib/azure/core/http/http_error.rb +88 -88
- data/lib/azure/core/http/http_filter.rb +52 -52
- data/lib/azure/core/http/http_request.rb +157 -157
- data/lib/azure/core/http/http_response.rb +140 -140
- data/lib/azure/core/http/retry_policy.rb +73 -73
- data/lib/azure/core/http/signer_filter.rb +33 -33
- data/lib/azure/core/service.rb +62 -62
- data/lib/azure/core/signed_service.rb +42 -42
- data/lib/azure/core/utility.rb +190 -190
- data/lib/azure/queue/message.rb +29 -29
- data/lib/azure/queue/queue.rb +28 -28
- data/lib/azure/queue/queue_service.rb +567 -567
- data/lib/azure/queue/serialization.rb +106 -106
- data/lib/azure/service/access_policy.rb +25 -25
- data/lib/azure/service/cors.rb +11 -11
- data/lib/azure/service/cors_rule.rb +15 -15
- data/lib/azure/service/enumeration_results.rb +20 -20
- data/lib/azure/service/logging.rb +31 -31
- data/lib/azure/service/metrics.rb +30 -30
- data/lib/azure/service/retention_policy.rb +24 -24
- data/lib/azure/service/serialization.rb +297 -297
- data/lib/azure/service/signed_identifier.rb +29 -29
- data/lib/azure/service/storage_service.rb +82 -82
- data/lib/azure/service/storage_service_properties.rb +37 -37
- data/lib/azure/service_bus/action.rb +21 -21
- data/lib/azure/service_bus/auth/wrap_service.rb +88 -88
- data/lib/azure/service_bus/auth/wrap_signer.rb +68 -68
- data/lib/azure/service_bus/brokered_message.rb +123 -123
- data/lib/azure/service_bus/brokered_message_serializer.rb +159 -159
- data/lib/azure/service_bus/correlation_filter.rb +45 -45
- data/lib/azure/service_bus/empty_rule_action.rb +29 -29
- data/lib/azure/service_bus/false_filter.rb +38 -38
- data/lib/azure/service_bus/filter.rb +21 -21
- data/lib/azure/service_bus/interval.rb +103 -103
- data/lib/azure/service_bus/queue.rb +229 -229
- data/lib/azure/service_bus/relay.rb +87 -87
- data/lib/azure/service_bus/resource.rb +108 -108
- data/lib/azure/service_bus/rule.rb +97 -97
- data/lib/azure/service_bus/rule_aspect.rb +34 -34
- data/lib/azure/service_bus/serialization.rb +161 -161
- data/lib/azure/service_bus/service_bus_service.rb +896 -896
- data/lib/azure/service_bus/sql_filter.rb +50 -50
- data/lib/azure/service_bus/sql_rule_action.rb +50 -50
- data/lib/azure/service_bus/subscription.rb +183 -183
- data/lib/azure/service_bus/topic.rb +186 -186
- data/lib/azure/service_bus/true_filter.rb +38 -38
- data/lib/azure/sql_database_management/serialization.rb +111 -111
- data/lib/azure/sql_database_management/sql_database.rb +31 -31
- data/lib/azure/sql_database_management/sql_database_management_service.rb +200 -200
- data/lib/azure/storage_management/serialization.rb +184 -184
- data/lib/azure/storage_management/storage_account.rb +40 -40
- data/lib/azure/storage_management/storage_management_service.rb +166 -166
- data/lib/azure/table/auth/shared_key.rb +92 -92
- data/lib/azure/table/auth/shared_key_lite.rb +44 -44
- data/lib/azure/table/batch.rb +329 -329
- data/lib/azure/table/batch_response.rb +118 -118
- data/lib/azure/table/edmtype.rb +126 -126
- data/lib/azure/table/entity.rb +30 -30
- data/lib/azure/table/guid.rb +23 -23
- data/lib/azure/table/query.rb +111 -111
- data/lib/azure/table/serialization.rb +107 -107
- data/lib/azure/table/table_service.rb +559 -559
- data/lib/azure/version.rb +31 -31
- data/lib/azure/virtual_machine_image_management/serialization.rb +66 -66
- data/lib/azure/virtual_machine_image_management/virtual_machine_disk.rb +25 -25
- data/lib/azure/virtual_machine_image_management/virtual_machine_image.rb +25 -25
- data/lib/azure/virtual_machine_image_management/virtual_machine_image_management_service.rb +94 -94
- data/lib/azure/virtual_machine_management/serialization.rb +462 -462
- data/lib/azure/virtual_machine_management/virtual_machine.rb +45 -45
- data/lib/azure/virtual_machine_management/virtual_machine_management_service.rb +588 -588
- data/lib/azure/virtual_network_management/serialization.rb +190 -190
- data/lib/azure/virtual_network_management/virtual_network.rb +37 -37
- data/lib/azure/virtual_network_management/virtual_network_management_service.rb +109 -109
- data/test/fixtures/affinity_group.xml +33 -33
- data/test/fixtures/all_containers.xml +20 -20
- data/test/fixtures/all_tables.xml +22 -22
- data/test/fixtures/certificate.pem +21 -21
- data/test/fixtures/container_acl.xml +11 -11
- data/test/fixtures/create_sql_database_server.xml +1 -1
- data/test/fixtures/create_storage_desc_error.xml +5 -5
- data/test/fixtures/create_storage_extendedprop_error.xml +8 -8
- data/test/fixtures/create_storage_extendedpropname_error.xml +6 -6
- data/test/fixtures/create_storage_full_error.xml +6 -6
- data/test/fixtures/create_storage_label_error.xml +5 -5
- data/test/fixtures/create_storage_location_error.xml +5 -5
- data/test/fixtures/create_storage_name_error.xml +6 -6
- data/test/fixtures/create_table_response_entry.xml +15 -15
- data/test/fixtures/delete_storage_container_error.xml +5 -5
- data/test/fixtures/delete_storage_error.xml +5 -5
- data/test/fixtures/deployment_error.xml +5 -5
- data/test/fixtures/get_storage_account_error.xml +5 -5
- data/test/fixtures/get_storage_account_properties.xml +31 -31
- data/test/fixtures/get_storage_account_properties_new.xml +31 -31
- data/test/fixtures/http_error.xml +5 -5
- data/test/fixtures/insert_entity_response_entry.xml +25 -25
- data/test/fixtures/list_affinity_groups.xml +22 -22
- data/test/fixtures/list_blobs.xml +120 -120
- data/test/fixtures/list_block_all_with_none_committed.xml +21 -21
- data/test/fixtures/list_blocks_all.xml +22 -22
- data/test/fixtures/list_blocks_committed.xml +12 -12
- data/test/fixtures/list_cloud_services.xml +38 -38
- data/test/fixtures/list_containers.xml +37 -37
- data/test/fixtures/list_firewall_management_endpoint.xml +27 -27
- data/test/fixtures/list_images.xml +110 -110
- data/test/fixtures/list_locations.xml +62 -62
- data/test/fixtures/list_page_ranges.xml +10 -10
- data/test/fixtures/list_sql_database.xml +36 -36
- data/test/fixtures/list_sql_server_firewall.xml +23 -23
- data/test/fixtures/list_storage_account_single.xml +24 -24
- data/test/fixtures/list_storage_accounts.xml +45 -45
- data/test/fixtures/list_virtual_networks.xml +92 -92
- data/test/fixtures/logging.xml +11 -11
- data/test/fixtures/management_certificate.pem +55 -55
- data/test/fixtures/messages.xml +12 -12
- data/test/fixtures/metrics.xml +10 -10
- data/test/fixtures/privatekey.key +28 -28
- data/test/fixtures/query_entities_empty_response.xml +7 -7
- data/test/fixtures/query_entities_response.xml +45 -45
- data/test/fixtures/queue_service_properties.xml +22 -22
- data/test/fixtures/queue_service_properties_original.xml +19 -19
- data/test/fixtures/queues.xml +16 -16
- data/test/fixtures/retention_policy.xml +5 -5
- data/test/fixtures/sb_default_create_queue_response.xml +23 -23
- data/test/fixtures/sb_default_create_relay_response.xml +15 -15
- data/test/fixtures/sb_default_create_topic_response.xml +18 -18
- data/test/fixtures/sb_get_access_token_response.txt +1 -1
- data/test/fixtures/sb_queues_runtime_peek_message_response_headers.txt +9 -9
- data/test/fixtures/storage_service_properties.xml +54 -54
- data/test/fixtures/update_storage_account.xml +16 -16
- data/test/fixtures/update_storage_error.xml +4 -4
- data/test/fixtures/updated_storage_accounts.xml +52 -52
- data/test/fixtures/virtual_machine.xml +113 -113
- data/test/fixtures/windows_virtual_machine.xml +106 -106
- data/test/integration/affinity_group/Affinity_test.rb +55 -55
- data/test/integration/affinity_group/Create_Affinity_test.rb +63 -63
- data/test/integration/affinity_group/Delete_Affinity_test.rb +56 -56
- data/test/integration/affinity_group/List_Affinity_test.rb +41 -41
- data/test/integration/affinity_group/Update_Affinity_test.rb +82 -82
- data/test/integration/blob/blob_gb18030_test.rb +199 -199
- data/test/integration/blob/blob_metadata_test.rb +75 -75
- data/test/integration/blob/blob_pages_test.rb +119 -119
- data/test/integration/blob/blob_properties_test.rb +77 -77
- data/test/integration/blob/block_blob_test.rb +254 -254
- data/test/integration/blob/container/container_acl_test.rb +69 -69
- data/test/integration/blob/container/container_metadata_test.rb +50 -50
- data/test/integration/blob/container/create_container_test.rb +60 -60
- data/test/integration/blob/container/delete_container_test.rb +39 -39
- data/test/integration/blob/container/get_container_properties_test.rb +48 -48
- data/test/integration/blob/container/list_containers_test.rb +79 -79
- data/test/integration/blob/container/root_container_test.rb +53 -53
- data/test/integration/blob/copy_blob_test.rb +113 -113
- data/test/integration/blob/create_blob_snapshot_test.rb +80 -80
- data/test/integration/blob/create_page_blob_test.rb +83 -83
- data/test/integration/blob/delete_blob_test.rb +159 -159
- data/test/integration/blob/get_blob_test.rb +65 -65
- data/test/integration/blob/informative_errors_test.rb +38 -38
- data/test/integration/blob/lease/acquire_lease_test.rb +36 -36
- data/test/integration/blob/lease/break_lease_test.rb +40 -40
- data/test/integration/blob/lease/release_lease_test.rb +40 -40
- data/test/integration/blob/lease/renew_lease_test.rb +42 -42
- data/test/integration/blob/list_blobs_test.rb +113 -113
- data/test/integration/cloud_service/Cloud_Create_test.rb +44 -44
- data/test/integration/cloud_service/Cloud_Delete_test.rb +44 -44
- data/test/integration/database/create_sql_server_firewall_test.rb +86 -86
- data/test/integration/database/create_sql_server_test.rb +53 -53
- data/test/integration/database/delete_sql_server_firewall_test.rb +70 -70
- data/test/integration/database/delete_sql_server_test.rb +58 -58
- data/test/integration/database/list_sql_server_firewall_test.rb +45 -45
- data/test/integration/database/list_sql_servers_test.rb +44 -44
- data/test/integration/database/reset_password_sql_server_test.rb +55 -55
- data/test/integration/location/Location_List_test.rb +39 -39
- data/test/integration/queue/clear_messages_test.rb +42 -42
- data/test/integration/queue/create_message_test.rb +75 -75
- data/test/integration/queue/create_queue_test.rb +50 -50
- data/test/integration/queue/delete_message_test.rb +67 -67
- data/test/integration/queue/delete_queue_test.rb +45 -45
- data/test/integration/queue/informative_errors_test.rb +41 -41
- data/test/integration/queue/list_messages_encoded_test.rb +79 -79
- data/test/integration/queue/list_messages_test.rb +79 -79
- data/test/integration/queue/list_queues_test.rb +44 -44
- data/test/integration/queue/peek_messages_test.rb +59 -59
- data/test/integration/queue/queue_gb18030_test.rb +131 -131
- data/test/integration/queue/queue_metadata_test.rb +40 -40
- data/test/integration/queue/update_message_test.rb +74 -74
- data/test/integration/service_bus/informative_errors_test.rb +36 -36
- data/test/integration/service_bus/queues_scenario_test.rb +200 -200
- data/test/integration/service_bus/queues_test.rb +265 -265
- data/test/integration/service_bus/relay_test.rb +131 -131
- data/test/integration/service_bus/rules_test.rb +144 -144
- data/test/integration/service_bus/sb_queue_gb18030_test.rb +182 -182
- data/test/integration/service_bus/scenario_test.rb +101 -101
- data/test/integration/service_bus/subscriptions_test.rb +211 -211
- data/test/integration/service_bus/topics_scenario_test.rb +406 -406
- data/test/integration/service_bus/topics_test.rb +129 -129
- data/test/integration/storage_management/storage_management_test.rb +160 -160
- data/test/integration/table/create_table_test.rb +35 -35
- data/test/integration/table/delete_entity_batch_test.rb +106 -106
- data/test/integration/table/delete_entity_test.rb +93 -93
- data/test/integration/table/delete_table_test.rb +39 -39
- data/test/integration/table/get_table_test.rb +36 -36
- data/test/integration/table/informative_errors_test.rb +38 -38
- data/test/integration/table/insert_entity_batch_test.rb +99 -99
- data/test/integration/table/insert_entity_test.rb +87 -87
- data/test/integration/table/insert_or_merge_entity_batch_test.rb +158 -158
- data/test/integration/table/insert_or_merge_entity_test.rb +142 -142
- data/test/integration/table/insert_or_replace_entity_batch_test.rb +151 -151
- data/test/integration/table/insert_or_replace_entity_test.rb +136 -136
- data/test/integration/table/merge_entity_batch_test.rb +127 -127
- data/test/integration/table/merge_entity_test.rb +112 -112
- data/test/integration/table/query_entities_test.rb +194 -194
- data/test/integration/table/query_tables_test.rb +42 -42
- data/test/integration/table/query_test.rb +250 -250
- data/test/integration/table/table_acl_test.rb +51 -51
- data/test/integration/table/table_gb18030_test.rb +355 -355
- data/test/integration/table/update_entity_batch_test.rb +148 -148
- data/test/integration/table/update_entity_test.rb +130 -130
- data/test/integration/test_helper.rb +42 -42
- data/test/integration/vm/VM_Create_test.rb +260 -260
- data/test/integration/vm/VM_Delete_test.rb +55 -55
- data/test/integration/vm/VM_Operations_test.rb +173 -173
- data/test/integration/vm_image/virtual_machine_disk_test.rb +37 -37
- data/test/integration/vm_image/virtual_machine_image_test.rb +36 -36
- data/test/integration/vnet/Virtual_Network_Create_test.rb +122 -122
- data/test/integration/vnet/Virtual_Network_list_test.rb +53 -53
- data/test/support/env.rb +19 -19
- data/test/support/fixtures.rb +36 -36
- data/test/support/name_generator.rb +168 -168
- data/test/support/stubs.rb +42 -42
- data/test/support/virtual_machine_name_generator.rb +102 -102
- data/test/support/virtual_network_helper.rb +73 -73
- data/test/test_helper.rb +53 -53
- data/test/unit/affinity_group/affinity_group_test.rb +192 -192
- data/test/unit/affinity_group/serialization_test.rb +88 -88
- data/test/unit/base_management/location_test.rb +57 -57
- data/test/unit/blob/blob_service_test.rb +1946 -1946
- data/test/unit/cloud_service_management/cloud_service_management_service_test.rb +94 -94
- data/test/unit/cloud_service_management/serialization_test.rb +169 -169
- data/test/unit/core/auth/shared_key_lite_test.rb +51 -51
- data/test/unit/core/auth/shared_key_test.rb +58 -58
- data/test/unit/core/auth/signer_test.rb +30 -30
- data/test/unit/core/http/http_error_test.rb +57 -57
- data/test/unit/core/http/http_request_test.rb +66 -66
- data/test/unit/core/http/http_response_test.rb +45 -45
- data/test/unit/core/http/retry_policy_test.rb +23 -23
- data/test/unit/database/serialization_test.rb +97 -97
- data/test/unit/database/sql_database_server_service_test.rb +288 -288
- data/test/unit/service/serialization_test.rb +532 -532
- data/test/unit/service/storage_service_test.rb +292 -292
- data/test/unit/storage_management/serialization_test.rb +232 -232
- data/test/unit/storage_management/storage_management_service_test.rb +261 -261
- data/test/unit/table/edmtype_test.rb +107 -107
- data/test/unit/virtual_machine_image_management/serialization_test.rb +35 -35
- data/test/unit/virtual_machine_image_management/virtual_machine_image_management_service_test.rb +65 -65
- data/test/unit/virtual_machine_management/serialization_test.rb +258 -258
- data/test/unit/virtual_machine_management/virtual_machine_management_service_test.rb +440 -440
- data/test/unit/vnet/serialization_test.rb +187 -187
- data/test/unit/vnet/virtual_network_management_service_test.rb +131 -131
- metadata +34 -27
@@ -1,560 +1,560 @@
|
|
1
|
-
#-------------------------------------------------------------------------
|
2
|
-
# # Copyright (c) Microsoft and contributors. All rights reserved.
|
3
|
-
#
|
4
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
-
# you may not use this file except in compliance with the License.
|
6
|
-
# You may obtain a copy of the License at
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
-
#
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
-
# See the License for the specific language governing permissions and
|
13
|
-
# limitations under the License.
|
14
|
-
#--------------------------------------------------------------------------
|
15
|
-
require 'azure/service/storage_service'
|
16
|
-
|
17
|
-
require 'azure/table/auth/shared_key'
|
18
|
-
|
19
|
-
require 'azure/table/serialization'
|
20
|
-
require 'azure/table/entity'
|
21
|
-
|
22
|
-
module Azure
|
23
|
-
module Table
|
24
|
-
class TableService < Azure::Service::StorageService
|
25
|
-
|
26
|
-
def initialize
|
27
|
-
super(Azure::Table::Auth::SharedKey.new)
|
28
|
-
@host = Azure.config.storage_table_host
|
29
|
-
end
|
30
|
-
|
31
|
-
# Public: Creates new table in the storage account
|
32
|
-
#
|
33
|
-
# ==== Attributes
|
34
|
-
#
|
35
|
-
# * +table_name+ - String. The table name
|
36
|
-
# * +options+ - Hash. Optional parameters.
|
37
|
-
#
|
38
|
-
# ==== Options
|
39
|
-
#
|
40
|
-
# Accepted key/value pairs in options parameter are:
|
41
|
-
#
|
42
|
-
# * +:timeout+ - Integer. A timeout in seconds.
|
43
|
-
#
|
44
|
-
# See http://msdn.microsoft.com/en-us/library/windowsazure/dd135729
|
45
|
-
#
|
46
|
-
# Returns nil on success
|
47
|
-
def create_table(table_name, options={})
|
48
|
-
query = { }
|
49
|
-
query["timeout"] = options[:timeout].to_s if options[:timeout]
|
50
|
-
|
51
|
-
body = Azure::Table::Serialization.hash_to_entry_xml({"TableName" => table_name}).to_xml
|
52
|
-
call(:post, collection_uri(query), body)
|
53
|
-
nil
|
54
|
-
end
|
55
|
-
|
56
|
-
# Public: Deletes the specified table and any data it contains.
|
57
|
-
#
|
58
|
-
# ==== Attributes
|
59
|
-
#
|
60
|
-
# * +table_name+ - String. The table name
|
61
|
-
# * +options+ - Hash. Optional parameters.
|
62
|
-
#
|
63
|
-
# ==== Options
|
64
|
-
#
|
65
|
-
# Accepted key/value pairs in options parameter are:
|
66
|
-
# * +:timeout+ - Integer. A timeout in seconds.
|
67
|
-
#
|
68
|
-
# See http://msdn.microsoft.com/en-us/library/windowsazure/dd179387
|
69
|
-
#
|
70
|
-
# Returns nil on success
|
71
|
-
def delete_table(table_name, options={})
|
72
|
-
query = { }
|
73
|
-
query["timeout"] = options[:timeout].to_s if options[:timeout]
|
74
|
-
|
75
|
-
call(:delete, table_uri(table_name, query))
|
76
|
-
nil
|
77
|
-
end
|
78
|
-
|
79
|
-
# Public: Gets the table.
|
80
|
-
#
|
81
|
-
# ==== Attributes
|
82
|
-
#
|
83
|
-
# * +table_name+ - String. The table name
|
84
|
-
# * +options+ - Hash. Optional parameters.
|
85
|
-
#
|
86
|
-
# ==== Options
|
87
|
-
#
|
88
|
-
# Accepted key/value pairs in options parameter are:
|
89
|
-
# * +:timeout+ - Integer. A timeout in seconds.
|
90
|
-
#
|
91
|
-
# Returns the last updated time for the table
|
92
|
-
def get_table(table_name, options={})
|
93
|
-
query = { }
|
94
|
-
query["timeout"] = options[:timeout].to_s if options[:timeout]
|
95
|
-
|
96
|
-
response = call(:get, table_uri(table_name, query))
|
97
|
-
results = Azure::Table::Serialization.hash_from_entry_xml(response.body)
|
98
|
-
results[:updated]
|
99
|
-
end
|
100
|
-
|
101
|
-
# Public: Gets a list of all tables on the account.
|
102
|
-
#
|
103
|
-
# ==== Attributes
|
104
|
-
#
|
105
|
-
# * +options+ - Hash. Optional parameters.
|
106
|
-
#
|
107
|
-
# ==== Options
|
108
|
-
#
|
109
|
-
# Accepted key/value pairs in options parameter are:
|
110
|
-
# * +:next_table_token+ - String. A token used to enumerate the next page of results, when the list of tables is
|
111
|
-
# larger than a single operation can return at once. (optional)
|
112
|
-
# * +:timeout+ - Integer. A timeout in seconds.
|
113
|
-
#
|
114
|
-
# See http://msdn.microsoft.com/en-us/library/windowsazure/dd179405
|
115
|
-
#
|
116
|
-
# Returns an array with an extra continuation_token property on success
|
117
|
-
def query_tables(options={})
|
118
|
-
query = { }
|
119
|
-
query["NextTable"] = options[:next_table_token] if options[:next_table_token]
|
120
|
-
query["timeout"] = options[:timeout].to_s if options[:timeout]
|
121
|
-
|
122
|
-
uri = collection_uri(query)
|
123
|
-
|
124
|
-
response = call(:get, uri)
|
125
|
-
entries = Azure::Table::Serialization.entries_from_feed_xml(response.body) || []
|
126
|
-
|
127
|
-
values = Azure::Service::EnumerationResults.new(entries)
|
128
|
-
values.continuation_token = response.headers["x-ms-continuation-NextTableName"]
|
129
|
-
values
|
130
|
-
end
|
131
|
-
|
132
|
-
# Public: Gets the access control list (ACL) for the table.
|
133
|
-
#
|
134
|
-
# ==== Attributes
|
135
|
-
#
|
136
|
-
# * +table_name+ - String. The table name
|
137
|
-
# * +options+ - Hash. Optional parameters.
|
138
|
-
#
|
139
|
-
# ==== Options
|
140
|
-
#
|
141
|
-
# Accepted key/value pairs in options parameter are:
|
142
|
-
# * +:timeout+ - Integer. A timeout in seconds.
|
143
|
-
#
|
144
|
-
# See http://msdn.microsoft.com/en-us/library/windowsazure/jj159100
|
145
|
-
#
|
146
|
-
# Returns a list of Azure::Entity::SignedIdentifier instances
|
147
|
-
def get_table_acl(table_name, options={})
|
148
|
-
query = { "comp" => "acl" }
|
149
|
-
query["timeout"] = options[:timeout].to_s if options[:timeout]
|
150
|
-
|
151
|
-
response = call(:get, generate_uri(table_name, query))
|
152
|
-
|
153
|
-
signed_identifiers = []
|
154
|
-
signed_identifiers = Azure::Table::Serialization.signed_identifiers_from_xml response.body unless response.body == nil or response.body.length < 1
|
155
|
-
signed_identifiers
|
156
|
-
end
|
157
|
-
|
158
|
-
# Public: Sets the access control list (ACL) for the table.
|
159
|
-
#
|
160
|
-
# ==== Attributes
|
161
|
-
#
|
162
|
-
# * +table_name+ - String. The table name
|
163
|
-
# * +options+ - Hash. Optional parameters.
|
164
|
-
#
|
165
|
-
# ==== Options
|
166
|
-
#
|
167
|
-
# Accepted key/value pairs in options parameter are:
|
168
|
-
# * +:signed_identifiers+ - Array. A list of Azure::Entity::SignedIdentifier instances
|
169
|
-
# * +:timeout+ - Integer. A timeout in seconds.
|
170
|
-
#
|
171
|
-
# See http://msdn.microsoft.com/en-us/library/windowsazure/jj159102
|
172
|
-
#
|
173
|
-
# Returns nil on success
|
174
|
-
def set_table_acl(table_name, options={})
|
175
|
-
query = { "comp" => "acl" }
|
176
|
-
query["timeout"] = options[:timeout].to_s if options[:timeout]
|
177
|
-
|
178
|
-
uri = generate_uri(table_name, query)
|
179
|
-
body = nil
|
180
|
-
body = Azure::Table::Serialization.signed_identifiers_to_xml options[:signed_identifiers] if options[:signed_identifiers] && options[:signed_identifiers].length > 0
|
181
|
-
|
182
|
-
call(:put, uri, body, {})
|
183
|
-
nil
|
184
|
-
end
|
185
|
-
|
186
|
-
# Public: Inserts new entity to the table.
|
187
|
-
#
|
188
|
-
#
|
189
|
-
# ==== Attributes
|
190
|
-
#
|
191
|
-
# * +table_name+ - String. The table name
|
192
|
-
# * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
|
193
|
-
# * +options+ - Hash. Optional parameters.
|
194
|
-
#
|
195
|
-
# ==== Options
|
196
|
-
#
|
197
|
-
# Accepted key/value pairs in options parameter are:
|
198
|
-
# * +:timeout+ - Integer. A timeout in seconds.
|
199
|
-
#
|
200
|
-
# See http://msdn.microsoft.com/en-us/library/windowsazure/dd179433
|
201
|
-
#
|
202
|
-
# Returns a Azure::Entity::Table::Entity
|
203
|
-
def insert_entity(table_name, entity_values, options={})
|
204
|
-
body = Azure::Table::Serialization.hash_to_entry_xml(entity_values).to_xml
|
205
|
-
|
206
|
-
query = { }
|
207
|
-
query["timeout"] = options[:timeout].to_s if options[:timeout]
|
208
|
-
|
209
|
-
response = call(:post, entities_uri(table_name, nil, nil, query), body)
|
210
|
-
|
211
|
-
result = Azure::Table::Serialization.hash_from_entry_xml(response.body)
|
212
|
-
|
213
|
-
Entity.new do |entity|
|
214
|
-
entity.table = table_name
|
215
|
-
entity.updated = result[:updated]
|
216
|
-
entity.etag = response.headers["etag"] || result[:etag]
|
217
|
-
entity.properties = result[:properties]
|
218
|
-
end
|
219
|
-
end
|
220
|
-
|
221
|
-
# Public: Queries entities for the given table name
|
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
|
-
# * +:partition_key+ - String. The partition key (optional)
|
232
|
-
# * +:row_key+ - String. The row key (optional)
|
233
|
-
# * +:select+ - Array. An array of property names to return (optional)
|
234
|
-
# * +:filter+ - String. A filter expression (optional)
|
235
|
-
# * +:top+ - Integer. A limit for the number of results returned (optional)
|
236
|
-
# * +:continuation_token+ - Hash. The continuation token.
|
237
|
-
# * +:timeout+ - Integer. A timeout in seconds.
|
238
|
-
#
|
239
|
-
# See http://msdn.microsoft.com/en-us/library/windowsazure/dd179421
|
240
|
-
#
|
241
|
-
# Returns an array with an extra continuation_token property on success
|
242
|
-
def query_entities(table_name, options={})
|
243
|
-
query ={}
|
244
|
-
query["$select"] = options[:select].join ',' if options[:select]
|
245
|
-
query["$filter"] = options[:filter] if options[:filter]
|
246
|
-
query["$top"] = options[:top].to_s if options[:top] unless options[:partition_key] and options[:row_key]
|
247
|
-
query["NextPartitionKey"] = options[:continuation_token][:next_partition_key] if options[:continuation_token] and options[:continuation_token][:next_partition_key]
|
248
|
-
query["NextRowKey"] = options[:continuation_token][:next_row_key] if options[:continuation_token] and options[:continuation_token][:next_row_key]
|
249
|
-
query["timeout"] = options[:timeout].to_s if options[:timeout]
|
250
|
-
|
251
|
-
uri = entities_uri(table_name, options[:partition_key], options[:row_key], query)
|
252
|
-
response = call(:get, uri, nil, { "DataServiceVersion" => "2.0;NetFx"})
|
253
|
-
|
254
|
-
entities = Azure::Service::EnumerationResults.new
|
255
|
-
|
256
|
-
results = (options[:partition_key] and options[:row_key]) ? [Azure::Table::Serialization.hash_from_entry_xml(response.body)] : Azure::Table::Serialization.entries_from_feed_xml(response.body)
|
257
|
-
|
258
|
-
results.each do |result|
|
259
|
-
entity = Entity.new do |e|
|
260
|
-
e.table = table_name
|
261
|
-
e.updated = result[:updated]
|
262
|
-
e.etag = response.headers["etag"] || result[:etag]
|
263
|
-
e.properties = result[:properties]
|
264
|
-
end
|
265
|
-
entities.push entity
|
266
|
-
end if results
|
267
|
-
|
268
|
-
entities.continuation_token = nil
|
269
|
-
entities.continuation_token = {
|
270
|
-
:next_partition_key=> response.headers["x-ms-continuation-NextPartitionKey"],
|
271
|
-
:next_row_key => response.headers["x-ms-continuation-NextRowKey"]
|
272
|
-
} if response.headers["x-ms-continuation-NextPartitionKey"]
|
273
|
-
|
274
|
-
entities
|
275
|
-
end
|
276
|
-
|
277
|
-
# Public: Updates an existing entity in a table. The Update Entity operation replaces
|
278
|
-
# the entire entity and can be used to remove properties.
|
279
|
-
#
|
280
|
-
# ==== Attributes
|
281
|
-
#
|
282
|
-
# * +table_name+ - String. The table name
|
283
|
-
# * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
|
284
|
-
# * +options+ - Hash. Optional parameters.
|
285
|
-
#
|
286
|
-
# ==== Options
|
287
|
-
#
|
288
|
-
# Accepted key/value pairs in options parameter are:
|
289
|
-
# * +:if_match+ - String. A matching condition which is required for update (optional, Default="*")
|
290
|
-
# * +:create_if_not_exists+ - Boolean. If true, and partition_key and row_key do not reference and existing entity,
|
291
|
-
# that entity will be inserted. If false, the operation will fail. (optional, Default=false)
|
292
|
-
# * +:timeout+ - Integer. A timeout in seconds.
|
293
|
-
#
|
294
|
-
# See http://msdn.microsoft.com/en-us/library/windowsazure/dd179427
|
295
|
-
#
|
296
|
-
# Returns the ETag for the entity on success
|
297
|
-
def update_entity(table_name, entity_values, options={})
|
298
|
-
if_match = "*"
|
299
|
-
if_match = options[:if_match] if options[:if_match]
|
300
|
-
|
301
|
-
query = { }
|
302
|
-
query["timeout"] = options[:timeout].to_s if options[:timeout]
|
303
|
-
|
304
|
-
uri = entities_uri(table_name, entity_values["PartitionKey"], entity_values["RowKey"], query)
|
305
|
-
|
306
|
-
headers = {}
|
307
|
-
headers["If-Match"] = if_match || "*" unless options[:create_if_not_exists]
|
308
|
-
|
309
|
-
body = Azure::Table::Serialization.hash_to_entry_xml(entity_values).to_xml
|
310
|
-
|
311
|
-
response = call(:put, uri, body, headers)
|
312
|
-
response.headers["etag"]
|
313
|
-
end
|
314
|
-
|
315
|
-
# Public: Updates an existing entity by updating the entity's properties. This operation
|
316
|
-
# does not replace the existing entity, as the update_entity operation does.
|
317
|
-
#
|
318
|
-
# ==== Attributes
|
319
|
-
#
|
320
|
-
# * +table_name+ - String. The table name
|
321
|
-
# * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
|
322
|
-
# * +options+ - Hash. Optional parameters.
|
323
|
-
#
|
324
|
-
# ==== Options
|
325
|
-
#
|
326
|
-
# Accepted key/value pairs in options parameter are:
|
327
|
-
# * +:if_match+ - String. A matching condition which is required for update (optional, Default="*")
|
328
|
-
# * +:create_if_not_exists+ - Boolean. If true, and partition_key and row_key do not reference and existing entity,
|
329
|
-
# that entity will be inserted. If false, the operation will fail. (optional, Default=false)
|
330
|
-
# * +:timeout+ - Integer. A timeout in seconds.
|
331
|
-
#
|
332
|
-
# See http://msdn.microsoft.com/en-us/library/windowsazure/dd179392
|
333
|
-
#
|
334
|
-
# Returns the ETag for the entity on success
|
335
|
-
def merge_entity(table_name, entity_values, options={})
|
336
|
-
if_match = "*"
|
337
|
-
if_match = options[:if_match] if options[:if_match]
|
338
|
-
|
339
|
-
query = { }
|
340
|
-
query["timeout"] = options[:timeout].to_s if options[:timeout]
|
341
|
-
|
342
|
-
uri = entities_uri(table_name, entity_values["PartitionKey"], entity_values["RowKey"], query)
|
343
|
-
|
344
|
-
headers = { "X-HTTP-Method"=> "MERGE" }
|
345
|
-
headers["If-Match"] = if_match || "*" unless options[:create_if_not_exists]
|
346
|
-
|
347
|
-
body = Azure::Table::Serialization.hash_to_entry_xml(entity_values).to_xml
|
348
|
-
|
349
|
-
response = call(:post, uri, body, headers)
|
350
|
-
response.headers["etag"]
|
351
|
-
end
|
352
|
-
|
353
|
-
# Public: Inserts or updates an existing entity within a table by merging new property values into the entity.
|
354
|
-
#
|
355
|
-
# ==== Attributes
|
356
|
-
#
|
357
|
-
# * +table_name+ - String. The table name
|
358
|
-
# * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
|
359
|
-
# * +options+ - Hash. Optional parameters.
|
360
|
-
#
|
361
|
-
# ==== Options
|
362
|
-
#
|
363
|
-
# Accepted key/value pairs in options parameter are:
|
364
|
-
# * +:timeout+ - Integer. A timeout in seconds.
|
365
|
-
#
|
366
|
-
# See http://msdn.microsoft.com/en-us/library/windowsazure/hh452241
|
367
|
-
#
|
368
|
-
# Returns the ETag for the entity on success
|
369
|
-
def insert_or_merge_entity(table_name, entity_values, options={})
|
370
|
-
options[:create_if_not_exists] = true
|
371
|
-
merge_entity(table_name, entity_values, options)
|
372
|
-
end
|
373
|
-
|
374
|
-
# Public: Inserts or updates a new entity into a table.
|
375
|
-
#
|
376
|
-
# ==== Attributes
|
377
|
-
#
|
378
|
-
# * +table_name+ - String. The table name
|
379
|
-
# * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
|
380
|
-
# * +options+ - Hash. Optional parameters.
|
381
|
-
#
|
382
|
-
# ==== Options
|
383
|
-
#
|
384
|
-
# Accepted key/value pairs in options parameter are:
|
385
|
-
# * +:timeout+ - Integer. A timeout in seconds.
|
386
|
-
#
|
387
|
-
# See http://msdn.microsoft.com/en-us/library/windowsazure/hh452242
|
388
|
-
#
|
389
|
-
# Returns the ETag for the entity on success
|
390
|
-
def insert_or_replace_entity(table_name, entity_values, options={})
|
391
|
-
options[:create_if_not_exists] = true
|
392
|
-
update_entity(table_name, entity_values, options)
|
393
|
-
end
|
394
|
-
|
395
|
-
# Public: Deletes an existing entity in the table.
|
396
|
-
#
|
397
|
-
# ==== Attributes
|
398
|
-
#
|
399
|
-
# * +table_name+ - String. The table name
|
400
|
-
# * +partition_key+ - String. The partition key
|
401
|
-
# * +row_key+ - String. The row key
|
402
|
-
# * +options+ - Hash. Optional parameters.
|
403
|
-
#
|
404
|
-
# ==== Options
|
405
|
-
#
|
406
|
-
# Accepted key/value pairs in options parameter are:
|
407
|
-
# * +:if_match+ - String. A matching condition which is required for update (optional, Default="*")
|
408
|
-
# * +:timeout+ - Integer. A timeout in seconds.
|
409
|
-
#
|
410
|
-
# See http://msdn.microsoft.com/en-us/library/windowsazure/dd135727
|
411
|
-
#
|
412
|
-
# Returns nil on success
|
413
|
-
def delete_entity(table_name, partition_key, row_key, options={})
|
414
|
-
if_match = "*"
|
415
|
-
if_match = options[:if_match] if options[:if_match]
|
416
|
-
|
417
|
-
query = { }
|
418
|
-
query["timeout"] = options[:timeout].to_s if options[:timeout]
|
419
|
-
|
420
|
-
call(:delete, entities_uri(table_name, partition_key, row_key, query), nil, { "If-Match"=> if_match })
|
421
|
-
nil
|
422
|
-
end
|
423
|
-
|
424
|
-
# Public: Executes a batch of operations.
|
425
|
-
#
|
426
|
-
# ==== Attributes
|
427
|
-
#
|
428
|
-
# * +batch+ - The Azure::Table::Batch instance to execute.
|
429
|
-
# * +options+ - Hash. Optional parameters.
|
430
|
-
#
|
431
|
-
# ==== Options
|
432
|
-
#
|
433
|
-
# Accepted key/value pairs in options parameter are:
|
434
|
-
# * +:timeout+ - Integer. A timeout in seconds.
|
435
|
-
#
|
436
|
-
# See http://msdn.microsoft.com/en-us/library/windowsazure/dd894038
|
437
|
-
#
|
438
|
-
# Returns an array of results, one for each operation in the batch
|
439
|
-
def execute_batch(batch, options={})
|
440
|
-
headers = {
|
441
|
-
"Content-Type"=> "multipart/mixed; boundary=#{batch.batch_id}",
|
442
|
-
"Accept"=> 'application/atom+xml,application/xml',
|
443
|
-
'Accept-Charset'=> 'UTF-8'
|
444
|
-
}
|
445
|
-
|
446
|
-
query = { }
|
447
|
-
query["timeout"] = options[:timeout].to_s if options[:timeout]
|
448
|
-
|
449
|
-
body = batch.to_body
|
450
|
-
response = call(:post, generate_uri("/$batch", query), body, headers)
|
451
|
-
batch.parse_response(response)
|
452
|
-
end
|
453
|
-
|
454
|
-
# Public: Gets an existing entity in the table.
|
455
|
-
#
|
456
|
-
# ==== Attributes
|
457
|
-
#
|
458
|
-
# * +table_name+ - String. The table name
|
459
|
-
# * +partition_key+ - String. The partition key
|
460
|
-
# * +row_key+ - String. The row key
|
461
|
-
# * +options+ - Hash. Optional parameters.
|
462
|
-
#
|
463
|
-
# ==== Options
|
464
|
-
#
|
465
|
-
# Accepted key/value pairs in options parameter are:
|
466
|
-
# * +:timeout+ - Integer. A timeout in seconds.
|
467
|
-
#
|
468
|
-
# Returns an Azure::Table::Entity instance on success
|
469
|
-
def get_entity(table_name, partition_key, row_key, options={})
|
470
|
-
options[:partition_key] = partition_key
|
471
|
-
options[:row_key] = row_key
|
472
|
-
results = query_entities(table_name, options)
|
473
|
-
results.length > 0 ? results[0] : nil
|
474
|
-
end
|
475
|
-
|
476
|
-
# Protected: Generate the URI for the collection of tables.
|
477
|
-
#
|
478
|
-
# Returns a URI
|
479
|
-
protected
|
480
|
-
def collection_uri(query={})
|
481
|
-
generate_uri("Tables", query)
|
482
|
-
end
|
483
|
-
|
484
|
-
# Public: Generate the URI for a specific table.
|
485
|
-
#
|
486
|
-
# ==== Attributes
|
487
|
-
#
|
488
|
-
# * +name+ - The table name. If this is a URI, we just return this
|
489
|
-
#
|
490
|
-
# Returns a URI
|
491
|
-
public
|
492
|
-
def table_uri(name, query={})
|
493
|
-
return name if name.kind_of? ::URI
|
494
|
-
generate_uri("Tables('#{name}')", query)
|
495
|
-
end
|
496
|
-
|
497
|
-
# Public: Generate the URI for an entity or group of entities in a table.
|
498
|
-
# If both the 'partition_key' and 'row_key' are specified, then the URI
|
499
|
-
# will match the entity under those specific keys.
|
500
|
-
#
|
501
|
-
# ==== Attributes
|
502
|
-
#
|
503
|
-
# * +table_name+ - The table name
|
504
|
-
# * +partition_key+ - The desired partition key (optional)
|
505
|
-
# * +row_key+ - The desired row key (optional)
|
506
|
-
#
|
507
|
-
# Returns a URI
|
508
|
-
public
|
509
|
-
def entities_uri(table_name, partition_key=nil, row_key=nil, query={})
|
510
|
-
return table_name if table_name.kind_of? ::URI
|
511
|
-
|
512
|
-
path = if partition_key && row_key
|
513
|
-
"%s(PartitionKey='%s',RowKey='%s')" % [
|
514
|
-
table_name.encode("UTF-8"), encodeODataUriValue(partition_key.encode("UTF-8")), encodeODataUriValue(row_key.encode("UTF-8"))
|
515
|
-
]
|
516
|
-
else
|
517
|
-
"%s()" % table_name.encode("UTF-8")
|
518
|
-
end
|
519
|
-
|
520
|
-
uri = generate_uri(path)
|
521
|
-
qs = []
|
522
|
-
if query
|
523
|
-
query.each do | key, val |
|
524
|
-
key = key.encode("UTF-8")
|
525
|
-
val = val.encode("UTF-8")
|
526
|
-
|
527
|
-
if key[0] == "$"
|
528
|
-
qs.push "#{key}#{::URI.encode_www_form(""=>val)}"
|
529
|
-
else
|
530
|
-
qs.push ::URI.encode_www_form(key=>val)
|
531
|
-
end
|
532
|
-
end
|
533
|
-
end
|
534
|
-
uri.query = qs.join '&' if qs.length > 0
|
535
|
-
uri
|
536
|
-
end
|
537
|
-
|
538
|
-
protected
|
539
|
-
def encodeODataUriValues(values)
|
540
|
-
new_values = []
|
541
|
-
values.each do |value|
|
542
|
-
new_values.push encodeODataUriValue(value)
|
543
|
-
end
|
544
|
-
new_values
|
545
|
-
end
|
546
|
-
|
547
|
-
protected
|
548
|
-
def encodeODataUriValue(value)
|
549
|
-
# Replace each single quote (') with double single quotes ('') not double
|
550
|
-
# quotes (")
|
551
|
-
value = value.gsub("'", "''")
|
552
|
-
|
553
|
-
# Encode the special URL characters
|
554
|
-
value = URI.escape(value)
|
555
|
-
|
556
|
-
value
|
557
|
-
end
|
558
|
-
end
|
559
|
-
end
|
1
|
+
#-------------------------------------------------------------------------
|
2
|
+
# # Copyright (c) Microsoft and contributors. All rights reserved.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
#--------------------------------------------------------------------------
|
15
|
+
require 'azure/service/storage_service'
|
16
|
+
|
17
|
+
require 'azure/table/auth/shared_key'
|
18
|
+
|
19
|
+
require 'azure/table/serialization'
|
20
|
+
require 'azure/table/entity'
|
21
|
+
|
22
|
+
module Azure
|
23
|
+
module Table
|
24
|
+
class TableService < Azure::Service::StorageService
|
25
|
+
|
26
|
+
def initialize
|
27
|
+
super(Azure::Table::Auth::SharedKey.new)
|
28
|
+
@host = Azure.config.storage_table_host
|
29
|
+
end
|
30
|
+
|
31
|
+
# Public: Creates new table in the storage account
|
32
|
+
#
|
33
|
+
# ==== Attributes
|
34
|
+
#
|
35
|
+
# * +table_name+ - String. The table name
|
36
|
+
# * +options+ - Hash. Optional parameters.
|
37
|
+
#
|
38
|
+
# ==== Options
|
39
|
+
#
|
40
|
+
# Accepted key/value pairs in options parameter are:
|
41
|
+
#
|
42
|
+
# * +:timeout+ - Integer. A timeout in seconds.
|
43
|
+
#
|
44
|
+
# See http://msdn.microsoft.com/en-us/library/windowsazure/dd135729
|
45
|
+
#
|
46
|
+
# Returns nil on success
|
47
|
+
def create_table(table_name, options={})
|
48
|
+
query = { }
|
49
|
+
query["timeout"] = options[:timeout].to_s if options[:timeout]
|
50
|
+
|
51
|
+
body = Azure::Table::Serialization.hash_to_entry_xml({"TableName" => table_name}).to_xml
|
52
|
+
call(:post, collection_uri(query), body)
|
53
|
+
nil
|
54
|
+
end
|
55
|
+
|
56
|
+
# Public: Deletes the specified table and any data it contains.
|
57
|
+
#
|
58
|
+
# ==== Attributes
|
59
|
+
#
|
60
|
+
# * +table_name+ - String. The table name
|
61
|
+
# * +options+ - Hash. Optional parameters.
|
62
|
+
#
|
63
|
+
# ==== Options
|
64
|
+
#
|
65
|
+
# Accepted key/value pairs in options parameter are:
|
66
|
+
# * +:timeout+ - Integer. A timeout in seconds.
|
67
|
+
#
|
68
|
+
# See http://msdn.microsoft.com/en-us/library/windowsazure/dd179387
|
69
|
+
#
|
70
|
+
# Returns nil on success
|
71
|
+
def delete_table(table_name, options={})
|
72
|
+
query = { }
|
73
|
+
query["timeout"] = options[:timeout].to_s if options[:timeout]
|
74
|
+
|
75
|
+
call(:delete, table_uri(table_name, query))
|
76
|
+
nil
|
77
|
+
end
|
78
|
+
|
79
|
+
# Public: Gets the table.
|
80
|
+
#
|
81
|
+
# ==== Attributes
|
82
|
+
#
|
83
|
+
# * +table_name+ - String. The table name
|
84
|
+
# * +options+ - Hash. Optional parameters.
|
85
|
+
#
|
86
|
+
# ==== Options
|
87
|
+
#
|
88
|
+
# Accepted key/value pairs in options parameter are:
|
89
|
+
# * +:timeout+ - Integer. A timeout in seconds.
|
90
|
+
#
|
91
|
+
# Returns the last updated time for the table
|
92
|
+
def get_table(table_name, options={})
|
93
|
+
query = { }
|
94
|
+
query["timeout"] = options[:timeout].to_s if options[:timeout]
|
95
|
+
|
96
|
+
response = call(:get, table_uri(table_name, query))
|
97
|
+
results = Azure::Table::Serialization.hash_from_entry_xml(response.body)
|
98
|
+
results[:updated]
|
99
|
+
end
|
100
|
+
|
101
|
+
# Public: Gets a list of all tables on the account.
|
102
|
+
#
|
103
|
+
# ==== Attributes
|
104
|
+
#
|
105
|
+
# * +options+ - Hash. Optional parameters.
|
106
|
+
#
|
107
|
+
# ==== Options
|
108
|
+
#
|
109
|
+
# Accepted key/value pairs in options parameter are:
|
110
|
+
# * +:next_table_token+ - String. A token used to enumerate the next page of results, when the list of tables is
|
111
|
+
# larger than a single operation can return at once. (optional)
|
112
|
+
# * +:timeout+ - Integer. A timeout in seconds.
|
113
|
+
#
|
114
|
+
# See http://msdn.microsoft.com/en-us/library/windowsazure/dd179405
|
115
|
+
#
|
116
|
+
# Returns an array with an extra continuation_token property on success
|
117
|
+
def query_tables(options={})
|
118
|
+
query = { }
|
119
|
+
query["NextTable"] = options[:next_table_token] if options[:next_table_token]
|
120
|
+
query["timeout"] = options[:timeout].to_s if options[:timeout]
|
121
|
+
|
122
|
+
uri = collection_uri(query)
|
123
|
+
|
124
|
+
response = call(:get, uri)
|
125
|
+
entries = Azure::Table::Serialization.entries_from_feed_xml(response.body) || []
|
126
|
+
|
127
|
+
values = Azure::Service::EnumerationResults.new(entries)
|
128
|
+
values.continuation_token = response.headers["x-ms-continuation-NextTableName"]
|
129
|
+
values
|
130
|
+
end
|
131
|
+
|
132
|
+
# Public: Gets the access control list (ACL) for the table.
|
133
|
+
#
|
134
|
+
# ==== Attributes
|
135
|
+
#
|
136
|
+
# * +table_name+ - String. The table name
|
137
|
+
# * +options+ - Hash. Optional parameters.
|
138
|
+
#
|
139
|
+
# ==== Options
|
140
|
+
#
|
141
|
+
# Accepted key/value pairs in options parameter are:
|
142
|
+
# * +:timeout+ - Integer. A timeout in seconds.
|
143
|
+
#
|
144
|
+
# See http://msdn.microsoft.com/en-us/library/windowsazure/jj159100
|
145
|
+
#
|
146
|
+
# Returns a list of Azure::Entity::SignedIdentifier instances
|
147
|
+
def get_table_acl(table_name, options={})
|
148
|
+
query = { "comp" => "acl" }
|
149
|
+
query["timeout"] = options[:timeout].to_s if options[:timeout]
|
150
|
+
|
151
|
+
response = call(:get, generate_uri(table_name, query))
|
152
|
+
|
153
|
+
signed_identifiers = []
|
154
|
+
signed_identifiers = Azure::Table::Serialization.signed_identifiers_from_xml response.body unless response.body == nil or response.body.length < 1
|
155
|
+
signed_identifiers
|
156
|
+
end
|
157
|
+
|
158
|
+
# Public: Sets the access control list (ACL) for the table.
|
159
|
+
#
|
160
|
+
# ==== Attributes
|
161
|
+
#
|
162
|
+
# * +table_name+ - String. The table name
|
163
|
+
# * +options+ - Hash. Optional parameters.
|
164
|
+
#
|
165
|
+
# ==== Options
|
166
|
+
#
|
167
|
+
# Accepted key/value pairs in options parameter are:
|
168
|
+
# * +:signed_identifiers+ - Array. A list of Azure::Entity::SignedIdentifier instances
|
169
|
+
# * +:timeout+ - Integer. A timeout in seconds.
|
170
|
+
#
|
171
|
+
# See http://msdn.microsoft.com/en-us/library/windowsazure/jj159102
|
172
|
+
#
|
173
|
+
# Returns nil on success
|
174
|
+
def set_table_acl(table_name, options={})
|
175
|
+
query = { "comp" => "acl" }
|
176
|
+
query["timeout"] = options[:timeout].to_s if options[:timeout]
|
177
|
+
|
178
|
+
uri = generate_uri(table_name, query)
|
179
|
+
body = nil
|
180
|
+
body = Azure::Table::Serialization.signed_identifiers_to_xml options[:signed_identifiers] if options[:signed_identifiers] && options[:signed_identifiers].length > 0
|
181
|
+
|
182
|
+
call(:put, uri, body, {})
|
183
|
+
nil
|
184
|
+
end
|
185
|
+
|
186
|
+
# Public: Inserts new entity to the table.
|
187
|
+
#
|
188
|
+
#
|
189
|
+
# ==== Attributes
|
190
|
+
#
|
191
|
+
# * +table_name+ - String. The table name
|
192
|
+
# * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
|
193
|
+
# * +options+ - Hash. Optional parameters.
|
194
|
+
#
|
195
|
+
# ==== Options
|
196
|
+
#
|
197
|
+
# Accepted key/value pairs in options parameter are:
|
198
|
+
# * +:timeout+ - Integer. A timeout in seconds.
|
199
|
+
#
|
200
|
+
# See http://msdn.microsoft.com/en-us/library/windowsazure/dd179433
|
201
|
+
#
|
202
|
+
# Returns a Azure::Entity::Table::Entity
|
203
|
+
def insert_entity(table_name, entity_values, options={})
|
204
|
+
body = Azure::Table::Serialization.hash_to_entry_xml(entity_values).to_xml
|
205
|
+
|
206
|
+
query = { }
|
207
|
+
query["timeout"] = options[:timeout].to_s if options[:timeout]
|
208
|
+
|
209
|
+
response = call(:post, entities_uri(table_name, nil, nil, query), body)
|
210
|
+
|
211
|
+
result = Azure::Table::Serialization.hash_from_entry_xml(response.body)
|
212
|
+
|
213
|
+
Entity.new do |entity|
|
214
|
+
entity.table = table_name
|
215
|
+
entity.updated = result[:updated]
|
216
|
+
entity.etag = response.headers["etag"] || result[:etag]
|
217
|
+
entity.properties = result[:properties]
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
# Public: Queries entities for the given table name
|
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
|
+
# * +:partition_key+ - String. The partition key (optional)
|
232
|
+
# * +:row_key+ - String. The row key (optional)
|
233
|
+
# * +:select+ - Array. An array of property names to return (optional)
|
234
|
+
# * +:filter+ - String. A filter expression (optional)
|
235
|
+
# * +:top+ - Integer. A limit for the number of results returned (optional)
|
236
|
+
# * +:continuation_token+ - Hash. The continuation token.
|
237
|
+
# * +:timeout+ - Integer. A timeout in seconds.
|
238
|
+
#
|
239
|
+
# See http://msdn.microsoft.com/en-us/library/windowsazure/dd179421
|
240
|
+
#
|
241
|
+
# Returns an array with an extra continuation_token property on success
|
242
|
+
def query_entities(table_name, options={})
|
243
|
+
query ={}
|
244
|
+
query["$select"] = options[:select].join ',' if options[:select]
|
245
|
+
query["$filter"] = options[:filter] if options[:filter]
|
246
|
+
query["$top"] = options[:top].to_s if options[:top] unless options[:partition_key] and options[:row_key]
|
247
|
+
query["NextPartitionKey"] = options[:continuation_token][:next_partition_key] if options[:continuation_token] and options[:continuation_token][:next_partition_key]
|
248
|
+
query["NextRowKey"] = options[:continuation_token][:next_row_key] if options[:continuation_token] and options[:continuation_token][:next_row_key]
|
249
|
+
query["timeout"] = options[:timeout].to_s if options[:timeout]
|
250
|
+
|
251
|
+
uri = entities_uri(table_name, options[:partition_key], options[:row_key], query)
|
252
|
+
response = call(:get, uri, nil, { "DataServiceVersion" => "2.0;NetFx"})
|
253
|
+
|
254
|
+
entities = Azure::Service::EnumerationResults.new
|
255
|
+
|
256
|
+
results = (options[:partition_key] and options[:row_key]) ? [Azure::Table::Serialization.hash_from_entry_xml(response.body)] : Azure::Table::Serialization.entries_from_feed_xml(response.body)
|
257
|
+
|
258
|
+
results.each do |result|
|
259
|
+
entity = Entity.new do |e|
|
260
|
+
e.table = table_name
|
261
|
+
e.updated = result[:updated]
|
262
|
+
e.etag = response.headers["etag"] || result[:etag]
|
263
|
+
e.properties = result[:properties]
|
264
|
+
end
|
265
|
+
entities.push entity
|
266
|
+
end if results
|
267
|
+
|
268
|
+
entities.continuation_token = nil
|
269
|
+
entities.continuation_token = {
|
270
|
+
:next_partition_key=> response.headers["x-ms-continuation-NextPartitionKey"],
|
271
|
+
:next_row_key => response.headers["x-ms-continuation-NextRowKey"]
|
272
|
+
} if response.headers["x-ms-continuation-NextPartitionKey"]
|
273
|
+
|
274
|
+
entities
|
275
|
+
end
|
276
|
+
|
277
|
+
# Public: Updates an existing entity in a table. The Update Entity operation replaces
|
278
|
+
# the entire entity and can be used to remove properties.
|
279
|
+
#
|
280
|
+
# ==== Attributes
|
281
|
+
#
|
282
|
+
# * +table_name+ - String. The table name
|
283
|
+
# * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
|
284
|
+
# * +options+ - Hash. Optional parameters.
|
285
|
+
#
|
286
|
+
# ==== Options
|
287
|
+
#
|
288
|
+
# Accepted key/value pairs in options parameter are:
|
289
|
+
# * +:if_match+ - String. A matching condition which is required for update (optional, Default="*")
|
290
|
+
# * +:create_if_not_exists+ - Boolean. If true, and partition_key and row_key do not reference and existing entity,
|
291
|
+
# that entity will be inserted. If false, the operation will fail. (optional, Default=false)
|
292
|
+
# * +:timeout+ - Integer. A timeout in seconds.
|
293
|
+
#
|
294
|
+
# See http://msdn.microsoft.com/en-us/library/windowsazure/dd179427
|
295
|
+
#
|
296
|
+
# Returns the ETag for the entity on success
|
297
|
+
def update_entity(table_name, entity_values, options={})
|
298
|
+
if_match = "*"
|
299
|
+
if_match = options[:if_match] if options[:if_match]
|
300
|
+
|
301
|
+
query = { }
|
302
|
+
query["timeout"] = options[:timeout].to_s if options[:timeout]
|
303
|
+
|
304
|
+
uri = entities_uri(table_name, entity_values["PartitionKey"], entity_values["RowKey"], query)
|
305
|
+
|
306
|
+
headers = {}
|
307
|
+
headers["If-Match"] = if_match || "*" unless options[:create_if_not_exists]
|
308
|
+
|
309
|
+
body = Azure::Table::Serialization.hash_to_entry_xml(entity_values).to_xml
|
310
|
+
|
311
|
+
response = call(:put, uri, body, headers)
|
312
|
+
response.headers["etag"]
|
313
|
+
end
|
314
|
+
|
315
|
+
# Public: Updates an existing entity by updating the entity's properties. This operation
|
316
|
+
# does not replace the existing entity, as the update_entity operation does.
|
317
|
+
#
|
318
|
+
# ==== Attributes
|
319
|
+
#
|
320
|
+
# * +table_name+ - String. The table name
|
321
|
+
# * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
|
322
|
+
# * +options+ - Hash. Optional parameters.
|
323
|
+
#
|
324
|
+
# ==== Options
|
325
|
+
#
|
326
|
+
# Accepted key/value pairs in options parameter are:
|
327
|
+
# * +:if_match+ - String. A matching condition which is required for update (optional, Default="*")
|
328
|
+
# * +:create_if_not_exists+ - Boolean. If true, and partition_key and row_key do not reference and existing entity,
|
329
|
+
# that entity will be inserted. If false, the operation will fail. (optional, Default=false)
|
330
|
+
# * +:timeout+ - Integer. A timeout in seconds.
|
331
|
+
#
|
332
|
+
# See http://msdn.microsoft.com/en-us/library/windowsazure/dd179392
|
333
|
+
#
|
334
|
+
# Returns the ETag for the entity on success
|
335
|
+
def merge_entity(table_name, entity_values, options={})
|
336
|
+
if_match = "*"
|
337
|
+
if_match = options[:if_match] if options[:if_match]
|
338
|
+
|
339
|
+
query = { }
|
340
|
+
query["timeout"] = options[:timeout].to_s if options[:timeout]
|
341
|
+
|
342
|
+
uri = entities_uri(table_name, entity_values["PartitionKey"], entity_values["RowKey"], query)
|
343
|
+
|
344
|
+
headers = { "X-HTTP-Method"=> "MERGE" }
|
345
|
+
headers["If-Match"] = if_match || "*" unless options[:create_if_not_exists]
|
346
|
+
|
347
|
+
body = Azure::Table::Serialization.hash_to_entry_xml(entity_values).to_xml
|
348
|
+
|
349
|
+
response = call(:post, uri, body, headers)
|
350
|
+
response.headers["etag"]
|
351
|
+
end
|
352
|
+
|
353
|
+
# Public: Inserts or updates an existing entity within a table by merging new property values into the entity.
|
354
|
+
#
|
355
|
+
# ==== Attributes
|
356
|
+
#
|
357
|
+
# * +table_name+ - String. The table name
|
358
|
+
# * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
|
359
|
+
# * +options+ - Hash. Optional parameters.
|
360
|
+
#
|
361
|
+
# ==== Options
|
362
|
+
#
|
363
|
+
# Accepted key/value pairs in options parameter are:
|
364
|
+
# * +:timeout+ - Integer. A timeout in seconds.
|
365
|
+
#
|
366
|
+
# See http://msdn.microsoft.com/en-us/library/windowsazure/hh452241
|
367
|
+
#
|
368
|
+
# Returns the ETag for the entity on success
|
369
|
+
def insert_or_merge_entity(table_name, entity_values, options={})
|
370
|
+
options[:create_if_not_exists] = true
|
371
|
+
merge_entity(table_name, entity_values, options)
|
372
|
+
end
|
373
|
+
|
374
|
+
# Public: Inserts or updates a new entity into a table.
|
375
|
+
#
|
376
|
+
# ==== Attributes
|
377
|
+
#
|
378
|
+
# * +table_name+ - String. The table name
|
379
|
+
# * +entity_values+ - Hash. A hash of the name/value pairs for the entity.
|
380
|
+
# * +options+ - Hash. Optional parameters.
|
381
|
+
#
|
382
|
+
# ==== Options
|
383
|
+
#
|
384
|
+
# Accepted key/value pairs in options parameter are:
|
385
|
+
# * +:timeout+ - Integer. A timeout in seconds.
|
386
|
+
#
|
387
|
+
# See http://msdn.microsoft.com/en-us/library/windowsazure/hh452242
|
388
|
+
#
|
389
|
+
# Returns the ETag for the entity on success
|
390
|
+
def insert_or_replace_entity(table_name, entity_values, options={})
|
391
|
+
options[:create_if_not_exists] = true
|
392
|
+
update_entity(table_name, entity_values, options)
|
393
|
+
end
|
394
|
+
|
395
|
+
# Public: Deletes an existing entity in the table.
|
396
|
+
#
|
397
|
+
# ==== Attributes
|
398
|
+
#
|
399
|
+
# * +table_name+ - String. The table name
|
400
|
+
# * +partition_key+ - String. The partition key
|
401
|
+
# * +row_key+ - String. The row key
|
402
|
+
# * +options+ - Hash. Optional parameters.
|
403
|
+
#
|
404
|
+
# ==== Options
|
405
|
+
#
|
406
|
+
# Accepted key/value pairs in options parameter are:
|
407
|
+
# * +:if_match+ - String. A matching condition which is required for update (optional, Default="*")
|
408
|
+
# * +:timeout+ - Integer. A timeout in seconds.
|
409
|
+
#
|
410
|
+
# See http://msdn.microsoft.com/en-us/library/windowsazure/dd135727
|
411
|
+
#
|
412
|
+
# Returns nil on success
|
413
|
+
def delete_entity(table_name, partition_key, row_key, options={})
|
414
|
+
if_match = "*"
|
415
|
+
if_match = options[:if_match] if options[:if_match]
|
416
|
+
|
417
|
+
query = { }
|
418
|
+
query["timeout"] = options[:timeout].to_s if options[:timeout]
|
419
|
+
|
420
|
+
call(:delete, entities_uri(table_name, partition_key, row_key, query), nil, { "If-Match"=> if_match })
|
421
|
+
nil
|
422
|
+
end
|
423
|
+
|
424
|
+
# Public: Executes a batch of operations.
|
425
|
+
#
|
426
|
+
# ==== Attributes
|
427
|
+
#
|
428
|
+
# * +batch+ - The Azure::Table::Batch instance to execute.
|
429
|
+
# * +options+ - Hash. Optional parameters.
|
430
|
+
#
|
431
|
+
# ==== Options
|
432
|
+
#
|
433
|
+
# Accepted key/value pairs in options parameter are:
|
434
|
+
# * +:timeout+ - Integer. A timeout in seconds.
|
435
|
+
#
|
436
|
+
# See http://msdn.microsoft.com/en-us/library/windowsazure/dd894038
|
437
|
+
#
|
438
|
+
# Returns an array of results, one for each operation in the batch
|
439
|
+
def execute_batch(batch, options={})
|
440
|
+
headers = {
|
441
|
+
"Content-Type"=> "multipart/mixed; boundary=#{batch.batch_id}",
|
442
|
+
"Accept"=> 'application/atom+xml,application/xml',
|
443
|
+
'Accept-Charset'=> 'UTF-8'
|
444
|
+
}
|
445
|
+
|
446
|
+
query = { }
|
447
|
+
query["timeout"] = options[:timeout].to_s if options[:timeout]
|
448
|
+
|
449
|
+
body = batch.to_body
|
450
|
+
response = call(:post, generate_uri("/$batch", query), body, headers)
|
451
|
+
batch.parse_response(response)
|
452
|
+
end
|
453
|
+
|
454
|
+
# Public: Gets an existing entity in the table.
|
455
|
+
#
|
456
|
+
# ==== Attributes
|
457
|
+
#
|
458
|
+
# * +table_name+ - String. The table name
|
459
|
+
# * +partition_key+ - String. The partition key
|
460
|
+
# * +row_key+ - String. The row key
|
461
|
+
# * +options+ - Hash. Optional parameters.
|
462
|
+
#
|
463
|
+
# ==== Options
|
464
|
+
#
|
465
|
+
# Accepted key/value pairs in options parameter are:
|
466
|
+
# * +:timeout+ - Integer. A timeout in seconds.
|
467
|
+
#
|
468
|
+
# Returns an Azure::Table::Entity instance on success
|
469
|
+
def get_entity(table_name, partition_key, row_key, options={})
|
470
|
+
options[:partition_key] = partition_key
|
471
|
+
options[:row_key] = row_key
|
472
|
+
results = query_entities(table_name, options)
|
473
|
+
results.length > 0 ? results[0] : nil
|
474
|
+
end
|
475
|
+
|
476
|
+
# Protected: Generate the URI for the collection of tables.
|
477
|
+
#
|
478
|
+
# Returns a URI
|
479
|
+
protected
|
480
|
+
def collection_uri(query={})
|
481
|
+
generate_uri("Tables", query)
|
482
|
+
end
|
483
|
+
|
484
|
+
# Public: Generate the URI for a specific table.
|
485
|
+
#
|
486
|
+
# ==== Attributes
|
487
|
+
#
|
488
|
+
# * +name+ - The table name. If this is a URI, we just return this
|
489
|
+
#
|
490
|
+
# Returns a URI
|
491
|
+
public
|
492
|
+
def table_uri(name, query={})
|
493
|
+
return name if name.kind_of? ::URI
|
494
|
+
generate_uri("Tables('#{name}')", query)
|
495
|
+
end
|
496
|
+
|
497
|
+
# Public: Generate the URI for an entity or group of entities in a table.
|
498
|
+
# If both the 'partition_key' and 'row_key' are specified, then the URI
|
499
|
+
# will match the entity under those specific keys.
|
500
|
+
#
|
501
|
+
# ==== Attributes
|
502
|
+
#
|
503
|
+
# * +table_name+ - The table name
|
504
|
+
# * +partition_key+ - The desired partition key (optional)
|
505
|
+
# * +row_key+ - The desired row key (optional)
|
506
|
+
#
|
507
|
+
# Returns a URI
|
508
|
+
public
|
509
|
+
def entities_uri(table_name, partition_key=nil, row_key=nil, query={})
|
510
|
+
return table_name if table_name.kind_of? ::URI
|
511
|
+
|
512
|
+
path = if partition_key && row_key
|
513
|
+
"%s(PartitionKey='%s',RowKey='%s')" % [
|
514
|
+
table_name.encode("UTF-8"), encodeODataUriValue(partition_key.encode("UTF-8")), encodeODataUriValue(row_key.encode("UTF-8"))
|
515
|
+
]
|
516
|
+
else
|
517
|
+
"%s()" % table_name.encode("UTF-8")
|
518
|
+
end
|
519
|
+
|
520
|
+
uri = generate_uri(path)
|
521
|
+
qs = []
|
522
|
+
if query
|
523
|
+
query.each do | key, val |
|
524
|
+
key = key.encode("UTF-8")
|
525
|
+
val = val.encode("UTF-8")
|
526
|
+
|
527
|
+
if key[0] == "$"
|
528
|
+
qs.push "#{key}#{::URI.encode_www_form(""=>val)}"
|
529
|
+
else
|
530
|
+
qs.push ::URI.encode_www_form(key=>val)
|
531
|
+
end
|
532
|
+
end
|
533
|
+
end
|
534
|
+
uri.query = qs.join '&' if qs.length > 0
|
535
|
+
uri
|
536
|
+
end
|
537
|
+
|
538
|
+
protected
|
539
|
+
def encodeODataUriValues(values)
|
540
|
+
new_values = []
|
541
|
+
values.each do |value|
|
542
|
+
new_values.push encodeODataUriValue(value)
|
543
|
+
end
|
544
|
+
new_values
|
545
|
+
end
|
546
|
+
|
547
|
+
protected
|
548
|
+
def encodeODataUriValue(value)
|
549
|
+
# Replace each single quote (') with double single quotes ('') not double
|
550
|
+
# quotes (")
|
551
|
+
value = value.gsub("'", "''")
|
552
|
+
|
553
|
+
# Encode the special URL characters
|
554
|
+
value = URI.escape(value)
|
555
|
+
|
556
|
+
value
|
557
|
+
end
|
558
|
+
end
|
559
|
+
end
|
560
560
|
end
|