提交 82e62227 编写于 作者: S Serge Rider

#5004 SQL Server: session manager

上级 eee3d78a
......@@ -4,4 +4,7 @@ Bundle-Name = DBeaver SQL Server UI
sqlserver.dialog.connection.header=SQL Server Connection Settings
editor.source.name = Source
editor.source.description = Source code
\ No newline at end of file
editor.source.description = Source code
tree.databaseInfo.node.name = Administration
editor.session_manager.name = Sessions
\ No newline at end of file
......@@ -71,4 +71,26 @@
</editor>
</extension>
<extension point="org.jkiss.dbeaver.dataSourceProvider">
<datasourcePatch id="sqlserver">
<treeInjection path="sqlserver/database" after="trigger">
<folder label="%tree.databaseInfo.node.name" icon="#folder_info" description="Database system information">
<object type="org.jkiss.dbeaver.ext.mssql.ui.editors.SQLServerSessionEditor" label="%tree.sessions.node.name" icon="#sessions" description="Server session manager" editor="org.jkiss.dbeaver.ext.mssql.ui.editors.SQLServerSessionEditor"/>
</folder>
</treeInjection>
</datasourcePatch>
</extension>
<extension point="org.eclipse.ui.editors">
<editor
name="%editor.session_manager.name"
icon="platform:/plugin/org.jkiss.dbeaver.model/icons/tree/sessions.png"
class="org.jkiss.dbeaver.ext.mssql.ui.editors.SQLServerSessionEditor"
id="org.jkiss.dbeaver.ext.mssql.ui.editors.SQLServerSessionEditor"
contributorClass="org.jkiss.dbeaver.ui.editors.EditorSearchActionsContributor">
</editor>
</extension>
</plugin>
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2019 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.mssql.ui.editors;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IContributionManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.ISharedImages;
import org.jkiss.dbeaver.ext.mssql.model.SQLServerDataSource;
import org.jkiss.dbeaver.ext.mssql.model.session.SQLServerSession;
import org.jkiss.dbeaver.ext.mssql.model.session.SQLServerSessionManager;
import org.jkiss.dbeaver.model.admin.sessions.DBAServerSession;
import org.jkiss.dbeaver.model.admin.sessions.DBAServerSessionManager;
import org.jkiss.dbeaver.model.exec.DBCExecutionContext;
import org.jkiss.dbeaver.ui.UIUtils;
import org.jkiss.dbeaver.ui.views.session.AbstractSessionEditor;
import org.jkiss.dbeaver.ui.views.session.SessionManagerViewer;
import java.util.List;
/**
* SQLServerSessionEditor
*/
public class SQLServerSessionEditor extends AbstractSessionEditor
{
private KillSessionAction terminateQueryAction;
@Override
public void createEditorControl(Composite parent) {
terminateQueryAction = new KillSessionAction();
super.createEditorControl(parent);
}
@Override
protected SessionManagerViewer createSessionViewer(DBCExecutionContext executionContext, Composite parent) {
return new SessionManagerViewer<SQLServerSession>(this, parent, new SQLServerSessionManager((SQLServerDataSource) executionContext.getDataSource())) {
@Override
protected void contributeToToolbar(DBAServerSessionManager sessionManager, IContributionManager contributionManager)
{
contributionManager.add(terminateQueryAction);
contributionManager.add(new Separator());
}
@Override
protected void onSessionSelect(DBAServerSession session)
{
super.onSessionSelect(session);
terminateQueryAction.setEnabled(session != null);
}
};
}
private class KillSessionAction extends Action {
KillSessionAction()
{
super(
"Terminate",
UIUtils.getShardImageDescriptor(ISharedImages.IMG_ELCL_STOP));
}
@Override
public void run()
{
final List<DBAServerSession> sessions = getSessionsViewer().getSelectedSessions();
if (sessions != null && UIUtils.confirmAction(
getSite().getShell(),
this.getText(),
NLS.bind("Terminate session {0}?", sessions)))
{
getSessionsViewer().alterSessions(
sessions,
null);
}
}
}
}
\ No newline at end of file
......@@ -13,7 +13,8 @@ Require-Bundle: org.eclipse.ui,
com.github.jsqlparser
Export-Package: org.jkiss.dbeaver.ext.mssql,
org.jkiss.dbeaver.ext.mssql.model,
org.jkiss.dbeaver.ext.mssql.model.generic
org.jkiss.dbeaver.ext.mssql.model.generic,
org.jkiss.dbeaver.ext.mssql.model.session
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-Vendor: %Bundle-Vendor
......
......@@ -108,4 +108,3 @@ tree.uni_keys.node.name = Unique Keys
tree.check_constraints.node.name = Check constraints
tree.check_constraint.node.name = Check constraint
tree.databaseTriggers.node.name = Database triggers
tree.databaseInfo.node.name = Database system info
......@@ -35,7 +35,7 @@
label="MS SQL Server"
icon="icons/mssql_icon.png">
<tree path="generic" label="Generic data source">
<tree path="sqlserver" label="SQL Server data source">
<items label="%tree.database.node.name" path="database" property="databases" icon="#database">
<folder type="org.jkiss.dbeaver.ext.mssql.model.SQLServerSchema" label="%tree.schemas.node.name" icon="#folder_schema" description="Schemas">
<items label="%tree.schema.node.name" path="schema" property="schemas" icon="#schema">
......@@ -116,13 +116,6 @@
<folder type="org.jkiss.dbeaver.ext.mssql.model.SQLServerDatabaseTrigger" label="%tree.databaseTriggers.node.name" icon="#triggers" description="All database triggers">
<items label="%tree.trigger.node.name" path="trigger" property="triggers" icon="#trigger"/>
</folder>
<folder label="%tree.databaseInfo.node.name" icon="#folder_info" description="Database system information">
<!--
<folder type="org.jkiss.dbeaver.ext.mysql.model.MySQLParameter" label="%tree.session_status.node.name" icon="#info" description="Session status">
<items label="%tree.variable.node.name" path="sessionStatus" property="sessionStatus" icon="#info" navigable="false" virtual="true"/>
</folder>
-->
</folder>
</items>
</tree>
......
......@@ -24,9 +24,10 @@ import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.ModelPreferences;
import org.jkiss.dbeaver.ext.mssql.SQLServerConstants;
import org.jkiss.dbeaver.ext.mssql.SQLServerUtils;
import org.jkiss.dbeaver.ext.mssql.model.session.SQLServerSessionManager;
import org.jkiss.dbeaver.model.*;
import org.jkiss.dbeaver.model.admin.sessions.DBAServerSessionManager;
import org.jkiss.dbeaver.model.connection.DBPConnectionConfiguration;
import org.jkiss.dbeaver.model.connection.DBPDriver;
import org.jkiss.dbeaver.model.exec.DBCException;
import org.jkiss.dbeaver.model.exec.DBCExecutionContext;
import org.jkiss.dbeaver.model.exec.DBCExecutionPurpose;
......@@ -43,9 +44,10 @@ import org.jkiss.dbeaver.utils.GeneralUtils;
import org.jkiss.utils.BeanUtils;
import org.jkiss.utils.CommonUtils;
import java.lang.reflect.InvocationTargetException;
import java.sql.SQLException;
import java.util.*;
import java.util.Collection;
import java.util.List;
import java.util.Properties;
public class SQLServerDataSource extends JDBCDataSource implements DBSObjectSelector, DBSInstanceContainer, /*DBCQueryPlanner, */IAdaptable {
......@@ -300,6 +302,8 @@ public class SQLServerDataSource extends JDBCDataSource implements DBSObjectSele
public <T> T getAdapter(Class<T> adapter) {
if (adapter == DBSStructureAssistant.class) {
return adapter.cast(new SQLServerStructureAssistant(this));
} else if (adapter == DBAServerSessionManager .class) {
return adapter.cast(new SQLServerSessionManager(this));
}
return super.getAdapter(adapter);
}
......
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2019 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.mssql.model.session;
import org.jkiss.dbeaver.model.admin.sessions.DBAServerSession;
import org.jkiss.dbeaver.model.impl.jdbc.JDBCUtils;
import org.jkiss.dbeaver.model.meta.Property;
import org.jkiss.utils.CommonUtils;
import java.sql.ResultSet;
import java.util.Date;
/**
* SQL Server session
*/
public class SQLServerSession implements DBAServerSession {
private static final String CAT_CLIENT = "Client";
private static final String CAT_TIMING = "Timings";
private static final String CAT_STATISTICS = "Statistics";
private long id;
private Date loginTime;
private Date lastRequestStart;
private Date lastRequestEnd;
private String hostName;
private String programName;
private String hostPID;
private String clientVersion;
private String clientInterface;
private String loginName;
private String ntDomain;
private String ntUserName;
private String status;
private long cpuTime;
private long memoryUsage;
private long totalScheduledTime;
private long totalElapsedTime;
private long readsNum;
private long writesNum;
private String language;
private long rowCount;
private String fileName;
private String databaseName;
private String sqlText;
public SQLServerSession(ResultSet dbResult) {
this.id = JDBCUtils.safeGetInt(dbResult, "session_id");
loginTime = JDBCUtils.safeGetTimestamp(dbResult, "login_time");;
lastRequestStart = JDBCUtils.safeGetTimestamp(dbResult, "last_request_start");
lastRequestEnd = JDBCUtils.safeGetTimestamp(dbResult, "last_request_end");
hostName = JDBCUtils.safeGetString(dbResult, "host_name");
programName = JDBCUtils.safeGetString(dbResult, "program_name");
hostPID = JDBCUtils.safeGetString(dbResult, "host_process_id");
clientVersion = JDBCUtils.safeGetString(dbResult, "client_version");
clientInterface = JDBCUtils.safeGetString(dbResult, "client_interface");
loginName = JDBCUtils.safeGetString(dbResult, "login_name");
ntDomain = JDBCUtils.safeGetString(dbResult, "nt_domain");
ntUserName = JDBCUtils.safeGetString(dbResult, "nt_user_name");
status = JDBCUtils.safeGetString(dbResult, "status");
cpuTime = JDBCUtils.safeGetLong(dbResult, "cpu_time");
memoryUsage = JDBCUtils.safeGetLong(dbResult, "memory_usage");
totalScheduledTime = JDBCUtils.safeGetLong(dbResult, "total_scheduled_time");
totalElapsedTime = JDBCUtils.safeGetLong(dbResult, "total_elapsed_time");
readsNum = JDBCUtils.safeGetLong(dbResult, "reads");
writesNum = JDBCUtils.safeGetLong(dbResult, "writes");
language = JDBCUtils.safeGetString(dbResult, "language");
rowCount = JDBCUtils.safeGetLong(dbResult, "row_count");
fileName = JDBCUtils.safeGetString(dbResult, "file_name");
databaseName = JDBCUtils.safeGetString(dbResult, "database_name");
sqlText = JDBCUtils.safeGetString(dbResult, "sql_text");
}
@Property(viewable = true, order = 1)
public long getId() {
return id;
}
@Property(viewable = false, category = CAT_TIMING, order = 10)
public Date getLoginTime() {
return loginTime;
}
@Property(viewable = false, category = CAT_TIMING, order = 11)
public Date getLastRequestStart() {
return lastRequestStart;
}
@Property(viewable = false, category = CAT_TIMING, order = 12)
public Date getLastRequestEnd() {
return lastRequestEnd;
}
@Property(viewable = false, category = CAT_CLIENT, order = 20)
public String getHostName() {
return hostName;
}
@Property(viewable = true, category = CAT_CLIENT, order = 21)
public String getProgramName() {
return programName;
}
@Property(viewable = true, category = CAT_CLIENT, order = 22)
public String getHostPID() {
return hostPID;
}
@Property(viewable = false, category = CAT_CLIENT, order = 23)
public String getClientVersion() {
return clientVersion;
}
@Property(viewable = false, category = CAT_CLIENT, order = 24)
public String getClientInterface() {
return clientInterface;
}
@Property(viewable = true, category = CAT_CLIENT, order = 25)
public String getLoginName() {
return loginName;
}
@Property(viewable = true, category = CAT_CLIENT, order = 26)
public String getNtDomain() {
return ntDomain;
}
@Property(viewable = false, category = CAT_CLIENT, order = 27)
public String getNtUserName() {
return ntUserName;
}
@Property(viewable = true, order = 5)
public String getStatus() {
return status;
}
@Property(viewable = true, category = CAT_STATISTICS, order = 40)
public long getCpuTime() {
return cpuTime;
}
@Property(viewable = true, category = CAT_STATISTICS, order = 41)
public long getMemoryUsage() {
return memoryUsage;
}
@Property(viewable = false, category = CAT_STATISTICS, order = 42)
public long getTotalScheduledTime() {
return totalScheduledTime;
}
@Property(viewable = false, category = CAT_STATISTICS, order = 43)
public long getTotalElapsedTime() {
return totalElapsedTime;
}
@Property(viewable = true, category = CAT_STATISTICS, order = 44)
public long getReadsNum() {
return readsNum;
}
@Property(viewable = true, category = CAT_STATISTICS, order = 45)
public long getWritesNum() {
return writesNum;
}
@Property(viewable = false, category = CAT_STATISTICS, order = 46)
public long getRowCount() {
return rowCount;
}
@Property(viewable = false, category = CAT_CLIENT, order = 30)
public String getFileName() {
return fileName;
}
@Property(viewable = false, category = CAT_CLIENT, order = 31)
public String getDatabaseName() {
return databaseName;
}
@Property(viewable = false, category = CAT_CLIENT, order = 32)
public String getLanguage() {
return language;
}
@Override
@Property(viewable = false, order = 9)
public String getActiveQuery()
{
return sqlText;
}
@Override
public String toString()
{
if (databaseName != null) {
return id + "@" + databaseName;
} else {
return String.valueOf(id);
}
}
}
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2019 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.mssql.model.session;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.ext.mssql.model.SQLServerDataSource;
import org.jkiss.dbeaver.model.DBPDataSource;
import org.jkiss.dbeaver.model.admin.sessions.DBAServerSessionManager;
import org.jkiss.dbeaver.model.exec.DBCSession;
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 java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* SQLServer session manager
*/
public class SQLServerSessionManager implements DBAServerSessionManager<SQLServerSession> {
private final SQLServerDataSource dataSource;
public SQLServerSessionManager(SQLServerDataSource dataSource)
{
this.dataSource = dataSource;
}
@Override
public DBPDataSource getDataSource()
{
return dataSource;
}
@Override
public Collection<SQLServerSession> getSessions(DBCSession session, Map<String, Object> options) throws DBException
{
try {
try (JDBCPreparedStatement dbStat = ((JDBCSession) session).prepareStatement(
"select *,db.name as database_name,r.sql_handle,(select text from sys.dm_exec_sql_text(r.sql_handle)) as sql_text\n" +
"from sys.dm_exec_sessions s\n" +
"left outer join sys.sysdatabases db on db.dbid=s.database_id\n" +
"left outer join sys.dm_exec_requests r on r.session_id=s.session_id")) {
try (JDBCResultSet dbResult = dbStat.executeQuery()) {
List<SQLServerSession> sessions = new ArrayList<>();
while (dbResult.next()) {
sessions.add(new SQLServerSession(dbResult));
}
return sessions;
}
}
} catch (SQLException e) {
throw new DBException(e, session.getDataSource());
}
}
@Override
public void alterSession(DBCSession session, SQLServerSession sessionType, Map<String, Object> options) throws DBException
{
try {
try (Statement dbStat = ((JDBCSession) session).createStatement()) {
dbStat.execute("KILL " + sessionType.getId() + ")");
}
}
catch (SQLException e) {
throw new DBException(e, session.getDataSource());
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册