Skip to content
Snippets Groups Projects
Commit 661e3285 authored by Alexander Kreft's avatar Alexander Kreft
Browse files

Merge branch 'f-retrieve-substructure' into 'dev'

F retrieve substructure

See merge request !16
parents d2457818 1edbf1f8
No related branches found
No related tags found
2 merge requests!33MAINT: change arguments of create_user,!16F retrieve substructure
Pipeline #14347 passed with warnings
...@@ -52,6 +52,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ...@@ -52,6 +52,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* `etag` property for the `caosdb.Query` class. The etag allows to debug the * `etag` property for the `caosdb.Query` class. The etag allows to debug the
caching and to decide whether the server has changed between queries. caching and to decide whether the server has changed between queries.
* function `_read_config_files` to read `pycaosdb.ini` files from different paths. * function `_read_config_files` to read `pycaosdb.ini` files from different paths.
* function `retrieve_substructure` that recursively adds connected entities.
### Changed ### ### Changed ###
......
...@@ -62,10 +62,21 @@ def is_list_datatype(datatype): ...@@ -62,10 +62,21 @@ def is_list_datatype(datatype):
def is_reference(datatype): def is_reference(datatype):
""" returns whether the value is a reference """Returns whether the value is a reference
FILE and REFERENCE properties are examples, but also datatypes that are FILE and REFERENCE properties are examples, but also datatypes that are
RecordTypes RecordTypes.
Parameters
----------
datatype : str
The datatype to check.
Returns
-------
bool
True if the datatype is a not base datatype or a list of a base datatype.
Otherwise False is returned.
""" """
if datatype is None: if datatype is None:
...@@ -79,6 +90,39 @@ def is_reference(datatype): ...@@ -79,6 +90,39 @@ def is_reference(datatype):
else: else:
return True return True
def get_referenced_recordtype(datatype):
"""Return the record type of the referenced datatype.
Raises
------
ValueError
In cases where datatype is not a reference, the list does not have
a referenced record type or the datatype is a FILE.
Parameters
----------
datatype : str
The datatype to check.
Returns
-------
str
String containing the name of the referenced datatype.
"""
if not is_reference(datatype):
raise ValueError("datatype must be a reference")
if is_list_datatype(datatype):
datatype = get_list_datatype(datatype)
if datatype is None:
raise ValueError("list does not have a list datatype")
if datatype == FILE:
raise ValueError("FILE references are not considered references with a record type")
return datatype
def get_id_of_datatype(datatype): def get_id_of_datatype(datatype):
""" returns the id of a Record Type """ returns the id of a Record Type
......
...@@ -36,11 +36,24 @@ plantuml FILENAME.pu -> FILENAME.png ...@@ -36,11 +36,24 @@ plantuml FILENAME.pu -> FILENAME.png
import os import os
import caosdb as db import caosdb as db
from caosdb.common.datatype import is_reference, get_referenced_recordtype
REFERENCE = "REFERENCE" REFERENCE = "REFERENCE"
def get_description(description_str): def get_description(description_str):
"""Extract and format a description string from a record type or property.
Parameters
----------
description_str : str
The description string that is going to be formatted.
Returns
-------
str
The reformatted description ending in a line break.
"""
words = description_str.split() words = description_str.split()
lines = [] lines = []
lines.append("") lines.append("")
...@@ -211,15 +224,76 @@ package \"The property P references an instance of D\" <<Rectangle>> { ...@@ -211,15 +224,76 @@ package \"The property P references an instance of D\" <<Rectangle>> {
return result return result
def retrieve_substructure(start_record_types, depth, result_id_set=None, result_container=None, cleanup=True):
"""Recursively retrieves CaosDB record types and properties, starting
from given initial types up to a specific depth.
Parameters
----------
start_record_types : Iterable[db.Entity]
Iterable with the entities to be displayed. Starting from these
entities more entities will be retrieved.
depth : int
The maximum depth up to which to retriev sub entities.
result_id_set : set[int]
Used by recursion. Filled with already visited ids.
result_container : db.Container
Used by recursion. Filled with already visited entities.
cleanup : bool
Used by recursion. If True return the resulting result_container.
Don't return anything otherwise.
Returns
-------
db.Container
A container containing all the retrieved entites or None if cleanup is False.
"""
# Initialize the id set and result container for level zero recursion depth:
if result_id_set is None:
result_id_set = set()
if result_container is None:
result_container = db.Container()
for entity in start_record_types:
entity.retrieve()
if entity.id not in result_id_set:
result_container.append(entity)
result_id_set.add(entity.id)
for prop in entity.properties:
if is_reference(prop.datatype) and prop.datatype != db.FILE and depth > 0:
rt = db.RecordType(name=get_referenced_recordtype(prop.datatype)).retrieve()
retrieve_substructure([rt], depth-1, result_id_set, result_container, False)
if prop.id not in result_id_set:
result_container.append(prop)
result_id_set.add(prop.id)
for parent in entity.parents:
rt = db.RecordType(id=parent.id).retrieve()
if parent.id not in result_id_set:
result_container.append(rt)
result_id_set.add(parent.id)
if depth > 0:
retrieve_substructure([rt], depth-1, result_id_set, result_container, False)
if cleanup:
return result_container
return None
def to_graphics(recordtypes, filename): def to_graphics(recordtypes, filename):
""" calls recordtypes_to_plantuml_string(), saves result to file and """Calls recordtypes_to_plantuml_string(), saves result to file and
creates an svg image creates an svg image
plantuml needs to be installed plantuml needs to be installed.
@params:
recordtypes: itrable with the record types to be displayed Parameters
filname: filename of the image (e.g. data_structure; data_structure.pu and ----------
data_structure.svg will be created. recordtypes : Iterable[db.Entity]
Iterable with the entities to be displayed.
filename : str
filename of the image without the extension(e.g. data_structure;
data_structure.pu and data_structure.svg will be created.)
""" """
pu = recordtypes_to_plantuml_string(recordtypes) pu = recordtypes_to_plantuml_string(recordtypes)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment