Skip to content

Commit

Permalink
Support @Jsql:cache for ddlx:table and ddlx:primaryKey, re #86
Browse files Browse the repository at this point in the history
  • Loading branch information
safris committed Oct 2, 2023
1 parent f382d35 commit bcd716f
Show file tree
Hide file tree
Showing 24 changed files with 847 additions and 468 deletions.
109 changes: 50 additions & 59 deletions ddlx/src/main/java/org/jaxdb/ddlx/Compiler.java

Large diffs are not rendered by default.

165 changes: 151 additions & 14 deletions ddlx/src/main/java/org/jaxdb/ddlx/DDLx.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,29 +22,53 @@
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;

import javax.xml.transform.TransformerException;

import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$Bigint;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$Binary;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$Blob;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$Boolean;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$Char;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$Clob;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$Column;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$ColumnIndex;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$Columns;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$Date;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$Datetime;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$Decimal;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$Double;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$Enum;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$Float;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$ForeignKeyComposite;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$ForeignKeyUnary;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$IndexesIndex;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$IndexesIndex.Unique$;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$Int;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$Named;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$PrimaryKey;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$Smallint;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$TableCommon;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$TableCommon.Extends$;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$Time;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$Tinyint;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.Schema;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.Schema.Table;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.Schema.Table.Constraints;
import org.jaxsb.runtime.BindingList;
import org.jaxsb.runtime.Bindings;
import org.libj.util.CollectionUtil;
import org.libj.util.RefDigraph;
import org.openjax.xml.transform.Transformer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3.www._2001.XMLSchema.yAA.$AnyType;
import org.xml.sax.SAXException;

