From a68a20cb0f29a5768a52271f196ef72d7cc12287 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Fri, 6 Nov 2020 17:05:47 +0100 Subject: [PATCH] [jOOQ/jOOQ#10546] Added Meta.getUniqueKeys(), getForeignKeys() --- jOOQ/src/main/java/org/jooq/Meta.java | 100 ++++++++++ .../main/java/org/jooq/impl/AbstractMeta.java | 178 ++++++++++++++++-- .../java/org/jooq/impl/AbstractTable.java | 3 +- 3 files changed, 262 insertions(+), 19 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/Meta.java b/jOOQ/src/main/java/org/jooq/Meta.java index 66fd8cbcdd..1720a40d9c 100644 --- a/jOOQ/src/main/java/org/jooq/Meta.java +++ b/jOOQ/src/main/java/org/jooq/Meta.java @@ -251,6 +251,86 @@ public interface Meta extends Scope { @Support List> getPrimaryKeys() throws DataAccessException; + /** + * Get all primary keys from the underlying meta data source. + * + * @throws DataAccessException If something went wrong fetching the meta + * objects + */ + @NotNull + @Support + List> getPrimaryKeys(String name) throws DataAccessException; + + /** + * Get all primary keys from the underlying meta data source. + * + * @throws DataAccessException If something went wrong fetching the meta + * objects + */ + @NotNull + @Support + List> getPrimaryKeys(Name name) throws DataAccessException; + + /** + * Get all unique keys from the underlying meta data source. + * + * @throws DataAccessException If something went wrong fetching the meta + * objects + */ + @NotNull + @Support + List> getUniqueKeys() throws DataAccessException; + + /** + * Get all unique keys from the underlying meta data source. + * + * @throws DataAccessException If something went wrong fetching the meta + * objects + */ + @NotNull + @Support + List> getUniqueKeys(String name) throws DataAccessException; + + /** + * Get all unique keys from the underlying meta data source. + * + * @throws DataAccessException If something went wrong fetching the meta + * objects + */ + @NotNull + @Support + List> getUniqueKeys(Name name) throws DataAccessException; + + /** + * Get all foreign keys from the underlying meta data source. + * + * @throws DataAccessException If something went wrong fetching the meta + * objects + */ + @NotNull + @Support + List> getForeignKeys() throws DataAccessException; + + /** + * Get all foreign keys from the underlying meta data source. + * + * @throws DataAccessException If something went wrong fetching the meta + * objects + */ + @NotNull + @Support + List> getForeignKeys(String name) throws DataAccessException; + + /** + * Get all foreign keys from the underlying meta data source. + * + * @throws DataAccessException If something went wrong fetching the meta + * objects + */ + @NotNull + @Support + List> getForeignKeys(Name name) throws DataAccessException; + /** * Get all indexes from the underlying meta data sources. * @@ -261,6 +341,26 @@ public interface Meta extends Scope { @Support List getIndexes() throws DataAccessException; + /** + * Get all indexes from the underlying meta data sources. + * + * @throws DataAccessException If something went wrong fetching the meta + * objects + */ + @NotNull + @Support + List getIndexes(String name) throws DataAccessException; + + /** + * Get all indexes from the underlying meta data sources. + * + * @throws DataAccessException If something went wrong fetching the meta + * objects + */ + @NotNull + @Support + List getIndexes(Name name) throws DataAccessException; + /** * A predicate to filter out query parts of a given type from meta data. */ diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractMeta.java b/jOOQ/src/main/java/org/jooq/impl/AbstractMeta.java index b156b78c0a..79b1ad075b 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractMeta.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractMeta.java @@ -71,20 +71,26 @@ import org.jooq.util.xml.jaxb.InformationSchema; */ abstract class AbstractMeta extends AbstractScope implements Meta, Serializable { - private static final long serialVersionUID = 910484713008245977L; + private static final long serialVersionUID = 910484713008245977L; // [#9010] TODO: Allow for opting out of this cache - private Map cachedCatalogs; - private Map cachedQualifiedSchemas; - private Map> cachedQualifiedTables; - private Map> cachedQualifiedDomains; - private Map> cachedQualifiedSequences; - private Map> cachedUnqualifiedSchemas; - private Map>> cachedUnqualifiedTables; - private Map>> cachedUnqualifiedDomains; - private Map>> cachedUnqualifiedSequences; - private List> cachedPrimaryKeys; - private List cachedIndexes; + private Map cachedCatalogs; + private Map cachedQualifiedSchemas; + private Map> cachedQualifiedTables; + private Map> cachedQualifiedDomains; + private Map> cachedQualifiedSequences; + private Map> cachedQualifiedPrimaryKeys; + private Map> cachedQualifiedUniqueKeys; + private Map> cachedQualifiedForeignKeys; + private Map cachedQualifiedIndexes; + private Map> cachedUnqualifiedSchemas; + private Map>> cachedUnqualifiedTables; + private Map>> cachedUnqualifiedDomains; + private Map>> cachedUnqualifiedSequences; + private Map>> cachedUnqualifiedPrimaryKeys; + private Map>> cachedUnqualifiedUniqueKeys; + private Map>> cachedUnqualifiedForeignKeys; + private Map> cachedUnqualifiedIndexes; AbstractMeta(Configuration configuration) { super(configuration); @@ -294,15 +300,39 @@ abstract class AbstractMeta extends AbstractScope implements Meta, Serializable return result; } + @Override + public final List> getPrimaryKeys(String name) { + return getPrimaryKeys(name(name)); + } + + @Override + public final List> getPrimaryKeys(Name name) { + initPrimaryKeys(); + return get(name, new Iterable>() { + @Override + public Iterator> iterator() { + return getPrimaryKeys().iterator(); + } + }, cachedQualifiedPrimaryKeys, cachedUnqualifiedPrimaryKeys); + } + @Override public final List> getPrimaryKeys() { initPrimaryKeys(); - return Collections.unmodifiableList(cachedPrimaryKeys); + return Collections.unmodifiableList(new ArrayList<>(cachedQualifiedPrimaryKeys.values())); } private final void initPrimaryKeys() { - if (cachedPrimaryKeys == null) - cachedPrimaryKeys = new ArrayList<>(getPrimaryKeys0()); + if (cachedQualifiedPrimaryKeys == null) { + cachedQualifiedPrimaryKeys = new LinkedHashMap<>(); + cachedUnqualifiedPrimaryKeys = new LinkedHashMap<>(); + get(name(""), new Iterable>() { + @Override + public Iterator> iterator() { + return getPrimaryKeys0().iterator(); + } + }, cachedQualifiedPrimaryKeys, cachedUnqualifiedPrimaryKeys); + } } List> getPrimaryKeys0() { @@ -315,15 +345,127 @@ abstract class AbstractMeta extends AbstractScope implements Meta, Serializable return result; } + @Override + public final List> getUniqueKeys(String name) { + return getUniqueKeys(name(name)); + } + + @Override + public final List> getUniqueKeys(Name name) { + initUniqueKeys(); + return get(name, new Iterable>() { + @Override + public Iterator> iterator() { + return getUniqueKeys().iterator(); + } + }, cachedQualifiedUniqueKeys, cachedUnqualifiedUniqueKeys); + } + + @Override + public final List> getUniqueKeys() { + initUniqueKeys(); + return Collections.unmodifiableList(new ArrayList<>(cachedQualifiedUniqueKeys.values())); + } + + private final void initUniqueKeys() { + if (cachedQualifiedUniqueKeys == null) { + cachedQualifiedUniqueKeys = new LinkedHashMap<>(); + cachedUnqualifiedUniqueKeys = new LinkedHashMap<>(); + get(name(""), new Iterable>() { + @Override + public Iterator> iterator() { + return getUniqueKeys0().iterator(); + } + }, cachedQualifiedUniqueKeys, cachedUnqualifiedUniqueKeys); + } + } + + List> getUniqueKeys0() { + List> result = new ArrayList<>(); + + for (Table table : getTables()) + result.addAll(table.getUniqueKeys()); + + return result; + } + + @Override + public final List> getForeignKeys(String name) { + return getForeignKeys(name(name)); + } + + @Override + public final List> getForeignKeys(Name name) { + initForeignKeys(); + return get(name, new Iterable>() { + @Override + public Iterator> iterator() { + return getForeignKeys().iterator(); + } + }, cachedQualifiedForeignKeys, cachedUnqualifiedForeignKeys); + } + + @Override + public final List> getForeignKeys() { + initForeignKeys(); + return Collections.unmodifiableList(new ArrayList<>(cachedQualifiedForeignKeys.values())); + } + + private final void initForeignKeys() { + if (cachedQualifiedForeignKeys == null) { + cachedQualifiedForeignKeys = new LinkedHashMap<>(); + cachedUnqualifiedForeignKeys = new LinkedHashMap<>(); + get(name(""), new Iterable>() { + @Override + public Iterator> iterator() { + return getForeignKeys0().iterator(); + } + }, cachedQualifiedForeignKeys, cachedUnqualifiedForeignKeys); + } + } + + List> getForeignKeys0() { + List> result = new ArrayList<>(); + + for (Table table : getTables()) + result.addAll(table.getReferences()); + + return result; + } + + @Override + public final List getIndexes(String name) { + return getIndexes(name(name)); + } + + @Override + public final List getIndexes(Name name) { + initIndexes(); + return get(name, new Iterable() { + @Override + public Iterator iterator() { + return getIndexes().iterator(); + } + }, cachedQualifiedIndexes, cachedUnqualifiedIndexes); + } + @Override public final List getIndexes() { initIndexes(); - return Collections.unmodifiableList(cachedIndexes); + return Collections.unmodifiableList(new ArrayList<>(cachedQualifiedIndexes.values())); } private final void initIndexes() { - if (cachedIndexes == null) - cachedIndexes = new ArrayList<>(getIndexes0()); + if (cachedQualifiedIndexes == null) { + cachedQualifiedIndexes = new LinkedHashMap<>(); + cachedUnqualifiedIndexes = new LinkedHashMap<>(); + get(name(""), new Iterable() { + @Override + public Iterator iterator() { + return getIndexes0().iterator(); + } + }, cachedQualifiedIndexes, cachedUnqualifiedIndexes); + } } List getIndexes0() { diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractTable.java b/jOOQ/src/main/java/org/jooq/impl/AbstractTable.java index 7e4d8b713a..28863f6969 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractTable.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractTable.java @@ -513,12 +513,13 @@ abstract class AbstractTable extends AbstractNamed implements */ @Override public List> getKeys() { - List> result = new ArrayList<>(getUniqueKeys()); + List> result = new ArrayList<>(); UniqueKey pk = getPrimaryKey(); if (pk != null) result.add(pk); + result.addAll(getUniqueKeys()); return result; }