diff --git a/schemacrawler-diagram/src/main/java/schemacrawler/tools/text/formatter/diagram/SchemaDotFormatter.java b/schemacrawler-diagram/src/main/java/schemacrawler/tools/text/formatter/diagram/SchemaDotFormatter.java index ade2b5ed69..cff1063dbb 100644 --- a/schemacrawler-diagram/src/main/java/schemacrawler/tools/text/formatter/diagram/SchemaDotFormatter.java +++ b/schemacrawler-diagram/src/main/java/schemacrawler/tools/text/formatter/diagram/SchemaDotFormatter.java @@ -249,7 +249,10 @@ public void handleTablesStart() { // No output required } - private String arrowhead(final ForeignKeyCardinality connectivity) { + private String arrowheadFk(final ForeignKeyCardinality connectivity) { + if (!options.isShowForeignKeyCardinality()) { + return "none"; + } switch (connectivity) { case zero_one: return "teeodot"; @@ -262,6 +265,26 @@ private String arrowhead(final ForeignKeyCardinality connectivity) { } } + private String arrowheadPk() { + final String pkSymbol; + if (options.isShowPrimaryKeyCardinality()) { + pkSymbol = "teetee"; + } else { + pkSymbol = "none"; + } + return pkSymbol; + } + + private String columnReferenceLineStyle(final boolean isForeignKey) { + final String style; + if (isForeignKey) { + style = "solid"; + } else { + style = "dashed"; + } + return style; + } + private String[] getPortIds(final Column column, final boolean isNewNode) { final String[] portIds = new String[2]; @@ -363,27 +386,9 @@ private String printColumnReference( final String[] fkPortIds = getPortIds(foreignKeyColumn, isFkColumnFiltered || !isFkColumnSignificant); - final DiagramOptions diagramOptions = options; - final String pkSymbol; - if (diagramOptions.isShowPrimaryKeyCardinality()) { - pkSymbol = "teetee"; - } else { - pkSymbol = "none"; - } - - final String fkSymbol; - if (diagramOptions.isShowForeignKeyCardinality()) { - fkSymbol = arrowhead(fkCardinality); - } else { - fkSymbol = "none"; - } - - final String style; - if (isForeignKey) { - style = "solid"; - } else { - style = "dashed"; - } + final String pkSymbol = arrowheadPk(); + final String fkSymbol = arrowheadFk(fkCardinality); + final String lineStyle = columnReferenceLineStyle(isForeignKey); final String associationName; if (isForeignKey && options.is(hideForeignKeyNames) @@ -403,7 +408,7 @@ private String printColumnReference( return String.format( " %s:w -> %s:e [label=<%s> style=\"%s\" dir=\"both\" arrowhead=\"%s\" arrowtail=\"%s\"];%n", - fkPortIds[0], pkPortIds[1], label, style, pkSymbol, fkSymbol); + fkPortIds[0], pkPortIds[1], label, lineStyle, pkSymbol, fkSymbol); } private void printForeignKeys(final Table table) { diff --git a/schemacrawler-docker-compose/mcsbart.yaml b/schemacrawler-docker-compose/mcsbart.yaml new file mode 100644 index 0000000000..7ad7fa6700 --- /dev/null +++ b/schemacrawler-docker-compose/mcsbart.yaml @@ -0,0 +1,13 @@ +services: + + sqlserver: + image: mcsbart_1 + container_name: sqlserver + ports: + - target: 1433 + published: 1433 + protocol: tcp + mode: host + environment: + ACCEPT_EULA: "Y" + SA_PASSWORD: Schem#Crawl3r diff --git a/schemacrawler-text/src/main/java/schemacrawler/tools/text/formatter/schema/SchemaTextFormatter.java b/schemacrawler-text/src/main/java/schemacrawler/tools/text/formatter/schema/SchemaTextFormatter.java index 5866d13369..909b3d2aa3 100644 --- a/schemacrawler-text/src/main/java/schemacrawler/tools/text/formatter/schema/SchemaTextFormatter.java +++ b/schemacrawler-text/src/main/java/schemacrawler/tools/text/formatter/schema/SchemaTextFormatter.java @@ -376,6 +376,54 @@ public void handleTablesStart() { formattingHelper.writeHeader(DocumentHeaderType.subTitle, "Tables"); } + private List filterPrintableConstraints( + final Collection constraintsCollection) { + final EnumSet printableConstraints = + EnumSet.of(TableConstraintType.check, TableConstraintType.unique); + + final List constraints = new ArrayList<>(); + for (final TableConstraint constraint : constraintsCollection) { + // 1. There is no point in showing a constraint if there is no information + // about the constrained columns, and the name is hidden + final List constrainedColumns = constraint.getConstrainedColumns(); + final boolean hasNoNameOrColumns = + options.is(hideTableConstraintNames) + && constrainedColumns.isEmpty() + && !constraint.hasRemarks(); + // 2. Print only check constraints and unique constraints + final boolean isNotPkOrFk = printableConstraints.contains(constraint.getType()); + // Keep only constraints that should be printed + if (!hasNoNameOrColumns && isNotPkOrFk) { + constraints.add(constraint); + } + } + return constraints; + } + + private String makeFkRuleString(final ForeignKey foreignKey) { + String updateRuleString = ""; + final ForeignKeyUpdateRule updateRule = foreignKey.getUpdateRule(); + if (updateRule != null && updateRule != ForeignKeyUpdateRule.unknown) { + updateRuleString = ", on update " + updateRule.toString(); + } + + String deleteRuleString = ""; + final ForeignKeyUpdateRule deleteRule = foreignKey.getDeleteRule(); + if (deleteRule != null && deleteRule != ForeignKeyUpdateRule.unknown) { + deleteRuleString = ", on delete " + deleteRule.toString(); + } + + final String ruleString; + if (deleteRule != null + && updateRule == deleteRule + && updateRule != ForeignKeyUpdateRule.unknown) { + ruleString = ", with " + deleteRule.toString(); + } else { + ruleString = updateRuleString + deleteRuleString; + } + return ruleString; + } + private void printAlternateKeys(final Table table) { if (table == null || options.is(hideAlternateKeys)) { LOGGER.log(Level.FINER, "Not showing alternate keys"); @@ -571,27 +619,7 @@ private void printForeignKeys(final Table table) { for (final ForeignKey foreignKey : foreignKeys) { if (foreignKey != null) { final String name = identifiers.quoteName(foreignKey); - - String updateRuleString = ""; - final ForeignKeyUpdateRule updateRule = foreignKey.getUpdateRule(); - if (updateRule != null && updateRule != ForeignKeyUpdateRule.unknown) { - updateRuleString = ", on update " + updateRule.toString(); - } - - String deleteRuleString = ""; - final ForeignKeyUpdateRule deleteRule = foreignKey.getDeleteRule(); - if (deleteRule != null && deleteRule != ForeignKeyUpdateRule.unknown) { - deleteRuleString = ", on delete " + deleteRule.toString(); - } - - final String ruleString; - if (deleteRule != null - && updateRule == deleteRule - && updateRule != ForeignKeyUpdateRule.unknown) { - ruleString = ", with " + deleteRule.toString(); - } else { - ruleString = updateRuleString + deleteRuleString; - } + final String ruleString = makeFkRuleString(foreignKey); formattingHelper.writeEmptyRow(); @@ -872,15 +900,7 @@ private void printTableConstraints(final Collection constraints return; } - final EnumSet printableConstraints = - EnumSet.of(TableConstraintType.check, TableConstraintType.unique); - - final List constraints = new ArrayList<>(); - for (final TableConstraint constraint : constraintsCollection) { - if (printableConstraints.contains(constraint.getType())) { - constraints.add(constraint); - } - } + final List constraints = filterPrintableConstraints(constraintsCollection); if (constraints.isEmpty()) { return; } @@ -888,27 +908,6 @@ private void printTableConstraints(final Collection constraints Collections.sort( constraints, NamedObjectSort.getNamedObjectSort(options.isAlphabeticalSortForIndexes())); - // There is no point in showing a constraint if there is no information - // about the constrained columns, and the name is hidden - boolean canDisplayTableConstraints = false; - for (final TableConstraint constraint : constraints) { - if (constraint == null) { - continue; - } - final List constrainedColumns = constraint.getConstrainedColumns(); - final boolean cannotDisplayTableConstraints = - (options.is(hideTableConstraintNames) - && constrainedColumns.isEmpty() - && !constraint.hasRemarks()); - if (!cannotDisplayTableConstraints) { - canDisplayTableConstraints = true; - break; - } - } - if (!canDisplayTableConstraints) { - return; - } - formattingHelper.writeEmptyRow(); formattingHelper.writeWideRow("Table Constraints", "section"); @@ -916,6 +915,7 @@ private void printTableConstraints(final Collection constraints if (constraint == null) { continue; } + final String constraintName; if (!options.is(hideTableConstraintNames)) { LOGGER.log( @@ -925,16 +925,6 @@ private void printTableConstraints(final Collection constraints } else { constraintName = ""; } - - final List constrainedColumns = constraint.getConstrainedColumns(); - if (options.is(hideTableConstraintNames) - && constrainedColumns.isEmpty() - && !constraint.hasRemarks()) { - // There is no point in showing a constraint if there is no information - // about the constrained columns, and the name is hidden - continue; - } - final String constraintType = constraint.getType().getValue().toLowerCase(); final String constraintDetails = "[" + constraintType + " constraint]"; formattingHelper.writeEmptyRow(); @@ -942,6 +932,7 @@ private void printTableConstraints(final Collection constraints printRemarks(constraint); if (!isBrief()) { + final List constrainedColumns = constraint.getConstrainedColumns(); printTableColumns(constrainedColumns, false); } printDependantObjectDefinition(constraint); @@ -985,7 +976,7 @@ private void printTriggers(final Collection triggers) { if (timingBuffer.length() > 0) { timingBuffer.append(SPACE); } - for (EventManipulationType eventManipulationType : eventManipulationTypes) { + for (final EventManipulationType eventManipulationType : eventManipulationTypes) { timingBuffer.append(eventManipulationType); if (eventManipulationTypes.indexOf(eventManipulationType) < eventManipulationTypes.size() - 1) { diff --git a/schemacrawler-utility/src/main/java/us/fatehi/utility/database/SqlScript.java b/schemacrawler-utility/src/main/java/us/fatehi/utility/database/SqlScript.java index 92d297ba19..c8d2279c60 100644 --- a/schemacrawler-utility/src/main/java/us/fatehi/utility/database/SqlScript.java +++ b/schemacrawler-utility/src/main/java/us/fatehi/utility/database/SqlScript.java @@ -33,6 +33,7 @@ import java.io.IOException; import java.io.Reader; import java.sql.Connection; +import java.sql.SQLException; import java.sql.SQLWarning; import java.sql.Statement; import java.util.ArrayList; @@ -102,7 +103,6 @@ public void run() { final List sqlList = readSql(new BufferedReader(scriptReader)); for (final Iterator iterator = sqlList.iterator(); iterator.hasNext(); ) { sql = iterator.next(); - statement.clearWarnings(); try { if (Pattern.matches("\\s+", sql)) { continue; @@ -111,15 +111,7 @@ public void run() { LOGGER.log(Level.INFO, "\n" + sql); } - final boolean hasResults = statement.execute(sql); - if (hasResults) { - throw new SQLWarning(String.format("Results not expected from SQL%n%s%n", sql)); - } - - final SQLWarning warnings = statement.getWarnings(); - if (warnings != null && !warnings.getMessage().startsWith("Can't drop database")) { - throw warnings; - } + executeSql(sql, statement); if (!connection.getAutoCommit()) { connection.commit(); @@ -144,6 +136,19 @@ public void run() { } } + private void executeSql(final String sql, final Statement statement) throws SQLException { + final boolean hasResults = statement.execute(sql); + if (hasResults) { + throw new SQLWarning(String.format("Results not expected from SQL%n%s%n", sql)); + } + + final SQLWarning warnings = statement.getWarnings(); + statement.clearWarnings(); + if (warnings != null && !warnings.getMessage().startsWith("Can't drop database")) { + throw warnings; + } + } + private Throwable getCause(final Throwable e) { Throwable cause; Throwable result = e;