/* * DBeaver - Universal Database Manager * 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.postgresql.model; import org.jkiss.code.NotNull; import org.jkiss.code.Nullable; import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.Log; import org.jkiss.dbeaver.model.DBPEvaluationContext; import org.jkiss.dbeaver.model.DBUtils; import org.jkiss.dbeaver.model.exec.jdbc.JDBCResultSet; import org.jkiss.dbeaver.model.impl.jdbc.JDBCUtils; import org.jkiss.dbeaver.model.meta.Property; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; import org.jkiss.dbeaver.model.struct.DBSEntityConstraint; import org.jkiss.dbeaver.model.struct.DBSEntityConstraintType; import org.jkiss.dbeaver.model.struct.rdb.DBSForeignKeyModifyRule; import org.jkiss.dbeaver.model.struct.rdb.DBSTableForeignKey; import java.util.ArrayList; import java.util.Collection; import java.util.List; /** * PostgreTableForeignKey */ public class PostgreTableForeignKey extends PostgreTableConstraintBase implements DBSTableForeignKey { private static final Log log = Log.getLog(PostgreTableForeignKey.class); private DBSForeignKeyModifyRule updateRule; private DBSForeignKeyModifyRule deleteRule; private DBSEntityConstraint refConstraint; private final List<PostgreTableForeignKeyColumn> columns = new ArrayList<>(); private final PostgreTableBase refTable; public PostgreTableForeignKey( @NotNull PostgreTableBase table, @NotNull String name, @NotNull JDBCResultSet resultSet) throws DBException { super(table, name, DBSEntityConstraintType.FOREIGN_KEY, resultSet); updateRule = getRuleFromAction(JDBCUtils.safeGetString(resultSet, "confupdtype")); deleteRule = getRuleFromAction(JDBCUtils.safeGetString(resultSet, "confdeltype")); final DBRProgressMonitor monitor = resultSet.getSession().getProgressMonitor(); final long refSchemaId = JDBCUtils.safeGetLong(resultSet, "refnamespace"); final long refTableId = JDBCUtils.safeGetLong(resultSet, "confrelid"); refTable = table.getDatabase().findTable( monitor, refSchemaId, refTableId); if (refTable == null) { throw new DBException("Reference table " + refTableId + " not found"); } } public PostgreTableForeignKey( @NotNull PostgreTableBase table, @NotNull DBSEntityConstraint refConstraint, @NotNull DBSForeignKeyModifyRule deleteRule, @NotNull DBSForeignKeyModifyRule updateRule) { super(table, null, DBSEntityConstraintType.FOREIGN_KEY); this.refConstraint = refConstraint; this.refTable = (PostgreTableBase) refConstraint.getParentObject(); this.updateRule = updateRule; this.deleteRule = deleteRule; } @NotNull private DBSForeignKeyModifyRule getRuleFromAction(String action) { switch (action) { case "a": return DBSForeignKeyModifyRule.NO_ACTION; case "r": return DBSForeignKeyModifyRule.RESTRICT; case "c": return DBSForeignKeyModifyRule.CASCADE; case "n": return DBSForeignKeyModifyRule.SET_NULL; case "d": return DBSForeignKeyModifyRule.SET_DEFAULT; default: log.warn("Unsupported constraint action: " + action); return DBSForeignKeyModifyRule.NO_ACTION; } } @Override @Property(viewable = true) public PostgreTableBase getAssociatedEntity() { return refTable; } @Nullable @Override @Property(id = "reference", viewable = true) public DBSEntityConstraint getReferencedConstraint() { return refConstraint; } @NotNull @Override @Property(viewable = true) public DBSForeignKeyModifyRule getDeleteRule() { return deleteRule; } @NotNull @Override @Property(viewable = true) public DBSForeignKeyModifyRule getUpdateRule() { return updateRule; } @Nullable @Override public List<PostgreTableForeignKeyColumn> getAttributeReferences(DBRProgressMonitor monitor) throws DBException { return columns; } void cacheAttributes(DBRProgressMonitor monitor, List<? extends PostgreTableConstraintColumn> children, boolean secondPass) { if (!secondPass) { return; } columns.clear(); columns.addAll((Collection<? extends PostgreTableForeignKeyColumn>) children); final List<PostgreAttribute> lst = new ArrayList<>(children.size()); for (PostgreTableConstraintColumn c : children) { lst.add(((PostgreTableForeignKeyColumn)c).getReferencedColumn()); } try { refConstraint = DBUtils.findEntityConstraint(monitor, refTable, lst); } catch (DBException e) { log.error("Error finding reference constraint", e); } if (refConstraint == null) { log.warn("Can't find reference constraint for foreign key '" + getFullyQualifiedName(DBPEvaluationContext.DDL) + "'"); } } public void addColumn(PostgreTableForeignKeyColumn column) { this.columns.add(column); } }