diff --git a/src/caosadvancedtools/json_schema_exporter.py b/src/caosadvancedtools/json_schema_exporter.py index 4854fb528672d41d7a66e58e41064ef173784e69..3ad8214dcfa1e7d4160958b72702be5c162040fa 100644 --- a/src/caosadvancedtools/json_schema_exporter.py +++ b/src/caosadvancedtools/json_schema_exporter.py @@ -33,13 +33,22 @@ def _make_required_list(rt: db.RecordType): if rt.get_importance(prop.name) == db.OBLIGATORY] -def _make_prop_from_prop(prop: db.Property, additional_options_for_text_props: Optional[dict], units_in_description: bool): +def _make_prop_from_prop(prop: db.Property, additional_properties: bool, + name_and_description_in_properties: bool, + additional_options_for_text_props: Optional[dict], + units_in_description: bool): """Return the JSON Schema segment for the given property Parameters ---------- prop : db.Property the property to be transformed + additional_properties : bool, optional + Whether additional propeties will be admitted in the resulting + schema. Optional, default is True. + name_and_description_in_properties : bool, optional + Whether to include name and description in the `properties` section of + the schema to be exported. Optional, default is False. additional_options_for_text_props : Optional[dict] dict of dicts that may contain the keys 'pattern' and 'format' to further define the rules for the JSON Schema segment @@ -49,11 +58,6 @@ def _make_prop_from_prop(prop: db.Property, additional_options_for_text_props: O instead. """ - if prop.is_reference(): - raise NotImplementedError( - "Reference properties are not supported in this version of the json schema exporter." - ) - if prop.datatype == db.TEXT or prop.datatype == db.DATETIME: text_format = None text_pattern = None @@ -94,7 +98,31 @@ def _make_prop_from_prop(prop: db.Property, additional_options_for_text_props: O list_element_prop = db.Property( name=prop.name, datatype=get_list_datatype(prop.datatype, strict=True)) json_prop["items"] = _make_prop_from_prop( - list_element_prop, additional_options_for_text_props, units_in_description) + list_element_prop, additional_properties, + name_and_description_in_properties, additional_options_for_text_props, + units_in_description + ) + elif prop.is_reference(): + if prop.datatype == db.REFERENCE: + # No Record creation since no RT is specified and we don't know what + # schema to use, so only enum of all Records and all Files. + values = _retrieve_enum_values("RECORD") + _retrieve_enum_values("FILE") + json_prop["enum"] = values + elif prop.datatype == db.FILE: + # TODO: different issue + raise NotImplementedError("Files have not been implemented yet.") + else: + values = _retrieve_enum_values(f"RECORD '{prop.datatype}'") + rt = db.execute_query(f"FIND RECORDTYPE '{prop.datatype}'", unique=True) + subschema = _treat_recordtype(rt, additional_properties, + name_and_description_in_properties, + additional_options_for_text_props, + units_in_description) + json_prop["oneOf"] = [ + {"enum": values}, + subschema + ] + else: raise ValueError( f"Unknown or no property datatype. Property {prop.name} with type {prop.datatype}") @@ -122,7 +150,7 @@ def _make_text_property(description="", text_format=None, text_pattern=None): def _retrieve_enum_values(role: str): - possible_values = db.execute_query(f"SELECT name, id FROM '{role}'") + possible_values = db.execute_query(f"SELECT name, id FROM {role}") vals = [] @@ -160,7 +188,8 @@ def _treat_recordtype(rt: db.RecordType, additional_properties: bool = True, f"Property {prop.name} occurs more than once." ) props[prop.name] = _make_prop_from_prop( - prop, additional_options_for_text_props, units_in_description) + prop, additional_properties, name_and_description_in_properties, + additional_options_for_text_props, units_in_description) schema["properties"] = props