class Dynamosaurus::DynamoBase

Constants

TYPES

Public Class Methods

add(key=[], attribute_nums={}) click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 562
def add key=[], attribute_nums={}, options={}
  Dynamosaurus.logger << "update"

  attribute_updates = {}
  attribute_nums.each do |k, v|
    attribute_updates[k.to_s] = {
      :value => v,
      :action => "ADD"
    }
  end

  keys = {
    hash_key.to_sym => key.is_a?(Array) ? key[0] : key
  }
  keys[range_key.to_sym] = key[1]  if has_renge

  query ={
    :table_name => table_name,
    :key => keys,
    :attribute_updates => attribute_updates
  }
  query = query.merge(options)
  res = dynamo_db.update_item(query)

end
all() click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 480
def all
  Dynamosaurus.logger << "all #{table_name}"
  res = dynamo_db.scan({
    :table_name => table_name,
  })
  if res.items
    res.items.map{|item|
      new :data => item
    }
  end
end
all_models() click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 4
def all_models
  subclasses = []
  ObjectSpace.each_object(Dynamosaurus::DynamoBase.singleton_class) do |k|
    subclasses << k if k.superclass == Dynamosaurus::DynamoBase
  end
  subclasses
end
attribute_definitions() click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 108
def attribute_definitions
  @attribute_definitions
end
batch_get_item(keys) click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 447
def batch_get_item keys
  return nil if keys.nil? or keys.empty?
  Dynamosaurus.logger << "batch_get_item #{table_name} #{keys}"
  _keys = conv_key_array(keys)

  res = dynamo_db.batch_get_item(
    :request_items => {
      table_name => {
        :keys => _keys
      }
    })

  if res.responses[table_name]
    return res.responses[table_name].map{|item|
      new :data => item
    }
  end
  nil
end
batch_write_item(put_items = [], delete_items = []) click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 513
def batch_write_item put_items = [], delete_items = []
  return nil if (put_items.nil? or put_items.empty?) and (delete_items.nil? or delete_items.empty?)
  Dynamosaurus.logger << "batch_write_item #{table_name}"

  requests = []
  if put_items and put_items.size > 0
    put_items.each do |item|
      if item["hash"] or item["num_hash"]
        new_item = put_data(item["hash"], item["num_hash"])
      else
        new_item = item.merge({:updated_at => Time.now.to_i})
      end
      requests << {
        put_request: {
          item: new_item
        }
      }
    end
  end

  if delete_items and delete_items.size > 0
    conv_key_array(delete_items).map{|key|
      requests << {
        delete_request: {
          key: key
        }
      }
    }
  end

  res = dynamo_db.batch_write_item(
    request_items: {
      table_name => requests
    },
    return_consumed_capacity: "TOTAL"
  )
  res
end
conv_key_array(keys) click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 419
def conv_key_array keys
  unless has_renge
    keys.map{|_key| {hash_key.to_s => _key.to_s } }
  else
    if keys.is_a?(Array)
      if keys[0].is_a?(Array)
        keys.map{|key| get_orderd_key_from_array(key)}
      elsif keys[0].is_a?(Hash)
        keys.map{|key| get_orderd_key_from_hash(key)}
      else
        [get_orderd_key_from_array(keys)]
      end
    else
      _keys = []
      ((p_key = keys[hash_key]).is_a?(Array) ? p_key : [p_key]).each do |key1|
        if (r_key = keys[range_key]).is_a?(Array)
          r_key.each do |key2|
            _keys << get_orderd_key(key1, key2)
          end
        else
          _keys << get_orderd_key(key1, r_key)
        end
      end
      _keys
    end
  end
end
create_table(option={}) click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 22
def create_table option={}
  schem = schema.merge(option)
  Dynamosaurus.logger << "create table #{schem}"
  dynamo_db.create_table(schem)
end
create_tables() click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 12
def create_tables
  tables = dynamo_db.list_tables.table_names

  Dynamosaurus::DynamoBase.all_models.each do |model_class|
    if tables.index(model_class.table_name).nil?
      model_class.create_table
    end
  end
end
delete_item(value) click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 588
def delete_item value
  return nil if value.nil?

  old_item = dynamo_db.delete_item(
    :table_name => table_name,
    :key => get_item_key(value),
    :return_values => "ALL_OLD"
  )
  new :data => old_item.attributes
