Skip to content

Commit b669385

Browse files
committed
Added IntendedExtentType mapping class and builder logic for diagnostic test intended extent filtering
1 parent 44aad50 commit b669385

File tree

4 files changed

+106
-34
lines changed

4 files changed

+106
-34
lines changed

classes/intended_extent_type.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
class IntendedExtentType:
2+
"""
3+
Maps intended extent values to nullability flags or valid value IDs.
4+
"""
5+
6+
NULL = "null"
7+
NOT_NULL = "not null"
8+
9+
_label_to_id = {
10+
"full": 9201,
11+
"partial": 9202,
12+
"none": 9203,
13+
# Add others as needed
14+
}
15+
16+
_null_flags = {NULL, NOT_NULL}
17+
18+
@classmethod
19+
def from_description(cls, description: str):
20+
key = description.strip().lower()
21+
if key in cls._null_flags:
22+
return key
23+
if key in cls._label_to_id:
24+
return cls._label_to_id[key]
25+
raise ValueError(f"Unknown intended extent: '{description}'")
26+
27+
@classmethod
28+
def get_id(cls, description: str) -> int:
29+
key = description.strip().lower()
30+
if key not in cls._label_to_id:
31+
raise ValueError(f"No ID available for intended extent: '{description}'")
32+
return cls._label_to_id[key]
33+
34+
@classmethod
35+
def get_description(cls, sentinel: str) -> str:
36+
if sentinel == cls.NULL:
37+
return "NULL"
38+
if sentinel == cls.NOT_NULL:
39+
return "NOT NULL"
40+
raise ValueError(f"Invalid sentinel: '{sentinel}'")

utils/oracle/mock_selection_builder.py

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,35 +7,43 @@
77

88

99
# Add helper class stubs below
10-
class DiagnosticTestHasOutcomeOfResult:
10+
class IntendedExtentType:
1111
"""
12-
Maps outcome-of-result criteria values to either flags or valid value IDs.
12+
Resolves intended extent descriptions to valid value IDs or null-check constants.
1313
"""
1414

15-
YES = "yes"
16-
NO = "no"
15+
NULL = "null"
16+
NOT_NULL = "not null"
1717

1818
_mapping = {
19-
"yes": YES,
20-
"no": NO,
21-
"referred": 9101,
22-
"treated": 9102,
23-
"not required": 9103,
19+
"null": NULL,
20+
"not null": NOT_NULL,
21+
"full": 9201,
22+
"partial": 9202,
23+
"none": 9203,
2424
}
2525

2626
@classmethod
2727
def from_description(cls, description: str):
2828
key = description.strip().lower()
2929
if key not in cls._mapping:
30-
raise ValueError(f"Unknown outcome description: '{description}'")
30+
raise ValueError(f"Unknown intended extent: '{description}'")
3131
return cls._mapping[key]
3232

3333
@classmethod
3434
def get_id(cls, description: str) -> int:
3535
val = cls.from_description(description)
3636
if isinstance(val, int):
3737
return val
38-
raise ValueError(f"No ID associated with outcome: '{description}'")
38+
raise ValueError(f"No ID associated with extent: '{description}'")
39+
40+
@classmethod
41+
def get_description(cls, sentinel: str) -> str:
42+
if sentinel == cls.NULL:
43+
return "NULL"
44+
if sentinel == cls.NOT_NULL:
45+
return "NOT NULL"
46+
raise ValueError(f"Unknown null sentinel: {sentinel}")
3947

4048

4149
class MockSelectionBuilder:
@@ -85,25 +93,22 @@ def _add_join_to_latest_episode(self) -> None:
8593
# Replace this with the one you want to test,
8694
# then use utils/oracle/test_subject_criteria_dev.py to run your scenarios
8795

88-
def _add_criteria_diagnostic_test_has_outcome_of_result(self) -> None:
96+
def _add_criteria_diagnostic_test_intended_extent(self) -> None:
8997
"""
90-
Adds WHERE clause filtering on whether the diagnostic test has an outcome-of-result.
98+
Adds WHERE clause filtering diagnostic tests by intended_extent_id.
99+
Supports null checks and value comparisons.
91100
"""
92101
try:
93102
idx = getattr(self, "criteria_index", 0)
94103
xt = f"xt{idx}"
95-
value = self.criteria_value.strip().lower()
96-
outcome = DiagnosticTestHasOutcomeOfResult.from_description(value)
104+
extent = IntendedExtentType.from_description(self.criteria_value)
97105

98-
self.sql_where.append(f"AND {xt}.outcome_of_result_id ")
106+
self.sql_where.append(f"AND {xt}.intended_extent_id ")
99107

100-
if outcome == DiagnosticTestHasOutcomeOfResult.YES:
101-
self.sql_where.append("IS NOT NULL")
102-
elif outcome == DiagnosticTestHasOutcomeOfResult.NO:
103-
self.sql_where.append("IS NULL")
108+
if extent in (IntendedExtentType.NULL, IntendedExtentType.NOT_NULL):
109+
self.sql_where.append(f"IS {IntendedExtentType.get_description(extent)}")
104110
else:
105-
outcome_id = DiagnosticTestHasOutcomeOfResult.get_id(value)
106-
self.sql_where.append(f"= {outcome_id}")
111+
self.sql_where.append(f"{self.criteria_comparator} {IntendedExtentType.get_id(self.criteria_value)}")
107112

