/* * 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.generic.model; import org.jkiss.code.NotNull; import org.jkiss.code.Nullable; import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.ext.generic.GenericConstants; import org.jkiss.dbeaver.ext.generic.model.meta.GenericMetaObject; import org.jkiss.dbeaver.model.DBPEvaluationContext; import org.jkiss.dbeaver.model.exec.jdbc.JDBCResultSet; import org.jkiss.dbeaver.model.exec.jdbc.JDBCSession; import org.jkiss.dbeaver.model.exec.jdbc.JDBCStatement; import org.jkiss.dbeaver.model.impl.jdbc.JDBCConstants; import org.jkiss.dbeaver.model.impl.jdbc.cache.JDBCCompositeCache; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; import org.jkiss.dbeaver.model.sql.SQLConstants; import org.jkiss.dbeaver.model.struct.DBSEntityConstraintType; import org.jkiss.utils.CommonUtils; import java.sql.SQLException; import java.util.List; import java.util.Locale; /** * Index cache implementation */ class PrimaryKeysCache extends JDBCCompositeCache<GenericStructContainer, GenericTable, GenericPrimaryKey, GenericTableConstraintColumn> { private final GenericMetaObject pkObject; PrimaryKeysCache(TableCache tableCache) { super( tableCache, GenericTable.class, GenericUtils.getColumn(tableCache.getDataSource(), GenericConstants.OBJECT_PRIMARY_KEY, JDBCConstants.TABLE_NAME), GenericUtils.getColumn(tableCache.getDataSource(), GenericConstants.OBJECT_PRIMARY_KEY, JDBCConstants.PK_NAME)); pkObject = tableCache.getDataSource().getMetaObject(GenericConstants.OBJECT_PRIMARY_KEY); } @NotNull @Override protected JDBCStatement prepareObjectsStatement(JDBCSession session, GenericStructContainer owner, GenericTable forParent) throws SQLException { try { return session.getMetaData().getPrimaryKeys( owner.getCatalog() == null ? null : owner.getCatalog().getName(), owner.getSchema() == null ? null : owner.getSchema().getName(), forParent == null ? owner.getDataSource().getAllObjectsPattern() : forParent.getName()) .getSourceStatement(); } catch (SQLException e) { throw e; } catch (Exception e) { if (forParent == null) { throw new SQLException("Global primary keys read not supported", e); } else { throw new SQLException(e); } } } protected String getDefaultObjectName(JDBCResultSet dbResult, String parentName) { int keySeq = GenericUtils.safeGetInt(pkObject, dbResult, JDBCConstants.KEY_SEQ); return parentName.toUpperCase(Locale.ENGLISH) + "_PK"; } @Nullable @Override protected GenericPrimaryKey fetchObject(JDBCSession session, GenericStructContainer owner, GenericTable parent, String pkName, JDBCResultSet dbResult) throws SQLException, DBException { return new GenericPrimaryKey( parent, pkName, null, DBSEntityConstraintType.PRIMARY_KEY, true); } @Nullable @Override protected GenericTableConstraintColumn[] fetchObjectRow( JDBCSession session, GenericTable parent, GenericPrimaryKey object, JDBCResultSet dbResult) throws SQLException, DBException { String columnName = GenericUtils.safeGetStringTrimmed(pkObject, dbResult, JDBCConstants.COLUMN_NAME); if (CommonUtils.isEmpty(columnName)) { log.debug("Null primary key column for '" + object.getName() + "'"); return null; } if ((columnName.startsWith("[") && columnName.endsWith("]")) || (columnName.startsWith(SQLConstants.DEFAULT_IDENTIFIER_QUOTE) && columnName.endsWith(SQLConstants.DEFAULT_IDENTIFIER_QUOTE))) { // [JDBC: SQLite] Escaped column name. Let's un-escape it columnName = columnName.substring(1, columnName.length() - 1); } int keySeq = GenericUtils.safeGetInt(pkObject, dbResult, JDBCConstants.KEY_SEQ); GenericTableColumn tableColumn = parent.getAttribute(session.getProgressMonitor(), columnName); if (tableColumn == null) { log.warn("Column '" + columnName + "' not found in table '" + parent.getFullyQualifiedName(DBPEvaluationContext.DDL) + "' for PK '" + object.getFullyQualifiedName(DBPEvaluationContext.DDL) + "'"); return null; } return new GenericTableConstraintColumn[] { new GenericTableConstraintColumn(object, tableColumn, keySeq) }; } @Override protected void cacheChildren(DBRProgressMonitor monitor, GenericPrimaryKey primaryKey, List<GenericTableConstraintColumn> rows) { primaryKey.setColumns(rows); } }