aws-sdk 1.2.6 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. data/lib/aws.rb +2 -0
  2. data/lib/aws/api_config/DynamoDB-2011-12-05.yml +721 -0
  3. data/lib/aws/core.rb +10 -1
  4. data/lib/aws/core/client.rb +17 -12
  5. data/lib/aws/core/configuration.rb +13 -3
  6. data/lib/aws/core/configured_json_client_methods.rb +71 -0
  7. data/lib/aws/core/lazy_error_classes.rb +7 -2
  8. data/lib/aws/core/option_grammar.rb +67 -13
  9. data/lib/aws/core/resource.rb +9 -1
  10. data/lib/aws/core/session_signer.rb +95 -0
  11. data/lib/aws/dynamo_db.rb +169 -0
  12. data/lib/aws/dynamo_db/attribute_collection.rb +460 -0
  13. data/lib/aws/dynamo_db/batch_get.rb +206 -0
  14. data/lib/aws/dynamo_db/client.rb +119 -0
  15. data/lib/aws/dynamo_db/config.rb +20 -0
  16. data/lib/aws/dynamo_db/errors.rb +57 -0
  17. data/lib/aws/dynamo_db/expectations.rb +40 -0
  18. data/lib/aws/dynamo_db/item.rb +130 -0
  19. data/lib/aws/dynamo_db/item_collection.rb +837 -0
  20. data/lib/aws/{record/optimistic_locking.rb → dynamo_db/item_data.rb} +9 -12
  21. data/lib/aws/{record/attributes/boolean.rb → dynamo_db/keys.rb} +15 -23
  22. data/lib/aws/dynamo_db/primary_key_element.rb +47 -0
  23. data/lib/aws/dynamo_db/request.rb +78 -0
  24. data/lib/aws/{record/attributes/float.rb → dynamo_db/resource.rb} +10 -25
  25. data/lib/aws/dynamo_db/table.rb +418 -0
  26. data/lib/aws/dynamo_db/table_collection.rb +165 -0
  27. data/lib/aws/dynamo_db/types.rb +86 -0
  28. data/lib/aws/ec2/resource_tag_collection.rb +3 -1
  29. data/lib/aws/record.rb +36 -8
  30. data/lib/aws/record/abstract_base.rb +642 -0
  31. data/lib/aws/record/attributes.rb +384 -0
  32. data/lib/aws/record/dirty_tracking.rb +0 -1
  33. data/lib/aws/record/errors.rb +0 -8
  34. data/lib/aws/record/hash_model.rb +163 -0
  35. data/lib/aws/record/hash_model/attributes.rb +182 -0
  36. data/lib/aws/record/hash_model/finder_methods.rb +178 -0
  37. data/lib/aws/record/hash_model/scope.rb +108 -0
  38. data/lib/aws/record/model.rb +429 -0
  39. data/lib/aws/record/model/attributes.rb +377 -0
  40. data/lib/aws/record/model/finder_methods.rb +232 -0
  41. data/lib/aws/record/model/scope.rb +213 -0
  42. data/lib/aws/record/scope.rb +43 -169
  43. data/lib/aws/record/validations.rb +11 -11
  44. data/lib/aws/s3/client.rb +9 -6
  45. data/lib/aws/s3/object_collection.rb +1 -1
  46. data/lib/aws/simple_db/expect_condition_option.rb +1 -1
  47. data/lib/aws/simple_db/item_collection.rb +5 -3
  48. data/lib/aws/sts/client.rb +9 -0
  49. metadata +73 -30
  50. data/lib/aws/record/attribute.rb +0 -94
  51. data/lib/aws/record/attribute_macros.rb +0 -312
  52. data/lib/aws/record/attributes/date.rb +0 -89
  53. data/lib/aws/record/attributes/datetime.rb +0 -86
  54. data/lib/aws/record/attributes/integer.rb +0 -68
  55. data/lib/aws/record/attributes/sortable_float.rb +0 -60
  56. data/lib/aws/record/attributes/sortable_integer.rb +0 -95
  57. data/lib/aws/record/attributes/string.rb +0 -69
  58. data/lib/aws/record/base.rb +0 -828
  59. data/lib/aws/record/finder_methods.rb +0 -230
  60. data/lib/aws/record/scopes.rb +0 -55