end
dynamo_db() click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 42
def dynamo_db
  return @dynamo_db if @dynamo_db
  if Aws::config.empty?
    @dynamo_db = Aws::DynamoDB::Client.new({
                                            endpoint: 'http://localhost:8000',
                                            region: 'us-west-2',
                                            access_key_id: 'fakeMyKeyId',
                                            secret_access_key: 'fakeSecretAccessKey'
                                           })
  else
    @dynamo_db = Aws::DynamoDB::Client.new
  end
end
first() click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 467
def first
  Dynamosaurus.logger << "first #{table_name}"
  res = dynamo_db.scan({
    :table_name => table_name,
    :limit => 1
  })
  if res.items && res.count > 0
    new :data => res.items[0]
  else
    nil
  end
end
get(value, option={}) click to toggle source

public method

# File lib/dynamosaurus/dynamo_class.rb, line 379
def get value, option={}
  if value.is_a? Hash
    if value[:index]
      get_from_local_index value, option
    elsif option[:noindex]
      option.delete(:noindex)
      query_without_index value, option
    else
      get_from_index value, option
    end
  else
    get_from_key value, option
  end
end
getOne(value, option={}) click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 394
def getOne value, option={}
  data = get(value, option)
  if data.nil? || data.empty?
    nil
  else
    data.first
  end
end
get_from_index(hash, option={}) click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 323
def get_from_index hash, option={}
  if index = get_index(hash)
    keys = {}

    index[:keys].each do |key|
      keys[key] = {
        :comparison_operator => "EQ",
        :attribute_value_list => [hash[key]]
      }
    end
    Dynamosaurus.logger << "query index #{table_name} #{keys}"
    query keys, index[:index_name], option
  end
end
get_from_key(value, option={}) click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 306
def get_from_key value, option={}
  return nil if value.nil?

  item_key = get_item_key(value)
  Dynamosaurus.logger << "get_item #{table_name} #{item_key}"

  res = dynamo_db.get_item(
    :table_name => table_name,
    :key => item_key
  )
  if res.item
    new :data => res.item
  else
    nil
  end
end
get_from_local_index(hash, option={}) click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 338
def get_from_local_index hash, option={}
  if index = hash.delete(:index)
    keys = {}
    hash.each do |k, v|
      keys[k] = {
        :comparison_operator => "EQ",
        :attribute_value_list => [ v.to_s ]
      }
    end
    Dynamosaurus.logger << "query local_index #{table_name} #{keys}"
    query keys, index, option
  end
end
get_global_index(name) click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 226
def get_global_index name
  @global_index[name]
end
get_global_indexes() click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 222
def get_global_indexes
  (@global_index) ? @global_index : {}

end
get_index(hash) click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 251
def get_index hash
  get_indexes.each{|key, value|
    if hash.size == 1 && hash.keys.first == value.first
      return {
        :index_name => key,
        :keys => [value[0]]
      }
    elsif hash.size == 2 && hash.keys.sort == [value[0], value[2]].sort
      return {
        :index_name => key,
        :keys => [value[0], value[2]]
      }
    end
  }
  nil
end
get_indexes() click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 247
def get_indexes
  get_secondary_indexes.merge(get_global_indexes)
end
get_item_key(value) click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 293
def get_item_key value
  if value.is_a? Array
    {
      hash_key => value[0].to_s,
      range_key => value[1].to_s,
    }
  else
    {
      hash_key => value.to_s,
    }
  end
end
get_key() click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 65
def get_key
 @key
end
get_orderd_key(value1, value2) click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 412
def get_orderd_key value1, value2
  {
    hash_key.to_s => value1,
      range_key.to_s => value2
  }
end
get_orderd_key_from_array(array) click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 408
def get_orderd_key_from_array array
  get_orderd_key(array[0], array[1])
end
get_orderd_key_from_hash(hash) click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 403
def get_orderd_key_from_hash hash
  get_orderd_key( (hash[hash_key.to_sym] || hash[hash_key.to_s]),
                 (hash[range_key.to_sym] || hash[range_key.to_s]))
end
get_secondary_index(name) click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 243
def get_secondary_index name
  @secondary_index[name]
end
get_secondary_indexes() click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 240
def get_secondary_indexes
  @secondary_index ? @secondary_index : {}
