use of org.jaxdb.www.ddlx_0_5.xLygluGCXAA.Schema in project jaxdb by jaxdb.
the class DDLxTest method recreateSchema.
// FIXME: The efficiency of this is TERRIBLE!
public static Schema recreateSchema(final Connection connection, final String ddlxFileName, final boolean unaltered) throws GeneratorExecutionException, IOException, SAXException, SQLException, TransformerException {
final DDLx ddlx = new DDLx(ClassLoader.getSystemClassLoader().getResource(ddlxFileName + ".ddlx"));
final Schema schema = ddlx.getMergedSchema();
if (!unaltered) {
final Dialect dialect = DBVendor.valueOf(connection.getMetaData()).getDialect();
for (final $Table table : schema.getTable()) {
if (table.getColumn() != null) {
for (final $Column column : table.getColumn()) {
if (column instanceof $Decimal) {
final $Decimal decimal = ($Decimal) column;
final int maxPrecision = dialect.decimalMaxPrecision();
decimal.setPrecision$(new $Decimal.Precision$(maxPrecision));
if (decimal.getScale$() != null && decimal.getScale$().text() > maxPrecision)
decimal.setScale$(new $Decimal.Scale$(maxPrecision));
}
}
}
}
}
final URL url = MemoryURLStreamHandler.createURL(schema.toString().getBytes());
Schemas.recreate(connection, url);
return schema;
}
use of org.jaxdb.www.ddlx_0_5.xLygluGCXAA.Schema in project jaxdb by jaxdb.
the class ReverseTest method testRecreateSchema.
@Test
public void testRecreateSchema(final Connection connection) throws GeneratorExecutionException, IOException, MarshalException, SAXException, SQLException, TransformerException, XPathExpressionException {
final Schema expected = recreateSchema(connection, "reverse", true);
sort(expected);
// logger.info(expected);
Schema actual = Decompiler.createDDL(connection);
// FIXME: Need to restrict which database/schema/tablespace we're looking at.
final Iterator<$Table> iterator = actual.getTable().iterator();
while (iterator.hasNext()) if (!iterator.next().getName$().text().startsWith("t_"))
iterator.remove();
sort(actual);
// logger.info(actual);
assertEqual(DBVendor.valueOf(connection.getMetaData()), expected, actual);
// logger.info(DOMs.domToString(actual.marshal(), Collections.singletonMap("http://www.jaxdb.org/ddlx.xsd", "http://www.jaxdb.org/ddlx.xsd"), DOMStyle.INDENT));
}
use of org.jaxdb.www.ddlx_0_5.xLygluGCXAA.Schema in project jaxdb by jaxdb.
the class DDLx method topologicalSort.
private static Schema topologicalSort(final Schema schema) {
final List<$Table> tables = new ArrayList<>(schema.getTable());
schema.getTable().clear();
tables.sort(tableNameComparator);
final RefDigraph<$Table, String> digraph = new RefDigraph<>(table -> table.getName$().text().toLowerCase());
for (final $Table table : tables) {
digraph.add(table);
if (table.getColumn() != null)
for (final $Column column : table.getColumn()) if (column.getForeignKey() != null)
digraph.add(table, column.getForeignKey().getReferences$().text().toLowerCase());
if (table.getConstraints() != null && table.getConstraints().getForeignKey() != null)
for (final $ForeignKeyComposite foreignKey : table.getConstraints().getForeignKey()) digraph.add(table, foreignKey.getReferences$().text().toLowerCase());
}
if (digraph.hasCycle())
throw new IllegalStateException("Cycle exists in relational model: " + CollectionUtil.toString(digraph.getCycle(), " -> "));
final List<$Table> topologialOrder = digraph.getTopologicalOrder();
final ListIterator<$Table> topological = topologialOrder.listIterator(digraph.size());
while (topological.hasPrevious()) schema.getTable().add(topological.previous());
return schema;
}
use of org.jaxdb.www.ddlx_0_5.xLygluGCXAA.Schema in project jaxdb by jaxdb.
the class DDLx method consolidateEnums.
private static void consolidateEnums(final Schema schema) {
final Map<String, String> enumToValues = new HashMap<>();
final List<$Column> templates = schema.getTemplate();
if (templates != null) {
for (final $Column template : templates) {
if (!(template instanceof $Enum))
throw new IllegalStateException("Input schema is not normalized");
enumToValues.put(template.getName$().text(), (($Enum) template).getValues$().text());
}
}
final Map<String, $Table> tableNameToTable = new HashMap<>();
for (final $Table table : schema.getTable()) {
tableNameToTable.put(table.getName$().text(), table);
if (table.getColumn() != null) {
for (final $Column column : table.getColumn()) {
if (column instanceof $Enum && column.getTemplate$() != null) {
final $Enum type = ($Enum) column;
final String values = enumToValues.get(column.getTemplate$().text());
type.setValues$(new $Enum.Values$(Objects.requireNonNull(values)));
}
}
}
}
}
use of org.jaxdb.www.ddlx_0_5.xLygluGCXAA.Schema in project jaxdb by jaxdb.
the class Decompiler method createDDL.
public static Schema createDDL(final Connection connection) throws SQLException {
final DBVendor vendor = DBVendor.valueOf(connection.getMetaData());
final Decompiler decompiler = Decompiler.getDecompiler(vendor);
final DatabaseMetaData metaData = connection.getMetaData();
try (final ResultSet tableRows = metaData.getTables(null, null, null, new String[] { "TABLE" })) {
final Schema schema = new Schema();
final Map<String, List<$CheckReference>> tableNameToChecks = decompiler.getCheckConstraints(connection);
final Map<String, List<$Table.Constraints.Unique>> tableNameToUniques = decompiler.getUniqueConstraints(connection);
final Map<String, $Table.Indexes> tableNameToIndexes = decompiler.getIndexes(connection);
final Map<String, Map<String, $ForeignKeyUnary>> tableNameToForeignKeys = decompiler.getForeignKeys(connection);
final Map<String, $Column> columnNameToColumn = new HashMap<>();
final Map<Integer, $Column> columnNumberToColumn = new TreeMap<>();
final Map<String, TreeMap<Short, String>> indexNameToIndex = new HashMap<>();
final Map<String, String> indexNameToType = new HashMap<>();
final Map<String, Boolean> indexNameToUnique = new HashMap<>();
while (tableRows.next()) {
final String tableName = tableRows.getString(3);
final $Table table = new Schema.Table();
table.setName$(new $Named.Name$(tableName.toLowerCase()));
schema.addTable(table);
try (final ResultSet columnRows = metaData.getColumns(null, null, tableName, null)) {
while (columnRows.next()) {
final String columnName = columnRows.getString("COLUMN_NAME").toLowerCase();
final String typeName = columnRows.getString("TYPE_NAME");
final int columnSize = columnRows.getInt("COLUMN_SIZE");
final String _default = columnRows.getString("COLUMN_DEF");
final int index = columnRows.getInt("ORDINAL_POSITION");
final String nullable = columnRows.getString("IS_NULLABLE");
final String autoIncrement = columnRows.getString("IS_AUTOINCREMENT");
final int decimalDigits = columnRows.getInt("DECIMAL_DIGITS");
final $Column column = decompiler.makeColumn(columnName.toLowerCase(), typeName, columnSize, decimalDigits, _default, nullable.length() == 0 ? null : "YES".equals(nullable), autoIncrement.length() == 0 ? null : "YES".equals(autoIncrement));
columnNameToColumn.put(columnName, column);
columnNumberToColumn.put(index, column);
}
columnNumberToColumn.values().forEach(table::addColumn);
try (final ResultSet primaryKeyRows = metaData.getPrimaryKeys(null, null, tableName)) {
while (primaryKeyRows.next()) {
final String columnName = primaryKeyRows.getString("COLUMN_NAME").toLowerCase();
if (table.getConstraints() == null)
table.setConstraints(new $Table.Constraints());
if (table.getConstraints().getPrimaryKey() == null)
table.getConstraints().setPrimaryKey(new $Table.Constraints.PrimaryKey());
final $Table.Constraints.PrimaryKey.Column column = new $Table.Constraints.PrimaryKey.Column();
column.setName$(new $Table.Constraints.PrimaryKey.Column.Name$(columnName));
table.getConstraints().getPrimaryKey().addColumn(column);
}
}
final List<$Table.Constraints.Unique> uniques = tableNameToUniques == null ? null : tableNameToUniques.get(tableName);
if (uniques != null && uniques.size() > 0) {
if (table.getConstraints() == null)
table.setConstraints(new $Table.Constraints());
for (final $Table.Constraints.Unique unique : uniques) table.getConstraints().addUnique(unique);
}
try (final ResultSet indexRows = metaData.getIndexInfo(null, null, tableName, false, true)) {
while (indexRows.next()) {
final String columnName = indexRows.getString("COLUMN_NAME").toLowerCase();
if (columnName == null)
continue;
final String indexName = indexRows.getString("INDEX_NAME").toLowerCase();
TreeMap<Short, String> indexes = indexNameToIndex.get(indexName);
if (indexes == null)
indexNameToIndex.put(indexName, indexes = new TreeMap<>());
final short ordinalPosition = indexRows.getShort("ORDINAL_POSITION");
indexes.put(ordinalPosition, columnName);
final String type = getType(indexRows.getShort("TYPE"));
final String currentType = indexNameToType.get(indexName);
if (currentType == null)
indexNameToType.put(indexName, type);
else if (!type.equals(currentType))
throw new IllegalStateException("Expected " + type + " = " + currentType);
final boolean unique = !indexRows.getBoolean("NON_UNIQUE");
final Boolean currentUnique = indexNameToUnique.get(indexName);
if (currentUnique == null)
indexNameToUnique.put(indexName, unique);
else if (unique != currentUnique)
throw new IllegalStateException("Expected " + unique + " = " + currentType);
}
}
final $Table.Indexes indexes = tableNameToIndexes == null ? null : tableNameToIndexes.get(tableName);
if (indexes != null)
table.setIndexes(indexes);
final List<$CheckReference> checks = tableNameToChecks == null ? null : tableNameToChecks.get(tableName);
if (checks != null)
for (final $CheckReference check : checks) addCheck(columnNameToColumn.get(check.getColumn$().text()), check);
final Map<String, $ForeignKeyUnary> foreignKeys = tableNameToForeignKeys == null ? null : tableNameToForeignKeys.get(tableName);
if (foreignKeys != null)
for (final Map.Entry<String, $ForeignKeyUnary> entry : foreignKeys.entrySet()) columnNameToColumn.get(entry.getKey().toLowerCase()).setForeignKey(entry.getValue());
}
columnNameToColumn.clear();
columnNumberToColumn.clear();
indexNameToIndex.clear();
indexNameToType.clear();
}
return schema;
}
}
Aggregations