1919 WorkspaceUpdates ,
2020)
2121from pydantic import NonNegativeInt
22+ from simcore_postgres_database .models .users import users
2223from simcore_postgres_database .models .workspaces import workspaces
2324from simcore_postgres_database .models .workspaces_access_rights import (
2425 workspaces_access_rights ,
4041_logger = logging .getLogger (__name__ )
4142
4243
43- _SELECTION_ARGS = (
44+ _WORKSPACE_SELECTION_COLS = (
4445 workspaces .c .workspace_id ,
4546 workspaces .c .name ,
4647 workspaces .c .description ,
5253 workspaces .c .trashed_by ,
5354)
5455
55- assert set (Workspace .model_fields ) == {c .name for c in _SELECTION_ARGS } # nosec
56+ assert set (Workspace .model_fields ).issubset (
57+ {c .name for c in _WORKSPACE_SELECTION_COLS } # nosec
58+ ), "part of the data-model is one-to-one to the domain model"
5659assert set (WorkspaceUpdates .model_fields ).issubset ( # nosec
5760 c .name for c in workspaces .columns
58- )
61+ ), "part of the data-model is one-to-one to the domain model"
5962
6063
6164async def create_workspace (
@@ -80,32 +83,54 @@ async def create_workspace(
8083 modified = func .now (),
8184 product_name = product_name ,
8285 )
83- .returning (* _SELECTION_ARGS )
86+ .returning (* _WORKSPACE_SELECTION_COLS )
8487 )
8588 row = await result .first ()
8689 return Workspace .model_validate (row )
8790
8891
89- _access_rights_subquery = (
90- select (
91- workspaces_access_rights .c .workspace_id ,
92- func .jsonb_object_agg (
93- workspaces_access_rights .c .gid ,
94- func .jsonb_build_object (
95- "read" ,
96- workspaces_access_rights .c .read ,
97- "write" ,
98- workspaces_access_rights .c .write ,
99- "delete" ,
100- workspaces_access_rights .c .delete ,
101- ),
92+ def _create_base_query (caller_user_id : UserID , product_name : ProductName ):
93+ # any other access
94+ access_rights_subquery = (
95+ select (
96+ workspaces_access_rights .c .workspace_id ,
97+ func .jsonb_object_agg (
98+ workspaces_access_rights .c .gid ,
99+ func .jsonb_build_object (
100+ "read" ,
101+ workspaces_access_rights .c .read ,
102+ "write" ,
103+ workspaces_access_rights .c .write ,
104+ "delete" ,
105+ workspaces_access_rights .c .delete ,
106+ ),
107+ )
108+ .filter (
109+ workspaces_access_rights .c .read # Filters out entries where "read" is False
110+ )
111+ .label ("access_rights" ),
112+ ).group_by (workspaces_access_rights .c .workspace_id )
113+ ).subquery ("access_rights_subquery" )
114+
115+ # caller's access rights
116+ my_access_rights_subquery = create_my_workspace_access_rights_subquery (
117+ user_id = caller_user_id
118+ )
119+
120+ return (
121+ select (
122+ * _WORKSPACE_SELECTION_COLS ,
123+ access_rights_subquery .c .access_rights ,
124+ my_access_rights_subquery .c .my_access_rights ,
125+ users .c .primary_gid .label ("trashed_by_primary_gid" ),
102126 )
103- .filter (
104- workspaces_access_rights .c .read # Filters out entries where "read" is False
127+ .select_from (
128+ workspaces .join (access_rights_subquery )
129+ .join (my_access_rights_subquery )
130+ .outerjoin (users , workspaces .c .trashed_by == users .c .id )
105131 )
106- .label ("access_rights" ),
107- ).group_by (workspaces_access_rights .c .workspace_id )
108- ).subquery ("access_rights_subquery" )
132+ .where (workspaces .c .product_name == product_name )
133+ )
109134
110135
111136async def list_workspaces_for_user (
@@ -120,21 +145,7 @@ async def list_workspaces_for_user(
120145 limit : NonNegativeInt ,
121146 order_by : OrderBy ,
122147) -> tuple [int , list [UserWorkspaceWithAccessRights ]]:
123- my_access_rights_subquery = create_my_workspace_access_rights_subquery (
124- user_id = user_id
125- )
126-
127- base_query = (
128- select (
129- * _SELECTION_ARGS ,
130- _access_rights_subquery .c .access_rights ,
131- my_access_rights_subquery .c .my_access_rights ,
132- )
133- .select_from (
134- workspaces .join (_access_rights_subquery ).join (my_access_rights_subquery )
135- )
136- .where (workspaces .c .product_name == product_name )
137- )
148+ base_query = _create_base_query (caller_user_id = user_id , product_name = product_name )
138149
139150 if filter_trashed is not None :
140151 base_query = base_query .where (
@@ -178,24 +189,7 @@ async def get_workspace_for_user(
178189 workspace_id : WorkspaceID ,
179190 product_name : ProductName ,
180191) -> UserWorkspaceWithAccessRights :
181- my_access_rights_subquery = create_my_workspace_access_rights_subquery (
182- user_id = user_id
183- )
184-
185- base_query = (
186- select (
187- * _SELECTION_ARGS ,
188- _access_rights_subquery .c .access_rights ,
189- my_access_rights_subquery .c .my_access_rights ,
190- )
191- .select_from (
192- workspaces .join (_access_rights_subquery ).join (my_access_rights_subquery )
193- )
194- .where (
195- (workspaces .c .workspace_id == workspace_id )
196- & (workspaces .c .product_name == product_name )
197- )
198- )
192+ base_query = _create_base_query (caller_user_id = user_id , product_name = product_name )
199193
200194 async with pass_or_acquire_connection (get_asyncpg_engine (app ), connection ) as conn :
201195 result = await conn .stream (base_query )
@@ -229,7 +223,7 @@ async def update_workspace(
229223 (workspaces .c .workspace_id == workspace_id )
230224 & (workspaces .c .product_name == product_name )
231225 )
232- .returning (* _SELECTION_ARGS )
226+ .returning (* _WORKSPACE_SELECTION_COLS )
233227 )
234228 row = await result .first ()
235229 if row is None :
0 commit comments