Source code for rowguard.results.query_result

from __future__ import annotations

from dataclasses import dataclass
from typing import Any, Generic, TypeVar

from pydantic import BaseModel

from rowguard.diagnostics import Diagnostic
from rowguard.results.quarantine import QuarantineReceipt
from rowguard.results.rejected_row import RejectedRow
from rowguard.statistics import QueryStatistics

T = TypeVar("T", bound=BaseModel)


[docs] @dataclass(frozen=True, slots=True) class QueryResult(Generic[T]): models: tuple[T, ...] rejected: tuple[RejectedRow, ...] statistics: QueryStatistics statement: Any | None = None diagnostics: tuple[Diagnostic, ...] = () quarantine_receipts: tuple[QuarantineReceipt, ...] = () @property def has_rejections(self) -> bool: """True if any row was rejected during execution (including skip).""" return self.statistics.rows_rejected > 0 @property def is_clean(self) -> bool: """True when no rows were rejected during execution.""" return not self.has_rejections @property def valid_count(self) -> int: return len(self.models) @property def rejected_count(self) -> int: """Number of retained rejected rows (empty under skip).""" return len(self.rejected) @property def execution_time(self) -> float: """End-to-end execution wall time in seconds (fetch + validation).""" return self.statistics.execution_time_ns / 1_000_000_000