From e902daeec9e093b058d3b11dbf61c4ca3f2f969f Mon Sep 17 00:00:00 2001 From: Anuj-Gupta4 Date: Fri, 27 Dec 2024 11:10:59 +0545 Subject: [PATCH 1/3] fix(project): search --- src/backend/app/db/models.py | 2 +- src/backend/app/projects/project_routes.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/backend/app/db/models.py b/src/backend/app/db/models.py index 212d475ee..2d234ccb6 100644 --- a/src/backend/app/db/models.py +++ b/src/backend/app/db/models.py @@ -1185,7 +1185,7 @@ async def all( # Filter by search term (project name using ILIKE for case-insensitive match) if search: - filters.append("slug ILIKE %(search)s") + filters.append("p.slug ILIKE %(search)s") params["search"] = f"%{search}%" # Base query with optional filtering diff --git a/src/backend/app/projects/project_routes.py b/src/backend/app/projects/project_routes.py index 4dcba3985..060780669 100644 --- a/src/backend/app/projects/project_routes.py +++ b/src/backend/app/projects/project_routes.py @@ -144,10 +144,11 @@ async def read_project_summaries( results_per_page: int = Query(13, le=100), user_id: Optional[int] = None, hashtags: Optional[str] = None, + search: Optional[str] = None, ): """Get a paginated summary of projects.""" return await project_crud.get_paginated_projects( - db, page, results_per_page, user_id, hashtags + db, page, results_per_page, user_id, hashtags, search ) From 46f6ddbce70a35a3652b7b41ac8077f81f7e52cf Mon Sep 17 00:00:00 2001 From: Anuj-Gupta4 Date: Fri, 27 Dec 2024 11:11:26 +0545 Subject: [PATCH 2/3] fix(project): pagination --- src/backend/app/projects/project_crud.py | 30 ++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/src/backend/app/projects/project_crud.py b/src/backend/app/projects/project_crud.py index 7bb316303..029446f9d 100644 --- a/src/backend/app/projects/project_crud.py +++ b/src/backend/app/projects/project_crud.py @@ -853,8 +853,8 @@ def generate_project_basemap( async def get_pagination(page: int, count: int, results_per_page: int, total: int): """Pagination result for splash page.""" - total_pages = (count + results_per_page - 1) // results_per_page - has_next = (page * results_per_page) < count # noqa: N806 + total_pages = (total + results_per_page - 1) // results_per_page + has_next = (page * results_per_page) < total # noqa: N806 has_prev = page > 1 # noqa: N806 pagination = project_schemas.PaginationInfo( @@ -892,9 +892,31 @@ async def get_paginated_projects( db, skip=skip, limit=limit, user_id=user_id, hashtags=hashtags, search=search ) - # Count total number of projects for pagination + filters = [] + params = {} + + if user_id: + filters.append("author_id = %(user_id)s") + params["user_id"] = user_id + + if hashtags: + filters.append("hashtags && %(hashtags)s") + params["hashtags"] = hashtags + + if search: + filters.append("slug ILIKE %(search)s") + params["search"] = f"%{search}%" + + where_clause = f"WHERE {' AND '.join(filters)}" if filters else "" + + total_project_count_query = f""" + SELECT COUNT(*) + FROM projects + {where_clause}; + """ + async with db.cursor() as cur: - await cur.execute("SELECT COUNT(*) FROM projects") + await cur.execute(total_project_count_query, params) total_project_count = await cur.fetchone() total_project_count = total_project_count[0] From 2f4cb3f4b54b087e5071efa4b4eaadee8bab3cec Mon Sep 17 00:00:00 2001 From: Anuj-Gupta4 Date: Mon, 30 Dec 2024 13:31:46 +0545 Subject: [PATCH 3/3] refactor(project): pagination --- src/backend/app/db/models.py | 12 +++++-- src/backend/app/projects/project_crud.py | 41 ++++-------------------- 2 files changed, 15 insertions(+), 38 deletions(-) diff --git a/src/backend/app/db/models.py b/src/backend/app/db/models.py index 2d234ccb6..24c990dba 100644 --- a/src/backend/app/db/models.py +++ b/src/backend/app/db/models.py @@ -1163,15 +1163,15 @@ async def one(cls, db: Connection, project_id: int, minimal: bool = False) -> Se async def all( cls, db: Connection, - skip: int = 0, - limit: int = 100, + skip: Optional[int] = None, + limit: Optional[int] = None, user_id: Optional[int] = None, hashtags: Optional[list[str]] = None, search: Optional[str] = None, ) -> Optional[list[Self]]: """Fetch all projects with optional filters for user, hashtags, and search.""" filters = [] - params = {"offset": skip, "limit": limit} + params = {"offset": skip, "limit": limit} if skip and limit else {} # Filter by user_id (project author) if user_id: @@ -1210,9 +1210,15 @@ async def all( p.id, project_org.id ORDER BY p.created_at DESC + """ + sql += ( + """ OFFSET %(offset)s LIMIT %(limit)s; """ + if skip and limit + else ";" + ) async with db.cursor(row_factory=class_row(cls)) as cur: await cur.execute(sql, params) diff --git a/src/backend/app/projects/project_crud.py b/src/backend/app/projects/project_crud.py index 029446f9d..2ec51881f 100644 --- a/src/backend/app/projects/project_crud.py +++ b/src/backend/app/projects/project_crud.py @@ -883,48 +883,19 @@ async def get_paginated_projects( if hashtags: hashtags = hashtags.split(",") - # Calculate pagination offsets - skip = (page - 1) * results_per_page - limit = results_per_page - # Get subset of projects projects = await DbProject.all( - db, skip=skip, limit=limit, user_id=user_id, hashtags=hashtags, search=search + db, user_id=user_id, hashtags=hashtags, search=search ) - - filters = [] - params = {} - - if user_id: - filters.append("author_id = %(user_id)s") - params["user_id"] = user_id - - if hashtags: - filters.append("hashtags && %(hashtags)s") - params["hashtags"] = hashtags - - if search: - filters.append("slug ILIKE %(search)s") - params["search"] = f"%{search}%" - - where_clause = f"WHERE {' AND '.join(filters)}" if filters else "" - - total_project_count_query = f""" - SELECT COUNT(*) - FROM projects - {where_clause}; - """ - - async with db.cursor() as cur: - await cur.execute(total_project_count_query, params) - total_project_count = await cur.fetchone() - total_project_count = total_project_count[0] + start_index = (page - 1) * results_per_page + end_index = start_index + results_per_page + paginated_projects = projects[start_index:end_index] pagination = await get_pagination( - page, len(projects), results_per_page, total_project_count + page, len(paginated_projects), results_per_page, len(projects) ) - return {"results": projects, "pagination": pagination} + return {"results": paginated_projects, "pagination": pagination} async def get_project_users_plus_contributions(db: Connection, project_id: int):