Skip to content

Commit 31a3be9

Browse files
committed
db and repo
1 parent 2fefc34 commit 31a3be9

File tree

2 files changed

+111
-11
lines changed

2 files changed

+111
-11
lines changed

services/web/server/src/simcore_service_webserver/projects/_projects_db.py

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -90,22 +90,16 @@ async def list_trashed_projects(
9090
return cast(int, total_count), folders
9191

9292

93-
async def patch_project(
93+
async def get_project(
9494
app: web.Application,
9595
connection: AsyncConnection | None = None,
9696
*,
9797
project_uuid: ProjectID,
98-
new_partial_project_data: dict,
9998
) -> ProjectDBGet:
100-
101-
async with transaction_context(get_asyncpg_engine(app), connection) as conn:
102-
result = await conn.stream(
103-
projects.update()
104-
.values(last_change_date=sql.func.now(), **new_partial_project_data)
105-
.where(projects.c.uuid == f"{project_uuid}")
106-
.returning(*PROJECT_DB_COLS)
107-
)
108-
row = await result.first()
99+
async with pass_or_acquire_connection(get_asyncpg_engine(app), connection) as conn:
100+
query = sql.select(PROJECT_DB_COLS).where(projects.c.uuid == f"{project_uuid}")
101+
result = await conn.execute(query)
102+
row = result.one_or_none()
109103
if row is None:
110104
raise ProjectNotFoundError(project_uuid=project_uuid)
111105
return ProjectDBGet.model_validate(row)
@@ -170,3 +164,43 @@ async def batch_get_trashed_by_primary_gid(
170164
rows = {row.uuid: row.trashed_by_primary_gid async for row in result}
171165

172166
return [rows.get(uuid) for uuid in projects_uuids_str]
167+
168+
169+
async def patch_project(
170+
app: web.Application,
171+
connection: AsyncConnection | None = None,
172+
*,
173+
project_uuid: ProjectID,
174+
new_partial_project_data: dict,
175+
) -> None:
176+
177+
async with transaction_context(get_asyncpg_engine(app), connection) as conn:
178+
result = await conn.stream(
179+
projects.update()
180+
.values(
181+
**new_partial_project_data,
182+
last_change_date=sql.func.now(),
183+
)
184+
.where(projects.c.uuid == f"{project_uuid}")
185+
)
186+
row = await result.one_or_none()
187+
if row is None:
188+
raise ProjectNotFoundError(project_uuid=project_uuid)
189+
190+
191+
async def delete_project(
192+
app: web.Application,
193+
connection: AsyncConnection | None = None,
194+
*,
195+
project_uuid: ProjectID,
196+
) -> ProjectDBGet:
197+
async with transaction_context(get_asyncpg_engine(app), connection) as conn:
198+
result = await conn.stream(
199+
projects.delete()
200+
.where(projects.c.uuid == f"{project_uuid}")
201+
.returning(*PROJECT_DB_COLS)
202+
)
203+
row = await result.one_or_none()
204+
if row is None:
205+
raise ProjectNotFoundError(project_uuid=project_uuid)
206+
return ProjectDBGet.model_validate(row)
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# NOTE: should replace _crud_api_delete.py:delete_project
2+
3+
import logging
4+
from typing import Protocol
5+
6+
from aiohttp import web
7+
from models_library.projects import ProjectID
8+
from servicelib.redis._errors import ProjectLockError
9+
from simcore_service_director_v2.core.errors import ProjectNotFoundError
10+
from simcore_service_webserver.projects.exceptions import ProjectDeleteError
11+
12+
from . import _projects_db as _projects_repository
13+
14+
_logger = logging.getLogger(__name__)
15+
16+
17+
class StopServicesCallback(Protocol):
18+
async def __call__(self, app: web.Application, project_uuid: ProjectID) -> None:
19+
...
20+
21+
22+
async def delete_project_as_admin(
23+
app: web.Application,
24+
*,
25+
project_uuid: ProjectID,
26+
stop_project_services_as_admin: StopServicesCallback | None,
27+
):
28+
hidden = False
29+
stopped = not stop_project_services_as_admin
30+
deleted = False
31+
32+
try:
33+
# hide
34+
await _projects_repository.patch_project(
35+
app,
36+
project_uuid=project_uuid,
37+
new_partial_project_data={"hidden": True},
38+
)
39+
hidden = True
40+
41+
if stop_project_services_as_admin:
42+
# NOTE: this callback could take long or raise whatever!
43+
await stop_project_services_as_admin(app, project_uuid)
44+
stopped = True
45+
46+
await _projects_repository.delete_project(app, project_uuid=project_uuid)
47+
deleted = True
48+
49+
except ProjectNotFoundError as err:
50+
_logger.debug(
51+
"Project %s being deleted is already gone. IGNORING error. Details: %s",
52+
project_uuid,
53+
err,
54+
)
55+
56+
except ProjectLockError as err:
57+
raise ProjectDeleteError(
58+
project_uuid=project_uuid,
59+
reason=f"Cannot delete project {project_uuid} because it is currently in use. Details: {err}",
60+
) from err
61+
62+
except Exception as err:
63+
raise ProjectDeleteError(
64+
project_uuid=project_uuid,
65+
reason=f"Unexpected error. Deletion sequence: {hidden=}, {stopped=}, {deleted=} ",
66+
) from err

0 commit comments

Comments
 (0)