Skip to content
Snippets Groups Projects
Commit 27605bd7 authored by Alexander Schlemmer's avatar Alexander Schlemmer
Browse files

MAINT: refactored funcction set_property

parent 51f5b5bf
No related branches found
No related tags found
2 merge requests!57RELEASE 0.7.3,!52F refactor high level api
......@@ -31,15 +31,16 @@ This is refactored from apiutils.
"""
from caosdb.common.datatype import (BOOLEAN, DATETIME, DOUBLE, FILE, INTEGER,
REFERENCE, TEXT)
REFERENCE, TEXT, is_list_datatype, get_list_datatype)
import caosdb as db
from .apiutils import get_type_of_entity_with
from typing import Any, Optional
from typing import Any, Optional, List, Union, Dict
from dataclasses import dataclass
@dataclass
class CaosDBPropertyMetaData:
# name is already the name of the attribute
......@@ -79,38 +80,42 @@ class CaosDBPythonEntity(object):
"""
Initialize a new CaosDBPythonEntity for the high level python api.
The new entity is initialized with a new negative ID using _get_id (static).
"""
# Save a copy of the dry state
# of this object in order to be
# able to detect conflicts.
self.do_not_expand = False
self._parents = []
self._id = CaosDBPythonEntity._get_id()
self._path = None
self._file = None
# TODO:
# 3.) resolve references up to a specific depth (including infinity)
# 4.) resolve parents function -> partially implemented by
# get_parent_names
self._references = {}
self._properties = set()
self._datatypes = {}
self._forbidden = dir(self)
Parents are either unresolved references or CaosDB RecordTypes.
@staticmethod
def _get_id():
Properties are stored directly as attributes for the object.
Property metadata is maintained in a dctionary _properties_metadata that should
never be accessed directly, but only using the get_property_metadata function.
If property values are references to other objects, they will be stored as
CaosDBPythonUnresolvedReference objects that can be resolved later into
CaosDBPythonRecords.
"""
Get a new negative ID for a CaosDB Entity.
The first ID is -1 and decremented with each call of this function.
"""
CaosDBPythonEntity._last_id -= 1
# Parents are either unresolved references or CaosDB RecordTypes
self._parents: List[Union[
CaosDBPythonUnresolvedParent, CaosDBPythonRecordType]] = []
# self._id: int = CaosDBPythonEntity._get_new_id()
self._id: Optional[int] = None
self._name: Optional[str] = None
self._description: Optional[str] = None
self._version: Optional[str] = None
# name: name of property, value: property metadata
self._properties_metadata: Dict[CaosDBPropertyMetaData] = dict()
return CaosDBPythonEntity._last_id
# Store all current attributes as forbidden attributes
# which must not be changed by the set_property function.
self._forbidden = dir(self) + ["_forbidden"]
# @staticmethod
# def _get_new_id():
# """
# Get a new negative ID for a CaosDB Entity.
# The first ID is -1 and decremented with each call of this function.
# """
# CaosDBPythonEntity._last_id -= 1
# return CaosDBPythonEntity._last_id
def _set_property_from_entity(self, ent: db.Entity):
"""
......@@ -126,10 +131,37 @@ class CaosDBPythonEntity(object):
val, reference = self._type_converted_value(val, pr)
self.set_property(name, val, reference, datatype=pr)
def get_property_metadata(self, prop_name: str) -> CaosDBPropertyMetaData:
"""
Retrieve the property metadata for the property with name prop_name.
If the property with the given name does not exist or is forbidden, raise an exception.
Else return the metadata associated with this property.
If no metadata does exist yet for the given property, a new object will be created
and returned.
prop_name: str
Name of the property to retrieve metadata for.
"""
if not self.property_exists(prop_name):
raise RuntimeError("The property with name {} does not exist.".format(prop_name))
if prop_name not in self._properties_metadata:
self._properties_metadata[prop_name] = CaosDBPropertyMetaData()
return self._properties_metadata[prop_name]
def property_exists(self, prop_name: str):
"""
Check whether a property exists already.
"""
return prop_name not in self._forbidden and prop_name in self.__dict__
def set_property(self,
name: str,
value: Any,
is_reference: bool = False,
overwrite: bool = False,
datatype: Optional[str] = None):
"""
......@@ -144,8 +176,6 @@ class CaosDBPythonEntity(object):
value: Any
Value of the property.
is_reference: bool
overwrite: bool
Use this if you definitely only want one property with
......@@ -156,8 +186,9 @@ class CaosDBPythonEntity(object):
# Store the datatype (if given) in a hidden field
# The datatypes will be stored in name, value pairs.
# TODO: check whether handling of lists is correct.
self._datatypes[name] = datatype
# TODO: check whether handling of lists and multi properties is correct.
metadata = self.get_property_metadata(name)
metadata.datatype = datatype
if isinstance(name, db.Entity):
# TODO: check, whether this is reasonable?
......@@ -169,7 +200,7 @@ class CaosDBPythonEntity(object):
"Python representation. Name of property " +
name + " is forbidden!")
already_exists = (name in dir(self))
already_exists = self.property_exists(name)
if already_exists and not overwrite:
# each call to set_property checks first if it already exists
......@@ -183,24 +214,12 @@ class CaosDBPythonEntity(object):
else:
old_att = self.__getattribute__(name)
self.__setattr__(name, [old_att])
if is_reference:
self._references[name] = [
self._references[name]]
att = self.__getattribute__(name)
att.append(value)
if is_reference:
self._references[name].append(int(value))
else:
if is_reference:
self._references[name] = value
self.__setattr__(name, value)
if not (already_exists and overwrite):
self._properties.add(name)
add_property = set_property
# add_property = set_property
def set_id(self, idx: int):
"""
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment