Skip to content

Commit

Permalink
Merge pull request #603 from npetzall/376_always_create_diagrams
Browse files Browse the repository at this point in the history
Always produce table diagram
  • Loading branch information
npetzall committed Sep 19, 2019
2 parents b3aa87d + 3f0eee9 commit 9569ef8
Show file tree
Hide file tree
Showing 31 changed files with 2,205 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,6 @@ public List<MustacheTableDiagram> generateTableDiagrams(Table table, WriteStats
Files.deleteIfExists(oneImpliedDotFile.toPath());
Files.deleteIfExists(twoImpliedDotFile.toPath());

if (hasNoRelationships(table)) {
return diagrams;
}

Set<ForeignKeyConstraint> impliedConstraints;

WriteStats oneStats = new WriteStats(stats);
Expand Down Expand Up @@ -122,10 +118,6 @@ public List<MustacheTableDiagram> generateTableDiagrams(Table table, WriteStats
return diagrams;
}

private static boolean hasNoRelationships(Table table) {
return table.getMaxChildren() + table.getMaxParents() < 1;
}

private static boolean notEmpty(Collection<?> collection) {
return !collection.isEmpty();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@
MysqlSchemaLeakageIT.class,
MysqlSpacesIT.class,
MysqlSpacesNoDotsIT.class,
MysqlXMLIT.class
MysqlXMLIT.class,
MysqlHTMLOrphanIT.class
})
public class MysqlSuite {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/*
* Copyright (C) 2018 Nils Petzaell
*
* This file is part of SchemaSpy.
*
* SchemaSpy is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SchemaSpy is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with SchemaSpy. If not, see <http://www.gnu.org/licenses/>.
*/
package org.schemaspy.integrationtesting.mysql;

import com.github.npetzall.testcontainers.junit.jdbc.JdbcContainerRule;
import org.assertj.core.api.SoftAssertions;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.schemaspy.cli.SchemaSpyRunner;
import org.schemaspy.integrationtesting.MysqlSuite;
import org.schemaspy.testing.HtmlOutputValidator;
import org.schemaspy.testing.SuiteOrTestJdbcContainerRule;
import org.schemaspy.testing.XmlOutputDiff;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.testcontainers.containers.MySQLContainer;
import org.xmlunit.builder.Input;
import org.xmlunit.diff.Diff;

import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.concurrent.atomic.AtomicBoolean;

import static com.github.npetzall.testcontainers.junit.jdbc.JdbcAssumptions.assumeDriverIsPresent;
import static org.assertj.core.api.Assertions.assertThat;

/**
* @author Nils Petzaell
*/
@RunWith(SpringRunner.class)
@SpringBootTest
@DirtiesContext
public class MysqlHTMLOrphanIT {

private static URL expectedXML = MysqlHTMLOrphanIT.class.getResource("/integrationTesting/mysql/expecting/mysqlhtmlorphan/htmlorphanit.htmlorphanit.xml");
private static URL expectedDeletionOrder = MysqlHTMLOrphanIT.class.getResource("/integrationTesting/mysql/expecting/mysqlhtmlorphan/deletionOrder.txt");
private static URL expectedInsertionOrder = MysqlHTMLOrphanIT.class.getResource("/integrationTesting/mysql/expecting/mysqlhtmlorphan/insertionOrder.txt");

@ClassRule
public static JdbcContainerRule<MySQLContainer> jdbcContainerRule =
new SuiteOrTestJdbcContainerRule<>(
MysqlSuite.jdbcContainerRule,
new JdbcContainerRule<MySQLContainer>(() -> new MySQLContainer<>("mysql:5"))
.assumeDockerIsPresent().withAssumptions(assumeDriverIsPresent())
.withQueryString("?useSSL=false")
.withInitScript("integrationTesting/mysql/dbScripts/htmlorphanit.sql")
.withInitUser("root", "test")
);

@Autowired
private SchemaSpyRunner schemaSpyRunner;

private static final AtomicBoolean shouldRun = new AtomicBoolean(true);

@Before
public synchronized void generateHTML() throws Exception {
if (shouldRun.get()) {
String[] args = new String[]{
"-t", "mysql",
"-db", "htmlorphanit",
"-s", "htmlorphanit",
"-host", jdbcContainerRule.getContainer().getContainerIpAddress() + ":" + String.valueOf(jdbcContainerRule.getContainer().getMappedPort(3306)),
"-port", String.valueOf(jdbcContainerRule.getContainer().getMappedPort(3306)),
"-u", jdbcContainerRule.getContainer().getUsername(),
"-p", jdbcContainerRule.getContainer().getPassword(),
"-o", "target/mysqlhtmlorphanit",
"-connprops", "useSSL\\=false"
};
schemaSpyRunner.run(args);
shouldRun.set(false);
}
}

@Test
public void verifyXML() {
Diff d = XmlOutputDiff.diffXmlOutput(
Input.fromFile("target/mysqlhtmlorphanit/htmlorphanit.htmlorphanit.xml"),
Input.fromURL(expectedXML)
);
assertThat(d.getDifferences()).isEmpty();
}

@Test
public void verifyDeletionOrder() throws IOException {
assertThat(Files.newInputStream(Paths.get("target/mysqlhtmlorphanit/deletionOrder.txt"), StandardOpenOption.READ)).hasSameContentAs(expectedDeletionOrder.openStream());
}

@Test
public void verifyInsertionOrder() throws IOException {
assertThat(Files.newInputStream(Paths.get("target/mysqlhtmlorphanit/insertionOrder.txt"), StandardOpenOption.READ)).hasSameContentAs(expectedInsertionOrder.openStream());
}

@Test
public void producesSameContent() throws IOException {
SoftAssertions softAssertions = HtmlOutputValidator
.hasProducedValidOutput(
Paths.get("target","mysqlhtmlorphanit"),
Paths.get("src","test","resources","integrationTesting","mysql","expecting","mysqlhtmlorphan")
);
softAssertions.assertThat(softAssertions.wasSuccess()).isTrue();
softAssertions.assertAll();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,22 @@ public static void setupTable() {
}

@Test
public void noDiagrams() throws IOException {
public void oneDiagrams() throws IOException {
WriteStats writeStats = new WriteStats(Collections.emptyList());
Table tableNoRelationships = mock(Table.class);
when(tableNoRelationships.getMaxChildren()).thenReturn(0);
when(tableNoRelationships.getMaxParents()).thenReturn(0);

MustacheTableDiagramFactory mustacheTableDiagramFactory = new MustacheTableDiagramFactory(null, null, temporaryFolder.newFolder("nodiagrams"), 2);
DotFormatter dotProducer = mock(DotFormatter.class);
when(dotProducer.writeRealRelationships(eq(table), eq(false), any(WriteStats.class), any(PrintWriter.class)))
.then(FIRST_DOT);

MustacheDiagramFactory mustacheDiagramFactory = mock(MustacheDiagramFactory.class);
when(mustacheDiagramFactory.generateTableDiagram(anyString(),any(File.class),anyString())).thenReturn(new MustacheTableDiagram());

MustacheTableDiagramFactory mustacheTableDiagramFactory = new MustacheTableDiagramFactory(dotProducer, mustacheDiagramFactory, temporaryFolder.newFolder("orphan"), 2);
List<MustacheTableDiagram> mustacheTableDiagramList = mustacheTableDiagramFactory.generateTableDiagrams(tableNoRelationships, writeStats);
assertThat(mustacheTableDiagramList).isEmpty();
assertThat(mustacheTableDiagramList).hasSize(1);
}

@Test
Expand All @@ -106,7 +113,7 @@ public void onlyOneDiagram() throws IOException {
.then(FIRST_DOT);

MustacheDiagramFactory mustacheDiagramFactory = mock(MustacheDiagramFactory.class);
when(mustacheDiagramFactory.generateTableDiagram(anyString(),any(File.class),anyString())).thenReturn(new MustacheTableDiagram());
when(mustacheDiagramFactory.generateTableDiagram(anyString(),any(File.class),anyString())).then(invocation -> new MustacheTableDiagram());

MustacheTableDiagramFactory mustacheTableDiagramFactory = new MustacheTableDiagramFactory(dotProducer, mustacheDiagramFactory, outputDir, 2);
List<MustacheTableDiagram> mustacheTableDiagramList = mustacheTableDiagramFactory.generateTableDiagrams(table, writeStats);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
digraph "oneDegreeRelationshipsDiagram" {
graph [
rankdir="RL"
bgcolor="#ffffff"
label="\nGenerated by SchemaSpy"
labeljust="l"
nodesep="0.18"
ranksep="0.46"
fontname="Helvetica"
fontsize="11"
ration="compress"
];
node [
fontname="Helvetica"
fontsize="11"
shape="plaintext"
];
edge [
arrowsize="0.8"
];
"userAndGroup" [
label=<
<TABLE BORDER="2" CELLBORDER="1" CELLSPACING="0" BGCOLOR="#ffffff">
<TR><TD COLSPAN="4" BGCOLOR="#f5f5f5"><TABLE BORDER="0" CELLSPACING="0"><TR><TD ALIGN="LEFT"><B>userAndGroup</B></TD><TD ALIGN="RIGHT">[view]</TD></TR></TABLE></TD></TR>
<TR><TD PORT="UserName" COLSPAN="2" ALIGN="LEFT"><TABLE BORDER="0" CELLSPACING="0" ALIGN="LEFT"><TR ALIGN="LEFT"><TD ALIGN="LEFT" FIXEDSIZE="TRUE" WIDTH="15" HEIGHT="16"></TD><TD ALIGN="LEFT" FIXEDSIZE="TRUE" WIDTH="97" HEIGHT="16">UserName</TD></TR></TABLE></TD><TD PORT="UserName.type" ALIGN="LEFT">varchar[16]</TD></TR>
<TR><TD PORT="GroupName" COLSPAN="2" ALIGN="LEFT"><TABLE BORDER="0" CELLSPACING="0" ALIGN="LEFT"><TR ALIGN="LEFT"><TD ALIGN="LEFT" FIXEDSIZE="TRUE" WIDTH="15" HEIGHT="16"></TD><TD ALIGN="LEFT" FIXEDSIZE="TRUE" WIDTH="97" HEIGHT="16">GroupName</TD></TR></TABLE></TD><TD PORT="GroupName.type" ALIGN="LEFT">varchar[16]</TD></TR>
</TABLE>>
URL="userAndGroup.html"
target="_top"
tooltip="userAndGroup"
];
}
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,32 @@ <h3 id="Columns" class="box-title">Columns</h3>
</table>
</div>
</div>
<div class="box box-primary">
<div class="box-header with-border">
<i class="fa fa-code-fork"></i>
<h3 id="Relationships" class="box-title">Relationships</h3>
<div class="box-tools pull-right">
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
<button type="button" class="btn btn-box-tool" data-widget="remove"><i class="fa fa-times"></i></button>
</div>
</div>
<div class="box-body">
<div class="nav-tabs-custom"><!-- Tabs within a box -->
<h5>Close relationships within degrees of separation</h5>
<ul class="nav nav-tabs pull-left ui-sortable-handle">
<li class="active"><a href="#oneDegreeImg-chart" data-toggle="tab" aria-expanded="true">One</a></li>
</ul>
<div class="tab-content no-padding">
<div class="chart tab-pane active" id="oneDegreeImg-chart" style="position: relative; overflow-x:auto;">
<map id="oneDegreeRelationshipsDiagram" name="oneDegreeRelationshipsDiagram">
<area shape="rect" id="node1" href="userAndGroup.html" target="_top" title="userAndGroup" alt="" coords="5,5,271,109">
</map>
<a name='diagram'><img id="oneDegreeImg" src="../diagrams/tables/userAndGroup.1degree.png" usemap="#oneDegreeRelationshipsDiagram" class="diagram" border="0" align="left"></a>
</div>
</div>
</div>
</div><!-- /.box-body -->
</div>
<div class="box box-primary">
<div class="box-header with-border">
<i class="fa fa-file-code-o"></i>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
CREATE DATABASE `htmlorphanit`;

CREATE TABLE `htmlorphanit`.`group` (
groupId INTEGER AUTO_INCREMENT,
name VARCHAR(16) NOT NULL,
description VARCHAR(80) NOT NULL,
PRIMARY KEY (groupId),
UNIQUE name_unique (name)
) engine=InnoDB COMMENT 'Orphan Groups';

GRANT SELECT, EXECUTE, SHOW VIEW on `htmlorphanit`.* to test@`%`;
FLUSH PRIVILEGES;
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
digraph "oneDegreeRelationshipsDiagram" {
graph [
rankdir="RL"
bgcolor="#ffffff"
label="\nGenerated by SchemaSpy"
labeljust="l"
nodesep="0.18"
ranksep="0.46"
fontname="Helvetica"
fontsize="11"
ration="compress"
];
node [
fontname="Helvetica"
fontsize="11"
shape="plaintext"
];
edge [
arrowsize="0.8"
];
"userAndGroup" [
label=<
<TABLE BORDER="2" CELLBORDER="1" CELLSPACING="0" BGCOLOR="#ffffff">
<TR><TD COLSPAN="4" BGCOLOR="#f5f5f5"><TABLE BORDER="0" CELLSPACING="0"><TR><TD ALIGN="LEFT"><B>userAndGroup</B></TD><TD ALIGN="RIGHT">[view]</TD></TR></TABLE></TD></TR>
<TR><TD PORT="UserName" COLSPAN="2" ALIGN="LEFT"><TABLE BORDER="0" CELLSPACING="0" ALIGN="LEFT"><TR ALIGN="LEFT"><TD ALIGN="LEFT" FIXEDSIZE="TRUE" WIDTH="15" HEIGHT="16"></TD><TD ALIGN="LEFT" FIXEDSIZE="TRUE" WIDTH="97" HEIGHT="16">UserName</TD></TR></TABLE></TD><TD PORT="UserName.type" ALIGN="LEFT">varchar[16]</TD></TR>
<TR><TD PORT="GroupName" COLSPAN="2" ALIGN="LEFT"><TABLE BORDER="0" CELLSPACING="0" ALIGN="LEFT"><TR ALIGN="LEFT"><TD ALIGN="LEFT" FIXEDSIZE="TRUE" WIDTH="15" HEIGHT="16"></TD><TD ALIGN="LEFT" FIXEDSIZE="TRUE" WIDTH="97" HEIGHT="16">GroupName</TD></TR></TABLE></TD><TD PORT="GroupName.type" ALIGN="LEFT">varchar[16]</TD></TR>
</TABLE>>
URL="userAndGroup.html"
target="_top"
tooltip="userAndGroup"
];
}
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,32 @@ <h3 id="Columns" class="box-title">Columns</h3>
</table>
</div>
</div>
<div class="box box-primary">
<div class="box-header with-border">
<i class="fa fa-code-fork"></i>
<h3 id="Relationships" class="box-title">Relationships</h3>
<div class="box-tools pull-right">
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>
<button type="button" class="btn btn-box-tool" data-widget="remove"><i class="fa fa-times"></i></button>
</div>
</div>
<div class="box-body">
<div class="nav-tabs-custom"><!-- Tabs within a box -->
<h5>Close relationships within degrees of separation</h5>
<ul class="nav nav-tabs pull-left ui-sortable-handle">
<li class="active"><a href="#oneDegreeImg-chart" data-toggle="tab" aria-expanded="true">One</a></li>
</ul>
<div class="tab-content no-padding">
<div class="chart tab-pane active" id="oneDegreeImg-chart" style="position: relative; overflow-x:auto;">
<map id="oneDegreeRelationshipsDiagram" name="oneDegreeRelationshipsDiagram">
<area shape="rect" id="node1" href="userAndGroup.html" target="_top" title="userAndGroup" alt="" coords="5,5,271,109">
</map>
<a name='diagram'><img id="oneDegreeImg" src="../diagrams/tables/userAndGroup.1degree.png" usemap="#oneDegreeRelationshipsDiagram" class="diagram" border="0" align="left"></a>
</div>
</div>
</div>
</div><!-- /.box-body -->
</div>
<div class="box box-primary">
<div class="box-header with-border">
<i class="fa fa-file-code-o"></i>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
digraph "oneDegreeRelationshipsDiagram" {
graph [
rankdir="RL"
bgcolor="#ffffff"
label="\nGenerated by SchemaSpy"
labeljust="l"
nodesep="0.18"
ranksep="0.46"
fontname="Helvetica"
fontsize="11"
ration="compress"
];
node [
fontname="Helvetica"
fontsize="11"
shape="plaintext"
];
edge [
arrowsize="0.8"
];
"userAndGroup" [
label=<
<TABLE BORDER="2" CELLBORDER="1" CELLSPACING="0" BGCOLOR="#ffffff">
<TR><TD COLSPAN="4" BGCOLOR="#f5f5f5"><TABLE BORDER="0" CELLSPACING="0"><TR><TD ALIGN="LEFT"><B>userAndGroup</B></TD><TD ALIGN="RIGHT">[view]</TD></TR></TABLE></TD></TR>
<TR><TD PORT="UserName" COLSPAN="2" ALIGN="LEFT"><TABLE BORDER="0" CELLSPACING="0" ALIGN="LEFT"><TR ALIGN="LEFT"><TD ALIGN="LEFT" FIXEDSIZE="TRUE" WIDTH="15" HEIGHT="16"></TD><TD ALIGN="LEFT" FIXEDSIZE="TRUE" WIDTH="97" HEIGHT="16">UserName</TD></TR></TABLE></TD><TD PORT="UserName.type" ALIGN="LEFT">varchar[16]</TD></TR>
<TR><TD PORT="GroupName" COLSPAN="2" ALIGN="LEFT"><TABLE BORDER="0" CELLSPACING="0" ALIGN="LEFT"><TR ALIGN="LEFT"><TD ALIGN="LEFT" FIXEDSIZE="TRUE" WIDTH="15" HEIGHT="16"></TD><TD ALIGN="LEFT" FIXEDSIZE="TRUE" WIDTH="97" HEIGHT="16">GroupName</TD></TR></TABLE></TD><TD PORT="GroupName.type" ALIGN="LEFT">varchar[16]</TD></TR>
</TABLE>>
URL="../../tables/userAndGroup.html"
target="_top"
tooltip="userAndGroup"
];
}

0 comments on commit 9569ef8

Please sign in to comment.