use of org.jooq.UniqueKey in project jOOQ by jOOQ.
the class JavaGenerator method generateRelations.
protected void generateRelations(SchemaDefinition schema) {
log.info("Generating Keys");
boolean empty = true;
JavaWriter out = newJavaWriter(getStrategy().getGlobalReferencesFile(schema, ConstraintDefinition.class));
out.refConflicts(getStrategy().getJavaIdentifiers(database.getKeys(schema)));
out.refConflicts(getStrategy().getJavaIdentifiers(database.getForeignKeys(schema)));
printGlobalReferencesPackage(out, schema, ConstraintDefinition.class);
if (!kotlin) {
printClassJavadoc(out, "A class modelling foreign key relationships and constraints of tables in " + schemaNameOrDefault(schema) + ".");
printClassAnnotations(out, schema, Mode.DEFAULT);
}
final String referencesClassName = getStrategy().getGlobalReferencesJavaClassName(schema, ConstraintDefinition.class);
if (scala)
out.println("%sobject %s {", visibility(), referencesClassName);
else if (kotlin) {
} else
out.println("%sclass %s {", visibility(), referencesClassName);
// [#1459] [#10554] [#10653] Distribute keys to nested classes only if necessary
boolean distributeUniqueKeys = database.getKeys(schema).size() > maxMembersPerInitialiser();
boolean distributeForeignKeys = database.getForeignKeys(schema).size() > maxMembersPerInitialiser();
List<UniqueKeyDefinition> allUniqueKeys = new ArrayList<>();
List<ForeignKeyDefinition> allForeignKeys = new ArrayList<>();
// Unique keys
try {
for (UniqueKeyDefinition uniqueKey : database.getKeys(schema)) {
empty = false;
final String keyType = out.ref(getStrategy().getFullJavaClassName(uniqueKey.getTable(), Mode.RECORD));
final String keyId = getStrategy().getJavaIdentifier(uniqueKey);
final int block = allUniqueKeys.size() / maxMembersPerInitialiser();
// [#10480] Print header before first key
if (allUniqueKeys.isEmpty()) {
out.header("UNIQUE and PRIMARY KEY definitions");
out.println();
}
if (distributeUniqueKeys)
if (scala)
out.println("%sval %s = UniqueKeys%s.%s", visibility(), keyId, block, keyId);
else if (kotlin)
out.println("%sval %s: %s<%s> = UniqueKeys%s.%s", visibility(), keyId, UniqueKey.class, keyType, block, keyId);
else
out.println("%sstatic final %s<%s> %s = UniqueKeys%s.%s;", visibility(), UniqueKey.class, keyType, keyId, block, keyId);
else
printUniqueKey(out, -1, uniqueKey, distributeUniqueKeys);
allUniqueKeys.add(uniqueKey);
}
} catch (Exception e) {
log.error("Error while generating unique keys for schema " + schema, e);
}
// Foreign keys
try {
for (ForeignKeyDefinition foreignKey : database.getForeignKeys(schema)) {
empty = false;
final String keyType = out.ref(getStrategy().getFullJavaClassName(foreignKey.getKeyTable(), Mode.RECORD));
final String referencedType = out.ref(getStrategy().getFullJavaClassName(foreignKey.getReferencedTable(), Mode.RECORD));
final String keyId = getStrategy().getJavaIdentifier(foreignKey);
final int block = allForeignKeys.size() / maxMembersPerInitialiser();
// [#10480] Print header before first key
if (allForeignKeys.isEmpty()) {
out.header("FOREIGN KEY definitions");
out.println();
}
if (distributeForeignKeys)
if (scala)
out.println("%sval %s = ForeignKeys%s.%s", visibility(), keyId, block, keyId);
else if (kotlin)
out.println("%sval %s: %s<%s, %s> = ForeignKeys%s.%s", visibility(), keyId, ForeignKey.class, keyType, referencedType, block, keyId);
else
out.println("%sstatic final %s<%s, %s> %s = ForeignKeys%s.%s;", visibility(), ForeignKey.class, keyType, referencedType, keyId, block, keyId);
else
printForeignKey(out, -1, foreignKey, distributeForeignKeys);
allForeignKeys.add(foreignKey);
}
} catch (Exception e) {
log.error("Error while generating foreign keys for schema " + schema, e);
}
// [#1459] [#10554] [#10653] Print nested classes for actual static field initialisations
// keeping top-level initialiser small
int uniqueKeyCounter = 0;
int foreignKeyCounter = 0;
if (distributeUniqueKeys || distributeForeignKeys) {
out.header("[#1459] [#10554] [#10653] distribute members to avoid static initialisers > 64kb");
if (distributeUniqueKeys) {
for (UniqueKeyDefinition uniqueKey : allUniqueKeys) printUniqueKey(out, uniqueKeyCounter++, uniqueKey, distributeUniqueKeys);
if (uniqueKeyCounter > 0)
out.println("}");
}
if (distributeForeignKeys) {
for (ForeignKeyDefinition foreignKey : allForeignKeys) printForeignKey(out, foreignKeyCounter++, foreignKey, distributeForeignKeys);
if (foreignKeyCounter > 0)
out.println("}");
}
}
generateRelationsClassFooter(schema, out);
if (!kotlin)
out.println("}");
if (empty) {
log.info("Skipping empty keys");
} else {
closeJavaWriter(out);
watch.splitInfo("Keys generated");
}
}
use of org.jooq.UniqueKey in project jOOQ by jOOQ.
the class JavaGenerator method generateTable.
protected void generateTable(TableDefinition table, JavaWriter out) {
final SchemaDefinition schema = table.getSchema();
final UniqueKeyDefinition primaryKey = table.getPrimaryKey();
final String className = getStrategy().getJavaClassName(table);
final String tableId = scala ? out.ref(getStrategy().getFullJavaIdentifier(table), 2) : getStrategy().getJavaIdentifier(table);
final String recordType = out.ref(getStrategy().getFullJavaClassName(table, Mode.RECORD));
final List<String> interfaces = out.ref(getStrategy().getJavaClassImplements(table, Mode.DEFAULT));
final String schemaId = out.ref(getStrategy().getFullJavaIdentifier(schema), 2);
final String tableType = table.isTemporary() ? "temporaryTable" : table.isView() ? "view" : table.isMaterializedView() ? "materializedView" : table.isTableValuedFunction() ? "function" : "table";
final List<ParameterDefinition> parameters = table.getParameters();
printPackage(out, table);
if (scala) {
out.println("object %s {", className);
printSingletonInstance(out, table);
out.println("}");
out.println();
}
generateTableClassJavadoc(table, out);
printClassAnnotations(out, table, Mode.DEFAULT);
if (scala) {
out.println("%sclass %s(", visibility(), className);
out.println("alias: %s,", Name.class);
out.println("child: %s[_ <: %s],", Table.class, Record.class);
out.println("path: %s[_ <: %s, %s],", ForeignKey.class, Record.class, recordType);
out.println("aliased: %s[%s],", Table.class, recordType);
out.println("parameters: %s[ %s[_] ]", out.ref("scala.Array"), Field.class);
out.println(")");
out.println("extends %s[%s](", TableImpl.class, recordType);
out.println("alias,");
out.println("%s,", schemaId);
out.println("child,");
out.println("path,");
out.println("aliased,");
out.println("parameters,");
out.println("%s.comment(\"%s\"),", DSL.class, escapeString(comment(table)));
if ((generateSourcesOnViews() || table.isSynthetic()) && table.isView() && table.getSource() != null)
out.println("%s.%s(\"%s\")", TableOptions.class, tableType, escapeString(table.getSource()));
else if (table.isSynthetic() && table.isTableValuedFunction() && table.getSource() != null)
out.println("%s.%s(\"%s\")", TableOptions.class, tableType, escapeString(table.getSource()));
else
out.println("%s.%s", TableOptions.class, tableType);
out.println(")[[before= with ][separator= with ][%s]] {", interfaces);
} else if (kotlin) {
out.println("%sopen class %s(", visibility(), className);
out.println("alias: %s,", Name.class);
out.println("child: %s<out %s>?,", Table.class, Record.class);
out.println("path: %s<out %s, %s>?,", ForeignKey.class, Record.class, recordType);
out.println("aliased: %s<%s>?,", Table.class, recordType);
out.println("parameters: Array<%s<*>?>?", Field.class);
out.println("): %s<%s>(", TableImpl.class, recordType);
out.println("alias,");
out.println("%s,", schemaId);
out.println("child,");
out.println("path,");
out.println("aliased,");
out.println("parameters,");
out.println("%s.comment(\"%s\"),", DSL.class, escapeString(comment(table)));
if ((generateSourcesOnViews() || table.isSynthetic()) && table.isView() && table.getSource() != null)
out.println("%s.%s(\"%s\")", TableOptions.class, tableType, escapeString(table.getSource()));
else if (table.isSynthetic() && table.isTableValuedFunction() && table.getSource() != null)
out.println("%s.%s(\"%s\")", TableOptions.class, tableType, escapeString(table.getSource()));
else
out.println("%s.%s()", TableOptions.class, tableType);
out.println(")[[before=, ][%s]] {", interfaces);
out.println("%scompanion object {", visibility());
printSingletonInstance(out, table);
out.println("}");
} else {
out.println("%sclass %s extends %s<%s>[[before= implements ][%s]] {", visibility(), className, TableImpl.class, recordType, interfaces);
out.printSerial();
printSingletonInstance(out, table);
}
printRecordTypeMethod(out, table);
if (table.isSynthetic()) {
if (scala) {
out.println();
out.println("protected override def isSynthetic(): Boolean = true");
} else if (kotlin) {
out.println();
out.println("protected override fun isSynthetic(): Boolean = true");
} else {
out.println();
out.override();
out.println("protected boolean isSynthetic() {");
out.println("return true;");
out.println("}");
}
}
for (ColumnDefinition column : table.getColumns()) {
final String columnTypeFull = getJavaType(column.getType(resolver(out)), out);
final String columnType = out.ref(columnTypeFull);
final String columnTypeRef = getJavaTypeReference(column.getDatabase(), column.getType(resolver(out)), out);
final String columnId = out.ref(getStrategy().getJavaIdentifier(column), colRefSegments(column));
final String columnName = column.getName();
final List<String> converter = out.ref(list(column.getType(resolver(out)).getConverter()));
final List<String> binding = out.ref(list(column.getType(resolver(out)).getBinding()));
final String columnVisibility = visibility();
if (!printDeprecationIfUnknownType(out, columnTypeFull))
out.javadoc("The column <code>%s</code>.[[before= ][%s]]", column.getQualifiedOutputName(), list(escapeEntities(comment(column))));
if (scala) {
out.println("%sval %s: %s[%s, %s] = createField(%s.name(\"%s\"), %s, \"%s\"" + converterTemplate(converter) + converterTemplate(binding) + ")", columnVisibility, scalaWhitespaceSuffix(columnId), TableField.class, recordType, columnType, DSL.class, columnName, columnTypeRef, escapeString(comment(column)), converter, binding);
} else if (kotlin) {
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("%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.getReferencedEmbeddables()) {
final String columnId = out.ref(getStrategy().getJavaIdentifier(embeddable), colRefSegments(null));
final String columnType = out.ref(getStrategy().getFullJavaClassName(embeddable, Mode.RECORD));
final List<String> columnIds = new ArrayList<>();
for (EmbeddableColumnDefinition column : embeddable.getColumns()) columnIds.add(out.ref(getStrategy().getJavaIdentifier(column.getReferencingColumn()), colRefSegments(column.getReferencingColumn())));
out.javadoc("The embeddable type <code>%s</code>.[[before= ][%s]]", embeddable.getOutputName(), list(escapeEntities(referencingComment(embeddable))));
if (scala)
out.println("%sval %s: %s[%s, %s] = %s.createEmbeddable(%s.name(\"%s\"), classOf[%s], %s, this, [[%s]])", visibility(), scalaWhitespaceSuffix(columnId), TableField.class, recordType, columnType, Internal.class, DSL.class, escapeString(embeddable.getName()), columnType, embeddable.replacesFields(), columnIds);
else if (kotlin)
out.println("%sval %s: %s<%s, %s> = %s.createEmbeddable(%s.name(\"%s\"), %s::class.java, %s, this, [[%s]])", visibility(), columnId, TableField.class, recordType, columnType, Internal.class, DSL.class, escapeString(embeddable.getName()), columnType, embeddable.replacesFields(), columnIds);
else
out.println("%sfinal %s<%s, %s> %s = %s.createEmbeddable(%s.name(\"%s\"), %s.class, %s, this, [[%s]]);", visibility(), TableField.class, recordType, columnType, columnId, Internal.class, DSL.class, escapeString(embeddable.getName()), columnType, embeddable.replacesFields(), columnIds);
}
out.println();
// "called constructor's definition must precede calling constructor's definition"
if (scala) {
if (table.isTableValuedFunction()) {
out.println("private def this(alias: %s, aliased: %s[%s]) = this(alias, null, null, aliased, %s(", Name.class, Table.class, recordType, out.ref("scala.Array"));
forEach(parameters, (parameter, separator) -> {
final String paramTypeRef = getJavaTypeReference(parameter.getDatabase(), parameter.getType(resolver(out)), out);
final List<String> converter = out.ref(list(parameter.getType(resolver(out)).getConverter()));
final List<String> binding = out.ref(list(parameter.getType(resolver(out)).getBinding()));
out.println("%s.value(null, %s" + converterTemplateForTableValuedFunction(converter) + converterTemplateForTableValuedFunction(binding) + ")%s", DSL.class, paramTypeRef, converter, binding, separator);
});
out.println("))");
} else
out.println("private def this(alias: %s, aliased: %s[%s]) = this(alias, null, null, aliased, null)", Name.class, Table.class, recordType);
} else if (kotlin) {
if (table.isTableValuedFunction()) {
out.println("private constructor(alias: %s, aliased: %s<%s>?): this(alias, null, null, aliased, arrayOf(", Name.class, Table.class, recordType, Field.class, parameters.size());
forEach(parameters, (parameter, separator) -> {
final String paramTypeRef = getJavaTypeReference(parameter.getDatabase(), parameter.getType(resolver(out)), out);
final List<String> converter = out.ref(list(parameter.getType(resolver(out)).getConverter()));
final List<String> binding = out.ref(list(parameter.getType(resolver(out)).getBinding()));
out.println("%s.value(null, %s" + converterTemplateForTableValuedFunction(converter) + converterTemplateForTableValuedFunction(binding) + ")%s", DSL.class, paramTypeRef, converter, binding, separator);
});
out.println("))");
} else
out.println("private constructor(alias: %s, aliased: %s<%s>?): this(alias, null, null, aliased, null)", Name.class, Table.class, recordType);
out.println("private constructor(alias: %s, aliased: %s<%s>?, parameters: Array<%s<*>?>?): this(alias, null, null, aliased, parameters)", Name.class, Table.class, recordType, Field.class);
} else {
out.println("private %s(%s alias, %s<%s> aliased) {", className, Name.class, Table.class, recordType);
if (table.isTableValuedFunction()) {
out.println("this(alias, aliased, new %s[] {", Field.class);
forEach(parameters, (parameter, separator) -> {
final String paramTypeRef = getJavaTypeReference(parameter.getDatabase(), parameter.getType(resolver(out)), out);
final List<String> converter = out.ref(list(parameter.getType(resolver(out)).getConverter()));
final List<String> binding = out.ref(list(parameter.getType(resolver(out)).getBinding()));
out.println("%s.val(null, %s" + converterTemplateForTableValuedFunction(converter) + converterTemplateForTableValuedFunction(binding) + ")%s", DSL.class, paramTypeRef, converter, binding, separator);
});
out.println("});");
} else
out.println("this(alias, aliased, null);");
out.println("}");
out.println();
out.println("private %s(%s alias, %s<%s> aliased, %s<?>[] parameters) {", className, Name.class, Table.class, recordType, Field.class);
if ((generateSourcesOnViews() || table.isSynthetic()) && table.isView() && table.getSource() != null)
out.println("super(alias, null, aliased, parameters, %s.comment(\"%s\"), %s.%s(\"%s\"));", DSL.class, escapeString(comment(table)), TableOptions.class, tableType, escapeString(table.getSource()));
else if (table.isSynthetic() && table.isTableValuedFunction() && table.getSource() != null)
out.println("super(alias, null, aliased, parameters, %s.comment(\"%s\"), %s.%s(\"%s\"));", DSL.class, escapeString(comment(table)), TableOptions.class, tableType, escapeString(table.getSource()));
else
out.println("super(alias, null, aliased, parameters, %s.comment(\"%s\"), %s.%s());", DSL.class, escapeString(comment(table)), TableOptions.class, tableType);
out.println("}");
}
if (scala) {
out.javadoc("Create an aliased <code>%s</code> table reference", table.getQualifiedOutputName());
out.println("%sdef this(alias: %s) = this(%s.name(alias), %s)", visibility(), String.class, DSL.class, tableId);
out.javadoc("Create an aliased <code>%s</code> table reference", table.getQualifiedOutputName());
out.println("%sdef this(alias: %s) = this(alias, %s)", visibility(), Name.class, tableId);
} else if (kotlin) {
out.javadoc("Create an aliased <code>%s</code> table reference", table.getQualifiedOutputName());
out.println("%sconstructor(alias: %s): this(%s.name(alias))", visibility(), String.class, DSL.class);
out.javadoc("Create an aliased <code>%s</code> table reference", table.getQualifiedOutputName());
out.println("%sconstructor(alias: %s): this(alias, null)", visibility(), Name.class, tableId);
} else // be public, as tables are no longer singletons
if (generateInstanceFields()) {
out.javadoc("Create an aliased <code>%s</code> table reference", table.getQualifiedOutputName());
out.println("%s%s(%s alias) {", visibility(), className, String.class);
out.println("this(%s.name(alias), %s);", DSL.class, tableId);
out.println("}");
out.javadoc("Create an aliased <code>%s</code> table reference", table.getQualifiedOutputName());
out.println("%s%s(%s alias) {", visibility(), className, Name.class);
out.println("this(alias, %s);", tableId);
out.println("}");
}
if (scala) {
out.javadoc("Create a <code>%s</code> table reference", table.getQualifiedOutputName());
out.println("%sdef this() = this(%s.name(\"%s\"), null)", visibility(), DSL.class, escapeString(table.getOutputName()));
} else if (kotlin) {
out.javadoc("Create a <code>%s</code> table reference", table.getQualifiedOutputName());
out.println("%sconstructor(): this(%s.name(\"%s\"), null)", visibility(), DSL.class, escapeString(table.getOutputName()));
} else {
// be public, as tables are no longer singletons
if (generateInstanceFields()) {
out.javadoc("Create a <code>%s</code> table reference", table.getQualifiedOutputName());
out.println("%s%s() {", visibility(), className);
} else {
out.javadoc(NO_FURTHER_INSTANCES_ALLOWED);
out.println("private %s() {", className);
}
out.println("this(%s.name(\"%s\"), null);", DSL.class, escapeString(table.getOutputName()));
out.println("}");
}
if (generateImplicitJoinPathsToOne() && generateGlobalKeyReferences() && !table.isTableValuedFunction()) {
out.println();
if (scala) {
out.println("%sdef this(child: %s[_ <: %s], key: %s[_ <: %s, %s]) = this(%s.createPathAlias(child, key), child, key, %s, null)", visibility(), Table.class, Record.class, ForeignKey.class, Record.class, recordType, Internal.class, tableId);
} else if (kotlin) {
out.println("%sconstructor(child: %s<out %s>, key: %s<out %s, %s>): this(%s.createPathAlias(child, key), child, key, %s, null)", visibility(), Table.class, Record.class, ForeignKey.class, Record.class, recordType, Internal.class, tableId);
} else {
out.println("%s<O extends %s> %s(%s<O> child, %s<O, %s> key) {", visibility(), Record.class, className, Table.class, ForeignKey.class, recordType);
out.println("super(child, key, %s);", tableId);
out.println("}");
}
}
if (scala) {
out.println();
out.println("%soverride def getSchema: %s = if (aliased()) null else %s", visibilityPublic(), Schema.class, schemaId);
} else if (kotlin) {
out.println("%soverride fun getSchema(): %s? = if (aliased()) null else %s", visibilityPublic(), Schema.class, schemaId);
} else {
out.overrideInherit();
printNonnullAnnotation(out);
out.println("%s%s getSchema() {", visibilityPublic(), Schema.class);
out.println("return aliased() ? null : %s;", schemaId);
out.println("}");
}
// Add index information
if (generateIndexes()) {
List<IndexDefinition> indexes = table.getIndexes();
if (!indexes.isEmpty()) {
if (generateGlobalIndexReferences()) {
final List<String> indexFullIds = kotlin ? out.ref(getStrategy().getFullJavaIdentifiers(indexes)) : out.ref(getStrategy().getFullJavaIdentifiers(indexes), 2);
if (scala) {
out.println();
out.println("%soverride def getIndexes: %s[%s] = %s.asList[ %s ]([[%s]])", visibilityPublic(), List.class, Index.class, Arrays.class, Index.class, indexFullIds);
} else if (kotlin) {
out.println("%soverride fun getIndexes(): %s<%s> = listOf([[%s]])", visibilityPublic(), out.ref(KLIST), Index.class, indexFullIds);
} else {
out.overrideInherit();
printNonnullAnnotation(out);
out.println("%s%s<%s> getIndexes() {", visibilityPublic(), List.class, Index.class);
out.println("return %s.asList([[%s]]);", Arrays.class, indexFullIds);
out.println("}");
}
} else {
if (scala) {
out.println();
out.println("%soverride def getIndexes: %s[%s] = %s.asList[%s](", visibilityPublic(), List.class, Index.class, Arrays.class, Index.class);
forEach(indexes, "", ", ", (index, separator) -> {
printCreateIndex(out, index);
out.println("%s", separator);
});
out.println(")");
} else if (kotlin) {
out.println("%soverride fun getIndexes(): %s<%s> = listOf(", visibilityPublic(), out.ref(KLIST), Index.class);
forEach(indexes, "", ", ", (index, separator) -> {
printCreateIndex(out, index);
out.println("%s", separator);
});
out.println(")");
} else {
out.overrideInherit();
printNonnullAnnotation(out);
out.println("%s%s<%s> getIndexes() {", visibilityPublic(), List.class, Index.class);
out.println("return %s.asList(", Arrays.class);
forEach(indexes, "", ", ", (index, separator) -> {
printCreateIndex(out, index);
out.println("%s", separator);
});
out.println(");");
out.println("}");
}
}
}
}
// Add primary / unique / foreign key information
if (generateRelations()) {
IdentityDefinition identity = table.getIdentity();
// The identity column
if (identity != null) {
final String identityTypeFull = getJavaType(identity.getColumn().getType(resolver(out)), out);
final String identityType = out.ref(identityTypeFull);
if (scala) {
out.println();
printDeprecationIfUnknownType(out, identityTypeFull);
out.println("%soverride def getIdentity: %s[%s, %s] = super.getIdentity.asInstanceOf[ %s[%s, %s] ]", visibilityPublic(), Identity.class, recordType, identityType, Identity.class, recordType, identityType);
} else if (kotlin) {
printDeprecationIfUnknownType(out, identityTypeFull);
out.println("%soverride fun getIdentity(): %s<%s, %s?> = super.getIdentity() as %s<%s, %s?>", visibilityPublic(), Identity.class, recordType, identityType, Identity.class, recordType, identityType);
} else {
if (printDeprecationIfUnknownType(out, identityTypeFull))
out.override();
else
out.overrideInherit();
printNonnullAnnotation(out);
out.println("%s%s<%s, %s> getIdentity() {", visibilityPublic(), Identity.class, recordType, identityType);
out.println("return (%s<%s, %s>) super.getIdentity();", Identity.class, recordType, identityType);
out.println("}");
}
}
// The primary / main unique key
if (primaryKey != null) {
final String keyFullId = generateGlobalKeyReferences() ? kotlin ? out.ref(getStrategy().getFullJavaIdentifier(primaryKey)) : out.ref(getStrategy().getFullJavaIdentifier(primaryKey), 2) : null;
if (scala) {
out.println();
out.print("%soverride def getPrimaryKey: %s[%s] = ", visibilityPublic(), UniqueKey.class, recordType);
if (keyFullId != null)
out.print("%s", keyFullId);
else
printCreateUniqueKey(out, primaryKey);
out.println();
} else if (kotlin) {
out.print("%soverride fun getPrimaryKey(): %s<%s> = ", visibilityPublic(), UniqueKey.class, recordType);
if (keyFullId != null)
out.print("%s", keyFullId);
else
printCreateUniqueKey(out, primaryKey);
out.println();
} else {
out.overrideInherit();
printNonnullAnnotation(out);
out.println("%s%s<%s> getPrimaryKey() {", visibilityPublic(), UniqueKey.class, recordType);
out.print("return ");
if (keyFullId != null)
out.print("%s", keyFullId);
else
printCreateUniqueKey(out, primaryKey);
out.println(";");
out.println("}");
}
}
// The remaining unique keys
List<UniqueKeyDefinition> uniqueKeys = table.getUniqueKeys();
if (uniqueKeys.size() > 0) {
if (generateGlobalKeyReferences()) {
final List<String> keyFullIds = kotlin ? out.ref(getStrategy().getFullJavaIdentifiers(uniqueKeys)) : out.ref(getStrategy().getFullJavaIdentifiers(uniqueKeys), 2);
if (scala) {
out.println();
out.println("%soverride def getUniqueKeys: %s[ %s[%s] ] = %s.asList[ %s[%s] ]([[%s]])", visibilityPublic(), List.class, UniqueKey.class, recordType, Arrays.class, UniqueKey.class, recordType, keyFullIds);
} else if (kotlin) {
out.println("%soverride fun getUniqueKeys(): %s<%s<%s>> = listOf([[%s]])", visibilityPublic(), out.ref(KLIST), UniqueKey.class, recordType, keyFullIds);
} else {
out.overrideInherit();
printNonnullAnnotation(out);
out.println("%s%s<%s<%s>> getUniqueKeys() {", visibilityPublic(), List.class, UniqueKey.class, recordType);
out.println("return %s.asList([[%s]]);", Arrays.class, keyFullIds);
out.println("}");
}
} else {
if (scala) {
out.println();
out.println("%soverride def getUniqueKeys: %s[ %s[%s] ] = %s.asList[ %s[%s] ](", visibilityPublic(), List.class, UniqueKey.class, recordType, Arrays.class, UniqueKey.class, recordType);
forEach(uniqueKeys, "", ", ", (uniqueKey, separator) -> {
printCreateUniqueKey(out, uniqueKey);
out.println("%s", separator);
});
out.println(")");
} else if (kotlin) {
out.println("%soverride fun getUniqueKeys(): %s<%s<%s>> = listOf(", visibilityPublic(), out.ref(KLIST), UniqueKey.class, recordType);
forEach(uniqueKeys, "", ", ", (uniqueKey, separator) -> {
printCreateUniqueKey(out, uniqueKey);
out.println("%s", separator);
});
out.println(")");
} else {
out.overrideInherit();
printNonnullAnnotation(out);
out.println("%s%s<%s<%s>> getUniqueKeys() {", visibilityPublic(), List.class, UniqueKey.class, recordType);
out.println("return %s.asList(", Arrays.class);
forEach(uniqueKeys, "", ", ", (uniqueKey, separator) -> {
printCreateUniqueKey(out, uniqueKey);
out.println("%s", separator);
});
out.println(");");
out.println("}");
}
}
}
// Foreign keys
List<ForeignKeyDefinition> foreignKeys = table.getForeignKeys();
// [#7554] [#8028] Not yet supported with global key references turned off
if (foreignKeys.size() > 0 && generateGlobalKeyReferences()) {
final List<String> keyFullIds = kotlin ? out.ref(getStrategy().getFullJavaIdentifiers(foreignKeys)) : out.ref(getStrategy().getFullJavaIdentifiers(foreignKeys), 2);
if (scala) {
out.println();
out.println("%soverride def getReferences: %s[ %s[%s, _] ] = %s.asList[ %s[%s, _] ]([[%s]])", visibilityPublic(), List.class, ForeignKey.class, recordType, Arrays.class, ForeignKey.class, recordType, keyFullIds);
} else if (kotlin) {
out.println("%soverride fun getReferences(): %s<%s<%s, *>> = listOf([[%s]])", visibilityPublic(), out.ref(KLIST), ForeignKey.class, recordType, keyFullIds);
} else {
out.overrideInherit();
printNonnullAnnotation(out);
out.println("%s%s<%s<%s, ?>> getReferences() {", visibilityPublic(), List.class, ForeignKey.class, recordType);
out.println("return %s.asList([[%s]]);", Arrays.class, keyFullIds);
out.println("}");
}
// Outbound (to-one) implicit join paths
if (generateImplicitJoinPathsToOne()) {
if (scala) {
} else {
out.println();
// [#8762] Cache these calls for much improved runtime performance!
for (ForeignKeyDefinition foreignKey : foreignKeys) {
final String referencedTableClassName = out.ref(getStrategy().getFullJavaClassName(foreignKey.getReferencedTable()));
final String keyMethodName = out.ref(getStrategy().getJavaMethodName(foreignKey));
// [#13008] Prevent conflicts with the below leading underscore
final String unquotedKeyMethodName = keyMethodName.replace("`", "");
if (kotlin)
out.println("private lateinit var _%s: %s", unquotedKeyMethodName, referencedTableClassName);
else
out.println("private transient %s _%s;", referencedTableClassName, keyMethodName);
}
}
Map<TableDefinition, Long> pathCounts = foreignKeys.stream().collect(groupingBy(ForeignKeyDefinition::getReferencedTable, counting()));
for (ForeignKeyDefinition foreignKey : foreignKeys) {
final String keyFullId = kotlin ? out.ref(getStrategy().getFullJavaIdentifier(foreignKey)) : out.ref(getStrategy().getFullJavaIdentifier(foreignKey), 2);
final String referencedTableClassName = out.ref(getStrategy().getFullJavaClassName(foreignKey.getReferencedTable()));
final String keyMethodName = out.ref(getStrategy().getJavaMethodName(foreignKey));
final String unquotedKeyMethodName = keyMethodName.replace("`", "");
out.javadoc("Get the implicit join path to the <code>" + foreignKey.getReferencedTable().getQualifiedName() + "</code> table" + (pathCounts.get(foreignKey.getReferencedTable()) > 1 ? ", via the <code>" + foreignKey.getInputName() + "</code> key" : "") + ".");
if (scala) {
out.println("%slazy val %s: %s = { new %s(this, %s) }", visibility(), scalaWhitespaceSuffix(keyMethodName), referencedTableClassName, referencedTableClassName, keyFullId);
} else if (kotlin) {
out.println("%sfun %s(): %s {", visibility(), keyMethodName, referencedTableClassName);
out.println("if (!this::_%s.isInitialized)", unquotedKeyMethodName);
out.println("_%s = %s(this, %s)", unquotedKeyMethodName, referencedTableClassName, keyFullId);
out.println();
out.println("return _%s;", unquotedKeyMethodName);
out.println("}");
} else {
out.println("%s%s %s() {", visibility(), referencedTableClassName, keyMethodName);
out.println("if (_%s == null)", keyMethodName);
out.println("_%s = new %s(this, %s);", keyMethodName, referencedTableClassName, keyFullId);
out.println();
out.println("return _%s;", keyMethodName);
out.println("}");
}
}
}
}
}
List<CheckConstraintDefinition> cc = table.getCheckConstraints();
if (!cc.isEmpty()) {
if (scala) {
out.println("%soverride def getChecks: %s[ %s[%s] ] = %s.asList[ %s[%s] ](", visibilityPublic(), List.class, Check.class, recordType, Arrays.class, Check.class, recordType);
} else if (kotlin) {
out.println("%soverride fun getChecks(): %s<%s<%s>> = listOf(", visibilityPublic(), out.ref(KLIST), Check.class, recordType);
} else {
out.overrideInherit();
printNonnullAnnotation(out);
out.println("%s%s<%s<%s>> getChecks() {", visibilityPublic(), List.class, Check.class, recordType);
out.println("return %s.asList(", Arrays.class);
}
forEach(cc, (c, separator) -> {
out.println("%s.createCheck(this, %s.name(\"%s\"), \"%s\", %s)%s", Internal.class, DSL.class, escapeString(c.getName()), escapeString(c.getCheckClause()), c.enforced(), separator);
});
if (scala || kotlin) {
out.println(")");
} else {
out.println(");");
out.println("}");
}
}
// can still be generated
versionLoop: for (String pattern : database.getRecordVersionFields()) {
Pattern p = Pattern.compile(pattern, Pattern.COMMENTS);
for (ColumnDefinition column : table.getColumns()) {
if ((p.matcher(column.getName()).matches() || p.matcher(column.getQualifiedName()).matches())) {
final String columnTypeFull = getJavaType(column.getType(resolver(out)), out);
final String columnType = out.ref(columnTypeFull);
final String columnId = getStrategy().getJavaIdentifier(column);
if (scala) {
printDeprecationIfUnknownType(out, columnTypeFull);
out.println("%soverride def getRecordVersion: %s[%s, %s] = %s", visibilityPublic(), TableField.class, recordType, columnType, columnId);
} else if (kotlin) {
printDeprecationIfUnknownType(out, columnTypeFull);
out.println("%soverride fun getRecordVersion(): %s<%s, %s?> = %s", visibilityPublic(), TableField.class, recordType, columnType, columnId);
} else {
if (printDeprecationIfUnknownType(out, columnTypeFull))
out.override();
else
out.overrideInherit();
printNonnullAnnotation(out);
out.println("%s%s<%s, %s> getRecordVersion() {", visibilityPublic(), TableField.class, recordType, columnType);
out.println("return %s;", columnId);
out.println("}");
}
// Avoid generating this method twice
break versionLoop;
}
}
}
timestampLoop: for (String pattern : database.getRecordTimestampFields()) {
Pattern p = Pattern.compile(pattern, Pattern.COMMENTS);
for (ColumnDefinition column : table.getColumns()) {
if ((p.matcher(column.getName()).matches() || p.matcher(column.getQualifiedName()).matches())) {
final String columnTypeFull = getJavaType(column.getType(resolver(out)), out);
final String columnType = out.ref(columnTypeFull);
final String columnId = getStrategy().getJavaIdentifier(column);
if (scala) {
printDeprecationIfUnknownType(out, columnTypeFull);
out.println("%soverride def getRecordTimestamp: %s[%s, %s] = %s", visibilityPublic(), TableField.class, recordType, columnType, columnId);
} else if (kotlin) {
printDeprecationIfUnknownType(out, columnTypeFull);
out.println("%soverride fun getRecordTimestamp(): %s<%s, %s?> = %s", visibilityPublic(), TableField.class, recordType, columnType, columnId);
} else {
if (printDeprecationIfUnknownType(out, columnTypeFull))
out.override();
else
out.overrideInherit();
printNonnullAnnotation(out);
out.println("%s%s<%s, %s> getRecordTimestamp() {", visibilityPublic(), TableField.class, recordType, columnType);
out.println("return %s;", columnId);
out.println("}");
}
// Avoid generating this method twice
break timestampLoop;
}
}
}
if (scala) {
out.print("%soverride def as(alias: %s): %s = ", visibilityPublic(), String.class, className);
if (table.isTableValuedFunction())
out.println("new %s(%s.name(alias), null, null, this, parameters)", className, DSL.class);
else
out.println("new %s(%s.name(alias), this)", className, DSL.class);
out.print("%soverride def as(alias: %s): %s = ", visibilityPublic(), Name.class, className);
if (table.isTableValuedFunction())
out.println("new %s(alias, null, null, this, parameters)", className);
else
out.println("new %s(alias, this)", className);
} else if (kotlin) {
out.print("%soverride fun `as`(alias: %s): %s = ", visibilityPublic(), String.class, className);
if (table.isTableValuedFunction())
out.println("%s(%s.name(alias), this, parameters)", className, DSL.class);
else
out.println("%s(%s.name(alias), this)", className, DSL.class);
out.print("%soverride fun `as`(alias: %s): %s = ", visibilityPublic(), Name.class, className);
if (table.isTableValuedFunction())
out.println("%s(alias, this, parameters)", className);
else
out.println("%s(alias, this)", className);
} else // type-safe table alias
if (generateInstanceFields()) {
out.overrideInherit();
printNonnullAnnotation(out);
out.println("%s%s as(%s alias) {", visibilityPublic(), className, String.class);
if (table.isTableValuedFunction())
out.println("return new %s(%s.name(alias), this, parameters);", className, DSL.class);
else
out.println("return new %s(%s.name(alias), this);", className, DSL.class);
out.println("}");
out.overrideInherit();
printNonnullAnnotation(out);
out.println("%s%s as(%s alias) {", visibilityPublic(), className, Name.class);
if (table.isTableValuedFunction())
out.println("return new %s(alias, this, parameters);", className);
else
out.println("return new %s(alias, this);", className);
out.println("}");
}
if (scala) {
out.javadoc("Rename this table");
out.print("%soverride def rename(name: %s): %s = ", visibilityPublic(), String.class, className);
if (table.isTableValuedFunction())
out.println("new %s(%s.name(name), null, null, null, parameters)", className, DSL.class);
else
out.println("new %s(%s.name(name), null)", className, DSL.class);
out.javadoc("Rename this table");
out.print("%soverride def rename(name: %s): %s = ", visibilityPublic(), Name.class, className);
if (table.isTableValuedFunction())
out.println("new %s(name, null, null, null, parameters)", className);
else
out.println("new %s(name, null)", className);
} else if (kotlin) {
out.javadoc("Rename this table");
out.print("%soverride fun rename(name: %s): %s = ", visibilityPublic(), String.class, className);
if (table.isTableValuedFunction())
out.println("%s(%s.name(name), null, parameters)", className, DSL.class);
else
out.println("%s(%s.name(name), null)", className, DSL.class);
out.javadoc("Rename this table");
out.print("%soverride fun rename(name: %s): %s = ", visibilityPublic(), Name.class, className);
if (table.isTableValuedFunction())
out.println("%s(name, null, parameters)", className);
else
out.println("%s(name, null)", className);
} else // [#2921] With instance fields, tables can be renamed.
if (generateInstanceFields()) {
out.javadoc("Rename this table");
out.override();
printNonnullAnnotation(out);
out.println("%s%s rename(%s name) {", visibilityPublic(), className, String.class);
if (table.isTableValuedFunction())
out.println("return new %s(%s.name(name), null, parameters);", className, DSL.class);
else
out.println("return new %s(%s.name(name), null);", className, DSL.class);
out.println("}");
out.javadoc("Rename this table");
out.override();
printNonnullAnnotation(out);
out.println("%s%s rename(%s name) {", visibilityPublic(), className, Name.class);
if (table.isTableValuedFunction())
out.println("return new %s(name, null, parameters);", className);
else
out.println("return new %s(name, null);", className);
out.println("}");
}
// [#7809] fieldsRow()
// [#10481] Use the types from replaced embeddables if applicable
List<Definition> replacingEmbeddablesAndUnreplacedColumns = replacingEmbeddablesAndUnreplacedColumns(table);
int degree = replacingEmbeddablesAndUnreplacedColumns.size();
String rowType = refRowType(out, replacingEmbeddablesAndUnreplacedColumns);
String rowTypeContravariantJava = refRowType(out, replacingEmbeddablesAndUnreplacedColumns, s -> "? super " + s);
if (generateRecordsImplementingRecordN() && degree > 0 && degree <= Constants.MAX_ROW_DEGREE) {
final String rowNType = out.ref(Row.class.getName() + degree);
out.header("Row%s type methods", degree);
if (scala) {
out.println("%soverride def fieldsRow: %s[%s] = super.fieldsRow.asInstanceOf[ %s[%s] ]", visibilityPublic(), rowNType, rowType, rowNType, rowType);
} else if (kotlin) {
out.println("%soverride fun fieldsRow(): %s<%s> = super.fieldsRow() as %s<%s>", visibilityPublic(), rowNType, rowType, rowNType, rowType);
} else {
out.overrideInherit();
printNonnullAnnotation(out);
out.println("%s%s<%s> fieldsRow() {", visibilityPublic(), rowNType, rowType);
out.println("return (%s) super.fieldsRow();", rowNType);
out.println("}");
}
}
// [#1070] Table-valued functions should generate an additional set of call() methods
if (table.isTableValuedFunction()) {
for (boolean parametersAsField : new boolean[] { false, true }) {
// Don't overload no-args call() methods
if (parametersAsField && parameters.size() == 0)
break;
out.javadoc("Call this table-valued function");
if (scala) {
out.print("%sdef call(", visibility()).printlnIf(!parameters.isEmpty());
printParameterDeclarations(out, parameters, parametersAsField, " ");
out.print("): %s = ", className);
out.print("Option(new %s(%s.name(\"%s\"), null, null, null, %s(", className, DSL.class, escapeString(table.getOutputName()), out.ref("scala.Array")).printlnIf(!parameters.isEmpty());
forEach(parameters, (parameter, separator) -> {
final String paramArgName = getStrategy().getJavaMemberName(parameter);
final String paramTypeRef = getJavaTypeReference(parameter.getDatabase(), parameter.getType(resolver(out)), out);
final List<String> converter = out.ref(list(parameter.getType(resolver(out)).getConverter()));
final List<String> binding = out.ref(list(parameter.getType(resolver(out)).getBinding()));
if (parametersAsField)
out.println("%s%s", paramArgName, separator);
else
out.println("%s.value(%s, %s" + converterTemplateForTableValuedFunction(converter) + converterTemplateForTableValuedFunction(binding) + ")%s", DSL.class, paramArgName, paramTypeRef, converter, binding, separator);
});
out.println("))).map(r => if (aliased()) r.as(getUnqualifiedName) else r).get");
} else if (kotlin) {
out.print("%sfun call(", visibility()).printlnIf(!parameters.isEmpty());
printParameterDeclarations(out, parameters, parametersAsField, " ");
out.print("): %s = %s(%s.name(\"%s\"), null, arrayOf(", className, className, DSL.class, escapeString(table.getOutputName()), Field.class).printlnIf(!parameters.isEmpty());
forEach(parameters, (parameter, separator) -> {
final String paramArgName = getStrategy().getJavaMemberName(parameter);
final String paramTypeRef = getJavaTypeReference(parameter.getDatabase(), parameter.getType(resolver(out)), out);
final List<String> converter = out.ref(list(parameter.getType(resolver(out)).getConverter()));
final List<String> binding = out.ref(list(parameter.getType(resolver(out)).getBinding()));
if (parametersAsField)
out.println("%s%s", paramArgName, separator);
else
out.println("%s.value(%s, %s" + converterTemplateForTableValuedFunction(converter) + converterTemplateForTableValuedFunction(binding) + ")%s", DSL.class, paramArgName, paramTypeRef, converter, binding, separator);
});
out.println(")).let { if (aliased()) it.`as`(unqualifiedName) else it }");
} else {
out.print("%s%s call(", visibility(), className).printlnIf(!parameters.isEmpty());
printParameterDeclarations(out, parameters, parametersAsField, " ");
out.println(") {");
out.print("%s result = new %s(%s.name(\"%s\"), null, new %s[] {", className, className, DSL.class, escapeString(table.getOutputName()), Field.class).printlnIf(!parameters.isEmpty());
forEach(parameters, (parameter, separator) -> {
final String paramArgName = getStrategy().getJavaMemberName(parameter);
final String paramTypeRef = getJavaTypeReference(parameter.getDatabase(), parameter.getType(resolver(out)), out);
final List<String> converter = out.ref(list(parameter.getType(resolver(out)).getConverter()));
final List<String> binding = out.ref(list(parameter.getType(resolver(out)).getBinding()));
if (parametersAsField)
out.println("%s%s", paramArgName, separator);
else
out.println("%s.val(%s, %s" + converterTemplateForTableValuedFunction(converter) + converterTemplateForTableValuedFunction(binding) + ")%s", DSL.class, paramArgName, paramTypeRef, converter, binding, separator);
});
out.println("});");
out.println();
out.println("return aliased() ? result.as(getUnqualifiedName()) : result;");
out.println("}");
}
}
}
if (generateRecordsImplementingRecordN() && degree > 0 && degree <= Constants.MAX_ROW_DEGREE) {
out.javadoc("Convenience mapping calling {@link #convertFrom(%s)}.", Function.class);
if (scala) {
out.println("%sdef mapping[U](from: (" + rowType + ") => U): %s[U] = convertFrom(r => from.apply(" + rangeClosed(1, degree).mapToObj(i -> "r.value" + i + "()").collect(joining(", ")) + "))", visibility(), SelectField.class);
} else if (kotlin) {
out.println("%sfun <U> mapping(from: (" + rowType + ") -> U): %s<U> = convertFrom(%s.mapping(from))", visibility(), SelectField.class, Records.class);
} else {
out.println("%s<U> %s<U> mapping(%s<" + rowTypeContravariantJava + ", ? extends U> from) {", visibility(), SelectField.class, out.ref("org.jooq.Function" + degree));
out.println("return convertFrom(%s.mapping(from));", Records.class);
out.println("}");
}
out.javadoc("Convenience mapping calling {@link #convertFrom(%s, %s)}.", Class.class, Function.class);
if (scala) {
out.println("%sdef mapping[U](toType: %s[U], from: (" + rowType + ") => U): %s[U] = convertFrom(toType,r => from.apply(" + rangeClosed(1, degree).mapToObj(i -> "r.value" + i + "()").collect(joining(", ")) + "))", visibility(), Class.class, SelectField.class);
} else if (kotlin) {
out.println("%sfun <U> mapping(toType: %s<U>, from: (" + rowType + ") -> U): %s<U> = convertFrom(toType, %s.mapping(from))", visibility(), Class.class, SelectField.class, Records.class);
} else {
out.println("%s<U> %s<U> mapping(%s<U> toType, %s<" + rowTypeContravariantJava + ", ? extends U> from) {", visibility(), SelectField.class, Class.class, out.ref("org.jooq.Function" + degree));
out.println("return convertFrom(toType, %s.mapping(from));", Records.class);
out.println("}");
}
}
generateTableClassFooter(table, out);
out.println("}");
closeJavaWriter(out);
}
use of org.jooq.UniqueKey in project jOOQ by jOOQ.
the class JavaGenerator method generateRelations.
protected void generateRelations(SchemaDefinition schema) {
log.info("Generating Keys");
JavaWriter out = newJavaWriter(new File(getFile(schema).getParentFile(), "Keys.java"));
printPackage(out, schema);
printClassJavadoc(out, "A class modelling foreign key relationships between tables of the <code>" + schema.getOutputName() + "</code> schema");
printClassAnnotations(out, schema);
if (scala)
out.println("object Keys {");
else
out.println("public class Keys {");
out.tab(1).header("IDENTITY definitions");
out.println();
List<IdentityDefinition> allIdentities = new ArrayList<IdentityDefinition>();
List<UniqueKeyDefinition> allUniqueKeys = new ArrayList<UniqueKeyDefinition>();
List<ForeignKeyDefinition> allForeignKeys = new ArrayList<ForeignKeyDefinition>();
for (TableDefinition table : database.getTables(schema)) {
try {
IdentityDefinition identity = table.getIdentity();
if (identity != null) {
final String identityType = out.ref(getStrategy().getFullJavaClassName(identity.getColumn().getContainer(), Mode.RECORD));
final String columnType = out.ref(getJavaType(identity.getColumn().getType()));
final String identityId = getStrategy().getJavaIdentifier(identity.getColumn().getContainer());
final int block = allIdentities.size() / INITIALISER_SIZE;
if (scala)
out.tab(1).println("val IDENTITY_%s = Identities%s.IDENTITY_%s", identityId, block, identityId);
else
out.tab(1).println("public static final %s<%s, %s> IDENTITY_%s = Identities%s.IDENTITY_%s;", Identity.class, identityType, columnType, identityId, block, identityId);
allIdentities.add(identity);
}
} catch (Exception e) {
log.error("Error while generating table " + table, e);
}
}
// Unique keys
out.tab(1).header("UNIQUE and PRIMARY KEY definitions");
out.println();
for (TableDefinition table : database.getTables(schema)) {
try {
List<UniqueKeyDefinition> uniqueKeys = table.getUniqueKeys();
for (UniqueKeyDefinition uniqueKey : uniqueKeys) {
final String keyType = out.ref(getStrategy().getFullJavaClassName(uniqueKey.getTable(), Mode.RECORD));
final String keyId = getStrategy().getJavaIdentifier(uniqueKey);
final int block = allUniqueKeys.size() / INITIALISER_SIZE;
if (scala)
out.tab(1).println("val %s = UniqueKeys%s.%s", keyId, block, keyId);
else
out.tab(1).println("public static final %s<%s> %s = UniqueKeys%s.%s;", UniqueKey.class, keyType, keyId, block, keyId);
allUniqueKeys.add(uniqueKey);
}
} catch (Exception e) {
log.error("Error while generating table " + table, e);
}
}
// Foreign keys
out.tab(1).header("FOREIGN KEY definitions");
out.println();
for (TableDefinition table : database.getTables(schema)) {
try {
List<ForeignKeyDefinition> foreignKeys = table.getForeignKeys();
for (ForeignKeyDefinition foreignKey : foreignKeys) {
final String keyType = out.ref(getStrategy().getFullJavaClassName(foreignKey.getKeyTable(), Mode.RECORD));
final String referencedType = out.ref(getStrategy().getFullJavaClassName(foreignKey.getReferencedTable(), Mode.RECORD));
final String keyId = getStrategy().getJavaIdentifier(foreignKey);
final int block = allForeignKeys.size() / INITIALISER_SIZE;
if (scala)
out.tab(1).println("val %s = ForeignKeys%s.%s", keyId, block, keyId);
else
out.tab(1).println("public static final %s<%s, %s> %s = ForeignKeys%s.%s;", ForeignKey.class, keyType, referencedType, keyId, block, keyId);
allForeignKeys.add(foreignKey);
}
} catch (Exception e) {
log.error("Error while generating reference " + table, e);
}
}
// [#1459] Print nested classes for actual static field initialisations
// keeping top-level initialiser small
int identityCounter = 0;
int uniqueKeyCounter = 0;
int foreignKeyCounter = 0;
out.tab(1).header("[#1459] distribute members to avoid static initialisers > 64kb");
for (IdentityDefinition identity : allIdentities) {
printIdentity(out, identityCounter, identity);
identityCounter++;
}
if (identityCounter > 0) {
out.tab(1).println("}");
}
for (UniqueKeyDefinition uniqueKey : allUniqueKeys) {
printUniqueKey(out, uniqueKeyCounter, uniqueKey);
uniqueKeyCounter++;
}
if (uniqueKeyCounter > 0) {
out.tab(1).println("}");
}
for (ForeignKeyDefinition foreignKey : allForeignKeys) {
printForeignKey(out, foreignKeyCounter, foreignKey);
foreignKeyCounter++;
}
if (foreignKeyCounter > 0) {
out.tab(1).println("}");
}
out.println("}");
closeJavaWriter(out);
watch.splitInfo("Keys generated");
}
use of org.jooq.UniqueKey in project jOOQ by jOOQ.
the class InformationSchemaMetaImpl method init.
@SuppressWarnings({ "unchecked", "rawtypes" })
private final void init(InformationSchema meta) {
List<String> errors = new ArrayList<>();
// Catalogs
// -------------------------------------------------------------------------------------------------------------
boolean hasCatalogs = false;
for (org.jooq.util.xml.jaxb.Catalog xc : meta.getCatalogs()) {
InformationSchemaCatalog ic = new InformationSchemaCatalog(xc.getCatalogName(), xc.getComment());
catalogs.add(ic);
catalogsByName.put(name(xc.getCatalogName()), ic);
hasCatalogs = true;
}
// -------------------------------------------------------------------------------------------------------------
schemaLoop: for (org.jooq.util.xml.jaxb.Schema xs : meta.getSchemata()) {
// [#6662] This is kept for backwards compatibility reasons
if (!hasCatalogs) {
InformationSchemaCatalog ic = new InformationSchemaCatalog(xs.getCatalogName(), null);
if (!catalogs.contains(ic)) {
catalogs.add(ic);
catalogsByName.put(name(xs.getCatalogName()), ic);
}
}
Name catalogName = name(xs.getCatalogName());
Catalog catalog = catalogsByName.get(catalogName);
if (catalog == null) {
errors.add("Catalog " + catalogName + " not defined for schema " + xs.getSchemaName());
continue schemaLoop;
}
InformationSchemaSchema is = new InformationSchemaSchema(xs.getSchemaName(), catalog, xs.getComment());
schemas.add(is);
schemasByName.put(name(xs.getCatalogName(), xs.getSchemaName()), is);
}
// -------------------------------------------------------------------------------------------------------------
domainLoop: for (org.jooq.util.xml.jaxb.Domain d : meta.getDomains()) {
Name schemaName = name(d.getDomainCatalog(), d.getDomainSchema());
Schema schema = schemasByName.get(schemaName);
if (schema == null) {
errors.add("Schema " + schemaName + " not defined for domain " + d.getDomainName());
continue domainLoop;
}
Name domainName = name(d.getDomainCatalog(), d.getDomainSchema(), d.getDomainName());
int length = d.getCharacterMaximumLength() == null ? 0 : d.getCharacterMaximumLength();
int precision = d.getNumericPrecision() == null ? 0 : d.getNumericPrecision();
int scale = d.getNumericScale() == null ? 0 : d.getNumericScale();
// TODO [#10239] Support NOT NULL constraints
boolean nullable = true;
List<Check<?>> checks = new ArrayList<>();
for (org.jooq.util.xml.jaxb.DomainConstraint dc : meta.getDomainConstraints()) {
if (domainName.equals(name(dc.getDomainCatalog(), dc.getDomainSchema(), dc.getDomainName()))) {
Name constraintName = name(dc.getConstraintCatalog(), dc.getConstraintSchema(), dc.getConstraintName());
for (org.jooq.util.xml.jaxb.CheckConstraint cc : meta.getCheckConstraints()) if (constraintName.equals(name(cc.getConstraintCatalog(), cc.getConstraintSchema(), cc.getConstraintName())))
checks.add(new CheckImpl<>(null, constraintName, DSL.condition(cc.getCheckClause()), true));
}
}
InformationSchemaDomain<?> id = new InformationSchemaDomain<Object>(schema, name(d.getDomainName()), (DataType) type(d.getDataType(), length, precision, scale, nullable, false, null, null), checks.toArray(EMPTY_CHECK));
domains.add(id);
domainsByName.put(domainName, id);
}
// -------------------------------------------------------------------------------------------------------------
tableLoop: for (org.jooq.util.xml.jaxb.Table xt : meta.getTables()) {
Name schemaName = name(xt.getTableCatalog(), xt.getTableSchema());
Schema schema = schemasByName.get(schemaName);
if (schema == null) {
errors.add("Schema " + schemaName + " not defined for table " + xt.getTableName());
continue tableLoop;
}
TableType tableType;
switch(xt.getTableType()) {
case GLOBAL_TEMPORARY:
tableType = TableType.TEMPORARY;
break;
case VIEW:
tableType = TableType.VIEW;
break;
case BASE_TABLE:
default:
tableType = TableType.TABLE;
break;
}
String sql = null;
if (tableType == TableType.VIEW) {
viewLoop: for (org.jooq.util.xml.jaxb.View vt : meta.getViews()) {
if (StringUtils.equals(defaultIfNull(xt.getTableCatalog(), ""), defaultIfNull(vt.getTableCatalog(), "")) && StringUtils.equals(defaultIfNull(xt.getTableSchema(), ""), defaultIfNull(vt.getTableSchema(), "")) && StringUtils.equals(defaultIfNull(xt.getTableName(), ""), defaultIfNull(vt.getTableName(), ""))) {
sql = vt.getViewDefinition();
break viewLoop;
}
}
}
InformationSchemaTable it = new InformationSchemaTable(xt.getTableName(), schema, xt.getComment(), tableType, sql);
tables.add(it);
tablesByName.put(name(xt.getTableCatalog(), xt.getTableSchema(), xt.getTableName()), it);
}
// Columns
// -------------------------------------------------------------------------------------------------------------
List<Column> columns = new ArrayList<>(meta.getColumns());
columns.sort((o1, o2) -> {
Integer p1 = o1.getOrdinalPosition();
Integer p2 = o2.getOrdinalPosition();
if (Objects.equals(p1, p2))
return 0;
if (p1 == null)
return -1;
if (p2 == null)
return 1;
return p1.compareTo(p2);
});
columnLoop: for (Column xc : columns) {
String typeName = xc.getDataType();
int length = xc.getCharacterMaximumLength() == null ? 0 : xc.getCharacterMaximumLength();
int precision = xc.getNumericPrecision() == null ? 0 : xc.getNumericPrecision();
int scale = xc.getNumericScale() == null ? 0 : xc.getNumericScale();
boolean nullable = !FALSE.equals(xc.isIsNullable());
boolean readonly = TRUE.equals(xc.isReadonly());
Field<?> generatedAlwaysAs = TRUE.equals(xc.isIsGenerated()) ? DSL.field(xc.getGenerationExpression()) : null;
GenerationOption generationOption = TRUE.equals(xc.isIsGenerated()) ? "STORED".equalsIgnoreCase(xc.getGenerationOption()) ? STORED : "VIRTUAL".equalsIgnoreCase(xc.getGenerationOption()) ? VIRTUAL : null : null;
// TODO: Exception handling should be moved inside SQLDataType
Name tableName = name(xc.getTableCatalog(), xc.getTableSchema(), xc.getTableName());
InformationSchemaTable table = tablesByName.get(tableName);
if (table == null) {
errors.add("Table " + tableName + " not defined for column " + xc.getColumnName());
continue columnLoop;
}
AbstractTable.createField(name(xc.getColumnName()), type(typeName, length, precision, scale, nullable, readonly, generatedAlwaysAs, generationOption), table, xc.getComment());
}
// Indexes
// -------------------------------------------------------------------------------------------------------------
Map<Name, List<SortField<?>>> columnsByIndex = new HashMap<>();
List<IndexColumnUsage> indexColumnUsages = new ArrayList<>(meta.getIndexColumnUsages());
indexColumnUsages.sort(comparingInt(IndexColumnUsage::getOrdinalPosition));
indexColumnLoop: for (IndexColumnUsage ic : indexColumnUsages) {
Name indexName = name(ic.getIndexCatalog(), ic.getIndexSchema(), ic.getTableName(), ic.getIndexName());
List<SortField<?>> fields = columnsByIndex.computeIfAbsent(indexName, k -> new ArrayList<>());
Name tableName = name(ic.getTableCatalog(), ic.getTableSchema(), ic.getTableName());
InformationSchemaTable table = tablesByName.get(tableName);
if (table == null) {
errors.add("Table " + tableName + " not defined for index " + indexName);
continue indexColumnLoop;
}
TableField<Record, ?> field = (TableField<Record, ?>) table.field(ic.getColumnName());
if (field == null) {
errors.add("Column " + ic.getColumnName() + " not defined for table " + tableName);
continue indexColumnLoop;
}
fields.add(Boolean.TRUE.equals(ic.isIsDescending()) ? field.desc() : field.asc());
}
indexLoop: for (org.jooq.util.xml.jaxb.Index i : meta.getIndexes()) {
Name tableName = name(i.getTableCatalog(), i.getTableSchema(), i.getTableName());
Name indexName = name(i.getIndexCatalog(), i.getIndexSchema(), i.getTableName(), i.getIndexName());
InformationSchemaTable table = tablesByName.get(tableName);
if (table == null) {
errors.add("Table " + tableName + " not defined for index " + indexName);
continue indexLoop;
}
List<SortField<?>> c = columnsByIndex.get(indexName);
if (c == null || c.isEmpty()) {
errors.add("No columns defined for index " + indexName);
continue indexLoop;
}
IndexImpl index = (IndexImpl) Internal.createIndex(i.getIndexName(), table, c.toArray(EMPTY_SORTFIELD), Boolean.TRUE.equals(i.isIsUnique()));
table.indexes.add(index);
indexesByName.put(indexName, index);
}
// Constraints
// -------------------------------------------------------------------------------------------------------------
Map<Name, List<TableField<Record, ?>>> columnsByConstraint = new HashMap<>();
List<KeyColumnUsage> keyColumnUsages = new ArrayList<>(meta.getKeyColumnUsages());
keyColumnUsages.sort(comparing(KeyColumnUsage::getOrdinalPosition));
keyColumnLoop: for (KeyColumnUsage xc : keyColumnUsages) {
Name constraintName = name(xc.getConstraintCatalog(), xc.getConstraintSchema(), xc.getConstraintName());
List<TableField<Record, ?>> fields = columnsByConstraint.computeIfAbsent(constraintName, k -> new ArrayList<>());
Name tableName = name(xc.getTableCatalog(), xc.getTableSchema(), xc.getTableName());
InformationSchemaTable table = tablesByName.get(tableName);
if (table == null) {
errors.add("Table " + tableName + " not defined for constraint " + constraintName);
continue keyColumnLoop;
}
TableField<Record, ?> field = (TableField<Record, ?>) table.field(xc.getColumnName());
if (field == null) {
errors.add("Column " + xc.getColumnName() + " not defined for table " + tableName);
continue keyColumnLoop;
}
fields.add(field);
}
tableConstraintLoop: for (TableConstraint xc : meta.getTableConstraints()) {
switch(xc.getConstraintType()) {
case PRIMARY_KEY:
case UNIQUE:
{
Name tableName = name(xc.getTableCatalog(), xc.getTableSchema(), xc.getTableName());
Name constraintName = name(xc.getConstraintCatalog(), xc.getConstraintSchema(), xc.getConstraintName());
InformationSchemaTable table = tablesByName.get(tableName);
if (table == null) {
errors.add("Table " + tableName + " not defined for constraint " + constraintName);
continue tableConstraintLoop;
}
List<TableField<Record, ?>> c = columnsByConstraint.get(constraintName);
if (c == null || c.isEmpty()) {
errors.add("No columns defined for constraint " + constraintName);
continue tableConstraintLoop;
}
UniqueKeyImpl<Record> key = (UniqueKeyImpl<Record>) Internal.createUniqueKey(table, xc.getConstraintName(), c.toArray(new TableField[0]));
if (xc.getConstraintType() == PRIMARY_KEY) {
table.primaryKey = key;
primaryKeys.add(key);
} else
table.uniqueKeys.add(key);
keysByName.put(constraintName, key);
break;
}
}
}
for (ReferentialConstraint xr : meta.getReferentialConstraints()) {
referentialKeys.put(name(xr.getConstraintCatalog(), xr.getConstraintSchema(), xr.getConstraintName()), name(xr.getUniqueConstraintCatalog(), xr.getUniqueConstraintSchema(), xr.getUniqueConstraintName()));
}
tableConstraintLoop: for (TableConstraint xc : meta.getTableConstraints()) {
switch(xc.getConstraintType()) {
case FOREIGN_KEY:
{
Name tableName = name(xc.getTableCatalog(), xc.getTableSchema(), xc.getTableName());
Name constraintName = name(xc.getConstraintCatalog(), xc.getConstraintSchema(), xc.getConstraintName());
InformationSchemaTable table = tablesByName.get(tableName);
if (table == null) {
errors.add("Table " + tableName + " not defined for constraint " + constraintName);
continue tableConstraintLoop;
}
List<TableField<Record, ?>> c = columnsByConstraint.get(constraintName);
if (c == null || c.isEmpty()) {
errors.add("No columns defined for constraint " + constraintName);
continue tableConstraintLoop;
}
UniqueKeyImpl<Record> uniqueKey = keysByName.get(referentialKeys.get(constraintName));
if (uniqueKey == null) {
errors.add("No unique key defined for foreign key " + constraintName);
continue tableConstraintLoop;
}
ForeignKey<Record, Record> key = Internal.createForeignKey(uniqueKey, table, xc.getConstraintName(), c.toArray(new TableField[0]));
table.foreignKeys.add(key);
break;
}
}
}
tableConstraintLoop: for (TableConstraint xc : meta.getTableConstraints()) {
switch(xc.getConstraintType()) {
case CHECK:
{
Name tableName = name(xc.getTableCatalog(), xc.getTableSchema(), xc.getTableName());
Name constraintName = name(xc.getConstraintCatalog(), xc.getConstraintSchema(), xc.getConstraintName());
InformationSchemaTable table = tablesByName.get(tableName);
if (table == null) {
errors.add("Table " + tableName + " not defined for constraint " + constraintName);
continue tableConstraintLoop;
}
for (CheckConstraint cc : meta.getCheckConstraints()) {
if (constraintName.equals(name(cc.getConstraintCatalog(), cc.getConstraintSchema(), cc.getConstraintName()))) {
table.checks.add(new CheckImpl<>(table, constraintName, DSL.condition(cc.getCheckClause()), true));
continue tableConstraintLoop;
}
}
errors.add("No check clause found for check constraint " + constraintName);
continue tableConstraintLoop;
}
}
}
// -------------------------------------------------------------------------------------------------------------
sequenceLoop: for (org.jooq.util.xml.jaxb.Sequence xs : meta.getSequences()) {
Name schemaName = name(xs.getSequenceCatalog(), xs.getSequenceSchema());
Schema schema = schemasByName.get(schemaName);
if (schema == null) {
errors.add("Schema " + schemaName + " not defined for sequence " + xs.getSequenceName());
continue sequenceLoop;
}
String typeName = xs.getDataType();
int length = xs.getCharacterMaximumLength() == null ? 0 : xs.getCharacterMaximumLength();
int precision = xs.getNumericPrecision() == null ? 0 : xs.getNumericPrecision();
int scale = xs.getNumericScale() == null ? 0 : xs.getNumericScale();
boolean nullable = true;
BigInteger startWith = xs.getStartValue();
BigInteger incrementBy = xs.getIncrement();
BigInteger minvalue = xs.getMinimumValue();
BigInteger maxvalue = xs.getMaximumValue();
Boolean cycle = xs.isCycleOption();
BigInteger cache = xs.getCache();
InformationSchemaSequence is = new InformationSchemaSequence(xs.getSequenceName(), schema, type(typeName, length, precision, scale, nullable, false, null, null), startWith, incrementBy, minvalue, maxvalue, cycle, cache);
sequences.add(is);
}
// -------------------------------------------------------------------------------------------------------------
for (Schema s : schemas) initLookup(schemasPerCatalog, s.getCatalog(), s);
for (InformationSchemaDomain<?> d : domains) initLookup(domainsPerSchema, d.getSchema(), d);
for (InformationSchemaTable t : tables) initLookup(tablesPerSchema, t.getSchema(), t);
for (Sequence<?> q : sequences) initLookup(sequencesPerSchema, q.getSchema(), q);
if (!errors.isEmpty())
throw new IllegalArgumentException(errors.toString());
}
Aggregations