Hi Stefan,
It might be a challenge for CTFE compatibility in the API, but it
would be interesting to see how much of it is workable. There
does need to be some optional API elements in cases where it's
not supported by the underlying database client(array binding for
example) and these compile time policies could also be used to
define a restricted subset if needed for your design.
I don't have any D code in production unfortunately, but I have a
similar design in C++ that has been in production for years.
As far as the design rationale, the primary aspect of the design
is to ensure deterministic resource lifetimes for each of the
resources commonly exposed by clients (connections, statements,
rowsets, buffer allocations, etc), which is why structs are used.
This could be done with with simple non-copyable structs for a
more limited design. I went with the value type structs (using
reference counting) which provides better composibility overall.
This can be seen in the call chaining examples, which I think
significantly increase ease-of-use. It also covers use cases in
application code where, for example, lazy results are returned
through code layers and they need to retain their underlying
connections.
Thanks for the questions and the interest.
erik