Class: MSFL::Converters::Operator
- Inherits:
-
Object
- Object
- MSFL::Converters::Operator
- Includes:
- Validators::Definitions::HashKey
- Defined in:
- lib/msfl/converters/operator.rb
Constant Summary collapse
- CONVERSIONS =
Order is respected by run_conversions in otherwords run_conversions executes conversions in the order they occur in CONVERSIONS, not in the order in which they are passed into the method
conversion order is context-free
[ :implicit_between_to_explicit_recursively, :between_to_gte_lte_recursively, :implicit_and_to_explicit_recursively ]
Instance Method Summary collapse
-
#between_to_gte_lte_recursively(obj) ⇒ Object
Recursively converts all between operators to equivalent anded gte / lte it currently creates the converted operators into the implied AND format.
-
#implicit_and_to_explicit_recursively(obj, parent_key = nil) ⇒ Hash
Convert a Hash containing an implict and into an explicit and.
-
#implicit_between_to_explicit_recursively(obj, parent_key = nil) ⇒ Object
{ year: { start: 2001, end: 2005 } } => { year: { between: { start: 2001, end: 2015 } } }.
-
#run_conversions(obj, conversions_to_run = nil) ⇒ Object
Runs conversions on an object It respects the order of CONVERSIONS, not the order of elements in conversions_to_run.
Methods included from Validators::Definitions::HashKey
#all_logical_operators?, #all_operators?, #any_operators?, #binary_operators, #hash_key_operators, #logical_operators, #valid_hash_key?, #valid_hash_keys
Instance Method Details
#between_to_gte_lte_recursively(obj) ⇒ Object
Recursively converts all between operators to equivalent anded gte / lte it currently creates the converted operators into the implied AND format
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/msfl/converters/operator.rb', line 70 def between_to_gte_lte_recursively(obj) result = obj if obj.is_a? Hash obj.each do |k, v| if v.is_a?(Hash) && v.has_key?(:between) && v[:between].has_key?(:start) && v[:between].has_key?(:end) lower_bound = between_to_gte_lte_recursively v[:between][:start] upper_bound = between_to_gte_lte_recursively v[:between][:end] result[k] = { gte: lower_bound, lte: upper_bound } else result[k] = between_to_gte_lte_recursively v end end elsif obj.is_a? Types::Set result = recurse_through_set :between_to_gte_lte_recursively, obj elsif obj.is_a? Array raise ArgumentError, "#between_to_gte_lte requires that it does not contain any Arrays - its argument should preprocessed by .arrays_to_sets and .convert_keys_to_symbols" end result end |
#implicit_and_to_explicit_recursively(obj, parent_key = nil) ⇒ Hash
Convert a Hash containing an implict and into an explicit and
TYPE 1 —
{ make: "chevy", year: 2010 }
=> { and: [ { make: "chevy" }, { year: 2010 }] }
TYPE 2 —
{ year: { gte: 2010, lte: 2012 } }
=> { and: [ { year: { gte: 2010 } }, { year: { lte: 2012 } } ] }
TYPE 3 —
{ make: "chevy", year: { gte: 2010, lte: 2012 } }
=> { and: [ { make: "chevy" }, { and: [ { year: { gte: 2010 } }, { year: { lte: 2012 } } ] } ] }
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/msfl/converters/operator.rb', line 105 def implicit_and_to_explicit_recursively(obj, parent_key = nil) if obj.is_a? Hash first_key = obj.keys.first if binary_operators.include?(first_key) result = i_to_e_bin_op obj, parent_key elsif logical_operators.include?(first_key) result = i_to_e_log_op obj, parent_key else # the first key is not an operator # if there is only one key just assign the result of calling this method recursively on the value to the result for the key if obj.keys.count == 1 if obj[first_key].is_a?(Hash) result = implicit_and_to_explicit_recursively obj[first_key], first_key elsif obj[first_key].is_a? MSFL::Types::Set # When an implicit and occurs under an MSFL::Types::Set when the key for the value which is the set # is not a binary or logical operator. This doesn't happen in known current cases. # ex. => { foo: [ { bar: { gte: 1, lte: 5 } } ] } result = Hash.new result[first_key] = recurse_through_set :implicit_and_to_explicit_recursively, obj[first_key] elsif obj[first_key].is_a? Array raise ArgumentError, "#implicit_and_to_explicit requires that it does not contain any Arrays - its argument should preprocessed by .arrays_to_sets and .convert_keys_to_symbols" end else raise ArgumentError, "#implicit_and_to_explicit requires that all or none of a hash's keys be operators" if any_operators?(obj.keys) # none of the keys are operators and_array = [] obj.each do |k, v| if v.is_a? Hash and_array << implicit_and_to_explicit_recursively(v, k) else and_array << { k => v } end end result = { and: MSFL::Types::Set.new(and_array) } end end elsif obj.is_a? MSFL::Types::Set result = i_to_e_set obj, parent_key elsif obj.is_a? Array raise ArgumentError, "#implicit_and_to_explicit requires that it does not contain any Arrays - its argument should preprocessed by .arrays_to_sets and .convert_keys_to_symbols" end result ||= obj end |
#implicit_between_to_explicit_recursively(obj, parent_key = nil) ⇒ Object
{ year: { start: 2001, end: 2005 } }
=> { year: { between: { start: 2001, end: 2015 } } }
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/msfl/converters/operator.rb', line 40 def implicit_between_to_explicit_recursively(obj, parent_key = nil) if parent_key == :between # The immediately ancestor key is :between, so don't do anything special with :start and :end result = Hash.new obj.each do |k, v| result[k] = implicit_between_to_explicit_recursively(v) end elsif obj.is_a? Hash # if the hash has two keys :start and :end, nest it inside a between and recurse on the values if obj.has_key?(:start) && obj.has_key?(:end) result = { between: { start: implicit_between_to_explicit_recursively(obj[:start]), end: implicit_between_to_explicit_recursively(obj[:end]) } } else result = Hash.new obj.each do |k, v| result[k] = implicit_between_to_explicit_recursively(v, k) end end elsif obj.is_a? Types::Set result = recurse_through_set :implicit_between_to_explicit_recursively, obj elsif obj.is_a? Array raise ArgumentError, "#implicit_between_to_explicit_recursively requires that it does not contain any Arrays - its argument should preprocessed by .arrays_to_sets and .convert_keys_to_symbols" end result ||= obj end |
#run_conversions(obj, conversions_to_run = nil) ⇒ Object
Runs conversions on an object It respects the order of CONVERSIONS, not the order of elements in conversions_to_run
23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/msfl/converters/operator.rb', line 23 def run_conversions(obj, conversions_to_run = nil) conversions_to_run ||= CONVERSIONS unless all_conversions?(conversions_to_run) raise ArgumentError, "#run_conversions second argument is optional, if specified it must be an Array of Symbols" end result = obj CONVERSIONS.each do |conv| # In the order that items are in CONVERSIONS run all of the conversions_to_run result = send(conv, result) if conversions_to_run.include?(conv) end result end |