main
1# frozen_string_literal: true
2
3module Scim
4 class Visitor < Scim::Kit::V2::Filter::Visitor
5 include Varkon
6
7 def initialize(clazz, mapper = {})
8 @clazz = clazz
9 @mapper = mapper
10 end
11
12 protected
13
14 def visit_and(node)
15 visit(node.left).merge(visit(node.right))
16 end
17
18 def visit_or(node)
19 visit(node.left).or(visit(node.right))
20 end
21
22 def visit_equals(node)
23 query_for(node, attr_for(node) => node.value)
24 end
25
26 def visit_not_equals(node)
27 if node.not?
28 @clazz.where(attr_for(node) => node.value)
29 else
30 @clazz.where.not(attr_for(node) => node.value)
31 end
32 end
33
34 def visit_contains(node)
35 query_for(
36 node,
37 "#{attr_for(node)} LIKE ?",
38 "%#{escape_sql_wildcards(node.value)}%"
39 )
40 end
41
42 def visit_starts_with(node)
43 query_for(
44 node,
45 "#{attr_for(node)} LIKE ?",
46 "#{escape_sql_wildcards(node.value)}%"
47 )
48 end
49
50 def visit_ends_with(node)
51 query_for(
52 node,
53 "#{attr_for(node)} LIKE ?",
54 "%#{escape_sql_wildcards(node.value)}"
55 )
56 end
57
58 def visit_greater_than(node)
59 query_for(node, "#{attr_for(node)} > ?", cast_value_from(node))
60 end
61
62 def visit_greater_than_equals(node)
63 query_for(node, "#{attr_for(node)} >= ?", cast_value_from(node))
64 end
65
66 def visit_less_than(node)
67 query_for(node, "#{attr_for(node)} < ?", cast_value_from(node))
68 end
69
70 def visit_less_than_equals(node)
71 query_for(node, "#{attr_for(node)} <= ?", cast_value_from(node))
72 end
73
74 def visit_presence(node)
75 if node.not?
76 @clazz.where(attr_for(node) => nil)
77 else
78 @clazz.where.not(attr_for(node) => nil)
79 end
80 end
81
82 def visit_unknown(_node)
83 @clazz.none
84 end
85
86 def cast_value_from(node)
87 case @clazz.columns_hash[attr_for(node).to_s].type
88 when :datetime
89 DateTime.parse(node.value).utc
90 else
91 node.value.to_s
92 end
93 end
94
95 def attr_for(node)
96 @mapper.fetch(node.attribute, node.attribute)
97 end
98
99 def query_for(node, *conditions)
100 node.not? ? @clazz.where.not(*conditions) : @clazz.where(*conditions)
101 end
102 end
103end