diff --git a/jOOQ-codegen-gradle/src/main/java/org/jooq/codegen/gradle/MetaExtensions.java b/jOOQ-codegen-gradle/src/main/java/org/jooq/codegen/gradle/MetaExtensions.java index b8e86fa0e7..3329c2ab2f 100644 --- a/jOOQ-codegen-gradle/src/main/java/org/jooq/codegen/gradle/MetaExtensions.java +++ b/jOOQ-codegen-gradle/src/main/java/org/jooq/codegen/gradle/MetaExtensions.java @@ -765,6 +765,12 @@ public class MetaExtensions { setIdentities(l); } + public void defaults(Action action) { + SyntheticDefaultTypeListExtension l = objects.newInstance(SyntheticDefaultTypeListExtension.class, objects); + action.execute(l); + setDefaults(l); + } + public void enums(Action action) { SyntheticEnumTypeListExtension l = objects.newInstance(SyntheticEnumTypeListExtension.class, objects); action.execute(l); @@ -842,6 +848,16 @@ public class MetaExtensions { } } + public static class SyntheticDefaultTypeExtension extends SyntheticDefaultType { + + final ObjectFactory objects; + + @Inject + public SyntheticDefaultTypeExtension(ObjectFactory objects) { + this.objects = objects; + } + } + public static class SyntheticEnumTypeExtension extends SyntheticEnumType { final ObjectFactory objects; @@ -1468,6 +1484,22 @@ public class MetaExtensions { } } + public static class SyntheticDefaultTypeListExtension extends ArrayList { + + final ObjectFactory objects; + + @Inject + public SyntheticDefaultTypeListExtension(ObjectFactory objects) { + this.objects = objects; + } + + public void default_(Action action) { + SyntheticDefaultTypeExtension o = objects.newInstance(SyntheticDefaultTypeExtension.class, objects); + action.execute(o); + add(o); + } + } + public static class SyntheticEnumTypeListExtension extends ArrayList { final ObjectFactory objects; diff --git a/jOOQ-meta-kotlin/src/main/kotlin/org/jooq/meta/kotlin/Extensions.kt b/jOOQ-meta-kotlin/src/main/kotlin/org/jooq/meta/kotlin/Extensions.kt index e3ecfc560c..d53ed9db3a 100644 --- a/jOOQ-meta-kotlin/src/main/kotlin/org/jooq/meta/kotlin/Extensions.kt +++ b/jOOQ-meta-kotlin/src/main/kotlin/org/jooq/meta/kotlin/Extensions.kt @@ -567,6 +567,17 @@ fun MutableList.identity(block: SyntheticIdentityType.() add(e) } +fun SyntheticObjectsType.defaults(block: MutableList.() -> Unit) { + block(defaults) +} + +@JvmName("mutableListSyntheticDefaultType") +fun MutableList.default_(block: SyntheticDefaultType.() -> Unit) { + val e = SyntheticDefaultType() + block(e) + add(e) +} + fun SyntheticObjectsType.enums(block: MutableList.() -> Unit) { block(enums) } diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/AbstractDatabase.java b/jOOQ-meta/src/main/java/org/jooq/meta/AbstractDatabase.java index 762476586b..77007196d9 100644 --- a/jOOQ-meta/src/main/java/org/jooq/meta/AbstractDatabase.java +++ b/jOOQ-meta/src/main/java/org/jooq/meta/AbstractDatabase.java @@ -143,6 +143,7 @@ import org.jooq.meta.jaxb.RegexFlag; import org.jooq.meta.jaxb.SchemaMappingType; import org.jooq.meta.jaxb.SyntheticColumnType; import org.jooq.meta.jaxb.SyntheticDaoType; +import org.jooq.meta.jaxb.SyntheticDefaultType; import org.jooq.meta.jaxb.SyntheticEnumType; import org.jooq.meta.jaxb.SyntheticForeignKeyType; import org.jooq.meta.jaxb.SyntheticIdentityType; @@ -253,6 +254,8 @@ public abstract class AbstractDatabase implements Database { private Set unusedSyntheticReadonlyRowids = new HashSet<>(); private List configuredSyntheticIdentities = new ArrayList<>(); private Set unusedSyntheticIdentities = new HashSet<>(); + private List configuredSyntheticDefaults = new ArrayList<>(); + private Set unusedSyntheticDefaults = new HashSet<>(); private List configuredSyntheticEnums = new ArrayList<>(); private Set unusedSyntheticEnums = new HashSet<>(); private List configuredSyntheticPrimaryKeys = new ArrayList<>(); @@ -3573,6 +3576,7 @@ public abstract class AbstractDatabase implements Database { getConfiguredSyntheticReadonlyColumns().addAll(configuredSyntheticObjects.getReadonlyColumns()); getConfiguredSyntheticReadonlyRowids().addAll(configuredSyntheticObjects.getReadonlyRowids()); getConfiguredSyntheticIdentities().addAll(configuredSyntheticObjects.getIdentities()); + getConfiguredSyntheticDefaults().addAll(configuredSyntheticObjects.getDefaults()); getConfiguredSyntheticEnums().addAll(configuredSyntheticObjects.getEnums()); getConfiguredSyntheticPrimaryKeys().addAll(configuredSyntheticObjects.getPrimaryKeys()); getConfiguredSyntheticUniqueKeys().addAll(configuredSyntheticObjects.getUniqueKeys()); @@ -3584,6 +3588,7 @@ public abstract class AbstractDatabase implements Database { unusedSyntheticReadonlyColumns.addAll(configuredSyntheticObjects.getReadonlyColumns()); unusedSyntheticReadonlyRowids.addAll(configuredSyntheticObjects.getReadonlyRowids()); unusedSyntheticIdentities.addAll(configuredSyntheticObjects.getIdentities()); + unusedSyntheticDefaults.addAll(configuredSyntheticObjects.getDefaults()); unusedSyntheticEnums.addAll(configuredSyntheticObjects.getEnums()); unusedSyntheticPrimaryKeys.addAll(configuredSyntheticObjects.getPrimaryKeys()); unusedSyntheticUniqueKeys.addAll(configuredSyntheticObjects.getUniqueKeys()); @@ -3597,6 +3602,8 @@ public abstract class AbstractDatabase implements Database { if (!configuredSyntheticObjects.getColumns().isEmpty()) log.info("Commercial feature", "Synthetic columns are a commercial only feature. Please upgrade to the jOOQ Professional Edition"); + if (!configuredSyntheticObjects.getDefaults().isEmpty()) + log.info("Commercial feature", "Synthetic defaults are a commercial only feature. Please upgrade to the jOOQ Professional Edition"); if (!configuredSyntheticObjects.getEnums().isEmpty()) log.info("Commercial feature", "Synthetic enums are a commercial only feature. Please upgrade to the jOOQ Professional Edition"); if (!configuredSyntheticObjects.getReadonlyColumns().isEmpty()) @@ -3642,6 +3649,14 @@ public abstract class AbstractDatabase implements Database { return configuredSyntheticIdentities; } + @Override + public List getConfiguredSyntheticDefaults() { + if (configuredSyntheticDefaults == null) + configuredSyntheticDefaults = new ArrayList<>(); + + return configuredSyntheticDefaults; + } + @Override public List getConfiguredSyntheticEnums() { if (configuredSyntheticEnums == null) @@ -3710,6 +3725,11 @@ public abstract class AbstractDatabase implements Database { unusedSyntheticIdentities.remove(identity); } + @Override + public void markUsed(SyntheticDefaultType default_) { + unusedSyntheticDefaults.remove(default_); + } + @Override public void markUsed(SyntheticEnumType e) { unusedSyntheticEnums.remove(e); @@ -3755,6 +3775,11 @@ public abstract class AbstractDatabase implements Database { return new ArrayList<>(unusedSyntheticIdentities); } + @Override + public List getUnusedSyntheticDefaults() { + return new ArrayList<>(unusedSyntheticDefaults); + } + @Override public List getUnusedSyntheticEnums() { return new ArrayList<>(unusedSyntheticEnums); diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/Database.java b/jOOQ-meta/src/main/java/org/jooq/meta/Database.java index e7ebb2ade2..c1422725f0 100644 --- a/jOOQ-meta/src/main/java/org/jooq/meta/Database.java +++ b/jOOQ-meta/src/main/java/org/jooq/meta/Database.java @@ -62,6 +62,7 @@ import org.jooq.meta.jaxb.RegexFlag; import org.jooq.meta.jaxb.SchemaMappingType; import org.jooq.meta.jaxb.SyntheticColumnType; import org.jooq.meta.jaxb.SyntheticDaoType; +import org.jooq.meta.jaxb.SyntheticDefaultType; import org.jooq.meta.jaxb.SyntheticEnumType; import org.jooq.meta.jaxb.SyntheticForeignKeyType; import org.jooq.meta.jaxb.SyntheticIdentityType; @@ -1371,6 +1372,11 @@ public interface Database extends AutoCloseable { */ List getConfiguredSyntheticIdentities(); + /** + * Get the configured synthetic defaults. + */ + List getConfiguredSyntheticDefaults(); + /** * Get the configured synthetic enums. */ @@ -1447,6 +1453,16 @@ public interface Database extends AutoCloseable { */ List getUnusedSyntheticIdentities(); + /** + * Mark a synthetic default as used. + */ + void markUsed(SyntheticDefaultType default_); + + /** + * Retrieve the not-yet used synthetic defaults. + */ + List getUnusedSyntheticDefaults(); + /** * Mark a synthetic enum as used. */ diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/DefaultColumnDefinition.java b/jOOQ-meta/src/main/java/org/jooq/meta/DefaultColumnDefinition.java index 36385c35fe..d2447be468 100644 --- a/jOOQ-meta/src/main/java/org/jooq/meta/DefaultColumnDefinition.java +++ b/jOOQ-meta/src/main/java/org/jooq/meta/DefaultColumnDefinition.java @@ -43,6 +43,7 @@ import static java.util.Collections.singletonList; import java.util.ArrayList; import java.util.List; +import org.jooq.meta.jaxb.SyntheticDefaultType; import org.jooq.meta.jaxb.SyntheticEnumType; import org.jooq.meta.jaxb.SyntheticIdentityType; import org.jooq.meta.jaxb.SyntheticReadonlyColumnType; @@ -60,6 +61,7 @@ public class DefaultColumnDefinition private static final JooqLogger log = JooqLogger.getLogger(DefaultColumnDefinition.class); private final int position; private final boolean identity; + private final String defaultValue; private final boolean hidden; private final boolean readonly; private transient List replacedByEmbeddables; @@ -102,6 +104,7 @@ public class DefaultColumnDefinition this.position = position; this.identity = identity || isSyntheticIdentity(this); + this.defaultValue = getSyntheticDefault(this); this.hidden = hidden; this.readonly = readonly || isSyntheticReadonlyColumn(this, this.identity); @@ -110,6 +113,7 @@ public class DefaultColumnDefinition dd.identity(this.identity); dd.hidden(this.hidden); dd.readonly(this.readonly); + dd.defaultValue(this.defaultValue); @@ -136,6 +140,25 @@ public class DefaultColumnDefinition return false; } + @SuppressWarnings("unused") + private static String getSyntheticDefault(DefaultColumnDefinition column) { + + + + + + + + + + + + + + + return column.getDefinedType().getDefaultValue(); + } + private static boolean isSyntheticReadonlyColumn(DefaultColumnDefinition column, boolean identity) { diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/DefaultDataTypeDefinition.java b/jOOQ-meta/src/main/java/org/jooq/meta/DefaultDataTypeDefinition.java index 50d352f5ed..c813aad66a 100644 --- a/jOOQ-meta/src/main/java/org/jooq/meta/DefaultDataTypeDefinition.java +++ b/jOOQ-meta/src/main/java/org/jooq/meta/DefaultDataTypeDefinition.java @@ -82,7 +82,7 @@ public class DefaultDataTypeDefinition implements DataTypeDefinition { private GenerationOption generationOption; private XMLTypeDefinition xmlTypeDefinition; private boolean identity; - private final String defaultValue; + private String defaultValue; private final int length; private final int precision; private final int scale; @@ -262,6 +262,11 @@ public class DefaultDataTypeDefinition implements DataTypeDefinition { return this; } + public final DefaultDataTypeDefinition defaultValue(String d) { + this.defaultValue = d; + return this; + } + @Override public final boolean isIdentity() { return identity; diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/ObjectFactory.java b/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/ObjectFactory.java index f923e10b0e..d7072356f2 100644 --- a/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/ObjectFactory.java +++ b/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/ObjectFactory.java @@ -253,6 +253,14 @@ public class ObjectFactory { return new SyntheticIdentityType(); } + /** + * Create an instance of {@link SyntheticDefaultType } + * + */ + public SyntheticDefaultType createSyntheticDefaultType() { + return new SyntheticDefaultType(); + } + /** * Create an instance of {@link SyntheticEnumType } * diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/SyntheticDefaultType.java b/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/SyntheticDefaultType.java new file mode 100644 index 0000000000..2f0b93f1c2 --- /dev/null +++ b/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/SyntheticDefaultType.java @@ -0,0 +1,243 @@ + +package org.jooq.meta.jaxb; + +import java.io.Serializable; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlType; +import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import org.jooq.util.jaxb.tools.StringAdapter; +import org.jooq.util.jaxb.tools.XMLAppendable; +import org.jooq.util.jaxb.tools.XMLBuilder; + + +/** + *

Java class for SyntheticDefaultType complex type. + * + *

The following schema fragment specifies the expected content contained within this class. + * + *

+ * <complexType name="SyntheticDefaultType">
+ *   <complexContent>
+ *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       <all>
+ *         <element name="tables" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="fields" type="{http://www.w3.org/2001/XMLSchema}string"/>
+ *         <element name="expression" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
+ *         <element name="ignoreUnused" type="{http://www.w3.org/2001/XMLSchema}boolean" minOccurs="0"/>
+ *       </all>
+ *     </restriction>
+ *   </complexContent>
+ * </complexType>
+ * 
+ * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "SyntheticDefaultType", propOrder = { + +}) +@SuppressWarnings({ + "all" +}) +public class SyntheticDefaultType implements Serializable, XMLAppendable +{ + + private final static long serialVersionUID = 32000L; + @XmlJavaTypeAdapter(StringAdapter.class) + protected String tables; + @XmlElement(required = true) + @XmlJavaTypeAdapter(StringAdapter.class) + protected String fields; + @XmlJavaTypeAdapter(StringAdapter.class) + protected String expression; + @XmlElement(defaultValue = "false") + protected Boolean ignoreUnused = false; + + /** + * A regular expression matching all tables on which to apply this synthetic default. + * + */ + public String getTables() { + return tables; + } + + /** + * A regular expression matching all tables on which to apply this synthetic default. + * + */ + public void setTables(String value) { + this.tables = value; + } + + /** + * A regular expression matching all fields on which to apply this synthetic default. + * + */ + public String getFields() { + return fields; + } + + /** + * A regular expression matching all fields on which to apply this synthetic default. + * + */ + public void setFields(String value) { + this.fields = value; + } + + /** + * The default expression to apply to the field. This is expected to be a valid SQL expression, e.g. 'some string', not some string + * + */ + public String getExpression() { + return expression; + } + + /** + * The default expression to apply to the field. This is expected to be a valid SQL expression, e.g. 'some string', not some string + * + */ + public void setExpression(String value) { + this.expression = value; + } + + /** + * Set this flag to true if no warning should be logged if this object was not used by a code generation run. + * + * @return + * possible object is + * {@link Boolean } + * + */ + public Boolean isIgnoreUnused() { + return ignoreUnused; + } + + /** + * Set this flag to true if no warning should be logged if this object was not used by a code generation run. + * + * @param value + * allowed object is + * {@link Boolean } + * + */ + public void setIgnoreUnused(Boolean value) { + this.ignoreUnused = value; + } + + /** + * A regular expression matching all tables on which to apply this synthetic default. + * + */ + public SyntheticDefaultType withTables(String value) { + setTables(value); + return this; + } + + /** + * A regular expression matching all fields on which to apply this synthetic default. + * + */ + public SyntheticDefaultType withFields(String value) { + setFields(value); + return this; + } + + /** + * The default expression to apply to the field. This is expected to be a valid SQL expression, e.g. 'some string', not some string + * + */ + public SyntheticDefaultType withExpression(String value) { + setExpression(value); + return this; + } + + /** + * Set this flag to true if no warning should be logged if this object was not used by a code generation run. + * + */ + public SyntheticDefaultType withIgnoreUnused(Boolean value) { + setIgnoreUnused(value); + return this; + } + + @Override + public final void appendTo(XMLBuilder builder) { + builder.append("tables", tables); + builder.append("fields", fields); + builder.append("expression", expression); + builder.append("ignoreUnused", ignoreUnused); + } + + @Override + public String toString() { + XMLBuilder builder = XMLBuilder.nonFormatting(); + appendTo(builder); + return builder.toString(); + } + + @Override + public boolean equals(Object that) { + if (this == that) { + return true; + } + if (that == null) { + return false; + } + if (getClass()!= that.getClass()) { + return false; + } + SyntheticDefaultType other = ((SyntheticDefaultType) that); + if (tables == null) { + if (other.tables!= null) { + return false; + } + } else { + if (!tables.equals(other.tables)) { + return false; + } + } + if (fields == null) { + if (other.fields!= null) { + return false; + } + } else { + if (!fields.equals(other.fields)) { + return false; + } + } + if (expression == null) { + if (other.expression!= null) { + return false; + } + } else { + if (!expression.equals(other.expression)) { + return false; + } + } + if (ignoreUnused == null) { + if (other.ignoreUnused!= null) { + return false; + } + } else { + if (!ignoreUnused.equals(other.ignoreUnused)) { + return false; + } + } + return true; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = ((prime*result)+((tables == null)? 0 :tables.hashCode())); + result = ((prime*result)+((fields == null)? 0 :fields.hashCode())); + result = ((prime*result)+((expression == null)? 0 :expression.hashCode())); + result = ((prime*result)+((ignoreUnused == null)? 0 :ignoreUnused.hashCode())); + return result; + } + +} diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/SyntheticObjectsType.java b/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/SyntheticObjectsType.java index c76d9d04ea..9aac194e28 100644 --- a/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/SyntheticObjectsType.java +++ b/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/SyntheticObjectsType.java @@ -43,6 +43,9 @@ public class SyntheticObjectsType implements Serializable, XMLAppendable @XmlElementWrapper(name = "identities") @XmlElement(name = "identity") protected List identities; + @XmlElementWrapper(name = "defaults") + @XmlElement(name = "default") + protected List defaults; @XmlElementWrapper(name = "enums") @XmlElement(name = "enum") protected List enums; @@ -106,6 +109,17 @@ public class SyntheticObjectsType implements Serializable, XMLAppendable this.identities = identities; } + public List getDefaults() { + if (defaults == null) { + defaults = new ArrayList(); + } + return defaults; + } + + public void setDefaults(List defaults) { + this.defaults = defaults; + } + public List getEnums() { if (enums == null) { enums = new ArrayList(); @@ -256,6 +270,27 @@ public class SyntheticObjectsType implements Serializable, XMLAppendable return this; } + public SyntheticObjectsType withDefaults(SyntheticDefaultType... values) { + if (values!= null) { + for (SyntheticDefaultType value: values) { + getDefaults().add(value); + } + } + return this; + } + + public SyntheticObjectsType withDefaults(Collection values) { + if (values!= null) { + getDefaults().addAll(values); + } + return this; + } + + public SyntheticObjectsType withDefaults(List defaults) { + setDefaults(defaults); + return this; + } + public SyntheticObjectsType withEnums(SyntheticEnumType... values) { if (values!= null) { for (SyntheticEnumType value: values) { @@ -388,6 +423,7 @@ public class SyntheticObjectsType implements Serializable, XMLAppendable builder.append("readonlyRowids", "readonlyRowid", readonlyRowids); builder.append("columns", "column", columns); builder.append("identities", "identity", identities); + builder.append("defaults", "default", defaults); builder.append("enums", "enum", enums); builder.append("primaryKeys", "primaryKey", primaryKeys); builder.append("uniqueKeys", "uniqueKey", uniqueKeys); @@ -451,6 +487,15 @@ public class SyntheticObjectsType implements Serializable, XMLAppendable return false; } } + if (defaults == null) { + if (other.defaults!= null) { + return false; + } + } else { + if (!defaults.equals(other.defaults)) { + return false; + } + } if (enums == null) { if (other.enums!= null) { return false; @@ -516,6 +561,7 @@ public class SyntheticObjectsType implements Serializable, XMLAppendable result = ((prime*result)+((readonlyRowids == null)? 0 :readonlyRowids.hashCode())); result = ((prime*result)+((columns == null)? 0 :columns.hashCode())); result = ((prime*result)+((identities == null)? 0 :identities.hashCode())); + result = ((prime*result)+((defaults == null)? 0 :defaults.hashCode())); result = ((prime*result)+((enums == null)? 0 :enums.hashCode())); result = ((prime*result)+((primaryKeys == null)? 0 :primaryKeys.hashCode())); result = ((prime*result)+((uniqueKeys == null)? 0 :uniqueKeys.hashCode())); diff --git a/jOOQ-meta/src/main/resources/org/jooq/meta/xsd/jooq-codegen-3.20.0.xsd b/jOOQ-meta/src/main/resources/org/jooq/meta/xsd/jooq-codegen-3.20.0.xsd index 20f1f5f51f..887a1db420 100644 --- a/jOOQ-meta/src/main/resources/org/jooq/meta/xsd/jooq-codegen-3.20.0.xsd +++ b/jOOQ-meta/src/main/resources/org/jooq/meta/xsd/jooq-codegen-3.20.0.xsd @@ -1475,6 +1475,10 @@ This feature is available in the commercial distribution only.]]>< + + + + @@ -1608,6 +1612,33 @@ Use this along with the synthetic primary key feature to replace existing primar + + + + + + + + + + + + + + + + + + + 'some string', not some string]]> + + + + + + + +