[jOOQ/jOOQ#2530] [jOOQ/jOOQ#6124] [jOOQ/jOOQ#10481] Improved embeddable support and added code generation support for embeddable keys
This commit is contained in:
parent
ee3bdcc6fd
commit
29bce7c908
@ -142,7 +142,6 @@ abstract class AbstractGenerator implements Generator {
|
||||
boolean generateTableValuedFunctions = false;
|
||||
boolean generateEmptyCatalogs = false;
|
||||
boolean generateEmptySchemas = false;
|
||||
boolean generatePrimaryKeyTypes = false;
|
||||
String generateNewline = "\n";
|
||||
String generateIndentation;
|
||||
|
||||
@ -1077,16 +1076,6 @@ abstract class AbstractGenerator implements Generator {
|
||||
this.generateEmptySchemas = generateEmptySchemas;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean generatePrimaryKeyTypes() {
|
||||
return generatePrimaryKeyTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGeneratePrimaryKeyTypes(boolean generatePrimaryKeyTypes) {
|
||||
this.generatePrimaryKeyTypes = generatePrimaryKeyTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateNewline() {
|
||||
return generateNewline;
|
||||
|
||||
@ -156,6 +156,10 @@ public class DefaultGeneratorStrategy extends AbstractGeneratorStrategy {
|
||||
else if (definition instanceof ForeignKeyDefinition && asList(POSTGRES).contains(definition.getDatabase().getDialect().family()))
|
||||
return ((ForeignKeyDefinition) definition).getTable().getOutputName().toUpperCase() + "__" + definition.getOutputName().toUpperCase();
|
||||
|
||||
// [#10481] Embeddables have a defining name (class name) and a referencing name (identifier name).
|
||||
else if (definition instanceof EmbeddableDefinition)
|
||||
return ((EmbeddableDefinition) definition).getReferencingOutputName().toUpperCase();
|
||||
|
||||
else
|
||||
return definition.getOutputName().toUpperCase();
|
||||
}
|
||||
|
||||
@ -546,6 +546,8 @@ public class GenerationTool {
|
||||
database.setConfiguredEnumTypes(d.getEnumTypes());
|
||||
database.setConfiguredForcedTypes(d.getForcedTypes());
|
||||
database.setConfiguredEmbeddables(d.getEmbeddables());
|
||||
database.setEmbeddablePrimaryKeys(TRUE.equals(g.getDatabase().isEmbeddablePrimaryKeys()));
|
||||
database.setEmbeddableUniqueKeys(TRUE.equals(g.getDatabase().isEmbeddableUniqueKeys()));
|
||||
database.setLogSlowQueriesAfterSeconds(defaultIfNull(g.getDatabase().getLogSlowQueriesAfterSeconds(), 5));
|
||||
database.setLogSlowResultsAfterSeconds(defaultIfNull(g.getDatabase().getLogSlowResultsAfterSeconds(), 5));
|
||||
|
||||
@ -806,8 +808,6 @@ public class GenerationTool {
|
||||
generator.setGenerateEmptyCatalogs(g.getGenerate().isEmptyCatalogs());
|
||||
if (g.getGenerate().isEmptySchemas() != null)
|
||||
generator.setGenerateEmptySchemas(g.getGenerate().isEmptySchemas());
|
||||
if (g.getGenerate().isPrimaryKeyTypes() != null)
|
||||
generator.setGeneratePrimaryKeyTypes(g.getGenerate().isPrimaryKeyTypes());
|
||||
if (g.getGenerate().getNewline() != null)
|
||||
generator.setGenerateNewline(g.getGenerate().getNewline());
|
||||
if (g.getGenerate().getIndentation() != null)
|
||||
|
||||
@ -959,16 +959,6 @@ public interface Generator {
|
||||
*/
|
||||
void setGenerateEmptySchemas(boolean generateEmptySchemas);
|
||||
|
||||
/**
|
||||
* Whether wrapper types for primary keys should be generated.
|
||||
*/
|
||||
boolean generatePrimaryKeyTypes();
|
||||
|
||||
/**
|
||||
* Whether wrapper types for primary keys should be generated.
|
||||
*/
|
||||
void setGeneratePrimaryKeyTypes(boolean generatePrimaryKeyTypes);
|
||||
|
||||
/**
|
||||
* The newline character(s) to be used in generated code.
|
||||
*/
|
||||
|
||||
@ -96,6 +96,7 @@ import org.jooq.Index;
|
||||
import org.jooq.Name;
|
||||
import org.jooq.OrderField;
|
||||
import org.jooq.Parameter;
|
||||
// ...
|
||||
import org.jooq.Record;
|
||||
import org.jooq.Result;
|
||||
import org.jooq.Row;
|
||||
@ -1036,7 +1037,44 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
out.println(";");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private void printCreateUniqueKey(JavaWriter out, UniqueKeyDefinition uniqueKey) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
printCreateNonEmbeddableUniqueKey(out, uniqueKey);
|
||||
}
|
||||
|
||||
private void printCreateNonEmbeddableUniqueKey(JavaWriter out, UniqueKeyDefinition uniqueKey) {
|
||||
if (scala)
|
||||
out.print("%s.createUniqueKey(%s, %s.name(\"%s\"), Array([[%s]]).asInstanceOf[Array[%s[%s, _] ] ], %s)",
|
||||
Internal.class,
|
||||
@ -1066,6 +1104,21 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
uniqueKey.enforced());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
protected void printForeignKey(JavaWriter out, int foreignKeyCounter, ForeignKeyDefinition foreignKey) {
|
||||
final int block = foreignKeyCounter / INITIALISER_SIZE;
|
||||
|
||||
@ -1083,11 +1136,47 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
}
|
||||
|
||||
if (scala)
|
||||
out.println("val %s: %s[%s, %s] = %s.createForeignKey(%s, %s.name(\"%s\"), Array([[%s]]).asInstanceOf[Array[%s[%s, _] ] ], %s, Array([[%s]]).asInstanceOf[Array[%s[%s, _] ] ], %s)",
|
||||
out.print("val %s: %s[%s, %s] = ",
|
||||
getStrategy().getJavaIdentifier(foreignKey),
|
||||
ForeignKey.class,
|
||||
out.ref(getStrategy().getFullJavaClassName(foreignKey.getKeyTable(), Mode.RECORD)),
|
||||
out.ref(getStrategy().getFullJavaClassName(foreignKey.getReferencedTable(), Mode.RECORD)));
|
||||
else if (kotlin)
|
||||
out.print("val %s: %s<%s, %s> = ",
|
||||
getStrategy().getJavaIdentifier(foreignKey),
|
||||
ForeignKey.class,
|
||||
out.ref(getStrategy().getFullJavaClassName(foreignKey.getKeyTable(), Mode.RECORD)),
|
||||
out.ref(getStrategy().getFullJavaClassName(foreignKey.getReferencedTable(), Mode.RECORD)));
|
||||
else
|
||||
out.print("static final %s<%s, %s> %s = ",
|
||||
ForeignKey.class,
|
||||
out.ref(getStrategy().getFullJavaClassName(foreignKey.getKeyTable(), Mode.RECORD)),
|
||||
out.ref(getStrategy().getFullJavaClassName(foreignKey.getReferencedTable(), Mode.RECORD)),
|
||||
getStrategy().getJavaIdentifier(foreignKey));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
printCreateNonEmbeddableForeignKey(out, foreignKey);
|
||||
|
||||
if (scala || kotlin)
|
||||
out.println();
|
||||
else
|
||||
out.println(";");
|
||||
}
|
||||
|
||||
private void printCreateNonEmbeddableForeignKey(JavaWriter out, ForeignKeyDefinition foreignKey) {
|
||||
if (scala)
|
||||
out.print("%s.createForeignKey(%s, %s.name(\"%s\"), Array([[%s]]).asInstanceOf[Array[%s[%s, _] ] ], %s, Array([[%s]]).asInstanceOf[Array[%s[%s, _] ] ], %s)",
|
||||
Internal.class,
|
||||
out.ref(getStrategy().getFullJavaIdentifier(foreignKey.getKeyTable()), 2),
|
||||
DSL.class,
|
||||
@ -1102,11 +1191,7 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
foreignKey.enforced()
|
||||
);
|
||||
else if (kotlin)
|
||||
out.println("val %s: %s<%s, %s> = %s.createForeignKey(%s, %s.name(\"%s\"), arrayOf([[%s]]), %s, arrayOf([[%s]]), %s)",
|
||||
getStrategy().getJavaIdentifier(foreignKey),
|
||||
ForeignKey.class,
|
||||
out.ref(getStrategy().getFullJavaClassName(foreignKey.getKeyTable(), Mode.RECORD)),
|
||||
out.ref(getStrategy().getFullJavaClassName(foreignKey.getReferencedTable(), Mode.RECORD)),
|
||||
out.print("%s.createForeignKey(%s, %s.name(\"%s\"), arrayOf([[%s]]), %s, arrayOf([[%s]]), %s)",
|
||||
Internal.class,
|
||||
out.ref(getStrategy().getFullJavaIdentifier(foreignKey.getKeyTable()), 2),
|
||||
DSL.class,
|
||||
@ -1117,11 +1202,7 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
foreignKey.enforced()
|
||||
);
|
||||
else
|
||||
out.println("static final %s<%s, %s> %s = %s.createForeignKey(%s, %s.name(\"%s\"), new %s[] { [[%s]] }, %s, new %s[] { [[%s]] }, %s);",
|
||||
ForeignKey.class,
|
||||
out.ref(getStrategy().getFullJavaClassName(foreignKey.getKeyTable(), Mode.RECORD)),
|
||||
out.ref(getStrategy().getFullJavaClassName(foreignKey.getReferencedTable(), Mode.RECORD)),
|
||||
getStrategy().getJavaIdentifier(foreignKey),
|
||||
out.print("%s.createForeignKey(%s, %s.name(\"%s\"), new %s[] { [[%s]] }, %s, new %s[] { [[%s]] }, %s)",
|
||||
Internal.class,
|
||||
out.ref(getStrategy().getFullJavaIdentifier(foreignKey.getKeyTable()), 2),
|
||||
DSL.class,
|
||||
@ -1135,6 +1216,31 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
protected void generateRecords(SchemaDefinition schema) {
|
||||
log.info("Generating table records");
|
||||
|
||||
@ -1226,35 +1332,44 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
if (generateInterfaces())
|
||||
interfaces.add(out.ref(getStrategy().getFullJavaClassName(tableUdtOrEmbeddable, Mode.INTERFACE)));
|
||||
|
||||
if (scala) {
|
||||
if (tableUdtOrEmbeddable instanceof EmbeddableDefinition) {
|
||||
out.println("private object %s {", className);
|
||||
out.println("val FIELDS: Array[%s [_] ] = Array(", Field.class);
|
||||
|
||||
String separator = " ";
|
||||
for (EmbeddableColumnDefinition column : ((EmbeddableDefinition) tableUdtOrEmbeddable).getColumns()) {
|
||||
final String colIdentifier = out.ref(getStrategy().getFullJavaIdentifier(column.getColumn()), colRefSegments(column));
|
||||
|
||||
out.println("%s%s.field(%s.name(\"%s\"), %s.getDataType)", separator, DSL.class, DSL.class, column.getOutputName(), colIdentifier);
|
||||
separator = ", ";
|
||||
}
|
||||
|
||||
out.println(")");
|
||||
out.println("}");
|
||||
out.println();
|
||||
}
|
||||
}
|
||||
|
||||
if (scala)
|
||||
if (tableUdtOrEmbeddable instanceof EmbeddableDefinition)
|
||||
out.println("class %s extends %s[%s](%s.FIELDS:_*)[[before= with ][separator= with ][%s]] {", className, baseClass, className, className, interfaces);
|
||||
out.println("class %s extends %s[%s](%s.fields(%s.%s):_*)[[before= with ][separator= with ][%s]] {",
|
||||
className,
|
||||
baseClass,
|
||||
className,
|
||||
Internal.class,
|
||||
out.ref(getStrategy().getFullJavaIdentifier(((EmbeddableDefinition) tableUdtOrEmbeddable).getTable()), 2),
|
||||
getStrategy().getJavaIdentifier(tableUdtOrEmbeddable),
|
||||
interfaces
|
||||
);
|
||||
else
|
||||
out.println("class %s extends %s[%s](%s)[[before= with ][separator= with ][%s]] {", className, baseClass, className, tableIdentifier, interfaces);
|
||||
out.println("class %s extends %s[%s](%s)[[before= with ][separator= with ][%s]] {",
|
||||
className,
|
||||
baseClass,
|
||||
className,
|
||||
tableIdentifier,
|
||||
interfaces
|
||||
);
|
||||
else if (kotlin)
|
||||
if (tableUdtOrEmbeddable instanceof EmbeddableDefinition)
|
||||
out.println("class %s() : %s<%s>(*FIELDS)[[before=, ][%s]] {", className, baseClass, className, interfaces);
|
||||
out.println("class %s() : %s<%s>(*%s.fields(%s.%s))[[before=, ][%s]] {",
|
||||
className,
|
||||
baseClass,
|
||||
className,
|
||||
Internal.class,
|
||||
out.ref(getStrategy().getFullJavaIdentifier(((EmbeddableDefinition) tableUdtOrEmbeddable).getTable()), 2),
|
||||
getStrategy().getJavaIdentifier(tableUdtOrEmbeddable),
|
||||
interfaces
|
||||
);
|
||||
else
|
||||
out.println("class %s() : %s<%s>(%s)[[before=, ][%s]] {", className, baseClass, className, tableIdentifier, interfaces);
|
||||
out.println("class %s() : %s<%s>(%s)[[before=, ][%s]] {",
|
||||
className,
|
||||
baseClass,
|
||||
className,
|
||||
tableIdentifier,
|
||||
interfaces
|
||||
);
|
||||
else
|
||||
out.println("public class %s extends %s<%s>[[before= implements ][%s]] {", className, baseClass, className, interfaces);
|
||||
|
||||
@ -1293,7 +1408,7 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
}
|
||||
|
||||
if (tableUdtOrEmbeddable instanceof TableDefinition) {
|
||||
List<EmbeddableDefinition> embeddables = ((TableDefinition) tableUdtOrEmbeddable).getEmbeddables();
|
||||
List<EmbeddableDefinition> embeddables = ((TableDefinition) tableUdtOrEmbeddable).getReferencedEmbeddables();
|
||||
|
||||
for (int i = 0; i < embeddables.size(); i++) {
|
||||
EmbeddableDefinition embeddable = embeddables.get(i);
|
||||
@ -1407,7 +1522,16 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
printDeprecationIfUnknownType(out, colTypeFull);
|
||||
|
||||
if (tableUdtOrEmbeddable instanceof EmbeddableDefinition)
|
||||
out.println("override def field%s: %s[%s] = %s.FIELDS(%s).asInstanceOf[%s [%s] ]", i, Field.class, colType, i - 1, className, Field.class, colType);
|
||||
out.println("override def field%s: %s[%s] = %s.fields(%s.%s):_*.asInstanceOf[%s [%s] ]",
|
||||
i,
|
||||
Field.class,
|
||||
colType,
|
||||
Internal.class,
|
||||
out.ref(getStrategy().getFullJavaIdentifier(((EmbeddableDefinition) tableUdtOrEmbeddable).getTable()), 2),
|
||||
getStrategy().getJavaIdentifier(tableUdtOrEmbeddable),
|
||||
Field.class,
|
||||
colType
|
||||
);
|
||||
else
|
||||
out.println("override def field%s: %s[%s] = %s", i, Field.class, colType, colIdentifier);
|
||||
}
|
||||
@ -1415,7 +1539,16 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
printDeprecationIfUnknownType(out, colTypeFull);
|
||||
|
||||
if (tableUdtOrEmbeddable instanceof EmbeddableDefinition)
|
||||
out.println("override fun field%s(): %s<%s?> = FIELDS[%s] as %s<%s>", i, Field.class, colType, i - 1, Field.class, colType);
|
||||
out.println("override fun field%s(): %s<%s?> = %s.fields(%s.%s) as %s<%s>",
|
||||
i,
|
||||
Field.class,
|
||||
colType,
|
||||
Internal.class,
|
||||
out.ref(getStrategy().getFullJavaIdentifier(((EmbeddableDefinition) tableUdtOrEmbeddable).getTable()), 2),
|
||||
getStrategy().getJavaIdentifier(tableUdtOrEmbeddable),
|
||||
Field.class,
|
||||
colType
|
||||
);
|
||||
else
|
||||
out.println("override fun field%s(): %s<%s?> = %s", i, Field.class, colType, colIdentifier);
|
||||
}
|
||||
@ -1597,47 +1730,19 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
printFromAndInto(out, tableUdtOrEmbeddable, Mode.RECORD);
|
||||
|
||||
|
||||
// [#2530] TODO Implement this for Scala & Kotlin
|
||||
if (scala) {}
|
||||
else if (kotlin) {
|
||||
if (tableUdtOrEmbeddable instanceof EmbeddableDefinition) {
|
||||
out.println();
|
||||
out.println("private companion object {");
|
||||
out.println("val FIELDS: Array<%s<*>> = arrayOf(", Field.class);
|
||||
|
||||
String separator = " ";
|
||||
for (EmbeddableColumnDefinition column : ((EmbeddableDefinition) tableUdtOrEmbeddable).getColumns()) {
|
||||
final String colIdentifier = out.ref(getStrategy().getFullJavaIdentifier(column.getColumn()), colRefSegments(column));
|
||||
|
||||
out.println("%s%s.field(%s.name(\"%s\"), %s.dataType)", separator, DSL.class, DSL.class, column.getOutputName(), colIdentifier);
|
||||
separator = ", ";
|
||||
}
|
||||
|
||||
out.println(")");
|
||||
out.println("}");
|
||||
}
|
||||
}
|
||||
else if (kotlin) {}
|
||||
else {
|
||||
out.header("Constructors");
|
||||
|
||||
if (tableUdtOrEmbeddable instanceof EmbeddableDefinition) {
|
||||
out.println();
|
||||
out.println("private static final %s<?>[] FIELDS = {", Field.class);
|
||||
|
||||
for (EmbeddableColumnDefinition column : ((EmbeddableDefinition) tableUdtOrEmbeddable).getColumns()) {
|
||||
final String colIdentifier = out.ref(getStrategy().getFullJavaIdentifier(column.getColumn()), colRefSegments(column));
|
||||
|
||||
out.println("%s.field(%s.name(\"%s\"), %s.getDataType()),", DSL.class, DSL.class, column.getOutputName(), colIdentifier);
|
||||
}
|
||||
|
||||
out.println("};");
|
||||
out.println();
|
||||
}
|
||||
|
||||
out.javadoc("Create a detached %s", className);
|
||||
|
||||
out.println("public %s() {", className);
|
||||
if (tableUdtOrEmbeddable instanceof EmbeddableDefinition)
|
||||
out.println("super(FIELDS);");
|
||||
out.println("super(%s.fields(%s.%s));",
|
||||
Internal.class,
|
||||
out.ref(getStrategy().getFullJavaIdentifier(((EmbeddableDefinition) tableUdtOrEmbeddable).getTable()), 2),
|
||||
getStrategy().getJavaIdentifier(tableUdtOrEmbeddable));
|
||||
else
|
||||
out.println("super(%s);", tableIdentifier);
|
||||
out.println("}");
|
||||
@ -4299,29 +4404,37 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
final String columnName = column.getName();
|
||||
final List<String> converter = out.ref(list(column.getType(resolver()).getConverter()));
|
||||
final List<String> binding = out.ref(list(column.getType(resolver()).getBinding()));
|
||||
final String columnVisibility =
|
||||
|
||||
|
||||
|
||||
|
||||
scala || kotlin ?
|
||||
"" :
|
||||
"public ";
|
||||
|
||||
if (!printDeprecationIfUnknownType(out, columnTypeFull))
|
||||
out.javadoc("The column <code>%s</code>.[[before= ][%s]]", column.getQualifiedOutputName(), list(escapeEntities(comment(column))));
|
||||
|
||||
if (scala) {
|
||||
out.println("val %s: %s[%s, %s] = createField(%s.name(\"%s\"), %s, \"%s\"" + converterTemplate(converter) + converterTemplate(binding) + ")",
|
||||
columnId, TableField.class, recordType, columnType, DSL.class, columnName, columnTypeRef, escapeString(comment(column)), converter, binding);
|
||||
out.println("%sval %s: %s[%s, %s] = createField(%s.name(\"%s\"), %s, \"%s\"" + converterTemplate(converter) + converterTemplate(binding) + ")",
|
||||
columnVisibility, columnId, TableField.class, recordType, columnType, DSL.class, columnName, columnTypeRef, escapeString(comment(column)), converter, binding);
|
||||
}
|
||||
else if (kotlin) {
|
||||
out.println("val %s: %s<%s, %s?> = createField(%s.name(\"%s\"), %s, this, \"%s\"" + converterTemplate(converter) + converterTemplate(binding) + ")",
|
||||
columnId, TableField.class, recordType, columnType, DSL.class, columnName, columnTypeRef, escapeString(comment(column)), converter, binding);
|
||||
out.println("%sval %s: %s<%s, %s?> = createField(%s.name(\"%s\"), %s, this, \"%s\"" + converterTemplate(converter) + converterTemplate(binding) + ")",
|
||||
columnVisibility, columnId, TableField.class, recordType, columnType, DSL.class, columnName, columnTypeRef, escapeString(comment(column)), converter, binding);
|
||||
}
|
||||
else {
|
||||
String isStatic = generateInstanceFields() ? "" : "static ";
|
||||
String tableRef = generateInstanceFields() ? "this" : out.ref(getStrategy().getJavaIdentifier(table), 2);
|
||||
|
||||
out.println("public %sfinal %s<%s, %s> %s = createField(%s.name(\"%s\"), %s, %s, \"%s\"" + converterTemplate(converter) + converterTemplate(binding) + ");",
|
||||
isStatic, TableField.class, recordType, columnType, columnId, DSL.class, columnName, columnTypeRef, tableRef, escapeString(comment(column)), converter, binding);
|
||||
out.println("%s%sfinal %s<%s, %s> %s = createField(%s.name(\"%s\"), %s, %s, \"%s\"" + converterTemplate(converter) + converterTemplate(binding) + ");",
|
||||
columnVisibility, isStatic, TableField.class, recordType, columnType, columnId, DSL.class, columnName, columnTypeRef, tableRef, escapeString(comment(column)), converter, binding);
|
||||
}
|
||||
}
|
||||
|
||||
// [#2530] Embeddable types
|
||||
for (EmbeddableDefinition embeddable : table.getEmbeddables()) {
|
||||
for (EmbeddableDefinition embeddable : table.getReferencedEmbeddables()) {
|
||||
final String columnId = out.ref(getStrategy().getJavaIdentifier(embeddable), colRefSegments(null));
|
||||
final String columnType = out.ref(getStrategy().getFullJavaClassName(embeddable, Mode.RECORD));
|
||||
|
||||
@ -4332,14 +4445,14 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
out.javadoc("The embeddable type <code>%s</code>.", embeddable.getOutputName());
|
||||
|
||||
if (scala)
|
||||
out.println("val %s: %s[%s, %s] = %s.createEmbeddable(%s.name(\"%s\"), classOf[%s], this, [[%s]])",
|
||||
columnId, TableField.class, recordType, columnType, Internal.class, DSL.class, embeddable.getName(), columnType, columnIds);
|
||||
out.println("val %s: %s[%s, %s] = %s.createEmbeddable(%s.name(\"%s\"), classOf[%s], %s, this, [[%s]])",
|
||||
columnId, TableField.class, recordType, columnType, Internal.class, DSL.class, escapeString(embeddable.getName()), columnType, embeddable.replacesFields(), columnIds);
|
||||
else if (kotlin)
|
||||
out.println("val %s: %s<%s, %s> = %s.createEmbeddable(%s.name(\"%s\"), %s::class.java, this, [[%s]])",
|
||||
columnId, TableField.class, recordType, columnType, Internal.class, DSL.class, embeddable.getName(), columnType, columnIds);
|
||||
out.println("val %s: %s<%s, %s> = %s.createEmbeddable(%s.name(\"%s\"), %s::class.java, %s, this, [[%s]])",
|
||||
columnId, TableField.class, recordType, columnType, Internal.class, DSL.class, escapeString(embeddable.getName()), columnType, embeddable.replacesFields(), columnIds);
|
||||
else
|
||||
out.println("public final %s<%s, %s> %s = %s.createEmbeddable(%s.name(\"%s\"), %s.class, this, [[%s]]);",
|
||||
TableField.class, recordType, columnType, columnId, Internal.class, DSL.class, embeddable.getName(), columnType, columnIds);
|
||||
out.println("public final %s<%s, %s> %s = %s.createEmbeddable(%s.name(\"%s\"), %s.class, %s, this, [[%s]]);",
|
||||
TableField.class, recordType, columnType, columnId, Internal.class, DSL.class, escapeString(embeddable.getName()), columnType, embeddable.replacesFields(), columnIds);
|
||||
}
|
||||
|
||||
out.println();
|
||||
@ -5073,7 +5186,10 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
|
||||
for (EmbeddableDefinition embeddable : database.getEmbeddables(schema)) {
|
||||
try {
|
||||
generateEmbeddable(schema, embeddable);
|
||||
|
||||
// [#6124] [#10481] Don't generate embeddable types for FKs
|
||||
if (embeddable.getTable().equals(embeddable.getReferencingTable()))
|
||||
generateEmbeddable(schema, embeddable);
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("Error while generating embeddable " + embeddable, e);
|
||||
|
||||
@ -38,12 +38,14 @@
|
||||
|
||||
package org.jooq.meta;
|
||||
|
||||
import static java.lang.Boolean.TRUE;
|
||||
import static org.jooq.Log.Level.ERROR;
|
||||
import static org.jooq.SQLDialect.CUBRID;
|
||||
import static org.jooq.SQLDialect.FIREBIRD;
|
||||
import static org.jooq.SQLDialect.SQLITE;
|
||||
import static org.jooq.impl.DSL.falseCondition;
|
||||
import static org.jooq.meta.AbstractTypedElementDefinition.customType;
|
||||
import static org.jooq.tools.StringUtils.defaultIfBlank;
|
||||
import static org.jooq.tools.StringUtils.defaultIfEmpty;
|
||||
|
||||
import java.io.File;
|
||||
@ -155,6 +157,8 @@ public abstract class AbstractDatabase implements Database {
|
||||
private String[] syntheticPrimaryKeys;
|
||||
private String[] overridePrimaryKeys;
|
||||
private String[] syntheticIdentities;
|
||||
private boolean embeddablePrimaryKeys = false;
|
||||
private boolean embeddableUniqueKeys = false;
|
||||
private boolean supportsUnsignedTypes;
|
||||
private boolean integerDisplayWidths;
|
||||
private boolean ignoreProcedureReturnValues;
|
||||
@ -208,8 +212,9 @@ public abstract class AbstractDatabase implements Database {
|
||||
private transient Map<SchemaDefinition, List<ForeignKeyDefinition>> foreignKeysBySchema;
|
||||
private transient Map<SchemaDefinition, List<CheckConstraintDefinition>> checkConstraintsBySchema;
|
||||
private transient Map<SchemaDefinition, List<TableDefinition>> tablesBySchema;
|
||||
private transient Map<SchemaDefinition, List<EmbeddableDefinition>> embeddablesBySchema;
|
||||
private transient Map<TableDefinition, List<EmbeddableDefinition>> embeddablesByTable;
|
||||
private transient Map<SchemaDefinition, List<EmbeddableDefinition>> embeddablesByDefiningSchema;
|
||||
private transient Map<TableDefinition, List<EmbeddableDefinition>> embeddablesByDefiningTable;
|
||||
private transient Map<TableDefinition, List<EmbeddableDefinition>> embeddablesByReferencingTable;
|
||||
private transient Map<SchemaDefinition, List<EnumDefinition>> enumsBySchema;
|
||||
private transient Map<SchemaDefinition, List<DomainDefinition>> domainsBySchema;
|
||||
private transient Map<SchemaDefinition, List<UDTDefinition>> udtsBySchema;
|
||||
@ -1533,10 +1538,8 @@ public abstract class AbstractDatabase implements Database {
|
||||
return filterSchema(identities, schema, identitiesBySchema);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public final List<UniqueKeyDefinition> getUniqueKeys(SchemaDefinition schema) {
|
||||
public final List<UniqueKeyDefinition> getUniqueKeys() {
|
||||
if (uniqueKeys == null) {
|
||||
uniqueKeys = new ArrayList<>();
|
||||
|
||||
@ -1549,14 +1552,19 @@ public abstract class AbstractDatabase implements Database {
|
||||
sort(uniqueKeys);
|
||||
}
|
||||
|
||||
if (uniqueKeysBySchema == null)
|
||||
uniqueKeysBySchema = new LinkedHashMap<>();
|
||||
|
||||
return filterSchema(uniqueKeys, schema, uniqueKeysBySchema);
|
||||
return uniqueKeys;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<ForeignKeyDefinition> getForeignKeys(SchemaDefinition schema) {
|
||||
public final List<UniqueKeyDefinition> getUniqueKeys(SchemaDefinition schema) {
|
||||
if (uniqueKeysBySchema == null)
|
||||
uniqueKeysBySchema = new LinkedHashMap<>();
|
||||
|
||||
return filterSchema(getUniqueKeys(), schema, uniqueKeysBySchema);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<ForeignKeyDefinition> getForeignKeys() {
|
||||
if (foreignKeys == null) {
|
||||
foreignKeys = new ArrayList<>();
|
||||
|
||||
@ -1569,10 +1577,15 @@ public abstract class AbstractDatabase implements Database {
|
||||
sort(foreignKeys);
|
||||
}
|
||||
|
||||
return foreignKeys;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<ForeignKeyDefinition> getForeignKeys(SchemaDefinition schema) {
|
||||
if (foreignKeysBySchema == null)
|
||||
foreignKeysBySchema = new LinkedHashMap<>();
|
||||
|
||||
return filterSchema(foreignKeys, schema, foreignKeysBySchema);
|
||||
return filterSchema(getForeignKeys(), schema, foreignKeysBySchema);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1596,7 +1609,7 @@ public abstract class AbstractDatabase implements Database {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<TableDefinition> getTables(SchemaDefinition schema) {
|
||||
public final List<TableDefinition> getTables() {
|
||||
if (tables == null) {
|
||||
tables = new ArrayList<>();
|
||||
|
||||
@ -1615,10 +1628,15 @@ public abstract class AbstractDatabase implements Database {
|
||||
log.info("Tables excluded");
|
||||
}
|
||||
|
||||
return tables;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<TableDefinition> getTables(SchemaDefinition schema) {
|
||||
if (tablesBySchema == null)
|
||||
tablesBySchema = new LinkedHashMap<>();
|
||||
|
||||
return filterSchema(tables, schema, tablesBySchema);
|
||||
return filterSchema(getTables(), schema, tablesBySchema);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1776,37 +1794,41 @@ public abstract class AbstractDatabase implements Database {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<EmbeddableDefinition> getEmbeddables() {
|
||||
List<EmbeddableDefinition> result = new ArrayList<>();
|
||||
public boolean embeddablePrimaryKeys() {
|
||||
return embeddablePrimaryKeys;
|
||||
}
|
||||
|
||||
for (SchemaDefinition schema : getSchemata()) {
|
||||
for (TableDefinition table : getTables(schema)) {
|
||||
for (Embeddable embeddable : getConfiguredEmbeddables()) {
|
||||
List<ColumnDefinition> columns = new ArrayList<>();
|
||||
List<String> names = new ArrayList<>();
|
||||
@SuppressWarnings("unused")
|
||||
@Override
|
||||
public void setEmbeddablePrimaryKeys(boolean embeddablePrimaryKeys) {
|
||||
|
||||
for (EmbeddableField embeddableField : embeddable.getFields()) {
|
||||
boolean matched = false;
|
||||
|
||||
for (ColumnDefinition column : table.getColumns())
|
||||
if (matches(patterns.pattern(embeddableField.getExpression()), column))
|
||||
if (matched)
|
||||
log.warn("EmbeddableField configuration matched several columns in table " + table + ": " + embeddableField);
|
||||
else
|
||||
matched = columns.add(column) && names.add(defaultIfEmpty(embeddableField.getName(), column.getName()));
|
||||
}
|
||||
|
||||
if (columns.size() == embeddable.getFields().size())
|
||||
result.add(new DefaultEmbeddableDefinition(embeddable.getName(), names, table, columns));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (embeddablePrimaryKeys)
|
||||
log.info("Commercial feature", "Embeddable primary and unique keys are a commercial only feature. Please consider upgrading to the jOOQ Professional Edition");
|
||||
|
||||
return result;
|
||||
this.embeddablePrimaryKeys = embeddablePrimaryKeys;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<EmbeddableDefinition> getEmbeddables(SchemaDefinition schema) {
|
||||
public boolean embeddableUniqueKeys() {
|
||||
return embeddableUniqueKeys;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Override
|
||||
public void setEmbeddableUniqueKeys(boolean embeddableUniqueKeys) {
|
||||
|
||||
|
||||
|
||||
if (embeddableUniqueKeys)
|
||||
log.info("Commercial feature", "Embeddable primary and unique keys are a commercial only feature. Please consider upgrading to the jOOQ Professional Edition");
|
||||
|
||||
this.embeddableUniqueKeys = embeddableUniqueKeys;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<EmbeddableDefinition> getEmbeddables() {
|
||||
if (embeddables == null) {
|
||||
embeddables = new ArrayList<>();
|
||||
|
||||
@ -1814,7 +1836,7 @@ public abstract class AbstractDatabase implements Database {
|
||||
onError(ERROR, "Error while fetching embeddables", new ExceptionRunnable() {
|
||||
@Override
|
||||
public void run() throws Exception {
|
||||
List<EmbeddableDefinition> r = getEmbeddables();
|
||||
List<EmbeddableDefinition> r = getEmbeddables0();
|
||||
|
||||
embeddables = sort(r);
|
||||
// indexes = sort(filterExcludeInclude(r)); TODO Support include / exclude for indexes (and constraints!)
|
||||
@ -1826,18 +1848,145 @@ public abstract class AbstractDatabase implements Database {
|
||||
log.info("Embeddables excluded");
|
||||
}
|
||||
|
||||
if (embeddablesBySchema == null)
|
||||
embeddablesBySchema = new LinkedHashMap<>();
|
||||
return embeddables;
|
||||
}
|
||||
|
||||
return filterSchema(embeddables, schema, embeddablesBySchema);
|
||||
@Override
|
||||
public final List<EmbeddableDefinition> getEmbeddables(SchemaDefinition schema) {
|
||||
if (embeddablesByDefiningSchema == null)
|
||||
embeddablesByDefiningSchema = new LinkedHashMap<>();
|
||||
|
||||
return filterSchema(getEmbeddables(), schema, embeddablesByDefiningSchema);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<EmbeddableDefinition> getEmbeddables(TableDefinition table) {
|
||||
if (embeddablesByTable == null)
|
||||
embeddablesByTable = new LinkedHashMap<>();
|
||||
if (embeddablesByDefiningTable == null)
|
||||
embeddablesByDefiningTable = new LinkedHashMap<>();
|
||||
|
||||
return filterTable(getEmbeddables(table.getSchema()), table, embeddablesByTable);
|
||||
return filterTable(getEmbeddables(table.getSchema()), table, embeddablesByDefiningTable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<EmbeddableDefinition> getEmbeddablesByReferencingTable(TableDefinition table) {
|
||||
if (embeddablesByReferencingTable == null)
|
||||
embeddablesByReferencingTable = new LinkedHashMap<>();
|
||||
|
||||
return filterReferencingTable(getEmbeddables(), table, embeddablesByReferencingTable);
|
||||
}
|
||||
|
||||
private final List<EmbeddableDefinition> getEmbeddables0() {
|
||||
Map<Name, EmbeddableDefinition> result = new LinkedHashMap<>();
|
||||
|
||||
for (TableDefinition table : getTables()) {
|
||||
for (Embeddable embeddable : getConfiguredEmbeddables()) {
|
||||
List<ColumnDefinition> columns = new ArrayList<>();
|
||||
List<String> names = new ArrayList<>();
|
||||
|
||||
for (EmbeddableField embeddableField : embeddable.getFields()) {
|
||||
boolean matched = false;
|
||||
|
||||
for (ColumnDefinition column : table.getColumns())
|
||||
if (matches(patterns.pattern(embeddableField.getExpression()), column))
|
||||
if (matched)
|
||||
log.warn("EmbeddableField configuration matched several columns in table " + table + ": " + embeddableField);
|
||||
else
|
||||
matched = columns.add(column) && names.add(defaultIfEmpty(embeddableField.getName(), column.getName()));
|
||||
}
|
||||
|
||||
|
||||
if (columns.size() == embeddable.getFields().size()) {
|
||||
Name name = table.getQualifiedNamePart().append(embeddable.getName());
|
||||
|
||||
if (result.containsKey(name))
|
||||
log.warn("Embeddable configuration", "Table " + table + " already has embeddable " + embeddable);
|
||||
else
|
||||
result.put(
|
||||
name,
|
||||
new DefaultEmbeddableDefinition(
|
||||
embeddable.getName(),
|
||||
table,
|
||||
names,
|
||||
defaultIfBlank(embeddable.getReferencingName(), embeddable.getName()),
|
||||
table,
|
||||
columns,
|
||||
TRUE.equals(embeddable.isReplacesFields())
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return new ArrayList<>(result.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -2219,6 +2368,30 @@ public abstract class AbstractDatabase implements Database {
|
||||
return result;
|
||||
}
|
||||
|
||||
private final <T extends EmbeddableDefinition> List<T> filterReferencingTable(List<T> definitions, TableDefinition table, Map<TableDefinition, List<T>> cache) {
|
||||
List<T> result = cache.get(table);
|
||||
|
||||
if (result == null) {
|
||||
result = filterReferencingTable(definitions, table);
|
||||
cache.put(table, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private final <T extends EmbeddableDefinition> List<T> filterReferencingTable(List<T> definitions, TableDefinition table) {
|
||||
if (table == null)
|
||||
return definitions;
|
||||
|
||||
List<T> result = new ArrayList<>();
|
||||
|
||||
for (T definition : definitions)
|
||||
if (definition.getReferencingTable().equals(table))
|
||||
result.add(definition);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <T extends Definition> List<T> filterExcludeInclude(List<T> definitions) {
|
||||
List<T> result = filterExcludeInclude(definitions, excludes, includes, filters);
|
||||
@ -2319,7 +2492,7 @@ public abstract class AbstractDatabase implements Database {
|
||||
onError(ERROR, "Error while fetching unique keys", new ExceptionRunnable() {
|
||||
@Override
|
||||
public void run() throws Exception {
|
||||
loadUniqueKeys(result);
|
||||
loadUniqueKeys(result);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -2328,7 +2501,7 @@ public abstract class AbstractDatabase implements Database {
|
||||
onError(ERROR, "Error while fetching foreign keys", new ExceptionRunnable() {
|
||||
@Override
|
||||
public void run() throws Exception {
|
||||
loadForeignKeys(result);
|
||||
loadForeignKeys(result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -80,6 +80,11 @@ implements TableDefinition {
|
||||
return getDatabase().getEmbeddables(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<EmbeddableDefinition> getReferencedEmbeddables() {
|
||||
return getDatabase().getEmbeddablesByReferencingTable(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final UniqueKeyDefinition getPrimaryKey() {
|
||||
for (ColumnDefinition column : getColumns())
|
||||
|
||||
@ -40,6 +40,8 @@ package org.jooq.meta;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
// ...
|
||||
|
||||
/**
|
||||
* An interface defining a column of a table.
|
||||
*
|
||||
@ -76,4 +78,22 @@ public interface ColumnDefinition extends TypedElementDefinition<TableDefinition
|
||||
*/
|
||||
@Deprecated
|
||||
boolean isNullable();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -114,11 +114,21 @@ public interface Database extends AutoCloseable {
|
||||
*/
|
||||
List<IndexDefinition> getIndexes(TableDefinition schema);
|
||||
|
||||
/**
|
||||
* The unique keys contained in this database.
|
||||
*/
|
||||
List<UniqueKeyDefinition> getUniqueKeys();
|
||||
|
||||
/**
|
||||
* The unique keys contained in this database.
|
||||
*/
|
||||
List<UniqueKeyDefinition> getUniqueKeys(SchemaDefinition schema);
|
||||
|
||||
/**
|
||||
* The foreign keys contained in this database.
|
||||
*/
|
||||
List<ForeignKeyDefinition> getForeignKeys();
|
||||
|
||||
/**
|
||||
* The foreign keys contained in this database.
|
||||
*/
|
||||
@ -129,6 +139,11 @@ public interface Database extends AutoCloseable {
|
||||
*/
|
||||
List<CheckConstraintDefinition> getCheckConstraints(SchemaDefinition schema);
|
||||
|
||||
/**
|
||||
* The tables contained in this database.
|
||||
*/
|
||||
List<TableDefinition> getTables();
|
||||
|
||||
/**
|
||||
* The tables contained in this database.
|
||||
*/
|
||||
@ -160,15 +175,20 @@ public interface Database extends AutoCloseable {
|
||||
List<EmbeddableDefinition> getEmbeddables();
|
||||
|
||||
/**
|
||||
* Get all embeddables for a given schema.
|
||||
* Get all embeddables for a given defining schema.
|
||||
*/
|
||||
List<EmbeddableDefinition> getEmbeddables(SchemaDefinition schema);
|
||||
|
||||
/**
|
||||
* Get all embeddables for a given table.
|
||||
* Get all embeddables for a given defining table.
|
||||
*/
|
||||
List<EmbeddableDefinition> getEmbeddables(TableDefinition table);
|
||||
|
||||
/**
|
||||
* Get all embeddables for a given referencing table.
|
||||
*/
|
||||
List<EmbeddableDefinition> getEmbeddablesByReferencingTable(TableDefinition table);
|
||||
|
||||
/**
|
||||
* The enum UDTs defined in this database.
|
||||
*/
|
||||
@ -868,6 +888,26 @@ public interface Database extends AutoCloseable {
|
||||
*/
|
||||
List<Embeddable> getConfiguredEmbeddables();
|
||||
|
||||
/**
|
||||
* Whether embeddable types for primary keys should be generated.
|
||||
*/
|
||||
boolean embeddablePrimaryKeys();
|
||||
|
||||
/**
|
||||
* Whether embeddable types for primary keys should be generated.
|
||||
*/
|
||||
void setEmbeddablePrimaryKeys(boolean embeddablePrimaryKeys);
|
||||
|
||||
/**
|
||||
* Whether embeddable types for unique keys should be generated.
|
||||
*/
|
||||
boolean embeddableUniqueKeys();
|
||||
|
||||
/**
|
||||
* Whether embeddable types for unique keys should be generated.
|
||||
*/
|
||||
void setEmbeddableUniqueKeys(boolean embeddableUniqueKeys);
|
||||
|
||||
/**
|
||||
* Get the dialect for this database.
|
||||
*/
|
||||
|
||||
@ -40,6 +40,8 @@ package org.jooq.meta;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.jooq.tools.JooqLogger;
|
||||
@ -53,9 +55,11 @@ public class DefaultColumnDefinition
|
||||
extends AbstractTypedElementDefinition<TableDefinition>
|
||||
implements ColumnDefinition {
|
||||
|
||||
private static final JooqLogger log = JooqLogger.getLogger(DefaultColumnDefinition.class);
|
||||
private final int position;
|
||||
private final boolean isIdentity;
|
||||
private static final JooqLogger log = JooqLogger.getLogger(DefaultColumnDefinition.class);
|
||||
private final int position;
|
||||
private final boolean isIdentity;
|
||||
private transient List<EmbeddableDefinition> containedInEmbeddables;
|
||||
private transient EmbeddableDefinition replacedByEmbeddable;
|
||||
|
||||
public DefaultColumnDefinition(TableDefinition table, String name, int position, DataTypeDefinition type,
|
||||
boolean isIdentity, String comment) {
|
||||
@ -110,4 +114,35 @@ public class DefaultColumnDefinition
|
||||
public final boolean isNullable() {
|
||||
return getType().isNullable();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -41,6 +41,8 @@ import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jooq.tools.JooqLogger;
|
||||
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
@ -48,28 +50,74 @@ public class DefaultEmbeddableDefinition
|
||||
extends AbstractElementContainerDefinition<EmbeddableColumnDefinition>
|
||||
implements EmbeddableDefinition {
|
||||
|
||||
private final List<String> columnNames;
|
||||
private final TableDefinition table;
|
||||
private static final JooqLogger log = JooqLogger.getLogger(DefaultEmbeddableDefinition.class);
|
||||
private final TableDefinition definingTable;
|
||||
private final List<String> definingColumnNames;
|
||||
private final String referencingName;
|
||||
private final TableDefinition referencingTable;
|
||||
private final List<EmbeddableColumnDefinition> embeddableColumns;
|
||||
private final boolean replacesFields;
|
||||
|
||||
public DefaultEmbeddableDefinition(String name, List<String> columnNames, TableDefinition table, List<ColumnDefinition> columns) {
|
||||
super(table.getSchema(), name, "");
|
||||
@SuppressWarnings("unused")
|
||||
public DefaultEmbeddableDefinition(
|
||||
String definingName,
|
||||
TableDefinition definingTable,
|
||||
List<String> definingColumnNames,
|
||||
String referencingName,
|
||||
TableDefinition referencingTable,
|
||||
List<ColumnDefinition> referencingColumns,
|
||||
boolean replacesFields
|
||||
) {
|
||||
super(definingTable.getSchema(), definingName, "");
|
||||
|
||||
this.columnNames = columnNames;
|
||||
this.table = table;
|
||||
this.definingColumnNames = definingColumnNames;
|
||||
this.definingTable = definingTable;
|
||||
this.referencingName = referencingName;
|
||||
this.referencingTable = referencingTable;
|
||||
this.embeddableColumns = new ArrayList<>();
|
||||
this.replacesFields = replacesFields;
|
||||
|
||||
for (int i = 0; i < columns.size(); i++)
|
||||
embeddableColumns.add(new DefaultEmbeddableColumnDefinition(this, columnNames.get(i), columns.get(i), i));
|
||||
|
||||
|
||||
|
||||
log.info("Commercial feature", "Embeddables replacing fields is a commercial only feature. Please upgrade to the jOOQ Professional Edition");
|
||||
|
||||
for (int i = 0; i < referencingColumns.size(); i++)
|
||||
embeddableColumns.add(new DefaultEmbeddableColumnDefinition(this, definingColumnNames.get(i), referencingColumns.get(i), i));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final TableDefinition getTable() {
|
||||
return table;
|
||||
return getDefiningTable();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<EmbeddableColumnDefinition> getElements0() throws SQLException {
|
||||
public final TableDefinition getDefiningTable() {
|
||||
return definingTable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getReferencingName() {
|
||||
return getReferencingInputName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getReferencingInputName() {
|
||||
return referencingName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getReferencingOutputName() {
|
||||
return referencingName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final TableDefinition getReferencingTable() {
|
||||
return referencingTable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final List<EmbeddableColumnDefinition> getElements0() throws SQLException {
|
||||
return embeddableColumns;
|
||||
}
|
||||
|
||||
@ -92,4 +140,9 @@ public class DefaultEmbeddableDefinition
|
||||
public final EmbeddableColumnDefinition getColumn(int columnIndex) {
|
||||
return getElement(columnIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean replacesFields() {
|
||||
return replacesFields;
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,9 +44,9 @@ import java.util.Set;
|
||||
|
||||
public class DefaultForeignKeyDefinition extends AbstractConstraintDefinition implements ForeignKeyDefinition {
|
||||
|
||||
private final List<ColumnDefinition> fkColumns;
|
||||
private final List<ColumnDefinition> ukColumns;
|
||||
private final UniqueKeyDefinition uk;
|
||||
private final List<ColumnDefinition> fkColumns;
|
||||
private final List<ColumnDefinition> ukColumns;
|
||||
private final UniqueKeyDefinition uk;
|
||||
|
||||
public DefaultForeignKeyDefinition(SchemaDefinition schema, String name, TableDefinition table, UniqueKeyDefinition uniqueKey) {
|
||||
this(schema, name, table, uniqueKey, true);
|
||||
@ -75,6 +75,11 @@ public class DefaultForeignKeyDefinition extends AbstractConstraintDefinition im
|
||||
return uk;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UniqueKeyDefinition resolveReferencedKey() {
|
||||
return uk.resolveReferencedKey();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableDefinition getReferencedTable() {
|
||||
return uk.getTable();
|
||||
|
||||
@ -40,11 +40,16 @@ package org.jooq.meta;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jooq.tools.JooqLogger;
|
||||
|
||||
public class DefaultUniqueKeyDefinition extends AbstractConstraintDefinition implements UniqueKeyDefinition {
|
||||
|
||||
private static final JooqLogger log = JooqLogger.getLogger(DefaultUniqueKeyDefinition.class);
|
||||
private final List<ForeignKeyDefinition> foreignKeys;
|
||||
private final List<ColumnDefinition> keyColumns;
|
||||
private final boolean isPrimaryKey;
|
||||
private transient boolean resolvedUKCalculated;
|
||||
private transient UniqueKeyDefinition resolvedUK;
|
||||
|
||||
public DefaultUniqueKeyDefinition(SchemaDefinition schema, String name, TableDefinition table, boolean isPrimaryKey) {
|
||||
this(schema, name, table, isPrimaryKey, true);
|
||||
@ -72,4 +77,28 @@ public class DefaultUniqueKeyDefinition extends AbstractConstraintDefinition imp
|
||||
public List<ForeignKeyDefinition> getForeignKeys() {
|
||||
return foreignKeys;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final UniqueKeyDefinition resolveReferencedKey() {
|
||||
if (!resolvedUKCalculated) {
|
||||
resolvedUKCalculated = true;
|
||||
|
||||
ForeignKeyDefinition candidate = null;
|
||||
for (ForeignKeyDefinition fk : getTable().getForeignKeys()) {
|
||||
if (keyColumns.equals(fk.getKeyColumns())) {
|
||||
if (candidate == null) {
|
||||
candidate = fk;
|
||||
}
|
||||
else {
|
||||
log.info("Cannot resolve key", (isPrimaryKey ? "Primary" : "Unique") + " key coincides with at least two foreign keys: " + candidate + " and " + fk);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resolvedUK = candidate == null ? this : candidate.resolveReferencedKey();
|
||||
}
|
||||
|
||||
return resolvedUK;
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,23 +48,56 @@ import java.util.List;
|
||||
public interface EmbeddableDefinition extends TableElementDefinition {
|
||||
|
||||
/**
|
||||
* All columns in the type, table or view.
|
||||
* The table defining the embeddable (same as {@link #getTable()}).
|
||||
*/
|
||||
TableDefinition getDefiningTable();
|
||||
|
||||
/**
|
||||
* The referencing name of this embeddable, if it differs from the defining
|
||||
* name ({@link #getName()}).
|
||||
*/
|
||||
String getReferencingName();
|
||||
|
||||
/**
|
||||
* The referencing input name of this embeddable, if it differs from the defining
|
||||
* name ({@link #getInputName()}).
|
||||
*/
|
||||
String getReferencingInputName();
|
||||
|
||||
/**
|
||||
* The referencing output name of this embeddable, if it differs from the defining
|
||||
* name ({@link #getOutputName()}).
|
||||
*/
|
||||
String getReferencingOutputName();
|
||||
|
||||
/**
|
||||
* The table referencing the embeddable.
|
||||
*/
|
||||
TableDefinition getReferencingTable();
|
||||
|
||||
/**
|
||||
* All referencing columns in the type, table or view.
|
||||
*/
|
||||
List<EmbeddableColumnDefinition> getColumns();
|
||||
|
||||
/**
|
||||
* Get a column in this type by its name.
|
||||
* Get a referencing column in this type by its name.
|
||||
*/
|
||||
EmbeddableColumnDefinition getColumn(String columnName);
|
||||
|
||||
/**
|
||||
* Get a column in this type by its name.
|
||||
* Get a referencing column in this type by its name.
|
||||
*/
|
||||
EmbeddableColumnDefinition getColumn(String columnName, boolean ignoreCase);
|
||||
|
||||
/**
|
||||
* Get a column in this type by its index (starting at 0).
|
||||
* Get a referencing column in this type by its index (starting at 0).
|
||||
*/
|
||||
EmbeddableColumnDefinition getColumn(int columnIndex);
|
||||
|
||||
/**
|
||||
* Whether this embeddable replaces the fields it represents.
|
||||
*/
|
||||
boolean replacesFields();
|
||||
|
||||
}
|
||||
|
||||
@ -64,6 +64,16 @@ public interface ForeignKeyDefinition extends ConstraintDefinition {
|
||||
*/
|
||||
UniqueKeyDefinition getReferencedKey();
|
||||
|
||||
/**
|
||||
* Resolve a referenced key.
|
||||
* <p>
|
||||
* If {@link #getReferencedKey()} coincides itself with a foreign key,
|
||||
* resolve that foreign key recursively. In case of ambiguity (two foreign
|
||||
* keys coinciding with a single unique key), this returns
|
||||
* <code>null</code>.
|
||||
*/
|
||||
UniqueKeyDefinition resolveReferencedKey();
|
||||
|
||||
/**
|
||||
* The definition of the referenced table.
|
||||
*/
|
||||
|
||||
@ -71,10 +71,15 @@ public interface TableDefinition extends Definition {
|
||||
ColumnDefinition getColumn(int columnIndex);
|
||||
|
||||
/**
|
||||
* All embeddable types in the table.
|
||||
* All embeddable types in this defining table.
|
||||
*/
|
||||
List<EmbeddableDefinition> getEmbeddables();
|
||||
|
||||
/**
|
||||
* All embeddable types in this referencing table.
|
||||
*/
|
||||
List<EmbeddableDefinition> getReferencedEmbeddables();
|
||||
|
||||
/**
|
||||
* Get the indexes for this table.
|
||||
*/
|
||||
|
||||
@ -63,4 +63,14 @@ public interface UniqueKeyDefinition extends ConstraintDefinition {
|
||||
* The foreign keys referencing this primary key
|
||||
*/
|
||||
List<ForeignKeyDefinition> getForeignKeys();
|
||||
|
||||
/**
|
||||
* Resolve a referenced key.
|
||||
* <p>
|
||||
* If this key coincides with a foreign key, resolve that foreign key
|
||||
* recursively. In case of ambiguity (two foreign keys coinciding with a
|
||||
* single unique key), this returns <code>null</code>.
|
||||
*/
|
||||
UniqueKeyDefinition resolveReferencedKey();
|
||||
|
||||
}
|
||||
|
||||
@ -133,6 +133,10 @@ public class Database implements Serializable, XMLAppendable
|
||||
@XmlElement(defaultValue = "")
|
||||
@XmlJavaTypeAdapter(StringAdapter.class)
|
||||
protected String orderProvider = "";
|
||||
@XmlElement(defaultValue = "false")
|
||||
protected Boolean embeddablePrimaryKeys = false;
|
||||
@XmlElement(defaultValue = "false")
|
||||
protected Boolean embeddableUniqueKeys = false;
|
||||
@XmlElement(defaultValue = "true")
|
||||
protected Boolean forceIntegerTypesOnZeroScaleDecimals = true;
|
||||
protected Boolean tableValuedFunctions;
|
||||
@ -1355,6 +1359,54 @@ public class Database implements Serializable, XMLAppendable
|
||||
this.orderProvider = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether wrapper types should be generated for primary key columns, and for their referencing foreign keys.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public Boolean isEmbeddablePrimaryKeys() {
|
||||
return embeddablePrimaryKeys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the embeddablePrimaryKeys property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public void setEmbeddablePrimaryKeys(Boolean value) {
|
||||
this.embeddablePrimaryKeys = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether wrapper types should be generated for unique key columns, and for their referencing foreign keys.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public Boolean isEmbeddableUniqueKeys() {
|
||||
return embeddableUniqueKeys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the embeddableUniqueKeys property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public void setEmbeddableUniqueKeys(Boolean value) {
|
||||
this.embeddableUniqueKeys = 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.
|
||||
*
|
||||
@ -1989,6 +2041,16 @@ public class Database implements Serializable, XMLAppendable
|
||||
return this;
|
||||
}
|
||||
|
||||
public Database withEmbeddablePrimaryKeys(Boolean value) {
|
||||
setEmbeddablePrimaryKeys(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Database withEmbeddableUniqueKeys(Boolean value) {
|
||||
setEmbeddableUniqueKeys(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Database withForceIntegerTypesOnZeroScaleDecimals(Boolean value) {
|
||||
setForceIntegerTypesOnZeroScaleDecimals(value);
|
||||
return this;
|
||||
@ -2215,6 +2277,8 @@ public class Database implements Serializable, XMLAppendable
|
||||
builder.append("schemaVersionProvider", schemaVersionProvider);
|
||||
builder.append("catalogVersionProvider", catalogVersionProvider);
|
||||
builder.append("orderProvider", orderProvider);
|
||||
builder.append("embeddablePrimaryKeys", embeddablePrimaryKeys);
|
||||
builder.append("embeddableUniqueKeys", embeddableUniqueKeys);
|
||||
builder.append("forceIntegerTypesOnZeroScaleDecimals", forceIntegerTypesOnZeroScaleDecimals);
|
||||
builder.append("tableValuedFunctions", tableValuedFunctions);
|
||||
builder.append("logSlowQueriesAfterSeconds", logSlowQueriesAfterSeconds);
|
||||
@ -2634,6 +2698,24 @@ public class Database implements Serializable, XMLAppendable
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (embeddablePrimaryKeys == null) {
|
||||
if (other.embeddablePrimaryKeys!= null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!embeddablePrimaryKeys.equals(other.embeddablePrimaryKeys)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (embeddableUniqueKeys == null) {
|
||||
if (other.embeddableUniqueKeys!= null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!embeddableUniqueKeys.equals(other.embeddableUniqueKeys)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (forceIntegerTypesOnZeroScaleDecimals == null) {
|
||||
if (other.forceIntegerTypesOnZeroScaleDecimals!= null) {
|
||||
return false;
|
||||
@ -2783,6 +2865,8 @@ public class Database implements Serializable, XMLAppendable
|
||||
result = ((prime*result)+((schemaVersionProvider == null)? 0 :schemaVersionProvider.hashCode()));
|
||||
result = ((prime*result)+((catalogVersionProvider == null)? 0 :catalogVersionProvider.hashCode()));
|
||||
result = ((prime*result)+((orderProvider == null)? 0 :orderProvider.hashCode()));
|
||||
result = ((prime*result)+((embeddablePrimaryKeys == null)? 0 :embeddablePrimaryKeys.hashCode()));
|
||||
result = ((prime*result)+((embeddableUniqueKeys == null)? 0 :embeddableUniqueKeys.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()));
|
||||
|
||||
@ -35,12 +35,16 @@ public class Embeddable implements Serializable, XMLAppendable
|
||||
private final static long serialVersionUID = 31400L;
|
||||
@XmlJavaTypeAdapter(StringAdapter.class)
|
||||
protected String name;
|
||||
@XmlJavaTypeAdapter(StringAdapter.class)
|
||||
protected String referencingName;
|
||||
@XmlElement(defaultValue = "false")
|
||||
protected Boolean replacesFields = false;
|
||||
@XmlElementWrapper(name = "fields")
|
||||
@XmlElement(name = "field")
|
||||
protected List<EmbeddableField> fields;
|
||||
|
||||
/**
|
||||
* The name of the embeddable type
|
||||
* The defining name of the embeddable type.
|
||||
*
|
||||
*/
|
||||
public String getName() {
|
||||
@ -48,13 +52,53 @@ public class Embeddable implements Serializable, XMLAppendable
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the embeddable type
|
||||
* The defining name of the embeddable type.
|
||||
*
|
||||
*/
|
||||
public void setName(String value) {
|
||||
this.name = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The referencing name of the embeddable type, defaulting to the defining name.
|
||||
*
|
||||
*/
|
||||
public String getReferencingName() {
|
||||
return referencingName;
|
||||
}
|
||||
|
||||
/**
|
||||
* The referencing name of the embeddable type, defaulting to the defining name.
|
||||
*
|
||||
*/
|
||||
public void setReferencingName(String value) {
|
||||
this.referencingName = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify that the embeddable field replaces its underlying fields in code generation output, and when working with asterisks.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public Boolean isReplacesFields() {
|
||||
return replacesFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the replacesFields property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public void setReplacesFields(Boolean value) {
|
||||
this.replacesFields = value;
|
||||
}
|
||||
|
||||
public List<EmbeddableField> getFields() {
|
||||
if (fields == null) {
|
||||
fields = new ArrayList<EmbeddableField>();
|
||||
@ -67,7 +111,7 @@ public class Embeddable implements Serializable, XMLAppendable
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the embeddable type
|
||||
* The defining name of the embeddable type.
|
||||
*
|
||||
*/
|
||||
public Embeddable withName(String value) {
|
||||
@ -75,6 +119,20 @@ public class Embeddable implements Serializable, XMLAppendable
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The referencing name of the embeddable type, defaulting to the defining name.
|
||||
*
|
||||
*/
|
||||
public Embeddable withReferencingName(String value) {
|
||||
setReferencingName(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Embeddable withReplacesFields(Boolean value) {
|
||||
setReplacesFields(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Embeddable withFields(EmbeddableField... values) {
|
||||
if (values!= null) {
|
||||
for (EmbeddableField value: values) {
|
||||
@ -99,6 +157,8 @@ public class Embeddable implements Serializable, XMLAppendable
|
||||
@Override
|
||||
public final void appendTo(XMLBuilder builder) {
|
||||
builder.append("name", name);
|
||||
builder.append("referencingName", referencingName);
|
||||
builder.append("replacesFields", replacesFields);
|
||||
builder.append("fields", "field", fields);
|
||||
}
|
||||
|
||||
@ -130,6 +190,24 @@ public class Embeddable implements Serializable, XMLAppendable
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (referencingName == null) {
|
||||
if (other.referencingName!= null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!referencingName.equals(other.referencingName)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (replacesFields == null) {
|
||||
if (other.replacesFields!= null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!replacesFields.equals(other.replacesFields)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (fields == null) {
|
||||
if (other.fields!= null) {
|
||||
return false;
|
||||
@ -147,6 +225,8 @@ public class Embeddable implements Serializable, XMLAppendable
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = ((prime*result)+((name == null)? 0 :name.hashCode()));
|
||||
result = ((prime*result)+((referencingName == null)? 0 :referencingName.hashCode()));
|
||||
result = ((prime*result)+((replacesFields == null)? 0 :replacesFields.hashCode()));
|
||||
result = ((prime*result)+((fields == null)? 0 :fields.hashCode()));
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -190,8 +190,6 @@ public class Generate implements Serializable, XMLAppendable
|
||||
protected Boolean emptySchemas = false;
|
||||
@XmlElement(defaultValue = "true")
|
||||
protected Boolean javaTimeTypes = true;
|
||||
@XmlElement(defaultValue = "false")
|
||||
protected Boolean primaryKeyTypes = false;
|
||||
@XmlElement(defaultValue = "\\n")
|
||||
@XmlJavaTypeAdapter(StringAdapter.class)
|
||||
protected String newline = "\\n";
|
||||
@ -2092,30 +2090,6 @@ public class Generate implements Serializable, XMLAppendable
|
||||
this.javaTimeTypes = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether wrapper types should be generated for primary key columns, and for their referencing foreign keys.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public Boolean isPrimaryKeyTypes() {
|
||||
return primaryKeyTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the primaryKeyTypes property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public void setPrimaryKeyTypes(Boolean value) {
|
||||
this.primaryKeyTypes = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The newline characters to be used in generated code. Whitespace characters can be used, e.g. \n, \r\n
|
||||
*
|
||||
@ -2568,11 +2542,6 @@ public class Generate implements Serializable, XMLAppendable
|
||||
return this;
|
||||
}
|
||||
|
||||
public Generate withPrimaryKeyTypes(Boolean value) {
|
||||
setPrimaryKeyTypes(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The newline characters to be used in generated code. Whitespace characters can be used, e.g. \n, \r\n
|
||||
*
|
||||
@ -2672,7 +2641,6 @@ public class Generate implements Serializable, XMLAppendable
|
||||
builder.append("emptyCatalogs", emptyCatalogs);
|
||||
builder.append("emptySchemas", emptySchemas);
|
||||
builder.append("javaTimeTypes", javaTimeTypes);
|
||||
builder.append("primaryKeyTypes", primaryKeyTypes);
|
||||
builder.append("newline", newline);
|
||||
builder.append("indentation", indentation);
|
||||
}
|
||||
@ -3407,15 +3375,6 @@ public class Generate implements Serializable, XMLAppendable
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (primaryKeyTypes == null) {
|
||||
if (other.primaryKeyTypes!= null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!primaryKeyTypes.equals(other.primaryKeyTypes)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (newline == null) {
|
||||
if (other.newline!= null) {
|
||||
return false;
|
||||
@ -3520,7 +3479,6 @@ public class Generate implements Serializable, XMLAppendable
|
||||
result = ((prime*result)+((emptyCatalogs == null)? 0 :emptyCatalogs.hashCode()));
|
||||
result = ((prime*result)+((emptySchemas == null)? 0 :emptySchemas.hashCode()));
|
||||
result = ((prime*result)+((javaTimeTypes == null)? 0 :javaTimeTypes.hashCode()));
|
||||
result = ((prime*result)+((primaryKeyTypes == null)? 0 :primaryKeyTypes.hashCode()));
|
||||
result = ((prime*result)+((newline == null)? 0 :newline.hashCode()));
|
||||
result = ((prime*result)+((indentation == null)? 0 :indentation.hashCode()));
|
||||
return result;
|
||||
|
||||
@ -793,6 +793,14 @@ This comparator can be used to influence the order of any object that is produce
|
||||
<element name="embeddables" type="tns:Embeddables" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Configure embeddable types.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="embeddablePrimaryKeys" type="boolean" default="false" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Whether wrapper types should be generated for primary key columns, and for their referencing foreign keys.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="embeddableUniqueKeys" type="boolean" default="false" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Whether wrapper types should be generated for unique key columns, and for their referencing foreign keys.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="customTypes" type="tns:CustomTypes" minOccurs="0" maxOccurs="1">
|
||||
<annotation>
|
||||
@ -1005,12 +1013,20 @@ for Oracle.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
<annotation><appinfo><jxb:class><jxb:javadoc><![CDATA[An embeddable type declaration]]></jxb:javadoc></jxb:class></appinfo></annotation>
|
||||
<all>
|
||||
<element name="name" type="string" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[The name of the embeddable type]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[The defining name of the embeddable type.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="referencingName" type="string" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[The referencing name of the embeddable type, defaulting to the defining name.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="fields" type="tns:EmbeddableFields" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[A set of field specifications for the embeddable type.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="replacesFields" type="boolean" minOccurs="0" maxOccurs="1" default="false">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Specify that the embeddable field replaces its underlying fields in code generation output, and when working with asterisks.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
</all>
|
||||
</complexType>
|
||||
|
||||
@ -1497,10 +1513,6 @@ source code generator, rather than JDBC's java.sql types.
|
||||
<p>
|
||||
This flag is ignored in the commercial Java 6 distribution of jOOQ 3.9+ ]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="primaryKeyTypes" type="boolean" default="false" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Whether wrapper types should be generated for primary key columns, and for their referencing foreign keys.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="newline" type="string" default="\n" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[The newline characters to be used in generated code. Whitespace characters can be used, e.g. \n, \r\n]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
|
||||
@ -41,6 +41,7 @@ import org.jooq.Converter;
|
||||
import org.jooq.EmbeddableRecord;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.Row;
|
||||
import org.jooq.TableField;
|
||||
|
||||
/**
|
||||
* A record implementation for a record originating from a single table
|
||||
@ -61,6 +62,10 @@ public class EmbeddableRecordImpl<R extends EmbeddableRecord<R>> extends Abstrac
|
||||
super(fields);
|
||||
}
|
||||
|
||||
public EmbeddableRecordImpl(TableField<?, ?>... fields) {
|
||||
super(fields);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public final <T> R with(Field<T> field, T value) {
|
||||
|
||||
@ -56,15 +56,17 @@ final class EmbeddableTableField<R extends Record, T extends Record> extends Abs
|
||||
* Generated UID
|
||||
*/
|
||||
private static final long serialVersionUID = -7105430856294526440L;
|
||||
final Class<T> recordType;
|
||||
final boolean replacesFields;
|
||||
final Table<R> table;
|
||||
final TableField<R, ?>[] fields;
|
||||
final Class<T> recordType;
|
||||
|
||||
EmbeddableTableField(Name name, Class<T> recordType, Table<R> table, TableField<R, ?>[] fields) {
|
||||
EmbeddableTableField(Name name, Class<T> recordType, boolean replacesFields, Table<R> table, TableField<R, ?>[] fields) {
|
||||
super(name, new DefaultDataType<>(SQLDialect.DEFAULT, recordType, name.last()));
|
||||
|
||||
this.table = table;
|
||||
this.recordType = recordType;
|
||||
this.replacesFields = replacesFields;
|
||||
this.table = table;
|
||||
this.fields = fields;
|
||||
}
|
||||
|
||||
|
||||
@ -42,6 +42,7 @@ import org.jooq.Check;
|
||||
import org.jooq.Converter;
|
||||
import org.jooq.DataType;
|
||||
import org.jooq.Domain;
|
||||
import org.jooq.EmbeddableRecord;
|
||||
import org.jooq.ForeignKey;
|
||||
import org.jooq.Identity;
|
||||
import org.jooq.Index;
|
||||
@ -76,9 +77,19 @@ public final class Internal {
|
||||
/**
|
||||
* Factory method for embeddable types.
|
||||
*/
|
||||
@SafeVarargs
|
||||
@NotNull
|
||||
public static final <R extends Record, T extends Record> TableField<R, T> createEmbeddable(Name name, Class<T> recordType, Table<R> table, TableField<R, ?>... fields) {
|
||||
return new EmbeddableTableField<>(name, recordType, table, fields);
|
||||
return createEmbeddable(name, recordType, false, table, fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for embeddable types.
|
||||
*/
|
||||
@SafeVarargs
|
||||
@NotNull
|
||||
public static final <R extends Record, T extends Record> TableField<R, T> createEmbeddable(Name name, Class<T> recordType, boolean replacesFields, Table<R> table, TableField<R, ?>... fields) {
|
||||
return new EmbeddableTableField<>(name, recordType, replacesFields, table, fields);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -123,6 +134,14 @@ public final class Internal {
|
||||
return new UniqueKeyImpl<>(table, name, fields, enforced);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for unique keys.
|
||||
*/
|
||||
@NotNull
|
||||
public static final <R extends Record, ER extends EmbeddableRecord<ER>> UniqueKey<R> createUniqueKey(Table<R> table, Name name, TableField<R, ER> embeddableField, boolean enforced) {
|
||||
return createUniqueKey(table, name, fields(embeddableField), enforced);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for foreign keys.
|
||||
*
|
||||
@ -148,6 +167,14 @@ public final class Internal {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for foreign keys.
|
||||
*/
|
||||
@NotNull
|
||||
public static final <R extends Record, U extends Record, ER extends EmbeddableRecord<ER>> ForeignKey<R, U> createForeignKey(Table<R> table, Name name, TableField<R, ER> fkEmbeddableField, UniqueKey<U> uk, TableField<U, ER> ukEmbeddableField, boolean enforced) {
|
||||
return createForeignKey(table, name, fields(fkEmbeddableField), uk, fields(ukEmbeddableField), enforced);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for sequences.
|
||||
*/
|
||||
@ -322,4 +349,12 @@ public final class Internal {
|
||||
public static final <R extends Record, U extends Record> ForeignKey<R, U> createForeignKey(UniqueKey<U> key, Table<R> table, String name, TableField<R, ?>[] fields, boolean enforced) {
|
||||
return createForeignKey(table, DSL.name(name), fields, key, key.getFieldsArray(), enforced);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the fields of an embeddable type.
|
||||
*/
|
||||
@NotNull
|
||||
public static final <R extends Record, ER extends EmbeddableRecord<ER>> TableField<R, ?>[] fields(TableField<R, ER> embeddableField) {
|
||||
return ((EmbeddableTableField<R, ER>) embeddableField).fields;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user