elwig-backend: Allow multiple values in filters
This commit is contained in:
@ -24,25 +24,31 @@ class BadRequestError(Exception):
|
|||||||
|
|
||||||
|
|
||||||
class Filter:
|
class Filter:
|
||||||
def __init__(self, name: str, value: int or str = None):
|
def __init__(self, name: str, values: list[int] or list[str] = None):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.value = value
|
self.values = values
|
||||||
|
|
||||||
def is_int(self) -> bool:
|
def is_int(self) -> bool:
|
||||||
return type(self.value) is int
|
return type(self.values[0]) is int
|
||||||
|
|
||||||
def is_str(self) -> bool:
|
def is_str(self) -> bool:
|
||||||
return type(self.value) is str
|
return type(self.values[0]) is str
|
||||||
|
|
||||||
def is_single(self) -> bool:
|
def is_single(self) -> bool:
|
||||||
return self.value is None
|
return self.values is None
|
||||||
|
|
||||||
|
def to_sql_list(self) -> str:
|
||||||
|
if self.is_int():
|
||||||
|
return ', '.join(str(v) for v in self.values)
|
||||||
|
else:
|
||||||
|
return ', '.join(f"'{v}'" for v in self.values)
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
if self.is_single():
|
if self.is_single():
|
||||||
return self.name
|
return self.name
|
||||||
elif self.name == 'kgnr':
|
elif self.name == 'kgnr':
|
||||||
return f'kgnr={self.value:05}'
|
return f'kgnr={";".join(f"{v:05}" for v in self.values)}'
|
||||||
return f'{self.name}={self.value}'
|
return f'{self.name}={";".join(str(v) for v in self.values)}'
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return self.__repr__()
|
return self.__repr__()
|
||||||
@ -54,7 +60,9 @@ class Filter:
|
|||||||
def from_str(string: str) -> Filter:
|
def from_str(string: str) -> Filter:
|
||||||
f = string.split('=', 1)
|
f = string.split('=', 1)
|
||||||
if len(f) == 2:
|
if len(f) == 2:
|
||||||
return Filter(f[0], int(f[1]) if f[1].isdigit() else f[1])
|
ps = f[1].split(';')
|
||||||
|
is_digit = all(p.isdigit() for p in ps)
|
||||||
|
return Filter(f[0], [int(p) for p in ps] if is_digit else ps)
|
||||||
return Filter(f[0])
|
return Filter(f[0])
|
||||||
|
|
||||||
|
|
||||||
@ -78,11 +86,11 @@ def get_delivery_schedule_filter_clauses(filters: list[Filter]) -> list[str]:
|
|||||||
clauses = []
|
clauses = []
|
||||||
for f in filters:
|
for f in filters:
|
||||||
if f.name == 'year' and f.is_int():
|
if f.name == 'year' and f.is_int():
|
||||||
clauses.append(f"s.year = {f.value}")
|
clauses.append(f"s.year IN ({f.to_sql_list()})")
|
||||||
elif f.name == 'sortid' and f.is_str() and len(f.value) == 2 and f.value.isalpha() and f.value.isupper():
|
elif f.name == 'sortid' and f.is_str() and all(len(v) == 2 and v.isalpha() and v.isupper() for v in f.values):
|
||||||
clauses.append(f"v.sortid = '{f.value}'")
|
clauses.append(f"v.sortid IN ({f.to_sql_list()})")
|
||||||
elif f.name == 'date' and f.is_str() and re.match(r'[0-9]{4}-[0-9]{2}-[0-9]{2}', f.value) is not None:
|
elif f.name == 'date' and f.is_str() and all(re.match(r'[0-9]{4}-[0-9]{2}-[0-9]{2}', v) is not None for v in f.values):
|
||||||
clauses.append(f"s.date = '{f.value}'")
|
clauses.append(f"s.date IN ({f.to_sql_list()})")
|
||||||
else:
|
else:
|
||||||
raise BadRequestError(f"Invalid filter '{f}'")
|
raise BadRequestError(f"Invalid filter '{f}'")
|
||||||
return clauses
|
return clauses
|
||||||
@ -279,27 +287,27 @@ class ElwigApi(BaseHTTPRequestHandler):
|
|||||||
self.exec_collection(
|
self.exec_collection(
|
||||||
"SELECT sortid, type, name, comment FROM wine_variety",
|
"SELECT sortid, type, name, comment FROM wine_variety",
|
||||||
lambda r: f'{{"sortid":{jdmp(r[0])},"type":{jdmp(r[1])},"name":{jdmp(r[2])},"comment":{jdmp(r[3])}}}',
|
lambda r: f'{{"sortid":{jdmp(r[0])},"type":{jdmp(r[1])},"name":{jdmp(r[2])},"comment":{jdmp(r[3])}}}',
|
||||||
filters)
|
[], offset, limit)
|
||||||
elif path == '/wine/quality_levels':
|
elif path == '/wine/quality_levels':
|
||||||
self.exec_collection(
|
self.exec_collection(
|
||||||
"SELECT qualid, name, min_kmw, predicate FROM wine_quality_level",
|
"SELECT qualid, name, min_kmw, predicate FROM wine_quality_level",
|
||||||
lambda r: f'{{"qualid":{jdmp(r[0])},"name":{jdmp(r[1]):22},"min_kmw":{jdmp(r[2])},"is_predicate":{jdmp(r[3], is_bool=True)}}}',
|
lambda r: f'{{"qualid":{jdmp(r[0])},"name":{jdmp(r[1]):22},"min_kmw":{jdmp(r[2])},"is_predicate":{jdmp(r[3], is_bool=True)}}}',
|
||||||
filters)
|
[], offset, limit)
|
||||||
elif path == '/wine/attributes':
|
elif path == '/wine/attributes':
|
||||||
self.exec_collection(
|
self.exec_collection(
|
||||||
"SELECT attrid, name FROM wine_attribute",
|
"SELECT attrid, name FROM wine_attribute",
|
||||||
lambda r: f'{{"attrid":{jdmp(r[0]):4},"name":{jdmp(r[1])}}}',
|
lambda r: f'{{"attrid":{jdmp(r[0]):4},"name":{jdmp(r[1])}}}',
|
||||||
filters)
|
[], offset, limit)
|
||||||
elif path == '/wine/cultivations':
|
elif path == '/wine/cultivations':
|
||||||
self.exec_collection(
|
self.exec_collection(
|
||||||
"SELECT cultid, name, description FROM wine_cultivation",
|
"SELECT cultid, name, description FROM wine_cultivation",
|
||||||
lambda r: f'{{"cultid":{jdmp(r[0]):5},"name":{jdmp(r[1])},"description":{jdmp(r[2])}}}',
|
lambda r: f'{{"cultid":{jdmp(r[0]):5},"name":{jdmp(r[1])},"description":{jdmp(r[2])}}}',
|
||||||
filters)
|
[], offset, limit)
|
||||||
elif path == '/modifiers':
|
elif path == '/modifiers':
|
||||||
self.exec_collection(
|
self.exec_collection(
|
||||||
"SELECT year, modid, name, ordering FROM modifier",
|
"SELECT year, modid, name, ordering FROM modifier",
|
||||||
lambda r: f'{{"year":{jdmp(r[0])},"modid":{jdmp(r[1]):5},"name":{jdmp(r[2]):18},"ordering":{jdmp(r[3])}}}',
|
lambda r: f'{{"year":{jdmp(r[0])},"modid":{jdmp(r[1]):5},"name":{jdmp(r[2]):18},"ordering":{jdmp(r[3])}}}',
|
||||||
filters)
|
[], offset, limit)
|
||||||
elif path == '/delivery_schedules':
|
elif path == '/delivery_schedules':
|
||||||
self.do_GET_delivery_schedules(filters, offset, limit, order)
|
self.do_GET_delivery_schedules(filters, offset, limit, order)
|
||||||
else:
|
else:
|
||||||
|
Reference in New Issue
Block a user