class Orchestrate::Rails::Model

Class to define rails models for Orchestrate.io DataBases-as-a-Service. The library provides a base class that, when subclassed to define a model, sets up a mapping between the model and an Orchestrate.io collection.

Public Class Methods

all() click to toggle source

Returns ordered array of all instances in the collection.

# File rails/lib/orchestrate_rails/model.rb, line 351
def self.all
  res = list
  (res.success?) ? res.results : false
end
attributes() click to toggle source
# File rails/lib/orchestrate_rails/model.rb, line 293
def self.attributes
  new.attributes
end
attrs() click to toggle source

Returns array of model attribute names.

# File rails/lib/orchestrate_rails/model.rb, line 289
def self.attrs
  schema.attrs ocollection
end
create(key_value_pairs) click to toggle source

Creates a new instance; updates the collection if the primary_key is not already present in the collection.

Returns the instance upon success; false upon failure.

# File rails/lib/orchestrate_rails/model.rb, line 317
def self.create(key_value_pairs)
  new(key_value_pairs).save_if_none_match
end
create!(key_value_pairs) click to toggle source

Creates a new instance; updates the collection.

Returns the instance upon success; false upon failure.

# File rails/lib/orchestrate_rails/model.rb, line 324
def self.create!(key_value_pairs)
  new(key_value_pairs).save!
end
destroy(id) click to toggle source

Deletes the specified instance from the collection.

Returns boolean status.

# File rails/lib/orchestrate_rails/model.rb, line 331
def self.destroy(id)
  new(:id => id).destroy
end
destroy!(id) click to toggle source

Deletes the specified instance and purges all of its immutable data from the collection.

Returns boolean status.

# File rails/lib/orchestrate_rails/model.rb, line 339
def self.destroy!(id)
  new(:id => id).destroy!
end
destroy_all() click to toggle source

Deletes the entire collection.

Returns boolean status.

# File rails/lib/orchestrate_rails/model.rb, line 346
def self.destroy_all
  orchio_delete ocollection
end
exists?(id) click to toggle source

Returns boolean to indicate whether the specified primary_key exists in the collection.

# File rails/lib/orchestrate_rails/model.rb, line 375
def self.exists?(id)
  find(id) ? true : false
end
find(arg) click to toggle source

Find by the primary_key (id). Can be a specific id, or an array of ids.

Returns instance, or array of instances, accordingly.

# File rails/lib/orchestrate_rails/model.rb, line 382
def self.find(arg)
  if arg.is_a? Integer or arg.is_a? String
    new(:id => arg).get
  elsif arg.is_a? Array
    arg.map { |id| new(:id => id).get }
  end
end
find_by(key_value_pairs) click to toggle source

Returns the first instance that matches the specified criteria.

# File rails/lib/orchestrate_rails/model.rb, line 396
def self.find_by(key_value_pairs)
  where(key_value_pairs).first
end
find_by_method(myattrs, *args, &block) click to toggle source

Calls ::find_by for properly constructed 'find_by_attribute(s)' calls.

Example: User.find_by_name_and_address(name, address) is executed as:

User.find_by(:name => name, :address => address)

# File rails/lib/orchestrate_rails/model.rb, line 406
def self.find_by_method(myattrs, *args, &block)
  attrs_with_args = [myattrs.split('_and_'), args].transpose
  attrs_with_args.each { |awa| return unless attrs.include? awa.first }
  find_by Hash[attrs_with_args]
end
first() click to toggle source

Returns the first (ordered) instance in the collection.

# File rails/lib/orchestrate_rails/model.rb, line 357
def self.first
  res = list(1)
  (res.success?) ? res.results.first : false
end
last() click to toggle source

Returns the last (ordered) instance in the collection.

# File rails/lib/orchestrate_rails/model.rb, line 363
def self.last
  all.last
end
list(limit=:all, start_key=nil, after_key=nil) click to toggle source

Returns Orchestrate::Application::Result.

The start index may be optionally specified by using either start_key (inclusive) or after_key (exclusive). The default is the first primary key in the collection.

# File rails/lib/orchestrate_rails/model.rb, line 471
def self.list(limit=:all, start_key=nil, after_key=nil)
  if limit == :all
    total_count = 0
    max = 100
    result = orchio_list ocollection, "?limit=#{max}"
    count = result.count
    docs = result.results
    while result.next
      result = orchio_list ocollection, "?#{result.next.split('?').last}"
      docs += result.results
      count += result.count
    end
    result = Orchestrate::Application::Result.new(
      results:  docs,
      count:    count,
      status:   result.status,
      response: result.response
    )
  else
    option_str = "?limit=#{limit}"
    option_str += "&startKey=#{start_key}" if start_key and after_key.nil?
    option_str += "&afterKey=#{after_key}" if after_key and start_key.nil?
    result = orchio_list ocollection, option_str
  end
  result.results.map! { |odoc| odoc.to_rails }
  result
end
method_missing(name, *args, &block) click to toggle source

Calls ::find_by_method for 'find_by_attribute(s)'.

Calls superclass method
# File rails/lib/orchestrate_rails/model.rb, line 413
def self.method_missing(name, *args, &block)
  if name.to_s =~ /^find_by_(.+)$/
    find_by_method($1, *args, &block) || super
  else
    super
  end
end
new(params={}) click to toggle source

Creates instance variable for each model attribute defined by the schema. Initializes any attribute values that are passed in via the params hash and then initializes the @attributes instance variable.

Any key/value pair in params whose key is not an attribute (i.e. :id or :define_collection_name) is passed on to the superclass.

Calls superclass method Orchestrate::Application::Record.new
# File rails/lib/orchestrate_rails/model.rb, line 26
def initialize(params={})super(params)
  # Define accessor and query methods for each attribute.
  attrs.each do |attribute|
    self.class.send :attr_accessor, attribute
    define_attr_query attribute
  end

  # Set instance variables and initialize @attributes with any
  # attribute values that were passed in the params hash.
  @attributes = {}
  params.each do |k,v|
    if attrs.include? k.to_s
      send("#{k}=", v)
      @attributes[k] = v
    end
  end
end
properties() click to toggle source

Returns array of property names.

Property names are the original key names in json documents stored in orchestrate collections - before they are converted to the snake_case style used for model attribute names. Attribute names are mapped to property names using ::qmap. Property names can be mapped to attribute names with Symbol#to_orchio_rails_attr or String#to_orchio_rails_attr.

# File rails/lib/orchestrate_rails/model.rb, line 306
def self.properties
  schema.properties(ocollection).select { |prop| prop !~ /id/i }
end
qmap() click to toggle source

Returns the table that maps attribute names to property names.

This mapping also works when the input is a property name.

# File rails/lib/orchestrate_rails/model.rb, line 284
def self.qmap
  schema.qmap ocollection
end
respond_to?(name) click to toggle source

Handles find_by_attribute methods.

Calls superclass method
# File rails/lib/orchestrate_rails/model.rb, line 422
def self.respond_to?(name)
  (attributes.include?(name) and name.to_s =~ /^find_by_.*$/) or super
end
search_results(query_str) click to toggle source

Returns array of model instances that match the query string.

# File rails/lib/orchestrate_rails/model.rb, line 429
def self.search_results(query_str)
  res = search(query_str)
  (res.success?) ? res.results : false
end
take() click to toggle source

Returns the first (random) instance in the collection.

# File rails/lib/orchestrate_rails/model.rb, line 368
def self.take
  res = search('*', 1)
  (res.success?) ? res.results.first : false
end
where(key_value_pairs) click to toggle source

Returns all instances that match the specified criteria.

# File rails/lib/orchestrate_rails/model.rb, line 391
def self.where(key_value_pairs)
  search_results(key_value_pairs.map{ |k,v| "#{k}:#{v}" }.join(' AND '))
end

Private Class Methods

orchio_query_str(query_str) click to toggle source

Returns an orchestrate-ready query string for the search request. The attribute names used by the model are replaced with the property names used in the collection.

# File rails/lib/orchestrate_rails/model.rb, line 517
def self.orchio_query_str(query_str)
  keys = query_str.scan(/^(\w+):/).map { |r| r.first } +
         query_str.scan(/\s(\w+):/).map { |r| r.first }
  keys.each { |k| query_str.gsub!(/#{k}:/, "#{qmap[k]}:") if qmap[k] }
  query_str
end
schema() click to toggle source

Returns handle to the Schema singleton instance.

# File rails/lib/orchestrate_rails/model.rb, line 510
def self.schema
  @@schema ||= Schema.instance
end

Public Instance Methods

attributes() click to toggle source

Returns hash of key/value pairs.

# File rails/lib/orchestrate_rails/model.rb, line 63
def attributes
  @attributes = Hash[attrs.map { |a| [a.to_sym, send("#{a}")] }]
end
attrs() click to toggle source

Returns array of model attribute names.

# File rails/lib/orchestrate_rails/model.rb, line 58
def attrs
  self.class.attrs
end
create_event(event_type, timestamp=nil, event_rec) click to toggle source

Creates event instance; calls save_event to update the collection.

Returns the event instance upon success; false upon failure.

# File rails/lib/orchestrate_rails/model.rb, line 215
def create_event(event_type, timestamp=nil, event_rec)
  save_event event_type, timestamp, Event.new(event_rec)
end
delete_graph(kind, to_collection, to_key) click to toggle source

Removes the specified relation from the graph.

Returns boolean status.

# File rails/lib/orchestrate_rails/model.rb, line 244
def delete_graph(kind, to_collection, to_key)
  retval orchio_delete_graph kind, to_collection, to_key
end
destroy() click to toggle source

Deletes the current primary_key from the collection. Calls orchio_delete

Returns boolean status.

# File rails/lib/orchestrate_rails/model.rb, line 176
def destroy
  orchio_delete
end
destroy!() click to toggle source

Deletes the current primary_key and purges all of its immutable data from the collection.

Returns boolean status.

# File rails/lib/orchestrate_rails/model.rb, line 184
def destroy!
  orchio_purge
end
events(event_type, timestamp={}) click to toggle source

Returns array of event instances specified by event_type and timestamp range,

where the timestamp range is specified as { :start => start, :end => end }

# File rails/lib/orchestrate_rails/model.rb, line 200
def events(event_type, timestamp={})
  res = orchio_get_events(event_type, timestamp)
  (res.success?) ? res.results.map { |odoc| odoc.to_event } : false
end
get() click to toggle source

Returns the key/value data for the current instance.

# File rails/lib/orchestrate_rails/model.rb, line 102
def get
  res = orchio_get
  (res.success?) ? res.result.update_rails(self) : false
end
get_by_ref(ref) click to toggle source

Returns the key/value data for the current instance, found by ref value.

# File rails/lib/orchestrate_rails/model.rb, line 109
def get_by_ref(ref)
  res = orchio_get_by_ref ref
  (res.success?) ? res.result.update_rails(self) : false
end
graph(kind) click to toggle source

Returns array of instances associated with the specified kind of relation.

# File rails/lib/orchestrate_rails/model.rb, line 229
def graph(kind)
  res = orchio_get_graph(kind)
  (res.success?) ? res.results.map { |odoc| odoc.to_rails } : false
end
orchestrate_collection_name() click to toggle source

Returns the collection name for the current instance.

# File rails/lib/orchestrate_rails/model.rb, line 77
def orchestrate_collection_name
  ocollection
end
orchestrate_ref_value() click to toggle source

Returns the ref value for the current instance. The ref value is an immutable value assigned to each version of primary_key data in an orchestrate.io collection.

# File rails/lib/orchestrate_rails/model.rb, line 84
def orchestrate_ref_value
  __ref_value__
end
read_attribute_for_serialization(attribute) click to toggle source

Called by ActiveModel::Serialization

# File rails/lib/orchestrate_rails/model.rb, line 50
def read_attribute_for_serialization(attribute)
  instance_variable_get("@#{attribute}")
end
read_attribute_for_validation(attribute) click to toggle source

Called by ActiveModel::Validation

# File rails/lib/orchestrate_rails/model.rb, line 45
def read_attribute_for_validation(attribute)
  instance_variable_get("@#{attribute}")
end
save() click to toggle source

Calls save_if_match.

# File rails/lib/orchestrate_rails/model.rb, line 135
def save
  save_if_match
end
save!() click to toggle source

Updates the collection with current instance data.

Returns the instance upon success; false upon failure.

# File rails/lib/orchestrate_rails/model.rb, line 142
def save!
  status = orchio_put(to_json_direct) if valid?
  retval status
end
save_event(event_type, timestamp=nil, event) click to toggle source

Updates the collection with the specified event instance.

Returns the event instance upon success; false upon failure.

# File rails/lib/orchestrate_rails/model.rb, line 208
def save_event(event_type, timestamp=nil, event)
  retval orchio_put_event(event_type, timestamp, event.to_json), event
end
save_graph(kind, to_collection, to_key) click to toggle source

Updates the collection with the specified graph relation.

Returns boolean status.

# File rails/lib/orchestrate_rails/model.rb, line 237
def save_graph(kind, to_collection, to_key)
  retval orchio_put_graph(kind, to_collection, to_key)
end
save_if_match() click to toggle source

Updates the collection with current instance data, if the ref value matches the ref value associated with the same primary_key in the collection.

Returns the instance upon success; false upon failure.

# File rails/lib/orchestrate_rails/model.rb, line 129
def save_if_match
  status = orchio_put_if_match(to_json_direct, __ref_value__) if valid?
  retval status
end
save_if_none_match() click to toggle source

Updates the collection with current instance data, if the primary_key (id) does not exist in the collection.

Returns the instance upon success; false upon failure.

# File rails/lib/orchestrate_rails/model.rb, line 118
def save_if_none_match
  status = orchio_put_if_none_match(to_json_direct) if valid?
  retval status
end
update_attribute(key, value) click to toggle source

Updates the attribute and calls save_if_match.

# File rails/lib/orchestrate_rails/model.rb, line 148
def update_attribute(key, value)
  instance_variable_set "@#{key}", value
  save_if_match
end
update_attributes(key_value_pairs) click to toggle source

Updates the attributes and calls save_if_match.

# File rails/lib/orchestrate_rails/model.rb, line 154
def update_attributes(key_value_pairs)
  key_value_pairs.each { |k,v| instance_variable_set "@#{k}", v }
  save_if_match
end

Private Instance Methods

define_attr_query(attribute) click to toggle source

Defines query method to test whether the attribute value is present.

# File rails/lib/orchestrate_rails/model.rb, line 252
def define_attr_query(attribute)
  self.class.send :define_method, "#{attribute}?" do
    !instance_variable_get("@#{attribute}").blank?
  end
end
retval(status, obj=nil) click to toggle source
# File rails/lib/orchestrate_rails/model.rb, line 92
def retval(status, obj=nil)
  if status == true
    (obj.blank?) ? self : obj
  else
    status
  end
end
to_json_direct() click to toggle source

Generates json for the attribute key/value pairs, replacing attribute names used by the model with the property names used in the collection.

# File rails/lib/orchestrate_rails/model.rb, line 261
def to_json_direct
  Hash[attrs.map { |a| [qmap[a], instance_variable_get("@#{a}")] }].to_json
end