Class: Dynamoid::Indexes::Index
- Inherits:
-
Object
- Object
- Dynamoid::Indexes::Index
- Defined in:
- lib/dynamoid/indexes/index.rb
Overview
The class contains all the information an index contains, including its keys and which attributes it covers.
Instance Attribute Summary collapse
-
#hash_keys ⇒ Object
Returns the value of attribute hash_keys.
-
#name ⇒ Object
Returns the value of attribute name.
-
#range_keys ⇒ Object
(also: #range_key?)
Returns the value of attribute range_keys.
-
#source ⇒ Object
Returns the value of attribute source.
Instance Method Summary collapse
-
#delete(obj, changed_attributes = false) ⇒ Object
Delete an object from this index, preserving existing ids if there are any, and failing gracefully if for some reason the index doesn’t already have this object in it.
-
#initialize(source, name, options = {}) ⇒ Index
constructor
Create a new index.
-
#keys ⇒ Object
Return the array of keys this index uses for its table.
-
#save(obj) ⇒ Object
Save an object to this index, merging it with existing ids if there’s already something present at this index location.
-
#sort(objs) ⇒ Object
Sort objects into alphabetical strings, used for composing index names correctly (since we always assume they’re alphabetical).
-
#table_name ⇒ Object
Return the table name for this index.
-
#values(attrs, changed_attributes = false) ⇒ Hash
Given either an object or a list of attributes, generate a hash key and a range key for the index.
Constructor Details
#initialize(source, name, options = {}) ⇒ Index
Create a new index. Pass either :range => true or :range => :column_name to create a ranged index on that column.
16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/dynamoid/indexes/index.rb', line 16 def initialize(source, name, = {}) @source = source if .delete(:range) @range_keys = sort(name) elsif [:range_key] @range_keys = sort([:range_key]) end @hash_keys = sort(name) @name = sort([hash_keys, range_keys]) raise Dynamoid::Errors::InvalidField, 'A key specified for an index is not a field' unless keys.all?{|n| source.attributes.include?(n)} end |
Instance Attribute Details
#hash_keys ⇒ Object
Returns the value of attribute hash_keys.
7 8 9 |
# File 'lib/dynamoid/indexes/index.rb', line 7 def hash_keys @hash_keys end |
#name ⇒ Object
Returns the value of attribute name.
7 8 9 |
# File 'lib/dynamoid/indexes/index.rb', line 7 def name @name end |
#range_keys ⇒ Object Also known as: range_key?
Returns the value of attribute range_keys.
7 8 9 |
# File 'lib/dynamoid/indexes/index.rb', line 7 def range_keys @range_keys end |
#source ⇒ Object
Returns the value of attribute source.
7 8 9 |
# File 'lib/dynamoid/indexes/index.rb', line 7 def source @source end |
Instance Method Details
#delete(obj, changed_attributes = false) ⇒ Object
Delete an object from this index, preserving existing ids if there are any, and failing gracefully if for some reason the index doesn’t already have this object in it.
93 94 95 96 97 98 99 |
# File 'lib/dynamoid/indexes/index.rb', line 93 def delete(obj, changed_attributes = false) values = values(obj, changed_attributes) return true if values[:hash_value].blank? || (!values[:range_value].nil? && values[:range_value].blank?) existing = Dynamoid::Adapter.read(self.table_name, values[:hash_value], { :range_key => values[:range_value]}) return true unless existing && existing[:ids] && existing[:ids].include?(obj.id) Dynamoid::Adapter.write(self.table_name, {:id => values[:hash_value], :ids => (existing[:ids] - Set[obj.id]), :range => values[:range_value]}) end |
#keys ⇒ Object
Return the array of keys this index uses for its table.
43 44 45 |
# File 'lib/dynamoid/indexes/index.rb', line 43 def keys [Array(hash_keys) + Array(range_keys)].flatten.uniq end |
#save(obj) ⇒ Object
Save an object to this index, merging it with existing ids if there’s already something present at this index location. First, though, delete this object from its old indexes (so the object isn’t listed in an erroneous index).
80 81 82 83 84 85 86 87 |
# File 'lib/dynamoid/indexes/index.rb', line 80 def save(obj) self.delete(obj, true) values = values(obj) return true if values[:hash_value].blank? || (!values[:range_value].nil? && values[:range_value].blank?) existing = Dynamoid::Adapter.read(self.table_name, values[:hash_value], { :range_key => values[:range_value] }) ids = ((existing and existing[:ids]) or Set.new) Dynamoid::Adapter.write(self.table_name, {:id => values[:hash_value], :ids => ids.merge([obj.id]), :range => values[:range_value]}) end |
#sort(objs) ⇒ Object
Sort objects into alphabetical strings, used for composing index names correctly (since we always assume they’re alphabetical).
36 37 38 |
# File 'lib/dynamoid/indexes/index.rb', line 36 def sort(objs) Array(objs).flatten.compact.uniq.collect(&:to_s).sort.collect(&:to_sym) end |
#table_name ⇒ Object
Return the table name for this index.
50 51 52 |
# File 'lib/dynamoid/indexes/index.rb', line 50 def table_name "#{Dynamoid::Config.namespace}_index_" + source.table_name.sub("#{Dynamoid::Config.namespace}_", '').singularize + "_#{name.collect(&:to_s).collect(&:pluralize).join('_and_')}" end |
#values(attrs, changed_attributes = false) ⇒ Hash
Given either an object or a list of attributes, generate a hash key and a range key for the index. Optionally pass in true to changed_attributes for a list of all the object’s dirty attributes in convenient index form (for deleting stale information from the indexes).
63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/dynamoid/indexes/index.rb', line 63 def values(attrs, changed_attributes = false) if changed_attributes hash = {} attrs.changes.each {|k, v| hash[k.to_sym] = (v.first || v.last)} attrs = hash end attrs = attrs.send(:attributes) if attrs.respond_to?(:attributes) {}.tap do |hash| hash[:hash_value] = hash_keys.collect{|key| attrs[key]}.join('.') hash[:range_value] = range_keys.inject(0.0) {|sum, key| sum + attrs[key].to_f} if self.range_key? end end |