blob: 0fef9eb78d65c8c0f22614a0e96369a89df04afe [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005 Sybase, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* Contributors:
* Sybase, Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.datatools.sqltools.sqleditor.plan;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Map;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.IJobManager;
import org.eclipse.datatools.sqltools.core.DatabaseIdentifier;
import org.eclipse.datatools.sqltools.core.SQLToolsFacade;
import org.eclipse.datatools.sqltools.core.services.SQLService;
import org.eclipse.datatools.sqltools.editor.ui.core.SQLToolsUIFacade;
import org.eclipse.datatools.sqltools.plan.EPVFacade;
import org.eclipse.datatools.sqltools.plan.IPlanService;
import org.eclipse.datatools.sqltools.plan.PlanRequest;
import org.eclipse.datatools.sqltools.plan.PlanSupportRunnable;
import org.eclipse.datatools.sqltools.sqleditor.internal.PreferenceConstants;
import org.eclipse.datatools.sqltools.sqleditor.internal.SQLEditorPlugin;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialogWithToggle;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.osgi.util.NLS;
/**
* Support explaining a group of SQL statements in SQL Editor.
*
* @author Hui Cao
* @author Dafan Yang
*/
public class GroupPlanSupportRunnable extends PlanSupportRunnable
{
private final class ConfirmRunnable implements Runnable
{
boolean goon = false;
public void run()
{
IPreferenceStore store = SQLEditorPlugin.getDefault().getPreferenceStore();
MessageDialogWithToggle dlg = MessageDialogWithToggle.openYesNoQuestion(SQLEditorPlugin
.getActiveWorkbenchShell(), Messages.getString("GroupPlanSupportRunnable.continue_explain"), //$NON-NLS-1$
Messages.getString("GroupPlanSupportRunnable.error_info"), //$NON-NLS-1$
null/* use default toggle message */, false, store, PreferenceConstants.EXECUTE_SQL_ERROR_MODE);
int result = dlg.getReturnCode();
// If we are not going to prompt anymore propogate the choice.
if (dlg.getToggleState())
{
String preferenceValue;
if (result == IDialogConstants.YES_ID)
{
preferenceValue = PreferenceConstants.PROMPT_MODE_ALWAYS;
}
else
{
preferenceValue = PreferenceConstants.PROMPT_MODE_NEVER;
}
store.setValue(PreferenceConstants.EXECUTE_SQL_ERROR_MODE, preferenceValue);
}
if (result == IDialogConstants.YES_ID)
{
goon = true;
}
else
{
goon = false;
}
}
}
private Runnable _postRun;
/**
* Constructs a runnable to execute a group of SQL statements.
*
* @param request the plan request
* @param databaseIdentifier the database identifier
* @param postRun the runnable which will be invoked at last
*/
public GroupPlanSupportRunnable(PlanRequest request, DatabaseIdentifier databaseIdentifier, Runnable postRun)
{
super(request, databaseIdentifier.getProfileName(), databaseIdentifier.getDBname());
this._postRun = postRun;
}
protected String explainPlan(Statement stmt) throws SQLException
{
return null;
}
public void run()
{
run(null);
}
protected void handleEnd(Connection connection, Statement stmt)
{
}
protected IStatus run(IProgressMonitor monitor)
{
IJobManager manager = Job.getJobManager();
if (monitor == null)
{
monitor = manager.createProgressGroup();
}
String[] groups = new String[]
{
_request.getSql()
};
DatabaseIdentifier databaseIdentifier = new DatabaseIdentifier(_profileName, _dbName);
SQLService helper = SQLToolsFacade.getSQLService(databaseIdentifier, "" //$NON-NLS-1$
+ _request.getDatabaseDefinitionId().toString());
if (helper != null)
{
groups = helper.splitSQL(_request.getSql());
}
String task = Messages.getString("GroupPlanSupportRunnable.sql_execution_plan"); //$NON-NLS-1$
if (groups.length > 1)
{
task += NLS.bind(Messages.getString("GroupPlanSupportRunnable.groups"), (new Object[] //$NON-NLS-1$
{
"" + groups.length //$NON-NLS-1$
}));
}
monitor.beginTask(task, groups.length);
for (int i = 0; i < groups.length; i++)
{
if (groups.length > 1)
{
monitor.subTask(NLS.bind(Messages.getString("GroupPlanSupportRunnable.group"), (new Object[] //$NON-NLS-1$
{
"" + i //$NON-NLS-1$
})));
}
PlanSupportRunnable planRunnable = null;
PlanRequest request = new PlanRequest(groups[i], _request.getDatabaseDefinitionId(),
_request.getPlanType(), _request.getMode());
request.setNoexec(_request.isNoexec());
// request.setSql(SQLUtil.getSQLWithDefOfAssAndRefAndEvaluations(
// request.getSql(), databaseIdentifier, _varDecs));
request.setSql(processVarDecs(request.getSql(), databaseIdentifier, _request.getVarDecs()));
// Returning null indicates that the user cancelled this job
if (request.getSql() == null)
{
monitor.worked(1);
continue;
}
IPlanService planService = SQLToolsUIFacade.getPlanService(databaseIdentifier);
if (planService != null)
{
planRunnable = planService.createPlanSupportRunnable(request, _profileName, _dbName);
}
if (planRunnable != null)
{
if(getConnection() != null)
{
planRunnable.setConnection(getConnection());
}
planRunnable.setProgressGroup(monitor, 1);
planRunnable.schedule();
try
{
// wait until it finishes
planRunnable.join();
}
catch (InterruptedException e)
{
// TODO:log
// _log
// .error(
// EditorMessages.GroupPlanSupportRunnable_error_interrupted,
// e);
}
monitor.worked(1);
// checks if the user cancels the operation
if (monitor.isCanceled())
{
return Status.CANCEL_STATUS;
}
if (EPVFacade.getInstance().getStatus(request) == PlanRequest.FAILED && i < groups.length - 1)
{
IPreferenceStore store = SQLEditorPlugin.getDefault().getPreferenceStore();
String errorpm = store.getString(PreferenceConstants.EXECUTE_SQL_ERROR_MODE);
if (errorpm == null || errorpm.equals("") || PreferenceConstants.PROMPT_MODE_PROMPT.equals(errorpm)) //$NON-NLS-1$
{
// prompt user whether to continue
ConfirmRunnable run = new ConfirmRunnable();
SQLEditorPlugin.getDisplay().syncExec(run);
if (!run.goon)
{
break;
}
}
else if (PreferenceConstants.PROMPT_MODE_ALWAYS.equals(errorpm))
{
continue;
}
else
{
// never
break;
}
}
}
}
if (_postRun != null)
{
SQLEditorPlugin.getDisplay().syncExec(_postRun);
}
return Status.OK_STATUS;
}
/**
* Subclass may override this method to add variable definitions to the sql statement, such that the statements can
* be explained even if the variable definitions statements are not selected.
*
* @param sql
* @param databaseIdentifier
* @param varDecs
* @return
*/
protected String processVarDecs(String sql, DatabaseIdentifier databaseIdentifier, Map varDecs)
{
return sql;
}
}