Module: Card::Query::CardQuery::Sorting
- Included in:
- Card::Query::CardQuery
- Defined in:
- card/lib/card/query/card_query/sorting.rb
Overview
handle relational (not simple) CQL sort values (see #interpret_as_modifier? and #order_directives)
sorting with subqueries is not fully supported; only a few experimental examples have been attempted, and even for those the syntax is likely to change.
Generally speaking, sorting subqueries will require a JOIN strategy (as opposed to the “WHERE EXISTS” strategy that is central to queries’ main conditions.)
Constant Summary collapse
- SORT_BY_ITEM_JOIN_MAP =
{ left: "left_id", right: "right_id" }.freeze
Instance Method Summary collapse
-
#count_sort_query ⇒ Object
-
#count_subselect(val) ⇒ Object
-
#join_cards(val, opts = {}) ⇒ Object
-
#join_count_sort_query(sort_query) ⇒ Object
-
#sort(val) ⇒ Object
-
#sort_by(val, item, sort_field) ⇒ Object
-
#sort_by_count(val, item) ⇒ Object
EXPERIMENTAL! sort_by: { referred_to_by { right: “*follow” }, return count }.
-
#sort_by_count_referred_to(val) ⇒ Object
-
#sort_by_item_join(val, item, sort_field) ⇒ Object
-
#sort_by_item_join_field(item) ⇒ Object
-
#sort_method_not_implemented(method, item) ⇒ Object
Instance Method Details
#count_sort_query ⇒ Object
82 83 84 85 86 |
# File 'card/lib/card/query/card_query/sorting.rb', line 82 def count_sort_query Query.new return: "coalesce(count(*), 0) as count", group: "sort_join_field", superquery: self end |
#count_subselect(val) ⇒ Object
78 79 80 |
# File 'card/lib/card/query/card_query/sorting.rb', line 78 def count_subselect val Query.new val.merge(return: "id", superquery: self) end |
#join_cards(val, opts = {}) ⇒ Object
88 89 90 91 92 93 94 95 96 97 |
# File 'card/lib/card/query/card_query/sorting.rb', line 88 def join_cards val, opts={} conditions_on_join = opts.delete :conditions_on_join s = subquery join_opts = { from: self, to: s }.merge opts card_join = Join.new join_opts joins << card_join unless opts[:from].is_a? Join s.conditions_on_join = card_join if conditions_on_join s.interpret val s end |
#join_count_sort_query(sort_query) ⇒ Object
69 70 71 72 73 74 75 76 |
# File 'card/lib/card/query/card_query/sorting.rb', line 69 def join_count_sort_query sort_query sort_query.mods[:sort_join_field] = "#{sort_query.table_alias}.id as sort_join_field" # FIXME: HACK! joins << Join.new(from: self, side: "LEFT", to: [sort_query, "srtbl", "sort_join_field"]) end |
#sort(val) ⇒ Object
17 18 19 20 21 22 23 |
# File 'card/lib/card/query/card_query/sorting.rb', line 17 def sort val return nil unless full? # eg, no sorting on simple count queries interpret_sort_hash val do |value, item, sort_field| sort_by value, item, sort_field end end |
#sort_by(val, item, sort_field) ⇒ Object
25 26 27 28 29 30 31 |
# File 'card/lib/card/query/card_query/sorting.rb', line 25 def sort_by val, item, sort_field if sort_field == "count" sort_by_count val, item else sort_by_item_join val, item, sort_field end end |
#sort_by_count(val, item) ⇒ Object
EXPERIMENTAL! sort_by: { referred_to_by { right: “*follow” }, return count }
48 49 50 51 52 |
# File 'card/lib/card/query/card_query/sorting.rb', line 48 def sort_by_count val, item method_name = "sort_by_count_#{item}" sort_method_not_implemented :count, item unless respond_to? method_name send method_name, val end |
#sort_by_count_referred_to(val) ⇒ Object
58 59 60 61 62 63 64 65 66 67 |
# File 'card/lib/card/query/card_query/sorting.rb', line 58 def sort_by_count_referred_to val @mods[:sort_by] = "coalesce(count,0)" # needed for postgres sort_query = count_sort_query sort_query.add_condition "referer_id in (#{count_subselect(val).sql})" # FIXME: - SQL generated before SQL phase sort_query.joins << Join.new(from: sort_query, side: "LEFT", to: %w[card_references wr referee_id]) join_count_sort_query sort_query end |
#sort_by_item_join(val, item, sort_field) ⇒ Object
33 34 35 36 37 38 39 |
# File 'card/lib/card/query/card_query/sorting.rb', line 33 def sort_by_item_join val, item, sort_field join_field = sort_by_item_join_field item join = join_cards val, to_field: join_field, side: "LEFT", conditions_on_join: true @mods[:sort_by] ||= "#{join.table_alias}.#{sort_field}" end |
#sort_by_item_join_field(item) ⇒ Object
41 42 43 |
# File 'card/lib/card/query/card_query/sorting.rb', line 41 def sort_by_item_join_field item SORT_BY_ITEM_JOIN_MAP[item.to_sym] || sort_method_not_implemented(:join, item) end |