Files
folkugat-web/folkugat_web/model/sql.py
2025-03-22 23:06:34 +01:00

74 lines
1.7 KiB
Python

from __future__ import annotations
import dataclasses
import enum
from abc import abstractmethod
from typing import Generic, Protocol, TypeVar
class Comparable(Protocol):
@abstractmethod
def __gt__(self: T, other: T, /) -> bool:
pass
@abstractmethod
def __ge__(self: T, other: T, /) -> bool:
pass
@abstractmethod
def __lt__(self: T, other: T, /) -> bool:
pass
@abstractmethod
def __le__(self: T, other: T, /) -> bool:
pass
T = TypeVar("T", bound=Comparable)
@dataclasses.dataclass
class Range(Generic[T]):
gt: T | None = None
gte: T | None = None
lt: T | None = None
lte: T | None = None
def lower_bound(self) -> tuple[T, bool] | None:
if self.gt is None and self.gte is None:
return None
elif self.gt is not None and self.gte is not None:
lb = self.gt if (self.gt > self.gte) else self.gte
eq = self.gt < self.gte
return lb, eq
elif self.gt is not None:
return self.gt, False
elif self.gte is not None:
return self.gte, True
def upper_bound(self) -> tuple[T, bool] | None:
if self.lt is None and self.lte is None:
return None
elif self.lt is not None and self.lte is not None:
ub = self.lt if (self.lt < self.lte) else self.lte
eq = self.lt > self.lte
return ub, eq
elif self.lt is not None:
return self.lt, False
elif self.lte is not None:
return self.lte, True
class Order(enum.Enum):
ASCENDING = 'ASC'
DESCENDING = 'DESC'
ColT = TypeVar("ColT")
@dataclasses.dataclass
class OrderCol(Generic[ColT]):
column: ColT
order: Order