hotpocket/services/packages/common/hotpocket_common/db/postgres.py
Tomek Wójcik b4338e2769
Some checks failed
CI / Checks (push) Failing after 13m2s
Release v1.0.0
2025-08-20 21:00:50 +02:00

54 lines
1.7 KiB
Python

# -*- coding: utf-8 -*-
from __future__ import annotations
import typing
from django.db.models.fields import Field
from django.db.models.lookups import PatternLookup
class BaseLikeLookup(PatternLookup):
"""
This class provides base for custom LIKE/ILIKE lookups for PostgreSQL.
Unlike the builtin `contains` and `icontains`, these lookups do not do
any DB-side processing of parameters. This opens up the ability to use
index ops provided by `pg_trgm` to better index text columns for pattern
searches.
These lookups currently support only PostgreSQL 15+.
"""
# This is the pattern operator used to generate SQL for the lookup
# when the right hand side isn't a raw string. Subclasses must specify this
# or the whole thing will blow up ;).
PATTERN_OP: str | None = None
# This is the rhs operator used to generate SQL for the lookup when the
# right hand side is a raw string. Subclasses must specify this or the
# whole thing will blow up ;).
RHS_OP: str | None = None
def get_rhs_op(self, connection: typing.Any, rhs: typing.Any) -> typing.Any:
if hasattr(self.rhs, 'as_sql') or self.bilateral_transforms:
pattern = typing.cast(str, self.PATTERN_OP).format(
connection.pattern_esc,
)
return pattern.format(rhs)
else:
return typing.cast(str, self.RHS_OP)
@Field.register_lookup
class Like(BaseLikeLookup):
PATTERN_OP = "LIKE '%%' || {} || '%%'"
RHS_OP = 'LIKE %s'
lookup_name = 'like'
@Field.register_lookup
class ILike(BaseLikeLookup):
PATTERN_OP = "ILIKE '%%' || {} || '%%'"
RHS_OP = 'ILIKE %s'
lookup_name = 'ilike'