lib/conceptql/operators/casting_operator.rb in conceptql-0.2.0 vs lib/conceptql/operators/casting_operator.rb in conceptql-0.3.0
- old
+ new
@@ -3,92 +3,100 @@
module ConceptQL
module Operators
# Parent class of all casting operators
#
# Subclasses must implement the following methods:
- # - my_type
+ # - my_domain
# - i_point_at
# - these_point_at_me
#
- # i_point_at returns a list of types for which the operator's table of origin
+ # i_point_at returns a list of domains for which the operator's table of origin
# has foreign_keys pointing to another table, e.g.:
# procedure_occurrence has an FK to visit_occurrence, so we'd put
# :visit_occurrence in the i_point_at array
#
- # these_point_at_me is a list of types for which that type's table
+ # these_point_at_me is a list of domains for which that domain's table
# of origin has a FK pointing to the current operator's
# table of origin, e.g.:
# procedure_cost has an FK to procedure_occurrence so we'd
# put :procedure_cost in procedure_occurrence's these_point_at_me array
#
# Also, if a casting operator is passed no streams, it will return all the
# rows in its table as results.
class CastingOperator < Operator
- category 'Casting'
- def types
- [type]
+ category "Get Related Data"
+ basic_type :cast
+ validate_at_most_one_upstream
+ validate_no_arguments
+
+ def domains(db)
+ [domain]
end
- def type
- my_type
+ def domain
+ my_domain
end
def castables
(i_point_at + these_point_at_me)
end
+ def query_cols
+ table_columns(make_table_name(my_domain))
+ end
+
def query(db)
- return db.from(make_table_name(my_type)) if stream.nil?
+ return db.from(make_table_name(my_domain)) if stream.nil?
base_query(db, stream.evaluate(db))
end
private
def base_query(db, stream_query)
- uncastable_types = stream.types - castables
- to_me_types = stream.types & these_point_at_me
- from_me_types = stream.types & i_point_at
+ uncastable_domains = stream.domains(db) - castables
+ to_me_domains = stream.domains(db) & these_point_at_me
+ from_me_domains = stream.domains(db) & i_point_at
- destination_table = make_table_name(my_type)
+ destination_table = make_table_name(my_domain)
casting_query = db.from(destination_table)
wheres = []
- unless uncastable_types.empty?
+ unless uncastable_domains.empty?
# We have a situation where one or more of the incoming streams
# isn't castable so we'll just return all rows for
# all people in each uncastable stream
uncastable_person_ids = db.from(stream_query)
- .where(criterion_type: uncastable_types.map(&:to_s))
+ .where(criterion_domain: uncastable_domains.map(&:to_s))
.select_group(:person_id)
wheres << Sequel.expr(person_id: uncastable_person_ids)
end
- destination_type_id = make_type_id(my_type)
+ destination_domain_id = make_domain_id(my_domain)
- unless to_me_types.empty?
- # For each castable type in the stream, setup a query that
- # casts each type to a set of IDs, union those IDs and fetch
+ unless to_me_domains.empty?
+ # For each castable domain in the stream, setup a query that
+ # casts each domain to a set of IDs, union those IDs and fetch
# them from the source table
- castable_type_query = to_me_types.map do |source_type|
+ castable_domain_query = to_me_domains.map do |source_domain|
source_ids = db.from(stream_query)
- .where(criterion_type: source_type.to_s)
+ .where(criterion_domain: source_domain.to_s)
.select_group(:criterion_id)
- source_table = make_table_name(source_type)
- source_type_id = make_type_id(source_type)
+ source_table = make_table_name(source_domain)
+ source_domain_id = make_domain_id(source_domain)
db.from(source_table)
- .where(source_type_id => source_ids)
- .select(destination_type_id)
+ .where(source_domain_id => source_ids)
+ .select(destination_domain_id)
end.inject do |union_query, q|
- union_query.union(q)
+ union_query.union(q, all: true)
end
- wheres << Sequel.expr(destination_type_id => castable_type_query)
+ wheres << Sequel.expr(destination_domain_id => castable_domain_query)
end
- unless from_me_types.empty?
- from_me_types.each do |from_me_type|
- fk_type_id = make_type_id(from_me_type)
- wheres << Sequel.expr(fk_type_id => db.from(stream_query).where(criterion_type: from_me_type.to_s).select_group(:criterion_id))
+ unless from_me_domains.empty?
+ from_me_domains.each do |from_me_domain|
+ fk_domain_id = make_domain_id(from_me_domain)
+ wheres << Sequel.expr(fk_domain_id => db.from(stream_query).where(criterion_domain: from_me_domain.to_s).select_group(:criterion_id))
end
end
casting_query.where(wheres.inject(&:|))
end