diff --git a/plugins/org.jkiss.dbeaver.core/src/org/jkiss/dbeaver/ui/editors/entity/EntityEditor.java b/plugins/org.jkiss.dbeaver.core/src/org/jkiss/dbeaver/ui/editors/entity/EntityEditor.java index d94e25c0f073ccb64100c9ed506ca6cb8b614bf3..80416ef2454dbf8f394de8c7336fbec3fb18d80a 100644 --- a/plugins/org.jkiss.dbeaver.core/src/org/jkiss/dbeaver/ui/editors/entity/EntityEditor.java +++ b/plugins/org.jkiss.dbeaver.core/src/org/jkiss/dbeaver/ui/editors/entity/EntityEditor.java @@ -232,7 +232,9 @@ public class EntityEditor extends MultiPageDatabaseEditor // Flush all nested object editors and result containers for (IEditorPart editor : editorMap.values()) { if (editor instanceof ObjectPropertiesEditor || editor instanceof IResultSetContainer) { - editor.doSave(monitor); + if (editor.isDirty()) { + editor.doSave(monitor); + } } if (monitor.isCanceled()) { return; @@ -418,9 +420,11 @@ public class EntityEditor extends MultiPageDatabaseEditor DBeaverUI.syncExec(() -> DBUserInterface.getInstance().showError("Validation", e.getMessage())); return IDialogConstants.CANCEL_ID; } + Map options = new HashMap<>(); + options.put(DBPScriptObject.OPTION_OBJECT_SAVE, true); script.append(SQLUtils.generateScript( commandContext.getExecutionContext().getDataSource(), - command.getPersistActions(DBPScriptObject.EMPTY_OPTIONS), + command.getPersistActions(options), false)); } if (script.length() == 0) { @@ -945,7 +949,9 @@ public class EntityEditor extends MultiPageDatabaseEditor try { final DBECommandContext commandContext = getCommandContext(); if (commandContext != null && commandContext.isDirty()) { - success = saveCommandContext(monitor, DBPScriptObject.EMPTY_OPTIONS); + Map options = new HashMap<>(); + options.put(DBPScriptObject.OPTION_OBJECT_SAVE, true); + success = saveCommandContext(monitor, options); } else { success = true; } diff --git a/plugins/org.jkiss.dbeaver.core/src/org/jkiss/dbeaver/ui/editors/entity/properties/ObjectPropertiesEditor.java b/plugins/org.jkiss.dbeaver.core/src/org/jkiss/dbeaver/ui/editors/entity/properties/ObjectPropertiesEditor.java index 45f85b012d71843e159845b08604912df1928500..484960fcde4ec0f96ff284a258b91d2140d86645 100644 --- a/plugins/org.jkiss.dbeaver.core/src/org/jkiss/dbeaver/ui/editors/entity/properties/ObjectPropertiesEditor.java +++ b/plugins/org.jkiss.dbeaver.core/src/org/jkiss/dbeaver/ui/editors/entity/properties/ObjectPropertiesEditor.java @@ -293,7 +293,9 @@ public class ObjectPropertiesEditor extends AbstractDatabaseObjectEditor actions, PostgreViewBase view) { - String sql = view.getSource().trim(); - if (!sql.toLowerCase(Locale.ENGLISH).startsWith("create")) { - sql = "CREATE OR REPLACE VIEW " + DBUtils.getObjectFullName(view, DBPEvaluationContext.DDL) + " AS\n" + sql; + if (!CommonUtils.isEmpty(view.getSource())) { + // Source may be empty if it wasn't yet read. Then it definitely wasn't changed + String sql = view.getSource().trim(); + if (!sql.toLowerCase(Locale.ENGLISH).startsWith("create")) { + sql = "CREATE OR REPLACE VIEW " + DBUtils.getObjectFullName(view, DBPEvaluationContext.DDL) + " AS\n" + sql; + } + actions.add( + new SQLDatabasePersistAction("Create view", sql)); } - actions.add( - new SQLDatabasePersistAction("Create view", sql)); } } diff --git a/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/model/PostgreViewBase.java b/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/model/PostgreViewBase.java index 91737a4beca1fea088261c8e8e70494b6930a6ae..70b93342f4d808b4f63bc99ad876193d006ad9b8 100644 --- a/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/model/PostgreViewBase.java +++ b/plugins/org.jkiss.dbeaver.ext.postgresql/src/org/jkiss/dbeaver/ext/postgresql/model/PostgreViewBase.java @@ -18,18 +18,27 @@ package org.jkiss.dbeaver.ext.postgresql.model; import org.jkiss.code.NotNull; import org.jkiss.dbeaver.DBException; +import org.jkiss.dbeaver.ext.postgresql.PostgreConstants; import org.jkiss.dbeaver.ext.postgresql.PostgreUtils; +import org.jkiss.dbeaver.model.DBPEvaluationContext; import org.jkiss.dbeaver.model.DBUtils; +import org.jkiss.dbeaver.model.edit.DBEPersistAction; import org.jkiss.dbeaver.model.exec.jdbc.JDBCSession; import org.jkiss.dbeaver.model.impl.DBObjectNameCaseTransformer; +import org.jkiss.dbeaver.model.impl.edit.SQLDatabasePersistAction; import org.jkiss.dbeaver.model.impl.jdbc.JDBCUtils; import org.jkiss.dbeaver.model.meta.Property; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; +import org.jkiss.dbeaver.model.sql.SQLUtils; +import org.jkiss.dbeaver.model.struct.DBSObject; import org.jkiss.dbeaver.model.struct.rdb.DBSTableIndex; +import org.jkiss.utils.CommonUtils; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.ArrayList; import java.util.Collection; +import java.util.List; import java.util.Map; /** @@ -95,7 +104,24 @@ public abstract class PostgreViewBase extends PostgreTableReal source = ""; } } - return source; + + List actions = new ArrayList<>(); + if (CommonUtils.getOption(options, PostgreConstants.OPTION_DDL_SHOW_COLUMN_COMMENTS) && getDescription() != null) { + actions.add( + new SQLDatabasePersistAction("Comment", + "COMMENT ON VIEW " + getFullyQualifiedName(DBPEvaluationContext.DDL) + " IS " + SQLUtils.quoteString(this, getDescription()))); + } + if (CommonUtils.getOption(options, PostgreConstants.OPTION_DDL_SHOW_PERMISSIONS)) { + PostgreUtils.getObjectGrantPermissionActions(monitor, this, actions, options); + } + + StringBuilder ddl = new StringBuilder(source); + if (!actions.isEmpty()) { + ddl.append("\n\n").append(SQLUtils.generateScript( + getDataSource(), actions.toArray(new DBEPersistAction[actions.size()]), false)); + } + + return ddl.toString(); } protected String readExtraDefinition(JDBCSession session, Map options) throws DBException { @@ -110,4 +136,9 @@ public abstract class PostgreViewBase extends PostgreTableReal public abstract String getViewType(); + @Override + public DBSObject refreshObject(DBRProgressMonitor monitor) throws DBException { + this.source = null; + return super.refreshObject(monitor); + } } diff --git a/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/DBPScriptObject.java b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/DBPScriptObject.java index 8161752de2fdd0a8be2424204fa758fa314914ab..672148373eeea0035e64d5d31a5c4c5f26a8c7ad 100644 --- a/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/DBPScriptObject.java +++ b/plugins/org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/DBPScriptObject.java @@ -46,6 +46,9 @@ public interface DBPScriptObject extends DBPObject { // nested objects (columns, constraints, etc) which can be embedded in parent object declaration (tables) String OPTION_EMBEDDED_SOURCE = "embedded.source"; + // Means that result script will be used for object save + String OPTION_OBJECT_SAVE = "object.save"; + Map EMPTY_OPTIONS = Collections.unmodifiableMap(new HashMap<>()); String getObjectDefinitionText(DBRProgressMonitor monitor, Map options)