class Rasti::DB::Collection

Constants

QUERY_METHODS

Attributes

environment[R]

Public Class Methods

collection_attributes() click to toggle source
# File lib/rasti/db/collection.rb, line 16
def collection_attributes
  @collection_attributes ||= model.attribute_names - relations.keys - computed_attributes.keys
end
collection_name() click to toggle source
# File lib/rasti/db/collection.rb, line 12
def collection_name
  @collection_name ||= underscore(demodulize(name)).to_sym
end
computed_attributes() click to toggle source
# File lib/rasti/db/collection.rb, line 50
def computed_attributes
  @computed_attributes ||= Hash::Indifferent.new
end
data_source_name() click to toggle source
# File lib/rasti/db/collection.rb, line 38
def data_source_name
  @data_source_name ||= superclass.respond_to?(:data_source_name) ? superclass.data_source_name : :default
end
foreign_key() click to toggle source
# File lib/rasti/db/collection.rb, line 24
def foreign_key
  @foreign_key ||= "#{singularize(collection_name)}_id".to_sym
end
model() click to toggle source
# File lib/rasti/db/collection.rb, line 28
def model
  if @model.is_a? Class
    @model
  elsif @model
    @model = Consty.get @model, self
  else
    @model = Consty.get demodulize(singularize(name)), self
  end
end
new(environment) click to toggle source
# File lib/rasti/db/collection.rb, line 105
def initialize(environment)
  @environment = environment
end
primary_key() click to toggle source
# File lib/rasti/db/collection.rb, line 20
def primary_key
  @primary_key ||= :id
end
queries() click to toggle source
# File lib/rasti/db/collection.rb, line 46
def queries
  @queries ||= Hash::Indifferent.new
end
relations() click to toggle source
# File lib/rasti/db/collection.rb, line 42
def relations
  @relations ||= Hash::Indifferent.new
end

Private Class Methods

computed_attribute(name, &block) click to toggle source
# File lib/rasti/db/collection.rb, line 98
def computed_attribute(name, &block)
  raise "Computed Attribute #{name} already exists" if computed_attributes.key? name
  computed_attributes[name] = block.call
end
query(name, lambda=nil, &block) click to toggle source
# File lib/rasti/db/collection.rb, line 88
def query(name, lambda=nil, &block)
  raise "Query #{name} already exists" if queries.key? name

  queries[name] = lambda || block

  define_method name do |*args|
    default_query.instance_exec(*args, &self.class.queries.fetch(name))
  end
end
set_collection_name(collection_name) click to toggle source
# File lib/rasti/db/collection.rb, line 56
def set_collection_name(collection_name)
  @collection_name = collection_name.to_sym
end
set_data_source_name(name) click to toggle source
# File lib/rasti/db/collection.rb, line 72
def set_data_source_name(name)
  @data_source_name = name.to_sym
end
set_foreign_key(foreign_key) click to toggle source
# File lib/rasti/db/collection.rb, line 64
def set_foreign_key(foreign_key)
  @foreign_key = foreign_key
end
set_model(model) click to toggle source
# File lib/rasti/db/collection.rb, line 68
def set_model(model)
  @model = model
end
set_primary_key(primary_key) click to toggle source
# File lib/rasti/db/collection.rb, line 60
def set_primary_key(primary_key)
  @primary_key = primary_key
end

Public Instance Methods

bulk_delete(&block) click to toggle source
# File lib/rasti/db/collection.rb, line 159
def bulk_delete(&block)
  build_query(&block).instance_eval { dataset.delete }
  nil
end
bulk_insert(attributes, options={}) click to toggle source
# File lib/rasti/db/collection.rb, line 125
def bulk_insert(attributes, options={})
  db_attributes = attributes.map { |attrs| transform_attributes_to_db attrs }
  dataset.multi_insert db_attributes, options
end
bulk_update(attributes, &block) click to toggle source
# File lib/rasti/db/collection.rb, line 148
def bulk_update(attributes, &block)
  db_attributes = transform_attributes_to_db attributes
  build_query(&block).instance_eval { dataset.update db_attributes }
  nil
end
delete(primary_key) click to toggle source
# File lib/rasti/db/collection.rb, line 154
def delete(primary_key)
  dataset.where(self.class.primary_key => primary_key).delete
  nil
end
delete_cascade(*primary_keys) click to toggle source
# File lib/rasti/db/collection.rb, line 174
def delete_cascade(*primary_keys)
  data_source.db.transaction do
    delete_cascade_relations primary_keys
    bulk_delete { |q| q.where self.class.primary_key => primary_keys }
  end
  nil
end
delete_relations(primary_key, relations) click to toggle source
# File lib/rasti/db/collection.rb, line 164
def delete_relations(primary_key, relations)
  data_source.db.transaction do
    relations.each do |relation_name, relation_primary_keys|
      relation = self.class.relations[relation_name]
      delete_relation_table relation, primary_key, relation_primary_keys
    end
  end
  nil
end
detect(filter=nil, &block) click to toggle source
# File lib/rasti/db/collection.rb, line 194
def detect(filter=nil, &block)
  build_query(filter, &block).first
end
exists?(filter=nil, &block) click to toggle source
# File lib/rasti/db/collection.rb, line 190
def exists?(filter=nil, &block)
  build_query(filter, &block).any?
end
find(primary_key) click to toggle source
# File lib/rasti/db/collection.rb, line 182
def find(primary_key)
  where(self.class.primary_key => primary_key).first
