diff --git a/CHANGELOG.md b/CHANGELOG.md index 4fde278f4931ceae2d2e0f87d376c6d1b7f1e1dc..4134859fad83374c1666ce8a23d88d6b3d22df27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,4 +25,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +* `get_value` functions for properties and entities + ### Security diff --git a/src/CaosDB.jl b/src/CaosDB.jl index db7ca7f20a8d45053e1f9a78240305b0eea372f0..6122a0baf4541346ebc67436956ad0594dc92bab 100644 --- a/src/CaosDB.jl +++ b/src/CaosDB.jl @@ -52,6 +52,7 @@ export get_id, get_datatype, get_unit, get_value, + get_property_list_length, get_version_id, get_property, get_properties, diff --git a/src/Entity.jl b/src/Entity.jl index d0527e7161b2d223a820fe3be6b2a8cbf476dc8d..9c23a8ee1794bbd5710b829b8f29d6b7124bfb3c 100644 --- a/src/Entity.jl +++ b/src/Entity.jl @@ -39,6 +39,7 @@ export get_id, get_datatype, get_unit, get_value, + get_property_list_length, get_version_id, get_property, get_properties, @@ -756,10 +757,6 @@ function get_unit(property::Ref{_Property}) return unsafe_string(out[]) end -# TODO(henrik,daniel) Replace ccall within the `get_value` function by -# a check of the datatype and then call the correct function in case -# of scalar values or construct a vector and fill it with all values -# in case of list values. """ function get_value(entity::Ref{_Entity}) @@ -767,41 +764,422 @@ Return the value of the given `entity` """ function get_value(entity::Ref{_Entity}) - out = Ref{Ptr{UInt8}}(Ptr{UInt8}()) + _caosdb_dtypes = ("INTEGER", "DOUBLE", "BOOLEAN", "TEXT") + + ent_datatype = get_datatype(entity) + is_list = ent_datatype[3] + if ent_datatype[1] in _caosdb_dtypes + if !is_list + if ent_datatype[1] == "INTEGER" + out = Ref{Clong}(0) + err_code = ccall( + (:caosdb_entity_entity_get_int_value, CaosDB.library_name), + Cint, + (Ref{_Entity}, Ref{Clong}), + entity, + out, + ) + + out = out[] + elseif ent_datatype[1] == "DOUBLE" + out = Ref{Cdouble}(0) + err_code = ccall( + (:caosdb_entity_entity_get_double_value, CaosDB.library_name), + Cint, + (Ref{_Entity}, Ref{Cdouble}), + entity, + out, + ) + out = out[] + elseif ent_datatype[1] == "BOOLEAN" + out = Ref{Cint}(0) + err_code = ccall( + (:caosdb_entity_entity_get_boolean_value, CaosDB.library_name), + Cint, + (Ref{_Entity}, Ref{Cint}), + entity, + out, + ) + out = convert(Bool, out[]) + elseif ent_datatype[1] == "TEXT" + out = Ref{Ptr{UInt8}}(Ptr{UInt8}()) + err_code = ccall( + (:caosdb_entity_entity_get_string_value, CaosDB.library_name), + Cint, + (Ref{_Entity}, Ref{Ptr{UInt8}}), + entity, + out, + ) + out = unsafe_string(out[]) + end + else + list_length = get_property_list_length(entity) + if ent_datatype[1] == "INTEGER" + out = Vector{Clong}() + for i::Cint = 1:list_length + temp = get_int_list_value_at(entity, i) + append!(out, temp) + end + elseif ent_datatype[1] == "DOUBLE" + out = Vector{Cdouble}() + for i::Cint = 1:list_length + temp = get_double_list_value_at(entity, i) + append!(out, temp) + end + elseif ent_datatype[1] == "BOOLEAN" + out = Vector{Bool}() + for i::Cint = 1:list_length + temp = get_bool_list_value_at(entity, i) + append!(out, temp) + end + elseif ent_datatype[1] == "TEXT" + out = Vector{String}() + for i::Cint = 1:list_length + temp = get_string_list_value_at(entity, i) + append!(out, [temp]) + end + end + end + elseif ent_datatype[2] + # is reference + if !is_list + out = Ref{Ptr{UInt8}}(Ptr{UInt8}()) + err_code = ccall( + (:caosdb_entity_entity_get_string_value, CaosDB.library_name), + Cint, + (Ref{_Entity}, Ref{Ptr{UInt8}}), + entity, + out, + ) + out = unsafe_string(out[]) + else + # is list of references + list_length = get_property_list_length(entity) + out = [get_string_list_value_at(entity, Cint(ii)) for ii = 1:list_length] + end + end + + if @isdefined err_code + CaosDB.Exceptions.evaluate_return_code(err_code) + end + + return out +end + +""" + function get_value(property::Ref{_Property}) + +Return the value of the given `property` +""" +function get_value(property::Ref{_Property}) + + _caosdb_dtypes = ("INTEGER", "DOUBLE", "BOOLEAN", "TEXT") + + prop_datatype = get_datatype(property) + is_list = prop_datatype[3] + if prop_datatype[1] in _caosdb_dtypes + if !is_list + if prop_datatype[1] == "INTEGER" + out = Ref{Clong}(0) + err_code = ccall( + (:caosdb_entity_property_get_int_value, CaosDB.library_name), + Cint, + (Ref{_Property}, Ref{Clong}), + property, + out, + ) + + out = out[] + elseif prop_datatype[1] == "DOUBLE" + out = Ref{Cdouble}(0) + err_code = ccall( + (:caosdb_entity_property_get_double_value, CaosDB.library_name), + Cint, + (Ref{_Property}, Ref{Cdouble}), + property, + out, + ) + out = out[] + elseif prop_datatype[1] == "BOOLEAN" + out = Ref{Cint}(0) + err_code = ccall( + (:caosdb_entity_property_get_boolean_value, CaosDB.library_name), + Cint, + (Ref{_Property}, Ref{Cint}), + property, + out, + ) + out = convert(Bool, out[]) + elseif prop_datatype[1] == "TEXT" + out = Ref{Ptr{UInt8}}(Ptr{UInt8}()) + err_code = ccall( + (:caosdb_entity_property_get_string_value, CaosDB.library_name), + Cint, + (Ref{_Property}, Ref{Ptr{UInt8}}), + property, + out, + ) + out = unsafe_string(out[]) + end + else + list_length = get_property_list_length(property) + if prop_datatype[1] == "INTEGER" + out = Vector{Clong}() + for i::Cint = 1:list_length + temp = get_int_list_value_at(property, i) + append!(out, temp) + end + elseif prop_datatype[1] == "DOUBLE" + out = Vector{Cdouble}() + for i::Cint = 1:list_length + temp = get_double_list_value_at(property, i) + append!(out, temp) + end + elseif prop_datatype[1] == "BOOLEAN" + out = Vector{Bool}() + for i::Cint = 1:list_length + temp = get_bool_list_value_at(property, i) + append!(out, temp) + end + elseif prop_datatype[1] == "TEXT" + out = Vector{String}() + for i::Cint = 1:list_length + temp = get_string_list_value_at(property, i) + append!(out, [temp]) + end + end + end + elseif prop_datatype[2] + # is reference + if !is_list + out = Ref{Ptr{UInt8}}(Ptr{UInt8}()) + err_code = ccall( + (:caosdb_entity_property_get_string_value, CaosDB.library_name), + Cint, + (Ref{_Property}, Ref{Ptr{UInt8}}), + property, + out, + ) + out = unsafe_string(out[]) + else + # is list of references + list_length = get_property_list_length(property) + out = [get_string_list_value_at(property, Cint(ii)) for ii = 1:list_length] + end + end + if @isdefined err_code + CaosDB.Exceptions.evaluate_return_code(err_code) + end + + return out +end + +""" + function get_property_list_length(property::Ref{_Property}) + +Return the length of the list of the given `property` +""" +function get_property_list_length(property::Ref{_Property}) + + length = Ref{Cint}(0) err_code = ccall( - (:caosdb_entity_entity_get_value, CaosDB.library_name), + (:caosdb_entity_property_get_value_list_length, CaosDB.library_name), Cint, - (Ref{_Entity}, Ref{Ptr{UInt8}}), + (Ref{_Property}, Ref{Cint}), + property, + length, + ) + + CaosDB.Exceptions.evaluate_return_code(err_code) + + return length[] +end + +""" + function get_property_list_length(entity::Ref{_Entity}) + +Return the length of the list of the given `entity` +""" +function get_property_list_length(entity::Ref{_Entity}) + + length = Ref{Cint}(0) + + err_code = ccall( + (:caosdb_entity_entity_get_value_list_length, CaosDB.library_name), + Cint, + (Ref{_Entity}, Ref{Cint}), + entity, + length, + ) + + CaosDB.Exceptions.evaluate_return_code(err_code) + + return length[] +end + +""" + function get_int_list_value_at(property::Ref{_Property}, index::Cint) + +Return the value of the INTEGER list of the given `property` at the position `index`. +""" +function get_int_list_value_at(property::Ref{_Property}, index::Cint) + out = Ref{Clong}(0) + err_code = ccall( + (:caosdb_entity_property_get_int_list_value_at, CaosDB.library_name), + Cint, + (Ref{_Property}, Ref{Clong}, Cint), + property, + out, + index - Cint(1), + ) + + CaosDB.Exceptions.evaluate_return_code(err_code) + return out[] +end + +""" + function get_int_list_value_at(entity::Ref{_Entity}, index::Cint) + +Return the value of the INTEGER list of the given `entity` at the position `index`. +""" +function get_int_list_value_at(entity::Ref{_Entity}, index::Cint) + out = Ref{Clong}(0) + err_code = ccall( + (:caosdb_entity_entity_get_int_list_value_at, CaosDB.library_name), + Cint, + (Ref{_Entity}, Ref{Clong}, Cint), entity, out, + index - Cint(1), ) CaosDB.Exceptions.evaluate_return_code(err_code) + return out[] +end - return unsafe_string(out[]) +""" + function get_double_list_value_at(property::Ref{_Property}, index::Cint) + +Return the value of the DOUBLE list of the given `property` at the position `index`. +""" +function get_double_list_value_at(property::Ref{_Property}, index::Cint) + out = Ref{Cdouble}(0) + err_code = ccall( + (:caosdb_entity_property_get_double_list_value_at, CaosDB.library_name), + Cint, + (Ref{_Property}, Ref{Cdouble}, Cint), + property, + out, + index - Cint(1), + ) + + CaosDB.Exceptions.evaluate_return_code(err_code) + return out[] end """ - function get_value(entity::Ref{_Property}) + function get_double_list_value_at(entity::Ref{_Entity}, index::Cint) -Return the value of the given `property` +Return the value of the DOUBLE list of the given `entity` at the position `index`. """ -function get_value(property::Ref{_Property}) +function get_double_list_value_at(entity::Ref{_Entity}, index::Cint) + out = Ref{Cdouble}(0) + err_code = ccall( + (:caosdb_entity_entity_get_double_list_value_at, CaosDB.library_name), + Cint, + (Ref{_Entity}, Ref{Cdouble}, Cint), + entity, + out, + index - Cint(1), + ) - out = Ref{Ptr{UInt8}}(Ptr{UInt8}()) + CaosDB.Exceptions.evaluate_return_code(err_code) + return out[] +end + +""" + function get_bool_list_value_at(property::Ref{_Property}, index::Cint) +Return the value of the BOOLEAN list of the given `property` at the position `index`. +""" +function get_bool_list_value_at(property::Ref{_Property}, index::Cint) + out = Ref{Cint}(0) err_code = ccall( - (:caosdb_entity_property_get_value, CaosDB.library_name), + (:caosdb_entity_property_get_boolean_list_value_at, CaosDB.library_name), Cint, - (Ref{_Property}, Ref{Ptr{UInt8}}), + (Ref{_Property}, Ref{Cint}, Cint), property, out, + index - Cint(1), ) CaosDB.Exceptions.evaluate_return_code(err_code) + out = convert(Bool, out[]) + return out +end - return unsafe_string(out[]) +""" + function get_bool_list_value_at(entity::Ref{_Entity}, index::Cint) + +Return the value of the BOOLEAN list of the given `entity` at the position `index`. +""" +function get_bool_list_value_at(entity::Ref{_Entity}, index::Cint) + out = Ref{Cint}(0) + err_code = ccall( + (:caosdb_entity_entity_get_boolean_list_value_at, CaosDB.library_name), + Cint, + (Ref{_Entity}, Ref{Cint}, Cint), + entity, + out, + index - Cint(1), + ) + + CaosDB.Exceptions.evaluate_return_code(err_code) + out = convert(Bool, out[]) + return out +end + +""" + function get_string_list_value_at(property::Ref{_Property}, index::Cint) + +Return the value of the TEXT list of the given `property` at the position `index`. +""" +function get_string_list_value_at(property::Ref{_Property}, index::Cint) + out = Ref{Ptr{UInt8}}(Ptr{UInt8}()) + err_code = ccall( + (:caosdb_entity_property_get_string_list_value_at, CaosDB.library_name), + Cint, + (Ref{_Property}, Ref{Ptr{UInt8}}, Cint), + property, + out, + index - Cint(1), + ) + + CaosDB.Exceptions.evaluate_return_code(err_code) + out = unsafe_string(out[]) + return out +end + +""" + function get_string_list_value_at(entity::Ref{_Entity}, index::Cint) + +Return the value of the TEXT list of the given `entity` at the position `index`. +""" +function get_string_list_value_at(entity::Ref{_Entity}, index::Cint) + out = Ref{Ptr{UInt8}}(Ptr{UInt8}()) + err_code = ccall( + (:caosdb_entity_entity_get_string_list_value_at, CaosDB.library_name), + Cint, + (Ref{_Entity}, Ref{Ptr{UInt8}}, Cint), + entity, + out, + index - Cint(1), + ) + + CaosDB.Exceptions.evaluate_return_code(err_code) + out = unsafe_string(out[]) + return out end """ @@ -1613,7 +1991,7 @@ function set_value( ) elseif in_type <: Number err_code = ccall( - (:caosdb_entity_entity_set_int_value, CaosDB.library_name), + (:caosdb_entity_entity_set_double_value, CaosDB.library_name), Cint, (Ref{_Entity}, Cdouble), entity, @@ -1621,7 +1999,7 @@ function set_value( ) else # Type is a vector now - length = Cint(length(value)) + vec_length = Cint(length(value)) if in_type <: Vector{T} where {T<:AbstractString} err_code = ccall( (:caosdb_entity_entity_set_string_list_value, CaosDB.library_name), @@ -1629,7 +2007,7 @@ function set_value( (Ref{_Entity}, Ptr{Ptr{Cchar}}, Cint), entity, value, - length, + vec_length, ) elseif in_type <: Vector{T} where {T<:Bool} err_code = ccall( @@ -1638,7 +2016,7 @@ function set_value( (Ref{_Entity}, Ptr{Bool}, Cint), entity, value, - length, + vec_length, ) elseif in_type <: Vector{T} where {T<:Integer} err_code = ccall( @@ -1647,16 +2025,16 @@ function set_value( (Ref{_Entity}, Ptr{Clong}, Cint), entity, Vector{Clong}(value), - length, + vec_length, ) - elseif integer <: Vector{T} where {T<:Number} + elseif in_type <: Vector{T} where {T<:Number} err_code = ccall( - (:caosdb_entity_entity_set_int_list_value, CaosDB.library_name), + (:caosdb_entity_entity_set_double_list_value, CaosDB.library_name), Cint, (Ref{_Entity}, Ptr{Cdouble}, Cint), entity, Vector{Cdouble}(value), - length, + vec_length, ) end end @@ -1702,7 +2080,7 @@ function set_value( ) elseif in_type <: Number err_code = ccall( - (:caosdb_entity_property_set_int_value, CaosDB.library_name), + (:caosdb_entity_property_set_double_value, CaosDB.library_name), Cint, (Ref{_Property}, Cdouble), property, @@ -1710,7 +2088,7 @@ function set_value( ) else # Type is a vector now - length = Cint(length(value)) + vec_length = Cint(length(value)) if in_type <: Vector{T} where {T<:AbstractString} err_code = ccall( (:caosdb_entity_property_set_string_list_value, CaosDB.library_name), @@ -1718,7 +2096,7 @@ function set_value( (Ref{_Property}, Ptr{Ptr{Cchar}}, Cint), property, value, - length, + vec_length, ) elseif in_type <: Vector{T} where {T<:Bool} err_code = ccall( @@ -1727,7 +2105,7 @@ function set_value( (Ref{_Property}, Ptr{Bool}, Cint), property, value, - length, + vec_length, ) elseif in_type <: Vector{T} where {T<:Integer} err_code = ccall( @@ -1736,16 +2114,16 @@ function set_value( (Ref{_Property}, Ptr{Clong}, Cint), property, Vector{Clong}(value), - length, + vec_length, ) - elseif integer <: Vector{T} where {T<:Number} + elseif in_type <: Vector{T} where {T<:Number} err_code = ccall( - (:caosdb_entity_property_set_int_list_value, CaosDB.library_name), + (:caosdb_entity_property_set_double_list_value, CaosDB.library_name), Cint, (Ref{_Property}, Ptr{Cdouble}, Cint), property, Vector{Cdouble}(value), - length, + vec_length, ) end end diff --git a/test/runtests.jl b/test/runtests.jl index aeaef889632063d2b204338418c0a95525e10eb9..b452f8f4d34797600b122315ffe9874f672f72ab 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -146,10 +146,10 @@ using CaosDB @test length(CaosDB.Entity.get_properties(rec_with_parent_and_props)) == 3 # properties can be accessed as a list - # TODO(henrik, daniel) - # @test CaosDB.Entity.get_value( - # CaosDB.Entity.get_properties(rec_with_parent_and_props)[1], - # ) == "2" + # TODO(florian) Fix this once we have a reasonable treatment of value objects in Extern C. + @test_broken CaosDB.Entity.get_value( + CaosDB.Entity.get_properties(rec_with_parent_and_props)[1], + ) == "2" type, is_ref, is_list = CaosDB.Entity.get_datatype( CaosDB.Entity.get_properties(rec_with_parent_and_props)[2], ) @@ -183,11 +183,175 @@ using CaosDB ) end - @testset "Datatype and values" begin - # TODO(hernik, daniel) tests for some kinds of datatypes and - # values. We probably don't need all since the actual - # functions are already being tested in the C++ client but at - # least some strings, numbers, and lists thereof should be - # tested here, too + @testset "Property values and datatypes" begin + @testset "Entity properties" begin + int_prop = + CaosDB.Entity.create_property_entity(name = "IntProp", datatype = "INTEGER") + double_prop = CaosDB.Entity.create_property_entity( + name = "DoubleProp", + datatype = "DOUBLE", + ) + bool_prop = CaosDB.Entity.create_property_entity( + name = "BoolProp", + datatype = "BOOLEAN", + ) + string_prop = + CaosDB.Entity.create_property_entity(name = "StringProp", datatype = "TEXT") + ref_prop = CaosDB.Entity.create_property_entity( + name = "RefProp", + datatype = "MyRefType", + is_reference = true, + ) + CaosDB.Entity.set_value(int_prop, 123) + CaosDB.Entity.set_value(double_prop, 10.246) + CaosDB.Entity.set_value(bool_prop, true) + CaosDB.Entity.set_value(string_prop, "Hello World") + CaosDB.Entity.set_value(ref_prop, "some_id") + @test CaosDB.Entity.get_value(int_prop) == 123 + @test CaosDB.Entity.get_value(double_prop) == 10.246 + @test CaosDB.Entity.get_value(bool_prop) === true + @test CaosDB.Entity.get_value(string_prop) == "Hello World" + @test CaosDB.Entity.get_value(ref_prop) == "some_id" + @test isa(CaosDB.Entity.get_value(int_prop), Integer) + @test isa(CaosDB.Entity.get_value(double_prop), Number) + @test isa(CaosDB.Entity.get_value(bool_prop), Bool) + @test isa(CaosDB.Entity.get_value(string_prop), String) + @test isa(CaosDB.Entity.get_value(ref_prop), String) + @test CaosDB.Entity.get_datatype(int_prop) == ("INTEGER", false, false) + @test CaosDB.Entity.get_datatype(double_prop) == ("DOUBLE", false, false) + @test CaosDB.Entity.get_datatype(bool_prop) == ("BOOLEAN", false, false) + @test CaosDB.Entity.get_datatype(string_prop) == ("TEXT", false, false) + @test CaosDB.Entity.get_datatype(ref_prop) == ("MyRefType", true, false) + + """ Test lists """ + int_list_prop = CaosDB.Entity.create_property_entity( + name = "IntProp", + datatype = "INTEGER", + is_list = true, + ) + double_list_prop = CaosDB.Entity.create_property_entity( + name = "DoubleProp", + datatype = "DOUBLE", + is_list = true, + ) + bool_list_prop = CaosDB.Entity.create_property_entity( + name = "BoolProp", + datatype = "BOOLEAN", + is_list = true, + ) + string_list_prop = CaosDB.Entity.create_property_entity( + name = "StringProp", + datatype = "TEXT", + is_list = true, + ) + ref_list_prop = CaosDB.Entity.create_property_entity( + name = "RefListProp", + datatype = "MyRefType", + is_list = true, + is_reference = true, + ) + CaosDB.Entity.set_value(int_list_prop, [123, 456]) + CaosDB.Entity.set_value(double_list_prop, [10.246, 3.14]) + CaosDB.Entity.set_value(bool_list_prop, [true, false]) + CaosDB.Entity.set_value(string_list_prop, ["Hello", "World"]) + CaosDB.Entity.set_value(ref_list_prop, ["some_id", "another_id"]) + @test CaosDB.Entity.get_value(int_list_prop) == [123, 456] + @test CaosDB.Entity.get_value(double_list_prop) == [10.246, 3.14] + @test CaosDB.Entity.get_value(bool_list_prop) == [true, false] + @test CaosDB.Entity.get_value(string_list_prop) == ["Hello", "World"] + @test CaosDB.Entity.get_value(ref_list_prop) == ["some_id", "another_id"] + @test isa(CaosDB.Entity.get_value(int_list_prop), Vector{Clong}) + @test isa(CaosDB.Entity.get_value(double_list_prop), Vector{Cdouble}) + @test isa(CaosDB.Entity.get_value(bool_list_prop), Vector{Bool}) + @test isa(CaosDB.Entity.get_value(string_list_prop), Vector{String}) + @test isa(CaosDB.Entity.get_value(ref_list_prop), Vector{String}) + @test CaosDB.Entity.get_datatype(int_list_prop) == ("INTEGER", false, true) + @test CaosDB.Entity.get_datatype(double_list_prop) == ("DOUBLE", false, true) + @test CaosDB.Entity.get_datatype(bool_list_prop) == ("BOOLEAN", false, true) + @test CaosDB.Entity.get_datatype(string_list_prop) == ("TEXT", false, true) + @test CaosDB.Entity.get_datatype(ref_list_prop) == ("MyRefType", true, true) + end + @testset "Property properties" begin + int_prop = CaosDB.Entity.create_property(name = "IntProp", datatype = "INTEGER") + double_prop = + CaosDB.Entity.create_property(name = "DoubleProp", datatype = "DOUBLE") + bool_prop = + CaosDB.Entity.create_property(name = "BoolProp", datatype = "BOOLEAN") + string_prop = + CaosDB.Entity.create_property(name = "StringProp", datatype = "TEXT") + ref_prop = CaosDB.Entity.create_property( + name = "RefProp", + datatype = "MyRefType", + is_reference = true, + ) + CaosDB.Entity.set_value(int_prop, 123) + CaosDB.Entity.set_value(double_prop, 10.246) + CaosDB.Entity.set_value(bool_prop, true) + CaosDB.Entity.set_value(string_prop, "Hello World") + CaosDB.Entity.set_value(ref_prop, "some_id") + @test CaosDB.Entity.get_value(int_prop) == 123 + @test CaosDB.Entity.get_value(double_prop) == 10.246 + @test CaosDB.Entity.get_value(bool_prop) === true + @test CaosDB.Entity.get_value(string_prop) == "Hello World" + @test CaosDB.Entity.get_value(ref_prop) == "some_id" + @test isa(CaosDB.Entity.get_value(int_prop), Integer) + @test isa(CaosDB.Entity.get_value(double_prop), Number) + @test isa(CaosDB.Entity.get_value(bool_prop), Bool) + @test isa(CaosDB.Entity.get_value(string_prop), String) + @test isa(CaosDB.Entity.get_value(ref_prop), String) + @test CaosDB.Entity.get_datatype(int_prop) == ("INTEGER", false, false) + @test CaosDB.Entity.get_datatype(double_prop) == ("DOUBLE", false, false) + @test CaosDB.Entity.get_datatype(bool_prop) == ("BOOLEAN", false, false) + @test CaosDB.Entity.get_datatype(string_prop) == ("TEXT", false, false) + @test CaosDB.Entity.get_datatype(ref_prop) == ("MyRefType", true, false) + + """ Test lists """ + int_list_prop = CaosDB.Entity.create_property( + name = "IntProp", + datatype = "INTEGER", + is_list = true, + ) + double_list_prop = CaosDB.Entity.create_property( + name = "DoubleProp", + datatype = "DOUBLE", + is_list = true, + ) + bool_list_prop = CaosDB.Entity.create_property( + name = "BoolProp", + datatype = "BOOLEAN", + is_list = true, + ) + string_list_prop = CaosDB.Entity.create_property( + name = "StringProp", + datatype = "TEXT", + is_list = true, + ) + ref_list_prop = CaosDB.Entity.create_property( + name = "RefListProp", + datatype = "MyRefType", + is_list = true, + is_reference = true, + ) + CaosDB.Entity.set_value(int_list_prop, [123, 456]) + CaosDB.Entity.set_value(double_list_prop, [10.246, 3.14]) + CaosDB.Entity.set_value(bool_list_prop, [true, false]) + CaosDB.Entity.set_value(string_list_prop, ["Hello", "World"]) + CaosDB.Entity.set_value(ref_list_prop, ["some_id", "another_id"]) + @test CaosDB.Entity.get_value(int_list_prop) == [123, 456] + @test CaosDB.Entity.get_value(double_list_prop) == [10.246, 3.14] + @test CaosDB.Entity.get_value(bool_list_prop) == [true, false] + @test CaosDB.Entity.get_value(string_list_prop) == ["Hello", "World"] + @test CaosDB.Entity.get_value(ref_list_prop) == ["some_id", "another_id"] + @test isa(CaosDB.Entity.get_value(int_list_prop), Vector{Clong}) + @test isa(CaosDB.Entity.get_value(double_list_prop), Vector{Cdouble}) + @test isa(CaosDB.Entity.get_value(bool_list_prop), Vector{Bool}) + @test isa(CaosDB.Entity.get_value(string_list_prop), Vector{String}) + @test isa(CaosDB.Entity.get_value(ref_list_prop), Vector{String}) + @test CaosDB.Entity.get_datatype(int_list_prop) == ("INTEGER", false, true) + @test CaosDB.Entity.get_datatype(double_list_prop) == ("DOUBLE", false, true) + @test CaosDB.Entity.get_datatype(bool_list_prop) == ("BOOLEAN", false, true) + @test CaosDB.Entity.get_datatype(string_list_prop) == ("TEXT", false, true) + @test CaosDB.Entity.get_datatype(ref_list_prop) == ("MyRefType", true, true) + end end end