diracx-db 0.0.1a15__py3-none-any.whl → 0.0.1a16__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
diracx/db/sql/jobs/db.py CHANGED
@@ -19,6 +19,9 @@ from diracx.core.models import (
19
19
  LimitedJobStatusReturn,
20
20
  ScalarSearchOperator,
21
21
  ScalarSearchSpec,
22
+ SearchSpec,
23
+ SortDirection,
24
+ SortSpec,
22
25
  )
23
26
  from diracx.core.properties import JOB_SHARING, SecurityProperty
24
27
 
@@ -83,14 +86,14 @@ class JobDB(BaseSQLDB):
83
86
 
84
87
  async def search(
85
88
  self,
86
- parameters,
87
- search,
88
- sorts,
89
+ parameters: list[str] | None,
90
+ search: list[SearchSpec],
91
+ sorts: list[SortSpec],
89
92
  *,
90
93
  distinct: bool = False,
91
94
  per_page: int = 100,
92
95
  page: int | None = None,
93
- ) -> list[dict[str, Any]]:
96
+ ) -> tuple[int, list[dict[Any, Any]]]:
94
97
  # Find which columns to select
95
98
  columns = _get_columns(Jobs.__table__, parameters)
96
99
  stmt = select(*columns)
@@ -98,28 +101,45 @@ class JobDB(BaseSQLDB):
98
101
  stmt = apply_search_filters(Jobs.__table__, stmt, search)
99
102
 
100
103
  # Apply any sort constraints
104
+ sort_columns = []
101
105
  for sort in sorts:
102
106
  if sort["parameter"] not in Jobs.__table__.columns:
103
107
  raise InvalidQueryError(
104
108
  f"Cannot sort by {sort['parameter']}: unknown column"
105
109
  )
106
110
  column = Jobs.__table__.columns[sort["parameter"]]
107
- if sort["direction"] == "asc":
108
- column = column.asc()
109
- elif sort["direction"] == "desc":
110
- column = column.desc()
111
+ sorted_column = None
112
+ if sort["direction"] == SortDirection.ASC:
113
+ sorted_column = column.asc()
114
+ elif sort["direction"] == SortDirection.DESC:
115
+ sorted_column = column.desc()
111
116
  else:
112
117
  raise InvalidQueryError(f"Unknown sort {sort['direction']=}")
118
+ sort_columns.append(sorted_column)
119
+
120
+ if sort_columns:
121
+ stmt = stmt.order_by(*sort_columns)
113
122
 
114
123
  if distinct:
115
124
  stmt = stmt.distinct()
116
125
 
126
+ # Calculate total count before applying pagination
127
+ total_count_subquery = stmt.alias()
128
+ total_count_stmt = select(func.count()).select_from(total_count_subquery)
129
+ total = (await self.conn.execute(total_count_stmt)).scalar_one()
130
+
117
131
  # Apply pagination
118
- if page:
119
- raise NotImplementedError("TODO Not yet implemented")
132
+ if page is not None:
133
+ if page < 1:
134
+ raise InvalidQueryError("Page must be a positive integer")
135
+ if per_page < 1:
136
+ raise InvalidQueryError("Per page must be a positive integer")
137
+ stmt = stmt.offset((page - 1) * per_page).limit(per_page)
120
138
 
121
139
  # Execute the query
122
- return [dict(row._mapping) async for row in (await self.conn.stream(stmt))]
140
+ return total, [
141
+ dict(row._mapping) async for row in (await self.conn.stream(stmt))
142
+ ]
123
143
 
124
144
  async def _insertNewJDL(self, jdl) -> int:
125
145
  from DIRAC.WorkloadManagementSystem.DB.JobDBUtils import compressJDL
@@ -314,7 +334,7 @@ class JobDB(BaseSQLDB):
314
334
  from DIRAC.Core.Utilities.ClassAd.ClassAdLight import ClassAd
315
335
  from DIRAC.Core.Utilities.ReturnValues import SErrorException
316
336
 