@@ -0,0 +1,232 @@
1
+ # Copyright 2011-2012 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
+ class Model
17
+ class << self
18
+
19
+ # @param [String] id The id of the record to load.
20
+ # @param [Hash] options
21
+ # @option options [String] :shard Specifies what shard (i.e. domain)
22
+ # should be searched.
23
+ # @raise [RecordNotFound] Raises a record not found exception if there
24
+ # was no data found for the given id.
25
+ # @return [Record::HashModel] Returns the record with the given id.
26
+ def find_by_id id, options = {}
27
+
28
+ domain = sdb_domain(options[:shard] || options[:domain])
29
+
30
+ data = domain.items[id].data.attributes
31
+
32
+ raise RecordNotFound, "no data found for id: #{id}" if data.empty?
33
+
34
+ obj = self.new(:shard => domain)
35
+ obj.send(:hydrate, id, data)
36
+ obj
37
+
38
+ end
39
+ alias_method :[], :find_by_id
40
+
41
+ # Finds records in SimpleDB and returns them as objects of the
42
+ # current class.
43
+ #
44
+ # Finding +:all+ returns an enumerable scope object
45
+ #
46
+ # People.find(:all, :order => [:age, :desc], :limit => 10).each do |person|
47
+ # puts person.name
48
+ # end
49
+ #
50
+ # Finding +:first+ returns a single record (or nil)
51
+ #
52
+ # boss = People.find(:first, :where => { :boss => true })
53
+ #
54
+ # Find accepts a hash of find modifiers (+:where+, +:order+ and
55
+ # +:limit+). You can also choose to omit these modifiers and
56
+ # chain them on the scope object returned. In the following
57
+ # example only one request is made to SimpleDB (when #each is
58
+ # called)
59
+ #
60
+ # people = People.find(:all)
61
+ #
62
+ # johns = people.where(:name => 'John Doe')
63
+ #
64
+ # johns.order(:age, :desc).limit(10).each do |suspects|
65
+ # # ...
66
+ # end
67
+ #
68
+ # See also {#where}, {#order} and {#limit} for more
69
+ # information and options.
70
+ #
71
+ # @overload find(id)
72
+ # @param id The record to find, raises an exception if the record is
73
+ # not found.
74
+ #
75
+ # @overload find(mode, options = {})
76
+ # @param [:all,:first] mode (:all) When finding +:all+ matching records
77
+ # and array is returned of records. When finding +:first+ then
78
+ # +nil+ or a single record will be returned.
79
+ # @param [Hash] options
80
+ # @option options [Mixed] :where Conditions that determine what
81
+ # records are returned.
82
+ # @option options [String,Array] :sort The order records should be
83
+ # returned in.
84
+ # @option options [Integer] :limit The max number of records to fetch.
85
+ def find *args
86
+ new_scope.find(*args)
87
+ end
88
+
89
+ # Returns a chainable scope object that restricts further scopes to a
90
+ # particular domain.
91
+ #
92
+ # Book.domain('books-2').each do |book|
93
+ # # ...
94
+ # end
95
+ #
96
+ # @param [String] domain
97
+ # @return [Scope] Returns a scope for restricting the domain of subsequent
98
+ def shard shard_name
99
+ new_scope.shard(shard_name)
100
+ end
101
+ alias_method :domain, :shard
102
+
103
+ # Returns an enumerable scope object represents all records.
104
+ #
105
+ # Book.all.each do |book|
106
+ # # ...
107
+ # end
108
+ #
109
+ # This method is equivalent to +find(:all)+, and therefore you can also
110
+ # pass aditional options. See {#find} for more information on what
111
+ # options you can pass.
112
+ #
113
+ # Book.all(:where => { :author' => 'me' }).each do |my_book|
114
+ # # ...
115
+ # end
116
+ #
117
+ # @return [Scope] Returns an enumerable scope object.
118
+ def all options = {}
119
+ new_scope.find(:all, options)
120
+ end
121
+
122
+ # Yields once for each record.
123
+ def each &block
124
+ all.each(&block)
125
+ end
126
+
127
+ # Counts records in SimpleDB.
128
+ #
129
+ # With no arguments, counts all records:
130
+ #
131
+ # People.count
132
+ #
133
+ # Accepts query options to count a subset of records:
134
+ #
135
+ # People.count(:where => { :boss => true })
136
+ #
137
+ # You can also count records on a scope object:
138
+ #
139
+ # People.find(:all).where(:boss => true).count
140
+ #
141
+ # See {#find} and {Scope#count} for more details.
142
+ #
143
+ # @param [Hash] options (<code>{}</code>) Options for counting
144
+ # records.
145
+ #
146
+ # @option options [Mixed] :where Conditions that determine what
147
+ # records are counted.
148
+ # @option options [Integer] :limit The max number of records to count.
149
+ def count(options = {})
150
+ new_scope.count(options)
151
+ end
152
+ alias_method :size, :count
153
+
154
+ # @return [Object,nil] Returns the first record found. If there were
155
+ # no records found, nil is returned.
156
+ def first options = {}
157
+ new_scope.first(options)
158
+ end
159
+
160
+ # Limits which records are retried from SimpleDB when performing a find.
161
+ #
162
+ # Simple string condition
163
+ #
164
+ # Car.where('color = "red" or color = "blue"').each {|car| ... }
165
+ #
166
+ # String with placeholders for quoting params
167
+ #
168
+ # Car.where('color = ?', 'red')
169
+ #
170
+ # Car.where('color = ? OR style = ?', 'red', 'compact')
171
+ #
172
+ # # produces a condition using in, like: WHERE color IN ('red', 'blue')
173
+ # Car.where('color IN ?', ['red','blue'])
174
+ #
175
+ # Hash arguments
176
+ #
177
+ # # WHERE age = '40' AND gender = 'male'
178
+ # People.where(:age => 40, :gender => 'male').each {|person| ... }
179
+ #
180
+ # # WHERE name IN ('John', 'Jane')
181
+ # People.where(:name => ['John', 'Jane']).each{|person| ... }
182
+ #
183
+ # Chaining where with other scope modifiers
184
+ #
185
+ # # 10 most expensive red cars
186
+ # Car.where(:color => 'red').order(:price, :desc).limit(10)
187
+ #
188
+ # @overload where(conditions_hash)
189
+ # @overload where(sql_fragment[, quote_params, ...])
190
+ #
191
+ # @param [Hash] conditions_hash A hash of attributes to values. Each
192
+ # key/value pair from the hash becomes a find condition. All conditions
193
+ # are joined by AND.
194
+ def where *args
195
+ new_scope.where(*args)
196
+ end
197
+
198
+ # Defines the order in which records are returned when performing a find.
199
+ # SimpleDB only allows sorting by one attribute per request.
200
+ #
201
+ # # oldest to youngest
202
+ # People.order(:age, :desc).each {|person| ... }
203
+ #
204
+ # You can chain order with the other scope modifiers:
205
+ #
206
+ # Pepole.order(:age, :desc).limit(10).each {|person| ... }
207
+ #
208
+ # @overload order(attribute, direction = :asc)
209
+ # @param [String,Symbol] attribute The attribute in SimpleDB to sort by.
210
+ # @param [:asc,:desc] direction (:asc) The direction to sort, ascending
211
+ # or descending order.
212
+ def order *args
213
+ new_scope.order(*args)
214
+ end
215
+
216
+ # The maximum number of records to return. By default, all records
217
+ # matching the where conditions will be returned from a find.
218
+ #
219
+ # People.limit(10).each {|person| ... }
220
+ #
221
+ # Limit can be chained with other scope modifiers:
222
+ #
223
+ # People.where(:age => 40).limit(10).each {|person| ... }
224
+ #
225
+ def limit limit
226
+ new_scope.limit(limit)
227
+ end
228
+
229
+ end
230
+ end
231
+ end
232
+ end
@@ -0,0 +1,213 @@
1
+ # Copyright 2011-2012 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
+ class Model
17
+
18
+ # The primary interface for finding records with {AWS::Record::Model}.
19
+ #
20
+ # == Getting a Scope Object
21
+ #
22
+ # You should normally never need to construct a Scope object directly.
23
+ # Scope objects are returned from the AWS::Record::Model finder methods
24
+ # (e.g. +shard+, +where+, +order+, +limit+, etc).
25
+ #
26
+ # books = Book.where(:author => 'John Doe')
27
+ # books.class #=> AWS::Record::Scope, not Array
28
+ #
29
+ # Scopes are also returned from methods defined with the +scope+ method.
30
+ #
31
+ # == Chaining Scopes
32
+ #
33
+ # Scope objects represent a request, but do not actualy make a request
34
+ # until required. This allows you to chain requests
35
+ #
36
+ # # no request made by the following 2 statements
37
+ # books = Book.where(:author => 'John Doe')
38
+ # books = books.limit(10)
39
+ #
40
+ # books.each do |book|
41
+ # # yields up to 10 books
42
+ # end
43
+ #
44
+ # Each of the following methods returns a scope that can be chained.
45
+ #
46
+ # * {#shard}
47
+ # * {#where}
48
+ # * {#order}
49
+ # * {#limit}
50
+ #
51
+ # == Terminating Scopes
52
+ #
53
+ # To terminate a scope you can enumerate it or call #first.
54
+ #
55
+ # # terminate a scope by enumerating
56
+ # Book.limit(10).each {|book| ... }
57
+ #
58
+ # # terminate a scope by getting the first value
59
+ # Book.where('author' => 'John Doe').first
60
+ #
61
+ class Scope < Record::Scope
62
+
63
+ # @private
64
+ def initialize base_class, options = {}
65
+ super
66
+ @options[:where] ||= []
67
+ end
68
+
69
+ def new attributes = {}
70
+
71
+ attributes = attributes.dup
72
+
73
+ @options[:where].each do |conditions|
74
+ if conditions.size == 1 and conditions.first.is_a?(Hash)
75
+ attributes.merge!(conditions.first)
76
+ end
77
+ end
78
+
79
+ super(attributes)
80
+
81
+ end
82
+
83
+ # Applies conditions to the scope that limit which records are returned.
84
+ # Only those matching all given conditions will be returned.
85
+ #
86
+ # @overload where(conditions_hash)
87
+ # Specify a hash of conditions to query with. Multiple conditions
88
+ # are joined together with AND.
89
+ #
90
+ # Book.where(:author => 'John Doe', :softcover => true)
91
+ # # where `author` = `John Doe` AND `softcover` = `1`
92
+ #
93
+ # @param [Hash] conditions
94
+ #
95
+ # @overload where(conditions_string, *values)
96
+ # A sql-like query fragment with optional placeholders and values.
97
+ # Placeholders are replaced with properly quoted values.
98
+ #
99
+ # Book.where('author = ?', 'John Doe')
100
+ #
101
+ # @param [String] conditions_string A sql-like where string with
102
+ # question mark placeholders. For each placeholder there should
103
+ # be a value that will be quoted into that position.
104
+ # @param [String] *values A value that should be quoted into the
105
+ # corresponding (by position) placeholder.
106
+ #
107
+ # @return [Scope] Returns a new scope with the passed conditions applied.
108
+ def where *conditions
109
+ if conditions.empty?
110
+ raise ArgumentError, 'missing required condition'
111
+ end
112
+ _with(:where => @options[:where] + [conditions])
113
+ end
114
+
115
+ # Specifies how to sort records returned.
116
+ #
117
+ # # enumerate books, starting with the most recently published ones
118
+ # Book.order(:published_at, :desc).each do |book|
119
+ # # ...
120
+ # end
121
+ #
122
+ # Only one order may be applied. If order is specified more than
123
+ # once the last one in the chain takes precedence:
124
+ #
125
+ #
126
+ # # books returned by this scope will be ordered by :published_at
127
+ # # and not :author.
128
+ # Book.where(:read => false).order(:author).order(:published_at)
129
+ #
130
+ # @param [String,Symbol] attribute_name The attribute to sort by.
131
+ # @param [:asc, :desc] order (:asc) The direct to sort.
132
+ def order attribute_name, order = :asc
133
+ _with(:order => [attribute_name, order])
134
+ end
135
+
136
+ # @private
137
+ private
138
+ def _each_object &block
139
+
140
+ items = _item_collection
141
+
142
+ items.select.each do |item_data|
143
+ obj = base_class.new(:shard => _shard)
144
+ obj.send(:hydrate, item_data.name, item_data.attributes)
145
+ yield(obj)
146
+ end
147
+
148
+ end
149
+
150
+ # Merges another scope with this scope. Conditions are added together
151
+ # and the limit and order parts replace those in this scope (if set).
152
+ # @param [Scope] scope A scope to merge with this one.
153
+ # @return [Scope] Returns a new scope with merged conditions and
154
+ # overriden order and limit.
155
+ # @private
156
+ private
157
+ def _merge_scope scope
158
+ merged = self
159
+ scope.instance_variable_get('@options').each_pair do |opt_name,opt_value|
160
+ unless [nil, []].include?(opt_value)
161
+ if opt_name == :where
162
+ opt_value.each do |condition|
163
+ merged = merged.where(*condition)
164
+ end
165
+ else
166
+ merged = merged.send(opt_name, *opt_value)
167
+ end
168
+ end
169
+ end
170
+ merged
171
+ end
172
+
173
+ # Consumes a hash of options (e.g. +:where+, +:order+ and +:limit+) and
174
+ # builds them onto the current scope, returning a new one.
175
+ # @param [Hash] options
176
+ # @option options :where
177
+ # @option options :order
178
+ # @option options [Integer] :limit
179
+ # @return [Scope] Returns a new scope with the hash of scope
180
+ # options applied.
181
+ # @private
182
+ private
183
+ def _handle_options options
184
+ scope = self
185
+ options.each_pair do |method, args|
186
+ if method == :where and args.is_a?(Hash)
187
+ # splatting a hash turns it into an array, bad juju
188
+ scope = scope.send(method, args)
189
+ else
190
+ scope = scope.send(method, *args)
191
+ end
192
+ end
193
+ scope
194
+ end
195
+
196
+ # Converts this scope object into an AWS::SimpleDB::ItemCollection
197
+ # @return [SimpleDB::ItemCollection]
198
+ # @private
199
+ private
200
+ def _item_collection
201
+ items = base_class.sdb_domain(_shard).items
202
+ items = items.order(*@options[:order]) if @options[:order]
203
+ items = items.limit(*@options[:limit]) if @options[:limit]
204
+ @options[:where].each do |where_condition|
205
+ items = items.where(*where_condition)
206
+ end
207
+ items
208
+ end
209
+
210
+ end
211
+ end
212
+ end
213
+ end
@@ -14,90 +14,59 @@
14
14
  module AWS