end
global_index(index_name, key, key_type, range_key_name=nil, range_key_type=nil) click to toggle source

indexes

# File lib/dynamosaurus/dynamo_class.rb, line 211
def global_index index_name, key, key_type, range_key_name=nil, range_key_type=nil
  @global_index = {} if @global_index.nil?
  @global_index[index_name] = [key, Dynamosaurus::DynamoBase::TYPES[key_type]]
  @global_index[index_name] << range_key_name <<  Dynamosaurus::DynamoBase::TYPES[range_key_type] if range_key_name
end
global_index_key_schema(index) click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 159
def global_index_key_schema index
  key_schema = [{
    :key_type => "HASH",
    :attribute_name => index[1][0]
  }]
  key_schema << {
        :key_type => "RANGE",
        :attribute_name => index[1][2]
      } if index[1].size == 4
  key_schema
end
global_index_option(index_name, option) click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 217
def global_index_option index_name, option
  @global_index_option = {} if @global_index_option.nil?
  @global_index_option[index_name] = option
end
global_index_schemas() click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 138
def global_index_schemas
  @global_index_option = {} if @global_index_option.nil?
  schema = []
  get_global_indexes.each do |index|
    option = @global_index_option[index[0]] || {}

    schema << {
      :index_name => index[0],
      :key_schema => global_index_key_schema(index),
      :projection => {
        :projection_type => (option[:projection_type] || "KEYS_ONLY"),
      },
      :provisioned_throughput => {
        :read_capacity_units => 10,
        :write_capacity_units => 10
      }
    }
  end
  schema
end
global_indexes_attribute_definitions() click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 177
def global_indexes_attribute_definitions
  get_global_indexes.each do |index|
    push_attribute_definitions(index[1][0].to_s, index[1][1].to_s.upcase)
    push_attribute_definitions(index[1][2].to_s, index[1][3].to_s.upcase) if index[1].size == 4
  end
end
has_renge() click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 69
def has_renge
  @key.size == 4
end
hash_key() click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 73
def hash_key
  @key[0]
end
key(k, type, range_key_name=nil, range_key_type=nil) click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 60
def key k, type, range_key_name=nil, range_key_type=nil
  @key = [k, Dynamosaurus::DynamoBase::TYPES[type]]
  @key << range_key_name << Dynamosaurus::DynamoBase::TYPES[range_key_type] if range_key_name
end
key_schema() click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 81
def key_schema
  key = [{
    :key_type => "HASH",
    :attribute_name => hash_key.to_s
  }]
  key << {
    :key_type => "RANGE",
    :attribute_name => range_key.to_s
  } if has_renge
  key
end
local_secondary_attribute_definitions() click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 171
def local_secondary_attribute_definitions
  get_secondary_indexes.each do |index_key, index_value|
    push_attribute_definitions(index_value[2].to_s, index_value[3].to_s.upcase)
  end
end
local_secondary_schemas() click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 112
def local_secondary_schemas
  @secondary_index_option = {} if @secondary_index_option.nil?
  schema = []
  get_secondary_indexes.each do |index_key, index_value|
    option = @secondary_index_option[index_key] || {}
    schema << {
      index_name: index_key,
      key_schema: [],
      projection: {
        :projection_type => (option[:projection_type] || "KEYS_ONLY"),
      },
      key_schema: [
        {
          key_type: "HASH",
          attribute_name: index_value[0]
        },
        {
          key_type: "RANGE",
          attribute_name: index_value[2]
        }
      ]
    }
  end
  schema
end
new(params) click to toggle source
# File lib/dynamosaurus/dynamo_base.rb, line 14
def initialize params
  data = params[:data] if params[:data]
  @data = Dynamosaurus::DynamoBase.res2hash(data)
end
push_attribute_definitions(name, type) click to toggle source

schema

# File lib/dynamosaurus/dynamo_class.rb, line 94
def push_attribute_definitions name, type
  if @attribute_definitions.nil?
    @attribute_definitions = []
    @attribute_names = []
  end
  if @attribute_names.index(name).nil?
    @attribute_definitions << {:attribute_name => name, :attribute_type => type}
    @attribute_names << name
  end
