Coverage for postrfp/shared/fetch/searchq.py: 100%
22 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-22 21:34 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2025-10-22 21:34 +0000
1from typing import (
2 List,
3 Sequence,
4 Dict,
5 Any,
6)
8from sqlalchemy import text
9from sqlalchemy.orm import Session
11from postrfp.model.questionnaire.b36 import from_b36
13from postrfp.model import misc # nopep8 # noqa: F403
14from postrfp.templates import get_template # nopep8 # noqa: F403
17def search(
18 session: Session,
19 org_id: str,
20 search_term: str,
21 search_options: Sequence[str],
22 project_id: int,
23 offset: int,
24) -> List[Dict[str, Any]]:
25 """
26 Run a search query.
27 'search_options' must be a sequence of strings. valid values:
28 "answers", "questions", "notes", "scoreComments"
29 """
30 available_options = {"answers", "questions", "notes", "scoreComments"}
32 if not set(search_options) <= available_options:
33 raise ValueError(
34 f"search_options {search_options} contains values not in {available_options}"
35 )
37 tmpl = get_template("sql/evaluator_search.sql")
38 sql = tmpl.render(options=set(search_options), project_id=project_id)
39 sql_text = text(sql)
40 params = {
41 "orgId": org_id,
42 "search_term": misc.clean_search_term(search_term),
43 "offset": int(offset),
44 }
45 hit_list = []
46 for row in session.execute(sql_text, params=params).fetchall():
47 doc = dict(row._mapping)
48 try:
49 doc["object_ref"] = from_b36(row.object_ref)
50 except TypeError:
51 pass
52 hit_list.append(doc)
53 return hit_list