diff --git a/jOOQ/src/main/java/org/jooq/DDLExportConfiguration.java b/jOOQ/src/main/java/org/jooq/DDLExportConfiguration.java
index 06a2be31c0..8539723318 100644
--- a/jOOQ/src/main/java/org/jooq/DDLExportConfiguration.java
+++ b/jOOQ/src/main/java/org/jooq/DDLExportConfiguration.java
@@ -56,6 +56,7 @@ public final class DDLExportConfiguration {
private final boolean createSchemaIfNotExists;
private final boolean createTableIfNotExists;
private final boolean createIndexIfNotExists;
+ private final boolean createDomainIfNotExists;
private final boolean createSequenceIfNotExists;
private final boolean createViewIfNotExists;
private final boolean createOrReplaceView;
@@ -66,6 +67,7 @@ public final class DDLExportConfiguration {
private final boolean respectColumnOrder;
private final boolean respectConstraintOrder;
private final boolean respectIndexOrder;
+ private final boolean respectDomainOrder;
private final boolean respectSequenceOrder;
private final boolean defaultSequenceFlags;
@@ -83,6 +85,7 @@ public final class DDLExportConfiguration {
false,
false,
false,
+ false,
false,
false,
@@ -91,6 +94,7 @@ public final class DDLExportConfiguration {
false,
false,
false,
+ false,
false
);
@@ -102,6 +106,7 @@ public final class DDLExportConfiguration {
boolean createSchemaIfNotExists,
boolean createTableIfNotExists,
boolean createIndexIfNotExists,
+ boolean createDomainIfNotExists,
boolean createSequenceIfNotExists,
boolean createViewIfNotExists,
boolean createOrReplaceView,
@@ -112,6 +117,7 @@ public final class DDLExportConfiguration {
boolean respectColumnOrder,
boolean respectConstraintOrder,
boolean respectIndexOrder,
+ boolean respectDomainOrder,
boolean respectSequenceOrder,
boolean defaultSequenceFlags
@@ -121,6 +127,7 @@ public final class DDLExportConfiguration {
this.createSchemaIfNotExists = createSchemaIfNotExists;
this.createTableIfNotExists = createTableIfNotExists;
this.createIndexIfNotExists = createIndexIfNotExists;
+ this.createDomainIfNotExists = createDomainIfNotExists;
this.createSequenceIfNotExists = createSequenceIfNotExists;
this.createViewIfNotExists = createViewIfNotExists;
this.createOrReplaceView = createOrReplaceView;
@@ -131,7 +138,9 @@ public final class DDLExportConfiguration {
this.respectColumnOrder = respectColumnOrder;
this.respectConstraintOrder = respectConstraintOrder;
this.respectIndexOrder = respectIndexOrder;
+ this.respectDomainOrder = respectDomainOrder;
this.respectSequenceOrder = respectSequenceOrder;
+
this.defaultSequenceFlags = defaultSequenceFlags;
}
@@ -158,6 +167,7 @@ public final class DDLExportConfiguration {
createSchemaIfNotExists,
createTableIfNotExists,
createIndexIfNotExists,
+ createDomainIfNotExists,
createSequenceIfNotExists,
createViewIfNotExists,
createOrReplaceView,
@@ -167,6 +177,7 @@ public final class DDLExportConfiguration {
respectColumnOrder,
respectConstraintOrder,
respectIndexOrder,
+ respectDomainOrder,
respectSequenceOrder,
defaultSequenceFlags
);
@@ -192,6 +203,7 @@ public final class DDLExportConfiguration {
newCreateSchemaIfNotExists,
createTableIfNotExists,
createIndexIfNotExists,
+ createDomainIfNotExists,
createSequenceIfNotExists,
createViewIfNotExists,
createOrReplaceView,
@@ -201,6 +213,7 @@ public final class DDLExportConfiguration {
respectColumnOrder,
respectConstraintOrder,
respectIndexOrder,
+ respectDomainOrder,
respectSequenceOrder,
defaultSequenceFlags
);
@@ -226,6 +239,7 @@ public final class DDLExportConfiguration {
createSchemaIfNotExists,
newCreateTableIfNotExists,
createIndexIfNotExists,
+ createDomainIfNotExists,
createSequenceIfNotExists,
createViewIfNotExists,
createOrReplaceView,
@@ -235,6 +249,7 @@ public final class DDLExportConfiguration {
respectColumnOrder,
respectConstraintOrder,
respectIndexOrder,
+ respectDomainOrder,
respectSequenceOrder,
defaultSequenceFlags
);
@@ -260,6 +275,7 @@ public final class DDLExportConfiguration {
createSchemaIfNotExists,
createTableIfNotExists,
newCreateIndexIfNotExists,
+ createDomainIfNotExists,
createSequenceIfNotExists,
createViewIfNotExists,
createOrReplaceView,
@@ -269,6 +285,43 @@ public final class DDLExportConfiguration {
respectColumnOrder,
respectConstraintOrder,
respectIndexOrder,
+ respectDomainOrder,
+ respectSequenceOrder,
+ defaultSequenceFlags
+ );
+ }
+
+ /**
+ * Whether to generate CREATE DOMAIN IF NOT EXISTS statements.
+ *
+ * Not all RDBMS support this flag. Check
+ * {@link DSLContext#createDomainIfNotExists(Domain)} to see if your
+ * {@link SQLDialect} supports the clause.
+ */
+ public final boolean createDomainIfNotExists() {
+ return createDomainIfNotExists;
+ }
+
+ /**
+ * Whether to generate CREATE DOMAIN IF NOT EXISTS statements.
+ */
+ public final DDLExportConfiguration createDomainIfNotExists(boolean newCreateDomainIfNotExists) {
+ return new DDLExportConfiguration(
+ flags,
+ createSchemaIfNotExists,
+ createTableIfNotExists,
+ createIndexIfNotExists,
+ newCreateDomainIfNotExists,
+ createSequenceIfNotExists,
+ createViewIfNotExists,
+ createOrReplaceView,
+ respectCatalogOrder,
+ respectSchemaOrder,
+ respectTableOrder,
+ respectColumnOrder,
+ respectConstraintOrder,
+ respectIndexOrder,
+ respectDomainOrder,
respectSequenceOrder,
defaultSequenceFlags
);
@@ -294,6 +347,7 @@ public final class DDLExportConfiguration {
createSchemaIfNotExists,
createTableIfNotExists,
createIndexIfNotExists,
+ createDomainIfNotExists,
newCreateSequenceIfNotExists,
createViewIfNotExists,
createOrReplaceView,
@@ -303,6 +357,7 @@ public final class DDLExportConfiguration {
respectColumnOrder,
respectConstraintOrder,
respectIndexOrder,
+ respectDomainOrder,
respectSequenceOrder,
defaultSequenceFlags
);
@@ -328,6 +383,7 @@ public final class DDLExportConfiguration {
createSchemaIfNotExists,
createTableIfNotExists,
createIndexIfNotExists,
+ createDomainIfNotExists,
createSequenceIfNotExists,
newCreateViewIfNotExists,
createOrReplaceView,
@@ -337,6 +393,7 @@ public final class DDLExportConfiguration {
respectColumnOrder,
respectConstraintOrder,
respectIndexOrder,
+ respectDomainOrder,
respectSequenceOrder,
defaultSequenceFlags
);
@@ -362,6 +419,7 @@ public final class DDLExportConfiguration {
createSchemaIfNotExists,
createTableIfNotExists,
createIndexIfNotExists,
+ createDomainIfNotExists,
createSequenceIfNotExists,
createViewIfNotExists,
newCreateOrReplaceView,
@@ -371,6 +429,7 @@ public final class DDLExportConfiguration {
respectColumnOrder,
respectConstraintOrder,
respectIndexOrder,
+ respectDomainOrder,
respectSequenceOrder,
defaultSequenceFlags
);
@@ -394,6 +453,7 @@ public final class DDLExportConfiguration {
createSchemaIfNotExists,
createTableIfNotExists,
createIndexIfNotExists,
+ createDomainIfNotExists,
createSequenceIfNotExists,
createViewIfNotExists,
createOrReplaceView,
@@ -403,6 +463,7 @@ public final class DDLExportConfiguration {
respectColumnOrder,
respectConstraintOrder,
respectIndexOrder,
+ respectDomainOrder,
respectSequenceOrder,
defaultSequenceFlags
);
@@ -426,6 +487,7 @@ public final class DDLExportConfiguration {
createSchemaIfNotExists,
createTableIfNotExists,
createIndexIfNotExists,
+ createDomainIfNotExists,
createSequenceIfNotExists,
createViewIfNotExists,
createOrReplaceView,
@@ -435,6 +497,7 @@ public final class DDLExportConfiguration {
respectColumnOrder,
respectConstraintOrder,
respectIndexOrder,
+ respectDomainOrder,
respectSequenceOrder,
defaultSequenceFlags
);
@@ -458,6 +521,7 @@ public final class DDLExportConfiguration {
createSchemaIfNotExists,
createTableIfNotExists,
createIndexIfNotExists,
+ createDomainIfNotExists,
createSequenceIfNotExists,
createViewIfNotExists,
createOrReplaceView,
@@ -467,6 +531,7 @@ public final class DDLExportConfiguration {
respectColumnOrder,
respectConstraintOrder,
respectIndexOrder,
+ respectDomainOrder,
respectSequenceOrder,
defaultSequenceFlags
);
@@ -490,6 +555,7 @@ public final class DDLExportConfiguration {
createSchemaIfNotExists,
createTableIfNotExists,
createIndexIfNotExists,
+ createDomainIfNotExists,
createSequenceIfNotExists,
createViewIfNotExists,
createOrReplaceView,
@@ -499,6 +565,7 @@ public final class DDLExportConfiguration {
newRespectColumnOrder,
respectConstraintOrder,
respectIndexOrder,
+ respectDomainOrder,
respectSequenceOrder,
defaultSequenceFlags
);
@@ -522,6 +589,7 @@ public final class DDLExportConfiguration {
createSchemaIfNotExists,
createTableIfNotExists,
createIndexIfNotExists,
+ createDomainIfNotExists,
createSequenceIfNotExists,
createViewIfNotExists,
createOrReplaceView,
@@ -531,6 +599,7 @@ public final class DDLExportConfiguration {
respectColumnOrder,
newRespectConstraintOrder,
respectIndexOrder,
+ respectDomainOrder,
respectSequenceOrder,
defaultSequenceFlags
);
@@ -554,6 +623,7 @@ public final class DDLExportConfiguration {
createSchemaIfNotExists,
createTableIfNotExists,
createIndexIfNotExists,
+ createDomainIfNotExists,
createSequenceIfNotExists,
createViewIfNotExists,
createOrReplaceView,
@@ -563,6 +633,41 @@ public final class DDLExportConfiguration {
respectColumnOrder,
respectConstraintOrder,
newRespectIndexOrder,
+ respectDomainOrder,
+ respectSequenceOrder,
+ defaultSequenceFlags
+ );
+ }
+
+ /**
+ * Whether to respect the domain order produced by the {@link Meta} source
+ * when generated domain DDL.
+ */
+ public final boolean respectDomainOrder() {
+ return respectDomainOrder;
+ }
+
+ /**
+ * Whether to respect the sequence order produced by the {@link Meta} source
+ * when generated sequence DDL.
+ */
+ public final DDLExportConfiguration respectDomainOrder(boolean newRespectDomainOrder) {
+ return new DDLExportConfiguration(
+ flags,
+ createSchemaIfNotExists,
+ createTableIfNotExists,
+ createIndexIfNotExists,
+ createDomainIfNotExists,
+ createSequenceIfNotExists,
+ createViewIfNotExists,
+ createOrReplaceView,
+ respectCatalogOrder,
+ respectSchemaOrder,
+ respectTableOrder,
+ respectColumnOrder,
+ respectConstraintOrder,
+ respectIndexOrder,
+ newRespectDomainOrder,
respectSequenceOrder,
defaultSequenceFlags
);
@@ -586,6 +691,7 @@ public final class DDLExportConfiguration {
createSchemaIfNotExists,
createTableIfNotExists,
createIndexIfNotExists,
+ createDomainIfNotExists,
createSequenceIfNotExists,
createViewIfNotExists,
createOrReplaceView,
@@ -595,6 +701,7 @@ public final class DDLExportConfiguration {
respectColumnOrder,
respectConstraintOrder,
respectIndexOrder,
+ respectDomainOrder,
newRespectSequenceOrder,
defaultSequenceFlags
);
@@ -618,6 +725,7 @@ public final class DDLExportConfiguration {
createSchemaIfNotExists,
createTableIfNotExists,
createIndexIfNotExists,
+ createDomainIfNotExists,
createSequenceIfNotExists,
createViewIfNotExists,
createOrReplaceView,
@@ -627,6 +735,7 @@ public final class DDLExportConfiguration {
respectColumnOrder,
respectConstraintOrder,
respectIndexOrder,
+ respectDomainOrder,
respectSequenceOrder,
newDefaultSequenceFlags
);
diff --git a/jOOQ/src/main/java/org/jooq/DDLFlag.java b/jOOQ/src/main/java/org/jooq/DDLFlag.java
index e19e1b73dd..c416de87f2 100644
--- a/jOOQ/src/main/java/org/jooq/DDLFlag.java
+++ b/jOOQ/src/main/java/org/jooq/DDLFlag.java
@@ -77,6 +77,11 @@ public enum DDLFlag {
*/
INDEX,
+ /**
+ * Whether DOMAIN statements should be generated.
+ */
+ DOMAIN,
+
/**
* Whether SEQUENCE statements should be generated.
*/
diff --git a/jOOQ/src/main/java/org/jooq/Meta.java b/jOOQ/src/main/java/org/jooq/Meta.java
index 767a99d140..d8dcca47cc 100644
--- a/jOOQ/src/main/java/org/jooq/Meta.java
+++ b/jOOQ/src/main/java/org/jooq/Meta.java
@@ -52,6 +52,7 @@ import static org.jooq.SQLDialect.HSQLDB;
import static org.jooq.SQLDialect.POSTGRES;
// ...
// ...
+// ...
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
@@ -169,6 +170,33 @@ public interface Meta extends Scope {
@Support
List
> getTables(Name name) throws DataAccessException;
+ /**
+ * Get all domain objects from the underlying meta data source.
+ *
+ * @throws DataAccessException If something went wrong fetching the meta
+ * objects
+ */
+ @Support({ H2, POSTGRES })
+ List> getDomains() throws DataAccessException;
+
+ /**
+ * Get all domain objects by name from the underlying meta data source.
+ *
+ * @throws DataAccessException If something went wrong fetching the meta
+ * objects
+ */
+ @Support({ H2, POSTGRES })
+ List> getDomains(String name) throws DataAccessException;
+
+ /**
+ * Get all domain objects by name from the underlying meta data source.
+ *
+ * @throws DataAccessException If something went wrong fetching the meta
+ * objects
+ */
+ @Support({ H2, POSTGRES })
+ List> getDomains(Name name) throws DataAccessException;
+
/**
* Get all sequence objects from the underlying meta data source.
*
diff --git a/jOOQ/src/main/java/org/jooq/Schema.java b/jOOQ/src/main/java/org/jooq/Schema.java
index 5c1e0ed795..7ef4c2a98e 100644
--- a/jOOQ/src/main/java/org/jooq/Schema.java
+++ b/jOOQ/src/main/java/org/jooq/Schema.java
@@ -119,6 +119,24 @@ public interface Schema extends Named {
*/
UDT> getUDT(String name);
+ /**
+ * Stream all domains contained in this schema.
+ */
+
+ Stream> domainStream();
+
+
+ /**
+ * List all domains contained in this schema.
+ */
+ List> getDomains();
+
+ /**
+ * Get a domain by its name (case-sensitive) in this schema, or
+ * null if no such domain exists.
+ */
+ Domain> getDomain(String name);
+
/**
* Stream all sequences contained in this schema.
*/
diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractMeta.java b/jOOQ/src/main/java/org/jooq/impl/AbstractMeta.java
index be90edc1f7..06d2dcd781 100644
--- a/jOOQ/src/main/java/org/jooq/impl/AbstractMeta.java
+++ b/jOOQ/src/main/java/org/jooq/impl/AbstractMeta.java
@@ -51,6 +51,7 @@ import java.util.Map;
import org.jooq.Catalog;
import org.jooq.Configuration;
import org.jooq.DDLExportConfiguration;
+import org.jooq.Domain;
import org.jooq.Index;
import org.jooq.Meta;
import org.jooq.Name;
@@ -74,9 +75,11 @@ abstract class AbstractMeta extends AbstractScope implements Meta, Serializable
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;
@@ -196,6 +199,48 @@ abstract class AbstractMeta extends AbstractScope implements Meta, Serializable
return result;
}
+ @Override
+ public final List> getDomains(String name) {
+ return getDomains(name(name));
+ }
+
+ @Override
+ public final List> getDomains(Name name) {
+ initDomains();
+ return get(name, new Iterable>() {
+ @Override
+ public Iterator> iterator() {
+ return getDomains().iterator();
+ }
+ }, cachedQualifiedDomains, cachedUnqualifiedDomains);
+ }
+
+ @Override
+ public final List> getDomains() {
+ initDomains();
+ return Collections.unmodifiableList(new ArrayList<>(cachedQualifiedDomains.values()));
+ }
+
+ private final void initDomains() {
+ if (cachedQualifiedDomains == null) {
+ cachedQualifiedDomains = new LinkedHashMap<>();
+ cachedUnqualifiedDomains = new LinkedHashMap<>();
+ get(name(""), new Iterable>() {
+ @Override
+ public Iterator> iterator() {
+ return getDomains0().iterator();
+ }
+ }, cachedQualifiedDomains, cachedUnqualifiedDomains);
+ }
+ }
+
+ protected List> getDomains0() {
+ List> result = new ArrayList<>();
+ for (Schema schema : getSchemas())
+ result.addAll(schema.getDomains());
+ return result;
+ }
+
@Override
public final List> getSequences(String name) {
return getSequences(name(name));
diff --git a/jOOQ/src/main/java/org/jooq/impl/DDL.java b/jOOQ/src/main/java/org/jooq/impl/DDL.java
index 6dc6aae530..2312a48a80 100644
--- a/jOOQ/src/main/java/org/jooq/impl/DDL.java
+++ b/jOOQ/src/main/java/org/jooq/impl/DDL.java
@@ -39,6 +39,7 @@ package org.jooq.impl;
import static org.jooq.DDLFlag.CHECK;
import static org.jooq.DDLFlag.COMMENT;
+import static org.jooq.DDLFlag.DOMAIN;
import static org.jooq.DDLFlag.FOREIGN_KEY;
import static org.jooq.DDLFlag.INDEX;
import static org.jooq.DDLFlag.PRIMARY_KEY;
@@ -59,11 +60,15 @@ import java.util.List;
import org.jooq.Check;
import org.jooq.Constraint;
import org.jooq.ConstraintEnforcementStep;
+import org.jooq.CreateDomainAsStep;
+import org.jooq.CreateDomainConstraintStep;
+import org.jooq.CreateDomainDefaultStep;
import org.jooq.CreateSequenceFlagsStep;
import org.jooq.CreateTableOnCommitStep;
import org.jooq.DDLExportConfiguration;
import org.jooq.DDLFlag;
import org.jooq.DSLContext;
+import org.jooq.Domain;
import org.jooq.Field;
import org.jooq.ForeignKey;
import org.jooq.Index;
@@ -171,6 +176,27 @@ final class DDL {
return result;
}
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ final Query createDomain(Domain> domain) {
+ CreateDomainAsStep s1 = configuration.createDomainIfNotExists()
+ ? ctx.createDomainIfNotExists(domain)
+ : ctx.createDomain(domain);
+
+ CreateDomainDefaultStep s2 = s1.as(domain.getDataType());
+ CreateDomainConstraintStep s3 = domain.getDataType().defaulted()
+ ? s2.default_(domain.getDataType().default_())
+ : s2;
+
+ if (domain.checks().isEmpty())
+ return s3;
+
+ List constraints = new ArrayList<>();
+ for (Check check : domain.checks())
+ constraints.add(check.constraint());
+
+ return s3.constraints(constraints);
+ }
+
private final Query createTable(Table> table) {
return createTable(table, constraints(table));
}
@@ -345,6 +371,11 @@ final class DDL {
for (Constraint constraint : foreignKeys(table))
queries.add(ctx.alterTable(table).add(constraint));
+ if (configuration.flags().contains(DOMAIN))
+ for (Schema schema : schemas)
+ for (Domain> domain : sortIf(schema.getDomains(), !configuration.respectDomainOrder()))
+ queries.add(createDomain(domain));
+
if (configuration.flags().contains(SEQUENCE))
for (Schema schema : schemas)
for (Sequence> sequence : sortIf(schema.getSequences(), !configuration.respectSequenceOrder()))
diff --git a/jOOQ/src/main/java/org/jooq/impl/DomainImpl.java b/jOOQ/src/main/java/org/jooq/impl/DomainImpl.java
index d362b3c023..dc9d1107af 100644
--- a/jOOQ/src/main/java/org/jooq/impl/DomainImpl.java
+++ b/jOOQ/src/main/java/org/jooq/impl/DomainImpl.java
@@ -52,7 +52,7 @@ import org.jooq.Schema;
/**
* @author Lukas Eder
*/
-final class DomainImpl extends AbstractTypedNamed implements Domain {
+class DomainImpl extends AbstractTypedNamed implements Domain {
/**
* Generated UID
diff --git a/jOOQ/src/main/java/org/jooq/impl/Interpreter.java b/jOOQ/src/main/java/org/jooq/impl/Interpreter.java
index a67c702eb2..b2d154a86a 100644
--- a/jOOQ/src/main/java/org/jooq/impl/Interpreter.java
+++ b/jOOQ/src/main/java/org/jooq/impl/Interpreter.java
@@ -49,6 +49,7 @@ import static org.jooq.impl.ConstraintType.PRIMARY_KEY;
import static org.jooq.impl.DSL.name;
import static org.jooq.impl.DSL.schema;
import static org.jooq.impl.SQLDataType.BIGINT;
+import static org.jooq.impl.Tools.EMPTY_CHECK;
import static org.jooq.impl.Tools.EMPTY_FIELD;
import static org.jooq.impl.Tools.intersect;
import static org.jooq.impl.Tools.normaliseNameCase;
@@ -74,6 +75,7 @@ import org.jooq.Configuration;
import org.jooq.Constraint;
import org.jooq.DataType;
import org.jooq.Delete;
+import org.jooq.Domain;
import org.jooq.Field;
import org.jooq.FieldOrConstraint;
import org.jooq.ForeignKey;
@@ -127,6 +129,7 @@ final class Interpreter {
private final Map> interpretedUniqueKeys = new HashMap<>();
private final Map> interpretedForeignKeys = new HashMap<>();
private final Map interpretedIndexes = new HashMap<>();
+ private final Map interpretedDomains = new HashMap<>();
private final Map interpretedSequences = new HashMap<>();
Interpreter(Configuration configuration) {
@@ -205,6 +208,9 @@ final class Interpreter {
else if (query instanceof DropIndexImpl)
accept0((DropIndexImpl) query);
+ else if (query instanceof CreateDomainImpl)
+ accept0((CreateDomainImpl) query);
+
else if (query instanceof CommentOnImpl)
accept0((CommentOnImpl) query);
@@ -248,7 +254,7 @@ final class Interpreter {
if (getSchema(schema, false) != null) {
if (!query.$createSchemaIfNotExists())
- throw schemaAlreadyExists(schema);
+ throw alreadyExists(schema);
return;
}
@@ -263,14 +269,14 @@ final class Interpreter {
MutableSchema oldSchema = getSchema(schema);
if (oldSchema == null) {
if (!query.$alterSchemaIfExists())
- throw schemaNotExists(schema);
+ throw notExists(schema);
return;
}
if (renameTo != null) {
if (getSchema(renameTo, false) != null)
- throw schemaAlreadyExists(renameTo);
+ throw alreadyExists(renameTo);
oldSchema.name((UnqualifiedName) renameTo.getUnqualifiedName());
return;
@@ -285,7 +291,7 @@ final class Interpreter {
if (mutableSchema == null) {
if (!query.$dropSchemaIfExists())
- throw schemaNotExists(schema);
+ throw notExists(schema);
return;
}
@@ -358,7 +364,7 @@ final class Interpreter {
MutableUniqueKey mu = null;
if (mrf == null)
- throw tableNotExists(impl.$referencesTable());
+ throw notExists(impl.$referencesTable());
List mfs = mt.fields(impl.$foreignKey(), true);
List mrfs = mrf.fields(impl.$references(), true);
@@ -472,7 +478,7 @@ final class Interpreter {
MutableTable existing = schema.table(table);
if (existing == null) {
if (!query.$ifExists())
- throw tableNotExists(table);
+ throw notExists(table);
return;
}
@@ -482,9 +488,9 @@ final class Interpreter {
if (query.$add() != null) {
for (FieldOrConstraint fc : query.$add())
if (fc instanceof Field && find(existing.fields, (Field>) fc) != null)
- throw fieldAlreadyExists((Field>) fc);
+ throw alreadyExists(fc);
else if (fc instanceof Constraint && !fc.getUnqualifiedName().empty() && existing.constraint((Constraint) fc) != null)
- throw constraintAlreadyExists((Constraint) fc);
+ throw alreadyExists(fc);
// TODO: ReverseIterable is not a viable approach if we also allow constraints to be added this way
if (query.$addFirst()) {
@@ -516,7 +522,7 @@ final class Interpreter {
else if (query.$addColumn() != null) {
if (find(existing.fields, query.$addColumn()) != null)
if (!query.$ifNotExistsColumn())
- throw fieldAlreadyExists(query.$addColumn());
+ throw alreadyExists(query.$addColumn());
else
return;
@@ -540,7 +546,7 @@ final class Interpreter {
if (existingField == null)
if (!query.$ifExistsColumn())
- throw columnNotExists(query.$alterColumn());
+ throw notExists(query.$alterColumn());
else
return;
@@ -566,9 +572,9 @@ final class Interpreter {
MutableField mf = find(existing.fields, query.$renameColumn());
if (mf == null)
- throw fieldNotExists(query.$renameColumn());
+ throw notExists(query.$renameColumn());
else if (find(existing.fields, query.$renameColumnTo()) != null)
- throw fieldAlreadyExists(query.$renameColumnTo());
+ throw alreadyExists(query.$renameColumnTo());
else
mf.name((UnqualifiedName) query.$renameColumnTo().getUnqualifiedName());
}
@@ -576,7 +582,7 @@ final class Interpreter {
MutableConstraint mc = existing.constraint(query.$renameConstraint(), true);
if (existing.constraint(query.$renameConstraintTo()) != null)
- throw constraintAlreadyExists(query.$renameConstraintTo());
+ throw alreadyExists(query.$renameConstraintTo());
else
mc.name((UnqualifiedName) query.$renameConstraintTo().getUnqualifiedName());
}
@@ -672,7 +678,7 @@ final class Interpreter {
}
if (!query.$ifExistsConstraint())
- throw constraintNotExists(query.$dropConstraint());
+ throw notExists(query.$dropConstraint());
}
else if (query.$dropConstraintType() == PRIMARY_KEY) {
if (existing.primaryKey != null)
@@ -732,11 +738,12 @@ final class Interpreter {
private final void addConstraint(Query query, ConstraintImpl impl, MutableTable existing) {
if (!impl.getUnqualifiedName().empty() && existing.constraint(impl) != null)
- throw constraintAlreadyExists(impl);
+ throw alreadyExists(impl);
+
boolean enforced = true ;
if (impl.$primaryKey() != null)
if (existing.primaryKey != null)
- throw constraintAlreadyExists(impl);
+ throw alreadyExists(impl);
else
existing.primaryKey = new MutableUniqueKey((UnqualifiedName) impl.getUnqualifiedName(), existing, existing.fields(impl.$primaryKey(), true), enforced);
else if (impl.$unique() != null)
@@ -756,7 +763,7 @@ final class Interpreter {
MutableTable existing = schema.table(table);
if (existing == null) {
if (!query.$ifExists())
- throw tableNotExists(table);
+ throw notExists(table);
return;
}
@@ -775,7 +782,7 @@ final class Interpreter {
MutableTable existing = schema.table(table);
if (existing == null)
- throw tableNotExists(table);
+ throw notExists(table);
else if (!existing.options.type().isTable())
throw objectNotTable(table);
else if (!query.$cascade() && existing.hasReferencingKeys())
@@ -850,7 +857,7 @@ final class Interpreter {
MutableSequence existing = schema.sequence(sequence);
if (existing != null) {
if (!query.$createSequenceIfNotExists())
- throw sequenceAlreadyExists(sequence);
+ throw alreadyExists(sequence);
return;
}
@@ -872,7 +879,7 @@ final class Interpreter {
MutableSequence existing = schema.sequence(sequence);
if (existing == null) {
if (!query.$ifExists())
- throw sequenceNotExists(sequence);
+ throw notExists(sequence);
return;
}
@@ -880,7 +887,7 @@ final class Interpreter {
Sequence> renameTo = query.$renameTo();
if (renameTo != null) {
if (schema.sequence(renameTo) != null)
- throw sequenceAlreadyExists(renameTo);
+ throw alreadyExists(renameTo);
existing.name((UnqualifiedName) renameTo.getUnqualifiedName());
}
@@ -932,7 +939,7 @@ final class Interpreter {
MutableSequence existing = schema.sequence(sequence);
if (existing == null) {
if (!query.$dropSequenceIfExists())
- throw sequenceNotExists(sequence);
+ throw notExists(sequence);
return;
}
@@ -947,14 +954,14 @@ final class Interpreter {
MutableTable mt = schema.table(table);
if (mt == null)
- throw tableNotExists(table);
+ throw notExists(table);
MutableIndex existing = find(mt.indexes, index);
List mtf = mt.sortFields(query.$sortFields());
if (existing != null) {
if (!query.$ifNotExists())
- throw indexAlreadyExists(index);
+ throw alreadyExists(index);
return;
}
@@ -972,7 +979,7 @@ final class Interpreter {
if (index(query.$renameTo(), table, false, false) == null)
existing.name((UnqualifiedName) query.$renameTo().getUnqualifiedName());
else
- throw indexAlreadyExists(query.$renameTo());
+ throw alreadyExists(query.$renameTo());
else
throw unsupportedQuery(query);
}
@@ -987,6 +994,39 @@ final class Interpreter {
existing.table.indexes.remove(existing);
}
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ private final void accept0(CreateDomainImpl> query) {
+ Domain> domain = query.$domain();
+ MutableSchema schema = getSchema(domain.getSchema(), true);
+
+ MutableDomain existing = schema.domain(domain);
+ if (existing != null) {
+ if (!query.$createDomainIfNotExists())
+ throw alreadyExists(domain);
+
+ return;
+ }
+
+ MutableDomain md = new MutableDomain((UnqualifiedName) domain.getUnqualifiedName(), schema, query.$dataType());
+
+ if (query.$default_() != null)
+ md.dataType = md.dataType.default_((Field) query.$default_());
+
+ // TODO: Support NOT NULL constraints
+ if (query.$constraints() != null) {
+ md.checks = new ArrayList<>();
+
+ for (Constraint constraint : query.$constraints())
+ if (((ConstraintImpl) constraint).$check() != null)
+ md.checks.add(new CheckImpl(
+ null,
+ constraint.getQualifiedName(),
+ ((ConstraintImpl) constraint).$check(),
+ true
+ ));
+ }
+ }
+
private final void accept0(CommentOnImpl query) {
Table> table = query.$table();
Field> field = query.$field();
@@ -1002,7 +1042,7 @@ final class Interpreter {
private final void accept0(SetSchema query) {
MutableSchema schema = getSchema(query.$schema());
if (schema == null)
- throw schemaNotExists(query.$schema());
+ throw notExists(query.$schema());
currentSchema = schema;
}
@@ -1022,27 +1062,14 @@ final class Interpreter {
// Exceptions
// -------------------------------------------------------------------------
- // TODO: Surely, these exception utilities can be refactored / improved?
private static final DataDefinitionException unsupportedQuery(Query query) {
return new DataDefinitionException("Unsupported query: " + query.getSQL());
}
- private static final DataDefinitionException schemaNotExists(Schema schema) {
- return new DataDefinitionException("Schema does not exist: " + schema.getQualifiedName());
- }
-
- private static final DataDefinitionException schemaAlreadyExists(Schema schema) {
- return new DataDefinitionException("Schema already exists: " + schema.getQualifiedName());
- }
-
private static final DataDefinitionException schemaNotEmpty(Schema schema) {
return new DataDefinitionException("Schema is not empty: " + schema.getQualifiedName());
}
- private static final DataDefinitionException tableNotExists(Table> table) {
- return new DataDefinitionException("Table does not exist: " + table.getQualifiedName());
- }
-
private static final DataDefinitionException objectNotTable(Table> table) {
return new DataDefinitionException("Object is not a table: " + table.getQualifiedName());
}
@@ -1055,10 +1082,6 @@ final class Interpreter {
return new DataDefinitionException("Object is not a view: " + table.getQualifiedName());
}
- private static final DataDefinitionException tableAlreadyExists(Table> table) {
- return new DataDefinitionException("Table already exists: " + table.getQualifiedName());
- }
-
private static final DataDefinitionException viewNotExists(Table> view) {
return new DataDefinitionException("View does not exist: " + view.getQualifiedName());
}
@@ -1067,58 +1090,22 @@ final class Interpreter {
return new DataDefinitionException("View already exists: " + view.getQualifiedName());
}
- private static final DataDefinitionException columnNotExists(Field> field) {
- return new DataDefinitionException("Column does not exist: " + field.getQualifiedName());
- }
-
- private static final DataDefinitionException columnAlreadyExists(Field> field) {
- return columnAlreadyExists(field.getQualifiedName());
- }
-
private static final DataDefinitionException columnAlreadyExists(Name name) {
return new DataDefinitionException("Column already exists: " + name);
}
- private static final DataDefinitionException sequenceNotExists(Sequence> sequence) {
- return new DataDefinitionException("Sequence does not exist: " + sequence.getQualifiedName());
+ private static final DataDefinitionException notExists(Named named) {
+ return new DataDefinitionException(named.getClass().getSimpleName() + " does not exist: " + named.getQualifiedName());
}
- private static final DataDefinitionException sequenceAlreadyExists(Sequence> sequence) {
- return new DataDefinitionException("Sequence already exists: " + sequence.getQualifiedName());
+ private static final DataDefinitionException alreadyExists(Named named) {
+ return new DataDefinitionException(named.getClass().getSimpleName() + " already exists: " + named.getQualifiedName());
}
private static final DataDefinitionException primaryKeyNotExists() {
return new DataDefinitionException("Primary key does not exist");
}
- private static final DataDefinitionException constraintAlreadyExists(Constraint constraint) {
- return new DataDefinitionException("Constraint already exists: " + constraint.getQualifiedName());
- }
-
- private static final DataDefinitionException constraintNotExists(Constraint constraint) {
- return new DataDefinitionException("Constraint does not exist: " + constraint.getQualifiedName());
- }
-
- private static final DataDefinitionException indexNotExists(Index index) {
- return new DataDefinitionException("Index does not exist: " + index.getQualifiedName());
- }
-
- private static final DataDefinitionException indexAlreadyExists(Index index) {
- return new DataDefinitionException("Index already exists: " + index.getQualifiedName());
- }
-
- private static final DataDefinitionException fieldNotExists(Field> field) {
- return new DataDefinitionException("Field does not exist: " + field.getQualifiedName());
- }
-
- private static final DataDefinitionException fieldAlreadyExists(Field> field) {
- return new DataDefinitionException("Field already exists: " + field.getQualifiedName());
- }
-
- private static final DataDefinitionException objectNotExists(Named named) {
- return new DataDefinitionException("Object does not exist: " + named.getQualifiedName());
- }
-
// -------------------------------------------------------------------------
// Auxiliary methods
// -------------------------------------------------------------------------
@@ -1206,7 +1193,7 @@ final class Interpreter {
private final MutableTable table(Table> table, boolean throwIfNotExists) {
MutableTable result = getSchema(table.getSchema()).table(table);
if (result == null && throwIfNotExists)
- throw tableNotExists(table);
+ throw notExists(table);
return result;
}
@@ -1233,10 +1220,10 @@ final class Interpreter {
if (mt != null)
mi = find(mt.indexes, index);
else if (table != null && throwIfNotExists)
- throw tableNotExists(table);
+ throw notExists(table);
if (mi == null && !ifExists && throwIfNotExists)
- throw indexNotExists(index);
+ throw notExists(index);
return mi;
}
@@ -1254,7 +1241,7 @@ final class Interpreter {
if (mt.options.type().isView())
return viewAlreadyExists(t);
else
- return tableAlreadyExists(t);
+ return alreadyExists(t);
}
private final MutableField field(Field> field) {
@@ -1270,7 +1257,7 @@ final class Interpreter {
MutableField result = find(table.fields, field);
if (result == null && throwIfNotExists)
- throw fieldNotExists(field);
+ throw notExists(field);
return result;
}
@@ -1312,7 +1299,7 @@ final class Interpreter {
}
if (result == -1)
- throw objectNotExists(named);
+ throw notExists(named);
return result;
}
@@ -1484,6 +1471,7 @@ final class Interpreter {
private final class MutableSchema extends MutableNamed {
MutableCatalog catalog;
List tables = new MutableNamedList<>();
+ List domains = new MutableNamedList<>();
List sequences = new MutableNamedList<>();
MutableSchema(UnqualifiedName name, MutableCatalog catalog) {
@@ -1499,7 +1487,10 @@ final class Interpreter {
for (MutableForeignKey referencingKey : table.referencingKeys())
referencingKey.table.foreignKeys.remove(referencingKey);
+ // TODO: Cascade domains?
+
tables.clear();
+ domains.clear();
sequences.clear();
}
@@ -1526,6 +1517,10 @@ final class Interpreter {
return find(tables, t);
}
+ final MutableDomain domain(Domain> d) {
+ return find(domains, d);
+ }
+
final MutableSequence sequence(Sequence> s) {
return find(sequences, s);
}
@@ -1545,6 +1540,16 @@ final class Interpreter {
return result;
}
+ @Override
+ public final List> getDomains() {
+ List> result = new ArrayList<>(domains.size());
+
+ for (MutableDomain domain : domains)
+ result.add(domain.interpretedDomain());
+
+ return result;
+ }
+
@Override
public final List> getSequences() {
List> result = new ArrayList<>(sequences.size());
@@ -1641,7 +1646,7 @@ final class Interpreter {
return result;
if (failIfNotFound)
- throw constraintNotExists(constraint);
+ throw notExists(constraint);
return null;
}
@@ -1754,6 +1759,48 @@ final class Interpreter {
}
}
+ private final class MutableDomain extends MutableNamed {
+ MutableSchema schema;
+ DataType> dataType;
+ List> checks;
+
+ MutableDomain(UnqualifiedName name, MutableSchema schema, DataType> dataType) {
+ super(name);
+
+ this.schema = schema;
+ this.dataType = dataType;
+ schema.domains.add(this);
+ }
+
+ @Override
+ final void onDrop() {
+ // TODO: Cascade
+ }
+
+ @Override
+ final MutableNamed parent() {
+ return schema;
+ }
+
+
+ final InterpretedDomain interpretedDomain() {
+ Name qualifiedName = qualifiedName();
+ InterpretedDomain result = interpretedDomains.get(qualifiedName);
+
+ if (result == null)
+ interpretedDomains.put(qualifiedName, result = new InterpretedDomain(schema.interpretedSchema()));
+
+ return result;
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ private final class InterpretedDomain extends DomainImpl {
+ InterpretedDomain(Schema schema) {
+ super(schema, MutableDomain.this.name(), dataType, checks != null ? checks.toArray(EMPTY_CHECK) : EMPTY_CHECK);
+ }
+ }
+ }
+
private final class MutableSequence extends MutableNamed {
MutableSchema schema;
Field extends Number> startWith;
diff --git a/jOOQ/src/main/java/org/jooq/impl/SchemaImpl.java b/jOOQ/src/main/java/org/jooq/impl/SchemaImpl.java
index e3d31c6e73..ceb511ae08 100644
--- a/jOOQ/src/main/java/org/jooq/impl/SchemaImpl.java
+++ b/jOOQ/src/main/java/org/jooq/impl/SchemaImpl.java
@@ -49,7 +49,9 @@ import org.jooq.Catalog;
import org.jooq.Clause;
import org.jooq.Comment;
import org.jooq.Context;
+import org.jooq.Domain;
import org.jooq.Name;
+import org.jooq.Named;
import org.jooq.Schema;
import org.jooq.Sequence;
import org.jooq.Table;
@@ -126,31 +128,32 @@ public class SchemaImpl extends AbstractNamed implements Schema {
return CLAUSES;
}
- @Override
- public final Table> getTable(String tableName) {
- for (Table> table : getTables())
- if (table.getName().equals(tableName))
- return table;
+ private final N getNamed(List list, String name) {
+ for (N named : list)
+ if (named.getName().equals(name))
+ return named;
return null;
}
@Override
- public final UDT> getUDT(String udtName) {
- for (UDT> udt : getUDTs())
- if (udt.getName().equals(udtName))
- return udt;
-
- return null;
+ public final Table> getTable(String name) {
+ return getNamed(getTables(), name);
}
@Override
- public final Sequence> getSequence(String sequenceName) {
- for (Sequence> sequence : getSequences())
- if (sequence.getName().equals(sequenceName))
- return sequence;
+ public final UDT> getUDT(String name) {
+ return getNamed(getUDTs(), name);
+ }
- return null;
+ @Override
+ public final Domain> getDomain(String name) {
+ return getNamed(getDomains(), name);
+ }
+
+ @Override
+ public final Sequence> getSequence(String name) {
+ return getNamed(getSequences(), name);
}
/**
@@ -173,6 +176,16 @@ public class SchemaImpl extends AbstractNamed implements Schema {
return Collections.emptyList();
}
+ /**
+ * {@inheritDoc}
+ *
+ * Subclasses should override this method
+ */
+ @Override
+ public List> getDomains() {
+ return Collections.emptyList();
+ }
+
/**
* {@inheritDoc}
*
@@ -194,6 +207,11 @@ public class SchemaImpl extends AbstractNamed implements Schema {
return getUDTs().stream();
}
+ @Override
+ public final Stream> domainStream() {
+ return getDomains().stream();
+ }
+
@Override
public final Stream> sequenceStream() {
return getSequences().stream();
diff --git a/jOOQ/src/main/java/org/jooq/impl/Tools.java b/jOOQ/src/main/java/org/jooq/impl/Tools.java
index 25e219b5ad..273e8a3a43 100644
--- a/jOOQ/src/main/java/org/jooq/impl/Tools.java
+++ b/jOOQ/src/main/java/org/jooq/impl/Tools.java
@@ -217,6 +217,7 @@ import org.jooq.Asterisk;
import org.jooq.Attachable;
import org.jooq.BindContext;
import org.jooq.Catalog;
+import org.jooq.Check;
import org.jooq.Clause;
import org.jooq.CommonTableExpression;
import org.jooq.Condition;
@@ -298,6 +299,7 @@ final class Tools {
// ------------------------------------------------------------------------
static final byte[] EMPTY_BYTE = {};
+ static final Check>[] EMPTY_CHECK = {};
static final Clause[] EMPTY_CLAUSE = {};
static final Collection>[] EMPTY_COLLECTION = {};
static final CommonTableExpression>[] EMPTY_COMMON_TABLE_EXPRESSION = {};