end
find_graph(primary_key, *relations) click to toggle source
# File lib/rasti/db/collection.rb, line 186
def find_graph(primary_key, *relations)
  where(self.class.primary_key => primary_key).graph(*relations).first
end
insert(attributes) click to toggle source
# File lib/rasti/db/collection.rb, line 115
def insert(attributes)
  data_source.db.transaction do
    db_attributes = transform_attributes_to_db attributes
    collection_attributes, relations_primary_keys = split_related_attributes db_attributes
    primary_key = dataset.insert collection_attributes
    save_relations primary_key, relations_primary_keys
    primary_key
  end
end
insert_relations(primary_key, relations) click to toggle source
# File lib/rasti/db/collection.rb, line 130
def insert_relations(primary_key, relations)
  relations.each do |relation_name, relation_primary_keys|
    relation = self.class.relations[relation_name]
    insert_relation_table relation, primary_key, relation_primary_keys
  end
  nil
end
update(primary_key, attributes) click to toggle source
# File lib/rasti/db/collection.rb, line 138
def update(primary_key, attributes)
  data_source.db.transaction do
    db_attributes = transform_attributes_to_db attributes
    collection_attributes, relations_primary_keys = split_related_attributes db_attributes
    dataset.where(self.class.primary_key => primary_key).update(collection_attributes) unless collection_attributes.empty?
    save_relations primary_key, relations_primary_keys
  end
  nil
end

Private Instance Methods

build_query(filter=nil, &block) click to toggle source
# File lib/rasti/db/collection.rb, line 225
def build_query(filter=nil, &block)
  raise ArgumentError, 'must specify filter hash or block' if filter.nil? && block.nil?

  if filter
    default_query.where(filter)
  else
    block.arity == 0 ? default_query.instance_eval(&block) : block.call(default_query)
  end
end
data_source() click to toggle source
# File lib/rasti/db/collection.rb, line 202
def data_source
  @data_source ||= environment.data_source_of self.class
end
dataset() click to toggle source
# File lib/rasti/db/collection.rb, line 206
def dataset
  data_source.db[qualified_collection_name]
end
default_query() click to toggle source
# File lib/rasti/db/collection.rb, line 219
def default_query
  Query.new collection_class: self.class,
            dataset: dataset.select_all(self.class.collection_name),
            environment: environment
end
delete_cascade_relations(primary_keys) click to toggle source
# File lib/rasti/db/collection.rb, line 259
def delete_cascade_relations(primary_keys)
  relations = self.class.relations.values

  relations.select(&:many_to_many?).each do |relation|
    delete_relation_table relation, primary_keys
  end

  relations.select { |r| r.one_to_many? || r.one_to_one? }.each do |relation|
    relation_data_source = environment.data_source_of relation.target_collection_class
    relation_collection_name = relation_data_source.qualify relation.target_collection_class.collection_name

    relations_ids = relation_data_source.db[relation_collection_name]
                                        .where(relation.foreign_key => primary_keys)
                                        .select(relation.target_collection_class.primary_key)
                                        .map(relation.target_collection_class.primary_key)

    target_collection = relation.target_collection_class.new environment
    target_collection.delete_cascade(*relations_ids) unless relations_ids.empty?
  end
end
delete_relation_table(relation, primary_keys, relation_primary_keys=nil) click to toggle source
# File lib/rasti/db/collection.rb, line 294
def delete_relation_table(relation, primary_keys, relation_primary_keys=nil)
  relation_data_source = environment.data_source relation.relation_data_source_name
  relation_collection_name = relation_data_source.qualify relation.relation_collection_name

  ds = relation_data_source.db[relation_collection_name].where(relation.source_foreign_key => primary_keys)
  ds = ds.where(relation.target_foreign_key => relation_primary_keys) if relation_primary_keys
  ds.delete
end
insert_relation_table(relation, primary_key, relation_primary_keys) click to toggle source
# File lib/rasti/db/collection.rb, line 280
def insert_relation_table(relation, primary_key, relation_primary_keys)
  relation_data_source = environment.data_source relation.relation_data_source_name
  relation_collection_name = relation_data_source.qualify relation.relation_collection_name

  values = relation_primary_keys.map do |relation_pk|
    {
      relation.source_foreign_key => primary_key,
      relation.target_foreign_key => relation_pk
    }
  end

  relation_data_source.db[relation_collection_name].multi_insert values
end
qualified_collection_name() click to toggle source
# File lib/rasti/db/collection.rb, line 210
def qualified_collection_name
  data_source.qualify self.class.collection_name
end
qualify(collection_name, data_source_name: nil) click to toggle source
# File lib/rasti/db/collection.rb, line 214
def qualify(collection_name, data_source_name: nil)
  data_source_name ||= self.class.data_source_name
  environment.qualify data_source_name, collection_name
end
save_relations(primary_key, relations_primary_keys) click to toggle source
# File lib/rasti/db/collection.rb, line 251
def save_relations(primary_key, relations_primary_keys)
  relations_primary_keys.each do |relation_name, relation_primary_keys|
    relation = self.class.relations[relation_name]
    delete_relation_table relation, [primary_key]
    insert_relation_table relation, primary_key, relation_primary_keys
  end
end
transform_attributes_to_db(attributes) click to toggle source
# File lib/rasti/db/collection.rb, line 235
def transform_attributes_to_db(attributes)
  attributes.each_with_object({}) do |(attribute_name, value), result|
    transformed_value = Rasti::DB.to_db data_source.db, qualified_collection_name, attribute_name, value
    result[attribute_name] = transformed_value
  end
end