DBI
view release on metacpan or search on metacpan
lib/DBI/DBD.pm view on Meta::CPAN
When a complete file of tests must be skipped, you can provide a reason
in a pseudo-comment:
if ($no_transactions_available)
{
print "1..0 # Skip: No transactions available\n";
exit 0;
}
Consider downloading the B<DBD::Informix> code and look at the code in
F<DBD/Informix/TestHarness.pm> which is used throughout the
B<DBD::Informix> tests in the F<t> sub-directory.
=head1 CREATING A C/XS DRIVER
Please also see the section under L<CREATING A PURE PERL DRIVER>
regarding the creation of the F<Makefile.PL>.
Creating a new C/XS driver from scratch will always be a daunting task.
You can and should greatly simplify your task by taking a good
reference driver implementation and modifying that to match the
database product for which you are writing a driver.
The de facto reference driver has been the one for B<DBD::Oracle> written
by Tim Bunce, who is also the author of the B<DBI> package. The B<DBD::Oracle>
module is a good example of a driver implemented around a C-level API.
Nowadays it it seems better to base on B<DBD::ODBC>, another driver
maintained by Tim and Jeff Urlwin, because it offers a lot of metadata
and seems to become the guideline for the future development. (Also as
B<DBD::Oracle> digs deeper into the Oracle 8 OCI interface it'll get even
more hairy than it is now.)
The B<DBD::Informix> driver is one driver implemented using embedded SQL
instead of a function-based API.
B<DBD::Ingres> may also be worth a look.
=head2 C/XS version of Driver.pm
A lot of the code in the F<Driver.pm> file is very similar to the code for pure Perl modules
- see above. However,
there are also some subtle (and not so subtle) differences, including:
=over 8
=item *
The variables I<$DBD::Driver::{dr|db|st}::imp_data_size> are not defined
here, but in the XS code, because they declare the size of certain
C structures.
=item *
Some methods are typically moved to the XS code, in particular
C<prepare()>, C<execute()>, C<disconnect()>, C<disconnect_all()> and the
C<STORE()> and C<FETCH()> methods.
=item *
Other methods are still part of F<Driver.pm>, but have callbacks to
the XS code.
=item *
If the driver-specific parts of the I<imp_drh_t> structure need to be
formally initialized (which does not seem to be a common requirement),
then you need to add a call to an appropriate XS function in the driver
method of C<DBD::Driver::driver()>, and you define the corresponding function
in F<Driver.xs>, and you define the C code in F<dbdimp.c> and the prototype in
F<dbdimp.h>.
For example, B<DBD::Informix> has such a requirement, and adds the
following call after the call to C<_new_drh()> in F<Informix.pm>:
DBD::Informix::dr::driver_init($drh);
and the following code in F<Informix.xs>:
# Initialize the DBD::Informix driver data structure
void
driver_init(drh)
SV *drh
CODE:
ST(0) = dbd_ix_dr_driver_init(drh) ? &sv_yes : &sv_no;
and the code in F<dbdimp.h> declares:
extern int dbd_ix_dr_driver_init(SV *drh);
and the code in F<dbdimp.ec> (equivalent to F<dbdimp.c>) defines:
/* Formally initialize the DBD::Informix driver structure */
int
dbd_ix_dr_driver(SV *drh)
{
D_imp_drh(drh);
imp_drh->n_connections = 0; /* No active connections */
imp_drh->current_connection = 0; /* No current connection */
imp_drh->multipleconnections = (ESQLC_VERSION >= 600) ? True : False;
dbd_ix_link_newhead(&imp_drh->head); /* Empty linked list of connections */
return 1;
}
B<DBD::Oracle> has a similar requirement but gets around it by checking
whether the private data part of the driver handle is all zeroed out,
rather than add extra functions.
=back
Now let's take a closer look at an excerpt from F<Oracle.pm> (revised
heavily to remove idiosyncrasies) as an example, ignoring things that
were already discussed for pure Perl drivers.
=head3 The connect method
The connect method is the database handle constructor.
You could write either of two versions of this method: either one which
takes connection attributes (new code) and one which ignores them (old
code only).
( run in 0.864 second using v1.01-cache-2.11-cpan-437f7b0c052 )