Changeset View
Changeset View
Standalone View
Standalone View
swh/storage/postgresql/converters.py
Show First 20 Lines • Show All 79 Lines • ▼ Show 20 Lines | |||||
def db_to_git_headers(db_git_headers): | def db_to_git_headers(db_git_headers): | ||||
ret = [] | ret = [] | ||||
for key, value in db_git_headers: | for key, value in db_git_headers: | ||||
ret.append([key.encode("utf-8"), encode_with_unescape(value)]) | ret.append([key.encode("utf-8"), encode_with_unescape(value)]) | ||||
return ret | return ret | ||||
def db_to_date( | def db_to_date( | ||||
date: Optional[datetime.datetime], | date: Optional[datetime.datetime], offset_bytes: bytes, | ||||
offset: int, | |||||
neg_utc_offset: Optional[bool], | |||||
offset_bytes: Optional[bytes], | |||||
) -> Optional[TimestampWithTimezone]: | ) -> Optional[TimestampWithTimezone]: | ||||
"""Convert the DB representation of a date to a swh-model compatible date. | """Convert the DB representation of a date to a swh-model compatible date. | ||||
Args: | Args: | ||||
date: a date pulled out of the database | date: a date pulled out of the database | ||||
offset: an integer number of minutes representing an UTC offset | offset_bytes: a byte representation of the latter two, usually as "+HHMM" | ||||
neg_utc_offset: whether an utc offset is negative | or "-HHMM" | ||||
Returns: | Returns: | ||||
a TimestampWithTimezone, or None if the date is None. | a TimestampWithTimezone, or None if the date is None. | ||||
""" | """ | ||||
if date is None: | if date is None: | ||||
return None | return None | ||||
if neg_utc_offset is None: | |||||
# For older versions of the database that were not migrated to schema v160 | |||||
neg_utc_offset = False | |||||
kwargs = {} | |||||
if offset_bytes: | |||||
# TODO: remove the conditional after migration is complete. | |||||
kwargs["offset_bytes"] = offset_bytes | |||||
return TimestampWithTimezone( | return TimestampWithTimezone( | ||||
timestamp=Timestamp( | timestamp=Timestamp( | ||||
# we use floor() instead of int() to round down, because of negative dates | # we use floor() instead of int() to round down, because of negative dates | ||||
seconds=math.floor(date.timestamp()), | seconds=math.floor(date.timestamp()), | ||||
microseconds=date.microsecond, | microseconds=date.microsecond, | ||||
), | ), | ||||
offset=offset, | offset_bytes=offset_bytes, | ||||
negative_utc=neg_utc_offset, | |||||
**kwargs, | |||||
) | ) | ||||
def date_to_db(ts_with_tz: Optional[TimestampWithTimezone]) -> Dict[str, Any]: | def date_to_db(ts_with_tz: Optional[TimestampWithTimezone]) -> Dict[str, Any]: | ||||
"""Convert a swh-model date_offset to its DB representation. | """Convert a swh-model date_offset to its DB representation. | ||||
Args: | Args: | ||||
ts_with_tz: a TimestampWithTimezone object | ts_with_tz: a TimestampWithTimezone object | ||||
Returns: | Returns: | ||||
dict: a dictionary with these keys: | dict: a dictionary with these keys: | ||||
- timestamp: a date in ISO format | - timestamp: a date in ISO format | ||||
- offset: the UTC offset in minutes | |||||
- neg_utc_offset: a boolean indicating whether a null offset is | |||||
negative or positive. | |||||
- offset_bytes: a byte representation of the latter two, usually as "+HHMM" | - offset_bytes: a byte representation of the latter two, usually as "+HHMM" | ||||
or "-HHMM" | or "-HHMM" | ||||
""" | """ | ||||
if ts_with_tz is None: | if ts_with_tz is None: | ||||
return DEFAULT_DATE | return DEFAULT_DATE | ||||
ts = ts_with_tz.timestamp | ts = ts_with_tz.timestamp | ||||
timestamp = datetime.datetime.fromtimestamp(ts.seconds, datetime.timezone.utc) | timestamp = datetime.datetime.fromtimestamp(ts.seconds, datetime.timezone.utc) | ||||
timestamp = timestamp.replace(microsecond=ts.microseconds) | timestamp = timestamp.replace(microsecond=ts.microseconds) | ||||
return { | return { | ||||
# PostgreSQL supports isoformatted timestamps | # PostgreSQL supports isoformatted timestamps | ||||
"timestamp": timestamp.isoformat(), | "timestamp": timestamp.isoformat(), | ||||
"offset": ts_with_tz.offset, | "offset": ts_with_tz.offset, | ||||
"neg_utc_offset": ts_with_tz.negative_utc, | "neg_utc_offset": ts_with_tz.offset == 0 | ||||
and ts_with_tz.offset_bytes.startswith(b"-"), | |||||
"offset_bytes": ts_with_tz.offset_bytes, | "offset_bytes": ts_with_tz.offset_bytes, | ||||
} | } | ||||
def revision_to_db(revision: Revision) -> Dict[str, Any]: | def revision_to_db(revision: Revision) -> Dict[str, Any]: | ||||
"""Convert a swh-model revision to its database representation. | """Convert a swh-model revision to its database representation. | ||||
""" | """ | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | if db_revision["type"] is None: | ||||
) | ) | ||||
return None | return None | ||||
author = db_to_author( | author = db_to_author( | ||||
db_revision["author_fullname"], | db_revision["author_fullname"], | ||||
db_revision["author_name"], | db_revision["author_name"], | ||||
db_revision["author_email"], | db_revision["author_email"], | ||||
) | ) | ||||
date = db_to_date( | date = db_to_date(db_revision["date"], db_revision["date_offset_bytes"],) | ||||
db_revision["date"], | |||||
db_revision["date_offset"], | |||||
db_revision["date_neg_utc_offset"], | |||||
db_revision["date_offset_bytes"], | |||||
) | |||||
committer = db_to_author( | committer = db_to_author( | ||||
db_revision["committer_fullname"], | db_revision["committer_fullname"], | ||||
db_revision["committer_name"], | db_revision["committer_name"], | ||||
db_revision["committer_email"], | db_revision["committer_email"], | ||||
) | ) | ||||
committer_date = db_to_date( | committer_date = db_to_date( | ||||
db_revision["committer_date"], | db_revision["committer_date"], db_revision["committer_date_offset_bytes"], | ||||
db_revision["committer_date_offset"], | |||||
db_revision["committer_date_neg_utc_offset"], | |||||
db_revision["committer_date_offset_bytes"], | |||||
) | ) | ||||
assert author, "author is None" | assert author, "author is None" | ||||
assert committer, "committer is None" | assert committer, "committer is None" | ||||
parents = [] | parents = [] | ||||
if "parents" in db_revision: | if "parents" in db_revision: | ||||
for parent in db_revision["parents"]: | for parent in db_revision["parents"]: | ||||
▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | if db_release["target_type"] is None: | ||||
assert all(v is None for (k, v) in db_release.items() if k != "id") | assert all(v is None for (k, v) in db_release.items() if k != "id") | ||||
return None | return None | ||||
author = db_to_author( | author = db_to_author( | ||||
db_release["author_fullname"], | db_release["author_fullname"], | ||||
db_release["author_name"], | db_release["author_name"], | ||||
db_release["author_email"], | db_release["author_email"], | ||||
) | ) | ||||
date = db_to_date( | date = db_to_date(db_release["date"], db_release["date_offset_bytes"],) | ||||
db_release["date"], | |||||
db_release["date_offset"], | |||||
db_release["date_neg_utc_offset"], | |||||
db_release["date_offset_bytes"], | |||||
) | |||||
return Release( | return Release( | ||||
author=author, | author=author, | ||||
date=date, | date=date, | ||||
id=db_release["id"], | id=db_release["id"], | ||||
name=db_release["name"], | name=db_release["name"], | ||||
message=db_release["comment"], | message=db_release["comment"], | ||||
synthetic=db_release["synthetic"], | synthetic=db_release["synthetic"], | ||||
▲ Show 20 Lines • Show All 46 Lines • Show Last 20 Lines |