module DynaModel::Schema::ClassMethods
Constants
- ATTR_TYPES
- KEY_TYPE
- PROJECTION_TYPE
Public Instance Methods
attribute_definitions()
click to toggle source
TODO - need to add projections?
# File lib/dyna_model/schema.rb, line 113 def attribute_definitions # Keys for hash/range/secondary # S | N | B keys = [] keys << hash_key[:attribute_name] keys << range_key[:attribute_name] if range_key local_secondary_indexes.each do |lsi| keys << lsi[:key_schema].select{|h| h[:key_type] == "RANGE"}.first[:attribute_name] end global_secondary_indexes.each do |lsi| lsi[:key_schema].each do |a| keys << a[:attribute_name] end end definitions = keys.uniq.collect do |k| attr = self.attributes[k.to_s] { attribute_name: attr.name, attribute_type: attribute_type_indicator(attr) } end end
attribute_type_indicator(attr)
click to toggle source
# File lib/dyna_model/schema.rb, line 139 def attribute_type_indicator(attr) if attr_type = ATTR_TYPES[attr.class] attr_type else raise "unsupported attribute type #{attr.class}" end end
global_secondary_index(index_name, options={})
click to toggle source
{ hash_key
: :hash_key_here, range_key
: :optional_range_key_here } :name :projection :read_provision :write_provision
# File lib/dyna_model/schema.rb, line 163 def global_secondary_index(index_name, options={}) options[:projection] ||= :keys_only global_secondary_index_hash = { projection: {}, provisioned_throughput: { read_capacity_units: options[:read_provision] || read_provision, write_capacity_units: options[:write_provision] || write_provision } } if options[:projection].is_a?(Array) && options[:projection].size > 0 options[:projection].each do |non_key_attr| attr = self.attributes[non_key_attr.to_s] raise(ArgumentError, "Could not find attribute definition for projection on #{non_key_attr}") unless attr (global_secondary_index_hash[:projection][:non_key_attributes] ||= []) << attr.name end global_secondary_index_hash[:projection][:projection_type] = PROJECTION_TYPE[:include] else raise(ArgumentError, 'projection must be :all, :keys_only, Array (or attrs)') unless options[:projection] == :keys_only || options[:projection] == :all global_secondary_index_hash[:projection][:projection_type] = PROJECTION_TYPE[options[:projection]] end if !options.has_key?(:hash_key) || self.attributes[options[:hash_key].to_s].blank? raise(ArgumentError, "Could not find attribute definition for global secondary index on hash_key specified") end hash_key_attr = self.attributes[options[:hash_key].to_s] if options.has_key?(:range_key) && self.attributes[options[:range_key].to_s].blank? raise(ArgumentError, "Could not find attribute definition for global secondary index on range_key specified") end range_key_attr = nil range_key_attr = self.attributes[options[:range_key].to_s] if options.has_key?(:range_key) ## Force naming of index_name for lookup later #global_secondary_index_hash[:index_name] = (index_name.to_s || "#{hash_key_attr.name}#{"_#{range_key_attr.name}" if range_key_attr}_gsi_index".camelcase) global_secondary_index_hash[:index_name] = index_name.to_s global_secondary_index_hash[:key_schema] = [ { attribute_name: hash_key_attr.name, key_type: KEY_TYPE[:hash] } ] global_secondary_index_hash[:key_schema] << { attribute_name: range_key_attr.name, key_type: KEY_TYPE[:range] } if range_key_attr return false if (@global_secondary_indexes ||= []).select {|i| i[:index_name] == global_secondary_index_hash[:index_name] }.present? # Do not add if we already have a range key set for this attr (@global_secondary_indexes ||= []) << global_secondary_index_hash end
global_secondary_indexes()
click to toggle source
# File lib/dyna_model/schema.rb, line 154 def global_secondary_indexes @global_secondary_indexes ||= [] end
guid_delimiter(val=nil)
click to toggle source
# File lib/dyna_model/schema.rb, line 43 def guid_delimiter(val=nil) if val raise(ArgumentError, "Invalid guid_delimiter") if val.blank? @guid_delimiter = val.to_s else @guid_delimiter || DynaModel::Config.default_guid_delimiter end end
hash_key(hash_key_key=nil)
click to toggle source
# File lib/dyna_model/schema.rb, line 78 def hash_key(hash_key_key=nil) if hash_key_key hash_key_attribute = self.attributes[hash_key_key.to_s] raise(ArgumentError, "Could not find attribute definition for hash_key #{hash_key_key}") unless hash_key_attribute raise(ArgumentError, "Invalid attribute type for hash_key") unless [AWS::Record::Attributes::StringAttr, AWS::Record::Attributes::IntegerAttr, AWS::Record::Attributes::FloatAttr].include?(hash_key_attribute.class) validates_presence_of hash_key_attribute.name.to_sym @dynamo_hash_key = { attribute_name: hash_key_attribute.name, key_type: KEY_TYPE[:hash] } else @dynamo_hash_key end end
key_schema()
click to toggle source
# File lib/dyna_model/schema.rb, line 147 def key_schema raise(ArgumentError, 'hash_key was not set for this table') if @dynamo_hash_key.blank? schema = [hash_key] schema << range_key if range_key schema end
local_secondary_index(range_key_attr, options={})
click to toggle source
# File lib/dyna_model/schema.rb, line 218 def local_secondary_index(range_key_attr, options={}) options[:projection] ||= :keys_only local_secondary_index_hash = { projection: {} } if options[:projection].is_a?(Array) && options[:projection].size > 0 options[:projection].each do |non_key_attr| attr = self.attributes[non_key_attr.to_s] raise(ArgumentError, "Could not find attribute definition for projection on #{non_key_attr}") unless attr (local_secondary_index_hash[:projection][:non_key_attributes] ||= []) << attr.name end local_secondary_index_hash[:projection][:projection_type] = PROJECTION_TYPE[:include] else raise(ArgumentError, 'projection must be :all, :keys_only, Array (or attrs)') unless options[:projection] == :keys_only || options[:projection] == :all local_secondary_index_hash[:projection][:projection_type] = PROJECTION_TYPE[options[:projection]] end range_attr = self.attributes[range_key_attr.to_s] raise(ArgumentError, "Could not find attribute definition for local secondary index on #{range_key_attr}") unless range_attr local_secondary_index_hash[:index_name] = (options[:name] || options[:index_name] || "#{range_attr.name}_index".camelcase) hash_key_attr = self.attributes[hash_key[:attribute_name].to_s] raise(ArgumentError, "Could not find attribute definition for hash_key") unless hash_key_attr local_secondary_index_hash[:key_schema] = [ { attribute_name: hash_key_attr.name, key_type: KEY_TYPE[:hash] }, { attribute_name: range_attr.name, key_type: KEY_TYPE[:range] } ] return false if (@local_secondary_indexes ||= []).select {|i| i[:index_name] == local_secondary_index_hash[:index_name] }.present? # Do not add if we already have a range key set for this attr (@local_secondary_indexes ||= []) << local_secondary_index_hash end
local_secondary_indexes()
click to toggle source
# File lib/dyna_model/schema.rb, line 214 def local_secondary_indexes @local_secondary_indexes ||= [] end
range_key(range_key_key=nil)
click to toggle source
# File lib/dyna_model/schema.rb, line 95 def range_key(range_key_key=nil) if range_key_key range_key_attribute = self.attributes[range_key_key.to_s] raise(ArgumentError, "Could not find attribute definition for range_key #{range_key_key}") unless range_key_attribute raise(ArgumentError, "Invalid attribute type for range_key") unless [AWS::Record::Attributes::StringAttr, AWS::Record::Attributes::IntegerAttr, AWS::Record::Attributes::FloatAttr, AWS::Record::Attributes::DateAttr, AWS::Record::Attributes::DateTimeAttr].include?(range_key_attribute.class) validates_presence_of range_key_attribute.name.to_sym @dynamo_range_key = { attribute_name: range_key_attribute.name, key_type: KEY_TYPE[:range] } else @dynamo_range_key end end
read_provision(val=nil)
click to toggle source
# File lib/dyna_model/schema.rb, line 52 def read_provision(val=nil) if val raise(ArgumentError, "Invalid read provision") unless val.to_i >= 1 @dynamo_read_provision = val.to_i else @dynamo_read_provision || DynaModel::Config.read_provision end end
table_prefix(val=nil)
click to toggle source
# File lib/dyna_model/schema.rb, line 70 def table_prefix(val=nil) if val @dynamo_table_prefix = val else @dynamo_table_prefix || AWS::Record.table_prefix || "#{DynaModel::Config.namespace}#{Rails.application.class.parent_name.to_s.underscore.dasherize}-#{Rails.env}-" end end
table_schema()
click to toggle source
# File lib/dyna_model/schema.rb, line 28 def table_schema schema = { table_name: dynamo_db_table_name, provisioned_throughput: { read_capacity_units: read_provision, write_capacity_units: write_provision }, key_schema: key_schema, attribute_definitions: attribute_definitions } schema[:local_secondary_indexes] = local_secondary_indexes unless local_secondary_indexes.blank? schema[:global_secondary_indexes] = global_secondary_indexes unless global_secondary_indexes.blank? schema end
write_provision(val=nil)
click to toggle source
# File lib/dyna_model/schema.rb, line 61 def write_provision(val=nil) if val raise(ArgumentError, "Invalid write provision") unless val.to_i >= 1 @dynamo_write_provision = val.to_i else @dynamo_write_provision || DynaModel::Config.write_provision end end