Class: Alf::Sequel::Translator

Inherits:
Sexpr::Processor
  • Object
show all
Defined in:
lib/alf/sequel/translator.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(connection) ⇒ Translator

Returns a new instance of Translator.



5
6
7
# File 'lib/alf/sequel/translator.rb', line 5

def initialize(connection)
  @connection = connection
end

Instance Attribute Details

#connectionObject (readonly)

Returns the value of attribute connection.



8
9
10
# File 'lib/alf/sequel/translator.rb', line 8

def connection
  @connection
end

Instance Method Details

#on_and(sexpr) ⇒ Object



176
177
178
179
# File 'lib/alf/sequel/translator.rb', line 176

def on_and(sexpr)
  body = sexpr.sexpr_body
  body[1..-1].inject(apply(body.first)){|f,t| f & apply(t) }
end

#on_column_name(sexpr) ⇒ Object



72
73
74
# File 'lib/alf/sequel/translator.rb', line 72

def on_column_name(sexpr)
  ::Sequel.expr(sexpr.last.to_sym)
end

#on_contradiction(sexpr) ⇒ Object



135
136
137
# File 'lib/alf/sequel/translator.rb', line 135

def on_contradiction(sexpr)
  ::Sequel::SQL::BooleanConstant.new(false)
end

#on_cross_join(sexpr) ⇒ Object



84
85
86
87
# File 'lib/alf/sequel/translator.rb', line 84

def on_cross_join(sexpr)
  left, right = apply(sexpr.left), apply(sexpr.right)
  dataset(left).cross_join(right)
end

#on_dyadic_comp(sexpr) ⇒ Object Also known as: on_lt, on_lte, on_gt, on_gte



153
154
155
156
# File 'lib/alf/sequel/translator.rb', line 153

def on_dyadic_comp(sexpr)
  left, right = apply(sexpr.left), apply(sexpr.right)
  left.send(sexpr.operator_symbol, right)
end

#on_eq(sexpr) ⇒ Object



143
144
145
146
# File 'lib/alf/sequel/translator.rb', line 143

def on_eq(sexpr)
  left, right = apply(sexpr.left), apply(sexpr.right)
  ::Sequel.expr(left => right)
end

#on_exists(sexpr) ⇒ Object



168
169
170
# File 'lib/alf/sequel/translator.rb', line 168

def on_exists(sexpr)
  apply(sexpr.last).exists
end

#on_from_clause(sexpr) ⇒ Object



76
77
78
# File 'lib/alf/sequel/translator.rb', line 76

def on_from_clause(sexpr)
  apply(sexpr.table_spec)
end

#on_identifier(sexpr) ⇒ Object

Predicate



123
124
125
# File 'lib/alf/sequel/translator.rb', line 123

def on_identifier(sexpr)
  ::Sequel.identifier(sexpr.last)
end

#on_in(sexpr) ⇒ Object



162
163
164
165
166
# File 'lib/alf/sequel/translator.rb', line 162

def on_in(sexpr)
  left, right = apply(sexpr.identifier), sexpr.last
  right = apply(right) if sexpr.subquery?
  ::Sequel.expr(left => right)
end

#on_inner_join(sexpr) ⇒ Object



89
90
91
92
93
94
95
# File 'lib/alf/sequel/translator.rb', line 89

def on_inner_join(sexpr)
  left, right = apply(sexpr.left), apply(sexpr.right)
  options = {qualify: false, table_alias: false}
  dataset(left).join_table(:inner, right, nil, options){|*args|
    apply(sexpr.predicate)
  }
end

#on_limit_clause(sexpr) ⇒ Object



113
114
115
# File 'lib/alf/sequel/translator.rb', line 113

def on_limit_clause(sexpr)
  sexpr.last
end

#on_literal(sexpr) ⇒ Object



139
140
141
# File 'lib/alf/sequel/translator.rb', line 139

def on_literal(sexpr)
  sexpr.last.nil? ? nil : ::Sequel.expr(sexpr.last)
end

#on_neq(sexpr) ⇒ Object



148
149
150
151
# File 'lib/alf/sequel/translator.rb', line 148

def on_neq(sexpr)
  left, right = apply(sexpr.left), apply(sexpr.right)
  ~::Sequel.expr(left => right)
end

#on_not(sexpr) ⇒ Object



172
173
174
# File 'lib/alf/sequel/translator.rb', line 172

def on_not(sexpr)
  ~apply(sexpr.last)
end

#on_offset_clause(sexpr) ⇒ Object



117
118
119
# File 'lib/alf/sequel/translator.rb', line 117

def on_offset_clause(sexpr)
  sexpr.last
end

#on_or(sexpr) ⇒ Object



181
182
183
184
# File 'lib/alf/sequel/translator.rb', line 181

