<commit_before>/*
 * DBeaver - Universal Database Manager
 * Copyright (C) 2010-2019 <NAME> (<EMAIL>)
 *
 * 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.generator;

import org.eclipse.jface.action.*;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
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.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.actions.CompoundContributionItem;
import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.model.*;
import org.jkiss.dbeaver.model.data.DBDAttributeBinding;
import org.jkiss.dbeaver.model.data.DBDRowIdentifier;
import org.jkiss.dbeaver.model.exec.DBCExecutionContext;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.runtime.DBRRunnableWithResult;
import org.jkiss.dbeaver.model.sql.SQLConstants;
import org.jkiss.dbeaver.model.sql.SQLDataSource;
import org.jkiss.dbeaver.model.sql.SQLDialect;
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.DBSTable;
import org.jkiss.dbeaver.ui.DBeaverIcons;
import org.jkiss.dbeaver.ui.UIIcon;
import org.jkiss.dbeaver.ui.UIUtils;
import org.jkiss.dbeaver.ui.controls.resultset.IResultSetController;
import org.jkiss.dbeaver.ui.controls.resultset.IResultSetSelection;
import org.jkiss.dbeaver.ui.controls.resultset.ResultSetModel;
import org.jkiss.dbeaver.ui.controls.resultset.ResultSetRow;
import org.jkiss.dbeaver.ui.editors.sql.dialogs.ViewSQLDialog;
import org.jkiss.dbeaver.ui.navigator.NavigatorUtils;
import org.jkiss.dbeaver.utils.RuntimeUtils;
import org.jkiss.utils.CommonUtils;

import java.lang.reflect.InvocationTargetException;
import java.util.*;

public class GenerateSQLContributor extends CompoundContributionItem {

    static protected final Log log = Log.getLog(GenerateSQLContributor.class);

    //////////////////////////////////////////////////////////
    // Contributors

    @Override
    protected IContributionItem[] getContributionItems()
    {
        IWorkbenchPart part = UIUtils.getActiveWorkbenchWindow().getActivePage().getActivePart();
        IStructuredSelection structuredSelection = NavigatorUtils.getSelectionFromPart(part);
        if (structuredSelection == null || structuredSelection.isEmpty()) {
            return new IContributionItem[0];
        }

        List<IContributionItem> menu = new ArrayList<>();
        if (structuredSelection instanceof IResultSetSelection) {
            // Results
            makeResultSetContributions(menu, (IResultSetSelection) structuredSelection);

        } else {
            List<DBSEntity> entities = new ArrayList<>();
            List<DBPScriptObject> scriptObjects = new ArrayList<>();
            for (Object sel : structuredSelection.toArray()) {
                final DBSObject object = RuntimeUtils.getObjectAdapter(sel, DBSObject.class);
                if (object instanceof DBSEntity) {
                    entities.add((DBSEntity) object);
                }
                if (object instanceof DBPScriptObject) {
                    scriptObjects.add((DBPScriptObject) object);
                }
            }
            if (!entities.isEmpty()) {
                makeTableContributions(menu, entities);
            }
            if (!scriptObjects.isEmpty()) {
                makeScriptContributions(menu, scriptObjects);
            }
        }
        return menu.toArray(new IContributionItem[0]);
    }

    private void makeTableContributions(List<IContributionItem> menu, final List<DBSEntity> entities)
    {
        // Table
        menu.add(makeAction("SELECT ", SELECT_GENERATOR(entities, true)));
        menu.add(makeAction("INSERT ", INSERT_GENERATOR(entities)));
        menu.add(makeAction("UPDATE ", UPDATE_GENERATOR(entities)));
        menu.add(makeAction("DELETE ", DELETE_GENERATOR(entities)));
        menu.add(makeAction("MERGE", MERGE_GENERATOR(entities)));
        if (entities.size() > 1) {
            menu.add(new Separator());
            menu.add(makeAction("JOIN", JOIN_GENERATOR(entities)));
        }
    }

    private void makeScriptContributions(List<IContributionItem> menu, final List<DBPScriptObject> scriptObjects)
    {
        if (menu.size() > 0) {
            menu.add(new Separator());
        }
        List<DBSProcedure> procedures = new ArrayList<>();
        for (DBPScriptObject so : scriptObjects) {
            if (so instanceof DBSProcedure) {
                procedures.add((DBSProcedure) so);
            }
        }
        if (!procedures.isEmpty()) {
            menu.add(makeAction("CALL", CALL_GENERATOR(procedures)));
        }
        menu.add(makeAction("DDL", new SQLGenerator<DBPScriptObject>(scriptObjects) {
            @Override
            public void run(DBRProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
                boolean allTables = true;
                List<DBSTable> tableList = new ArrayList<>();
                for (DBPScriptObject object : objects) {
                    if (!(object instanceof DBSTable)) {
                        allTables = false;
                        break;
                    } else {
                        tableList.add((DBSTable) object);
                    }
                }
                if (!allTables) {
                    super.run(monitor);
                    return;
                }

                StringBuilder sql = new StringBuilder(100);
                Map<String, Object> options = new HashMap<>();
                try {
                    DBStructUtils.generateTableListDDL(monitor, sql, tableList, options, false);
                } catch (DBException e) {
                    throw new InvocationTargetException(e);
                }
                result = sql.toString();<commit_msg>#6387 Generate SQL->DDL: options pass fixed<commit_after>/*
 * DBeaver - Universal Database Manager
 * Copyright (C) 2010-2019 <NAME> (<EMAIL>)
 *
 * 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.generator;

import org.eclipse.jface.action.*;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
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.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.actions.CompoundContributionItem;
import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.model.*;
import org.jkiss.dbeaver.model.data.DBDAttributeBinding;
import org.jkiss.dbeaver.model.data.DBDRowIdentifier;
import org.jkiss.dbeaver.model.exec.DBCExecutionContext;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.runtime.DBRRunnableWithResult;
import org.jkiss.dbeaver.model.sql.SQLConstants;
import org.jkiss.dbeaver.model.sql.SQLDataSource;
import org.jkiss.dbeaver.model.sql.SQLDialect;
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.DBSTable;
import org.jkiss.dbeaver.ui.DBeaverIcons;
import org.jkiss.dbeaver.ui.UIIcon;
import org.jkiss.dbeaver.ui.UIUtils;
import org.jkiss.dbeaver.ui.controls.resultset.IResultSetController;
import org.jkiss.dbeaver.ui.controls.resultset.IResultSetSelection;
import org.jkiss.dbeaver.ui.controls.resultset.ResultSetModel;
import org.jkiss.dbeaver.ui.controls.resultset.ResultSetRow;
import org.jkiss.dbeaver.ui.editors.sql.dialogs.ViewSQLDialog;
import org.jkiss.dbeaver.ui.navigator.NavigatorUtils;
import org.jkiss.dbeaver.utils.RuntimeUtils;
import org.jkiss.utils.CommonUtils;

import java.lang.reflect.InvocationTargetException;
import java.util.*;

public class GenerateSQLContributor extends CompoundContributionItem {

    static protected final Log log = Log.getLog(GenerateSQLContributor.class);

    //////////////////////////////////////////////////////////
    // Contributors

    @Override
    protected IContributionItem[] getContributionItems()
    {
        IWorkbenchPart part = UIUtils.getActiveWorkbenchWindow().getActivePage().getActivePart();
        IStructuredSelection structuredSelection = NavigatorUtils.getSelectionFromPart(part);
        if (structuredSelection == null || structuredSelection.isEmpty()) {
            return new IContributionItem[0];
        }

        List<IContributionItem> menu = new ArrayList<>();
        if (structuredSelection instanceof IResultSetSelection) {
            // Results
            makeResultSetContributions(menu, (IResultSetSelection) structuredSelection);

        } else {
            List<DBSEntity> entities = new ArrayList<>();
            List<DBPScriptObject> scriptObjects = new ArrayList<>();
            for (Object sel : structuredSelection.toArray()) {
                final DBSObject object = RuntimeUtils.getObjectAdapter(sel, DBSObject.class);
                if (object instanceof DBSEntity) {
                    entities.add((DBSEntity) object);
                }
                if (object instanceof DBPScriptObject) {
                    scriptObjects.add((DBPScriptObject) object);
                }
            }
            if (!entities.isEmpty()) {
                makeTableContributions(menu, entities);
            }
            if (!scriptObjects.isEmpty()) {
                makeScriptContributions(menu, scriptObjects);
            }
        }
        return menu.toArray(new IContributionItem[0]);
    }

    private void makeTableContributions(List<IContributionItem> menu, final List<DBSEntity> entities)
    {
        // Table
        menu.add(makeAction("SELECT ", SELECT_GENERATOR(entities, true)));
        menu.add(makeAction("INSERT ", INSERT_GENERATOR(entities)));
        menu.add(makeAction("UPDATE ", UPDATE_GENERATOR(entities)));
        menu.add(makeAction("DELETE ", DELETE_GENERATOR(entities)));
        menu.add(makeAction("MERGE", MERGE_GENERATOR(entities)));
        if (entities.size() > 1) {
            menu.add(new Separator());
            menu.add(makeAction("JOIN", JOIN_GENERATOR(entities)));
        }
    }

    private void makeScriptContributions(List<IContributionItem> menu, final List<DBPScriptObject> scriptObjects)
    {
        if (menu.size() > 0) {
            menu.add(new Separator());
        }
        List<DBSProcedure> procedures = new ArrayList<>();
        for (DBPScriptObject so : scriptObjects) {
            if (so instanceof DBSProcedure) {
                procedures.add((DBSProcedure) so);
            }
        }
        if (!procedures.isEmpty()) {
            menu.add(makeAction("CALL", CALL_GENERATOR(procedures)));
        }
        menu.add(makeAction("DDL", new SQLGenerator<DBPScriptObject>(scriptObjects) {
            @Override
            public void run(DBRProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
                boolean allTables = true;
                List<DBSTable> tableList = new ArrayList<>();
                for (DBPScriptObject object : objects) {
                    if (!(object instanceof DBSTable)) {
                        allTables = false;
                        break;
                    } else {
                        tableList.add((DBSTable) object);
                    }
                }
                if (!allTables) {
                    super.run(monitor);
                    return;
                }

                StringBuilder sql = new StringBuilder(100);
                Map<String, Object> options = new HashMap<>();
                addOptions(options);
                try {
                    DBStructUtils.generateTableListDDL(monitor, sql, tableList, options, false);
                } catch (DBException e) {
                    throw new InvocationTargetException(e);
                }
                result = sql.toString();
{'fraction_non_alphanumeric': 0.11023790812316925, 'fraction_numerical': 0.0030006429949274846, 'mean_word_length': 2.728822589238146, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 46, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7326954', 'n_tokens_mistral': 3998, 'n_tokens_neox': 3852, 'n_words': 763}