class Sequel::ToDot

Constants

TO_DOT_OPTIONS

The option keys that should be included in the dot output.

Public Class Methods

new(ds) click to toggle source

Given a Dataset, parse the internal structure to generate a dataset visualization.

   # File lib/sequel/extensions/to_dot.rb
37 def initialize(ds)
38   @i = 0
39   @stack = [@i]
40   @dot = ["digraph G {", "0 [label=\"self\"];"]
41   v(ds, "")
42   @dot << "}"
43 end
output(ds) click to toggle source

Given a Dataset, return a string in dot format that will generate a visualization of the dataset.

   # File lib/sequel/extensions/to_dot.rb
31 def self.output(ds)
32   new(ds).output
33 end

Public Instance Methods

output() click to toggle source

Output the dataset visualization as a string in dot format.

   # File lib/sequel/extensions/to_dot.rb
46 def output
47   @dot.join("\n")
48 end

Private Instance Methods

dot(label, j=nil) click to toggle source

Add an entry to the dot output with the given label. If j is given, it is used directly as the node or transition. Otherwise a node is created for the current object.

   # File lib/sequel/extensions/to_dot.rb
55 def dot(label, j=nil)
56   @dot << "#{j||@i} [label=#{label.to_s.inspect}];"
57 end
v(e, l) click to toggle source

Recursive method that parses all of Sequel's internal datastructures, adding the appropriate nodes and transitions to the internal dot structure.

    # File lib/sequel/extensions/to_dot.rb
 62 def v(e, l)
 63   @i += 1
 64   dot(l, "#{@stack.last} -> #{@i}") if l
 65   @stack.push(@i)
 66   case e
 67   when LiteralString
 68     dot "Sequel.lit(#{e.to_s.inspect})"
 69   when Symbol, Numeric, String, Class, TrueClass, FalseClass, NilClass
 70     dot e.inspect
 71   when Array
 72     dot "Array"
 73     e.each_with_index do |val, j|
 74       v(val, j)
 75     end
 76   when Hash
 77     dot "Hash"
 78     e.each do |k, val|
 79       v(val, k)
 80     end
 81   when SQL::ComplexExpression 
 82     dot "ComplexExpression: #{e.op}"
 83     e.args.each_with_index do |val, j|
 84       v(val, j)
 85     end
 86   when SQL::Identifier
 87     dot "Identifier"
 88     v(e.value, :value)
 89   when SQL::QualifiedIdentifier
 90     dot "QualifiedIdentifier"
 91     v(e.table, :table)
 92     v(e.column, :column)
 93   when SQL::OrderedExpression
 94     dot "OrderedExpression: #{e.descending ? :DESC : :ASC}#{" NULLS #{e.nulls.to_s.upcase}" if e.nulls}"
 95     v(e.expression, :expression)
 96   when SQL::AliasedExpression
 97     dot "AliasedExpression"
 98     v(e.expression, :expression)
 99     v(e.alias, :alias)
100     v(e.columns, :columns) if e.columns
101   when SQL::CaseExpression
102     dot "CaseExpression"
103     v(e.expression, :expression) if e.expression
104     v(e.conditions, :conditions)
105     v(e.default, :default)
106   when SQL::Cast
107     dot "Cast"
108     v(e.expr, :expr)
109     v(e.type, :type)
110   when SQL::Function
111     dot "Function: #{e.name}"
112     e.args.each_with_index do |val, j|
113       v(val, j)
114     end
115     v(e.args, :args)
116     v(e.opts, :opts)
117   when SQL::Subscript 
118     dot "Subscript"
119     v(e.f, :f)
120     v(e.sub, :sub)
121   when SQL::Window
122     dot "Window"
123     v(e.opts, :opts)
124   when SQL::PlaceholderLiteralString
125     str = e.str
126     str = "(#{str})" if e.parens
127     dot "PlaceholderLiteralString: #{str.inspect}"
128     v(e.args, :args)
129   when SQL::JoinClause
130     str = "#{e.join_type.to_s.upcase} JOIN".dup
131     if e.is_a?(SQL::JoinOnClause)
132       str << " ON"
133     elsif e.is_a?(SQL::JoinUsingClause)
134       str << " USING"
135     end
136     dot str
137     v(e.table_expr, :table)
138     if e.is_a?(SQL::JoinOnClause)
139       v(e.on, :on) 
140     elsif e.is_a?(SQL::JoinUsingClause)
141       v(e.using, :using) 
142     end
143   when Dataset
144     dot "Dataset"
145     TO_DOT_OPTIONS.each do |k|
146       if val = e.opts[k]
147         v(val, k.to_s) 
148       end
149     end
150   else
151     dot "Unhandled: #{e.inspect}"
152   end
153   @stack.pop
154 end