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
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
# File rails/lib/orchestrate_rails/model.rb, line 293 def self.attributes new.attributes end
Returns array of model attribute names.
# File rails/lib/orchestrate_rails/model.rb, line 289 def self.attrs schema.attrs ocollection end
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
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
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
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
Deletes the entire collection.
Returns boolean status.
# File rails/lib/orchestrate_rails/model.rb, line 346 def self.destroy_all orchio_delete ocollection end
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 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
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
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
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
Returns the last (ordered) instance in the collection.
# File rails/lib/orchestrate_rails/model.rb, line 363 def self.last all.last end
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
Calls ::find_by_method for 'find_by_attribute(s)'.
# 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
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.
# 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
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
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
Handles find_by_attribute methods.
# 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
Returns SearchResult. Orchestrate.io search implements Lucene Query Parser Syntax.
# File rails/lib/orchestrate_rails/model.rb, line 436 def self.search(query_str, limit=:all, offset=0) query_str = orchio_query_str(query_str) unless query_str == '*' if limit == :all total_count = offset + 1 max = 100 qdocs = [] while offset < total_count qresult = orchio_search( ocollection, "#{query_str}&limit=#{max}&offset=#{offset}" ) offset += qresult.count total_count = qresult.total_count qdocs += qresult.results end qresult = SearchResult.new( results: qdocs, count: offset, total_count: total_count, status: qresult.status, response: qresult.response ) else qresult = orchio_search( ocollection, "#{query_str}&limit=#{limit}&offset=#{offset}" ) end qresult.results.map! { |odoc| odoc.to_rails } qresult end
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
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
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
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
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
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
Returns array of model attribute names.
# File rails/lib/orchestrate_rails/model.rb, line 58 def attrs self.class.attrs end
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
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
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
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
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
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
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
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
Returns the collection name for the current instance.
# File rails/lib/orchestrate_rails/model.rb, line 77 def orchestrate_collection_name ocollection end
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
Called by ActiveModel::Serialization
# File rails/lib/orchestrate_rails/model.rb, line 50 def read_attribute_for_serialization(attribute) instance_variable_get("@#{attribute}") end
Called by ActiveModel::Validation
# File rails/lib/orchestrate_rails/model.rb, line 45 def read_attribute_for_validation(attribute) instance_variable_get("@#{attribute}") end
Calls save_if_match.
# File rails/lib/orchestrate_rails/model.rb, line 135 def save save_if_match end
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
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
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
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
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
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
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
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
# 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
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