15
15
  module Record
16
16
 
17
- # The primary interface for finding records with AWS::Record.
18
- #
19
- # == Getting a Scope Object
20
- #
21
- # You should normally never need to construct a Scope object directly.
22
- # Scope objects are returned from the AWS::Record::Base finder methods
23
- # (e.g. +find+ +all+, +where+, +order+, +limit+, etc).
24
- #
25
- # books = Book.where(:author => 'John Doe')
26
- # books.class #=> AWS::Record::Scope, not Array
27
- #
28
- # Scopes are also returned from methods defined with the +scope+ method.
29
- #
30
- # == Delayed Execution
31
- #
32
- # Scope objects represent a select expression, but do not actually
33
- # cause a request to be made until enumerated.
34
- #
35
- # # no request made yet
36
- # books = Book.where(:author => 'John Doe')
37
- #
38
- # # a request is made now
39
- # books.each {|book| ... }
40
- #
41
- # You can refine a scope object by calling other scope methods on
42
- # it.
43
- #
44
- # # refine the previous books Scope, no request
45
- # top_10 = books.order(:popularity, :desc).limit(10)
46
- #
47
- # # another request is made now
48
- # top_10.first
49
- #
17
+ # Base class for {AWS::Record::Model::Scope} and
18
+ # {AWS::Record::HashModel::Scope}.
50
19
  class Scope
