Add support for DATE_TRUNC from INTERVAL to SQLite backend

This commit is contained in:
Cédric Krier
2024-12-15 20:55:42 +01:00
parent 90ffa4ad8a
commit d85f0b4456
3 changed files with 45 additions and 0 deletions
+1
View File
@@ -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
+26
View File
@@ -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"