From eb57ac6c16bbf99297876ad2249fd9c586125838 Mon Sep 17 00:00:00 2001
From: florian <f.spreckelsen@inidscale.com>
Date: Sat, 21 Aug 2021 10:07:52 +0200
Subject: [PATCH] ENH: Check that only properties can have a datatype

---
 src/Entity.jl    | 52 ++++++++++++++++++++++++++++++++++++++----------
 test/runtests.jl |  5 +++++
 2 files changed, 46 insertions(+), 11 deletions(-)

diff --git a/src/Entity.jl b/src/Entity.jl
index cfe4493..8f01a03 100644
--- a/src/Entity.jl
+++ b/src/Entity.jl
@@ -603,11 +603,13 @@ function get_description(message::Ref{_Message})
     return unsafe_string(out[])
 end
 
-# TODO(henrik, daniel) Include Bools for list and reference here. How should they be returned to the user? 
+# TODO(henrik, daniel) Is this the best way to return name, is_ref,
+# and is_list to the users? Should we split it up?
 """
     function get_datatype(entity::Ref{_Entity})
 
-Return the datatype of the given `entity`
+Return a tuple that contains the name of the datatype of the given
+`entity`, whether it is a reference, and whether it is a list. 
 """
 function get_datatype(entity::Ref{_Entity})
 
@@ -633,7 +635,8 @@ end
 """
     function get_datatype(entity::Ref{_Property})
 
-Return the datatype of the given `property`
+Return a tuple that contains the name of the datatype of the given
+`property`, whether it is a reference, and whether it is a list.
 """
 function get_datatype(property::Ref{_Property})
 
@@ -1389,14 +1392,22 @@ function set_description(entity::Ref{_Entity}, description::AbstractString)
     CaosDB.Exceptions.evaluate_return_code(err_code)
 end
 
-# TODO(henrik, daniel) Should throw an error if role != PROPERTY since
-# it is silently ignored by C(++) otherwise. Also include bools for
-# lists and references. Convenience functions for lists and
-# references, too?
+# TODO(henrik, daniel) Convenience functions for lists and references,
+# too?
 """
-    function set_datatype(entity::Ref{_Entity}, datatype::AbstractString)
+    function set_datatype(
+        entity::Ref{_Entity}, 
+        datatype::AbstractString;
+        is_list::Bool = false,
+        is_reference::Bool = false,
+    )
 
-Set the datatype of the given `entity` object.
+Set the datatype of the given `entity` object to the given `datatype`
+name. Only possible if the role of the entity is "PROPERTY". Specify
+whether it is a reference or a list with the optional `is_list` and
+`is_reference` keyword arguments. If the datatype is not a reference,
+it is checked against the Atomic Datatypes known to CaosDB and an
+exception is thrown if it is not known.
 """
 function set_datatype(
     entity::Ref{_Entity},
@@ -1404,6 +1415,15 @@ function set_datatype(
     is_list::Bool = false,
     is_reference::Bool = false,
 )
+
+    if get_role(entity) != "PROPERTY"
+        throw(
+            CaosDB.Exceptions.ClientException(
+                "Only entities with role PROPERTY can be assigned a datatype.",
+            ),
+        )
+    end
+
     err_code = ccall(
         (:caosdb_entity_entity_set_datatype, CaosDB.library_name),
         Cint,
@@ -1419,9 +1439,19 @@ end
 
 
 """
-    function set_datatype(property::Ref{_Property}, datatype::AbstractString)
+    function set_datatype(
+        property::Ref{_Property}, 
+        datatype::AbstractString;
+        is_list::Bool = false,
+        is_reference::Bool = false,
+    )
 
-Set the datatype of the given `property` object.
+Set the datatype of the given `property` object to the given
+`datatype` name. Specify whether it is a reference or a list with the
+optional `is_list` and `is_reference` keyword arguments. If the
+datatype is not a reference, it is checked against the Atomic
+Datatypes known to CaosDB and an exception is thrown if it is not
+known.
 """
 function set_datatype(
     property::Ref{_Property},
diff --git a/test/runtests.jl b/test/runtests.jl
index a37bcd8..bda1115 100644
--- a/test/runtests.jl
+++ b/test/runtests.jl
@@ -111,6 +111,11 @@ using CaosDB
             rec_with_parent_and_props,
             "some_id",
         )
+        # cannot set the datatype of a record
+        @test_throws CaosDB.Exceptions.ClientException CaosDB.Entity.set_datatype(
+            rec_with_parent_and_props,
+            "INTEGER",
+        )
 
         par1 = CaosDB.Entity.create_parent(name = "Parent1")
         par2 = CaosDB.Entity.create_parent(name = "Parent2", id = "id_of_parent_2")
-- 
GitLab