TurtleDB
A mini distributed database system
src/ca/uqac/dim/turtledb/GraphvizQueryVisitor.java
Go to the documentation of this file.
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 = <&sigma;<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 = <&pi;<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 = <&cap;>];\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 = <&cup;>];\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 = <&#x22C8;<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 = <&times;>];\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 }