Skip to content

Commit

Permalink
Merge branch 'main' into dto-transfer-type-deterministic-name
Browse files Browse the repository at this point in the history
  • Loading branch information
JacobCoffee authored Sep 30, 2023
2 parents 551cddc + fd18f36 commit 18e7858
Show file tree
Hide file tree
Showing 11 changed files with 485 additions and 401 deletions.
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ repos:
sqlalchemy>=2.0.12,
starlette,
structlog,
advanced-alchemy==0.2.1,
advanced-alchemy==0.2.2,
time-machine,
types-beautifulsoup4,
types-python-jose,
Expand Down Expand Up @@ -176,7 +176,7 @@ repos:
rich,
rich-click,
sqlalchemy>=2.0.12,
advanced-alchemy==0.2.1,
advanced-alchemy==0.2.2,
starlette,
structlog,
time-machine,
Expand Down
2 changes: 2 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@
(PY_CLASS, "advanced_alchemy.types.BigIntIdentity"),
(PY_FUNC, "sqlalchemy.get_engine"),
(PY_ATTR, "advanced_alchemy.repository.AbstractAsyncRepository.id_attribute"),
("py:exc", "RepositoryError"),
]

nitpick_ignore_regex = [
Expand All @@ -179,6 +180,7 @@
(PY_RE, r"litestar\.connection\.base\.UserT"),
(PY_RE, r"litestar\.pagination\.C"),
(PY_RE, r"multidict\..*"),
(PY_RE, r"advanced_alchemy.*\.T"),
]

# Warnings about missing references to those targets in the specified location will be ignored.
Expand Down
3 changes: 1 addition & 2 deletions docs/reference/repository/exceptions.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
exceptions
==========

.. automodule:: litestar.repository.exceptions
:members:
This page has moved to :doc:`advanced-alchemy:reference/filters`
3 changes: 1 addition & 2 deletions docs/reference/repository/filters.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
filters
=======

.. automodule:: litestar.repository.filters
:members:
This page has moved to :doc:`advanced-alchemy:reference/filters`
15 changes: 15 additions & 0 deletions litestar/repository/_exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from __future__ import annotations

__all__ = ("ConflictError", "NotFoundError", "RepositoryError")


class RepositoryError(Exception):
"""Base repository exception type."""


class ConflictError(RepositoryError):
"""Data integrity error."""


class NotFoundError(RepositoryError):
"""An identity does not exist."""
116 changes: 116 additions & 0 deletions litestar/repository/_filters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
"""Collection filter datastructures."""
from __future__ import annotations

from collections import abc # noqa: TCH003
from dataclasses import dataclass
from datetime import datetime # noqa: TCH003
from typing import TYPE_CHECKING, Any, Generic, Literal, TypeVar

if TYPE_CHECKING:
from typing_extensions import TypeAlias

T = TypeVar("T")

__all__ = (
"BeforeAfter",
"CollectionFilter",
"FilterTypes",
"LimitOffset",
"OrderBy",
"SearchFilter",
"NotInCollectionFilter",
"OnBeforeAfter",
"NotInSearchFilter",
)


FilterTypes: TypeAlias = "BeforeAfter | OnBeforeAfter | CollectionFilter[Any] | LimitOffset | OrderBy | SearchFilter | NotInCollectionFilter[Any] | NotInSearchFilter"
"""Aggregate type alias of the types supported for collection filtering."""


@dataclass
class BeforeAfter:
"""Data required to filter a query on a ``datetime`` column."""

field_name: str
"""Name of the model attribute to filter on."""
before: datetime | None
"""Filter results where field earlier than this."""
after: datetime | None
"""Filter results where field later than this."""


@dataclass
class OnBeforeAfter:
"""Data required to filter a query on a ``datetime`` column."""

field_name: str
"""Name of the model attribute to filter on."""
on_or_before: datetime | None
"""Filter results where field is on or earlier than this."""
on_or_after: datetime | None
"""Filter results where field on or later than this."""


@dataclass
class CollectionFilter(Generic[T]):
"""Data required to construct a ``WHERE ... IN (...)`` clause."""

field_name: str
"""Name of the model attribute to filter on."""
values: abc.Collection[T]
"""Values for ``IN`` clause."""


@dataclass
class NotInCollectionFilter(Generic[T]):
"""Data required to construct a ``WHERE ... NOT IN (...)`` clause."""

field_name: str
"""Name of the model attribute to filter on."""
values: abc.Collection[T]
"""Values for ``NOT IN`` clause."""


@dataclass
class LimitOffset:
"""Data required to add limit/offset filtering to a query."""

limit: int
"""Value for ``LIMIT`` clause of query."""
offset: int
"""Value for ``OFFSET`` clause of query."""


@dataclass
class OrderBy:
"""Data required to construct a ``ORDER BY ...`` clause."""

field_name: str
"""Name of the model attribute to sort on."""
sort_order: Literal["asc", "desc"] = "asc"
"""Sort ascending or descending"""


