From 591afd7fcb3ad1796ed9b90c8331d5a46289af47 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Sun, 23 Jun 2013 13:50:07 +0200 Subject: [PATCH] [#2135] Postgres ENUM data type isn't supported correctly, if the ENUM needs full qualification --- .../jooq/util/DefaultGeneratorStrategy.java | 4 +-- .../java/org/jooq/util/JavaGenerator.java | 13 +++++++- jOOQ-test/src/org/jooq/test/PostgresTest.java | 32 +++++++++++++++++++ jOOQ/src/main/java/org/jooq/EnumType.java | 6 ++++ jOOQ/src/main/java/org/jooq/impl/Val.java | 19 +++++++++-- 5 files changed, 68 insertions(+), 6 deletions(-) diff --git a/jOOQ-codegen/src/main/java/org/jooq/util/DefaultGeneratorStrategy.java b/jOOQ-codegen/src/main/java/org/jooq/util/DefaultGeneratorStrategy.java index f76942029d..014947149f 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/util/DefaultGeneratorStrategy.java +++ b/jOOQ-codegen/src/main/java/org/jooq/util/DefaultGeneratorStrategy.java @@ -200,8 +200,8 @@ public class DefaultGeneratorStrategy extends AbstractGeneratorStrategy { private String getJavaClassName0(Definition definition, Mode mode) { StringBuilder result = new StringBuilder(); - String name = GenerationUtil.convertToJavaIdentifier(definition.getOutputName()); - result.append(StringUtils.toCamelCase(name)); + String cc = StringUtils.toCamelCase(definition.getOutputName()); + result.append(GenerationUtil.convertToJavaIdentifier(cc)); if (mode == Mode.RECORD) { result.append("Record"); diff --git a/jOOQ-codegen/src/main/java/org/jooq/util/JavaGenerator.java b/jOOQ-codegen/src/main/java/org/jooq/util/JavaGenerator.java index c0d3b69a03..1723735b76 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/util/JavaGenerator.java +++ b/jOOQ-codegen/src/main/java/org/jooq/util/JavaGenerator.java @@ -57,6 +57,7 @@ import org.jooq.Identity; import org.jooq.Parameter; import org.jooq.Record; import org.jooq.Row; +import org.jooq.Schema; import org.jooq.Sequence; import org.jooq.Table; import org.jooq.TableField; @@ -84,6 +85,7 @@ import org.jooq.tools.StringUtils; import org.jooq.tools.reflect.Reflect; import org.jooq.tools.reflect.ReflectException; import org.jooq.util.GeneratorStrategy.Mode; +import org.jooq.util.postgres.PostgresDatabase; /** @@ -980,9 +982,18 @@ public class JavaGenerator extends AbstractGenerator { out.tab(2).println("this.literal = literal;"); out.tab(1).println("}"); + // [#2135] Only the PostgreSQL database supports schema-scoped enum types + out.tab(1).overrideInherit(); + out.tab(1).println("public %s getSchema() {", Schema.class); + out.tab(2).println("return %s;", + (e.isSynthetic() || !(e.getDatabase() instanceof PostgresDatabase)) + ? "null" + : getStrategy().getFullJavaIdentifier(e.getSchema())); + out.tab(1).println("}"); + out.tab(1).overrideInherit(); out.tab(1).println("public java.lang.String getName() {"); - out.tab(2).println("return %s;", e.isSynthetic() ? "null" : "\"" + e.getName() + "\""); + out.tab(2).println("return %s;", e.isSynthetic() ? "null" : "\"" + e.getName().replace("\"", "\\\"") + "\""); out.tab(1).println("}"); out.tab(1).overrideInherit(); diff --git a/jOOQ-test/src/org/jooq/test/PostgresTest.java b/jOOQ-test/src/org/jooq/test/PostgresTest.java index f59590ab75..f782b1058c 100644 --- a/jOOQ-test/src/org/jooq/test/PostgresTest.java +++ b/jOOQ-test/src/org/jooq/test/PostgresTest.java @@ -71,6 +71,7 @@ import org.jooq.DSLContext; import org.jooq.DataType; import org.jooq.Field; import org.jooq.ForeignKey; +import org.jooq.Param; import org.jooq.Record; import org.jooq.Record1; import org.jooq.Result; @@ -78,6 +79,9 @@ import org.jooq.SQLDialect; import org.jooq.Table; import org.jooq.TableField; import org.jooq.UDTRecord; +import org.jooq.conf.MappedSchema; +import org.jooq.conf.RenderMapping; +import org.jooq.conf.RenderNameStyle; import org.jooq.conf.Settings; import org.jooq.impl.DSL; import org.jooq.test._.converters.Boolean_10; @@ -90,6 +94,7 @@ import org.jooq.test._.converters.Boolean_YN_UC; import org.jooq.test.postgres.generatedclasses.Keys; import org.jooq.test.postgres.generatedclasses.Routines; import org.jooq.test.postgres.generatedclasses.Sequences; +import org.jooq.test.postgres.generatedclasses.enums.UCountry; import org.jooq.test.postgres.generatedclasses.enums.U_959; import org.jooq.test.postgres.generatedclasses.tables.records.TArraysRecord; import org.jooq.test.postgres.generatedclasses.tables.records.TAuthorRecord; @@ -913,4 +918,31 @@ public class PostgresTest extends jOOQAbstractTest< assertEquals(uuid1, record.getValue(val).getU2()[0]); assertEquals(uuid2, record.getValue(val).getU2()[1]); } + + @Test + public void testPostgresEnumType() throws Exception { + // [#2549] TODO: Re-enable this + // Param val = val(UCountry.England); + Param val = val(UCountry.England, UAddressType.COUNTRY.getDataType()); + + // [#2135] Be sure that all settings are applied to explicit casts to + // PostgreSQL enum types + assertEquals("'England'", create().renderInlined(val)); + assertEquals("?::\"public\".\"u_country\"", + create().render(val)); + assertEquals("?::\"u_country\"", + create(new Settings().withRenderSchema(false)).render(val)); + assertEquals("?::PUBLIC.U_COUNTRY", + create(new Settings().withRenderNameStyle(RenderNameStyle.UPPER)).render(val)); + assertEquals("?::\"u_country\"", + create(new Settings().withRenderMapping( + new RenderMapping().withDefaultSchema("public"))).render(val)); + assertEquals("?::\"test\".\"u_country\"", + create(new Settings().withRenderMapping( + new RenderMapping().withSchemata( + new MappedSchema().withInput("public") + .withOutput("test")))).render(val)); + + + } } diff --git a/jOOQ/src/main/java/org/jooq/EnumType.java b/jOOQ/src/main/java/org/jooq/EnumType.java index 43c80408e0..4a5f3b0bb5 100644 --- a/jOOQ/src/main/java/org/jooq/EnumType.java +++ b/jOOQ/src/main/java/org/jooq/EnumType.java @@ -53,6 +53,12 @@ public interface EnumType { */ String getLiteral(); + /** + * The schema of the enum type, if applicable (Postgres schema-scope enum + * type only). Otherwise, this returns null + */ + Schema getSchema(); + /** * The type name as registered in the database, if applicable (Postgres * schema-scope enum type only). Otherwise, this returns null diff --git a/jOOQ/src/main/java/org/jooq/impl/Val.java b/jOOQ/src/main/java/org/jooq/impl/Val.java index f2233d7782..e065cc7519 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Val.java +++ b/jOOQ/src/main/java/org/jooq/impl/Val.java @@ -35,6 +35,7 @@ */ package org.jooq.impl; +import static java.lang.Boolean.TRUE; import static java.lang.Integer.toOctalString; import static java.util.Arrays.asList; import static org.jooq.SQLDialect.ASE; @@ -52,6 +53,8 @@ import static org.jooq.SQLDialect.SQLITE; import static org.jooq.SQLDialect.SQLSERVER; import static org.jooq.SQLDialect.SYBASE; import static org.jooq.conf.ParamType.NAMED; +import static org.jooq.impl.DSL.name; +import static org.jooq.impl.DSL.using; import static org.jooq.tools.StringUtils.leftPad; import java.math.BigDecimal; @@ -66,6 +69,7 @@ import org.jooq.DataType; import org.jooq.EnumType; import org.jooq.RenderContext; import org.jooq.SQLDialect; +import org.jooq.Schema; import org.jooq.UDTRecord; import org.jooq.tools.StringUtils; import org.jooq.types.Interval; @@ -522,10 +526,19 @@ class Val extends AbstractParam { context.sql(getBindVariable(context)); // [#968] Don't cast "synthetic" enum types (note, val can be null!) - String name = ((EnumType) type.getEnumConstants()[0]).getName(); - if (!StringUtils.isBlank(name)) { + EnumType e = (EnumType) type.getEnumConstants()[0]; + Schema schema = e.getSchema(); + + if (schema != null) { context.sql("::"); - context.literal(name); + + schema = using(context.configuration()).map(schema); + if (schema != null && TRUE.equals(context.configuration().settings().isRenderSchema())) { + context.sql(schema); + context.sql("."); + } + + context.sql(name(e.getName())); } }