Module: SQLDependencyGrapher
- Defined in:
- lib/sql_dep_grapher.rb
Overview
SQLDependencyGrapher allows you to visualize the query dependencies between your database tables to better understand how they actually get used. It generates a graph of the connections between tables based on joins found in a SQL query log.
To generate a graph, you run the sql_dep_graph command whiche creates a dot file that you can render with Graphviz or OmniGraffle.
Usage:
sql_dep_graph log/production.log > sql_deps.dot
dot -Tpng sql_deps.dot > sql_deps.png
Then open sql_deps.png in your favorite image viewer.
You can find Graphviz here:
And can download it for various platforms from here:
Constant Summary collapse
- VERSION =
The Version of SQLDependencyGrapher
'1.0.0'
Class Method Summary collapse
-
.build_graph(stream = ARGF) ⇒ Object
Builds a Graph from a SQL query log given to
stream
. -
.collect(stream) ⇒ Object
Returns an Array of SQL joins from
stream
. -
.count(data) ⇒ Object
Counts the number of times a join between two tables occurs.
-
.graph(data, counts) ⇒ Object
Creates a Graph of
data
usingcounts
for edge weights.
Class Method Details
.build_graph(stream = ARGF) ⇒ Object
Builds a Graph from a SQL query log given to stream
.
40 41 42 43 44 |
# File 'lib/sql_dep_grapher.rb', line 40 def self.build_graph(stream = ARGF) data = collect stream counts = count data return graph(data, counts) end |
.collect(stream) ⇒ Object
Returns an Array of SQL joins from stream
.
51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/sql_dep_grapher.rb', line 51 def self.collect(stream) data = [] stream.each_line do |line| line.grep(/FROM\s+(.*?)\s+WHERE/) do tables = $1.split(',').reject { |t| t =~ /\(/ } tables = tables.map { |t| t.split(' ').first } data << tables if tables.size > 1 end end return data end |
.count(data) ⇒ Object
Counts the number of times a join between two tables occurs. Returns a Hash of pair => count.
69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/sql_dep_grapher.rb', line 69 def self.count(data) counts = Hash.new 0 data.each do |tables| tables = tables.sort curr = tables.shift tables.each do |table| counts[[curr, table]] += 1 end end return counts end |
.graph(data, counts) ⇒ Object
Creates a Graph of data
using counts
for edge weights.
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/sql_dep_grapher.rb', line 86 def self.graph(data, counts) graph = Graph.new max_count = counts.values.max solid = Math.log10(max_count).floor dotted = solid / 3 dashed = solid / 3 * 2 counts.each do |(first, second), count| graph[first] << second edge = ["weight=#{count}", "label=\"#{count}\"", "dir=none"] case Math.log10 count when 0.0..dotted then edge << "style = dotted" when dotted..dashed then edge << "style = dashed" when dashed..solid then edge << "style = solid" else edge << "style = bold" end graph.edge[first][second].push(*edge) end return graph end |