/* * Copyright (C) 2006 SQL Explorer Development Team * http://sourceforge.net/projects/eclipsesql * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package net.sourceforge.sqlexplorer.sqlpanel; import java.sql.SQLException; import java.sql.Statement; import net.sourceforge.sqlexplorer.IConstants; import net.sourceforge.sqlexplorer.Messages; import net.sourceforge.sqlexplorer.dataset.DataSet; import net.sourceforge.sqlexplorer.dataset.DataSetTable; import net.sourceforge.sqlexplorer.dbproduct.DatabaseProduct; import net.sourceforge.sqlexplorer.parsers.Query; import net.sourceforge.sqlexplorer.parsers.QueryParser; import net.sourceforge.sqlexplorer.plugin.SQLExplorerPlugin; import net.sourceforge.sqlexplorer.plugin.editors.Message; import net.sourceforge.sqlexplorer.plugin.editors.SQLEditor; import net.sourceforge.sqlexplorer.sqleditor.results.ResultsTab; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialogWithToggle; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; /** * Executes one or more SQL statements in sequence, displaying the results in tabs * and/or in the Messages tab * @modified John Spackman * */ public class SQLExecution extends AbstractSQLExecution { // Whether the editor has any messages private boolean hasMessages; // Maximum number of rows to return protected int _maxRows; // The Statement being used to execute the current query protected Statement _stmt; /** * Constructor * @param _editor * @param queryParser * @param maxRows * @param _session */ public SQLExecution(SQLEditor _editor, QueryParser queryParser, int maxRows) { super(_editor, queryParser); _maxRows = maxRows; } /** * Display SQL Results in result pane * @param sqlResult the results of the query */ protected void displayResults(final SQLResult sqlResult) { // Switch to the UI thread to execute this getEditor().getSite().getShell().getDisplay().asyncExec(new Runnable() { public void run() { ResultsTab resultsTab = allocateResultsTab(sqlResult.getQuery()); if (resultsTab == null) return; String caption = sqlResult.getDataSet().getCaption(); if (caption != null) resultsTab.getTabItem().setText(caption); try { // set initial message setProgressMessage(Messages.getString("SQLResultsView.ConnectionWait")); Composite composite = resultsTab.getParent(); GridLayout gLayout = new GridLayout(); gLayout.numColumns = 2; gLayout.marginLeft = 0; gLayout.horizontalSpacing = 0; gLayout.verticalSpacing = 0; gLayout.marginWidth = 0; gLayout.marginHeight = 0; composite.setLayout(gLayout); int resultCount = sqlResult.getDataSet().getRows().length; String statusMessage = Messages.getString("SQLResultsView.Time.Prefix") + " " + sqlResult.getExecutionTimeMillis() + " " + Messages.getString("SQLResultsView.Time.Postfix"); getEditor().setMessage(statusMessage); if (resultCount > 0) statusMessage = statusMessage + " " + Messages.getString("SQLResultsView.Count.Prefix") + " " + resultCount; Query sql = sqlResult.getQuery(); int lineNo = sql.getLineNo(); lineNo = getQueryParser().adjustLineNo(lineNo); getEditor().addMessage(new Message(Message.Status.SUCCESS, lineNo, 0, sql.getQuerySql(), statusMessage)); new DataSetTable(composite, sqlResult.getDataSet(), statusMessage); composite.setData("parenttab", resultsTab.getTabItem()); composite.layout(); composite.redraw(); // reset to start message in case F5 will be used setProgressMessage(Messages.getString("SQLResultsView.ConnectionWait")); } catch (Exception e) { // add message if (resultsTab != null) { String message = e.getMessage(); Label errorLabel = new Label(resultsTab.getParent(), SWT.FILL); errorLabel.setText(message); errorLabel.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); } SQLExplorerPlugin.error("Error creating result tab", e); } }; }); } private void closeStatement() { if (_stmt == null) { return; } if (_stmt != null) { try { _stmt.close(); } catch (Exception e) { SQLExplorerPlugin.error("Error closing statement.", e); } } _stmt = null; } protected void doExecution(IProgressMonitor monitor) throws Exception { int numErrors = 0; SQLException lastSQLException = null; try { long overallUpdateCount = 0; long overallStartTime = System.currentTimeMillis(); for (Query query : getQueryParser()) { if (monitor.isCanceled()) break; if (getEditor().isClosed()) break; // Get the next bit of SQL to run and store it as "current" if (query == null) break; String querySQL = query.getQuerySql().toString(); if (querySQL == null) continue; // Initialise setProgressMessage(Messages.getString("SQLResultsView.Executing")); final long startTime = System.currentTimeMillis(); // Run it DatabaseProduct.ExecutionResults results = null; try { DatabaseProduct product = getEditor().getSession().getDatabaseProduct(); try { results = product.executeQuery(_connection, query, _maxRows); }catch(RuntimeException e) { throw new SQLException(e.getMessage()); } final long endTime = System.currentTimeMillis(); DataSet dataSet; boolean checkedForMessages = false; while ((dataSet = results.nextDataSet()) != null) { // update sql result SQLResult sqlResult = new SQLResult(); sqlResult.setQuery(query); sqlResult.setDataSet(dataSet); sqlResult.setExecutionTimeMillis(endTime - startTime); // Save successfull query SQLExplorerPlugin.getDefault().getSQLHistory().addSQL(querySQL, _session); if (monitor.isCanceled()) return; checkForMessages(query); checkedForMessages = true; // show results.. displayResults(sqlResult); } overallUpdateCount += results.getUpdateCount(); if (!checkedForMessages) checkForMessages(query); debugLogQuery(query, null); } catch(final SQLException e) { debugLogQuery(query, e); boolean stopOnError = SQLExplorerPlugin.getDefault().getPreferenceStore().getBoolean(IConstants.STOP_ON_ERROR); logException(e, query, stopOnError); closeStatement(); hasMessages = true; if (stopOnError) { errorDialog(Messages.getString("SQLResultsView.Error.Title"), e.getMessage()); return; } numErrors++; lastSQLException = e; } finally { try { if (results != null) { results.close(); results = null; } }catch(SQLException e) { // Nothing } } } if (!hasMessages || SQLExplorerPlugin.getDefault().getPreferenceStore().getBoolean(IConstants.LOG_SUCCESS_MESSAGES)) { long overallTime = System.currentTimeMillis() - overallStartTime; String message = Long.toString(overallUpdateCount) + " " + Messages.getString("SQLEditor.Update.Prefix") + " " + Long.toString(overallTime) + " " + Messages.getString("SQLEditor.Update.Postfix"); addMessage(new Message(Message.Status.STATUS, getQueryParser().adjustLineNo(1), 0, "", message)); } } catch (Exception e) { closeStatement(); throw e; } if (numErrors == 1) throw lastSQLException; else if (numErrors > 1 && SQLExplorerPlugin.getDefault().getPreferenceStore().getBoolean(IConstants.CONFIRM_BOOL_SHOW_DIALOG_ON_QUERY_ERROR)) getEditor().getSite().getShell().getDisplay().asyncExec(new Runnable() { public void run() { MessageDialogWithToggle dialog = MessageDialogWithToggle.openInformation(getEditor().getSite().getShell(), Messages.getString("SQLExecution.Error.Title"), Messages.getString("SQLExecution.Error.Message"), Messages.getString("SQLExecution.Error.Toggle"), false, null, null); if (dialog.getToggleState() && dialog.getReturnCode() == IDialogConstants.OK_ID) SQLExplorerPlugin.getDefault().getPluginPreferences().setValue(IConstants.CONFIRM_BOOL_SHOW_DIALOG_ON_QUERY_ERROR, false); } }); } /** * Cancel sql execution and close execution tab. */ public void doStop() { if (_stmt != null) { try { _stmt.cancel(); } catch (Exception e) { SQLExplorerPlugin.error("Error cancelling statement.", e); } try { closeStatement(); } catch (Exception e) { SQLExplorerPlugin.error("Error closing statement.", e); } } } }