From c03f15ec8c04e11acca9b19ba715fecbe3d8646a Mon Sep 17 00:00:00 2001 From: Avery Lee Date: Tue, 10 Dec 2024 18:08:51 -0800 Subject: [PATCH] Attempt to move include parameter in GET requests to Cases into database service. --- src/dispatch/case/models.py | 2 -- src/dispatch/case/views.py | 1 + src/dispatch/database/service.py | 33 ++++++++++++++++++++++---------- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/dispatch/case/models.py b/src/dispatch/case/models.py index 7405bd194282..9065db786413 100644 --- a/src/dispatch/case/models.py +++ b/src/dispatch/case/models.py @@ -288,8 +288,6 @@ class CaseReadMinimal(CaseBase): project: ProjectRead reporter: Optional[ParticipantReadMinimal] reported_at: Optional[datetime] = None - tags: Optional[List[TagRead]] = [] - ticket: Optional[TicketRead] = None total_cost: float | None triage_at: Optional[datetime] = None diff --git a/src/dispatch/case/views.py b/src/dispatch/case/views.py index 34de7640e621..bc70665bf1d0 100644 --- a/src/dispatch/case/views.py +++ b/src/dispatch/case/views.py @@ -117,6 +117,7 @@ def get_cases( expand: bool = Query(default=False), ): """Retrieves all cases.""" + common["include_keys"] = include pagination = search_filter_sort_paginate(model="Case", **common) if expand: diff --git a/src/dispatch/database/service.py b/src/dispatch/database/service.py index ba326ff4edea..d966be4c4cce 100644 --- a/src/dispatch/database/service.py +++ b/src/dispatch/database/service.py @@ -341,8 +341,7 @@ def apply_filters(query, filter_spec, model_cls=None, do_auto_join=True): return query -def apply_filter_specific_joins(model: Base, filter_spec: dict, query: orm.query): - """Applies any model specific implicitly joins.""" +def get_model_map(filters: dict) -> dict: # this is required because by default sqlalchemy-filter's auto-join # knows nothing about how to join many-many relationships. model_map = { @@ -371,19 +370,21 @@ def apply_filter_specific_joins(model: Base, filter_spec: dict, query: orm.query (SignalInstance, "EntityType"): (SignalInstance.entities, True), (Tag, "TagType"): (Tag.tag_type, False), } - filters = build_filters(filter_spec) - # Replace mapping if looking for commander - if "Commander" in str(filter_spec): + if "Commander" in filters: model_map.update({(Incident, "IndividualContact"): (Incident.commander, True)}) - if "Assignee" in str(filter_spec): + if "Assignee" in filters: model_map.update({(Case, "IndividualContact"): (Case.assignee, True)}) + return model_map - filter_models = get_named_models(filters) + +def apply_model_specific_joins(model: Base, models: List[str], query: orm.query): + model_map = get_model_map(models) joined_models = [] - for filter_model in filter_models: - if model_map.get((model, filter_model)): - joined_model, is_outer = model_map[(model, filter_model)] + + for include_model in models: + if model_map.get((model, include_model)): + joined_model, is_outer = model_map[(model, include_model)] try: if joined_model not in joined_models: query = query.join(joined_model, isouter=is_outer) @@ -394,6 +395,14 @@ def apply_filter_specific_joins(model: Base, filter_spec: dict, query: orm.query return query +def apply_filter_specific_joins(model: Base, filter_spec: dict, query: orm.query): + """Applies any model specific implicitly joins.""" + filters = build_filters(filter_spec) + filter_models = get_named_models(filters) + + return apply_model_specific_joins(model, filter_models, query) + + def composite_search(*, db_session, query_str: str, models: List[Base], current_user: DispatchUser): """Perform a multi-table search based on the supplied query.""" s = CompositeSearch(db_session, models) @@ -537,6 +546,7 @@ def search_filter_sort_paginate( model, query_str: str = None, filter_spec: str | dict | None = None, + include_keys: List[str] = None, page: int = 1, items_per_page: int = 5, sort_by: List[str] = None, @@ -574,6 +584,9 @@ def search_filter_sort_paginate( else: query = apply_filters(query, filter_spec, model_cls) + if include_keys: + query = apply_model_specific_joins(model_cls, include_keys, query) + if model == "Incident": query = query.intersect(query_restricted) for filter in tag_all_filters: