aws-sdk 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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