From c1a4986a393fd6f900e7932b4bd53afcd4fcae33 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Thu, 6 Aug 2020 17:10:32 +0200 Subject: [PATCH] [jOOQ/jOOQ#681] Added code generator support for H2 domains --- .../codegen/AbstractGeneratorStrategy.java | 7 ++++ .../java/org/jooq/codegen/JavaGenerator.java | 42 +++++++++++++++---- .../org/jooq/meta/h2/H2TableDefinition.java | 14 ++++++- 3 files changed, 54 insertions(+), 9 deletions(-) diff --git a/jOOQ-codegen/src/main/java/org/jooq/codegen/AbstractGeneratorStrategy.java b/jOOQ-codegen/src/main/java/org/jooq/codegen/AbstractGeneratorStrategy.java index 9faa52552a..0d5fbddeb5 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/codegen/AbstractGeneratorStrategy.java +++ b/jOOQ-codegen/src/main/java/org/jooq/codegen/AbstractGeneratorStrategy.java @@ -46,6 +46,7 @@ import java.util.List; import org.jooq.meta.CatalogDefinition; import org.jooq.meta.ColumnDefinition; import org.jooq.meta.Definition; +import org.jooq.meta.DomainDefinition; import org.jooq.meta.ForeignKeyDefinition; import org.jooq.meta.IdentityDefinition; import org.jooq.meta.IndexDefinition; @@ -128,6 +129,12 @@ public abstract class AbstractGeneratorStrategy implements GeneratorStrategy { sb.append(".Sequences"); } + // Domains + else if (definition instanceof DomainDefinition) { + sb.append(getJavaPackageName(definition.getSchema())); + sb.append(".Domains"); + } + // Attributes, Parameters else if (definition instanceof TypedElementDefinition) { TypedElementDefinition e = (TypedElementDefinition) definition; diff --git a/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java b/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java index 0db0293c55..c9a56730e1 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java +++ b/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java @@ -75,6 +75,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.TimeZone; +import java.util.concurrent.Callable; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -118,6 +119,7 @@ import org.jooq.impl.DSL; import org.jooq.impl.DefaultDataType; import org.jooq.impl.EmbeddableRecordImpl; import org.jooq.impl.Internal; +import org.jooq.impl.LazySchema; import org.jooq.impl.PackageImpl; import org.jooq.impl.SQLDataType; import org.jooq.impl.SchemaImpl; @@ -2501,6 +2503,8 @@ public class JavaGenerator extends AbstractGenerator { log.info("Generating DOMAIN references"); JavaWriter out = newJavaWriter(new File(getFile(schema).getParentFile(), "Domains.java")); + final String schemaId = out.ref(getStrategy().getFullJavaIdentifier(schema), 2); + printPackage(out, schema); printClassJavadoc(out, "Convenience access to all Domains in " + schemaNameOrDefault(schema) + "."); printClassAnnotations(out, schema, Mode.DOMAIN); @@ -2512,7 +2516,6 @@ public class JavaGenerator extends AbstractGenerator { for (DomainDefinition domain : database.getDomains(schema)) { final String id = getStrategy().getJavaIdentifier(domain); - final String schemaId = out.ref(getStrategy().getFullJavaIdentifier(schema), 2); final String domainTypeFull = getJavaType(domain.getType(resolver())); final String domainType = out.ref(domainTypeFull); final String domainTypeRef = getJavaTypeReference(domain.getDatabase(), domain.getType(resolver())); @@ -2521,7 +2524,7 @@ public class JavaGenerator extends AbstractGenerator { if (scala) { out.println("val %s: %s[%s] = %s.createDomain(", id, Domain.class, domainType, Internal.class); - out.println(" %s", schemaId); + out.println(" schema"); out.println(", %s.name(\"%s\")", DSL.class, escapeString(domain.getOutputName())); out.println(", %s", domainTypeRef); @@ -2532,7 +2535,7 @@ public class JavaGenerator extends AbstractGenerator { } else if (kotlin) { out.println("val %s: %s<%s> = %s.createDomain(", id, Domain.class, domainType, Internal.class); - out.println(" %s", schemaId); + out.println(" schema()"); out.println(", %s.name(\"%s\")", DSL.class, escapeString(domain.getOutputName())); out.println(", %s", domainTypeRef); @@ -2543,7 +2546,7 @@ public class JavaGenerator extends AbstractGenerator { } else { out.println("public static final %s<%s> %s = %s.createDomain(", Domain.class, domainType, id, Internal.class); - out.println(" %s", schemaId); + out.println(" schema()"); out.println(", %s.name(\"%s\")", DSL.class, escapeString(domain.getOutputName())); out.println(", %s", domainTypeRef); @@ -2554,6 +2557,26 @@ public class JavaGenerator extends AbstractGenerator { } } + if (scala) { + out.println(); + out.println("private def schema: %s = new %s(%s.name(\"%s\"), %s.comment(\"\"), () => %s)", Schema.class, LazySchema.class, DSL.class, escapeString(schema.getOutputName()), DSL.class, schemaId); + } + else if (kotlin) { + out.println(); + out.println("private fun schema(): %s = %s(%s.name(\"%s\"), %s.comment(\"\"), %s { %s })", Schema.class, LazySchema.class, DSL.class, escapeString(schema.getOutputName()), DSL.class, Callable.class, schemaId); + } + else { + out.println(); + out.println("private static final %s schema() {", Schema.class); + out.println("return new %s(%s.name(\"%s\"), %s.comment(\"\"), new %s<%s>() {", LazySchema.class, DSL.class, escapeString(schema.getOutputName()), DSL.class, Callable.class, Schema.class); + out.override(); + out.println("public %s call() {", Schema.class); + out.println("return %s;", schemaId); + out.println("}"); + out.println("});"); + out.println("}"); + } + out.println("}"); closeJavaWriter(out); @@ -5390,10 +5413,10 @@ public class JavaGenerator extends AbstractGenerator { printClassAnnotations(out, schema, Mode.DEFAULT); if (scala) { - out.println("class %s extends %s(\"%s\", %s)[[before= with ][separator= with ][%s]] {", className, SchemaImpl.class, schema.getOutputName(), catalogId, interfaces); + out.println("class %s extends %s(\"%s\", %s)[[before= with ][separator= with ][%s]] {", className, SchemaImpl.class, escapeString(schema.getOutputName()), catalogId, interfaces); } else if (kotlin) { - out.println("class %s : %s(\"%s\", %s)[[before=, ][%s]] {", className, SchemaImpl.class, schema.getOutputName(), catalogId, interfaces); + out.println("class %s : %s(\"%s\", %s)[[before=, ][%s]] {", className, SchemaImpl.class, escapeString(schema.getOutputName()), catalogId, interfaces); out.println("companion object {"); out.javadoc("The reference instance of %s", schemaName); @@ -5444,7 +5467,7 @@ public class JavaGenerator extends AbstractGenerator { if (!scala && !kotlin) { out.javadoc(NO_FURTHER_INSTANCES_ALLOWED); out.println("private %s() {", className); - out.println("super(\"%s\", null);", schema.getOutputName()); + out.println("super(\"%s\", null);", escapeString(schema.getOutputName())); out.println("}"); } @@ -7255,6 +7278,7 @@ public class JavaGenerator extends AbstractGenerator { protected String getTypeReference(Database db, SchemaDefinition schema, String t, int p, int s, int l, boolean n, boolean i, String d, Name u) { StringBuilder sb = new StringBuilder(); + if (db.getArray(schema, u) != null) { ArrayDefinition array = database.getArray(schema, u); @@ -7263,6 +7287,10 @@ public class JavaGenerator extends AbstractGenerator { sb.append(classOf(getStrategy().getFullJavaClassName(array, Mode.RECORD))); sb.append(")"); } + else if (db.getDomain(schema, u) != null) { + sb.append(getStrategy().getFullJavaIdentifier(db.getDomain(schema, u))); + sb.append(".getDataType()"); + } else if (db.getUDT(schema, u) != null) { sb.append(getStrategy().getFullJavaIdentifier(db.getUDT(schema, u))); sb.append(".getDataType()"); diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/h2/H2TableDefinition.java b/jOOQ-meta/src/main/java/org/jooq/meta/h2/H2TableDefinition.java index 8c577ff230..52893282f1 100644 --- a/jOOQ-meta/src/main/java/org/jooq/meta/h2/H2TableDefinition.java +++ b/jOOQ-meta/src/main/java/org/jooq/meta/h2/H2TableDefinition.java @@ -51,6 +51,7 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.List; +import org.jooq.Name; import org.jooq.Param; import org.jooq.Record; import org.jooq.TableOptions.TableType; @@ -104,7 +105,10 @@ public class H2TableDefinition extends AbstractTableDefinition { COLUMNS.IS_NULLABLE, COLUMNS.COLUMN_DEFAULT, COLUMNS.REMARKS, - COLUMNS.SEQUENCE_NAME) + COLUMNS.SEQUENCE_NAME, + COLUMNS.DOMAIN_SCHEMA, + COLUMNS.DOMAIN_NAME + ) .from(COLUMNS) .where(COLUMNS.TABLE_SCHEMA.equal(getSchema().getName())) .and(COLUMNS.TABLE_NAME.equal(getName())) @@ -126,6 +130,11 @@ public class H2TableDefinition extends AbstractTableDefinition { // [#7644] H2 puts DATETIME_PRECISION in NUMERIC_SCALE column boolean isTimestamp = record.get(COLUMNS.TYPE_NAME).trim().toLowerCase().startsWith("timestamp"); + // [#681] Domain name if available + Name userType = record.get(COLUMNS.DOMAIN_NAME) != null + ? name(record.get(COLUMNS.DOMAIN_SCHEMA), record.get(COLUMNS.DOMAIN_NAME)) + : name(getSchema().getName(), getName() + "_" + record.get(COLUMNS.COLUMN_NAME)); + DataTypeDefinition type = new DefaultDataTypeDefinition( getDatabase(), getSchema(), @@ -139,7 +148,8 @@ public class H2TableDefinition extends AbstractTableDefinition { : record.get(COLUMNS.NUMERIC_SCALE), record.get(COLUMNS.IS_NULLABLE, boolean.class), isIdentity ? null : record.get(COLUMNS.COLUMN_DEFAULT), - name(getSchema().getName(), getName() + "_" + record.get(COLUMNS.COLUMN_NAME))); + userType + ); ColumnDefinition column = new DefaultColumnDefinition( getDatabase().getTable(getSchema(), getName()),