Search in sources :

Example 1 with UniqueKey

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");
    }
}
Also used : UniqueKeyDefinition(org.jooq.meta.UniqueKeyDefinition) ArrayList(java.util.ArrayList) ForeignKey(org.jooq.ForeignKey) IOException(java.io.IOException) SQLDialectNotSupportedException(org.jooq.exception.SQLDialectNotSupportedException) ReflectException(org.jooq.tools.reflect.ReflectException) CheckConstraintDefinition(org.jooq.meta.CheckConstraintDefinition) ConstraintDefinition(org.jooq.meta.ConstraintDefinition) ForeignKeyDefinition(org.jooq.meta.ForeignKeyDefinition) UniqueKey(org.jooq.UniqueKey)

Example 2 with UniqueKey

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);
}
Also used : RandomAccessFile(java.io.RandomAccessFile) Arrays(java.util.Arrays) TableRecordImpl(org.jooq.impl.TableRecordImpl) DSL(org.jooq.impl.DSL) SCALA(org.jooq.codegen.Language.SCALA) StringUtils.isBlank(org.jooq.tools.StringUtils.isBlank) Collectors.counting(java.util.stream.Collectors.counting) Internal(org.jooq.impl.Internal) POSTGRES(org.jooq.SQLDialect.POSTGRES) DatatypeConverter(jakarta.xml.bind.DatatypeConverter) AttributeDefinition(org.jooq.meta.AttributeDefinition) ColumnDefinition(org.jooq.meta.ColumnDefinition) RoutineDefinition(org.jooq.meta.RoutineDefinition) Matcher(java.util.regex.Matcher) IndexColumnDefinition(org.jooq.meta.IndexColumnDefinition) SelectField(org.jooq.SelectField) IdentityDefinition(org.jooq.meta.IdentityDefinition) Arrays.asList(java.util.Arrays.asList) Index(org.jooq.Index) Map(java.util.Map) BigInteger(java.math.BigInteger) SQLDialect(org.jooq.SQLDialect) Domain(org.jooq.Domain) Database(org.jooq.meta.Database) EmbeddableColumnDefinition(org.jooq.meta.EmbeddableColumnDefinition) CheckConstraintDefinition(org.jooq.meta.CheckConstraintDefinition) Set(java.util.Set) Constants(org.jooq.Constants) AggregateFunction(org.jooq.AggregateFunction) Result(org.jooq.Result) Collectors.joining(java.util.stream.Collectors.joining) GenerationOption(org.jooq.impl.QOM.GenerationOption) Stream(java.util.stream.Stream) TableField(org.jooq.TableField) SQLDataType(org.jooq.impl.SQLDataType) GeneratedAnnotationType(org.jooq.meta.jaxb.GeneratedAnnotationType) SequenceDefinition(org.jooq.meta.SequenceDefinition) Collectors.groupingBy(java.util.stream.Collectors.groupingBy) Parameter(org.jooq.Parameter) TableDefinition(org.jooq.meta.TableDefinition) CatalogImpl(org.jooq.impl.CatalogImpl) IndexDefinition(org.jooq.meta.IndexDefinition) Sequence(org.jooq.Sequence) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) Calendar(java.util.Calendar) Records(org.jooq.Records) Schema(org.jooq.Schema) BiConsumer(java.util.function.BiConsumer) RowId(org.jooq.RowId) LinkedHashSet(java.util.LinkedHashSet) MYSQL(org.jooq.SQLDialect.MYSQL) Record(org.jooq.Record) Mode(org.jooq.codegen.GeneratorStrategy.Mode) TypeVariable(java.lang.reflect.TypeVariable) IOException(java.io.IOException) StringUtils(org.jooq.tools.StringUtils) File(java.io.File) YUGABYTEDB(org.jooq.SQLDialect.YUGABYTEDB) VIRTUAL(org.jooq.impl.QOM.GenerationOption.VIRTUAL) SchemaDefinition(org.jooq.meta.SchemaDefinition) LazySupplier(org.jooq.impl.LazySupplier) TableImpl(org.jooq.impl.TableImpl) CatalogDefinition(org.jooq.meta.CatalogDefinition) UniqueKey(org.jooq.UniqueKey) Row(org.jooq.Row) IntStream.rangeClosed(java.util.stream.IntStream.rangeClosed) Time(java.sql.Time) Table(org.jooq.Table) DataTypeDefinition(org.jooq.meta.DataTypeDefinition) DAOImpl(org.jooq.impl.DAOImpl) PackageDefinition(org.jooq.meta.PackageDefinition) DefaultDataType(org.jooq.impl.DefaultDataType) UDT(org.jooq.UDT) PostgresDatabase(org.jooq.meta.postgres.PostgresDatabase) SortOrder(org.jooq.SortOrder) DataType(org.jooq.DataType) DSL.name(org.jooq.impl.DSL.name) IdentityHashMap(java.util.IdentityHashMap) JooqLogger(org.jooq.tools.JooqLogger) SQLDialectNotSupportedException(org.jooq.exception.SQLDialectNotSupportedException) Collections.nCopies(java.util.Collections.nCopies) TimeZone(java.util.TimeZone) Name(org.jooq.Name) Timestamp(java.sql.Timestamp) Collection(java.util.Collection) Check(org.jooq.Check) Field(org.jooq.Field) CloseResult(org.jooq.codegen.GeneratorWriter.CloseResult) PostgresRoutineDefinition(org.jooq.meta.postgres.PostgresRoutineDefinition) Collectors(java.util.stream.Collectors) UpdatableRecordImpl(org.jooq.impl.UpdatableRecordImpl) TypedElementDefinition(org.jooq.meta.TypedElementDefinition) JAVA(org.jooq.codegen.Language.JAVA) DomainDefinition(org.jooq.meta.DomainDefinition) Reflect(org.jooq.tools.reflect.Reflect) List(java.util.List) Modifier(java.lang.reflect.Modifier) Function.identity(java.util.function.Function.identity) Optional(java.util.Optional) Pattern(java.util.regex.Pattern) IntStream(java.util.stream.IntStream) UniqueKeyDefinition(org.jooq.meta.UniqueKeyDefinition) KOTLIN(org.jooq.codegen.Language.KOTLIN) UDTField(org.jooq.UDTField) DefaultDataTypeDefinition(org.jooq.meta.DefaultDataTypeDefinition) HashMap(java.util.HashMap) STORED(org.jooq.impl.QOM.GenerationOption.STORED) EnumType(org.jooq.EnumType) ForeignKey(org.jooq.ForeignKey) Function(java.util.function.Function) PackageImpl(org.jooq.impl.PackageImpl) Definition(org.jooq.meta.Definition) HashSet(java.util.HashSet) Identity(org.jooq.Identity) TableLike(org.jooq.TableLike) EmbeddableRecordImpl(org.jooq.impl.EmbeddableRecordImpl) EmbeddableDefinition(org.jooq.meta.EmbeddableDefinition) AbstractRoutine(org.jooq.impl.AbstractRoutine) Function2(org.jooq.Function2) ArrayDefinition(org.jooq.meta.ArrayDefinition) UDTDefinition(org.jooq.meta.UDTDefinition) AbstractTypedElementDefinition.getDataType(org.jooq.meta.AbstractTypedElementDefinition.getDataType) JavaTypeResolver(org.jooq.meta.JavaTypeResolver) ParameterDefinition(org.jooq.meta.ParameterDefinition) UDTRecordImpl(org.jooq.impl.UDTRecordImpl) ConstraintDefinition(org.jooq.meta.ConstraintDefinition) LazySchema(org.jooq.impl.LazySchema) DESC(org.jooq.SortOrder.DESC) SchemaImpl(org.jooq.impl.SchemaImpl) Date(java.sql.Date) ReflectException(org.jooq.tools.reflect.ReflectException) AbstractTypedElementDefinition(org.jooq.meta.AbstractTypedElementDefinition) Configuration(org.jooq.Configuration) Collectors.toList(java.util.stream.Collectors.toList) Catalog(org.jooq.Catalog) UDTImpl(org.jooq.impl.UDTImpl) StopWatch(org.jooq.tools.StopWatch) OrderField(org.jooq.OrderField) TableOptions(org.jooq.TableOptions) EnumDefinition(org.jooq.meta.EnumDefinition) ForeignKeyDefinition(org.jooq.meta.ForeignKeyDefinition) Collections(java.util.Collections) CheckConstraintDefinition(org.jooq.meta.CheckConstraintDefinition) Internal(org.jooq.impl.Internal) Schema(org.jooq.Schema) LazySchema(org.jooq.impl.LazySchema) TableImpl(org.jooq.impl.TableImpl) ArrayList(java.util.ArrayList) Check(org.jooq.Check) Index(org.jooq.Index) Name(org.jooq.Name) ForeignKeyDefinition(org.jooq.meta.ForeignKeyDefinition) SelectField(org.jooq.SelectField) TableField(org.jooq.TableField) Field(org.jooq.Field) UDTField(org.jooq.UDTField) OrderField(org.jooq.OrderField) TableOptions(org.jooq.TableOptions) IndexDefinition(org.jooq.meta.IndexDefinition) TableDefinition(org.jooq.meta.TableDefinition) Record(org.jooq.Record) Arrays.asList(java.util.Arrays.asList) ArrayList(java.util.ArrayList) List(java.util.List) Collectors.toList(java.util.stream.Collectors.toList) DSL(org.jooq.impl.DSL) Identity(org.jooq.Identity) Records(org.jooq.Records) Pattern(java.util.regex.Pattern) SchemaDefinition(org.jooq.meta.SchemaDefinition) Table(org.jooq.Table) EmbeddableColumnDefinition(org.jooq.meta.EmbeddableColumnDefinition) UniqueKeyDefinition(org.jooq.meta.UniqueKeyDefinition) SelectField(org.jooq.SelectField) IdentityDefinition(org.jooq.meta.IdentityDefinition) EmbeddableDefinition(org.jooq.meta.EmbeddableDefinition) AttributeDefinition(org.jooq.meta.AttributeDefinition) ColumnDefinition(org.jooq.meta.ColumnDefinition) RoutineDefinition(org.jooq.meta.RoutineDefinition) IndexColumnDefinition(org.jooq.meta.IndexColumnDefinition) IdentityDefinition(org.jooq.meta.IdentityDefinition) EmbeddableColumnDefinition(org.jooq.meta.EmbeddableColumnDefinition) CheckConstraintDefinition(org.jooq.meta.CheckConstraintDefinition) SequenceDefinition(org.jooq.meta.SequenceDefinition) TableDefinition(org.jooq.meta.TableDefinition) IndexDefinition(org.jooq.meta.IndexDefinition) SchemaDefinition(org.jooq.meta.SchemaDefinition) CatalogDefinition(org.jooq.meta.CatalogDefinition) DataTypeDefinition(org.jooq.meta.DataTypeDefinition) PackageDefinition(org.jooq.meta.PackageDefinition) PostgresRoutineDefinition(org.jooq.meta.postgres.PostgresRoutineDefinition) TypedElementDefinition(org.jooq.meta.TypedElementDefinition) DomainDefinition(org.jooq.meta.DomainDefinition) UniqueKeyDefinition(org.jooq.meta.UniqueKeyDefinition) DefaultDataTypeDefinition(org.jooq.meta.DefaultDataTypeDefinition) Definition(org.jooq.meta.Definition) EmbeddableDefinition(org.jooq.meta.EmbeddableDefinition) ArrayDefinition(org.jooq.meta.ArrayDefinition) UDTDefinition(org.jooq.meta.UDTDefinition) ParameterDefinition(org.jooq.meta.ParameterDefinition) ConstraintDefinition(org.jooq.meta.ConstraintDefinition) AbstractTypedElementDefinition(org.jooq.meta.AbstractTypedElementDefinition) EnumDefinition(org.jooq.meta.EnumDefinition) ForeignKeyDefinition(org.jooq.meta.ForeignKeyDefinition) ForeignKey(org.jooq.ForeignKey) TableField(org.jooq.TableField) ColumnDefinition(org.jooq.meta.ColumnDefinition) IndexColumnDefinition(org.jooq.meta.IndexColumnDefinition) EmbeddableColumnDefinition(org.jooq.meta.EmbeddableColumnDefinition) UniqueKey(org.jooq.UniqueKey) Arrays(java.util.Arrays) ParameterDefinition(org.jooq.meta.ParameterDefinition)

