aws-sdk 1.0.0

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.
Files changed (205) hide show
  1. data/.yardopts +6 -0
  2. data/LICENSE.txt +171 -0
  3. data/NOTICE.txt +2 -0
  4. data/README.rdoc +189 -0
  5. data/lib/aws-sdk.rb +14 -0
  6. data/lib/aws.rb +63 -0
  7. data/lib/aws/api_config.rb +45 -0
  8. data/lib/aws/api_config/.document +0 -0
  9. data/lib/aws/api_config/EC2-2011-02-28.yml +2314 -0
  10. data/lib/aws/api_config/SNS-2010-03-31.yml +171 -0
  11. data/lib/aws/api_config/SQS-2009-02-01.yml +161 -0
  12. data/lib/aws/api_config/SimpleDB-2009-04-15.yml +278 -0
  13. data/lib/aws/api_config/SimpleEmailService-2010-12-01.yml +147 -0
  14. data/lib/aws/api_config_transform.rb +32 -0
  15. data/lib/aws/async_handle.rb +90 -0
  16. data/lib/aws/authorize_v2.rb +37 -0
  17. data/lib/aws/authorize_v3.rb +37 -0
  18. data/lib/aws/base_client.rb +524 -0
  19. data/lib/aws/cacheable.rb +92 -0
  20. data/lib/aws/common.rb +228 -0
  21. data/lib/aws/configurable.rb +36 -0
  22. data/lib/aws/configuration.rb +272 -0
  23. data/lib/aws/configured_client_methods.rb +81 -0
  24. data/lib/aws/configured_grammars.rb +65 -0
  25. data/lib/aws/configured_option_grammars.rb +46 -0
  26. data/lib/aws/configured_xml_grammars.rb +47 -0
  27. data/lib/aws/default_signer.rb +38 -0
  28. data/lib/aws/ec2.rb +321 -0
  29. data/lib/aws/ec2/attachment.rb +149 -0
  30. data/lib/aws/ec2/attachment_collection.rb +57 -0
  31. data/lib/aws/ec2/availability_zone.rb +80 -0
  32. data/lib/aws/ec2/availability_zone_collection.rb +47 -0
  33. data/lib/aws/ec2/block_device_mappings.rb +53 -0
  34. data/lib/aws/ec2/client.rb +54 -0
  35. data/lib/aws/ec2/client/xml.rb +127 -0
  36. data/lib/aws/ec2/collection.rb +39 -0
  37. data/lib/aws/ec2/config_transform.rb +63 -0
  38. data/lib/aws/ec2/elastic_ip.rb +107 -0
  39. data/lib/aws/ec2/elastic_ip_collection.rb +85 -0
  40. data/lib/aws/ec2/errors.rb +29 -0
  41. data/lib/aws/ec2/filtered_collection.rb +65 -0
  42. data/lib/aws/ec2/has_permissions.rb +46 -0
  43. data/lib/aws/ec2/image.rb +245 -0
  44. data/lib/aws/ec2/image_collection.rb +235 -0
  45. data/lib/aws/ec2/instance.rb +515 -0
  46. data/lib/aws/ec2/instance_collection.rb +276 -0
  47. data/lib/aws/ec2/key_pair.rb +86 -0
  48. data/lib/aws/ec2/key_pair_collection.rb +102 -0
  49. data/lib/aws/ec2/permission_collection.rb +177 -0
  50. data/lib/aws/ec2/region.rb +81 -0
  51. data/lib/aws/ec2/region_collection.rb +55 -0
  52. data/lib/aws/ec2/request.rb +27 -0
  53. data/lib/aws/ec2/reserved_instances.rb +50 -0
  54. data/lib/aws/ec2/reserved_instances_collection.rb +44 -0
  55. data/lib/aws/ec2/reserved_instances_offering.rb +55 -0
  56. data/lib/aws/ec2/reserved_instances_offering_collection.rb +43 -0
  57. data/lib/aws/ec2/resource.rb +340 -0
  58. data/lib/aws/ec2/resource_tag_collection.rb +218 -0
  59. data/lib/aws/ec2/security_group.rb +246 -0
  60. data/lib/aws/ec2/security_group/ip_permission.rb +70 -0
  61. data/lib/aws/ec2/security_group/ip_permission_collection.rb +59 -0
  62. data/lib/aws/ec2/security_group_collection.rb +132 -0
  63. data/lib/aws/ec2/snapshot.rb +138 -0
  64. data/lib/aws/ec2/snapshot_collection.rb +90 -0
  65. data/lib/aws/ec2/tag.rb +88 -0
  66. data/lib/aws/ec2/tag_collection.rb +114 -0
  67. data/lib/aws/ec2/tagged_collection.rb +48 -0
  68. data/lib/aws/ec2/tagged_item.rb +87 -0
  69. data/lib/aws/ec2/volume.rb +190 -0
  70. data/lib/aws/ec2/volume_collection.rb +95 -0
  71. data/lib/aws/errors.rb +129 -0
  72. data/lib/aws/http/builtin_handler.rb +69 -0
  73. data/lib/aws/http/curb_handler.rb +123 -0
  74. data/lib/aws/http/handler.rb +77 -0
  75. data/lib/aws/http/httparty_handler.rb +61 -0
  76. data/lib/aws/http/request.rb +136 -0
  77. data/lib/aws/http/request_param.rb +63 -0
  78. data/lib/aws/http/response.rb +75 -0
  79. data/lib/aws/ignore_result_element.rb +38 -0
  80. data/lib/aws/indifferent_hash.rb +86 -0
  81. data/lib/aws/inflection.rb +46 -0
  82. data/lib/aws/lazy_error_classes.rb +64 -0
  83. data/lib/aws/meta_utils.rb +43 -0
  84. data/lib/aws/model.rb +57 -0
  85. data/lib/aws/naming.rb +32 -0
  86. data/lib/aws/option_grammar.rb +544 -0
  87. data/lib/aws/policy.rb +912 -0
  88. data/lib/aws/rails.rb +209 -0
  89. data/lib/aws/record.rb +79 -0
  90. data/lib/aws/record/attribute.rb +94 -0
  91. data/lib/aws/record/attribute_macros.rb +288 -0
  92. data/lib/aws/record/attributes/boolean.rb +49 -0
  93. data/lib/aws/record/attributes/datetime.rb +86 -0
  94. data/lib/aws/record/attributes/float.rb +48 -0
  95. data/lib/aws/record/attributes/integer.rb +68 -0
  96. data/lib/aws/record/attributes/sortable_float.rb +60 -0
  97. data/lib/aws/record/attributes/sortable_integer.rb +95 -0
  98. data/lib/aws/record/attributes/string.rb +69 -0
  99. data/lib/aws/record/base.rb +728 -0
  100. data/lib/aws/record/conversion.rb +38 -0
  101. data/lib/aws/record/dirty_tracking.rb +286 -0
  102. data/lib/aws/record/errors.rb +153 -0
  103. data/lib/aws/record/exceptions.rb +48 -0
  104. data/lib/aws/record/finder_methods.rb +262 -0
  105. data/lib/aws/record/naming.rb +31 -0
  106. data/lib/aws/record/scope.rb +157 -0
  107. data/lib/aws/record/validations.rb +653 -0
  108. data/lib/aws/record/validator.rb +237 -0
  109. data/lib/aws/record/validators/acceptance.rb +51 -0
  110. data/lib/aws/record/validators/block.rb +38 -0
  111. data/lib/aws/record/validators/confirmation.rb +43 -0
  112. data/lib/aws/record/validators/count.rb +108 -0
  113. data/lib/aws/record/validators/exclusion.rb +43 -0
  114. data/lib/aws/record/validators/format.rb +57 -0
  115. data/lib/aws/record/validators/inclusion.rb +56 -0
  116. data/lib/aws/record/validators/length.rb +107 -0
  117. data/lib/aws/record/validators/numericality.rb +138 -0
  118. data/lib/aws/record/validators/presence.rb +45 -0
  119. data/lib/aws/resource_cache.rb +39 -0
  120. data/lib/aws/response.rb +113 -0
  121. data/lib/aws/response_cache.rb +50 -0
  122. data/lib/aws/s3.rb +109 -0
  123. data/lib/aws/s3/access_control_list.rb +252 -0
  124. data/lib/aws/s3/acl_object.rb +266 -0
  125. data/lib/aws/s3/bucket.rb +320 -0
  126. data/lib/aws/s3/bucket_collection.rb +122 -0
  127. data/lib/aws/s3/bucket_version_collection.rb +85 -0
  128. data/lib/aws/s3/client.rb +999 -0
  129. data/lib/aws/s3/client/xml.rb +190 -0
  130. data/lib/aws/s3/data_options.rb +99 -0
  131. data/lib/aws/s3/errors.rb +43 -0
  132. data/lib/aws/s3/multipart_upload.rb +318 -0
  133. data/lib/aws/s3/multipart_upload_collection.rb +78 -0
  134. data/lib/aws/s3/object_collection.rb +159 -0
  135. data/lib/aws/s3/object_metadata.rb +67 -0
  136. data/lib/aws/s3/object_upload_collection.rb +83 -0
  137. data/lib/aws/s3/object_version.rb +141 -0
  138. data/lib/aws/s3/object_version_collection.rb +78 -0
  139. data/lib/aws/s3/paginated_collection.rb +94 -0
  140. data/lib/aws/s3/policy.rb +76 -0
  141. data/lib/aws/s3/prefix_and_delimiter_collection.rb +56 -0
  142. data/lib/aws/s3/prefixed_collection.rb +84 -0
  143. data/lib/aws/s3/presigned_post.rb +504 -0
  144. data/lib/aws/s3/request.rb +198 -0
  145. data/lib/aws/s3/s3_object.rb +794 -0
  146. data/lib/aws/s3/tree.rb +116 -0
  147. data/lib/aws/s3/tree/branch_node.rb +71 -0
  148. data/lib/aws/s3/tree/child_collection.rb +108 -0
  149. data/lib/aws/s3/tree/leaf_node.rb +99 -0
  150. data/lib/aws/s3/tree/node.rb +22 -0
  151. data/lib/aws/s3/tree/parent.rb +90 -0
  152. data/lib/aws/s3/uploaded_part.rb +82 -0
  153. data/lib/aws/s3/uploaded_part_collection.rb +86 -0
  154. data/lib/aws/service_interface.rb +60 -0
  155. data/lib/aws/simple_db.rb +202 -0
  156. data/lib/aws/simple_db/attribute.rb +159 -0
  157. data/lib/aws/simple_db/attribute_collection.rb +227 -0
  158. data/lib/aws/simple_db/client.rb +52 -0
  159. data/lib/aws/simple_db/client/options.rb +34 -0
  160. data/lib/aws/simple_db/client/xml.rb +68 -0
  161. data/lib/aws/simple_db/consistent_read_option.rb +42 -0
  162. data/lib/aws/simple_db/delete_attributes.rb +64 -0
  163. data/lib/aws/simple_db/domain.rb +118 -0
  164. data/lib/aws/simple_db/domain_collection.rb +116 -0
  165. data/lib/aws/simple_db/domain_metadata.rb +112 -0
  166. data/lib/aws/simple_db/errors.rb +46 -0
  167. data/lib/aws/simple_db/expect_condition_option.rb +45 -0
  168. data/lib/aws/simple_db/item.rb +84 -0
  169. data/lib/aws/simple_db/item_collection.rb +594 -0
  170. data/lib/aws/simple_db/item_data.rb +70 -0
  171. data/lib/aws/simple_db/put_attributes.rb +62 -0
  172. data/lib/aws/simple_db/request.rb +27 -0
  173. data/lib/aws/simple_email_service.rb +373 -0
  174. data/lib/aws/simple_email_service/client.rb +39 -0
  175. data/lib/aws/simple_email_service/client/options.rb +24 -0
  176. data/lib/aws/simple_email_service/client/xml.rb +38 -0
  177. data/lib/aws/simple_email_service/email_address_collection.rb +66 -0
  178. data/lib/aws/simple_email_service/errors.rb +29 -0
  179. data/lib/aws/simple_email_service/quotas.rb +64 -0
  180. data/lib/aws/simple_email_service/request.rb +27 -0
  181. data/lib/aws/sns.rb +69 -0
  182. data/lib/aws/sns/client.rb +37 -0
  183. data/lib/aws/sns/client/options.rb +24 -0
  184. data/lib/aws/sns/client/xml.rb +38 -0
  185. data/lib/aws/sns/errors.rb +29 -0
  186. data/lib/aws/sns/policy.rb +49 -0
  187. data/lib/aws/sns/request.rb +27 -0
  188. data/lib/aws/sns/subscription.rb +100 -0
  189. data/lib/aws/sns/subscription_collection.rb +84 -0
  190. data/lib/aws/sns/topic.rb +384 -0
  191. data/lib/aws/sns/topic_collection.rb +70 -0
  192. data/lib/aws/sns/topic_subscription_collection.rb +58 -0
  193. data/lib/aws/sqs.rb +70 -0
  194. data/lib/aws/sqs/client.rb +38 -0
  195. data/lib/aws/sqs/client/xml.rb +36 -0
  196. data/lib/aws/sqs/errors.rb +33 -0
  197. data/lib/aws/sqs/policy.rb +50 -0
  198. data/lib/aws/sqs/queue.rb +507 -0
  199. data/lib/aws/sqs/queue_collection.rb +105 -0
  200. data/lib/aws/sqs/received_message.rb +184 -0
  201. data/lib/aws/sqs/received_sns_message.rb +112 -0
  202. data/lib/aws/sqs/request.rb +44 -0
  203. data/lib/aws/xml_grammar.rb +923 -0
  204. data/rails/init.rb +15 -0
  205. metadata +298 -0
