提交 b9816c62 编写于 作者: S Serge Rider

#12 PostgreSQL class cache

上级 03798494
......@@ -24,9 +24,9 @@
<items label="%tree.column.node.name" path="attribute" property="attributes" icon="#column">
</items>
</folder>
<folder type="org.jkiss.dbeaver.ext.generic.model.GenericPrimaryKey" label="%tree.uni_keys.node.name" icon="#constraints" description="Table unique keys" visibleIf="!object.view">
<items label="%tree.uni_key.node.name" path="uniqueKey" property="constraints" icon="#unique-key">
<items label="%tree.uni_key.columns.node.name" itemLabel="%tree.column.node.name" path="column" property="attributeReferences" navigable="false" inline="true">
<folder type="org.jkiss.dbeaver.ext.generic.model.GenericPrimaryKey" label="%tree.constraints.node.name" icon="#constraints" description="Table unique keys" visibleIf="!object.view">
<items label="%tree.constraint.node.name" path="uniqueKey" property="constraints" icon="#unique-key">
<items label="%tree.constraint.columns.node.name" itemLabel="%tree.column.node.name" path="column" property="attributeReferences" navigable="false" inline="true">
</items>
</items>
</folder>
......
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2015 Serge Rieder (serge@jkiss.org)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License (version 2)
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jkiss.dbeaver.ext.postgresql.model;
import org.jkiss.code.NotNull;
import org.jkiss.dbeaver.model.DBPNamedObject2;
import org.jkiss.dbeaver.model.DBPRefreshableObject;
import org.jkiss.dbeaver.model.struct.DBSObject;
/**
* PostgreClass
*/
public interface PostgreClass extends PostgreObject,DBSObject,DBPNamedObject2,DBPRefreshableObject
{
enum RelKind {
r,// ordinary table
i, // index
S, // sequence
v, // view
m, // materialized view
c, // composite type
t, // TOAST table
f, // = foreign table
}
@NotNull
PostgreDataSource getDataSource();
}
......@@ -199,7 +199,7 @@ public class PostgreDatabase implements DBSInstance, DBSCatalog, PostgreObject {
@Override
protected JDBCStatement prepareObjectsStatement(@NotNull JDBCSession session, @NotNull PostgreDatabase owner) throws SQLException
{
StringBuilder catalogQuery = new StringBuilder("SELECT * FROM pg_catalog.pg_namespace");
StringBuilder catalogQuery = new StringBuilder("SELECT n.oid,n.* FROM pg_catalog.pg_namespace n");
DBSObjectFilter catalogFilters = owner.getDataSource().getContainer().getObjectFilter(PostgreSchema.class, null, false);
if (catalogFilters != null) {
JDBCUtils.appendFilterClause(catalogQuery, catalogFilters, PostgreConstants.COL_SCHEMA_NAME, true);
......
......@@ -20,6 +20,7 @@ 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.ext.postgresql.PostgreConstants;
import org.jkiss.dbeaver.model.DBPRefreshableObject;
import org.jkiss.dbeaver.model.DBPSaveableObject;
......@@ -53,15 +54,18 @@ import java.util.List;
/**
* PostgreSchema
*/
public class PostgreSchema implements DBSSchema, DBPSaveableObject, DBPRefreshableObject, DBPSystemObject, DBSProcedureContainer {
public class PostgreSchema implements DBSSchema, DBPSaveableObject, DBPRefreshableObject, DBPSystemObject, DBSProcedureContainer, PostgreObject {
static final Log log = Log.getLog(PostgreSchema.class);
private PostgreDatabase database;
private int oid;
private String name;
private int ownerId;
private PostgreCharset defaultCharset;
private boolean persisted;
final TableCache tableCache = new TableCache();
final ClassCache classCache = new ClassCache();
final ProceduresCache proceduresCache = new ProceduresCache();
final TriggerCache triggerCache = new TriggerCache();
final ConstraintCache constraintCache = new ConstraintCache();
......@@ -79,6 +83,7 @@ public class PostgreSchema implements DBSSchema, DBPSaveableObject, DBPRefreshab
private void loadInfo(ResultSet dbResult)
throws SQLException
{
this.oid = JDBCUtils.safeGetInt(dbResult, "oid");
this.ownerId = JDBCUtils.safeGetInt(dbResult, "nspowner");
this.defaultCharset = null;
this.persisted = true;
......@@ -98,6 +103,11 @@ public class PostgreSchema implements DBSSchema, DBPSaveableObject, DBPRefreshab
return name;
}
@Override
public int getObjectId() {
return this.oid;
}
@Property(viewable = true, order = 4)
public int getOwnerId() {
return ownerId;
......@@ -148,20 +158,20 @@ public class PostgreSchema implements DBSSchema, DBPSaveableObject, DBPRefreshab
public Collection<PostgreTable> getTables(DBRProgressMonitor monitor)
throws DBException
{
return tableCache.getTypedObjects(monitor, this, PostgreTable.class);
return classCache.getTypedObjects(monitor, this, PostgreTable.class);
}
public PostgreTable getTable(DBRProgressMonitor monitor, String name)
throws DBException
{
return tableCache.getObject(monitor, this, name, PostgreTable.class);
return classCache.getObject(monitor, this, name, PostgreTable.class);
}
@Association
public Collection<PostgreView> getViews(DBRProgressMonitor monitor)
throws DBException
{
return tableCache.getTypedObjects(monitor, this, PostgreView.class);
return classCache.getTypedObjects(monitor, this, PostgreView.class);
}
@Association
......@@ -194,14 +204,14 @@ public class PostgreSchema implements DBSSchema, DBPSaveableObject, DBPRefreshab
public Collection<PostgreTableBase> getChildren(@NotNull DBRProgressMonitor monitor)
throws DBException
{
return tableCache.getAllObjects(monitor, this);
return classCache.getAllObjects(monitor, this);
}
@Override
public PostgreTableBase getChild(@NotNull DBRProgressMonitor monitor, @NotNull String childName)
throws DBException
{
return tableCache.getObject(monitor, this, childName);
return classCache.getObject(monitor, this, childName);
}
@Override
......@@ -216,10 +226,10 @@ public class PostgreSchema implements DBSSchema, DBPSaveableObject, DBPRefreshab
throws DBException
{
monitor.subTask("Cache tables");
tableCache.getAllObjects(monitor, this);
classCache.getAllObjects(monitor, this);
if ((scope & STRUCT_ATTRIBUTES) != 0) {
monitor.subTask("Cache table columns");
tableCache.loadChildren(monitor, this, null);
classCache.loadChildren(monitor, this, null);
}
if ((scope & STRUCT_ASSOCIATIONS) != 0) {
monitor.subTask("Cache table constraints");
......@@ -231,7 +241,7 @@ public class PostgreSchema implements DBSSchema, DBPSaveableObject, DBPRefreshab
public synchronized boolean refreshObject(@NotNull DBRProgressMonitor monitor)
throws DBException
{
tableCache.clearCache();
classCache.clearCache();
indexCache.clearCache();
constraintCache.clearCache();
proceduresCache.clearCache();
......@@ -245,19 +255,19 @@ public class PostgreSchema implements DBSSchema, DBPSaveableObject, DBPRefreshab
return PostgreConstants.INFO_SCHEMA_NAME.equalsIgnoreCase(getName()) || PostgreConstants.CATALOG_SCHEMA_NAME.equalsIgnoreCase(getName());
}
public class TableCache extends JDBCStructCache<PostgreSchema, PostgreTableBase, PostgreTableColumn> {
public class ClassCache extends JDBCStructCache<PostgreSchema, PostgreTableBase, PostgreTableColumn> {
protected TableCache()
protected ClassCache()
{
super(JDBCConstants.TABLE_NAME);
super("relname");
}
@Override
protected JDBCStatement prepareObjectsStatement(@NotNull JDBCSession session, @NotNull PostgreSchema owner)
throws SQLException
{
final JDBCPreparedStatement dbStat = session.prepareStatement("SELECT * FROM pg_catalog.pg_tables WHERE schemaname=?");
dbStat.setString(1, getName());
final JDBCPreparedStatement dbStat = session.prepareStatement("SELECT c.oid,c.* FROM pg_catalog.pg_class c WHERE c.relnamespace=?");
dbStat.setInt(1, getObjectId());
return dbStat;
}
......@@ -265,7 +275,23 @@ public class PostgreSchema implements DBSSchema, DBPSaveableObject, DBPRefreshab
protected PostgreTableBase fetchObject(@NotNull JDBCSession session, @NotNull PostgreSchema owner, @NotNull ResultSet dbResult)
throws SQLException, DBException
{
return new PostgreTable(PostgreSchema.this, dbResult);
final String kindString = JDBCUtils.safeGetString(dbResult, "relkind");
PostgreClass.RelKind kind;
try {
kind = PostgreClass.RelKind.valueOf(kindString);
} catch (IllegalArgumentException e) {
log.warn("Unexpected class '" + kindString + "'", e);
return null;
}
switch (kind) {
case r:
return new PostgreTable(PostgreSchema.this, dbResult);
case v:
return new PostgreView(PostgreSchema.this, dbResult);
default:
log.warn("Unsupported class '" + kind + "'");
return null;
}
}
@Override
......@@ -273,18 +299,12 @@ public class PostgreSchema implements DBSSchema, DBPSaveableObject, DBPRefreshab
throws SQLException
{
StringBuilder sql = new StringBuilder();
sql
.append("SELECT * FROM ").append(PostgreConstants.META_TABLE_COLUMNS)
.append(" WHERE ").append(PostgreConstants.COL_TABLE_SCHEMA).append("=?");
if (forTable != null) {
sql.append(" AND ").append(PostgreConstants.COL_TABLE_NAME).append("=?");
}
sql.append(" ORDER BY ").append(PostgreConstants.COL_ORDINAL_POSITION);
sql.append("SELECT c.relname,a.* FROM pg_catalog.pg_attribute a,pg_catalog.pg_class c WHERE a.attrelid=c.oid AND c.oid=?");
sql.append(" ORDER BY a.attnum");
JDBCPreparedStatement dbStat = session.prepareStatement(sql.toString());
dbStat.setString(1, PostgreSchema.this.getName());
if (forTable != null) {
dbStat.setString(2, forTable.getName());
dbStat.setInt(1, forTable.getObjectId());
}
return dbStat;
}
......@@ -303,7 +323,7 @@ public class PostgreSchema implements DBSSchema, DBPSaveableObject, DBPRefreshab
class IndexCache extends JDBCCompositeCache<PostgreSchema, PostgreTable, PostgreTableIndex, PostgreTableIndexColumn> {
protected IndexCache()
{
super(tableCache, PostgreTable.class, PostgreConstants.COL_TABLE_NAME, PostgreConstants.COL_INDEX_NAME);
super(classCache, PostgreTable.class, PostgreConstants.COL_TABLE_NAME, PostgreConstants.COL_INDEX_NAME);
}
@Override
......@@ -389,7 +409,7 @@ public class PostgreSchema implements DBSSchema, DBPSaveableObject, DBPRefreshab
class ConstraintCache extends JDBCCompositeCache<PostgreSchema, PostgreTable, PostgreTableConstraint, PostgreTableConstraintColumn> {
protected ConstraintCache()
{
super(tableCache, PostgreTable.class, PostgreConstants.COL_TABLE_NAME, PostgreConstants.COL_CONSTRAINT_NAME);
super(classCache, PostgreTable.class, PostgreConstants.COL_TABLE_NAME, PostgreConstants.COL_CONSTRAINT_NAME);
}
@Override
......
......@@ -366,7 +366,7 @@ public class PostgreTable extends PostgreTableBase
@Override
public String getObjectDefinitionText(DBRProgressMonitor monitor) throws DBException {
return getDDL(monitor);
return "";
}
@Override
......
......@@ -20,30 +20,25 @@ package org.jkiss.dbeaver.ext.postgresql.model;
import org.jkiss.code.NotNull;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.model.DBPNamedObject2;
import org.jkiss.dbeaver.model.DBPRefreshableObject;
import org.jkiss.dbeaver.model.DBUtils;
import org.jkiss.dbeaver.model.exec.jdbc.JDBCSession;
import org.jkiss.dbeaver.model.impl.jdbc.JDBCUtils;
import org.jkiss.dbeaver.model.impl.jdbc.cache.JDBCStructCache;
import org.jkiss.dbeaver.model.impl.jdbc.struct.JDBCTable;
import org.jkiss.dbeaver.model.impl.jdbc.struct.JDBCTableColumn;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import java.io.UnsupportedEncodingException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collection;
/**
* PostgreTable base
*/
public abstract class PostgreTableBase extends JDBCTable<PostgreDataSource, PostgreSchema>
implements DBPNamedObject2,DBPRefreshableObject, PostgreScriptObject
public abstract class PostgreTableBase extends JDBCTable<PostgreDataSource, PostgreSchema> implements PostgreClass, PostgreScriptObject
{
static final Log log = Log.getLog(PostgreTableBase.class);
private int oid;
protected PostgreTableBase(PostgreSchema catalog)
{
super(catalog, false);
......@@ -53,13 +48,19 @@ public abstract class PostgreTableBase extends JDBCTable<PostgreDataSource, Post
PostgreSchema catalog,
ResultSet dbResult)
{
super(catalog, JDBCUtils.safeGetString(dbResult, 1), true);
super(catalog, JDBCUtils.safeGetString(dbResult, "relname"), true);
this.oid = JDBCUtils.safeGetInt(dbResult, "oid");
}
@Override
public JDBCStructCache<PostgreSchema, ? extends JDBCTable, ? extends JDBCTableColumn> getCache()
{
return getContainer().tableCache;
return getContainer().classCache;
}
@Override
public int getObjectId() {
return this.oid;
}
@NotNull
......@@ -75,58 +76,21 @@ public abstract class PostgreTableBase extends JDBCTable<PostgreDataSource, Post
public Collection<PostgreTableColumn> getAttributes(DBRProgressMonitor monitor)
throws DBException
{
return getContainer().tableCache.getChildren(monitor, getContainer(), this);
return getContainer().classCache.getChildren(monitor, getContainer(), this);
}
@Override
public PostgreTableColumn getAttribute(DBRProgressMonitor monitor, String attributeName)
throws DBException
{
return getContainer().tableCache.getChild(monitor, getContainer(), this, attributeName);
return getContainer().classCache.getChild(monitor, getContainer(), this, attributeName);
}
@Override
public boolean refreshObject(@NotNull DBRProgressMonitor monitor) throws DBException
{
getContainer().tableCache.clearChildrenCache(this);
getContainer().classCache.clearChildrenCache(this);
return true;
}
public String getDDL(DBRProgressMonitor monitor)
throws DBException
{
if (!isPersisted()) {
return "";
}
try (JDBCSession session = DBUtils.openMetaSession(monitor, getDataSource(), "Retrieve table DDL")) {
try (PreparedStatement dbStat = session.prepareStatement(
"SHOW CREATE " + (isView() ? "VIEW" : "TABLE") + " " + getFullQualifiedName())) {
try (ResultSet dbResult = dbStat.executeQuery()) {
if (dbResult.next()) {
byte[] ddl;
if (isView()) {
ddl = dbResult.getBytes("Create View");
} else {
ddl = dbResult.getBytes("Create Table");
}
if (ddl == null) {
return null;
} else {
try {
return new String(ddl, getContainer().getDefaultCharset().getName());
} catch (UnsupportedEncodingException e) {
log.debug(e);
return new String(ddl);
}
}
} else {
return "DDL is not available";
}
}
}
} catch (SQLException ex) {
throw new DBException(ex, getDataSource());
}
}
}
......@@ -91,8 +91,8 @@ public class PostgreTableColumn extends JDBCTableColumn<PostgreTableBase> implem
private void loadInfo(ResultSet dbResult)
throws DBException
{
setName(JDBCUtils.safeGetString(dbResult, PostgreConstants.COL_COLUMN_NAME));
setOrdinalPosition(JDBCUtils.safeGetInt(dbResult, PostgreConstants.COL_ORDINAL_POSITION));
setName(JDBCUtils.safeGetString(dbResult, "attname"));
setOrdinalPosition(JDBCUtils.safeGetInt(dbResult, "attnum"));
String typeName = JDBCUtils.safeGetString(dbResult, PostgreConstants.COL_DATA_TYPE);
assert typeName != null;
String keyTypeName = JDBCUtils.safeGetString(dbResult, PostgreConstants.COL_COLUMN_KEY);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册