diff --git a/jOOQ-codegen/src/main/java/org/jooq/util/AbstractGenerator.java b/jOOQ-codegen/src/main/java/org/jooq/util/AbstractGenerator.java index a04bac7d5f..be39065ce5 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/util/AbstractGenerator.java +++ b/jOOQ-codegen/src/main/java/org/jooq/util/AbstractGenerator.java @@ -57,6 +57,7 @@ abstract class AbstractGenerator implements Generator { boolean generateInstanceFields = true; boolean generateGeneratedAnnotation = true; boolean useSchemaVersionProvider = false; + boolean useCatalogVersionProvider = false; boolean generateRecords = true; boolean generatePojos = false; boolean generatePojosEqualsAndHashCode = false; @@ -131,8 +132,9 @@ abstract class AbstractGenerator implements Generator { @Override public boolean generateGeneratedAnnotation() { - // [#3121] The schema version is generated into @Generated annotations - return generateGeneratedAnnotation || useSchemaVersionProvider; + // [#3121] [#4827] The schema and catalog versions are generated into + // @Generated annotations + return generateGeneratedAnnotation || useSchemaVersionProvider || useCatalogVersionProvider; } @Override @@ -150,6 +152,16 @@ abstract class AbstractGenerator implements Generator { this.useSchemaVersionProvider = useSchemaVersionProvider; } + @Override + public boolean useCatalogVersionProvider() { + return useCatalogVersionProvider; + } + + @Override + public void setUseCatalogVersionProvider(boolean useCatalogVersionProvider) { + this.useCatalogVersionProvider = useCatalogVersionProvider; + } + @Override public boolean generateRecords() { diff --git a/jOOQ-codegen/src/main/java/org/jooq/util/ConstantCatalogVersionProvider.java b/jOOQ-codegen/src/main/java/org/jooq/util/ConstantCatalogVersionProvider.java new file mode 100644 index 0000000000..aa95c74d01 --- /dev/null +++ b/jOOQ-codegen/src/main/java/org/jooq/util/ConstantCatalogVersionProvider.java @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2009-2015, Data Geekery GmbH (http://www.datageekery.com) + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Other licenses: + * ----------------------------------------------------------------------------- + * Commercial licenses for this work are available. These replace the above + * ASL 2.0 and offer limited warranties, support, maintenance, and commercial + * database integrations. + * + * For more information, please visit: http://www.jooq.org/licenses + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +package org.jooq.util; + +/** + * @author Lukas Eder + */ +class ConstantCatalogVersionProvider implements CatalogVersionProvider { + + private String constant; + + ConstantCatalogVersionProvider(String constant) { + this.constant = constant; + } + + @Override + public String version(CatalogDefinition catalog) { + return constant; + } +} diff --git a/jOOQ-codegen/src/main/java/org/jooq/util/GenerationTool.java b/jOOQ-codegen/src/main/java/org/jooq/util/GenerationTool.java index da4851a71d..31a7b49e43 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/util/GenerationTool.java +++ b/jOOQ-codegen/src/main/java/org/jooq/util/GenerationTool.java @@ -330,6 +330,7 @@ public class GenerationTool { database.setRegexFlags(d.getRegexFlags()); SchemaVersionProvider svp = null; + CatalogVersionProvider cvp = null; if (!StringUtils.isBlank(d.getSchemaVersionProvider())) { try { @@ -347,10 +348,29 @@ public class GenerationTool { } } + if (!StringUtils.isBlank(d.getCatalogVersionProvider())) { + try { + cvp = (CatalogVersionProvider) Class.forName(d.getCatalogVersionProvider()).newInstance(); + log.info("Using custom catalog version provider : " + cvp); + } + catch (Exception ignore) { + if (d.getCatalogVersionProvider().toLowerCase().startsWith("select")) { + cvp = new SQLCatalogVersionProvider(connection, d.getCatalogVersionProvider()); + log.info("Using SQL catalog version provider : " + d.getCatalogVersionProvider()); + } + else { + cvp = new ConstantCatalogVersionProvider(d.getCatalogVersionProvider()); + } + } + } + if (svp == null) svp = new ConstantSchemaVersionProvider(null); + if (cvp == null) + cvp = new ConstantCatalogVersionProvider(null); database.setSchemaVersionProvider(svp); + database.setCatalogVersionProvider(cvp); if (d.getEnumTypes().size() > 0) log.warn("DEPRECATED", "The configuration property /configuration/generator/database/enumTypes is experimental and deprecated and will be removed in the future."); @@ -426,6 +446,8 @@ public class GenerationTool { g.setDatabase(new org.jooq.util.jaxb.Database()); if (!StringUtils.isBlank(g.getDatabase().getSchemaVersionProvider())) generator.setUseSchemaVersionProvider(true); + if (!StringUtils.isBlank(g.getDatabase().getCatalogVersionProvider())) + generator.setUseCatalogVersionProvider(true); // Generator properties that should in fact be strategy properties strategy.setInstanceFields(generator.generateInstanceFields()); diff --git a/jOOQ-codegen/src/main/java/org/jooq/util/Generator.java b/jOOQ-codegen/src/main/java/org/jooq/util/Generator.java index ab28bc449e..7fb0c45621 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/util/Generator.java +++ b/jOOQ-codegen/src/main/java/org/jooq/util/Generator.java @@ -107,6 +107,8 @@ public interface Generator { boolean useSchemaVersionProvider(); void setUseSchemaVersionProvider(boolean useSchemaVersionProvider); + boolean useCatalogVersionProvider(); + void setUseCatalogVersionProvider(boolean useCatalogVersionProvider); /** * Whether TableRecords should be generated in addition to tables 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 cfbf1bb31b..45b405cd06 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/util/JavaGenerator.java +++ b/jOOQ-codegen/src/main/java/org/jooq/util/JavaGenerator.java @@ -162,7 +162,12 @@ public class JavaGenerator extends AbstractGenerator { private String isoDate; /** - * The cached catalog version numbers + * The cached schema version numbers. + */ + private Map schemaVersions; + + /** + * The cached catalog version numbers. */ private Map catalogVersions; @@ -188,6 +193,7 @@ public class JavaGenerator extends AbstractGenerator { @Override public final void generate(Database db) { this.isoDate = DatatypeConverter.printDateTime(Calendar.getInstance(TimeZone.getTimeZone("UTC"))); + this.schemaVersions = new LinkedHashMap(); this.catalogVersions = new LinkedHashMap(); this.database = db; @@ -223,7 +229,8 @@ public class JavaGenerator extends AbstractGenerator { log.info(" strategy", strategy.delegate.getClass()); log.info(" deprecated", generateDeprecated()); log.info(" generated annotation", generateGeneratedAnnotation() - + ((!generateGeneratedAnnotation && useSchemaVersionProvider) ? " (forced to true because of )" : "")); + + ((!generateGeneratedAnnotation && (useSchemaVersionProvider || useCatalogVersionProvider)) ? + " (forced to true because of or )" : "")); log.info(" JPA annotations", generateJPAAnnotations()); log.info(" validation annotations", generateValidationAnnotations()); log.info(" instance fields", generateInstanceFields()); @@ -274,6 +281,27 @@ public class JavaGenerator extends AbstractGenerator { } private final void generate(CatalogDefinition catalog) { + String newVersion = catalog.getDatabase().getCatalogVersionProvider().version(catalog); + + if (StringUtils.isBlank(newVersion)) { + log.info("No schema version is applied for catalog " + catalog.getInputName() + ". Regenerating."); + } + else { + catalogVersions.put(catalog, newVersion); + String oldVersion = readVersion(getStrategy().getFile(catalog), "catalog"); + + if (StringUtils.isBlank(oldVersion)) { + log.info("No previous version available for catalog " + catalog.getInputName() + ". Regenerating."); + } + else if (!oldVersion.equals(newVersion)) { + log.info("Existing version " + oldVersion + " is not up to date with " + newVersion + " for catalog " + catalog.getInputName() + ". Regenerating."); + } + else { + log.info("Existing version " + oldVersion + " is up to date with " + newVersion + " for catalog " + catalog.getInputName() + ". Ignoring catalog."); + return; + } + } + generateCatalog(catalog); log.info("Generating schemata", "Total: " + catalog.getSchemata().size()); @@ -294,8 +322,8 @@ public class JavaGenerator extends AbstractGenerator { log.info("No schema version is applied for schema " + schema.getInputName() + ". Regenerating."); } else { - catalogVersions.put(schema.getCatalog(), newVersion); - String oldVersion = readVersion(getStrategy().getFile(schema)); + schemaVersions.put(schema, newVersion); + String oldVersion = readVersion(getStrategy().getFile(schema), "schema"); if (StringUtils.isBlank(oldVersion)) { log.info("No previous version available for schema " + schema.getInputName() + ". Regenerating."); @@ -453,7 +481,7 @@ public class JavaGenerator extends AbstractGenerator { xxxxxxxxxx xxx x xxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxx xxxxxxxx xxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxx xxxxxx xx xxx xxxxxx xx x x xxxxxxxxxxxxxxxxxxxxxxxx - xxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxx xx xxxxxxx xxxxxxxxxxxxxxxxxxx xxxxxx xxxx @@ -490,7 +518,7 @@ public class JavaGenerator extends AbstractGenerator { xxxxxxxxxx xxx x xxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxx xxxxxxxx xxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxx xxxxxx xx xxx xxxxxxxx xxxxx xx x x xxxxxxxxxxxxxxxxxxxxxxxx - xxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxx xx xxxxxxx xxxxxxxxxxxxxxxxxxx xxxxx xxxx @@ -534,7 +562,7 @@ public class JavaGenerator extends AbstractGenerator { printPackage(out, schema); printClassJavadoc(out, "A class modelling foreign key relationships between tables of the " + schema.getOutputName() + " schema"); - printClassAnnotations(out, schema.getCatalog()); + printClassAnnotations(out, schema); if (scala) out.println("object Keys {"); @@ -837,7 +865,7 @@ public class JavaGenerator extends AbstractGenerator { else generateUDTRecordClassJavadoc((UDTDefinition) tableOrUdt, out); - printClassAnnotations(out, tableOrUdt.getSchema().getCatalog()); + printClassAnnotations(out, tableOrUdt.getSchema()); if (tableOrUdt instanceof TableDefinition) printTableJPAAnnotation(out, (TableDefinition) tableOrUdt); @@ -1312,7 +1340,7 @@ public class JavaGenerator extends AbstractGenerator { else generateUDTInterfaceClassJavadoc((UDTDefinition) tableOrUDT, out); - printClassAnnotations(out, tableOrUDT.getSchema().getCatalog()); + printClassAnnotations(out, tableOrUDT.getSchema()); if (tableOrUDT instanceof TableDefinition) printTableJPAAnnotation(out, (TableDefinition) tableOrUDT); @@ -1419,7 +1447,6 @@ public class JavaGenerator extends AbstractGenerator { } protected void generateUDT(UDTDefinition udt, JavaWriter out) { - final CatalogDefinition catalog = udt.getCatalog(); final SchemaDefinition schema = udt.getSchema(); final String className = getStrategy().getJavaClassName(udt); final String recordType = out.ref(getStrategy().getFullJavaClassName(udt, Mode.RECORD)); @@ -1446,7 +1473,7 @@ public class JavaGenerator extends AbstractGenerator { } generateUDTClassJavadoc(udt, out); - printClassAnnotations(out, catalog); + printClassAnnotations(out, schema); // [#799] Oracle UDTs with member procedures have similarities with packages if (udt.getRoutines().size() > 0) { @@ -1663,7 +1690,7 @@ public class JavaGenerator extends AbstractGenerator { printPackage(out, schema); printClassJavadoc(out, "Convenience access to all UDTs in " + schema.getOutputName()); - printClassAnnotations(out, schema.getCatalog()); + printClassAnnotations(out, schema); if (scala) out.println("object UDTs {"); @@ -1715,7 +1742,6 @@ public class JavaGenerator extends AbstractGenerator { protected void generateArray(ArrayDefinition array, JavaWriter out) { /* [pro] xx xxxxx xxxxxxxxxxxxxxxx xxxxxx x xxxxxxxxxxxxxxxxxx - xxxxx xxxxxxxxxxxxxxxxx xxxxxxx x xxxxxxxxxxxxxxxxxxx xxxxx xxxxxx xxxxxxxxx x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxx xxxxx xxxxxx xxxxxxxxxxx x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxx xxxxxx xxxxxxxxxxxxxx x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxx @@ -1729,7 +1755,7 @@ public class JavaGenerator extends AbstractGenerator { xxxxxxxxxxxxxxxxx xxxxxx xxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxx - xxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxx xx xxxxxxx xxxxxxxxxxxxxxxxxx xx xxxxxxx xxxxxxxxxx xxxxxxx xxxxxxxxxxxx xxxxx xxxxxxxxxxxxxxxx xxxx xxxxxxxxxxxx xxxx xxxxxx xxx @@ -1863,7 +1889,7 @@ public class JavaGenerator extends AbstractGenerator { printPackage(out, e); generateEnumClassJavadoc(e, out); - printClassAnnotations(out, e.getSchema().getCatalog()); + printClassAnnotations(out, e.getSchema()); interfaces.add(out.ref(EnumType.class)); @@ -1942,7 +1968,7 @@ public class JavaGenerator extends AbstractGenerator { printPackage(out, d); generateDomainClassJavadoc(d, out); - printClassAnnotations(out, d.getSchema().getCatalog()); + printClassAnnotations(out, d.getSchema()); for (String clause : d.getCheckClauses()) out.println("// " + clause); @@ -1972,7 +1998,7 @@ public class JavaGenerator extends AbstractGenerator { JavaWriter out = newJavaWriter(new File(getStrategy().getFile(schema).getParentFile(), "Routines.java")); printPackage(out, schema); printClassJavadoc(out, "Convenience access to all stored procedures and functions in " + schema.getOutputName()); - printClassAnnotations(out, schema.getCatalog()); + printClassAnnotations(out, schema); if (scala) out.println("object Routines {"); @@ -2081,7 +2107,6 @@ public class JavaGenerator extends AbstractGenerator { xxxxxxxxx xxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxx xxxxxxxxxx xxxx x xx xxxxx xx xxxxx xxxxxxxxxxxxxxxx xxxxxx x xxxxxxxxxxxxxxxx - xxxxx xxxxxxxxxxxxxxxxx xxxxxxx x xxxxxxxxxxxxxxxxx xxxxx xxxxxx xxxxxxxxx x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxx xxxxxx xxxxxxxxxx x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxx xxxxxx xxxxxxxxxxxxxxxx x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxx @@ -2090,7 +2115,7 @@ public class JavaGenerator extends AbstractGenerator { xx xxxxxx xxxxxxxxxxx xxxxxxx xxxxxxxxxxxxxxxxx xxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxx - xxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxx xx xxxxxxx x xxxxxxxxxxxxxxxxxxx xx xxxxxxx xxxxxxxxxx xxxxxxxxxxxx xxxx xxxxxxxxxxxx xxxx xxxxxx xxx xxxxxxxxxx xxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxx xxxxxxxxxxxx @@ -2155,7 +2180,7 @@ public class JavaGenerator extends AbstractGenerator { printPackage(out, schema); printClassJavadoc(out, "Convenience access to all tables in " + schema.getOutputName()); - printClassAnnotations(out, schema.getCatalog()); + printClassAnnotations(out, schema); if (scala) out.println("object Tables {"); @@ -2255,7 +2280,7 @@ public class JavaGenerator extends AbstractGenerator { printPackage(out, table, Mode.DAO); generateDaoClassJavadoc(table, out); - printClassAnnotations(out, table.getSchema().getCatalog()); + printClassAnnotations(out, table.getSchema()); if (generateSpringAnnotations()) out.println("@%s", out.ref("org.springframework.stereotype.Repository")); @@ -2454,7 +2479,7 @@ public class JavaGenerator extends AbstractGenerator { else generateUDTPojoClassJavadoc((UDTDefinition) tableOrUDT, out); - printClassAnnotations(out, tableOrUDT.getSchema().getCatalog()); + printClassAnnotations(out, tableOrUDT.getSchema()); if (tableOrUDT instanceof TableDefinition) printTableJPAAnnotation(out, (TableDefinition) tableOrUDT); @@ -2947,7 +2972,6 @@ public class JavaGenerator extends AbstractGenerator { protected void generateTable(TableDefinition table, JavaWriter out) { final SchemaDefinition schema = table.getSchema(); - final CatalogDefinition catalog = table.getCatalog(); final UniqueKeyDefinition primaryKey = table.getPrimaryKey(); final boolean updatable = generateRelations() && primaryKey != null; @@ -2976,7 +3000,7 @@ public class JavaGenerator extends AbstractGenerator { } generateTableClassJavadoc(table, out); - printClassAnnotations(out, catalog); + printClassAnnotations(out, schema); if (scala) { out.println("class %s(alias : String, aliased : %s[%s], parameters : Array[ %s[_] ]) extends %s[%s](alias, %s, aliased, parameters, \"%s\")[[before= with ][separator= with ][%s]] {", @@ -3343,7 +3367,7 @@ public class JavaGenerator extends AbstractGenerator { printPackage(out, schema); printClassJavadoc(out, "Convenience access to all sequences in " + schema.getOutputName()); - printClassAnnotations(out, schema.getCatalog()); + printClassAnnotations(out, schema); if (scala) out.println("object Sequences {"); @@ -3397,7 +3421,7 @@ public class JavaGenerator extends AbstractGenerator { } generateCatalogClassJavadoc(catalog, out); - printClassAnnotations(out, catalog); + printClassAnnotations(out, null, catalog); if (scala) { out.println("class %s extends %s(\"%s\")[[before= with ][separator= with ][%s]] {", className, CatalogImpl.class, catalog.getOutputName(), interfaces); @@ -3459,7 +3483,7 @@ public class JavaGenerator extends AbstractGenerator { } generateSchemaClassJavadoc(schema, out); - printClassAnnotations(out, schema.getCatalog()); + printClassAnnotations(out, schema); if (scala) { out.println("class %s extends %s(\"%s\", %s)[[before= with ][separator= with ][%s]] {", className, SchemaImpl.class, schema.getOutputName(), catalogId, interfaces); @@ -3723,7 +3747,6 @@ public class JavaGenerator extends AbstractGenerator { } protected void generateRoutine(RoutineDefinition routine, JavaWriter out) { - final CatalogDefinition catalog = routine.getCatalog(); final SchemaDefinition schema = routine.getSchema(); final String className = getStrategy().getJavaClassName(routine); final String returnType = (routine.getReturnValue() == null) @@ -3771,7 +3794,7 @@ public class JavaGenerator extends AbstractGenerator { } generateRoutineClassJavadoc(routine, out); - printClassAnnotations(out, catalog); + printClassAnnotations(out, schema); if (scala) { out.println("class %s extends %s[%s](\"%s\", %s[[before=, ][%s]][[before=, ][%s]][[before=, ][new %s()]])[[before= with ][separator= with ][%s]] {", @@ -4385,11 +4408,15 @@ public class JavaGenerator extends AbstractGenerator { out.println(" */"); } - protected void printClassAnnotations(JavaWriter out, CatalogDefinition catalog) { + protected void printClassAnnotations(JavaWriter out, SchemaDefinition schema) { + printClassAnnotations(out, schema, schema.getCatalog()); + } + + protected void printClassAnnotations(JavaWriter out, SchemaDefinition schema, CatalogDefinition catalog) { if (generateGeneratedAnnotation()) { out.println("@%s(", out.ref("javax.annotation.Generated")); - if (useSchemaVersionProvider()) { + if (useSchemaVersionProvider() || useCatalogVersionProvider()) { if (scala) out.tab(1).println("value = Array("); else @@ -4397,7 +4424,11 @@ public class JavaGenerator extends AbstractGenerator { out.tab(2).println("\"http://www.jooq.org\","); out.tab(2).println("\"jOOQ version:%s\",", Constants.VERSION); - out.tab(2).println("\"catalog version:%s\"", catalogVersions.get(catalog).replace("\"", "\\\"")); + + if (!StringUtils.isBlank(catalogVersions.get(catalog))) + out.tab(2).println("\"catalog version:%s\",", catalogVersions.get(catalog).replace("\"", "\\\"")); + if (!StringUtils.isBlank(schemaVersions.get(schema))) + out.tab(2).println("\"schema version:%s\",", schemaVersions.get(schema).replace("\"", "\\\"")); if (scala) out.tab(1).println("),"); @@ -4431,7 +4462,7 @@ public class JavaGenerator extends AbstractGenerator { out.println("@%s({ \"all\", \"unchecked\", \"rawtypes\" })", out.ref("java.lang.SuppressWarnings")); } - private final String readVersion(File file) { + private final String readVersion(File file, String type) { String result = null; try { @@ -4442,7 +4473,7 @@ public class JavaGenerator extends AbstractGenerator { f.readFully(bytes); String string = new String(bytes); - Matcher matcher = Pattern.compile("@(?:javax\\.annotation\\.)?Generated\\(\\s*?value\\s*?=\\s*?\\{[^}]*?\"schema version:([^\"]*?)\"").matcher(string); + Matcher matcher = Pattern.compile("@(?:javax\\.annotation\\.)?Generated\\(\\s*?value\\s*?=\\s*?\\{[^}]*?\"" + type + " version:([^\"]*?)\"").matcher(string); if (matcher.find()) { result = matcher.group(1); } diff --git a/jOOQ-codegen/src/main/java/org/jooq/util/SQLCatalogVersionProvider.java b/jOOQ-codegen/src/main/java/org/jooq/util/SQLCatalogVersionProvider.java new file mode 100644 index 0000000000..6400fb41eb --- /dev/null +++ b/jOOQ-codegen/src/main/java/org/jooq/util/SQLCatalogVersionProvider.java @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2009-2015, Data Geekery GmbH (http://www.datageekery.com) + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Other licenses: + * ----------------------------------------------------------------------------- + * Commercial licenses for this work are available. These replace the above + * ASL 2.0 and offer limited warranties, support, maintenance, and commercial + * database integrations. + * + * For more information, please visit: http://www.jooq.org/licenses + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +package org.jooq.util; + +import static org.jooq.conf.StatementType.STATIC_STATEMENT; +import static org.jooq.impl.DSL.param; + +import java.sql.Connection; + +import org.jooq.conf.Settings; +import org.jooq.impl.DSL; +import org.jooq.impl.DefaultConfiguration; + +/** + * @author Lukas Eder + */ +class SQLCatalogVersionProvider implements CatalogVersionProvider { + + private Connection connection; + private String sql; + + SQLCatalogVersionProvider(Connection connection, String sql) { + this.connection = connection; + this.sql = sql; + } + + @Override + public String version(CatalogDefinition catalog) { + return "" + + DSL.using( + new DefaultConfiguration() + .set(connection) + .set(new Settings().withStatementType(STATIC_STATEMENT)) + ).fetchValue( + // [#2906] TODO Plain SQL statements do not yet support named parameters + sql.replace(":catalog_name", "?"), param("catalog_name", catalog.getInputName()) + ); + } +} diff --git a/jOOQ-examples/jOOQ-flyway-example/pom.xml b/jOOQ-examples/jOOQ-flyway-example/pom.xml index 3014bc3f44..4370cf1380 100644 --- a/jOOQ-examples/jOOQ-flyway-example/pom.xml +++ b/jOOQ-examples/jOOQ-flyway-example/pom.xml @@ -123,6 +123,7 @@ .* FLYWAY_TEST + SELECT 'DEFAULT_CATALOG_' || TO_CHAR(current_timestamp, 'YYYYMMDDHHMISS') SELECT :schema_name || '_' || MAX("version") FROM "schema_version" diff --git a/jOOQ-meta/src/main/java/org/jooq/util/AbstractDatabase.java b/jOOQ-meta/src/main/java/org/jooq/util/AbstractDatabase.java index 4b3d5d0575..2d145680bd 100644 --- a/jOOQ-meta/src/main/java/org/jooq/util/AbstractDatabase.java +++ b/jOOQ-meta/src/main/java/org/jooq/util/AbstractDatabase.java @@ -118,6 +118,7 @@ public abstract class AbstractDatabase implements Database { private List configuredEnumTypes; private List configuredForcedTypes; private SchemaVersionProvider schemaVersionProvider; + private CatalogVersionProvider catalogVersionProvider; // ------------------------------------------------------------------------- // Loaded definitions @@ -669,6 +670,16 @@ public abstract class AbstractDatabase implements Database { this.schemaVersionProvider = schemaVersionProvider; } + @Override + public final CatalogVersionProvider getCatalogVersionProvider() { + return catalogVersionProvider; + } + + @Override + public final void setCatalogVersionProvider(CatalogVersionProvider catalogVersionProvider) { + this.catalogVersionProvider = catalogVersionProvider; + } + @Override public final void setSupportsUnsignedTypes(boolean supportsUnsignedTypes) { this.supportsUnsignedTypes = supportsUnsignedTypes; diff --git a/jOOQ-meta/src/main/java/org/jooq/util/CatalogVersionProvider.java b/jOOQ-meta/src/main/java/org/jooq/util/CatalogVersionProvider.java new file mode 100644 index 0000000000..bf1063f91d --- /dev/null +++ b/jOOQ-meta/src/main/java/org/jooq/util/CatalogVersionProvider.java @@ -0,0 +1,66 @@ +/** + * Copyright (c) 2009-2015, Data Geekery GmbH (http://www.datageekery.com) + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Other licenses: + * ----------------------------------------------------------------------------- + * Commercial licenses for this work are available. These replace the above + * ASL 2.0 and offer limited warranties, support, maintenance, and commercial + * database integrations. + * + * For more information, please visit: http://www.jooq.org/licenses + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +package org.jooq.util; + +/** + * An SPI that can be used to provide a catalog version to the jOOQ code + * generator. + *

+ * If between subsequent meta data accesses, at least one + * {@link SchemaDefinition}'s version changes, that schema's + * {@link CatalogDefinition}'s version must change as well. In other words, it + * can be safely assumed that when between two subsequent schema meta data + * accesses, the {@link CatalogDefinition}'s version stays the same, all + * {@link SchemaDefinition}'s versions have stayed the same as well. + *

+ * A {@link CatalogDefinition} is said to be unversioned if + * {@link #version(CatalogDefinition)} returns null. + * + * @author Lukas Eder + * @see SchemaVersionProvider + */ +public interface CatalogVersionProvider { + + /** + * Get a custom schema version. + */ + String version(CatalogDefinition catalog); +} diff --git a/jOOQ-meta/src/main/java/org/jooq/util/Database.java b/jOOQ-meta/src/main/java/org/jooq/util/Database.java index 5e76c2becc..fd7fc7fa31 100644 --- a/jOOQ-meta/src/main/java/org/jooq/util/Database.java +++ b/jOOQ-meta/src/main/java/org/jooq/util/Database.java @@ -376,9 +376,26 @@ public interface Database { */ void setConfiguredForcedTypes(List types); + /** + * The database's schema version provider. + */ SchemaVersionProvider getSchemaVersionProvider(); + + /** + * The database's schema version provider. + */ void setSchemaVersionProvider(SchemaVersionProvider provider); + /** + * The database's catalog version provider. + */ + CatalogVersionProvider getCatalogVersionProvider(); + + /** + * The database's catalog version provider. + */ + void setCatalogVersionProvider(CatalogVersionProvider provider); + /** * Database objects matching any of these field names will be generated as * forced types. diff --git a/jOOQ-meta/src/main/java/org/jooq/util/SchemaVersionProvider.java b/jOOQ-meta/src/main/java/org/jooq/util/SchemaVersionProvider.java index f824678688..1c8a05a5f7 100644 --- a/jOOQ-meta/src/main/java/org/jooq/util/SchemaVersionProvider.java +++ b/jOOQ-meta/src/main/java/org/jooq/util/SchemaVersionProvider.java @@ -43,8 +43,19 @@ package org.jooq.util; /** * An SPI that can be used to provide a schema version to the jOOQ code * generator. + *

+ * If between subsequent meta data accesses, at least one + * {@link SchemaDefinition}'s version changes, that schema's + * {@link CatalogDefinition}'s version must change as well. In other words, it + * can be safely assumed that when between two subsequent schema meta data + * accesses, the {@link CatalogDefinition}'s version stays the same, all + * {@link SchemaDefinition}'s versions have stayed the same as well. + *

+ * A {@link SchemaDefinition} is said to be unversioned if + * {@link #version(SchemaDefinition)} returns null. * * @author Lukas Eder + * @see CatalogVersionProvider */ public interface SchemaVersionProvider { diff --git a/jOOQ-meta/src/main/resources/xsd/jooq-codegen-3.8.0.xsd b/jOOQ-meta/src/main/resources/xsd/jooq-codegen-3.8.0.xsd index 69e37ae6eb..905825419e 100644 --- a/jOOQ-meta/src/main/resources/xsd/jooq-codegen-3.8.0.xsd +++ b/jOOQ-meta/src/main/resources/xsd/jooq-codegen-3.8.0.xsd @@ -486,6 +486,23 @@ --> + + +