/* * DBeaver - Universal Database Manager * Copyright (C) 2016-2016 Karl Griesser (fullref@gmail.com) * 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.ext.exasol.tools.maintenance; 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.swt.SWT; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeColumn; import org.eclipse.swt.widgets.TreeItem; import org.eclipse.ui.IWorkbenchPartSite; import org.jkiss.code.NotNull; import org.jkiss.code.Nullable; import org.jkiss.dbeaver.core.DBeaverUI; import org.jkiss.dbeaver.ext.exasol.ExasolMessages; import org.jkiss.dbeaver.ext.exasol.model.ExasolTableBase; import org.jkiss.dbeaver.model.DBPDataKind; import org.jkiss.dbeaver.model.DBPEvaluationContext; import org.jkiss.dbeaver.model.DBUtils; import org.jkiss.dbeaver.model.exec.*; import org.jkiss.dbeaver.model.exec.jdbc.JDBCSession; import org.jkiss.dbeaver.model.impl.jdbc.exec.JDBCStatementImpl; import org.jkiss.dbeaver.model.impl.local.LocalResultSet; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; import org.jkiss.dbeaver.runtime.jobs.DataSourceJob; import org.jkiss.dbeaver.ui.UIUtils; import org.jkiss.dbeaver.ui.dialogs.sql.GenerateMultiSQLDialog; import org.jkiss.dbeaver.ui.dialogs.sql.SQLScriptProgressListener; import org.jkiss.dbeaver.ui.dialogs.sql.SQLScriptStatusDialog; import org.jkiss.dbeaver.utils.GeneralUtils; import org.jkiss.utils.CommonUtils; import java.sql.Statement; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.*; public abstract class ExasolBaseTableToolDialog extends GenerateMultiSQLDialog<ExasolTableBase> { private static final String VARIABLE_DATE = "date"; private static final String VARIABLE_TABLE = "table"; private static final String VARIABLE_SCHEMA = "schema"; ExasolBaseTableToolDialog(IWorkbenchPartSite partSite, String title, Collection<ExasolTableBase> objects) { super(partSite, title, objects, true); } protected int getNumberExtraResultingColumns() { return 0; } protected String replaceVars(String input, final ExasolTableBase table) { String outString = GeneralUtils.replaceVariables(input, new GeneralUtils.IVariableResolver() { @Override public String get(String name) { switch (name) { case VARIABLE_TABLE: return table.getName(); case VARIABLE_SCHEMA: return table.getContainer().getName(); case VARIABLE_DATE: DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); Calendar cal = Calendar.getInstance(); return dateFormat.format(cal.getTime()); default: System.getProperty(name); } return null; } }); return outString; } @Override protected SQLScriptProgressListener<ExasolTableBase> getScriptListener() { final int nbExtraColumns = getNumberExtraResultingColumns(); return new SQLScriptStatusDialog<ExasolTableBase>(getTitle() + " " + ExasolMessages.dialog_table_tools_progress,null) { @Override protected void createStatusColumns(Tree objectTree) { TreeColumn msgColumn = new TreeColumn(objectTree, SWT.NONE); msgColumn.setText(ExasolMessages.dialog_table_tools_result); for (int i = 0; i < nbExtraColumns; i++) { new TreeColumn(objectTree, SWT.NONE); } } @Override public void endObjectProcessing(@NotNull ExasolTableBase exasolTable, Exception exception) { TreeItem treeItem = getTreeItem(exasolTable); if (exception == null) { treeItem.setText(1, ExasolMessages.dialog_table_tools_success_title); } else { treeItem.setText(1, exception.getMessage()); } UIUtils.packColumns(treeItem.getParent(), false, null); } // DF: This method is for tools that return resultsets @Override public void processObjectResults(@NotNull ExasolTableBase exasolTable, @Nullable DBCStatement statement, @Nullable DBCResultSet resultSet) throws DBCException { if (resultSet == null) { return; } // Retrieve column names DBCResultSetMetaData rsMetaData = resultSet.getMeta(); try { TreeItem treeItem = getTreeItem(exasolTable); Font f = UIUtils.makeBoldFont(treeItem.getFont()); if (treeItem != null) { // Display the column names TreeItem subItem = null; subItem = new TreeItem(treeItem, SWT.NONE); subItem.setFont(f); for (DBCAttributeMetaData column: rsMetaData.getAttributes()) { subItem.setText(column.getOrdinalPosition(), column.getName()); subItem.setGrayed(true); } // Display the data for each row while (resultSet.nextRow()) { subItem = new TreeItem(treeItem, SWT.NONE); for (int i = 0; i < rsMetaData.getAttributes().size(); i++) { subItem.setText(i, CommonUtils.toString(resultSet.getAttributeValue(i))); i++; } } treeItem.setExpanded(true); } } catch (Exception e) { throw new DBCException(e.getMessage()); } } }; } @Override protected void executeSQL() { final String jobName = getShell().getText(); final SQLScriptProgressListener<ExasolTableBase> scriptListener = getScriptListener(); final List<ExasolTableBase> objects = getCheckedObjects(); final Map<ExasolTableBase, List<String>> objectsSQL = new LinkedHashMap<>(); for (ExasolTableBase object : objects) { final List<String> lines = new ArrayList<>(); generateObjectCommand(lines, object); objectsSQL.put(object, lines); } final DataSourceJob job = new DataSourceJob(jobName, null, getExecutionContext()) { public Exception objectProcessingError; @SuppressWarnings("rawtypes") @Override protected IStatus run(final DBRProgressMonitor monitor) { final DataSourceJob curJob = this; DBeaverUI.asyncExec(new Runnable() { @Override public void run() { scriptListener.beginScriptProcessing(curJob, objects); } }); monitor.beginTask(jobName, objects.size()); try (DBCSession session = getExecutionContext().openSession(monitor, DBCExecutionPurpose.UTIL, jobName)) { for (int i = 0; i < objects.size(); i++) { if (monitor.isCanceled()) { break; } final int objectNumber = i; final ExasolTableBase object = objects.get(i); monitor.subTask("Process " + DBUtils.getObjectFullName(object, DBPEvaluationContext.UI)); objectProcessingError = null; DBeaverUI.asyncExec(new Runnable() { @Override public void run() { scriptListener.beginObjectProcessing(object, objectNumber); } }); try { final List<String> lines = objectsSQL.get(object); for (String line : lines) { try (final Statement statement = ((JDBCSession) session).getOriginal().createStatement()) { int affectedRows = statement.executeUpdate(line); Integer[] resultSetData = new Integer[] { affectedRows }; final LocalResultSet resultSet = new LocalResultSet<>(session, new JDBCStatementImpl<>((JDBCSession) session, statement, true)); resultSet.addColumn("ROWS_AFFECTED", DBPDataKind.NUMERIC); resultSet.addRow((Object[]) resultSetData ); // Run in sync because we need result set DBeaverUI.syncExec(new Runnable() { @Override public void run() { try { scriptListener.processObjectResults(object, null, resultSet); } catch (DBCException e) { objectProcessingError = e; } } }); if (objectProcessingError != null) { break; } } } } catch (Exception e) { objectProcessingError = e; } finally { DBeaverUI.asyncExec(new Runnable() { @Override public void run() { scriptListener.endObjectProcessing(object, objectProcessingError); } }); } monitor.worked(1); } } finally { monitor.done(); DBeaverUI.asyncExec(new Runnable() { @Override public void run() { scriptListener.endScriptProcessing(); } }); } return Status.OK_STATUS; } }; job.setUser(false); job.addJobChangeListener(new JobChangeAdapter() { @Override public void done(IJobChangeEvent event) { } }); job.schedule(); } }