public class DDLx {
private static final Logger logger = LoggerFactory.getLogger(DDLx.class);
private static final Comparator<$TableCommon> tableNameComparator = (o1, o2) -> o1 == null ? o2 == null ? 0 : 1 : o2 == null ? -1 : o1.getName$().text().compareTo(o2.getName$().text());
private static final Comparator<$Named> tableNameComparator = (final $Named o1, final $Named o2) -> o1 == null ? o2 == null ? 0 : 1 : o2 == null ? -1 : o1.getName$().text().compareTo(o2.getName$().text());
private static final URL normalizeXsl;
private static final URL mergeXsl;

Expand All @@ -61,13 +85,125 @@ private static URL findResource(final String name) {
return url;
}

/*static $ForeignKeyUnary newForeignKey(final $Column column) {
if (column instanceof $Tinyint)
return new $Tinyint.ForeignKey();
if (column instanceof $Smallint)
return new $Smallint.ForeignKey();
if (column instanceof $Int)
return new $Int.ForeignKey();
if (column instanceof $Bigint)
return new $Bigint.ForeignKey();
if (column instanceof $Float)
return new $Float.ForeignKey();
if (column instanceof $Double)
return new $Double.ForeignKey();
if (column instanceof $Decimal)
return new $Decimal.ForeignKey();
if (column instanceof $Binary)
return new $Binary.ForeignKey();
if (column instanceof $Blob)
return new $Blob.ForeignKey();
if (column instanceof $Char)
return new $Char.ForeignKey();
if (column instanceof $Clob)
return new $Clob.ForeignKey();
if (column instanceof $Enum)
return new $Enum.ForeignKey();
if (column instanceof $Date)
return new $Date.ForeignKey();
if (column instanceof $Time)
return new $Time.ForeignKey();
if (column instanceof $Datetime)
return new $Datetime.ForeignKey();
if (column instanceof $Boolean)
return new $Boolean.ForeignKey();
throw new RuntimeException("Unknown column type: " + column.getClass().getName());
}*/

static void setForeignKey(final $Column column, final $ForeignKeyUnary foreignKey) {
if (column instanceof $Tinyint)
(($Tinyint)column).setForeignKey(foreignKey);
else if (column instanceof $Smallint)
(($Smallint)column).setForeignKey(foreignKey);
if (column instanceof $Int)
(($Int)column).setForeignKey(foreignKey);
else if (column instanceof $Bigint)
(($Bigint)column).setForeignKey(foreignKey);
else if (column instanceof $Float)
(($Float)column).setForeignKey(foreignKey);
else if (column instanceof $Double)
(($Double)column).setForeignKey(foreignKey);
else if (column instanceof $Decimal)
(($Decimal)column).setForeignKey(foreignKey);
else if (column instanceof $Binary)
(($Binary)column).setForeignKey(foreignKey);
else if (column instanceof $Blob)
(($Blob)column).setForeignKey(foreignKey);
else if (column instanceof $Char)
(($Char)column).setForeignKey(foreignKey);
else if (column instanceof $Clob)
(($Clob)column).setForeignKey(foreignKey);
else if (column instanceof $Enum)
(($Enum)column).setForeignKey(foreignKey);
else if (column instanceof $Date)
(($Date)column).setForeignKey(foreignKey);
else if (column instanceof $Time)
(($Time)column).setForeignKey(foreignKey);
else if (column instanceof $Datetime)
(($Datetime)column).setForeignKey(foreignKey);
else if (column instanceof $Boolean)
(($Boolean)column).setForeignKey(foreignKey);
else
throw new RuntimeException("Unknown column type: " + column.getClass().getName());
}

private static $AnyType<?> getChildElement(final $AnyType<String> element, final String localName) {
final Iterator<$AnyType<?>> childElements = element.elementIterator();
while (childElements.hasNext()) {
final $AnyType<?> childElement = childElements.next();
if (localName.equals(childElement.name().getLocalPart()))
return childElement;
}

return null;
}

public static $PrimaryKey getPrimaryKey(final Constraints column) {
return ($PrimaryKey)getChildElement(column, "primaryKey");
}

public static $ForeignKeyUnary getForeignKey(final $Column column) {
return ($ForeignKeyUnary)getChildElement(column, "foreignKey");
}

public static $ColumnIndex getIndex(final $Column column) {
return ($ColumnIndex)getChildElement(column, "index");
}

private static Schema topologicalSort(final Schema schema) {
final ArrayList<$TableCommon> tables = new ArrayList<>(schema.getTable());
final ArrayList<Table> tables = new ArrayList<>(schema.getTable());
schema.getTable().clear();
tables.sort(tableNameComparator);
final RefDigraph<Schema.Table,String> digraph = new RefDigraph<>(table -> table.getName$().text());
final RefDigraph<Table,String> digraph = new RefDigraph<>((final Table table) -> table.getName$().text());
for (int i = 0, i$ = tables.size(); i < i$; ++i) { // [RA]
final Schema.Table table = (Schema.Table)tables.get(i);
final Table table = tables.get(i);
digraph.add(table);
final Extends$ extends$ = table.getExtends$();
if (extends$ != null)
Expand All @@ -76,13 +212,13 @@ private static Schema topologicalSort(final Schema schema) {
final BindingList<$Column> columns = table.getColumn();
if (columns != null) {
for (int j = 0, j$ = columns.size(); j < j$; ++j) { // [RA]
final $Column column = columns.get(j);
if (column.getForeignKey() != null)
digraph.add(table, column.getForeignKey().getReferences$().text());
final $ForeignKeyUnary foreignKey = getForeignKey(columns.get(j));
if (foreignKey != null)
digraph.add(table, foreignKey.getReferences$().text());
}
}

final Schema.Table.Constraints constraints = table.getConstraints();
final Table.Constraints constraints = table.getConstraints();
if (constraints != null) {
final BindingList<$ForeignKeyComposite> foreignKeys = constraints.getForeignKey();
if (foreignKeys != null) {
Expand All @@ -95,7 +231,7 @@ private static Schema topologicalSort(final Schema schema) {
if (digraph.hasCycle())
throw new IllegalStateException("Cycle exists in relational model: " + CollectionUtil.toString(digraph.getCycle(), " -> "));

final ArrayList<Schema.Table> topologicalOrder = digraph.getTopologicalOrder();
final ArrayList<Table> topologicalOrder = digraph.getTopologicalOrder();
for (int i = topologicalOrder.size() - 1; i >= 0; --i) // [RA]
schema.getTable().add(topologicalOrder.get(i));

Expand All @@ -118,7 +254,7 @@ public DDLx(final URL url) throws IOException, SAXException, TransformerExceptio

this.mergedXml = Transformer.transform(mergeXsl, normalizeddXml, null);
this.mergedSchema = topologicalSort((Schema)Bindings.parse(mergedXml));
final BindingList<Schema.Table> tables = mergedSchema.getTable();
final BindingList<Table> tables = mergedSchema.getTable();
for (int i = 0, i$ = tables.size(); i < i$; ++i) { // [RA]
final $TableCommon table = tables.get(i);
if (table.getExtends$() != null)
Expand All @@ -127,8 +263,8 @@ public DDLx(final URL url) throws IOException, SAXException, TransformerExceptio
}

// FIXME: Remove this.
public boolean isUnique(final Schema.Table table, final $Named column) {
final Schema.Table.Constraints constraints = table.getConstraints();
public boolean isUnique(final Table table, final $Named column) {
final Table.Constraints constraints = table.getConstraints();
if (constraints != null) {
final BindingList<$Columns> uniques = constraints.getUnique();
if (uniques != null) {
Expand All @@ -140,13 +276,14 @@ public boolean isUnique(final Schema.Table table, final $Named column) {
}
}

final Schema.Table.Indexes tableIndexes = table.getIndexes();
final Table.Indexes tableIndexes = table.getIndexes();
if (tableIndexes != null) {
final BindingList<$IndexesIndex> indexes = tableIndexes.getIndex();
if (indexes != null) {
for (int i = 0, i$ = indexes.size(); i < i$; ++i) { // [RA]
final $IndexesIndex index = indexes.get(i);
if (index.getUnique$() != null && index.getUnique$().text() && index.getColumn().size() == 1 && column.getName$().text().equals(index.getColumn(0).getName$().text()))
final Unique$ unique$ = index.getUnique$();
if (unique$ != null && unique$.text() && index.getColumn().size() == 1 && column.getName$().text().equals(index.getColumn(0).getName$().text()))
return true;
}
}
Expand Down
43 changes: 23 additions & 20 deletions ddlx/src/main/java/org/jaxdb/ddlx/Decompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.RandomAccess;
import java.util.TreeMap;

import org.jaxdb.vendor.DbVendor;
Expand Down Expand Up @@ -59,7 +58,6 @@
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$Tinyint;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$TinyintCheck;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.Schema;
import org.jaxsb.runtime.BindingList;

abstract class Decompiler {
private static final Decompiler[] decompilers = {
Expand All @@ -86,15 +84,15 @@ public static Schema createDDL(final Connection connection) throws SQLException
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,BindingList<$CheckReference>> tableNameToChecks = decompiler.getCheckConstraints(connection);
final Map<String,BindingList<Schema.Table.Constraints.Unique>> tableNameToUniques = decompiler.getUniqueConstraints(connection);
final Map<String,ArrayList<$CheckReference>> tableNameToChecks = decompiler.getCheckConstraints(connection);
final Map<String,ArrayList<Schema.Table.Constraints.Unique>> tableNameToUniques = decompiler.getUniqueConstraints(connection);
final Map<String,Schema.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<>();
final HashMap<String,$Column> columnNameToColumn = new HashMap<>();
final TreeMap<Integer,$Column> columnNumberToColumn = new TreeMap<>();
final HashMap<String,TreeMap<Short,String>> indexNameToIndex = new HashMap<>();
final HashMap<String,String> indexNameToType = new HashMap<>();
final HashMap<String,Boolean> indexNameToUnique = new HashMap<>();
while (tableRows.next()) {
final String tableName = tableRows.getString(3);
final Schema.Table table = new Schema.Table();
Expand Down Expand Up @@ -133,7 +131,7 @@ public static Schema createDDL(final Connection connection) throws SQLException
}
}

final BindingList<Schema.Table.Constraints.Unique> uniques = tableNameToUniques == null ? null : tableNameToUniques.get(tableName);
final ArrayList<Schema.Table.Constraints.Unique> uniques = tableNameToUniques == null ? null : tableNameToUniques.get(tableName);
if (uniques != null && uniques.size() > 0) {
if (table.getConstraints() == null)
table.setConstraints(new Schema.Table.Constraints());
Expand Down Expand Up @@ -176,7 +174,7 @@ else if (unique != currentUnique)
if (indexes != null)
table.setIndexes(indexes);

final BindingList<$CheckReference> checks = tableNameToChecks == null ? null : tableNameToChecks.get(tableName);
final ArrayList<$CheckReference> checks = tableNameToChecks == null ? null : tableNameToChecks.get(tableName);
if (checks != null) {
for (int i = 0, i$ = checks.size(); i < i$; ++i) { // [RA]
final $CheckReference check = checks.get(i);
Expand All @@ -187,7 +185,7 @@ else if (unique != currentUnique)
final Map<String,$ForeignKeyUnary> foreignKeys = tableNameToForeignKeys == null ? null : tableNameToForeignKeys.get(tableName);
if (foreignKeys != null)
for (final Map.Entry<String,$ForeignKeyUnary> entry : foreignKeys.entrySet()) // [S]
columnNameToColumn.get(entry.getKey().toLowerCase()).setForeignKey(entry.getValue());
DDLx.setForeignKey(columnNameToColumn.get(entry.getKey().toLowerCase()), entry.getValue());
}

columnNameToColumn.clear();
Expand Down Expand Up @@ -248,8 +246,8 @@ else if (check instanceof $DecimalCheck)

abstract DbVendor getVendor();
abstract $Column makeColumn(String columnName, String typeName, long size, int decimalDigits, String _default, Boolean nullable, Boolean autoIncrement);
abstract <L extends List<$CheckReference> & RandomAccess> Map<String,L> getCheckConstraints(Connection connection) throws SQLException;
abstract <L extends List<Schema.Table.Constraints.Unique> & RandomAccess> Map<String,L> getUniqueConstraints(Connection connection) throws SQLException;
abstract Map<String,ArrayList<$CheckReference>> getCheckConstraints(Connection connection) throws SQLException;
abstract Map<String,ArrayList<Schema.Table.Constraints.Unique>> getUniqueConstraints(Connection connection) throws SQLException;
abstract Map<String,Schema.Table.Indexes> getIndexes(Connection connection) throws SQLException;

private static $ChangeRule.Enum toBinding(final short rule) {
Expand All @@ -276,7 +274,7 @@ else if (check instanceof $DecimalCheck)
Map<String,Map<String,$ForeignKeyUnary>> getForeignKeys(final Connection connection) throws SQLException {
final DatabaseMetaData metaData = connection.getMetaData();
try (final ResultSet foreignKeyRows = metaData.getImportedKeys(null, null, null)) {
final Map<String,Map<String,$ForeignKeyUnary>> tableNameToForeignKeys = new HashMap<>();
final HashMap<String,Map<String,$ForeignKeyUnary>> tableNameToForeignKeys = new HashMap<>();
String lastTable = null;
Map<String,$ForeignKeyUnary> columnNameToForeignKey = null;
while (foreignKeyRows.next()) {
Expand All @@ -291,17 +289,22 @@ else if (check instanceof $DecimalCheck)
final String columnName = foreignKeyRows.getString("FKCOLUMN_NAME").toLowerCase();
final short updateRule = foreignKeyRows.getShort("UPDATE_RULE");
final short deleteRule = foreignKeyRows.getShort("DELETE_RULE");
final $ForeignKeyUnary foreignKey = new $Column.ForeignKey();
foreignKey.setReferences$(new $Column.ForeignKey.References$(primaryTable));
final $ForeignKeyUnary foreignKey = new $ForeignKeyUnary() {
@Override
protected $ForeignKeyUnary inherits() {
return null;
}
};
foreignKey.setReferences$(new $ForeignKeyUnary.References$(primaryTable));
foreignKey.setColumn$(new Column$(primaryColumn));

final $ChangeRule.Enum onUpdate = toBinding(updateRule);
if (onUpdate != null)
foreignKey.setOnUpdate$(new $Column.ForeignKey.OnUpdate$(onUpdate));
foreignKey.setOnUpdate$(new $ForeignKeyUnary.OnUpdate$(onUpdate));

final $ChangeRule.Enum onDelete = toBinding(deleteRule);
if (onDelete != null)
foreignKey.setOnDelete$(new $Column.ForeignKey.OnDelete$(onDelete));
foreignKey.setOnDelete$(new $ForeignKeyUnary.OnDelete$(onDelete));

columnNameToForeignKey.put(columnName, foreignKey);
}
Expand Down
4 changes: 2 additions & 2 deletions ddlx/src/main/java/org/jaxdb/ddlx/DerbyCompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@
import org.jaxdb.vendor.DbVendor;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$ChangeRule;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$Column;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$Constraints.PrimaryKey;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$IndexType;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$Integer;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$Named;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.$PrimaryKey;
import org.jaxdb.www.ddlx_0_6.xLygluGCXAA.Schema;
import org.libj.io.Readers;
import org.slf4j.Logger;
Expand Down Expand Up @@ -183,7 +183,7 @@ StringBuilder onUpdate(final StringBuilder b, final $ChangeRule onUpdate) {
}

@Override
StringBuilder primaryKey(final StringBuilder b, final Schema.Table table, final int[] columns, final PrimaryKey.Using$ using) {
StringBuilder primaryKey(final StringBuilder b, final Schema.Table table, final int[] columns, final $PrimaryKey.Using$ using) {
return super.primaryKey(b, table, columns, null);
}

Expand Down

0 comments on commit bcd716f

Please sign in to comment.