sts-sponsors team mailing list archive
-
sts-sponsors team
-
Mailing list archive
-
Message #05838
Re: [Merge] ~thorsten-merten/maas-site-manager:MAASENG-1290-add-filter-to-sites into maas-site-manager:main
Review: Needs Fixing
Diff comments:
> diff --git a/backend/msm/db/queries.py b/backend/msm/db/queries.py
> index ce2bd93..19ba033 100644
> --- a/backend/msm/db/queries.py
> +++ b/backend/msm/db/queries.py
> @@ -15,6 +25,87 @@ from ._tables import (
> )
>
>
> +def filters_from_arguments(
> + table: Table,
> + **kwargs: list[str] | None,
**kwargs is a dict[str, ...] not a list of strs
> +) -> ColumnElement[bool]:
> + """
> + Joins all keys of the kwargs by AND and all entries for a single arg by OR.
> + This enables to convert query params such as
> +
> + ?name=name1&name=name2&city=city
> +
> + to a where clause such as
> +
> + (name ilike %name1% OR name ilike %name2%) AND city ilike %city%
> +
> + :param table: the table to create the WHERE clause for
> + :param kwargs: the parameters matching the table's column name
> + as keys and lists of Strings that will be matched
> + via ilike
> + :returns: a where clause that joins all queries per column
> + with OR and all columns with AND
> + """
> + ands: list[ColumnElement[Any]] = []
> + for key in kwargs:
> + entries = kwargs[key]
for key, entries in kwargs.items()
> + if entries and len(entries) == 1:
feels like a good match (pun intended) for Python's match statement https://docs.python.org/3/tutorial/controlflow.html#match-statements
> + ands.append(
> + cast(
> + ColumnElement[Any],
> + table.c[key].icontains(entries[0], autoescape=True),
> + )
> + )
> + if entries and len(entries) > 1:
> + ors: list[ColumnElement[Any]] = [
> + cast(
> + ColumnElement[Any],
> + table.c[key].icontains(entry, autoescape=True),
> + )
> + for entry in entries
> + ]
> + ands.append(or_(true(), *ors))
> + return and_(true(), *ands)
> +
> +
> +async def get_filtered_sites(
> + session: AsyncSession,
> + city: list[str] | None = [],
> + name: list[str] | None = [],
> + note: list[str] | None = [],
> + region: list[str] | None = [],
> + street: list[str] | None = [],
> + timezone: list[str] | None = [],
> + url: list[str] | None = [],
> +) -> Iterable[dict[str, Any]]:
can we be stricter about the types here - we should know what the types of the keys and values are for the returned dict
> + where = filters_from_arguments(
> + Site,
> + city=city,
> + name=name,
> + note=note,
> + region=region,
> + street=street,
> + timezone=timezone,
> + url=url,
> + )
> +
> + stmt = select(
> + Site.c.id,
> + Site.c.name,
> + Site.c.identifier,
> + Site.c.city,
> + Site.c.latitude,
> + Site.c.longitude,
> + Site.c.note,
> + Site.c.region,
> + Site.c.street,
> + Site.c.timezone,
> + Site.c.url,
> + ).where(where)
> + result = await session.execute(stmt)
> + return (row._asdict() for row in result.all())
> +
> +
> async def get_sites(session: AsyncSession) -> Iterable[dict[str, Any]]:
> stmt = select(
> Site.c.id,
--
https://code.launchpad.net/~thorsten-merten/maas-site-manager/+git/maas-site-manager/+merge/438678
Your team MAAS Committers is subscribed to branch ~thorsten-merten/maas-site-manager:MAASENG-1290-add-filter-to-sites.
References