[#3154] Add code-generation configuration to generate synthetic primary keys for updatable views
This commit is contained in:
parent
a0bef16560
commit
a507d50bc4
@ -314,6 +314,7 @@ public class GenerationTool {
|
||||
database.setIncludeExcludeColumns(TRUE.equals(d.isIncludeExcludeColumns()));
|
||||
database.setRecordVersionFields(new String[] { defaultString(d.getRecordVersionFields()) });
|
||||
database.setRecordTimestampFields(new String[] { defaultString(d.getRecordTimestampFields()) });
|
||||
database.setSyntheticPrimaryKeys(new String[] { defaultString(d.getSyntheticPrimaryKeys()) });
|
||||
database.setOverridePrimaryKeys(new String[] { defaultString(d.getOverridePrimaryKeys()) });
|
||||
database.setConfiguredCustomTypes(d.getCustomTypes());
|
||||
database.setConfiguredEnumTypes(d.getEnumTypes());
|
||||
|
||||
@ -94,6 +94,7 @@ public abstract class AbstractDatabase implements Database {
|
||||
private boolean includeExcludeColumns;
|
||||
private String[] recordVersionFields;
|
||||
private String[] recordTimestampFields;
|
||||
private String[] syntheticPrimaryKeys;
|
||||
private String[] overridePrimaryKeys;
|
||||
private boolean supportsUnsignedTypes;
|
||||
private boolean dateAsTimestamp;
|
||||
@ -332,6 +333,16 @@ public abstract class AbstractDatabase implements Database {
|
||||
return recordTimestampFields;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSyntheticPrimaryKeys(String[] syntheticPrimaryKeys) {
|
||||
this.syntheticPrimaryKeys = syntheticPrimaryKeys;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getSyntheticPrimaryKeys() {
|
||||
return syntheticPrimaryKeys;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOverridePrimaryKeys(String[] overridePrimaryKeys) {
|
||||
this.overridePrimaryKeys = overridePrimaryKeys;
|
||||
@ -883,6 +894,13 @@ public abstract class AbstractDatabase implements Database {
|
||||
log.error("Error while fetching check constraints", e);
|
||||
}
|
||||
|
||||
try {
|
||||
syntheticPrimaryKeys(result);
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("Error while generating synthetic primary keys", e);
|
||||
}
|
||||
|
||||
try {
|
||||
overridePrimaryKeys(result);
|
||||
}
|
||||
@ -910,6 +928,28 @@ public abstract class AbstractDatabase implements Database {
|
||||
return fetched.size() + " (" + included.size() + " included, " + (fetched.size() - included.size()) + " excluded)";
|
||||
}
|
||||
|
||||
private final void syntheticPrimaryKeys(DefaultRelations r) {
|
||||
List<UniqueKeyDefinition> syntheticKeys = new ArrayList<UniqueKeyDefinition>();
|
||||
|
||||
for (SchemaDefinition schema : getSchemata()) {
|
||||
for (TableDefinition table : schema.getTables()) {
|
||||
List<ColumnDefinition> columns = filterExcludeInclude(table.getColumns(), null, getSyntheticPrimaryKeys());
|
||||
|
||||
if (!columns.isEmpty()) {
|
||||
DefaultUniqueKeyDefinition syntheticKey = new DefaultUniqueKeyDefinition(schema, "SYNTHETIC_PK_" + table.getName(), table, true);
|
||||
syntheticKey.getKeyColumns().addAll(columns);
|
||||
syntheticKeys.add(syntheticKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log.info("Synthetic primary keys", fetchedSize(syntheticKeys, syntheticKeys));
|
||||
|
||||
for (UniqueKeyDefinition key : syntheticKeys) {
|
||||
r.overridePrimaryKey(key);
|
||||
}
|
||||
}
|
||||
|
||||
private final void overridePrimaryKeys(DefaultRelations r) {
|
||||
List<UniqueKeyDefinition> allKeys = r.getUniqueKeys();
|
||||
List<UniqueKeyDefinition> filteredKeys = filterExcludeInclude(allKeys, null, overridePrimaryKeys);
|
||||
|
||||
@ -259,6 +259,18 @@ public interface Database {
|
||||
*/
|
||||
String[] getRecordTimestampFields();
|
||||
|
||||
/**
|
||||
* Columns matching these regular expressions will be considered as members
|
||||
* of synthetic primary keys in generated code.
|
||||
*/
|
||||
void setSyntheticPrimaryKeys(String[] primaryKeys);
|
||||
|
||||
/**
|
||||
* Columns matching these regular expressions will be considered as members
|
||||
* of synthetic primary keys in generated code.
|
||||
*/
|
||||
String[] getSyntheticPrimaryKeys();
|
||||
|
||||
/**
|
||||
* Unique keys matching these regular expressions will be considered as
|
||||
* primary keys in generated code.
|
||||
|
||||
@ -105,8 +105,9 @@ public class DefaultRelations implements Relations {
|
||||
|
||||
// Remove the existing key from the column -> key mapping
|
||||
primaryKeysByColumn = null;
|
||||
uniqueKeysByColumn = null;
|
||||
|
||||
// Remove the existing key from the key mapping
|
||||
// Remove the existing key from the primary key mapping (not from the unique key mapping!)
|
||||
Iterator<Entry<Key, UniqueKeyDefinition>> it = primaryKeys.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Entry<Key, UniqueKeyDefinition> entry = it.next();
|
||||
@ -119,7 +120,9 @@ public class DefaultRelations implements Relations {
|
||||
}
|
||||
|
||||
// Add the new primary key
|
||||
primaryKeys.put(key(key.getTable(), key.getName()), key);
|
||||
Key mapKey = key(key.getTable(), key.getName());
|
||||
primaryKeys.put(mapKey, key);
|
||||
uniqueKeys.put(mapKey, key);
|
||||
log.info("Overriding primary key", "Table : " + key.getTable() +
|
||||
", previous key : " + ((old == null) ? "none" : old.getName()) +
|
||||
", new key : " + key.getName());
|
||||
|
||||
@ -371,6 +371,19 @@
|
||||
-->
|
||||
<element name="recordTimestampFields" type="string" default="" minOccurs="0" maxOccurs="1" />
|
||||
|
||||
<!--
|
||||
A regular expression matching all columns that participate in "synthetic" primary keys,
|
||||
which should be placed on generated UpdatableRecords, to be used with
|
||||
|
||||
- UpdatableRecord.store()
|
||||
- UpdatableRecord.update()
|
||||
- UpdatableRecord.delete()
|
||||
- UpdatableRecord.refresh()
|
||||
|
||||
Synthetic primary keys will override existing primary keys.
|
||||
-->
|
||||
<element name="syntheticPrimaryKeys" type="string" default="" minOccurs="0" maxOccurs="1" />
|
||||
|
||||
<!--
|
||||
All (UNIQUE) key names that should be used instead of primary keys on
|
||||
generated UpdatableRecords, to be used with
|
||||
@ -381,6 +394,8 @@
|
||||
- UpdatableRecord.refresh()
|
||||
|
||||
If several keys match, a warning is emitted and the first one encountered will be used.
|
||||
|
||||
This flag will also replace synthetic primary keys, if it matches.
|
||||
-->
|
||||
<element name="overridePrimaryKeys" type="string" default="" minOccurs="0" maxOccurs="1" />
|
||||
|
||||
|
||||
@ -1 +1,9 @@
|
||||
SET MAVEN_OPTS=-Xdebug -Xnoagent -Djava.compile=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005
|
||||
@ECHO OFF
|
||||
|
||||
IF "%1" == "off" (
|
||||
SET MAVEN_OPTS=
|
||||
) ELSE (
|
||||
SET MAVEN_OPTS=-Xdebug -Xnoagent -Djava.compile=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005
|
||||
)
|
||||
|
||||
SET MAVEN_OPTS
|
||||
@ -1170,6 +1170,13 @@
|
||||
| ASDF_ASDF_ASDF # This should not have any effect
|
||||
| ASDF_ASDF_ASDF # This should not have any effect
|
||||
</recordTimestampFields>
|
||||
<syntheticPrimaryKeys>
|
||||
.*\. # All schemas
|
||||
(?i:
|
||||
V_AUTHOR\.ID # Some updatable view columns
|
||||
| V_BOOK\.ID # Some updatable view columns
|
||||
)
|
||||
</syntheticPrimaryKeys>
|
||||
<dateAsTimestamp>false</dateAsTimestamp>
|
||||
<unsignedTypes>true</unsignedTypes>
|
||||
<inputSchema>${db.h2.schema}</inputSchema>
|
||||
|
||||
@ -46,6 +46,8 @@ public class Keys {
|
||||
public static final org.jooq.UniqueKey<org.jooq.test.h2.generatedclasses.tables.records.XTestCase_64_69Record> PK_X_TEST_CASE_64_69 = UniqueKeys0.PK_X_TEST_CASE_64_69;
|
||||
public static final org.jooq.UniqueKey<org.jooq.test.h2.generatedclasses.tables.records.XTestCase_71Record> PK_X_TEST_CASE_71 = UniqueKeys0.PK_X_TEST_CASE_71;
|
||||
public static final org.jooq.UniqueKey<org.jooq.test.h2.generatedclasses.tables.records.XTestCase_85Record> PK_X_TEST_CASE_85 = UniqueKeys0.PK_X_TEST_CASE_85;
|
||||
public static final org.jooq.UniqueKey<org.jooq.test.h2.generatedclasses.tables.records.VAuthorRecord> SYNTHETIC_PK_V_AUTHOR = UniqueKeys0.SYNTHETIC_PK_V_AUTHOR;
|
||||
public static final org.jooq.UniqueKey<org.jooq.test.h2.generatedclasses.tables.records.VBookRecord> SYNTHETIC_PK_V_BOOK = UniqueKeys0.SYNTHETIC_PK_V_BOOK;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// FOREIGN KEY definitions
|
||||
@ -98,6 +100,8 @@ public class Keys {
|
||||
public static final org.jooq.UniqueKey<org.jooq.test.h2.generatedclasses.tables.records.XTestCase_64_69Record> PK_X_TEST_CASE_64_69 = createUniqueKey(org.jooq.test.h2.generatedclasses.tables.XTestCase_64_69.X_TEST_CASE_64_69, org.jooq.test.h2.generatedclasses.tables.XTestCase_64_69.X_TEST_CASE_64_69.ID);
|
||||
public static final org.jooq.UniqueKey<org.jooq.test.h2.generatedclasses.tables.records.XTestCase_71Record> PK_X_TEST_CASE_71 = createUniqueKey(org.jooq.test.h2.generatedclasses.tables.XTestCase_71.X_TEST_CASE_71, org.jooq.test.h2.generatedclasses.tables.XTestCase_71.X_TEST_CASE_71.ID);
|
||||
public static final org.jooq.UniqueKey<org.jooq.test.h2.generatedclasses.tables.records.XTestCase_85Record> PK_X_TEST_CASE_85 = createUniqueKey(org.jooq.test.h2.generatedclasses.tables.XTestCase_85.X_TEST_CASE_85, org.jooq.test.h2.generatedclasses.tables.XTestCase_85.X_TEST_CASE_85.ID);
|
||||
public static final org.jooq.UniqueKey<org.jooq.test.h2.generatedclasses.tables.records.VAuthorRecord> SYNTHETIC_PK_V_AUTHOR = createUniqueKey(org.jooq.test.h2.generatedclasses.tables.VAuthor.V_AUTHOR, org.jooq.test.h2.generatedclasses.tables.VAuthor.V_AUTHOR.ID);
|
||||
public static final org.jooq.UniqueKey<org.jooq.test.h2.generatedclasses.tables.records.VBookRecord> SYNTHETIC_PK_V_BOOK = createUniqueKey(org.jooq.test.h2.generatedclasses.tables.VBook.V_BOOK, org.jooq.test.h2.generatedclasses.tables.VBook.V_BOOK.ID);
|
||||
}
|
||||
|
||||
private static class ForeignKeys0 extends org.jooq.impl.AbstractKeys {
|
||||
|
||||
@ -9,7 +9,7 @@ package org.jooq.test.h2.generatedclasses.tables;
|
||||
@java.lang.SuppressWarnings({ "all", "unchecked", "rawtypes" })
|
||||
public class VAuthor extends org.jooq.impl.TableImpl<org.jooq.test.h2.generatedclasses.tables.records.VAuthorRecord> {
|
||||
|
||||
private static final long serialVersionUID = -1789099087;
|
||||
private static final long serialVersionUID = 2131959173;
|
||||
|
||||
/**
|
||||
* The singleton instance of <code>PUBLIC.V_AUTHOR</code>
|
||||
@ -76,6 +76,22 @@ public class VAuthor extends org.jooq.impl.TableImpl<org.jooq.test.h2.generatedc
|
||||
super(alias, org.jooq.test.h2.generatedclasses.Public.PUBLIC, aliased, parameters, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public org.jooq.UniqueKey<org.jooq.test.h2.generatedclasses.tables.records.VAuthorRecord> getPrimaryKey() {
|
||||
return org.jooq.test.h2.generatedclasses.Keys.SYNTHETIC_PK_V_AUTHOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public java.util.List<org.jooq.UniqueKey<org.jooq.test.h2.generatedclasses.tables.records.VAuthorRecord>> getKeys() {
|
||||
return java.util.Arrays.<org.jooq.UniqueKey<org.jooq.test.h2.generatedclasses.tables.records.VAuthorRecord>>asList(org.jooq.test.h2.generatedclasses.Keys.SYNTHETIC_PK_V_AUTHOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
||||
@ -9,7 +9,7 @@ package org.jooq.test.h2.generatedclasses.tables;
|
||||
@java.lang.SuppressWarnings({ "all", "unchecked", "rawtypes" })
|
||||
public class VBook extends org.jooq.impl.TableImpl<org.jooq.test.h2.generatedclasses.tables.records.VBookRecord> {
|
||||
|
||||
private static final long serialVersionUID = 2008359507;
|
||||
private static final long serialVersionUID = 424616229;
|
||||
|
||||
/**
|
||||
* The singleton instance of <code>PUBLIC.V_BOOK</code>
|
||||
@ -101,6 +101,38 @@ public class VBook extends org.jooq.impl.TableImpl<org.jooq.test.h2.generatedcla
|
||||
super(alias, org.jooq.test.h2.generatedclasses.Public.PUBLIC, aliased, parameters, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public org.jooq.UniqueKey<org.jooq.test.h2.generatedclasses.tables.records.VBookRecord> getPrimaryKey() {
|
||||
return org.jooq.test.h2.generatedclasses.Keys.SYNTHETIC_PK_V_BOOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public java.util.List<org.jooq.UniqueKey<org.jooq.test.h2.generatedclasses.tables.records.VBookRecord>> getKeys() {
|
||||
return java.util.Arrays.<org.jooq.UniqueKey<org.jooq.test.h2.generatedclasses.tables.records.VBookRecord>>asList(org.jooq.test.h2.generatedclasses.Keys.SYNTHETIC_PK_V_BOOK);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public org.jooq.TableField<org.jooq.test.h2.generatedclasses.tables.records.VBookRecord, java.lang.Integer> getRecordVersion() {
|
||||
return org.jooq.test.h2.generatedclasses.tables.VBook.V_BOOK.REC_VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public org.jooq.TableField<org.jooq.test.h2.generatedclasses.tables.records.VBookRecord, java.sql.Timestamp> getRecordTimestamp() {
|
||||
return org.jooq.test.h2.generatedclasses.tables.VBook.V_BOOK.REC_TIMESTAMP;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
||||
@ -7,9 +7,9 @@ package org.jooq.test.h2.generatedclasses.tables.records;
|
||||
* This class is generated by jOOQ.
|
||||
*/
|
||||
@java.lang.SuppressWarnings({ "all", "unchecked", "rawtypes" })
|
||||
public class VAuthorRecord extends org.jooq.impl.TableRecordImpl<org.jooq.test.h2.generatedclasses.tables.records.VAuthorRecord> implements org.jooq.Record6<java.lang.Integer, java.lang.String, java.lang.String, java.sql.Date, java.lang.Integer, java.lang.String>, org.jooq.test.h2.generatedclasses.tables.interfaces.IVAuthor {
|
||||
public class VAuthorRecord extends org.jooq.impl.UpdatableRecordImpl<org.jooq.test.h2.generatedclasses.tables.records.VAuthorRecord> implements org.jooq.Record6<java.lang.Integer, java.lang.String, java.lang.String, java.sql.Date, java.lang.Integer, java.lang.String>, org.jooq.test.h2.generatedclasses.tables.interfaces.IVAuthor {
|
||||
|
||||
private static final long serialVersionUID = -1737704365;
|
||||
private static final long serialVersionUID = 355974962;
|
||||
|
||||
/**
|
||||
* Setter for <code>PUBLIC.V_AUTHOR.ID</code>.
|
||||
@ -113,6 +113,18 @@ public class VAuthorRecord extends org.jooq.impl.TableRecordImpl<org.jooq.test.h
|
||||
return (java.lang.String) getValue(5);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Primary key information
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public org.jooq.Record1<java.lang.Integer> key() {
|
||||
return (org.jooq.Record1) super.key();
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Record6 type implementation
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@ -7,9 +7,9 @@ package org.jooq.test.h2.generatedclasses.tables.records;
|
||||
* This class is generated by jOOQ.
|
||||
*/
|
||||
@java.lang.SuppressWarnings({ "all", "unchecked", "rawtypes" })
|
||||
public class VBookRecord extends org.jooq.impl.TableRecordImpl<org.jooq.test.h2.generatedclasses.tables.records.VBookRecord> implements org.jooq.Record11<java.lang.Integer, java.lang.Integer, java.lang.Integer, java.lang.Integer, java.lang.String, java.lang.Integer, java.lang.Integer, java.lang.String, byte[], java.lang.Integer, java.sql.Timestamp>, org.jooq.test.h2.generatedclasses.tables.interfaces.IVBook {
|
||||
public class VBookRecord extends org.jooq.impl.UpdatableRecordImpl<org.jooq.test.h2.generatedclasses.tables.records.VBookRecord> implements org.jooq.Record11<java.lang.Integer, java.lang.Integer, java.lang.Integer, java.lang.Integer, java.lang.String, java.lang.Integer, java.lang.Integer, java.lang.String, byte[], java.lang.Integer, java.sql.Timestamp>, org.jooq.test.h2.generatedclasses.tables.interfaces.IVBook {
|
||||
|
||||
private static final long serialVersionUID = 1399887711;
|
||||
private static final long serialVersionUID = -1694762730;
|
||||
|
||||
/**
|
||||
* Setter for <code>PUBLIC.V_BOOK.ID</code>.
|
||||
@ -198,6 +198,18 @@ public class VBookRecord extends org.jooq.impl.TableRecordImpl<org.jooq.test.h2.
|
||||
return (java.sql.Timestamp) getValue(10);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Primary key information
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public org.jooq.Record1<java.lang.Integer> key() {
|
||||
return (org.jooq.Record1) super.key();
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Record11 type implementation
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
Loading…
Reference in New Issue
Block a user