提交 4ee7aa18 编写于 作者: S Serge Rider

Merge remote-tracking branch 'origin/devel' into devel

......@@ -16,6 +16,8 @@
*/
package org.jkiss.dbeaver.ui.dialogs.connection;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
......@@ -59,7 +61,7 @@ public class EditConnectionNavigatorSettingsDialog extends BaseDialog {
composite,
CoreMessages.pref_page_ui_general_group_general,
1, GridData.VERTICAL_ALIGN_BEGINNING, 0);
miscGroup.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
miscGroup.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL));
showSystemObjects = UIUtils.createCheckbox(
miscGroup,
......@@ -89,17 +91,45 @@ public class EditConnectionNavigatorSettingsDialog extends BaseDialog {
navigatorSettings.isMergeEntities(),
1);
boolean mergeEntitiesEnabled;
if (dataSourceDescriptor != null) {
mergeEntities.setEnabled(
dataSourceDescriptor.getDriver().getProviderDescriptor().getTreeDescriptor().supportsEntityMerge());
mergeEntitiesEnabled = dataSourceDescriptor.getDriver().getProviderDescriptor().getTreeDescriptor().supportsEntityMerge();
mergeEntities.setEnabled(mergeEntitiesEnabled);
} else {
mergeEntitiesEnabled = false;
}
mergeEntities.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (hideFolders != null) {
if (mergeEntities.getSelection()) {
hideFolders.setEnabled(false);
} else if (!hideFolders.getEnabled()) {
hideFolders.setEnabled(true);
}
}
}
});
hideFolders = UIUtils.createCheckbox(
miscGroup,
CoreMessages.dialog_connection_wizard_final_checkbox_hide_folders,
CoreMessages.dialog_connection_wizard_final_checkbox_hide_folders_tip,
navigatorSettings.isHideFolders(),
1);
hideFolders.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (hideFolders.getSelection()) {
mergeEntities.setEnabled(false);
} else if (mergeEntitiesEnabled) {
mergeEntities.setEnabled(true);
}
}
});
}
return composite;
......
......@@ -41,6 +41,7 @@
<parameter name="omit-catalog" value="true"/>
<property name="@dbeaver-default-resultset.maxrows.sql" value="true"/>
<parameter name="read-only-data" value="true"/>
<parameter name="read-only-meta-data" value="true"/>
</driver>
</drivers>
......
......@@ -146,6 +146,7 @@
<property id="supports-truncate" label="Driver supports TRUNCATE operation" description="Driver supports TRUNCATE command. It is much faster than DELETE without criteria." type="boolean" required="false" defaultValue="true"/>
<property id="supports-set-array" label="Driver supports setArray JDBC API" description="Driver supports setArray JDBC API for binding array values. Some drivers may not support setArray in favor of setObject." type="boolean" required="false" defaultValue="false"/>
<property id="read-only-data" label="Driver cannot modify data" description="Driver does not support data (e.g. in table) editing." type="boolean" required="false" defaultValue="false"/>
<property id="read-only-meta-data" label="Driver cannot modify meta data" description="Driver does not support meta data (e.g. table or column creating) editing." type="boolean" required="false" defaultValue="false"/>
</propertyGroup>
<propertyGroup label="Queries" description="Custom driver queries">
<property id="query-get-active-db" label="Get active database" description="Query to obtain active database name" type="string" required="false" defaultValue=""/>
......@@ -569,6 +570,8 @@
<parameter name="supports-indexes" value="false"/>
<parameter name="supports-references" value="false"/>
<parameter name="driver-properties" value="charset,columnTypes,commentChar,cryptoFilterClassName,cryptoFilterParameterTypes,cryptoFilterParameters,defectiveHeaders,fileExtension,fileTailParts,fileTailPattern,fileTailPrepend,fixedWidths,function.NAME,headerline,ignoreNonParseableLines,indexedFiles,isHeaderFixedWidth,missingValue,quotechar,quoteStyle,locale,separator,skipLeadingLines,skipLeadingDataLines,suppressHeaders,timestampFormat, timeFormat, dateFormat,timeZoneName,trimHeaders,trimValues"/>
<parameter name="read-only-data" value="true"/>
<parameter name="read-only-meta-data" value="true"/>
<file type="jar" path="maven:/net.sourceforge.csvjdbc:csvjdbc:RELEASE" bundle="!drivers.csvjdbc"/>
<file type="jar" path="drivers/csvjdbc" bundle="drivers.csvjdbc"/>
......@@ -597,6 +600,8 @@
<parameter name="supports-indexes" value="false"/>
<parameter name="supports-references" value="false"/>
<parameter name="driver-properties" value="charset,columnTypes,commentChar,cryptoFilterClassName,cryptoFilterParameterTypes,cryptoFilterParameters,defectiveHeaders,fileExtension,fileTailParts,fileTailPattern,fileTailPrepend,fixedWidths,function.NAME,headerline,ignoreNonParseableLines,indexedFiles,isHeaderFixedWidth,missingValue,quotechar,quoteStyle,locale,separator,skipLeadingLines,skipLeadingDataLines,suppressHeaders,timestampFormat, timeFormat, dateFormat,timeZoneName,trimHeaders,trimValues"/>
<parameter name="read-only-data" value="true"/>
<parameter name="read-only-meta-data" value="true"/>
<file type="jar" path="maven:/net.sourceforge.csvjdbc:csvjdbc:RELEASE" bundle="!drivers.csvjdbc"/>
<file type="jar" path="repo:/drivers/dbf/dans-dbf-lib-1.0.0-beta-10.jar" bundle="!drivers.csvjdbc"/>
......@@ -801,6 +806,7 @@
<parameter name="supports-references" value="false"/>
<parameter name="supports-indexes" value="false"/>
<parameter name="read-only-data" value="true"/>
<parameter name="read-only-meta-data" value="true"/>
</driver>
<!-- Virtuoso -->
......
......@@ -65,6 +65,7 @@ public class GenericConstants {
public static final String PARAM_SUPPORTS_SET_ARRAY = "supports-set-array";
public static final String PARAM_SUPPORTS_TRANSACTIONS_FOR_DDL = "supports-ddl-transactions";
public static final String PARAM_READ_ONLY_DATA = "read-only-data";
public static final String PARAM_READ_ONLY_META_DATA = "read-only-meta-data";
public static final String PARAM_NATIVE_FORMAT_TIMESTAMP = "native-format-timestamp";
public static final String PARAM_NATIVE_FORMAT_TIME = "native-format-time";
......
......@@ -43,7 +43,8 @@ public class GenericDataSourceInfo extends JDBCDataSourceInfo {
supportsMultipleResults = CommonUtils.getBoolean(driver.getDriverParameter(GenericConstants.PARAM_SUPPORTS_MULTIPLE_RESULTS), false);
supportsSetArray = CommonUtils.getBoolean(driver.getDriverParameter(GenericConstants.PARAM_SUPPORTS_SET_ARRAY), false);
supportsTransactionsForDDL = CommonUtils.getBoolean(driver.getDriverParameter(GenericConstants.PARAM_SUPPORTS_TRANSACTIONS_FOR_DDL), true);
setReadOnly(CommonUtils.getBoolean(driver.getDriverParameter(GenericConstants.PARAM_READ_ONLY_DATA), false));
setReadOnlyData(CommonUtils.getBoolean(driver.getDriverParameter(GenericConstants.PARAM_READ_ONLY_DATA), false));
setReadOnlyMetaData(CommonUtils.getBoolean(driver.getDriverParameter(GenericConstants.PARAM_READ_ONLY_META_DATA), false));
supportsNullableUniqueConstraints = false;
supportsConstraints = CommonUtils.getBoolean(driver.getDriverParameter(GenericConstants.PARAM_SUPPORTS_CONSTRAINTS), true);
......
......@@ -86,6 +86,9 @@ meta.org.jkiss.dbeaver.ext.mssql.model.SQLServerTriggerBase.triggerTypeDescripti
meta.org.jkiss.dbeaver.ext.mssql.model.generic.SQLServerGenericTable.description.name=Description
meta.org.jkiss.dbeaver.ext.mssql.model.generic.SQLServerGenericTable.description.description=Table description
meta.org.jkiss.dbeaver.ext.mssql.model.generic.SQLServerGenericTable.tableSize.name = Table size
meta.org.jkiss.dbeaver.ext.mssql.model.generic.SQLServerGenericTable.pages.name = Pages
meta.org.jkiss.dbeaver.ext.mssql.model.generic.SQLServerGenericSynonym.targetObject.name=Base object
meta.org.jkiss.dbeaver.ext.mssql.model.generic.SQLServerGenericSynonym.targetObject.description=Object to which the user of this synonym is redirected
......@@ -145,6 +148,8 @@ meta.org.jkiss.dbeaver.ext.mssql.model.SQLServerLogin.modifyDate.name = Modify D
meta.org.jkiss.dbeaver.ext.mssql.model.SQLServerLogin.defaultLanguageName.name = Default Language
meta.org.jkiss.dbeaver.ext.mssql.model.SQLServerLogin.defaultDatabase.name = Default Database
meta.org.jkiss.dbeaver.ext.mssql.model.generic.SQLServerGenericSchema.schemaId.name = Schema ID
tree.databases.node.name = Databases
tree.databases.node.tip = Server databases
tree.database.node.name = Database
......
......@@ -95,6 +95,9 @@ meta.org.jkiss.dbeaver.ext.mssql.model.SQLServerTriggerBase.triggerTypeDescripti
meta.org.jkiss.dbeaver.ext.mssql.model.generic.SQLServerGenericTable.description.name=\u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435
meta.org.jkiss.dbeaver.ext.mssql.model.generic.SQLServerGenericTable.description.description=\u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 \u0442\u0430\u0431\u043B\u0438\u0446\u044B
meta.org.jkiss.dbeaver.ext.mssql.model.generic.SQLServerGenericTable.tableSize.name = \u0420\u0430\u0437\u043C\u0435\u0440 \u0442\u0430\u0431\u043B\u0438\u0446\u044B
meta.org.jkiss.dbeaver.ext.mssql.model.generic.SQLServerGenericTable.pages.name = \u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E \u0441\u0442\u0440\u0430\u043D\u0438\u0446
meta.org.jkiss.dbeaver.ext.mssql.model.generic.SQLServerGenericSynonym.targetObject.name=\u0411\u0430\u0437\u043E\u0432\u044B\u0439 \u043E\u0431\u044A\u0435\u043A\u0442
meta.org.jkiss.dbeaver.ext.mssql.model.generic.SQLServerGenericSynonym.targetObject.description=\u041E\u0431\u044A\u0435\u043A\u0442, \u043A \u043A\u043E\u0442\u043E\u0440\u043E\u043C\u0443 \u043F\u0435\u0440\u0435\u043D\u0430\u043F\u0440\u0430\u0432\u043B\u044F\u0435\u0442\u0441\u044F \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C \u044D\u0442\u043E\u0433\u043E \u0441\u0438\u043D\u043E\u043D\u0438\u043C\u0430
......@@ -104,3 +107,5 @@ meta.org.jkiss.dbeaver.ext.mssql.model.SQLServerExtendedProperty.value.name=\u04
meta.org.jkiss.dbeaver.ext.mssql.model.SQLServerExtendedProperty.value.description=\u0417\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u043D\u043E\u0433\u043E \u0441\u0432\u043E\u0439\u0441\u0442\u0432\u0430
meta.org.jkiss.dbeaver.ext.mssql.model.SQLServerExtendedProperty.valueType.name=\u0422\u0438\u043F \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044F
meta.org.jkiss.dbeaver.ext.mssql.model.SQLServerExtendedProperty.valueType.description=\u0422\u0438\u043F \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044F \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u043D\u043E\u0433\u043E \u0441\u0432\u043E\u0439\u0441\u0442\u0432\u0430
meta.org.jkiss.dbeaver.ext.mssql.model.generic.SQLServerGenericSchema.schemaId.name = ID \u0441\u0445\u0435\u043C\u044B
\ No newline at end of file
......@@ -18,6 +18,7 @@
package org.jkiss.dbeaver.ext.mssql;
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.mssql.model.*;
......@@ -37,7 +38,9 @@ import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.sql.SQLDialect;
import org.jkiss.dbeaver.model.sql.SQLQuery;
import org.jkiss.dbeaver.model.sql.SQLUtils;
import org.jkiss.dbeaver.model.struct.rdb.DBSCatalog;
import org.jkiss.dbeaver.model.struct.rdb.DBSForeignKeyModifyRule;
import org.jkiss.dbeaver.model.struct.rdb.DBSTable;
import org.jkiss.utils.CommonUtils;
import java.sql.Connection;
......@@ -135,6 +138,14 @@ public class SQLServerUtils {
return SQLServerUtils.getSystemSchemaFQN(database.getDataSource(), database.getName(), SQLServerConstants.SQL_SERVER_SYSTEM_SCHEMA) + "." + tableName;
}
public static String getSystemTableFQN(@NotNull JDBCDataSource dataSource, @NotNull DBSCatalog database, @NotNull String tableName, boolean isSQLServer) {
return SQLServerUtils.getSystemSchemaFQN(
dataSource,
database.getName(),
isSQLServer? SQLServerConstants.SQL_SERVER_SYSTEM_SCHEMA : SQLServerConstants.SYBASE_SYSTEM_SCHEMA)
+ "." + tableName;
}
public static String getExtendedPropsTableName(SQLServerDatabase database) {
return getSystemTableName(database, SQLServerConstants.SYS_TABLE_EXTENDED_PROPERTIES);
}
......@@ -278,4 +289,39 @@ public class SQLServerUtils {
return null;
}
public static JDBCPreparedStatement prepareTableStatisticLoadStatement(@NotNull JDBCSession session, @NotNull JDBCDataSource dataSource, @NotNull DBSCatalog catalog, long schemaId, @Nullable DBSTable table, boolean isSQLServer) throws SQLException {
String query;
if (isSQLServer) {
query = "SELECT t.name, p.rows, SUM(a.total_pages) * 8 AS totalSize, SUM(a.used_pages) * 8 AS usedSize\n" +
"FROM " + SQLServerUtils.getSystemTableFQN(dataSource, catalog, "tables", true) + " t\n" +
"INNER JOIN " + SQLServerUtils.getSystemTableFQN(dataSource, catalog, "indexes", true) + " i ON t.OBJECT_ID = i.object_id\n" +
"INNER JOIN " + SQLServerUtils.getSystemTableFQN(dataSource, catalog, "partitions", true) + " p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id\n" +
"INNER JOIN " + SQLServerUtils.getSystemTableFQN(dataSource, catalog, "allocation_units", true) + " a ON p.partition_id = a.container_id\n" +
"LEFT OUTER JOIN " + SQLServerUtils.getSystemTableFQN(dataSource, catalog, "schemas", true) + " s ON t.schema_id = s.schema_id\n" +
"WHERE t.schema_id = ?\n" + (table != null ? "AND t.object_id=?\n" : "") +
"GROUP BY t.name, p.rows";
} else {
query = "SELECT convert(varchar(100),o.name) AS 'name',\n" +
"row_count(db_id(), o.id) AS 'rows',\n" +
"data_pages(db_id(), o.id, 0) AS 'pages',\n" +
"data_pages(db_id(), o.id, 0) * (@@maxpagesize) AS 'totalSize'\n" +
"FROM " + SQLServerUtils.getSystemTableFQN(dataSource, catalog, "sysobjects", false) + " o\n" +
"WHERE type = 'U'\n" +
"AND o.uid = ?\n" +
(table != null ? " AND 'name'=?\n" : "") +
"ORDER BY 'name'";
}
JDBCPreparedStatement dbStat = session.prepareStatement(query);
dbStat.setLong(1, schemaId);
if (table != null) {
if (isSQLServer) {
SQLServerTable sqlServerTable = (SQLServerTable) table;
dbStat.setLong(2, sqlServerTable.getObjectId());
} else {
dbStat.setString(2, table.getName());
}
}
return dbStat;
}
}
......@@ -325,29 +325,26 @@ public class SQLServerSchema implements DBSSchema, DBPSaveableObject, DBPQualifi
return;
}
try (JDBCSession session = DBUtils.openMetaSession(monitor, this, "Load table statistics")) {
try (JDBCPreparedStatement dbStat = session.prepareStatement(
"SELECT t.name, p.rows, SUM(a.total_pages) * 8 AS totalSize, SUM(a.used_pages) * 8 AS usedSize\n" +
"FROM " + SQLServerUtils.getSystemTableName(getDatabase(), "tables") + " t\n" +
"INNER JOIN " + SQLServerUtils.getSystemTableName(getDatabase(), "indexes") + " i ON t.OBJECT_ID = i.object_id\n" +
"INNER JOIN " + SQLServerUtils.getSystemTableName(getDatabase(), "partitions") + " p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id\n" +
"INNER JOIN " + SQLServerUtils.getSystemTableName(getDatabase(), "allocation_units") + " a ON p.partition_id = a.container_id\n" +
"LEFT OUTER JOIN " + SQLServerUtils.getSystemTableName(getDatabase(), "schemas") + " s ON t.schema_id = s.schema_id\n" +
"WHERE t.schema_id = ?\n" +
"GROUP BY t.name, p.rows"))
{
dbStat.setLong(1, getObjectId());
try (JDBCPreparedStatement dbStat = SQLServerUtils.prepareTableStatisticLoadStatement(
session,
getDataSource(),
getDatabase(),
getObjectId(),
null,
true
)) {
try (JDBCResultSet dbResult = dbStat.executeQuery()) {
while (dbResult.next()) {
String tableName = dbResult.getString("name");
SQLServerTableBase table = getTable(monitor, tableName);
if (table instanceof SQLServerTable) {
((SQLServerTable)table).fetchTableStats(dbResult);
((SQLServerTable) table).fetchTableStats(dbResult);
}
}
}
for (SQLServerTableBase table : tableCache.getCachedObjects()) {
if (table instanceof SQLServerTable && !((SQLServerTable)table).hasStatistics()) {
((SQLServerTable)table).setDefaultTableStats();
if (table instanceof SQLServerTable && !((SQLServerTable) table).hasStatistics()) {
((SQLServerTable) table).setDefaultTableStats();
}
}
}
......
......@@ -225,18 +225,13 @@ public class SQLServerTable extends SQLServerTableBase
return;
}
try (JDBCSession session = DBUtils.openMetaSession(monitor, this, "Load table statistics")) {
try (JDBCPreparedStatement dbStat = session.prepareStatement(
"SELECT t.name, p.rows, SUM(a.total_pages) * 8 AS totalSize, SUM(a.used_pages) * 8 AS usedSize\n" +
"FROM " + SQLServerUtils.getSystemTableName(getDatabase(), "tables") + " t\n" +
"INNER JOIN " + SQLServerUtils.getSystemTableName(getDatabase(), "indexes") + " i ON t.OBJECT_ID = i.object_id\n" +
"INNER JOIN " + SQLServerUtils.getSystemTableName(getDatabase(), "partitions") + " p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id\n" +
"INNER JOIN " + SQLServerUtils.getSystemTableName(getDatabase(), "allocation_units") + " a ON p.partition_id = a.container_id\n" +
"LEFT OUTER JOIN " + SQLServerUtils.getSystemTableName(getDatabase(), "schemas") + " s ON t.schema_id = s.schema_id\n" +
"WHERE t.schema_id = ?\n AND t.object_id=?\n" +
"GROUP BY t.name, p.rows"))
{
dbStat.setLong(1, getSchema().getObjectId());
dbStat.setLong(2, getObjectId());
try (JDBCPreparedStatement dbStat = SQLServerUtils.prepareTableStatisticLoadStatement(
session,
getDataSource(),
getDatabase(),
getSchema().getObjectId(),
this,
true)) {
try (JDBCResultSet dbResult = dbStat.executeQuery()) {
if (dbResult.next()) {
fetchTableStats(dbResult);
......
......@@ -16,24 +16,86 @@
*/
package org.jkiss.dbeaver.ext.mssql.model.generic;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.ext.generic.model.GenericCatalog;
import org.jkiss.dbeaver.ext.generic.model.GenericDataSource;
import org.jkiss.dbeaver.ext.generic.model.GenericSchema;
import org.jkiss.dbeaver.ext.generic.model.GenericTableBase;
import org.jkiss.dbeaver.ext.mssql.SQLServerUtils;
import org.jkiss.dbeaver.model.DBPObjectStatisticsCollector;
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.meta.Property;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import java.sql.SQLException;
/**
* SQL Server schemas
*/
public class SQLServerGenericSchema extends GenericSchema {
public class SQLServerGenericSchema extends GenericSchema implements DBPObjectStatisticsCollector {
private static final Log log = Log.getLog(SQLServerGenericSchema.class);
private long schemaId;
private boolean hasStatistics;
public SQLServerGenericSchema(GenericDataSource dataSource, GenericCatalog catalog, String schemaName, long schemaId) {
super(dataSource, catalog, schemaName);
this.schemaId = schemaId;
}
@Property(viewable = true, order = 3)
public long getSchemaId() {
return schemaId;
}
@Override
public boolean isStatisticsCollected() {
return hasStatistics;
}
@Override
public void collectObjectStatistics(DBRProgressMonitor monitor, boolean totalSizeOnly, boolean forceRefresh) throws DBException {
if (hasStatistics && !forceRefresh) {
return;
}
boolean isSQLServer = ((SQLServerMetaModel) getDataSource().getMetaModel()).isSqlServer();
if (!isSQLServer && !getDataSource().isServerVersionAtLeast(15, 0)) {
hasStatistics = true;
return;
}
GenericCatalog catalog = getCatalog();
if (catalog == null) {
log.debug("Can't read tables statistics due to lack of schemas catalog");
return;
}
try (JDBCSession session = DBUtils.openMetaSession(monitor, this, "Load table statistics")) {
try (JDBCPreparedStatement dbStat = SQLServerUtils.prepareTableStatisticLoadStatement(
session,
getDataSource(),
catalog,
getSchemaId(),
null,
isSQLServer)) {
try (JDBCResultSet dbResult = dbStat.executeQuery()) {
while (dbResult.next()) {
String tableName = dbResult.getString("name");
GenericTableBase table = getTable(monitor, tableName);
if (table instanceof SQLServerGenericTable) {
((SQLServerGenericTable) table).fetchTableStats(dbResult);
}
}
}
}
} catch (SQLException e) {
throw new DBCException("Error reading table statistics", e);
} finally {
hasStatistics = true;
}
}
}
......@@ -19,17 +19,25 @@ package org.jkiss.dbeaver.ext.mssql.model.generic;
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.generic.model.GenericStructContainer;
import org.jkiss.dbeaver.ext.generic.model.GenericTable;
import org.jkiss.dbeaver.ext.mssql.SQLServerUtils;
import org.jkiss.dbeaver.model.DBConstants;
import org.jkiss.dbeaver.model.DBPObjectStatistics;
import org.jkiss.dbeaver.model.DBPObjectWithLazyDescription;
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.jdbc.JDBCUtils;
import org.jkiss.dbeaver.model.meta.Property;
import org.jkiss.dbeaver.model.meta.PropertyLength;
import org.jkiss.dbeaver.model.preferences.DBPPropertySource;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.struct.DBSObject;
import org.jkiss.utils.ByteNumberFormat;
import java.sql.SQLException;
import java.util.List;
......@@ -37,12 +45,35 @@ import java.util.List;
/**
* SQL Server table
*/
public class SQLServerGenericTable extends GenericTable implements DBPObjectWithLazyDescription {
public class SQLServerGenericTable extends GenericTable implements DBPObjectWithLazyDescription, DBPObjectStatistics {
private static final Log log = Log.getLog(SQLServerGenericTable.class);
private long tableSize = -1;
private long rowCount;
private long pages;
public SQLServerGenericTable(GenericStructContainer container, String tableName, String tableType, JDBCResultSet dbResult) {
super(container, tableName, tableType, dbResult);
}
@Property(category = DBConstants.CAT_STATISTICS, order = 3, formatter = ByteNumberFormat.class)
public long getTableSize(DBRProgressMonitor monitor) {
readTableStats(monitor);
return tableSize;
}
@Property(category = DBConstants.CAT_STATISTICS, order = 4)
public Long getRowCount(DBRProgressMonitor monitor) {
readTableStats(monitor);
return rowCount;
}
@Property(category = DBConstants.CAT_STATISTICS, order = 5)
public long getPages() {
return pages;
}
@Nullable
@Override
public synchronized List<SQLServerGenericTableColumn> getAttributes(@NotNull DBRProgressMonitor monitor) throws DBException {
......@@ -103,6 +134,7 @@ public class SQLServerGenericTable extends GenericTable implements DBPObjectWith
return description;
}
@NotNull
@Override
public SQLServerGenericDataSource getDataSource() {
return (SQLServerGenericDataSource)super.getDataSource();
......@@ -116,4 +148,57 @@ public class SQLServerGenericTable extends GenericTable implements DBPObjectWith
protected boolean isTruncateSupported() {
return true;
}
void fetchTableStats(JDBCResultSet dbResult) {
tableSize = JDBCUtils.safeGetLong(dbResult,"totalSize");
if (isSqlServer()) {
tableSize = tableSize * 1024;
} else {
pages = JDBCUtils.safeGetLong(dbResult,"pages");
}
rowCount = JDBCUtils.safeGetLong(dbResult,"rows");
}
@Override
public boolean hasStatistics() {
return tableSize != -1;
}
@Override
public long getStatObjectSize() {
return tableSize;
}
@Nullable
@Override
public DBPPropertySource getStatProperties() {
return null;
}
private void readTableStats(DBRProgressMonitor monitor) {
if (hasStatistics()) {
return;
}
if (!isSqlServer() && !getDataSource().isServerVersionAtLeast(15, 0)) {
tableSize = 0;
return;
}
try (JDBCSession session = DBUtils.openMetaSession(monitor, this, "Load table statistics")) {
try (JDBCPreparedStatement dbStat = SQLServerUtils.prepareTableStatisticLoadStatement(
session,
getDataSource(),
getCatalog(),
((SQLServerGenericSchema) getSchema()).getSchemaId(),
this,
isSqlServer())) {
try (JDBCResultSet dbResult = dbStat.executeQuery()) {
if (dbResult.next()) {
fetchTableStats(dbResult);
}
}
}
} catch (SQLException | DBCException e) {
log.error("Error reading table statistics", e);
}
}
}
......@@ -384,7 +384,12 @@ public class SQLServerMetaModel extends GenericMetaModel implements DBCQueryTran
continue;
}
long schemaId = JDBCUtils.safeGetLong(dbResult, "schema_id");
long schemaId;
if (isSqlServer()) {
schemaId = JDBCUtils.safeGetLong(dbResult, "schema_id");
} else {
schemaId = JDBCUtils.safeGetLong(dbResult, "uid");
}
SQLServerGenericSchema schema = new SQLServerGenericSchema(
dataSource, catalog, name, schemaId);
result.add(schema);
......
......@@ -2089,7 +2089,9 @@ public final class DBUtils {
return true;
}
DBPDataSource dataSource = object.getDataSource();
return dataSource == null || !dataSource.getContainer().hasModifyPermission(DBPDataSourcePermission.PERMISSION_EDIT_METADATA);
return dataSource == null ||
!dataSource.getContainer().hasModifyPermission(DBPDataSourcePermission.PERMISSION_EDIT_METADATA) ||
dataSource.getInfo().isReadOnlyMetaData();
}
public static <T> T createNewAttributeValue(DBCExecutionContext context, DBDValueHandler valueHandler, DBSTypedObject valueType, Class<T> targetType) throws DBCException {
......
......@@ -43,6 +43,8 @@ public class JDBCDataSourceInfo extends AbstractDataSourceInfo
public static final String TERM_CATALOG = ModelMessages.model_jdbc_Database;
private boolean readOnly;
private boolean readOnlyData;
private boolean readOnlyMetaData;
private String databaseProductName;
private String databaseProductVersion;
private String driverName;
......@@ -198,17 +200,21 @@ public class JDBCDataSourceInfo extends AbstractDataSourceInfo
@Override
public boolean isReadOnlyData()
{
return readOnly;
return readOnly || readOnlyData;
}
protected void setReadOnly(boolean readOnly) {
this.readOnly = readOnly;
protected void setReadOnlyData(boolean readOnly) {
this.readOnlyData = readOnly;
}
@Override
public boolean isReadOnlyMetaData()
{
return readOnly;
return readOnly || readOnlyMetaData;
}
protected void setReadOnlyMetaData(boolean readOnlyMetaData) {
this.readOnlyMetaData = readOnlyMetaData;
}
@Override
......
......@@ -21,6 +21,7 @@ import org.eclipse.jface.action.IContributionItem;
import org.eclipse.swt.widgets.Display;
import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.model.DBPDataSource;
import org.jkiss.dbeaver.model.DBPOrderedObject;
import org.jkiss.dbeaver.model.DBUtils;
import org.jkiss.dbeaver.model.app.DBPResourceHandler;
......@@ -229,6 +230,10 @@ public class ObjectPropertyTester extends PropertyTester
// Can't create virtual objects
return false;
}
DBPDataSource dataSource = ((DBNDatabaseNode) node).getDataSource();
if (dataSource != null && dataSource.getInfo().isReadOnlyMetaData()) {
return false;
}
if (!(node instanceof DBNDataSource) && isMetadataChangeDisabled(((DBNDatabaseNode)node))) {
return false;
}
......
......@@ -418,6 +418,9 @@ public class StatisticsNavigatorNodeRenderer extends DefaultNavigatorNodeRendere
}
}
sizeText = format.format(statObjectSize);
} else if (statsWasRead) {
// Statistic is not available
return;
} else {
sizeText = "...";
percentFull = 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册