未验证 提交 e2467b81 编写于 作者: S Serge Rider 提交者: GitHub

Merge pull request #2747 from dbeaver/2556-postgres-generics

2556 postgres generics
......@@ -17,12 +17,34 @@
package org.jkiss.dbeaver.ui.editors.sql;
import org.eclipse.jface.action.*;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.*;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentPartitioner;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.ITextViewerExtension;
import org.eclipse.jface.text.TextSelection;
import org.eclipse.jface.text.rules.FastPartitioner;
import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.source.*;
import org.eclipse.jface.text.source.DefaultCharacterPairMatcher;
import org.eclipse.jface.text.source.IAnnotationAccess;
import org.eclipse.jface.text.source.ICharacterPairMatcher;
import org.eclipse.jface.text.source.IOverviewRuler;
import org.eclipse.jface.text.source.ISharedTextColors;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.IVerticalRuler;
import org.eclipse.jface.text.source.VerticalRuler;
import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel;
import org.eclipse.jface.text.source.projection.ProjectionSupport;
import org.eclipse.jface.text.source.projection.ProjectionViewer;
......@@ -35,8 +57,12 @@ import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.PreferencesUtil;
import org.eclipse.ui.internal.editors.text.EditorsPlugin;
import org.eclipse.ui.texteditor.*;
import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.texteditor.DefaultRangeIndicator;
import org.eclipse.ui.texteditor.ITextEditorActionConstants;
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;
import org.eclipse.ui.texteditor.TextOperationAction;
import org.eclipse.ui.texteditor.templates.ITemplatesPage;
import org.eclipse.ui.themes.IThemeManager;
import org.jkiss.code.NotNull;
......@@ -47,12 +73,24 @@ import org.jkiss.dbeaver.core.CoreCommands;
import org.jkiss.dbeaver.core.DBeaverActivator;
import org.jkiss.dbeaver.core.DBeaverCore;
import org.jkiss.dbeaver.core.DBeaverUI;
import org.jkiss.dbeaver.model.*;
import org.jkiss.dbeaver.model.DBPDataSource;
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
import org.jkiss.dbeaver.model.DBPErrorAssistant;
import org.jkiss.dbeaver.model.DBUtils;
import org.jkiss.dbeaver.model.IDataSourceContainerProvider;
import org.jkiss.dbeaver.model.exec.DBCExecutionContext;
import org.jkiss.dbeaver.model.impl.sql.BasicSQLDialect;
import org.jkiss.dbeaver.model.preferences.DBPPreferenceStore;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.sql.*;
import org.jkiss.dbeaver.model.sql.SQLConstants;
import org.jkiss.dbeaver.model.sql.SQLControlCommand;
import org.jkiss.dbeaver.model.sql.SQLDataSource;
import org.jkiss.dbeaver.model.sql.SQLDialect;
import org.jkiss.dbeaver.model.sql.SQLQuery;
import org.jkiss.dbeaver.model.sql.SQLQueryParameter;
import org.jkiss.dbeaver.model.sql.SQLScriptElement;
import org.jkiss.dbeaver.model.sql.SQLSyntaxManager;
import org.jkiss.dbeaver.model.sql.SQLUtils;
import org.jkiss.dbeaver.ui.ActionUtils;
import org.jkiss.dbeaver.ui.ICommentsSupport;
import org.jkiss.dbeaver.ui.IErrorVisualizer;
......@@ -64,29 +102,29 @@ import org.jkiss.dbeaver.ui.editors.sql.syntax.tokens.SQLToken;
import org.jkiss.dbeaver.ui.editors.sql.templates.SQLTemplatesPage;
import org.jkiss.dbeaver.ui.editors.sql.util.SQLSymbolInserter;
import org.jkiss.dbeaver.ui.editors.text.BaseTextEditor;
import org.jkiss.dbeaver.ui.preferences.*;
import org.jkiss.dbeaver.ui.preferences.PrefPageSQLCompletion;
import org.jkiss.dbeaver.ui.preferences.PrefPageSQLEditor;
import org.jkiss.dbeaver.ui.preferences.PrefPageSQLExecute;
import org.jkiss.dbeaver.ui.preferences.PrefPageSQLFormat;
import org.jkiss.dbeaver.ui.preferences.PrefPageSQLTemplates;
import org.jkiss.utils.ArrayUtils;
import org.jkiss.utils.CommonUtils;
import org.jkiss.utils.Pair;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
/**
* SQL Executor
*/
public abstract class SQLEditorBase extends BaseTextEditor implements IErrorVisualizer {
static protected final Log log = Log.getLog(SQLEditorBase.class);
public static final String SQL_EDITOR_CONTEXT = "org.jkiss.dbeaver.ui.editors.sql";
static {
// SQL editor preferences. Do this here because it initializes display
// (that's why we can't run it in prefs initializer classes which run before workbench creation)
{
IPreferenceStore editorStore = EditorsPlugin.getDefault().getPreferenceStore();
IPreferenceStore editorStore = EditorsUI.getPreferenceStore();
editorStore.setDefault(SQLPreferenceConstants.MATCHING_BRACKETS, true);
editorStore.setDefault(SQLPreferenceConstants.MATCHING_BRACKETS_COLOR, "128,128,128");
editorStore.setDefault(SQLPreferenceConstants.MATCHING_BRACKETS_COLOR, "128,128,128"); //$NON-NLS-1$
}
}
......@@ -131,7 +169,14 @@ public abstract class SQLEditorBase extends BaseTextEditor implements IErrorVisu
//setDocumentProvider(new SQLDocumentProvider());
setSourceViewerConfiguration(new SQLEditorSourceViewerConfiguration(this, getPreferenceStore()));
setKeyBindingScopes(new String[]{TEXT_EDITOR_CONTEXT, SQL_EDITOR_CONTEXT}); //$NON-NLS-1$
setKeyBindingScopes(new String[]{TEXT_EDITOR_CONTEXT, SQLEditorContributions.SQL_EDITOR_CONTEXT}); //$NON-NLS-1$
}
@Override
protected void initializeEditor() {
super.initializeEditor();
setEditorContextMenuId(SQLEditorContributions.SQL_EDITOR_CONTEXT_MENU_ID);
setRulerContextMenuId(SQLEditorContributions.SQL_RULER_CONTEXT_MENU_ID);
}
@Nullable
......@@ -304,18 +349,18 @@ public abstract class SQLEditorBase extends BaseTextEditor implements IErrorVisu
}
}
*/
@SuppressWarnings("unchecked")
@Override
public Object getAdapter(Class required)
{
public <T> T getAdapter(Class<T> required) {
if (projectionSupport != null) {
Object adapter = projectionSupport.getAdapter(
getSourceViewer(), required);
if (adapter != null)
return adapter;
return (T) adapter;
}
if (ITemplatesPage.class.equals(required)) {
return getTemplatesPage();
return (T) getTemplatesPage();
}
return super.getAdapter(required);
......
package org.jkiss.dbeaver.ui.editors.sql;
public class SQLEditorContributions {
public static final String SQL_EDITOR_CONTEXT = "org.jkiss.dbeaver.ui.editors.sql"; //$NON-NLS-1$
public static final String SQL_EDITOR_CONTEXT_MENU_ID = "#SQLEditorContext"; //$NON-NLS-1$
public static final String SQL_RULER_CONTEXT_MENU_ID = "#SQLRulerContext"; //$NON-NLS-1$
}
......@@ -19,7 +19,5 @@
Bundle-Vendor = JKISS
Bundle-Name = DBeaver Debug Core
procedureControllers.name = Procedure Controllers
databaseBreakpoint.name=Database Breakpoint
databaseLineBreakpoint.name=Database Line Breakpoint
......@@ -3,5 +3,4 @@ output.. = target/classes/
bin.includes = META-INF/,\
.,\
OSGI-INF/,\
schema/,\
plugin.xml
......@@ -2,8 +2,6 @@
<?eclipse version="3.4"?>
<plugin>
<extension-point id="org.jkiss.dbeaver.debug.core.controllers" name="%procedureControllers.name" schema="schema/procedureControllers.exsd"/>
<extension
id="databaseBreakpointMarker"
name="%databaseBreakpoint.name"
......
<?xml version='1.0' encoding='UTF-8'?>
<!-- Schema file written by PDE -->
<schema targetNamespace="org.jkiss.dbeaver.debug.core" xmlns="http://www.w3.org/2001/XMLSchema">
<annotation>
<appinfo>
<meta.schema plugin="org.jkiss.dbeaver.debug.core" id="procedureControllers" name="Procedure Controllers"/>
</appinfo>
<documentation>
</documentation>
</annotation>
<element name="extension">
<annotation>
<appinfo>
<meta.element />
</appinfo>
</annotation>
<complexType>
<choice>
<sequence minOccurs="1" maxOccurs="unbounded">
<element ref="controller"/>
</sequence>
</choice>
<attribute name="point" type="string" use="required">
<annotation>
<documentation>
</documentation>
</annotation>
</attribute>
<attribute name="id" type="string">
<annotation>
<documentation>
</documentation>
</annotation>
</attribute>
<attribute name="name" type="string">
<annotation>
<documentation>
</documentation>
<appinfo>
<meta.attribute translatable="true"/>
</appinfo>
</annotation>
</attribute>
</complexType>
</element>
<element name="controller">
<complexType>
<attribute name="providerId" type="string" use="required">
<annotation>
<documentation>
</documentation>
</annotation>
</attribute>
<attribute name="class" type="string" use="required">
<annotation>
<documentation>
</documentation>
<appinfo>
<meta.attribute kind="java" basedOn="org.jkiss.dbeaver.debug.DBGProcedureController:"/>
</appinfo>
</annotation>
</attribute>
</complexType>
</element>
</schema>
......@@ -20,7 +20,7 @@ package org.jkiss.dbeaver.debug;
public interface DBGBreakpoint {
DBGObject<?> getDebugObject();
DBGObject getDebugObject();
DBGBreakpointProperties getProperties();
......
......@@ -17,6 +17,10 @@
package org.jkiss.dbeaver.debug;
import java.util.Map;
public interface DBGBreakpointProperties {
Map<String, Object> toMap();
}
......@@ -17,10 +17,7 @@
*/
package org.jkiss.dbeaver.debug;
import java.util.Map;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.registry.DataSourceDescriptor;
/**
* This interface is expected to be used in synch manner
......
......@@ -18,10 +18,13 @@
package org.jkiss.dbeaver.debug;
public interface DBGObject<OBJECT_ID_TYPE> {
import java.util.Map;
OBJECT_ID_TYPE getID();
public interface DBGObject {
Object getID();
String getName();
Map<String, Object> toMap();
}
......@@ -20,14 +20,15 @@ package org.jkiss.dbeaver.debug;
import java.util.List;
public interface DBGSession<SESSION_INFO extends DBGSessionInfo<SESSION_ID_TYPE>, DEBUG_OBJECT extends DBGObject<OBJECT_ID_TYPE>, SESSION_ID_TYPE, OBJECT_ID_TYPE> {
SESSION_INFO getSessionInfo();
public interface DBGSession {
DBGSessionInfo getSessionInfo();
String getTitle();
List<? extends DBGBreakpoint> getBreakpoints();
DBGBreakpoint setBreakpoint(DEBUG_OBJECT obj, DBGBreakpointProperties properties) throws DBGException;
DBGBreakpoint setBreakpoint(DBGObject obj, DBGBreakpointProperties properties) throws DBGException;
void removeBreakpoint(DBGBreakpoint bp) throws DBGException;
......@@ -47,7 +48,7 @@ public interface DBGSession<SESSION_INFO extends DBGSessionInfo<SESSION_ID_TYPE>
List<? extends DBGStackFrame> getStack() throws DBGException;
SESSION_ID_TYPE getSessionId();
Object getSessionId();
// move Stack
}
......@@ -18,8 +18,12 @@
package org.jkiss.dbeaver.debug;
public interface DBGSessionInfo<SESSION_ID_TYPE> {
import java.util.Map;
SESSION_ID_TYPE getID();
public interface DBGSessionInfo {
Object getID();
Map<String, Object> toMap();
}
......@@ -18,27 +18,26 @@
package org.jkiss.dbeaver.debug;
import org.jkiss.dbeaver.model.exec.DBCExecutionContext;
import java.sql.Connection;
import java.util.List;
public interface DBGSessionManager<SESSION_ID_TYPE, OBJECT_ID_TYPE> {
DBGSessionInfo<SESSION_ID_TYPE> getSessionInfo(DBCExecutionContext connection) throws DBGException;
import org.jkiss.dbeaver.model.exec.DBCExecutionContext;
public interface DBGSessionManager {
DBGSessionInfo getSessionInfo(DBCExecutionContext connection) throws DBGException;
List<? extends DBGSessionInfo<SESSION_ID_TYPE>> getSessions() throws DBGException;
List<? extends DBGSessionInfo> getSessions() throws DBGException;
DBGSession<? extends DBGSessionInfo<SESSION_ID_TYPE>, ? extends DBGObject<OBJECT_ID_TYPE>, SESSION_ID_TYPE, OBJECT_ID_TYPE> getDebugSession(SESSION_ID_TYPE id) throws DBGException;
DBGSession getDebugSession(Object id) throws DBGException;
List<DBGSession<?, ?, SESSION_ID_TYPE, OBJECT_ID_TYPE>> getDebugSessions() throws DBGException;
List<DBGSession> getDebugSessions() throws DBGException;
void terminateSession(SESSION_ID_TYPE id);
void terminateSession(Object id);
DBGSession<? extends DBGSessionInfo<SESSION_ID_TYPE>, ? extends DBGObject<OBJECT_ID_TYPE>, SESSION_ID_TYPE, OBJECT_ID_TYPE> createDebugSession(DBCExecutionContext connection) throws DBGException;
DBGSession createDebugSession(DBCExecutionContext connection) throws DBGException;
boolean isSessionExists(SESSION_ID_TYPE id);
boolean isSessionExists(Object id);
List<? extends DBGObject<OBJECT_ID_TYPE>> getObjects(String ownerCtx, String nameCtx) throws DBGException;
List<? extends DBGObject> getObjects(String ownerCtx, String nameCtx) throws DBGException;
void dispose();
}
/*
* 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.debug.core;
import org.eclipse.core.runtime.IConfigurationElement;
import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.debug.DBGControllerRegistry;
import org.jkiss.dbeaver.model.DBPDataKind;
import org.jkiss.dbeaver.model.DBPDataSource;
import org.jkiss.dbeaver.model.impl.AbstractDescriptor;
import org.jkiss.dbeaver.model.struct.DBSDataType;
import org.jkiss.dbeaver.model.struct.DBSTypedObject;
import org.jkiss.dbeaver.model.struct.DBSTypedObjectEx;
import org.jkiss.dbeaver.registry.RegistryConstants;
import org.jkiss.dbeaver.registry.driver.DriverDescriptor;
import org.jkiss.dbeaver.ui.data.IValueManager;
import org.jkiss.utils.CommonUtils;
/**
* ValueManagerDescriptor
*/
public class DebugControllerDescriptor extends AbstractDescriptor
{
private static final Log log = Log.getLog(DebugControllerDescriptor.class);
public static final String EXTENSION_ID = "org.jkiss.dbeaver.debug.core.controllers"; //$NON-NLS-1$
public static final String TAG_CONTROLLER = "controller"; //$NON-NLS-1$
public static final String ATTR_DATASOURCE = "datasource"; //$NON-NLS-1$
private String dataSourceID;
private ObjectType implType;
private DBGControllerRegistry isntance;
public DebugControllerDescriptor(IConfigurationElement config)
{
super(config);
this.dataSourceID = config.getAttribute(ATTR_DATASOURCE);
this.implType = new ObjectType(config.getAttribute(RegistryConstants.ATTR_CLASS));
}
public String getDataSourceID()
{
return dataSourceID;
}
@NotNull
public DBGControllerRegistry getInstance()
{
if (isntance == null ) {
try {
isntance = implType.createInstance(DBGControllerRegistry.class);
} catch (Exception e) {
throw new IllegalStateException("Can't instantiate debug controller '" + this.dataSourceID + "'", e); //$NON-NLS-1$
}
}
return isntance;
}
@Override
public String toString() {
return dataSourceID;
}
}
\ No newline at end of file
/*
* 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.debug.core;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;
import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.debug.DBGControllerRegistry;
import org.jkiss.dbeaver.model.DBPDataSource;
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
import org.jkiss.dbeaver.model.data.DBDContent;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.struct.DBSTypedObject;
import org.jkiss.dbeaver.ui.data.IStreamValueManager;
import org.jkiss.dbeaver.ui.data.IValueManager;
import org.jkiss.dbeaver.ui.data.managers.DefaultValueManager;
import org.jkiss.dbeaver.ui.data.registry.StreamValueManagerDescriptor;
import org.jkiss.dbeaver.ui.data.registry.ValueManagerDescriptor;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* EntityEditorsRegistry
*/
public class DebugControllersRegistry {
private static DebugControllersRegistry instance = null;
public synchronized static DebugControllersRegistry getInstance() {
if (instance == null) {
instance = new DebugControllersRegistry(Platform.getExtensionRegistry());
}
return instance;
}
private List<DebugControllerDescriptor> controllers = new ArrayList<>();
private DebugControllersRegistry(IExtensionRegistry registry) {
// Load datasource providers from external plugins
IConfigurationElement[] extElements = registry.getConfigurationElementsFor(DebugControllerDescriptor.EXTENSION_ID);
for (IConfigurationElement ext : extElements) {
if (DebugControllerDescriptor.TAG_CONTROLLER.equals(ext.getName())) {
controllers.add(new DebugControllerDescriptor(ext));
}
}
}
@NotNull
public DBGControllerRegistry createControllerRegistry(@NotNull DBPDataSourceContainer dataSource) {
for (DebugControllerDescriptor controllerDescriptor : controllers) {
if (controllerDescriptor.getDataSourceID().equals(dataSource.getDriver().getProviderId())) {
return controllerDescriptor.getInstance();
}
}
return null;
}
}
......@@ -17,6 +17,9 @@
*/
package org.jkiss.dbeaver.debug.core;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.Adapters;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
......@@ -25,16 +28,11 @@ import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.osgi.util.NLS;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.debug.DBGController;
import org.jkiss.dbeaver.debug.DBGControllerRegistry;
import org.jkiss.dbeaver.debug.DBGException;
import org.jkiss.dbeaver.debug.internal.core.DebugCoreActivator;
import org.jkiss.dbeaver.debug.internal.core.DebugCoreMessages;
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
import org.jkiss.dbeaver.model.struct.DBSObject;
import java.util.ArrayList;
import java.util.List;
public class DebugCore {
public static final String BUNDLE_SYMBOLIC_NAME = "org.jkiss.dbeaver.debug.core"; //$NON-NLS-1$
......@@ -46,6 +44,9 @@ public class DebugCore {
public static final String BREAKPOINT_DATABASE = BUNDLE_SYMBOLIC_NAME + '.' + "databaseBreakpointMarker"; //$NON-NLS-1$
public static final String BREAKPOINT_DATABASE_LINE = BUNDLE_SYMBOLIC_NAME + '.' + "databaseLineBreakpointMarker"; //$NON-NLS-1$
public static final String ATTR_DRIVER = BUNDLE_SYMBOLIC_NAME + '.' + "ATTR_DRIVER"; //$NON-NLS-1$
public static final String ATTR_DRIVER_DEFAULT = ""; //$NON-NLS-1$
public static final String ATTR_DATASOURCE = BUNDLE_SYMBOLIC_NAME + '.' + "ATTR_DATASOURCE"; //$NON-NLS-1$
public static final String ATTR_DATASOURCE_DEFAULT = ""; //$NON-NLS-1$
......@@ -97,6 +98,10 @@ public class DebugCore {
return extracted;
}
public static String extractDriverId(ILaunchConfiguration configuration) {
return extractStringAttribute(configuration, ATTR_DRIVER, ATTR_DRIVER_DEFAULT);
}
public static String extractDatasourceId(ILaunchConfiguration configuration) {
return extractStringAttribute(configuration, ATTR_DATASOURCE, ATTR_DATASOURCE_DEFAULT);
}
......@@ -130,16 +135,14 @@ public class DebugCore {
return newErrorStatus(message, null);
}
public static DBGControllerRegistry getProcedureControllerRegistry(DBPDataSourceContainer dataSourceContainer) {
return DebugControllersRegistry.getInstance().createControllerRegistry(dataSourceContainer);
}
public static DBGController findProcedureController(DBPDataSourceContainer dataSourceContainer) throws DBGException {
DBGControllerRegistry registry = getProcedureControllerRegistry(dataSourceContainer);
if (registry == null) {
throw new DBGException("Can't find registry for datasource '" + dataSourceContainer.getDriver().getProviderId() + "'");
DBGController controller = Adapters.adapt(dataSourceContainer, DBGController.class);
if (controller != null) {
return controller;
}
return registry.createController(dataSourceContainer);
String providerId = dataSourceContainer.getDriver().getProviderId();
String message = NLS.bind("Unable to find controller for datasource \"{0}\"", providerId);
throw new DBGException(message);
}
}
......@@ -9,6 +9,7 @@ Require-Bundle: org.eclipse.core.runtime,
org.eclipse.core.expressions,
org.eclipse.jface.text,
org.eclipse.ui;visibility:=reexport,
org.eclipse.ui.workbench.texteditor,
org.eclipse.debug.ui;visibility:=reexport,
org.jkiss.dbeaver.core,
org.jkiss.dbeaver.ui,
......
......@@ -17,4 +17,6 @@
# limitations under the License.
Bundle-Vendor = JKISS
Bundle-Name = DBeaver Debug UI
\ No newline at end of file
Bundle-Name = DBeaver Debug UI
command.ToggleBreakpoint.label = Toggle Breakpoint
\ No newline at end of file
......@@ -60,4 +60,25 @@
</detailFactories>
</extension>
<extension
point="org.eclipse.ui.handlers">
<handler
class="org.jkiss.dbeaver.debug.ui.actions.ToggleBreakpointHandler"
commandId="org.eclipse.debug.ui.commands.ToggleBreakpoint">
</handler>
</extension>
<extension
point="org.eclipse.ui.menus">
<menuContribution
allPopups="false"
locationURI="popup:#SQLRulerContext?before=additions">
<command
commandId="org.eclipse.debug.ui.commands.ToggleBreakpoint"
label="%command.ToggleBreakpoint.label"
style="push">
</command>
</menuContribution>
</extension>
</plugin>
......@@ -20,13 +20,21 @@ package org.jkiss.dbeaver.debug.internal.ui;
import org.eclipse.osgi.util.NLS;
public class DebugUIMessages extends NLS {
private static final String BUNDLE_NAME = "org.jkiss.dbeaver.debug.internal.ui.DebugUIMessages"; //$NON-NLS-1$
public static String DatabaseStandardBreakpointPane_description;
public static String DatabaseStandardBreakpointPane_name;
public static String DatabaseTab_driver_group_text;
public static String DatabaseTab_driver_label_text;
public static String DatabaseTab_database_group_text;
public static String DatabaseTab_database_label_text;
public static String DatabaseTab_datasource_group_text;
public static String DatabaseTab_datasource_label_text;
public static String DatabaseTab_oid_group_text;
public static String DatabaseTab_oid_label_text;
public static String DatabaseTab_name;
public static String LaunchShortcut_e_launch;
......
......@@ -16,10 +16,16 @@
DatabaseStandardBreakpointPane_name=Breakpoint Settings
DatabaseStandardBreakpointPane_description=Breakpoint settings
DatabaseTab_driver_group_text=Driver
DatabaseTab_driver_label_text=Driver
DatabaseTab_database_group_text=Database
DatabaseTab_database_label_text=Database
DatabaseTab_datasource_group_text=Connection
DatabaseTab_datasource_label_text=Connection
DatabaseTab_oid_group_text=OID
DatabaseTab_oid_label_text=OID
DatabaseTab_name=&Main
LaunchShortcut_e_launch=Launch error
......
......@@ -3,7 +3,7 @@ package org.jkiss.dbeaver.debug.internal.ui.actions;
import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.debug.ui.actions.ILaunchable;
import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget;
import org.jkiss.dbeaver.debug.ui.actions.ToggleSqlBreakpointTarget;
import org.jkiss.dbeaver.debug.ui.actions.ToggleProcedureBreakpointTarget;
public class DebugActionAdapterFactory implements IAdapterFactory {
......@@ -12,7 +12,7 @@ public class DebugActionAdapterFactory implements IAdapterFactory {
private static final ILaunchable LAUNCHABLE = new ILaunchable() {
};
private final IToggleBreakpointsTarget toggleBreakpointTarget = new ToggleSqlBreakpointTarget();
private final IToggleBreakpointsTarget toggleBreakpointTarget = new ToggleProcedureBreakpointTarget();
@Override
@SuppressWarnings("unchecked")
......
......@@ -17,12 +17,14 @@
*/
package org.jkiss.dbeaver.debug.ui;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.ui.AbstractLaunchConfigurationTab;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
......@@ -31,12 +33,19 @@ import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.jkiss.dbeaver.debug.core.DebugCore;
import org.jkiss.dbeaver.debug.internal.ui.DebugUIMessages;
import org.jkiss.dbeaver.model.DBIcon;
import org.jkiss.dbeaver.model.DBPImage;
import org.jkiss.dbeaver.registry.DataSourceProviderRegistry;
import org.jkiss.dbeaver.registry.driver.DriverDescriptor;
import org.jkiss.dbeaver.ui.DBeaverIcons;
import org.jkiss.dbeaver.ui.UIUtils;
public class DatabaseTab extends AbstractLaunchConfigurationTab {
private Text driverText;
private Text datasourceText;
private Text databaseText;
private Text oidText;
/**
* Modify listener that simply updates the owning launch configuration
......@@ -64,8 +73,21 @@ public class DatabaseTab extends AbstractLaunchConfigurationTab {
protected void createComponents(Composite comp)
{
createDriverComponent(comp);
createDatasourceComponent(comp);
createDatabaseComponent(comp);
createOidComponent(comp);
}
protected void createDriverComponent(Composite comp)
{
Group driverGroup = UIUtils.createControlGroup(comp, DebugUIMessages.DatabaseTab_driver_group_text, 2, GridData.FILL_HORIZONTAL,
SWT.DEFAULT);
driverText = UIUtils.createLabelText(driverGroup, DebugUIMessages.DatabaseTab_driver_label_text, DebugCore.ATTR_DRIVER_DEFAULT);
driverText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
driverText.addModifyListener(modifyListener);
driverText.setEditable(false);
}
protected void createDatasourceComponent(Composite comp)
......@@ -88,18 +110,37 @@ public class DatabaseTab extends AbstractLaunchConfigurationTab {
databaseText.addModifyListener(modifyListener);
}
protected void createOidComponent(Composite comp)
{
Group datasourceGroup = UIUtils.createControlGroup(comp, DebugUIMessages.DatabaseTab_oid_group_text, 2, GridData.FILL_HORIZONTAL, SWT.DEFAULT);
oidText = UIUtils.createLabelText(datasourceGroup, DebugUIMessages.DatabaseTab_oid_label_text, DebugCore.ATTR_OID_DEFAULT);
oidText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
oidText.addModifyListener(modifyListener);
}
@Override
public void setDefaults(ILaunchConfigurationWorkingCopy configuration)
{
configuration.setAttribute(DebugCore.ATTR_DRIVER, DebugCore.ATTR_DRIVER);
configuration.setAttribute(DebugCore.ATTR_DATASOURCE, DebugCore.ATTR_DATASOURCE_DEFAULT);
configuration.setAttribute(DebugCore.ATTR_DATABASE, DebugCore.ATTR_DATABASE_DEFAULT);
configuration.setAttribute(DebugCore.ATTR_OID, DebugCore.ATTR_OID_DEFAULT);
}
@Override
public void initializeFrom(ILaunchConfiguration configuration)
{
initializeDriver(configuration);
initializeDatasource(configuration);
initializeDatabase(configuration);
initializeOid(configuration);
}
protected void initializeDriver(ILaunchConfiguration configuration)
{
String extracted = DebugCore.extractDriverId(configuration);
driverText.setText(extracted);
}
protected void initializeDatasource(ILaunchConfiguration configuration)
......@@ -113,12 +154,48 @@ public class DatabaseTab extends AbstractLaunchConfigurationTab {
String extracted = DebugCore.extractDatabaseName(configuration);
databaseText.setText(extracted);
}
protected void initializeOid(ILaunchConfiguration configuration)
{
String oid = null;
try {
oid = configuration.getAttribute(DebugCore.ATTR_OID, (String)null);
} catch (CoreException e) {
}
if (oid == null) {
oid = DebugCore.ATTR_OID_DEFAULT;
}
oidText.setText(oid);
}
@Override
public Image getImage() {
DBPImage image = extractDriverImage();
if (image == null) {
image = DBIcon.TREE_DATABASE;
}
return DBeaverIcons.getImage(image );
}
protected DBPImage extractDriverImage() {
if (driverText == null || driverText.isDisposed()) {
return null;
}
String driverName = driverText.getText();
DriverDescriptor driver = DataSourceProviderRegistry.getInstance().findDriver(driverName);
if (driver == null) {
return null;
}
return driver.getIcon();
}
@Override
public void performApply(ILaunchConfigurationWorkingCopy configuration)
{
configuration.setAttribute(DebugCore.ATTR_DRIVER, driverText.getText());
configuration.setAttribute(DebugCore.ATTR_DATASOURCE, datasourceText.getText());
configuration.setAttribute(DebugCore.ATTR_DATABASE, databaseText.getText());
configuration.setAttribute(DebugCore.ATTR_OID, oidText.getText());
}
@Override
......
package org.jkiss.dbeaver.debug.ui.actions;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler;
import org.eclipse.debug.ui.actions.RulerToggleBreakpointActionDelegate;
import org.eclipse.swt.widgets.Event;
public class ToggleBreakpointHandler extends AbstractHandler implements IHandler {
@Override
public Object execute(ExecutionEvent event) throws ExecutionException {
//FIXME:AF: this is a dirty hack to enable ancient 3.x- actions with handlers, needs rework
RulerToggleBreakpointActionDelegate delegate = new RulerToggleBreakpointActionDelegate();
delegate.runWithEvent(null, (Event) event.getTrigger());
return null;
}
}
......@@ -18,7 +18,7 @@ import org.jkiss.dbeaver.debug.core.DebugCore;
import org.jkiss.dbeaver.debug.core.breakpoints.DatabaseLineBreakpoint;
import org.jkiss.dbeaver.model.app.DBPProjectManager;
public class ToggleSqlBreakpointTarget implements IToggleBreakpointsTargetExtension2 {
public class ToggleProcedureBreakpointTarget implements IToggleBreakpointsTargetExtension2 {
@Override
public void toggleBreakpoints(IWorkbenchPart part, ISelection selection) throws CoreException
......
......@@ -31,8 +31,15 @@
</launchConfigurationType>
</extension>
<extension point="org.jkiss.dbeaver.debug.core.controllers">
<controller datasource="postgresql" class="org.jkiss.dbeaver.ext.postgresql.debug.internal.PostgreDebugControllerRegistry"/>
<extension
point="org.eclipse.core.runtime.adapters">
<factory
adaptableType="org.jkiss.dbeaver.model.DBPDataSourceContainer"
class="org.jkiss.dbeaver.ext.postgresql.debug.internal.PostgreDebugAdapterFactory">
<adapter
type="org.jkiss.dbeaver.debug.DBGController">
</adapter>
</factory>
</extension>
</plugin>
......@@ -58,6 +58,7 @@ public class PostgreSqlDebugCore {
//Let's use metadata area for storage
IContainer container = null;
ILaunchConfigurationWorkingCopy workingCopy = createConfiguration(container, name);
workingCopy.setAttribute(DebugCore.ATTR_DRIVER, dataSourceContainer.getDriver().getId());
workingCopy.setAttribute(DebugCore.ATTR_DATASOURCE, dataSourceContainer.getId());
workingCopy.setAttribute(DebugCore.ATTR_DATABASE, databaseName);
workingCopy.setAttribute(DebugCore.ATTR_OID, String.valueOf(procedure.getObjectId()));
......
package org.jkiss.dbeaver.ext.postgresql.debug.internal;
import org.eclipse.core.runtime.IAdapterFactory;
import org.jkiss.dbeaver.debug.DBGController;
import org.jkiss.dbeaver.ext.postgresql.PostgreDataSourceProvider;
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
import org.jkiss.dbeaver.model.DBPDataSourceProvider;
import org.jkiss.dbeaver.model.connection.DBPDriver;
public class PostgreDebugAdapterFactory implements IAdapterFactory {
private static final Class<?>[] CLASSES = new Class[] { DBGController.class };
@SuppressWarnings("unchecked")
@Override
public <T> T getAdapter(Object adaptableObject, Class<T> adapterType) {
if (adapterType == DBGController.class) {
if (adaptableObject instanceof DBPDataSourceContainer) {
DBPDataSourceContainer sourceContainer = (DBPDataSourceContainer) adaptableObject;
DBPDriver driver = sourceContainer.getDriver();
if (driver == null) {
return null;
}
DBPDataSourceProvider dataSourceProvider = driver.getDataSourceProvider();
if (dataSourceProvider instanceof PostgreDataSourceProvider) {
PostgreDebugController postgreDebugController = new PostgreDebugController(sourceContainer);
return (T) postgreDebugController;
}
}
}
return null;
}
@Override
public Class<?>[] getAdapterList() {
return CLASSES;
}
}
......@@ -52,7 +52,7 @@ public class PostgreDebugController extends DBGBaseController {
PostgreDebugSessionManager sessionManager = getSessionManager(monitor);
try {
JDBCExecutionContext sessionContext = (JDBCExecutionContext) getDataSourceContainer().getDataSource().openIsolatedContext(monitor, "Debug session");
return this.sessionManager.createDebugSession(sessionContext);
return sessionManager.createDebugSession(sessionContext);
} catch (DBException e) {
throw new DBGException("Can't initiate debug session", e);
}
......
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 Serge Rider (serge@jkiss.org)
* Copyright (C) 2017 Alexander Fedorov (alexander.fedorov@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.postgresql.debug.internal;
import org.jkiss.dbeaver.debug.DBGController;
import org.jkiss.dbeaver.debug.DBGControllerRegistry;
import org.jkiss.dbeaver.debug.DBGException;
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
public class PostgreDebugControllerRegistry implements DBGControllerRegistry {
@Override
public DBGController createController(DBPDataSourceContainer dataSource) throws DBGException {
return new PostgreDebugController(dataSource);
}
}
......@@ -27,8 +27,13 @@ import org.jkiss.dbeaver.debug.DBGException;
import org.jkiss.dbeaver.debug.DBGSession;
import org.jkiss.dbeaver.debug.DBGStackFrame;
import org.jkiss.dbeaver.debug.DBGVariable;
import org.jkiss.dbeaver.ext.postgresql.debug.internal.impl.*;
import org.jkiss.dbeaver.model.impl.jdbc.JDBCExecutionContext;
import org.jkiss.dbeaver.ext.postgresql.debug.internal.impl.PostgreDebugBreakpoint;
import org.jkiss.dbeaver.ext.postgresql.debug.internal.impl.PostgreDebugBreakpointProperties;
import org.jkiss.dbeaver.ext.postgresql.debug.internal.impl.PostgreDebugObject;
import org.jkiss.dbeaver.ext.postgresql.debug.internal.impl.PostgreDebugSession;
import org.jkiss.dbeaver.ext.postgresql.debug.internal.impl.PostgreDebugSessionInfo;
import org.jkiss.dbeaver.ext.postgresql.debug.internal.impl.PostgreDebugSessionManager;
import org.jkiss.dbeaver.ext.postgresql.debug.internal.impl.PostgreDebugVariable;
@SuppressWarnings("nls")
public class Debugger {
......@@ -206,7 +211,7 @@ public class Debugger {
PostgreDebugSession debugSession = null;
List<DBGSession<?, ?, Integer, Integer>> sessions = pgDbgManager.getDebugSessions();
List<DBGSession> sessions = pgDbgManager.getDebugSessions();
Scanner scArg;
......@@ -220,7 +225,7 @@ public class Debugger {
int sessNo = 1;
for (DBGSession<?, ?, Integer, Integer> s : sessions) {
for (DBGSession s : sessions) {
System.out.println(String.format(" (%d) %s", sessNo++, s.toString()));
}
......@@ -333,7 +338,7 @@ public class Debugger {
break;
}
pgDbgManager.terminateSession(debugSessionC.getSessionInfo().getPid());
pgDbgManager.terminateSession(debugSessionC.getSessionId());
System.out.println("Session closed");
......@@ -657,7 +662,7 @@ public class Debugger {
System.out.println("no debug sessions");
break;
}
for (DBGSession<?, ?, Integer, Integer> s : pgDbgManager.getDebugSessions()) {
for (DBGSession s : pgDbgManager.getDebugSessions()) {
System.out.println(s);
}
......
......@@ -18,6 +18,9 @@
package org.jkiss.dbeaver.ext.postgresql.debug.internal.impl;
import java.util.HashMap;
import java.util.Map;
import org.jkiss.dbeaver.debug.DBGBreakpointProperties;
public class PostgreDebugBreakpointProperties implements DBGBreakpointProperties {
......@@ -72,6 +75,17 @@ public class PostgreDebugBreakpointProperties implements DBGBreakpointProperties
this.global = global;
}
@Override
public Map<String, Object> toMap() {
Map<String, Object> map = new HashMap<String, Object>();
map.put("lineNo", lineNo);
map.put("onStart", onStart);
map.put("targetId", targetId);
map.put("all", all);
map.put("global", global);
return map;
}
@Override
public String toString() {
return "PostgreDebugBreakpointProperties [lineNo=" + lineNo + ", onStart=" + onStart + ", targetId=" + targetId
......
......@@ -18,10 +18,13 @@
package org.jkiss.dbeaver.ext.postgresql.debug.internal.impl;
import java.util.HashMap;
import java.util.Map;
import org.jkiss.dbeaver.debug.DBGObject;
@SuppressWarnings("nls")
public class PostgreDebugObject implements DBGObject<Integer> {
public class PostgreDebugObject implements DBGObject {
private final Integer oid;
......@@ -63,6 +66,17 @@ public class PostgreDebugObject implements DBGObject<Integer> {
public String getName() {
return proname;
}
@Override
public Map<String, Object> toMap() {
Map<String, Object> map = new HashMap<String, Object>();
map.put("oid", oid);
map.put("proname", proname);
map.put("owner", owner);
map.put("schema", schema);
map.put("lang", lang);
return map;
}
@Override
public String toString() {
......
......@@ -18,21 +18,47 @@
package org.jkiss.dbeaver.ext.postgresql.debug.internal.impl;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.debug.*;
import org.jkiss.dbeaver.model.exec.DBCExecutionContext;
import org.jkiss.dbeaver.model.impl.jdbc.JDBCExecutionContext;
import org.jkiss.dbeaver.model.runtime.VoidProgressMonitor;
import java.sql.*;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.debug.DBGBreakpoint;
import org.jkiss.dbeaver.debug.DBGBreakpointProperties;
import org.jkiss.dbeaver.debug.DBGException;
import org.jkiss.dbeaver.debug.DBGObject;
import org.jkiss.dbeaver.debug.DBGSession;
import org.jkiss.dbeaver.debug.DBGSessionInfo;
import org.jkiss.dbeaver.debug.DBGStackFrame;
import org.jkiss.dbeaver.debug.DBGVariable;
import org.jkiss.dbeaver.model.exec.DBCExecutionContext;
import org.jkiss.dbeaver.model.impl.jdbc.JDBCExecutionContext;
import org.jkiss.dbeaver.model.runtime.VoidProgressMonitor;
/**
* Typical scenario for debug session <br/>
* <br/>
* 0. create session (now it can only attached to target Procedure)<br/><br/>
* 1. attach to target this method attaches to a debugging target and listening on the given port -
* waiting for run procedure in other session(s) debugger client should invoke this function after creation
* also created implicit breakpoint for target procedure, after this call debug session in <b>WAITING</b> state -
* isDone returns false and is isWaiting returns true<br/><br/>
* 2. when target procedure will called debug session implicit breakpoint will be reached
* and session goes in state <b>READY</b> (isDone - true, isWaiting - true) in this state possible to call
* getStack, getVariables, setVariables, setBreakpoint or execStepXXX\continue<br/><br/>
* 3. when execStepXXX or continue will called session goes in <b>WAITING</b> state until next breakpoint or end of
* procedure will be reached <br/>
*
*/
@SuppressWarnings("nls")
public class PostgreDebugSession implements DBGSession<PostgreDebugSessionInfo, PostgreDebugObject, Integer, Integer> {
public class PostgreDebugSession implements DBGSession {
private static final Log log = Log.getLog(PostgreDebugSession.class);
......@@ -70,12 +96,21 @@ public class PostgreDebugSession implements DBGSession<PostgreDebugSessionInfo,
private List<PostgreDebugBreakpoint> breakpoints = new ArrayList<PostgreDebugBreakpoint>(1);
private PostgreDebugBreakpoint entry;
private PostgreDebugBreakpoint entry = null;
private FutureTask<Void> task;
private Thread workerThread = null;
/**
* This method attach debug session to debug object (procedure)
* and wait forever while target or any (depend on targetPID) session will run target procedure
*
* @param connection - connection for debug session after attach this connection will forever belong to debug
* @param OID - OID for target procedure
* @param targetPID - target session PID (-1 for any target)
* @throws DBGException
*/
public void attach(JDBCExecutionContext connection,int OID,int targetPID) throws DBGException {
lock.writeLock().lock();
......@@ -84,20 +119,14 @@ public class PostgreDebugSession implements DBGSession<PostgreDebugSessionInfo,
this.connection = connection;
try (Statement stmt = getConnection(connection).createStatement()) {
ResultSet rs = stmt.executeQuery(SQL_LISTEN);
try (Statement stmt = getConnection(connection).createStatement();
ResultSet rs = stmt.executeQuery(SQL_LISTEN)) {
if (rs.next()) {
getConnection(connection).setClientInfo("ApplicationName", "Debug Mode : " + String.valueOf(sessionId));
sessionId = rs.getInt("sessionid");
} else {
throw new DBGException("Unable to create debug instance");
}
} catch (SQLException e) {
......@@ -107,7 +136,7 @@ public class PostgreDebugSession implements DBGSession<PostgreDebugSessionInfo,
PostgreDebugBreakpointProperties properties = new PostgreDebugBreakpointProperties(true);
PostgreDebugObject obj = new PostgreDebugObject(OID,"ENTRY","SESSION","THIS","PG");
entry = new PostgreDebugBreakpoint(this,obj,properties);
this.entry = new PostgreDebugBreakpoint(this,obj,properties);
runAsync(SQL_ATTACH.replaceAll("\\?sessionid", String.valueOf(sessionId)),
String.valueOf(sessionId) + " global attached to " + String.valueOf(sessionManagerInfo.pid));
......@@ -128,6 +157,14 @@ public class PostgreDebugSession implements DBGSession<PostgreDebugSessionInfo,
}
/**
* Create session with two description
* after creation session need to be attached to postgres procedure by attach method
*
* @param sessionManagerInfo - manager (caller connection) description
* @param sessionDebugInfo - session (debugger client connection) description
* @throws DBGException
*/
public PostgreDebugSession(PostgreDebugSessionInfo sessionManagerInfo, PostgreDebugSessionInfo sessionDebugInfo) throws DBGException {
this.sessionManagerInfo = sessionManagerInfo;
this.sessionDebugInfo = sessionDebugInfo;
......@@ -135,13 +172,18 @@ public class PostgreDebugSession implements DBGSession<PostgreDebugSessionInfo,
}
/**
* @param connectionTarget - DBCExecutionContext of debug client (will be used in debug process)
* @return Connection - java.sql.Connection
* @throws SQLException
*/
private static Connection getConnection(DBCExecutionContext connectionTarget) throws SQLException {
return ((JDBCExecutionContext) connectionTarget).getConnection(new VoidProgressMonitor());
}
@Override
public PostgreDebugSessionInfo getSessionInfo() {
@Override
public DBGSessionInfo getSessionInfo() {
return sessionDebugInfo;
}
......@@ -152,19 +194,18 @@ public class PostgreDebugSession implements DBGSession<PostgreDebugSessionInfo,
@Override
public List<PostgreDebugBreakpoint> getBreakpoints() {
return breakpoints;
}
@Override
public DBGBreakpoint setBreakpoint(PostgreDebugObject obj, DBGBreakpointProperties properties) throws DBGException {
public DBGBreakpoint setBreakpoint(DBGObject obj, DBGBreakpointProperties properties) throws DBGException {
acquireReadLock();
PostgreDebugBreakpoint bp = null;
try {
bp = new PostgreDebugBreakpoint(this, obj, (PostgreDebugBreakpointProperties) properties);
bp = new PostgreDebugBreakpoint(this, (PostgreDebugObject)obj, (PostgreDebugBreakpointProperties) properties);
breakpoints.add(bp);
} finally {
......@@ -209,6 +250,14 @@ public class PostgreDebugSession implements DBGSession<PostgreDebugSessionInfo,
}
/**
* Execute step SQL command asynchronously, set debug session name to
* [sessionID] name [managerPID]
*
* @param commandSQL - SQL command for execute step
* @param name - session 'name' part
* @throws DBGException
*/
public void execStep(String commandSQL, String name) throws DBGException {
acquireWriteLock();
......@@ -268,16 +317,20 @@ public class PostgreDebugSession implements DBGSession<PostgreDebugSessionInfo,
List<DBGVariable<?>> vars = new ArrayList<>();
try (Statement stmt = getConnection(connection).createStatement()) {
ResultSet rs = stmt.executeQuery(SQL_GET_VARS.replaceAll("\\?sessionid", String.valueOf(sessionId)));
String sql = SQL_GET_VARS.replaceAll("\\?sessionid", String.valueOf(sessionId));
try (Statement stmt = getConnection(connection).createStatement(); ResultSet rs = stmt.executeQuery(sql)) {
while (rs.next()) {
PostgreDebugVariable var = new PostgreDebugVariable(rs.getString("name"), rs.getString("varclass"),
rs.getInt("linenumber"), rs.getBoolean("isunique"), rs.getBoolean("isconst"),
rs.getBoolean("isnotnull"), rs.getInt("dtype"), rs.getString("value"));
String name = rs.getString("name");
String varclass = rs.getString("varclass");
int linenumber = rs.getInt("linenumber");
boolean isunique = rs.getBoolean("isunique");
boolean isconst = rs.getBoolean("isconst");
boolean isnotnull = rs.getBoolean("isnotnull");
int dtype = rs.getInt("dtype");
String value = rs.getString("value");
PostgreDebugVariable var = new PostgreDebugVariable(name, varclass, linenumber, isunique, isconst,
isnotnull, dtype, value);
vars.add(var);
}
......@@ -336,13 +389,15 @@ public class PostgreDebugSession implements DBGSession<PostgreDebugSessionInfo,
List<DBGStackFrame> stack = new ArrayList<DBGStackFrame>(1);
try (Statement stmt = getConnection(connection).createStatement()) {
ResultSet rs = stmt.executeQuery(SQL_GET_STACK.replaceAll("\\?sessionid", String.valueOf(sessionId)));
String sql = SQL_GET_STACK.replaceAll("\\?sessionid", String.valueOf(sessionId));
try (Statement stmt = getConnection(connection).createStatement(); ResultSet rs = stmt.executeQuery(sql)) {
while (rs.next()) {
PostgreDebugStackFrame frame = new PostgreDebugStackFrame(rs.getInt("level"), rs.getString("targetname"),
rs.getInt("func"), rs.getInt("linenumber"), rs.getString("args"));
int level = rs.getInt("level");
String targetname = rs.getString("targetname");
int func = rs.getInt("func");
int linenumber = rs.getInt("linenumber");
String args = rs.getString("args");
PostgreDebugStackFrame frame = new PostgreDebugStackFrame(level, targetname, func, linenumber, args);
stack.add(frame);
}
......@@ -354,6 +409,12 @@ public class PostgreDebugSession implements DBGSession<PostgreDebugSessionInfo,
return stack;
}
/**
* Return connection used in debug session
*
* @return java.sql.Connection
* @throws DBGException
*/
public Connection getConnection() throws DBGException {
try {
return getConnection(connection);
......@@ -373,11 +434,21 @@ public class PostgreDebugSession implements DBGSession<PostgreDebugSessionInfo,
public Integer getSessionId() {
return sessionId;
}
/**
* Return true if session up and running debug thread
*
* @return boolean
*/
public boolean isWaiting() {
return (task == null ? false : !task.isDone()) && (workerThread == null ? false : workerThread.isAlive());
}
/**
* Return true if session waiting target connection (on breakpoint, after step or continue) in debug thread
*
* @return boolean
*/
public boolean isDone(){
if (task == null)
......@@ -401,10 +472,22 @@ public class PostgreDebugSession implements DBGSession<PostgreDebugSessionInfo,
}
/**
* Return true if debug session up and running on server
*
* @return boolean
*/
public boolean isAttached() {
return (connection != null && sessionId > 0);
}
/**
* Start thread for SQL command
*
* @param commandSQL
* @param name
* @throws DBGException
*/
private void runAsync(String commandSQL, String name) throws DBGException {
Connection connection = getConnection();
......@@ -428,6 +511,11 @@ public class PostgreDebugSession implements DBGSession<PostgreDebugSessionInfo,
}
}
/**
* Try to acquire shared lock
*
* @throws DBGException
*/
private void acquireReadLock() throws DBGException {
try {
......@@ -457,6 +545,11 @@ public class PostgreDebugSession implements DBGSession<PostgreDebugSessionInfo,
}
/**
* Try to acquire exclusive lock
*
* @throws DBGException
*/
private void acquireWriteLock() throws DBGException {
try {
......
......@@ -18,10 +18,23 @@
package org.jkiss.dbeaver.ext.postgresql.debug.internal.impl;
import java.util.HashMap;
import java.util.Map;
import org.jkiss.dbeaver.debug.DBGSessionInfo;
@SuppressWarnings("nls")
public class PostgreDebugSessionInfo implements DBGSessionInfo<Integer> {
public class PostgreDebugSessionInfo implements DBGSessionInfo {
public static final String QUERY_PROP = "query";
public static final String STATE_PROP = "state";
public static final String APP_PROP = "application";
public static final String USER_PROP = "user";
public static final String PID = "pid";
public static final String CREATE_LISTEN = "CREATE LISTEN";
......@@ -65,6 +78,16 @@ public class PostgreDebugSessionInfo implements DBGSessionInfo<Integer> {
return query;
}
public Map<String, Object> toMap() {
Map<String, Object> map = new HashMap<String, Object>();
map.put(PID, pid);
map.put(USER_PROP, user);
map.put(APP_PROP, application);
map.put(STATE_PROP, state);
map.put(QUERY_PROP, query);
return map;
}
@Override
public String toString() {
......
......@@ -35,7 +35,7 @@ import org.jkiss.dbeaver.model.impl.jdbc.JDBCExecutionContext;
import org.jkiss.dbeaver.model.runtime.VoidProgressMonitor;
@SuppressWarnings("nls")
public class PostgreDebugSessionManager implements DBGSessionManager<Integer, Integer> {
public class PostgreDebugSessionManager implements DBGSessionManager {
private final DBCExecutionContext context;
......@@ -53,14 +53,16 @@ public class PostgreDebugSessionManager implements DBGSessionManager<Integer, In
@Override
public PostgreDebugSessionInfo getSessionInfo(DBCExecutionContext connectionTarget) throws DBGException {
try (Statement stmt = getConnection(connectionTarget).createStatement()) {
ResultSet rs = stmt.executeQuery(SQL_CURRENT_SESSION);
try (Statement stmt = getConnection(connectionTarget).createStatement();
ResultSet rs = stmt.executeQuery(SQL_CURRENT_SESSION)) {
if (rs.next()) {
PostgreDebugSessionInfo res = new PostgreDebugSessionInfo(rs.getInt("pid"), rs.getString("usename"),
rs.getString("application_name"), rs.getString("state"), rs.getString("query"));
int pid = rs.getInt("pid");
String usename = rs.getString("usename");
String applicationName = rs.getString("application_name");
String state = rs.getString("state");
String query = rs.getString("query");
PostgreDebugSessionInfo res = new PostgreDebugSessionInfo(pid, usename, applicationName, state, query);
return res;
}
......@@ -79,16 +81,17 @@ public class PostgreDebugSessionManager implements DBGSessionManager<Integer, In
@Override
public List<PostgreDebugSessionInfo> getSessions() throws DBGException {
try (Statement stmt = getConnection(context).createStatement()) {
ResultSet rs = stmt.executeQuery(SQL_SESSION);
try (Statement stmt = getConnection(context).createStatement(); ResultSet rs = stmt.executeQuery(SQL_SESSION)) {
List<PostgreDebugSessionInfo> res = new ArrayList<PostgreDebugSessionInfo>();
while (rs.next()) {
res.add(new PostgreDebugSessionInfo(rs.getInt("pid"), rs.getString("usename"),
rs.getString("application_name"), rs.getString("state"), rs.getString("query")));
int pid = rs.getInt("pid");
String usename = rs.getString("usename");
String state = rs.getString("state");
String applicationName = rs.getString("application_name");
String query = rs.getString("query");
PostgreDebugSessionInfo info = new PostgreDebugSessionInfo(pid, usename, applicationName, state, query);
res.add(info);
}
return res;
......@@ -109,18 +112,19 @@ public class PostgreDebugSessionManager implements DBGSessionManager<Integer, In
@Override
public List<PostgreDebugObject> getObjects(String ownerCtx, String nameCtx) throws DBGException {
try (Statement stmt = getConnection(context).createStatement()) {
ResultSet rs = stmt.executeQuery(
SQL_OBJECT.replaceAll("\\?nameCtx", nameCtx).replaceAll("\\?userCtx", ownerCtx).toLowerCase());
String sql = SQL_OBJECT.replaceAll("\\?nameCtx", nameCtx).replaceAll("\\?userCtx", ownerCtx).toLowerCase();
try (Statement stmt = getConnection(context).createStatement(); ResultSet rs = stmt.executeQuery(sql)) {
List<PostgreDebugObject> res = new ArrayList<PostgreDebugObject>();
while (rs.next()) {
res.add(new PostgreDebugObject(rs.getInt("oid"), rs.getString("proname"), rs.getString("owner"),
rs.getString("nspname"), rs.getString("lang")));
int oid = rs.getInt("oid");
String proname = rs.getString("proname");
String owner = rs.getString("owner");
String nspname = rs.getString("nspname");
String lang = rs.getString("lang");
PostgreDebugObject object = new PostgreDebugObject(oid, proname, owner, nspname, lang);
res.add(object);
}
return res;
......@@ -131,7 +135,7 @@ public class PostgreDebugSessionManager implements DBGSessionManager<Integer, In
}
@Override
public DBGSession<PostgreDebugSessionInfo, PostgreDebugObject, Integer, Integer> getDebugSession(Integer id)
public DBGSession getDebugSession(Object id)
throws DBGException {
return sessions.get(id);
}
......@@ -154,12 +158,12 @@ public class PostgreDebugSessionManager implements DBGSessionManager<Integer, In
}
@Override
public boolean isSessionExists(Integer id) {
public boolean isSessionExists(Object id) {
return sessions.containsKey(id);
}
@Override
public void terminateSession(Integer id) {
public void terminateSession(Object id) {
PostgreDebugSession session = sessions.get(id);
......@@ -174,8 +178,8 @@ public class PostgreDebugSessionManager implements DBGSessionManager<Integer, In
}
@Override
public List<DBGSession<?, ?, Integer, Integer>> getDebugSessions() throws DBGException {
return new ArrayList<DBGSession<?, ?, Integer, Integer>>(sessions.values());
public List<DBGSession> getDebugSessions() throws DBGException {
return new ArrayList<DBGSession>(sessions.values());
}
@Override
......
......@@ -21,6 +21,7 @@ import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup;
import org.eclipse.debug.ui.CommonTab;
import org.eclipse.debug.ui.ILaunchConfigurationDialog;
import org.eclipse.debug.ui.ILaunchConfigurationTab;
import org.jkiss.dbeaver.debug.ui.DatabaseTab;
public class PgSqlLaunchConfigurationTabGroup extends AbstractLaunchConfigurationTabGroup {
......@@ -31,10 +32,10 @@ public class PgSqlLaunchConfigurationTabGroup extends AbstractLaunchConfiguratio
@Override
public void createTabs(ILaunchConfigurationDialog dialog, String mode)
{
PgSqlTab pgSqlTab = new PgSqlTab();
DatabaseTab databaseTab = new DatabaseTab();
CommonTab commonTab = new CommonTab();
ILaunchConfigurationTab[] tabs = new ILaunchConfigurationTab[] {
pgSqlTab,
databaseTab,
commonTab
};
setTabs(tabs);
......
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 Serge Rider (serge@jkiss.org)
* Copyright (C) 2017 Alexander Fedorov (alexander.fedorov@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.postgresql.debug.ui.internal;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Text;
import org.jkiss.dbeaver.debug.core.DebugCore;
import org.jkiss.dbeaver.debug.ui.DatabaseTab;
import org.jkiss.dbeaver.ext.postgresql.PostgreActivator;
import org.jkiss.dbeaver.ui.UIUtils;
public class PgSqlTab extends DatabaseTab {
private final ImageRegistry imageRegistry;
public PgSqlTab()
{
this.imageRegistry = PostgreActivator.getDefault().getImageRegistry();
}
private Text oidText;
@Override
protected void createComponents(Composite comp)
{
super.createComponents(comp);
createOidComponent(comp);
}
@Override
public Image getImage()
{
return imageRegistry.get(PostgreActivator.IMG_PG_SQL);
}
protected void createOidComponent(Composite comp)
{
Group datasourceGroup = UIUtils.createControlGroup(comp, PostgreDebugUIMessages.PgSqlTab_oid_group_text, 2, GridData.FILL_HORIZONTAL, SWT.DEFAULT);
oidText = UIUtils.createLabelText(datasourceGroup, PostgreDebugUIMessages.PgSqlTab_oid_label_text, DebugCore.ATTR_OID_DEFAULT);
oidText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
oidText.addModifyListener(modifyListener);
}
@Override
public void setDefaults(ILaunchConfigurationWorkingCopy configuration)
{
super.setDefaults(configuration);
configuration.setAttribute(DebugCore.ATTR_OID, DebugCore.ATTR_OID_DEFAULT);
}
@Override
public void initializeFrom(ILaunchConfiguration configuration)
{
super.initializeFrom(configuration);
initializeOid(configuration);
}
protected void initializeOid(ILaunchConfiguration configuration)
{
String oid = null;
try {
oid = configuration.getAttribute(DebugCore.ATTR_OID, (String)null);
} catch (CoreException e) {
}
if (oid == null) {
oid = DebugCore.ATTR_OID_DEFAULT;
}
oidText.setText(oid);
}
@Override
public void performApply(ILaunchConfigurationWorkingCopy configuration)
{
super.performApply(configuration);
configuration.setAttribute(DebugCore.ATTR_OID, oidText.getText());
}
}
......@@ -28,10 +28,6 @@ public class PostgreDebugUIMessages extends NLS {
public static String PgSqlLaunchShortcut_select_procedure_message;
public static String PgSqlLaunchShortcut_select_procedure_title;
public static String PgSqlTab_oid_group_text;
public static String PgSqlTab_oid_label_text;
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, PostgreDebugUIMessages.class);
......
......@@ -18,5 +18,3 @@ PgSqlLaunchShortcut_e_editor_empty=Editor does not containt PostgreSQL procedure
PgSqlLaunchShortcut_e_selection_empty=Selection does not containt PostgreSQL procedure
PgSqlLaunchShortcut_select_procedure_message=Select &PostgreSQL Procedure (? = any character, * = any String):
PgSqlLaunchShortcut_select_procedure_title=Select PostgreSQL Procedure
PgSqlTab_oid_group_text=OID
PgSqlTab_oid_label_text=OID
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册