51
20
 
52
21
  include Enumerable
53
22
 
54
- # @param [Record::Base] base_class A class that extends
55
- # {AWS::Record::Base}.
23
+ # @param base_class A class that extends {AWS::Record::AbstractBase}.
56
24
  # @param [Hash] options
57
25
  # @option options :
58
26
  # @private
59
27
  def initialize base_class, options = {}
28
+
60
29
  @base_class = base_class
30
+
61
31
  @options = options.dup
62
- @options[:where] ||= []
63
- @options[:domain] ||= base_class.domain_name
32
+
33
+ # backwards compat
34
+ @options[:shard] = @options.delete(:domain) if @options[:domain]
35
+
64
36
  end
65
37
 
66
- # @return [Class] Returns the AWS::Record::Base extending class that
38
+ # @return [Class] Returns the AWS::Record::Model extending class that
67
39
  # this scope will find records for.
68
40
  attr_reader :base_class
69
41
 
70
42
  def new attributes = {}
71
43
 
72
- options = {}
73
- options.merge!(attributes)
74
- unless options.key?(:domain) or options.key?('domain')
75
- options[:domain] = _domain
76
- end
44
+ attributes = attributes.dup
45
+ attributes[:shard] ||= attributes.delete(:shard)
46
+ attributes[:shard] ||= attributes.delete('shard')
47
+ # for backwards compatability, domain is accepted
48
+ attributes[:shard] ||= attributes.delete('domain')
49
+ attributes[:shard] ||= attributes.delete(:domain)
50
+ attributes[:shard] ||= _shard
77
51
 