end
put(hash, num_hash={}) click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 492
def put hash, num_hash={}, return_values=nil
  new_hash = put_data(hash, num_hash)

  res = dynamo_db.put_item(
    :table_name => table_name,
    :item => new_hash,
    :return_values => return_values || "NONE"
  )
end
put_data(hash, num_hash={}) click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 502
def put_data hash, num_hash={}
  new_hash = {}
  hash.each{|key, value|
    new_hash[key] = value unless value.nil?
  }
  num_hash.merge({:updated_at => Time.now.to_i}).each{|key, value|
    new_hash[key] = value.to_i unless value.nil?
  } if num_hash
  new_hash
end
query(keys, index=nil, option={}) click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 352
def query keys, index=nil, option={}
  query = {
    :table_name => table_name
  }
  unless keys.nil? || keys.empty?
    query[:key_conditions] = keys
  end

  if index
    query[:index_name] = index
  end

  query.deep_merge!(option)
  res = dynamo_db.query(query)
  if query[:select] == "COUNT"
    res[:count]
  else
    if res.items
      return res.items.map{|item|
       new :data => item
      }
    end
  end
end
query_without_index(value, option) click to toggle source

query

# File lib/dynamosaurus/dynamo_class.rb, line 280
def query_without_index value, option
  keys = {}

  value.each_with_index{|(k,v), i|
    keys[k] = {
      :comparison_operator => "EQ",
      :attribute_value_list => [v.to_s]
    }
  }
  Dynamosaurus.logger << "query index #{table_name} #{keys}"
  query keys, nil, option
end
range_key() click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 77
def range_key
  @key[2]
end
res2hash(hash) click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 273
def res2hash hash
  new_hash = {}
  return new_hash if hash.nil?
  hash
end
save(hash, num_hash={}) click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 552
def save hash, num_hash={}, return_values=nil
  put(hash, num_hash, return_values)

  if has_renge
    get([hash[hash_key], hash[range_key]])
  else
    get(hash[hash_key])
  end
end
schema() click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 184
def schema
  set_init_attribute_definitions

  @schema = {
    table_name: table_name,
    key_schema: key_schema,
    provisioned_throughput: {
      read_capacity_units: 10,
      write_capacity_units: 10
    }
  }

  unless get_global_indexes.empty?
    @schema[:global_secondary_indexes] = global_index_schemas
    global_indexes_attribute_definitions
  end
  unless get_secondary_indexes.empty?
    @schema[:local_secondary_indexes] = local_secondary_schemas
    local_secondary_attribute_definitions
  end
  @schema[:attribute_definitions] = attribute_definitions

  @schema
end
secondary_index(index_name, range_key_name=nil, range_key_type=nil) click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 230
def secondary_index index_name, range_key_name=nil, range_key_type=nil
  @secondary_index = {} if @secondary_index.nil?
  @secondary_index[index_name.to_sym] = [@key[0], @key[1], range_key_name, Dynamosaurus::DynamoBase::TYPES[range_key_type]] if range_key_name
end
secondary_index_option(index_name, option) click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 235
def secondary_index_option index_name, option
  @secondary_index_option = {} if @secondary_index_option.nil?
  @secondary_index_option[index_name] = option
end
set_init_attribute_definitions() click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 104
def set_init_attribute_definitions
  push_attribute_definitions(hash_key.to_s,  get_key[1].to_s.upcase)
  push_attribute_definitions(range_key.to_s, get_key[3].to_s.upcase) if has_renge
end
table(options = {}) click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 56
def table options = {}
  @table ||= options
end
table_name() click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 34
def table_name
  if @table && @table.has_key?(:name) && !@table[:name].empty?
    @table[:name].to_s
  else
    (@table_prefix || name.downcase.split("::").last) + (ENV['DYNAMODB_SUFFIX'] || "_local")
  end
end
table_prefix(name) click to toggle source

end of indexes

# File lib/dynamosaurus/dynamo_class.rb, line 269
def table_prefix name
  @table_prefix = name
end
tables() click to toggle source
# File lib/dynamosaurus/dynamo_class.rb, line 28
def tables
  Dynamosaurus::DynamoBase.all_models.map do |model_class|
    model_class.table_name
  end
end

Public Instance Methods

[](key) click to toggle source
# File lib/dynamosaurus/dynamo_base.rb, line 23
def [] key
  @data[key.to_s]
