feat(api, db): support board_id filter on images service get_many()

This commit is contained in:
psychedelicious 2023-06-21 19:56:19 +10:00
parent 3c032c0767
commit 67a75f6895
4 changed files with 51 additions and 6 deletions

View File

@ -221,6 +221,9 @@ async def list_images_with_metadata(
is_intermediate: Optional[bool] = Query( is_intermediate: Optional[bool] = Query(
default=None, description="Whether to list intermediate images" default=None, description="Whether to list intermediate images"
), ),
board_id: Optional[str] = Query(
default=None, description="The board id to filter by"
),
offset: int = Query(default=0, description="The page offset"), offset: int = Query(default=0, description="The page offset"),
limit: int = Query(default=10, description="The number of images per page"), limit: int = Query(default=10, description="The number of images per page"),
) -> OffsetPaginatedResults[ImageDTO]: ) -> OffsetPaginatedResults[ImageDTO]:
@ -232,6 +235,7 @@ async def list_images_with_metadata(
image_origin, image_origin,
categories, categories,
is_intermediate, is_intermediate,
board_id,
) )
return image_dtos return image_dtos

View File

@ -178,6 +178,7 @@ class SqliteBoardImageRecordStorage(BoardImageRecordStorageBase):
offset: int = 0, offset: int = 0,
limit: int = 10, limit: int = 10,
) -> OffsetPaginatedResults[ImageRecord]: ) -> OffsetPaginatedResults[ImageRecord]:
# TODO: this isn't paginated yet?
try: try:
self._lock.acquire() self._lock.acquire()
self._cursor.execute( self._cursor.execute(

View File

@ -82,6 +82,7 @@ class ImageRecordStorageBase(ABC):
image_origin: Optional[ResourceOrigin] = None, image_origin: Optional[ResourceOrigin] = None,
categories: Optional[list[ImageCategory]] = None, categories: Optional[list[ImageCategory]] = None,
is_intermediate: Optional[bool] = None, is_intermediate: Optional[bool] = None,
board_id: Optional[str] = None,
) -> OffsetPaginatedResults[ImageRecord]: ) -> OffsetPaginatedResults[ImageRecord]:
"""Gets a page of image records.""" """Gets a page of image records."""
pass pass
@ -280,20 +281,42 @@ class SqliteImageRecordStorage(ImageRecordStorageBase):
image_origin: Optional[ResourceOrigin] = None, image_origin: Optional[ResourceOrigin] = None,
categories: Optional[list[ImageCategory]] = None, categories: Optional[list[ImageCategory]] = None,
is_intermediate: Optional[bool] = None, is_intermediate: Optional[bool] = None,
board_id: Optional[str] = None,
) -> OffsetPaginatedResults[ImageRecord]: ) -> OffsetPaginatedResults[ImageRecord]:
try: try:
self._lock.acquire() self._lock.acquire()
# Manually build two queries - one for the count, one for the records # Manually build two queries - one for the count, one for the records
count_query = f"""SELECT COUNT(*) FROM images WHERE 1=1\n""" # count_query = """--sql
images_query = f"""SELECT * FROM images WHERE 1=1\n""" # SELECT COUNT(*) FROM images WHERE 1=1
# """
count_query = """--sql
SELECT COUNT(*)
FROM images
LEFT JOIN board_images ON board_images.image_name = images.image_name
WHERE 1=1
"""
images_query = """--sql
SELECT images.*
FROM images
LEFT JOIN board_images ON board_images.image_name = images.image_name
WHERE 1=1
"""
# images_query = """--sql
# SELECT * FROM images WHERE 1=1
# """
query_conditions = "" query_conditions = ""
query_params = [] query_params = []
if image_origin is not None: if image_origin is not None:
query_conditions += f"""AND image_origin = ?\n""" query_conditions += """--sql
AND images.image_origin = ?
"""
query_params.append(image_origin.value) query_params.append(image_origin.value)
if categories is not None: if categories is not None:
@ -301,17 +324,31 @@ class SqliteImageRecordStorage(ImageRecordStorageBase):
category_strings = list(map(lambda c: c.value, set(categories))) category_strings = list(map(lambda c: c.value, set(categories)))
# Create the correct length of placeholders # Create the correct length of placeholders
placeholders = ",".join("?" * len(category_strings)) placeholders = ",".join("?" * len(category_strings))
query_conditions += f"AND image_category IN ( {placeholders} )\n"
query_conditions += f"""--sql
AND images.image_category IN ( {placeholders} )
"""
# Unpack the included categories into the query params # Unpack the included categories into the query params
for c in category_strings: for c in category_strings:
query_params.append(c) query_params.append(c)
if is_intermediate is not None: if is_intermediate is not None:
query_conditions += f"""AND is_intermediate = ?\n""" query_conditions += """--sql
AND images.is_intermediate = ?
"""
query_params.append(is_intermediate) query_params.append(is_intermediate)
query_pagination = f"""ORDER BY created_at DESC LIMIT ? OFFSET ?\n""" if board_id is not None:
query_conditions += """--sql
AND board_images.board_id = ?
"""
query_params.append(board_id)
query_pagination = """--sql
ORDER BY images.created_at DESC LIMIT ? OFFSET ?
"""
# Final images query with pagination # Final images query with pagination
images_query += query_conditions + query_pagination + ";" images_query += query_conditions + query_pagination + ";"

View File

@ -102,6 +102,7 @@ class ImageServiceABC(ABC):
image_origin: Optional[ResourceOrigin] = None, image_origin: Optional[ResourceOrigin] = None,
categories: Optional[list[ImageCategory]] = None, categories: Optional[list[ImageCategory]] = None,
is_intermediate: Optional[bool] = None, is_intermediate: Optional[bool] = None,
board_id: Optional[str] = None,
) -> OffsetPaginatedResults[ImageDTO]: ) -> OffsetPaginatedResults[ImageDTO]:
"""Gets a paginated list of image DTOs.""" """Gets a paginated list of image DTOs."""
pass pass
@ -290,6 +291,7 @@ class ImageService(ImageServiceABC):
image_origin: Optional[ResourceOrigin] = None, image_origin: Optional[ResourceOrigin] = None,
categories: Optional[list[ImageCategory]] = None, categories: Optional[list[ImageCategory]] = None,
is_intermediate: Optional[bool] = None, is_intermediate: Optional[bool] = None,
board_id: Optional[str] = None,
) -> OffsetPaginatedResults[ImageDTO]: ) -> OffsetPaginatedResults[ImageDTO]:
try: try:
results = self._services.image_records.get_many( results = self._services.image_records.get_many(
@ -298,6 +300,7 @@ class ImageService(ImageServiceABC):
image_origin, image_origin,
categories, categories,
is_intermediate, is_intermediate,
board_id,
) )
image_dtos = list( image_dtos = list(