mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Fix handling of array types as inputs to the debugger. Fixes #3354
This commit is contained in:
parent
c79ac2f8d2
commit
bdf9f3404f
@ -9,6 +9,7 @@ for it.
|
||||
|
||||
.. toctree::
|
||||
|
||||
release_notes_3_7
|
||||
release_notes_3_6
|
||||
release_notes_3_5
|
||||
release_notes_3_4
|
||||
|
17
docs/en_US/release_notes_3_7.rst
Normal file
17
docs/en_US/release_notes_3_7.rst
Normal file
@ -0,0 +1,17 @@
|
||||
***********
|
||||
Version 3.7
|
||||
***********
|
||||
|
||||
Release date: 2019-01-10
|
||||
|
||||
This release contains a number of features and fixes reported since the release of pgAdmin4 3.6
|
||||
|
||||
|
||||
Features
|
||||
********
|
||||
|
||||
|
||||
Bug fixes
|
||||
*********
|
||||
|
||||
| `Bug #3354 <https://redmine.postgresql.org/issues/3354>`_ - Fix handling of array types as inputs to the debugger.
|
@ -799,7 +799,7 @@ define([
|
||||
|
||||
var arrayCellModel = Backbone.Model.extend({
|
||||
defaults: {
|
||||
value: undefined,
|
||||
value: null,
|
||||
},
|
||||
});
|
||||
|
||||
@ -817,11 +817,41 @@ define([
|
||||
render: function() {
|
||||
var self = this,
|
||||
arrayValuesCol = this.model.get(this.column.get('name')),
|
||||
gridCols = [{
|
||||
cell_type = 'string';
|
||||
|
||||
var data_type = this.model.get('type').replace('[]' ,'');
|
||||
switch (data_type) {
|
||||
case 'boolean':
|
||||
cell_type = 'boolean';
|
||||
break;
|
||||
case 'integer':
|
||||
case 'smallint':
|
||||
case 'bigint':
|
||||
case 'serial':
|
||||
case 'smallserial':
|
||||
case 'bigserial':
|
||||
case 'oid':
|
||||
case 'cid':
|
||||
case 'xid':
|
||||
case 'tid':
|
||||
cell_type = 'integer';
|
||||
break;
|
||||
case 'real':
|
||||
case 'numeric':
|
||||
case 'double precision':
|
||||
case 'decimal':
|
||||
cell_type = 'number';
|
||||
break;
|
||||
case 'date':
|
||||
cell_type = 'date';
|
||||
break;
|
||||
}
|
||||
|
||||
var gridCols = [{
|
||||
name: 'value',
|
||||
label: gettext('Array Values'),
|
||||
type: 'text',
|
||||
cell: 'string',
|
||||
cell: cell_type,
|
||||
headerCell: Backgrid.Extension.CustomHeaderIconCell,
|
||||
cellHeaderClasses: 'width_percent_100',
|
||||
}],
|
||||
@ -844,6 +874,22 @@ define([
|
||||
collection: arrayValuesCol,
|
||||
});
|
||||
|
||||
this.grid.listenTo(arrayValuesCol, 'backgrid:error',
|
||||
(function(obj) {
|
||||
return function(ev) {
|
||||
obj.model.trigger('backgrid:error', obj.model, obj.column, new Backgrid.Command(ev));
|
||||
};
|
||||
})(this)
|
||||
);
|
||||
|
||||
this.grid.listenTo(arrayValuesCol, 'backgrid:edited',
|
||||
(function(obj) {
|
||||
return function(ev) {
|
||||
obj.model.trigger('backgrid:edited', obj.model, obj.column, new Backgrid.Command(ev));
|
||||
};
|
||||
})(this)
|
||||
);
|
||||
|
||||
grid.render();
|
||||
|
||||
gridBody.append(grid.$el);
|
||||
@ -893,8 +939,6 @@ define([
|
||||
self.grid = null;
|
||||
}
|
||||
}, 10);
|
||||
|
||||
|
||||
}
|
||||
}, 10);
|
||||
return;
|
||||
@ -944,8 +988,8 @@ define([
|
||||
var values = [];
|
||||
rawData.each(function(m) {
|
||||
var val = m.get('value');
|
||||
if (_.isUndefined(val)) {
|
||||
values.push('null');
|
||||
if (_.isUndefined(val) || _.isNull(val)) {
|
||||
values.push('NULL');
|
||||
} else {
|
||||
values.push(m.get('value'));
|
||||
}
|
||||
@ -963,6 +1007,40 @@ define([
|
||||
},
|
||||
});
|
||||
|
||||
/*
|
||||
* This will help us transform the user input numeric array values in proper format to be
|
||||
* displayed in the cell.
|
||||
*/
|
||||
var InputNumberArrayCellFormatter= Backgrid.Extension.InputNumberArrayCellFormatter =
|
||||
function() {};
|
||||
_.extend(InputNumberArrayCellFormatter.prototype, {
|
||||
/**
|
||||
* Takes a raw value from a model and returns an optionally formatted
|
||||
* string for display.
|
||||
*/
|
||||
fromRaw: function(rawData) {
|
||||
var values = [];
|
||||
rawData.each(function(m) {
|
||||
var val = m.get('value');
|
||||
if (_.isUndefined(val) || _.isNull(val)) {
|
||||
values.push('NULL');
|
||||
} else {
|
||||
values.push(m.get('value'));
|
||||
}
|
||||
});
|
||||
return values.toString();
|
||||
},
|
||||
toRaw: function(formattedData) {
|
||||
formattedData.each(function(m) {
|
||||
m.set('value', parseFloat(m.get('value')), {
|
||||
silent: true,
|
||||
});
|
||||
});
|
||||
|
||||
return formattedData;
|
||||
},
|
||||
});
|
||||
|
||||
/*
|
||||
* InputStringArrayCell for rendering and taking input for string array type in debugger
|
||||
*/
|
||||
@ -982,7 +1060,6 @@ define([
|
||||
}
|
||||
|
||||
this.model.set(this.column.get('name'), this.collection);
|
||||
|
||||
this.listenTo(this.collection, 'remove', this.render);
|
||||
},
|
||||
});
|
||||
@ -990,13 +1067,70 @@ define([
|
||||
/*
|
||||
* InputIntegerArrayCell for rendering and taking input for integer array type in debugger
|
||||
*/
|
||||
Backgrid.Extension.InputIntegerArrayCell = Backgrid.Cell.extend({
|
||||
Backgrid.Extension.InputIntegerArrayCell = Backgrid.IntegerCell.extend({
|
||||
className: 'width_percent_25',
|
||||
formatter: InputIntegerArrayCellFormatter,
|
||||
editor: InputArrayCellEditor,
|
||||
|
||||
initialize: function() {
|
||||
Backgrid.Cell.prototype.initialize.apply(this, arguments);
|
||||
Backgrid.IntegerCell.prototype.initialize.apply(this, arguments);
|
||||
// set value to empty array.
|
||||
var m = arguments[0].model;
|
||||
_.each(m.get('value'), function(arrVal) {
|
||||
if (arrVal.value === 'NULL') {
|
||||
arrVal.value = null;
|
||||
}
|
||||
});
|
||||
|
||||
if (_.isUndefined(this.collection)) {
|
||||
this.collection = new(Backbone.Collection.extend({
|
||||
model: arrayCellModel,
|
||||
}))(m.get('value'));
|
||||
}
|
||||
|
||||
this.model.set(this.column.get('name'), this.collection);
|
||||
this.listenTo(this.collection, 'remove', this.render);
|
||||
},
|
||||
});
|
||||
|
||||
/*
|
||||
* InputNumberArrayCell for rendering and taking input for numeric array type in debugger
|
||||
*/
|
||||
Backgrid.Extension.InputNumberArrayCell = Backgrid.NumberCell.extend({
|
||||
className: 'width_percent_25',
|
||||
formatter: InputNumberArrayCellFormatter,
|
||||
editor: InputArrayCellEditor,
|
||||
|
||||
initialize: function() {
|
||||
Backgrid.NumberCell.prototype.initialize.apply(this, arguments);
|
||||
// set value to empty array.
|
||||
var m = arguments[0].model;
|
||||
_.each(m.get('value'), function(arrVal) {
|
||||
if (arrVal.value === 'NULL') {
|
||||
arrVal.value = null;
|
||||
}
|
||||
});
|
||||
|
||||
if (_.isUndefined(this.collection)) {
|
||||
this.collection = new(Backbone.Collection.extend({
|
||||
model: arrayCellModel,
|
||||
}))(m.get('value'));
|
||||
}
|
||||
|
||||
this.model.set(this.column.get('name'), this.collection);
|
||||
this.listenTo(this.collection, 'remove', this.render);
|
||||
},
|
||||
});
|
||||
|
||||
/*
|
||||
* InputBooleanArrayCell for rendering and taking input for boolean array type in debugger
|
||||
*/
|
||||
Backgrid.Extension.InputBooleanArrayCell = Backgrid.BooleanCell.extend({
|
||||
className: 'width_percent_25',
|
||||
editor: InputArrayCellEditor,
|
||||
|
||||
initialize: function() {
|
||||
Backgrid.BooleanCell.prototype.initialize.apply(this, arguments);
|
||||
// set value to empty array.
|
||||
var m = arguments[0].model;
|
||||
if (_.isUndefined(this.collection)) {
|
||||
@ -1005,9 +1139,7 @@ define([
|
||||
}))(m.get('value'));
|
||||
}
|
||||
|
||||
|
||||
this.model.set(this.column.get('name'), this.collection);
|
||||
|
||||
this.listenTo(this.collection, 'remove', this.render);
|
||||
},
|
||||
});
|
||||
@ -1479,6 +1611,22 @@ define([
|
||||
remove: Backgrid.Extension.DependentCell.prototype.remove,
|
||||
});
|
||||
|
||||
Backgrid.BooleanCellFormatter = _.extend(Backgrid.CellFormatter.prototype, {
|
||||
fromRaw: function (rawValue) {
|
||||
if (_.isUndefined(rawValue) || _.isNull(rawValue)) {
|
||||
return false;
|
||||
} else if (rawValue === '1' || rawValue === 'True') {
|
||||
return true;
|
||||
} else if (rawValue === '0' || rawValue === 'False') {
|
||||
return false;
|
||||
}
|
||||
return rawValue;
|
||||
},
|
||||
toRaw: function (formattedData) {
|
||||
return formattedData;
|
||||
},
|
||||
});
|
||||
|
||||
return Backgrid;
|
||||
|
||||
});
|
||||
|
@ -1810,7 +1810,10 @@ def set_arguments_sqlite(sid, did, scid, func_id):
|
||||
if data[i]['value'].__class__.__name__ in (
|
||||
'list') and data[i]['value']:
|
||||
for k in range(0, len(data[i]['value'])):
|
||||
array_string += data[i]['value'][k]['value']
|
||||
if data[i]['value'][k]['value'] is None:
|
||||
array_string += 'NULL'
|
||||
else:
|
||||
array_string += str(data[i]['value'][k]['value'])
|
||||
if k != (len(data[i]['value']) - 1):
|
||||
array_string += ','
|
||||
elif data[i]['value'].__class__.__name__ in (
|
||||
|
@ -17,42 +17,76 @@ define([
|
||||
|
||||
// if variable type is an array then we need to render the custom control to take the input from user.
|
||||
if (variable_type.indexOf('[]') != -1) {
|
||||
if (variable_type.indexOf('integer') != -1) {
|
||||
var data_type = variable_type.replace('[]' ,'');
|
||||
|
||||
switch (data_type) {
|
||||
case 'boolean':
|
||||
return Backgrid.Extension.InputBooleanArrayCell;
|
||||
case 'integer':
|
||||
case 'smallint':
|
||||
case 'bigint':
|
||||
case 'serial':
|
||||
case 'smallserial':
|
||||
case 'bigserial':
|
||||
case 'oid':
|
||||
case 'cid':
|
||||
case 'xid':
|
||||
case 'tid':
|
||||
return Backgrid.Extension.InputIntegerArrayCell;
|
||||
case 'real':
|
||||
case 'numeric':
|
||||
case 'double precision':
|
||||
case 'decimal':
|
||||
return Backgrid.Extension.InputNumberArrayCell;
|
||||
default:
|
||||
return Backgrid.Extension.InputStringArrayCell;
|
||||
}
|
||||
return Backgrid.Extension.InputStringArrayCell;
|
||||
}
|
||||
|
||||
switch (variable_type) {
|
||||
case 'bool':
|
||||
return Backgrid.BooleanCell;
|
||||
case 'integer':
|
||||
// As we are getting this value as text from sqlite database so we need to type cast it.
|
||||
if (model.get('value') != undefined) {
|
||||
model.set({
|
||||
'value': parseInt(model.get('value')),
|
||||
}, {
|
||||
silent: true,
|
||||
} else {
|
||||
switch (variable_type) {
|
||||
case 'boolean':
|
||||
return Backgrid.BooleanCell.extend({
|
||||
formatter: Backgrid.BooleanCellFormatter,
|
||||
});
|
||||
}
|
||||
case 'integer':
|
||||
case 'smallint':
|
||||
case 'bigint':
|
||||
case 'serial':
|
||||
case 'smallserial':
|
||||
case 'bigserial':
|
||||
case 'oid':
|
||||
case 'cid':
|
||||
case 'xid':
|
||||
case 'tid':
|
||||
// As we are getting this value as text from sqlite database so we need to type cast it.
|
||||
if (model.get('value') != undefined) {
|
||||
model.set({
|
||||
'value': parseInt(model.get('value')),
|
||||
}, {
|
||||
silent: true,
|
||||
});
|
||||
}
|
||||
|
||||
return Backgrid.IntegerCell;
|
||||
case 'real':
|
||||
// As we are getting this value as text from sqlite database so we need to type cast it.
|
||||
if (model.get('value') != undefined) {
|
||||
model.set({
|
||||
'value': parseFloat(model.get('value')),
|
||||
}, {
|
||||
silent: true,
|
||||
});
|
||||
return Backgrid.IntegerCell;
|
||||
case 'real':
|
||||
case 'numeric':
|
||||
case 'double precision':
|
||||
case 'decimal':
|
||||
// As we are getting this value as text from sqlite database so we need to type cast it.
|
||||
if (model.get('value') != undefined) {
|
||||
model.set({
|
||||
'value': parseFloat(model.get('value')),
|
||||
}, {
|
||||
silent: true,
|
||||
});
|
||||
}
|
||||
return Backgrid.NumberCell;
|
||||
case 'string':
|
||||
return Backgrid.StringCell;
|
||||
case 'date':
|
||||
return Backgrid.DateCell;
|
||||
default:
|
||||
return Backgrid.Cell;
|
||||
}
|
||||
return Backgrid.NumberCell;
|
||||
case 'string':
|
||||
return Backgrid.StringCell;
|
||||
case 'date':
|
||||
return Backgrid.DateCell;
|
||||
default:
|
||||
return Backgrid.Cell;
|
||||
}
|
||||
};
|
||||
|
||||
@ -378,13 +412,6 @@ define([
|
||||
values = [];
|
||||
if (argtype[index].indexOf('[]') != -1) {
|
||||
vals = func_args_data[i]['value'].split(',');
|
||||
if (argtype[index].indexOf('integer') != -1) {
|
||||
_.each(vals, function(val) {
|
||||
values.push({
|
||||
'value': parseInt(val),
|
||||
});
|
||||
});
|
||||
}
|
||||
_.each(vals, function(val) {
|
||||
values.push({
|
||||
'value': val,
|
||||
@ -485,13 +512,6 @@ define([
|
||||
values = [];
|
||||
if (argtype[index].indexOf('[]') != -1) {
|
||||
vals = func_args_data[i]['value'].split(',');
|
||||
if (argtype[index].indexOf('integer') != -1) {
|
||||
_.each(vals, function(val) {
|
||||
values.push({
|
||||
'value': parseInt(val),
|
||||
});
|
||||
});
|
||||
}
|
||||
_.each(vals, function(val) {
|
||||
values.push({
|
||||
'value': val,
|
||||
@ -918,6 +938,14 @@ define([
|
||||
};
|
||||
})(this)
|
||||
);
|
||||
|
||||
this.grid.listenTo(this.debuggerInputArgsColl, 'backgrid:error',
|
||||
(function(obj) {
|
||||
return function() {
|
||||
obj.__internal.buttons[0].element.disabled = true;
|
||||
};
|
||||
})(this)
|
||||
);
|
||||
},
|
||||
};
|
||||
});
|
||||
|
@ -11,7 +11,7 @@
|
||||
{% if data %}
|
||||
{% for dict_item in data %}
|
||||
{% if 'type' in dict_item and 'value' in dict_item %}
|
||||
{% if dict_item['value'] != 'NULL' %}
|
||||
{% if dict_item['value'] != 'NULL' and '[]' not in dict_item['type'] %}
|
||||
{{ dict_item['value']|qtLiteral }}::{{ dict_item['type'] }}{% if not loop.last %}, {% endif %}
|
||||
{% elif dict_item['value'] == 'NULL' %}
|
||||
{{ dict_item['value'] }}::{{ dict_item['type'] }}{% if not loop.last %}, {% endif %}
|
||||
|
Loading…
Reference in New Issue
Block a user