Changeset View
Changeset View
Standalone View
Standalone View
swh/provenance/postgresql/provenance.py
Show First 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | def handle_raise_on_commit(f): | ||||
return handle | return handle | ||||
class ProvenanceStoragePostgreSql: | class ProvenanceStoragePostgreSql: | ||||
def __init__( | def __init__( | ||||
self, page_size: Optional[int] = None, raise_on_commit: bool = False, **kwargs | self, page_size: Optional[int] = None, raise_on_commit: bool = False, **kwargs | ||||
) -> None: | ) -> None: | ||||
self.conn: Optional[psycopg2.extensions.connection] = None | |||||
self.conn_args = kwargs | self.conn_args = kwargs | ||||
self._flavor: Optional[str] = None | self._flavor: Optional[str] = None | ||||
self.page_size = page_size | self.page_size = page_size | ||||
self.raise_on_commit = raise_on_commit | self.raise_on_commit = raise_on_commit | ||||
def __enter__(self) -> ProvenanceStorageInterface: | def __enter__(self) -> ProvenanceStorageInterface: | ||||
self.open() | self.open() | ||||
return self | return self | ||||
def __exit__( | def __exit__( | ||||
self, | self, | ||||
exc_type: Optional[Type[BaseException]], | exc_type: Optional[Type[BaseException]], | ||||
exc_val: Optional[BaseException], | exc_val: Optional[BaseException], | ||||
exc_tb: Optional[TracebackType], | exc_tb: Optional[TracebackType], | ||||
) -> None: | ) -> None: | ||||
self.close() | self.close() | ||||
@contextmanager | @contextmanager | ||||
def transaction( | def transaction( | ||||
self, readonly: bool = False | self, readonly: bool = False | ||||
) -> Generator[psycopg2.extras.RealDictCursor, None, None]: | ) -> Generator[psycopg2.extras.RealDictCursor, None, None]: | ||||
if self.conn is None: # somehow, "implicit" __enter__ call did not happen | |||||
ardumont: @olasd mentions this could be the source of the failing build. | |||||
Done Inline Actionsand instead i should wrap the client call in a with provenance: (which explicitly opens/closes the connection to the backend storage). ardumont: and instead i should wrap the client call in a `with provenance:` (which explicitly… | |||||
self.open() | |||||
assert self.conn is not None | |||||
self.conn.set_session(readonly=readonly) | self.conn.set_session(readonly=readonly) | ||||
with self.conn: | with self.conn: | ||||
with self.conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor) as cur: | with self.conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor) as cur: | ||||
yield cur | yield cur | ||||
@property | @property | ||||
def flavor(self) -> str: | def flavor(self) -> str: | ||||
if self._flavor is None: | if self._flavor is None: | ||||
with self.transaction(readonly=True) as cursor: | with self.transaction(readonly=True) as cursor: | ||||
cursor.execute("SELECT swh_get_dbflavor() AS flavor") | cursor.execute("SELECT swh_get_dbflavor() AS flavor") | ||||
self._flavor = cursor.fetchone()["flavor"] | self._flavor = cursor.fetchone()["flavor"] | ||||
assert self._flavor is not None | assert self._flavor is not None | ||||
return self._flavor | return self._flavor | ||||
@property | @property | ||||
def denormalized(self) -> bool: | def denormalized(self) -> bool: | ||||
return "denormalized" in self.flavor | return "denormalized" in self.flavor | ||||
@statsd.timed(metric=STORAGE_DURATION_METRIC, tags={"method": "close"}) | @statsd.timed(metric=STORAGE_DURATION_METRIC, tags={"method": "close"}) | ||||
def close(self) -> None: | def close(self) -> None: | ||||
assert self.conn is not None | |||||
self.conn.close() | self.conn.close() | ||||
@statsd.timed(metric=STORAGE_DURATION_METRIC, tags={"method": "content_add"}) | @statsd.timed(metric=STORAGE_DURATION_METRIC, tags={"method": "content_add"}) | ||||
@handle_raise_on_commit | @handle_raise_on_commit | ||||
def content_add(self, cnts: Dict[Sha1Git, datetime]) -> bool: | def content_add(self, cnts: Dict[Sha1Git, datetime]) -> bool: | ||||
if cnts: | if cnts: | ||||
sql = """ | sql = """ | ||||
INSERT INTO content(sha1, date) VALUES %s | INSERT INTO content(sha1, date) VALUES %s | ||||
▲ Show 20 Lines • Show All 274 Lines • Show Last 20 Lines |
@olasd mentions this could be the source of the failing build.