Open schveiguy opened 5 years ago
Or alternatively, you can use a different mechanism from Nullable
to indicate an empty set.
I suppose this is moot since Phobos' Nullable will eventually require a get call.
However, I'll leave this open, because an updated API surely could do better than requiring get.get
.
This would also be alleviated somewhat with the move to TaggedUnion
as discussed in #175
Is it possible to instead specify the type to queryValue itself, and have it return a Nullable!T? something like:
Sounds like an excellent idea.
Only potential problem is that some of the queryValue
overloads already take templated varargs (for prepared statements):
Nullable!Variant queryValue(T...)(conn, sql, T args) {...}
int myInt=...;
myConnection.queryRow("SELECT * FROM `myTable` WHERE `a` = ?", myInt)
It shouldn’t be a problem to change it to:
Nullable!T1 queryValue(T1, T2...)(conn, sql, T2 args) {...}
Buuuut….we’d probably want Variant (or rather, TaggedUnion, whatever...) as a default, and I’m wondering if that would be inherently ambiguous:
Nullable!T1 queryValue(T1=Variant, T2...)(conn, sql, T2 args) {...}
Assuming that works, we’d also need to decide how to handle the case when the type requested doesn’t match the type received. Attempt a silent conversion? Throw? Support both possibilities using different function names: queryValueA
vs queryValueB
(but with better names ;) )???
This would also be alleviated somewhat with the move to TaggedUnion as discussed in #175
Yea, TaggedUnion
definitely sounds like a good idea. One of my other projects, SDLang-D I think, switched from Variant
to TaggedAlgebraic
some time ago (before TaggedUnion
existed) and it definitely proved to be a good move.
Only potential problem is that some of the
queryValue
overloads already take templated varargs
That is solved with double-layer templates:
template queryValue(Ret = Variant)
{
Nullable!Ret queryValue(Args...)(Connection conn, string sql, Args args) { ...}
}
Yes, still does full IFTI. At that point, you cannot specify the Args part of the template, but I'm assuming that is not a problem.
Assuming that works, we’d also need to decide how to handle the case when the type requested doesn’t match the type received
Existing behavior is to throw, so just throw.
In regards to the switch to TaggedUnion, would probably be something like:
auto total = conn.queryValue("select count(*) from ...").get.longValue;
So really maybe this request will resolve itself once we get there.
That is solved with double-layer templates: [...] Existing behavior is to throw, so just throw.
Awesome, sounds great.
In regards to the switch to TaggedUnion, would probably be something like:
auto total = conn.queryValue("select count(*) from ...").get.longValue;
So really maybe this request will resolve itself once we get there.
Ahh, true. But maybe there's still value (perhaps for generic code?) in being able to specify the requested type as the actual type rather than via TaggedUnion's identifiers? In any case, the template idea is probably just a cleaner interface anyway: It's a little more idiomatic and doesn't require anyone to know anything whatsoever about TaggedUnion.
Oh, also, another thought on the whole migration thing: Maybe we could offer a simple util function to just convert the TaggedUnion to a Variant:
alias MySQLValue = TaggedUnion!blahblahwhatever...;
Variant toVariant(MySQLValue v) {...}
Nullable!Variant toVariant(Nullable!MySQLValue v) {...}
...
var = conn.queryValue(sql).toVariant;
Maybe that could even obviate the need for all those migration path gymnastics I outlined earlier (ugh, might've been in a different ticket...)
I suppose this is moot since Phobos' Nullable will eventually require a get call.
Don't know why I said this, it will still require get.get
.
queryValue
returns aNullable!Variant
. Let's say it returns along
(In my case, I was querying aCOUNT(*)
to get the total rows)My code I put was:
But this doesn't work, because
Nullable
intercepts theget
call! So instead I have to do:Which IMO is ugly and annoying. Really this is an issue with
Nullable
andVariant
reusing the same member name, but I doubt that will change.Is it possible to instead specify the type to
queryValue
itself, and have it return aNullable!T
? something like: