Module: Miscellany::SortLang
- Defined in:
- lib/miscellany/sort_lang.rb
Defined Under Namespace
Classes: Parser
Class Method Summary collapse
- .distinct_sorts(sorts) ⇒ Object
-
.normalize_sort(sort, key: nil) ⇒ Object
Normalized Format: { key: string, column: string, order: ‘DESC’ | ‘ASC’, force_order?: boolean, # Prevent overriding order nulls?: ‘high’ | ‘low’ | ‘first’ | ‘last’, }.
- .sqlize(sorts) ⇒ Object
Class Method Details
.distinct_sorts(sorts) ⇒ Object
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/miscellany/sort_lang.rb', line 25 def self.distinct_sorts(sorts) seen_sorts = Set.new # Only include each sort key/"column" once sorts.select do |sort| sid = sort[:key] || sort[:column] next true unless sid.present? if seen_sorts.include?(sid) false else seen_sorts << sid true end end end |
.normalize_sort(sort, key: nil) ⇒ Object
Normalized Format:
key: string,
column: string,
order: 'DESC' | 'ASC',
force_order?: boolean, # Prevent overriding order
nulls?: 'high' | 'low' | 'first' | 'last',
11 12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/miscellany/sort_lang.rb', line 11 def self.normalize_sort(sort, key: nil) sort = sort.to_s if sort.is_a?(Symbol) if sort.is_a?(Array) sort = { **normalize_sort(sort[0]), **(sort[1] || {}) } elsif sort.is_a?(String) m = sort.match(/^([\w\.]+)(?: (ASC|DESC)(!?))?$/) sort = { column: m[1], order: m[2], force_order: m[3].present? }.compact elsif sort.is_a?(Proc) sort = { column: sort } end sort[:key] = key || sort[:column] sort.compact end |
.sqlize(sorts) ⇒ Object
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/miscellany/sort_lang.rb', line 42 def self.sqlize(sorts) sorts.map do |sort| order = sort[:order] || 'ASC' if sort[:column].is_a?(Proc) sort[:column].call(order) else desired_nulls = (sort[:nulls] || :low).to_s.downcase.to_sym nulls = case desired_nulls when :last 'LAST' when :first 'FIRST' else (desired_nulls == :high) == (order.to_s.upcase == 'DESC') ? 'FIRST' : 'LAST' end "#{sort[:column]} #{order} NULLS #{nulls}" end end.join(', ') end |