changeset bfc90c50b591 in trytond:default
details: https://hg.tryton.org/trytond?cmd=changeset;node=bfc90c50b591
description:
        Always use search method on translations

        This ensure to have always the same order when selecting the record out 
of many
        duplicates (which can happen as there is no unique constraint
        since r 426276806f60).

        issue8705
        review260271002
diffstat:

 trytond/ir/translation.py      |  80 +++++++++++++++++------------------------
 trytond/tests/test_modelsql.py |  24 ++++++++++++
 2 files changed, 58 insertions(+), 46 deletions(-)

diffs (162 lines):

diff -r f1ac853b1006 -r bfc90c50b591 trytond/ir/translation.py
--- a/trytond/ir/translation.py Wed Oct 16 21:24:06 2019 +0200
+++ b/trytond/ir/translation.py Wed Oct 16 21:31:25 2019 +0200
@@ -11,7 +11,6 @@
 from sql import Column, Null, Literal
 from sql.functions import Substring, Position
 from sql.conditionals import Case
-from sql.operators import Or, And
 from sql.aggregate import Max
 
 from genshi.filters.i18n import extract as genshi_extract
@@ -24,7 +23,7 @@
 from ..model import ModelView, ModelSQL, fields
 from ..wizard import Wizard, StateView, StateTransition, StateAction, \
     Button
-from ..tools import file_open, reduce_ids, grouped_slice, cursor_dict
+from ..tools import file_open, grouped_slice, cursor_dict
 from ..pyson import PYSONEncoder, Eval
 from ..transaction import Transaction
 from ..pool import Pool
@@ -346,27 +345,20 @@
                 translations.update(
                     cls.get_ids(name, ttype, parent_lang, to_fetch))
 
-            transaction = Transaction()
-            cursor = transaction.connection.cursor()
-            table = cls.__table__()
-            fuzzy_sql = table.fuzzy == False
             if Transaction().context.get('fuzzy_translation', False):
-                fuzzy_sql = None
-            in_max = transaction.database.IN_MAX // 7
-            for sub_to_fetch in grouped_slice(to_fetch, in_max):
-                red_sql = reduce_ids(table.res_id, sub_to_fetch)
-                where = And(((table.lang == lang),
-                        (table.type == ttype),
-                        (table.name == name),
-                        (table.value != ''),
-                        (table.value != Null),
-                        red_sql,
-                        ))
-                if fuzzy_sql:
-                    where &= fuzzy_sql
-                cursor.execute(*table.select(table.res_id, table.value,
-                        where=where))
-                translations.update(cursor)
+                fuzzy_clause = []
+            else:
+                fuzzy_clause = [('fuzzy', '=', False)]
+            for sub_to_fetch in grouped_slice(to_fetch):
+                for translation in cls.search([
+                            ('lang', '=', lang),
+                            ('type', '=', ttype),
+                            ('name', '=', name),
+                            ('value', '!=', ''),
+                            ('value', '!=', None),
+                            ('res_id', 'in', list(sub_to_fetch)),
+                            ] + fuzzy_clause):
+                    translations[translation.res_id] = translation.value
             # Don't store fuzzy translation in cache
             if not Transaction().context.get('fuzzy_translation', False):
                 for res_id in to_fetch:
@@ -526,10 +518,8 @@
         res = {}
         parent_args = []
         parent_langs = []
-        clause = []
+        clauses = []
         transaction = Transaction()
-        cursor = transaction.connection.cursor()
-        table = cls.__table__()
         if len(args) > transaction.database.IN_MAX:
             for sub_args in grouped_slice(args):
                 res.update(cls.get_sources(list(sub_args)))
@@ -552,17 +542,18 @@
                     parent_args.append((name, ttype, parent_lang, source))
                     parent_langs.append(lang)
                 res[(name, ttype, lang, source)] = None
-                where = And(((table.lang == lang),
-                        (table.type == ttype),
-                        (table.name == name),
-                        (table.value != ''),
-                        (table.value != Null),
-                        (table.fuzzy == False),
-                        (table.res_id == -1),
-                        ))
+                clause = [
+                    ('lang', '=', lang),
+                    ('type', '=', ttype),
+                    ('name', '=', name),
+                    ('value', '!=', ''),
+                    ('value', '!=', None),
+                    ('fuzzy', '=', False),
+                    ('res_id', '=', -1),
+                    ]
                 if source is not None:
-                    where &= table.src == source
-                clause.append(where)
+                    clause.append(('src', '=', source))
+                clauses.append(clause)
 
         # Get parent transactions
         if parent_args:
@@ -572,17 +563,14 @@
                 res[(name, ttype, lang, source)] = parent_src[
                     (name, ttype, parent_lang, source)]
 
-        if clause:
-            in_max = transaction.database.IN_MAX // 7
-            for sub_clause in grouped_slice(clause, in_max):
-                cursor.execute(*table.select(
-                        table.lang, table.type, table.name, table.src,
-                        table.value,
-                        where=Or(list(sub_clause))))
-                for lang, ttype, name, source, value in cursor.fetchall():
-                    if (name, ttype, lang, source) not in args:
-                        source = None
-                    res[(name, ttype, lang, source)] = value
+        in_max = transaction.database.IN_MAX // 7
+        for sub_clause in grouped_slice(clauses, in_max):
+            for translation in cls.search(['OR'] + list(sub_clause)):
+                key = (translation.name, translation.type,
+                    translation.name, translation.name, translation.src)
+                if key not in args:
+                    key = key[:-1] + (None,)
+                res[key] = translation.value
         for key in to_cache:
             cls._translation_cache.set(key, res[key])
         return res
diff -r f1ac853b1006 -r bfc90c50b591 trytond/tests/test_modelsql.py
--- a/trytond/tests/test_modelsql.py    Wed Oct 16 21:24:06 2019 +0200
+++ b/trytond/tests/test_modelsql.py    Wed Oct 16 21:31:25 2019 +0200
@@ -701,6 +701,30 @@
         self.assertEqual(record.name, "Foo")
         self.assertEqual(other.name, "Bar")
 
+    @with_transaction()
+    def test_read_last_translation(self):
+        "Test read last translation record"
+        pool = Pool()
+        Model = pool.get('test.modelsql.translation')
+        Translation = pool.get('ir.translation')
+
+        with Transaction().set_context(language=self.default_language):
+            record, = Model.create([{'name': "Foo"}])
+        with Transaction().set_context(language=self.other_language):
+            Model.write([record], {'name': "Bar"})
+            other = Model(record.id)
+
+        translation, = Translation.search([
+                ('lang', '=', self.other_language),
+                ('name', '=', 'test.modelsql.translation,name'),
+                ('type', '=', 'model'),
+                ('res_id', '=', record.id),
+                ])
+        Translation.copy([translation], default={'value': "Baz"})
+
+        self.assertEqual(record.name, "Foo")
+        self.assertEqual(other.name, "Baz")
+
 
 def suite():
     suite_ = unittest.TestSuite()

Reply via email to