78
- @options[:where].each do |conditions|
79
- if conditions.size == 1 and conditions.first.is_a?(Hash)
80
- options.merge!(conditions.first)
81
- end
82
- end
83
-
84
- base_class.new(options)
52
+ base_class.new(attributes)
85
53
 
86
54
  end
87
55
  alias_method :build, :new
88
56
 
89
- # @param [String] domain
90
- # @return [Scope] Returns a scope for restricting the domain of subsequent
91
- # scope operations
92
- def domain name
93
- _with(:domain => name)
57
+ # @param [String] shard_name
58
+ # @return [Scope] Returns a scope that specifies which shard
59
+ # (i.e. SimpleDB domain) should be used.
60
+ def shard shard_name
61
+ _with(:shard => shard_name)
94
62
  end
63
+ alias_method :domain, :shard
95
64
 
96
65
  # @overload find(id)
97
66
  # Finds and returns a single record by id. If no record is found
98
67
  # with the given +id+, then a RecordNotFound error will be raised.
99
68
  # @param [String] id ID of the record to find.
100
- # @return [Record::Base] Returns the record.
69
+ # @return Returns the record.
101
70
  #
102
71
  # @overload find(:first, options = {})
103
72
  # Returns the first record found. If no records were matched then
@@ -125,7 +94,7 @@ module AWS
125
94
  when id_or_mode == :all then scope
