PR#4115: fix tz mismatch issues with various queries
Merges #4115 https://pagure.io/koji/pull-request/4115 Fixes: #4114 https://pagure.io/koji/issue/4114 Hub encodes timestamps for db without tz
This commit is contained in:
commit
690ed8cf01
3 changed files with 23 additions and 17 deletions
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import datetime
|
||||
import logging
|
||||
import koji
|
||||
import os
|
||||
|
|
@ -39,6 +40,7 @@ import time
|
|||
import traceback
|
||||
|
||||
import psycopg2
|
||||
from dateutil.tz import tzutc
|
||||
|
||||
import koji.context
|
||||
context = koji.context.context
|
||||
|
|
@ -299,6 +301,11 @@ def _singleRow(query, values, fields, strict=False):
|
|||
return None
|
||||
|
||||
|
||||
def convert_timestamp(ts):
|
||||
"""Convert a numeric timestamp to a string suitable for a datetimetz field"""
|
||||
return datetime.datetime.fromtimestamp(ts, tzutc()).isoformat(' ')
|
||||
|
||||
|
||||
def get_event():
|
||||
"""Get an event id for this transaction
|
||||
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ from .db import ( # noqa: F401
|
|||
get_event,
|
||||
nextval,
|
||||
currval,
|
||||
convert_timestamp,
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -7085,10 +7086,8 @@ class CG_Importer(object):
|
|||
buildinfo['build_id'] = metadata['build']['build_id']
|
||||
# epoch is not in the metadata spec, but we allow it to be specified
|
||||
buildinfo['epoch'] = metadata['build'].get('epoch', None)
|
||||
buildinfo['start_time'] = \
|
||||
datetime.datetime.fromtimestamp(float(metadata['build']['start_time'])).isoformat(' ')
|
||||
buildinfo['completion_time'] = \
|
||||
datetime.datetime.fromtimestamp(float(metadata['build']['end_time'])).isoformat(' ')
|
||||
buildinfo['start_time'] = convert_timestamp(float(metadata['build']['start_time']))
|
||||
buildinfo['completion_time'] = convert_timestamp(float(metadata['build']['end_time']))
|
||||
owner = metadata['build'].get('owner', None)
|
||||
# get task id from OSBS or from standard place
|
||||
buildinfo['task_id'] = self.get_task_id_from_metadata(metadata)
|
||||
|
|
@ -8775,7 +8774,7 @@ def query_history(tables=None, **kwargs):
|
|||
fields['revoker.id = %(editor)i'] = '_revoked_by'
|
||||
elif arg == 'after':
|
||||
if not isinstance(value, str):
|
||||
value = datetime.datetime.fromtimestamp(value).isoformat(' ')
|
||||
value = convert_timestamp(value)
|
||||
data['after'] = value
|
||||
clauses.append('ev1.time > %(after)s OR ev2.time > %(after)s')
|
||||
fields['ev1.time > %(after)s'] = '_created_after'
|
||||
|
|
@ -8791,7 +8790,7 @@ def query_history(tables=None, **kwargs):
|
|||
fields[r_test] = '_revoked_after_event'
|
||||
elif arg == 'before':
|
||||
if not isinstance(value, str):
|
||||
value = datetime.datetime.fromtimestamp(value).isoformat(' ')
|
||||
value = convert_timestamp(value)
|
||||
data['before'] = value
|
||||
clauses.append('ev1.time < %(before)s OR ev2.time < %(before)s')
|
||||
# clauses.append("date_part('epoch', ev1.time) < %(before)s OR "
|
||||
|
|
@ -12581,19 +12580,19 @@ class RootExports(object):
|
|||
clauses.append('build.state = %(state)i')
|
||||
if createdBefore:
|
||||
if not isinstance(createdBefore, str):
|
||||
createdBefore = datetime.datetime.fromtimestamp(createdBefore).isoformat(' ')
|
||||
createdBefore = convert_timestamp(createdBefore)
|
||||
clauses.append('events.time < %(createdBefore)s')
|
||||
if createdAfter:
|
||||
if not isinstance(createdAfter, str):
|
||||
createdAfter = datetime.datetime.fromtimestamp(createdAfter).isoformat(' ')
|
||||
createdAfter = convert_timestamp(createdAfter)
|
||||
clauses.append('events.time > %(createdAfter)s')
|
||||
if completeBefore:
|
||||
if not isinstance(completeBefore, str):
|
||||
completeBefore = datetime.datetime.fromtimestamp(completeBefore).isoformat(' ')
|
||||
completeBefore = convert_timestamp(completeBefore)
|
||||
clauses.append('build.completion_time < %(completeBefore)s')
|
||||
if completeAfter:
|
||||
if not isinstance(completeAfter, str):
|
||||
completeAfter = datetime.datetime.fromtimestamp(completeAfter).isoformat(' ')
|
||||
completeAfter = convert_timestamp(completeAfter)
|
||||
clauses.append('build.completion_time > %(completeAfter)s')
|
||||
if cgID:
|
||||
cgID = lookup_name('content_generator', cgID, strict=False)
|
||||
|
|
@ -13762,7 +13761,7 @@ class RootExports(object):
|
|||
if opts.get(key) is not None:
|
||||
value = opts[key]
|
||||
if not isinstance(value, str):
|
||||
opts[key] = datetime.datetime.fromtimestamp(value).isoformat(' ')
|
||||
opts[key] = convert_timestamp(value)
|
||||
conditions.append('%(field)s %(cmp)s %%(%(key)s)s' % locals())
|
||||
|
||||
query = QueryProcessor(columns=fields, aliases=aliases, tables=tables, joins=joins,
|
||||
|
|
|
|||
|
|
@ -259,7 +259,7 @@ class TestQueryHistory(DBQueryTestCase):
|
|||
"LEFT OUTER JOIN users AS revoker ON revoker.id = revoker_id",
|
||||
'LEFT OUTER JOIN users ON user_id = users.id',
|
||||
'LEFT OUTER JOIN content_generator ON cg_id = content_generator.id'])
|
||||
self.assertEqual(query.values, {'affected_user_id': 159, 'before': '2023-04-19 17:23:40'})
|
||||
self.assertEqual(query.values, {'affected_user_id': 159, 'before': '2023-04-19 17:23:40+00:00'})
|
||||
|
||||
query = self.queries[1]
|
||||
self.assertEqual(query.tables, ['tag_package_owners'])
|
||||
|
|
@ -284,7 +284,7 @@ class TestQueryHistory(DBQueryTestCase):
|
|||
'LEFT OUTER JOIN package ON package_id = package.id',
|
||||
'LEFT OUTER JOIN tag ON tag_id = tag.id',
|
||||
'LEFT OUTER JOIN users AS owner ON owner = owner.id'])
|
||||
self.assertEqual(query.values, {'affected_user_id': 159, 'before': '2023-04-19 17:23:40'})
|
||||
self.assertEqual(query.values, {'affected_user_id': 159, 'before': '2023-04-19 17:23:40+00:00'})
|
||||
|
||||
query = self.queries[2]
|
||||
self.assertEqual(query.tables, ['user_groups'])
|
||||
|
|
@ -306,7 +306,7 @@ class TestQueryHistory(DBQueryTestCase):
|
|||
"LEFT OUTER JOIN users AS revoker ON revoker.id = revoker_id",
|
||||
'LEFT OUTER JOIN users ON user_id = users.id',
|
||||
'users AS usergroup ON group_id = usergroup.id'])
|
||||
self.assertEqual(query.values, {'affected_user_id': 159, 'before': '2023-04-19 17:23:40'})
|
||||
self.assertEqual(query.values, {'affected_user_id': 159, 'before': '2023-04-19 17:23:40+00:00'})
|
||||
|
||||
query = self.queries[3]
|
||||
self.assertEqual(query.tables, ['user_perms'])
|
||||
|
|
@ -328,7 +328,7 @@ class TestQueryHistory(DBQueryTestCase):
|
|||
"LEFT OUTER JOIN users AS revoker ON revoker.id = revoker_id",
|
||||
'LEFT OUTER JOIN users ON user_id = users.id',
|
||||
'LEFT OUTER JOIN permissions AS permission ON perm_id = permission.id'])
|
||||
self.assertEqual(query.values, {'affected_user_id': 159, 'before': '2023-04-19 17:23:40'})
|
||||
self.assertEqual(query.values, {'affected_user_id': 159, 'before': '2023-04-19 17:23:40+00:00'})
|
||||
|
||||
def test_permission_and_after_key(self):
|
||||
self.get_perm_id.return_value = 66
|
||||
|
|
@ -356,7 +356,7 @@ class TestQueryHistory(DBQueryTestCase):
|
|||
"LEFT OUTER JOIN users AS revoker ON revoker.id = revoker_id",
|
||||
'LEFT OUTER JOIN tag ON tag_id = tag.id',
|
||||
'LEFT OUTER JOIN permissions AS permission ON perm_id = permission.id'])
|
||||
self.assertEqual(query.values, {'after': '2023-04-19 17:23:40', 'perm_id': 66})
|
||||
self.assertEqual(query.values, {'after': '2023-04-19 17:23:40+00:00', 'perm_id': 66})
|
||||
|
||||
query = self.queries[1]
|
||||
self.assertEqual(query.tables, ['user_perms'])
|
||||
|
|
@ -378,7 +378,7 @@ class TestQueryHistory(DBQueryTestCase):
|
|||
"LEFT OUTER JOIN users AS revoker ON revoker.id = revoker_id",
|
||||
'LEFT OUTER JOIN users ON user_id = users.id',
|
||||
'LEFT OUTER JOIN permissions AS permission ON perm_id = permission.id'])
|
||||
self.assertEqual(query.values, {'after': '2023-04-19 17:23:40', 'perm_id': 66})
|
||||
self.assertEqual(query.values, {'after': '2023-04-19 17:23:40+00:00', 'perm_id': 66})
|
||||
|
||||
def test_cg_key(self):
|
||||
self.lookup_name.return_value = {'id': 147}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue