From c181530c972bbc88f09588cfcbcd8a88e49fd681 Mon Sep 17 00:00:00 2001 From: florian <f.spreckelsen@inidscale.com> Date: Mon, 20 Sep 2021 16:11:22 +0200 Subject: [PATCH] Re-implement set_value and get_value --- src/CaosDB.jl | 1 - src/Entity.jl | 664 +++++++++++++------------------------------------- 2 files changed, 166 insertions(+), 499 deletions(-) diff --git a/src/CaosDB.jl b/src/CaosDB.jl index 8bbfd4a..376fa3a 100644 --- a/src/CaosDB.jl +++ b/src/CaosDB.jl @@ -64,7 +64,6 @@ 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 ae7fbb0..54ba7b9 100644 --- a/src/Entity.jl +++ b/src/Entity.jl @@ -39,7 +39,6 @@ export get_id, get_datatype, get_unit, get_value, - get_property_list_length, get_version_id, get_property, get_properties, @@ -998,428 +997,229 @@ function get_unit(property::Ref{_Property}) end """ - function get_value(entity::Ref{_Entity}) + function _get_value(value::Ref{_Value}) -Return the value of the given `entity` +Return the value of the given CaosDB value object. """ -function get_value(entity::Ref{_Entity}) +function _get_value(value::Ref{_Value}) - _caosdb_dtypes = ("INTEGER", "DOUBLE", "BOOLEAN", "TEXT") + is_a = Ref{Bool}(false) - 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, - ) + # value may be null + err_code = ccall( + (:caosdb_entity_value_is_null, CaosDB.library_name), + Cint, + (Ref{_Value}, Ref{Bool}), + value, + is_a, + ) - 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 + CaosDB.Exceptions.evaluate_return_code(err_code) - if @isdefined err_code - CaosDB.Exceptions.evaluate_return_code(err_code) + if is_a[] + return nothing end - return out -end - -""" - function get_value(property::Ref{_Property}) + # scalar string + err_code = ccall( + (:caosdb_entity_value_is_string, CaosDB.library_name), + Cint, + (Ref{_Value}, Ref{Bool}), + value, + is_a, + ) -Return the value of the given `property` -""" -function get_value(property::Ref{_Property}) + CaosDB.Exceptions.evaluate_return_code(err_code) - _caosdb_dtypes = ("INTEGER", "DOUBLE", "BOOLEAN", "TEXT") + if is_a[] + out = Ref{Ptr{UInt8}}(Ptr{UInt8}()) - 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, - ) + ccall( + (:caosdb_entity_value_get_as_string, CaosDB.library_name), + Cint, + (Ref{_Value}, Ref{Ptr{UInt8}}), + value, + 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) + return unsafe_string(out[]) + end + # integer err_code = ccall( - (:caosdb_entity_property_get_value_list_length, CaosDB.library_name), + (:caosdb_entity_value_is_integer, CaosDB.library_name), Cint, - (Ref{_Property}, Ref{Cint}), - property, - length, + (Ref{_Value}, Ref{Bool}), + value, + is_a, ) CaosDB.Exceptions.evaluate_return_code(err_code) - return length[] -end + if is_a[] + out = Ref{Clong}(0) -""" - function get_property_list_length(entity::Ref{_Entity}) + ccall( + (:caosdb_entity_value_get_as_integer, CaosDB.library_name), + Cint, + (Ref{_Value}, Ref{Clong}), + value, + out, + ) -Return the length of the list of the given `entity` -""" -function get_property_list_length(entity::Ref{_Entity}) + CaosDB.Exceptions.evaluate_return_code(err_code) - length = Ref{Cint}(0) + return out[] + end + # double err_code = ccall( - (:caosdb_entity_entity_get_value_list_length, CaosDB.library_name), + (:caosdb_entity_value_is_double, CaosDB.library_name), Cint, - (Ref{_Entity}, Ref{Cint}), - entity, - length, + (Ref{_Value}, Ref{Bool}), + value, + is_a, ) CaosDB.Exceptions.evaluate_return_code(err_code) - return length[] -end + if is_a[] + out = Ref{Cdouble}(0) -""" - function get_int_list_value_at(property::Ref{_Property}, index::Cint) + ccall( + (:caosdb_entity_value_get_as_double, CaosDB.library_name), + Cint, + (Ref{_Value}, Ref{Cdouble}), + value, + out, + ) -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) + CaosDB.Exceptions.evaluate_return_code(err_code) + + return out[] + end + + # bool err_code = ccall( - (:caosdb_entity_property_get_int_list_value_at, CaosDB.library_name), + (:caosdb_entity_value_is_bool, CaosDB.library_name), Cint, - (Ref{_Property}, Ref{Clong}, Cint), - property, - out, - index - Cint(1), + (Ref{_Value}, Ref{Bool}), + value, + is_a, ) CaosDB.Exceptions.evaluate_return_code(err_code) - return out[] -end -""" - function get_int_list_value_at(entity::Ref{_Entity}, index::Cint) + if is_a[] + out = Ref{Bool}(false) -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), - ) + ccall( + (:caosdb_entity_value_get_as_bool, CaosDB.library_name), + Cint, + (Ref{_Value}, Ref{Bool}), + value, + out, + ) - CaosDB.Exceptions.evaluate_return_code(err_code) - return out[] -end + CaosDB.Exceptions.evaluate_return_code(err_code) -""" - function get_double_list_value_at(property::Ref{_Property}, index::Cint) + return convert(Bool, out[]) + end -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) + # vector err_code = ccall( - (:caosdb_entity_property_get_double_list_value_at, CaosDB.library_name), + (:caosdb_entity_value_is_vector, CaosDB.library_name), Cint, - (Ref{_Property}, Ref{Cdouble}, Cint), - property, - out, - index - Cint(1), + (Ref{_Value}, Ref{Bool}), + value, + is_a, ) CaosDB.Exceptions.evaluate_return_code(err_code) - return out[] -end -""" - function get_double_list_value_at(entity::Ref{_Entity}, index::Cint) + if is_a[] + vector_size = Ref{Cint}(0) -Return the value of the DOUBLE list of the given `entity` at the position `index`. -""" -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), - ) + err_code = ccall( + (:caosdb_entity_value_get_as_vector_size, CaosDB.library_name), + Cint, + (Ref{_Value}, Ref{Cint}), + value, + vector_size, + ) - CaosDB.Exceptions.evaluate_return_code(err_code) - return out[] -end + CaosDB.Exceptions.evaluate_return_code(err_code) -""" - function get_bool_list_value_at(property::Ref{_Property}, index::Cint) + out = [] + value_elt = Ref{_Value}(_Value(false)) + for ii::Cint = 1:vector_size[] + err_code = ccall( + (:caosdb_entity_value_get_as_vector_at, CaosDB.library_name), + Cint, + (Ref{_Value}, Ref{_Value}, Cint), + value, + value_elt, + ii - Cint(1), + ) + CaosDB.Exceptions.evaluate_return_code(err_code) + push!(out, _get_value(value_elt)) + end -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_boolean_list_value_at, CaosDB.library_name), - Cint, - (Ref{_Property}, Ref{Cint}, Cint), - property, - out, - index - Cint(1), - ) + if length(out) > 0 + # convert to vector of type of elements s.th. it can be re-used in a + # `set_value` function. + elt_type = typeof(out[1]) + convert(Vector{elt_type}, out) + end - CaosDB.Exceptions.evaluate_return_code(err_code) - out = convert(Bool, out[]) - return out + return out + end + + throw(CaosDB.Exceptions.ClientException("Unkown value.")) end """ - function get_bool_list_value_at(entity::Ref{_Entity}, index::Cint) + function get_value(entity::Ref{_Entity}) -Return the value of the BOOLEAN list of the given `entity` at the position `index`. +Return the value of the given `entity` """ -function get_bool_list_value_at(entity::Ref{_Entity}, index::Cint) - out = Ref{Cint}(0) +function get_value(entity::Ref{_Entity}) + + value = Ref{_Value}(_Value()) + err_code = ccall( - (:caosdb_entity_entity_get_boolean_list_value_at, CaosDB.library_name), + (:caosdb_entity_entity_get_value, CaosDB.library_name), Cint, - (Ref{_Entity}, Ref{Cint}, Cint), + (Ref{_Entity}, Ref{_Value}), entity, - out, - index - Cint(1), + value, ) - CaosDB.Exceptions.evaluate_return_code(err_code) - out = convert(Bool, out[]) - return out + + return _get_value(value) end """ - function get_string_list_value_at(property::Ref{_Property}, index::Cint) + function get_value(property::Ref{_Property}) -Return the value of the TEXT list of the given `property` at the position `index`. +Return the value of the given `property` """ -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_value(property::Ref{_Property}) -""" - function get_string_list_value_at(entity::Ref{_Entity}, index::Cint) + value = Ref{_Value}(_Value()) -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), + (:caosdb_entity_property_get_value, CaosDB.library_name), Cint, - (Ref{_Entity}, Ref{Ptr{UInt8}}, Cint), - entity, - out, - index - Cint(1), + (Ref{_Property}, Ref{_Value}), + property, + value, ) - CaosDB.Exceptions.evaluate_return_code(err_code) - out = unsafe_string(out[]) - return out + + return _get_value(value) end """ @@ -2178,8 +1978,6 @@ function set_unit(property::Ref{_Property}, unit::AbstractString) CaosDB.Exceptions.evaluate_return_code(err_code) end -# TODO(henrik, daniel) There is no check for the correct datatype -# here. Should we add this? """ function set_value( entity::Ref{_Entity}, @@ -2204,80 +2002,15 @@ function set_value( ) end - 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_double_value, CaosDB.library_name), - Cint, - (Ref{_Entity}, Cdouble), - entity, - Cdouble(value), - ) - else - # Type is a vector now - 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), - Cint, - (Ref{_Entity}, Ptr{Ptr{Cchar}}, Cint), - entity, - value, - vec_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, - vec_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), - vec_length, - ) - elseif in_type <: Vector{T} where {T<:Number} - err_code = ccall( - (:caosdb_entity_entity_set_double_list_value, CaosDB.library_name), - Cint, - (Ref{_Entity}, Ptr{Cdouble}, Cint), - entity, - Vector{Cdouble}(value), - vec_length, - ) - end - end + value_ref = create_value(value) + + err_code = ccall( + (:caosdb_entity_entity_set_value, CaosDB.library_name), + Cint, + (Ref{_Entity}, Ref{_Value}), + entity, + value_ref, + ) CaosDB.Exceptions.evaluate_return_code(err_code) end @@ -2293,80 +2026,15 @@ function set_value( 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_double_value, CaosDB.library_name), - Cint, - (Ref{_Property}, Cdouble), - property, - Cdouble(value), - ) - else - # Type is a vector now - 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), - Cint, - (Ref{_Property}, Ptr{Ptr{Cchar}}, Cint), - property, - value, - vec_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, - vec_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), - vec_length, - ) - elseif in_type <: Vector{T} where {T<:Number} - err_code = ccall( - (:caosdb_entity_property_set_double_list_value, CaosDB.library_name), - Cint, - (Ref{_Property}, Ptr{Cdouble}, Cint), - property, - Vector{Cdouble}(value), - vec_length, - ) - end - end + value_ref = create_value(value) + + err_code = ccall( + (:caosdb_entity_property_set_value, CaosDB.library_name), + Cint, + (Ref{_Property}, Ref{_Value}), + property, + value_ref, + ) CaosDB.Exceptions.evaluate_return_code(err_code) end -- GitLab