class AWS::Record::HashModel
Public Class Methods
Returns an enumerable scope object represents all records.
Book.all.each do |book| # ... end
This method is equivalent to `find(:all)`, and therefore you can also pass aditional options.
Book.all(:where => { :author' => 'me' }).each do |my_book| # ... end
@return [Scope] Returns an enumerable scope object.
# File lib/aws/record/hash_model/finder_methods.rb, line 109 def all options = {} new_scope.find(:all, options) end
Adds a DynamoDB
binary attribute to this class. A binary attribute acts the same as a string attribute, except
@param [Symbol] name The name of the attribute.
@param [Hash] options
@option options [Boolean] :set (false) When true this attribute
can have multiple values.
@note This should not be used for large objects.
# File lib/aws/record/hash_model/attributes.rb, line 169 def binary_attr name, options = {} end
Adds a boolean attribute to this class.
@example
class Book < AWS::Record::HashModel boolean_attr :read end b = Book.new b.read? # => false b.read = true b.read? # => true listing = Listing.new(:score => '123.456' listing.score # => 123.456
@param [Symbol] name The name of the attribute.
# File lib/aws/record/hash_model/attributes.rb, line 98 def boolean_attr name, options = {} attr = add_attribute(Attributes::BooleanAttr.new(name, options)) # add the boolean question mark method define_method("#{attr.name}?") do !!__send__(attr.name) end end
Counts records Amazon DynamoDB
.
class Product < AWS::Record::HashModel end # returns the count of records in the 'Product' table Product.count
You can specify the table via shard
# returns the count of records in the 'products-1' table Product.shard('products-1').count
You can also specify the shard as an option to count.
Product.count(:shard => 'table-name')
Chaining count with limit has no effect on the count.
Product.limit(10).count # same as Product.count, limit ignored
@param [Hash] options
@option [String] :shard Which shard to count records in.
@return [Integer] The count of records in the table.
# File lib/aws/record/hash_model/finder_methods.rb, line 145 def count options = {} new_scope.count(options) end
Creates the DynamoDB
table that is configured for this class.
class Product < AWS::Record::HashModel end # create the table 'Product' with 10 read/write capacity units Product.create_table 10, 10
If you shard you data across multiple tables, you can specify the shard name:
# create two tables, with the given names Product.create_table 500, 10, :shard_name => 'products-1' Product.create_table 500, 10, :shard_name => 'products-2'
If you share a single AWS
account with multiple applications, you can provide a table prefix to group tables and to avoid name collisions:
AWS::Record.table_prefix = 'myapp-' # creates the table 'myapp-Product' Product.create_table 250, 50 # creates the table 'myapp-products-1' Product.create_table 250, 50, :shard_name => 'products-1'
@param [Integer] read_capacity_units
See {DynamoDB::TableCollection#create} for more information.
@param [Integer] write_capacity_units
See {DynamoDB::TableCollection#create} for more information.
@param [Hash] options
@option options [String] :shard_name Defaults to the class name. The
shard name will be prefixed with {AWS::Record.table_prefix}, and that becomes the table name.
@return [DynamoDB::Table]
# File lib/aws/record/hash_model.rb, line 78 def create_table read_capacity_units, write_capacity_units, options = {} table_name = dynamo_db_table_name(options[:shard_name]) create_opts = {} create_opts[:hash_key] = { hash_key => :string } dynamo_db.tables.create( table_name, read_capacity_units, write_capacity_units, create_opts) end
Adds a date attribute to this class.
@example A standard date attribute
class Person < AWS::Record::HashModel date_attr :birthdate end baby = Person.new baby.birthdate = Time.now baby.birthdate #=> <Date: ....>
@param [Symbol] name The name of the attribute.
@param [Hash] options
@option options [Boolean] :set (false) When true this attribute
can have multiple dates.
# File lib/aws/record/hash_model/attributes.rb, line 153 def date_attr name, options = {} add_attribute(Attributes::DateAttr.new(name, options)) end
Adds a datetime attribute to this class.
@example A standard datetime attribute
class Recipe < AWS::Record::HashModel datetime_attr :invented end recipe = Recipe.new(:invented => Time.now) recipe.invented #=> <DateTime ...>
If you add a datetime_attr
for `:created_at` and/or `:updated_at` those will be automanaged.
@param [Symbol] name The name of the attribute.
@param [Hash] options
@option options [Boolean] :set (false) When true this attribute
can have multiple date times.
# File lib/aws/record/hash_model/attributes.rb, line 130 def datetime_attr name, options = {} add_attribute(Attributes::DateTimeAttr.new(name, options)) end
@return [DynamoDB::Table] @api private
# File lib/aws/record/hash_model.rb, line 95 def dynamo_db_table shard_name = nil table = dynamo_db.tables[dynamo_db_table_name(shard_name)] table.hash_key = [hash_key, :string] table end
Yields once for each record.
# File lib/aws/record/hash_model/finder_methods.rb, line 114 def each &block all.each(&block) end
Finds records in Amazon DynamoDB
and returns them as objects of the current class.
Finding `:all` returns an enumerable scope object
People.find(:all, :limit => 10).each do |person| puts person.name end
Finding `:first` returns a single record (or nil)
boss = People.find(:first)
Find accepts a hash of find modifiers (`:shard` and `:limit`). You can also choose to omit these modifiers and chain them on the scope object returned. In the following example only one request is made to SimpleDB
(when each is called)
people = People.find(:all, :limit => 10) people = people.limit(10).find(:all)
@overload find(id)
@param id The record to find, raises an exception if the record is not found.
@overload find(mode, options = {})
@param [:all,:first] mode (:all) When finding `:all` matching records and array is returned of records. When finding `:first` then `nil` or a single record will be returned. @param [Hash] options @option options [Integer] :shard The shard name of the Amazon DynamoDB table to search. @option options [Integer] :limit The max number of records to fetch.
# File lib/aws/record/hash_model/finder_methods.rb, line 76 def find *args new_scope.find(*args) end
@param [String] id The id of the record to load. @param [Hash] options @option options [String] :shard Specifies what shard (i.e. table)
should be searched.
@raise [RecordNotFound] Raises a record not found exception if there
was no data found for the given id.
@return [Record::HashModel] Returns the record with the given id.
# File lib/aws/record/hash_model/finder_methods.rb, line 26 def find_by_id id, options = {} table = dynamo_db_table(options[:shard]) data = table.items[id].attributes.to_h raise RecordNotFound, "no data found for id: #{id}" if data.empty? obj = self.new(:shard => table) obj.send(:hydrate, id, data) obj end
@return [Object,nil] Returns the first record found. If there were
no records found, nil is returned.
# File lib/aws/record/hash_model/finder_methods.rb, line 152 def first options = {} new_scope.first(options) end
Adds a float attribute to this class.
class Listing < AWS::Record::HashModel float_attr :score end listing = Listing.new(:score => '123.456') listing.score # => 123.456
@param [Symbol] name The name of the attribute. @param [Hash] options @option options [Boolean] :set (false) When true this attribute
can have multiple values.
# File lib/aws/record/hash_model/attributes.rb, line 77 def float_attr name, options = {} add_attribute(Attributes::FloatAttr.new(name, options)) end
@api private
# File lib/aws/record/hash_model.rb, line 102 def hash_key hash_key_attribute.name end
@api private
# File lib/aws/record/hash_model.rb, line 107 def hash_key_attribute @hash_key_attribute end
# File lib/aws/record/hash_model.rb, line 24 def self.inherited(sub_class) sub_class.string_attr :id, :hash_key => true, :default_hash_key_attribute => true end
Adds an integer attribute to this class.
class Recipe < AWS::Record::HashModel integer_attr :servings end recipe = Recipe.new(:servings => '10') recipe.servings #=> 10
@param [Symbol] name The name of the attribute. @param [Hash] options @option options [Boolean] :set (false) When true this attribute
can have multiple values.
# File lib/aws/record/hash_model/attributes.rb, line 60 def integer_attr name, options = {} add_attribute(Attributes::IntegerAttr.new(name, options)) end
The maximum number of records to return. By default, all records matching the where conditions will be returned from a find.
People.limit(10).each {|person| ... }
Limit can be chained with other scope modifiers:
People.where(:age => 40).limit(10).each {|person| ... }
# File lib/aws/record/hash_model/finder_methods.rb, line 165 def limit limit new_scope.limit(limit) end
Returns a chainable scope object that restricts further scopes to a particular table.
Book.shard('books-2').each do |book| # ... end
@param [String] shard_name @return [Scope] Returns a scope for restricting the table searched.
# File lib/aws/record/hash_model/finder_methods.rb, line 89 def shard shard_name new_scope.shard(shard_name) end
Adds a string attribute to this class.
@example A standard string attribute
class Recipe < AWS::Record::HashModel string_attr :name end recipe = Recipe.new(:name => "Buttermilk Pancakes") recipe.name #=> 'Buttermilk Pancakes'
@example A string attribute with `:set` set to true
class Recipe < AWS::Record::HashModel string_attr :tags, :set => true end recipe = Recipe.new(:tags => %w(popular dessert)) recipe.tags #=> #<Set: {"popular", "desert"}>
@param [Symbol] name The name of the attribute. @param [Hash] options @option options [Boolean] :set (false) When true this attribute
can have multiple values.
# File lib/aws/record/hash_model/attributes.rb, line 43 def string_attr name, options = {} add_attribute(Attributes::StringAttr.new(name, options)) end
A convenience method for adding the standard two datetime attributes `:created_at` and `:updated_at`.
@example
class Recipe < AWS::Record::HashModel timestamps end recipe = Recipe.new recipe.save recipe.created_at #=> <DateTime ...> recipe.updated_at #=> <DateTime ...>
# File lib/aws/record/hash_model/attributes.rb, line 186 def timestamps c = datetime_attr :created_at u = datetime_attr :updated_at [c, u] end
Private Class Methods
# File lib/aws/record/hash_model.rb, line 131 def add_attribute(attribute) set_hash_key_attribute(attribute) if attribute.options[:hash_key] super(attribute) end
# File lib/aws/record/hash_model.rb, line 127 def dynamo_db AWS::DynamoDB.new end
# File lib/aws/record/hash_model.rb, line 123 def dynamo_db_table_name shard_name = nil "#{Record.table_prefix}#{self.shard_name(shard_name)}" end
# File lib/aws/record/hash_model.rb, line 113 def set_hash_key_attribute(attribute) if hash_key_attribute and hash_key_attribute.options[:default_hash_key_attribute] then remove_attribute(hash_key_attribute) end @hash_key_attribute = attribute end
Public Instance Methods
@return [String,nil]
# File lib/aws/record/hash_model.rb, line 31 def hash_key self[self.class.hash_key] end
Private Instance Methods
# File lib/aws/record/hash_model.rb, line 163 def create_storage dynamo_db_table.items.create(serialize_attributes, opt_lock_conditions) end
# File lib/aws/record/hash_model.rb, line 185 def delete_storage dynamo_db_item.delete(opt_lock_conditions) end
# File lib/aws/record/hash_model.rb, line 190 def deserialize_item_data data data.inject({}) do |hash,(attr_name,value)| if attribute = self.class.attributes[attr_name] hash[attr_name] = value.is_a?(Set) ? value.map{|v| attribute.deserialize(v) } : attribute.deserialize(value) end hash end end
@return [DynamoDB::Item] Returns a reference to the item as stored in
simple db.
@api private
# File lib/aws/record/hash_model.rb, line 151 def dynamo_db_item dynamo_db_table.items[hash_key] end
@return [SimpleDB::Domain] Returns the domain this record is
persisted to or will be persisted to.
# File lib/aws/record/hash_model.rb, line 158 def dynamo_db_table self.class.dynamo_db_table(shard) end
# File lib/aws/record/hash_model.rb, line 140 def populate_id hash_key = self.class.hash_key_attribute if hash_key.options[:default_hash_key_attribute] self[hash_key.name] = SecureRandom.uuid end end
# File lib/aws/record/hash_model.rb, line 168 def update_storage # Only enumerating dirty (i.e. changed) attributes. Empty # (nil and empty set) values are deleted, the others are replaced. dynamo_db_item.attributes.update(opt_lock_conditions) do |u| changed.each do |attr_name| attribute = self.class.attribute_for(attr_name) value = serialize_attribute(attribute, @_data[attr_name]) if value.nil? or value == [] u.delete(attr_name) else u.set(attr_name => value) end end end end