diff --git a/plugins/org.jkiss.dbeaver.ext.postgresql.ui/plugin.xml b/plugins/org.jkiss.dbeaver.ext.postgresql.ui/plugin.xml index 4ee0ae8c99351c4f47c03791e6e9ccdaf1913afe..849a150d56677bf89a02132240d4369478bafc5d 100644 --- a/plugins/org.jkiss.dbeaver.ext.postgresql.ui/plugin.xml +++ b/plugins/org.jkiss.dbeaver.ext.postgresql.ui/plugin.xml @@ -114,6 +114,10 @@ + + + + @@ -212,6 +216,24 @@ label="Disable trigger" singleton="false"> + + + + + + { + @Override + public PostgreExtension configureObject(DBRProgressMonitor monitor, Object parent, PostgreExtension extension) { + return new UITask() { + @Override + protected PostgreExtension runTask() { + PostgreCreateExtensionDialog dialog = new PostgreCreateExtensionDialog(UIUtils.getActiveWorkbenchShell(), extension); + if (dialog.open() != IDialogConstants.OK_ID) { + return null; + } + extension.setName(dialog.getExtension().getName()); + extension.setSchema(dialog.getSchema().getName()); + return extension; + } + }.execute(); + } + +} diff --git a/plugins/org.jkiss.dbeaver.ext.postgresql.ui/src/org/jkiss/dbeaver/ext/postgresql/tools/maintenance/PostgreToolExtensionUninstall.java b/plugins/org.jkiss.dbeaver.ext.postgresql.ui/src/org/jkiss/dbeaver/ext/postgresql/tools/maintenance/PostgreToolExtensionUninstall.java new file mode 100644 index 0000000000000000000000000000000000000000..554a5649e8b20e1ef81510e0a841611e5faee447 --- /dev/null +++ b/plugins/org.jkiss.dbeaver.ext.postgresql.ui/src/org/jkiss/dbeaver/ext/postgresql/tools/maintenance/PostgreToolExtensionUninstall.java @@ -0,0 +1,89 @@ +/* + * DBeaver - Universal Database Manager + * Copyright (C) 2010-2019 Serge Rider (serge@jkiss.org) + * Copyright (C) 2019 Andrew Khitrin (ahitrin@gmail.com) + * + * 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.postgresql.tools.maintenance; + +import java.lang.reflect.InvocationTargetException; +import java.util.Collection; +import java.util.List; + +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchPartSite; +import org.eclipse.ui.IWorkbenchWindow; +import org.jkiss.dbeaver.DBException; +import org.jkiss.dbeaver.ext.postgresql.model.PostgreObject; +import org.jkiss.dbeaver.model.navigator.DBNDatabaseNode; +import org.jkiss.dbeaver.model.navigator.DBNUtils; +import org.jkiss.dbeaver.model.struct.DBSObject; +import org.jkiss.dbeaver.runtime.DBWorkbench; +import org.jkiss.dbeaver.ui.UIUtils; +import org.jkiss.dbeaver.ui.tools.IUserInterfaceTool; +import org.jkiss.utils.CommonUtils; + +public class PostgreToolExtensionUninstall implements IUserInterfaceTool { + + @Override + public void execute(IWorkbenchWindow window, IWorkbenchPart activePart, Collection objects) + throws DBException { + List extensionList = CommonUtils.filterCollection(objects, PostgreObject.class); + if (!extensionList.isEmpty()) { + SQLDialog dialog = new SQLDialog(activePart.getSite(), extensionList); + if (dialog.open() == IDialogConstants.OK_ID) { + refreshObjectsState(extensionList); + } + } + + } + private void refreshObjectsState(List extList) { + try { + UIUtils.runInProgressDialog(monitor -> { + for (PostgreObject ext : extList) { + try { + DBNDatabaseNode extNode = DBNUtils.getNodeByObject(ext); + if (extNode != null) { + extNode.refreshNode(monitor, PostgreToolExtensionUninstall.this); + } + } catch (DBException e) { + throw new InvocationTargetException(e); + } + } + }); + } catch (InvocationTargetException e) { + DBWorkbench.getPlatformUI().showError("Refresh extensions state", "Error refreshign extension state", e.getTargetException()); + } + } + + class SQLDialog extends TableToolDialog { + + public SQLDialog(IWorkbenchPartSite partSite, List exts) { + super(partSite, "Uninstall extension", exts); + } + + @Override + protected void generateObjectCommand(List lines, PostgreObject object) { + lines.add("DROP EXTENSION " + ((PostgreObject) object).getName() + " CASCADE"); + } + + @Override + protected void createControls(Composite parent) { + createObjectsSelector(parent); + } + } +} diff --git a/plugins/org.jkiss.dbeaver.ext.postgresql.ui/src/org/jkiss/dbeaver/ext/postgresql/ui/PostgreCreateExtensionDialog.java b/plugins/org.jkiss.dbeaver.ext.postgresql.ui/src/org/jkiss/dbeaver/ext/postgresql/ui/PostgreCreateExtensionDialog.java new file mode 100644 index 0000000000000000000000000000000000000000..cdc24c5dbb8f53723ed626c645fd84e4b1e20d0e --- /dev/null +++ b/plugins/org.jkiss.dbeaver.ext.postgresql.ui/src/org/jkiss/dbeaver/ext/postgresql/ui/PostgreCreateExtensionDialog.java @@ -0,0 +1,151 @@ +/* + * DBeaver - Universal Database Manager + * Copyright (C) 2010-2019 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.postgresql.ui; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +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.layout.GridLayout; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.jkiss.dbeaver.DBException; +import org.jkiss.dbeaver.ext.postgresql.PostgreMessages; +import org.jkiss.dbeaver.ext.postgresql.model.PostgreSchema; +import org.jkiss.dbeaver.ext.postgresql.model.PostgreAvailableExtension; +import org.jkiss.dbeaver.ext.postgresql.model.PostgreExtension; +import org.jkiss.dbeaver.model.runtime.AbstractJob; +import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; +import org.jkiss.dbeaver.ui.UIUtils; +import org.jkiss.dbeaver.ui.dialogs.BaseDialog; +import org.jkiss.dbeaver.utils.GeneralUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + * PostgreCreateExtensionDialog + */ +public class PostgreCreateExtensionDialog extends BaseDialog +{ + private PostgreAvailableExtension extension; + private final PostgreExtension newextension; + private List allSchemas; + private String name; + private PostgreSchema schema; + private List installed; + + public PostgreCreateExtensionDialog(Shell parentShell, PostgreExtension extension) { + super(parentShell, PostgreMessages.dialog_create_extension_title, null); + this.newextension = extension; + } + + private void checkEnabled() { + getButton(IDialogConstants.OK_ID).setEnabled(extension != null && schema != null); + } + + @Override + protected Composite createDialogArea(Composite parent) { + final Composite composite = super.createDialogArea(parent); + + final Composite group = new Composite(composite, SWT.NONE); + group.setLayout(new GridLayout(2, false)); + group.setLayoutData(new GridData(GridData.FILL_BOTH)); + + final Text databaseText = UIUtils.createLabelText(group, "Database", newextension.getDatabase().getName(), SWT.BORDER | SWT.READ_ONLY); //$NON-NLS-2$ + + final Combo extensionCombo = UIUtils.createLabelCombo(group, PostgreMessages.dialog_create_extension_name, SWT.BORDER | SWT.DROP_DOWN | SWT.READ_ONLY); + final Combo schemaCombo = UIUtils.createLabelCombo(group, PostgreMessages.dialog_create_extension_schema, SWT.BORDER | SWT.DROP_DOWN | SWT.READ_ONLY); + + schemaCombo.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + schema = allSchemas.get(schemaCombo.getSelectionIndex()); + checkEnabled(); + } + }); + + extensionCombo.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + extension = installed.get(extensionCombo.getSelectionIndex()); + extensionCombo.setToolTipText(installed.get(extensionCombo.getSelectionIndex()).getDescription()); + checkEnabled(); + } + }); + + new AbstractJob("Load schemas") { + + @Override + protected IStatus run(DBRProgressMonitor monitor) { + try { + allSchemas = new ArrayList<>(newextension.getDatabase().getSchemas(monitor)); + UIUtils.syncExec(() -> { + for (PostgreSchema schema : allSchemas) { + schemaCombo.add(schema.getName()); + } + }); + } catch (DBException e) { + return GeneralUtils.makeExceptionStatus(e); + } + return Status.OK_STATUS; + } + }.schedule(); + + new AbstractJob("Load available extensions") { + + @Override + protected IStatus run(DBRProgressMonitor monitor) { + try { + installed = new ArrayList<>(newextension.getDatabase().getAvailableExtensions(monitor)); + UIUtils.syncExec(() -> { + for (PostgreAvailableExtension e : installed) { + extensionCombo.add(e.getName()); + } + }); + } catch (DBException e) { + return GeneralUtils.makeExceptionStatus(e); + } + return Status.OK_STATUS; + } + }.schedule(); + + return composite; + } + + @Override + protected void createButtonsForButtonBar(Composite parent) + { + super.createButtonsForButtonBar(parent); + getButton(IDialogConstants.OK_ID).setEnabled(false); + } + + public PostgreAvailableExtension getExtension() { + return extension; + } + + public PostgreSchema getSchema() { + return schema; + } + + +} diff --git a/plugins/org.jkiss.dbeaver.ext.postgresql/OSGI-INF/l10n/bundle.properties b/plugins/org.jkiss.dbeaver.ext.postgresql/OSGI-INF/l10n/bundle.properties index 87de67455ed32e72e9b6e3077e92c4194d7f74c1..d9852fcf559487538bf64623d0f71a2acee47301 100644 --- a/plugins/org.jkiss.dbeaver.ext.postgresql/OSGI-INF/l10n/bundle.properties +++ b/plugins/org.jkiss.dbeaver.ext.postgresql/OSGI-INF/l10n/bundle.properties @@ -178,11 +178,25 @@ meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreDatabase.name.description= meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreDatabase.template.name=Template meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreDatabase.template.description= meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreExtension.name.name=Name -meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreExtension.name.description= +meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreExtension.name.description=Extension name meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreExtension.schema.name=Schema -meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreExtension.schema.description= +meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreExtension.schema.description=Installed schema meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreExtension.version.name=Version -meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreExtension.version.description= +meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreExtension.version.description=Installed version +meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreExtension.relocatable.name=Relocatable +meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreExtension.relocatable.description=Can be relocated +meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreExtension.tables.name=Tables +meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreExtension.tables.description=Using tables +meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreExtension.conditions.name=Conditions +meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreExtension.conditions.description=ExtensionConditions +meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreAvailableExtension.name.name=Name +meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreAvailableExtension.name.description=Extension name +meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreAvailableExtension.version.name=Version +meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreAvailableExtension.version.description=Extension version +meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreAvailableExtension.installedVersion.name=Installed +meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreAvailableExtension.installedVersion.description=Installed version +meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreAvailableExtension.description.name=Description +meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreAvailableExtension.description.description=Comment meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreAggregate.name.name=Name meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreAggregate.name.description=Aggregate function name meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreAggregate.inputTypes.name=Inputs @@ -576,8 +590,10 @@ tree.database.node.name=Database tree.databases.node.name=Databases tree.encoding.node.name=Encoding tree.encodings.node.name=Encodings -tree.extension.node.name=Extension -tree.extensions.node.name=Extensions +tree.extension.node.name=Installed Extension +tree.extensions.node.name=Installed Extensions +tree.avalextension.node.name=Available Extension +tree.avalextensions.node.name=Available Extensions tree.foreignDataWrapper.node.name=Foreign data wrapper tree.foreignDataWrappers.node.name=Foreign data wrappers tree.foreignServer.node.name=Foreign server diff --git a/plugins/org.jkiss.dbeaver.ext.postgresql/OSGI-INF/l10n/bundle_ru.properties b/plugins/org.jkiss.dbeaver.ext.postgresql/OSGI-INF/l10n/bundle_ru.properties index 95c77bf7db87ec73fca47e929a968d3e1f576cb2..c451aa17a80b78ed20863362bbce8792d90bb833 100644 --- a/plugins/org.jkiss.dbeaver.ext.postgresql/OSGI-INF/l10n/bundle_ru.properties +++ b/plugins/org.jkiss.dbeaver.ext.postgresql/OSGI-INF/l10n/bundle_ru.properties @@ -174,6 +174,20 @@ meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreExtension.schema.name=\u0421\ meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreExtension.schema.description= meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreExtension.version.name=\u0412\u0435\u0440\u0441\u0438\u044F meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreExtension.version.description= +meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreExtension.relocatable.name=\u041F\u0435\u0440\u0435\u043C\u0435\u0449\u0430\u0435\u043C\u043E\u0435 +meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreExtension.relocatable.description=\u041C\u043E\u0436\u043D\u043E \u043F\u0435\u0440\u0435\u043C\u0435\u0441\u0442\u0438\u0442\u044C \u0432 \u0434\u0440\u0443\u0433\u0443\u044E \u0441\u0445\u0435\u043C\u0443 +meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreExtension.tables.name=\u0422\u0430\u0431\u043B\u0438\u0446\u044B +meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreExtension.tables.description=\u0442\u0430\u0431\u043B\u0438\u0446\u044B \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F +meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreExtension.conditions.name=\u0423\u0441\u043B\u043E\u0432\u0438\u044F +meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreExtension.conditions.description=\u0444\u0438\u043B\u044C\u0442\u0440\u0430 WHERE \u0434\u043B\u044F \u0442\u0430\u0431\u043B\u0438\u0446 \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F +meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreAvailableExtension.name.name=\u0418\u043C\u044F +meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreAvailableExtension.name.description=\u0418\u043C\u044F \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F +meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreAvailableExtension.version.name=\u0412\u0435\u0440\u0441\u0438\u044F +meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreAvailableExtension.version.description=\u0412\u0435\u0440\u0441\u0438\u044F \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F +meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreAvailableExtension.installedVersion.name=\u0423\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u043E +meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreAvailableExtension.installedVersion.description=\u0423\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u043D\u0430\u044F \u0432\u0435\u0440\u0441\u0438\u044F +meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreAvailableExtension.description.name=\u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 +meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreAvailableExtension.description.description=\u041A\u0440\u0430\u0442\u043A\u043E\u0435 \u043E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreForeignDataWrapper.handler.name=\u0424\u0443\u043D\u043A\u0446\u0438\u044F \u0443\u043A\u0430\u0437\u0430\u0442\u0435\u043B\u044F meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreForeignDataWrapper.handler.description=\u0424\u0443\u043D\u043A\u0446\u0438\u044F \u0443\u043A\u0430\u0437\u0430\u0442\u0435\u043B\u044F meta.org.jkiss.dbeaver.ext.postgresql.model.PostgreForeignDataWrapper.name.name=\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435 @@ -493,8 +507,10 @@ tree.database.node.name=\u0411\u0430\u0437\u0430 \u0434\u0430\u043D\u043D\u044B\ tree.databases.node.name=\u0411\u0430\u0437\u044B \u0434\u0430\u043D\u043D\u044B\u0445 tree.encoding.node.name=\u041A\u043E\u0434\u0438\u0440\u043E\u0432\u043A\u0430 tree.encodings.node.name=\u041A\u043E\u0434\u0438\u0440\u043E\u0432\u043A\u0438 -tree.extension.node.name=\u041C\u043E\u0434\u0443\u043B\u044C \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F -tree.extensions.node.name=\u041C\u043E\u0434\u0443\u043B\u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F +tree.extension.node.name=\u0423\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u043D\u043E\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F +tree.extensions.node.name=\u0423\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u043D\u044B\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F +tree.avalextension.node.name=\u0414\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F +tree.avalextensions.node.name=\u0414\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F tree.extensions.node.tip=\u0421\u043F\u0438\u0441\u043E\u043A \u0438\u043C\u0435\u043D \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u0439 tree.foreignDataWrapper.node.name=\u041E\u0431\u043E\u043B\u043E\u0447\u043A\u0430 \u0432\u043D\u0435\u0448\u043D\u0438\u0445 \u0434\u0430\u043D\u043D\u044B\u0445 tree.foreignDataWrappers.node.name=\u041E\u0431\u043E\u043B\u043E\u0447\u043A\u0438 \u0432\u043D\u0435\u0448\u043D\u0438\u0445 \u0434\u0430\u043D\u043D\u044B\u0445 diff --git a/plugins/org.jkiss.dbeaver.ext.postgresql/plugin.xml b/plugins/org.jkiss.dbeaver.ext.postgresql/plugin.xml index d6ee3d157cd3dd4caa9efafc87fc7637cd939831..7b1132ab3031ad1fef908d181328823d23856b0d 100644 --- a/plugins/org.jkiss.dbeaver.ext.postgresql/plugin.xml +++ b/plugins/org.jkiss.dbeaver.ext.postgresql/plugin.xml @@ -160,11 +160,6 @@ - - - - - @@ -220,6 +215,9 @@ + + + @@ -447,6 +445,7 @@ + diff --git a/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/edit/PostgreExtensionManager.java b/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/edit/PostgreExtensionManager.java new file mode 100644 index 0000000000000000000000000000000000000000..6e4093dc794dbfe9ebee36d47b23b4d628d8fc6f --- /dev/null +++ b/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/edit/PostgreExtensionManager.java @@ -0,0 +1,92 @@ +/* + * DBeaver - Universal Database Manager + * Copyright (C) 2010-2019 Serge Rider (serge@jkiss.org) + * Copyright (C) 2019 Andrew Khitrin (ahitrin@gmail.com) + * + * 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.postgresql.edit; + +import java.util.List; +import java.util.Map; + +import org.jkiss.dbeaver.DBException; +import org.jkiss.dbeaver.ext.postgresql.model.PostgreDatabase; +import org.jkiss.dbeaver.ext.postgresql.model.PostgreExtension; +import org.jkiss.dbeaver.model.DBPDataSource; +import org.jkiss.dbeaver.model.DBUtils; +import org.jkiss.dbeaver.model.edit.DBECommandContext; +import org.jkiss.dbeaver.model.edit.DBEPersistAction; +import org.jkiss.dbeaver.model.impl.DBSObjectCache; +import org.jkiss.dbeaver.model.impl.edit.SQLDatabasePersistAction; +import org.jkiss.dbeaver.model.impl.sql.edit.SQLObjectEditor; +import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; + +public class PostgreExtensionManager extends SQLObjectEditor{ + + @Override + public long getMakerOptions(DBPDataSource dataSource) { + return FEATURE_SAVE_IMMEDIATELY; + } + + @Override + public DBSObjectCache getObjectsCache(PostgreExtension object) { + return object.getDatabase().extensionCache; + } + + @Override + protected PostgreExtension createDatabaseObject(DBRProgressMonitor monitor, DBECommandContext context, + Object container, Object copyFrom, Map options) throws DBException { + return new PostgreExtension((PostgreDatabase) container); + } + + + @Override + protected void addObjectCreateActions(DBRProgressMonitor monitor, List actions, + SQLObjectEditor.ObjectCreateCommand command, + Map options) { + final PostgreExtension extension = command.getObject(); + final StringBuilder script = new StringBuilder("CREATE EXTENSION " + DBUtils.getQuotedIdentifier(extension)); + script.append(" SCHEMA ").append(extension.getSchema()); + + actions.add( + new SQLDatabasePersistAction("Create extension", script.toString()) //$NON-NLS-2$ + ); + } + + @Override + protected void addObjectDeleteActions(List actions, + SQLObjectEditor.ObjectDeleteCommand command, + Map options) { + } + + @Override + public boolean canCreateObject(Object container) { + return true; + } + + @Override + public boolean canDeleteObject(PostgreExtension object) { + return false; + } + + @Override + public boolean canEditObject(PostgreExtension object) { + return false; + } + + + + +} diff --git a/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/model/PostgreAvailableExtension.java b/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/model/PostgreAvailableExtension.java new file mode 100644 index 0000000000000000000000000000000000000000..daec0903e6d929c82cdcddc7bb583f4eaa1dcb1b --- /dev/null +++ b/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/model/PostgreAvailableExtension.java @@ -0,0 +1,101 @@ +/* + * DBeaver - Universal Database Manager + * Copyright (C) 2010-2019 Serge Rider (serge@jkiss.org) + * Copyright (C) 2019 Andrew Khitrin (ahitrin@gmail.com) + * + * 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.postgresql.model; + +import java.sql.ResultSet; +import org.jkiss.dbeaver.model.impl.jdbc.JDBCUtils; +import org.jkiss.dbeaver.model.meta.Property; +import org.jkiss.dbeaver.model.struct.DBSObject; + +public class PostgreAvailableExtension implements PostgreObject{ + + private final PostgreDatabase database; + private final String name; + private final long oid; + private final String description; + private final String version; + private final String installed_version; + private final boolean installed; + + public PostgreAvailableExtension(PostgreDatabase database,ResultSet dbResult) + + { + this.database = database; + this.oid = JDBCUtils.safeGetLong(dbResult, "oid"); + this.name = JDBCUtils.safeGetString(dbResult, "name"); + this.version = JDBCUtils.safeGetString(dbResult, "default_version"); + this.installed_version = JDBCUtils.safeGetString(dbResult, "installed_version"); + installed = installed_version != null; + this.description = JDBCUtils.safeGetString(dbResult, "comment"); + } + + @Override + public DBSObject getParentObject() { + return null; + } + + @Override + @Property(viewable = true, order = 1) + public String getName() { + return name; + } + + @Property(viewable = true, order = 2) + public String getVersion() { + return version; + } + + @Property(viewable = true, order = 3) + public String getInstalledVersion() { + return installed_version; + } + + @Override + @Property(viewable = true, order = 4) + public String getDescription() { + return description; + } + + @Override + public boolean isPersisted() { + return false; + } + + @Override + public long getObjectId() { + return oid; + } + + @Override + public PostgreDataSource getDataSource() { + return database.getDataSource(); + } + + @Override + public PostgreDatabase getDatabase() { + return database; + } + + public boolean isInstalled() { + return installed; + } + + + +} diff --git a/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/model/PostgreDatabase.java b/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/model/PostgreDatabase.java index a0b9ff5878f2ea4ce9958310605c3d7a584a0005..57b29afadac8b16041666c936217c72f700c8fb2 100644 --- a/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/model/PostgreDatabase.java +++ b/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/model/PostgreDatabase.java @@ -22,6 +22,7 @@ import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.Log; import org.jkiss.dbeaver.ext.postgresql.PostgreConstants; import org.jkiss.dbeaver.ext.postgresql.PostgreUtils; +import org.jkiss.dbeaver.ext.postgresql.model.PostgreSchema.ExtensionCache; import org.jkiss.dbeaver.model.*; import org.jkiss.dbeaver.model.exec.DBCException; import org.jkiss.dbeaver.model.exec.DBCExecutionPurpose; @@ -91,6 +92,8 @@ public class PostgreDatabase extends JDBCRemoteInstance public final ForeignServerCache foreignServerCache = new ForeignServerCache(); public final LanguageCache languageCache = new LanguageCache(); public final EncodingCache encodingCache = new EncodingCache(); + public final ExtensionCache extensionCache = new ExtensionCache(); + public final AvailableExtensionCache availableExtensionCache = new AvailableExtensionCache(); public final CollationCache collationCache = new CollationCache(); public final TablespaceCache tablespaceCache = new TablespaceCache(); public final LongKeyMap dataTypeCache = new LongKeyMap<>(); @@ -414,7 +417,20 @@ public class PostgreDatabase extends JDBCRemoteInstance checkInstanceConnection(monitor); return encodingCache.getAllObjects(monitor, this); } - + + @Association + public Collection getExtensions(DBRProgressMonitor monitor) + throws DBException { + return extensionCache.getAllObjects(monitor, this); + } + + @Association + public Collection getAvailableExtensions(DBRProgressMonitor monitor) + throws DBException { + return availableExtensionCache.getAllObjects(monitor, this); + } + + @Association public Collection getCollations(DBRProgressMonitor monitor) throws DBException { @@ -1016,6 +1032,65 @@ public class PostgreDatabase extends JDBCRemoteInstance return new PostgreTablespace(owner, dbResult); } } + + class AvailableExtensionCache extends JDBCObjectCache { + + @Override + protected JDBCStatement prepareObjectsStatement(@NotNull JDBCSession session, @NotNull PostgreDatabase owner) + throws SQLException { + final JDBCPreparedStatement dbStat = session.prepareStatement( + "SELECT name,default_version,installed_version,comment FROM pg_catalog.pg_available_extensions ORDER BY name" + ); + return dbStat; + } + + @Override + protected PostgreAvailableExtension fetchObject(@NotNull JDBCSession session, @NotNull PostgreDatabase owner, @NotNull JDBCResultSet dbResult) + throws SQLException, DBException { + return new PostgreAvailableExtension(owner, dbResult); + } + } + + class ExtensionCache extends JDBCObjectCache { + + @Override + protected JDBCStatement prepareObjectsStatement(@NotNull JDBCSession session, @NotNull PostgreDatabase owner) + throws SQLException { + final JDBCPreparedStatement dbStat = session.prepareStatement( + "SELECT \n" + + " e.oid,\n" + + " a.rolname oname,\n" + + " cfg.tbls,\n" + + " e.* \n" + + "FROM \n" + + " pg_catalog.pg_extension e \n" + + " join pg_authid a on a.oid = e.extowner\n" + + " join pg_namespace n on n.oid =e.extnamespace\n" + + " left join (\n" + + " select\n" + + " ARRAY_AGG(ns.nspname || '.' || cls.relname) tbls, oid_ext\n" + + " from\n" + + " (\n" + + " select\n" + + " unnest(e1.extconfig) oid , e1.oid oid_ext\n" + + " from\n" + + " pg_catalog.pg_extension e1 ) c \n" + + " join pg_class cls on cls.oid = c.oid \n" + + " join pg_namespace ns on ns.oid = cls.relnamespace\n" + + " group by oid_ext \n" + + " ) cfg on cfg.oid_ext = e.oid\n" + + "ORDER BY e.oid" + ); + // dbStat.setLong(1, PostgreSchema.this.getObjectId()); + return dbStat; + } + + @Override + protected PostgreExtension fetchObject(@NotNull JDBCSession session, @NotNull PostgreDatabase owner, @NotNull JDBCResultSet dbResult) + throws SQLException, DBException { + return new PostgreExtension(owner, dbResult); + } + } public static class SchemaCache extends JDBCObjectLookupCache { @NotNull diff --git a/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/model/PostgreExtension.java b/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/model/PostgreExtension.java index 7deaded2101edf91e8d943ad5f2bbbcda801a6bb..b479706851e7be0ee441eb709dffc4bbd775d50d 100644 --- a/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/model/PostgreExtension.java +++ b/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/model/PostgreExtension.java @@ -20,15 +20,16 @@ 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.DBUtils; import org.jkiss.dbeaver.model.impl.jdbc.JDBCUtils; +import org.jkiss.dbeaver.model.meta.IPropertyValueListProvider; import org.jkiss.dbeaver.model.meta.Property; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; +import org.jkiss.dbeaver.model.runtime.VoidProgressMonitor; import org.jkiss.dbeaver.model.struct.DBSObject; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.LinkedHashMap; +import java.util.Collection; import java.util.Map; /** @@ -37,17 +38,29 @@ import java.util.Map; public class PostgreExtension implements PostgreObject, PostgreScriptObject { private static final Log log = Log.getLog(PostgreExtension.class); + + private PostgreDatabase database; - private PostgreSchema schema; private long oid; private String name; + private String owner; + private String tables; + private String conditions; + private boolean relocatable; private String version; private Map tableConditions; + + public PostgreExtension(PostgreDatabase database) + { + this.database = database; + this.owner = "postgres"; + } + - public PostgreExtension(PostgreSchema schema, ResultSet dbResult) + public PostgreExtension(PostgreDatabase database, ResultSet dbResult) throws SQLException { - this.schema = schema; + this.database = database; this.loadInfo(dbResult); } @@ -57,36 +70,50 @@ public class PostgreExtension implements PostgreObject, PostgreScriptObject { this.oid = JDBCUtils.safeGetLong(dbResult, "oid"); this.name = JDBCUtils.safeGetString(dbResult, "extname"); this.version = JDBCUtils.safeGetString(dbResult, "extversion"); - try { - Long[] extTableIDs = JDBCUtils.safeGetArray(dbResult, "extconfig"); - String[] extTableConditions = JDBCUtils.safeGetArray(dbResult, "extcondition"); - if (extTableIDs != null && extTableConditions != null) { - if (extTableIDs.length != extTableConditions.length) { - log.error("extconfig.length <> extcondition.length"); - } else { - tableConditions = new LinkedHashMap<>(); - for (int i = 0; i < extTableIDs.length; i++) { - tableConditions.put(extTableIDs[i], extTableConditions[i]); - } - } - } - } catch (Exception e) { - log.error(e); - } + this.owner = JDBCUtils.safeGetString(dbResult, "oname"); + this.tables = JDBCUtils.safeGetString(dbResult, "tbls"); + this.relocatable = JDBCUtils.safeGetBoolean(dbResult, "extrelocatable"); + this.conditions = JDBCUtils.safeGetString(dbResult, "extcondition"); } @NotNull @Override - @Property(viewable = true, order = 1) + @Property(viewable = true,editable = true, order = 1) public String getName() { return name; } + + public void setName(String name) { + this.name = name; + } @NotNull - @Property(viewable = true, order = 2) - public PostgreSchema getSchema() { - return schema; + @Property(viewable = true, order = 5) + public String getTables() { + return tables; + } + + @NotNull + @Property(viewable = true, order = 6) + public String getConditions() { + return conditions; + } + + @NotNull + @Property(viewable = true,editable = true,updatable = true, order = 4, listProvider = SchemaListProvider.class) + public String getSchema() { + return owner; + } + + public void setSchema(String schema) { + this.owner = schema; + } + + @NotNull + @Property(viewable = true, order = 3) + public boolean getRelocatable() { + return relocatable; } @Override @@ -94,7 +121,7 @@ public class PostgreExtension implements PostgreObject, PostgreScriptObject { return oid; } - @Property(viewable = true, order = 4) + @Property(viewable = true, order = 2) public String getVersion() { return version; } @@ -117,13 +144,13 @@ public class PostgreExtension implements PostgreObject, PostgreScriptObject { @Override public DBSObject getParentObject() { - return schema; + return database; } @NotNull @Override public PostgreDataSource getDataSource() { - return schema.getDataSource(); + return database.getDataSource(); } @Override @@ -134,7 +161,7 @@ public class PostgreExtension implements PostgreObject, PostgreScriptObject { @NotNull @Override public PostgreDatabase getDatabase() { - return schema.getDatabase(); + return database; } @Override @@ -143,7 +170,7 @@ public class PostgreExtension implements PostgreObject, PostgreScriptObject { "-- Extension: " + getName() + "\n\n" + "-- DROP EXTENSION " + getName() + ";\n\n" + "CREATE EXTENSION " + getName() + "\n\t" + - "SCHEMA " + DBUtils.getQuotedIdentifier(getSchema()) + "\n\t" + + "SCHEMA \"" + getSchema() + "\"\n\t" + "VERSION " + version; } @@ -151,4 +178,23 @@ public class PostgreExtension implements PostgreObject, PostgreScriptObject { public void setObjectDefinitionText(String sourceText) throws DBException { } + + public static class SchemaListProvider implements IPropertyValueListProvider { + @Override + public boolean allowCustomValue() + { + return false; + } + @Override + public Object[] getPossibleValues(PostgreExtension object) + { + try { + Collection schemas = object.getDatabase().getSchemas(new VoidProgressMonitor()); + return schemas.toArray(new Object[schemas.size()]); + } catch (DBException e) { + log.error(e); + return new Object[0]; + } + } + } } diff --git a/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/model/PostgreSchema.java b/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/model/PostgreSchema.java index 86561a200218140a23e3651b611d242bec768ba6..459125ea5d9edcb1e1b2b362bb3c5156f3df1318 100644 --- a/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/model/PostgreSchema.java +++ b/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/model/PostgreSchema.java @@ -439,9 +439,30 @@ public class PostgreSchema implements DBSSchema, DBPNamedObject2, DBPSaveableObj protected JDBCStatement prepareObjectsStatement(@NotNull JDBCSession session, @NotNull PostgreSchema owner) throws SQLException { final JDBCPreparedStatement dbStat = session.prepareStatement( - "SELECT e.oid,e.* FROM pg_catalog.pg_extension e " + - "\nWHERE e.extnamespace=?" + - "\nORDER BY e.oid" + "SELECT \n" + + " e.oid,\n" + + " a.rolname oname,\n" + + " cfg.tbls,\n" + + " e.* \n" + + "FROM \n" + + " pg_catalog.pg_extension e \n" + + " join pg_authid a on a.oid = e.extowner\n" + + " join pg_namespace n on n.oid =e.extnamespace\n" + + " left join (\n" + + " select\n" + + " ARRAY_AGG(ns.nspname || '.' || cls.relname) tbls, oid_ext\n" + + " from\n" + + " (\n" + + " select\n" + + " unnest(e1.extconfig) oid , e1.oid oid_ext\n" + + " from\n" + + " pg_catalog.pg_extension e1 ) c \n" + + " join pg_class cls on cls.oid = c.oid \n" + + " join pg_namespace ns on ns.oid = cls.relnamespace\n" + + " group by oid_ext \n" + + " ) cfg on cfg.oid_ext = e.oid\n" + + "\nWHERE e.extnamespace=?\n" + + "ORDER BY e.oid" ); dbStat.setLong(1, PostgreSchema.this.getObjectId()); return dbStat; @@ -450,7 +471,8 @@ public class PostgreSchema implements DBSSchema, DBPNamedObject2, DBPSaveableObj @Override protected PostgreExtension fetchObject(@NotNull JDBCSession session, @NotNull PostgreSchema owner, @NotNull JDBCResultSet dbResult) throws SQLException, DBException { - return new PostgreExtension(owner, dbResult); + //return new PostgreExtension(owner, dbResult); + return null; } }