def on_or(sexpr)
  body = sexpr.sexpr_body
  body[1..-1].inject(apply(body.first)){|f,t| f | apply(t) }
end

#on_order_by_clause(sexpr) ⇒ Object



105
106
107
# File 'lib/alf/sequel/translator.rb', line 105

def on_order_by_clause(sexpr)
  sexpr.sexpr_body.map{|c| apply(c)}
end

#on_order_by_term(sexpr) ⇒ Object



109
110
111
# File 'lib/alf/sequel/translator.rb', line 109

def on_order_by_term(sexpr)
  ::Sequel.send(sexpr.direction, apply(sexpr.qualified_name))
end

#on_qualified_identifier(sexpr) ⇒ Object



127
128
129
# File 'lib/alf/sequel/translator.rb', line 127

def on_qualified_identifier(sexpr)
  ::Sequel.as(sexpr.qualifier, sexpr.name)
end

#on_qualified_name(sexpr) ⇒ Object



68
69
70
# File 'lib/alf/sequel/translator.rb', line 68

def on_qualified_name(sexpr)
  apply(sexpr.last).qualify(sexpr.qualifier)
end

#on_select_exp(sexpr) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/alf/sequel/translator.rb', line 38

def on_select_exp(sexpr)
  dataset   = sequel_db.select(1)
  dataset   = dataset(apply(sexpr.from_clause)) if sexpr.from_clause
  #
  selection = apply(sexpr.select_list)
  predicate = apply(sexpr.predicate)       if sexpr.predicate
  order     = apply(sexpr.order_by_clause) if sexpr.order_by_clause
  limit     = apply(sexpr.limit_clause)    if sexpr.limit_clause
  offset    = apply(sexpr.offset_clause)   if sexpr.offset_clause
  #
  dataset   = dataset.select(*selection)
  dataset   = dataset.distinct             if sexpr.distinct?
  dataset   = dataset.where(predicate)     if predicate
  dataset   = dataset.order_by(*order)     if order
  dataset   = dataset.limit(limit, offset) if limit or offset
  dataset
end

#on_select_item(sexpr) ⇒ Object



64
65
66
# File 'lib/alf/sequel/translator.rb', line 64

def on_select_item(sexpr)
  ::Sequel.as(apply(sexpr.left), apply(sexpr.right))
end

#on_select_list(sexpr) ⇒ Object



56
57
58
# File 'lib/alf/sequel/translator.rb', line 56

def on_select_list(sexpr)
  sexpr.sexpr_body.map{|c| apply(c) }
end

#on_select_star(sexpr) ⇒ Object



60
61
62
# File 'lib/alf/sequel/translator.rb', line 60

def on_select_star(sexpr)
  ::Sequel.lit('*')
end

#on_set_operator(sexpr) ⇒ Object Also known as: on_union, on_intersect, on_except



29
30
31
32
33
# File 'lib/alf/sequel/translator.rb', line 29

def on_set_operator(sexpr)
  left, right = apply(sexpr.left), apply(sexpr.right)
  left = left.from_self if sexpr.left.set_operator?
  left.send(sexpr.first, right, all: sexpr.all?, from_self: false)
end

#on_subquery_as(sexpr) ⇒ Object



101
102
103
# File 'lib/alf/sequel/translator.rb', line 101

def on_subquery_as(sexpr)
  ::Sequel.as(apply(sexpr.subquery), sexpr.as_name)
end

#on_table_as(sexpr) ⇒ Object



97
98
99
# File 'lib/alf/sequel/translator.rb', line 97

def on_table_as(sexpr)
  ::Sequel.as(sexpr.table_name.to_sym, sexpr.as_name)
end

#on_table_name(sexpr) ⇒ Object



80
81
82
# File 'lib/alf/sequel/translator.rb', line 80

def on_table_name(sexpr)
  ::Sequel.identifier(sexpr.last)
end

#on_tautology(sexpr) ⇒ Object



131
132
133
# File 'lib/alf/sequel/translator.rb', line 131

def on_tautology(sexpr)
  ::Sequel::SQL::BooleanConstant.new(true)
end

#on_with_exp(sexpr) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
# File 'lib/alf/sequel/translator.rb', line 10

def on_with_exp(sexpr)
  if sequel_db.select(1).supports_cte?
    dataset = apply(sexpr.select_exp)
    apply(sexpr.with_spec).each_pair do |name,subquery|
      dataset = dataset.with(name, subquery)
    end
    dataset
  else
    apply(Sql::Processor::Flatten.new(Sql::Builder.new).call(sexpr))
  end
end

#on_with_spec(sexpr) ⇒ Object



22
23
24
25
26
27
# File 'lib/alf/sequel/translator.rb', line 22

def on_with_spec(sexpr)
  sexpr.each_with_object({}){|child,hash|
    next if child == :with_spec
    hash[apply(child.table_name)] = apply(child.subquery)
  }
end