end
[]=(key,value) click to toggle source
# File lib/dynamosaurus/dynamo_base.rb, line 27
def []=(key,value)
  @data[key.to_s] = value
end
add(attribute_nums={}) click to toggle source
# File lib/dynamosaurus/dynamo_base.rb, line 100
def add attribute_nums={}, options={}
  if self.class.has_renge
    key_value = [@data[key[0].to_s], @data[key[2].to_s]]
  else
    key_value = @data[key[0].to_s]
  end
  attribute_nums.each do |k, v|
    @data[k.to_s] = @data[k.to_s] + v.to_i
  end
  self.class.add(key_value, attribute_nums, options)
end
attr_delete(attributes=[]) click to toggle source
# File lib/dynamosaurus/dynamo_base.rb, line 131
def attr_delete attributes=[]
  Dynamosaurus.logger << "delete"

  attribute_updates = {}
  attributes.each do |k|
    attribute_updates[k.to_s] = {
      :action => "DELETE"
    }
    @data.delete(k.to_s)
  end

  res = dynamo_db.update_item(
    :table_name => self.class.table_name,
    :key => keys,
    :attribute_updates => attribute_updates
  )
end
data() click to toggle source
# File lib/dynamosaurus/dynamo_base.rb, line 31
def data
  @data
end
delete() click to toggle source
# File lib/dynamosaurus/dynamo_base.rb, line 149
def delete
  dynamo_db.delete_item(
    :table_name => self.class.table_name,
    :key => keys
  )
end
dynamo_db() click to toggle source
# File lib/dynamosaurus/dynamo_base.rb, line 10
def dynamo_db
  self.class.dynamo_db
end
empty?() click to toggle source
# File lib/dynamosaurus/dynamo_base.rb, line 39
def empty?
  @data.empty?
end
exist?() click to toggle source
# File lib/dynamosaurus/dynamo_base.rb, line 35
def exist?
  ! @data.empty?
end
key() click to toggle source
# File lib/dynamosaurus/dynamo_base.rb, line 60
def key
  return @key if @key
  @key = self.class.get_key
end
keys() click to toggle source
# File lib/dynamosaurus/dynamo_base.rb, line 65
def keys
  item_key = {}
  item_key[key[0].to_sym] = @data[key[0].to_s]
  item_key[key[2].to_sym] = @data[key[2].to_s] if key.size == 4
  item_key
end
method_missing(name, *params) click to toggle source
Calls superclass method
# File lib/dynamosaurus/dynamo_base.rb, line 47
def method_missing(name, *params)
  name = name.to_s[0..-2] if name.to_s[-1] == "="
  if exist? and @data.has_key?(name.to_s)
    if params.empty?
      @data[name.to_s]
    else
      @data[name.to_s] = params[0]
    end
  else
    super
  end
end
save() click to toggle source
# File lib/dynamosaurus/dynamo_base.rb, line 112
def save
  attribute_updates = {}
  @data.each do |k, v|
    if key.index(k.to_sym).nil?
      attribute_updates[k.to_s] = {
        :value => v,
        :action => "PUT"
      }
    end
  end

  query = {
    :table_name => self.class.table_name,
    :key => keys,
    :attribute_updates => attribute_updates
  }
  res = dynamo_db.update_item(query)
end
table_name() click to toggle source
# File lib/dynamosaurus/dynamo_base.rb, line 19
def table_name
  self.class.table_name
end
try(name) click to toggle source
# File lib/dynamosaurus/dynamo_base.rb, line 43
def try name
  @data[name.to_s]
end
update(attributes={}) click to toggle source
# File lib/dynamosaurus/dynamo_base.rb, line 72
def update attributes={}, attribute_nums={}, options={}
  Dynamosaurus.logger << "update"

  attribute_updates = {}
  attributes.each do |k, v|
    @data[k.to_s] = v
    attribute_updates[k.to_s] = {
      :value => v,
      :action => "PUT"
    }
  end

  attribute_nums.each do |k, v|
    @data[k.to_s] = v.to_i
    attribute_updates[k.to_s] = {
      :value => v.to_i,
      :action => "PUT"
    }
  end

  query = {
    :table_name => self.class.table_name,
    :key => keys,
    :attribute_updates => attribute_updates
  }.merge(options)
  res = dynamo_db.update_item(query)
end