Commit 26b77fdd authored by Jérome Perrin's avatar Jérome Perrin

utils: parse_tid rework

parent 6ceb2558
...@@ -96,5 +96,4 @@ with open(os.path.join(os.path.dirname(__file__), "testdata", "tidrange-formats. ...@@ -96,5 +96,4 @@ with open(os.path.join(os.path.dirname(__file__), "testdata", "tidrange-formats.
@pytest.mark.parametrize("reference_time,reference_tid,input_time", test_parameters) @pytest.mark.parametrize("reference_time,reference_tid,input_time", test_parameters)
def test_parse_tid(europe_paris_timezone, fake_time, reference_time, reference_tid, input_time): def test_parse_tid(europe_paris_timezone, fake_time, reference_time, reference_tid, input_time):
print ("parsing", input_time, "expecting", reference_time)
assert reference_tid == ashex(parse_tid(input_time)) assert reference_tid == ashex(parse_tid(input_time))
...@@ -66,40 +66,52 @@ def txnobjv(txn): ...@@ -66,40 +66,52 @@ def txnobjv(txn):
class TidRangeInvalid(Exception): class TidRangeInvalid(Exception):
pass pass
def tid_from_date(date_string):
"""Try to parse `date_string` as a date and returns the def parse_tid(tid_string, raw_only=False):
corresponding TID. """Try to parse `tid_string` as a time and returns the
If `date_string` cannot be parsed as a date, assume it was corresponding raw TID.
If `tid_string` cannot be parsed as a time, assume it was
already a TID. already a TID.
This function also raise TidRangeInvalid when `tid_string`
is invalid.
""" """
if not date_string: if not tid_string:
return date_string return tid_string
# If it "looks like a TID", don't try to parse it as date, # If it "looks like a TID", don't try to parse it as time,
# because parsing as date is slow. # because parsing is slow.
if len(date_string) == 16: if len(tid_string) == 16:
try: try:
fromhex(date_string) return fromhex(tid_string)
return date_string
except TypeError: except TypeError:
pass pass
date = None
date = dateparser.parse( if not raw_only:
date_string, # preprocess to support `1.day.ago` style formats like git log does.
settings={ if "ago" in tid_string:
'TO_TIMEZONE': 'UTC'}) tid_string = tid_string.replace(".", " ").replace("_", " ")
date = dateparser.parse(
tid_string,
settings={
'TO_TIMEZONE': 'UTC',
'RETURN_AS_TIMEZONE_AWARE': True
})
if not date: if not date:
# parsing failed # parsing failed
return date_string try:
return fromhex(tid_string)
except TypeError:
raise TidRangeInvalid(tid_string)
# build a ZODB.TimeStamp to convert as a TID # build a ZODB.TimeStamp to convert as a TID
return ashex( return TimeStamp(
TimeStamp(
date.year, date.year,
date.month, date.month,
date.day, date.day,
date.hour, date.hour,
date.minute, date.minute,
date.second + date.microsecond / 1000000.).raw()) date.second + date.microsecond / 1000000.).raw()
# parse_tidrange parses a string into (tidmin, tidmax). # parse_tidrange parses a string into (tidmin, tidmax).
# #
...@@ -110,14 +122,8 @@ def parse_tidrange(tidrange): ...@@ -110,14 +122,8 @@ def parse_tidrange(tidrange):
except ValueError: # not exactly 2 parts in between ".." except ValueError: # not exactly 2 parts in between ".."
raise TidRangeInvalid(tidrange) raise TidRangeInvalid(tidrange)
tidmin = tid_from_date(tidmin) tidmin = parse_tid(tidmin)
tidmax = tid_from_date(tidmax) tidmax = parse_tid(tidmax)
try:
tidmin = tidmin.decode("hex")
tidmax = tidmax.decode("hex")
except TypeError: # hex decoding error
raise TidRangeInvalid(tidrange)
# empty tid means -inf / +inf respectively # empty tid means -inf / +inf respectively
# ( which is None in IStorage.iterator() ) # ( which is None in IStorage.iterator() )
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment