On Mon, Dec 02, 2002 at 05:14:14PM +0100, Henrik Tougaard wrote:
> I am in the (long drawn) process of migrating DBD::Ingres from embedded SQl to
> the vendorsupplied API.
> This leads me to read both the docs and the code in DBI with great enthusiasm,
> but also rasies some questions:
>
> 1) preparse.
> It is still undocumented (mu quess: patches welcome), but I assume that it is
> ready for use - especially as it has been included in the test suite.
> Is that correct? ie. that the interface is stable (or as stable as we can
> expect it to be).
No, sadly.
> I would like to add a format (or maybe two) to the function. Ingres uses '~V'
> (yes: a tilde followed by a capital letter V) as a placeholdermarker, and '$n
> = ~V' for repeated queries (where the 'n' is a sequence number from 0 and
> up). Patches wellcome I assume...
The "big question" is whether to continue down the current path of
a pure-C implementation or to change it to a pure-perl implementation
(perhaps with a C version for greater speed).
I expect the functionality offered by preparse (esp ODBC escape
sequences) to become very important over time and thus DBI::PurePerl
would be very limited without it. So a pure-perl implementation
will be needed sometime.
I'm still in two minds about that.
Scott Hildreth has been working on it from time to time for me.
He's looking into a Parse::RecDecent implementation now.
> 2) fetchall_arrayref.
> The code in Driver_xst.h for fetchall_arrayref seems to be a stub for
> something to come. I would love to be able to 'get my fingers on'
> fetchall_arrayref as the Ingres API has methods for returning all rows from a
> select without involving a cursor - and sligthly faster than a cursor open as well!
Ah, what's needed there is very simple - I mentioned it a week or two ago...
All the methods in Driver.xst should have #ifdef dbd_foo around
them, where dbd_foo if the name of the underlying implementation
function in your driver code.
See the rows method for the one (and I think) only example currently in Driver.xst.
For fetchall_arrayref (and some like it) instead of just an #ifdef
it needs a #else part that'll contain the current code.
> 3) dbd_db_do
> is referenced several places: DBD.pm and dbd_xsh.h (and in both the Oracle and
> ODBC drivers), but all I can find is the declaration - the function and any
> call to it seems to be missing. Not that I'll miss it, but it does confuse
> things...
Something like this:
#ifdef dbd_db_do
void
do(dbh)
SV * dbh
CODE:
D_imp_dbh(dbh);
... etc ...
#endif
is missing from Driver.xst.
> 4) STORE_attrib_k and FETCH_attrib_k
> are only declared in dbd_xsh.h, but are not defined/used anywhere. Are they
> reserved for future use or???
Kind of. Vauge ideas (related to hashing attribute names to speed
up lookup etc) that never got very far, partly because get_info
took a different, better, direction. You can ignore them.
> 5) DBIS and DBILOGFP
> The latest Changes states:
> Changes for driver authors, not required but strongly recommended:
> Change DBIS to DBIc_DBISTATE(imp_xxh) [or imp_dbh, imp_sth etc]
> Change DBILOGFP to DBIc_LOGPIO(imp_xxh) [or imp_dbh, imp_sth etc]
> Any function from which all instances of DBIS and DBILOGFP are
> removed can also have dPERLINTERP removed (a good thing).
> I must have blinked at some time. This is the first time I have noticed
> 'dPERLINTERP' - it is nowhere in the old DBD::Ingres (will that cause things
> to fail so that I should hurry and put it in, or can I relax and leave things
> as they are?).
Leave them as they are and tell anyone who uses perl 5.005 threads to upgrade.
> I have changed all references as given above, but could we please have a
> shorthand for the debug output, as it does look a bit longwinded to write:
> if (DBIc_DBISTATE(imp_sth)->debug >= 5)
> PerlIO_printf(DBIc_LOGPIO(imp_sth), ....);
> all over the place.
That could be
if (DBIc_DEBUGIV(imp_sth) >= 5)
...
which is a _little_ better :) Though actually that doesn't do quite
the right thing. I'll either add a new macro or change that one (or
what it refers to) to do-the-right-thing.
> Something like:
> DBI_DEBUG(imp_sth, 5, ....);
> would be nice - yes I know: patches....
Doing vararg macros with portable C is a bit tricky. I'd like
to make that a call back into DBI internals. Maybe something like:
if (DBIc_DEBUGIV(imp_sth) >= 5)
DBI_TRACE(imp_sth)(...);
> 6) DBIh_EVENTx
> are to be removed. The macroes do nothing now as far as I can see.
> This leads me to wonder how can I signal an error now? The DBD.pm states eg
> under dbd_db_STORE:
> The return value is TRUE, if you have handled the
> attribute or FALSE otherwise. If you are handling an
> attribute and something fails, you should call do_error,
> so DBI can raise exceptions, if desired. If do_error
> returns, however, you have a problem: The user will never
> know about the error, because he typically will not check
> "$dbh->errstr".
> 'do_error' records the error in err and friends and then calls DBIh_EVENT2 to
> get the error handled. This is not done now (perhaps has never been done).
May have been 'done', but never 'did' anything much :)
> As far as I can discover the errorchecking is done when the driver returns to
> the DBI-layer, then the DBI dispatcher checks DBI->err and handles the error
> if any.
> Am I correct?
Yes.
> So a patch for DBD.pm would seemingly be welcome....
Of course! :) [There's lots that's out of date or incomplete.
All driver authors are encouraged to trip over parts and send in a
patch when they pick themselves up ;-]
> All in all it is quite fun to be redoing the driver implementation. The DBI
> has become a lot friendlier since I did it last (or is it just that I know a
> lot more about what is going on... hmmm), so the progress is not quite as
> slow as I feared ;-)
:)
It's my intention that the DBI provide more 'hand-holding' for
drivers over time as part of a (very) vague perl6 migration strategy.
Tim.