126
95
  when id_or_mode == :first then scope.limit(1).to_a.first
127
96
  else
128
- base_class.find_by_id(id_or_mode, :domain => scope._domain)
97
+ base_class.find_by_id(id_or_mode, :shard => scope._shard)
129
98
  end
130
99
 
131
100
  end
@@ -141,64 +110,11 @@ module AWS
141
110
  end
142
111
  alias_method :size, :count
143
112
 
144
- # @return [Record::Base,nil] Gets the first record from the domain
145
- # and returns it, or returns nil if the domain is empty.
113
+ # @return Returns the first record found, returns
114
+ # nil if the domain/table is empty.
146
115
  def first options = {}
147
116
  _handle_options(options).find(:first)
148
117
  end
149
-
150
- # Applies conditions to the scope that limit which records are returned.
151
- # Only those matching all given conditions will be returned.
152
- #
153
- # @overload where(conditions_hash)
154
- # Specify a hash of conditions to query with. Multiple conditions
155
- # are joined together with AND.
156
- #
157
- # Book.where(:author => 'John Doe', :softcover => true)
158
- # # where `author` = `John Doe` AND `softcover` = `1`
159
- #
160
- # @param [Hash] conditions
161
- #
162
- # @overload where(conditions_string, *values)
163
- # A sql-like query fragment with optional placeholders and values.
164
- # Placeholders are replaced with properly quoted values.
165
- #
166
- # Book.where('author = ?', 'John Doe')
167
- #
168
- # @param [String] conditions_string A sql-like where string with
169
- # question mark placeholders. For each placeholder there should
170
- # be a value that will be quoted into that position.
171
- # @param [String] *values A value that should be quoted into the
172
- # corresponding (by position) placeholder.
173
- #
174
- # @return [Scope] Returns a new scope with the passed conditions applied.
175
- def where *conditions
176
- if conditions.empty?
177
- raise ArgumentError, 'missing required condition'
178
- end
179
- _with(:where => @options[:where] + [conditions])
180
- end
181
-
182
- # Specifies how to sort records returned.
183
- #
184
- # # enumerate books, starting with the most recently published ones
185
- # Book.order(:published_at, :desc).each do |book|
186
- # # ...
187
- # end
188
- #
189
- # Only one order may be applied. If order is specified more than
190
- # once the last one in the chain takes precedence:
191
- #
192
- #
193
- # # books returned by this scope will be ordered by :published_at
194
- # # and not :author.
195
- # Book.where(:read => false).order(:author).order(:published_at)
196
- #
197
- # @param [String,Symbol] attribute_name The attribute to sort by.
198
- # @param [:asc, :desc] order (:asc) The direct to sort.
199
- def order attribute_name, order = :asc
200
- _with(:order => [attribute_name, order])
201
- end
202
118
 
