[jOOQ/jOOQ#8972] jOOQ-meta should query dictionary views for column existence rather than the column itself (WIP)
This commit is contained in:
parent
24f703eeb3
commit
83a6711412
@ -61,6 +61,7 @@ import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.jooq.Condition;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.DSLContext;
|
||||
import org.jooq.ExecuteContext;
|
||||
@ -68,7 +69,9 @@ import org.jooq.ExecuteListenerProvider;
|
||||
import org.jooq.Name;
|
||||
import org.jooq.Query;
|
||||
import org.jooq.SQLDialect;
|
||||
import org.jooq.Schema;
|
||||
import org.jooq.Table;
|
||||
import org.jooq.TableField;
|
||||
import org.jooq.conf.Settings;
|
||||
import org.jooq.conf.SettingsTools;
|
||||
import org.jooq.exception.DataAccessException;
|
||||
@ -200,12 +203,14 @@ public abstract class AbstractDatabase implements Database {
|
||||
private final List<Definition> all;
|
||||
private final List<Definition> included;
|
||||
private final List<Definition> excluded;
|
||||
private final Map<Table<?>, Boolean> exists;
|
||||
private final Map<Table<?>, Boolean> existTables;
|
||||
private final Map<TableField<?, ?>, Boolean> existFields;
|
||||
private final Patterns patterns;
|
||||
private final Statements statements;
|
||||
|
||||
protected AbstractDatabase() {
|
||||
exists = new HashMap<>();
|
||||
existTables = new HashMap<>();
|
||||
existFields = new HashMap<>();
|
||||
patterns = new Patterns();
|
||||
statements = new Statements();
|
||||
filters = new ArrayList<>();
|
||||
@ -364,25 +369,102 @@ public abstract class AbstractDatabase implements Database {
|
||||
}
|
||||
}
|
||||
|
||||
// [#8972] TODO: Implement these for all non-PostgresDatabase databases.
|
||||
@Override
|
||||
public final boolean exists(Table<?> table) {
|
||||
Boolean result = exists.get(table);
|
||||
public TableQualifier tableQualifier() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColumnQualifier columnQualifier() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean exists(TableField<?, ?> field) {
|
||||
Boolean result = existFields.get(field);
|
||||
|
||||
if (result == null) {
|
||||
try {
|
||||
create(true)
|
||||
.selectOne()
|
||||
.from(table)
|
||||
.where(falseCondition())
|
||||
.fetch();
|
||||
ColumnQualifier qualifier = columnQualifier();
|
||||
|
||||
result = true;
|
||||
// [#8972] In the presence of a qualifier, avoid running an error-
|
||||
// triggering query, which may lead to unwanted log messages
|
||||
if (qualifier == null) {
|
||||
try {
|
||||
create(true)
|
||||
.select(field)
|
||||
.from(field.getTable())
|
||||
.where(falseCondition())
|
||||
.fetch();
|
||||
|
||||
result = true;
|
||||
}
|
||||
catch (DataAccessException e) {
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
catch (DataAccessException e) {
|
||||
result = false;
|
||||
else {
|
||||
Condition condition = qualifier.columnName().eq(field.getName());
|
||||
|
||||
Table<?> table = field.getTable();
|
||||
condition = condition.and(qualifier.tableName().eq(table.getName()));
|
||||
|
||||
Schema schema = table.getSchema();
|
||||
if (schema != null)
|
||||
condition = condition.and(qualifier.tableSchema().eq(schema.getName()));
|
||||
|
||||
result = create().fetchExists(qualifier.table(), condition);
|
||||
}
|
||||
|
||||
exists.put(table, result);
|
||||
existFields.put(field, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean existAll(TableField<?, ?>... f) {
|
||||
for (TableField<?, ?> field : f)
|
||||
if (!exists(field))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean exists(Table<?> table) {
|
||||
Boolean result = existTables.get(table);
|
||||
|
||||
if (result == null) {
|
||||
TableQualifier qualifier = tableQualifier();
|
||||
|
||||
// [#8972] In the presence of a qualifier, avoid running an error-
|
||||
// triggering query, which may lead to unwanted log messages
|
||||
if (qualifier == null) {
|
||||
try {
|
||||
create(true)
|
||||
.selectOne()
|
||||
.from(table)
|
||||
.where(falseCondition())
|
||||
.fetch();
|
||||
|
||||
result = true;
|
||||
}
|
||||
catch (DataAccessException e) {
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Condition condition = qualifier.tableName().eq(table.getName());
|
||||
|
||||
Schema schema = table.getSchema();
|
||||
if (schema != null)
|
||||
condition = condition.and(qualifier.tableSchema().eq(schema.getName()));
|
||||
|
||||
result = create().fetchExists(qualifier.table(), condition);
|
||||
}
|
||||
|
||||
existTables.put(table, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
75
jOOQ-meta/src/main/java/org/jooq/meta/ColumnQualifier.java
Normal file
75
jOOQ-meta/src/main/java/org/jooq/meta/ColumnQualifier.java
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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.meta;
|
||||
|
||||
import org.jooq.Table;
|
||||
import org.jooq.TableField;
|
||||
|
||||
/**
|
||||
* A qualifier for columns in the dictionary views.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public interface ColumnQualifier {
|
||||
|
||||
/**
|
||||
* The table containing column meta information.
|
||||
*/
|
||||
Table<?> table();
|
||||
|
||||
/**
|
||||
* The field specifying the column table's catalog name.
|
||||
*/
|
||||
TableField<?, String> tableCatalog();
|
||||
|
||||
/**
|
||||
* The field specifying the column table's schema name.
|
||||
*/
|
||||
TableField<?, String> tableSchema();
|
||||
|
||||
/**
|
||||
* The field specifying the column table's table name.
|
||||
*/
|
||||
TableField<?, String> tableName();
|
||||
|
||||
/**
|
||||
* The field specifying the column name.
|
||||
*/
|
||||
TableField<?, String> columnName();
|
||||
|
||||
}
|
||||
@ -47,6 +47,7 @@ import org.jooq.DSLContext;
|
||||
import org.jooq.Name;
|
||||
import org.jooq.SQLDialect;
|
||||
import org.jooq.Table;
|
||||
import org.jooq.TableField;
|
||||
import org.jooq.meta.jaxb.CatalogMappingType;
|
||||
import org.jooq.meta.jaxb.CustomType;
|
||||
import org.jooq.meta.jaxb.Embeddable;
|
||||
@ -903,6 +904,28 @@ public interface Database extends AutoCloseable {
|
||||
*/
|
||||
boolean tableValuedFunctions();
|
||||
|
||||
/**
|
||||
* The table qualifier used by this database, or <code>null</code>, if this
|
||||
* database doesn't specify such a qualifier.
|
||||
*/
|
||||
TableQualifier tableQualifier();
|
||||
|
||||
/**
|
||||
* The column qualifier used by this database, or <code>null</code>, if this
|
||||
* database doesn't specify such a qualifier.
|
||||
*/
|
||||
ColumnQualifier columnQualifier();
|
||||
|
||||
/**
|
||||
* Check for the existence of a table field in the dictionary views.
|
||||
*/
|
||||
boolean exists(TableField<?, ?> field);
|
||||
|
||||
/**
|
||||
* Check for the existence of several table fields in the dictionary views.
|
||||
*/
|
||||
boolean existAll(TableField<?, ?>... fields);
|
||||
|
||||
/**
|
||||
* Check for the existence of a table in the dictionary views.
|
||||
*/
|
||||
|
||||
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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.meta;
|
||||
|
||||
import org.jooq.Table;
|
||||
import org.jooq.TableField;
|
||||
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public class DefaultColumnQualifier implements ColumnQualifier {
|
||||
|
||||
private final Table<?> table;
|
||||
private final TableField<?, String> tableCatalog;
|
||||
private final TableField<?, String> tableSchema;
|
||||
private final TableField<?, String> tableName;
|
||||
private final TableField<?, String> columnName;
|
||||
|
||||
public DefaultColumnQualifier(
|
||||
Table<?> table,
|
||||
TableField<?, String> tableCatalog,
|
||||
TableField<?, String> tableSchema,
|
||||
TableField<?, String> tableName,
|
||||
TableField<?, String> columnName
|
||||
) {
|
||||
this.table = table;
|
||||
this.tableCatalog = tableCatalog;
|
||||
this.tableSchema = tableSchema;
|
||||
this.tableName = tableName;
|
||||
this.columnName = columnName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Table<?> table() {
|
||||
return table;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableField<?, String> tableCatalog() {
|
||||
return tableCatalog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableField<?, String> tableSchema() {
|
||||
return tableSchema;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableField<?, String> tableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableField<?, String> columnName() {
|
||||
return columnName;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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.meta;
|
||||
|
||||
import org.jooq.Table;
|
||||
import org.jooq.TableField;
|
||||
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public class DefaultTableQualifier implements TableQualifier {
|
||||
|
||||
private final Table<?> table;
|
||||
private final TableField<?, String> tableCatalog;
|
||||
private final TableField<?, String> tableSchema;
|
||||
private final TableField<?, String> tableName;
|
||||
|
||||
public DefaultTableQualifier(
|
||||
Table<?> table,
|
||||
TableField<?, String> tableCatalog,
|
||||
TableField<?, String> tableSchema,
|
||||
TableField<?, String> tableName
|
||||
) {
|
||||
this.table = table;
|
||||
this.tableCatalog = tableCatalog;
|
||||
this.tableSchema = tableSchema;
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Table<?> table() {
|
||||
return table;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableField<?, String> tableCatalog() {
|
||||
return tableCatalog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableField<?, String> tableSchema() {
|
||||
return tableSchema;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableField<?, String> tableName() {
|
||||
return tableName;
|
||||
}
|
||||
}
|
||||
70
jOOQ-meta/src/main/java/org/jooq/meta/TableQualifier.java
Normal file
70
jOOQ-meta/src/main/java/org/jooq/meta/TableQualifier.java
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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.meta;
|
||||
|
||||
import org.jooq.Table;
|
||||
import org.jooq.TableField;
|
||||
|
||||
/**
|
||||
* A qualifier for tables in the dictionary views.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public interface TableQualifier {
|
||||
|
||||
/**
|
||||
* The table containing table meta information.
|
||||
*/
|
||||
Table<?> table();
|
||||
|
||||
/**
|
||||
* The field specifying the table's catalog name.
|
||||
*/
|
||||
TableField<?, String> tableCatalog();
|
||||
|
||||
/**
|
||||
* The field specifying the table's schema name.
|
||||
*/
|
||||
TableField<?, String> tableSchema();
|
||||
|
||||
/**
|
||||
* The field specifying the table's table name.
|
||||
*/
|
||||
TableField<?, String> tableName();
|
||||
|
||||
}
|
||||
@ -57,6 +57,7 @@ import static org.jooq.impl.DSL.select;
|
||||
import static org.jooq.impl.DSL.when;
|
||||
import static org.jooq.meta.postgres.information_schema.Tables.ATTRIBUTES;
|
||||
import static org.jooq.meta.postgres.information_schema.Tables.CHECK_CONSTRAINTS;
|
||||
import static org.jooq.meta.postgres.information_schema.Tables.COLUMNS;
|
||||
import static org.jooq.meta.postgres.information_schema.Tables.KEY_COLUMN_USAGE;
|
||||
import static org.jooq.meta.postgres.information_schema.Tables.PARAMETERS;
|
||||
import static org.jooq.meta.postgres.information_schema.Tables.ROUTINES;
|
||||
@ -102,14 +103,17 @@ import org.jooq.meta.AbstractIndexDefinition;
|
||||
import org.jooq.meta.ArrayDefinition;
|
||||
import org.jooq.meta.CatalogDefinition;
|
||||
import org.jooq.meta.ColumnDefinition;
|
||||
import org.jooq.meta.ColumnQualifier;
|
||||
import org.jooq.meta.DataTypeDefinition;
|
||||
import org.jooq.meta.DefaultCheckConstraintDefinition;
|
||||
import org.jooq.meta.DefaultColumnQualifier;
|
||||
import org.jooq.meta.DefaultDataTypeDefinition;
|
||||
import org.jooq.meta.DefaultDomainDefinition;
|
||||
import org.jooq.meta.DefaultEnumDefinition;
|
||||
import org.jooq.meta.DefaultIndexColumnDefinition;
|
||||
import org.jooq.meta.DefaultRelations;
|
||||
import org.jooq.meta.DefaultSequenceDefinition;
|
||||
import org.jooq.meta.DefaultTableQualifier;
|
||||
import org.jooq.meta.DomainDefinition;
|
||||
import org.jooq.meta.EnumDefinition;
|
||||
import org.jooq.meta.IndexColumnDefinition;
|
||||
@ -119,6 +123,7 @@ import org.jooq.meta.RoutineDefinition;
|
||||
import org.jooq.meta.SchemaDefinition;
|
||||
import org.jooq.meta.SequenceDefinition;
|
||||
import org.jooq.meta.TableDefinition;
|
||||
import org.jooq.meta.TableQualifier;
|
||||
import org.jooq.meta.UDTDefinition;
|
||||
import org.jooq.meta.hsqldb.HSQLDBDatabase;
|
||||
import org.jooq.meta.postgres.information_schema.tables.CheckConstraints;
|
||||
@ -871,23 +876,22 @@ public class PostgresDatabase extends AbstractDatabase {
|
||||
|
||||
// [#7785] pg_proc.prokind was added in PostgreSQL 11 only, and
|
||||
// pg_proc.proisagg was removed, incompatibly
|
||||
try {
|
||||
create(true)
|
||||
.select(PG_PROC.PROKIND)
|
||||
.from(PG_PROC)
|
||||
.where(falseCondition())
|
||||
.fetch();
|
||||
|
||||
is11 = true;
|
||||
}
|
||||
catch (DataAccessException e) {
|
||||
is11 = false;
|
||||
}
|
||||
is11 = exists(PG_PROC.PROKIND);
|
||||
}
|
||||
|
||||
return is11;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableQualifier tableQualifier() {
|
||||
return new DefaultTableQualifier(TABLES, TABLES.TABLE_CATALOG, TABLES.TABLE_SCHEMA, TABLES.TABLE_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColumnQualifier columnQualifier() {
|
||||
return new DefaultColumnQualifier(COLUMNS, COLUMNS.TABLE_CATALOG, COLUMNS.TABLE_SCHEMA, COLUMNS.TABLE_NAME, COLUMNS.COLUMN_NAME);
|
||||
}
|
||||
|
||||
boolean canCombineArrays() {
|
||||
if (canCombineArrays == null) {
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user