Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions trytond/CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
* Use JSONB to store MultiSelection field on PostgreSQL
* Use multiple jobs to dump and restore a test database
* Support database cache as template for tests

Expand Down
1 change: 1 addition & 0 deletions trytond/trytond/backend/postgresql/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ def add_comment():
if base_type != typname:
if (typname, base_type) in [
('varchar', 'text'),
('varchar', 'jsonb'),
('text', 'varchar'),
('text', 'jsonb'),
('date', 'timestamp'),
Expand Down
2 changes: 1 addition & 1 deletion trytond/trytond/model/fields/multiselection.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
class MultiSelection(SelectionMixin, Field):
"Define a multi-selection field."
_type = 'multiselection'
_sql_type = 'VARCHAR'
_sql_type = 'JSON'
_py_type = tuple

def __init__(self, selection, string='', sort=True, translate=True,
Expand Down
13 changes: 13 additions & 0 deletions trytond/trytond/tests/field_multiselection.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,21 @@ class MultiSelectionRequired(ModelSQL):
[('foo', "Foo"), ('bar', "Bar")], "Selects", required=True)


class MultiSelectionText(ModelSQL):
"MultiSelection TEXT"
__name__ = 'test.multi_selection_text'

selects = fields.MultiSelection([
('foo', "Foo"),
('bar', "Bar"),
('foobar', "FooBar"),
], "Selections")
selects._sql_type = 'TEXT'


def register(module):
Pool.register(
MultiSelection,
MultiSelectionRequired,
MultiSelectionText,
module=module, type_='model')
63 changes: 41 additions & 22 deletions trytond/trytond/tests/test_field_multiselection.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,29 +358,48 @@ def test_read_string_dynamic_selection(self):
self.assertEqual(bar_read['dyn_selects:string'], ["Bar", "Baz"])
self.assertEqual(null_read['dyn_selects:string'], [])

@with_transaction()
def test_create_text(self):
"Test creating multiselection with text"
Selection = Pool().get('test.multi_selection_text')

@unittest.skipIf(
backend.name != 'postgresql', 'jsonb only supported by postgresql')
class FieldMultiSelectionJSONBTestCase(FieldMultiSelectionTestCase):
selection, selection_none = Selection.create([{
'selects': ['foo', 'bar'],
}, {
'selects': None,
}])

@classmethod
def setUpClass(cls):
super().setUpClass()
cls.setup_model()
self.assertEqual(selection.selects, ('bar', 'foo'))
self.assertEqual(selection_none.selects, ())

@with_transaction()
def test_write_text(self):
"Test write selection with text"
Selection = Pool().get('test.multi_selection_text')
selection, = Selection.create([{
'selects': ['foo'],
}])

Selection.write([selection], {
'selects': ['foo', 'bar'],
})

self.assertEqual(selection.selects, ('bar', 'foo'))

@classmethod
@with_transaction()
def setup_model(cls):
connection = Transaction().connection
if backend.Database().get_version(connection) < (9, 2):
return
pool = Pool()
for model in ['test.multi_selection', 'test.multi_selection_required']:
Model = pool.get(model)
cursor = connection.cursor()
for name, field in Model._fields.items():
if field._type == 'multiselection':
cursor.execute('ALTER TABLE "%s" '
'ALTER COLUMN %s TYPE json USING %s::json' % (
Model._table, name, name))
Transaction().commit()
def test_search_equals_text(self):
"Test search selection equals"
Selection = Pool().get('test.multi_selection_text')
selection, = Selection.create([{
'selects': ['bar', 'foo'],
}])

foo_bar = Selection.search([
('selects', '=', ['foo', 'bar']),
])
foo = Selection.search([
('selects', '=', ['foo']),
])

self.assertEqual(foo_bar, [selection])
self.assertEqual(foo, [])