203
119
  # Limits the maximum number of total records to return when finding
204
120
  # or counting. Returns a scope, does not make a request.
@@ -229,28 +145,21 @@ module AWS
229
145
  end
230
146
 
231
147
  protected
232
- def _domain
233
- @options[:domain]
148
+ def _shard
149
+ @options[:shard] || base_class.shard_name
234
150
  end
151
+ alias_method :domain, :shard
235
152
 
236
153
  # @private
237
154
  private
238
155
  def _each_object &block
239
-
240
- items = _item_collection
241
-
242
- items.select.each do |item_data|
243
- obj = base_class.new(:domain => _domain)
244
- obj.send(:hydrate, item_data.name, item_data.attributes)
245
- yield(obj)
246
- end
247
-
156
+ raise NotImplementedError
248
157
  end
249
158
 
250
159
  # @private
251
160
  private
252
161
  def _with options
253
- Scope.new(base_class, @options.merge(options))
162
+ self.class.new(base_class, @options.merge(options))
254
163
  end
255
164
 
256
165
  # @private
@@ -260,66 +169,31 @@ module AWS
260
169
  _merge_scope(base_class.send(scope_name, *args))
261
170
  end
262
171
 
263
- # Merges another scope with this scope. Conditions are added together
264
- # and the limit and order parts replace those in this scope (if set).
265
- # @param [Scope] scope A scope to merge with this one.
266
- # @return [Scope] Returns a new scope with merged conditions and
267
- # overriden order and limit.
172
+ # Merges the one scope with the current scope, returning a 3rd.
173
+ # @param [Scope] scope
174
+ # @return [Scope]
268
175
  # @private
269
176
  private
270
177
  def _merge_scope scope
271
- merged = self
272
- scope.instance_variable_get('@options').each_pair do |opt_name,opt_value|
273
- unless [nil, []].include?(opt_value)
274
- if opt_name == :where
275
- opt_value.each do |condition|
276
- merged = merged.where(*condition)
277
- end
278
- else
279
- merged = merged.send(opt_name, *opt_value)
280
- end
281
- end
282
- end
283
- merged
178
+ raise NotImplementedError
284
179
  end
285
180
 
286
- # Consumes a hash of options (e.g. +:where+, +:order+ and +:limit+) and
287
- # builds them onto the current scope, returning a new one.
288
- # @param [Hash] options
289
- # @option options :where
290
- # @option options :order
291
- # @option options [Integer] :limit
292
- # @return [Scope] Returns a new scope with the hash of scope
293
- # options applied.
181
+ # Consumes a hash of options (e.g. +:shard+, +:limit) and returns
182
+ # a new scope with those applied.
183
+ # @return [Scope]
294
184
  # @private
295
185
  private
296
186
  def _handle_options options
297
- scope = self
298
- options.each_pair do |method, args|
299
- if method == :where and args.is_a?(Hash)
300
- # splatting a hash turns it into an array, bad juju
301
- scope = scope.send(method, args)
302
- else
303
- scope = scope.send(method, *args)
304
- end
305
- end
306
- scope
187
+ raise NotImplementedError
307
188
  end
308
189
 
309
- # Converts this scope object into an AWS::SimpleDB::ItemCollection
310
- # @return [SimpleDB::ItemCollection]
311
190
  # @private
312
191
  private
313
192
  def _item_collection
314
- items = base_class.sdb_domain(_domain).items
315
- items = items.order(*@options[:order]) if @options[:order]
316
- items = items.limit(*@options[:limit]) if @options[:limit]
317
- @options[:where].each do |where_condition|
318
- items = items.where(*where_condition)
319
- end
320
- items
193
+ raise NotImplementedError
321
194
  end
322
195
 
323
196
  end
197
+
324
198
  end
325
199
  end