diff --git a/src/Entity.jl b/src/Entity.jl index c41711b48719bf4df408a1c2b1be445391d85ea3..119729b789b6eca53d4ea0414b2c8f67d022d95c 100644 --- a/src/Entity.jl +++ b/src/Entity.jl @@ -1524,15 +1524,23 @@ function set_unit(property::Ref{_Property}, unit::AbstractString) CaosDB.Exceptions.evaluate_return_code(err_code) end -# TODO(henrik, daniel) overload to choose the correct set -# function. +# TODO(henrik, daniel) There is no check for the correct datatype +# here. Should we add this? """ - function set_value(entity::Ref{_Entity}, value::AbstractString) + function set_value( + entity::Ref{_Entity}, + value::Union{AbstractString,Number,Bool,Vector{T}}, + ) where {T<:Union{AbstractString,Number,Bool}} + Set the value of the given `entity` object. Throw an error if it -doesn't have the correct role. +doesn't have the correct role. The value must be either string, +Boolean, Integer, Float, or a vector thereof. """ -function set_value(entity::Ref{_Entity}, value::AbstractString) +function set_value( + entity::Ref{_Entity}, + value::Union{AbstractString,Number,Bool,Vector{T}}, +) where {T<:Union{AbstractString,Number,Bool}} if get_role(entity) != "PROPERTY" throw( @@ -1542,13 +1550,80 @@ function set_value(entity::Ref{_Entity}, value::AbstractString) ) end - err_code = ccall( - (:caosdb_entity_entity_set_value, CaosDB.library_name), - Cint, - (Ref{_Entity}, Cstring), - entity, - value, - ) + in_type = typeof(value) + if in_type <: AbstractString + err_code = ccall( + (:caosdb_entity_entity_set_string_value, CaosDB.library_name), + Cint, + (Ref{_Entity}, Cstring), + entity, + value, + ) + elseif in_type <: Bool + err_code = ccall( + (:caosdb_entity_entity_set_boolean_value, CaosDB.library_name), + Cint, + (Ref{_Entity}, Bool), + entity, + value, + ) + elseif in_type <: Integer + err_code = ccall( + (:caosdb_entity_entity_set_int_value, CaosDB.library_name), + Cint, + (Ref{_Entity}, Clong), + entity, + Clong(value), + ) + elseif in_type <: Number + err_code = ccall( + (:caosdb_entity_entity_set_int_value, CaosDB.library_name), + Cint, + (Ref{_Entity}, Cdouble), + entity, + Cdouble(value), + ) + else + # Type is a vector now + 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), + Cint, + (Ref{_Entity}, Ptr{Ptr{Cchar}}, Cint), + entity, + value, + length, + ) + elseif in_type <: Vector{T} where {T<:Bool} + err_code = ccall( + (:caosdb_entity_entity_set_boolean_list_value, CaosDB.library_name), + Cint, + (Ref{_Entity}, Ptr{Bool}, Cint), + entity, + value, + length, + ) + elseif in_type <: Vector{T} where {T<:Integer} + err_code = ccall( + (:caosdb_entity_entity_set_int_list_value, CaosDB.library_name), + Cint, + (Ref{_Entity}, Ptr{Clong}, Cint), + entity, + Vector{Clong}(value), + length, + ) + elseif integer <: Vector{T} where {T<:Number} + err_code = ccall( + (:caosdb_entity_entity_set_int_list_value, CaosDB.library_name), + Cint, + (Ref{_Entity}, Ptr{Cdouble}, Cint), + entity, + Vector{Cdouble}(value), + length, + ) + end + end CaosDB.Exceptions.evaluate_return_code(err_code) end @@ -1559,14 +1634,85 @@ end Set the value of the given `property` object. """ -function set_value(property::Ref{_Property}, value::AbstractString) - err_code = ccall( - (:caosdb_entity_property_set_value, CaosDB.library_name), - Cint, - (Ref{_Property}, Cstring), - property, - value, - ) +function set_value( + property::Ref{_Property}, + value::Union{AbstractString,Number,Bool,Vector{T}}, +) where {T<:Union{AbstractString,Number,Bool}} + + in_type = typeof(value) + if in_type <: AbstractString + err_code = ccall( + (:caosdb_entity_property_set_string_value, CaosDB.library_name), + Cint, + (Ref{_Property}, Cstring), + property, + value, + ) + elseif in_type <: Bool + err_code = ccall( + (:caosdb_entity_property_set_boolean_value, CaosDB.library_name), + Cint, + (Ref{_Property}, Bool), + property, + value, + ) + elseif in_type <: Integer + err_code = ccall( + (:caosdb_entity_property_set_int_value, CaosDB.library_name), + Cint, + (Ref{_Property}, Clong), + property, + Clong(value), + ) + elseif in_type <: Number + err_code = ccall( + (:caosdb_entity_property_set_int_value, CaosDB.library_name), + Cint, + (Ref{_Property}, Cdouble), + property, + Cdouble(value), + ) + else + # Type is a vector now + 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), + Cint, + (Ref{_Property}, Ptr{Ptr{Cchar}}, Cint), + property, + value, + length, + ) + elseif in_type <: Vector{T} where {T<:Bool} + err_code = ccall( + (:caosdb_entity_property_set_boolean_list_value, CaosDB.library_name), + Cint, + (Ref{_Property}, Ptr{Bool}, Cint), + property, + value, + length, + ) + elseif in_type <: Vector{T} where {T<:Integer} + err_code = ccall( + (:caosdb_entity_property_set_int_list_value, CaosDB.library_name), + Cint, + (Ref{_Property}, Ptr{Clong}, Cint), + property, + Vector{Clong}(value), + length, + ) + elseif integer <: Vector{T} where {T<:Number} + err_code = ccall( + (:caosdb_entity_property_set_int_list_value, CaosDB.library_name), + Cint, + (Ref{_Property}, Ptr{Cdouble}, Cint), + property, + Vector{Cdouble}(value), + length, + ) + end + end CaosDB.Exceptions.evaluate_return_code(err_code) end diff --git a/test/runtests.jl b/test/runtests.jl index bda1115c720e03d3a1b800508aac06b8b6fdfd99..ca2eedff8eed918349989b77f01f0f57501a0760 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -138,10 +138,7 @@ using CaosDB CaosDB.Entity.get_parent(rec_with_parent_and_props, Cint(1)), ) == "Parent2" - # TODO(henrik, daniel) re-enable once values can be set again - prop1 = CaosDB.Entity.create_property( - name = "Property1", # value = "2" - ) + prop1 = CaosDB.Entity.create_property(name = "Property1", value = "2") prop2 = CaosDB.Entity.create_property(id = "id_of_property_2") CaosDB.Entity.set_datatype(prop2, "TEXT") prop3 = CaosDB.Entity.create_property(name = "Property3") @@ -168,4 +165,12 @@ using CaosDB CaosDB.Entity.get_properties(rec_with_parent_and_props)[2], ) == "Property3" 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 + end end