{
    "mode": "perldoc",
    "parameter": "DBI::DBD",
    "section": "",
    "url": "https://www.chedong.com/phpMan.php/perldoc/DBI%3A%3ADBD/json",
    "generated": "2026-06-10T14:08:45Z",
    "synopsis": "perldoc DBI::DBD",
    "sections": {
        "NAME": {
            "content": "DBI::DBD - Perl DBI Database Driver Writer's Guide\n",
            "subsections": []
        },
        "SYNOPSIS": {
            "content": "perldoc DBI::DBD\n",
            "subsections": [
                {
                    "name": "Version and volatility",
                    "content": "This document is *still* a minimal draft which is in need of further work.\n\nPlease read the DBI documentation first and fully. Then look at the implementation of some\nhigh-profile and regularly maintained drivers like DBD::Oracle, DBD::ODBC, DBD::Pg etc. (Those\nare no no particular order.)\n\nThen reread the DBI specification and the code of those drivers again as you're reading this.\nIt'll help. Where this document and the driver code differ it's likely that the driver code is\nmore correct, especially if multiple drivers do the same thing.\n\nThis document is a patchwork of contributions from various authors. More contributions\n(preferably as patches) are very welcome.\n"
                }
            ]
        },
        "DESCRIPTION": {
            "content": "This document is primarily intended to help people writing new database drivers for the Perl\nDatabase Interface (Perl DBI). It may also help others interested in discovering why the\ninternals of a DBD driver are written the way they are.\n\nThis is a guide. Few (if any) of the statements in it are completely authoritative under all\npossible circumstances. This means you will need to use judgement in applying the guidelines in\nthis document. If in *any* doubt at all, please do contact the *dbi-dev* mailing list (details\ngiven below) where Tim Bunce and other driver authors can help.\n",
            "subsections": []
        },
        "CREATING A NEW DRIVER": {
            "content": "The first rule for creating a new database driver for the Perl DBI is very simple: DON'T!\n\nThere is usually a driver already available for the database you want to use, almost regardless\nof which database you choose. Very often, the database will provide an ODBC driver interface, so\nyou can often use DBD::ODBC to access the database. This is typically less convenient on a Unix\nbox than on a Microsoft Windows box, but there are numerous options for ODBC driver managers on\nUnix too, and very often the ODBC driver is provided by the database supplier.\n\nBefore deciding that you need to write a driver, do your homework to ensure that you are not\nwasting your energies.\n\n[As of December 2002, the consensus is that if you need an ODBC driver manager on Unix, then the\nunixODBC driver (available from <http://www.unixodbc.org/>) is the way to go.]\n\nThe second rule for creating a new database driver for the Perl DBI is also very simple: Don't\n-- get someone else to do it for you!\n\nNevertheless, there are occasions when it is necessary to write a new driver, often to use a\nproprietary language or API to access the database more swiftly, or more comprehensively, than\nan ODBC driver can. Then you should read this document very carefully, but with a suitably\nsceptical eye.\n\nIf there is something in here that does not make any sense, question it. You might be right that\nthe information is bogus, but don't come to that conclusion too quickly.\n\nURLs and mailing lists\nThe primary web-site for locating DBI software and information is\n\nhttp://dbi.perl.org/\n\nThere are two main and one auxiliary mailing lists for people working with DBI. The primary\nlists are *dbi-users@perl.org* for general users of DBI and DBD drivers, and *dbi-dev@perl.org*\nmainly for DBD driver writers (don't join the *dbi-dev* list unless you have a good reason). The\nauxiliary list is *dbi-announce@perl.org* for announcing new releases of DBI or DBD drivers.\n\nYou can join these lists by accessing the web-site <http://dbi.perl.org/>. The lists are closed\nso you cannot send email to any of the lists unless you join the list first.\n\nYou should also consider monitoring the *comp.lang.perl. newsgroups, especially\n*comp.lang.perl.modules*.\n",
            "subsections": [
                {
                    "name": "The Cheetah book",
                    "content": "The definitive book on Perl DBI is the Cheetah book, so called because of the picture on the\ncover. Its proper title is '*Programming the Perl DBI: Database programming with Perl*' by\nAlligator Descartes and Tim Bunce, published by O'Reilly Associates, February 2000, ISBN\n1-56592-699-4. Buy it now if you have not already done so, and read it.\n"
                },
                {
                    "name": "Locating drivers",
                    "content": "Before writing a new driver, it is in your interests to find out whether there already is a\ndriver for your database. If there is such a driver, it would be much easier to make use of it\nthan to write your own!\n\nThe primary web-site for locating Perl software is <http://search.cpan.org/>. You should look\nunder the various modules listings for the software you are after. For example:\n\nhttp://search.cpan.org/modlist/DatabaseInterfaces\n\nFollow the DBD:: and DBIx:: links at the top to see those subsets.\n\nSee the DBI docs for information on DBI web sites and mailing lists.\n"
                },
                {
                    "name": "Registering a new driver",
                    "content": "Before going through any official registration process, you will need to establish that there is\nno driver already in the works. You'll do that by asking the DBI mailing lists whether there is\nsuch a driver available, or whether anybody is working on one.\n\nWhen you get the go ahead, you will need to establish the name of the driver and a prefix for\nthe driver. Typically, the name is based on the name of the database software it uses, and the\nprefix is a contraction of that. Hence, DBD::Oracle has the name *Oracle* and the prefix\n'*ora*'. The prefix must be lowercase and contain no underscores other than the one at the end.\n\nThis information will be recorded in the DBI module. Apart from documentation purposes,\nregistration is a prerequisite for installing private methods.\n\nIf you are writing a driver which will not be distributed on CPAN, then you should choose a\nprefix beginning with '*x*', to avoid potential prefix collisions with drivers registered in\nthe future. Thus, if you wrote a non-CPAN distributed driver called DBD::CustomDB, the prefix\nmight be '*xcdb*'.\n\nThis document assumes you are writing a driver called DBD::Driver, and that the prefix '*drv*'\nis assigned to the driver.\n"
                },
                {
                    "name": "Two styles of database driver",
                    "content": "There are two distinct styles of database driver that can be written to work with the Perl DBI.\n\nYour driver can be written in pure Perl, requiring no C compiler. When feasible, this is the\nbest solution, but most databases are not written in such a way that this can be done. Some\nexamples of pure Perl drivers are DBD::File and DBD::CSV.\n\nAlternatively, and most commonly, your driver will need to use some C code to gain access to the\ndatabase. This will be classified as a C/XS driver.\n\nWhat code will you write?\nThere are a number of files that need to be written for either a pure Perl driver or a C/XS\ndriver. There are no extra files needed only by a pure Perl driver, but there are several extra\nfiles needed only by a C/XS driver.\n\nFiles common to pure Perl and C/XS drivers\nAssuming that your driver is called DBD::Driver, these files are:\n\n*   Makefile.PL\n\n*   META.yml\n\n*   README\n\n*   MANIFEST\n\n*   Driver.pm\n\n*   lib/Bundle/DBD/Driver.pm\n\n*   lib/DBD/Driver/Summary.pm\n\n*   t/*.t\n\nThe first four files are mandatory. Makefile.PL is used to control how the driver is built and\ninstalled. The README file tells people who download the file about how to build the module and\nany prerequisite software that must be installed. The MANIFEST file is used by the standard Perl\nmodule distribution mechanism. It lists all the source files that need to be distributed with\nyour module. Driver.pm is what is loaded by the DBI code; it contains the methods peculiar to\nyour driver.\n\nAlthough the META.yml file is not required you are advised to create one. Of particular\nimportance are the *buildrequires* and *configurerequires* attributes which newer CPAN modules\nunderstand. You use these to tell the CPAN module (and CPANPLUS) that your build and configure\nmechanisms require DBI. The best reference for META.yml (at the time of writing) is\n<http://module-build.sourceforge.net/META-spec-v1.4.html>. You can find a reasonable example of\na META.yml in DBD::ODBC.\n\nThe lib/Bundle/DBD/Driver.pm file allows you to specify other Perl modules on which yours\ndepends in a format that allows someone to type a simple command and ensure that all the\npre-requisites are in place as well as building your driver.\n\nThe lib/DBD/Driver/Summary.pm file contains (an updated version of) the information that was\nincluded - or that would have been included - in the appendices of the Cheetah book as a summary\nof the abilities of your driver and the associated database.\n\nThe files in the t subdirectory are unit tests for your driver. You should write your tests as\nstringently as possible, while taking into account the diversity of installations that you can\nencounter:\n\n*   Your tests should not casually modify operational databases.\n\n*   You should never damage existing tables in a database.\n\n*   You should code your tests to use a constrained name space within the database. For example,\nthe tables (and all other named objects) that are created could all begin with '*dbddrv*'.\n\n*   At the end of a test run, there should be no testing objects left behind in the database.\n\n*   If you create any databases, you should remove them.\n\n*   If your database supports temporary tables that are automatically removed at the end of a\nsession, then exploit them as often as possible.\n\n*   Try to make your tests independent of each other. If you have a test t/t11dowhat.t that\ndepends upon the successful running of t/t10thingamy.t, people cannot run the single test\ncase t/t11dowhat.t. Further, running t/t11dowhat.t twice in a row is likely to fail (at\nleast, if t/t11dowhat.t modifies the database at all) because the database at the start of\nthe second run is not what you saw at the start of the first run.\n\n*   Document in your README file what you do, and what privileges people need to do it.\n\n*   You can, and probably should, sequence your tests by including a test number before an\nabbreviated version of the test name; the tests are run in the order in which the names are\nexpanded by shell-style globbing.\n\n*   It is in your interests to ensure that your tests work as widely as possible.\n\nMany drivers also install sub-modules DBD::Driver::SubModule for any of a variety of different\nreasons, such as to support the metadata methods (see the discussion of \"METADATA METHODS\"\nbelow). Such sub-modules are conventionally stored in the directory lib/DBD/Driver. The module\nitself would usually be in a file SubModule.pm. All such sub-modules should themselves be\nversion stamped (see the discussions far below).\n\nExtra files needed by C/XS drivers\nThe software for a C/XS driver will typically contain at least four extra files that are not\nrelevant to a pure Perl driver.\n\n*   Driver.xs\n\n*   Driver.h\n\n*   dbdimp.h\n\n*   dbdimp.c\n\nThe Driver.xs file is used to generate C code that Perl can call to gain access to the C\nfunctions you write that will, in turn, call down onto your database software.\n\nThe Driver.h header is a stylized header that ensures you can access the necessary Perl and DBI\nmacros, types, and function declarations.\n\nThe dbdimp.h is used to specify which functions have been implemented by your driver.\n\nThe dbdimp.c file is where you write the C code that does the real work of translating between\nPerl-ish data types and what the database expects to use and return.\n\nThere are some (mainly small, but very important) differences between the contents of\nMakefile.PL and Driver.pm for pure Perl and C/XS drivers, so those files are described both in\nthe section on creating a pure Perl driver and in the section on creating a C/XS driver.\n\nObviously, you can add extra source code files to the list.\n"
                },
                {
                    "name": "Requirements on a driver and driver writer",
                    "content": "To be remotely useful, your driver must be implemented in a format that allows it to be\ndistributed via CPAN, the Comprehensive Perl Archive Network (<http://www.cpan.org/> and\n<http://search.cpan.org>). Of course, it is easier if you do not have to meet this criterion,\nbut you will not be able to ask for much help if you do not do so, and no-one is likely to want\nto install your module if they have to learn a new installation mechanism.\n"
                }
            ]
        },
        "CREATING A PURE PERL DRIVER": {
            "content": "Writing a pure Perl driver is surprisingly simple. However, there are some problems you should\nbe aware of. The best option is of course picking up an existing driver and carefully modifying\none method after the other.\n\nAlso look carefully at DBD::AnyData and DBD::Template.\n\nAs an example we take a look at the DBD::File driver, a driver for accessing plain files as\ntables, which is part of the DBD::CSV package.\n\nThe minimal set of files we have to implement are Makefile.PL, README, MANIFEST and Driver.pm.\n",
            "subsections": [
                {
                    "name": "Pure Perl version of Makefile.PL",
                    "content": "You typically start with writing Makefile.PL, a Makefile generator. The contents of this file\nare described in detail in the ExtUtils::MakeMaker man pages. It is definitely a good idea if\nyou start reading them. At least you should know about the variables *CONFIGURE*, *DEFINED*,\n*PM*, *DIR*, *EXEFILES*, *INC*, *LIBS*, *LINKTYPE*, *NAME*, *OPTIMIZE*, *PLFILES*, *VERSION*,\n*VERSIONFROM*, *clean*, *depend*, *realclean* from the ExtUtils::MakeMaker man page: these are\nused in almost any Makefile.PL.\n\nAdditionally read the section on *Overriding MakeMaker Methods* and the descriptions of the\n*distcheck*, *disttest* and *dist* targets: They will definitely be useful for you.\n\nOf special importance for DBI drivers is the *postamble* method from the ExtUtils::MMUnix man\npage.\n\nFor Emacs users, I recommend the *libscan* method, which removes Emacs backup files (file names\nwhich end with a tilde '~') from lists of files.\n\nNow an example, I use the word \"Driver\" wherever you should insert your driver's name:\n\n# -*- perl -*-\n\nuse ExtUtils::MakeMaker;\n\nWriteMakefile(\ndbdeditmmattribs( {\n'NAME'         => 'DBD::Driver',\n'VERSIONFROM' => 'Driver.pm',\n'INC'          => '',\n'dist'         => { 'SUFFIX'   => '.gz',\n'COMPRESS' => 'gzip -9f' },\n'realclean'    => { FILES => '*.xsi' },\n'PREREQPM'    => '1.03',\n'CONFIGURE'    => sub {\neval {require DBI::DBD;};\nif ($@) {\nwarn $@;\nexit 0;\n}\nmy $dbiarchdir = dbddbiarchdir();\nif (exists($opts{INC})) {\nreturn {INC => \"$opts{INC} -I$dbiarchdir\"};\n} else {\nreturn {INC => \"-I$dbiarchdir\"};\n}\n}\n},\n{ createpptests => 1})\n);\n\npackage MY;\nsub postamble { return main::dbdpostamble(@); }\nsub libscan {\nmy ($self, $path) = @;\n($path =~ m/\\~$/) ? undef : $path;\n}\n\nNote the calls to \"dbdeditmmattribs()\" and \"dbdpostamble()\".\n\nThe second hash reference in the call to \"dbdeditmmattribs()\" (containing\n\"createpptests()\") is optional; you should not use it unless your driver is a pure Perl driver\n(that is, it does not use C and XS code). Therefore, the call to \"dbdeditmmattribs()\" is not\nrelevant for C/XS drivers and may be omitted; simply use the (single) hash reference containing\nNAME etc as the only argument to \"WriteMakefile()\".\n\nNote that the \"dbdeditmmattribs()\" code will fail if you do not have a t sub-directory\ncontaining at least one test case.\n\n*PREREQPM* tells MakeMaker that DBI (version 1.03 in this case) is required for this module.\nThis will issue a warning that DBI 1.03 is missing if someone attempts to install your DBD\nwithout DBI 1.03. See *CONFIGURE* below for why this does not work reliably in stopping cpan\ntesters failing your module if DBI is not installed.\n\n*CONFIGURE* is a subroutine called by MakeMaker during \"WriteMakefile\". By putting the \"require\nDBI::DBD\" in this section we can attempt to load DBI::DBD but if it is missing we exit with\nsuccess. As we exit successfully without creating a Makefile when DBI::DBD is missing cpan\ntesters will not report a failure. This may seem at odds with *PREREQPM* but *PREREQPM* does\nnot cause \"WriteMakefile\" to fail (unless you also specify PREREQFATAL which is strongly\ndiscouraged by MakeMaker) so \"WriteMakefile\" would continue to call \"dbddbiarchdir\" and fail.\n\nAll drivers must use \"dbdpostamble()\" or risk running into problems.\n\nNote the specification of *VERSIONFROM*; the named file (Driver.pm) will be scanned for the\nfirst line that looks like an assignment to *$VERSION*, and the subsequent text will be used to\ndetermine the version number. Note the commentary in ExtUtils::MakeMaker on the subject of\ncorrectly formatted version numbers.\n\nIf your driver depends upon external software (it usually will), you will need to add code to\nensure that your environment is workable before the call to \"WriteMakefile()\". If you need to\ncheck for the existence of an external library and perhaps modify *INC* to include the paths to\nwhere the external library header files are located and you cannot find the library or header\nfiles make sure you output a message saying they cannot be found but \"exit 0\" (success) before\ncalling \"WriteMakefile\" or CPAN testers will fail your module if the external library is not\nfound.\n\nA full-fledged *Makefile.PL* can be quite large (for example, the files for DBD::Oracle and\nDBD::Informix are both over 1000 lines long, and the Informix one uses - and creates - auxiliary\nmodules too).\n\nSee also ExtUtils::MakeMaker and ExtUtils::MMUnix. Consider using CPAN::MakeMaker in place of\n*ExtUtils::MakeMaker*.\n\nREADME\nThe README file should describe what the driver is for, the pre-requisites for the build\nprocess, the actual build process, how to report errors, and who to report them to.\n\nUsers will find ways of breaking the driver build and test process which you would never even\nhave dreamed to be possible in your worst nightmares. Therefore, you need to write this document\ndefensively, precisely and concisely.\n\nAs always, use the README from one of the established drivers as a basis for your own; the\nversion in DBD::Informix is worth a look as it has been quite successful in heading off\nproblems.\n\n*   Note that users will have versions of Perl and DBI that are both older and newer than you\nexpected, but this will seldom cause much trouble. When it does, it will be because you are\nusing features of DBI that are not supported in the version they are using.\n\n*   Note that users will have versions of the database software that are both older and newer\nthan you expected. You will save yourself time in the long run if you can identify the range\nof versions which have been tested and warn about versions which are not known to be OK.\n\n*   Note that many people trying to install your driver will not be experts in the database\nsoftware.\n\n*   Note that many people trying to install your driver will not be experts in C or Perl.\n\nMANIFEST\nThe MANIFEST will be used by the Makefile's dist target to build the distribution tar file that\nis uploaded to CPAN. It should list every file that you want to include in your distribution,\none per line.\n\nlib/Bundle/DBD/Driver.pm\nThe CPAN module provides an extremely powerful bundle mechanism that allows you to specify\npre-requisites for your driver.\n\nThe primary pre-requisite is Bundle::DBI; you may want or need to add some more. With the bundle\nset up correctly, the user can type:\n\nperl -MCPAN -e 'install Bundle::DBD::Driver'\n\nand Perl will download, compile, test and install all the Perl modules needed to build your\ndriver.\n\nThe prerequisite modules are listed in the \"CONTENTS\" section, with the official name of the\nmodule followed by a dash and an informal name or description.\n\n*   Listing Bundle::DBI as the main pre-requisite simplifies life.\n\n*   Don't forget to list your driver.\n\n*   Note that unless the DBMS is itself a Perl module, you cannot list it as a pre-requisite in\nthis file.\n\n*   You should keep the version of the bundle the same as the version of your driver.\n\n*   You should add configuration management, copyright, and licencing information at the top.\n\nA suitable skeleton for this file is shown below.\n\npackage Bundle::DBD::Driver;\n\n$VERSION = '0.01';\n\n1;\n\nEND\n\n=head1 NAME\n\nBundle::DBD::Driver - A bundle to install all DBD::Driver related modules\n\n=head1 SYNOPSIS\n\nC<perl -MCPAN -e 'install Bundle::DBD::Driver'>\n\n=head1 CONTENTS\n\nBundle::DBI  - Bundle for DBI by TIMB (Tim Bunce)\n\nDBD::Driver  - DBD::Driver by YOU (Your Name)\n\n=head1 DESCRIPTION\n\nThis bundle includes all the modules used by the Perl Database\nInterface (DBI) driver for Driver (DBD::Driver), assuming the\nuse of DBI version 1.13 or later, created by Tim Bunce.\n\nIf you've not previously used the CPAN module to install any\nbundles, you will be interrogated during its setup phase.\nBut when you've done it once, it remembers what you told it.\nYou could start by running:\n\nC<perl -MCPAN -e 'install Bundle::CPAN'>\n\n=head1 SEE ALSO\n\nBundle::DBI\n\n=head1 AUTHOR\n\nYour Name E<lt>F<you@yourdomain.com>E<gt>\n\n=head1 THANKS\n\nThis bundle was created by ripping off Bundle::libnet created by\nGraham Barr E<lt>F<gbarr@ti.com>E<gt>, and radically simplified\nwith some information from Jochen Wiedmann E<lt>F<joe@ispsoft.de>E<gt>.\nThe template was then included in the DBI::DBD documentation by\nJonathan Leffler E<lt>F<jleffler@informix.com>E<gt>.\n\n=cut\n\nlib/DBD/Driver/Summary.pm\nThere is no substitute for taking the summary file from a driver that was documented in the Perl\nbook (such as DBD::Oracle or DBD::Informix or DBD::ODBC, to name but three), and adapting it to\ndescribe the facilities available via DBD::Driver when accessing the Driver database.\n"
                },
                {
                    "name": "Pure Perl version of Driver.pm",
                    "content": "The Driver.pm file defines the Perl module DBD::Driver for your driver. It will define a package\nDBD::Driver along with some version information, some variable definitions, and a function\n\"driver()\" which will have a more or less standard structure.\n\nIt will also define three sub-packages of DBD::Driver:\n\nDBD::Driver::dr\nwith methods \"connect()\", \"datasources()\" and \"disconnectall()\";\n\nDBD::Driver::db\nwith methods such as \"prepare()\";\n\nDBD::Driver::st\nwith methods such as \"execute()\" and \"fetch()\".\n\nThe Driver.pm file will also contain the documentation specific to DBD::Driver in the format\nused by perldoc.\n\nIn a pure Perl driver, the Driver.pm file is the core of the implementation. You will need to\nprovide all the key methods needed by DBI.\n\nNow let's take a closer look at an excerpt of File.pm as an example. We ignore things that are\ncommon to any module (even non-DBI modules) or really specific to the DBD::File package.\n\nThe DBD::Driver package\nThe header\npackage DBD::File;\n\nuse strict;\nuse vars qw($VERSION $drh);\n\n$VERSION = \"1.23.00\"  # Version number of DBD::File\n\nThis is where the version number of your driver is specified, and is where Makefile.PL looks for\nthis information. Please ensure that any other modules added with your driver are also version\nstamped so that CPAN does not get confused.\n\nIt is recommended that you use a two-part (1.23) or three-part (1.23.45) version number. Also\nconsider the CPAN system, which gets confused and considers version 1.10 to precede version 1.9,\nso that using a raw CVS, RCS or SCCS version number is probably not appropriate (despite being\nvery common).\n\nFor Subversion you could use:\n\n$VERSION = \"12.012346\";\n\n(use lots of leading zeros on the second portion so if you move the code to a shared repository\nlike svn.perl.org the much larger revision numbers won't cause a problem, at least not for a few\nyears). For RCS or CVS you can use:\n\n$VERSION = \"11.22\";\n\nwhich pads out the fractional part with leading zeros so all is well (so long as you don't go\npast x.99)\n\n$drh = undef;         # holds driver handle once initialized\n\nThis is where the driver handle will be stored, once created. Note that you may assume there is\nonly one handle for your driver.\n\nThe driver constructor\nThe \"driver()\" method is the driver handle constructor. Note that the \"driver()\" method is in\nthe DBD::Driver package, not in one of the sub-packages DBD::Driver::dr, DBD::Driver::db, or\nDBD::Driver::db.\n\nsub driver\n{\nreturn $drh if $drh;      # already created - return same one\nmy ($class, $attr) = @;\n\n$class .= \"::dr\";\n\nDBD::Driver::db->installmethod('drvexampledbhmethod');\nDBD::Driver::st->installmethod('drvexamplesthmethod');\n\n# not a 'my' since we use it above to prevent multiple drivers\n$drh = DBI::newdrh($class, {\n'Name'        => 'File',\n'Version'     => $VERSION,\n'Attribution' => 'DBD::File by Jochen Wiedmann',\n})\nor return undef;\n\nreturn $drh;\n}\n\nThis is a reasonable example of how DBI implements its handles. There are three kinds: driver\nhandles (typically stored in *$drh*; from now on called *drh* or *$drh*), database handles (from\nnow on called *dbh* or *$dbh*) and statement handles (from now on called *sth* or *$sth*).\n\nThe prototype of \"DBI::newdrh()\" is\n\n$drh = DBI::newdrh($class, $publicattrs, $privateattrs);\n\nwith the following arguments:\n\n*$class*\nis typically the class for your driver, (for example, \"DBD::File::dr\"), passed as the first\nargument to the \"driver()\" method.\n\n*$publicattrs*\nis a hash ref to attributes like *Name*, *Version*, and *Attribution*. These are processed\nand used by DBI. You had better not make any assumptions about them nor should you add\nprivate attributes here.\n\n*$privateattrs*\nThis is another (optional) hash ref with your private attributes. DBI will store them and\notherwise leave them alone.\n\nThe \"DBI::newdrh()\" method and the \"driver()\" method both return \"undef\" for failure (in which\ncase you must look at *$DBI::err* and *$DBI::errstr* for the failure information, because you\nhave no driver handle to use).\n\nUsing installmethod() to expose driver-private methods\nDBD::Foo::db->installmethod($methodname, \\%attr);\n\nInstalls the driver-private method named by $methodname into the DBI method dispatcher so it\ncan be called directly, avoiding the need to use the func() method.\n\nIt is called as a static method on the driver class to which the method belongs. The method name\nmust begin with the corresponding registered driver-private prefix. For example, for DBD::Oracle\n$methodname must being with '\"ora\"', and for DBD::AnyData it must begin with '\"ad\"'.\n\nThe \"\\%attr\" attributes can be used to provide fine control over how the DBI dispatcher handles\nthe dispatching of the method. However it's undocumented at the moment. See the IMA* #define's\nin DBI.xs and the O=>0x000x values in the initialization of %DBI::DBImethods in DBI.pm.\n(Volunteers to polish up and document the interface are very welcome to get in touch via\ndbi-dev@perl.org).\n\nMethods installed using installmethod default to the standard error handling behaviour for DBI\nmethods: clearing err and errstr before calling the method, and checking for errors to trigger\nRaiseError etc. on return. This differs from the default behaviour of func().\n\nNote for driver authors: The DBD::Foo::xx->installmethod call won't work until the\nclass-hierarchy has been setup. Normally the DBI looks after that just after the driver is\nloaded. This means installmethod() can't be called at the time the driver is loaded unless the\nclass-hierarchy is set up first. The way to do that is to call the setupdriver() method:\n\nDBI->setupdriver('DBD::Foo');\n\nbefore using installmethod().\n\nThe CLONE special subroutine\nAlso needed here, in the DBD::Driver package, is a \"CLONE()\" method that will be called by perl\nwhen an interpreter is cloned. All your \"CLONE()\" method needs to do, currently, is clear the\ncached *$drh* so the new interpreter won't start using the cached *$drh* from the old\ninterpreter:\n\nsub CLONE {\nundef $drh;\n}\n\nSee <http://search.cpan.org/dist/perl/pod/perlmod.pod#Makingyourmodulethreadsafe> for\ndetails.\n\nThe DBD::Driver::dr package\nThe next lines of code look as follows:\n\npackage DBD::Driver::dr; # ====== DRIVER ======\n\n$DBD::Driver::dr::impdatasize = 0;\n\nNote that no *@ISA* is needed here, or for the other DBD::Driver::* classes, because the DBI\ntakes care of that for you when the driver is loaded.\n\n*FIX ME* Explain what the impdatasize is, so that implementors aren't\npracticing cargo-cult programming.\n\nThe database handle constructor\nThe database handle constructor is the driver's (hence the changed namespace) \"connect()\"\nmethod:\n\nsub connect\n{\nmy ($drh, $drdsn, $user, $auth, $attr) = @;\n\n# Some database specific verifications, default settings\n# and the like can go here. This should only include\n# syntax checks or similar stuff where it's legal to\n# 'die' in case of errors.\n# For example, many database packages requires specific\n# environment variables to be set; this could be where you\n# validate that they are set, or default them if they are not set.\n\nmy $driverprefix = \"drv\"; # the assigned prefix for this driver\n\n# Process attributes from the DSN; we assume ODBC syntax\n# here, that is, the DSN looks like var1=val1;...;varN=valN\nforeach my $var ( split /;/, $drdsn ) {\nmy ($attrname, $attrvalue) = split '=', $var, 2;\nreturn $drh->seterr($DBI::stderr, \"Can't parse DSN part '$var'\")\nunless defined $attrvalue;\n\n# add driver prefix to attribute name if it doesn't have it already\n$attrname = $driverprefix.$attrname\nunless $attrname =~ /^$driverprefix/o;\n\n# Store attribute into %$attr, replacing any existing value.\n# The DBI will STORE() these into $dbh after we've connected\n$attr->{$attrname} = $attrvalue;\n}\n\n# Get the attributes we'll use to connect.\n# We use delete here because these no need to STORE them\nmy $db = delete $attr->{drvdatabase} || delete $attr->{drvdb}\nor return $drh->seterr($DBI::stderr, \"No database name given in DSN '$drdsn'\");\nmy $host = delete $attr->{drvhost} || 'localhost';\nmy $port = delete $attr->{drvport} || 123456;\n\n# Assume you can attach to your database via drvconnect:\nmy $connection = drvconnect($db, $host, $port, $user, $auth)\nor return $drh->seterr($DBI::stderr, \"Can't connect to $drdsn: ...\");\n\n# create a 'blank' dbh (call superclass constructor)\nmy ($outer, $dbh) = DBI::newdbh($drh, { Name => $drdsn });\n\n$dbh->STORE('Active', 1 );\n$dbh->{drvconnection} = $connection;\n\nreturn $outer;\n}\n\nThis is mostly the same as in the *driver handle constructor* above. The arguments are described\nin DBI.\n\nThe constructor \"DBI::newdbh()\" is called, returning a database handle. The constructor's\nprototype is:\n\n($outer, $inner) = DBI::newdbh($drh, $publicattr, $privateattr);\n\nwith similar arguments to those in the *driver handle constructor*, except that the *$class* is\nreplaced by *$drh*. The *Name* attribute is a standard DBI attribute (see \"Database Handle\nAttributes\" in DBI).\n\nIn scalar context, only the outer handle is returned.\n\nNote the use of the \"STORE()\" method for setting the *dbh* attributes. That's because within the\ndriver code, the handle object you have is the 'inner' handle of a tied hash, not the outer\nhandle that the users of your driver have.\n\nBecause you have the inner handle, tie magic doesn't get invoked when you get or set values in\nthe hash. This is often very handy for speed when you want to get or set simple non-special\ndriver-specific attributes.\n\nHowever, some attribute values, such as those handled by the DBI like *PrintError*, don't\nactually exist in the hash and must be read via \"$h->FETCH($attrib)\" and set via\n\"$h->STORE($attrib, $value)\". If in any doubt, use these methods.\n\nThe datasources() method\nThe \"datasources()\" method must populate and return a list of valid data sources, prefixed with\nthe \"*dbi:Driver*\" incantation that allows them to be used in the first argument of the\n\"DBI->connect()\" method. An example of this might be scanning the $HOME/.odbcini file on Unix\nfor ODBC data sources (DSNs).\n\nAs a trivial example, consider a fixed list of data sources:\n\nsub datasources\n{\nmy($drh, $attr) = @;\nmy(@list) = ();\n# You need more sophisticated code than this to set @list...\npush @list, \"dbi:Driver:abc\";\npush @list, \"dbi:Driver:def\";\npush @list, \"dbi:Driver:ghi\";\n# End of code to set @list\nreturn @list;\n}\n\nThe disconnectall() method\nIf you need to release any resources when the driver is unloaded, you can provide a\ndisconnectall method.\n\nOther driver handle methods\nIf you need any other driver handle methods, they can follow here.\n\nError handling\nIt is quite likely that something fails in the connect method. With DBD::File for example, you\nmight catch an error when setting the current directory to something not existent by using the\n(driver-specific) *fdir* attribute.\n\nTo report an error, you use the \"seterr()\" method:\n\n$h->seterr($err, $errmsg, $state);\n\nThis will ensure that the error is recorded correctly and that *RaiseError* and *PrintError* etc\nare handled correctly.\n\nTypically you'll always use the method instance, aka your method's first argument.\n\nAs \"seterr()\" always returns \"undef\" your error handling code can usually be simplified to\nsomething like this:\n\nreturn $h->seterr($err, $errmsg, $state) if ...;\n\nThe DBD::Driver::db package\npackage DBD::Driver::db; # ====== DATABASE ======\n\n$DBD::Driver::db::impdatasize = 0;\n\nThe statement handle constructor\nThere's nothing much new in the statement handle constructor, which is the \"prepare()\" method:\n\nsub prepare\n{\nmy ($dbh, $statement, @attribs) = @;\n\n# create a 'blank' sth\nmy ($outer, $sth) = DBI::newsth($dbh, { Statement => $statement });\n\n$sth->STORE('NUMOFPARAMS', ($statement =~ tr/?//));\n\n$sth->{drvparams} = [];\n\nreturn $outer;\n}\n\nThis is still the same -- check the arguments and call the super class constructor\n\"DBI::newsth()\". Again, in scalar context, only the outer handle is returned. The *Statement*\nattribute should be cached as shown.\n\nNote the prefix *drv* in the attribute names: it is required that all your private attributes\nuse a lowercase prefix unique to your driver. As mentioned earlier in this document, the DBI\ncontains a registry of known driver prefixes and may one day warn about unknown attributes that\ndon't have a registered prefix.\n\nNote that we parse the statement here in order to set the attribute *NUMOFPARAMS*. The\ntechnique illustrated is not very reliable; it can be confused by question marks appearing in\nquoted strings, delimited identifiers or in SQL comments that are part of the SQL statement. We\ncould set *NUMOFPARAMS* in the \"execute()\" method instead because the DBI specification\nexplicitly allows a driver to defer this, but then the user could not call \"bindparam()\".\n\nTransaction handling\nPure Perl drivers will rarely support transactions. Thus your \"commit()\" and \"rollback()\"\nmethods will typically be quite simple:\n\nsub commit\n{\nmy ($dbh) = @;\nif ($dbh->FETCH('Warn')) {\nwarn(\"Commit ineffective while AutoCommit is on\");\n}\n0;\n}\n\nsub rollback {\nmy ($dbh) = @;\nif ($dbh->FETCH('Warn')) {\nwarn(\"Rollback ineffective while AutoCommit is on\");\n}\n0;\n}\n\nOr even simpler, just use the default methods provided by the DBI that do nothing except return\n\"undef\".\n\nThe DBI's default \"beginwork()\" method can be used by inheritance.\n\nThe STORE() and FETCH() methods\nThese methods (that we have already used, see above) are called for you, whenever the user does\na:\n\n$dbh->{$attr} = $val;\n\nor, respectively,\n\n$val = $dbh->{$attr};\n\nSee perltie for details on tied hash refs to understand why these methods are required.\n\nThe DBI will handle most attributes for you, in particular attributes like *RaiseError* or\n*PrintError*. All you have to do is handle your driver's private attributes and any attributes,\nlike *AutoCommit* and *ChopBlanks*, that the DBI can't handle for you.\n\nA good example might look like this:\n\nsub STORE\n{\nmy ($dbh, $attr, $val) = @;\nif ($attr eq 'AutoCommit') {\n# AutoCommit is currently the only standard attribute we have\n# to consider.\nif (!$val) { die \"Can't disable AutoCommit\"; }\nreturn 1;\n}\nif ($attr =~ m/^drv/) {\n# Handle only our private attributes here\n# Note that we could trigger arbitrary actions.\n# Ideally we should warn about unknown attributes.\n$dbh->{$attr} = $val; # Yes, we are allowed to do this,\nreturn 1;             # but only for our private attributes\n}\n# Else pass up to DBI to handle for us\n$dbh->SUPER::STORE($attr, $val);\n}\n\nsub FETCH\n{\nmy ($dbh, $attr) = @;\nif ($attr eq 'AutoCommit') { return 1; }\nif ($attr =~ m/^drv/) {\n# Handle only our private attributes here\n# Note that we could trigger arbitrary actions.\nreturn $dbh->{$attr}; # Yes, we are allowed to do this,\n# but only for our private attributes\n}\n# Else pass up to DBI to handle\n$dbh->SUPER::FETCH($attr);\n}\n\nThe DBI will actually store and fetch driver-specific attributes (with all lowercase names)\nwithout warning or error, so there's actually no need to implement driver-specific any code in\nyour \"FETCH()\" and \"STORE()\" methods unless you need extra logic/checks, beyond getting or\nsetting the value.\n\nUnless your driver documentation indicates otherwise, the return value of the \"STORE()\" method\nis unspecified and the caller shouldn't use that value.\n\nOther database handle methods\nAs with the driver package, other database handle methods may follow here. In particular you\nshould consider a (possibly empty) \"disconnect()\" method and possibly a \"quote()\" method if\nDBI's default isn't correct for you. You may also need the \"typeinfoall()\" and \"getinfo()\"\nmethods, as described elsewhere in this document.\n\nWhere reasonable use \"$h->SUPER::foo()\" to call the DBI's method in some or all cases and just\nwrap your custom behavior around that.\n\nIf you want to use private trace flags you'll probably want to be able to set them by name. To\ndo that you'll need to define a \"parsetraceflag()\" method (note that's \"parsetraceflag\",\nsingular, not \"parsetraceflags\", plural).\n\nsub parsetraceflag {\nmy ($h, $name) = @;\nreturn 0x01000000 if $name eq 'foo';\nreturn 0x02000000 if $name eq 'bar';\nreturn 0x04000000 if $name eq 'baz';\nreturn 0x08000000 if $name eq 'boo';\nreturn 0x10000000 if $name eq 'bop';\nreturn $h->SUPER::parsetraceflag($name);\n}\n\nAll private flag names must be lowercase, and all private flags must be in the top 8 of the 32\nbits.\n\nThe DBD::Driver::st package\nThis package follows the same pattern the others do:\n\npackage DBD::Driver::st;\n\n$DBD::Driver::st::impdatasize = 0;\n\nThe execute() and bindparam() methods\nThis is perhaps the most difficult method because we have to consider parameter bindings here.\nIn addition to that, there are a number of statement attributes which must be set for inherited\nDBI methods to function correctly (see \"Statement attributes\" below).\n\nWe present a simplified implementation by using the *drvparams* attribute from above:\n\nsub bindparam\n{\nmy ($sth, $pNum, $val, $attr) = @;\nmy $type = (ref $attr) ? $attr->{TYPE} : $attr;\nif ($type) {\nmy $dbh = $sth->{Database};\n$val = $dbh->quote($sth, $type);\n}\nmy $params = $sth->{drvparams};\n$params->[$pNum-1] = $val;\n1;\n}\n\nsub execute\n{\nmy ($sth, @bindvalues) = @;\n\n# start of by finishing any previous execution if still active\n$sth->finish if $sth->FETCH('Active');\n\nmy $params = (@bindvalues) ?\n\\@bindvalues : $sth->{drvparams};\nmy $numParam = $sth->FETCH('NUMOFPARAMS');\nreturn $sth->seterr($DBI::stderr, \"Wrong number of parameters\")\nif @$params != $numParam;\nmy $statement = $sth->{'Statement'};\nfor (my $i = 0;  $i < $numParam;  $i++) {\n$statement =~ s/?/$params->[$i]/; # XXX doesn't deal with quoting etc!\n}\n# Do anything ... we assume that an array ref of rows is\n# created and store it:\n$sth->{'drvdata'} = $data;\n$sth->{'drvrows'} = @$data; # number of rows\n$sth->STORE('NUMOFFIELDS') = $numFields;\n$sth->{Active} = 1;\n@$data || '0E0';\n}\n\nThere are a number of things you should note here.\n\nWe initialize the *NUMOFFIELDS* and *Active* attributes here, because they are essential for\n\"bindcolumns()\" to work.\n\nWe use attribute \"$sth->{Statement}\" which we created within \"prepare()\". The attribute\n\"$sth->{Database}\", which is nothing else than the *dbh*, was automatically created by DBI.\n\nFinally, note that (as specified in the DBI specification) we return the string '0E0' instead of\nthe number 0, so that the result tests true but equal to zero.\n\n$sth->execute() or die $sth->errstr;\n\nThe executearray(), executeforfetch() and bindparamarray() methods\nIn general, DBD's only need to implement \"executeforfetch()\" and \"bindparamarray\". DBI's\ndefault \"executearray()\" will invoke the DBD's \"executeforfetch()\" as needed.\n\nThe following sequence describes the interaction between DBI \"executearray\" and a DBD's\n\"executeforfetch\":\n\n1   App calls \"$sth->executearray(\\%attrs, @arrayofarrays)\"\n\n2   If @arrayofarrays was specified, DBI processes @arrayofarrays by calling DBD's\n\"bindparamarray()\". Alternately, App may have directly called \"bindparamarray()\"\n\n3   DBD validates and binds each array\n\n4   DBI retrieves the validated param arrays from DBD's ParamArray attribute\n\n5   DBI calls DBD's \"executeforfetch($fetchtuplesub, \\@tuplestatus)\", where\n&$fetchtuplesub is a closure to iterate over the returned ParamArray values, and\n\"\\@tuplestatus\" is an array to receive the disposition status of each tuple.\n\n6   DBD iteratively calls &$fetchtuplesub to retrieve parameter tuples to be added to its bulk\ndatabase operation/request.\n\n7   when DBD reaches the limit of tuples it can handle in a single database operation/request,\nor the &$fetchtuplesub indicates no more tuples by returning undef, the DBD executes the\nbulk operation, and reports the disposition of each tuple in \\@tuplestatus.\n\n8   DBD repeats steps 6 and 7 until all tuples are processed.\n\nE.g., here's the essence of DBD::Oracle's executeforfetch:\n\nwhile (1) {\nmy @tuplebatch;\nfor (my $i = 0; $i < $batchsize; $i++) {\npush @tuplebatch, [ @{$fetchtuplesub->() || last} ];\n}\nlast unless @tuplebatch;\nmy $res = oraexecutearray($sth, \\@tuplebatch,\nscalar(@tuplebatch), $tuplebatchstatus);\npush @$tuplestatus, @$tuplebatchstatus;\n}\n\nNote that DBI's default executearray()/executeforfetch() implementation requires the use of\npositional (i.e., '?') placeholders. Drivers which require named placeholders must either\nemulate positional placeholders (e.g., see DBD::Oracle), or must implement their own"
                },
                {
                    "name": "execute_array",
                    "content": "Fetching data\nOnly one method needs to be written for fetching data, \"fetchrowarrayref()\". The other methods,\n\"fetchrowarray()\", \"fetchallarrayref()\", etc, as well as the database handle's \"select*\"\nmethods are part of DBI, and call \"fetchrowarrayref()\" as necessary.\n\nsub fetchrowarrayref\n{\nmy ($sth) = @;\nmy $data = $sth->{drvdata};\nmy $row = shift @$data;\nif (!$row) {\n$sth->STORE(Active => 0); # mark as no longer active\nreturn undef;\n}\nif ($sth->FETCH('ChopBlanks')) {\nmap { $ =~ s/\\s+$//; } @$row;\n}\nreturn $sth->setfbav($row);\n}\n*fetch = \\&fetchrowarrayref; # required alias for fetchrowarrayref\n\nNote the use of the method \"setfbav()\" -- this is required so that \"bindcol()\" and\n\"bindcolumns()\" work.\n\nIf an error occurs which leaves the *$sth* in a state where remaining rows can't be fetched then\n*Active* should be turned off before the method returns.\n\nThe \"rows()\" method for this driver can be implemented like this:\n\nsub rows { shift->{drvrows} }\n\nbecause it knows in advance how many rows it has fetched. Alternatively you could delete that\nmethod and so fallback to the DBI's own method which does the right thing based on the number of\ncalls to \"setfbav()\".\n\nThe moreresults method\nIf your driver doesn't support multiple result sets, then don't even implement this method.\n\nOtherwise, this method needs to get the statement handle ready to fetch results from the next\nresult set, if there is one. Typically you'd start with:\n\n$sth->finish;\n\nthen you should delete all the attributes from the attribute cache that may no longer be\nrelevant for the new result set:\n\ndelete $sth->{$}\nfor qw(NAME TYPE PRECISION SCALE ...);\n\nfor drivers written in C use:\n\nhvdelete((HV*)SvRV(sth), \"NAME\", 4, GDISCARD);\nhvdelete((HV*)SvRV(sth), \"NULLABLE\", 8, GDISCARD);\nhvdelete((HV*)SvRV(sth), \"NUMOFFIELDS\", 13, GDISCARD);\nhvdelete((HV*)SvRV(sth), \"PRECISION\", 9, GDISCARD);\nhvdelete((HV*)SvRV(sth), \"SCALE\", 5, GDISCARD);\nhvdelete((HV*)SvRV(sth), \"TYPE\", 4, GDISCARD);\n\nDon't forget to also delete, or update, any driver-private attributes that may not be correct\nfor the next resultset.\n\nThe NUMOFFIELDS attribute is a special case. It should be set using STORE:\n\n$sth->STORE(NUMOFFIELDS => 0); /* for DBI <= 1.53 */\n$sth->STORE(NUMOFFIELDS => $newvalue);\n\nfor drivers written in C use this incantation:\n\n/* Adjust NUMOFFIELDS - which also adjusts the row buffer size */\nDBIcNUMFIELDS(impsth) = 0; /* for DBI <= 1.53 */\nDBIcSTATE(impxxh)->setattrk(sth, sv2mortal(newSVpvn(\"NUMOFFIELDS\",13)), 0,\nsv2mortal(newSViv(mysqlnumfields(impsth->result)))\n);\n\nFor DBI versions prior to 1.54 you'll also need to explicitly adjust the number of elements in\nthe row buffer array (\"DBIcFIELDSAV(impsth)\") to match the new result set. Fill any new\nvalues with newSV(0) not &svundef. Alternatively you could free DBIcFIELDSAV(impsth) and set\nit to null, but that would mean bindcolumns() wouldn't work across result sets.\n\nStatement attributes\nThe main difference between *dbh* and *sth* attributes is, that you should implement a lot of\nattributes here that are required by the DBI, such as *NAME*, *NULLABLE*, *TYPE*, etc. See\n\"Statement Handle Attributes\" in DBI for a complete list.\n\nPay attention to attributes which are marked as read only, such as *NUMOFPARAMS*. These\nattributes can only be set the first time a statement is executed. If a statement is prepared,\nthen executed multiple times, warnings may be generated.\n\nYou can protect against these warnings, and prevent the recalculation of attributes which might\nbe expensive to calculate (such as the *NAME* and *NAME attributes):\n\nmy $storedNumParams = $sth->FETCH('NUMOFPARAMS');\nif (!defined $storedNumParams or $storedNumFields < 0) {\n$sth->STORE('NUMOFPARAMS') = $numParams;\n\n# Set other useful attributes that only need to be set once\n# for a statement, like $sth->{NAME} and $sth->{TYPE}\n}\n\nOne particularly important attribute to set correctly (mentioned in \"ATTRIBUTES COMMON TO ALL\nHANDLES\" in DBI is *Active*. Many DBI methods, including \"bindcolumns()\", depend on this\nattribute.\n\nBesides that the \"STORE()\" and \"FETCH()\" methods are mainly the same as above for *dbh*'s.\n\nOther statement methods\nA trivial \"finish()\" method to discard stored data, reset any attributes (such as *Active*) and\ndo \"$sth->SUPER::finish()\".\n\nIf you've defined a \"parsetraceflag()\" method in ::db you'll also want it in ::st, so just\nalias it in:\n\n*parsetraceflag = \\&DBD::foo:db::parsetraceflag;\n\nAnd perhaps some other methods that are not part of the DBI specification, in particular to make\nmetadata available. Remember that they must have names that begin with your drivers registered\nprefix so they can be installed using \"installmethod()\".\n\nIf \"DESTROY()\" is called on a statement handle that's still active (\"$sth->{Active}\" is true)\nthen it should effectively call \"finish()\".\n\nsub DESTROY {\nmy $sth = shift;\n$sth->finish if $sth->FETCH('Active');\n}\n"
                },
                {
                    "name": "Tests",
                    "content": "The test process should conform as closely as possibly to the Perl standard test harness.\n\nIn particular, most (all) of the tests should be run in the t sub-directory, and should simply\nproduce an \"ok\" when run under \"make test\". For details on how this is done, see the Camel book\nand the section in Chapter 7, \"The Standard Perl Library\" on Test::Harness.\n\nThe tests may need to adapt to the type of database which is being used for testing, and to the\nprivileges of the user testing the driver. For example, the DBD::Informix test code has to adapt\nin a number of places to the type of database to which it is connected as different Informix\ndatabases have different capabilities: some of the tests are for databases without transaction\nlogs; others are for databases with a transaction log; some versions of the server have support\nfor blobs, or stored procedures, or user-defined data types, and others do not.\n\nWhen a complete file of tests must be skipped, you can provide a reason in a pseudo-comment:\n\nif ($notransactionsavailable)\n{\nprint \"1..0 # Skip: No transactions available\\n\";\nexit 0;\n}\n\nConsider downloading the DBD::Informix code and look at the code in DBD/Informix/TestHarness.pm\nwhich is used throughout the DBD::Informix tests in the t sub-directory.\n"
                }
            ]
        },
        "CREATING A C/XS DRIVER": {
            "content": "Please also see the section under \"CREATING A PURE PERL DRIVER\" regarding the creation of the\nMakefile.PL.\n\nCreating a new C/XS driver from scratch will always be a daunting task. You can and should\ngreatly simplify your task by taking a good reference driver implementation and modifying that\nto match the database product for which you are writing a driver.\n\nThe de facto reference driver has been the one for DBD::Oracle written by Tim Bunce, who is also\nthe author of the DBI package. The DBD::Oracle module is a good example of a driver implemented\naround a C-level API.\n\nNowadays it it seems better to base on DBD::ODBC, another driver maintained by Tim and Jeff\nUrlwin, because it offers a lot of metadata and seems to become the guideline for the future\ndevelopment. (Also as DBD::Oracle digs deeper into the Oracle 8 OCI interface it'll get even\nmore hairy than it is now.)\n\nThe DBD::Informix driver is one driver implemented using embedded SQL instead of a\nfunction-based API. DBD::Ingres may also be worth a look.\n\nC/XS version of Driver.pm\nA lot of the code in the Driver.pm file is very similar to the code for pure Perl modules - see\nabove. However, there are also some subtle (and not so subtle) differences, including:\n\n*       The variables *$DBD::Driver::{dr|db|st}::impdatasize* are not defined here, but in the\nXS code, because they declare the size of certain C structures.\n\n*       Some methods are typically moved to the XS code, in particular \"prepare()\", \"execute()\",\n\"disconnect()\", \"disconnectall()\" and the \"STORE()\" and \"FETCH()\" methods.\n\n*       Other methods are still part of Driver.pm, but have callbacks to the XS code.\n\n*       If the driver-specific parts of the *impdrht* structure need to be formally\ninitialized (which does not seem to be a common requirement), then you need to add a\ncall to an appropriate XS function in the driver method of \"DBD::Driver::driver()\", and\nyou define the corresponding function in Driver.xs, and you define the C code in\ndbdimp.c and the prototype in dbdimp.h.\n\nFor example, DBD::Informix has such a requirement, and adds the following call after the\ncall to \"newdrh()\" in Informix.pm:\n\nDBD::Informix::dr::driverinit($drh);\n\nand the following code in Informix.xs:\n\n# Initialize the DBD::Informix driver data structure\nvoid\ndriverinit(drh)\nSV *drh\nCODE:\nST(0) = dbdixdrdriverinit(drh) ? &svyes : &svno;\n\nand the code in dbdimp.h declares:\n\nextern int dbdixdrdriverinit(SV *drh);\n\nand the code in dbdimp.ec (equivalent to dbdimp.c) defines:\n\n/* Formally initialize the DBD::Informix driver structure */\nint\ndbdixdrdriver(SV *drh)\n{\nDimpdrh(drh);\nimpdrh->nconnections = 0;       /* No active connections */\nimpdrh->currentconnection = 0;  /* No current connection */\nimpdrh->multipleconnections = (ESQLCVERSION >= 600) ? True : False;\ndbdixlinknewhead(&impdrh->head);  /* Empty linked list of connections */\nreturn 1;\n}\n\nDBD::Oracle has a similar requirement but gets around it by checking whether the private\ndata part of the driver handle is all zeroed out, rather than add extra functions.\n\nNow let's take a closer look at an excerpt from Oracle.pm (revised heavily to remove\nidiosyncrasies) as an example, ignoring things that were already discussed for pure Perl\ndrivers.\n\nThe connect method\nThe connect method is the database handle constructor. You could write either of two versions of\nthis method: either one which takes connection attributes (new code) and one which ignores them\n(old code only).\n\nIf you ignore the connection attributes, then you omit all mention of the *$auth* variable\n(which is a reference to a hash of attributes), and the XS system manages the differences for\nyou.\n\nsub connect\n{\nmy ($drh, $dbname, $user, $auth, $attr) = @;\n\n# Some database specific verifications, default settings\n# and the like following here. This should only include\n# syntax checks or similar stuff where it's legal to\n# 'die' in case of errors.\n\nmy $dbh = DBI::newdbh($drh, {\n'Name'   => $dbname,\n})\nor return undef;\n\n# Call the driver-specific function login in Driver.xs file which\n# calls the DBMS-specific function(s) to connect to the database,\n# and populate internal handle data.\nDBD::Driver::db::login($dbh, $dbname, $user, $auth, $attr)\nor return undef;\n\n$dbh;\n}\n\nThis is mostly the same as in the pure Perl case, the exception being the use of the private\n\"login()\" callback, which is the function that will really connect to the database. It is\nimplemented in Driver.xst (you should not implement it) and calls \"dbddblogin6()\" or\n\"dbddblogin6sv\" from dbdimp.c. See below for details.\n\nIf your driver has driver-specific attributes which may be passed in the connect method and\nhence end up in $attr in \"dbddblogin6\" then it is best to delete any you process so DBI does\nnot send them again via STORE after connect. You can do this in C like this:\n\nDBDATTRIBDELETE(attr, \"myattributename\",\nstrlen(\"myattributename\"));\n\nHowever, prior to DBI subversion version 11605 (and fixed post 1.607) DBDATTRIBDELETE\nsegfaulted so if you cannot guarantee the DBI version will be post 1.607 you need to use:\n\nhvdelete((HV*)SvRV(attr), \"myattributename\",\nstrlen(\"myattributename\"), GDISCARD);\n\n*FIX ME* Discuss removing attributes in Perl code.\n\nThe disconnectall method\n*FIX ME* T.B.S\n\nThe datasources method\nIf your \"datasources()\" method can be implemented in pure Perl, then do so because it is easier\nthan doing it in XS code (see the section above for pure Perl drivers).\n\nIf your \"datasources()\" method must call onto compiled functions, then you will need to define\n*dbddrdatasources* in your dbdimp.h file, which will trigger Driver.xst (in DBI v1.33 or\ngreater) to generate the XS code that calls your actual C function (see the discussion below for\ndetails) and you do not code anything in Driver.pm to handle it.\n\nThe prepare method\nThe prepare method is the statement handle constructor, and most of it is not new. Like the\n\"connect()\" method, it now has a C callback:\n\npackage DBD::Driver::db; # ====== DATABASE ======\nuse strict;\n\nsub prepare\n{\nmy ($dbh, $statement, $attribs) = @;\n\n# create a 'blank' sth\nmy $sth = DBI::newsth($dbh, {\n'Statement' => $statement,\n})\nor return undef;\n\n# Call the driver-specific function prepare in Driver.xs file\n# which calls the DBMS-specific function(s) to prepare a statement\n# and populate internal handle data.\nDBD::Driver::st::prepare($sth, $statement, $attribs)\nor return undef;\n$sth;\n}\n\nThe execute method\n*FIX ME* T.B.S\n\nThe fetchrowarrayref method\n*FIX ME* T.B.S\n\nOther methods?\n*FIX ME* T.B.S\n",
            "subsections": [
                {
                    "name": "Driver.xs",
                    "content": "Driver.xs should look something like this:\n\n#include \"Driver.h\"\n\nDBISTATEDECLARE;\n\nINCLUDE: Driver.xsi\n\nMODULE = DBD::Driver    PACKAGE = DBD::Driver::dr\n\n/* Non-standard drh XS methods following here, if any.       */\n/* If none (the usual case), omit the MODULE line above too. */\n\nMODULE = DBD::Driver    PACKAGE = DBD::Driver::db\n\n/* Non-standard dbh XS methods following here, if any.       */\n/* Currently this includes things like listtables from     */\n/* DBD::mSQL and DBD::mysql.                                 */\n\nMODULE = DBD::Driver    PACKAGE = DBD::Driver::st\n\n/* Non-standard sth XS methods following here, if any.       */\n/* In particular this includes things like listfields from */\n/* DBD::mSQL and DBD::mysql for accessing metadata.          */\n\nNote especially the include of Driver.xsi here: DBI inserts stub functions for almost all\nprivate methods here which will typically do much work for you.\n\nWherever you really have to implement something, it will call a private function in dbdimp.c,\nand this is what you have to implement.\n\nYou need to set up an extra routine if your driver needs to export constants of its own,\nanalogous to the SQL types available when you say:\n\nuse DBI qw(:sqltypes);\n\n*FIX ME* T.B.S\n"
                },
                {
                    "name": "Driver.h",
                    "content": "Driver.h is very simple and the operational contents should look like this:\n\n#ifndef DRIVERHINCLUDED\n#define DRIVERHINCLUDED\n\n#define NEEDDBIXSVERSION 93    /* 93 for DBI versions 1.00 to 1.51+ */\n#define PERLNOGETCONTEXT      /* if used require DBI 1.51+ */\n\n#include <DBIXS.h>      /* installed by the DBI module  */\n\n#include \"dbdimp.h\"\n\n#include \"dbivport.h\"   /* see below                    */\n\n#include <dbdxsh.h>    /* installed by the DBI module  */\n\n#endif /* DRIVERHINCLUDED */\n\nThe DBIXS.h header defines most of the interesting information that the writer of a driver\nneeds.\n\nThe file dbdxsh.h header provides prototype declarations for the C functions that you might\ndecide to implement. Note that you should normally only define one of \"dbddblogin()\",\n\"dbddblogin6()\" or \"dbddblogin6sv\" unless you are intent on supporting really old versions\nof DBI (prior to DBI 1.06) as well as modern versions. The only standard, DBI-mandated functions\nthat you need write are those specified in the dbdxsh.h header. You might also add extra\ndriver-specific functions in Driver.xs.\n\nThe dbivport.h file should be *copied* from the latest DBI release into your distribution each\ntime you modify your driver. Its job is to allow you to enhance your code to work with the\nlatest DBI API while still allowing your driver to be compiled and used with older versions of\nthe DBI (for example, when the \"DBIhSETERRCHAR()\" macro was added to DBI 1.41, an emulation\nof it was added to dbivport.h). This makes users happy and your life easier. Always read the\nnotes in dbivport.h to check for any limitations in the emulation that you should be aware of.\n\nWith DBI v1.51 or better I recommend that the driver defines *PERLNOGETCONTEXT* before\nDBIXS.h is included. This can significantly improve efficiency when running under a thread\nenabled perl. (Remember that the standard perl in most Linux distributions is built with threads\nenabled. So is ActiveState perl for Windows, and perl built for Apache modperl2.) If you do\nthis there are some things to keep in mind:\n\n*   If *PERLNOGETCONTEXT* is defined, then every function that calls the Perl API will need\nto start out with a \"dTHX;\" declaration.\n\n*   You'll know which functions need this, because the C compiler will complain that the\nundeclared identifier \"myperl\" is used if *and only if* the perl you are using to develop\nand test your driver has threads enabled.\n\n*   If you don't remember to test with a thread-enabled perl before making a release it's likely\nthat you'll get failure reports from users who are.\n\n*   For driver private functions it is possible to gain even more efficiency by replacing\n\"dTHX;\" with \"pTHX\" prepended to the parameter list and then \"aTHX\" prepended to the\nargument list where the function is called.\n\nSee \"How multiple interpreters and concurrency are supported\" in perlguts for additional\ninformation about *PERLNOGETCONTEXT*.\n"
                },
                {
                    "name": "Implementation header dbdimp.h",
                    "content": "This header file has two jobs:\n\nFirst it defines data structures for your private part of the handles. Note that the DBI\nprovides many common fields for you. For example the statement handle (impsth) already has a\nrowcount field with an IV type that accessed via the DBIcROWCOUNT(impsth) macro. Using this\nis strongly recommended as it's built in to some DBI internals so the DBI can 'just work' in\nmore cases and you'll have less driver-specific code to write. Study DBIXS.h to see what's\nincluded with each type of handle.\n\nSecond it defines macros that rename the generic names like \"dbddblogin()\" to database\nspecific names like \"oradblogin()\". This avoids name clashes and enables use of different\ndrivers when you work with a statically linked perl.\n\nIt also will have the important task of disabling XS methods that you don't want to implement.\n\nFinally, the macros will also be used to select alternate implementations of some functions. For\nexample, the \"dbddblogin()\" function is not passed the attribute hash.\n\nSince DBI v1.06, if a \"dbddblogin6()\" macro is defined (for a function with 6 arguments), it\nwill be used instead with the attribute hash passed as the sixth argument.\n\nSince DBI post v1.607, if a \"dbddblogin6sv()\" macro is defined (for a function like\ndbddblogin6 but with scalar pointers for the dbname, username and password), it will be used\ninstead. This will allow your login6 function to see if there are any Unicode characters in the\ndbname.\n\nSimilarly defining dbddbdo4iv is preferred over dbddbdo4, dbdstrowsiv over dbdstrows,\nand dbdstexecuteiv over dbdstexecute. The *iv forms are declared to return the IV type\ninstead of an int.\n\nPeople used to just pick Oracle's dbdimp.c and use the same names, structures and types. I\nstrongly recommend against that. At first glance this saves time, but your implementation will\nbe less readable. It was just hell when I had to separate DBI specific parts, Oracle specific\nparts, mSQL specific parts and mysql specific parts in DBD::mysql's *dbdimp.h* and *dbdimp.c*.\n(DBD::mysql was a port of DBD::mSQL which was based on DBD::Oracle.) [Seconded, based on the\nexperience taking DBD::Informix apart, even though the version inherited in 1996 was only based\non DBD::Oracle.]\n\nThis part of the driver is *your exclusive part*. Rewrite it from scratch, so it will be clean\nand short: in other words, a better piece of code. (Of course keep an eye on other people's\nwork.)\n\nstruct impdrhst {\ndbihdrct com;           /* MUST be first element in structure   */\n/* Insert your driver handle attributes here */\n};\n\nstruct impdbhst {\ndbihdbct com;           /* MUST be first element in structure   */\n/* Insert your database handle attributes here */\n};\n\nstruct impsthst {\ndbihstct com;           /* MUST be first element in structure   */\n/* Insert your statement handle attributes here */\n};\n\n/*  Rename functions for avoiding name clashes; prototypes are  */\n/*  in dbdxsh.h                                                */\n#define dbdinit            drvdrinit\n#define dbddblogin6sv    drvdbloginsv\n#define dbddbdo           drvdbdo\n... many more here ...\n\nThese structures implement your private part of the handles.\n\nYou *have* to use the name \"impdbh{dr|db|st}\" and the first field *must* be of type\n*dbihdrct|dbct|stct* and *must* be called \"com\".\n\nYou should never access these fields directly, except by using the *DBIcxxx()* macros below.\n"
                },
                {
                    "name": "Implementation source dbdimp.c",
                    "content": "Conventionally, dbdimp.c is the main implementation file (but DBD::Informix calls the file\ndbdimp.ec). This section includes a short note on each function that is used in the Driver.xsi\ntemplate and thus *has* to be implemented.\n\nOf course, you will probably also need to implement other support functions, which should\nusually be file static if they are placed in dbdimp.c. If they are placed in other files, you\nneed to list those files in Makefile.PL (and MANIFEST) to handle them correctly.\n\nIt is wise to adhere to a namespace convention for your functions to avoid conflicts. For\nexample, for a driver with prefix *drv*, you might call externally visible functions\n*dbddrvxxxx*. You should also avoid non-constant global variables as much as possible to\nimprove the support for threading.\n\nSince Perl requires support for function prototypes (ANSI or ISO or Standard C), you should\nwrite your code using function prototypes too.\n\nIt is possible to use either the unmapped names such as \"dbdinit()\" or the mapped names such as\n\"dbdixdrinit()\" in the dbdimp.c file. DBD::Informix uses the mapped names which makes it\neasier to identify where to look for linkage problems at runtime (which will report errors using\nthe mapped names).\n\nMost other drivers, and in particular DBD::Oracle, use the unmapped names in the source code\nwhich makes it a little easier to compare code between drivers and eases discussions on the\n*dbi-dev* mailing list. The majority of the code fragments here will use the unmapped names.\n\nUltimately, you should provide implementations for most of the functions listed in the dbdxsh.h\nheader. The exceptions are optional functions (such as \"dbdstrows()\") and those functions with\nalternative signatures, such as \"dbddblogin6sv\", \"dbddblogin6()\" and *dbddblogin()*. Then\nyou should only implement one of the alternatives, and generally the newer one of the\nalternatives.\n\nThe dbdinit method\n#include \"Driver.h\"\n\nDBISTATEDECLARE;\n\nvoid dbdinit(dbistatet* dbistate)\n{\nDBISTATEINIT;  /*  Initialize the DBI macros  */\n}\n\nThe \"dbdinit()\" function will be called when your driver is first loaded; the bootstrap command\nin \"DBD::Driver::dr::driver()\" triggers this, and the call is generated in the *BOOT* section of\nDriver.xst. These statements are needed to allow your driver to use the DBI macros. They will\ninclude your private header file dbdimp.h in turn. Note that *DBISTATEINIT* requires the name\nof the argument to \"dbdinit()\" to be called \"dbistate()\".\n\nThe dbddrverror method\nYou need a function to record errors so DBI can access them properly. You can call it whatever\nyou like, but we'll call it \"dbddrverror()\" here.\n\nThe argument list depends on your database software; different systems provide different ways to\nget at error information.\n\nstatic void dbddrverror(SV *h, int rc, const char *what)\n{\n\nNote that *h* is a generic handle, may it be a driver handle, a database or a statement handle.\n\nDimpxxh(h);\n\nThis macro will declare and initialize a variable *impxxh* with a pointer to your private\nhandle pointer. You may cast this to to *impdrht*, *impdbht* or *impstht*.\n\nTo record the error correctly, equivalent to the \"seterr()\" method, use one of the\n\"DBIhSETERRCHAR(...)\" or \"DBIhSETERRSV(...)\" macros, which were added in DBI 1.41:\n\nDBIhSETERRSV(h, impxxh, err, errstr, state, method);\nDBIhSETERRCHAR(h, impxxh, errc, erri, errstr, state, method);\n\nFor \"DBIhSETERRSV\" the *err*, *errstr*, *state*, and *method* parameters are \"SV*\" (use\n&svundef instead of NULL).\n\nFor \"DBIhSETERRCHAR\" the *errc*, *errstr*, *state*, *method* parameters are \"char*\".\n\nThe *erri* parameter is an \"IV\" that's used instead of *errc* if *errc* is \"Null\".\n\nThe *method* parameter can be ignored.\n\nThe \"DBIhSETERRCHAR\" macro is usually the simplest to use when you just have an integer error\ncode and an error message string:\n\nDBIhSETERRCHAR(h, impxxh, Nullch, rc, what, Nullch, Nullch);\n\nAs you can see, any parameters that aren't relevant to you can be \"Null\".\n\nTo make drivers compatible with DBI < 1.41 you should be using dbivport.h as described in\n\"Driver.h\" above.\n\nThe (obsolete) macros such as \"DBIhEVENT2\" should be removed from drivers.\n\nThe names \"dbis\" and \"DBIS\", which were used in previous versions of this document, should be\nreplaced with the \"DBIcDBISTATE(impxxh)\" macro.\n\nThe name \"DBILOGFP\", which was also used in previous versions of this document, should be\nreplaced by \"DBIcLOGPIO(impxxh)\".\n\nYour code should not call the C \"<stdio.h>\" I/O functions; you should use \"PerlIOprintf()\" as\nshown:\n\nif (DBIcTRACELEVEL(impxxh) >= 2)\nPerlIOprintf(DBIcLOGPIO(impxxh), \"foobar %s: %s\\n\",\nfoo, neatsvpv(errstr,0));\n\nThat's the first time we see how tracing works within a DBI driver. Make use of this as often as\nyou can, but don't output anything at a trace level less than 3. Levels 1 and 2 are reserved for\nthe DBI.\n\nYou can define up to 8 private trace flags using the top 8 bits of \"DBIcTRACEFLAGS(imp)\", that\nis: 0xFF000000. See the \"parsetraceflag()\" method elsewhere in this document.\n\nThe dbddrdatasources method\nThis method is optional; the support for it was added in DBI v1.33.\n\nAs noted in the discussion of Driver.pm, if the data sources can be determined by pure Perl\ncode, do it that way. If, as in DBD::Informix, the information is obtained by a C function call,\nthen you need to define a function that matches the prototype:\n\nextern AV *dbddrdatasources(SV *drh, impdrht *impdrh, SV *attrs);\n\nAn outline implementation for DBD::Informix follows, assuming that the \"sqgetdbs()\" function\ncall shown will return up to 100 databases names, with the pointers to each name in the array\ndbsname and the name strings themselves being stores in dbsarea.\n\nAV *dbddrdatasources(SV *drh, impdrht *impdrh, SV *attr)\n{\nint ndbs;\nint i;\nchar *dbsname[100];\nchar  dbsarea[10000];\nAV *av = Nullav;\n\nif (sqgetdbs(&ndbs, dbsname, 100, dbsarea, sizeof(dbsarea)) == 0)\n{\nav = NewAV();\navextend(av, (I32)ndbs);\nsv2mortal((SV *)av);\nfor (i = 0; i < ndbs; i++)\navstore(av, i, newSVpvf(\"dbi:Informix:%s\", dbsname[i]));\n}\nreturn(av);\n}\n\nThe actual DBD::Informix implementation has a number of extra lines of code, logs function entry\nand exit, reports the error from \"sqgetdbs()\", and uses \"#define\"'d constants for the array\nsizes.\n\nThe dbddblogin6 method\nint dbddblogin6sv(SV* dbh, impdbht* impdbh, SV* dbname,\nSV* user, SV* auth, SV *attr);\n\nor\n\nint dbddblogin6(SV* dbh, impdbht* impdbh, char* dbname,\nchar* user, char* auth, SV *attr);\n\nThis function will really connect to the database. The argument *dbh* is the database handle.\n*impdbh* is the pointer to the handles private data, as is *impxxx* in \"dbddrverror()\"\nabove. The arguments *dbname*, *user*, *auth* and *attr* correspond to the arguments of the\ndriver handle's \"connect()\" method.\n\nYou will quite often use database specific attributes here, that are specified in the DSN. I\nrecommend you parse the DSN (using Perl) within the \"connect()\" method and pass the segments of\nthe DSN via the attributes parameter through \"login()\" to \"dbddblogin6()\".\n\nHere's how you fetch them; as an example we use *hostname* attribute, which can be up to 12\ncharacters long excluding null terminator:\n\nSV svp;\nSTRLEN len;\nchar* hostname;\n\nif ( (svp = DBDATTRIBGETSVP(attr, \"drvhostname\", 12)) && SvTRUE(*svp)) {\nhostname = SvPV(*svp, len);\nDBDATTRIBDELETE(attr, \"drvhostname\", 12); /* avoid later STORE */\n} else {\nhostname = \"localhost\";\n}\n\nIf you handle any driver specific attributes in the dbddblogin6 method you probably want to\ndelete them from \"attr\" (as above with DBDATTRIBDELETE). If you don't delete your handled\nattributes DBI will call \"STORE\" for each attribute after the connect/login and this is at best\nredundant for attributes you have already processed.\n\nNote: Until revision 11605 (post DBI 1.607), there was a problem with DBDATTRIBUTEDELETE so\nunless you require a DBI version after 1.607 you need to replace each DBDATTRIBUTEDELETE call\nwith:\n\nhvdelete((HV*)SvRV(attr), key, keylen, GDISCARD)\n\nNote that you can also obtain standard attributes such as *AutoCommit* and *ChopBlanks* from the\nattributes parameter, using \"DBDATTRIBGETIV\" for integer attributes.\n\nIf, for example, your database does not support transactions but *AutoCommit* is set off\n(requesting transaction support), then you can emulate a 'failure to connect'.\n\nNow you should really connect to the database. In general, if the connection fails, it is best\nto ensure that all allocated resources are released so that the handle does not need to be\ndestroyed separately. If you are successful (and possibly even if you fail but you have\nallocated some resources), you should use the following macros:\n\nDBIcIMPSETon(impdbh);\n\nThis indicates that the driver (implementor) has allocated resources in the *impdbh* structure\nand that the implementors private \"dbddbdestroy()\" function should be called when the handle\nis destroyed.\n\nDBIcACTIVEon(impdbh);\n\nThis indicates that the handle has an active connection to the server and that the\n\"dbddbdisconnect()\" function should be called before the handle is destroyed.\n\nNote that if you do need to fail, you should report errors via the *drh* or *impdrh* rather\nthan via *dbh* or *impdbh* because *impdbh* will be destroyed by the failure, so errors\nrecorded in that handle will not be visible to DBI, and hence not the user either.\n\nNote too, that the function is passed *dbh* and *impdbh*, and there is a macro\n\"Dimpdrhfromdbh\" which can recover the *impdrh* from the *impdbh*. However, there is no\nDBI macro to provide you with the *drh* given either the *impdbh* or the *dbh* or the *impdrh*\n(and there's no way to recover the *dbh* given just the *impdbh*).\n\nThis suggests that, despite the above notes about \"dbddrverror()\" taking an \"SV *\", it may be\nbetter to have two error routines, one taking *impdbh* and one taking *impdrh* instead. With\ncare, you can factor most of the formatting code out so that these are small routines calling a\ncommon error formatter. See the code in DBD::Informix 1.05.00 for more information.\n\nThe \"dbddblogin6()\" function should return *TRUE* for success, *FALSE* otherwise.\n\nDrivers implemented long ago may define the five-argument function \"dbddblogin()\" instead of\n\"dbddblogin6()\". The missing argument is the attributes. There are ways to work around the\nmissing attributes, but they are ungainly; it is much better to use the 6-argument form. Even\nlater drivers will use \"dbddblogin6sv()\" which provides the dbname, username and password as\nSVs.\n\nThe dbddbcommit and dbddbrollback methods\nint dbddbcommit(SV *dbh, impdbht *impdbh);\nint dbddbrollback(SV* dbh, impdbht* impdbh);\n\nThese are used for commit and rollback. They should return *TRUE* for success, *FALSE* for\nerror.\n\nThe arguments *dbh* and *impdbh* are the same as for \"dbddblogin6()\" above; I will omit\ndescribing them in what follows, as they appear always.\n\nThese functions should return *TRUE* for success, *FALSE* otherwise.\n\nThe dbddbdisconnect method\nThis is your private part of the \"disconnect()\" method. Any *dbh* with the *ACTIVE* flag on must\nbe disconnected. (Note that you have to set it in \"dbddbconnect()\" above.)\n\nint dbddbdisconnect(SV* dbh, impdbht* impdbh);\n\nThe database handle will return *TRUE* for success, *FALSE* otherwise. In any case it should do\na:\n\nDBIcACTIVEoff(impdbh);\n\nbefore returning so DBI knows that \"dbddbdisconnect()\" was executed.\n\nNote that there's nothing to stop a *dbh* being *disconnected* while it still have active\nchildren. If your database API reacts badly to trying to use an *sth* in this situation then\nyou'll need to add code like this to all *sth* methods:\n\nif (!DBIcACTIVE(DBIcPARENTCOM(impsth)))\nreturn 0;\n\nAlternatively, you can add code to your driver to keep explicit track of the statement handles\nthat exist for each database handle and arrange to destroy those handles before disconnecting\nfrom the database. There is code to do this in DBD::Informix. Similar comments apply to the\ndriver handle keeping track of all the database handles.\n\nNote that the code which destroys the subordinate handles should only release the associated\ndatabase resources and mark the handles inactive; it does not attempt to free the actual handle\nstructures.\n\nThis function should return *TRUE* for success, *FALSE* otherwise, but it is not clear what\nanything can do about a failure.\n\nThe dbddbdisconall method\nint dbddisconall (SV *drh, impdrht *impdrh);\n\nThis function may be called at shutdown time. It should make best-efforts to disconnect all\ndatabase handles - if possible. Some databases don't support that, in which case you can do\nnothing but return 'success'.\n\nThis function should return *TRUE* for success, *FALSE* otherwise, but it is not clear what\nanything can do about a failure.\n\nThe dbddbdestroy method\nThis is your private part of the database handle destructor. Any *dbh* with the *IMPSET* flag on\nmust be destroyed, so that you can safely free resources. (Note that you have to set it in\n\"dbddbconnect()\" above.)\n\nvoid dbddbdestroy(SV* dbh, impdbht* impdbh)\n{\nDBIcIMPSEToff(impdbh);\n}\n\nThe DBI Driver.xst code will have called \"dbddbdisconnect()\" for you, if the handle is still\n'active', before calling \"dbddbdestroy()\".\n\nBefore returning the function must switch *IMPSET* to off, so DBI knows that the destructor was\ncalled.\n\nA DBI handle doesn't keep references to its children. But children do keep references to their\nparents. So a database handle won't be \"DESTROY\"'d until all its children have been \"DESTROY\"'d.\n\nThe dbddbSTOREattrib method\nThis function handles\n\n$dbh->{$key} = $value;\n\nIts prototype is:\n\nint dbddbSTOREattrib(SV* dbh, impdbht* impdbh, SV* keysv,\nSV* valuesv);\n\nYou do not handle all attributes; on the contrary, you should not handle DBI attributes here:\nleave this to DBI. (There are two exceptions, *AutoCommit* and *ChopBlanks*, which you should\ncare about.)\n\nThe return value is *TRUE* if you have handled the attribute or *FALSE* otherwise. If you are\nhandling an attribute and something fails, you should call \"dbddrverror()\", so DBI can raise\nexceptions, if desired. If \"dbddrverror()\" returns, however, you have a problem: the user will\nnever know about the error, because he typically will not check \"$dbh->errstr()\".\n\nI cannot recommend a general way of going on, if \"dbddrverror()\" returns, but there are\nexamples where even the DBI specification expects that you \"croak()\". (See the *AutoCommit*\nmethod in DBI.)\n\nIf you have to store attributes, you should either use your private data structure *impxxx*,\nthe handle hash (via \"(HV*)SvRV(dbh)\"), or use the private *impdata*.\n\nThe first is best for internal C values like integers or pointers and where speed is important\nwithin the driver. The handle hash is best for values the user may want to get/set via\ndriver-specific attributes. The private *impdata* is an additional \"SV\" attached to the handle.\nYou could think of it as an unnamed handle attribute. It's not normally used.\n\nThe dbddbFETCHattrib method\nThis is the counterpart of \"dbddbSTOREattrib()\", needed for:\n\n$value = $dbh->{$key};\n\nIts prototype is:\n\nSV* dbddbFETCHattrib(SV* dbh, impdbht* impdbh, SV* keysv);\n\nUnlike all previous methods this returns an \"SV\" with the value. Note that you should normally\nexecute \"sv2mortal()\", if you return a nonconstant value. (Constant values are &svundef,\n&svno and &svyes.)\n\nNote, that DBI implements a caching algorithm for attribute values. If you think, that an\nattribute may be fetched, you store it in the *dbh* itself:\n\nif (cacheit) /* cache value for later DBI 'quick' fetch? */\nhvstore((HV*)SvRV(dbh), key, kl, cachesv, 0);\n\nThe dbdstprepare method\nThis is the private part of the \"prepare()\" method. Note that you must not really execute the\nstatement here. You may, however, preparse and validate the statement, or do similar things.\n\nint dbdstprepare(SV* sth, impstht* impsth, char* statement,\nSV* attribs);\n\nA typical, simple, possibility is to do nothing and rely on the perl \"prepare()\" code that set\nthe *Statement* attribute on the handle. This attribute can then be used by \"dbdstexecute()\".\n\nIf the driver supports placeholders then the *NUMOFPARAMS* attribute must be set correctly by\n\"dbdstprepare()\":\n\nDBIcNUMPARAMS(impsth) = ...\n\nIf you can, you should also setup attributes like *NUMOFFIELDS*, *NAME*, etc. here, but DBI\ndoesn't require that - they can be deferred until execute() is called. However, if you do,\ndocument it.\n\nIn any case you should set the *IMPSET* flag, as you did in \"dbddbconnect()\" above:\n\nDBIcIMPSETon(impsth);\n\nThe dbdstexecute method\nThis is where a statement will really be executed.\n\nint dbdstexecute(SV* sth, impstht* impsth);\n\n\"dbdstexecute\" should return -2 for any error, -1 if the number of rows affected is unknown\nelse it should be the number of affected (updated, inserted) rows.\n\nNote that you must be aware a statement may be executed repeatedly. Also, you should not expect\nthat \"finish()\" will be called between two executions, so you might need code, like the\nfollowing, near the start of the function:\n\nif (DBIcACTIVE(impsth))\ndbdstfinish(h, impsth);\n\nIf your driver supports the binding of parameters (it should!), but the database doesn't, you\nmust do it here. This can be done as follows:\n\nSV *svp;\nchar* statement = DBDATTRIBGETPV(h, \"Statement\", 9, svp, \"\");\nint numParam = DBIcNUMPARAMS(impsth);\nint i;\n\nfor (i = 0; i < numParam; i++)\n{\nchar* value = dbddbgetparam(sth, impsth, i);\n/* It is your drivers task to implement dbddbgetparam,    */\n/* it must be setup as a counterpart of dbdbindph.         */\n/* Look for '?' and replace it with 'value'.  Difficult      */\n/* task, note that you may have question marks inside        */\n/* quotes and comments the like ...  :-(                     */\n/* See DBD::mysql for an example. (Don't look too deep into  */\n/* the example, you will notice where I was lazy ...)        */\n}\n\nThe next thing is to really execute the statement.\n\nNote that you must set the attributes *NUMOFFIELDS*, *NAME*, etc when the statement is\nsuccessfully executed if the driver has not already done so: they may be used even before a\npotential \"fetchrow()\". In particular you have to tell DBI the number of fields that the\nstatement has, because it will be used by DBI internally. Thus the function will typically ends\nwith:\n\nif (isSelectStatement) {\nDBIcNUMFIELDS(impsth) = numFields;\nDBIcACTIVEon(impsth);\n}\n\nIt is important that the *ACTIVE* flag only be set for \"SELECT\" statements (or any other\nstatements that can return many values from the database using a cursor-like mechanism). See\n\"dbddbconnect()\" above for more explanations.\n\nThere plans for a preparse function to be provided by DBI, but this has not reached fruition\nyet. Meantime, if you want to know how ugly it can get, try looking at the \"dbdixpreparse()\"\nin DBD::Informix dbdimp.ec and the related functions in iustoken.c and sqltoken.c.\n\nThe dbdstfetch method\nThis function fetches a row of data. The row is stored in in an array, of \"SV\"'s that DBI\nprepares for you. This has two advantages: it is fast (you even reuse the \"SV\"'s, so they don't\nhave to be created after the first \"fetchrow()\"), and it guarantees that DBI handles\n\"bindcols()\" for you.\n\nWhat you do is the following:\n\nAV* av;\nint numFields = DBIcNUMFIELDS(impsth); /* Correct, if NUMFIELDS\nis constant for this statement. There are drivers where this is\nnot the case! */\nint chopBlanks = DBIcis(impsth, DBIcfChopBlanks);\nint i;\n\nif (!fetchnewrowofdata(...)) {\n... /* check for error or end-of-data */\nDBIcACTIVEoff(impsth); /* turn off Active flag automatically */\nreturn Nullav;\n}\n/* get the fbav (field buffer array value) for this row       */\n/* it is very important to only call this after you know      */\n/* that you have a row of data to return.                     */\nav = DBIcDBISTATE(impsth)->getfbav(impsth);\nfor (i = 0; i < numFields; i++) {\nSV* sv = fetchafield(..., i);\nif (chopBlanks && SvOK(sv) && typeisblankpadded(fieldtype[i])) {\n/*  Remove white space from end (only) of sv  */\n}\nsvsetsv(AvARRAY(av)[i], sv); /* Note: (re)use! */\n}\nreturn av;\n\nThere's no need to use a \"fetchafield()\" function returning an \"SV*\". It's more common to use\nyour database API functions to fetch the data as character strings and use code like this:\n\nsvsetpvn(AvARRAY(av)[i], charptr, charcount);\n\n\"NULL\" values must be returned as \"undef\". You can use code like this:\n\nSvOKoff(AvARRAY(av)[i]);\n\nThe function returns the \"AV\" prepared by DBI for success or \"Nullav\" otherwise.\n\n*FIX ME* Discuss what happens when there's no more data to fetch.\nAre errors permitted if another fetch occurs after the first fetch\nthat reports no more data. (Permitted, not required.)\n\nIf an error occurs which leaves the *$sth* in a state where remaining rows can't be fetched then\n*Active* should be turned off before the method returns.\n\nThe dbdstfinish3 method\nThe \"$sth->finish()\" method can be called if the user wishes to indicate that no more rows will\nbe fetched even if the database has more rows to offer, and the DBI code can call the function\nwhen handles are being destroyed. See the DBI specification for more background details.\n\nIn both circumstances, the DBI code ends up calling the \"dbdstfinish3()\" method (if you\nprovide a mapping for \"dbdstfinish3()\" in dbdimp.h), or \"dbdstfinish()\" otherwise. The\ndifference is that \"dbdstfinish3()\" takes a third argument which is an \"int\" with the value 1\nif it is being called from a \"destroy()\" method and 0 otherwise.\n\nNote that DBI v1.32 and earlier test on \"dbddbfinish3()\" to call \"dbdstfinish3()\"; if you\nprovide \"dbdstfinish3()\", either define \"dbddbfinish3()\" too, or insist on DBI v1.33 or\nlater.\n\nAll it *needs* to do is turn off the *Active* flag for the *sth*. It will only be called by\nDriver.xst code, if the driver has set *ACTIVE* to on for the *sth*.\n\nOutline example:\n\nint dbdstfinish3(SV* sth, impstht* impsth, int fromdestroy) {\nif (DBIcACTIVE(impsth))\n{\n/* close cursor or equivalent action */\nDBIcACTIVEoff(impsth);\n}\nreturn 1;\n}\n\nThe fromdestroy parameter is true if \"dbdstfinish3()\" is being called from \"DESTROY()\" - and\nso the statement is about to be destroyed. For many drivers there is no point in doing anything\nmore than turning off the *Active* flag in this case.\n\nThe function returns *TRUE* for success, *FALSE* otherwise, but there isn't a lot anyone can do\nto recover if there is an error.\n\nThe dbdstdestroy method\nThis function is the private part of the statement handle destructor.\n\nvoid dbdstdestroy(SV* sth, impstht* impsth) {\n... /* any clean-up that's needed */\nDBIcIMPSEToff(impsth); /* let DBI know we've done it   */\n}\n\nThe DBI Driver.xst code will call \"dbdstfinish()\" for you, if the *sth* has the *ACTIVE* flag\nset, before calling \"dbdstdestroy()\".\n\nThe dbdstSTOREattrib and dbdstFETCHattrib methods\nThese functions correspond to \"dbddbSTORE()\" and \"dbddbFETCH()\" attrib above, except that\nthey are for statement handles. See above.\n\nint dbdstSTOREattrib(SV* sth, impstht* impsth, SV* keysv,\nSV* valuesv);\nSV* dbdstFETCHattrib(SV* sth, impstht* impsth, SV* keysv);\n\nThe dbdbindph method\nThis function is internally used by the \"bindparam()\" method, the \"bindparaminout()\" method\nand by the DBI Driver.xst code if \"execute()\" is called with any bind parameters.\n\nint dbdbindph (SV *sth, impstht *impsth, SV *param,\nSV *value, IV sqltype, SV *attribs,\nint isinout, IV maxlen);\n\nThe *param* argument holds an \"IV\" with the parameter number (1, 2, ...). The *value* argument\nis the parameter value and *sqltype* is its type.\n\nIf your driver does not support \"bindparaminout()\" then you should ignore *maxlen* and croak\nif *isinout* is *TRUE*.\n\nIf your driver *does* support \"bindparaminout()\" then you should note that *value* is the \"SV\"\n*after* dereferencing the reference passed to \"bindparaminout()\".\n\nIn drivers of simple databases the function will, for example, store the value in a parameter\narray and use it later in \"dbdstexecute()\". See the DBD::mysql driver for an example.\n\nImplementing bindparaminout support\nTo provide support for parameters bound by reference rather than by value, the driver must do a\nnumber of things. First, and most importantly, it must note the references and stash them in its\nown driver structure. Secondly, when a value is bound to a column, the driver must discard any\nprevious reference bound to the column. On each execute, the driver must evaluate the references\nand internally bind the values resulting from the references. This is only applicable if the\nuser writes:\n\n$sth->execute;\n\nIf the user writes:\n\n$sth->execute(@values);\n\nthen DBI automatically calls the binding code for each element of *@values*. These calls are\nindistinguishable from explicit user calls to \"bindparam()\".\n\nC/XS version of Makefile.PL\nThe Makefile.PL file for a C/XS driver is similar to the code needed for a pure Perl driver, but\nthere are a number of extra bits of information needed by the build system.\n\nFor example, the attributes list passed to \"WriteMakefile()\" needs to specify the object files\nthat need to be compiled and built into the shared object (DLL). This is often, but not\nnecessarily, just dbdimp.o (unless that should be dbdimp.obj because you're building on MS\nWindows).\n\nNote that you can reliably determine the extension of the object files from the\n*$Config{objext}* values, and there are many other useful pieces of configuration information\nlurking in that hash. You get access to it with:\n\nuse Config;\n"
                },
                {
                    "name": "Methods which do not need to be written",
                    "content": "The DBI code implements the majority of the methods which are accessed using the notation\n\"DBI->function()\", the only exceptions being \"DBI->connect()\" and \"DBI->datasources()\" which\nrequire support from the driver.\n\nThe DBI code implements the following documented driver, database and statement functions which\ndo not need to be written by the DBD driver writer.\n\n$dbh->do()\nThe default implementation of this function prepares, executes and destroys the statement.\nThis can be replaced if there is a better way to implement this, such as \"EXECUTE IMMEDIATE\"\nwhich can sometimes be used if there are no parameters.\n\n$h->errstr()\n$h->err()\n$h->state()\n$h->trace()\nThe DBD driver does not need to worry about these routines at all.\n\n$h->{ChopBlanks}\nThis attribute needs to be honored during \"fetch()\" operations, but does not need to be\nhandled by the attribute handling code.\n\n$h->{RaiseError}\nThe DBD driver does not need to worry about this attribute at all.\n\n$h->{PrintError}\nThe DBD driver does not need to worry about this attribute at all.\n\n$sth->bindcol()\nAssuming the driver uses the \"DBIcDBISTATE(impxxh)->getfbav()\" function (C drivers, see\nbelow), or the \"$sth->setfbav($data)\" method (Perl drivers) the driver does not need to do\nanything about this routine.\n\n$sth->bindcolumns()\nRegardless of whether the driver uses \"DBIcDBISTATE(impxxh)->getfbav()\", the driver does\nnot need to do anything about this routine as it simply iteratively calls\n\"$sth->bindcol()\".\n\nThe DBI code implements a default implementation of the following functions which do not need to\nbe written by the DBD driver writer unless the default implementation is incorrect for the\nDriver.\n\n$dbh->quote()\nThis should only be written if the database does not accept the ANSI SQL standard for\nquoting strings, with the string enclosed in single quotes and any embedded single quotes\nreplaced by two consecutive single quotes.\n\nFor the two argument form of quote, you need to implement the \"typeinfo()\" method to\nprovide the information that quote needs.\n\n$dbh->ping()\nThis should be implemented as a simple efficient way to determine whether the connection to\nthe database is still alive. Typically code like this:\n\nsub ping {\nmy $dbh = shift;\n$sth = $dbh->preparecached(q{\nselect * from ATABLENAME where 1=0\n}) or return 0;\n$sth->execute or return 0;\n$sth->finish;\nreturn 1;\n}\n\nwhere *ATABLENAME* is the name of a table that always exists (such as a database system\ncatalogue).\n\n$drh->defaultuser\nThe default implementation of defaultuser will get the database username and password\nfields from $ENV{DBIUSER} and $ENV{DBIPASS}. You can override this method. It is called as\nfollows:\n\n($user, $pass) = $drh->defaultuser($user, $pass, $attr)\n"
                }
            ]
        },
        "METADATA METHODS": {
            "content": "The exposition above ignores the DBI MetaData methods. The metadata methods are all associated\nwith a database handle.\n",
            "subsections": [
                {
                    "name": "Using DBI::DBD::Metadata",
                    "content": "The DBI::DBD::Metadata module is a good semi-automatic way for the developer of a DBD module to\nwrite the \"getinfo()\" and \"typeinfo()\" functions quickly and accurately.\n\nGenerating the getinfo method\nPrior to DBI v1.33, this existed as the method \"writegetinfopm()\" in the DBI::DBD module. From\nDBI v1.33, it exists as the method \"writegetinfopm()\" in the DBI::DBD::Metadata module. This\ndiscussion assumes you have DBI v1.33 or later.\n\nYou examine the documentation for \"writegetinfopm()\" using:\n\nperldoc DBI::DBD::Metadata\n\nTo use it, you need a Perl DBI driver for your database which implements the \"getinfo()\"\nmethod. In practice, this means you need to install DBD::ODBC, an ODBC driver manager, and an\nODBC driver for your database.\n\nWith the pre-requisites in place, you might type:\n\nperl -MDBI::DBD::Metadata -we \\\n\"writegetinfopm (qw{ dbi:ODBC:foodb username password Driver })\"\n\nThe procedure writes to standard output the code that should be added to your Driver.pm file and\nthe code that should be written to lib/DBD/Driver/GetInfo.pm.\n\nYou should review the output to ensure that it is sensible.\n\nGenerating the typeinfo method\nGiven the idea of the \"writegetinfopm()\" method, it was not hard to devise a parallel method,\n\"writetypeinfopm()\", which does the analogous job for the DBI \"typeinfoall()\" metadata\nmethod. The \"writetypeinfopm()\" method was added to DBI v1.33.\n\nYou examine the documentation for \"writetypeinfopm()\" using:\n\nperldoc DBI::DBD::Metadata\n\nThe setup is exactly analogous to the mechanism described in \"Generating the getinfo method\".\n\nWith the pre-requisites in place, you might type:\n\nperl -MDBI::DBD::Metadata -we \\\n\"writetypeinfopm (qw{ dbi:ODBC:foodb username password Driver })\"\n\nThe procedure writes to standard output the code that should be added to your Driver.pm file and\nthe code that should be written to lib/DBD/Driver/TypeInfo.pm.\n\nYou should review the output to ensure that it is sensible.\n"
                },
                {
                    "name": "Writing DBD::Driver::db::getinfo",
                    "content": "If you use the DBI::DBD::Metadata module, then the code you need is generated for you.\n\nIf you decide not to use the DBI::DBD::Metadata module, you should probably borrow the code from\na driver that has done so (eg DBD::Informix from version 1.05 onwards) and crib the code from\nthere, or look at the code that generates that module and follow that. The method in Driver.pm\nwill be very simple; the method in lib/DBD/Driver/GetInfo.pm is not very much more complex\nunless your DBMS itself is much more complex.\n\nNote that some of the DBI utility methods rely on information from the \"getinfo()\" method to\nperform their operations correctly. See, for example, the \"quoteidentifier()\" and quote\nmethods, discussed below.\n"
                },
                {
                    "name": "Writing DBD::Driver::db::typeinfoall",
                    "content": "If you use the \"DBI::DBD::Metadata\" module, then the code you need is generated for you.\n\nIf you decide not to use the \"DBI::DBD::Metadata\" module, you should probably borrow the code\nfrom a driver that has done so (eg \"DBD::Informix\" from version 1.05 onwards) and crib the code\nfrom there, or look at the code that generates that module and follow that. The method in\nDriver.pm will be very simple; the method in lib/DBD/Driver/TypeInfo.pm is not very much more\ncomplex unless your DBMS itself is much more complex.\n"
                },
                {
                    "name": "Writing DBD::Driver::db::typeinfo",
                    "content": "The guidelines on writing this method are still not really clear. No sample implementation is\navailable.\n"
                },
                {
                    "name": "Writing DBD::Driver::db::tableinfo",
                    "content": "*FIX ME* The guidelines on writing this method have not been written yet.\nNo sample implementation is available.\n"
                },
                {
                    "name": "Writing DBD::Driver::db::columninfo",
                    "content": "*FIX ME* The guidelines on writing this method have not been written yet.\nNo sample implementation is available.\n"
                },
                {
                    "name": "Writing DBD::Driver::db::primarykeyinfo",
                    "content": "*FIX ME* The guidelines on writing this method have not been written yet.\nNo sample implementation is available.\n"
                },
                {
                    "name": "Writing DBD::Driver::db::primarykey",
                    "content": "*FIX ME* The guidelines on writing this method have not been written yet.\nNo sample implementation is available.\n"
                },
                {
                    "name": "Writing DBD::Driver::db::foreignkeyinfo",
                    "content": "*FIX ME* The guidelines on writing this method have not been written yet.\nNo sample implementation is available.\n"
                },
                {
                    "name": "Writing DBD::Driver::db::tables",
                    "content": "This method generates an array of names in a format suitable for being embedded in SQL\nstatements in places where a table name is expected.\n\nIf your database hews close enough to the SQL standard or if you have implemented an appropriate\n\"tableinfo()\" function and and the appropriate \"quoteidentifier()\" function, then the DBI\ndefault version of this method will work for your driver too.\n\nOtherwise, you have to write a function yourself, such as:\n\nsub tables\n{\nmy($dbh, $cat, $sch, $tab, $typ) = @;\nmy(@res);\nmy($sth) = $dbh->tableinfo($cat, $sch, $tab, $typ);\nmy(@arr);\nwhile (@arr = $sth->fetchrowarray)\n{\npush @res, $dbh->quoteidentifier($arr[0], $arr[1], $arr[2]);\n}\nreturn @res;\n}\n\nSee also the default implementation in DBI.pm.\n"
                },
                {
                    "name": "Writing DBD::Driver::db::quote",
                    "content": "This method takes a value and converts it into a string suitable for embedding in an SQL\nstatement as a string literal.\n\nIf your DBMS accepts the SQL standard notation for strings (single quotes around the string as a\nwhole with any embedded single quotes doubled up), then you do not need to write this method as\nDBI provides a default method that does it for you.\n\nIf your DBMS uses an alternative notation or escape mechanism, then you need to provide an\nequivalent function. For example, suppose your DBMS used C notation with double quotes around\nthe string and backslashes escaping both double quotes and backslashes themselves. Then you\nmight write the function as:\n\nsub quote\n{\nmy($dbh, $str) = @;\n$str =~ s/[\"\\\\]/\\\\$&/gmo;\nreturn qq{\"$str\"};\n}\n\nHandling newlines and other control characters is left as an exercise for the reader.\n\nThis sample method ignores the *$datatype* indicator which is the optional second argument to\nthe method.\n"
                },
                {
                    "name": "Writing DBD::Driver::db::quoteidentifier",
                    "content": "This method is called to ensure that the name of the given table (or other database object) can\nbe embedded into an SQL statement without danger of misinterpretation. The result string should\nbe usable in the text of an SQL statement as the identifier for a table.\n\nIf your DBMS accepts the SQL standard notation for quoted identifiers (which uses double quotes\naround the identifier as a whole, with any embedded double quotes doubled up) and accepts\n*\"schema\".\"identifier\"* (and *\"catalog\".\"schema\".\"identifier\"* when a catalog is specified),\nthen you do not need to write this method as DBI provides a default method that does it for you.\n\nIn fact, even if your DBMS does not handle exactly that notation but you have implemented the\n\"getinfo()\" method and it gives the correct responses, then it will work for you. If your\ndatabase is fussier, then you need to implement your own version of the function.\n\nFor example, DBD::Informix has to deal with an environment variable *DELIMIDENT*. If it is not\nset, then the DBMS treats names enclosed in double quotes as strings rather than names, which is\nusually a syntax error. Additionally, the catalog portion of the name is separated from the\nschema and table by a different delimiter (colon instead of dot), and the catalog portion is\nnever enclosed in quotes. (Fortunately, valid strings for the catalog will never contain weird\ncharacters that might need to be escaped, unless you count dots, dashes, slashes and at-signs as\nweird.) Finally, an Informix database can contain objects that cannot be accessed because they\nwere created by a user with the *DELIMIDENT* environment variable set, but the current user does\nnot have it set. By design choice, the \"quoteidentifier()\" method encloses those identifiers in\ndouble quotes anyway, which generally triggers a syntax error, and the metadata methods which\ngenerate lists of tables etc omit those identifiers from the result sets.\n\nsub quoteidentifier\n{\nmy($dbh, $cat, $sch, $obj) = @;\nmy($rv) = \"\";\nmy($qq) = (defined $ENV{DELIMIDENT}) ? '\"' : '';\n$rv .= qq{$cat:} if (defined $cat);\nif (defined $sch)\n{\nif ($sch !~ m/^\\w+$/o)\n{\n$qq = '\"';\n$sch =~ s/$qq/$qq$qq/gm;\n}\n$rv .= qq{$qq$sch$qq.};\n}\nif (defined $obj)\n{\nif ($obj !~ m/^\\w+$/o)\n{\n$qq = '\"';\n$obj =~ s/$qq/$qq$qq/gm;\n}\n$rv .= qq{$qq$obj$qq};\n}\nreturn $rv;\n}\n\nHandling newlines and other control characters is left as an exercise for the reader.\n\nNote that there is an optional fourth parameter to this function which is a reference to a hash\nof attributes; this sample implementation ignores that.\n\nThis sample implementation also ignores the single-argument variant of the method.\n"
                }
            ]
        },
        "TRACING": {
            "content": "Tracing in DBI is controlled with a combination of a trace level and a set of flags which\ntogether are known as the trace settings. The trace settings are stored in a single integer and\ndivided into levels and flags by a set of masks (\"DBIcTRACELEVELMASK\" and\n\"DBIcTRACEFLAGSMASK\").\n\nEach handle has it's own trace settings and so does the DBI. When you call a method the DBI\nmerges the handles settings into its own for the duration of the call: the trace flags of the\nhandle are OR'd into the trace flags of the DBI, and if the handle has a higher trace level then\nthe DBI trace level is raised to match it. The previous DBI trace settings are restored when the\ncalled method returns.\n",
            "subsections": [
                {
                    "name": "Trace Level",
                    "content": "The trace level is the first 4 bits of the trace settings (masked by \"DBIcTRACEFLAGSMASK\")\nand represents trace levels of 1 to 15. Do not output anything at trace levels less than 3 as\nthey are reserved for DBI.\n\nFor advice on what to output at each level see \"Trace Levels\" in DBI.\n\nTo test for a trace level you can use the \"DBIcTRACELEVEL\" macro like this:\n\nif (DBIcTRACELEVEL(impxxh) >= 2) {\nPerlIOprintf(DBIcLOGPIO(impxxh), \"foobar\");\n}\n\nAlso note the use of PerlIOprintf which you should always use for tracing and never the C\n\"stdio.h\" I/O functions.\n"
                },
                {
                    "name": "Trace Flags",
                    "content": "Trace flags are used to enable tracing of specific activities within the DBI and drivers. The\nDBI defines some trace flags and drivers can define others. DBI trace flag names begin with a\ncapital letter and driver specific names begin with a lowercase letter. For a list of DBI\ndefined trace flags see \"Trace Flags\" in DBI.\n\nIf you want to use private trace flags you'll probably want to be able to set them by name.\nDrivers are expected to override the parsetraceflag (note the singular) and check if\n$traceflagname is a driver specific trace flags and, if not, then call the DBIs default"
                },
                {
                    "name": "parse_trace_flag",
                    "content": "sub parsetraceflag {\nmy ($h, $name) = @;\nreturn 0x01000000 if $name eq 'foo';\nreturn 0x02000000 if $name eq 'bar';\nreturn 0x04000000 if $name eq 'baz';\nreturn 0x08000000 if $name eq 'boo';\nreturn 0x10000000 if $name eq 'bop';\nreturn $h->SUPER::parsetraceflag($name);\n}\n\nAll private flag names must be lowercase, and all private flags must be in the top 8 of the 32\nbits of \"DBIcTRACEFLAGS(imp)\" i.e., 0xFF000000.\n\nIf you've defined a parsetraceflag() method in ::db you'll also want it in ::st, so just alias\nit in:\n\n*parsetraceflag = \\&DBD::foo:db::parsetraceflag;\n\nYou may want to act on the current 'SQL' trace flag that DBI defines to output SQL\nprepared/executed as DBI currently does not do SQL tracing.\n"
                },
                {
                    "name": "Trace Macros",
                    "content": "Access to the trace level and trace flags is via a set of macros.\n\nDBIcTRACESETTINGS(imp) returns the trace settings\nDBIcTRACELEVEL(imp) returns the trace level\nDBIcTRACEFLAGS(imp) returns the trace flags\nDBIcTRACE(imp, flags, flaglevel, level)\n\ne.g.,\n\nDBIcTRACE(imp, 0, 0, 4)\nif level >= 4\n\nDBIcTRACE(imp, DBDtfFOO, 2, 4)\nif tracing DBDtfFOO & level>=2 or level>=4\n\nDBIcTRACE(imp, DBDtfFOO, 2, 0)\nas above but never trace just due to level\n\nWRITING AN EMULATION LAYER FOR AN OLD PERL INTERFACE\nStudy Oraperl.pm (supplied with DBD::Oracle) and Ingperl.pm (supplied with DBD::Ingres) and the\ncorresponding *dbdimp.c* files for ideas.\n\nNote that the emulation code sets \"$dbh->{CompatMode} = 1;\" for each connection so that the\ninternals of the driver can implement behaviour compatible with the old interface when dealing\nwith those handles.\n"
                },
                {
                    "name": "Setting emulation perl variables",
                    "content": "For example, ingperl has a *$sqlrowcount* variable. Rather than try to manually update this in\nIngperl.pm it can be done faster in C code. In \"dbdinit()\":\n\nsqlrowcount = perlgetsv(\"Ingperl::sqlrowcount\", GVADDMULTI);\n\nIn the relevant places do:\n\nif (DBIcCOMPAT(impsth))     /* only do this for compatibility mode handles */\nsvsetiv(sqlrowcount, therowcount);\n"
                }
            ]
        },
        "OTHER MISCELLANEOUS INFORMATION": {
            "content": "",
            "subsections": [
                {
                    "name": "The impxyzt types",
                    "content": "Any handle has a corresponding C structure filled with private data. Some of this data is\nreserved for use by DBI (except for using the DBIc macros below), some is for you. See the\ndescription of the dbdimp.h file above for examples. Most functions in dbdimp.c are passed both\nthe handle \"xyz\" and a pointer to \"impxyz\". In rare cases, however, you may use the following\nmacros:\n\nDimpdbh(dbh)\nGiven a function argument *dbh*, declare a variable *impdbh* and initialize it with a\npointer to the handles private data. Note: This must be a part of the function header,\nbecause it declares a variable.\n\nDimpsth(sth)\nLikewise for statement handles.\n\nDimpxxx(h)\nGiven any handle, declare a variable *impxxx* and initialize it with a pointer to the\nhandles private data. It is safe, for example, to cast *impxxx* to \"impdbht*\", if\n\"DBIcTYPE(impxxx) == DBItDB\". (You can also call \"svderivedfrom(h, \"DBI::db\")\", but\nthat's much slower.)\n\nDimpdbhfromsth\nGiven a *impsth*, declare a variable *impdbh* and initialize it with a pointer to the\nparent database handle's implementors structure.\n"
                },
                {
                    "name": "Using DBIcIMPSETon",
                    "content": "The driver code which initializes a handle should use \"DBIcIMPSETon()\" as soon as its state is\nsuch that the cleanup code must be called. When this happens is determined by your driver code.\n\nFailure to call this can lead to corruption of data structures.\n\nFor example, DBD::Informix maintains a linked list of database handles in the driver, and within\neach handle, a linked list of statements. Once a statement is added to the linked list, it is\ncrucial that it is cleaned up (removed from the list). When *DBIcIMPSETon()* was being called\ntoo late, it was able to cause all sorts of problems.\n\nUsing DBIcis(), DBIchas(), DBIcon() and DBIcoff()\nOnce upon a long time ago, the only way of handling the internal DBI boolean flags/attributes\nwas through macros such as:\n\nDBIcWARN       DBIcWARNon        DBIcWARNoff\nDBIcCOMPAT     DBIcCOMPATon      DBIcCOMPAToff\n\nEach of these took an *impxxh* pointer as an argument.\n\nSince then, new attributes have been added such as *ChopBlanks*, *RaiseError* and *PrintError*,\nand these do not have the full set of macros. The approved method for handling these is now the\nfour macros:\n\nDBIcis(imp, flag)\nDBIchas(imp, flag)       an alias for DBIcis\nDBIcon(imp, flag)\nDBIcoff(imp, flag)\nDBIcset(imp, flag, on)   set if on is true, else clear\n\nConsequently, the \"DBIcXXXXX\" family of macros is now mostly deprecated and new drivers should\navoid using them, even though the older drivers will probably continue to do so for quite a\nwhile yet. However...\n\nThere is an *important exception* to that. The *ACTIVE* and *IMPSET* flags should be set via the\n\"DBIcACTIVEon()\" and \"DBIcIMPSETon()\" macros, and unset via the \"DBIcACTIVEoff()\" and\n\"DBIcIMPSEToff()\" macros.\n\nUsing the getfbav() method\nTHIS IS CRITICAL for C/XS drivers.\n\nThe \"$sth->bindcol()\" and \"$sth->bindcolumns()\" documented in the DBI specification do not\nhave to be implemented by the driver writer because DBI takes care of the details for you.\n\nHowever, the key to ensuring that bound columns work is to call the function\n\"DBIcDBISTATE(impxxh)->getfbav()\" in the code which fetches a row of data.\n\nThis returns an \"AV\", and each element of the \"AV\" contains the \"SV\" which should be set to\ncontain the returned data.\n\nThe pure Perl equivalent is the \"$sth->setfbav($data)\" method, as described in the part on\npure Perl drivers.\n"
                },
                {
                    "name": "Casting strings to Perl types based on a SQL type",
                    "content": "DBI from 1.611 (and DBIXSREVISION 13606) defines the sqltypecastsvpv method which may be\nused to cast a string representation of a value to a more specific Perl type based on a SQL\ntype. You should consider using this method when processing bound column data as it provides\nsome support for the TYPE bindcol attribute which is rarely used in drivers.\n\nint sqltypecastsvpv(pTHX SV *sv, int sqltype, U32 flags, void *v)\n\n\"sv\" is what you would like cast, \"sqltype\" is one of the DBI defined SQL types (e.g.,\n\"SQLINTEGER\") and \"flags\" is a bitmask as follows:\n\nDBIstcfSTRICT\nIf set this indicates you want an error state returned if the cast cannot be performed.\n\nDBIstcfDISCARDSTRING\nIf set and the pv portion of the \"sv\" is cast then this will cause sv's pv to be freed up.\n\nsqltypecastsvpv returns the following states:\n\n-2 sqltype is not handled - sv not changed\n-1 sv is undef, sv not changed\n0 sv could not be cast cleanly and DBIstcfSTRICT was specified\n1 sv could not be case cleanly and DBIstcfSTRICT was not specified\n2 sv was cast ok\n\nThe current implementation of sqltypecastsvpv supports \"SQLINTEGER\", \"SQLDOUBLE\" and\n\"SQLNUMERIC\". \"SQLINTEGER\" uses sv2iv and hence may set IV, UV or NV depending on the number.\n\"SQLDOUBLE\" uses sv2nv so may set NV and \"SQLNUMERIC\" will set IV or UV or NV.\n\nDBIstcfSTRICT should be implemented as the StrictlyTyped attribute and DBIstcfDISCARDSTRING\nimplemented as the DiscardString attribute to the bindcol method and both default to off.\n\nSee DBD::Oracle for an example of how this is used.\n"
                }
            ]
        },
        "SUBCLASSING DBI DRIVERS": {
            "content": "This is definitely an open subject. It can be done, as demonstrated by the DBD::File driver, but\nit is not as simple as one might think.\n\n(Note that this topic is different from subclassing the DBI. For an example of that, see the\nt/subclass.t file supplied with the DBI.)\n\nThe main problem is that the *dbh*'s and *sth*'s that your \"connect()\" and \"prepare()\" methods\nreturn are not instances of your DBD::Driver::db or DBD::Driver::st packages, they are not even\nderived from it. Instead they are instances of the DBI::db or DBI::st classes or a derived\nsubclass. Thus, if you write a method \"mymethod()\" and do a\n\n$dbh->mymethod()\n\nthen the autoloader will search for that method in the package DBI::db. Of course you can\ninstead to a\n\n$dbh->func('mymethod')\n\nand that will indeed work, even if \"mymethod()\" is inherited, but not without additional work.\nSetting *@ISA* is not sufficient.\n",
            "subsections": [
                {
                    "name": "Overwriting methods",
                    "content": "The first problem is, that the \"connect()\" method has no idea of subclasses. For example, you\ncannot implement base class and subclass in the same file: The \"installdriver()\" method wants\nto do a\n\nrequire DBD::Driver;\n\nIn particular, your subclass has to be a separate driver, from the view of DBI, and you cannot\nshare driver handles.\n\nOf course that's not much of a problem. You should even be able to inherit the base classes\n\"connect()\" method. But you cannot simply overwrite the method, unless you do something like\nthis, quoted from DBD::CSV:\n\nsub connect ($$;$$$) {\nmy ($drh, $dbname, $user, $auth, $attr) = @;\n\nmy $this = $drh->DBD::File::dr::connect($dbname, $user, $auth, $attr);\nif (!exists($this->{csvtables})) {\n$this->{csvtables} = {};\n}\n\n$this;\n}\n\nNote that we cannot do a\n\n$drh->SUPER::connect($dbname, $user, $auth, $attr);\n\nas we would usually do in a an OO environment, because *$drh* is an instance of DBI::dr. And\nnote, that the \"connect()\" method of DBD::File is able to handle subclass attributes. See the\ndescription of Pure Perl drivers above.\n\nIt is essential that you always call superclass method in the above manner. However, that should\ndo.\n"
                },
                {
                    "name": "Attribute handling",
                    "content": "Fortunately the DBI specifications allow a simple, but still performant way of handling\nattributes. The idea is based on the convention that any driver uses a prefix *driver* for its\nprivate methods. Thus it's always clear whether to pass attributes to the super class or not.\nFor example, consider this \"STORE()\" method from the DBD::CSV class:\n\nsub STORE {\nmy ($dbh, $attr, $val) = @;\nif ($attr !~ /^driver/) {\nreturn $dbh->DBD::File::db::STORE($attr, $val);\n}\nif ($attr eq 'driverfoo') {\n...\n}\n"
                }
            ]
        },
        "AUTHORS": {
            "content": "Jonathan Leffler <jleffler@us.ibm.com> (previously <jleffler@informix.com>), Jochen Wiedmann\n<joe@ispsoft.de>, Steffen Goeldner <sgoeldner@cpan.org>, and Tim Bunce <dbi-users@perl.org>.\n",
            "subsections": []
        }
    },
    "summary": "DBI::DBD - Perl DBI Database Driver Writer's Guide",
    "flags": [],
    "examples": [],
    "see_also": []
}