/* * 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.model; import org.jkiss.code.NotNull; import org.jkiss.code.Nullable; import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.ext.db2.DB2Constants; import org.jkiss.dbeaver.ext.db2.DB2Utils; import org.jkiss.dbeaver.ext.db2.model.dict.DB2IndexColOrder; import org.jkiss.dbeaver.ext.db2.model.dict.DB2IndexColVirtual; import org.jkiss.dbeaver.model.DBUtils; import org.jkiss.dbeaver.model.exec.jdbc.JDBCPreparedStatement; import org.jkiss.dbeaver.model.exec.jdbc.JDBCResultSet; import org.jkiss.dbeaver.model.exec.jdbc.JDBCSession; import org.jkiss.dbeaver.model.impl.jdbc.JDBCUtils; import org.jkiss.dbeaver.model.impl.struct.AbstractTableIndexColumn; import org.jkiss.dbeaver.model.meta.Property; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; import org.jkiss.utils.CommonUtils; import java.sql.ResultSet; import java.sql.SQLException; /** * DB2 Index Column * * @author Denis Forveille */ public class DB2IndexColumn extends AbstractTableIndexColumn { private static final String I_DEP = "SELECT BSCHEMA,BNAME FROM SYSCAT.INDEXDEP WHERE INDSCHEMA = ? AND INDNAME = ? AND BTYPE = 'V' WITH UR"; private DB2Index db2Index; private DB2TableColumn tableColumn; private Integer colSeq; private DB2IndexColOrder colOrder; private String collationSchema; private String collationNane; private DB2IndexColVirtual virtualCol; private String virtualColName; private String virtualColText; // ----------------- // Constructors // ----------------- public DB2IndexColumn(DBRProgressMonitor monitor, DB2Index db2Index, ResultSet dbResult) throws DBException { DB2DataSource db2DataSource = db2Index.getDataSource(); this.db2Index = db2Index; this.colSeq = JDBCUtils.safeGetInteger(dbResult, "COLSEQ"); this.colOrder = CommonUtils.valueOf(DB2IndexColOrder.class, JDBCUtils.safeGetString(dbResult, "COLORDER")); if (db2DataSource.isAtLeastV9_5()) { this.collationSchema = JDBCUtils.safeGetStringTrimmed(dbResult, "COLLATIONSCHEMA"); this.collationNane = JDBCUtils.safeGetString(dbResult, "COLLATIONNAME"); } if (db2DataSource.isAtLeastV10_1()) { this.virtualCol = CommonUtils.valueOf(DB2IndexColVirtual.class, JDBCUtils.safeGetString(dbResult, "VIRTUAL")); this.virtualColText = JDBCUtils.safeGetStringTrimmed(dbResult, "TEXT"); } // Look for Table Column if column is not virtual... DB2TableBase db2Table = db2Index.getTable(); String columnName = JDBCUtils.safeGetString(dbResult, "COLNAME"); if ((virtualCol == null) || (virtualCol.isNotVirtual())) { this.tableColumn = db2Table.getAttribute(monitor, columnName); if (tableColumn == null) { throw new DBException("Column '" + columnName + "' not found in table '" + db2Table.getName() + "' for index '" + db2Index.getName() + "'"); } } else { // Virtual Column // Store Virtual col name instead of real table column name this.virtualColName = columnName; // Look for the associated View and get the associtaed column DB2View viewDep = getDependentView(monitor, db2DataSource, db2Index.getIndSchema().getName().trim(), db2Index.getName()); if (viewDep != null) { this.tableColumn = viewDep.getAttribute(monitor, columnName); } } } public DB2IndexColumn(DB2Index db2Index, DB2TableColumn tableColumn, int ordinalPosition, boolean ascending) { this.db2Index = db2Index; this.tableColumn = tableColumn; this.colSeq = ordinalPosition; this.colOrder = ascending ? DB2IndexColOrder.A : DB2IndexColOrder.D; // Force Ascending or Descending .. this.virtualCol = DB2IndexColVirtual.N; // Force real column... } // ----------------- // Helpers // ----------------- private DB2View getDependentView(DBRProgressMonitor monitor, DB2DataSource db2DataSource, String indexSchema, String indexName) throws DBException { try (JDBCSession session = DBUtils.openMetaSession(monitor, db2DataSource, "Read Index view dependency")) { try (JDBCPreparedStatement stmtSel = session.prepareStatement(I_DEP)) { stmtSel.setString(1, indexSchema); stmtSel.setString(2, indexName); JDBCResultSet dbResult = stmtSel.executeQuery(); if (dbResult.next()) { String viewSchema = dbResult.getString("BSCHEMA").trim(); String viewName = dbResult.getString("BNAME"); return DB2Utils.findViewBySchemaNameAndName(monitor, db2DataSource, viewSchema, viewName); } else { return null; } } } catch (SQLException e) { throw new DBException(e, db2DataSource); } } // ----------------- // Business Contract // ----------------- @NotNull @Override public DB2DataSource getDataSource() { return db2Index.getDataSource(); } @Override public DB2Index getParentObject() { return db2Index; } @NotNull @Override public DB2Index getIndex() { return db2Index; } @Nullable @Override public String getDescription() { if ((virtualCol == null) || (virtualCol.isNotVirtual())) { return tableColumn.getDescription(); } else { return virtualCol.getName(); } } @Override public int getOrdinalPosition() { return colSeq; } @Override public boolean isAscending() { return colOrder.isAscending(); } @NotNull @Override public String getName() { if ((virtualCol != null) && (virtualCol.isVirtual())) { return virtualColName; } else { return tableColumn.getName(); } } // ----------------- // Properties // ----------------- @Nullable @Override // col name in index name @Property(viewable = true, order = 1, id = "name") public DB2TableColumn getTableColumn() { return tableColumn; } // order in index schema name @Property(viewable = true, editable = false, order = 2, id = "indSchema") public Integer getColSeq() { return colSeq; } @Property(viewable = true, editable = true, order = 3, id = "table") public DB2IndexColOrder getColOrder() { return colOrder; } @Property(viewable = true, editable = false, order = 4, id = "indexType") public DB2IndexColVirtual getVirtualCol() { return virtualCol; } @Property(viewable = true, editable = false, order = 5) public String getVirtualColText() { return virtualColText; } @Property(viewable = false, editable = false, category = DB2Constants.CAT_COLLATION) public String getCollationSchema() { return collationSchema; } @Property(viewable = false, editable = false, category = DB2Constants.CAT_COLLATION) public String getCollationNane() { return collationNane; } }