Class: Scim2::Filter::ArelHandler
- Inherits:
-
Object
- Object
- Scim2::Filter::ArelHandler
- Defined in:
- lib/scim2/filter/arel_handler.rb
Overview
Implementation of parser handler which translates SCIM 2.0 filters into AREL. In order to do this, instances of this class will need to be passed the mapping of attribute names to columns/AREL.
Instance Attribute Summary collapse
-
#arel_mapping ⇒ Object
readonly
Returns the value of attribute arel_mapping.
Instance Method Summary collapse
- #apply_arel_operation(arel, op, value) ⇒ Object protected
-
#before_nested_filter(*_ignored) ⇒ Object
Begins capturing nested filter conditions inside a SimpleHandler.
-
#initialize(arel_mapping) ⇒ ArelHandler
constructor
A new instance of ArelHandler.
-
#lookup_arel(attribute_path) ⇒ Object
protected
Looks up the arel object from the mapping according to the given attribute path.
-
#on_attribute_filter(attribute_path, value, context:, op:, schema: nil) ⇒ Hash<Symbol, Object>
Handle basic attribute comparison filters (e.g.
preference.color eq "red"
). -
#on_logical_filter(filter1, filter2, context:, op:) ⇒ Hash<Symbol, Object>
Handle logical filters (e.g.
name.givenName sw "D" AND title co "VP"
). -
#on_nested_filter(attribute_path, filter, context:, schema: nil) ⇒ Hash<Symbol, Object>
Handle nested filters (e.g.
emails[type eq "work"]
). -
#on_not_filter(filter, context:) ⇒ Hash<Symbol, Object>
Handle NOT filters (e.g.
not (color eq "red")
). - #recursively_handle_nested_filter(arel, op, condition) ⇒ Object protected
Constructor Details
#initialize(arel_mapping) ⇒ ArelHandler
Returns a new instance of ArelHandler.
49 50 51 |
# File 'lib/scim2/filter/arel_handler.rb', line 49 def initialize(arel_mapping) @arel_mapping = arel_mapping end |
Instance Attribute Details
#arel_mapping ⇒ Object (readonly)
Returns the value of attribute arel_mapping.
47 48 49 |
# File 'lib/scim2/filter/arel_handler.rb', line 47 def arel_mapping @arel_mapping end |
Instance Method Details
#apply_arel_operation(arel, op, value) ⇒ Object (protected)
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/scim2/filter/arel_handler.rb', line 124 def apply_arel_operation(arel, op, value) case op when :eq arel.eq(value) when :ne arel.not_eq(value) when :co arel.matches("%#{value}%") when :sw arel.matches("#{value}%") when :ew arel.matches("%#{value}") when :gt arel.gt(value) when :ge arel.gteq(value) when :lt arel.lt(value) when :le arel.lteq(value) when :pr arel.not_eq(nil) end end |
#before_nested_filter(*_ignored) ⇒ Object
Begins capturing nested filter conditions inside a SimpleHandler
90 91 92 93 |
# File 'lib/scim2/filter/arel_handler.rb', line 90 def before_nested_filter(*_ignored) @nested_filter_handler = SimpleHandler.new nil end |
#lookup_arel(attribute_path) ⇒ Object (protected)
Looks up the arel object from the mapping according to the given attribute path
152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/scim2/filter/arel_handler.rb', line 152 def lookup_arel(attribute_path) arel = arel_mapping.dig(*attribute_path) case arel when NilClass raise ArgumentError, "Attribute #{attribute_path.join(',').inspect} not found in mapping" when Arel::Predications, Proc arel else raise ArgumentError, "Mapping for attribute #{attribute_path.join(',').inspect} is not a valid arel object" end end |
#on_attribute_filter(attribute_path, value, context:, op:, schema: nil) ⇒ Hash<Symbol, Object>
Handle basic attribute comparison filters (e.g. preference.color eq "red"
)
66 67 68 69 70 |
# File 'lib/scim2/filter/arel_handler.rb', line 66 def on_attribute_filter(attribute_path, value, context:, op:, schema: nil) arel = lookup_arel(attribute_path) arel = arel.call(attribute_path, op, value) if arel.is_a?(Proc) apply_arel_operation(arel, op, value) or raise Racc::ParseError, "invalid attribute operand #{op.inspect} with argument #{value.inspect}" end |
#on_logical_filter(filter1, filter2, context:, op:) ⇒ Hash<Symbol, Object>
Handle logical filters (e.g. name.givenName sw "D" AND title co "VP"
)
77 78 79 80 81 82 83 84 85 86 |
# File 'lib/scim2/filter/arel_handler.rb', line 77 def on_logical_filter(filter1, filter2, context:, op:) case op when :and filter1.and(filter2) when :or filter1.or(filter2) else raise Racc::ParseError, "invalid logical operand #{op.inspect}" end end |
#on_nested_filter(attribute_path, filter, context:, schema: nil) ⇒ Hash<Symbol, Object>
Handle nested filters (e.g. emails[type eq "work"]
)
100 101 102 103 104 |
# File 'lib/scim2/filter/arel_handler.rb', line 100 def on_nested_filter(attribute_path, filter, context:, schema: nil) @nested_filter_handler = nil arel = lookup_arel(attribute_path) recursively_handle_nested_filter(arel, *filter.first) end |
#on_not_filter(filter, context:) ⇒ Hash<Symbol, Object>
Handle NOT filters (e.g. not (color eq "red")
)
56 57 58 |
# File 'lib/scim2/filter/arel_handler.rb', line 56 def on_not_filter(filter, context:) filter.not end |
#recursively_handle_nested_filter(arel, op, condition) ⇒ Object (protected)
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/scim2/filter/arel_handler.rb', line 165 def recursively_handle_nested_filter(arel, op, condition) case op when :not recursively_handle_nested_filter(arel, *condition.first).not when :and, :or condition.map do |c| recursively_handle_nested_filter(arel, *c.first) end.reduce(op) else path, value = condition.values_at(:path, :value) arel = arel.call(path, op, value) if arel.is_a?(Proc) arel = apply_arel_operation(arel, op, value) if arel && !arel.is_a?(Arel::Nodes::Node) arel || Arel::Nodes::False.new end end |