From eba0cb2d448dbb7cb1e8cc9b59d6f466019ad369 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Mon, 4 Aug 2014 11:21:06 +0200 Subject: [PATCH] [#3488] Compilation error in generated code, when a similar tables T_A and TA exist --- .../java/org/jooq/util/JavaGenerator.java | 29 +++++++++++++++++++ .../java/org/jooq/util/AbstractDatabase.java | 27 ++++++++++++++--- .../AbstractElementContainerDefinition.java | 2 +- .../src/main/java/org/jooq/util/Database.java | 22 ++++++++++++++ .../resources/org/jooq/test/h2/create.sql | 21 +++++++++++--- 5 files changed, 92 insertions(+), 9 deletions(-) diff --git a/jOOQ-codegen/src/main/java/org/jooq/util/JavaGenerator.java b/jOOQ-codegen/src/main/java/org/jooq/util/JavaGenerator.java index e0157a3dbd..772d571510 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/util/JavaGenerator.java +++ b/jOOQ-codegen/src/main/java/org/jooq/util/JavaGenerator.java @@ -51,8 +51,10 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.regex.Pattern; @@ -141,6 +143,7 @@ public class JavaGenerator extends AbstractGenerator { @Override public final void generate(Database db) { this.database = db; + this.database.addFilter(new AvoidAmbiguousClassesFilter()); String url = ""; try { @@ -314,6 +317,32 @@ public class JavaGenerator extends AbstractGenerator { watch.splitInfo("GENERATION FINISHED!"); } + private class AvoidAmbiguousClassesFilter implements Database.Filter { + + private Map included = new HashMap(); + + @Override + public boolean exclude(Definition definition) { + + // These definitions don't generate types of their own. + if ( definition instanceof ColumnDefinition + || definition instanceof AttributeDefinition + || definition instanceof ParameterDefinition) + return false; + + // Check if we've previously encountered a Java type of the same case-insensitive, fully-qualified name. + String name = getStrategy().getFullJavaClassName(definition); + String nameLC = name.toLowerCase(); + String existing = included.put(nameLC, name); + + if (existing == null) + return false; + + log.warn("Ambiguous type name", "The object " + definition.getQualifiedOutputName() + " generates a type " + name + " which conflicts with the existing type " + existing + " on some operating systems. Use a custom generator strategy to disambiguate the types."); + return true; + } + } + /* [pro] xx xxxxxxxxx xxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxx x xxxxxxxxxxxxxx xxxxxxxxxxxxxx x xxxxxxxxxxxxxxxx xxxxxxxxx diff --git a/jOOQ-meta/src/main/java/org/jooq/util/AbstractDatabase.java b/jOOQ-meta/src/main/java/org/jooq/util/AbstractDatabase.java index 81b323b9f9..d7ae081858 100644 --- a/jOOQ-meta/src/main/java/org/jooq/util/AbstractDatabase.java +++ b/jOOQ-meta/src/main/java/org/jooq/util/AbstractDatabase.java @@ -50,6 +50,7 @@ import java.math.BigInteger; import java.sql.Connection; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; @@ -91,6 +92,7 @@ public abstract class AbstractDatabase implements Database { private SQLDialect dialect; private Connection connection; private DSLContext create; + private List filters; private String[] excludes; private String[] includes; private boolean includeExcludeColumns; @@ -142,6 +144,7 @@ public abstract class AbstractDatabase implements Database { protected AbstractDatabase() { exists = new HashMap, Boolean>(); + filters = new ArrayList(); } @Override @@ -294,6 +297,16 @@ public abstract class AbstractDatabase implements Database { return properties; } + @Override + public final List getFilters() { + return Collections.unmodifiableList(filters); + } + + @Override + public final void addFilter(Filter filter) { + filters.add(filter); + } + @Override public final void setExcludes(String[] excludes) { this.excludes = excludes; @@ -833,10 +846,10 @@ public abstract class AbstractDatabase implements Database { } protected final List filterExcludeInclude(List definitions) { - return filterExcludeInclude(definitions, excludes, includes); + return filterExcludeInclude(definitions, excludes, includes, filters); } - protected static final List filterExcludeInclude(List definitions, String[] excludes, String[] includes) { + protected static final List filterExcludeInclude(List definitions, String[] excludes, String[] includes, List filters) { List result = new ArrayList(); definitionsLoop: for (T definition : definitions) { @@ -853,6 +866,12 @@ public abstract class AbstractDatabase implements Database { } } + for (Filter filter : filters) { + if (filter.exclude(definition)) { + continue definitionsLoop; + } + } + if (includes != null) { for (String include : includes) { Pattern p = Pattern.compile(include, Pattern.COMMENTS); @@ -944,7 +963,7 @@ public abstract class AbstractDatabase implements Database { for (SchemaDefinition schema : getSchemata()) { for (TableDefinition table : schema.getTables()) { - List columns = filterExcludeInclude(table.getColumns(), null, getSyntheticPrimaryKeys()); + List columns = filterExcludeInclude(table.getColumns(), null, getSyntheticPrimaryKeys(), filters); if (!columns.isEmpty()) { DefaultUniqueKeyDefinition syntheticKey = new DefaultUniqueKeyDefinition(schema, "SYNTHETIC_PK_" + table.getName(), table, true); @@ -963,7 +982,7 @@ public abstract class AbstractDatabase implements Database { private final void overridePrimaryKeys(DefaultRelations r) { List allKeys = r.getUniqueKeys(); - List filteredKeys = filterExcludeInclude(allKeys, null, overridePrimaryKeys); + List filteredKeys = filterExcludeInclude(allKeys, null, overridePrimaryKeys, filters); log.info("Overriding primary keys", fetchedSize(allKeys, filteredKeys)); diff --git a/jOOQ-meta/src/main/java/org/jooq/util/AbstractElementContainerDefinition.java b/jOOQ-meta/src/main/java/org/jooq/util/AbstractElementContainerDefinition.java index 627c55bc30..ac62315505 100644 --- a/jOOQ-meta/src/main/java/org/jooq/util/AbstractElementContainerDefinition.java +++ b/jOOQ-meta/src/main/java/org/jooq/util/AbstractElementContainerDefinition.java @@ -91,7 +91,7 @@ extends AbstractDefinition { // [#2603] Filter exclude / include also for table columns if (this instanceof TableDefinition && db.getIncludeExcludeColumns()) { - elements = filterExcludeInclude(e, db.getExcludes(), db.getIncludes()); + elements = filterExcludeInclude(e, db.getExcludes(), db.getIncludes(), db.getFilters()); log.info("Columns fetched", fetchedSize(e, elements)); } else { diff --git a/jOOQ-meta/src/main/java/org/jooq/util/Database.java b/jOOQ-meta/src/main/java/org/jooq/util/Database.java index d345ca8400..ccdb34efda 100644 --- a/jOOQ-meta/src/main/java/org/jooq/util/Database.java +++ b/jOOQ-meta/src/main/java/org/jooq/util/Database.java @@ -236,6 +236,17 @@ public interface Database { */ boolean getIncludeExcludeColumns(); + /** + * [#3488] Add an additional filter to the database that is applied in + * addition to include / exclude. + */ + void addFilter(Filter filter); + + /** + * [#3488] The filters that are applied in addition to include / exclude. + */ + List getFilters(); + /** * Table columns matching these regular expressions will be considered as * record version fields in generated code. @@ -381,4 +392,15 @@ public interface Database { * Database properties. */ void setProperties(Properties properties); + + /** + * A filter type that can be used with {@link Database#addFilter(Filter)} + */ + public interface Filter { + + /** + * Whether to include an object in this database. + */ + boolean exclude(Definition definition); + } } diff --git a/jOOQ-test/src/main/resources/org/jooq/test/h2/create.sql b/jOOQ-test/src/main/resources/org/jooq/test/h2/create.sql index 970ac51b7c..2d429bc27d 100644 --- a/jOOQ-test/src/main/resources/org/jooq/test/h2/create.sql +++ b/jOOQ-test/src/main/resources/org/jooq/test/h2/create.sql @@ -201,18 +201,31 @@ CREATE TABLE t_2718 ( / CREATE TABLE t_3488_abc_xyz_eee ( - ID INT + ID INT, + + CONSTRAINT pk_t_3488_1 PRIMARY KEY (ID) )/ CREATE TABLE t_3488_abcxyz_eee ( - ID INT + ID INT, + + CONSTRAINT pk_t_3488_2 PRIMARY KEY (ID) )/ CREATE TABLE t_3488_abc_xyzeee ( - ID INT + ID INT, + + CONSTRAINT pk_t_3488_3 PRIMARY KEY (ID) )/ CREATE TABLE t_3488_abcxyzeee ( - ID INT + ID INT, + + CONSTRAINT pk_t_3488_4 PRIMARY KEY (ID) )/ +ALTER TABLE t_3488_abc_xyz_eee ADD CONSTRAINT fk_t_3488_1 FOREIGN KEY (ID) REFERENCES t_3488_abcxyzeee (ID)/ +ALTER TABLE t_3488_abcxyz_eee ADD CONSTRAINT fk_t_3488_2 FOREIGN KEY (ID) REFERENCES t_3488_abc_xyz_eee (ID)/ +ALTER TABLE t_3488_abc_xyzeee ADD CONSTRAINT fk_t_3488_3 FOREIGN KEY (ID) REFERENCES t_3488_abcxyz_eee (ID)/ +ALTER TABLE t_3488_abcxyzeee ADD CONSTRAINT fk_t_3488_4 FOREIGN KEY (ID) REFERENCES t_3488_abc_xyzeee (ID)/ + CREATE TABLE t_author ( ID INT NOT NULL, FIRST_NAME VARCHAR(50),