Example 3 with UniqueKey

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");
}
Also used : ArrayList(java.util.ArrayList) StringUtils.defaultString(org.jooq.tools.StringUtils.defaultString) ForeignKey(org.jooq.ForeignKey) SQLDialectNotSupportedException(org.jooq.exception.SQLDialectNotSupportedException) IOException(java.io.IOException) ReflectException(org.jooq.tools.reflect.ReflectException) UniqueKey(org.jooq.UniqueKey) Identity(org.jooq.Identity) RandomAccessFile(java.io.RandomAccessFile) File(java.io.File)

Example 4 with UniqueKey

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());
}
Also used : UniqueKey(org.jooq.UniqueKey) EMPTY_SORTFIELD(org.jooq.impl.Tools.EMPTY_SORTFIELD) Table(org.jooq.Table) HashMap(java.util.HashMap) STORED(org.jooq.impl.QOM.GenerationOption.STORED) ForeignKey(org.jooq.ForeignKey) Sequence(org.jooq.Sequence) ArrayList(java.util.ArrayList) InformationSchema(org.jooq.util.xml.jaxb.InformationSchema) Index(org.jooq.Index) Map(java.util.Map) Schema(org.jooq.Schema) BigInteger(java.math.BigInteger) Comparator.comparing(java.util.Comparator.comparing) KeyColumnUsage(org.jooq.util.xml.jaxb.KeyColumnUsage) EMPTY_CHECK(org.jooq.impl.Tools.EMPTY_CHECK) Domain(org.jooq.Domain) FALSE(java.lang.Boolean.FALSE) Record(org.jooq.Record) Comparator.comparingInt(java.util.Comparator.comparingInt) DataType(org.jooq.DataType) DSL.name(org.jooq.impl.DSL.name) SQLDialectNotSupportedException(org.jooq.exception.SQLDialectNotSupportedException) Collections.emptyList(java.util.Collections.emptyList) Name(org.jooq.Name) CheckConstraint(org.jooq.util.xml.jaxb.CheckConstraint) ReferentialConstraint(org.jooq.util.xml.jaxb.ReferentialConstraint) Check(org.jooq.Check) Field(org.jooq.Field) StringUtils(org.jooq.tools.StringUtils) PRIMARY_KEY(org.jooq.util.xml.jaxb.TableConstraintType.PRIMARY_KEY) GenerationOption(org.jooq.impl.QOM.GenerationOption) Objects(java.util.Objects) TableType(org.jooq.TableOptions.TableType) Configuration(org.jooq.Configuration) List(java.util.List) Catalog(org.jooq.Catalog) SortField(org.jooq.SortField) VIRTUAL(org.jooq.impl.QOM.GenerationOption.VIRTUAL) TableField(org.jooq.TableField) TableConstraint(org.jooq.util.xml.jaxb.TableConstraint) TableOptions(org.jooq.TableOptions) StringUtils.defaultIfNull(org.jooq.tools.StringUtils.defaultIfNull) IndexColumnUsage(org.jooq.util.xml.jaxb.IndexColumnUsage) TRUE(java.lang.Boolean.TRUE) Collections(java.util.Collections) Column(org.jooq.util.xml.jaxb.Column) HashMap(java.util.HashMap) InformationSchema(org.jooq.util.xml.jaxb.InformationSchema) Schema(org.jooq.Schema) ArrayList(java.util.ArrayList) Index(org.jooq.Index) Name(org.jooq.Name) KeyColumnUsage(org.jooq.util.xml.jaxb.KeyColumnUsage) GenerationOption(org.jooq.impl.QOM.GenerationOption) ArrayList(java.util.ArrayList) Collections.emptyList(java.util.Collections.emptyList) List(java.util.List) CheckConstraint(org.jooq.util.xml.jaxb.CheckConstraint) Sequence(org.jooq.Sequence) TableField(org.jooq.TableField) Catalog(org.jooq.Catalog) BigInteger(java.math.BigInteger) Domain(org.jooq.Domain) IndexColumnUsage(org.jooq.util.xml.jaxb.IndexColumnUsage) Field(org.jooq.Field) SortField(org.jooq.SortField) TableField(org.jooq.TableField) Column(org.jooq.util.xml.jaxb.Column) DataType(org.jooq.DataType) Record(org.jooq.Record) Table(org.jooq.Table) TableType(org.jooq.TableOptions.TableType) ReferentialConstraint(org.jooq.util.xml.jaxb.ReferentialConstraint) BigInteger(java.math.BigInteger) TableConstraint(org.jooq.util.xml.jaxb.TableConstraint)

Aggregations

ArrayList (java.util.ArrayList)4 ForeignKey (org.jooq.ForeignKey)4 UniqueKey (org.jooq.UniqueKey)4 SQLDialectNotSupportedException (org.jooq.exception.SQLDialectNotSupportedException)4 IOException (java.io.IOException)3 File (java.io.File)2 RandomAccessFile (java.io.RandomAccessFile)2 BigInteger (java.math.BigInteger)2 Collections (java.util.Collections)2 HashMap (java.util.HashMap)2 List (java.util.List)2 Map (java.util.Map)2 CheckConstraintDefinition (org.jooq.meta.CheckConstraintDefinition)2 ConstraintDefinition (org.jooq.meta.ConstraintDefinition)2 ForeignKeyDefinition (org.jooq.meta.ForeignKeyDefinition)2 UniqueKeyDefinition (org.jooq.meta.UniqueKeyDefinition)2 ReflectException (org.jooq.tools.reflect.ReflectException)2 DatatypeConverter (jakarta.xml.bind.DatatypeConverter)1 FALSE (java.lang.Boolean.FALSE)1 TRUE (java.lang.Boolean.TRUE)1