module Dynamoid::Persistence::ClassMethods

Public Instance Methods

create_table(options = {}) click to toggle source

Creates a table.

@param [Hash] options options to pass for table creation @option options [Symbol] :id the id field for the table @option options [Symbol] :table_name the actual name for the table @option options [Integer] :read_capacity set the read capacity for the table; does not work on existing tables @option options [Integer] :write_capacity set the write capacity for the table; does not work on existing tables @option options [Hash] {range_key => :type} a hash of the name of the range key and a symbol of its type @option options [Symbol] :hash_key_type the dynamo type of the hash key (:string or :number) @since 0.4.0

# File lib/dynamoid/persistence.rb, line 40
def create_table(options = {})
  if self.range_key
    range_key_hash = { range_key => dynamo_type(attributes[range_key][:type]) }
  else
    range_key_hash = nil
  end
  options = {
    :id => self.hash_key,
    :table_name => self.table_name,
    :write_capacity => self.write_capacity,
    :read_capacity => self.read_capacity,
    :range_key => range_key_hash,
    :hash_key_type => dynamo_type(attributes[self.hash_key][:type]),
    :local_secondary_indexes => self.local_secondary_indexes.values,
    :global_secondary_indexes => self.global_secondary_indexes.values
  }.merge(options)

  Dynamoid.adapter.create_table(options[:table_name], options[:id], options)
end
dynamo_type(type) click to toggle source
# File lib/dynamoid/persistence.rb, line 133
def dynamo_type(type)
  if type.is_a?(Class)
    type.respond_to?(:dynamoid_field_type) ? type.dynamoid_field_type : :string
  else
    case type
      when :integer, :number, :datetime
        :number
      when :string, :serialized
        :string
      else
        raise 'unknown type'
    end
  end
end
from_database(attrs = {}) click to toggle source
# File lib/dynamoid/persistence.rb, line 60
def from_database(attrs = {})
  clazz = attrs[:type] ? obj = attrs[:type].constantize : self
  clazz.new(attrs).tap { |r| r.new_record = false }
end
table_name() click to toggle source
# File lib/dynamoid/persistence.rb, line 18
def table_name
  table_base_name = options[:name] || base_class.name.split('::').last
    .downcase.pluralize
  table_prefix = if Dynamoid::Config.namespace.nil? then
    ''
  else
    "#{Dynamoid::Config.namespace}_"
  end

  @table_name ||= "#{table_prefix}#{table_base_name}"
end
undump(incoming = nil) click to toggle source

Undump an object into a hash, converting each type from a string representation of itself into the type specified by the field.

@since 0.2.0

# File lib/dynamoid/persistence.rb, line 68
def undump(incoming = nil)
  incoming = (incoming || {}).symbolize_keys
  Hash.new.tap do |hash|
    self.attributes.each do |attribute, options|
      hash[attribute] = undump_field(incoming[attribute], options)
    end
    incoming.each {|attribute, value| hash[attribute] = value unless hash.has_key? attribute }
  end
end
undump_field(value, options) click to toggle source

Undump a string value for a given type.

@since 0.2.0

# File lib/dynamoid/persistence.rb, line 81
def undump_field(value, options)
  if (field_class = options[:type]).is_a?(Class)
    raise 'Dynamoid class-type fields do not support default values' if options[:default]

    if field_class.respond_to?(:dynamoid_load)
      field_class.dynamoid_load(value)
    end
  elsif options[:type] == :serialized
    if value.is_a?(String)
      options[:serializer] ? options[:serializer].load(value) : YAML.load(value)
    else
      value
    end
  else
    if value.nil? && (default_value = options[:default])
      value = default_value.respond_to?(:call) ? default_value.call : default_value
    end

    if !value.nil?
      case options[:type]
        when :string
          value.to_s
        when :integer
          Integer(value)
        when :number
          BigDecimal.new(value.to_s)
        when :array
          value.to_a
        when :set
          Set.new(value)
        when :datetime
          if value.is_a?(Date) || value.is_a?(DateTime) || value.is_a?(Time)
            value
          else
            Time.at(value).to_datetime
          end
        when :boolean
          # persisted as 't', but because undump is called during initialize it can come in as true
          if value == 't' || value == true
            true
          elsif value == 'f' || value == false
            false
          else
            raise ArgumentError, "Boolean column neither true nor false"
          end
        else
          raise ArgumentError, "Unknown type #{options[:type]}"
      end
    end
  end
end