1616 FolderID ,
1717 FolderQuery ,
1818 FolderScope ,
19- UserFolderAccessRightsDB ,
19+ UserFolder ,
2020)
2121from models_library .groups import GroupID
2222from models_library .products import ProductName
3030from simcore_postgres_database .models .projects_to_folders import projects_to_folders
3131from simcore_postgres_database .models .users import users
3232from simcore_postgres_database .utils_repos import (
33+ get_columns_from_db_model ,
3334 pass_or_acquire_connection ,
3435 transaction_context ,
3536)
4950_unset : Final = UnSet ()
5051
5152
52- _FOLDERS_SELECTION_COLS = (
53- folders_v2 .c .folder_id ,
54- folders_v2 .c .name ,
55- folders_v2 .c .parent_folder_id ,
56- folders_v2 .c .created_by_gid ,
57- folders_v2 .c .created ,
58- folders_v2 .c .modified ,
59- folders_v2 .c .trashed ,
60- folders_v2 .c .trashed_by ,
61- folders_v2 .c .trashed_explicitly ,
62- folders_v2 .c .user_id ,
63- folders_v2 .c .workspace_id ,
64- )
53+ _FOLDER_DB_MODEL_COLS = get_columns_from_db_model (folders_v2 , FolderDB )
6554
6655
6756async def create (
@@ -92,7 +81,7 @@ async def create(
9281 created = func .now (),
9382 modified = func .now (),
9483 )
95- .returning (* _FOLDERS_SELECTION_COLS )
84+ .returning (* _FOLDER_DB_MODEL_COLS )
9685 )
9786 row = await result .first ()
9887 return FolderDB .model_validate (row )
@@ -110,7 +99,7 @@ def _create_private_workspace_query(
11099 )
111100 return (
112101 select (
113- * _FOLDERS_SELECTION_COLS ,
102+ * _FOLDER_DB_MODEL_COLS ,
114103 func .json_build_object (
115104 "read" ,
116105 sa .text ("true" ),
@@ -147,7 +136,7 @@ def _create_shared_workspace_query(
147136
148137 shared_workspace_query = (
149138 select (
150- * _FOLDERS_SELECTION_COLS ,
139+ * _FOLDER_DB_MODEL_COLS ,
151140 workspace_access_rights_subquery .c .my_access_rights ,
152141 )
153142 .select_from (
@@ -191,7 +180,7 @@ async def list_( # pylint: disable=too-many-arguments,too-many-branches
191180 limit : int ,
192181 # order
193182 order_by : OrderBy ,
194- ) -> tuple [int , list [UserFolderAccessRightsDB ]]:
183+ ) -> tuple [int , list [UserFolder ]]:
195184 """
196185 folder_query - Used to filter in which folder we want to list folders.
197186 trashed - If set to true, it returns folders **explicitly** trashed, if false then non-trashed folders.
@@ -266,23 +255,16 @@ async def list_( # pylint: disable=too-many-arguments,too-many-branches
266255 total_count = await conn .scalar (count_query )
267256
268257 result = await conn .stream (list_query )
269- folders : list [UserFolderAccessRightsDB ] = [
270- UserFolderAccessRightsDB .model_validate (row ) async for row in result
258+ folders : list [UserFolder ] = [
259+ UserFolder .model_validate (row ) async for row in result
271260 ]
272261 return cast (int , total_count ), folders
273262
274263
275- def _create_base_select_query (folder_id : FolderID , product_name : ProductName ):
276- return (
277- select (
278- * _FOLDERS_SELECTION_COLS ,
279- users .c .primary_gid .label ("trashed_by_primary_gid" ),
280- )
281- .select_from (folders_v2 .outerjoin (users , folders_v2 .c .trashed_by == users .c .id ))
282- .where (
283- (folders_v2 .c .product_name == product_name )
284- & (folders_v2 .c .folder_id == folder_id )
285- )
264+ def _create_base_select_query (folder_id : FolderID , product_name : ProductName ) -> Select :
265+ return select (* _FOLDER_DB_MODEL_COLS ,).where (
266+ (folders_v2 .c .product_name == product_name )
267+ & (folders_v2 .c .folder_id == folder_id )
286268 )
287269
288270
@@ -369,7 +351,7 @@ async def update(
369351 query = (
370352 (folders_v2 .update ().values (modified = func .now (), ** updated ))
371353 .where (folders_v2 .c .product_name == product_name )
372- .returning (* _FOLDERS_SELECTION_COLS )
354+ .returning (* _FOLDER_DB_MODEL_COLS )
373355 )
374356
375357 if isinstance (folders_id_or_ids , set ):
@@ -587,3 +569,48 @@ async def get_folders_recursively(
587569 final_query = select (folder_hierarchy_cte )
588570 result = await conn .stream (final_query )
589571 return cast (list [FolderID ], [row .folder_id async for row in result ])
572+
573+
574+ async def get_trashed_by_primary_gid (
575+ app : web .Application ,
576+ connection : AsyncConnection | None = None ,
577+ * ,
578+ folder_id : FolderID ,
579+ ) -> GroupID | None :
580+ query = (
581+ sa .select (
582+ users .c .primary_gid .label ("trashed_by_primary_gid" ),
583+ )
584+ .select_from (projects .outerjoin (users , projects .c .trashed_by == users .c .id ))
585+ .where (folders_v2 .c .folder_id == folder_id )
586+ )
587+
588+ async with pass_or_acquire_connection (get_asyncpg_engine (app ), connection ) as conn :
589+ result = await conn .execute (query )
590+ row = result .first ()
591+ return row .trashed_by_primary_gid if row else None
592+
593+
594+ async def batch_get_trashed_by_primary_gid (
595+ app : web .Application ,
596+ connection : AsyncConnection | None = None ,
597+ * ,
598+ folders_ids : list [FolderID ],
599+ ) -> list [GroupID | None ]:
600+
601+ query = (
602+ sa .select (
603+ users .c .primary_gid .label ("trashed_by_primary_gid" ),
604+ )
605+ .select_from (folders_v2 .outerjoin (users , folders_v2 .c .trashed_by == users .c .id ))
606+ .where (folders_v2 .c .folder_id .in_ (folders_ids ))
607+ ).order_by (
608+ * [
609+ folders_v2 .c .folder_id == _id for _id in folders_ids
610+ ] # Preserves the order of folders_ids
611+ )
612+
613+ async with pass_or_acquire_connection (get_asyncpg_engine (app ), connection ) as conn :
614+ result = await conn .execute (query )
615+ rows = result .fetchall ()
616+ return [row .trashed_by_primary_gid for row in rows ]
0 commit comments