Allow maintenance operations on Index/Primary key/Unique constraints. Fixes #1390
parent
d63b54610b
commit
e9ad27678f
|
@ -112,6 +112,11 @@ class Message(IProcessDesc):
|
||||||
|
|
||||||
if self.data['op'] == "REINDEX":
|
if self.data['op'] == "REINDEX":
|
||||||
if 'schema' in self.data and self.data['schema']:
|
if 'schema' in self.data and self.data['schema']:
|
||||||
|
if 'primary_key' in self.data or\
|
||||||
|
'unique_constraint' in self.data or\
|
||||||
|
'index' in self.data:
|
||||||
|
return _('REINDEX INDEX')
|
||||||
|
else:
|
||||||
return _('REINDEX TABLE')
|
return _('REINDEX TABLE')
|
||||||
res = _('REINDEX')
|
res = _('REINDEX')
|
||||||
|
|
||||||
|
@ -170,6 +175,15 @@ def create_maintenance_job(sid, did):
|
||||||
else:
|
else:
|
||||||
data = json.loads(request.data.decode())
|
data = json.loads(request.data.decode())
|
||||||
|
|
||||||
|
index_name = None
|
||||||
|
|
||||||
|
if 'primary_key' in data and data['primary_key']:
|
||||||
|
index_name = data['primary_key']
|
||||||
|
elif 'unique_constraint' in data and data['unique_constraint']:
|
||||||
|
index_name = data['unique_constraint']
|
||||||
|
elif 'index' in data and data['index']:
|
||||||
|
index_name = data['index']
|
||||||
|
|
||||||
# Fetch the server details like hostname, port, roles etc
|
# Fetch the server details like hostname, port, roles etc
|
||||||
server = Server.query.filter_by(
|
server = Server.query.filter_by(
|
||||||
id=sid).first()
|
id=sid).first()
|
||||||
|
@ -189,14 +203,15 @@ def create_maintenance_job(sid, did):
|
||||||
if not connected:
|
if not connected:
|
||||||
return make_json_response(
|
return make_json_response(
|
||||||
success=0,
|
success=0,
|
||||||
errormsg=_("Please connect to the server first...")
|
errormsg=_("Please connect to the server first.")
|
||||||
)
|
)
|
||||||
|
|
||||||
utility = manager.utility('sql')
|
utility = manager.utility('sql')
|
||||||
|
|
||||||
# Create the command for the vacuum operation
|
# Create the command for the vacuum operation
|
||||||
query = render_template(
|
query = render_template(
|
||||||
'maintenance/sql/command.sql', conn=conn, data=data
|
'maintenance/sql/command.sql', conn=conn, data=data,
|
||||||
|
index_name=index_name
|
||||||
)
|
)
|
||||||
|
|
||||||
args = [
|
args = [
|
||||||
|
@ -224,5 +239,5 @@ def create_maintenance_job(sid, did):
|
||||||
|
|
||||||
# Return response
|
# Return response
|
||||||
return make_json_response(
|
return make_json_response(
|
||||||
data={'job_id': jid, 'status': True, 'info': 'Maintenance job created'}
|
data={'job_id': jid, 'status': True, 'info': 'Maintenance job created.'}
|
||||||
)
|
)
|
||||||
|
|
|
@ -38,6 +38,15 @@ define(
|
||||||
vacuum_analyze: false,
|
vacuum_analyze: false,
|
||||||
verbose: true
|
verbose: true
|
||||||
},
|
},
|
||||||
|
initialize: function() {
|
||||||
|
var node_info = arguments[1]['node_info'];
|
||||||
|
// If node is Unique or Primary key then set op to reindex
|
||||||
|
if ('primary_key' in node_info || 'unique_constraint' in node_info
|
||||||
|
|| 'index' in node_info) {
|
||||||
|
this.set('op', 'REINDEX');
|
||||||
|
this.set('verbose', false);
|
||||||
|
}
|
||||||
|
},
|
||||||
schema: [
|
schema: [
|
||||||
{
|
{
|
||||||
id: 'op', label:'{{ _('Maintenance operation') }}', cell: 'string',
|
id: 'op', label:'{{ _('Maintenance operation') }}', cell: 'string',
|
||||||
|
@ -88,7 +97,8 @@ define(
|
||||||
|
|
||||||
// Enable/Disable the items based on the user maintenance operation selection
|
// Enable/Disable the items based on the user maintenance operation selection
|
||||||
isDisabled: function(m) {
|
isDisabled: function(m) {
|
||||||
name = this.name;
|
var name = this.name,
|
||||||
|
node_info = this.node_info;
|
||||||
switch(name) {
|
switch(name) {
|
||||||
case 'vacuum_full':
|
case 'vacuum_full':
|
||||||
case 'vacuum_freeze':
|
case 'vacuum_freeze':
|
||||||
|
@ -101,6 +111,13 @@ define(
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'verbose':
|
case 'verbose':
|
||||||
|
if ('primary_key' in node_info || 'unique_constraint' in node_info ||
|
||||||
|
'index' in node_info ) {
|
||||||
|
if (m.get('op') == 'REINDEX') {
|
||||||
|
setTimeout(function() { m.set('verbose', false); }, 10);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (m.get('op') == 'REINDEX') {
|
if (m.get('op') == 'REINDEX') {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -125,7 +142,8 @@ define(
|
||||||
this.initialized = true;
|
this.initialized = true;
|
||||||
|
|
||||||
var maintenance_supported_nodes = [
|
var maintenance_supported_nodes = [
|
||||||
'database', 'table'
|
'database', 'table', 'primary_key',
|
||||||
|
'unique_constraint', 'index'
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -203,7 +221,7 @@ define(
|
||||||
},{
|
},{
|
||||||
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"
|
||||||
}],
|
}],
|
||||||
options: { modal: 0}
|
options: { modal: 0, pinnable: false}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
// Callback functions when click on the buttons of the Alertify dialogs
|
// Callback functions when click on the buttons of the Alertify dialogs
|
||||||
|
@ -221,9 +239,11 @@ define(
|
||||||
|
|
||||||
if (e.button.text === "{{ _('OK') }}") {
|
if (e.button.text === "{{ _('OK') }}") {
|
||||||
|
|
||||||
var schema = '';
|
var schema = undefined,
|
||||||
var table = '';
|
table = undefined,
|
||||||
|
primary_key = undefined,
|
||||||
|
unique_constraint = undefined,
|
||||||
|
index = undefined;
|
||||||
|
|
||||||
if (!d)
|
if (!d)
|
||||||
return;
|
return;
|
||||||
|
@ -237,9 +257,20 @@ define(
|
||||||
table = treeInfo.table.label;
|
table = treeInfo.table.label;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (treeInfo.primary_key != undefined) {
|
||||||
|
primary_key = treeInfo.primary_key.label;
|
||||||
|
} else if (treeInfo.unique_constraint != undefined) {
|
||||||
|
unique_constraint = treeInfo.unique_constraint.label;
|
||||||
|
} else if (treeInfo.index != undefined) {
|
||||||
|
index = treeInfo.index.label;
|
||||||
|
}
|
||||||
|
|
||||||
this.view.model.set({'database': treeInfo.database.label,
|
this.view.model.set({'database': treeInfo.database.label,
|
||||||
'schema': schema,
|
'schema': schema,
|
||||||
'table': table})
|
'table': table,
|
||||||
|
'primary_key': primary_key,
|
||||||
|
'unique_constraint': unique_constraint,
|
||||||
|
'index': index})
|
||||||
|
|
||||||
baseUrl = "{{ url_for('maintenance.index') }}" +
|
baseUrl = "{{ url_for('maintenance.index') }}" +
|
||||||
"create_job/" + treeInfo.server._id + "/" + treeInfo.database._id,
|
"create_job/" + treeInfo.server._id + "/" + treeInfo.database._id,
|
||||||
|
@ -256,12 +287,12 @@ define(
|
||||||
pgBrowser.Events.trigger('pgadmin-bgprocess:created', self);
|
pgBrowser.Events.trigger('pgadmin-bgprocess:created', self);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Alertify.error(res.data.info);
|
Alertify.error(res.data.errmsg);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error: function(e) {
|
error: function(e) {
|
||||||
Alertify.alert(
|
Alertify.alert(
|
||||||
"{{ _('Maintenance job creation failed') }}"
|
"{{ _('Maintenance job creation failed.') }}"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -303,9 +334,19 @@ define(
|
||||||
});
|
});
|
||||||
|
|
||||||
$(this.elements.body.childNodes[0]).addClass('alertify_tools_dialog_properties obj_properties');
|
$(this.elements.body.childNodes[0]).addClass('alertify_tools_dialog_properties obj_properties');
|
||||||
|
|
||||||
view.render();
|
view.render();
|
||||||
|
|
||||||
|
// If node is Index, Unique or Primary key then disable vacuum & analyze button
|
||||||
|
if (d._type == 'primary_key' || d._type == 'unique_constraint'
|
||||||
|
|| d._type == 'index') {
|
||||||
|
var vacuum_analyze_btns = $container.find(
|
||||||
|
'.pgadmin-controls label:lt(2)'
|
||||||
|
).removeClass('active').addClass('disabled');
|
||||||
|
// Find reindex button element & add active class to it
|
||||||
|
var reindex_btn = vacuum_analyze_btns[1].nextElementSibling;
|
||||||
|
$(reindex_btn).addClass('active');
|
||||||
|
}
|
||||||
|
|
||||||
this.elements.content.appendChild($container.get(0));
|
this.elements.content.appendChild($container.get(0));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,8 +5,13 @@ VACUUM{% if data.vacuum_full %} FULL{% endif %}{% if data.vacuum_freeze %} FREEZ
|
||||||
ANALYZE{% if data.verbose %} VERBOSE{% endif %}{% if data.schema %} {{ conn|qtIdent(data.schema, data.table) }}{% endif %};
|
ANALYZE{% if data.verbose %} VERBOSE{% endif %}{% if data.schema %} {{ conn|qtIdent(data.schema, data.table) }}{% endif %};
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if data.op == "REINDEX" %}
|
{% if data.op == "REINDEX" %}
|
||||||
|
{% if index_name %}
|
||||||
|
REINDEX INDEX {{ conn|qtIdent(data.schema, index_name) }};
|
||||||
|
{% else %}
|
||||||
REINDEX{% if not data.schema %} DATABASE {{ conn|qtIdent(data.database) }}{% else %} TABLE {{ conn|qtIdent(data.schema, data.table) }}{% endif %};
|
REINDEX{% if not data.schema %} DATABASE {{ conn|qtIdent(data.database) }}{% else %} TABLE {{ conn|qtIdent(data.schema, data.table) }}{% endif %};
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if data.op == "CLUSTER" %}
|
{% endif %}
|
||||||
CLUSTER{% if data.verbose %} VERBOSE {% endif %}{% if data.schema %} {{ conn|qtIdent(data.schema, data.table) }}{% endif %}
|
{% if data.op == "CLUSTER" %}
|
||||||
|
CLUSTER{% if data.verbose %} VERBOSE {% endif %}{% if data.schema %} {{ conn|qtIdent(data.schema, data.table) }}{% endif %}{% if index_name %}
|
||||||
|
USING {{ conn|qtIdent(index_name) }}{% endif %};
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
Loading…
Reference in New Issue