diff --git a/docs/en_US/backup_dialog.rst b/docs/en_US/backup_dialog.rst index 78329c639..bb5aec9d6 100644 --- a/docs/en_US/backup_dialog.rst +++ b/docs/en_US/backup_dialog.rst @@ -178,6 +178,9 @@ the type of statements that should be included in the backup. position to add an IF EXISTS clause to drop databases and other objects. This option is not valid unless *Include DROP DATABASE statement* is also set. +.. image:: images/backup_table.png + :alt: Backup dialog tables section + :align: center Click the *Table Options* tab to continue. Use the fields in the *Table Options* tab related to tables that should be included in the backup. @@ -213,7 +216,7 @@ tab to provide other backup options. * Move switches in the **Disable** field box to specify the type of statements that should be excluded from the backup. - * Move the switch next to *Trigger* (active when creating a data-only backup) + * Move the switch next to *Triggers* (active when creating a data-only backup) towards right position to include commands that will disable triggers on the target table while the data is being loaded. @@ -238,6 +241,9 @@ tab to provide other backup options. position to include a statement that will use a SET SESSION AUTHORIZATION command to determine object ownership (instead of an ALTER OWNER command). + * Use the *Exclude schema* field to not dump schemas whose name matches + pattern. + * Use the *Extra float digits* field to use the specified value when dumping floating-point data, instead of the maximum available precision. diff --git a/docs/en_US/backup_server_dialog.rst b/docs/en_US/backup_server_dialog.rst index f6d8d18c0..b9685c659 100644 --- a/docs/en_US/backup_server_dialog.rst +++ b/docs/en_US/backup_server_dialog.rst @@ -119,6 +119,9 @@ the type of statements that should be included in the backup. position to add an IF EXISTS clause to drop databases and other objects. This option is not valid unless *Include DROP DATABASE statement* is also set. +.. image:: images/backup_server_table.png + :alt: Backup dialog tables section + :align: center Click the *Table Options* tab to continue. Use the fields in the *Table Options* tab related to tables that should be included in the backup. @@ -146,7 +149,7 @@ tab to provide other backup options. * Move switches in the **Disable** field box to specify the type of statements that should be excluded from the backup. - * Move the switch next to *Trigger* (active when creating a data-only backup) + * Move the switch next to *Triggers* (active when creating a data-only backup) towards right position to include commands that will disable triggers on the target table while the data is being loaded. @@ -171,6 +174,9 @@ tab to provide other backup options. position to include a statement that will use a SET SESSION AUTHORIZATION command to determine object ownership (instead of an ALTER OWNER command). + * Use the *Exclude database* field to not dump databases whose name matches + pattern. + * Use the *Extra float digits* field to use the specified value when dumping floating-point data, instead of the maximum available precision. @@ -178,9 +184,6 @@ tab to provide other backup options. table locks at the beginning of the dump. Instead, fail if unable to lock a table within the specified timeout. - * Use the *Exclude database* field to not dump databases whose name matches - pattern. - When you’ve specified the details that will be incorporated into the pg_dumpall command: diff --git a/docs/en_US/images/backup_disable.png b/docs/en_US/images/backup_disable.png index f1f8cd442..920f5995d 100644 Binary files a/docs/en_US/images/backup_disable.png and b/docs/en_US/images/backup_disable.png differ diff --git a/docs/en_US/images/backup_do_not_save.png b/docs/en_US/images/backup_do_not_save.png index 08a8f9e07..2ecf35a58 100644 Binary files a/docs/en_US/images/backup_do_not_save.png and b/docs/en_US/images/backup_do_not_save.png differ diff --git a/docs/en_US/images/backup_general.png b/docs/en_US/images/backup_general.png index 0dec65738..9c47a3e9e 100644 Binary files a/docs/en_US/images/backup_general.png and b/docs/en_US/images/backup_general.png differ diff --git a/docs/en_US/images/backup_miscellaneous.png b/docs/en_US/images/backup_miscellaneous.png index ffb74e1b2..2655cacff 100644 Binary files a/docs/en_US/images/backup_miscellaneous.png and b/docs/en_US/images/backup_miscellaneous.png differ diff --git a/docs/en_US/images/backup_objects.png b/docs/en_US/images/backup_objects.png index 9448ca3ed..e99463dd1 100644 Binary files a/docs/en_US/images/backup_objects.png and b/docs/en_US/images/backup_objects.png differ diff --git a/docs/en_US/images/backup_queries.png b/docs/en_US/images/backup_queries.png index 2100459ff..320ae6579 100644 Binary files a/docs/en_US/images/backup_queries.png and b/docs/en_US/images/backup_queries.png differ diff --git a/docs/en_US/images/backup_sections.png b/docs/en_US/images/backup_sections.png index eef0a2460..83f387cd1 100644 Binary files a/docs/en_US/images/backup_sections.png and b/docs/en_US/images/backup_sections.png differ diff --git a/docs/en_US/images/backup_server_disable.png b/docs/en_US/images/backup_server_disable.png index 5918aa41d..76b12cecb 100644 Binary files a/docs/en_US/images/backup_server_disable.png and b/docs/en_US/images/backup_server_disable.png differ diff --git a/docs/en_US/images/backup_server_do_not_save.png b/docs/en_US/images/backup_server_do_not_save.png index 327d9854f..3e90c34b8 100644 Binary files a/docs/en_US/images/backup_server_do_not_save.png and b/docs/en_US/images/backup_server_do_not_save.png differ diff --git a/docs/en_US/images/backup_server_general.png b/docs/en_US/images/backup_server_general.png index 2c73e8aeb..63296d9a1 100644 Binary files a/docs/en_US/images/backup_server_general.png and b/docs/en_US/images/backup_server_general.png differ diff --git a/docs/en_US/images/backup_server_miscellaneous.png b/docs/en_US/images/backup_server_miscellaneous.png index ec2fcfd78..74e882ae3 100644 Binary files a/docs/en_US/images/backup_server_miscellaneous.png and b/docs/en_US/images/backup_server_miscellaneous.png differ diff --git a/docs/en_US/images/backup_server_objects.png b/docs/en_US/images/backup_server_objects.png index d8ab389d3..a9c27cc2f 100644 Binary files a/docs/en_US/images/backup_server_objects.png and b/docs/en_US/images/backup_server_objects.png differ diff --git a/docs/en_US/images/backup_server_queries.png b/docs/en_US/images/backup_server_queries.png index cbe08aba7..53ac1dcc0 100644 Binary files a/docs/en_US/images/backup_server_queries.png and b/docs/en_US/images/backup_server_queries.png differ diff --git a/docs/en_US/images/backup_server_table.png b/docs/en_US/images/backup_server_table.png new file mode 100644 index 000000000..e5387075a Binary files /dev/null and b/docs/en_US/images/backup_server_table.png differ diff --git a/docs/en_US/images/backup_table.png b/docs/en_US/images/backup_table.png new file mode 100644 index 000000000..60033dab9 Binary files /dev/null and b/docs/en_US/images/backup_table.png differ diff --git a/docs/en_US/images/restore_do_not_save.png b/docs/en_US/images/restore_do_not_save.png index 546732b5e..0033d7eea 100644 Binary files a/docs/en_US/images/restore_do_not_save.png and b/docs/en_US/images/restore_do_not_save.png differ diff --git a/docs/en_US/images/restore_general.png b/docs/en_US/images/restore_general.png index fdc934453..59b144063 100644 Binary files a/docs/en_US/images/restore_general.png and b/docs/en_US/images/restore_general.png differ diff --git a/docs/en_US/images/restore_miscellaneous.png b/docs/en_US/images/restore_miscellaneous.png index e90d78143..1057e4468 100644 Binary files a/docs/en_US/images/restore_miscellaneous.png and b/docs/en_US/images/restore_miscellaneous.png differ diff --git a/docs/en_US/images/restore_objects.png b/docs/en_US/images/restore_objects.png index d59c16022..d3914fa98 100644 Binary files a/docs/en_US/images/restore_objects.png and b/docs/en_US/images/restore_objects.png differ diff --git a/docs/en_US/images/restore_queries.png b/docs/en_US/images/restore_queries.png index 2667b8876..dada11732 100644 Binary files a/docs/en_US/images/restore_queries.png and b/docs/en_US/images/restore_queries.png differ diff --git a/docs/en_US/images/restore_sections.png b/docs/en_US/images/restore_sections.png index 7716474e8..671b6d952 100644 Binary files a/docs/en_US/images/restore_sections.png and b/docs/en_US/images/restore_sections.png differ diff --git a/docs/en_US/images/restore_table.png b/docs/en_US/images/restore_table.png new file mode 100644 index 000000000..dc0b69f88 Binary files /dev/null and b/docs/en_US/images/restore_table.png differ diff --git a/docs/en_US/release_notes_7_5.rst b/docs/en_US/release_notes_7_5.rst index a51dd9eba..c27faf68e 100644 --- a/docs/en_US/release_notes_7_5.rst +++ b/docs/en_US/release_notes_7_5.rst @@ -24,6 +24,7 @@ New features | `Issue #6374 `_ - Added all supported index storage parameters while creating an index. | `Issue #6416 `_ - Added new/missing parameters to pg_dumpall (Backup Server). | `Issue #6417 `_ - Added new/missing parameters to pg_dump (Backup Objects). + | `Issue #6562 `_ - Added new/missing parameters to pg_restore. Housekeeping ************ @@ -51,3 +52,5 @@ Bug fixes | `Issue #6531 `_ - Fixed an issue where pgAdmin failed to setup role with hyphens in name. | `Issue #6537 `_ - Fixed an issue where filters are not working and query history shows empty queries. | `Issue #6544 `_ - Fix an issue where adding a sub-folder inside a folder is not working as expected in File Manager. + | `Issue #6556 `_ - Fix an error 'list' object has no attribute 'strip' while attempting to populate auto-complete manually the first time. + | `Issue #6558 `_ - Fixed an issue where ERD Tool can't load the saved pgerd file from Shared Storage. diff --git a/docs/en_US/restore_dialog.rst b/docs/en_US/restore_dialog.rst index 89003776b..9641e7ff2 100644 --- a/docs/en_US/restore_dialog.rst +++ b/docs/en_US/restore_dialog.rst @@ -38,21 +38,22 @@ restore process: * Use the drop-down listbox next to *Rolename* to specify the role that will be used to authenticate with the server during the restore process. -Click the *Data/Objects* tab to continue. Use the fields on the *Data/Objects* -tab to specify options related to data or pgAdmin objects that correspond to -*pg_restore* options. +Click the *Data Options* tab to continue. Use the fields in the *Data Options* +tab to provide options related to data or pgAdmin objects that correspond to *pg_restore*. .. image:: images/restore_sections.png :alt: Restore dialog options section :align: center -* Use the switches in the **Sections** box to specify the content that will be +* Move switches in the **Sections** field box to specify the content that will be restored: * Move the switch next to *Pre-data* towards right position to restore all data definition items not included in the data or post-data item lists. + * Move the switch next to *Data* towards right position to restore actual table data, large-object contents, and sequence values. + * Move the switch next to *Post-data* towards right position position to restore definitions of indexes, triggers, rules, and constraints (other than validated check constraints). @@ -61,11 +62,12 @@ tab to specify options related to data or pgAdmin objects that correspond to :alt: Restore dialog sections section :align: center -* Use the switches in the **Type of objects** box to specify the objects that +* Move switches in the **Type of objects** field box to specify the objects that will be restored: * Move the switch next to *Only data* towards right position to limit the restoration to data. + * Move the switch next to *Only schema* to limit the restoration to schema-level database objects. @@ -73,62 +75,94 @@ tab to specify options related to data or pgAdmin objects that correspond to :alt: Restore dialog do not save section :align: center -* Use the switches in the **Do not save** box to specify which objects will not +* Move switches in the **Do not save** box to specify which objects will not be restored: * Move the switch next to *Owner* towards right position to exclude commands that set object ownership. - * Move the switch next to *Privilege* towards right position to exclude + + * Move the switch next to *Privileges* towards right position to exclude commands that create access privileges. - * Move the switch next to *Tablespace* towards right position to exclude + + * Move the switch next to *Tablespaces* towards right position to exclude tablespaces. + * Move the switch next to *Comments* towards right position to exclude commands that set the comments. **Note:** This option is visible only for database server greater than or equal to 11. -Click the *Options* tab to continue. Use these additional fields to specify -options like cleaning before restore, verbose message or using set session -authorization that correspond to *pg_restore* options. + * Move the switch next to *Publications* towards right position to exclude + publications. + + * Move the switch next to *Subscriptions* towards right position to exclude + subscriptions. + + * Move the switch next to *Security labels* towards right position to exclude + Security labels. + + * Move the switch next to *Table access methods* towards right position to exclude + Table access methods. **Note:** This option is visible only for + database server greater than or equal to 15. .. image:: images/restore_queries.png :alt: Restore dialog queries section :align: center -* Use the switches in the **Queries** box to specify the type of statements that - should be included in the restore: +Click the *Query Options* tab to continue. Use these additional fields to specify +the type of statements that should be included in the restore: + * Move the switch next to *Include CREATE DATABASE statement* towards right position to include a command that creates a new database before performing the restore. + * Move the switch next to *Clean before restore* towards right position to drop each existing database object (and data) before restoring. + + * Move the switch next to *Include IF EXISTS clause* towards right + position to add an IF EXISTS clause to drop databases and other objects. + This option is not valid unless *Clean before restore* is also set. + * Move the switch next to *Single transaction* towards right position to execute the restore as a single transaction (that is, wrap the emitted commands in *BEGIN/COMMIT*). This ensures that either all the commands complete successfully, or no changes are applied. This option implies *--exit-on-error*. -.. image:: images/restore_disable.png - :alt: Restore dialog disable section +.. image:: images/restore_table.png + :alt: Restore dialog tables section :align: center -* Use the switches in the **Disable** box to specify the type of statements that - should be excluded from the restore: +Click the *Table Options* tab to continue. Use the fields in the *Table Options* +tab related to tables that should be included in the backup. - * Move the switch next to *Trigger* (active when creating a data-only - restore) towards right position to include commands that will disable - triggers on the target table while the data is being loaded. - * Move the switch next to *No data for Failed Tables* towards right position + * Move the switch next to *Enable row security* towards right position to + set row_security to on instead, allowing the user to dump the parts of the + contents of the table that they have access to. This option is relevant + only when dumping the contents of a table which has row security. + + * Move the switch next to *No data for failed tables* towards right position to ignore data that fails a trigger. +Click the *Options* tab to continue. Use the fields in the *Options* +tab to provide other restore options. + .. image:: images/restore_miscellaneous.png :alt: Restore dialog miscellaneous section :align: center -* Use the switches in the **Miscellaneous/Behavior** box to specify +* Move switches in the **Disable** box to specify the type of statements that + should be excluded from the restore: + + * Move the switch next to *Triggers* (active when creating a data-only + restore) towards right position to include commands that will disable + triggers on the target table while the data is being loaded. + +* Move switches in the **Miscellaneous/Behavior** box to specify miscellaneous restore options: * Move the switch next to *Verbose messages* towards left to instruct *pg_restore* to exclude verbose messages. + * Move the switch next to *Use SET SESSION AUTHORIZATION* towards right position to include a statement that will use a SET SESSION AUTHORIZATION command to determine object ownership (instead of an ALTER OWNER command). @@ -138,6 +172,9 @@ authorization that correspond to *pg_restore* options. The default is to continue and to display a count of errors at the end of the restore. + * Use the *Exclude schema* field to not dump schemas whose name matches + pattern. + When you’ve specified the details that will be incorporated into the pg_restore command, click the *Restore* button to start the process, or click the *Cancel* button to exit without saving your work. A popup will confirm if the restore is @@ -145,4 +182,4 @@ successful. pgAdmin will run the restore process in background. You can view all the background process with there running status and logs on the :ref:`Processes ` -tab \ No newline at end of file +tab diff --git a/web/pgadmin/tools/backup/__init__.py b/web/pgadmin/tools/backup/__init__.py index adc0c177d..3cf0bb274 100644 --- a/web/pgadmin/tools/backup/__init__.py +++ b/web/pgadmin/tools/backup/__init__.py @@ -331,6 +331,7 @@ def _get_args_params_values(data, conn, backup_obj_type, backup_file, server, set_param('verbose', '--verbose') set_param('dqoute', '--quote-all-identifiers') set_param('use_set_session_auth', '--use-set-session-authorization') + set_value('exclude_schema', '--exclude-schema') set_value('extra_float_digits', '--extra-float-digits', None, manager.version >= 120000) set_value('lock_wait_timeout', '--lock-wait-timeout') diff --git a/web/pgadmin/tools/backup/static/js/backup.ui.js b/web/pgadmin/tools/backup/static/js/backup.ui.js index 6251ed9fb..458d6b5ca 100644 --- a/web/pgadmin/tools/backup/static/js/backup.ui.js +++ b/web/pgadmin/tools/backup/static/js/backup.ui.js @@ -379,6 +379,21 @@ export class MiscellaneousSchema extends BaseUISchema { disabled: false, group: gettext('Miscellaneous'), inlineNext: true, + }, { + id: 'exclude_schema', + label: gettext('Exclude schema'), + type: 'text', + disabled: false, + group: gettext('Miscellaneous'), + visible: isVisibleForServerBackup(obj?._top?.backupType) + }, { + id: 'exclude_database', + label: gettext('Exclude database'), + type: 'text', + disabled: false, + min_version: 160000, + group: gettext('Miscellaneous'), + visible: isVisibleForObjectBackup(obj?._top?.backupType) }, { id: 'extra_float_digits', label: gettext('Extra float digits'), @@ -392,14 +407,6 @@ export class MiscellaneousSchema extends BaseUISchema { type: 'int', disabled: false, group: gettext('Miscellaneous') - }, { - id: 'exclude_database', - label: gettext('Exclude database'), - type: 'text', - disabled: false, - min_version: 160000, - group: gettext('Miscellaneous'), - visible: isVisibleForObjectBackup(obj.backupType) }]; } } @@ -569,7 +576,7 @@ export default class BackupSchema extends BaseUISchema { state.on_conflict_do_nothing = false; return true; }, - inlineNext: true, + inlineNext: obj.backupType == 'server'? false : true, }, { id: 'include_create_database', label: gettext('Include CREATE DATABASE statement'), @@ -691,6 +698,15 @@ export default class BackupSchema extends BaseUISchema { label: gettext('Miscellaneous'), group: gettext('Options'), schema: obj.getMiscellaneousSchema(), + }, { + id: 'objects', + label: gettext('objects'), + group: gettext('Objects'), + type: 'tree', + visible: () => { + return isVisibleForServerBackup(obj?.backupType); + }, + tree_type: 'checkbox' }]; } diff --git a/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py b/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py index 5ea3f8de0..bfb2e8da1 100644 --- a/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py +++ b/web/pgadmin/tools/backup/tests/test_backup_create_job_unit_test.py @@ -538,6 +538,31 @@ class BackupCreateJobTest(BaseTestGenerator): not_expected_cmd_opts=[], expected_exit_code=[0, None] )), + ('When backup the object with option - Exclude schema', + dict( + class_params=dict( + sid=1, + name='test_backup_server', + port=5444, + host='localhost', + database='postgres', + bfile='test_backup', + username='postgres' + ), + params=dict( + file='test_backup_file', + format='custom', + verbose=True, + schemas=[], + tables=[], + database='postgres', + exclude_schema="sch*" + ), + url=BACKUP_OBJECT_URL, + expected_cmd_opts=[VERBOSE, '--exclude-schema', 'sch*'], + not_expected_cmd_opts=[], + expected_exit_code=[0, None] + )), ('When backup the object with option - Extra float digits', dict( class_params=dict( diff --git a/web/pgadmin/tools/restore/__init__.py b/web/pgadmin/tools/restore/__init__.py index bf15fcf4b..d8839f68e 100644 --- a/web/pgadmin/tools/restore/__init__.py +++ b/web/pgadmin/tools/restore/__init__.py @@ -10,21 +10,17 @@ """Implements Restore Utility""" import json -import os -from flask import render_template, request, current_app, \ - url_for, Response +from flask import render_template, request, current_app, Response from flask_babel import gettext as _ from flask_security import login_required, current_user from pgadmin.misc.bgprocess.processes import BatchProcess, IProcessDesc -from pgadmin.utils import PgAdminModule, get_storage_directory, html, \ - fs_short_path, document_dir, does_utility_exist, get_server, \ - filename_with_file_manager_path +from pgadmin.utils import PgAdminModule, fs_short_path, does_utility_exist, \ + get_server, filename_with_file_manager_path from pgadmin.utils.ajax import make_json_response, bad_request, \ internal_server_error from config import PG_DEFAULT_DRIVER -from pgadmin.model import Server, SharedServer from pgadmin.utils.constants import MIMETYPE_APP_JS # set template path for sql scripts @@ -294,33 +290,50 @@ def _set_args_param_values(data, manager, server, driver, conn, _file): if data['format'] == 'directory': args.extend(['--format=d']) + set_value('no_of_jobs', '--jobs', data, args) + # Sections set_param('pre_data', '--section=pre-data', data, args) set_param('data', '--section=data', data, args) set_param('post_data', '--section=post-data', data, args) + # Do not Save if not set_param('only_data', '--data-only', data, args): set_param('dns_owner', '--no-owner', data, args) set_param('dns_privilege', '--no-privileges', data, args) set_param('dns_tablespace', '--no-tablespaces', data, args) + if manager.version >= 110000: + set_param('dns_comments', '--no-comments', data, args) + set_param('dns_publications', '--no-publications', data, args) + set_param('dns_subscriptions', '--no-subscriptions', data, + args) + set_param('dns_security_labels', '--no-security-labels', data, + args) + if manager.version >= 150000: + set_param('dns_table_access_method', + '--no-table-access-method', data, args) + # Query Options + set_param('include_create_database', '--create', data, args) + set_param('clean', '--clean', data, args) + set_param('if_exists', '--if-exists', data, args) + set_param('single_transaction', '--single-transaction', data, args) + + # Table options + set_param('enable_row_security', '--enable-row-security', data, args) + set_param('no_data_fail_table', '--no-data-for-failed-tables', data, + args) + + # Disable options if not set_param('only_schema', '--schema-only', data, args): set_param('disable_trigger', '--disable-triggers', data, args) - set_param('include_create_database', '--create', data, args) - set_param('clean', '--clean', data, args) - set_param('single_transaction', '--single-transaction', data, args) - set_param('no_data_fail_table', '--no-data-for-failed-tables', data, - args) + # Misc Options + set_param('verbose', '--verbose', data, args) set_param('use_set_session_auth', '--use-set-session-authorization', data, args) set_param('exit_on_error', '--exit-on-error', data, args) - - if manager.version >= 110000: - set_param('no_comments', '--no-comments', data, args) - - set_value('no_of_jobs', '--jobs', data, args) - set_param('verbose', '--verbose', data, args) + set_value('exclude_schema', '--exclude-schema', data, args) set_multiple('schemas', '--schema', data, args, driver, conn, False) set_multiple('tables', '--table', data, args, driver, conn, False) diff --git a/web/pgadmin/tools/restore/static/js/restore.js b/web/pgadmin/tools/restore/static/js/restore.js index 752b0e0ba..2dd0978b5 100644 --- a/web/pgadmin/tools/restore/static/js/restore.js +++ b/web/pgadmin/tools/restore/static/js/restore.js @@ -12,7 +12,7 @@ import {getUtilityView} from '../../../../browser/static/js/utility_view'; import Notify from '../../../../static/js/helpers/Notifier'; import getApiInstance from 'sources/api_instance'; import {retrieveAncestorOfTypeServer} from 'sources/tree/tree_utils'; -import RestoreSchema, {getRestoreSaveOptSchema, getRestoreQueryOptionSchema, getRestoreDisableOptionSchema, getRestoreMiscellaneousSchema, getRestoreTypeObjSchema, getRestoreSectionSchema} from './restore.ui'; +import RestoreSchema, {getRestoreSaveOptSchema, getRestoreDisableOptionSchema, getRestoreMiscellaneousSchema, getRestoreTypeObjSchema, getRestoreSectionSchema} from './restore.ui'; define('tools.restore', [ 'sources/gettext', 'sources/url_for', 'pgadmin.browser', @@ -79,7 +79,6 @@ define('tools.restore', [ ()=>getRestoreSectionSchema({selectedNodeType: itemNodeData._type}), ()=>getRestoreTypeObjSchema({selectedNodeType: itemNodeData._type}), ()=>getRestoreSaveOptSchema({nodeInfo: treeNodeInfo}), - ()=>getRestoreQueryOptionSchema({selectedNodeType: itemNodeData._type, nodeInfo: treeNodeInfo}), ()=>getRestoreDisableOptionSchema({nodeInfo: treeNodeInfo}), ()=>getRestoreMiscellaneousSchema({nodeInfo: treeNodeInfo}), { diff --git a/web/pgadmin/tools/restore/static/js/restore.ui.js b/web/pgadmin/tools/restore/static/js/restore.ui.js index 013b79696..fd28d6c7e 100644 --- a/web/pgadmin/tools/restore/static/js/restore.ui.js +++ b/web/pgadmin/tools/restore/static/js/restore.ui.js @@ -42,6 +42,7 @@ export class RestoreSectionSchema extends BaseUISchema { label: gettext('Pre-data'), type: 'switch', group: gettext('Sections'), + inlineNext: true, deps: ['only_data', 'only_schema'], disabled: function(state) { return obj.isDisabled(state); @@ -51,6 +52,7 @@ export class RestoreSectionSchema extends BaseUISchema { label: gettext('Data'), type: 'switch', group: gettext('Sections'), + inlineNext: true, deps: ['only_data', 'only_schema'], disabled: function(state) { return obj.isDisabled(state); @@ -95,6 +97,7 @@ export class RestoreTypeObjSchema extends BaseUISchema { label: gettext('Only data'), type: 'switch', group: gettext('Type of objects'), + inlineNext: true, deps: ['pre_data', 'data', 'post_data', 'only_schema'], disabled: function(state) { if(obj.selectedNodeType == 'table') { @@ -156,26 +159,62 @@ export class RestoreSaveOptSchema extends BaseUISchema { label: gettext('Owner'), type: 'switch', disabled: false, + inlineNext: true, group: gettext('Do not save'), }, { id: 'dns_privilege', - label: gettext('Privilege'), + label: gettext('Privileges'), type: 'switch', disabled: false, + inlineNext: true, group: gettext('Do not save'), }, { id: 'dns_tablespace', - label: gettext('Tablespace'), + label: gettext('Tablespaces'), type: 'switch', disabled: false, + inlineNext: true, group: gettext('Do not save'), }, { - id: 'no_comments', + id: 'dns_comments', label: gettext('Comments'), type: 'switch', disabled: false, + inlineNext: true, group: gettext('Do not save'), min_version: 110000 + }, { + id: 'dns_publications', + label: gettext('Publications'), + type: 'switch', + disabled: false, + group: gettext('Do not save'), + inlineNext: true, + min_version: 110000 + }, { + id: 'dns_subscriptions', + label: gettext('Subscriptions'), + type: 'switch', + disabled: false, + group: gettext('Do not save'), + inlineNext: true, + min_version: 110000 + }, { + id: 'dns_security_labels', + label: gettext('Security labels'), + type: 'switch', + disabled: false, + group: gettext('Do not save'), + inlineNext: true, + min_version: 110000 + }, { + id: 'dns_table_access_method', + label: gettext('Table access methods'), + type: 'switch', + disabled: false, + group: gettext('Do not save'), + inlineNext: true, + min_version: 150000 }]; } } @@ -184,59 +223,6 @@ export function getRestoreSaveOptSchema(fieldOptions) { return new RestoreSaveOptSchema(fieldOptions); } -export class RestoreQueryOptionSchema extends BaseUISchema { - constructor(fieldOptions={}, initValues={}) { - super({ - id: null, - ...initValues, - }); - - this.fieldOptions = { - nodeInfo: null, - backupType: null, - ...fieldOptions, - }; - - this.selectedNodeType = this.fieldOptions.selectedNodeType; - } - - get idAttribute() { - return 'id'; - } - - get baseFields() { - let obj = this; - return [{ - id: 'include_create_database', - label: gettext('Include CREATE DATABASE statement'), - type: 'switch', - disabled: false, - group: gettext('Queries') - }, { - id: 'clean', - label: gettext('Clean before restore'), - type: 'switch', - group: gettext('Queries'), - disabled: function(state) { - if(obj.selectedNodeType === 'function' || obj.selectedNodeType === 'trigger_function') { - state.clean = true; - return true; - } - }, - }, { - id: 'single_transaction', - label: gettext('Single transaction'), - type: 'switch', - disabled: false, - group: gettext('Queries'), - }]; - } -} - -export function getRestoreQueryOptionSchema(fieldOptions) { - return new RestoreQueryOptionSchema(fieldOptions); -} - export class RestoreDisableOptionSchema extends BaseUISchema { constructor(fieldOptions={}, initValues={}) { super({ @@ -258,16 +244,10 @@ export class RestoreDisableOptionSchema extends BaseUISchema { get baseFields() { return [{ id: 'disable_trigger', - label: gettext('Trigger'), + label: gettext('Triggers'), type: 'switch', disable: false, group: gettext('Disable') - }, { - id: 'no_data_fail_table', - label: gettext('No data for Failed Tables'), - type: 'switch', - disabled: false, - group: gettext('Disable'), }]; } } @@ -313,6 +293,12 @@ export class RestoreMiscellaneousSchema extends BaseUISchema { type: 'switch', disabled: false, group: gettext('Miscellaneous / Behavior'), + }, { + id: 'exclude_schema', + label: gettext('Exclude schema'), + type: 'text', + disabled: false, + group: gettext('Miscellaneous / Behavior') }]; } } @@ -324,7 +310,7 @@ export function getRestoreMiscellaneousSchema(fieldOptions) { //Restore Schema export default class RestoreSchema extends BaseUISchema { - constructor(restoreSectionSchema, restoreTypeObjSchema, restoreSaveOptSchema, restoreQueryOptionSchema, restoreDisableOptionSchema, restoreMiscellaneousSchema, fieldOptions = {}, treeNodeInfo={}, pgBrowser=null) { + constructor(restoreSectionSchema, restoreTypeObjSchema, restoreSaveOptSchema, restoreDisableOptionSchema, restoreMiscellaneousSchema, fieldOptions = {}, treeNodeInfo={}, pgBrowser=null) { super({ custom: false, file: undefined, @@ -351,7 +337,6 @@ export default class RestoreSchema extends BaseUISchema { this.getSectionSchema = restoreSectionSchema; this.getRestoreTypeObjSchema = restoreTypeObjSchema; this.getRestoreSaveOptSchema = restoreSaveOptSchema; - this.getRestoreQueryOptionSchema = restoreQueryOptionSchema; this.getRestoreDisableOptionSchema = restoreDisableOptionSchema; this.getRestoreMiscellaneousSchema = restoreMiscellaneousSchema; this.treeNodeInfo = treeNodeInfo; @@ -408,27 +393,70 @@ export default class RestoreSchema extends BaseUISchema { }, { type: 'nested-fieldset', label: gettext('Sections'), - group: gettext('Data/Objects'), + group: gettext('Data Options'), schema:obj.getSectionSchema(), visible: true }, { type: 'nested-fieldset', label: gettext('Type of objects'), - group: gettext('Data/Objects'), + group: gettext('Data Options'), schema:obj.getRestoreTypeObjSchema(), visible: true }, { type: 'nested-fieldset', label: gettext('Do not save'), - group: gettext('Data/Objects'), + group: gettext('Data Options'), schema:obj.getRestoreSaveOptSchema(), visible: true }, { - type: 'nested-fieldset', - label: gettext('Queries'), - group: gettext('Options'), - schema:obj.getRestoreQueryOptionSchema(), - visible: true + id: 'include_create_database', + label: gettext('Include CREATE DATABASE statement'), + type: 'switch', + disabled: false, + group: gettext('Query Options') + }, { + id: 'clean', + label: gettext('Clean before restore'), + type: 'switch', + group: gettext('Query Options'), + inlineNext: true, + disabled: function(state) { + if(obj.selectedNodeType === 'function' || obj.selectedNodeType === 'trigger_function') { + state.clean = true; + return true; + } + }, + }, { + id: 'if_exists', + label: gettext('Include IF EXISTS clause'), + type: 'switch', + group: gettext('Query Options'), + deps: ['clean'], + disabled: function(state) { + if (state.clean) { + return false; + } + state.if_exists = false; + return true; + }, + }, { + id: 'single_transaction', + label: gettext('Single transaction'), + type: 'switch', + disabled: false, + group: gettext('Query Options'), + }, { + id: 'enable_row_security', + label: gettext('Enable row security'), + type: 'switch', + disabled: false, + group: gettext('Table Options'), + }, { + id: 'no_data_fail_table', + label: gettext('No data for failed tables'), + type: 'switch', + disabled: false, + group: gettext('Table Options'), }, { type: 'nested-fieldset', label: gettext('Disable'), diff --git a/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py b/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py index 7bb69bc5e..10f3662a8 100644 --- a/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py +++ b/web/pgadmin/tools/restore/tests/test_restore_create_job_unit_test.py @@ -18,6 +18,8 @@ from pgadmin.browser.server_groups.servers.databases.tests import utils as \ from unittest.mock import patch, MagicMock from config import PG_DEFAULT_DRIVER +RESTORE_JOB_URL = '/restore/job/{0}' + class RestoreCreateJobTest(BaseTestGenerator): """Test the RestoreCreateJob class""" @@ -43,7 +45,7 @@ class RestoreCreateJobTest(BaseTestGenerator): tables=[], database='postgres' ), - url='/restore/job/{0}', + url=RESTORE_JOB_URL, expected_cmd_opts=['--verbose'], not_expected_cmd_opts=[], expected_exit_code=[0, None] @@ -69,7 +71,7 @@ class RestoreCreateJobTest(BaseTestGenerator): tables=[], database='postgres' ), - url='/restore/job/{0}', + url=RESTORE_JOB_URL, expected_cmd_opts=['--verbose', '--format=d'], not_expected_cmd_opts=[], expected_exit_code=[0, None] @@ -100,7 +102,7 @@ class RestoreCreateJobTest(BaseTestGenerator): only_data=True, only_schema=True ), - url='/restore/job/{0}', + url=RESTORE_JOB_URL, expected_cmd_opts=['--verbose', '--jobs', '2', '--section=pre-data', '--section=data', '--section=post-data'], @@ -133,7 +135,7 @@ class RestoreCreateJobTest(BaseTestGenerator): only_schema=True, dns_owner=True ), - url='/restore/job/{0}', + url=RESTORE_JOB_URL, expected_cmd_opts=['--verbose', '--data-only'], not_expected_cmd_opts=[], # Below options should be enabled once we fix the issue #3368 @@ -164,14 +166,15 @@ class RestoreCreateJobTest(BaseTestGenerator): dns_tablespace=True, only_data=False ), - url='/restore/job/{0}', + url=RESTORE_JOB_URL, expected_cmd_opts=['--no-owner', '--no-tablespaces', '--no-privileges'], not_expected_cmd_opts=[], expected_exit_code=[0, None] )), - ('When restore object with option - Do not save comments', + ('When restore object with option - Do not save comments, ' + 'Publications, Subscriptions, Security Labels', dict( class_params=dict( sid=1, @@ -190,22 +193,27 @@ class RestoreCreateJobTest(BaseTestGenerator): schemas=[], tables=[], database='postgres', - no_comments=True, + dns_comments=True, + dns_publications=True, + dns_subscriptions=True, + dns_security_labels=True, only_data=False ), - url='/restore/job/{0}', - expected_cmd_opts=['--no-comments'], + url=RESTORE_JOB_URL, + expected_cmd_opts=['--no-comments', '--no-publications', + '--no-subscriptions', '--no-security-labels'], not_expected_cmd_opts=[], expected_exit_code=[0, None], server_min_version=110000, - message='Restore object with --no-comments is not supported ' - 'by EPAS/PG server less than 11.0' + message='Restore object with --no-comments --no-publications,' + '--no-subscriptions, --no-security-labels is not ' + 'supported by EPAS/PG server less than 11.0' )), - ('When restore object with option - Queries', + ('When restore object with option - Do not save Table Access Method ', dict( class_params=dict( sid=1, - name='test_restore_file', + name='test_restore_server', port=5444, host='localhost', database='postgres', @@ -213,7 +221,36 @@ class RestoreCreateJobTest(BaseTestGenerator): username='postgres' ), params=dict( - file='test_backup_file', + file='test_restore_file', + format='custom', + verbose=True, + custom=False, + schemas=[], + tables=[], + database='postgres', + dns_table_access_method=True + ), + url=RESTORE_JOB_URL, + expected_cmd_opts=['--no-table-access-method'], + not_expected_cmd_opts=[], + expected_exit_code=[0, None], + server_min_version=150000, + message='Restore object with --no-table-access-method is not ' + 'supported by EPAS/PG server less than 15.0' + )), + ('When restore object with option - Queries', + dict( + class_params=dict( + sid=1, + name='test_restore_server', + port=5444, + host='localhost', + database='postgres', + bfile='test_restore', + username='postgres' + ), + params=dict( + file='test_restore_file', format='custom', verbose=True, schemas=[], @@ -222,10 +259,40 @@ class RestoreCreateJobTest(BaseTestGenerator): clean=True, include_create_database=True, single_transaction=True, + if_exists=True, ), - url='/restore/job/{0}', + url=RESTORE_JOB_URL, expected_cmd_opts=['--create', '--clean', - '--single-transaction'], + '--single-transaction', '--if-exists'], + not_expected_cmd_opts=[], + expected_exit_code=[0, None] + )), + ('When restore object with Table options - enable row security and ' + 'No data for failed tables', + dict( + class_params=dict( + sid=1, + name='test_restore_server', + port=5444, + host='localhost', + database='postgres', + bfile='test_restore', + username='postgres' + ), + params=dict( + file='test_restore_file', + format='custom', + verbose=True, + schemas=[], + tables=[], + database='postgres', + enable_row_security=True, + no_data_fail_table=True, + only_schema=False + ), + url=RESTORE_JOB_URL, + expected_cmd_opts=['--enable-row-security', + '--no-data-for-failed-tables'], not_expected_cmd_opts=[], expected_exit_code=[0, None] )), @@ -233,7 +300,7 @@ class RestoreCreateJobTest(BaseTestGenerator): dict( class_params=dict( sid=1, - name='test_restore_file', + name='test_restore_server', port=5444, host='localhost', database='postgres', @@ -241,19 +308,17 @@ class RestoreCreateJobTest(BaseTestGenerator): username='postgres' ), params=dict( - file='test_backup_file', + file='test_restore_file', format='custom', verbose=True, schemas=[], tables=[], database='postgres', disable_trigger=True, - no_data_fail_table=True, only_schema=False ), - url='/restore/job/{0}', - expected_cmd_opts=['--disable-triggers', - '--no-data-for-failed-tables'], + url=RESTORE_JOB_URL, + expected_cmd_opts=['--disable-triggers'], not_expected_cmd_opts=[], expected_exit_code=[0, None] )), @@ -261,7 +326,7 @@ class RestoreCreateJobTest(BaseTestGenerator): dict( class_params=dict( sid=1, - name='test_restore_file', + name='test_restore_server', port=5444, host='localhost', database='postgres', @@ -269,7 +334,7 @@ class RestoreCreateJobTest(BaseTestGenerator): username='postgres' ), params=dict( - file='test_backup_file', + file='test_restore_file', format='custom', verbose=True, schemas=[], @@ -278,10 +343,34 @@ class RestoreCreateJobTest(BaseTestGenerator): use_set_session_auth=True, exit_on_error=True, ), - url='/restore/job/{0}', - # Add '--use_set_session_auth' into - # expected_cmd_opts once #3363 fixed - expected_cmd_opts=['--exit-on-error'], + url=RESTORE_JOB_URL, + expected_cmd_opts=['--exit-on-error', + '--use-set-session-authorization'], + not_expected_cmd_opts=[], + expected_exit_code=[0, None] + )), + ('When restore object with option - Exclude schema', + dict( + class_params=dict( + sid=1, + name='test_restore_server', + port=5444, + host='localhost', + database='postgres', + bfile='test_restore', + username='postgres' + ), + params=dict( + file='test_restore_file', + format='custom', + verbose=True, + schemas=[], + tables=[], + database='postgres', + exclude_schema="sch*" + ), + url=RESTORE_JOB_URL, + expected_cmd_opts=['--exclude-schema', 'sch*'], not_expected_cmd_opts=[], expected_exit_code=[0, None] )), @@ -305,20 +394,17 @@ class RestoreCreateJobTest(BaseTestGenerator): if os.name == 'nt': binary_path = binary_path + '.exe' - retVal = does_utility_exist(binary_path) - if retVal is not None: - self.skipTest(retVal) + ret_val = does_utility_exist(binary_path) + if ret_val is not None: + self.skipTest(ret_val) - @patch('pgadmin.tools.restore.Server') - @patch('pgadmin.tools.restore.current_user') @patch('pgadmin.tools.restore.RestoreMessage') @patch('pgadmin.tools.restore.filename_with_file_manager_path') @patch('pgadmin.tools.restore.BatchProcess') @patch('pgadmin.utils.driver.{0}.server_manager.ServerManager.' 'export_password_env'.format(PG_DEFAULT_DRIVER)) def runTest(self, export_password_env_mock, batch_process_mock, - filename_mock, restore_message_mock, - current_user_mock, server_mock): + filename_mock, restore_message_mock): class TestMockServer(): def __init__(self, name, host, port, id, username): self.name = name @@ -336,8 +422,6 @@ class RestoreCreateJobTest(BaseTestGenerator): self.server_id, self.class_params['username'] ) - mock_result = server_mock.query.filter_by.return_value - mock_result.first.return_value = mock_obj filename_mock.return_value = self.params['file'] diff --git a/web/pgadmin/tools/sqleditor/__init__.py b/web/pgadmin/tools/sqleditor/__init__.py index d882cc012..8425eee0c 100644 --- a/web/pgadmin/tools/sqleditor/__init__.py +++ b/web/pgadmin/tools/sqleditor/__init__.py @@ -1866,7 +1866,6 @@ def load_file(): # get the current storage from request if available # or get it from last_storage preference. - storage_folder = '' if 'storage' in file_data: storage_folder = file_data['storage'] else: diff --git a/web/regression/javascript/schema_ui_files/restore.ui.spec.js b/web/regression/javascript/schema_ui_files/restore.ui.spec.js index 2ac78866c..e5d3e8f9b 100644 --- a/web/regression/javascript/schema_ui_files/restore.ui.spec.js +++ b/web/regression/javascript/schema_ui_files/restore.ui.spec.js @@ -10,7 +10,7 @@ import '../helper/enzyme.helper'; import { createMount } from '@material-ui/core/test-utils'; import pgAdmin from 'sources/pgadmin'; -import RestoreSchema, {getRestoreSaveOptSchema, getRestoreQueryOptionSchema, getRestoreDisableOptionSchema, getRestoreMiscellaneousSchema, getRestoreTypeObjSchema, getRestoreSectionSchema} from '../../../pgadmin/tools/restore/static/js/restore.ui'; +import RestoreSchema, {getRestoreSaveOptSchema, getRestoreDisableOptionSchema, getRestoreMiscellaneousSchema, getRestoreTypeObjSchema, getRestoreSectionSchema} from '../../../pgadmin/tools/restore/static/js/restore.ui'; import {getCreateView} from '../genericFunctions'; describe('RestoreSchema', ()=>{ @@ -26,7 +26,6 @@ describe('RestoreSchema', ()=>{ ()=>getRestoreSectionSchema({selectedNodeType: 'table'}), ()=>getRestoreTypeObjSchema({selectedNodeType: 'table'}), ()=>getRestoreSaveOptSchema({nodeInfo: {server: {version: 11000}}}), - ()=>getRestoreQueryOptionSchema({nodeInfo: {server: {version: 11000}}}), ()=>getRestoreDisableOptionSchema({nodeInfo: {server: {version: 11000}}}), ()=>getRestoreMiscellaneousSchema({nodeInfo: {server: {version: 11000}}}), {