synamoid 1.2.1 → 1.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +52 -52
- metadata +5 -41
- data/.document +0 -5
- data/.gitignore +0 -67
- data/.rspec +0 -2
- data/.travis.yml +0 -15
- data/CHANGELOG.md +0 -48
- data/Gemfile +0 -4
- data/Rakefile +0 -64
- data/dynamoid.gemspec +0 -53
- data/lib/dynamoid.rb +0 -53
- data/lib/dynamoid/adapter.rb +0 -190
- data/lib/dynamoid/adapter_plugin/aws_sdk_v2.rb +0 -892
- data/lib/dynamoid/associations.rb +0 -106
- data/lib/dynamoid/associations/association.rb +0 -116
- data/lib/dynamoid/associations/belongs_to.rb +0 -44
- data/lib/dynamoid/associations/has_and_belongs_to_many.rb +0 -40
- data/lib/dynamoid/associations/has_many.rb +0 -39
- data/lib/dynamoid/associations/has_one.rb +0 -39
- data/lib/dynamoid/associations/many_association.rb +0 -193
- data/lib/dynamoid/associations/single_association.rb +0 -69
- data/lib/dynamoid/components.rb +0 -37
- data/lib/dynamoid/config.rb +0 -58
- data/lib/dynamoid/config/options.rb +0 -78
- data/lib/dynamoid/criteria.rb +0 -29
- data/lib/dynamoid/criteria/chain.rb +0 -214
- data/lib/dynamoid/dirty.rb +0 -47
- data/lib/dynamoid/document.rb +0 -201
- data/lib/dynamoid/errors.rb +0 -66
- data/lib/dynamoid/fields.rb +0 -164
- data/lib/dynamoid/finders.rb +0 -199
- data/lib/dynamoid/identity_map.rb +0 -92
- data/lib/dynamoid/indexes.rb +0 -273
- data/lib/dynamoid/middleware/identity_map.rb +0 -16
- data/lib/dynamoid/persistence.rb +0 -359
- data/lib/dynamoid/validations.rb +0 -63
- data/lib/dynamoid/version.rb +0 -3
data/lib/dynamoid/finders.rb
DELETED
@@ -1,199 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
module Dynamoid
|
3
|
-
|
4
|
-
# This module defines the finder methods that hang off the document at the
|
5
|
-
# class level, like find, find_by_id, and the method_missing style finders.
|
6
|
-
module Finders
|
7
|
-
extend ActiveSupport::Concern
|
8
|
-
|
9
|
-
RANGE_MAP = {
|
10
|
-
'gt' => :range_greater_than,
|
11
|
-
'lt' => :range_less_than,
|
12
|
-
'gte' => :range_gte,
|
13
|
-
'lte' => :range_lte,
|
14
|
-
'begins_with' => :range_begins_with,
|
15
|
-
'between' => :range_between,
|
16
|
-
'eq' => :range_eq
|
17
|
-
}
|
18
|
-
|
19
|
-
module ClassMethods
|
20
|
-
|
21
|
-
# Find one or many objects, specified by one id or an array of ids.
|
22
|
-
#
|
23
|
-
# @param [Array/String] *id an array of ids or one single id
|
24
|
-
#
|
25
|
-
# @return [Dynamoid::Document] one object or an array of objects, depending on whether the input was an array or not
|
26
|
-
#
|
27
|
-
# @since 0.2.0
|
28
|
-
def find(*ids)
|
29
|
-
options = if ids.last.is_a? Hash
|
30
|
-
ids.slice!(-1)
|
31
|
-
else
|
32
|
-
{}
|
33
|
-
end
|
34
|
-
expects_array = ids.first.kind_of?(Array)
|
35
|
-
|
36
|
-
ids = Array(ids.flatten.uniq)
|
37
|
-
if ids.count == 1
|
38
|
-
result = self.find_by_id(ids.first, options)
|
39
|
-
expects_array ? Array(result) : result
|
40
|
-
else
|
41
|
-
find_all(ids)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
# Return objects found by the given array of ids, either hash keys, or hash/range key combinations using BatchGet.
|
46
|
-
# Returns empty array if no results found.
|
47
|
-
#
|
48
|
-
# @param [Array<ID>] ids
|
49
|
-
# @param [Hash] options: Passed to the underlying query.
|
50
|
-
#
|
51
|
-
# @example
|
52
|
-
# find all the user with hash key
|
53
|
-
# User.find_all(['1', '2', '3'])
|
54
|
-
#
|
55
|
-
# find all the tweets using hash key and range key with consistent read
|
56
|
-
# Tweet.find_all([['1', 'red'], ['1', 'green']], :consistent_read => true)
|
57
|
-
def find_all(ids, options = {})
|
58
|
-
items = Dynamoid.adapter.read(self.table_name, ids, options)
|
59
|
-
items ? items[self.table_name].map{|i| from_database(i)} : []
|
60
|
-
end
|
61
|
-
|
62
|
-
# Find one object directly by id.
|
63
|
-
#
|
64
|
-
# @param [String] id the id of the object to find
|
65
|
-
#
|
66
|
-
# @return [Dynamoid::Document] the found object, or nil if nothing was found
|
67
|
-
#
|
68
|
-
# @since 0.2.0
|
69
|
-
def find_by_id(id, options = {})
|
70
|
-
if item = Dynamoid.adapter.read(self.table_name, id, options)
|
71
|
-
from_database(item)
|
72
|
-
else
|
73
|
-
nil
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
# Find one object directly by hash and range keys
|
78
|
-
#
|
79
|
-
# @param [String] hash_key of the object to find
|
80
|
-
# @param [String/Number] range_key of the object to find
|
81
|
-
#
|
82
|
-
def find_by_composite_key(hash_key, range_key, options = {})
|
83
|
-
find_by_id(hash_key, options.merge({:range_key => range_key}))
|
84
|
-
end
|
85
|
-
|
86
|
-
# Find all objects by hash and range keys.
|
87
|
-
#
|
88
|
-
# @example find all ChamberTypes whose level is greater than 1
|
89
|
-
# class ChamberType
|
90
|
-
# include Dynamoid::Document
|
91
|
-
# field :chamber_type, :string
|
92
|
-
# range :level, :integer
|
93
|
-
# table :key => :chamber_type
|
94
|
-
# end
|
95
|
-
# ChamberType.find_all_by_composite_key('DustVault', range_greater_than: 1)
|
96
|
-
#
|
97
|
-
# @param [String] hash_key of the objects to find
|
98
|
-
# @param [Hash] options the options for the range key
|
99
|
-
# @option options [Range] :range_value find the range key within this range
|
100
|
-
# @option options [Number] :range_greater_than find range keys greater than this
|
101
|
-
# @option options [Number] :range_less_than find range keys less than this
|
102
|
-
# @option options [Number] :range_gte find range keys greater than or equal to this
|
103
|
-
# @option options [Number] :range_lte find range keys less than or equal to this
|
104
|
-
#
|
105
|
-
# @return [Array] an array of all matching items
|
106
|
-
#
|
107
|
-
def find_all_by_composite_key(hash_key, options = {})
|
108
|
-
Dynamoid.adapter.query(self.table_name, options.merge({hash_value: hash_key})).collect do |item|
|
109
|
-
from_database(item)
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
# Find all objects by using local secondary or global secondary index
|
114
|
-
#
|
115
|
-
# @example
|
116
|
-
# class User
|
117
|
-
# include Dynamoid::Document
|
118
|
-
# field :email, :string
|
119
|
-
# field :age, :integer
|
120
|
-
# field :gender, :string
|
121
|
-
# field :rank :number
|
122
|
-
# table :key => :email
|
123
|
-
# global_secondary_index :hash_key => :age, :range_key => :rank
|
124
|
-
# end
|
125
|
-
# # NOTE: the first param and the second param are both hashes,
|
126
|
-
# # so curly braces must be used on first hash param if sending both params
|
127
|
-
# User.find_all_by_secondary_index({:age => 5}, :range => {"rank.lte" => 10})
|
128
|
-
#
|
129
|
-
# @param [Hash] eg: {:age => 5}
|
130
|
-
# @param [Hash] eg: {"rank.lte" => 10}
|
131
|
-
# @param [Hash] options - query filter, projected keys, scan_index_forward etc
|
132
|
-
# @return [Array] an array of all matching items
|
133
|
-
def find_all_by_secondary_index(hash, options = {})
|
134
|
-
range = options[:range] || {}
|
135
|
-
hash_key_field, hash_key_value = hash.first
|
136
|
-
range_key_field, range_key_value = range.first
|
137
|
-
range_op_mapped = nil
|
138
|
-
|
139
|
-
if range_key_field
|
140
|
-
range_key_field = range_key_field.to_s
|
141
|
-
range_key_op = "eq"
|
142
|
-
if range_key_field.include?(".")
|
143
|
-
range_key_field, range_key_op = range_key_field.split(".", 2)
|
144
|
-
end
|
145
|
-
range_op_mapped = RANGE_MAP.fetch(range_key_op)
|
146
|
-
end
|
147
|
-
|
148
|
-
# Find the index
|
149
|
-
index = self.find_index(hash_key_field, range_key_field)
|
150
|
-
raise Dynamoid::Errors::MissingIndex.new("attempted to find #{[hash_key_field, range_key_field]}") if index.nil?
|
151
|
-
|
152
|
-
# query
|
153
|
-
opts = {
|
154
|
-
:hash_key => hash_key_field.to_s,
|
155
|
-
:hash_value => hash_key_value,
|
156
|
-
:index_name => index.name,
|
157
|
-
}
|
158
|
-
if range_key_field
|
159
|
-
opts[:range_key] = range_key_field
|
160
|
-
opts[range_op_mapped] = range_key_value
|
161
|
-
end
|
162
|
-
dynamo_options = opts.merge(options.reject {|key, _| key == :range })
|
163
|
-
Dynamoid.adapter.query(self.table_name, dynamo_options).map do |item|
|
164
|
-
from_database(item)
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
# Find using exciting method_missing finders attributes. Uses criteria chains under the hood to accomplish this neatness.
|
169
|
-
#
|
170
|
-
# @example find a user by a first name
|
171
|
-
# User.find_by_first_name('Josh')
|
172
|
-
#
|
173
|
-
# @example find all users by first and last name
|
174
|
-
# User.find_all_by_first_name_and_last_name('Josh', 'Symonds')
|
175
|
-
#
|
176
|
-
# @return [Dynamoid::Document/Array] the found object, or an array of found objects if all was somewhere in the method
|
177
|
-
#
|
178
|
-
# @since 0.2.0
|
179
|
-
def method_missing(method, *args)
|
180
|
-
if method =~ /find/
|
181
|
-
finder = method.to_s.split('_by_').first
|
182
|
-
attributes = method.to_s.split('_by_').last.split('_and_')
|
183
|
-
|
184
|
-
chain = Dynamoid::Criteria::Chain.new(self)
|
185
|
-
chain.query = Hash.new.tap {|h| attributes.each_with_index {|attr, index| h[attr.to_sym] = args[index]}}
|
186
|
-
|
187
|
-
if finder =~ /all/
|
188
|
-
return chain.all
|
189
|
-
else
|
190
|
-
return chain.first
|
191
|
-
end
|
192
|
-
else
|
193
|
-
super
|
194
|
-
end
|
195
|
-
end
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
end
|
@@ -1,92 +0,0 @@
|
|
1
|
-
module Dynamoid
|
2
|
-
module IdentityMap
|
3
|
-
extend ActiveSupport::Concern
|
4
|
-
|
5
|
-
def self.clear
|
6
|
-
Dynamoid.included_models.each { |m| m.identity_map.clear }
|
7
|
-
end
|
8
|
-
|
9
|
-
module ClassMethods
|
10
|
-
def identity_map
|
11
|
-
@identity_map ||= {}
|
12
|
-
end
|
13
|
-
|
14
|
-
def from_database(attrs = {})
|
15
|
-
return super if identity_map_off?
|
16
|
-
|
17
|
-
key = identity_map_key(attrs)
|
18
|
-
document = identity_map[key]
|
19
|
-
|
20
|
-
if document.nil?
|
21
|
-
document = super
|
22
|
-
identity_map[key] = document
|
23
|
-
else
|
24
|
-
document.load(attrs)
|
25
|
-
end
|
26
|
-
|
27
|
-
document
|
28
|
-
end
|
29
|
-
|
30
|
-
def find_by_id(id, options = {})
|
31
|
-
return super if identity_map_off?
|
32
|
-
|
33
|
-
key = id.to_s
|
34
|
-
|
35
|
-
if range_key = options[:range_key]
|
36
|
-
key += "::#{range_key}"
|
37
|
-
end
|
38
|
-
|
39
|
-
if identity_map[key]
|
40
|
-
identity_map[key]
|
41
|
-
else
|
42
|
-
super
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def identity_map_key(attrs)
|
47
|
-
key = attrs[hash_key].to_s
|
48
|
-
if range_key
|
49
|
-
key += "::#{attrs[range_key]}"
|
50
|
-
end
|
51
|
-
key
|
52
|
-
end
|
53
|
-
|
54
|
-
def identity_map_on?
|
55
|
-
Dynamoid::Config.identity_map
|
56
|
-
end
|
57
|
-
|
58
|
-
def identity_map_off?
|
59
|
-
!identity_map_on?
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def identity_map
|
64
|
-
self.class.identity_map
|
65
|
-
end
|
66
|
-
|
67
|
-
def save(*args)
|
68
|
-
return super if self.class.identity_map_off?
|
69
|
-
|
70
|
-
if result = super
|
71
|
-
identity_map[identity_map_key] = self
|
72
|
-
end
|
73
|
-
result
|
74
|
-
end
|
75
|
-
|
76
|
-
def delete
|
77
|
-
return super if self.class.identity_map_off?
|
78
|
-
|
79
|
-
identity_map.delete(identity_map_key)
|
80
|
-
super
|
81
|
-
end
|
82
|
-
|
83
|
-
|
84
|
-
def identity_map_key
|
85
|
-
key = hash_key.to_s
|
86
|
-
if self.class.range_key
|
87
|
-
key += "::#{range_value}"
|
88
|
-
end
|
89
|
-
key
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
data/lib/dynamoid/indexes.rb
DELETED
@@ -1,273 +0,0 @@
|
|
1
|
-
module Dynamoid
|
2
|
-
module Indexes
|
3
|
-
extend ActiveSupport::Concern
|
4
|
-
|
5
|
-
included do
|
6
|
-
class_attribute :local_secondary_indexes
|
7
|
-
class_attribute :global_secondary_indexes
|
8
|
-
self.local_secondary_indexes = {}
|
9
|
-
self.global_secondary_indexes = {}
|
10
|
-
end
|
11
|
-
|
12
|
-
module ClassMethods
|
13
|
-
# Defines a Global Secondary index on a table. Keys can be specified as
|
14
|
-
# hash-only, or hash & range.
|
15
|
-
#
|
16
|
-
# @param [Hash] options options to pass for this table
|
17
|
-
# @option options [Symbol] :name the name for the index; this still gets
|
18
|
-
# namespaced. If not specified, will use a default name.
|
19
|
-
# @option options [Symbol] :hash_key the index hash key column.
|
20
|
-
# @option options [Symbol] :range_key the index range key column (if
|
21
|
-
# applicable).
|
22
|
-
# @option options [Symbol, Array<Symbol>] :projected_attributes table
|
23
|
-
# attributes to project for this index. Can be :keys_only, :all
|
24
|
-
# or an array of included fields. If not specified, defaults to
|
25
|
-
# :keys_only.
|
26
|
-
# @option options [Integer] :read_capacity set the read capacity for the
|
27
|
-
# index; does not work on existing indexes.
|
28
|
-
# @option options [Integer] :write_capacity set the write capacity for
|
29
|
-
# the index; does not work on existing indexes.
|
30
|
-
def global_secondary_index(options={})
|
31
|
-
unless options.present?
|
32
|
-
raise Dynamoid::Errors::InvalidIndex.new('empty index definition')
|
33
|
-
end
|
34
|
-
|
35
|
-
unless options[:hash_key].present?
|
36
|
-
raise Dynamoid::Errors::InvalidIndex.new(
|
37
|
-
'A global secondary index requires a :hash_key to be specified'
|
38
|
-
)
|
39
|
-
end
|
40
|
-
|
41
|
-
index_opts = {
|
42
|
-
:read_capacity => Dynamoid::Config.read_capacity,
|
43
|
-
:write_capacity => Dynamoid::Config.write_capacity
|
44
|
-
}.merge(options)
|
45
|
-
|
46
|
-
index_opts[:dynamoid_class] = self
|
47
|
-
index_opts[:type] = :global_secondary
|
48
|
-
|
49
|
-
index = Dynamoid::Indexes::Index.new(index_opts)
|
50
|
-
gsi_key = index_key(options[:hash_key], options[:range_key])
|
51
|
-
self.global_secondary_indexes[gsi_key] = index
|
52
|
-
self
|
53
|
-
end
|
54
|
-
|
55
|
-
|
56
|
-
# Defines a local secondary index on a table. Will use the same primary
|
57
|
-
# hash key as the table.
|
58
|
-
#
|
59
|
-
# @param [Hash] options options to pass for this index.
|
60
|
-
# @option options [Symbol] :name the name for the index; this still gets
|
61
|
-
# namespaced. If not specified, a name is automatically generated.
|
62
|
-
# @option options [Symbol] :range_key the range key column for the index.
|
63
|
-
# @option options [Symbol, Array<Symbol>] :projected_attributes table
|
64
|
-
# attributes to project for this index. Can be :keys_only, :all
|
65
|
-
# or an array of included fields. If not specified, defaults to
|
66
|
-
# :keys_only.
|
67
|
-
def local_secondary_index(options={})
|
68
|
-
unless options.present?
|
69
|
-
raise Dynamoid::Errors::InvalidIndex.new('empty index definition')
|
70
|
-
end
|
71
|
-
|
72
|
-
primary_hash_key = self.hash_key
|
73
|
-
primary_range_key = self.range_key
|
74
|
-
index_range_key = options[:range_key]
|
75
|
-
|
76
|
-
unless index_range_key.present?
|
77
|
-
raise Dynamoid::Errors::InvalidIndex.new('A local secondary index '\
|
78
|
-
'requires a :range_key to be specified')
|
79
|
-
end
|
80
|
-
|
81
|
-
if primary_range_key.present? && index_range_key == primary_range_key
|
82
|
-
raise Dynamoid::Errors::InvalidIndex.new('A local secondary index'\
|
83
|
-
' must use a different :range_key than the primary key')
|
84
|
-
end
|
85
|
-
|
86
|
-
index_opts = options.merge({
|
87
|
-
:dynamoid_class => self,
|
88
|
-
:type => :local_secondary,
|
89
|
-
:hash_key => primary_hash_key
|
90
|
-
})
|
91
|
-
|
92
|
-
index = Dynamoid::Indexes::Index.new(index_opts)
|
93
|
-
key = index_key(primary_hash_key, index_range_key)
|
94
|
-
self.local_secondary_indexes[key] = index
|
95
|
-
self
|
96
|
-
end
|
97
|
-
|
98
|
-
|
99
|
-
def find_index(hash, range=nil)
|
100
|
-
index = self.indexes[index_key(hash, range)]
|
101
|
-
index
|
102
|
-
end
|
103
|
-
|
104
|
-
|
105
|
-
# Returns true iff the provided hash[,range] key combo is a local
|
106
|
-
# secondary index.
|
107
|
-
#
|
108
|
-
# @param [Symbol] hash hash key name.
|
109
|
-
# @param [Symbol] range range key name.
|
110
|
-
# @return [Boolean] true iff provided keys correspond to a local
|
111
|
-
# secondary index.
|
112
|
-
def is_local_secondary_index?(hash, range=nil)
|
113
|
-
self.local_secondary_indexes[index_key(hash, range)].present?
|
114
|
-
end
|
115
|
-
|
116
|
-
|
117
|
-
# Returns true iff the provided hash[,range] key combo is a global
|
118
|
-
# secondary index.
|
119
|
-
#
|
120
|
-
# @param [Symbol] hash hash key name.
|
121
|
-
# @param [Symbol] range range key name.
|
122
|
-
# @return [Boolean] true iff provided keys correspond to a global
|
123
|
-
# secondary index.
|
124
|
-
def is_global_secondary_index?(hash, range=nil)
|
125
|
-
self.global_secondary_indexes[index_key(hash, range)].present?
|
126
|
-
end
|
127
|
-
|
128
|
-
|
129
|
-
# Generates a convenient lookup key name for a hash/range index.
|
130
|
-
# Should normally not be used directly.
|
131
|
-
#
|
132
|
-
# @param [Symbol] hash hash key name.
|
133
|
-
# @param [Symbol] range range key name.
|
134
|
-
# @return [String] returns "hash" if hash only, "hash_range" otherwise.
|
135
|
-
def index_key(hash, range=nil)
|
136
|
-
name = hash.to_s
|
137
|
-
if range.present?
|
138
|
-
name += "_#{range.to_s}"
|
139
|
-
end
|
140
|
-
name
|
141
|
-
end
|
142
|
-
|
143
|
-
|
144
|
-
# Generates a default index name.
|
145
|
-
#
|
146
|
-
# @param [Symbol] hash hash key name.
|
147
|
-
# @param [Symbol] range range key name.
|
148
|
-
# @return [String] index name of the form "table_name_index_index_key".
|
149
|
-
def index_name(hash, range=nil)
|
150
|
-
"#{self.table_name}_index_#{self.index_key(hash, range)}"
|
151
|
-
end
|
152
|
-
|
153
|
-
|
154
|
-
# Convenience method to return all indexes on the table.
|
155
|
-
#
|
156
|
-
# @return [Hash<String, Object>] the combined hash of global and local
|
157
|
-
# secondary indexes.
|
158
|
-
def indexes
|
159
|
-
self.local_secondary_indexes.merge(self.global_secondary_indexes)
|
160
|
-
end
|
161
|
-
|
162
|
-
def indexed_hash_keys
|
163
|
-
self.global_secondary_indexes.map do |name, index|
|
164
|
-
index.hash_key.to_s
|
165
|
-
end
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
|
170
|
-
# Represents the attributes of a DynamoDB index.
|
171
|
-
class Index
|
172
|
-
include ActiveModel::Validations
|
173
|
-
|
174
|
-
PROJECTION_TYPES = [:keys_only, :all].to_set
|
175
|
-
DEFAULT_PROJECTION_TYPE = :keys_only
|
176
|
-
|
177
|
-
attr_accessor :name, :dynamoid_class, :type, :hash_key, :range_key,
|
178
|
-
:hash_key_schema, :range_key_schema, :projected_attributes,
|
179
|
-
:read_capacity, :write_capacity
|
180
|
-
|
181
|
-
|
182
|
-
validate do
|
183
|
-
validate_index_type
|
184
|
-
validate_hash_key
|
185
|
-
validate_range_key
|
186
|
-
validate_projected_attributes
|
187
|
-
end
|
188
|
-
|
189
|
-
|
190
|
-
def initialize(attrs={})
|
191
|
-
unless attrs[:dynamoid_class].present?
|
192
|
-
raise Dynamoid::Errors::InvalidIndex.new(':dynamoid_class is required')
|
193
|
-
end
|
194
|
-
|
195
|
-
@dynamoid_class = attrs[:dynamoid_class]
|
196
|
-
@type = attrs[:type]
|
197
|
-
@hash_key = attrs[:hash_key]
|
198
|
-
@range_key = attrs[:range_key]
|
199
|
-
@name = attrs[:name] || @dynamoid_class.index_name(@hash_key, @range_key)
|
200
|
-
@projected_attributes =
|
201
|
-
attrs[:projected_attributes] || DEFAULT_PROJECTION_TYPE
|
202
|
-
@read_capacity = attrs[:read_capacity]
|
203
|
-
@write_capacity = attrs[:write_capacity]
|
204
|
-
|
205
|
-
raise Dynamoid::Errors::InvalidIndex.new(self) unless self.valid?
|
206
|
-
end
|
207
|
-
|
208
|
-
|
209
|
-
# Convenience method to determine the projection type for an index.
|
210
|
-
# Projection types are: :keys_only, :all, :include.
|
211
|
-
#
|
212
|
-
# @return [Symbol] the projection type.
|
213
|
-
def projection_type
|
214
|
-
if @projected_attributes.is_a? Array
|
215
|
-
:include
|
216
|
-
else
|
217
|
-
@projected_attributes
|
218
|
-
end
|
219
|
-
end
|
220
|
-
|
221
|
-
|
222
|
-
private
|
223
|
-
|
224
|
-
def validate_projected_attributes
|
225
|
-
unless (@projected_attributes.is_a?(Array) ||
|
226
|
-
PROJECTION_TYPES.include?(@projected_attributes))
|
227
|
-
errors.add(:projected_attributes, 'Invalid projected attributes specified.')
|
228
|
-
end
|
229
|
-
end
|
230
|
-
|
231
|
-
def validate_index_type
|
232
|
-
unless (@type.present? &&
|
233
|
-
[:local_secondary, :global_secondary].include?(@type))
|
234
|
-
errors.add(:type, 'Invalid index :type specified')
|
235
|
-
end
|
236
|
-
end
|
237
|
-
|
238
|
-
def validate_range_key
|
239
|
-
if @range_key.present?
|
240
|
-
range_field_attributes = @dynamoid_class.attributes[@range_key]
|
241
|
-
if range_field_attributes.present?
|
242
|
-
range_key_type = range_field_attributes[:type]
|
243
|
-
if Dynamoid::Fields::PERMITTED_KEY_TYPES.include?(range_key_type)
|
244
|
-
@range_key_schema = {
|
245
|
-
@range_key => @dynamoid_class.dynamo_type(range_key_type)
|
246
|
-
}
|
247
|
-
else
|
248
|
-
errors.add(:range_key, 'Index :range_key is not a valid key type')
|
249
|
-
end
|
250
|
-
else
|
251
|
-
errors.add(:range_key, "No such field #{@range_key} defined on table")
|
252
|
-
end
|
253
|
-
end
|
254
|
-
end
|
255
|
-
|
256
|
-
def validate_hash_key
|
257
|
-
hash_field_attributes = @dynamoid_class.attributes[@hash_key]
|
258
|
-
if hash_field_attributes.present?
|
259
|
-
hash_field_type = hash_field_attributes[:type]
|
260
|
-
if Dynamoid::Fields::PERMITTED_KEY_TYPES.include?(hash_field_type)
|
261
|
-
@hash_key_schema = {
|
262
|
-
@hash_key => @dynamoid_class.dynamo_type(hash_field_type)
|
263
|
-
}
|
264
|
-
else
|
265
|
-
errors.add(:hash_key, 'Index :hash_key is not a valid key type')
|
266
|
-
end
|
267
|
-
else
|
268
|
-
errors.add(:hash_key, "No such field #{@hash_key} defined on table")
|
269
|
-
end
|
270
|
-
end
|
271
|
-
end
|
272
|
-
end
|
273
|
-
end
|