108113
except Exception:
109114
raise SelectionBuilderException(self.criteria_key_name, self.criteria_value)

utils/oracle/subject_selection_query_builder.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
from classes.diagnostic_test_has_outcome_of_result import (
3535
DiagnosticTestHasOutcomeOfResult,
3636
)
37+
from classes.intended_extent_type import IntendedExtentType
3738

3839

3940
class SubjectSelectionQueryBuilder:
@@ -1797,6 +1798,30 @@ def _add_criteria_diagnostic_test_has_outcome_of_result(self) -> None:
17971798
except Exception:
17981799
raise SelectionBuilderException(self.criteria_key_name, self.criteria_value)
17991800

1801+
def _add_criteria_diagnostic_test_intended_extent(self) -> None:
1802+
"""
1803+
Adds WHERE clause filtering diagnostic tests by intended_extent_id.
1804+
Supports null checks and value comparisons.
1805+
"""
1806+
try:
1807+
idx = getattr(self, "criteria_index", 0)
1808+
xt = f"xt{idx}"
1809+
extent = IntendedExtentType.from_description(self.criteria_value)
1810+
1811+
self.sql_where.append(f"AND {xt}.intended_extent_id ")
1812+
1813+
if extent in (IntendedExtentType.NULL, IntendedExtentType.NOT_NULL):
1814+
self.sql_where.append(
1815+
f"IS {IntendedExtentType.get_description(extent)}"
1816+
)
1817+
else:
1818+
self.sql_where.append(
1819+
f"{self.criteria_comparator} {IntendedExtentType.get_id(self.criteria_value)}"
1820+
)
1821+
1822+
except Exception:
1823+
raise SelectionBuilderException(self.criteria_key_name, self.criteria_value)
1824+
18001825
# ------------------------------------------------------------------------
18011826
# 🧬 CADS Clinical Dataset Filters
18021827
# ------------------------------------------------------------------------

utils/oracle/test_subject_criteria_dev.py

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,22 +37,24 @@ def make_builder(key, value, index=0):
3737
return b
3838

3939

40-
# === Test: DIAGNOSTIC_TEST_HAS_OUTCOME (yes) ===
41-
b = make_builder(SubjectSelectionCriteriaKey.DIAGNOSTIC_TEST_HAS_OUTCOME, "yes")
42-
b._add_criteria_diagnostic_test_has_outcome_of_result()
43-
print("=== DIAGNOSTIC_TEST_HAS_OUTCOME (yes) ===")
40+
# === Test: DIAGNOSTIC_TEST_INTENDED_EXTENT (null) ===
41+
b = make_builder(SubjectSelectionCriteriaKey.DIAGNOSTIC_TEST_INTENDED_EXTENT, "null")
42+
b._add_criteria_diagnostic_test_intended_extent()
43+
print("=== DIAGNOSTIC_TEST_INTENDED_EXTENT (null) ===")
4444
print(b.dump_sql(), end="\n\n")
4545

46-
# === Test: DIAGNOSTIC_TEST_HAS_OUTCOME (no) ===
47-
b = make_builder(SubjectSelectionCriteriaKey.DIAGNOSTIC_TEST_HAS_OUTCOME, "no", index=1)
48-
b._add_criteria_diagnostic_test_has_outcome_of_result()
49-
print("=== DIAGNOSTIC_TEST_HAS_OUTCOME (no) ===")
46+
# === Test: DIAGNOSTIC_TEST_INTENDED_EXTENT (not null) ===
47+
b = make_builder(
48+
SubjectSelectionCriteriaKey.DIAGNOSTIC_TEST_INTENDED_EXTENT, "not null", index=1
49+
)
50+
b._add_criteria_diagnostic_test_intended_extent()
51+
print("=== DIAGNOSTIC_TEST_INTENDED_EXTENT (not null) ===")
5052
print(b.dump_sql(), end="\n\n")
5153

52-
# === Test: DIAGNOSTIC_TEST_HAS_OUTCOME (treated) ===
54+
# === Test: DIAGNOSTIC_TEST_INTENDED_EXTENT (partial) ===
5355
b = make_builder(
54-
SubjectSelectionCriteriaKey.DIAGNOSTIC_TEST_HAS_OUTCOME, "treated", index=2
56+
SubjectSelectionCriteriaKey.DIAGNOSTIC_TEST_INTENDED_EXTENT, "partial", index=2
5557
)
56-
b._add_criteria_diagnostic_test_has_outcome_of_result()
57-
print("=== DIAGNOSTIC_TEST_HAS_OUTCOME (treated) ===")
58+
b._add_criteria_diagnostic_test_intended_extent()
59+
print("=== DIAGNOSTIC_TEST_INTENDED_EXTENT (partial) ===")
5860
print(b.dump_sql(), end="\n\n")

0 commit comments

Comments
 (0)