Using a consistent numeric interpretation for timestamps, dates and
times simplifies a bunch of operations. It certainly simplifies
conversion between the Postgres formats.
Copied from TUWF::Validate with a few small changes. I have a few more
features planned, but let's see how this goes first.
It's been an incredibly useful module in the past, I'm not sure right
now if I had ideas for potential improvements at some point, will need
to check notes.
And with this, I have a working rewrite of the manned.org backend into
FU. \o/
The $st->row methods are very useful even for queries that may not
return anything, so their old behavior was unhelpful. Interestingly
enough, the error-on-multiple-rows did catch an actual bug in
Manned.org, so I'm keeping that behavior.
...I was hoping not to have to implement the date type, because date
conversions suck, but it turns out manned.org actually needs it.
(Only to then convert it into a Unix timestamp again, hmm, maybe this
string conversion isn't useful at all?)
What I'd really like, in addition to this, is a way to extract a query
from an $st object that can be run in the psql CLI. VNDB has a debugging
feature for that, but it's less trivial to make that work with binary
query parameters.
And remove UTF-8 check in JSON writer. It honestly feels kind of silly
to do that validation there while I've never done similar validations in
any other output routines - including this XML writer.
FU::XMLWriter is a copy of TUWF::XMLXS with a bunch of improvements
applied: now uses refcounts to determine the current output instance,
auto-generates XS functions and has faster escaped string output -
inspired by the JSON writer.
TODO:
- Integrate into FU
- Do something with bool attribute values
- Benchmarks
- Should $content be optional for all tags? The reason they weren't in
TUWF::XMLXS is because TUWF::XML supports opening tags without closing
them, but that idea turned out to suck and isn't supported anymore.
This is hopefully the last XS module for the FU framework. The only C
code being written now should be bug fixes and extending FU::Pg with
some planned features. Already ended up with more C than I had
planned...
I initially planned to only implement the bare minimum to support
FastCGI under nginx, but ended up implementing the full protocol
instead. This is more code than I had expected and the code is also less
trivial than I had hoped. Will need to do more testing, pretty sure
there's bugs left.
Also TODO: test under alternative process managers + document
FU_LISTEN_PROTO.
I've also removed the max_request_body setting, this is something that
really ought to be configured in the web server instead.
I always keep messing up the aTHX_ and pTHX_ stuff because my system
perl isn't built with multiplicity, and I still haven't found a
satisfactory way of finding SV leaks. Valgrind can't track those :(
The tests are not as thourough as I would like. There's many ways to
mess this up.
I was initially planning to drop the ref on the prepared statement
immediately after executing the query, so that the $st object can be
kept around for introspection without consuming excess resources.
Unfortunately, PQcopyResult does not copy over information about bind
parameters, so we need another way to keep that information alive. I
ended up going for the simple solution: keep the ref on the prepared
statement...
This is simply magical. \o/
Vendored in khashl.h. I wouldn't have used it if this were the only
place where I'd need a custom hash table, but it should come in handy
for other tasks as well, especially when I get to implementing an LRU
for prepared statement caching.
(Can all be done with Perl HV's, but they're less efficient and more
cumbersome for these tasks)
+ refactor things a bit so that send & recv functions use the same
context struct, because the way they're setup is pretty much the same
for both. This also adds recursive type resolution for bind parameters.
These macros don't assume alignment and may be somewhat inefficient with
all that copying. I'm hoping GCC is able to optimize that crap somewhat.
Also the pg type receive functions can not, in fact, assume that their
input buffers are properly aligned. That won't necessarily be the case
for array elements.
NOW we're really getting to the part where this module is more awesome
than DBD::Pg.
(When I started working on this module I was expecting that the Postgres
binary protocol would send jsonb in a binary format as well and that I'd
be duplicating parts of the JSON parser/formatter to make that work, but
it turns out that Postgres just uses plain json for exchange. Saves me
some trouble, I guess)
I liked the Perl implementation of transactions, but managing state
between Perl and C is a bit cumbersome, so I've moved the whole thing
into C.
Also added a few statement configuration methods that currently don't do
anything yet.
Partly because some errors currently appeared to come from within FU::PG
itself, which is useless, and partly because it's common to wrap
database access methods, while that's exactly the kind of operation
where you *really* want to know where the error originated from.
(Source: too much time wasted debugging VNDB errors)
Was expecting the implementation of this to get overly complicated and
brittle, but using a counter-based cookie and doing parts of it in Perl
made it pretty easy actually. Pretty happy with how this turned out so
far.
TODO: documentation -.-