Skip to content

Instantly share code, notes, and snippets.

@ruliana
Last active December 25, 2015 01:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ruliana/6899514 to your computer and use it in GitHub Desktop.
Save ruliana/6899514 to your computer and use it in GitHub Desktop.
class Synthetizer
def initialize
@heap = []
end
def push(element)
@heap << element
end
def synth(sexp)
head, *tail = *sexp
case head
when Symbol
send("synth_#{head}", tail)
when Array
synth(head)
synth(tail)
end
@heap.join(' ')
end
def synth_select(sexp)
push 'SELECT'
if sexp.empty?
push '*'
else
push sexp.join(', ')
end
end
def synth_from(sexp)
return if sexp.empty?
push 'FROM'
push sexp.first
synth_join(sexp.drop(1))
end
def synth_join(sexp)
return if sexp.empty?
push 'INNER JOIN'
push sexp.first
push 'ON'
synth_cond(sexp.drop(1))
synth_join(sexp.drop(2))
end
def synth_where(sexp)
return if sexp.empty?
push 'WHERE'
synth_cond(sexp)
end
def synth_cond(sexp)
push sexp and return unless sexp.is_a? Array
return if sexp.empty?
head, *tail = *sexp
case head
when :'='
left, right = *tail
synth_cond(left)
push '='
synth_cond(right)
when :and
left, right = *tail
synth_cond(left)
push 'AND'
synth_cond(right)
when Array
synth_cond(head)
synth_cond(tail)
end
end
end
sql1 = [[:select, 'campo1', 'campo2'], [:from, 'tabela1']]
sql2 = [[:select],
[:from, 'tabela1',
'tabela2', [:'=', 'id', 'tabela1_id']],
[:where, [:and, [:'=', 'campo1', 5], [:'=', 'campo2', 'campo1']]]]
sql3 = [[:select, 'campo1'], [:from, 'tabela1',
'tabela2', [:'=', 'tabela1.id', 'tabela1_id'],
'tabela3', [:'=', 'tabela2.id', 'tabela2_id'],
'tabela4', [:'=', 'tabela1.id', 'tabela3_id']]]
puts Synthetizer.new.synth(sql1)
puts Synthetizer.new.synth(sql2)
puts Synthetizer.new.synth(sql3)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment