Make CurrentTimestamp transactional for SQLite backend
It must return the same timestamp during the all transaction. issue8457 review271641002
This commit is contained in:
1 parent
7dbcc96b8e
commit
190657e0ef
3 files changed
+73
-1
No files matched your search
@@ -6,6 +6,7 @@ import os
|
||||
import threading
|
||||
import time
|
||||
from decimal import Decimal
|
||||
from weakref import WeakKeyDictionary
|
||||
|
||||
_FIX_ROWCOUNT = False
|
||||
try:
|
||||
@@ -25,6 +26,7 @@ from sql.functions import (Function, Extract, Position, Substring,
|
||||
|
||||
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 replace(text, pattern, replacement):
|
||||
|
||||
|
||||
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):
|
||||
|
||||
@@ -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)
|
||||
@@ -219,6 +219,7 @@ class Transaction(object):
|
||||
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:
|
||||
|
||||
Reference in new issue
Block a user