org.jkiss.dbeaver.ui.dialogs.sql.GenerateMultiSQLDialog.java Source code

Java tutorial

Introduction

Here is the source code for org.jkiss.dbeaver.ui.dialogs.sql.GenerateMultiSQLDialog.java

Source

/*
 * DBeaver - Universal Database Manager
 * Copyright (C) 2010-2016 Serge Rieder (serge@jkiss.org)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License (version 2)
 * as published by the Free Software Foundation.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
package org.jkiss.dbeaver.ui.dialogs.sql;

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.jface.dialogs.IDialogConstants;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.IWorkbenchPartSite;
import org.jkiss.code.NotNull;
import org.jkiss.dbeaver.model.DBPDataSource;
import org.jkiss.dbeaver.model.DBUtils;
import org.jkiss.dbeaver.model.exec.*;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.struct.DBSObject;
import org.jkiss.dbeaver.runtime.jobs.DataSourceJob;
import org.jkiss.dbeaver.model.DBIcon;
import org.jkiss.dbeaver.ui.DBeaverIcons;
import org.jkiss.dbeaver.ui.UIUtils;

import java.util.*;

/**
 * Super class for handling dialogs related to
 * 
 * @author Serge Rieder
 * 
 */
public abstract class GenerateMultiSQLDialog<T extends DBSObject> extends GenerateSQLDialog {

    protected final Collection<T> selectedObjects;
    private Table objectsTable;

    public GenerateMultiSQLDialog(IWorkbenchPartSite partSite, String title, Collection<T> objects, boolean meta) {
        this(partSite, getContextFromObjects(objects, meta), title, objects);
    }

    public GenerateMultiSQLDialog(IWorkbenchPartSite partSite, DBCExecutionContext context, String title,
            Collection<T> objects) {
        super(partSite, context, title, null);
        this.selectedObjects = objects;
    }

    protected abstract SQLScriptProgressListener<T> getScriptListener();

    protected String[] generateSQLScript() {
        List<T> checkedObjects = getCheckedObjects();
        List<String> lines = new ArrayList<>();
        for (T object : checkedObjects) {
            generateObjectCommand(lines, object);
        }

        return lines.toArray(new String[lines.size()]);
    }

    public List<T> getCheckedObjects() {
        List<T> checkedObjects = new ArrayList<>();
        if (objectsTable != null) {
            for (TableItem item : objectsTable.getItems()) {
                if (item.getChecked()) {
                    checkedObjects.add((T) item.getData());
                }
            }
        } else {
            checkedObjects.addAll(selectedObjects);
        }
        return checkedObjects;
    }

    protected void createObjectsSelector(Composite parent) {
        if (selectedObjects.size() < 2) {
            // Don't need it for a single object
            return;
        }
        UIUtils.createControlLabel(parent, "Tables");
        objectsTable = new Table(parent, SWT.BORDER | SWT.CHECK);
        GridData gd = new GridData(GridData.FILL_HORIZONTAL);
        gd.heightHint = 100;
        objectsTable.setLayoutData(gd);
        for (T table : selectedObjects) {
            TableItem item = new TableItem(objectsTable, SWT.NONE);
            item.setText(DBUtils.getObjectFullName(table));
            item.setImage(DBeaverIcons.getImage(DBIcon.TREE_TABLE));
            item.setChecked(true);
            item.setData(table);
        }
        objectsTable.addSelectionListener(SQL_CHANGE_LISTENER);
        objectsTable.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                boolean hasChecked = !getCheckedObjects().isEmpty();
                getButton(IDialogConstants.OK_ID).setEnabled(hasChecked);
                getButton(IDialogConstants.DETAILS_ID).setEnabled(hasChecked);
            }
        });
    }

    @Override
    protected void executeSQL() {
        final String jobName = getShell().getText();
        final SQLScriptProgressListener<T> scriptListener = getScriptListener();
        final List<T> objects = getCheckedObjects();
        final Map<T, List<String>> objectsSQL = new LinkedHashMap<>();
        for (T 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;

            @Override
            protected IStatus run(final DBRProgressMonitor monitor) {
                final DataSourceJob curJob = this;
                UIUtils.runInDetachedUI(getShell(), 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 T object = objects.get(i);
                        monitor.subTask("Process " + DBUtils.getObjectFullName(object));
                        objectProcessingError = null;
                        UIUtils.runInDetachedUI(getShell(), new Runnable() {
                            @Override
                            public void run() {
                                scriptListener.beginObjectProcessing(object, objectNumber);
                            }
                        });
                        try {
                            final List<String> lines = objectsSQL.get(object);
                            for (String line : lines) {
                                DBCStatement statement = DBUtils.prepareStatement(session, line, false);
                                try {
                                    if (statement.executeStatement()) {
                                        final DBCResultSet resultSet = statement.openResultSet();
                                        try {
                                            // Run in sync because we need result set
                                            UIUtils.runInUI(getShell(), new Runnable() {
                                                @Override
                                                public void run() {
                                                    try {
                                                        scriptListener.processObjectResults(object, resultSet);
                                                    } catch (DBCException e) {
                                                        objectProcessingError = e;
                                                    }
                                                }
                                            });
                                        } finally {
                                            resultSet.close();
                                        }
                                        if (objectProcessingError != null) {
                                            break;
                                        }
                                    }
                                } finally {
                                    statement.close();
                                }
                            }
                        } catch (Exception e) {
                            objectProcessingError = e;
                        } finally {
                            UIUtils.runInDetachedUI(getShell(), new Runnable() {
                                @Override
                                public void run() {
                                    scriptListener.endObjectProcessing(object, objectProcessingError);
                                }
                            });
                        }
                        monitor.worked(1);
                    }
                } finally {
                    monitor.done();
                    UIUtils.runInDetachedUI(getShell(), 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();
    }

    protected abstract void generateObjectCommand(List<String> sql, T object);

    protected static <T extends DBSObject> DBCExecutionContext getContextFromObjects(@NotNull Collection<T> objects,
            boolean meta) {
        Iterator<T> iterator = objects.iterator();
        if (iterator.hasNext()) {
            T object = iterator.next();
            DBPDataSource dataSource = object.getDataSource();
            return dataSource == null ? null : dataSource.getDefaultContext(meta);
        }
        return null;
    }

}