Add support for DATE_TRUNC from INTERVAL to SQLite backend
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
* Add support for DATE_TRUNC from INTERVAL to SQLite backend
|
||||
* Add support for EXTRACT from INTERVAL to SQLite backend
|
||||
* Add msg_gettext and msg_ngettext to Report context
|
||||
* Support plural translation of messages
|
||||
|
||||
@@ -161,6 +161,8 @@ class SQLiteExtract(Function):
|
||||
def date_trunc(field, source):
|
||||
if field is None or source is None:
|
||||
return None
|
||||
if isinstance(source, (int, float)): # interval
|
||||
return _date_trunc_interval(field, source)
|
||||
for fromisoformat in [
|
||||
dt.date.fromisoformat,
|
||||
dt.time.fromisoformat,
|
||||
@@ -199,6 +201,22 @@ def date_trunc(field, source):
|
||||
return adapt_timedelta(value)
|
||||
|
||||
|
||||
def _date_trunc_interval(field, source):
|
||||
value = dt.timedelta(seconds=source)
|
||||
field = field.lower()
|
||||
for attribute, delta in [
|
||||
('microseconds', value.microseconds),
|
||||
('seconds', value.seconds % 60),
|
||||
('minutes', (value.seconds // 60) % 60),
|
||||
('hours', (value.seconds // (60 * 60)) % 24),
|
||||
('days', value.days),
|
||||
]:
|
||||
if field.startswith(attribute[:-1]):
|
||||
break
|
||||
value -= dt.timedelta(**{attribute: delta})
|
||||
return adapt_timedelta(value)
|
||||
|
||||
|
||||
def split_part(text, delimiter, count):
|
||||
if text is None:
|
||||
return None
|
||||
|
||||
@@ -228,6 +228,32 @@ class BackendTestCase(TestCase):
|
||||
value, = cursor.fetchone()
|
||||
self.assertEqual(value, result)
|
||||
|
||||
@with_transaction()
|
||||
def test_function_date_trunc_timedelta(self):
|
||||
"Test DateTrunc function with timedelta"
|
||||
cursor = Transaction().connection.cursor()
|
||||
date = dt.timedelta(
|
||||
days=16, hours=20, minutes=38, seconds=40, microseconds=100)
|
||||
for type_, result in [
|
||||
('microsecond', dt.timedelta(
|
||||
days=16, hours=20, minutes=38, seconds=40,
|
||||
microseconds=100)),
|
||||
('second', dt.timedelta(
|
||||
days=16, hours=20, minutes=38, seconds=40)),
|
||||
('minute', dt.timedelta(days=16, hours=20, minutes=38)),
|
||||
('hour', dt.timedelta(days=16, hours=20)),
|
||||
('day', dt.timedelta(days=16)),
|
||||
('month', dt.timedelta()),
|
||||
]:
|
||||
for type_ in [type_.lower(), type_.upper()]:
|
||||
with self.subTest(type_=type_):
|
||||
query = Select([DateTrunc(type_, date).as_('value')])
|
||||
if backend.name == 'sqlite':
|
||||
sqlite_apply_types(query, ['INTERVAL'])
|
||||
cursor.execute(*query)
|
||||
value, = cursor.fetchone()
|
||||
self.assertEqual(value, result)
|
||||
|
||||
@with_transaction()
|
||||
def test_function_date_trunc_null(self):
|
||||
"test DateTrunc function with NULL"
|
||||
|
||||
Reference in New Issue
Block a user