Class: Kasket::Visitor
- Inherits:
-
Arel::Visitors::Visitor
- Object
- Arel::Visitors::Visitor
- Kasket::Visitor
show all
- Defined in:
- lib/kasket/visitor.rb
Instance Method Summary
collapse
Constructor Details
#initialize(model_class, binds) ⇒ Visitor
Returns a new instance of Visitor.
5
6
7
8
|
# File 'lib/kasket/visitor.rb', line 5
def initialize(model_class, binds)
@model_class = model_class
@binds = binds.dup
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, &block) ⇒ Object
130
131
132
133
|
# File 'lib/kasket/visitor.rb', line 130
def method_missing(name, *args, &block)
return :unsupported if name.to_s.start_with?('visit_')
super
end
|
Instance Method Details
#accept(node) ⇒ Object
10
11
12
13
|
# File 'lib/kasket/visitor.rb', line 10
def accept(node)
self.last_column = nil
super
end
|
#column_for(name) ⇒ Object
23
24
25
|
# File 'lib/kasket/visitor.rb', line 23
def column_for(name)
@model_class.columns_hash[name.to_s]
end
|
#last_column ⇒ Object
19
20
21
|
# File 'lib/kasket/visitor.rb', line 19
def last_column
Thread.current[:arel_visitors_to_sql_last_column]
end
|
#last_column=(col) ⇒ Object
15
16
17
|
# File 'lib/kasket/visitor.rb', line 15
def last_column=(col)
Thread.current[:arel_visitors_to_sql_last_column] = col
end
|
#literal(node) ⇒ Object
Also known as:
visit_String, visit_Fixnum, visit_TrueClass, visit_FalseClass, visit_Arel_Nodes_SqlLiteral
101
102
103
104
105
106
107
108
|
# File 'lib/kasket/visitor.rb', line 101
def literal(node)
if node == '?'
column, value = @binds.shift
value.to_s
else
node.to_s
end
end
|
#quoted(node) ⇒ Object
TODO: We are actually not using this?
120
121
122
|
# File 'lib/kasket/visitor.rb', line 120
def quoted(node)
@model_class.connection.quote(node, self.last_column)
end
|
#respond_to?(name, include_private = false) ⇒ Boolean
135
136
137
|
# File 'lib/kasket/visitor.rb', line 135
def respond_to?(name, include_private = false)
return super || name.to_s.start_with?('visit_')
end
|
#visit_Arel_Attributes_Attribute(node) ⇒ Object
96
97
98
99
|
# File 'lib/kasket/visitor.rb', line 96
def visit_Arel_Attributes_Attribute(node)
self.last_column = column_for(node.name)
node.name.to_sym
end
|
#visit_Arel_Nodes_And(node) ⇒ Object
77
78
79
80
81
82
|
# File 'lib/kasket/visitor.rb', line 77
def visit_Arel_Nodes_And(node)
attributes = node.children.map { |child| visit(child) }
return :unsupported if attributes.include?(:unsupported)
attributes.sort! { |pair1, pair2| pair1[0].to_s <=> pair2[0].to_s }
{ :attributes => attributes }
end
|
#visit_Arel_Nodes_BindParam(x) ⇒ Object
111
112
113
|
# File 'lib/kasket/visitor.rb', line 111
def visit_Arel_Nodes_BindParam(x)
@binds.shift[1]
end
|
#visit_Arel_Nodes_Equality(node) ⇒ Object
91
92
93
94
|
# File 'lib/kasket/visitor.rb', line 91
def visit_Arel_Nodes_Equality(node)
right = node.right
[visit(node.left), right ? visit(right) : nil]
end
|
#visit_Arel_Nodes_In(node) ⇒ Object
84
85
86
87
88
89
|
# File 'lib/kasket/visitor.rb', line 84
def visit_Arel_Nodes_In(node)
left = visit(node.left)
return :unsupported if left != :id
[left, visit(node.right)]
end
|
#visit_Arel_Nodes_JoinSource(node) ⇒ Object
67
68
69
70
71
|
# File 'lib/kasket/visitor.rb', line 67
def visit_Arel_Nodes_JoinSource(node)
return :unsupported if !node.left || node.right.any?
return :unsupported if !node.left.is_a?(Arel::Table)
visit(node.left)
end
|
#visit_Arel_Nodes_Limit(node) ⇒ Object
63
64
65
|
# File 'lib/kasket/visitor.rb', line 63
def visit_Arel_Nodes_Limit(node)
{:limit => node.value.to_i}
end
|
#visit_Arel_Nodes_SelectCore(node) ⇒ Object
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
# File 'lib/kasket/visitor.rb', line 45
def visit_Arel_Nodes_SelectCore(node)
return :unsupported if node.groups.any?
return :unsupported if node.having
return :unsupported if !AR30 && node.set_quantifier
return :unsupported if !AR30 && (!node.source || node.source.empty?)
return :unsupported if node.projections.size != 1
select = node.projections[0]
select = select.name if select.respond_to?(:name)
return :unsupported if select != '*'
parts = [visit(node.source)]
parts += node.wheres.map {|where| visit(where) }
parts.include?(:unsupported) ? :unsupported : parts
end
|
#visit_Arel_Nodes_SelectStatement(node) ⇒ Object
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
# File 'lib/kasket/visitor.rb', line 27
def visit_Arel_Nodes_SelectStatement(node)
return :unsupported if !AR30 && node.with
return :unsupported if node.offset
return :unsupported if node.lock
return :unsupported if node.orders.any?
return :unsupported if node.cores.size != 1
query = visit_Arel_Nodes_SelectCore(node.cores[0])
return query if query == :unsupported
query = query.inject({}) do |memo, item|
memo.merge(item)
end
query.merge!(visit(node.limit)) if node.limit
query
end
|
#visit_Arel_Table(node) ⇒ Object
73
74
75
|
# File 'lib/kasket/visitor.rb', line 73
def visit_Arel_Table(node)
{:from => node.name}
end
|
#visit_Array(node) ⇒ Object
115
116
117
|
# File 'lib/kasket/visitor.rb', line 115
def visit_Array(node)
node.map {|value| quoted(value) }
end
|