diff --git a/src/caosadvancedtools/json_schema_exporter.py b/src/caosadvancedtools/json_schema_exporter.py index 4aabf50e619d172c7915327918323e074b6db43f..5d18ad066452968abdc04c3c5d0ff1c5ba63a384 100644 --- a/src/caosadvancedtools/json_schema_exporter.py +++ b/src/caosadvancedtools/json_schema_exporter.py @@ -28,6 +28,7 @@ from collections import OrderedDict from typing import Any, Dict, Iterable, List, Optional, Sequence, Tuple, Union import linkahead as db +from linkahead.cached import cached_query, cache_clear from linkahead.common.datatype import get_list_datatype, is_list_datatype from .models.data_model import DataModel @@ -115,6 +116,8 @@ class JsonSchemaExporter: if not multiple_choice: multiple_choice = [] + cache_clear() + self._additional_properties = additional_properties self._name_property_for_new_records = name_property_for_new_records self._description_property_for_new_records = description_property_for_new_records @@ -267,8 +270,12 @@ class JsonSchemaExporter: elif self._no_remote: rt = prop.datatype else: - rt = db.execute_query(f"FIND RECORDTYPE WITH name='{prop_name}'", - unique=True) + results = cached_query(f"FIND RECORDTYPE WITH name='{prop_name}'") + assert len(results) <= 1 + if len(results): + rt = results[0] + else: + rt = db.Entity() subschema, ui_schema = self._make_segment_from_recordtype(rt) if prop.is_reference(): if prop.name: @@ -348,7 +355,7 @@ class JsonSchemaExporter: if self._no_remote: return [] - possible_values = db.execute_query(f"SELECT name, id FROM {role}") + possible_values = cached_query(f"SELECT name, id FROM {role}") vals = [] for val in possible_values: diff --git a/unittests/test_json_schema_exporter.py b/unittests/test_json_schema_exporter.py index 3dc4496b277b7d8034053e8c0e58c1bed7754a2a..b8c1ddd18973fc85a0cd227aac1fafb6708e8d0b 100644 --- a/unittests/test_json_schema_exporter.py +++ b/unittests/test_json_schema_exporter.py @@ -58,6 +58,14 @@ RT21 = GLOBAL_MODEL.get_deep("RT21") RT31 = GLOBAL_MODEL.get_deep("RT31") +def _make_unique(entity, unique: bool): + """Mock the `unique` behavior of execute_query(). + """ + if unique: + return entity + return db.Container().append(entity) + + def _mock_execute_query(query_string, unique=False, **kwargs): """Mock the response to queries for references.""" all_records = db.Container() @@ -83,20 +91,20 @@ def _mock_execute_query(query_string, unique=False, **kwargs): if query_string == "SELECT name, id FROM RECORD 'OtherType'": return other_type_records - elif query_string == "FIND RECORDTYPE WITH name='OtherType'" and unique is True: - return other_type_rt + elif query_string == "FIND RECORDTYPE WITH name='OtherType'": + return _make_unique(other_type_rt, unique) elif query_string == "SELECT name, id FROM RECORD 'ReferencingType'": return referencing_type_records - elif query_string == "FIND RECORDTYPE WITH name='ReferencingType'" and unique is True: - return referencing_type_rt + elif query_string == "FIND RECORDTYPE WITH name='ReferencingType'": + return _make_unique(referencing_type_rt, unique) elif query_string == "SELECT name, id FROM RECORD 'RT1'": return referencing_type_records # wrong types, but who cares for the test? - elif query_string == "FIND RECORDTYPE WITH name='RT1'" and unique is True: - return RT1 - elif query_string == "FIND RECORDTYPE WITH name='RT21'" and unique is True: - return RT21 - elif query_string == "FIND RECORDTYPE WITH name='RT31'" and unique is True: - return RT31 + elif query_string == "FIND RECORDTYPE WITH name='RT1'": + return _make_unique(RT1, unique) + elif query_string == "FIND RECORDTYPE WITH name='RT21'": + return _make_unique(RT21, unique) + elif query_string == "FIND RECORDTYPE WITH name='RT31'": + return _make_unique(RT31, unique) elif query_string == "SELECT name, id FROM RECORD": return all_records elif query_string == "SELECT name, id FROM FILE": @@ -333,6 +341,7 @@ def test_rt_with_list_props(): @patch("linkahead.execute_query", new=Mock(side_effect=_mock_execute_query)) +@patch("linkahead.cached.execute_query", new=Mock(side_effect=_mock_execute_query)) def test_rt_with_references(): rt = db.RecordType() @@ -653,6 +662,7 @@ def test_broken(): @patch("linkahead.execute_query", new=Mock(side_effect=_mock_execute_query)) +@patch("linkahead.cached.execute_query", new=Mock(side_effect=_mock_execute_query)) def test_reference_options(): """Testing miscellaneous options. """ @@ -883,6 +893,7 @@ RT5: @patch("linkahead.execute_query", new=Mock(side_effect=_mock_execute_query)) +@patch("linkahead.cached.execute_query", new=Mock(side_effect=_mock_execute_query)) def test_empty_retrieve(): """Special case: ``do_not_retrieve`` is set, or the retrieve result is empty.""" model_str = """ @@ -925,6 +936,7 @@ RT3: @patch("linkahead.execute_query", new=Mock(side_effect=_mock_execute_query)) +@patch("linkahead.cached.execute_query", new=Mock(side_effect=_mock_execute_query)) def test_multiple_choice(): """Multiple choice is mostyly a matter of UI.""" model_str = """ @@ -965,6 +977,7 @@ RT4: @patch("linkahead.execute_query", new=Mock(side_effect=_mock_execute_query)) +@patch("linkahead.cached.execute_query", new=Mock(side_effect=_mock_execute_query)) def test_uischema(): model_str = """ RT1: @@ -1015,6 +1028,7 @@ RT3: @patch("linkahead.execute_query", new=Mock(side_effect=_mock_execute_query)) +@patch("linkahead.cached.execute_query", new=Mock(side_effect=_mock_execute_query)) def test_schema_customization_with_dicts(): """Testing the ``additional_json_schema`` and ``additional_ui_schema`` parameters.""" model_str = """