|
8 | 8 |
|
9 | 9 | package schemacrawler.tools.command.script; |
10 | 10 |
|
11 | | -import static java.util.stream.Collectors.toList; |
12 | | -import static schemacrawler.ermodel.model.RelationshipCardinality.many_many; |
13 | | -import static schemacrawler.ermodel.model.RelationshipCardinality.one_many; |
14 | | -import static schemacrawler.ermodel.model.RelationshipCardinality.zero_many; |
15 | | -import static schemacrawler.utility.MetaDataUtility.getSimpleTypeName; |
16 | | -import static schemacrawler.utility.MetaDataUtility.isPartial; |
17 | | - |
18 | | -import java.util.ArrayList; |
19 | | -import java.util.Collection; |
20 | | -import java.util.EnumSet; |
21 | | -import java.util.List; |
22 | | -import java.util.Objects; |
23 | | -import java.util.Optional; |
24 | | -import java.util.logging.Level; |
25 | | -import java.util.logging.Logger; |
26 | | -import schemacrawler.ermodel.model.ERModel; |
27 | | -import schemacrawler.ermodel.model.Entity; |
28 | | -import schemacrawler.ermodel.model.Relationship; |
29 | | -import schemacrawler.ermodel.model.RelationshipCardinality; |
30 | | -import schemacrawler.ermodel.utility.ERModelUtility; |
31 | | -import schemacrawler.schema.Column; |
32 | | -import schemacrawler.schema.ColumnReference; |
33 | | -import schemacrawler.schema.DatabaseObject; |
34 | | -import schemacrawler.schema.DescribedObject; |
35 | | -import schemacrawler.schema.ForeignKey; |
36 | | -import schemacrawler.schema.IdentifierQuotingStrategy; |
37 | | -import schemacrawler.schema.Identifiers; |
38 | | -import schemacrawler.schema.IdentifiersBuilder; |
39 | | -import schemacrawler.schema.Index; |
40 | | -import schemacrawler.schema.NamedObject; |
41 | | -import schemacrawler.schema.PrimaryKey; |
42 | | -import schemacrawler.schema.Table; |
43 | | -import schemacrawler.schema.TableReference; |
44 | 11 | import schemacrawler.tools.state.AbstractExecutionState; |
45 | | -import schemacrawler.utility.MetaDataUtility; |
46 | | -import schemacrawler.utility.MetaDataUtility.SimpleDatabaseObjectType; |
47 | | -import us.fatehi.utility.string.StringFormat; |
48 | | - |
49 | | -public final class ScriptSupport extends AbstractExecutionState { |
50 | | - |
51 | | - private static final Logger LOGGER = Logger.getLogger(CommandChain.class.getName()); |
52 | | - |
53 | | - private final Identifiers quotedIdentifiers; |
54 | | - |
55 | | - public ScriptSupport() { |
56 | | - quotedIdentifiers = |
57 | | - IdentifiersBuilder.builder() |
58 | | - .withIdentifierQuotingStrategy(IdentifierQuotingStrategy.quote_all) |
59 | | - .toOptions(); |
60 | | - } |
61 | | - |
62 | | - public RelationshipCardinality cardinality(final TableReference fk) { |
63 | | - return ERModelUtility.inferCardinality(fk); |
64 | | - } |
65 | | - |
66 | | - /** |
67 | | - * Show cardinality symbol, from PK to FK column. |
68 | | - * |
69 | | - * @param rel Foreign key |
70 | | - * @return Cardinality symbol, from PK to FK column |
71 | | - */ |
72 | | - public String cardinalitySymbol(final Relationship rel) { |
73 | | - final RelationshipCardinality cardinality; |
74 | | - if (rel == null) { |
75 | | - cardinality = RelationshipCardinality.unknown; |
76 | | - } else { |
77 | | - cardinality = rel.getType(); |
78 | | - } |
79 | | - return cardinalitySymbol(cardinality); |
80 | | - } |
81 | | - |
82 | | - /** |
83 | | - * Show cardinality symbol, from PK to FK column. |
84 | | - * |
85 | | - * @param fk Foreign key |
86 | | - * @return Cardinality symbol, from PK to FK column |
87 | | - */ |
88 | | - public String cardinalitySymbol(final TableReference fk) { |
89 | | - final RelationshipCardinality cardinality = ERModelUtility.inferCardinality(fk); |
90 | | - return cardinalitySymbol(cardinality); |
91 | | - } |
92 | | - |
93 | | - public String cleanFullName(final NamedObject namedObject) { |
94 | | - if (namedObject == null) { |
95 | | - return ""; |
96 | | - } |
97 | | - return namedObject.getFullName().replace("\"", ""); |
98 | | - } |
99 | | - |
100 | | - public String cleanName(final NamedObject namedObject) { |
101 | | - if (namedObject == null) { |
102 | | - return ""; |
103 | | - } |
104 | | - return namedObject.getName().replace("\"", ""); |
105 | | - } |
106 | | - |
107 | | - public List<ColumnReference> columnReferences(final ForeignKey foreignKey) { |
108 | | - final List<ColumnReference> refs = new ArrayList<>(); |
109 | | - if (foreignKey == null || foreignKey.getColumnReferences() == null) { |
110 | | - return refs; |
111 | | - } |
112 | | - refs.addAll(foreignKey.getColumnReferences()); |
113 | | - return refs; |
114 | | - } |
115 | | - |
116 | | - public String columns(final Index index) { |
117 | | - if (index == null) { |
118 | | - return ""; |
119 | | - } |
120 | | - return MetaDataUtility.getColumnsListAsString(index, quotedIdentifiers); |
121 | | - } |
122 | | - |
123 | | - public String columns(final PrimaryKey primaryKey) { |
124 | | - if (primaryKey == null) { |
125 | | - return ""; |
126 | | - } |
127 | | - return MetaDataUtility.getColumnsListAsString(primaryKey, quotedIdentifiers); |
128 | | - } |
129 | | - |
130 | | - public String columnType(final Column column) { |
131 | | - if (column == null || column.getColumnDataType() == null) { |
132 | | - return ""; |
133 | | - } |
134 | | - return column.getColumnDataType().getName(); |
135 | | - } |
136 | | - |
137 | | - public Collection<Entity> entities() { |
138 | | - if (!hasERModel()) { |
139 | | - return List.of(); |
140 | | - } |
141 | | - final ERModel erModel = getERModel(); |
142 | | - final List<Entity> allEntities = new ArrayList<>(erModel.getEntities()); |
143 | | - for (final Table table : erModel.getUnmodeledTables()) { |
144 | | - if (isPartial(table) || getSimpleTypeName(table) == SimpleDatabaseObjectType.view) { |
145 | | - LOGGER.log(Level.FINE, new StringFormat("Excluding table <%s>", table)); |
146 | | - continue; |
147 | | - } |
148 | | - final Optional<Entity> optionalEntity = erModel.lookupEntity(table); |
149 | | - if (optionalEntity.isEmpty()) { |
150 | | - LOGGER.log(Level.FINE, new StringFormat("Entity not found for table <%s>", table)); |
151 | | - continue; |
152 | | - } |
153 | | - final Entity entity = optionalEntity.get(); |
154 | | - allEntities.add(entity); |
155 | | - } |
156 | | - return List.copyOf(allEntities); |
157 | | - } |
158 | | - |
159 | | - public String fkColumns(final ForeignKey foreignKey) { |
160 | | - if (foreignKey == null) { |
161 | | - return ""; |
162 | | - } |
163 | | - return MetaDataUtility.joinColumns( |
164 | | - foreignKey.getConstrainedColumns(), false, quotedIdentifiers); |
165 | | - } |
166 | | - |
167 | | - public boolean hasName(final DatabaseObject dbObject) { |
168 | | - return !MetaDataUtility.hasSystemGeneratedName(dbObject); |
169 | | - } |
170 | | - |
171 | | - public String indent(final String text, final int indent) { |
172 | | - if (text == null) { |
173 | | - return ""; |
174 | | - } |
175 | | - return text.indent(indent); |
176 | | - } |
177 | | - |
178 | | - public boolean isToMany(final TableReference fk) { |
179 | | - final RelationshipCardinality cardinality = ERModelUtility.inferCardinality(fk); |
180 | | - return EnumSet.of(many_many, one_many, zero_many).contains(cardinality); |
181 | | - } |
182 | | - |
183 | | - public List<Index> nonPrimaryIndexes(final Table table) { |
184 | | - final List<Index> indexes = new ArrayList<>(); |
185 | | - if (table == null || table.getIndexes() == null || table.getIndexes().isEmpty()) { |
186 | | - return indexes; |
187 | | - } |
188 | | - for (final Index index : table.getIndexes()) { |
189 | | - if (!isPrimaryKeyEquivalentIndex(table, index)) { |
190 | | - indexes.add(index); |
191 | | - } |
192 | | - } |
193 | | - return indexes; |
194 | | - } |
195 | | - |
196 | | - public String pkColumns(final ForeignKey foreignKey) { |
197 | | - if (foreignKey == null) { |
198 | | - return ""; |
199 | | - } |
200 | | - final List<Column> pkColumns = |
201 | | - foreignKey.getColumnReferences().stream() |
202 | | - .map(ColumnReference::getPrimaryKeyColumn) |
203 | | - .collect(toList()); |
204 | | - return MetaDataUtility.joinColumns(pkColumns, false, quotedIdentifiers); |
205 | | - } |
206 | | - |
207 | | - /** |
208 | | - * Puts remarks on a single line. |
209 | | - * |
210 | | - * @param describedObject Object with remarks |
211 | | - * @return Remarks on a single line |
212 | | - */ |
213 | | - public String remarks(final DescribedObject describedObject) { |
214 | | - if (describedObject == null || !describedObject.hasRemarks()) { |
215 | | - return ""; |
216 | | - } |
217 | | - return describedObject.getRemarks().replaceAll("\\R", " ").replace('"', '\'').strip(); |
218 | | - } |
219 | | - |
220 | | - public String stripName(final NamedObject namedObject) { |
221 | | - if (namedObject == null) { |
222 | | - return ""; |
223 | | - } |
224 | | - return namedObject.getName().replace("[^\\d\\w\\-]", ""); |
225 | | - } |
226 | | - |
227 | | - public TableReference tableReference(final Column column) { |
228 | | - if (MetaDataUtility.isPartial(column) || !column.isPartOfForeignKey()) { |
229 | | - return null; |
230 | | - } |
231 | | - final Table table = column.getParent(); |
232 | | - for (final ForeignKey foreignKey : table.getImportedForeignKeys()) { |
233 | | - for (final ColumnReference columnReference : foreignKey) { |
234 | | - if (column.equals(columnReference.getForeignKeyColumn())) { |
235 | | - return foreignKey; |
236 | | - } |
237 | | - } |
238 | | - } |
239 | | - return null; |
240 | | - } |
241 | | - |
242 | | - public String type(final Table table) { |
243 | | - return MetaDataUtility.getSimpleTypeName(table).toString(); |
244 | | - } |
245 | | - |
246 | | - /** |
247 | | - * This cardinality symbol syntax is used by Mermaid. When the graph is generated, the foreign key |
248 | | - * is on the left and the primary key is on the right. |
249 | | - * |
250 | | - * @param cardinality Relationship cardinality |
251 | | - * @return Mermaid cardinality symbol from foreign key to primary key |
252 | | - */ |
253 | | - private String cardinalitySymbol(final RelationshipCardinality cardinality) { |
254 | | - return switch (cardinality) { |
255 | | - case zero_one -> "|o--||"; |
256 | | - case zero_many -> "}o--||"; |
257 | | - case one_one -> "||--||"; |
258 | | - case one_many -> "}|--||"; |
259 | | - case many_many -> "}o--o{"; // bridge table implied |
260 | | - default -> "}o--||"; |
261 | | - }; |
262 | | - } |
263 | 12 |
|
264 | | - private boolean isPrimaryKeyEquivalentIndex(final Table table, final Index index) { |
265 | | - if (table == null || index == null || !table.hasPrimaryKey()) { |
266 | | - return false; |
267 | | - } |
268 | | - return Objects.equals(columns(table.getPrimaryKey()), columns(index)); |
269 | | - } |
270 | | -} |
| 13 | +public final class ScriptSupport extends AbstractExecutionState {} |
0 commit comments