Skip to content

Instantly share code, notes, and snippets.

@tenderlove
Created March 7, 2013 19:03
Show Gist options
  • Save tenderlove/5110775 to your computer and use it in GitHub Desktop.
Save tenderlove/5110775 to your computer and use it in GitHub Desktop.

Commandline output

$ ruby treetoar.rb 
SELECT "topics".* FROM "topics"  WHERE "topics"."id" = 1
Topic.where(id: 1)
SELECT "topics".* FROM "topics"  WHERE "topics"."id" IN (1, 2, 3)
Topic.where(id: [1, 2, 3])

GraphViz (x.dot)

x.dot

Program

require 'gda'
require 'active_support/core_ext/string/inflections'

class AR < GDA::Visitors::Visitor
  def accept node
    @list = []
    super
    @list.join '.'
  end

  def visit_GDA_Nodes_From node
    @list << node.targets.map { |n|
      n.table_name.gsub(/^"|"$/, '').singularize
    }.first.capitalize
  end

  def visit_GDA_Nodes_Operation node
    case node.operator
    when 'IN'
      column = split(node.operands.first.value).last
      value  = node.operands.drop(1).map { |e| e.value }.join(', ')
      @list << "where(#{column}: [#{value}])"
    when '='
      column = split(node.operands.first.value).last
      value  = node.operands.last.value
      @list << "where(#{column}: #{value})"
    else
      raise NotImplementedError, node.operator
    end
  end

  private

  def split str
    GDA.sql_identifier_split(str).map { |s| s.gsub(/^"|"$/, '') }
  end
end

viz = AR.new
parser = GDA::SQL::Parser.new

[
  'SELECT "topics".* FROM "topics"  WHERE "topics"."id" = 1',
  'SELECT "topics".* FROM "topics"  WHERE "topics"."id" IN (1, 2, 3)',
].each do |select|
  puts select
  stmt = parser.parse select
  File.open('x.dot', 'w') { |f| f.write stmt.ast.to_dot }
  puts viz.accept stmt.ast
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment