/* * 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.mysql.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.ext.mysql.MySQLConstants; import org.jkiss.dbeaver.model.DBUtils; import org.jkiss.dbeaver.model.exec.DBCException; 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.DBObjectNameCaseTransformer; import org.jkiss.dbeaver.model.impl.jdbc.JDBCUtils; import org.jkiss.dbeaver.model.meta.IPropertyCacheValidator; import org.jkiss.dbeaver.model.meta.LazyProperty; import org.jkiss.dbeaver.model.meta.Property; import org.jkiss.dbeaver.model.meta.PropertyGroup; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; import org.jkiss.dbeaver.model.sql.SQLUtils; import org.jkiss.dbeaver.model.struct.DBSObject; import org.jkiss.dbeaver.model.struct.rdb.DBSTableConstraint; import org.jkiss.dbeaver.model.struct.rdb.DBSTableForeignKey; import org.jkiss.dbeaver.model.struct.rdb.DBSTableIndex; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; /** * MySQLView */ public class MySQLView extends MySQLTableBase { private static final Log log = Log.getLog(MySQLView.class); public enum CheckOption { NONE(null), CASCADE("CASCADED"), LOCAL("LOCAL"); private final String definitionName; CheckOption(String definitionName) { this.definitionName = definitionName; } public String getDefinitionName() { return definitionName; } } public static class AdditionalInfo { private volatile boolean loaded = false; private String definition; private CheckOption checkOption; private boolean updatable; private String definer; public boolean isLoaded() { return loaded; } @Property(hidden = true, editable = true, updatable = true, order = -1) public String getDefinition() { return definition; } public void setDefinition(String definition) { this.definition = definition; } @Property(viewable = true, editable = true, updatable = true, order = 4) public CheckOption getCheckOption() { return checkOption; } public void setCheckOption(CheckOption checkOption) { this.checkOption = checkOption; } @Property(viewable = true, order = 5) public boolean isUpdatable() { return updatable; } public void setUpdatable(boolean updatable) { this.updatable = updatable; } @Property(viewable = true, order = 6) public String getDefiner() { return definer; } public void setDefiner(String definer) { this.definer = definer; } } public static class AdditionalInfoValidator implements IPropertyCacheValidator<MySQLView> { @Override public boolean isPropertyCached(MySQLView object, Object propertyId) { return object.additionalInfo.loaded; } } private final AdditionalInfo additionalInfo = new AdditionalInfo(); public MySQLView(MySQLCatalog catalog) { super(catalog); } public MySQLView( MySQLCatalog catalog, ResultSet dbResult) { super(catalog, dbResult); } @NotNull @Property(viewable = true, editable = true, valueTransformer = DBObjectNameCaseTransformer.class, order = 1) @Override public String getName() { return super.getName(); } @Override public boolean isView() { return true; } public AdditionalInfo getAdditionalInfo() { return additionalInfo; } @PropertyGroup() @LazyProperty(cacheValidator = AdditionalInfoValidator.class) public AdditionalInfo getAdditionalInfo(DBRProgressMonitor monitor) throws DBCException { synchronized (additionalInfo) { if (!additionalInfo.loaded) { loadAdditionalInfo(monitor); } return additionalInfo; } } @Override public List<? extends DBSTableIndex> getIndexes(DBRProgressMonitor monitor) throws DBException { return null; } @Nullable @Override public List<? extends DBSTableConstraint> getConstraints(@NotNull DBRProgressMonitor monitor) throws DBException { return null; } @Override public List<? extends DBSTableForeignKey> getAssociations(@NotNull DBRProgressMonitor monitor) throws DBException { return null; } @Override public List<? extends DBSTableForeignKey> getReferences(@NotNull DBRProgressMonitor monitor) throws DBException { return null; } @Nullable @Override public String getDescription() { return null; } private void loadAdditionalInfo(DBRProgressMonitor monitor) throws DBCException { if (!isPersisted() || getContainer().isSystem()) { additionalInfo.loaded = true; return; } try (JDBCSession session = DBUtils.openMetaSession(monitor, getDataSource(), "Load table status")) { try (JDBCPreparedStatement dbStat = session.prepareStatement( "SELECT * FROM " + MySQLConstants.META_TABLE_VIEWS + " WHERE " + MySQLConstants.COL_TABLE_SCHEMA + "=? AND " + MySQLConstants.COL_TABLE_NAME + "=?")) { dbStat.setString(1, getContainer().getName()); dbStat.setString(2, getName()); try (JDBCResultSet dbResult = dbStat.executeQuery()) { if (dbResult.next()) { try { additionalInfo.setCheckOption(CheckOption.valueOf(JDBCUtils.safeGetString(dbResult, MySQLConstants.COL_CHECK_OPTION))); } catch (IllegalArgumentException e) { log.warn(e); } additionalInfo.setDefiner(JDBCUtils.safeGetString(dbResult, MySQLConstants.COL_DEFINER)); additionalInfo.setDefinition( SQLUtils.formatSQL( getDataSource(), JDBCUtils.safeGetString(dbResult, MySQLConstants.COL_VIEW_DEFINITION))); additionalInfo.setUpdatable("YES".equals(JDBCUtils.safeGetString(dbResult, MySQLConstants.COL_IS_UPDATABLE))); } additionalInfo.loaded = true; } } } catch (SQLException e) { throw new DBCException(e, getDataSource()); } } @Override @Property(hidden = true, editable = true, updatable = true, order = -1) public String getObjectDefinitionText(DBRProgressMonitor monitor) throws DBException { return getAdditionalInfo(monitor).getDefinition(); } @Override public void setObjectDefinitionText(String sourceText) throws DBException { getAdditionalInfo().setDefinition(sourceText); } }