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