Class: Scim2::Filter::ArelHandler

Inherits:
Object
  • Object
show all
Defined in:
lib/scim2/filter/arel_handler.rb

Overview

Note:

Nested filters (e.g. ‘emails[type eq “work”]` are not supported at this time and will result in an ArgumentError

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.

Examples:

# userName sw "J"

mapping = {
  userName: User.arel_table[:name],
}

# "users"."name" LIKE 'J%'
# urn:ietf:params:scim:schemas:core:2.0:User:userType ne "Employee" and not (emails.value co "example.com" or emails.value co "example.org")

mapping = {
  userType: User.arel_table[:type],
  emails: {
    value: User.arel_table[:email],
  },
}

# "users"."type" != 'Employee' AND NOT ("users"."email" LIKE '%example.com' OR "users"."email" LIKE '%example.org%')

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(arel_mapping) ⇒ ArelHandler

Returns a new instance of ArelHandler.



36
37
38
# File 'lib/scim2/filter/arel_handler.rb', line 36

def initialize(arel_mapping)
  @arel_mapping = arel_mapping
end

Instance Attribute Details

#arel_mappingObject (readonly)

Returns the value of attribute arel_mapping.



34
35
36
# File 'lib/scim2/filter/arel_handler.rb', line 34

def arel_mapping
  @arel_mapping
end

Instance Method Details

#on_attribute_filter(attribute_path, value, context:, op:, schema: nil) ⇒ Hash<Symbol, Object>

Handle basic attribute comparison filters (e.g. ‘preference.color eq “red”`)

Parameters:

  • attribute_path (Array<Symbol>)

    the attribute name(s) being filtered on, split by .

  • value (Object)

    the value being compared against

  • op (Object)

    the comparison operator (e.g. :eq)

  • schema (String) (defaults to: nil)

    schema namespace of the attribute

Returns:

  • (Hash<Symbol, Object>)


53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/scim2/filter/arel_handler.rb', line 53

def on_attribute_filter(attribute_path, value, context:, op:, schema: nil)
  arel = lookup_arel(attribute_path)
  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)
  else
    raise Racc::ParseError, "invalid attribute operand #{op.inspect} with argument #{value.inspect}"
  end
end

#on_logical_filter(filter1, filter2, context:, op:) ⇒ Hash<Symbol, Object>

Handle logical filters (e.g. ‘name.givenName sw “D” AND title co “VP”`)

Parameters:

  • filter1 (Hash<Symbol, Object>)

    the left-hand side filter

  • filter2 (Hash<Symbol, Object>)

    the right-hand side filter

  • op (Object)

    the logical operator (e.g. AND)

Returns:

  • (Hash<Symbol, Object>)


86
87
88
89
90
91
92
93
94
95
# File 'lib/scim2/filter/arel_handler.rb', line 86

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”]`)

Parameters:

  • attribute_path (Array<Symbol>)

    the attribute name(s) being filtered on, split by .

  • filter (Hash<Symbol, Object>)

    the nested filter inside the backets

  • schema (String) (defaults to: nil)

    schema namespace of the attribute

Returns:

  • (Hash<Symbol, Object>)

Raises:

  • (ArgumentError)


102
103
104
# File 'lib/scim2/filter/arel_handler.rb', line 102

def on_nested_filter(attribute_path, filter, context:, schema: nil)
  raise ArgumentError, 'Nested attributes are not currently supported for AREL'
end

#on_not_filter(filter, context:) ⇒ Hash<Symbol, Object>

Handle NOT filters (e.g. ‘not (color eq “red”)`)

Parameters:

  • filter (Hash<Symbol, Object>)

    the internal filter being NOT’ed

Returns:

  • (Hash<Symbol, Object>)


43
44
45
# File 'lib/scim2/filter/arel_handler.rb', line 43

def on_not_filter(filter, context:)
  filter.not
end