changeset 7c169c9a3b38 in trytond:default
details: https://hg.tryton.org/trytond?cmd=changeset;node=7c169c9a3b38
description:
        Make CurrentTimestamp transactional for SQLite backend

        It must return the same timestamp during the all transaction.

        issue8457
        review271641002
diffstat:

 trytond/backend/sqlite/database.py |   9 ++++-
 trytond/tests/test_backend.py      |  64 ++++++++++++++++++++++++++++++++++++++
 trytond/transaction.py             |   1 +
 3 files changed, 73 insertions(+), 1 deletions(-)

diffs (112 lines):

diff -r 634f8347fb75 -r 7c169c9a3b38 trytond/backend/sqlite/database.py
--- a/trytond/backend/sqlite/database.py        Mon Jul 08 21:24:33 2019 +0200
+++ b/trytond/backend/sqlite/database.py        Mon Jul 08 21:27:55 2019 +0200
@@ -6,6 +6,7 @@
 import threading
 import time
 from decimal import Decimal
+from weakref import WeakKeyDictionary
 
 _FIX_ROWCOUNT = False
 try:
@@ -25,6 +26,7 @@
 
 from trytond.backend.database import DatabaseInterface, SQLType
 from trytond.config import config
+from trytond.transaction import Transaction
 
 __all__ = ['Database', 'DatabaseIntegrityError', 'DatabaseOperationalError']
 logger = logging.getLogger(__name__)
@@ -130,7 +132,12 @@
 
 
 def now():
-    return datetime.datetime.now().isoformat(' ')
+    transaction = Transaction()
+    return _nows.setdefault(transaction, {}).setdefault(
+        transaction.started_at, datetime.datetime.now().isoformat(' '))
+
+
+_nows = WeakKeyDictionary()
 
 
 class SQLiteSubstring(Function):
diff -r 634f8347fb75 -r 7c169c9a3b38 trytond/tests/test_backend.py
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/trytond/tests/test_backend.py     Mon Jul 08 21:27:55 2019 +0200
@@ -0,0 +1,64 @@
+# This file is part of Tryton.  The COPYRIGHT file at the top level of
+# this repository contains the full copyright notices and license terms.
+import unittest
+
+from sql import Select
+from sql.functions import CurrentTimestamp
+
+from trytond.tests.test_tryton import activate_module, with_transaction
+from trytond.transaction import Transaction
+
+
+class BackendTestCase(unittest.TestCase):
+    "Test the backend"
+
+    @classmethod
+    def setUpClass(cls):
+        activate_module('tests')
+
+    @with_transaction()
+    def test_current_timestamp_static_transaction(self):
+        "Test CURRENT_TIMESTAMP is static during transaction"
+        query = Select([CurrentTimestamp()])
+        cursor = Transaction().connection.cursor()
+
+        cursor.execute(*query)
+        current, = cursor.fetchone()
+        cursor.execute(*query)
+        second, = cursor.fetchone()
+
+        self.assertEqual(current, second)
+
+    @with_transaction()
+    def test_current_timestamp_reset_after_commit(self):
+        "Test CURRENT_TIMESTAMP is reset after commit"
+        query = Select([CurrentTimestamp()])
+        cursor = Transaction().connection.cursor()
+
+        cursor.execute(*query)
+        current, = cursor.fetchone()
+        Transaction().commit()
+        cursor.execute(*query)
+        second, = cursor.fetchone()
+
+        self.assertNotEqual(current, second)
+
+    @with_transaction()
+    def test_current_timestamp_different_transaction(self):
+        "Test CURRENT_TIMESTAMP is different per transaction"
+        query = Select([CurrentTimestamp()])
+        cursor = Transaction().connection.cursor()
+
+        cursor.execute(*query)
+        current, = cursor.fetchone()
+
+        with Transaction().new_transaction() as transaction:
+            cursor = transaction.connection.cursor()
+            cursor.execute(*query)
+            second, = cursor.fetchone()
+
+        self.assertNotEqual(current, second)
+
+
+def suite():
+    return unittest.TestLoader().loadTestsFromTestCase(BackendTestCase)
diff -r 634f8347fb75 -r 7c169c9a3b38 trytond/transaction.py
--- a/trytond/transaction.py    Mon Jul 08 21:24:33 2019 +0200
+++ b/trytond/transaction.py    Mon Jul 08 21:27:55 2019 +0200
@@ -219,6 +219,7 @@
                     datamanager.commit(self)
                 for datamanager in self._datamanagers:
                     datamanager.tpc_vote(self)
+            self.started_at = self.monotonic_time()
             Cache.commit(self)
             self.connection.commit()
         except:

Reply via email to