TurtleDB
A mini distributed database system
|
00001 /*------------------------------------------------------------------------- 00002 Simple distributed database engine 00003 Copyright (C) 2012 Sylvain HallĂ© 00004 00005 This program is free software: you can redistribute it and/or modify 00006 it under the terms of the GNU General Public License as published by 00007 the Free Software Foundation, either version 3 of the License, or 00008 (at your option) any later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program. If not, see <http://www.gnu.org/licenses/>. 00017 -------------------------------------------------------------------------*/ 00018 package ca.uqac.dim.turtledb; 00019 00020 import java.util.Stack; 00021 00022 /*package*/ class GraphvizQueryVisitor extends QueryVisitor 00023 { 00024 protected StringBuilder m_nodes; 00025 protected StringBuilder m_connectivity; 00026 protected Stack<String> m_nodeList; 00027 protected int m_nodeCounter; 00028 00029 public GraphvizQueryVisitor() 00030 { 00031 super(); 00032 m_nodeList = new Stack<String>(); 00033 m_nodes = new StringBuilder(); 00034 m_connectivity = new StringBuilder(); 00035 m_nodeCounter = 0; 00036 } 00037 00038 public String getGraphviz() 00039 { 00040 StringBuilder out = new StringBuilder(); 00041 out.append("graph G\n{\n"); 00042 out.append(" node [shape=plaintext];\n"); 00043 out.append(m_nodes); 00044 out.append(m_connectivity); 00045 out.append("}\n"); 00046 return out.toString(); 00047 } 00048 00049 @Override 00050 public void visit(Selection r) 00051 { 00052 String newNode = "node" + m_nodeCounter; 00053 m_nodeCounter++; 00054 String m_operand = m_nodeList.pop(); 00055 m_connectivity.append(" ").append(newNode).append(" -- ").append(m_operand).append(";\n"); 00056 m_nodes.append(" ").append(newNode).append("[label = <σ<sub>").append(createConditionString(r.m_condition)).append("</sub>>];\n"); 00057 m_nodeList.push(newNode); 00058 } 00059 00060 @Override 00061 public void visit(Projection r) 00062 { 00063 String newNode = "node" + m_nodeCounter; 00064 m_nodeCounter++; 00065 String m_operand = m_nodeList.pop(); 00066 m_connectivity.append(" ").append(newNode).append(" -- ").append(m_operand).append(";\n"); 00067 m_nodes.append(" ").append(newNode).append("[label = <π<sub>").append(createSchemaString(r.m_schema)).append("</sub>>];\n"); 00068 m_nodeList.push(newNode); 00069 } 00070 00071 @Override 00072 public void visit(Intersection r) 00073 { 00074 String newNode = "node" + m_nodeCounter; 00075 m_nodeCounter++; 00076 for (int i = 0; i < r.m_relations.size(); i++) 00077 { 00078 String m_operand = m_nodeList.pop(); 00079 m_connectivity.append(" ").append(newNode).append(" -- ").append(m_operand).append(";\n"); 00080 } 00081 m_nodes.append(" ").append(newNode).append("[label = <∩>];\n"); 00082 m_nodeList.push(newNode); 00083 } 00084 00085 @Override 00086 public void visit(Union r) 00087 { 00088 String newNode = "node" + m_nodeCounter; 00089 m_nodeCounter++; 00090 for (int i = 0; i < r.m_relations.size(); i++) 00091 { 00092 String m_operand = m_nodeList.pop(); 00093 m_connectivity.append(" ").append(newNode).append(" -- ").append(m_operand).append(";\n"); 00094 } 00095 m_nodes.append(" ").append(newNode).append("[label = <∪>];\n"); 00096 m_nodeList.push(newNode); 00097 } 00098 00099 @Override 00100 public void visit(Join r) 00101 { 00102 String newNode = "node" + m_nodeCounter; 00103 m_nodeCounter++; 00104 String m_operand = m_nodeList.pop(); // RHS 00105 m_connectivity.append(" ").append(newNode).append(" -- ").append(m_operand).append(";\n"); 00106 m_operand = m_nodeList.pop(); // LHS 00107 m_connectivity.append(" ").append(newNode).append(" -- ").append(m_operand).append(";\n"); 00108 m_nodes.append(" ").append(newNode).append("[label = <⋈<sub>").append(createConditionString(r.m_condition)).append("</sub>>];\n"); 00109 m_nodeList.push(newNode); 00110 } 00111 00112 @Override 00113 public void visit(Product r) 00114 { 00115 String newNode = "node" + m_nodeCounter; 00116 m_nodeCounter++; 00117 for (int i = 0; i < r.m_relations.size(); i++) 00118 { 00119 String m_operand = m_nodeList.pop(); 00120 m_connectivity.append(" ").append(newNode).append(" -- ").append(m_operand).append(";\n"); 00121 } 00122 m_nodes.append(" ").append(newNode).append("[label = <×>];\n"); 00123 m_nodeList.push(newNode); 00124 } 00125 00126 @Override 00127 public void visit(Table r) 00128 { 00129 String newNode = "node" + m_nodeCounter; 00130 m_nodeCounter++; 00131 m_nodes.append(" ").append(newNode).append("[label = <").append(r.getName()).append(">];\n"); 00132 m_nodeList.push(newNode); 00133 } 00134 00135 @Override 00136 public void visit(VariableTable r) 00137 { 00138 String newNode = "node" + m_nodeCounter; 00139 m_nodeCounter++; 00140 if (r.m_relation != null) 00141 { 00142 String m_operand = m_nodeList.pop(); 00143 m_connectivity.append(" ").append(newNode).append(" -- ").append(m_operand).append(";\n"); 00144 } 00145 m_nodes.append(" ").append(newNode).append("[shape=circle,label = <").append(r.getName()).append(">];\n"); 00146 m_nodeList.push(newNode); 00147 } 00148 00149 protected String createConditionString(Condition c) 00150 { 00151 GraphvizConditionVisitor gcv = new GraphvizConditionVisitor(); 00152 c.accept(gcv); 00153 return gcv.getGraphviz(); 00154 } 00155 00156 protected String createSchemaString(Schema sch) 00157 { 00158 StringBuilder out = new StringBuilder(); 00159 boolean first = true; 00160 for (Attribute a : sch) 00161 { 00162 out.append(a.toString()); 00163 if (!first) 00164 out.append(","); 00165 first = false; 00166 } 00167 return out.toString(); 00168 } 00169 00170 }