@dataclass
class SearchFilter:
"""Data required to construct a ``WHERE field_name LIKE '%' || :value || '%'`` clause."""

field_name: str
"""Name of the model attribute to sort on."""
value: str
"""Values for ``LIKE`` clause."""
ignore_case: bool | None = False
"""Should the search be case insensitive."""


@dataclass
class NotInSearchFilter:
"""Data required to construct a ``WHERE field_name NOT LIKE '%' || :value || '%'`` clause."""

field_name: str
"""Name of the model attribute to search on."""
value: str
"""Values for ``NOT LIKE`` clause."""
ignore_case: bool | None = False
"""Should the search be case insensitive."""
17 changes: 4 additions & 13 deletions litestar/repository/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,6 @@
from __future__ import annotations
try:
from advanced_alchemy.exceptions import ConflictError, NotFoundError, RepositoryError
except ImportError:
from ._exceptions import ConflictError, NotFoundError, RepositoryError # type: ignore[assignment]

__all__ = ("ConflictError", "NotFoundError", "RepositoryError")


class RepositoryError(Exception):
"""Base repository exception type."""


class ConflictError(RepositoryError):
"""Data integrity error."""


class NotFoundError(RepositoryError):
"""An identity does not exist."""
127 changes: 24 additions & 103 deletions litestar/repository/filters.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,28 @@
"""Collection filter datastructures."""
from __future__ import annotations
try:
from advanced_alchemy.filters import (
BeforeAfter,
CollectionFilter,
FilterTypes,
LimitOffset,
NotInCollectionFilter,
NotInSearchFilter,
OnBeforeAfter,
OrderBy,
SearchFilter,
)
except ImportError:
from ._filters import ( # type: ignore[assignment]
BeforeAfter,
CollectionFilter,
FilterTypes,
LimitOffset,
NotInCollectionFilter,
NotInSearchFilter,
OnBeforeAfter,
OrderBy,
SearchFilter,
)

from collections import abc # noqa: TCH003
from dataclasses import dataclass
from datetime import datetime # noqa: TCH003
from typing import TYPE_CHECKING, Any, Generic, Literal, TypeVar

if TYPE_CHECKING:
from typing_extensions import TypeAlias

T = TypeVar("T")

__all__ = (
"BeforeAfter",
Expand All @@ -22,95 +35,3 @@
"OnBeforeAfter",
"NotInSearchFilter",
)


FilterTypes: TypeAlias = "BeforeAfter | OnBeforeAfter | CollectionFilter[Any] | LimitOffset | OrderBy | SearchFilter | NotInCollectionFilter[Any] | NotInSearchFilter"
"""Aggregate type alias of the types supported for collection filtering."""


@dataclass
class BeforeAfter:
"""Data required to filter a query on a ``datetime`` column."""

field_name: str
"""Name of the model attribute to filter on."""
before: datetime | None
"""Filter results where field earlier than this."""
after: datetime | None
"""Filter results where field later than this."""


@dataclass
class OnBeforeAfter:
"""Data required to filter a query on a ``datetime`` column."""

field_name: str
"""Name of the model attribute to filter on."""
on_or_before: datetime | None
"""Filter results where field is on or earlier than this."""
on_or_after: datetime | None
"""Filter results where field on or later than this."""


@dataclass
class CollectionFilter(Generic[T]):
"""Data required to construct a ``WHERE ... IN (...)`` clause."""

field_name: str
"""Name of the model attribute to filter on."""
values: abc.Collection[T]
"""Values for ``IN`` clause."""


@dataclass
class NotInCollectionFilter(Generic[T]):
"""Data required to construct a ``WHERE ... NOT IN (...)`` clause."""

field_name: str
"""Name of the model attribute to filter on."""
values: abc.Collection[T]
"""Values for ``NOT IN`` clause."""


@dataclass
class LimitOffset:
"""Data required to add limit/offset filtering to a query."""

limit: int
"""Value for ``LIMIT`` clause of query."""
offset: int
"""Value for ``OFFSET`` clause of query."""


@dataclass
class OrderBy:
"""Data required to construct a ``ORDER BY ...`` clause."""

field_name: str
"""Name of the model attribute to sort on."""
sort_order: Literal["asc", "desc"] = "asc"
"""Sort ascending or descending"""


@dataclass
class SearchFilter:
"""Data required to construct a ``WHERE field_name LIKE '%' || :value || '%'`` clause."""

field_name: str
"""Name of the model attribute to sort on."""
value: str
"""Values for ``LIKE`` clause."""
ignore_case: bool | None = False
"""Should the search be case insensitive."""


@dataclass
class NotInSearchFilter:
"""Data required to construct a ``WHERE field_name NOT LIKE '%' || :value || '%'`` clause."""

field_name: str
"""Name of the model attribute to search on."""
value: str
"""Values for ``NOT LIKE`` clause."""
ignore_case: bool | None = False
"""Should the search be case insensitive."""
Loading

0 comments on commit 18e7858

Please sign in to comment.