@@ -0,0 +1,209 @@
1
+ # Copyright 2011 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"). You
4
+ # may not use this file except in compliance with the License. A copy of
5
+ # the License is located at
6
+ #
7
+ # http://aws.amazon.com/apache2.0/
8
+ #
9
+ # or in the "license" file accompanying this file. This file is
10
+ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11
+ # ANY KIND, either express or implied. See the License for the specific
12
+ # language governing permissions and limitations under the License.
13
+
14
+ require 'aws'
15
+
16
+ module AWS
17
+
18
+ if Object.const_defined?(:Rails) and Rails.const_defined?(:Railtie)
19
+
20
+ class Railtie < Rails::Railtie
21
+
22
+ # configure our plugin on boot. other extension points such
23
+ # as configuration, rake tasks, etc, are also available
24
+ initializer "aws-sdk.initialize" do |app|
25
+ AWS::Rails.setup
26
+ end
27
+ end
28
+
29
+ end
30
+
31
+ # A handful of useful Rails integration methods.
32
+ #
33
+ # If you require this gem inside a Rails application (via config.gem
34
+ # for rails 2 and bundler for rails 3) then AWS::Rails.setup
35
+ # is called automatically.
36
+ module Rails
37
+
38
+ # Adds extra functionality to Rails.
39
+ #
40
+ # Normailly this method is invoked automatically when you require this
41
+ # gem in a Rails Application:
42
+ #
43
+ # Rails 3+ (RAILS_ROOT/Gemfile)
44
+ #
45
+ # gem 'aws-sdk-rails'
46
+ #
47
+ # Rails 2.1 - 2.3 (RAILS_ROOT/config/environment.rb)
48
+ #
49
+ # config.gem 'aws-sdk-rails'
50
+ #
51
+ # === Selective Rails Features
52
+ #
53
+ # If you would prefer to cherry pick a few of the features added by this
54
+ # gem you can change your gem requirement to load 'aws/rails' instead:
55
+ #
56
+ # Rails 3+ (RAILS_ROOT/Gemfile)
57
+ #
58
+ # gem 'aws-sdk-rails', :require => 'aws/rails'
59
+ #
60
+ # Rails 2.1 - 2.3 (RAILS_ROOT/config/environment.rb)
61
+ #
62
+ # config.gem 'aws-sdk-rails', :lib => 'aws/rails'
63
+ #
64
+ # In both of the examples above you can now configure AWS and call the setup
65
+ # methods of choice inside a config initializer (e.g.
66
+ # RAILS_ROOT/config/initializers/aws.rb):
67
+ #
68
+ # AWS.config(...)
69
+ # AWS.log_to_rails_logger
70
+ # AWS.add_action_mailer_delivery_method
71
+ #
72
+ # @return [nil]
73
+ def self.setup
74
+ load_yaml_config
75
+ add_action_mailer_delivery_method
76
+ log_to_rails_logger
77
+ nil
78
+ end
79
+
80
+ # Loads AWS configuration options from +RAILS_ROOT/config/aws.yml+.
81
+ #
82
+ # This configuration file is optional. You can omit this file and instead
83
+ # use ruby to configure AWS inside a configuration initialization script
84
+ # (e.g. RAILS_ROOT/config/intializers/aws.rb).
85
+ #
86
+ # If you have a yaml configuration file it should be formatted like the
87
+ # standard +database.yml+ file in a Rails application. This means there
88
+ # should be one section for Rails environment:
89
+ #
90
+ # development:
91
+ # access_key_id: YOUR_ACCESS_KEY_ID
92
+ # secret_access_key: YOUR_SECRET_ACCESS_KEY
93
+ # simple_db_consistent_reads: false
94
+ #
95
+ # production:
96
+ # access_key_id: YOUR_ACCESS_KEY_ID
97
+ # secret_access_key: YOUR_SECRET_ACCESS_KEY
98
+ # simple_db_consistent_reads: true
99
+ #
100
+ # You should also consider DRYing up your configuration file using
101
+ # YAML references:
102
+ #
103
+ # development:
104
+ # access_key_id: YOUR_ACCESS_KEY_ID
105
+ # secret_access_key: YOUR_SECRET_ACCESS_KEY
106
+ # simple_db_consistent_reads: false
107
+ #
108
+ # production:
109
+ # <<: *development
110
+ # simple_db_consistent_reads: true
111
+ #
112
+ # The yaml file will also be ERB parsed so you can use ruby inside of it:
113
+ #
114
+ # development:
115
+ # access_key_id: YOUR_ACCESS_KEY_ID
116
+ # secret_access_key: <%= read_secret_from_a_secure_location %>
117
+ # simple_db_consistent_reads: false
118
+ #
119
+ # production:
120
+ # <<: *development
121
+ # simple_db_consistent_reads: true
122
+ #
123
+ def self.load_yaml_config
124
+
125
+ path = Pathname.new("#{rails_root}/config/aws.yml")
126
+
127
+ if File.exists?(path)
128
+ cfg = YAML::load(ERB.new(File.read(path)).result)[rails_env]
129
+ AWS.config(cfg)
130
+ end
131
+
132
+ end
133
+
134
+ # Adds a delivery method to ActionMailer that uses {AWS::SimplEmailService}.
135
+ #
136
+ # Once you have an SES delivery method you can configure Rails to use this
137
+ # for ActionMailer in your environment configuration (e.g.
138
+ # RAILS_ROOT/config/environments/production.rb)
139
+ #
140
+ # config.action_mailer.delivery_method = :amazon_ses
141
+ #
142
+ # === Defaults
143
+ #
144
+ # Normally you don't need to call this method. By default a delivery method
145
+ # named +:amazon_ses+ is added to ActionMailer::Base. This delivery method
146
+ # uses your default configuration (#{AWS.config}).
147
+ #
148
+ # === Custom SES Options
149
+ #
150
+ # If you need to supply configuration values for SES that are different than
151
+ # those in {AWS.config} then you can pass those options:
152
+ #
153
+ # AWS.add_action_mailer_delivery_method(:ses, custom_options)
154
+ #
155
+ # @param [Hash] options
156
+ # @param [Symbol] name (:amazon_ses) The name of the delivery
157
+ # method. The name used here should be the same as you set in your
158
+ # environment config. If you name the delivery method +:amazon_ses+ then
159
+ # you could do something like this in your config/environments/ENV.rb file:
160
+ #
161
+ # config.action_mailer.delivery_method = :amazon_ses
162
+ #
163
+ # @param [Hash] options ({}) A hash of options that are passes to
164
+ # {AWS::SimpleEmailService#new} before delivering email.
165
+ #
166
+ # @return [nil]
167
+ def self.add_action_mailer_delivery_method name = :amazon_ses, options = {}
168
+
169
+ amb = ::ActionMailer::Base
170
+
171
+ if ::Rails.version.to_f >= 3
172
+ amb.add_delivery_method(name, AWS::SimpleEmailService, options)
173
+ else
174
+ amb.send(:define_method, "perform_delivery_#{name}") do |mail|
175
+ AWS::SimpleEmailService.new(options).send_raw_email(mail)
176
+ end
177
+ end
178
+
179
+ nil
180
+
181
+ end
182
+
183
+ # Configures AWS to log to the Rails defualt logger.
184
+ # @return [nil]
185
+ def self.log_to_rails_logger
186
+ AWS.config(:logger => rails_logger)
187
+ nil
188
+ end
189
+
190
+ # @private
191
+ protected
192
+ def self.rails_env
193
+ ::Rails.respond_to?(:env) ? ::Rails.env : RAILS_ENV
194
+ end
195
+
196
+ # @private
197
+ protected
198
+ def self.rails_root
199
+ ::Rails.respond_to?(:root) ? ::Rails.root.to_s : RAILS_ROOT
200
+ end
201
+
202
+ # @private
203
+ protected
204
+ def self.rails_logger
205
+ ::Rails.respond_to?(:logger) ? ::Rails.logger : ::RAILS_DEFAULT_LOGGER
206
+ end
207
+
208
+ end
209
+ end
@@ -0,0 +1,79 @@
1
+ # Copyright 2011 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"). You
4
+ # may not use this file except in compliance with the License. A copy of
5
+ # the License is located at
6
+ #
7
+ # http://aws.amazon.com/apache2.0/
8
+ #
9
+ # or in the "license" file accompanying this file. This file is
10
+ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11
+ # ANY KIND, either express or implied. See the License for the specific
12
+ # language governing permissions and limitations under the License.
13
+
14
+ require 'set'
15
+ require 'aws/record/base'
16
+
17
+ module AWS
18
+ module Record
19
+
20
+ # @private
21
+ class RecordNotFound < Exception; end
22
+
23
+ # Sets a prefix to be applied to all SimpleDB domains associated with
24
+ # AWS::Record::Base classes.
25
+ #
26
+ # AWS::Record.domain_prefix = 'production_'
27
+ #
28
+ # class Product < AWS::Record::Base
29
+ # set_domain_name 'products'
30
+ # end
31
+ #
32
+ # Product.domain_name #=> 'production_products'
33
+ #
34
+ # @param [String] A prefix to append to all domains. This is useful for
35
+ # grouping domains used by one application with a single prefix.
36
+ def self.domain_prefix= prefix
37
+ @prefix = prefix
38
+ end
39
+
40
+ # @return [String,nil] The string that is prepended to all domain names.
41
+ def self.domain_prefix
42
+ @prefix
43
+ end
44
+
45
+ # A utility method for casting values into an array.
46
+ #
47
+ # * nil is returned as an empty array, []
48
+ # * Arrays are returned unmodified
49
+ # * Everything else is returned as the sole element of an array
50
+ #
51
+ # @param [Object] value
52
+ # @return [Array] The value cast into an array
53
+ # @private
54
+ def self.as_array value
55
+ case value
56
+ when nil then []
57
+ when Set then value.to_a
58
+ when Array then value
59
+ else [value]
60
+ end
61
+ end
62
+
63
+ # A utility method for casting values into
64
+ #
65
+ # * Sets are returned unmodified
66
+ # * everything else is passed through #{as_array} and then into a new Set
67
+ #
68
+ # @param [Object] value
69
+ # @return [Set] The value cast into a Set.
70
+ # @private
71
+ def self.as_set value
72
+ case value
73
+ when Set then value
74
+ else Set.new(as_array(value))
75
+ end
76
+ end
77
+
78
+ end
79
+ end
@@ -0,0 +1,94 @@
1
+ # Copyright 2011 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"). You
4
+ # may not use this file except in compliance with the License. A copy of
5
+ # the License is located at
6
+ #
7
+ # http://aws.amazon.com/apache2.0/
8
+ #
9
+ # or in the "license" file accompanying this file. This file is
10
+ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11
+ # ANY KIND, either express or implied. See the License for the specific
12
+ # language governing permissions and limitations under the License.
13
+
14
+ module AWS
15
+ module Record
16
+
17
+ # Base class for all of the AWS::Record attributes.
18
+ # @private
19
+ class Attribute
20
+
21
+ # @param [Symbol] Name of this attribute. It should be a name that
22
+ # is safe to use as a method.
23
+ # @param [Hash] options
24
+ # @option options [Boolean] :set (false) When true this attribute can
25
+ # accept multiple unique values.
26
+ def initialize name, options = {}
27
+ @name = name.to_s
28
+ @options = options.dup
29
+ if options[:set] and !self.class.allow_set?
30
+ raise ArgumentError, "invalid option :set for #{self.class}"
31
+ end
32
+ end
33
+
34
+ # @return [String] The name of this attribute
35
+ attr_reader :name
36
+
37
+ # @return [Hash] The hash of options this attribute was constructed with
38
+ attr_reader :options
39
+
40
+ # @return [Boolean] Returns true if this attribute can have
41
+ # multiple values.
42
+ def set?
43
+ options[:set] ? true : false
44
+ end
45
+
46
+ # @return Returns the default value for this attribute. Defaults to nil.
47
+ def default_value
48
+ options[:default_value]
49
+ end
50
+
51
+ # @param [Mixed] A single value to type cast.
52
+ # @return [Mixed] Returns the type casted value.
53
+ def type_cast raw_value
54
+ self.class.type_cast(raw_value, options)
55
+ end
56
+
57
+ # @param [String] The serialized string value.
58
+ # @return [Mixed] Returns a deserialized type-casted value.
59
+ def deserialize serialized_value
60
+ self.class.deserialize(serialized_value, options)
61
+ end
62
+
63
+ # Takes the type casted value and serializes it
64
+ # @param [Mixed] A single value to serialize.
65
+ # @return [Mixed] Returns the serialized value.
66
+ def serialize type_casted_value
67
+ self.class.serialize(type_casted_value, options)
68
+ end
69
+
70
+ # @param [String] serialized_value The string value as returned from AWS.
71
+ # @return [Mixed] Returns the type-casted deserialized value.
72
+ def self.deserialize serialized_value, options = {}
73
+ self.type_cast(serialized_value, options)
74
+ end
75
+
76
+ # @return [Boolean] Returns true if this attribute type can be used
77
+ # with the +:set => true+ option. Certain attirbutes can not
78
+ # be represented with multiple values (like BooleanAttribute).
79
+ def self.allow_set?
80
+ raise 'allow_set? must be defined in subclasses'
81
+ end
82
+
83
+ # @private
84
+ protected
85
+ def self.expect klass, value, &block
86
+ unless value.is_a?(klass)
87
+ raise ArgumentError, "expected a #{klass} value, got #{value.class}"
88
+ end
89
+ yield
90
+ end
91
+
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,288 @@
1
+ # Copyright 2011 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"). You
4
+ # may not use this file except in compliance with the License. A copy of
5
+ # the License is located at
6
+ #
7
+ # http://aws.amazon.com/apache2.0/
8
+ #
9
+ # or in the "license" file accompanying this file. This file is
10
+ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11
+ # ANY KIND, either express or implied. See the License for the specific
12
+ # language governing permissions and limitations under the License.
13
+
14
+ require 'aws/record/attributes/string'
15
+ require 'aws/record/attributes/integer'
16
+ require 'aws/record/attributes/sortable_integer'
17
+ require 'aws/record/attributes/float'
18
+ require 'aws/record/attributes/sortable_float'
19
+ require 'aws/record/attributes/boolean'
20
+ require 'aws/record/attributes/datetime'
21
+
22
+ module AWS
23
+ module Record
24
+ module AttributeMacros
25
+
26
+ # Adds a string attribute to this class.
27
+ #
28
+ # @example A standard string attribute
29
+ #
30
+ # class Recipe < AWS::Record::Base
31
+ # string_attr :name
32
+ # end
33
+ #
34
+ # recipe = Recipe.new(:name => "Buttermilk Pancakes")
35
+ # recipe.name #=> 'Buttermilk Pancakes'
36
+ #
37
+ # @example A string attribute with +:set+ set to true
38
+ #
39
+ # class Recipe < AWS::Record::Base
40
+ # string_attr :tags, :set => true
41
+ # end
42
+ #
43
+ # recipe = Recipe.new(:tags => %w(popular dessert))
44
+ # recipe.tags #=> #<Set: {"popular", "desert"}>
45
+ #
46
+ # @param [Symbol] name The name of the attribute.
47
+ # @param [Hash] options
48
+ # @option options [Boolean] :set (false) When true this attribute
49
+ # can have multiple values.
50
+ def string_attr name, options = {}
51
+ add_attribute(StringAttribute.new(name, options))
52
+ end
53
+
54
+ # Adds an integer attribute to this class.
55
+ #
56
+ # class Recipe < AWS::Record::Base
57
+ # integer_attr :servings
58
+ # end
59
+ #
60
+ # recipe = Recipe.new(:servings => '10')
61
+ # recipe.servings #=> 10
62
+ #
63
+ # @param [Symbol] name The name of the attribute.
64
+ # @param [Hash] options
65
+ # @option options [Boolean] :set (false) When true this attribute
66
+ # can have multiple values.
67
+ def integer_attr name, options = {}
68
+ add_attribute(IntegerAttribute.new(name, options))
69
+ end
70
+
71
+ # Adds a sortable integer attribute to this class.
72
+ #
73
+ # class Person < AWS::Record::Base
74
+ # sortable_integer_attr :age, :range => 0..150
75
+ # end
76
+ #
77
+ # person = Person.new(:age => 10)
78
+ # person.age #=> 10
79
+ #
80
+ # === Validations
81
+ #
82
+ # It is recomended to apply a validates_numericality_of with
83
+ # minimum and maximum value constraints. If a value is assigned
84
+ # to a sortable integer that falls outside of the +:range: it will
85
+ # raise a runtime error when the record is saved.
86
+ #
87
+ # === Difference Between Sortable an Regular Integer Attributes
88
+ #
89
+ # Because SimpleDB does not support numeric types, all values must
90
+ # be converted to strings. This complicates sorting by numeric values.
91
+ # To accomplish sorting numeric attributes the values must be
92
+ # zero padded and have an offset applied to eliminate negative values.
93
+ #
94
+ # @param [Symbol] name The name of the attribute.
95
+ # @param [Hash] options
96
+ # @option options [Range] :range A numeric range the represents the
97
+ # minimum and maximum values this attribute should accept.
98
+ # @option options [Boolean] :set (false) When true this attribute
99
+ # can have multiple values.
100
+ def sortable_integer_attr name, options = {}
101
+ add_attribute(SortableIntegerAttribute.new(name, options))
102
+ end
103
+
104
+ # Adds a float attribute to this class.
105
+ #
106
+ # class Listing < AWS::Record::Base
107
+ # float_attr :score
108
+ # end
109
+ #
110
+ # listing = Listing.new(:score => '123.456')
111
+ # listing.score # => 123.456
112
+ #
113
+ # @param [Symbol] name The name of the attribute.
114
+ # @param [Hash] options
115
+ # @option options [Boolean] :set (false) When true this attribute
116
+ # can have multiple values.
117
+ def float_attr name, options = {}
118
+ add_attribute(FloatAttribute.new(name, options))
119
+ end
120
+
121
+ # Adds sortable float attribute to this class.
122
+ #
123
+ # Persisted values are stored (and sorted) as strings. This makes it
124
+ # more difficult to sort numbers because they don't sort
125
+ # lexicographically unless they have been offset to be positive and
126
+ # then zero padded.
127
+ #
128
+ # === Postive Floats
129
+ #
130
+ # To store floats in a sort-friendly manor:
131
+ #
132
+ # sortable_float_attr :score, :range => (0..10)
133
+ #
134
+ # This will cause values like 5.5 to persist as a string like '05.5' so
135
+ # that they can be sorted lexicographically.
136
+ #
137
+ # === Negative Floats
138
+ #
139
+ # If you need to store negative sortable floats, increase your +:range+
140
+ # to include a negative value.
141
+ #
142
+ # sortable_float_attr :position, :range => (-10..10)
143
+ #
144
+ # AWS::Record will add 10 to all values and zero pad them
145
+ # (e.g. -10.0 will be represented as '00.0' and 10 will be represented as
146
+ # '20.0'). This will allow the values to be compared lexicographically.
147
+ #
148
+ # @note If you change the +:range+ after some values have been persisted
149
+ # you must also manually migrate all of the old values to have the
150
+ # correct padding & offset or they will be interpreted differently.
151
+ #
152
+ # @param [Symbol] name The name of the attribute.
153
+ # @param [Hash] options
154
+ # @option options [Range] :range The range of numbers this attribute
155
+ # should represent. The min and max values of this range will determine
156
+ # how many digits of precision are required and how much of an offset
157
+ # is required to make the numbers sort lexicographically.
158
+ # @option options [Boolean] :set (false) When true this attribute
159
+ # can have multiple values.
160
+ def sortable_float_attr name, options = {}
161
+ add_attribute(SortableFloatAttribute.new(name, options))
162
+ end
163
+
164
+ # Adds a boolean attribute to this class.
165
+ #
166
+ # @example
167
+ #
168
+ # class Book < AWS::Record::Base
169
+ # boolean_attr :read
170
+ # end
171
+ #
172
+ # b = Book.new
173
+ # b.read? # => false
174
+ # b.read = true
175
+ # b.read? # => true
176
+ #
177
+ # listing = Listing.new(:score => '123.456'
178
+ # listing.score # => 123.456
179
+ #
180
+ # @param [Symbol] name The name of the attribute.
181
+ def boolean_attr name, options = {}
182
+
183
+ attr = add_attribute(BooleanAttribute.new(name, options))
184
+
185
+ # add the boolean question mark method
186
+ define_method("#{attr.name}?") do
187
+ !!__send__(attr.name)
188
+ end
189
+
190
+ end
191
+
192
+ # Adds a datetime attribute to this class.
193
+ #
194
+ # @example A standard datetime attribute
195
+ #
196
+ # class Recipe < AWS::Record::Base
197
+ # datetime_attr :invented
198
+ # end
199
+ #
200
+ # recipe = Recipe.new(:invented => Time.now)
201
+ # recipe.invented #=> <DateTime ...>
202
+ #
203
+ # If you add a datetime_attr for +:created_at+ and/or +:updated_at+ those
204
+ # will be automanaged.
205
+ #
206
+ # @param [Symbol] name The name of the attribute.
207
+ # @param [Hash] options
208
+ # @option options [Integer] :precision When set, the integer will be
209
+ # serialized with the correct number of digits to SimpleDB, left
210
+ # padded by zeros to allow sorting.
211
+ # @option options [Boolean] :set (false) When true this attribute
212
+ # can have multiple values.
213
+ def datetime_attr name, options = {}
214
+ add_attribute(DateTimeAttribute.new(name, options))
215
+ end
216
+
217
+ # A convenience method for adding the standard two datetime attributes
218
+ # +:created_at+ and +:updated_at+.
219
+ #
220
+ # @example
221
+ #
222
+ # class Recipe < AWS::Record::Base
223
+ # timestamps
224
+ # end
225
+ #
226
+ # recipe = Recipe.new
227
+ # recipe.save
228
+ # recipe.created_at #=> <DateTime ...>
229
+ # recipe.updated_at #=> <DateTime ...>
230
+ #
231
+ def timestamps
232
+ c = datetime_attr :created_at
233
+ u = datetime_attr :updated_at
234
+ [c, u]
235
+ end
236
+
237
+ # @private
238
+ private
239
+ def add_attribute attribute
240
+
241
+ attr_name = attribute.name
242
+
243
+ attributes[attr_name] = attribute
244
+
245
+ # setter
246
+ define_method("#{attr_name}=") do |value|
247
+ self[attr_name] = value
248
+ end
249
+
250
+ # getter
251
+ define_method(attr_name) do
252
+ self[attr_name]
253
+ end
254
+
255
+ # before type-cast getter
256
+ define_method("#{attr_name}_before_type_cast") do
257
+ @_data[attr_name]
258
+ end
259
+
260
+ ## dirty tracking methods
261
+
262
+ define_method("#{attr_name}_changed?") do
263
+ attribute_changed?(attr_name)
264
+ end
265
+
266
+ define_method("#{attr_name}_change") do
267
+ attribute_change(attr_name)
268
+ end
269
+
270
+ define_method("#{attr_name}_was") do
271
+ attribute_was(attr_name)
272
+ end
273
+
274
+ define_method("#{attr_name}_will_change!") do
275
+ attribute_will_change!(attr_name)
276
+ end
277
+
278
+ define_method("reset_#{attr_name}!") do
279
+ reset_attribute!(attr_name)
280
+ end
281
+
282
+ attribute
283
+
284
+ end
285
+
286
+ end
287
+ end
288
+ end