[jOOQ/jOOQ#8528] Refactorings (WIP)
This commit is contained in:
parent
70f0fe3426
commit
8f375b6cf4
@ -1,224 +0,0 @@
|
||||
/*
|
||||
* 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.impl;
|
||||
|
||||
import static org.jooq.conf.SettingsTools.renderLocale;
|
||||
import static org.jooq.impl.DSL.name;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Locale;
|
||||
import java.util.Properties;
|
||||
import java.util.Scanner;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.jooq.DSLContext;
|
||||
import org.jooq.Name;
|
||||
import org.jooq.Name.Quoted;
|
||||
import org.jooq.Queries;
|
||||
import org.jooq.Query;
|
||||
import org.jooq.Source;
|
||||
import org.jooq.VisitContext;
|
||||
import org.jooq.conf.RenderNameCase;
|
||||
import org.jooq.conf.Settings;
|
||||
import org.jooq.conf.SettingsTools;
|
||||
import org.jooq.exception.DataAccessException;
|
||||
import org.jooq.tools.JooqLogger;
|
||||
|
||||
/**
|
||||
* Utility to create an in-memory H2 database, against which a list of DDL
|
||||
* scripts are executed.
|
||||
* <p>
|
||||
* Instead of directly executing the DDL scripts against the H2 database, they
|
||||
* are first parsed and translated to the H2 dialect, and only then executed
|
||||
* against the H2 database.
|
||||
*
|
||||
* @author Knut Wannheden
|
||||
*/
|
||||
final class DDLDatabaseInitializer {
|
||||
|
||||
private static final JooqLogger log = JooqLogger.getLogger(DDLDatabaseInitializer.class);
|
||||
private static final Pattern P_NAME = Pattern.compile("(?s:.*?\"([^\"]*)\".*)");
|
||||
|
||||
private Connection connection;
|
||||
private DSLContext ctx;
|
||||
|
||||
private DDLDatabaseInitializer(final Settings settings) {
|
||||
try {
|
||||
Properties info = new Properties();
|
||||
info.put("user", "sa");
|
||||
info.put("password", "");
|
||||
connection = DriverManager.getConnection("jdbc:h2:mem:jooq-extensions-" + UUID.randomUUID(), info);
|
||||
ctx = DSL.using(connection, settings);
|
||||
|
||||
// [#7771] [#8011] Ignore all parsed storage clauses when executing the statements
|
||||
ctx.data("org.jooq.ddl.ignore-storage-clauses", true);
|
||||
|
||||
// [#8910] Parse things a bit differently for use with the DDLDatabase
|
||||
ctx.data("org.jooq.ddl.parse-for-ddldatabase", true);
|
||||
|
||||
final RenderNameCase nameCase = settings.getRenderNameCase();
|
||||
final Locale locale = renderLocale(ctx.settings());
|
||||
if (nameCase != null && nameCase != RenderNameCase.AS_IS) {
|
||||
ctx.configuration().set(new DefaultVisitListener() {
|
||||
@Override
|
||||
public void visitStart(VisitContext c) {
|
||||
if (c.queryPart() instanceof Name) {
|
||||
Name[] parts = ((Name) c.queryPart()).parts();
|
||||
boolean changed = false;
|
||||
|
||||
for (int i = 0; i < parts.length; i++) {
|
||||
Name replacement = parts[i];
|
||||
switch (nameCase) {
|
||||
case LOWER_IF_UNQUOTED:
|
||||
if (parts[i].quoted() == Quoted.QUOTED) break;
|
||||
case LOWER:
|
||||
replacement = DSL.quotedName(parts[i].first().toLowerCase(locale));
|
||||
break;
|
||||
|
||||
case UPPER_IF_UNQUOTED:
|
||||
if (parts[i].quoted() == Quoted.QUOTED) break;
|
||||
case UPPER:
|
||||
replacement = DSL.quotedName(parts[i].first().toUpperCase(locale));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!replacement.equals(parts[i])) {
|
||||
parts[i] = replacement;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed)
|
||||
c.queryPart(DSL.name(parts));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (SQLException e) {
|
||||
if ("08001".equals(e.getSQLState()))
|
||||
throw new DataAccessException("The h2.jar was not found on the classpath, which is required for this internal feature", e);
|
||||
throw new DataAccessException("Error while exporting schema", e);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new DataAccessException("Error while exporting schema", e);
|
||||
}
|
||||
}
|
||||
|
||||
static Connection initializeUsing(final Settings settings, Source... scripts) {
|
||||
DDLDatabaseInitializer initializer = new DDLDatabaseInitializer(settings == null ? SettingsTools.defaultSettings() : settings);
|
||||
for (Source script : scripts)
|
||||
initializer.loadScript(script);
|
||||
return initializer.connection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses and executes the script represented by {@code reader} against the
|
||||
* H2 database. If the script references a schema which doesn't exist, it
|
||||
* will be automatically created first.
|
||||
* <p>
|
||||
* Any parser errors will be thrown. It is however possible to delimit
|
||||
* sections which cannot be parsed using special comments.
|
||||
*
|
||||
* @see Settings#getParseIgnoreCommentStart()
|
||||
* @see Settings#getParseIgnoreCommentStop()
|
||||
*/
|
||||
private final void loadScript(Source source) {
|
||||
Reader reader = source.reader();
|
||||
try {
|
||||
Scanner s = new Scanner(reader).useDelimiter("\\A");
|
||||
Queries queries = ctx.parser().parse(s.hasNext() ? s.next() : "");
|
||||
|
||||
for (Query query : queries) {
|
||||
|
||||
repeat:
|
||||
for (;;) {
|
||||
try {
|
||||
query.execute();
|
||||
log.info(query);
|
||||
break repeat;
|
||||
}
|
||||
catch (DataAccessException e) {
|
||||
|
||||
// [#7039] Auto create missing schemas. We're using the
|
||||
if ("90079" /* ErrorCode.SCHEMA_NOT_FOUND_1 */.equals(e.sqlState())) {
|
||||
SQLException cause = e.getCause(SQLException.class);
|
||||
|
||||
if (cause != null) {
|
||||
Matcher m = P_NAME.matcher(cause.getMessage());
|
||||
|
||||
if (m.find()) {
|
||||
Query createSchema = ctx.createSchemaIfNotExists(name(m.group(1)));
|
||||
createSchema.execute();
|
||||
log.info(createSchema);
|
||||
continue repeat;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ParserException e) {
|
||||
log.error("An exception occurred while parsing a DDL script: " + e.getMessage()
|
||||
+ ". Please report this error to https://github.com/jOOQ/jOOQ/issues/new", e);
|
||||
throw e;
|
||||
}
|
||||
finally {
|
||||
if (reader != null)
|
||||
try {
|
||||
reader.close();
|
||||
}
|
||||
catch (Exception ignore) {}
|
||||
}
|
||||
}
|
||||
|
||||
private final Connection connection() {
|
||||
return connection;
|
||||
}
|
||||
|
||||
}
|
||||
@ -37,13 +37,35 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.SQLDialect.H2;
|
||||
import static org.jooq.conf.SettingsTools.renderLocale;
|
||||
import static org.jooq.impl.DSL.name;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Locale;
|
||||
import java.util.Properties;
|
||||
import java.util.Scanner;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.DSLContext;
|
||||
import org.jooq.Meta;
|
||||
import org.jooq.MetaProvider;
|
||||
import org.jooq.SQLDialect;
|
||||
import org.jooq.Name;
|
||||
import org.jooq.Name.Quoted;
|
||||
import org.jooq.Queries;
|
||||
import org.jooq.Query;
|
||||
import org.jooq.Source;
|
||||
import org.jooq.VisitContext;
|
||||
import org.jooq.conf.RenderNameCase;
|
||||
import org.jooq.conf.Settings;
|
||||
import org.jooq.exception.DataAccessException;
|
||||
import org.jooq.tools.JooqLogger;
|
||||
import org.jooq.tools.jdbc.JDBCUtils;
|
||||
|
||||
/**
|
||||
@ -55,8 +77,11 @@ import org.jooq.tools.jdbc.JDBCUtils;
|
||||
*/
|
||||
final class DDLMetaProvider implements MetaProvider {
|
||||
|
||||
private final Configuration configuration;
|
||||
private final Source[] scripts;
|
||||
private static final JooqLogger log = JooqLogger.getLogger(DDLMetaProvider.class);
|
||||
private static final Pattern P_NAME = Pattern.compile("(?s:.*?\"([^\"]*)\".*)");
|
||||
|
||||
private final Configuration configuration;
|
||||
private final Source[] scripts;
|
||||
|
||||
public DDLMetaProvider(Configuration configuration, Source... scripts) {
|
||||
this.configuration = configuration == null ? new DefaultConfiguration() : configuration;
|
||||
@ -65,16 +90,154 @@ final class DDLMetaProvider implements MetaProvider {
|
||||
|
||||
@Override
|
||||
public Meta provide() {
|
||||
Configuration localConfiguration = configuration.derive();
|
||||
Connection connection = DDLDatabaseInitializer.initializeUsing(localConfiguration.settings(), scripts);
|
||||
Connection connection = null;
|
||||
|
||||
try {
|
||||
localConfiguration.set(connection);
|
||||
localConfiguration.set(SQLDialect.H2);
|
||||
MetaProvider defaultProvider = new DefaultMetaProvider(localConfiguration);
|
||||
Meta meta = DetachedMeta.copyOf(defaultProvider.provide());
|
||||
return meta;
|
||||
} finally {
|
||||
DDLDatabaseInitializer initializer = new DDLDatabaseInitializer(configuration.settings());
|
||||
|
||||
for (Source script : scripts)
|
||||
initializer.loadScript(script);
|
||||
|
||||
return DetachedMeta.detach(new DefaultMetaProvider(
|
||||
configuration.derive().set(initializer.connection).set(H2)
|
||||
));
|
||||
}
|
||||
finally {
|
||||
JDBCUtils.safeClose(connection);
|
||||
}
|
||||
}
|
||||
|
||||
static final class DDLDatabaseInitializer {
|
||||
|
||||
private Connection connection;
|
||||
private DSLContext ctx;
|
||||
|
||||
private DDLDatabaseInitializer(final Settings settings) {
|
||||
try {
|
||||
Properties info = new Properties();
|
||||
info.put("user", "sa");
|
||||
info.put("password", "");
|
||||
connection = DriverManager.getConnection("jdbc:h2:mem:jooq-extensions-" + UUID.randomUUID(), info);
|
||||
ctx = DSL.using(connection, settings);
|
||||
|
||||
// [#7771] [#8011] Ignore all parsed storage clauses when executing the statements
|
||||
ctx.data("org.jooq.ddl.ignore-storage-clauses", true);
|
||||
|
||||
// [#8910] Parse things a bit differently for use with the DDLDatabase
|
||||
ctx.data("org.jooq.ddl.parse-for-ddldatabase", true);
|
||||
|
||||
final RenderNameCase nameCase = settings.getRenderNameCase();
|
||||
final Locale locale = renderLocale(ctx.settings());
|
||||
if (nameCase != null && nameCase != RenderNameCase.AS_IS) {
|
||||
ctx.configuration().set(new DefaultVisitListener() {
|
||||
@Override
|
||||
public void visitStart(VisitContext c) {
|
||||
if (c.queryPart() instanceof Name) {
|
||||
Name[] parts = ((Name) c.queryPart()).parts();
|
||||
boolean changed = false;
|
||||
|
||||
for (int i = 0; i < parts.length; i++) {
|
||||
Name replacement = parts[i];
|
||||
switch (nameCase) {
|
||||
case LOWER_IF_UNQUOTED:
|
||||
if (parts[i].quoted() == Quoted.QUOTED) break;
|
||||
case LOWER:
|
||||
replacement = DSL.quotedName(parts[i].first().toLowerCase(locale));
|
||||
break;
|
||||
|
||||
case UPPER_IF_UNQUOTED:
|
||||
if (parts[i].quoted() == Quoted.QUOTED) break;
|
||||
case UPPER:
|
||||
replacement = DSL.quotedName(parts[i].first().toUpperCase(locale));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!replacement.equals(parts[i])) {
|
||||
parts[i] = replacement;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed)
|
||||
c.queryPart(DSL.name(parts));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (SQLException e) {
|
||||
if ("08001".equals(e.getSQLState()))
|
||||
throw new DataAccessException("The h2.jar was not found on the classpath, which is required for this internal feature", e);
|
||||
throw new DataAccessException("Error while exporting schema", e);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new DataAccessException("Error while exporting schema", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses and executes the script represented by {@code reader} against the
|
||||
* H2 database. If the script references a schema which doesn't exist, it
|
||||
* will be automatically created first.
|
||||
* <p>
|
||||
* Any parser errors will be thrown. It is however possible to delimit
|
||||
* sections which cannot be parsed using special comments.
|
||||
*
|
||||
* @see Settings#getParseIgnoreCommentStart()
|
||||
* @see Settings#getParseIgnoreCommentStop()
|
||||
*/
|
||||
private final void loadScript(Source source) {
|
||||
Reader reader = source.reader();
|
||||
try {
|
||||
Scanner s = new Scanner(reader).useDelimiter("\\A");
|
||||
Queries queries = ctx.parser().parse(s.hasNext() ? s.next() : "");
|
||||
|
||||
for (Query query : queries) {
|
||||
|
||||
repeat:
|
||||
for (;;) {
|
||||
try {
|
||||
query.execute();
|
||||
log.info(query);
|
||||
break repeat;
|
||||
}
|
||||
catch (DataAccessException e) {
|
||||
|
||||
// [#7039] Auto create missing schemas. We're using the
|
||||
if ("90079" /* ErrorCode.SCHEMA_NOT_FOUND_1 */.equals(e.sqlState())) {
|
||||
SQLException cause = e.getCause(SQLException.class);
|
||||
|
||||
if (cause != null) {
|
||||
Matcher m = P_NAME.matcher(cause.getMessage());
|
||||
|
||||
if (m.find()) {
|
||||
Query createSchema = ctx.createSchemaIfNotExists(name(m.group(1)));
|
||||
createSchema.execute();
|
||||
log.info(createSchema);
|
||||
continue repeat;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ParserException e) {
|
||||
log.error("An exception occurred while parsing a DDL script: " + e.getMessage()
|
||||
+ ". Please report this error to https://github.com/jOOQ/jOOQ/issues/new", e);
|
||||
throw e;
|
||||
}
|
||||
finally {
|
||||
if (reader != null)
|
||||
try {
|
||||
reader.close();
|
||||
}
|
||||
catch (Exception ignore) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,16 +38,17 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.jooq.Catalog;
|
||||
import org.jooq.Comment;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.DataType;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.ForeignKey;
|
||||
import org.jooq.Index;
|
||||
import org.jooq.Meta;
|
||||
import org.jooq.MetaProvider;
|
||||
import org.jooq.Name;
|
||||
import org.jooq.Package;
|
||||
import org.jooq.Record;
|
||||
@ -70,18 +71,19 @@ import org.jooq.exception.DataAccessException;
|
||||
final class DetachedMeta extends AbstractMeta {
|
||||
|
||||
private static final long serialVersionUID = 5561057000510740144L;
|
||||
private Meta delegate;
|
||||
private Meta delegate;
|
||||
|
||||
private DetachedMeta(Configuration configuration) {
|
||||
super(configuration);
|
||||
static Meta detach(MetaProvider provider) {
|
||||
return new DetachedMeta(provider.provide());
|
||||
}
|
||||
|
||||
private final DetachedMeta copy(Meta meta) {
|
||||
private DetachedMeta(Meta meta) {
|
||||
super(meta.configuration());
|
||||
|
||||
delegate = meta;
|
||||
getCatalogs();
|
||||
delegate = null;
|
||||
resolveReferences();
|
||||
return this;
|
||||
}
|
||||
|
||||
private final void resolveReferences() {
|
||||
@ -89,10 +91,6 @@ final class DetachedMeta extends AbstractMeta {
|
||||
((DetachedCatalog) catalog).resolveReferences(this);
|
||||
}
|
||||
|
||||
static Meta copyOf(Meta meta) {
|
||||
return new DetachedMeta(meta.configuration()).copy(meta);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final List<Catalog> getCatalogs0() throws DataAccessException {
|
||||
List<Catalog> result = new ArrayList<>();
|
||||
@ -110,24 +108,23 @@ final class DetachedMeta extends AbstractMeta {
|
||||
super(name, comment);
|
||||
}
|
||||
|
||||
private final DetachedCatalog copy(Catalog catalog) {
|
||||
for (Schema schema : catalog.getSchemas())
|
||||
schemas.add(DetachedSchema.copyOf(schema, this));
|
||||
return this;
|
||||
}
|
||||
|
||||
private final void resolveReferences(Meta meta) {
|
||||
for (Schema schema : schemas)
|
||||
((DetachedSchema) schema).resolveReferences(meta);
|
||||
}
|
||||
|
||||
static DetachedCatalog copyOf(Catalog catalog) {
|
||||
return new DetachedCatalog(catalog.getName(), catalog.getComment()).copy(catalog);
|
||||
DetachedCatalog result = new DetachedCatalog(catalog.getName(), catalog.getComment());
|
||||
|
||||
for (Schema schema : catalog.getSchemas())
|
||||
result.schemas.add(DetachedSchema.copyOf(schema, result));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<Schema> getSchemas() {
|
||||
return schemas;
|
||||
return Collections.unmodifiableList(schemas);
|
||||
}
|
||||
}
|
||||
|
||||
@ -142,38 +139,37 @@ final class DetachedMeta extends AbstractMeta {
|
||||
super(name, owner, comment);
|
||||
}
|
||||
|
||||
private final DetachedSchema copy(Schema schema) {
|
||||
for (Table<?> table : schema.getTables())
|
||||
tables.add(DetachedTable.copyOf(table, this));
|
||||
for (Sequence<?> sequence : schema.getSequences())
|
||||
sequences.add(DetachedSequence.copyOf(sequence, this));
|
||||
for (UDT<?> udt : schema.getUDTs())
|
||||
udts.add(DetachedUDT.copyOf(udt, this));
|
||||
return this;
|
||||
}
|
||||
|
||||
static DetachedSchema copyOf(Schema schema, Catalog owner) {
|
||||
return new DetachedSchema(schema.getName(), owner, schema.getComment()).copy(schema);
|
||||
DetachedSchema result = new DetachedSchema(schema.getName(), owner, schema.getComment());
|
||||
|
||||
for (Table<?> table : schema.getTables())
|
||||
result.tables.add(DetachedTable.copyOf(table, result));
|
||||
for (Sequence<?> sequence : schema.getSequences())
|
||||
result.sequences.add(DetachedSequence.copyOf(sequence, result));
|
||||
for (UDT<?> udt : schema.getUDTs())
|
||||
result.udts.add(DetachedUDT.copyOf(udt, result));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public final void resolveReferences(Meta meta) {
|
||||
final void resolveReferences(Meta meta) {
|
||||
for (Table<?> table : tables)
|
||||
((DetachedTable<?>) table).resolveReferences(meta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<Table<?>> getTables() {
|
||||
return tables;
|
||||
return Collections.unmodifiableList(tables);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<Sequence<?>> getSequences() {
|
||||
return sequences;
|
||||
return Collections.unmodifiableList(sequences);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<UDT<?>> getUDTs() {
|
||||
return udts;
|
||||
return Collections.unmodifiableList(udts);
|
||||
}
|
||||
}
|
||||
|
||||
@ -189,48 +185,49 @@ final class DetachedMeta extends AbstractMeta {
|
||||
super(name, owner, null, null, comment);
|
||||
}
|
||||
|
||||
private final DetachedTable<?> copy(Table<R> table) {
|
||||
for (Field<?> field : table.fields())
|
||||
createField(field.getName(), field.getDataType(), this, field.getComment());
|
||||
for (Index index : table.getIndexes()) {
|
||||
List<SortField<?>> indexFields = index.getFields();
|
||||
SortField<?>[] copiedFields = new SortField[indexFields.size()];
|
||||
for (int i = 0; i < indexFields.size(); i++) {
|
||||
SortField<?> field = indexFields.get(i);
|
||||
copiedFields[i] = field(field.getName()).sort(field.getOrder());
|
||||
// [#9009] TODO NULLS FIRST / NULLS LAST
|
||||
}
|
||||
indexes.add(org.jooq.impl.Internal.createIndex(index.getName(), this, copiedFields, index.getUnique()));
|
||||
}
|
||||
for (UniqueKey<R> key : table.getKeys())
|
||||
keys.add(org.jooq.impl.Internal.createUniqueKey(this, key.getName(), copiedFields(key.getFieldsArray())));
|
||||
UniqueKey<R> pk = table.getPrimaryKey();
|
||||
if (pk != null)
|
||||
primaryKey = org.jooq.impl.Internal.createUniqueKey(this, pk.getName(), copiedFields(pk.getFieldsArray()));
|
||||
references.addAll(table.getReferences());
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private final TableField<R, ?>[] copiedFields(TableField<R, ?>[] tableFields) {
|
||||
@Deprecated
|
||||
private final TableField<R, ?>[] fields(TableField<R, ?>[] tableFields) {
|
||||
|
||||
// TODO: [#9456] This auxiliary method should not be necessary
|
||||
// We should be able to call TableLike.fields instead.
|
||||
TableField<R, ?>[] result = new TableField[tableFields.length];
|
||||
for (int i = 0; i < tableFields.length; i++)
|
||||
result[i] = (TableField<R, ?>) field(tableFields[i].getName());
|
||||
return result;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static DetachedTable<?> copyOf(Table<?> table, Schema owner) {
|
||||
return new DetachedTable<>(table.getUnqualifiedName(), owner, DSL.comment(table.getComment())).copy((Table<Record>) table);
|
||||
static <R extends Record> DetachedTable<R> copyOf(Table<R> table, Schema owner) {
|
||||
DetachedTable<R> result = new DetachedTable<>(table.getUnqualifiedName(), owner, DSL.comment(table.getComment()));
|
||||
|
||||
for (Field<?> field : table.fields())
|
||||
DetachedTable.createField(field.getName(), field.getDataType(), result, field.getComment());
|
||||
for (Index index : table.getIndexes()) {
|
||||
List<SortField<?>> indexFields = index.getFields();
|
||||
SortField<?>[] copiedFields = new SortField[indexFields.size()];
|
||||
for (int i = 0; i < indexFields.size(); i++) {
|
||||
SortField<?> field = indexFields.get(i);
|
||||
copiedFields[i] = result.field(field.getName()).sort(field.getOrder());
|
||||
// [#9009] TODO NULLS FIRST / NULLS LAST
|
||||
}
|
||||
result.indexes.add(org.jooq.impl.Internal.createIndex(index.getName(), result, copiedFields, index.getUnique()));
|
||||
}
|
||||
for (UniqueKey<R> key : table.getKeys())
|
||||
result.keys.add(org.jooq.impl.Internal.createUniqueKey(result, key.getName(), result.fields(key.getFieldsArray())));
|
||||
UniqueKey<R> pk = table.getPrimaryKey();
|
||||
if (pk != null)
|
||||
result.primaryKey = org.jooq.impl.Internal.createUniqueKey(result, pk.getName(), result.fields(pk.getFieldsArray()));
|
||||
result.references.addAll(table.getReferences());
|
||||
return result;
|
||||
}
|
||||
|
||||
public final void resolveReferences(Meta meta) {
|
||||
final void resolveReferences(Meta meta) {
|
||||
for (int i = 0; i < references.size(); i++) {
|
||||
ForeignKey<R, ?> ref = references.get(i);
|
||||
Name name = ref.getKey().getTable().getQualifiedName();
|
||||
Table<?> table = resolveTable(name, meta);
|
||||
UniqueKey<?> pk = table == null ? null : table.getPrimaryKey();
|
||||
references.set(i, org.jooq.impl.Internal.createForeignKey(pk, this, ref.getName(), copiedFields(ref.getFieldsArray())));
|
||||
references.set(i, org.jooq.impl.Internal.createForeignKey(pk, this, ref.getName(), fields(ref.getFieldsArray())));
|
||||
}
|
||||
}
|
||||
|
||||
@ -241,12 +238,12 @@ final class DetachedMeta extends AbstractMeta {
|
||||
|
||||
@Override
|
||||
public final List<Index> getIndexes() {
|
||||
return indexes;
|
||||
return Collections.unmodifiableList(indexes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<UniqueKey<R>> getKeys() {
|
||||
return keys;
|
||||
return Collections.unmodifiableList(keys);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -256,7 +253,7 @@ final class DetachedMeta extends AbstractMeta {
|
||||
|
||||
@Override
|
||||
public final List<ForeignKey<R, ?>> getReferences() {
|
||||
return references;
|
||||
return Collections.unmodifiableList(references);
|
||||
}
|
||||
}
|
||||
|
||||
@ -267,12 +264,8 @@ final class DetachedMeta extends AbstractMeta {
|
||||
super(name, owner, dataType);
|
||||
}
|
||||
|
||||
private final DetachedSequence<?> copy(Sequence<?> sequence) {
|
||||
return this;
|
||||
}
|
||||
|
||||
static DetachedSequence<?> copyOf(Sequence<?> sequence, Schema owner) {
|
||||
return new DetachedSequence<>(sequence.getName(), owner, sequence.getDataType()).copy(sequence);
|
||||
return new DetachedSequence<>(sequence.getName(), owner, sequence.getDataType());
|
||||
}
|
||||
}
|
||||
|
||||
@ -283,16 +276,12 @@ final class DetachedMeta extends AbstractMeta {
|
||||
super(name, owner, package_, synthetic);
|
||||
}
|
||||
|
||||
private final DetachedUDT<?> copy(UDT<?> udt) {
|
||||
return this;
|
||||
}
|
||||
|
||||
static DetachedUDT<?> copyOf(UDT<?> udt, Schema owner) {
|
||||
Package package_ = null;
|
||||
|
||||
|
||||
|
||||
return new DetachedUDT<>(udt.getName(), owner, package_, udt.isSynthetic()).copy(udt);
|
||||
return new DetachedUDT<>(udt.getName(), owner, package_, udt.isSynthetic());
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user