I'm still trying to get all() to work with this resource.
As a work-around to that first issue, I'm using this code temporarily, although it totally isn't right (I shouldn't be allowing the making of models that are invalid).
#This is used to store the beginning and end of a time tracking period for a given user on a given node.
@kwdef mutable struct TTInterval <: AbstractModel
id::DbId = DbId()
#TODO: When https://github.com/GenieFramework/SearchLight.jl/issues/55 is resolved,
# use these commented lines instead. We shouldn't really be able to make models that aren't valid.
#node_id::Int64
#user_id::Int64
#start_time::DateTime
node_id::Int64=-1
user_id::Int64=-1
start_time::DateTime=DateTime(1900)
#end_times can be nothing (aka NULL):
end_time::Union{Nothing,DateTime}=nothing
end
The issue I'm having now is with the end_time field.
julia> using TTIntervals
julia> all(TTIntervals.TTInterval)
[ Info: 2022-05-22 05:36:00 SELECT `ttintervals`.`id` AS `ttintervals_id`, `ttintervals`.`node_id` AS `ttintervals_node_id`, `ttintervals`.`user_id` AS `ttintervals_user_id`, `ttintervals`.`start_time` AS `ttintervals_start_time`, `ttintervals`.`end_time` AS `ttintervals_end_time` FROM `ttintervals` ORDER BY ttintervals.id ASC
┌ Error: 2022-05-22 05:36:02 MethodError(convert, (Union{}, Dates.DateTime("2023-01-01T00:00:00")), 0xffffffffffffffff)
└ @ SearchLight ~/.julia/packages/SearchLight/2kAM0/src/SearchLight.jl:536
ERROR: MethodError: Cannot `convert` an object of type
Dates.DateTime to an object of type
Union{}
Closest candidates are:
convert(::Type{Union{}}, ::Any) at essentials.jl:203
convert(::Type{T}, ::Any) where T<:VecElement at baseext.jl:8
convert(::Type{T}, ::T) where T<:Tuple at essentials.jl:315
...
Stacktrace:
[1] convert(#unused#::Core.TypeofBottom, x::Dates.DateTime)
@ Base ./essentials.jl:203
[2] convert(#unused#::Type{Nothing}, x::Dates.DateTime)
@ Base ./some.jl:36
[3] oftype(x::Nothing, y::Dates.DateTime)
@ Base ./essentials.jl:375
[4] to_model(m::Type{TTIntervals.TTInterval}, row::DataFrames.DataFrameRow{DataFrames.DataFrame, DataFrames.Index}; skip_callbacks::Vector{Symbol})
@ SearchLight ~/.julia/packages/SearchLight/2kAM0/src/SearchLight.jl:534
[5] to_model
@ ~/.julia/packages/SearchLight/2kAM0/src/SearchLight.jl:492 [inlined]
[6] to_model!!
@ ~/.julia/packages/SearchLight/2kAM0/src/SearchLight.jl:572 [inlined]
[7] to_models(m::Type{TTIntervals.TTInterval}, df::DataFrames.DataFrame)
@ SearchLight ~/.julia/packages/SearchLight/2kAM0/src/SearchLight.jl:473
[8] find(m::Type{TTIntervals.TTInterval}, q::SearchLight.SQLQuery, j::Nothing) (repeats 2 times)
@ SearchLight ~/.julia/packages/SearchLight/2kAM0/src/SearchLight.jl:92
[9] #all#34
@ ~/.julia/packages/SearchLight/2kAM0/src/SearchLight.jl:179 [inlined]
[10] all(m::Type{TTIntervals.TTInterval})
@ SearchLight ~/.julia/packages/SearchLight/2kAM0/src/SearchLight.jl:179
[11] top-level scope
@ REPL[2]:1
Digging into the SearchLight here's the relevant to_model() code in SearchLight.j:
491: function to_model(m::Type{T}, row::DataFrames.DataFrameRow; skip_callbacks::Vector{Symbol} = Symbol[])::T where {T<:AbstractModel}
....
498: obj=m() #Simplified for clarity
...
534: setfield!(obj, unq_field, oftype(getfield(_m, unq_field), value))
So, basically, on line 498, SearchLight makes an empty struct, and then later it tries to set the fields using oftype(getfield(_m, unq_field), value). In other words, it looks at the type of each field in the initialized object and assumes that everything we ever put in that field will be of the same type. But, what about Unions? They can hold different types. So here we have a case where we initialized to nothing, but we tried to put a DateTime in it's place instead. That's totally valid according to the struct, but the way that to_model is making the assumption that "once a T, always a T" doesn't seem right when Unions are involved. I really hope I'm doing something dumb at this point, because being able to make a field in a database NULLable doesn't seem like a radical thing, yet everywhere I turn there's a new error message and more of other people's code to read to figure out why. 😢
I'm still trying to get all() to work with this resource.
As a work-around to that first issue, I'm using this code temporarily, although it totally isn't right (I shouldn't be allowing the making of models that are invalid).
The issue I'm having now is with the end_time field.
Digging into the SearchLight here's the relevant to_model() code in SearchLight.j:
So, basically, on line 498, SearchLight makes an empty struct, and then later it tries to set the fields using oftype(getfield(_m, unq_field), value). In other words, it looks at the type of each field in the initialized object and assumes that everything we ever put in that field will be of the same type. But, what about Unions? They can hold different types. So here we have a case where we initialized to nothing, but we tried to put a DateTime in it's place instead. That's totally valid according to the struct, but the way that to_model is making the assumption that "once a T, always a T" doesn't seem right when Unions are involved. I really hope I'm doing something dumb at this point, because being able to make a field in a database NULLable doesn't seem like a radical thing, yet everywhere I turn there's a new error message and more of other people's code to read to figure out why. 😢