[jOOQ/jOOQ#8388] Generate Table.rowid() overrides, implement KotlinGenerator and ScalaGenerator, improved configuration

This commit is contained in:
Lukas Eder 2021-11-02 14:17:48 +01:00
parent e1d3a45206
commit eb126b2ee0
10 changed files with 176 additions and 94 deletions

View File

@ -576,17 +576,16 @@ public class GenerationTool {
database.setEmbeddablePrimaryKeys(d.getEmbeddablePrimaryKeys());
database.setEmbeddableUniqueKeys(d.getEmbeddableUniqueKeys());
database.setEmbeddableDomains(d.getEmbeddableDomains());
database.setReadonlyRowids(d.getReadonlyRowids());
database.setLogSlowQueriesAfterSeconds(defaultIfNull(d.getLogSlowQueriesAfterSeconds(), 5));
database.setLogSlowResultsAfterSeconds(defaultIfNull(d.getLogSlowResultsAfterSeconds(), 5));
if (d.getRegexFlags() != null) {
database.setRegexFlags(d.getRegexFlags());
if (strategy instanceof MatcherStrategy) {
if (strategy instanceof MatcherStrategy)
((MatcherStrategy) strategy).getPatterns().setRegexFlags(d.getRegexFlags());
}
}
database.setRegexMatchesPartialQualification(!FALSE.equals(d.isRegexMatchesPartialQualification()));
database.setSqlMatchesPartialQualification(!FALSE.equals(d.isSqlMatchesPartialQualification()));

View File

@ -108,6 +108,7 @@ import org.jooq.Parameter;
import org.jooq.Record;
import org.jooq.Result;
import org.jooq.Row;
import org.jooq.RowId;
import org.jooq.SQLDialect;
import org.jooq.Schema;
import org.jooq.Sequence;
@ -6210,6 +6211,31 @@ public class JavaGenerator extends AbstractGenerator {
out.println("}");
}
// [#7809] fieldsRow()
// [#10481] Use the types from replaced embeddables if applicable
List<Definition> replacingEmbeddablesAndUnreplacedColumns = replacingEmbeddablesAndUnreplacedColumns(table);

View File

@ -123,6 +123,7 @@ import org.jooq.meta.jaxb.SyntheticIdentityType;
import org.jooq.meta.jaxb.SyntheticObjectsType;
import org.jooq.meta.jaxb.SyntheticPrimaryKeyType;
import org.jooq.meta.jaxb.SyntheticReadonlyColumnType;
import org.jooq.meta.jaxb.SyntheticReadonlyRowidType;
import org.jooq.meta.jaxb.SyntheticUniqueKeyType;
import org.jooq.meta.jaxb.SyntheticViewType;
// ...
@ -204,6 +205,8 @@ public abstract class AbstractDatabase implements Database {
private Set<CommentType> unusedComments = new HashSet<>();
private List<SyntheticReadonlyColumnType> configuredSyntheticReadonlyColumns = new ArrayList<>();
private Set<SyntheticReadonlyColumnType> unusedSyntheticReadonlyColumns = new HashSet<>();
private List<SyntheticReadonlyRowidType> configuredSyntheticReadonlyRowids = new ArrayList<>();
private Set<SyntheticReadonlyRowidType> unusedSyntheticReadonlyRowids = new HashSet<>();
private List<SyntheticIdentityType> configuredSyntheticIdentities = new ArrayList<>();
private Set<SyntheticIdentityType> unusedSyntheticIdentities = new HashSet<>();
private List<SyntheticPrimaryKeyType> configuredSyntheticPrimaryKeys = new ArrayList<>();
@ -1996,23 +1999,6 @@ public abstract class AbstractDatabase implements Database {
this.embeddableDomains = embeddableDomains;
}
@Override
public String readonlyRowids() {
return readonlyRowids;
}
@SuppressWarnings("unused")
@Override
public void setReadonlyRowids(String readonlyRowids) {
if (!isBlank(readonlyRowids))
log.info("Commercial feature", "Readonly ROWIDs are a commercial only feature. Please consider upgrading to the jOOQ Professional Edition");
this.readonlyRowids = readonlyRowids;
}
@Override
public final List<EmbeddableDefinition> getEmbeddables() {
if (embeddables == null) {
@ -2838,12 +2824,15 @@ public abstract class AbstractDatabase implements Database {
// list but append it.
getConfiguredSyntheticReadonlyColumns().addAll(configuredSyntheticObjects.getReadonlyColumns());
getConfiguredSyntheticReadonlyRowids().addAll(configuredSyntheticObjects.getReadonlyRowids());
getConfiguredSyntheticIdentities().addAll(configuredSyntheticObjects.getIdentities());
getConfiguredSyntheticPrimaryKeys().addAll(configuredSyntheticObjects.getPrimaryKeys());
getConfiguredSyntheticUniqueKeys().addAll(configuredSyntheticObjects.getUniqueKeys());
getConfiguredSyntheticForeignKeys().addAll(configuredSyntheticObjects.getForeignKeys());
getConfiguredSyntheticViews().addAll(configuredSyntheticObjects.getViews());
unusedSyntheticReadonlyColumns.addAll(configuredSyntheticObjects.getReadonlyColumns());
unusedSyntheticReadonlyRowids.addAll(configuredSyntheticObjects.getReadonlyRowids());
unusedSyntheticIdentities.addAll(configuredSyntheticObjects.getIdentities());
unusedSyntheticPrimaryKeys.addAll(configuredSyntheticObjects.getPrimaryKeys());
unusedSyntheticUniqueKeys.addAll(configuredSyntheticObjects.getUniqueKeys());
@ -2857,6 +2846,8 @@ public abstract class AbstractDatabase implements Database {
if (!configuredSyntheticObjects.getReadonlyColumns().isEmpty())
log.info("Commercial feature", "Synthetic read only columns are a commercial only feature. Please upgrade to the jOOQ Professional Edition");
if (!configuredSyntheticObjects.getReadonlyRowids().isEmpty())
log.info("Commercial feature", "Synthetic read only rowids are a commercial only feature. Please upgrade to the jOOQ Professional Edition");
if (!configuredSyntheticObjects.getUniqueKeys().isEmpty())
log.info("Commercial feature", "Synthetic unique keys are a commercial only feature. Please upgrade to the jOOQ Professional Edition");
if (!configuredSyntheticObjects.getForeignKeys().isEmpty())
@ -2872,6 +2863,14 @@ public abstract class AbstractDatabase implements Database {
return configuredSyntheticReadonlyColumns;
}
@Override
public List<SyntheticReadonlyRowidType> getConfiguredSyntheticReadonlyRowids() {
if (configuredSyntheticReadonlyRowids == null)
configuredSyntheticReadonlyRowids = new ArrayList<>();
return configuredSyntheticReadonlyRowids;
}
@Override
public List<SyntheticIdentityType> getConfiguredSyntheticIdentities() {
if (configuredSyntheticIdentities == null)
@ -2917,6 +2916,11 @@ public abstract class AbstractDatabase implements Database {
unusedSyntheticReadonlyColumns.remove(readonlyColumn);
}
@Override
public void markUsed(SyntheticReadonlyRowidType readonlyRowid) {
unusedSyntheticReadonlyRowids.remove(readonlyRowid);
}
@Override
public void markUsed(SyntheticIdentityType identity) {
unusedSyntheticIdentities.remove(identity);
@ -2947,6 +2951,11 @@ public abstract class AbstractDatabase implements Database {
return new ArrayList<>(unusedSyntheticReadonlyColumns);
}
@Override
public List<SyntheticReadonlyRowidType> getUnusedSyntheticReadonlyRowids() {
return new ArrayList<>(unusedSyntheticReadonlyRowids);
}
@Override
public List<SyntheticIdentityType> getUnusedSyntheticIdentities() {
return new ArrayList<>(unusedSyntheticIdentities);

View File

@ -38,8 +38,10 @@
package org.jooq.meta;
import static java.util.Collections.singletonList;
import static org.jooq.meta.AbstractDatabase.fetchedSize;
import static org.jooq.meta.AbstractDatabase.getDefinition;
import static org.jooq.tools.StringUtils.defaultIfEmpty;
import java.sql.SQLException;
import java.util.ArrayList;
@ -47,6 +49,9 @@ import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
// ...
import org.jooq.meta.jaxb.SyntheticReadonlyColumnType;
import org.jooq.meta.jaxb.SyntheticReadonlyRowidType;
import org.jooq.tools.JooqLogger;
import org.jooq.tools.StringUtils;
@ -89,7 +94,7 @@ extends AbstractDefinition {
List<E> e = getElements0();
// [#5335] Warn if a table definition contains several identity columns
if (this instanceof TableDefinition) {
if (this instanceof TableDefinition) { TableDefinition t = (TableDefinition) this;
if (e.stream().map(c -> (ColumnDefinition) c).filter(ColumnDefinition::isIdentity).count() > 1)
log.warn("Multiple identities", "Table " + getOutputName() + " has multiple identity columns. Only the first one is considered.");
@ -107,6 +112,7 @@ extends AbstractDefinition {
}
// [#2603] Filter exclude / include also for table columns
@ -127,6 +133,25 @@ extends AbstractDefinition {
return elements;
}
protected final E getElement(String name) {
return getElement(name, false);
}

View File

@ -63,6 +63,7 @@ import org.jooq.meta.jaxb.SyntheticIdentityType;
import org.jooq.meta.jaxb.SyntheticObjectsType;
import org.jooq.meta.jaxb.SyntheticPrimaryKeyType;
import org.jooq.meta.jaxb.SyntheticReadonlyColumnType;
import org.jooq.meta.jaxb.SyntheticReadonlyRowidType;
import org.jooq.meta.jaxb.SyntheticUniqueKeyType;
import org.jooq.meta.jaxb.SyntheticViewType;
@ -1068,20 +1069,6 @@ public interface Database extends AutoCloseable {
*/
void setEmbeddableDomains(String embeddableDomains);
/**
* A regular expression matching all tables for which a synthetic <code>ROWID</code> column should be generated.
* <p>
* This feature is available in the commercial distribution only.
*/
String readonlyRowids();
/**
* A regular expression matching all tables for which a synthetic <code>ROWID</code> column should be generated.
* <p>
* This feature is available in the commercial distribution only.
*/
void setReadonlyRowids(String readonlyRowids);
/**
* Configure the comments.
*/
@ -1112,6 +1099,11 @@ public interface Database extends AutoCloseable {
*/
List<SyntheticReadonlyColumnType> getConfiguredSyntheticReadonlyColumns();
/**
* Get the configured synthetic readonly rowids.
*/
List<SyntheticReadonlyRowidType> getConfiguredSyntheticReadonlyRowids();
/**
* Get the configured synthetic identities.
*/
@ -1147,6 +1139,16 @@ public interface Database extends AutoCloseable {
*/
List<SyntheticReadonlyColumnType> getUnusedSyntheticReadonlyColumns();
/**
* Mark a synthetic readonly rowids as used.
*/
void markUsed(SyntheticReadonlyRowidType readonlyRowid);
/**
* Retrieve the not-yet used synthetic readonly rowids.
*/
List<SyntheticReadonlyRowidType> getUnusedSyntheticReadonlyRowids();
/**
* Mark a synthetic identity as used.
*/

View File

@ -150,8 +150,6 @@ public class Database implements Serializable, XMLAppendable
protected String embeddableUniqueKeys;
@XmlJavaTypeAdapter(StringAdapter.class)
protected String embeddableDomains;
@XmlJavaTypeAdapter(StringAdapter.class)
protected String readonlyRowids;
@XmlElement(defaultValue = "true")
protected Boolean forceIntegerTypesOnZeroScaleDecimals = true;
protected Boolean tableValuedFunctions;
@ -1575,30 +1573,6 @@ public class Database implements Serializable, XMLAppendable
this.embeddableDomains = value;
}
/**
* A regular expression matching all tables for which a synthetic <code>ROWID</code> column should be generated.
* <p>
* Use this along with the synthetic primary key feature to replace existing primary key usage by <code>ROWID</code> usage, if this makes sense for your {@link UpdatableRecord}.
* <p>
* This feature is available in the commercial distribution only.
*
*/
public String getReadonlyRowids() {
return readonlyRowids;
}
/**
* A regular expression matching all tables for which a synthetic <code>ROWID</code> column should be generated.
* <p>
* Use this along with the synthetic primary key feature to replace existing primary key usage by <code>ROWID</code> usage, if this makes sense for your {@link UpdatableRecord}.
* <p>
* This feature is available in the commercial distribution only.
*
*/
public void setReadonlyRowids(String value) {
this.readonlyRowids = value;
}
/**
* Historically, zero-scale decimal types are generated as their most appropriate, corresponding integer type (e.g. NUMBER(2, 0) and less: Byte). This allows for turning off this feature. In case of conflict between this rule and actual {@link #getForcedTypes()}, the latter will win.
*
@ -2312,19 +2286,6 @@ public class Database implements Serializable, XMLAppendable
return this;
}
/**
* A regular expression matching all tables for which a synthetic <code>ROWID</code> column should be generated.
* <p>
* Use this along with the synthetic primary key feature to replace existing primary key usage by <code>ROWID</code> usage, if this makes sense for your {@link UpdatableRecord}.
* <p>
* This feature is available in the commercial distribution only.
*
*/
public Database withReadonlyRowids(String value) {
setReadonlyRowids(value);
return this;
}
public Database withForceIntegerTypesOnZeroScaleDecimals(Boolean value) {
setForceIntegerTypesOnZeroScaleDecimals(value);
return this;
@ -2581,7 +2542,6 @@ public class Database implements Serializable, XMLAppendable
builder.append("embeddablePrimaryKeys", embeddablePrimaryKeys);
builder.append("embeddableUniqueKeys", embeddableUniqueKeys);
builder.append("embeddableDomains", embeddableDomains);
builder.append("readonlyRowids", readonlyRowids);
builder.append("forceIntegerTypesOnZeroScaleDecimals", forceIntegerTypesOnZeroScaleDecimals);
builder.append("tableValuedFunctions", tableValuedFunctions);
builder.append("logSlowQueriesAfterSeconds", logSlowQueriesAfterSeconds);
@ -3083,15 +3043,6 @@ public class Database implements Serializable, XMLAppendable
return false;
}
}
if (readonlyRowids == null) {
if (other.readonlyRowids!= null) {
return false;
}
} else {
if (!readonlyRowids.equals(other.readonlyRowids)) {
return false;
}
}
if (forceIntegerTypesOnZeroScaleDecimals == null) {
if (other.forceIntegerTypesOnZeroScaleDecimals!= null) {
return false;
@ -3259,7 +3210,6 @@ public class Database implements Serializable, XMLAppendable
result = ((prime*result)+((embeddablePrimaryKeys == null)? 0 :embeddablePrimaryKeys.hashCode()));
result = ((prime*result)+((embeddableUniqueKeys == null)? 0 :embeddableUniqueKeys.hashCode()));
result = ((prime*result)+((embeddableDomains == null)? 0 :embeddableDomains.hashCode()));
result = ((prime*result)+((readonlyRowids == null)? 0 :readonlyRowids.hashCode()));
result = ((prime*result)+((forceIntegerTypesOnZeroScaleDecimals == null)? 0 :forceIntegerTypesOnZeroScaleDecimals.hashCode()));
result = ((prime*result)+((tableValuedFunctions == null)? 0 :tableValuedFunctions.hashCode()));
result = ((prime*result)+((logSlowQueriesAfterSeconds == null)? 0 :logSlowQueriesAfterSeconds.hashCode()));

View File

@ -181,6 +181,14 @@ public class ObjectFactory {
return new SyntheticReadonlyColumnType();
}
/**
* Create an instance of {@link SyntheticReadonlyRowidType }
*
*/
public SyntheticReadonlyRowidType createSyntheticReadonlyRowidType() {
return new SyntheticReadonlyRowidType();
}
/**
* Create an instance of {@link SyntheticIdentityType }
*

View File

@ -34,6 +34,9 @@ public class SyntheticObjectsType implements Serializable, XMLAppendable
@XmlElementWrapper(name = "readonlyColumns")
@XmlElement(name = "readonlyColumn")
protected List<SyntheticReadonlyColumnType> readonlyColumns;
@XmlElementWrapper(name = "readonlyRowids")
@XmlElement(name = "readonlyRowid")
protected List<SyntheticReadonlyRowidType> readonlyRowids;
@XmlElementWrapper(name = "identities")
@XmlElement(name = "identity")
protected List<SyntheticIdentityType> identities;
@ -61,6 +64,17 @@ public class SyntheticObjectsType implements Serializable, XMLAppendable
this.readonlyColumns = readonlyColumns;
}
public List<SyntheticReadonlyRowidType> getReadonlyRowids() {
if (readonlyRowids == null) {
readonlyRowids = new ArrayList<SyntheticReadonlyRowidType>();
}
return readonlyRowids;
}
public void setReadonlyRowids(List<SyntheticReadonlyRowidType> readonlyRowids) {
this.readonlyRowids = readonlyRowids;
}
public List<SyntheticIdentityType> getIdentities() {
if (identities == null) {
identities = new ArrayList<SyntheticIdentityType>();
@ -137,6 +151,27 @@ public class SyntheticObjectsType implements Serializable, XMLAppendable
return this;
}
public SyntheticObjectsType withReadonlyRowids(SyntheticReadonlyRowidType... values) {
if (values!= null) {
for (SyntheticReadonlyRowidType value: values) {
getReadonlyRowids().add(value);
}
}
return this;
}
public SyntheticObjectsType withReadonlyRowids(Collection<SyntheticReadonlyRowidType> values) {
if (values!= null) {
getReadonlyRowids().addAll(values);
}
return this;
}
public SyntheticObjectsType withReadonlyRowids(List<SyntheticReadonlyRowidType> readonlyRowids) {
setReadonlyRowids(readonlyRowids);
return this;
}
public SyntheticObjectsType withIdentities(SyntheticIdentityType... values) {
if (values!= null) {
for (SyntheticIdentityType value: values) {
@ -245,6 +280,7 @@ public class SyntheticObjectsType implements Serializable, XMLAppendable
@Override
public final void appendTo(XMLBuilder builder) {
builder.append("readonlyColumns", "readonlyColumn", readonlyColumns);
builder.append("readonlyRowids", "readonlyRowid", readonlyRowids);
builder.append("identities", "identity", identities);
builder.append("primaryKeys", "primaryKey", primaryKeys);
builder.append("uniqueKeys", "uniqueKey", uniqueKeys);
@ -280,6 +316,15 @@ public class SyntheticObjectsType implements Serializable, XMLAppendable
return false;
}
}
if (readonlyRowids == null) {
if (other.readonlyRowids!= null) {
return false;
}
} else {
if (!readonlyRowids.equals(other.readonlyRowids)) {
return false;
}
}
if (identities == null) {
if (other.identities!= null) {
return false;
@ -333,6 +378,7 @@ public class SyntheticObjectsType implements Serializable, XMLAppendable
final int prime = 31;
int result = 1;
result = ((prime*result)+((readonlyColumns == null)? 0 :readonlyColumns.hashCode()));
result = ((prime*result)+((readonlyRowids == null)? 0 :readonlyRowids.hashCode()));
result = ((prime*result)+((identities == null)? 0 :identities.hashCode()));
result = ((prime*result)+((primaryKeys == null)? 0 :primaryKeys.hashCode()));
result = ((prime*result)+((uniqueKeys == null)? 0 :uniqueKeys.hashCode()));

View File

@ -887,14 +887,6 @@ This feature is available in the commercial distribution only.]]></jxb:javadoc><
<element name="embeddableDomains" type="string" minOccurs="0" maxOccurs="1">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[A regular expression matching all domain type declarations for which wrapper types should be generated.
<p>
This feature is available in the commercial distribution only.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
<element name="readonlyRowids" type="string" minOccurs="0" maxOccurs="1">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[A regular expression matching all tables for which a synthetic <code>ROWID</code> column should be generated.
<p>
Use this along with the synthetic primary key feature to replace existing primary key usage by <code>ROWID</code> usage, if this makes sense for your {@link UpdatableRecord}.
<p>
This feature is available in the commercial distribution only.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
@ -987,6 +979,10 @@ This feature is available in the commercial distribution only.]]></jxb:javadoc><
<element name="readonlyColumns" type="tns:SyntheticReadonlyColumnsType" minOccurs="0" maxOccurs="1">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Synthetic read only columns configuration]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
<element name="readonlyRowids" type="tns:SyntheticReadonlyRowidsType" minOccurs="0" maxOccurs="1">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Synthetic ROWIDs configuration.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
<element name="identities" type="tns:SyntheticIdentitiesType" minOccurs="0" maxOccurs="1">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Synthetic identity configuration]]></jxb:javadoc></jxb:property></appinfo></annotation>
@ -1033,6 +1029,27 @@ This feature is available in the commercial distribution only.]]></jxb:javadoc><
</all>
</complexType>
<complexType name="SyntheticReadonlyRowidsType">
<sequence>
<element name="readonlyRowid" type="tns:SyntheticReadonlyRowidType" minOccurs="1" maxOccurs="unbounded"/>
</sequence>
</complexType>
<complexType name="SyntheticReadonlyRowidType">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Synthetic ROWIDs configurationA regular expression matching all tables for which a synthetic <code>ROWID</code> column should be generated.
<p>
Use this along with the synthetic primary key feature to replace existing primary key usage by <code>ROWID</code> usage, if this makes sense for your {@link UpdatableRecord}.]]></jxb:javadoc></jxb:property></appinfo></annotation>
<all>
<element name="name" type="string" minOccurs="0" maxOccurs="1">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[The optional ROWID column name.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
<element name="tables" type="string" minOccurs="0" maxOccurs="1">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[A regular expression matching all tables on which to apply this synthetic ROWID.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
</all>
</complexType>
<complexType name="SyntheticIdentitiesType">
<sequence>
<element name="identity" type="tns:SyntheticIdentityType" minOccurs="1" maxOccurs="unbounded"/>

View File

@ -784,7 +784,7 @@ abstract class AbstractTable<R extends Record> extends AbstractNamed implements
// -------------------------------------------------------------------------
@Override
public final Field<RowId> rowid() {
public /* non-final */ Field<RowId> rowid() {
return new QualifiedRowid(this);
}