Skip to content
Snippets Groups Projects
Verified Commit 61105629 authored by Timm Fitschen's avatar Timm Fitschen
Browse files

Merge branch 'dev' into f-send-mail

parents 065df3d1 63132c67
No related branches found
No related tags found
1 merge request!22Release 0.3
...@@ -39,6 +39,7 @@ treat the match. This occurs in basically three steps: ...@@ -39,6 +39,7 @@ treat the match. This occurs in basically three steps:
import logging import logging
import re import re
import warnings
from abc import ABCMeta, abstractmethod from abc import ABCMeta, abstractmethod
import caosdb as db import caosdb as db
...@@ -367,7 +368,8 @@ def assure_object_is_in_list(obj, containing_object, property_name, ...@@ -367,7 +368,8 @@ def assure_object_is_in_list(obj, containing_object, property_name,
datatype=datatype) datatype=datatype)
if not isinstance(containing_object.get_property(property_name).value, list): if not isinstance(containing_object.get_property(property_name).value, list):
containing_object.get_property(property_name).value = [containing_object.get_property(property_name).value] containing_object.get_property(property_name).value = [
containing_object.get_property(property_name).value]
containing_object.get_property(property_name).datatype = datatype containing_object.get_property(property_name).datatype = datatype
current_list = containing_object.get_property(property_name).value current_list = containing_object.get_property(property_name).value
...@@ -394,11 +396,11 @@ def assure_object_is_in_list(obj, containing_object, property_name, ...@@ -394,11 +396,11 @@ def assure_object_is_in_list(obj, containing_object, property_name,
if contained: if contained:
logger.debug("{} is in {} of entity {}".format( logger.debug("{} is in {} of entity {}".format(
o, property_name, containing_object.id)) o, property_name, containing_object.id))
else: else:
logger.debug("UPDATE: Appending {} to {} of entity {}".format( logger.debug("UPDATE: Appending {} to {} of entity {}".format(
o, property_name, containing_object.id)) o, property_name, containing_object.id))
current_list.append(o) current_list.append(o)
update = True update = True
...@@ -446,7 +448,7 @@ def assure_has_parent(entity, parent, to_be_updated=None, ...@@ -446,7 +448,7 @@ def assure_has_parent(entity, parent, to_be_updated=None,
contained = False contained = False
for el in parents: for el in parents:
if el.name == parent: if el.name.lower() == parent.lower():
contained = True contained = True
break break
...@@ -463,9 +465,6 @@ def assure_has_parent(entity, parent, to_be_updated=None, ...@@ -463,9 +465,6 @@ def assure_has_parent(entity, parent, to_be_updated=None,
if to_be_updated is None: if to_be_updated is None:
get_ids_for_entities_with_names([entity]) get_ids_for_entities_with_names([entity])
# TODO move the unique argument?
# TODO find a better way then force?
if force: if force:
entity.update(unique=unique) entity.update(unique=unique)
else: else:
...@@ -474,18 +473,81 @@ def assure_has_parent(entity, parent, to_be_updated=None, ...@@ -474,18 +473,81 @@ def assure_has_parent(entity, parent, to_be_updated=None,
to_be_updated.append(entity) to_be_updated.append(entity)
def assure_has_property(entity, name, value, to_be_updated=None, def assure_parents_are(entity, parents, to_be_updated=None,
datatype=None): force=False, unique=True):
""" """
Checks whether `entity` has a property `name` with the value `value`. Checks whether `entity` has the provided parents (and only those).
If this is the case this function ends. Otherwise the entity is assigned If this is the case this function ends. Otherwise the entity is assigned
a new parent. The list to_be_updated is supplied, the entity is added to the new parents and the old ones are discarded.
Note that parent matching occurs based on names.
If the list to_be_updated is supplied, the entity is added to
the list in order to indicate, that the entity `entity` should be updated. the list in order to indicate, that the entity `entity` should be updated.
Otherwise it is directly updated Otherwise it is directly updated
parents: single string or list of strings
"""
if not isinstance(parents, list):
parents = [parents]
for i, e in enumerate(parents):
if isinstance(e, db.Entity):
if e.name is None:
raise Exception("Entity should have name")
parents[i] = e.name
if ([p.name.lower() for p in entity.get_parents()]
== [p.lower() for p in parents]):
logger.debug("entity {} has parents {}".format(entity.id, parents))
return
logger.debug("UPDATE: Adding parent {} to entity {}".format(parents,
entity.id))
while len(entity.parents) > 0:
entity.parents.pop()
for parent in parents:
entity.add_parent(parent)
if to_be_updated is None:
get_ids_for_entities_with_names([entity])
if force:
entity.update(unique=unique)
else:
guard.safe_update(entity, unique=unique)
else:
to_be_updated.append(entity)
def assure_has_property(entity, name, value, to_be_updated=None,
datatype=None, setproperty=False):
"""Checks whether `entity` has a property `name` with the value
`value`.
If this is the case this function ends. Otherwise the entity is
assigned a new parent.
Note that property matching occurs based on names.
If the list to_be_updated is supplied, the entity is added to the
list in order to indicate, that the entity `entity` should be
updated. Otherwise it is directly updated
setproperty: boolean, if True, overwrite existing properties.
""" """
if name.lower() == "description": if name.lower() == "description":
warnings.warn("Do not use assure_has_property with 'description'. "
"Use assure_has_description.", DeprecationWarning)
if entity.description == value: if entity.description == value:
return return
else: else:
...@@ -508,6 +570,10 @@ def assure_has_property(entity, name, value, to_be_updated=None, ...@@ -508,6 +570,10 @@ def assure_has_property(entity, name, value, to_be_updated=None,
name.lower()] name.lower()]
contained = False contained = False
if setproperty and len(possible_properties) > 1:
raise ValueError("Trying to set the property value of {} but more"
" than one such properties exist.".format(name))
if isinstance(value, db.Entity): if isinstance(value, db.Entity):
value = value.id value = value.id
...@@ -519,7 +585,7 @@ def assure_has_property(entity, name, value, to_be_updated=None, ...@@ -519,7 +585,7 @@ def assure_has_property(entity, name, value, to_be_updated=None,
if contained: if contained:
logger.debug("entity {} has property {} with value {}".format( logger.debug("entity {} has property {} with value {}".format(
entity.id, name, value)) entity.id, name, value))
return return
...@@ -527,6 +593,9 @@ def assure_has_property(entity, name, value, to_be_updated=None, ...@@ -527,6 +593,9 @@ def assure_has_property(entity, name, value, to_be_updated=None,
"UPDATE: Adding property {} with value {} to entity {}".format( "UPDATE: Adding property {} with value {} to entity {}".format(
name, value, entity.id)) name, value, entity.id))
if setproperty and possible_properties:
entity.properties.remove(possible_properties[0])
if datatype is None: if datatype is None:
entity.add_property(name=name, value=value) entity.add_property(name=name, value=value)
else: else:
...@@ -540,6 +609,23 @@ def assure_has_property(entity, name, value, to_be_updated=None, ...@@ -540,6 +609,23 @@ def assure_has_property(entity, name, value, to_be_updated=None,
to_be_updated.append(entity) to_be_updated.append(entity)
def assure_property_is(entity, name, value, datatype=None, to_be_updated=None,
force=False):
"""
Checks whether `entity` has a Property `name` with the given value.
If this is the case this function ends. Otherwise the entity is assigned
a new property or an existing one is updated.
If the list to_be_updated is supplied, the entity is added to
the list in order to indicate, that the entity `entity` should be updated.
Otherwise it is directly updated
"""
assure_has_property(entity, name, value, to_be_updated=to_be_updated,
datatype=datatype, setproperty=True)
def insert_id_based_on_name(entity): def insert_id_based_on_name(entity):
if entity.name is not None and (entity.id is None or entity.id < 0): if entity.name is not None and (entity.id is None or entity.id < 0):
if isinstance(entity, db.Property): if isinstance(entity, db.Property):
......
...@@ -28,6 +28,7 @@ import caosdb as db ...@@ -28,6 +28,7 @@ import caosdb as db
from caosadvancedtools.cfood import (AbstractCFood, AbstractFileCFood, CMeal, from caosadvancedtools.cfood import (AbstractCFood, AbstractFileCFood, CMeal,
assure_has_parent, assure_has_property, assure_has_parent, assure_has_property,
assure_object_is_in_list, assure_object_is_in_list,
assure_parents_are, assure_property_is,
get_entity_for_path) get_entity_for_path)
from caosadvancedtools.crawler import FileCrawler from caosadvancedtools.crawler import FileCrawler
from caosadvancedtools.example_cfood import ExampleCFood from caosadvancedtools.example_cfood import ExampleCFood
...@@ -156,6 +157,64 @@ class InsertionTest(unittest.TestCase): ...@@ -156,6 +157,64 @@ class InsertionTest(unittest.TestCase):
value=new_int, to_be_updated=to_be_updated) value=new_int, to_be_updated=to_be_updated)
assert to_be_updated[0] is entity assert to_be_updated[0] is entity
def test_property_is(self):
"""Test properties with string, int, float, and Boolean values"""
entity = db.Record()
to_be_updated = []
int_name = "Test int"
types_and_values = {
int_name: ("INT", 5),
"Test float": (db.DOUBLE, 3.14),
"Test bool": (db.BOOLEAN, True),
"Test string": (db.TEXT, "bla")
}
for name, ty_val in types_and_values.items():
entity.add_property(name=name, datatype=ty_val[0],
value=ty_val[1])
assure_property_is(entity=entity, name=name,
value=ty_val[1], to_be_updated=to_be_updated)
assert len(to_be_updated) == 0
# Test overwriting existing values
types_and_values = {
int_name: ("INT", 7),
"Test float": (db.DOUBLE, 3.34),
"Test bool": (db.BOOLEAN, False),
"Test string": (db.TEXT, "blasdkfjlj")
}
for i, (name, ty_val) in enumerate(types_and_values.items()):
assure_property_is(entity=entity, name=name,
value=ty_val[1], to_be_updated=to_be_updated)
assert len(to_be_updated) == i+1
assert entity.get_property(name).value == ty_val[1]
entity.add_property(name="Test float", datatype=db.DOUBLE, value=3.2)
self.assertRaises(Exception, assure_property_is, entity=entity,
name="Test float",
value=4.2, to_be_updated=to_be_updated)
def test_parents_are(self):
entity = db.Record()
to_be_updated = []
assure_parents_are(entity, "parent", to_be_updated)
assert to_be_updated[0] is entity
assure_parents_are(entity, "parent", to_be_updated)
assert len(to_be_updated) == 1
assure_parents_are(entity, ["parent", "other_parent"], to_be_updated)
assert len(to_be_updated) == 2
ps = [p.name for p in entity.get_parents()]
assert "parent" in ps
assert "other_parent" in ps
assure_parents_are(entity, ["parent", "other_parent"], to_be_updated)
assert len(to_be_updated) == 2
assure_parents_are(entity, "yet_another_parent", to_be_updated)
assert len(to_be_updated) == 3
ps = [p.name for p in entity.get_parents()]
assert "yet_another_parent" in ps
assert "parent" not in ps
assert "other_parent" not in ps
class DependendTest(unittest.TestCase): class DependendTest(unittest.TestCase):
def test(self): def test(self):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment