D1PreparedStatement API
the conversion from D1Type -> JsValue is done once per item per row, which means that every time you call bind_refs, all the D1Types have to be converted.
Say we have 4 things we want to bind, and 2 are static, this means that every time we are passing all 4 to js and back.
If we're clever with our iterator and are able to use jsvalue, we can instead always return the same 2 references to the static jsvalues and and only convert the 2 dynamic ones every
bind_refs
28 Replies
Unknown User•9mo ago
Message Not Public
Sign In & Join Server To View
yeah, that would work too
I like this approach regardless because you're able to make various changes in the future without the API changing
the D1Type approach I mean
Unknown User•9mo ago
Message Not Public
Sign In & Join Server To View
yeah for sure, it was a bit of an adventure for me trying to figure out how to manage a blob when I started looking at this stuff, so being able to have rust's type system to help here would be awesome
actually
one thing
Number(f64)
I believe currently that is accurate because of the way this is managed JS side, but this could change in the future? Idk what your guys' plans are but sqlite does technically support i64
, and I assume at some point the bindings will be tweaked to allow that
So maybe take inspiration from sqlite and go with Real(f64)
and then either later add Integer(i64)
or add it now and panic when it's used or something?Unknown User•9mo ago
Message Not Public
Sign In & Join Server To View
I'm thinking that I liked the way the enum used rusts type system in case someone wanted to bypass JS entirely at some point, and I'm trying to think if there's a nice way to still make that work together with this approach
I also just generally don't really like how we lose the values after convert to jsvalue
I kinda like something like this
except for the name
I'm terrible at naming things in case that isn't abundantly obvious
But this approach means that if someone doesn't care, they can just use
D1Type
If they want some 'caching' they use D1TypeObj
JS supports i64 with BigInts but I'm uncertain if they can be used in D1: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt
(BigInts are arbitrary precision)
iirc they weren't, I loooked into this at one point
tbh the & impls aren't necessary
actually the obj doesn't even need ownership of the value
in fact it shouldn't have it
Unknown User•9mo ago
Message Not Public
Sign In & Join Server To View
ye sorry
I'm working on making it all work well rn
Unknown User•9mo ago
Message Not Public
Sign In & Join Server To View
you can mark the enum as [non_exhaustive]
but this is useful for debugging imo and in principle this information doesn't really make sense to be lost imo
is what I have right now, which works with both
Unknown User•9mo ago
Message Not Public
Sign In & Join Server To View
yes, true
Tbh, maybe I'm overthinking it, but I'm trying to make this both inspectable and extendable in the future. maybe it's okay if it's not inspectable, I also just really like working with rust enums as doing stuff like this just feels great
I think copilot wrote that part for me which is why both of those were bad lol
final proposal
Unknown User•9mo ago
Message Not Public
Sign In & Join Server To View
I still hate the name D1TypeObj, but sounds good
could also be really naughty and implement
into_iter
for &D1Type, returning an Iterator<&D1Type> lol
would mean no wrappers would be needed for a single &D1Type bind_refsUnknown User•9mo ago
Message Not Public
Sign In & Join Server To View
Right, I forgot Rust allows field mutation directly. Two solutions, either implement
From<&D1TypeObj> for &D1Type
or add a getter. I think I prefer the trait personally, makes it a little more ergonomic because in my mind they are still ~ the same thing, the D1TypeObj
is just a precalculated version of the D1Type
maybe a good name would be going in the direction of calculated or cached
Maybe D1TypeCached, I'd say that's a good descriptor for what it actually doesUnknown User•9mo ago
Message Not Public
Sign In & Join Server To View
yup, looks amazing now, only 2 tiny suggestions at this point are to rename
PreparedArgument
to D1PreparedArgument
since everything else around there is D1XYZ
and then a very pedantic thing but I think
is nicer than
especially since this way you don't pass &&str and &&[u8]
Big fan of how this turned out
also D1PreparedArgument seems so obvious in hindsight considering all the other types around there it's really a painful reminder of how bad I am at naming things 😅
Actually thoughts on this kinda thing to really maximize ergonomics?
actually the compiler doesn't seem to be clever enough for that
That's really unfortunate, maybe there's a clever way to do that in rust but I don't have that much experience with rust traits
I mean tbf something like this is useful even if the compiler currently can't automatically figure out the correct types imoUnknown User•9mo ago
Message Not Public
Sign In & Join Server To View
True
man it's so much nicer to have
instead of
I am having some trouble with
batch_bind
ok, the simple example works, but trying to be clever with the iterator seems to be difficult...
Am I incompetent? I can't get this to work
this works
imo, if it's not possible to make the batch_bind work nicely with the previous example, I'm not sure it's necessary at all, this is fine imoUnknown User•9mo ago
Message Not Public
Sign In & Join Server To View
batch_bind is asking for type annotations, which makes it pretty much useless at that point imo
this isn't the issue though
Unknown User•9mo ago
Message Not Public
Sign In & Join Server To View
this is kinda neat
I'd argue this is worse than doing it with bind_refs directly, but maybe that's just me
I don't think we can get any better with rust's inference though unfortunately