class Bmg::Sequel::Translator
Attributes
sequel_db[R]
Public Class Methods
new(sequel_db)
click to toggle source
# File lib/bmg/sequel/translator.rb, line 6 def initialize(sequel_db) @sequel_db = sequel_db end
Public Instance Methods
on_column_name(sexpr)
click to toggle source
# File lib/bmg/sequel/translator.rb, line 110 def on_column_name(sexpr) ::Sequel.expr(sexpr.last.to_sym) end
on_from_clause(sexpr)
click to toggle source
# File lib/bmg/sequel/translator.rb, line 114 def on_from_clause(sexpr) orderer = Sql::Support::FromClauseOrderer.new ordering = orderer.call(sexpr) ordering.inject(nil) do |ds,(kind,table,on)| if ds.nil? dataset(apply(table)) elsif kind == :cross_join ds.cross_join(apply(table)) elsif kind == :inner_join options = { qualify: false, table_alias: false } ds.join_table(:inner, apply(table), nil, options){|*args| compile_predicate(on) } elsif kind == :left_join options = { qualify: false, table_alias: false } ds.join_table(:left, apply(table), nil, options){|*args| compile_predicate(on) } else raise IllegalArgumentError, "Unrecognized from clause: `#{sexpr}`" end end end
on_func_call(sexpr)
click to toggle source
# File lib/bmg/sequel/translator.rb, line 80 def on_func_call(sexpr) case sexpr.func_name when :cast to_cast = apply(sexpr.func_args.first) type = sexpr.func_args.last.last to_cast.cast(type) else args = sexpr.func_args.map{|fa| apply(fa) } ::Sequel.function(sexpr.func_name, *args) end end
on_group_by_clause(sexpr)
click to toggle source
# File lib/bmg/sequel/translator.rb, line 160 def on_group_by_clause(sexpr) return nil unless sexpr.size > 1 sexpr.sexpr_body.map{|c| apply(c)} end
on_limit_clause(sexpr)
click to toggle source
# File lib/bmg/sequel/translator.rb, line 173 def on_limit_clause(sexpr) sexpr.last end
on_native_table_as(sexpr)
click to toggle source
# File lib/bmg/sequel/translator.rb, line 142 def on_native_table_as(sexpr) sexpr[1].from_self(:alias => sexpr.as_name) end
on_offset_clause(sexpr)
click to toggle source
# File lib/bmg/sequel/translator.rb, line 177 def on_offset_clause(sexpr) sexpr.last end
on_order_by_clause(sexpr)
click to toggle source
# File lib/bmg/sequel/translator.rb, line 165 def on_order_by_clause(sexpr) sexpr.sexpr_body.map{|c| apply(c)} end
on_order_by_term(sexpr)
click to toggle source
# File lib/bmg/sequel/translator.rb, line 169 def on_order_by_term(sexpr) ::Sequel.send(sexpr.direction, apply(sexpr.qualified_name)) end
on_qualified_name(sexpr)
click to toggle source
# File lib/bmg/sequel/translator.rb, line 106 def on_qualified_name(sexpr) apply(sexpr.last).qualify(sexpr.qualifier) end
on_select_exp(sexpr)
click to toggle source
# File lib/bmg/sequel/translator.rb, line 39 def on_select_exp(sexpr) dataset = sequel_db.select(1) dataset = apply(sexpr.from_clause) if sexpr.from_clause # selection = apply(sexpr.select_list) predicate = compile_predicate(sexpr.predicate) if sexpr.predicate grouping = apply(sexpr.group_by_clause) if sexpr.group_by_clause 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.group(*grouping) if grouping dataset = dataset.order_by(*order) if order dataset = dataset.limit(limit, offset == 0 ? nil : offset) if limit or offset dataset end
on_select_item(sexpr)
click to toggle source
# File lib/bmg/sequel/translator.rb, line 67 def on_select_item(sexpr) left = apply(sexpr.left) right = apply(sexpr.right) case kind = sexpr.left.first when :qualified_name left.column == right.value ? left : ::Sequel.as(left, right) when :literal, :summarizer, :func_call ::Sequel.as(left, right) else raise NotImplementedError, "Unexpected select item `#{kind}`" end end
on_select_list(sexpr)
click to toggle source
# File lib/bmg/sequel/translator.rb, line 59 def on_select_list(sexpr) sexpr.sexpr_body.map{|c| apply(c) } end
on_select_star(sexpr)
click to toggle source
# File lib/bmg/sequel/translator.rb, line 63 def on_select_star(sexpr) ::Sequel.lit('*') end
on_set_operator(sexpr)
click to toggle source
# File lib/bmg/sequel/translator.rb, line 30 def on_set_operator(sexpr) sexpr.tail_exprs.inject(apply(sexpr.head_expr)) do |left,right| left.send(sexpr.first, apply(right), all: sexpr.all?, from_self: false) end end
on_subquery_as(sexpr)
click to toggle source
# File lib/bmg/sequel/translator.rb, line 156 def on_subquery_as(sexpr) ::Sequel.as(apply(sexpr.subquery), ::Sequel.identifier(sexpr.as_name)) end
on_summarizer(sexpr)
click to toggle source
# File lib/bmg/sequel/translator.rb, line 92 def on_summarizer(sexpr) func, distinct = if sexpr.summary_func == :distinct_count [:count, true] else [sexpr.summary_func, false] end f = if sexpr.summary_expr ::Sequel.function(func, apply(sexpr.summary_expr)) else ::Sequel.function(func).* end distinct ? f.distinct : f end
on_table_as(sexpr)
click to toggle source
# File lib/bmg/sequel/translator.rb, line 146 def on_table_as(sexpr) table_name = case sexpr.table_name when String, Symbol then ::Sequel.expr(sexpr.table_name.to_sym) when ::Sequel::SQL::QualifiedIdentifier then sexpr.table_name else raise ArgumentError, "Invalid table name `#{sexpr.table_name}`" end ::Sequel.as(table_name, ::Sequel.identifier(sexpr.as_name)) end
on_table_name(sexpr)
click to toggle source
# File lib/bmg/sequel/translator.rb, line 138 def on_table_name(sexpr) ::Sequel.expr(sexpr.last.to_sym) end
on_with_exp(sexpr)
click to toggle source
# File lib/bmg/sequel/translator.rb, line 11 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)
click to toggle source
# File lib/bmg/sequel/translator.rb, line 23 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
Private Instance Methods
compile_predicate(predicate)
click to toggle source
# File lib/bmg/sequel/translator.rb, line 188 def compile_predicate(predicate) PredicateTranslator.new(self).call(predicate) end
dataset(expr)
click to toggle source
# File lib/bmg/sequel/translator.rb, line 183 def dataset(expr) return expr if ::Sequel::Dataset===expr sequel_db[expr] end
on_exists(sexpr)
click to toggle source
# File lib/bmg/sequel/translator.rb, line 205 def on_exists(sexpr) @parent.apply(sexpr.last).exists end