提交 add1f163 编写于 作者: E Evgeny Fradkin

#2374 Execute stored procedure


Former-commit-id: 8701442a
上级 38b0bb6e
......@@ -536,4 +536,7 @@ public class CommonUtils {
return Boolean.TRUE.equals(optionValue);
}
public static String fixedLengthString(String string, int length) {
return String.format("%1$"+length+ "s", string);
}
}
......@@ -118,6 +118,9 @@ command.org.jkiss.dbeaver.core.txn.pending.name=Pending transactions
command.org.jkiss.dbeaver.core.txn.pending.description=List of all pending transactions
command.org.jkiss.dbeaver.core.transaction_mode.name=Transaction mode
command.org.jkiss.dbeaver.core.procedure.execute.name=Execute Stored Procedure
command.org.jkiss.dbeaver.core.procedure.execute.description=Open new SQL console with execute stored procedure query
command.org.jkiss.dbeaver.core.sql.editor.open.name=SQL Editor
command.org.jkiss.dbeaver.core.sql.editor.open.description=Open SQL editor (existing or new)
command.org.jkiss.dbeaver.core.sql.editor.recent.name=Recent SQL Editor
......
......@@ -103,7 +103,7 @@
class="org.jkiss.dbeaver.ui.editors.sql.generator.SQLUtilsPropertyTester"
id="org.jkiss.dbeaver.ui.editors.sql.generator.SQLUtilsPropertyTester"
namespace="org.jkiss.dbeaver.ui.editors.sql.util"
properties="canGenerate,hasTools"
properties="canGenerate,hasTools,isProcedure"
type="org.eclipse.ui.IWorkbenchPart"/>
<propertyTester
class="org.jkiss.dbeaver.ui.controls.resultset.ResultSetPropertyTester"
......@@ -243,6 +243,7 @@
<command id="org.jkiss.dbeaver.core.sql.editor.recent" name="%command.org.jkiss.dbeaver.core.sql.editor.recent.name" description="%command.org.jkiss.dbeaver.core.sql.editor.recent.description" categoryId="org.jkiss.dbeaver.core.database"/>
<command id="org.jkiss.dbeaver.core.sql.editor.create" name="%command.org.jkiss.dbeaver.core.sql.editor.create.name" description="%command.org.jkiss.dbeaver.core.sql.editor.create.description" categoryId="org.jkiss.dbeaver.core.database"/>
<command id="org.jkiss.dbeaver.core.sql.editor.forSelection" name="%command.org.jkiss.dbeaver.core.sql.editor.forSelection.name" description="%command.org.jkiss.dbeaver.core.sql.editor.forSelection.description" categoryId="org.jkiss.dbeaver.core.database"/>
<command id="command.org.jkiss.dbeaver.core.procedure.execute" name="%command.org.jkiss.dbeaver.core.procedure.execute.name" description="%command.org.jkiss.dbeaver.core.procedure.execute.description" categoryId="org.jkiss.dbeaver.core.database"/>
<command id="org.jkiss.dbeaver.core.object.open" name="%command.org.jkiss.dbeaver.core.object.open.name" description="%command.org.jkiss.dbeaver.core.object.open.description" categoryId="org.jkiss.dbeaver.core.database"/>
<command id="org.jkiss.dbeaver.core.object.create" name="%command.org.jkiss.dbeaver.core.object.create.name" description="%command.org.jkiss.dbeaver.core.object.create.description" categoryId="org.jkiss.dbeaver.core.database"/>
<command id="org.jkiss.dbeaver.core.object.delete" name="%command.org.jkiss.dbeaver.core.object.delete.name" description="%command.org.jkiss.dbeaver.core.object.delete.description" categoryId="org.jkiss.dbeaver.core.database"/>
......@@ -1005,6 +1006,12 @@
</with>
</enabledWhen>
</handler>
<handler commandId="command.org.jkiss.dbeaver.core.procedure.execute" class="org.jkiss.dbeaver.ui.editors.sql.handlers.RunProcedureConsoleHandler">
<parameter
name="org.jkiss.dbeaver.core.resource.link.file.contenttype"
value="org.jkiss.dbeaver.sql">
</parameter>
</handler>
<handler commandId="org.jkiss.dbeaver.ui.editors.sql.rename" class="org.jkiss.dbeaver.ui.editors.sql.handlers.RenameHandler">
<enabledWhen>
......@@ -2081,6 +2088,15 @@
<menuContribution allPopups="false" locationURI="popup:org.eclipse.ui.popup.any?after=tools">
<separator name="data" visible="true"/>
<command
commandId="command.org.jkiss.dbeaver.core.procedure.execute"
label="%command.org.jkiss.dbeaver.core.procedure.execute.name">
<visibleWhen>
<with variable="activePart">
<test property="org.jkiss.dbeaver.ui.editors.sql.util.isProcedure"/>
</with>
</visibleWhen>
</command>
<command
commandId="org.jkiss.dbeaver.core.sql.editor.forSelection"
label="%command.org.jkiss.dbeaver.core.sql.editor.forSelection.name">
......
......@@ -48,6 +48,9 @@ import org.jkiss.dbeaver.model.runtime.DBRRunnableWithResult;
import org.jkiss.dbeaver.model.sql.SQLConstants;
import org.jkiss.dbeaver.model.sql.SQLUtils;
import org.jkiss.dbeaver.model.struct.*;
import org.jkiss.dbeaver.model.struct.rdb.DBSProcedure;
import org.jkiss.dbeaver.model.struct.rdb.DBSProcedureParameter;
import org.jkiss.dbeaver.model.struct.rdb.DBSProcedureParameterKind;
import org.jkiss.dbeaver.model.struct.rdb.DBSTable;
import org.jkiss.dbeaver.ui.DBeaverIcons;
import org.jkiss.dbeaver.ui.UIIcon;
......@@ -482,6 +485,24 @@ public class GenerateSQLContributor extends CompoundContributionItem {
}
}
private abstract static class ProcedureAnalysisRunner extends BaseAnalysisRunner<DBSProcedure> {
protected ProcedureAnalysisRunner(List<DBSProcedure> entities)
{
super(entities);
}
protected Collection<? extends DBSEntityAttribute> getAllAttributes(DBRProgressMonitor monitor, DBSProcedure object) throws DBException
{
return Collections.emptyList();
}
protected Collection<? extends DBSEntityAttribute> getKeyAttributes(DBRProgressMonitor monitor, DBSProcedure object) throws DBException
{
return Collections.emptyList();
}
}
private abstract static class ResultSetAnalysisRunner extends BaseAnalysisRunner<ResultSetModel> {
ResultSetAnalysisRunner(DBPDataSource dataSource, ResultSetModel model)
......@@ -795,4 +816,61 @@ public class GenerateSQLContributor extends CompoundContributionItem {
};
}
@NotNull
public static SQLGenerator<DBSProcedure> CALL_GENERATOR(final List<DBSProcedure> entities) {
return new ProcedureAnalysisRunner(entities) {
@Override
protected void generateSQL(DBRProgressMonitor monitor, StringBuilder sql, DBSProcedure proc) throws DBException {
Collection<? extends DBSProcedureParameter> parameters = proc.getParameters(monitor);
List<DBSProcedureParameter> inParameters = new ArrayList<>();
int maxParamLength = 0;
for (DBSProcedureParameter param : parameters) {
if (param.getParameterKind() == DBSProcedureParameterKind.IN) {
inParameters.add(param);
if (param.getName().length() > maxParamLength) {
maxParamLength = param.getName().length();
}
}
}
String dbName = proc.getDataSource().getInfo().getDatabaseProductName();
String schemaName;
switch (dbName) {
case "Microsoft SQL Server":
schemaName = proc.getContainer().getParentObject().getName();
sql.append("USE [" + schemaName + "]\n");
sql.append("GO\n\n");
sql.append("DECLARE @return_value int\n\n");
sql.append("EXEC\t@return_value = [" + proc.getContainer().getName() +"].[" + proc.getName() + "]\n");
for (int i = 0; i < inParameters.size(); i++) {
String name = inParameters.get(i).getName();
sql.append("\t\t" + name + " = ?");
if (i < (inParameters.size() - 1)) {
sql.append(", ");
} else {
sql.append(" ");
}
sql.append(CommonUtils.fixedLengthString("-- put the " + name + " parameter value instead of ?\n", (maxParamLength + 50) - name.length()/2));
}
sql.append("\nSELECT\t'Return Value' = @return_value\n\n");
sql.append("GO\n\n");
return;
default:
schemaName = proc.getParentObject().getName();
sql.append(("Oracle".equalsIgnoreCase(dbName) ? "CALL " + schemaName + "." : "select ") + proc.getName() + "(\n");
for (int i = 0; i < inParameters.size(); i++) {
sql.append("\t\t\t?");
if (i < (inParameters.size() - 1)) {
sql.append(",");
} else {
sql.append(" ");
}
sql.append("\t-- put the " + inParameters.get(i).getName() + " parameter value instead of ?\n");
}
sql.append(");\n\n");
}
}
};
}
}
......@@ -19,7 +19,9 @@ package org.jkiss.dbeaver.ui.editors.sql.generator;
import org.eclipse.core.expressions.PropertyTester;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.IWorkbenchPart;
import org.jkiss.dbeaver.model.impl.struct.AbstractProcedure;
import org.jkiss.dbeaver.model.struct.DBSObject;
import org.jkiss.dbeaver.model.struct.rdb.DBSProcedure;
import org.jkiss.dbeaver.registry.tools.ToolsRegistry;
import org.jkiss.dbeaver.ui.ActionUtils;
import org.jkiss.dbeaver.ui.controls.resultset.IResultSetSelection;
......@@ -34,6 +36,7 @@ public class SQLUtilsPropertyTester extends PropertyTester
public static final String NAMESPACE = "org.jkiss.dbeaver.ui.editors.sql.util";
public static final String PROP_CAN_GENERATE = "canGenerate";
public static final String PROP_HAS_TOOLS = "hasTools";
public static final String PROP_IS_PROCEDURE = "isProcedure";
public SQLUtilsPropertyTester() {
super();
......@@ -60,6 +63,11 @@ public class SQLUtilsPropertyTester extends PropertyTester
DBSObject object = NavigatorUtils.getSelectedObject(structuredSelection);
return object != null && !CommonUtils.isEmpty(ToolsRegistry.getInstance().getTools(structuredSelection));
}
case PROP_IS_PROCEDURE: {
DBSObject object = NavigatorUtils.getSelectedObject(structuredSelection);
return object instanceof DBSProcedure;
// && "Microsoft SQL Server".equals(object.getDataSource().getInfo().getDatabaseProductName());
}
}
return false;
}
......
/*
* 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.ui.editors.sql.handlers;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.handlers.HandlerUtil;
import org.jkiss.dbeaver.core.DBeaverUI;
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
import org.jkiss.dbeaver.model.runtime.AbstractJob;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.runtime.DBRRunnableWithResult;
import org.jkiss.dbeaver.model.struct.DBSEntity;
import org.jkiss.dbeaver.model.struct.DBSObject;
import org.jkiss.dbeaver.model.struct.rdb.DBSProcedure;
import org.jkiss.dbeaver.ui.editors.sql.SQLEditor;
import org.jkiss.dbeaver.ui.editors.sql.generator.GenerateSQLContributor;
import org.jkiss.dbeaver.ui.navigator.NavigatorUtils;
import org.jkiss.dbeaver.utils.RuntimeUtils;
import java.util.ArrayList;
import java.util.List;
public class RunProcedureConsoleHandler extends AbstractHandler {
public RunProcedureConsoleHandler()
{
}
@Override
public Object execute(ExecutionEvent event) throws ExecutionException
{
IWorkbenchWindow workbenchWindow = HandlerUtil.getActiveWorkbenchWindow(event);
DBPDataSourceContainer ds = null;
List<DBSObject> selectedObjects = NavigatorUtils.getSelectedObjects(
HandlerUtil.getCurrentSelection(event));
List<DBSProcedure> entities = new ArrayList<>();
for (DBSObject object : selectedObjects) {
if (object instanceof DBSProcedure) {
entities.add((DBSProcedure) object);
ds = object.getDataSource().getContainer();
}
}
DBRRunnableWithResult<String> generator = GenerateSQLContributor.CALL_GENERATOR(entities);
DBeaverUI.runInUI(workbenchWindow, generator);
String sql = generator.getResult();
SQLEditor editor = OpenHandler.openSQLConsole(workbenchWindow, ds, "Query", sql);
if (editor != null) {
AbstractJob execJob = new AbstractJob("Execute SQL in console") {
@Override
protected IStatus run(DBRProgressMonitor monitor) {
// If we open new connection for each editor it may take some time
// So let's give it a chance and wait for 10 seconds
for (int i = 0; i < 100; i++) {
if (editor.getExecutionContext() != null) {
break;
}
RuntimeUtils.pause(100);
}
return Status.OK_STATUS;
}
};
execJob.addJobChangeListener(new JobChangeAdapter() {
@Override
public void done(IJobChangeEvent event) {
DBeaverUI.syncExec(new Runnable() {
@Override
public void run() {
// editor.processSQL(false, false); TODO
}
});
}
});
execJob.schedule();
}
return null;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册