317
- result = await self.search(
337
+ _, result = await self.search(
318
338
  parameters=[
319
339
  "Status",
320
340
  "MinorStatus",
@@ -43,7 +43,7 @@ async def set_job_status(
43
43
  for key, value in status.items():
44
44
  statusDict[key] = {k: v for k, v in value.dict().items() if v is not None}
45
45
 
46
- res = await job_db.search(
46
+ _, res = await job_db.search(
47
47
  parameters=["Status", "StartExecTime", "EndExecTime"],
48
48
  search=[
49
49
  {
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: diracx-db
3
- Version: 0.0.1a15
3
+ Version: 0.0.1a16
4
4
  Summary: TODO
5
5
  License: GPL-3.0-only
6
6
  Classifier: Intended Audience :: Science/Research
@@ -14,14 +14,14 @@ diracx/db/sql/dummy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
14
14
  diracx/db/sql/dummy/db.py,sha256=5PIPv6aKY7CGIwmvnGKowjVr9ZQWpbjFSd2PIX7YOUw,1627
15
15
  diracx/db/sql/dummy/schema.py,sha256=uEkGDNVZbmJecytkHY1CO-M1MiKxe5w1_h0joJMPC9E,680
16
16
  diracx/db/sql/jobs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
- diracx/db/sql/jobs/db.py,sha256=Y_2mx5kPTeuz6nxXVwGLzTssKsIH6nfnoTvWvilSgxA,29876
17
+ diracx/db/sql/jobs/db.py,sha256=CyQIPX2g5ancBIBEMLijAyTi5HZxTgeVH0qQZ3p3KcU,30722
18
18
  diracx/db/sql/jobs/schema.py,sha256=YkxIdjTkvLlEZ9IQt86nj80eMvOPbcrfk9aisjmNpqY,9275
19
- diracx/db/sql/jobs/status_utility.py,sha256=_3Wdd11ShA4Z6HKr0_D_o8-zPZhdzgFpZSYAyYkH4Q0,10525
19
+ diracx/db/sql/jobs/status_utility.py,sha256=YZzQfU96A062NC4MkB5-0y96TCPq8Y8dfNBEETzPtrw,10528
20
20
  diracx/db/sql/sandbox_metadata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
21
  diracx/db/sql/sandbox_metadata/db.py,sha256=0EDFMfOW_O3pEPTShqBCME9z4j-JKpyYM6-BBccr27E,6303
22
22
  diracx/db/sql/sandbox_metadata/schema.py,sha256=rngYYkJxBhjETBHGLD1CTipDGe44mRYR0wdaFoAJwp0,1400
23
- diracx_db-0.0.1a15.dist-info/METADATA,sha256=FZYiBySbRiAkcMDFxAkmUCoJ1nspddUoq9iD4keaPD8,681
24
- diracx_db-0.0.1a15.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
25
- diracx_db-0.0.1a15.dist-info/entry_points.txt,sha256=xEFGu_zgmPgQPlUeFtdahQfQIboJ1ugFOK8eMio9gtw,271
26
- diracx_db-0.0.1a15.dist-info/top_level.txt,sha256=vJx10tdRlBX3rF2Psgk5jlwVGZNcL3m_7iQWwgPXt-U,7
27
- diracx_db-0.0.1a15.dist-info/RECORD,,
23
+ diracx_db-0.0.1a16.dist-info/METADATA,sha256=-weqkdxDh05swLO8E-bkWpbhm_Zno2qUnRyKy1pzA7c,681
24
+ diracx_db-0.0.1a16.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
25
+ diracx_db-0.0.1a16.dist-info/entry_points.txt,sha256=xEFGu_zgmPgQPlUeFtdahQfQIboJ1ugFOK8eMio9gtw,271
26
+ diracx_db-0.0.1a16.dist-info/top_level.txt,sha256=vJx10tdRlBX3rF2Psgk5jlwVGZNcL3m_7iQWwgPXt-U,7
27
+ diracx_db-0.0.1a16.dist-info/RECORD,,