Class: Dynamoid::Indexes::Index

Inherits:
Object
  • Object
show all
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)

Instance Method Summary (collapse)

Constructor Details

- (Index) initialize(source, name, options = {})

Create a new index. Pass either :range => true or :range => :column_name to create a ranged index on that column.

Parameters:

  • source (Class)

    the source class for the index

  • name (Symbol)

    the name of the index

Raises:

Since:

  • 0.2.0



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, options = {})
  @source = source
  
  if options.delete(:range)
    @range_keys = sort(name)
  elsif options[:range_key]
    @range_keys = sort(options[: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

- (Object) hash_keys

Returns the value of attribute hash_keys



7
8
9
# File 'lib/dynamoid/indexes/index.rb', line 7

def hash_keys
  @hash_keys
end

- (Object) name

Returns the value of attribute name



7
8
9
# File 'lib/dynamoid/indexes/index.rb', line 7

def name
  @name
end

- (Object) range_keys 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

- (Object) source

Returns the value of attribute source



7
8
9
# File 'lib/dynamoid/indexes/index.rb', line 7

def source
  @source
end

Instance Method Details

- (Object) delete(obj)

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.

Since:

  • 0.2.0



84
85
86
87
88
89
90
# File 'lib/dynamoid/indexes/index.rb', line 84

def delete(obj)
  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], 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

- (Object) keys

Return the array of keys this index uses for its table.

Since:

  • 0.2.0



43
44
45
# File 'lib/dynamoid/indexes/index.rb', line 43

def keys
  [Array(hash_keys) + Array(range_keys)].flatten.uniq
end

- (Object) save(obj)

Save an object to this index, merging it with existing ids if there's already something present at this index location.

Since:

  • 0.2.0



72
73
74
75
76
77
78
# File 'lib/dynamoid/indexes/index.rb', line 72

def save(obj)
  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], 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

- (Object) sort(objs)

Sort objects into alphabetical strings, used for composing index names correctly (since we always assume they're alphabetical).

Examples:

find all users by first and last name

sort([:gamma, :alpha, :beta, :omega]) # => [:alpha, :beta, :gamma, :omega]

Since:

  • 0.2.0



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

- (Object) table_name

Return the table name for this index.

Since:

  • 0.2.0



50
51
52
# File 'lib/dynamoid/indexes/index.rb', line 50

def table_name
  "#{Dynamoid::Config.namespace}_index_#{source.to_s.downcase}_#{name.collect(&:to_s).collect(&:pluralize).join('_and_')}"
end

- (Hash) values(attrs)

Given either an object or a list of attributes, generate a hash key and a range key for the index.

Parameters:

  • attrs (Object)

    either an object that responds to :attributes, or a hash of attributes

Returns:

  • (Hash)

    a hash with the keys :hash_value and :range_value

Since:

  • 0.2.0



61
62
63
64
65
66
67
# File 'lib/dynamoid/indexes/index.rb', line 61

def values(attrs)
  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