Module: Card::Query::AbstractQuery::Tie
- Included in:
- Card::Query::AbstractQuery
- Defined in:
- card/lib/card/query/abstract_query/tie.rb
Overview
The “Tie” methods support tying two queries (CardQuery, ReferenceQuery, etc) together. The “subquery_type” variable determines which tying strategy is used.
We currently support three values for “subquery_type”: :join, :exist, and :in
In concept, here’s how the different strategies would tie table A to table B in SQL assuming A.id = B.a_id
- :join … FROM A JOIN B ON A.id = B.a_id
- :exist … FROM A WHERE EXISTS (SELECT * FROM B WHERE A.id = B.a_id …)
- :in … FROM A WHERE A.id IN (SELECT B.a_id FROM B WHERE …)
The different strategies will return the same values but the relative speed is context dependent.
Instance Method Summary collapse
-
#fasten ⇒ Object
-
#fasten_tie(subquery, fields = {}) ⇒ Object
-
#id_from_val(val) ⇒ Object
-
#inherit_fasten ⇒ Object
-
#left_join?(subquery) ⇒ Boolean
-
#list_of_ids?(val) ⇒ Boolean
-
#negate_join(subquery, join, fields) ⇒ Object
-
#op_and_id_or_ids_from_val(val) ⇒ Object
-
#restrict(id_field, val) ⇒ Object
-
#super_conditions(fields) ⇒ Object
-
#superfield(myfield, superfield) ⇒ Object
-
#tie(subquery_type, val, fields = {}, subquery_args = {}) ⇒ Object
-
#tie_subquery(subquery_type, subquery_args) ⇒ Object
-
#tie_with_exist(subquery, fields) ⇒ Object
-
#tie_with_in(subquery, fields) ⇒ Object
-
#tie_with_join(subquery, fields = {}) ⇒ Object
-
#tie_with_join_args(subquery, fields) ⇒ Object
Instance Method Details
#fasten ⇒ Object
52 53 54 |
# File 'card/lib/card/query/abstract_query/tie.rb', line 52 def fasten @fasten ||= root? ? :join : inherit_fasten end |
#fasten_tie(subquery, fields = {}) ⇒ Object
31 32 33 34 35 |
# File 'card/lib/card/query/abstract_query/tie.rb', line 31 def fasten_tie subquery, fields={} method = "tie_with_#{subquery.fasten}" send method, subquery, fields subquery end |
#id_from_val(val) ⇒ Object
94 95 96 97 98 99 |
# File 'card/lib/card/query/abstract_query/tie.rb', line 94 def id_from_val val case val when Integer then val when String, Symbol then val.card_id || -999 end end |
#inherit_fasten ⇒ Object
73 74 75 76 |
# File 'card/lib/card/query/abstract_query/tie.rb', line 73 def inherit_fasten superfasten = superquery.fasten superfasten == :direct ? superquery.inherit_fasten : superfasten end |
#left_join?(subquery) ⇒ Boolean
63 64 65 66 |
# File 'card/lib/card/query/abstract_query/tie.rb', line 63 def left_join? subquery current_conjunction == "or" || subquery.negate # reverse conjunction if negated? end |
#list_of_ids?(val) ⇒ Boolean
109 110 111 112 113 |
# File 'card/lib/card/query/abstract_query/tie.rb', line 109 def list_of_ids? val return unless val.is_a? Array !val.find { |v| !id_from_val v } end |
#negate_join(subquery, join, fields) ⇒ Object
68 69 70 71 |
# File 'card/lib/card/query/abstract_query/tie.rb', line 68 def negate_join subquery, join, fields subquery.conditions_on_join = join add_condition "#{subquery.fld fields[:to]} is null" end |
#op_and_id_or_ids_from_val(val) ⇒ Object
101 102 103 104 105 106 107 |
# File 'card/lib/card/query/abstract_query/tie.rb', line 101 def op_and_id_or_ids_from_val val if (single_id = id_from_val val) "= #{single_id}" elsif list_of_ids? val "in (#{val.map { |v| id_from_val v }.join ', '})" end end |
#restrict(id_field, val) ⇒ Object
86 87 88 89 90 91 92 |
# File 'card/lib/card/query/abstract_query/tie.rb', line 86 def restrict id_field, val if (id = id_from_val val) interpret id_field => id else tie :card, val, from: id_field end end |
#super_conditions(fields) ⇒ Object
78 79 80 |
# File 'card/lib/card/query/abstract_query/tie.rb', line 78 def super_conditions fields superfield fields[:to], fields[:from] end |
#superfield(myfield, superfield) ⇒ Object
82 83 84 |
# File 'card/lib/card/query/abstract_query/tie.rb', line 82 def superfield myfield, superfield add_condition "#{fld myfield} = #{superquery.fld superfield}" end |
#tie(subquery_type, val, fields = {}, subquery_args = {}) ⇒ Object
19 20 21 22 23 24 |
# File 'card/lib/card/query/abstract_query/tie.rb', line 19 def tie subquery_type, val, fields={}, subquery_args={} subquery = tie_subquery subquery_type, subquery_args subquery.interpret val fields = { from: :id, to: :id }.merge fields fasten_tie subquery, fields end |
#tie_subquery(subquery_type, subquery_args) ⇒ Object
26 27 28 29 |
# File 'card/lib/card/query/abstract_query/tie.rb', line 26 def tie_subquery subquery_type, subquery_args subquery_args[:class] = Query.class_for subquery_type subquery(subquery_args) end |
#tie_with_exist(subquery, fields) ⇒ Object
48 49 50 |
# File 'card/lib/card/query/abstract_query/tie.rb', line 48 def tie_with_exist subquery, fields subquery.super_conditions fields if fields.present? end |
#tie_with_in(subquery, fields) ⇒ Object
43 44 45 46 |
# File 'card/lib/card/query/abstract_query/tie.rb', line 43 def tie_with_in subquery, fields subquery.mods[:return] = fields[:to] subquery.mods[:in_field] = fld(fields[:from]) end |
#tie_with_join(subquery, fields = {}) ⇒ Object
37 38 39 40 41 |
# File 'card/lib/card/query/abstract_query/tie.rb', line 37 def tie_with_join subquery, fields={} join = Join.new tie_with_join_args(subquery, fields) negate_join(subquery, join, fields) if subquery.negate joins << join end |
#tie_with_join_args(subquery, fields) ⇒ Object
56 57 58 59 60 61 |
# File 'card/lib/card/query/abstract_query/tie.rb', line 56 def tie_with_join_args subquery, fields args = { from: self, from_field: fields[:from], to: subquery, to_field: fields[:to] } args[:side] = :left if left_join? subquery args end |