Add "Move objects..” functionality in tablespace node. Fixes #1286

This commit is contained in:
Murtuza Zabuawala 2016-06-15 13:21:01 +01:00 committed by Dave Page
parent 0717b40543
commit d4e5d9c4f4
4 changed files with 106 additions and 15 deletions

View File

@ -74,7 +74,8 @@ class TablespaceView(PGChildNodeView):
'dependent': [{'get': 'dependents'}], 'dependent': [{'get': 'dependents'}],
'module.js': [{}, {}, {'get': 'module_js'}], 'module.js': [{}, {}, {'get': 'module_js'}],
'vopts': [{}, {'get': 'variable_options'}], 'vopts': [{}, {'get': 'variable_options'}],
'move_objects': [{'put': 'move_objects'}] 'move_objects': [{'put': 'move_objects'}],
'move_objects_sql': [{'get': 'move_objects_sql'}],
}) })
def module_js(self): def module_js(self):
@ -744,4 +745,40 @@ class TablespaceView(PGChildNodeView):
current_app.logger.exception(e) current_app.logger.exception(e)
return internal_server_error(errormsg=str(e)) return internal_server_error(errormsg=str(e))
@check_precondition
def move_objects_sql(self, gid, sid, tsid):
"""
This function returns sql for Move Objects.. dialog
Args:
gid: Server Group ID
sid: Server ID
tsid: Tablespace ID
"""
required_args = ['old_tblspc', 'tblspc', 'obj_type']
data = dict()
for k, v in request.args.items():
try:
data[k] = json.loads(v)
except ValueError as ve:
current_app.logger.exception(ve)
data[k] = v
for arg in required_args:
if arg not in data:
return make_json_response(
data=gettext("-- Incomplete definition"),
status=200
)
sql = render_template("/".join(
[self.template_path, 'move_objects.sql']),
data=data, conn=self.conn
)
return make_json_response(
data=sql.strip('\n'),
status=200
)
TablespaceView.register_node_view(blueprint) TablespaceView.register_node_view(blueprint)

View File

