"""Thoth/PostgREST implementation of the DWH port.""" from tht.config import DatabaseIdentityConfig, RestConfig from tht.db.introspect import introspect_rest from tht.db import sampling from tht.execute import ExecResult, ExecutionError, PlanSummary from tht.mschema.models import PhysicalSchema from tht.ports.dwh import DistinctValues, DwhCapabilities, DwhHealth from tht.rest.client import RestClient, RestError from tht.rest.execute import explain_rest, run_controlled_rest class ThothRestDwhAdapter: capabilities = DwhCapabilities() def __init__(self, database: DatabaseIdentityConfig, rest: RestConfig): self._database = database self._client = RestClient(rest) def health(self) -> DwhHealth: try: result = self._client.ping() except RestError as exc: return DwhHealth(ok=False, detail=str(exc), error_kind="connection") ok = bool(result.get("db_connected") and result.get("schema_accessible")) return DwhHealth(ok=ok, detail=None if ok else str(result), database=self._database.database, schema=self._database.db_schema, endpoint=self._client.cfg.base_url, read_only=True, error_kind=None if ok else "inaccessible") def introspect(self) -> PhysicalSchema: return introspect_rest( self._client, self._database.database, self._database.db_schema ) def run_query(self, sql: str, *, limit: int) -> ExecResult: return run_controlled_rest(self._client, sql, limit=limit) def explain(self, sql: str) -> PlanSummary: return explain_rest(self._client, sql) def sample_column(self, table: str, column: str, *, limit: int) -> list[object]: try: return sampling.sample_column_rest( self._client, self._database.db_schema, table, column, limit=limit ) except RestError as exc: raise ExecutionError(str(exc)) from exc def distinct_values(self, table: str, column: str, *, limit: int) -> DistinctValues: try: return sampling.distinct_values_rest( self._client, self._database.db_schema, table, column, max_values=limit ) except RestError as exc: raise ExecutionError(str(exc)) from exc