/* * 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.model.cache.*; import org.jkiss.dbeaver.ext.db2.model.dict.DB2OwnerType; import org.jkiss.dbeaver.ext.db2.model.dict.DB2RoutineType; import org.jkiss.dbeaver.ext.db2.model.dict.DB2YesNo; import org.jkiss.dbeaver.ext.db2.model.fed.DB2Nickname; import org.jkiss.dbeaver.ext.db2.model.module.DB2Module; import org.jkiss.dbeaver.model.DBPRefreshableObject; import org.jkiss.dbeaver.model.DBPSystemObject; import org.jkiss.dbeaver.model.impl.DBSObjectCache; import org.jkiss.dbeaver.model.impl.jdbc.JDBCUtils; import org.jkiss.dbeaver.model.impl.jdbc.cache.JDBCObjectSimpleCache; import org.jkiss.dbeaver.model.meta.Association; import org.jkiss.dbeaver.model.meta.Property; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; import org.jkiss.dbeaver.model.struct.DBSObject; import org.jkiss.dbeaver.model.struct.rdb.DBSProcedureContainer; import org.jkiss.dbeaver.model.struct.rdb.DBSSchema; import org.jkiss.utils.CommonUtils; import java.sql.ResultSet; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; /** * DB2Schema * * @author Denis Forveille */ public class DB2Schema extends DB2GlobalObject implements DBSSchema, DBPRefreshableObject, DBPSystemObject, DBSProcedureContainer { private static final List<String> SYSTEM_SCHEMA = Arrays.asList("SYS", "DB2QP", "SQLJ", "NULLID"); private static final String C_SEQ = "SELECT * FROM SYSCAT.SEQUENCES WHERE SEQSCHEMA = ? AND SEQTYPE <> 'A' ORDER BY SEQNAME WITH UR"; private static final String C_PKG = "SELECT * FROM SYSCAT.PACKAGES WHERE PKGSCHEMA = ? ORDER BY PKGNAME WITH UR"; private static final String C_XSR = "SELECT * FROM SYSCAT.XSROBJECTS WHERE OBJECTSCHEMA = ? ORDER BY OBJECTNAME WITH UR"; private static final String C_MOD = "SELECT * FROM SYSCAT.MODULES WHERE MODULESCHEMA = ? AND MODULETYPE <> 'A' ORDER BY MODULENAME WITH UR"; private static final String C_DTT = "SELECT * FROM SYSCAT.DATATYPES WHERE TYPESCHEMA = ? AND METATYPE <> 'S' ORDER BY TYPENAME WITH UR"; private static final String C_DTT_97 = "SELECT * FROM SYSCAT.DATATYPES WHERE TYPESCHEMA = ? AND METATYPE <> 'S' AND TYPEMODULENAME IS NULL ORDER BY TYPENAME WITH UR"; // DB2Schema's children private final DB2TableCache tableCache = new DB2TableCache(); private final DB2ViewCache viewCache = new DB2ViewCache(); private final DB2MaterializedQueryTableCache mqtCache = new DB2MaterializedQueryTableCache(); private final DB2NicknameCache nicknameCache = new DB2NicknameCache(); private final DBSObjectCache<DB2Schema, DB2Sequence> sequenceCache; private final DB2IndexCache indexCache = new DB2IndexCache(); private final DB2TriggerCache triggerCache = new DB2TriggerCache(); private final DB2AliasCache aliasCache = new DB2AliasCache(); private final DBSObjectCache<DB2Schema, DB2Package> packageCache; private DBSObjectCache<DB2Schema, DB2XMLSchema> xmlSchemaCache; private final DB2RoutineCache udfCache = new DB2RoutineCache(DB2RoutineType.F); private final DB2RoutineCache methodCache = new DB2RoutineCache(DB2RoutineType.M); private final DB2RoutineCache procedureCache = new DB2RoutineCache(DB2RoutineType.P); private final DBSObjectCache<DB2Schema, DB2DataType> udtCache; private DBSObjectCache<DB2Schema, DB2Module> moduleCache; // DB2Table's children private final DB2TableUniqueKeyCache constraintCache = new DB2TableUniqueKeyCache(tableCache); private final DB2TableForeignKeyCache associationCache = new DB2TableForeignKeyCache(tableCache); private final DB2TableReferenceCache referenceCache = new DB2TableReferenceCache(tableCache); private final DB2TableCheckConstraintCache checkCache = new DB2TableCheckConstraintCache(tableCache); private String name; private String owner; private DB2OwnerType ownerType; private Timestamp createTime; private Integer auditPolicyID; private String auditPolicyName; private Boolean dataCapture; private String remarks; // ------------ // Constructors // ------------ public DB2Schema(DB2DataSource db2DataSource, ResultSet dbResult) throws DBException { this(db2DataSource, JDBCUtils.safeGetStringTrimmed(dbResult, "SCHEMANAME")); this.owner = JDBCUtils.safeGetString(dbResult, "OWNER"); this.createTime = JDBCUtils.safeGetTimestamp(dbResult, "CREATE_TIME"); this.remarks = JDBCUtils.safeGetString(dbResult, "REMARKS"); if (db2DataSource.isAtLeastV9_5()) { this.ownerType = CommonUtils.valueOf(DB2OwnerType.class, JDBCUtils.safeGetString(dbResult, "OWNERTYPE")); } if (db2DataSource.isAtLeastV10_1()) { this.auditPolicyID = JDBCUtils.safeGetInteger(dbResult, "AUDITPOLICYID"); this.auditPolicyName = JDBCUtils.safeGetString(dbResult, "AUDITPOLICYNAME"); this.dataCapture = JDBCUtils.safeGetBoolean(dbResult, "DATACAPTURE", DB2YesNo.Y.name()); } } public DB2Schema(DB2DataSource db2DataSource, String name) { super(db2DataSource, true); this.name = name; this.sequenceCache = new JDBCObjectSimpleCache<>(DB2Sequence.class, C_SEQ, name); this.packageCache = new JDBCObjectSimpleCache<>(DB2Package.class, C_PKG, name); this.xmlSchemaCache = new JDBCObjectSimpleCache<>(DB2XMLSchema.class, C_XSR, name); if (db2DataSource.isAtLeastV9_7()) { this.moduleCache = new JDBCObjectSimpleCache<>(DB2Module.class, C_MOD, name); } String datatypeSQL; if (db2DataSource.isAtLeastV9_7()) { datatypeSQL = C_DTT_97; } else { datatypeSQL = C_DTT; } this.udtCache = new JDBCObjectSimpleCache<>(DB2DataType.class, datatypeSQL, name); } // ----------------- // Business Contract // ----------------- @Override public boolean isSystem() { return SYSTEM_SCHEMA.contains(name); } @Override public String toString() { return "Schema " + name; } @Override public synchronized void cacheStructure(@NotNull DBRProgressMonitor monitor, int scope) throws DBException { if ((scope & STRUCT_ENTITIES) != 0) { monitor.subTask("Cache tables"); tableCache.getAllObjects(monitor, this); monitor.subTask("Cache Views"); viewCache.getAllObjects(monitor, this); monitor.subTask("Cache MQTs"); mqtCache.getAllObjects(monitor, this); monitor.subTask("Cache Nicknames"); nicknameCache.getAllObjects(monitor, this); monitor.subTask("Cache Check Constraints"); checkCache.getAllObjects(monitor, this); monitor.subTask("Cache Sequences"); sequenceCache.getAllObjects(monitor, this); if (xmlSchemaCache != null) { monitor.subTask("Cache XML Schemas"); xmlSchemaCache.getAllObjects(monitor, this); } if (moduleCache != null) { monitor.subTask("Cache Modules"); moduleCache.getAllObjects(monitor, this); } } if ((scope & STRUCT_ATTRIBUTES) != 0) { monitor.subTask("Cache table columns"); tableCache.loadChildren(monitor, this, null); } if ((scope & STRUCT_ASSOCIATIONS) != 0) { monitor.subTask("Cache table unique keys"); constraintCache.getObjects(monitor, this, null); monitor.subTask("Cache table foreign keys"); associationCache.getObjects(monitor, this, null); monitor.subTask("Cache table references"); referenceCache.getObjects(monitor, this, null); monitor.subTask("Cache indexes"); indexCache.getAllObjects(monitor, this); } } @Override public synchronized DBSObject refreshObject(@NotNull DBRProgressMonitor monitor) throws DBException { tableCache.clearCache(); viewCache.clearCache(); mqtCache.clearCache(); nicknameCache.clearCache(); packageCache.clearCache(); procedureCache.clearCache(); udfCache.clearCache(); udtCache.clearCache(); sequenceCache.clearCache(); aliasCache.clearCache(); if (xmlSchemaCache != null) { xmlSchemaCache.clearCache(); } if (moduleCache != null) { moduleCache.clearCache(); } // For those 2, need to refresh dependent cache (cache for tables..?) indexCache.clearCache(); triggerCache.clearCache(); constraintCache.clearCache(); associationCache.clearCache(); referenceCache.clearCache(); checkCache.clearCache(); return this; } // -------------------------- // Schema "Children" = Tables // -------------------------- @Override public Class<DB2TableBase> getChildType(@NotNull DBRProgressMonitor monitor) throws DBException { return DB2TableBase.class; } @Override public Collection<DB2TableBase> getChildren(@NotNull DBRProgressMonitor monitor) throws DBException { List<DB2TableBase> allChildren = new ArrayList<>(); allChildren.addAll(tableCache.getAllObjects(monitor, this)); allChildren.addAll(viewCache.getAllObjects(monitor, this)); allChildren.addAll(mqtCache.getAllObjects(monitor, this)); allChildren.addAll(nicknameCache.getAllObjects(monitor, this)); return allChildren; } @Override public DB2TableBase getChild(@NotNull DBRProgressMonitor monitor, @NotNull String childName) throws DBException { DB2TableBase child = tableCache.getObject(monitor, this, childName); if (child == null) { child = viewCache.getObject(monitor, this, childName); } if (child == null) { child = mqtCache.getObject(monitor, this, childName); } if (child == null) { child = nicknameCache.getObject(monitor, this, childName); } return child; } // ----------------- // Associations // ----------------- @Association public Collection<DB2Table> getTables(DBRProgressMonitor monitor) throws DBException { return tableCache.getTypedObjects(monitor, this, DB2Table.class); } public DB2Table getTable(DBRProgressMonitor monitor, String name) throws DBException { return tableCache.getObject(monitor, this, name, DB2Table.class); } @Association public Collection<DB2View> getViews(DBRProgressMonitor monitor) throws DBException { return viewCache.getTypedObjects(monitor, this, DB2View.class); } public DB2View getView(DBRProgressMonitor monitor, String name) throws DBException { return viewCache.getObject(monitor, this, name, DB2View.class); } @Association public Collection<DB2Nickname> getNicknames(DBRProgressMonitor monitor) throws DBException { return nicknameCache.getTypedObjects(monitor, this, DB2Nickname.class); } public DB2Nickname getNickname(DBRProgressMonitor monitor, String name) throws DBException { return nicknameCache.getObject(monitor, this, name, DB2Nickname.class); } @Association public Collection<DB2MaterializedQueryTable> getMaterializedQueryTables(DBRProgressMonitor monitor) throws DBException { return mqtCache.getTypedObjects(monitor, this, DB2MaterializedQueryTable.class); } public DB2MaterializedQueryTable getMaterializedQueryTable(DBRProgressMonitor monitor, String name) throws DBException { return mqtCache.getObject(monitor, this, name, DB2MaterializedQueryTable.class); } @Association public Collection<DB2Index> getIndexes(DBRProgressMonitor monitor) throws DBException { return indexCache.getAllObjects(monitor, this); } public DB2Index getIndex(DBRProgressMonitor monitor, String name) throws DBException { return indexCache.getObject(monitor, this, name, DB2Index.class); } @Association public Collection<DB2Trigger> getTriggers(DBRProgressMonitor monitor) throws DBException { return triggerCache.getAllObjects(monitor, this); } public DB2Trigger getTrigger(DBRProgressMonitor monitor, String name) throws DBException { return triggerCache.getObject(monitor, this, name, DB2Trigger.class); } @Association public Collection<DB2DataType> getUDTs(DBRProgressMonitor monitor) throws DBException { return udtCache.getAllObjects(monitor, this); } public DB2DataType getUDT(DBRProgressMonitor monitor, String name) throws DBException { return udtCache.getObject(monitor, this, name); } @Association public Collection<DB2Sequence> getSequences(DBRProgressMonitor monitor) throws DBException { return sequenceCache.getAllObjects(monitor, this); } public DB2Sequence getSequence(DBRProgressMonitor monitor, String name) throws DBException { return sequenceCache.getObject(monitor, this, name); } @Association public Collection<DB2XMLSchema> getXMLSchemas(DBRProgressMonitor monitor) throws DBException { return xmlSchemaCache.getAllObjects(monitor, this); } public DB2XMLSchema getXMLSchema(DBRProgressMonitor monitor, String name) throws DBException { return xmlSchemaCache.getObject(monitor, this, name); } @Association public Collection<DB2Alias> getAliases(DBRProgressMonitor monitor) throws DBException { return aliasCache.getAllObjects(monitor, this); } public DB2Alias getAlias(DBRProgressMonitor monitor, String name) throws DBException { return aliasCache.getObject(monitor, this, name, DB2Alias.class); } @Association public Collection<DB2Package> getPackages(DBRProgressMonitor monitor) throws DBException { return packageCache.getAllObjects(monitor, this); } public DB2Package getPackage(DBRProgressMonitor monitor, String name) throws DBException { return packageCache.getObject(monitor, this, name); } @Association public Collection<DB2Routine> getProcedures(DBRProgressMonitor monitor) throws DBException { return procedureCache.getAllObjects(monitor, this); } public DB2Routine getProcedure(DBRProgressMonitor monitor, String name) throws DBException { return procedureCache.getObject(monitor, this, name); } @Association public Collection<DB2Routine> getMethods(DBRProgressMonitor monitor) throws DBException { return methodCache.getAllObjects(monitor, this); } public DB2Routine getMethod(DBRProgressMonitor monitor, String name) throws DBException { return methodCache.getObject(monitor, this, name); } @Association public Collection<DB2Routine> getUDFs(DBRProgressMonitor monitor) throws DBException { return udfCache.getAllObjects(monitor, this); } public DB2Routine getUDF(DBRProgressMonitor monitor, String name) throws DBException { return udfCache.getObject(monitor, this, name); } @Association public Collection<DB2Module> getModules(DBRProgressMonitor monitor) throws DBException { return moduleCache.getAllObjects(monitor, this); } public DB2Module getModule(DBRProgressMonitor monitor, String name) throws DBException { return moduleCache.getObject(monitor, this, name); } // ----------------- // Properties // ----------------- @NotNull @Override @Property(viewable = true, editable = false, order = 1) public String getName() { return name; } public void setName(String name) { this.name = name; } @Property(viewable = false, editable = false, category = DB2Constants.CAT_OWNER) public String getOwner() { return owner; } @Property(viewable = false, editable = false, category = DB2Constants.CAT_OWNER) public DB2OwnerType getOwnerType() { return ownerType; } @Property(viewable = true, editable = false, category = DB2Constants.CAT_DATETIME) public Timestamp getCreateTime() { return createTime; } @Property(viewable = false, editable = false, order = 7, category = DB2Constants.CAT_AUDIT) public Integer getAuditPolicyID() { return auditPolicyID; } @Property(viewable = false, editable = false, order = 8, category = DB2Constants.CAT_AUDIT) public String getAuditPolicyName() { return auditPolicyName; } @Property(viewable = false, editable = false) public Boolean getDataCapture() { return dataCapture; } @Nullable @Override @Property(viewable = false, editable = false) public String getDescription() { return remarks; } // ------------------------- // Standards Getters // ------------------------- public DB2TableCache getTableCache() { return tableCache; } public DB2ViewCache getViewCache() { return viewCache; } public DB2NicknameCache getNicknameCache() { return nicknameCache; } public DB2MaterializedQueryTableCache getMaterializedQueryTableCache() { return mqtCache; } public DBSObjectCache<DB2Schema, DB2DataType> getUdtCache() { return udtCache; } public DB2RoutineCache getUdfCache() { return udfCache; } public DBSObjectCache<DB2Schema, DB2Sequence> getSequenceCache() { return sequenceCache; } public DBSObjectCache<DB2Schema, DB2XMLSchema> getXMLSchemaCache() { return xmlSchemaCache; } public DB2AliasCache getAliasCache() { return aliasCache; } public DBSObjectCache<DB2Schema, DB2Package> getPackageCache() { return packageCache; } public DB2RoutineCache getProcedureCache() { return procedureCache; } public DB2IndexCache getIndexCache() { return indexCache; } public DB2TableUniqueKeyCache getConstraintCache() { return constraintCache; } public DB2TableForeignKeyCache getAssociationCache() { return associationCache; } public DB2TableReferenceCache getReferenceCache() { return referenceCache; } public DB2TriggerCache getTriggerCache() { return triggerCache; } public DB2TableCheckConstraintCache getCheckCache() { return checkCache; } public DBSObjectCache<DB2Schema, DB2Module> getModuleCache() { return moduleCache; } public DBSObjectCache<DB2Schema, DB2XMLSchema> getXmlSchemaCache() { return xmlSchemaCache; } public DBSObjectCache<DB2Schema, DB2Routine> getMethodCache() { return methodCache; } }