@ -54,7 +54,7 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
category: 'move_tablespace', priority: 5, category: 'move_tablespace', priority: 5,
label: '{{ _('Move objects to...') }}', label: '{{ _('Move objects to...') }}',
icon: 'fa fa-exchange', data: {action: 'create'}, icon: 'fa fa-exchange', data: {action: 'create'},
enable: 'can_create_tablespace' enable: 'can_move_objects'
} }
]); ]);
}, },
@ -64,6 +64,14 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
return server.connected && server.user.is_superuser; return server.connected && server.user.is_superuser;
}, },
can_move_objects: function(node, item) {
var treeData = this.getTreeNodeHierarchy(item),
server = treeData['server'];
// Only supported PG9.4 and above version
return server.connected &&
server.user.is_superuser &&
server.version >= 90400;
},
callbacks: { callbacks: {
/* Move objects from one tablespace to another */ /* Move objects from one tablespace to another */
move_objects: function(args){ move_objects: function(args){
@ -73,7 +81,8 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
i = input.item || t.selected(), i = input.item || t.selected(),
d = i && i.length == 1 ? t.itemData(i) : undefined, d = i && i.length == 1 ? t.itemData(i) : undefined,
node = d && pgBrowser.Nodes[d._type], node = d && pgBrowser.Nodes[d._type],
url = obj.generate_url(i, 'move_objects', d, true); url = obj.generate_url(i, 'move_objects', d, true),
msql_url = obj.generate_url(i, 'move_objects_sql', d, true);
if (!d) if (!d)
return false; return false;
@ -107,6 +116,41 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
id: 'user', label: '{{ _('Object owner') }}', id: 'user', label: '{{ _('Object owner') }}',
type: 'text', disabled: false, control: 'node-list-by-name', type: 'text', disabled: false, control: 'node-list-by-name',
node: 'role', select2: {allowClear: false} node: 'role', select2: {allowClear: false}
},{
id: 'sqltab', label: '{{ _('SQL') }}', group: '{{ _('SQL') }}',
type: 'text', disabled: false, control: Backform.SqlTabControl.extend({
initialize: function() {
// Initialize parent class
Backform.SqlTabControl.prototype.initialize.apply(this, arguments);
},
onTabChange: function(obj) {
// Fetch the information only if the SQL tab is visible at the moment.
if (this.dialog && obj.shown == this.tabIndex) {
var self = this,
args = self.model.toJSON();
// Add existing tablespace
args.old_tblspc = d.label;
// Fetches modified SQL
$.ajax({
url: msql_url,
type: 'GET',
cache: false,
data: args,
dataType: "json",
contentType: "application/json"
}).done(function(res) {
self.sqlCtrl.clearHistory();
self.sqlCtrl.setValue(res.data);
self.sqlCtrl.refresh();
}).fail(function() {
self.model.trigger('pgadmin-view:msql:error');
}).always(function() {
self.model.trigger('pgadmin-view:msql:fetched');
});
}
}
})
}], }],
validate: function() { validate: function() {
return null; return null;
@ -123,7 +167,11 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
setup:function() { setup:function() {
return { return {
buttons: [{ buttons: [{
text: '{{ _('Ok') }}', key: 27, className: 'btn btn-primary fa fa-lg fa-save pg-alertify-button' text: '', key: 27, className: 'btn btn-default pull-left fa fa-lg fa-question',
attrs:{name:'dialog_help', type:'button', label: '{{ _('Users') }}',
url: '{{ url_for('help.static', filename='move_objects.html') }}'}
},{
text: '{{ _('OK') }}', key: 27, className: 'btn btn-primary fa fa-lg fa-save pg-alertify-button'
},{ },{
text: '{{ _('Cancel') }}', key: 27, className: 'btn btn-danger fa fa-lg fa-times pg-alertify-button' text: '{{ _('Cancel') }}', key: 27, className: 'btn btn-danger fa fa-lg fa-times pg-alertify-button'
}], }],
@ -132,7 +180,7 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
//disable both padding and overflow control. //disable both padding and overflow control.
padding : !1, padding : !1,
overflow: !1, overflow: !1,
model: 0, modal: false,
resizable: true, resizable: true,
maximizable: true, maximizable: true,
pinnable: false, pinnable: false,
@ -153,7 +201,7 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
var self = this, var self = this,
$container = $("<div class='move_objects'></div>"); $container = $("<div class='move_objects'></div>");
//Disbale Okay button //Disbale Okay button
this.__internal.buttons[0].element.disabled = true; this.__internal.buttons[1].element.disabled = true;
// Find current/selected node // Find current/selected node
var t = pgBrowser.tree, var t = pgBrowser.tree,
i = t.selected(), i = t.selected(),
@ -188,16 +236,22 @@ function($, _, S, pgAdmin, pgBrowser, alertify) {
this.view.model.on('change', function() { this.view.model.on('change', function() {
if (!_.isUndefined(this.get('tblspc')) && this.get('tblspc') !== '') { if (!_.isUndefined(this.get('tblspc')) && this.get('tblspc') !== '') {
this.errorModel.clear(); this.errorModel.clear();
self.__internal.buttons[0].element.disabled = false; self.__internal.buttons[1].element.disabled = false;
} else { } else {
self.__internal.buttons[0].element.disabled = true; self.__internal.buttons[1].element.disabled = true;
this.errorModel.set('tblspc', '{{ _('Please select tablespace') }}') this.errorModel.set('tblspc', '{{ _('Please select tablespace') }}')
} }
}); });
}, },
// Callback functions when click on the buttons of the Alertify dialogs // Callback functions when click on the buttons of the Alertify dialogs
callback: function(e) { callback: function(e) {
if (e.button.text === '{{ _('Ok') }}') { if (e.button.element.name == "dialog_help") {
e.cancel = true;
pgBrowser.showHelp(e.button.element.name, e.button.element.getAttribute('url'),
null, null, e.button.element.getAttribute('label'));
return;
}
if (e.button.text === '{{ _('OK') }}') {
var self = this, var self = this,
args = this.view.model.toJSON(); args = this.view.model.toJSON();
args.old_tblspc = d.label; args.old_tblspc = d.label;

View File

@ -3,19 +3,19 @@
{% if data.obj_type == 'all' or data.obj_type == 'tables' %} {% if data.obj_type == 'all' or data.obj_type == 'tables' %}
ALTER TABLE ALL IN TABLESPACE {{ conn|qtIdent(data.old_tblspc) }} ALTER TABLE ALL IN TABLESPACE {{ conn|qtIdent(data.old_tblspc) }}
{% if data.user %} OWNED BY {{ conn|qtIdent(data.user) }}{% endif %} {% if data.user %} OWNED BY {{ conn|qtIdent(data.user) }}{% endif %}
SET TABLESPACE {{ conn|qtIdent(data.tblspc) }}; SET TABLESPACE {{ conn|qtIdent(data.tblspc) }};
{% endif %} {% endif %}
{% if data.obj_type == 'all' or data.obj_type == 'indexes' %} {% if data.obj_type == 'all' or data.obj_type == 'indexes' %}
ALTER INDEX ALL IN TABLESPACE {{ conn|qtIdent(data.old_tblspc) }} ALTER INDEX ALL IN TABLESPACE {{ conn|qtIdent(data.old_tblspc) }}
{% if data.user %} OWNED BY {{ conn|qtIdent(data.user) }}{% endif %} {% if data.user %} OWNED BY {{ conn|qtIdent(data.user) }}{% endif %}
SET TABLESPACE {{ conn|qtIdent(data.tblspc) }}; SET TABLESPACE {{ conn|qtIdent(data.tblspc) }};
{% endif %} {% endif %}
{% if data.obj_type == 'all' or data.obj_type == 'materialized_views' %} {% if data.obj_type == 'all' or data.obj_type == 'materialized_views' %}
ALTER MATERIALIZED VIEW ALL IN TABLESPACE {{ conn|qtIdent(data.old_tblspc) }} ALTER MATERIALIZED VIEW ALL IN TABLESPACE {{ conn|qtIdent(data.old_tblspc) }}
{% if data.user %} OWNED BY {{ conn|qtIdent(data.user) }}{% endif %} {% if data.user %} OWNED BY {{ conn|qtIdent(data.user) }}{% endif %}
SET TABLESPACE {{ conn|qtIdent(data.tblspc) }}; SET TABLESPACE {{ conn|qtIdent(data.tblspc) }};
{% endif %} {% endif %}
{% endif %} {% endif %}

View File

@ -3,19 +3,19 @@
{% if data.obj_type == 'all' or data.obj_type == 'tables' %} {% if data.obj_type == 'all' or data.obj_type == 'tables' %}
ALTER TABLE ALL IN TABLESPACE {{ conn|qtIdent(data.old_tblspc) }} ALTER TABLE ALL IN TABLESPACE {{ conn|qtIdent(data.old_tblspc) }}
{% if data.user %} OWNED BY {{ conn|qtIdent(data.user) }}{% endif %} {% if data.user %} OWNED BY {{ conn|qtIdent(data.user) }}{% endif %}
SET TABLESPACE {{ conn|qtIdent(data.tblspc) }}; SET TABLESPACE {{ conn|qtIdent(data.tblspc) }};
{% endif %} {% endif %}
{% if data.obj_type == 'all' or data.obj_type == 'indexes' %} {% if data.obj_type == 'all' or data.obj_type == 'indexes' %}
ALTER INDEX ALL IN TABLESPACE {{ conn|qtIdent(data.old_tblspc) }} ALTER INDEX ALL IN TABLESPACE {{ conn|qtIdent(data.old_tblspc) }}
{% if data.user %} OWNED BY {{ conn|qtIdent(data.user) }}{% endif %} {% if data.user %} OWNED BY {{ conn|qtIdent(data.user) }}{% endif %}
SET TABLESPACE {{ conn|qtIdent(data.tblspc) }}; SET TABLESPACE {{ conn|qtIdent(data.tblspc) }};
{% endif %} {% endif %}
{% if data.obj_type == 'all' or data.obj_type == 'materialized_views' %} {% if data.obj_type == 'all' or data.obj_type == 'materialized_views' %}
ALTER MATERIALIZED VIEW ALL IN TABLESPACE {{ conn|qtIdent(data.old_tblspc) }} ALTER MATERIALIZED VIEW ALL IN TABLESPACE {{ conn|qtIdent(data.old_tblspc) }}
{% if data.user %} OWNED BY {{ conn|qtIdent(data.user) }}{% endif %} {% if data.user %} OWNED BY {{ conn|qtIdent(data.user) }}{% endif %}
SET TABLESPACE {{ conn|qtIdent(data.tblspc) }}; SET TABLESPACE {{ conn|qtIdent(data.tblspc) }};
{% endif %} {% endif %}
{% endif %} {% endif %}