提交 3aa9e208 编写于 作者: S Serge Rider

#5384 Virtual FKs + dictionary reading + dictionary model refactoring


Former-commit-id: 8bd4bb7a
上级 657f1a3c
......@@ -21,10 +21,7 @@ import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.ModelPreferences;
import org.jkiss.dbeaver.model.DBPDataSource;
import org.jkiss.dbeaver.model.DBPEvaluationContext;
import org.jkiss.dbeaver.model.DBPSaveableObject;
import org.jkiss.dbeaver.model.DBUtils;
import org.jkiss.dbeaver.model.*;
import org.jkiss.dbeaver.model.data.*;
import org.jkiss.dbeaver.model.exec.*;
import org.jkiss.dbeaver.model.exec.jdbc.JDBCStatement;
......@@ -40,14 +37,23 @@ import org.jkiss.dbeaver.model.sql.SQLDataSource;
import org.jkiss.dbeaver.model.sql.SQLDialect;
import org.jkiss.dbeaver.model.sql.SQLUtils;
import org.jkiss.dbeaver.model.struct.*;
import org.jkiss.dbeaver.model.virtual.DBVEntity;
import org.jkiss.dbeaver.model.virtual.DBVUtils;
import org.jkiss.utils.ArrayUtils;
import org.jkiss.utils.CommonUtils;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* JDBC abstract table implementation
*/
public abstract class JDBCTable<DATASOURCE extends DBPDataSource, CONTAINER extends DBSObject>
extends AbstractTable<DATASOURCE, CONTAINER>
implements DBSDataManipulator, DBPSaveableObject
implements DBSDictionary, DBSDataManipulator, DBPSaveableObject
{
private static final Log log = Log.getLog(JDBCTable.class);
......@@ -534,6 +540,280 @@ public abstract class JDBCTable<DATASOURCE extends DBPDataSource, CONTAINER exte
};
}
////////////////////////////////////////////////////////////////////
// Dictionary
/**
* Enumerations supported only for unique constraints
* @return true for unique constraint else otherwise
*/
@Override
public boolean supportsDictionaryEnumeration() {
return true;
}
/**
* Returns prepared statements for enumeration fetch
* @param session execution context
* @param keyColumn enumeration column.
* @param keyPattern pattern for enumeration values. If null or empty then returns full enumration set
* @param preceedingKeys other constrain key values. May be null.
* @param sortByValue sort results by eky value. If false then sort by description
* @param sortAsc sort ascending/descending
* @param maxResults maximum enumeration values in result set @return @throws DBException
*/
@NotNull
@Override
public List<DBDLabelValuePair> getDictionaryEnumeration(
@NotNull DBCSession session,
@NotNull DBSEntityAttribute keyColumn,
Object keyPattern,
List<DBDAttributeValue> preceedingKeys,
boolean sortByValue,
boolean sortAsc,
int maxResults)
throws DBException
{
// Use default one
return readKeyEnumeration(
session,
keyColumn,
keyPattern,
preceedingKeys,
sortByValue,
sortAsc,
maxResults);
}
@NotNull
@Override
public List<DBDLabelValuePair> getDictionaryValues(@NotNull DBCSession session, @NotNull DBSEntityAttribute keyColumn, @NotNull List<Object> keyValues, List<DBDAttributeValue> preceedingKeys, boolean sortByValue, boolean sortAsc) throws DBException {
DBDValueHandler keyValueHandler = DBUtils.findValueHandler(session, keyColumn);
StringBuilder query = new StringBuilder();
query.append("SELECT ").append(DBUtils.getQuotedIdentifier(keyColumn));
String descColumns = DBVUtils.getDictionaryDescriptionColumns(session.getProgressMonitor(), keyColumn);
if (descColumns != null) {
query.append(", ").append(descColumns);
}
query.append(" FROM ").append(DBUtils.getObjectFullName(this, DBPEvaluationContext.DML)).append(" WHERE ");
boolean hasCond = false;
// Preceeding keys
if (preceedingKeys != null && !preceedingKeys.isEmpty()) {
for (DBDAttributeValue pk : preceedingKeys) {
if (hasCond) query.append(" AND ");
query.append(DBUtils.getQuotedIdentifier(getDataSource(), pk.getAttribute().getName())).append(" = ?");
hasCond = true;
}
}
if (hasCond) query.append(" AND ");
query.append(DBUtils.getQuotedIdentifier(keyColumn)).append(" IN (");
for (int i = 0; i < keyValues.size(); i++) {
if (i > 0) query.append(",");
query.append("?");
}
query.append(")");
query.append(" ORDER BY ");
if (sortByValue) {
query.append(DBUtils.getQuotedIdentifier(keyColumn));
} else {
// Sort by description
query.append(descColumns);
}
if (!sortAsc) {
query.append(" DESC");
}
try (DBCStatement dbStat = session.prepareStatement(DBCStatementType.QUERY, query.toString(), false, false, false)) {
int paramPos = 0;
if (preceedingKeys != null && !preceedingKeys.isEmpty()) {
for (DBDAttributeValue precAttribute : preceedingKeys) {
DBDValueHandler precValueHandler = DBUtils.findValueHandler(session, precAttribute.getAttribute());
precValueHandler.bindValueObject(session, dbStat, precAttribute.getAttribute(), paramPos++, precAttribute.getValue());
}
}
for (Object value : keyValues) {
keyValueHandler.bindValueObject(session, dbStat, keyColumn, paramPos++, value);
}
dbStat.setLimit(0, keyValues.size());
if (dbStat.executeStatement()) {
try (DBCResultSet dbResult = dbStat.openResultSet()) {
return DBVUtils.readDictionaryRows(session, keyColumn, keyValueHandler, dbResult);
}
} else {
return Collections.emptyList();
}
}
}
private List<DBDLabelValuePair> readKeyEnumeration(
DBCSession session,
DBSEntityAttribute keyColumn,
Object keyPattern,
List<DBDAttributeValue> preceedingKeys,
boolean sortByValue,
boolean sortAsc,
int maxResults)
throws DBException
{
if (keyColumn.getParentObject() != this) {
throw new IllegalArgumentException("Bad key column argument");
}
DBDValueHandler keyValueHandler = DBUtils.findValueHandler(session, keyColumn);
if (keyPattern instanceof CharSequence && keyColumn.getDataKind() != DBPDataKind.NUMERIC) {
if (((CharSequence)keyPattern).length() > 0) {
keyPattern = "%" + keyPattern.toString() + "%";
} else {
keyPattern = null;
}
}
boolean searchInKeys = keyPattern != null;
if (keyPattern != null) {
if (keyColumn.getDataKind() == DBPDataKind.NUMERIC) {
if (keyPattern instanceof Number) {
// Subtract gap value to see some values before specified
int gapSize = maxResults / 2;
if (keyPattern instanceof Integer) {
keyPattern = (Integer) keyPattern - gapSize;
} else if (keyPattern instanceof Short) {
keyPattern = (Short) keyPattern - gapSize;
} else if (keyPattern instanceof Long) {
keyPattern = (Long) keyPattern - gapSize;
} else if (keyPattern instanceof Float) {
keyPattern = (Float) keyPattern - gapSize;
} else if (keyPattern instanceof Double) {
keyPattern = (Double) keyPattern - gapSize;
} else if (keyPattern instanceof BigInteger) {
keyPattern = ((BigInteger) keyPattern).subtract(BigInteger.valueOf(gapSize));
} else if (keyPattern instanceof BigDecimal) {
keyPattern = ((BigDecimal) keyPattern).subtract(new BigDecimal(gapSize));
} else {
searchInKeys = false;
}
} else if (keyPattern instanceof String) {
//searchInKeys = false;
// Ignore it
//keyPattern = Double.parseDouble((String) keyPattern) - gapSize;
}
} else if (keyPattern instanceof CharSequence && keyColumn.getDataKind() == DBPDataKind.STRING) {
// Its ok
} else {
searchInKeys = false;
}
}
StringBuilder query = new StringBuilder();
query.append("SELECT ").append(DBUtils.getQuotedIdentifier(keyColumn));
String descColumns = DBVUtils.getDictionaryDescriptionColumns(session.getProgressMonitor(), keyColumn);
Collection<DBSEntityAttribute> descAttributes = null;
if (descColumns != null) {
descAttributes = DBVEntity.getDescriptionColumns(session.getProgressMonitor(), this, descColumns);
query.append(", ").append(descColumns);
}
query.append(" FROM ").append(DBUtils.getObjectFullName(this, DBPEvaluationContext.DML));
boolean searchInDesc = keyPattern instanceof CharSequence && descAttributes != null;
if (searchInDesc) {
boolean hasStringAttrs = false;
for (DBSEntityAttribute descAttr : descAttributes) {
if (descAttr.getDataKind() == DBPDataKind.STRING) {
hasStringAttrs = true;
break;
}
}
if (!hasStringAttrs) {
searchInDesc = false;
}
}
if (!CommonUtils.isEmpty(preceedingKeys) || searchInKeys || searchInDesc) {
query.append(" WHERE ");
}
boolean hasCond = false;
// Preceeding keys
if (preceedingKeys != null && !preceedingKeys.isEmpty()) {
for (int i = 0; i < preceedingKeys.size(); i++) {
if (hasCond) query.append(" AND ");
query.append(DBUtils.getQuotedIdentifier(getDataSource(), preceedingKeys.get(i).getAttribute().getName())).append(" = ?");
hasCond = true;
}
}
if (keyPattern != null) {
if (hasCond) query.append(" AND (");
if (searchInKeys) {
query.append(DBUtils.getQuotedIdentifier(keyColumn));
if (keyColumn.getDataKind() == DBPDataKind.NUMERIC) {
query.append(" >= ?");
} else {
query.append(" LIKE ?");
}
}
}
// Add desc columns conditions
if (searchInDesc) {
boolean hasCondition = searchInKeys;
for (DBSEntityAttribute descAttr : descAttributes) {
if (descAttr.getDataKind() == DBPDataKind.STRING) {
if (hasCondition) {
query.append(" OR ");
}
query.append(DBUtils.getQuotedIdentifier(descAttr)).append(" LIKE ?");
hasCondition = true;
}
}
}
if (hasCond) query.append(")");
query.append(" ORDER BY ");
if (sortByValue) {
query.append(DBUtils.getQuotedIdentifier(keyColumn));
} else {
// Sort by description
query.append(descColumns);
}
if (!sortAsc) {
query.append(" DESC");
}
try (DBCStatement dbStat = session.prepareStatement(DBCStatementType.QUERY, query.toString(), false, false, false)) {
int paramPos = 0;
if (preceedingKeys != null && !preceedingKeys.isEmpty()) {
for (DBDAttributeValue precAttribute : preceedingKeys) {
DBDValueHandler precValueHandler = DBUtils.findValueHandler(session, precAttribute.getAttribute());
precValueHandler.bindValueObject(session, dbStat, precAttribute.getAttribute(), paramPos++, precAttribute.getValue());
}
}
if (keyPattern != null && searchInKeys) {
keyValueHandler.bindValueObject(session, dbStat, keyColumn, paramPos++, keyPattern);
}
if (searchInDesc) {
for (DBSEntityAttribute descAttr : descAttributes) {
if (descAttr.getDataKind() == DBPDataKind.STRING) {
final DBDValueHandler valueHandler = DBUtils.findValueHandler(session, descAttr);
valueHandler.bindValueObject(session, dbStat, keyColumn, paramPos++, keyPattern);
}
}
}
dbStat.setLimit(0, maxResults);
if (dbStat.executeStatement()) {
try (DBCResultSet dbResult = dbStat.openResultSet()) {
return DBVUtils.readDictionaryRows(session, keyColumn, keyValueHandler, dbResult);
}
} else {
return Collections.emptyList();
}
}
}
////////////////////////////////////////////////////////////////////
// Truncate
......
......@@ -18,41 +18,19 @@ package org.jkiss.dbeaver.model.impl.jdbc.struct;
import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.model.DBPDataKind;
import org.jkiss.dbeaver.model.DBPEvaluationContext;
import org.jkiss.dbeaver.model.DBPSaveableObject;
import org.jkiss.dbeaver.model.DBUtils;
import org.jkiss.dbeaver.model.data.DBDAttributeValue;
import org.jkiss.dbeaver.model.data.DBDLabelValuePair;
import org.jkiss.dbeaver.model.data.DBDValueHandler;
import org.jkiss.dbeaver.model.exec.DBCResultSet;
import org.jkiss.dbeaver.model.exec.DBCSession;
import org.jkiss.dbeaver.model.exec.DBCStatement;
import org.jkiss.dbeaver.model.exec.DBCStatementType;
import org.jkiss.dbeaver.model.impl.DBObjectNameCaseTransformer;
import org.jkiss.dbeaver.model.impl.struct.AbstractTableConstraint;
import org.jkiss.dbeaver.model.meta.Property;
import org.jkiss.dbeaver.model.struct.DBSConstraintEnumerable;
import org.jkiss.dbeaver.model.struct.DBSEntityAttribute;
import org.jkiss.dbeaver.model.struct.DBSEntityConstraint;
import org.jkiss.dbeaver.model.struct.DBSEntityConstraintType;
import org.jkiss.dbeaver.model.virtual.DBVEntity;
import org.jkiss.dbeaver.model.virtual.DBVUtils;
import org.jkiss.utils.CommonUtils;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
/**
* JDBC abstract constraint
*/
public abstract class JDBCTableConstraint<TABLE extends JDBCTable>
extends AbstractTableConstraint<TABLE>
implements DBSConstraintEnumerable, DBPSaveableObject
implements DBPSaveableObject
{
private boolean persisted;
......@@ -87,277 +65,4 @@ public abstract class JDBCTableConstraint<TABLE extends JDBCTable>
this.persisted = persisted;
}
/**
* Enumerations supported only for unique constraints
* @return true for unique constraint else otherwise
*/
@Override
public boolean supportsEnumeration() {
return getConstraintType().isUnique();
}
/**
* Returns prepared statements for enumeration fetch
* @param session execution context
* @param keyColumn enumeration column.
* @param keyPattern pattern for enumeration values. If null or empty then returns full enumration set
* @param preceedingKeys other constrain key values. May be null.
* @param sortByValue sort results by eky value. If false then sort by description
* @param sortAsc sort ascending/descending
* @param maxResults maximum enumeration values in result set @return @throws DBException
*/
@Override
public List<DBDLabelValuePair> getKeyEnumeration(
DBCSession session,
DBSEntityAttribute keyColumn,
Object keyPattern,
List<DBDAttributeValue> preceedingKeys,
boolean sortByValue,
boolean sortAsc,
int maxResults)
throws DBException
{
// Use default one
return readKeyEnumeration(
session,
keyColumn,
keyPattern,
preceedingKeys,
sortByValue,
sortAsc,
maxResults);
}
@Override
public List<DBDLabelValuePair> getKeyEnumeration(DBCSession session, DBSEntityAttribute keyColumn, @NotNull List<Object> keyValues, List<DBDAttributeValue> preceedingKeys, boolean sortByValue, boolean sortAsc) throws DBException {
final TABLE table = getParentObject();
DBDValueHandler keyValueHandler = DBUtils.findValueHandler(session, keyColumn);
StringBuilder query = new StringBuilder();
query.append("SELECT ").append(DBUtils.getQuotedIdentifier(keyColumn));
String descColumns = DBVUtils.getDictionaryDescriptionColumns(session.getProgressMonitor(), keyColumn);
if (descColumns != null) {
query.append(", ").append(descColumns);
}
query.append(" FROM ").append(DBUtils.getObjectFullName(table, DBPEvaluationContext.DML)).append(" WHERE ");
boolean hasCond = false;
// Preceeding keys
if (preceedingKeys != null && !preceedingKeys.isEmpty()) {
for (DBDAttributeValue pk : preceedingKeys) {
if (hasCond) query.append(" AND ");
query.append(DBUtils.getQuotedIdentifier(getDataSource(), pk.getAttribute().getName())).append(" = ?");
hasCond = true;
}
}
if (hasCond) query.append(" AND ");
query.append(DBUtils.getQuotedIdentifier(keyColumn)).append(" IN (");
for (int i = 0; i < keyValues.size(); i++) {
if (i > 0) query.append(",");
query.append("?");
}
query.append(")");
query.append(" ORDER BY ");
if (sortByValue) {
query.append(DBUtils.getQuotedIdentifier(keyColumn));
} else {
// Sort by description
query.append(descColumns);
}
if (!sortAsc) {
query.append(" DESC");
}
try (DBCStatement dbStat = session.prepareStatement(DBCStatementType.QUERY, query.toString(), false, false, false)) {
int paramPos = 0;
if (preceedingKeys != null && !preceedingKeys.isEmpty()) {
for (DBDAttributeValue precAttribute : preceedingKeys) {
DBDValueHandler precValueHandler = DBUtils.findValueHandler(session, precAttribute.getAttribute());
precValueHandler.bindValueObject(session, dbStat, precAttribute.getAttribute(), paramPos++, precAttribute.getValue());
}
}
for (Object value : keyValues) {
keyValueHandler.bindValueObject(session, dbStat, keyColumn, paramPos++, value);
}
dbStat.setLimit(0, keyValues.size());
if (dbStat.executeStatement()) {
try (DBCResultSet dbResult = dbStat.openResultSet()) {
return DBVUtils.readDictionaryRows(session, keyColumn, keyValueHandler, dbResult);
}
} else {
return Collections.emptyList();
}
}
}
private List<DBDLabelValuePair> readKeyEnumeration(
DBCSession session,
DBSEntityAttribute keyColumn,
Object keyPattern,
List<DBDAttributeValue> preceedingKeys,
boolean sortByValue,
boolean sortAsc,
int maxResults)
throws DBException
{
if (keyColumn.getParentObject() != this.getTable()) {
throw new IllegalArgumentException("Bad key column argument");
}
final TABLE table = getParentObject();
assert table != null;
DBDValueHandler keyValueHandler = DBUtils.findValueHandler(session, keyColumn);
if (keyPattern instanceof CharSequence && keyColumn.getDataKind() != DBPDataKind.NUMERIC) {
if (((CharSequence)keyPattern).length() > 0) {
keyPattern = "%" + keyPattern.toString() + "%";
} else {
keyPattern = null;
}
}
boolean searchInKeys = keyPattern != null;
if (keyPattern != null) {
if (keyColumn.getDataKind() == DBPDataKind.NUMERIC) {
if (keyPattern instanceof Number) {
// Subtract gap value to see some values before specified
int gapSize = maxResults / 2;
if (keyPattern instanceof Integer) {
keyPattern = (Integer) keyPattern - gapSize;
} else if (keyPattern instanceof Short) {
keyPattern = (Short) keyPattern - gapSize;
} else if (keyPattern instanceof Long) {
keyPattern = (Long) keyPattern - gapSize;
} else if (keyPattern instanceof Float) {
keyPattern = (Float) keyPattern - gapSize;
} else if (keyPattern instanceof Double) {
keyPattern = (Double) keyPattern - gapSize;
} else if (keyPattern instanceof BigInteger) {
keyPattern = ((BigInteger) keyPattern).subtract(BigInteger.valueOf(gapSize));
} else if (keyPattern instanceof BigDecimal) {
keyPattern = ((BigDecimal) keyPattern).subtract(new BigDecimal(gapSize));
} else {
searchInKeys = false;
}
} else if (keyPattern instanceof String) {
//searchInKeys = false;
// Ignore it
//keyPattern = Double.parseDouble((String) keyPattern) - gapSize;
}
} else if (keyPattern instanceof CharSequence && keyColumn.getDataKind() == DBPDataKind.STRING) {
// Its ok
} else {
searchInKeys = false;
}
}
StringBuilder query = new StringBuilder();
query.append("SELECT ").append(DBUtils.getQuotedIdentifier(keyColumn));
String descColumns = DBVUtils.getDictionaryDescriptionColumns(session.getProgressMonitor(), keyColumn);
Collection<DBSEntityAttribute> descAttributes = null;
if (descColumns != null) {
descAttributes = DBVEntity.getDescriptionColumns(session.getProgressMonitor(), table, descColumns);
query.append(", ").append(descColumns);
}
query.append(" FROM ").append(DBUtils.getObjectFullName(table, DBPEvaluationContext.DML));
boolean searchInDesc = keyPattern instanceof CharSequence && descAttributes != null;
if (searchInDesc) {
boolean hasStringAttrs = false;
for (DBSEntityAttribute descAttr : descAttributes) {
if (descAttr.getDataKind() == DBPDataKind.STRING) {
hasStringAttrs = true;
break;
}
}
if (!hasStringAttrs) {
searchInDesc = false;
}
}
if (!CommonUtils.isEmpty(preceedingKeys) || searchInKeys || searchInDesc) {
query.append(" WHERE ");
}
boolean hasCond = false;
// Preceeding keys
if (preceedingKeys != null && !preceedingKeys.isEmpty()) {
for (int i = 0; i < preceedingKeys.size(); i++) {
if (hasCond) query.append(" AND ");
query.append(DBUtils.getQuotedIdentifier(getDataSource(), preceedingKeys.get(i).getAttribute().getName())).append(" = ?");
hasCond = true;
}
}
if (keyPattern != null) {
if (hasCond) query.append(" AND (");
if (searchInKeys) {
query.append(DBUtils.getQuotedIdentifier(keyColumn));
if (keyColumn.getDataKind() == DBPDataKind.NUMERIC) {
query.append(" >= ?");
} else {
query.append(" LIKE ?");
}
}
}
// Add desc columns conditions
if (searchInDesc) {
boolean hasCondition = searchInKeys;
for (DBSEntityAttribute descAttr : descAttributes) {
if (descAttr.getDataKind() == DBPDataKind.STRING) {
if (hasCondition) {
query.append(" OR ");
}
query.append(DBUtils.getQuotedIdentifier(descAttr)).append(" LIKE ?");
hasCondition = true;
}
}
}
if (hasCond) query.append(")");
query.append(" ORDER BY ");
if (sortByValue) {
query.append(DBUtils.getQuotedIdentifier(keyColumn));
} else {
// Sort by description
query.append(descColumns);
}
if (!sortAsc) {
query.append(" DESC");
}
try (DBCStatement dbStat = session.prepareStatement(DBCStatementType.QUERY, query.toString(), false, false, false)) {
int paramPos = 0;
if (preceedingKeys != null && !preceedingKeys.isEmpty()) {
for (DBDAttributeValue precAttribute : preceedingKeys) {
DBDValueHandler precValueHandler = DBUtils.findValueHandler(session, precAttribute.getAttribute());
precValueHandler.bindValueObject(session, dbStat, precAttribute.getAttribute(), paramPos++, precAttribute.getValue());
}
}
if (keyPattern != null && searchInKeys) {
keyValueHandler.bindValueObject(session, dbStat, keyColumn, paramPos++, keyPattern);
}
if (searchInDesc) {
for (DBSEntityAttribute descAttr : descAttributes) {
if (descAttr.getDataKind() == DBPDataKind.STRING) {
final DBDValueHandler valueHandler = DBUtils.findValueHandler(session, descAttr);
valueHandler.bindValueObject(session, dbStat, keyColumn, paramPos++, keyPattern);
}
}
}
dbStat.setLimit(0, maxResults);
if (dbStat.executeStatement()) {
try (DBCResultSet dbResult = dbStat.openResultSet()) {
return DBVUtils.readDictionaryRows(session, keyColumn, keyValueHandler, dbResult);
}
} else {
return Collections.emptyList();
}
}
}
}
......@@ -32,8 +32,10 @@ import org.jkiss.dbeaver.model.app.DBPPlatform;
import org.jkiss.dbeaver.model.app.DBPProject;
import org.jkiss.dbeaver.model.navigator.meta.DBXTreeFolder;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.struct.DBSEntity;
import org.jkiss.dbeaver.model.struct.DBSObject;
import org.jkiss.dbeaver.model.struct.DBSObjectState;
import org.jkiss.dbeaver.model.virtual.DBVUtils;
import org.jkiss.dbeaver.runtime.DBWorkbench;
import org.jkiss.dbeaver.utils.RuntimeUtils;
import org.jkiss.utils.ArrayUtils;
......@@ -191,6 +193,13 @@ public class DBNModel implements IResourceChangeListener {
@Nullable
public DBNDatabaseNode getNodeByObject(DBRProgressMonitor monitor, DBSObject object, boolean addFiltered)
{
if (object instanceof DBSEntity) {
try {
object = DBVUtils.getRealEntity(monitor, (DBSEntity)object);
} catch (DBException e) {
log.debug("Error dereferencing virtual entity", e);
}
}
DBNDatabaseNode node = getNodeByObject(object);
if (node != null) {
return node;
......
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2019 Serge Rider (serge@jkiss.org)
*
* 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.
*/
package org.jkiss.dbeaver.model.struct;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.model.data.DBDAttributeValue;
import org.jkiss.dbeaver.model.data.DBDLabelValuePair;
import org.jkiss.dbeaver.model.exec.DBCSession;
import java.util.List;
/**
* Enumerable Constraint.
* May return possible values for one of constraint's key.
*/
public interface DBSConstraintEnumerable extends DBSEntityConstraint
{
/**
* Checks that this constrain supports key enumerations.
* Usually it depends on constraint type (enumerations makes sense only for unique constraints).
* @return true or false
*/
boolean supportsEnumeration();
/**
* Gets enumeration values
* @param session
* @param keyColumn enumeration column.
* @param keyPattern pattern for enumeration values. If null or empty then returns full enumration set
* @param preceedingKeys other constrain key values. May be null.
* @param sortByValue
* @param sortAsc
* @param maxResults maximum enumeration values in result set @return statement with result set which contains valid enumeration values. */
List<DBDLabelValuePair> getKeyEnumeration(
DBCSession session,
DBSEntityAttribute keyColumn,
Object keyPattern,
@Nullable List<DBDAttributeValue> preceedingKeys,
boolean sortByValue,
boolean sortAsc,
int maxResults)
throws DBException;
List<DBDLabelValuePair> getKeyEnumeration(
DBCSession session,
DBSEntityAttribute keyColumn,
List<Object> keyValues,
@Nullable List<DBDAttributeValue> preceedingKeys,
boolean sortByValue,
boolean sortAsc)
throws DBException;
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2019 Serge Rider (serge@jkiss.org)
*
* 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.
*/
package org.jkiss.dbeaver.model.struct;
import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.model.data.DBDAttributeValue;
import org.jkiss.dbeaver.model.data.DBDLabelValuePair;
import org.jkiss.dbeaver.model.exec.DBCSession;
import java.util.List;
/**
* Dictionary table (entity).
* May return possible values for a set of attributes.
*/
public interface DBSDictionary
{
/**
* Checks that this constrain supports key enumerations.
* Usually it depends on constraint type (enumerations makes sense only for unique constraints).
* @return true or false
*/
boolean supportsDictionaryEnumeration();
/**
* Gets enumeration values
* @param session session
* @param keyColumn enumeration column.
* @param keyPattern pattern for enumeration values. If null or empty then returns full enumration set
* @param preceedingKeys other constrain key values. May be null.
* @param sortByValue sort results by value
* @param sortAsc ascending sorting (irrelevant is @sortByValue is false)
* @param maxResults maximum enumeration values in result set
* @return statement with result set which contains valid enumeration values.
*/
@NotNull
List<DBDLabelValuePair> getDictionaryEnumeration(
@NotNull DBCSession session,
@NotNull DBSEntityAttribute keyColumn,
Object keyPattern,
@Nullable List<DBDAttributeValue> preceedingKeys,
boolean sortByValue,
boolean sortAsc,
int maxResults)
throws DBException;
@NotNull
List<DBDLabelValuePair> getDictionaryValues(
@NotNull DBCSession session,
@NotNull DBSEntityAttribute keyColumn,
@NotNull List<Object> keyValues,
@Nullable List<DBDAttributeValue> preceedingKeys,
boolean sortByValue,
boolean sortAsc)
throws DBException;
}
\ No newline at end of file
......@@ -22,8 +22,11 @@ import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.model.*;
import org.jkiss.dbeaver.model.data.DBDAttributeBinding;
import org.jkiss.dbeaver.model.data.DBDAttributeValue;
import org.jkiss.dbeaver.model.data.DBDLabelValuePair;
import org.jkiss.dbeaver.model.data.json.JSONUtils;
import org.jkiss.dbeaver.model.exec.DBCLogicalOperator;
import org.jkiss.dbeaver.model.exec.DBCSession;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.struct.*;
import org.jkiss.utils.CommonUtils;
......@@ -33,7 +36,7 @@ import java.util.*;
/**
* Virtual entity descriptor
*/
public class DBVEntity extends DBVObject implements DBSEntity, DBPQualifiedObject, IAdaptable {
public class DBVEntity extends DBVObject implements DBSEntity, DBPQualifiedObject, DBSDictionary, IAdaptable {
private static final String[] DESC_COLUMN_PATTERNS = {
"title",
......@@ -587,4 +590,26 @@ public class DBVEntity extends DBVObject implements DBSEntity, DBPQualifiedObjec
return null;
}
@Override
public boolean supportsDictionaryEnumeration() {
return true;
}
@NotNull
@Override
public List<DBDLabelValuePair> getDictionaryEnumeration(@NotNull DBCSession session, @NotNull DBSEntityAttribute keyColumn, Object keyPattern, @Nullable List<DBDAttributeValue> preceedingKeys, boolean sortByValue, boolean sortAsc, int maxResults) throws DBException {
DBSEntity realEntity = getRealEntity(session.getProgressMonitor());
return realEntity instanceof DBSDictionary ?
((DBSDictionary) realEntity).getDictionaryEnumeration(session, keyColumn, keyPattern, preceedingKeys, sortByValue, sortAsc, maxResults) :
Collections.emptyList();
}
@NotNull
@Override
public List<DBDLabelValuePair> getDictionaryValues(@NotNull DBCSession session, @NotNull DBSEntityAttribute keyColumn, @NotNull List<Object> keyValues, @Nullable List<DBDAttributeValue> preceedingKeys, boolean sortByValue, boolean sortAsc) throws DBException {
DBSEntity realEntity = getRealEntity(session.getProgressMonitor());
return realEntity instanceof DBSDictionary ?
((DBSDictionary) realEntity).getDictionaryValues(session, keyColumn, keyValues, preceedingKeys, sortByValue, sortAsc) :
Collections.emptyList();
}
}
......@@ -18,11 +18,7 @@ package org.jkiss.dbeaver.model.virtual;
import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.model.DBPDataSource;
import org.jkiss.dbeaver.model.data.DBDAttributeValue;
import org.jkiss.dbeaver.model.data.DBDLabelValuePair;
import org.jkiss.dbeaver.model.exec.DBCSession;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.struct.*;
......@@ -33,7 +29,7 @@ import java.util.List;
/**
* Virtual constraint
*/
public class DBVEntityConstraint implements DBSEntityConstraint, DBSEntityReferrer, DBSConstraintEnumerable
public class DBVEntityConstraint implements DBSEntityConstraint, DBSEntityReferrer
{
@NotNull
private final DBVEntity entity;
......@@ -143,22 +139,4 @@ public class DBVEntityConstraint implements DBSEntityConstraint, DBSEntityReferr
return null;
}
@Override
public boolean supportsEnumeration() {
return getEnumAttr() != null;
}
@Override
public List<DBDLabelValuePair> getKeyEnumeration(DBCSession session, DBSEntityAttribute keyColumn, Object keyPattern, @Nullable List<DBDAttributeValue> preceedingKeys, boolean sortByValue, boolean sortAsc, int maxResults) throws DBException {
DBSAttributeEnumerable enumAttr = getEnumAttr();
if (enumAttr == null) {
throw new DBException("Enumeration not supported");
}
return enumAttr.getValueEnumeration(session, keyPattern, maxResults);
}
@Override
public List<DBDLabelValuePair> getKeyEnumeration(DBCSession session, DBSEntityAttribute keyColumn, List<Object> keyValues, @Nullable List<DBDAttributeValue> preceedingKeys, boolean sortByValue, boolean sortAsc) throws DBException {
throw new DBException("Multi-key enumeration is not supported");
}
}
......@@ -202,9 +202,9 @@ class GenericFilterValueEdit {
}
final DBSEntityAttribute fkAttribute = fkColumn.getAttribute();
final DBSEntityConstraint refConstraint = association.getReferencedConstraint();
final DBSConstraintEnumerable enumConstraint = (DBSConstraintEnumerable) refConstraint;
final DBSDictionary enumConstraint = (DBSDictionary) refConstraint.getParentObject();
if (fkAttribute != null && enumConstraint != null) {
return enumConstraint.getKeyEnumeration(
return enumConstraint.getDictionaryEnumeration(
session,
refColumn,
filterPattern,
......
......@@ -107,10 +107,10 @@ public class ReferenceValueEditor {
List<DBSEntityReferrer> refs = DBUtils.getAttributeReferrers(new VoidProgressMonitor(), entityAttribute, true);
DBSEntityReferrer constraint = refs.isEmpty() ? null : refs.get(0);
if (constraint instanceof DBSEntityAssociation &&
((DBSEntityAssociation)constraint).getReferencedConstraint() instanceof DBSConstraintEnumerable)
((DBSEntityAssociation)constraint).getAssociatedEntity() instanceof DBSDictionary)
{
final DBSConstraintEnumerable refConstraint = (DBSConstraintEnumerable) ((DBSEntityAssociation) constraint).getReferencedConstraint();
if (refConstraint != null && refConstraint.supportsEnumeration()) {
final DBSDictionary dictionary = (DBSDictionary) ((DBSEntityAssociation) constraint).getAssociatedEntity();
if (dictionary != null && dictionary.supportsDictionaryEnumeration()) {
return constraint;
}
}
......@@ -494,13 +494,13 @@ public class ReferenceValueEditor {
}
final DBSEntityAttribute fkAttribute = fkColumn.getAttribute();
final DBSEntityConstraint refConstraint = association.getReferencedConstraint();
final DBSConstraintEnumerable enumConstraint = (DBSConstraintEnumerable) refConstraint;
final DBSDictionary enumConstraint = (DBSDictionary) refConstraint.getParentObject();
if (fkAttribute != null && enumConstraint != null) {
try (DBCSession session = valueController.getExecutionContext().openSession(
monitor,
DBCExecutionPurpose.UTIL,
NLS.bind(ResultSetMessages.dialog_value_view_context_name, fkAttribute.getName()))) {
Collection<DBDLabelValuePair> enumValues = enumConstraint.getKeyEnumeration(
Collection<DBDLabelValuePair> enumValues = enumConstraint.getDictionaryEnumeration(
session,
refColumn,
pattern,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册