Quote empty string when formatting list value of domain

This is needed to keep the empty string in the list on a second parsing.

Closes #13558
(grafted from 747825bc93a35fef995094be5ca9d7e04c414692)

--HG--
branch : 6.0
This commit is contained in:
Cédric Krier
2024-10-02 17:06:58 +02:00
parent 075c60bc62
commit ed15911ab3
4 changed files with 19 additions and 8 deletions
+8 -4
View File
@@ -1904,10 +1904,13 @@
.replace(escape + '%', '%')
.replace(escape + '_', '_');
},
quote: function(value) {
quote: function(value, empty=false) {
if (typeof value != 'string') {
return value;
}
if (empty && value === '') {
return '""';
}
if (value.contains('\\')) {
value = value.replace(new RegExp('\\\\', 'g'), '\\\\');
}
@@ -2069,7 +2072,8 @@
return value;
}
},
format_value: function(field, value, target, context) {
format_value: function(
field, value, target, context, _quote_empty=false) {
if (target === undefined) {
target = null;
}
@@ -2190,7 +2194,7 @@
converts.timestamp = converts.datetime;
if (value instanceof Array) {
return value.map(function(v) {
return this.format_value(field, v);
return this.format_value(field, v, null, context, true);
}.bind(this)).join(';');
} else {
var func = converts[field.type];
@@ -2199,7 +2203,7 @@
} else if (value === null) {
return '';
} else {
return this.quote(value);
return this.quote(value, _quote_empty);
}
}
},
+1
View File
@@ -2192,6 +2192,7 @@
[[['name', 'ilike', 'Doe\\%']], 'Name: =Doe%'],
[[['name', 'not ilike', '%Doe%']], 'Name: !Doe'],
[[['name', 'in', ['John', 'Jane']]], 'Name: John;Jane'],
[[['name', 'in', ['John', '']]], 'Name: John;""'],
[[['name', 'in', ['John']]], 'Name: =John'],
[[['name', 'not in', ['John', 'Jane']]], 'Name: !John;Jane'],
[[['name', 'not in', ['John']]], 'Name: !=John'],
+8 -4
View File
@@ -126,10 +126,12 @@ def unescape(value, escape='\\'):
return value.replace(escape + '%', '%').replace(escape + '_', '_')
def quote(value):
def quote(value, empty=False):
"Quote string if needed"
if not isinstance(value, str):
return value
if empty and value == '':
return '""'
if '\\' in value:
value = value.replace('\\', '\\\\')
if '"' in value:
@@ -305,7 +307,7 @@ def convert_value(field, value, context=None):
return converts.get(field['type'], lambda: value)()
def format_value(field, value, target=None, context=None):
def format_value(field, value, target=None, context=None, _quote_empty=False):
"Format value for field"
if context is None:
context = {}
@@ -408,9 +410,11 @@ def format_value(field, value, target=None, context=None):
'many2one': format_many2one,
}
if isinstance(value, (list, tuple)):
return ';'.join(format_value(field, x, context=context) for x in value)
return ';'.join(
format_value(field, x, context=context, _quote_empty=True)
for x in value)
return quote(converts.get(field['type'],
lambda: value if value is not None else '')())
lambda: value if value is not None else '')(), empty=_quote_empty)
def complete_value(field, value):
@@ -681,6 +681,8 @@ class DomainParserTestCase(TestCase):
dom.string([('name', 'not ilike', '%Doe%')]), 'Name: !Doe')
self.assertEqual(
dom.string([('name', 'in', ['John', 'Jane'])]), 'Name: John;Jane')
self.assertEqual(
dom.string([('name', 'in', ['John', ''])]), 'Name: John;""')
self.assertEqual(
dom.string([('name', 'in', ['John'])]), 'Name: =John')
self.assertEqual(