diff --git a/CHANGELOG b/CHANGELOG index 5a247f4b25..7bb1bf8ad3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Use CURRENT_TIMESTAMP instead of now * Use Constraint instance in ModelSQL._sql_constraints * Only return default record if no domain supplied on ModelSingleton search * Rule.domain_get returns a domain and Rule.query_get a SQL query diff --git a/trytond/backend/sqlite/database.py b/trytond/backend/sqlite/database.py index 2fcc1a3970..5fb6691b8e 100644 --- a/trytond/backend/sqlite/database.py +++ b/trytond/backend/sqlite/database.py @@ -21,8 +21,8 @@ except ImportError: from sqlite3 import IntegrityError as DatabaseIntegrityError from sqlite3 import OperationalError as DatabaseOperationalError from sql import Flavor, Table -from sql.functions import (Function, Extract, Position, Now, Substring, - Overlay, CharLength) +from sql.functions import (Function, Extract, Position, Substring, + Overlay, CharLength, CurrentTimestamp) __all__ = ['Database', 'DatabaseIntegrityError', 'DatabaseOperationalError', 'Cursor'] @@ -138,6 +138,11 @@ class SQLiteCharLength(Function): _function = 'LENGTH' +class SQLiteCurrentTimestamp(Function): + __slots__ = () + _function = 'NOW' # More precise + + def sign(value): if value > 0: return 1 @@ -153,6 +158,7 @@ MAPPING = { Substring: SQLiteSubstring, Overlay: SQLiteOverlay, CharLength: SQLiteCharLength, + CurrentTimestamp: SQLiteCurrentTimestamp, } @@ -307,7 +313,7 @@ class Database(DatabaseInterface): insert = ir_module.insert( [ir_module.create_uid, ir_module.create_date, ir_module.name, ir_module.state], - [[0, Now(), module, state]]) + [[0, CurrentTimestamp(), module, state]]) cursor.execute(*insert) cursor.execute('SELECT last_insert_rowid()') module_id, = cursor.fetchone() @@ -317,7 +323,7 @@ class Database(DatabaseInterface): ir_module_dependency.create_date, ir_module_dependency.module, ir_module_dependency.name ], - [[0, Now(), module_id, dependency]]) + [[0, CurrentTimestamp(), module_id, dependency]]) cursor.execute(*insert) diff --git a/trytond/cache.py b/trytond/cache.py index 2caf83f2ca..a23998740e 100644 --- a/trytond/cache.py +++ b/trytond/cache.py @@ -4,7 +4,7 @@ from threading import Lock from collections import OrderedDict from sql import Table -from sql.functions import Now +from sql.functions import CurrentTimestamp from trytond.transaction import Transaction @@ -108,11 +108,12 @@ class Cache(object): if cursor.fetchone(): # It would be better to insert only cursor.execute(*table.update([table.timestamp], - [Now()], where=table.name == name)) + [CurrentTimestamp()], + where=table.name == name)) else: cursor.execute(*table.insert( [table.timestamp, table.name], - [[Now(), name]])) + [[CurrentTimestamp(), name]])) Cache._resets[dbname].clear() cursor.commit() diff --git a/trytond/model/modelsql.py b/trytond/model/modelsql.py index 04f2026ab8..809dc344d0 100644 --- a/trytond/model/modelsql.py +++ b/trytond/model/modelsql.py @@ -5,7 +5,7 @@ from itertools import islice, izip, chain, ifilter from collections import OrderedDict from sql import Table, Column, Literal, Desc, Asc, Expression, Null -from sql.functions import Now, Extract +from sql.functions import CurrentTimestamp, Extract from sql.conditionals import Coalesce from sql.operators import Or, And, Operator from sql.aggregate import Count, Max @@ -352,7 +352,7 @@ class ModelSQL(ModelStorage): table.select(*columns, where=where))) else: cursor.execute(*history.insert(hcolumns, - [[id_, Now(), user] for id_ in sub_ids])) + [[id_, CurrentTimestamp(), user] for id_ in sub_ids])) @classmethod def _restore_history(cls, ids, datetime, _before=False): @@ -371,7 +371,7 @@ class ModelSQL(ModelStorage): if fname == 'write_uid': hcolumns.append(Literal(transaction.user)) elif fname == 'write_date': - hcolumns.append(Now()) + hcolumns.append(CurrentTimestamp()) else: hcolumns.append(Column(history, fname)) @@ -490,7 +490,7 @@ class ModelSQL(ModelStorage): values.update(cls._clean_defaults(defaults)) insert_columns = [table.create_uid, table.create_date] - insert_values = [transaction.user, Now()] + insert_values = [transaction.user, CurrentTimestamp()] # Insert record for fname, value in values.iteritems(): @@ -851,7 +851,7 @@ class ModelSQL(ModelStorage): del values[key] columns = [table.write_uid, table.write_date] - update_values = [transaction.user, Now()] + update_values = [transaction.user, CurrentTimestamp()] store_translation = Transaction().language == Config.get_language() for fname, value in values.iteritems(): field = cls._fields[fname] diff --git a/trytond/modules/__init__.py b/trytond/modules/__init__.py index 315a1a7689..66ddda47d2 100644 --- a/trytond/modules/__init__.py +++ b/trytond/modules/__init__.py @@ -11,7 +11,7 @@ import ConfigParser from glob import iglob from sql import Table -from sql.functions import Now +from sql.functions import CurrentTimestamp import trytond.tools as tools from trytond.config import config @@ -272,7 +272,7 @@ def load_module_graph(graph, pool, update=None, lang=None): cursor.execute(*ir_module.insert( [ir_module.create_uid, ir_module.create_date, ir_module.name, ir_module.state], - [[0, Now(), package.name, 'installed']])) + [[0, CurrentTimestamp(), package.name, 'installed']])) module2state[package.name] = 'installed' cursor.commit() diff --git a/trytond/tests/test_history.py b/trytond/tests/test_history.py index d0f6e7a53f..0131dac85a 100644 --- a/trytond/tests/test_history.py +++ b/trytond/tests/test_history.py @@ -76,8 +76,8 @@ class HistoryTestCase(unittest.TestCase): with Transaction().set_context(_datetime=datetime.datetime.min): self.assertRaises(UserError, History.read, [history_id]) - @unittest.skipIf(backend.name() in ('sqlite', 'mysql'), - 'now() is not the start of the transaction') + @unittest.skipUnless(backend.name() == 'postgresql', + 'CURRENT_TIMESTAMP as transaction_timestamp is specific to postgresql') def test0020read_same_timestamp(self): 'Test read history with same timestamp' History = POOL.get('test.history') @@ -227,8 +227,8 @@ class HistoryTestCase(unittest.TestCase): history = History(history_id) self.assertEqual(history.value, 1) - @unittest.skipIf(backend.name() in ('sqlite', 'mysql'), - 'now() is not the start of the transaction') + @unittest.skipUnless(backend.name() == 'postgresql', + 'CURRENT_TIMESTAMP as transaction_timestamp is specific to postgresql') def test0045restore_history_same_timestamp(self): 'Test restore history with same timestamp' History = POOL.get('test.history') @@ -330,8 +330,8 @@ class HistoryTestCase(unittest.TestCase): records = History.search([], order=order) self.assertEqual(records, instances) - @unittest.skipIf(backend.name() in ('sqlite', 'mysql'), - 'now() is not the start of the transaction') + @unittest.skipUnless(backend.name() == 'postgresql', + 'CURRENT_TIMESTAMP as transaction_timestamp is specific to postgresql') def test0060_ordered_search_same_timestamp(self): 'Test ordered search with same timestamp' History = POOL.get('test.history')