/*
* DBeaver - Universal Database Manager
* Copyright (C) 2013-2015 Denis Forveille (titou10.titou10@gmail.com)
* Copyright (C) 2010-2017 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.ext.db2.editors;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.ext.db2.model.DB2Alias;
import org.jkiss.dbeaver.ext.db2.model.DB2DataSource;
import org.jkiss.dbeaver.ext.db2.model.DB2DataType;
import org.jkiss.dbeaver.ext.db2.model.DB2Index;
import org.jkiss.dbeaver.ext.db2.model.DB2MaterializedQueryTable;
import org.jkiss.dbeaver.ext.db2.model.DB2Package;
import org.jkiss.dbeaver.ext.db2.model.DB2Routine;
import org.jkiss.dbeaver.ext.db2.model.DB2Schema;
import org.jkiss.dbeaver.ext.db2.model.DB2Sequence;
import org.jkiss.dbeaver.ext.db2.model.DB2Table;
import org.jkiss.dbeaver.ext.db2.model.DB2TableCheckConstraint;
import org.jkiss.dbeaver.ext.db2.model.DB2TableColumn;
import org.jkiss.dbeaver.ext.db2.model.DB2TableForeignKey;
import org.jkiss.dbeaver.ext.db2.model.DB2TableReference;
import org.jkiss.dbeaver.ext.db2.model.DB2TableUniqueKey;
import org.jkiss.dbeaver.ext.db2.model.DB2Tablespace;
import org.jkiss.dbeaver.ext.db2.model.DB2Trigger;
import org.jkiss.dbeaver.ext.db2.model.DB2Variable;
import org.jkiss.dbeaver.ext.db2.model.DB2View;
import org.jkiss.dbeaver.ext.db2.model.DB2XMLSchema;
import org.jkiss.dbeaver.ext.db2.model.fed.DB2Nickname;
import org.jkiss.dbeaver.ext.db2.model.module.DB2Module;
import org.jkiss.dbeaver.model.DBPImage;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.struct.DBSObject;
import org.jkiss.dbeaver.model.struct.DBSObjectType;
import org.jkiss.dbeaver.model.DBIcon;
import java.util.HashMap;
import java.util.Map;
/**
* DB2 Object type used by Search, Content Assist and object dependency resolution
*
* @author Denis Forveille
*/
public enum DB2ObjectType implements DBSObjectType {
ALIAS(DBIcon.TREE_SYNONYM, DB2Alias.class, new ObjectFinder() {
@Override
public DB2Alias findObject(DBRProgressMonitor monitor, DB2Schema schema, String objectName) throws DBException
{
return schema.getAliasCache().getObject(monitor, schema, objectName);
}
}),
CHECK(DBIcon.TREE_CONSTRAINT, DB2TableCheckConstraint.class, new ObjectFinder() {
@Override
public DB2TableCheckConstraint findObject(DBRProgressMonitor monitor, DB2Schema schema, String objectName)
throws DBException
{
return schema.getCheckCache().getObject(monitor, schema, objectName);
}
}),
COLUMN(DBIcon.TREE_COLUMN, DB2TableColumn.class, new ObjectFinder() {
@Override
public DB2TableColumn findObject(DBRProgressMonitor monitor, DB2Table db2Table, String objectName) throws DBException
{
return db2Table.getAttribute(monitor, objectName);
}
@Override
public DB2TableColumn findObject(DBRProgressMonitor monitor, DB2View db2View, String objectName) throws DBException
{
return db2View.getAttribute(monitor, objectName);
}
}),
FOREIGN_KEY(DBIcon.TREE_FOREIGN_KEY, DB2TableForeignKey.class, new ObjectFinder() {
@Override
public DB2TableForeignKey findObject(DBRProgressMonitor monitor, DB2Schema schema, String objectName) throws DBException
{
return schema.getAssociationCache().getObject(monitor, schema, objectName);
}
}),
MODULE(DBIcon.TREE_PACKAGE, DB2Module.class, new ObjectFinder() {
@Override
public DB2Module findObject(DBRProgressMonitor monitor, DB2Schema schema, String objectName) throws DBException
{
return schema.getModuleCache().getObject(monitor, schema, objectName);
}
}),
MQT(DBIcon.TREE_TABLE, DB2MaterializedQueryTable.class, new ObjectFinder() {
@Override
public DB2MaterializedQueryTable findObject(DBRProgressMonitor monitor, DB2Schema schema, String objectName)
throws DBException
{
return schema.getMaterializedQueryTableCache().getObject(monitor, schema, objectName);
}
}),
INDEX(DBIcon.TREE_INDEX, DB2Index.class, new ObjectFinder() {
@Override
public DB2Index findObject(DBRProgressMonitor monitor, DB2Schema schema, String objectName) throws DBException
{
return schema.getIndexCache().getObject(monitor, schema, objectName);
}
}),
NICKNAME(DBIcon.TREE_SYNONYM, DB2View.class, new ObjectFinder() {
@Override
public DB2Nickname findObject(DBRProgressMonitor monitor, DB2Schema schema, String objectName) throws DBException
{
return schema.getNicknameCache().getObject(monitor, schema, objectName, DB2Nickname.class);
}
}),
PACKAGE(DBIcon.TREE_PACKAGE, DB2Package.class, new ObjectFinder() {
@Override
public DB2Package findObject(DBRProgressMonitor monitor, DB2Schema schema, String objectName) throws DBException
{
return schema.getPackageCache().getObject(monitor, schema, objectName);
}
}),
PROCEDURE(DBIcon.TREE_PROCEDURE, DB2Routine.class, new ObjectFinder() {
@Override
public DB2Routine findObject(DBRProgressMonitor monitor, DB2Schema schema, String objectName) throws DBException
{
// Procedure may be global or from a Module
DB2Routine procedure;
String[] tokens = objectName.split(SPLIT_DOT);
if (tokens.length == 1) {
procedure = schema.getProcedureCache().getObject(monitor, schema, tokens[0]);
} else {
DB2Module module = schema.getModuleCache().getObject(monitor, schema, tokens[0]);
procedure = module.getProcedureCache().getObject(monitor, module, tokens[1]);
}
return procedure;
}
}),
REFERENCE(DBIcon.TREE_REFERENCE, DB2TableReference.class, new ObjectFinder() {
@Override
public DB2TableReference findObject(DBRProgressMonitor monitor, DB2Schema schema, String objectName) throws DBException
{
return schema.getReferenceCache().getObject(monitor, schema, objectName);
}
}),
ROUTINE(DBIcon.TREE_PROCEDURE, DB2Routine.class, new ObjectFinder() {
@Override
public DB2Routine findObject(DBRProgressMonitor monitor, DB2Schema schema, String objectName) throws DBException
{
// Routines may be an UDF, a Method or a Procedure
// Routines may be global or from a Module
DB2Routine routine;
String[] tokens = objectName.split(SPLIT_DOT);
if (tokens.length == 1) {
routine = schema.getUdfCache().getObject(monitor, schema, tokens[0]);
if (routine == null) {
routine = schema.getProcedureCache().getObject(monitor, schema, tokens[0]);
if (routine == null) {
routine = schema.getMethodCache().getObject(monitor, schema, tokens[0]);
}
}
} else {
DB2Module module = schema.getModuleCache().getObject(monitor, schema, tokens[0]);
routine = module.getFunctionCache().getObject(monitor, module, tokens[1]);
if (routine == null) {
routine = module.getProcedureCache().getObject(monitor, module, tokens[1]);
if (routine == null) {
routine = module.getMethodCache().getObject(monitor, module, tokens[1]);
}
}
}
return routine;
}
}),
SCHEMA(DBIcon.TREE_SCHEMA, DB2Schema.class, null),
SEQUENCE(DBIcon.TREE_SEQUENCE, DB2Sequence.class, new ObjectFinder() {
@Override
public DB2Sequence findObject(DBRProgressMonitor monitor, DB2Schema schema, String objectName) throws DBException
{
return schema.getSequenceCache().getObject(monitor, schema, objectName);
}
}),
TABLE(DBIcon.TREE_TABLE, DB2Table.class, new ObjectFinder() {
@Override
public DB2Table findObject(DBRProgressMonitor monitor, DB2Schema schema, String objectName) throws DBException
{
return schema.getTableCache().getObject(monitor, schema, objectName);
}
}),
TABLESPACE(DBIcon.TREE_TABLESPACE, DB2Tablespace.class, new ObjectFinder() {
@Override
public DB2Tablespace findObject(DBRProgressMonitor monitor, DB2DataSource db2DataSource, String objectName)
throws DBException
{
return db2DataSource.getTablespace(monitor, objectName);
}
}),
TRIGGER(DBIcon.TREE_TABLE, DB2Trigger.class, new ObjectFinder() {
@Override
public DB2Trigger findObject(DBRProgressMonitor monitor, DB2Schema schema, String objectName) throws DBException
{
return schema.getTriggerCache().getObject(monitor, schema, objectName);
}
}),
UDF(DBIcon.TREE_PROCEDURE, DB2Routine.class, new ObjectFinder() {
@Override
public DB2Routine findObject(DBRProgressMonitor monitor, DB2Schema schema, String objectName) throws DBException
{
// Function may be global or from a Module
DB2Routine udf;
String[] tokens = objectName.split(SPLIT_DOT);
if (tokens.length == 1) {
udf = schema.getUdfCache().getObject(monitor, schema, tokens[0]);
} else {
DB2Module module = schema.getModuleCache().getObject(monitor, schema, tokens[0]);
udf = module.getFunctionCache().getObject(monitor, module, tokens[1]);
}
return udf;
}
}),
UDT(DBIcon.TREE_DATA_TYPE, DB2DataType.class, new ObjectFinder() {
@Override
public DB2DataType findObject(DBRProgressMonitor monitor, DB2Schema schema, String objectName) throws DBException
{
// Type may be global or from a Module
String[] tokens = objectName.split(SPLIT_DOT);
if (tokens.length == 1) {
return schema.getUdtCache().getObject(monitor, schema, tokens[0]);
} else {
DB2Module module = schema.getModuleCache().getObject(monitor, schema, tokens[0]);
return module.getTypeCache().getObject(monitor, module, tokens[1]);
}
}
}),
UNIQUE_KEY(DBIcon.TREE_UNIQUE_KEY, DB2TableUniqueKey.class, new ObjectFinder() {
@Override
public DB2TableUniqueKey findObject(DBRProgressMonitor monitor, DB2Schema schema, String objectName) throws DBException
{
return schema.getConstraintCache().getObject(monitor, schema, objectName);
}
}),
VIEW(DBIcon.TREE_VIEW, DB2View.class, new ObjectFinder() {
@Override
public DB2View findObject(DBRProgressMonitor monitor, DB2Schema schema, String objectName) throws DBException
{
return schema.getViewCache().getObject(monitor, schema, objectName, DB2View.class);
}
}),
VARIABLE(DBIcon.TREE_ATTRIBUTE, DB2Variable.class, new ObjectFinder() {
@Override
public DB2Variable findObject(DBRProgressMonitor monitor, DB2Schema schema, String objectName) throws DBException
{
// Variable may be global or from a Module
DB2Variable variable;
DB2DataSource db2DataSource = schema.getDataSource();
String[] tokens = objectName.split(SPLIT_DOT);
if (tokens.length == 1) {
variable = db2DataSource.getVariableCache().getObject(monitor, db2DataSource, tokens[0]);
} else {
DB2Module module = schema.getModuleCache().getObject(monitor, schema, tokens[0]);
variable = module.getVariableCache().getObject(monitor, module, tokens[1]);
}
return variable;
}
}),
XML_SCHEMA(DBIcon.TREE_DATA_TYPE, DB2XMLSchema.class, new ObjectFinder() {
@Override
public DB2XMLSchema findObject(DBRProgressMonitor monitor, DB2Schema schema, String objectName) throws DBException
{
return schema.getXmlSchemaCache().getObject(monitor, schema, objectName);
}
});
private final static Log LOG = Log.getLog(DB2ObjectType.class);
private final static String SPLIT_DOT = "\\.";
private final DBPImage image;
private final Class<? extends DBSObject> typeClass;
private final ObjectFinder finder;
// -----------
// Constructor
// -----------
<OBJECT_TYPE extends DBSObject> DB2ObjectType(DBPImage image, Class<OBJECT_TYPE> typeClass, ObjectFinder finder)
{
this.image = image;
this.typeClass = typeClass;
this.finder = finder;
}
@Override
public String getTypeName()
{
return this.name();
}
public boolean isBrowsable()
{
return finder != null;
}
public DBSObject findObject(DBRProgressMonitor monitor, DB2DataSource db2DataSource, String objectName) throws DBException
{
if (finder != null) {
return finder.findObject(monitor, db2DataSource, objectName);
} else {
return null;
}
}
public DBSObject findObject(DBRProgressMonitor monitor, DB2Schema schema, String objectName) throws DBException
{
if (finder != null) {
return finder.findObject(monitor, schema, objectName);
} else {
return null;
}
}
public DBSObject findObject(DBRProgressMonitor monitor, DB2Table db2Table, String objectName) throws DBException
{
if (finder != null) {
return finder.findObject(monitor, db2Table, objectName);
} else {
return null;
}
}
public DBSObject findObject(DBRProgressMonitor monitor, DB2View db2View, String objectName) throws DBException
{
if (finder != null) {
return finder.findObject(monitor, db2View, objectName);
} else {
return null;
}
}
// ----------------
// Standard Getters
// ----------------
@Override
public String getDescription()
{
return null;
}
@Override
public DBPImage getImage()
{
return image;
}
@Override
public Class<? extends DBSObject> getTypeClass()
{
return typeClass;
}
// ----------------
// Helpers
// ----------------
private static class ObjectFinder {
DBSObject findObject(DBRProgressMonitor monitor, DB2DataSource db2DataSource, String objectName) throws DBException
{
return null;
}
DBSObject findObject(DBRProgressMonitor monitor, DB2Schema schema, String objectName) throws DBException
{
return null;
}
DBSObject findObject(DBRProgressMonitor monitor, DB2Table db2Table, String objectName) throws DBException
{
return null;
}
DBSObject findObject(DBRProgressMonitor monitor, DB2View db2View, String objectName) throws DBException
{
return null;
}
}
public static DB2ObjectType getByType(String typeName)
{
return typeMap.get(typeName);
}
// TODO DF: to be factorised
public static Object resolveObject(DBRProgressMonitor monitor, DB2DataSource dataSource, String objectTypeName,
String objectOwner, String objectName) throws DBException
{
DB2ObjectType objectType = DB2ObjectType.getByType(objectTypeName);
if (objectType == null) {
LOG.debug("Unrecognized object type: " + objectTypeName);
return objectName;
}
if (!objectType.isBrowsable()) {
LOG.debug("Unsupported object type: " + objectTypeName);
return objectName;
}
final DB2Schema schema = dataSource.getSchema(monitor, objectOwner);
if (schema == null) {
LOG.debug("Schema '" + objectOwner + "' not found");
return objectName;
}
final DBSObject object = objectType.findObject(monitor, schema, objectName);
if (object == null) {
LOG.debug(objectTypeName + " '" + objectName + "' not found in '" + schema.getName() + "'");
return objectName;
}
return object;
}
// ---
// Init
// ---
private static Map<String, DB2ObjectType> typeMap = new HashMap<>();
static {
for (DB2ObjectType type : values()) {
typeMap.put(type.getTypeName(), type);
}
}
}