{
    "content": [
        {
            "type": "text",
            "text": "# DBI::DBD (info)\n\n## NAME\n\nDBI::DBD - Perl DBI Database Driver Writer's Guide\n\n## SYNOPSIS\n\nperldoc DBI::DBD\nVersion and volatility\nThis document is still a minimal draft which is in need of further\nwork.\nPlease read the DBI documentation first and fully.  Then look at the\nimplementation of some high-profile and regularly maintained drivers\nlike DBD::Oracle, DBD::ODBC, DBD::Pg etc. (Those are no no particular\norder.)\nThen reread the DBI specification and the code of those drivers again\nas you're reading this. It'll help.  Where this document and the driver\ncode differ it's likely that the driver code is more correct,\nespecially if multiple drivers do the same thing.\nThis document is a patchwork of contributions from various authors.\nMore contributions (preferably as patches) are very welcome.\n\n## DESCRIPTION\n\nThis document is primarily intended to help people writing new database\ndrivers for the Perl Database Interface (Perl DBI).  It may also help\nothers interested in discovering why the internals of a DBD driver are\nwritten the way they are.\n\n## Sections\n\n- **NAME**\n- **SYNOPSIS**\n- **DESCRIPTION**\n- **CREATING A NEW DRIVER**\n- **CREATING A PURE PERL DRIVER**\n- **CREATING A C/XS DRIVER**\n- **METADATA METHODS**\n- **TRACING**\n- **OTHER MISCELLANEOUS INFORMATION**\n- **SUBCLASSING DBI DRIVERS**\n- **AUTHORS**\n\nUse structuredContent.sections for detailed options, examples, and full documentation.\n"
        }
    ],
    "structuredContent": {
        "command": "DBI::DBD",
        "section": "",
        "mode": "info",
        "summary": "DBI::DBD - Perl DBI Database Driver Writer's Guide",
        "synopsis": "perldoc DBI::DBD\nVersion and volatility\nThis document is still a minimal draft which is in need of further\nwork.\nPlease read the DBI documentation first and fully.  Then look at the\nimplementation of some high-profile and regularly maintained drivers\nlike DBD::Oracle, DBD::ODBC, DBD::Pg etc. (Those are no no particular\norder.)\nThen reread the DBI specification and the code of those drivers again\nas you're reading this. It'll help.  Where this document and the driver\ncode differ it's likely that the driver code is more correct,\nespecially if multiple drivers do the same thing.\nThis document is a patchwork of contributions from various authors.\nMore contributions (preferably as patches) are very welcome.",
        "tldr_summary": null,
        "tldr_examples": [],
        "tldr_source": null,
        "flags": [],
        "examples": [],
        "see_also": [],
        "section_outline": [
            {
                "name": "NAME",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "SYNOPSIS",
                "lines": 19,
                "subsections": []
            },
            {
                "name": "DESCRIPTION",
                "lines": 12,
                "subsections": []
            },
            {
                "name": "CREATING A NEW DRIVER",
                "lines": 256,
                "subsections": []
            },
            {
                "name": "CREATING A PURE PERL DRIVER",
                "lines": 1049,
                "subsections": []
            },
            {
                "name": "CREATING A C/XS DRIVER",
                "lines": 1157,
                "subsections": []
            },
            {
                "name": "METADATA METHODS",
                "lines": 237,
                "subsections": []
            },
            {
                "name": "TRACING",
                "lines": 106,
                "subsections": []
            },
            {
                "name": "OTHER MISCELLANEOUS INFORMATION",
                "lines": 127,
                "subsections": []
            },
            {
                "name": "SUBCLASSING DBI DRIVERS",
                "lines": 76,
                "subsections": []
            },
            {
                "name": "AUTHORS",
                "lines": 5,
                "subsections": []
            }
        ],
        "sections": {
            "NAME": {
                "content": "DBI::DBD - Perl DBI Database Driver Writer's Guide\n",
                "subsections": []
            },
            "SYNOPSIS": {
                "content": "perldoc DBI::DBD\n\nVersion and volatility\nThis document is still a minimal draft which is in need of further\nwork.\n\nPlease read the DBI documentation first and fully.  Then look at the\nimplementation of some high-profile and regularly maintained drivers\nlike DBD::Oracle, DBD::ODBC, DBD::Pg etc. (Those are no no particular\norder.)\n\nThen reread the DBI specification and the code of those drivers again\nas you're reading this. It'll help.  Where this document and the driver\ncode differ it's likely that the driver code is more correct,\nespecially if multiple drivers do the same thing.\n\nThis document is a patchwork of contributions from various authors.\nMore contributions (preferably as patches) are very welcome.\n",
                "subsections": []
            },
            "DESCRIPTION": {
                "content": "This document is primarily intended to help people writing new database\ndrivers for the Perl Database Interface (Perl DBI).  It may also help\nothers interested in discovering why the internals of a DBD driver are\nwritten the way they are.\n\nThis is a guide.  Few (if any) of the statements in it are completely\nauthoritative under all possible circumstances.  This means you will\nneed to use judgement in applying the guidelines in this document.  If\nin any doubt at all, please do contact the dbi-dev mailing list\n(details given below) where Tim Bunce and other driver authors can\nhelp.\n",
                "subsections": []
            },
            "CREATING A NEW DRIVER": {
                "content": "The first rule for creating a new database driver for the Perl DBI is\nvery simple: DON'T!\n\nThere is usually a driver already available for the database you want\nto use, almost regardless of which database you choose. Very often, the\ndatabase will provide an ODBC driver interface, so you can often use\nDBD::ODBC to access the database. This is typically less convenient on\na Unix box than on a Microsoft Windows box, but there are numerous\noptions for ODBC driver managers on Unix too, and very often the ODBC\ndriver is provided by the database supplier.\n\nBefore deciding that you need to write a driver, do your homework to\nensure that you are not wasting your energies.\n\n[As of December 2002, the consensus is that if you need an ODBC driver\nmanager on Unix, then the unixODBC driver (available from\n<http://www.unixodbc.org/>) is the way to go.]\n\nThe second rule for creating a new database driver for the Perl DBI is\nalso very simple: Don't -- get someone else to do it for you!\n\nNevertheless, there are occasions when it is necessary to write a new\ndriver, often to use a proprietary language or API to access the\ndatabase more swiftly, or more comprehensively, than an ODBC driver\ncan.  Then you should read this document very carefully, but with a\nsuitably sceptical eye.\n\nIf there is something in here that does not make any sense, question\nit.  You might be right that the information is bogus, but don't come\nto 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\nwith DBI.  The primary lists are dbi-users@perl.org for general users\nof DBI and DBD drivers, and dbi-dev@perl.org mainly for DBD driver\nwriters (don't join the dbi-dev list unless you have a good reason).\nThe auxiliary list is dbi-announce@perl.org for announcing new releases\nof DBI or DBD drivers.\n\nYou can join these lists by accessing the web-site\n<http://dbi.perl.org/>.  The lists are closed so you cannot send email\nto any of the lists unless you join the list first.\n\nYou should also consider monitoring the comp.lang.perl.* newsgroups,\nespecially comp.lang.perl.modules.\n\nThe Cheetah book\nThe definitive book on Perl DBI is the Cheetah book, so called because\nof the picture on the cover. Its proper title is 'Programming the Perl\nDBI: Database programming with Perl' by Alligator Descartes and Tim\nBunce, 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\nLocating drivers\nBefore writing a new driver, it is in your interests to find out\nwhether there already is a driver for your database.  If there is such\na driver, it would be much easier to make use of it than to write your\nown!\n\nThe primary web-site for locating Perl software is\n<http://search.cpan.org/>.  You should look under the various modules\nlistings 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\nRegistering a new driver\nBefore going through any official registration process, you will need\nto establish that there is no driver already in the works. You'll do\nthat by asking the DBI mailing lists whether there is such a driver\navailable, or whether anybody is working on one.\n\nWhen you get the go ahead, you will need to establish the name of the\ndriver and a prefix for the driver. Typically, the name is based on the\nname of the database software it uses, and the prefix is a contraction\nof that. Hence, DBD::Oracle has the name Oracle and the prefix 'ora'.\nThe prefix must be lowercase and contain no underscores other than the\none at the end.\n\nThis information will be recorded in the DBI module. Apart from\ndocumentation purposes, registration is a prerequisite for installing\nprivate methods.\n\nIf you are writing a driver which will not be distributed on CPAN, then\nyou should choose a prefix beginning with 'x', to avoid potential\nprefix collisions with drivers registered in the future. Thus, if you\nwrote 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\nthat the prefix 'drv' is assigned to the driver.\n\nTwo styles of database driver\nThere are two distinct styles of database driver that can be written to\nwork with the Perl DBI.\n\nYour driver can be written in pure Perl, requiring no C compiler.  When\nfeasible, this is the best solution, but most databases are not written\nin such a way that this can be done. Some examples of pure Perl drivers\nare DBD::File and DBD::CSV.\n\nAlternatively, and most commonly, your driver will need to use some C\ncode to gain access to the database. This will be classified as a C/XS\ndriver.\n\nWhat code will you write?\nThere are a number of files that need to be written for either a pure\nPerl driver or a C/XS driver. There are no extra files needed only by a\npure Perl driver, but there are several extra files needed only by a\nC/XS driver.\n\nFiles common to pure Perl and C/XS drivers\n\nAssuming that your driver is called DBD::Driver, these files are:\n\no   Makefile.PL\n\no   META.yml\n\no   README\n\no   MANIFEST\n\no   Driver.pm\n\no   lib/Bundle/DBD/Driver.pm\n\no   lib/DBD/Driver/Summary.pm\n\no   t/*.t\n\nThe first four files are mandatory. Makefile.PL is used to control how\nthe driver is built and installed. The README file tells people who\ndownload the file about how to build the module and any prerequisite\nsoftware that must be installed. The MANIFEST file is used by the\nstandard Perl module distribution mechanism. It lists all the source\nfiles that need to be distributed with your module. Driver.pm is what\nis loaded by the DBI code; it contains the methods peculiar to your\ndriver.\n\nAlthough the META.yml file is not required you are advised to create\none. Of particular importance are the buildrequires and\nconfigurerequires attributes which newer CPAN modules understand.  You\nuse these to tell the CPAN module (and CPANPLUS) that your build and\nconfigure mechanisms require DBI. The best reference for META.yml (at\nthe time of writing) is\n<http://module-build.sourceforge.net/META-spec-v1.4.html>. You can find\na reasonable example of a META.yml in DBD::ODBC.\n\nThe lib/Bundle/DBD/Driver.pm file allows you to specify other Perl\nmodules on which yours depends in a format that allows someone to type\na simple command and ensure that all the pre-requisites are in place as\nwell as building your driver.\n\nThe lib/DBD/Driver/Summary.pm file contains (an updated version of) the\ninformation that was included - or that would have been included - in\nthe appendices of the Cheetah book as a summary of the abilities of\nyour driver and the associated database.\n\nThe files in the t subdirectory are unit tests for your driver.  You\nshould write your tests as stringently as possible, while taking into\naccount the diversity of installations that you can encounter:\n\no   Your tests should not casually modify operational databases.\n\no   You should never damage existing tables in a database.\n\no   You should code your tests to use a constrained name space within\nthe database. For example, the tables (and all other named objects)\nthat are created could all begin with 'dbddrv'.\n\no   At the end of a test run, there should be no testing objects left\nbehind in the database.\n\no   If you create any databases, you should remove them.\n\no   If your database supports temporary tables that are automatically\nremoved at the end of a session, then exploit them as often as\npossible.\n\no   Try to make your tests independent of each other. If you have a\ntest t/t11dowhat.t that depends upon the successful running of\nt/t10thingamy.t, people cannot run the single test case\nt/t11dowhat.t. Further, running t/t11dowhat.t twice in a row is\nlikely to fail (at least, if t/t11dowhat.t modifies the database at\nall) because the database at the start of the second run is not\nwhat you saw at the start of the first run.\n\no   Document in your README file what you do, and what privileges\npeople need to do it.\n\no   You can, and probably should, sequence your tests by including a\ntest number before an abbreviated version of the test name; the\ntests are run in the order in which the names are expanded by\nshell-style globbing.\n\no   It is in your interests to ensure that your tests work as widely as\npossible.\n\nMany drivers also install sub-modules DBD::Driver::SubModule for any of\na variety of different reasons, such as to support the metadata methods\n(see the discussion of \"METADATA METHODS\" below). Such sub-modules are\nconventionally stored in the directory lib/DBD/Driver. The module\nitself would usually be in a file SubModule.pm. All such sub-modules\nshould themselves be version stamped (see the discussions far below).\n\nExtra files needed by C/XS drivers\n\nThe software for a C/XS driver will typically contain at least four\nextra files that are not relevant to a pure Perl driver.\n\no   Driver.xs\n\no   Driver.h\n\no   dbdimp.h\n\no   dbdimp.c\n\nThe Driver.xs file is used to generate C code that Perl can call to\ngain access to the C functions you write that will, in turn, call down\nonto your database software.\n\nThe Driver.h header is a stylized header that ensures you can access\nthe necessary Perl and DBI macros, types, and function declarations.\n\nThe dbdimp.h is used to specify which functions have been implemented\nby your driver.\n\nThe dbdimp.c file is where you write the C code that does the real work\nof translating between Perl-ish data types and what the database\nexpects to use and return.\n\nThere are some (mainly small, but very important) differences between\nthe contents of Makefile.PL and Driver.pm for pure Perl and C/XS\ndrivers, so those files are described both in the section on creating a\npure 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\nRequirements on a driver and driver writer\nTo be remotely useful, your driver must be implemented in a format that\nallows it to be distributed via CPAN, the Comprehensive Perl Archive\nNetwork (<http://www.cpan.org/> and <http://search.cpan.org>).  Of\ncourse, it is easier if you do not have to meet this criterion, but you\nwill not be able to ask for much help if you do not do so, and no-one\nis likely to want to install your module if they have to learn a new\ninstallation mechanism.\n",
                "subsections": []
            },
            "CREATING A PURE PERL DRIVER": {
                "content": "Writing a pure Perl driver is surprisingly simple. However, there are\nsome problems you should be aware of. The best option is of course\npicking up an existing driver and carefully modifying one method after\nthe 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\naccessing plain files as tables, which is part of the DBD::CSV package.\n\nThe minimal set of files we have to implement are Makefile.PL, README,\nMANIFEST and Driver.pm.\n\nPure Perl version of Makefile.PL\nYou typically start with writing Makefile.PL, a Makefile generator. The\ncontents of this file are described in detail in the\nExtUtils::MakeMaker man pages. It is definitely a good idea if you\nstart reading them. At least you should know about the variables\nCONFIGURE, DEFINED, PM, DIR, EXEFILES, INC, LIBS, LINKTYPE, NAME,\nOPTIMIZE, PLFILES, VERSION, VERSIONFROM, clean, depend, realclean\nfrom the ExtUtils::MakeMaker man page: these are used in almost any\nMakefile.PL.\n\nAdditionally read the section on Overriding MakeMaker Methods and the\ndescriptions of the distcheck, disttest and dist targets: They will\ndefinitely be useful for you.\n\nOf special importance for DBI drivers is the postamble method from the\nExtUtils::MMUnix man page.\n\nFor Emacs users, I recommend the libscan method, which removes Emacs\nbackup files (file names which end with a tilde '~') from lists of\nfiles.\n\nNow an example, I use the word \"Driver\" wherever you should insert your\ndriver'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()\"\n(containing \"createpptests()\") is optional; you should not use it\nunless your driver is a pure Perl driver (that is, it does not use C\nand XS code). Therefore, the call to \"dbdeditmmattribs()\" is not\nrelevant for C/XS drivers and may be omitted; simply use the (single)\nhash reference containing NAME etc as the only argument to\n\"WriteMakefile()\".\n\nNote that the \"dbdeditmmattribs()\" code will fail if you do not have\na t sub-directory containing at least one test case.\n\nPREREQPM tells MakeMaker that DBI (version 1.03 in this case) is\nrequired for this module. This will issue a warning that DBI 1.03 is\nmissing if someone attempts to install your DBD without DBI 1.03. See\nCONFIGURE below for why this does not work reliably in stopping cpan\ntesters failing your module if DBI is not installed.\n\nCONFIGURE is a subroutine called by MakeMaker during \"WriteMakefile\".\nBy putting the \"require DBI::DBD\" in this section we can attempt to\nload DBI::DBD but if it is missing we exit with success. As we exit\nsuccessfully without creating a Makefile when DBI::DBD is missing cpan\ntesters will not report a failure. This may seem at odds with PREREQPM\nbut PREREQPM does not cause \"WriteMakefile\" to fail (unless you also\nspecify PREREQFATAL which is strongly discouraged by MakeMaker) so\n\"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\nbe scanned for the first line that looks like an assignment to\n$VERSION, and the subsequent text will be used to determine the version\nnumber.  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\nwill need to add code to ensure that your environment is workable\nbefore the call to \"WriteMakefile()\". If you need to check for the\nexistence of an external library and perhaps modify INC to include the\npaths to where the external library header files are located and you\ncannot find the library or header files make sure you output a message\nsaying they cannot be found but \"exit 0\" (success) before calling\n\"WriteMakefile\" or CPAN testers will fail your module if the external\nlibrary is not found.\n\nA full-fledged Makefile.PL can be quite large (for example, the files\nfor DBD::Oracle and DBD::Informix are both over 1000 lines long, and\nthe Informix one uses - and creates - auxiliary modules too).\n\nSee also ExtUtils::MakeMaker and ExtUtils::MMUnix. Consider using\nCPAN::MakeMaker in place of ExtUtils::MakeMaker.\n\nREADME\nThe README file should describe what the driver is for, the pre-\nrequisites for the build process, the actual build process, how to\nreport errors, and who to report them to.\n\nUsers will find ways of breaking the driver build and test process\nwhich you would never even have dreamed to be possible in your worst\nnightmares. Therefore, you need to write this document defensively,\nprecisely and concisely.\n\nAs always, use the README from one of the established drivers as a\nbasis for your own; the version in DBD::Informix is worth a look as it\nhas been quite successful in heading off problems.\n\no   Note that users will have versions of Perl and DBI that are both\nolder and newer than you expected, but this will seldom cause much\ntrouble.  When it does, it will be because you are using features\nof DBI that are not supported in the version they are using.\n\no   Note that users will have versions of the database software that\nare both older and newer than you expected. You will save yourself\ntime in the long run if you can identify the range of versions\nwhich have been tested and warn about versions which are not known\nto be OK.\n\no   Note that many people trying to install your driver will not be\nexperts in the database software.\n\no   Note that many people trying to install your driver will not be\nexperts in C or Perl.\n\nMANIFEST\nThe MANIFEST will be used by the Makefile's dist target to build the\ndistribution tar file that is uploaded to CPAN. It should list every\nfile that you want to include in your distribution, one per line.\n\nlib/Bundle/DBD/Driver.pm\nThe CPAN module provides an extremely powerful bundle mechanism that\nallows you to specify pre-requisites for your driver.\n\nThe primary pre-requisite is Bundle::DBI; you may want or need to add\nsome more. With the bundle set 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\nneeded to build your driver.\n\nThe prerequisite modules are listed in the \"CONTENTS\" section, with the\nofficial name of the module followed by a dash and an informal name or\ndescription.\n\no   Listing Bundle::DBI as the main pre-requisite simplifies life.\n\no   Don't forget to list your driver.\n\no   Note that unless the DBMS is itself a Perl module, you cannot list\nit as a pre-requisite in this file.\n\no   You should keep the version of the bundle the same as the version\nof your driver.\n\no   You should add configuration management, copyright, and licencing\ninformation 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\nwas documented in the Perl book (such as DBD::Oracle or DBD::Informix\nor DBD::ODBC, to name but three), and adapting it to describe the\nfacilities available via DBD::Driver when accessing the Driver\ndatabase.\n\nPure Perl version of Driver.pm\nThe Driver.pm file defines the Perl module DBD::Driver for your driver.\nIt will define a package DBD::Driver along with some version\ninformation, some variable definitions, and a function \"driver()\" which\nwill 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\nDBD::Driver in the format used by perldoc.\n\nIn a pure Perl driver, the Driver.pm file is the core of the\nimplementation. You will need to provide all the key methods needed by\nDBI.\n\nNow let's take a closer look at an excerpt of File.pm as an example.\nWe ignore things that are common to any module (even non-DBI modules)\nor really specific to the DBD::File package.\n\nThe DBD::Driver package\n\nThe header\n\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\nwhere Makefile.PL looks for this information. Please ensure that any\nother modules added with your driver are also version stamped so that\nCPAN does not get confused.\n\nIt is recommended that you use a two-part (1.23) or three-part\n(1.23.45) version number. Also consider the CPAN system, which gets\nconfused and considers version 1.10 to precede version 1.9, so that\nusing a raw CVS, RCS or SCCS version number is probably not appropriate\n(despite being very 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\ncode to a shared repository like svn.perl.org the much larger revision\nnumbers won't cause a problem, at least not for a few years).  For RCS\nor CVS you can use:\n\n$VERSION = \"11.22\";\n\nwhich pads out the fractional part with leading zeros so all is well\n(so long as you don't go past x.99)\n\n$drh = undef;         # holds driver handle once initialized\n\nThis is where the driver handle will be stored, once created.  Note\nthat you may assume there is only one handle for your driver.\n\nThe driver constructor\n\nThe \"driver()\" method is the driver handle constructor. Note that the\n\"driver()\" method is in the DBD::Driver package, not in one of the sub-\npackages DBD::Driver::dr, DBD::Driver::db, or DBD::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\nare three kinds: driver handles (typically stored in $drh; from now on\ncalled drh or $drh), database handles (from now on called dbh or $dbh)\nand 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,\n\"DBD::File::dr\"), passed as the first argument to the \"driver()\"\nmethod.\n\n$publicattrs\nis a hash ref to attributes like Name, Version, and Attribution.\nThese are processed and used by DBI. You had better not make any\nassumptions about them nor should you add private attributes here.\n\n$privateattrs\nThis is another (optional) hash ref with your private attributes.\nDBI will store them and otherwise leave them alone.\n\nThe \"DBI::newdrh()\" method and the \"driver()\" method both return\n\"undef\" for failure (in which case you must look at $DBI::err and\n$DBI::errstr for the failure information, because you have no driver\nhandle to use).\n\nUsing installmethod() to expose driver-private methods\n\nDBD::Foo::db->installmethod($methodname, \\%attr);\n\nInstalls the driver-private method named by $methodname into the DBI\nmethod dispatcher so it can be called directly, avoiding the need to\nuse the func() method.\n\nIt is called as a static method on the driver class to which the method\nbelongs. The method name must begin with the corresponding registered\ndriver-private prefix. For example, for DBD::Oracle $methodname must\nbeing with '\"ora\"', and for DBD::AnyData it must begin with '\"ad\"'.\n\nThe \"\\%attr\" attributes can be used to provide fine control over how\nthe DBI dispatcher handles the dispatching of the method. However it's\nundocumented at the moment. See the IMA* #define's in DBI.xs and the\nO=>0x000x values in the initialization of %DBI::DBImethods in DBI.pm.\n(Volunteers to polish up and document the interface are very welcome to\nget in touch via dbi-dev@perl.org).\n\nMethods installed using installmethod default to the standard error\nhandling behaviour for DBI methods: clearing err and errstr before\ncalling the method, and checking for errors to trigger RaiseError etc.\non return. This differs from the default behaviour of func().\n\nNote for driver authors: The DBD::Foo::xx->installmethod call won't\nwork until the class-hierarchy has been setup. Normally the DBI looks\nafter that just after the driver is loaded. This means installmethod()\ncan't be called at the time the driver is loaded unless the class-\nhierarchy is set up first. The way to do that is to call the\nsetupdriver() method:\n\nDBI->setupdriver('DBD::Foo');\n\nbefore using installmethod().\n\nThe CLONE special subroutine\n\nAlso needed here, in the DBD::Driver package, is a \"CLONE()\" method\nthat will be called by perl when an interpreter is cloned. All your\n\"CLONE()\" method needs to do, currently, is clear the cached $drh so\nthe new interpreter won't start using the cached $drh from the old\ninterpreter:\n\nsub CLONE {\nundef $drh;\n}\n\nSee\n<http://search.cpan.org/dist/perl/pod/perlmod.pod#Makingyourmodulethreadsafe>\nfor details.\n\nThe DBD::Driver::dr package\n\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::*\nclasses, because the DBI takes care of that for you when the driver is\nloaded.\n\n*FIX ME* Explain what the impdatasize is, so that implementors aren't\npracticing cargo-cult programming.\n\nThe database handle constructor\n\nThe database handle constructor is the driver's (hence the changed\nnamespace) \"connect()\" method:\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\narguments are described in DBI.\n\nThe constructor \"DBI::newdbh()\" is called, returning a database\nhandle.  The constructor's prototype is:\n\n($outer, $inner) = DBI::newdbh($drh, $publicattr, $privateattr);\n\nwith similar arguments to those in the driver handle constructor,\nexcept that the $class is replaced by $drh. The Name attribute is a\nstandard DBI attribute (see \"Database Handle Attributes\" 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.\nThat's because within the driver code, the handle object you have is\nthe 'inner' handle of a tied hash, not the outer handle that the users\nof your driver have.\n\nBecause you have the inner handle, tie magic doesn't get invoked when\nyou get or set values in the hash. This is often very handy for speed\nwhen you want to get or set simple non-special driver-specific\nattributes.\n\nHowever, some attribute values, such as those handled by the DBI like\nPrintError, don't actually exist in the hash and must be read via\n\"$h->FETCH($attrib)\" and set via \"$h->STORE($attrib, $value)\".  If in\nany doubt, use these methods.\n\nThe datasources() method\n\nThe \"datasources()\" method must populate and return a list of valid\ndata sources, prefixed with the \"dbi:Driver\" incantation that allows\nthem to be used in the first argument of the \"DBI->connect()\" method.\nAn 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\n\nIf you need to release any resources when the driver is unloaded, you\ncan provide a disconnectall method.\n\nOther driver handle methods\n\nIf you need any other driver handle methods, they can follow here.\n\nError handling\n\nIt is quite likely that something fails in the connect method.  With\nDBD::File for example, you might catch an error when setting the\ncurrent directory to something not existent by using the (driver-\nspecific) 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\nRaiseError and PrintError etc are handled correctly.\n\nTypically you'll always use the method instance, aka your method's\nfirst argument.\n\nAs \"seterr()\" always returns \"undef\" your error handling code can\nusually be simplified to something like this:\n\nreturn $h->seterr($err, $errmsg, $state) if ...;\n\nThe DBD::Driver::db package\n\npackage DBD::Driver::db; # ====== DATABASE ======\n\n$DBD::Driver::db::impdatasize = 0;\n\nThe statement handle constructor\n\nThere's nothing much new in the statement handle constructor, which is\nthe \"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\nconstructor \"DBI::newsth()\". Again, in scalar context, only the outer\nhandle is returned. The Statement attribute should be cached as shown.\n\nNote the prefix drv in the attribute names: it is required that all\nyour private attributes use a lowercase prefix unique to your driver.\nAs mentioned earlier in this document, the DBI contains a registry of\nknown driver prefixes and may one day warn about unknown attributes\nthat don't have a registered prefix.\n\nNote that we parse the statement here in order to set the attribute\nNUMOFPARAMS. The technique illustrated is not very reliable; it can\nbe confused by question marks appearing in quoted strings, delimited\nidentifiers or in SQL comments that are part of the SQL statement. We\ncould set NUMOFPARAMS in the \"execute()\" method instead because the\nDBI specification explicitly allows a driver to defer this, but then\nthe user could not call \"bindparam()\".\n\nTransaction handling\n\nPure Perl drivers will rarely support transactions. Thus your\n\"commit()\" and \"rollback()\" methods 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\ndo nothing except return \"undef\".\n\nThe DBI's default \"beginwork()\" method can be used by inheritance.\n\nThe STORE() and FETCH() methods\n\nThese methods (that we have already used, see above) are called for\nyou, whenever the user does a:\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\nmethods are required.\n\nThe DBI will handle most attributes for you, in particular attributes\nlike RaiseError or PrintError. All you have to do is handle your\ndriver's private attributes and any attributes, like AutoCommit and\nChopBlanks, 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\nall lowercase names) without warning or error, so there's actually no\nneed to implement driver-specific any code in your \"FETCH()\" and\n\"STORE()\" methods unless you need extra logic/checks, beyond getting or\nsetting the value.\n\nUnless your driver documentation indicates otherwise, the return value\nof the \"STORE()\" method is unspecified and the caller shouldn't use\nthat value.\n\nOther database handle methods\n\nAs with the driver package, other database handle methods may follow\nhere.  In particular you should consider a (possibly empty)\n\"disconnect()\" method and possibly a \"quote()\" method if DBI's default\nisn't correct for you. You may also need the \"typeinfoall()\" and\n\"getinfo()\" methods, as described elsewhere in this document.\n\nWhere reasonable use \"$h->SUPER::foo()\" to call the DBI's method in\nsome or all cases and just wrap your custom behavior around that.\n\nIf you want to use private trace flags you'll probably want to be able\nto set them by name. To do that you'll need to define a\n\"parsetraceflag()\" method (note that's \"parsetraceflag\", singular,\nnot \"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\nin the top 8 of the 32 bits.\n\nThe DBD::Driver::st package\n\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\n\nThis is perhaps the most difficult method because we have to consider\nparameter bindings here. In addition to that, there are a number of\nstatement attributes which must be set for inherited DBI methods to\nfunction correctly (see \"Statement attributes\" below).\n\nWe present a simplified implementation by using the drvparams\nattribute 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\nthey are essential for \"bindcolumns()\" to work.\n\nWe use attribute \"$sth->{Statement}\" which we created within\n\"prepare()\". The attribute \"$sth->{Database}\", which is nothing else\nthan the dbh, was automatically created by DBI.\n\nFinally, note that (as specified in the DBI specification) we return\nthe string '0E0' instead of the number 0, so that the result tests true\nbut equal to zero.\n\n$sth->execute() or die $sth->errstr;\n\nThe executearray(), executeforfetch() and bindparamarray() methods\n\nIn general, DBD's only need to implement \"executeforfetch()\" and\n\"bindparamarray\". DBI's default \"executearray()\" will invoke the\nDBD's \"executeforfetch()\" as needed.\n\nThe following sequence describes the interaction between DBI\n\"executearray\" and a DBD's \"executeforfetch\":\n\n1.  App calls \"$sth->executearray(\\%attrs, @arrayofarrays)\"\n\n2.  If @arrayofarrays was specified, DBI processes @arrayofarrays\nby calling DBD's \"bindparamarray()\". Alternately, App may have\ndirectly called \"bindparamarray()\"\n\n3.  DBD validates and binds each array\n\n4.  DBI retrieves the validated param arrays from DBD's ParamArray\nattribute\n\n5.  DBI calls DBD's \"executeforfetch($fetchtuplesub,\n\\@tuplestatus)\", where &$fetchtuplesub is a closure to iterate\nover the returned ParamArray values, and \"\\@tuplestatus\" is an\narray to receive the disposition status of each tuple.\n\n6.  DBD iteratively calls &$fetchtuplesub to retrieve parameter\ntuples to be added to its bulk database operation/request.\n\n7.  when DBD reaches the limit of tuples it can handle in a single\ndatabase operation/request, or the &$fetchtuplesub indicates no\nmore tuples by returning undef, the DBD executes the bulk\noperation, and reports the disposition of each tuple in\n\\@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()\nimplementation requires the use of positional (i.e., '?') placeholders.\nDrivers which require named placeholders must either emulate positional\nplaceholders (e.g., see DBD::Oracle), or must implement their own\nexecutearray()/executeforfetch() methods to properly sequence bound\nparameter arrays.\n\nFetching data\n\nOnly one method needs to be written for fetching data,\n\"fetchrowarrayref()\".  The other methods, \"fetchrowarray()\",\n\"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\n\"bindcol()\" and \"bindcolumns()\" work.\n\nIf an error occurs which leaves the $sth in a state where remaining\nrows can't be fetched then Active should be turned off before the\nmethod 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.\nAlternatively you could delete that method and so fallback to the DBI's\nown method which does the right thing based on the number of calls to\n\"setfbav()\".\n\nThe moreresults method\n\nIf your driver doesn't support multiple result sets, then don't even\nimplement this method.\n\nOtherwise, this method needs to get the statement handle ready to fetch\nresults from the next result set, if there is one. Typically you'd\nstart with:\n\n$sth->finish;\n\nthen you should delete all the attributes from the attribute cache that\nmay no longer be relevant 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\nthat may not be correct for the next resultset.\n\nThe NUMOFFIELDS attribute is a special case. It should be set using\nSTORE:\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\nthe number of elements in the row buffer array\n(\"DBIcFIELDSAV(impsth)\") to match the new result set. Fill any new\nvalues with newSV(0) not &svundef.  Alternatively you could free\nDBIcFIELDSAV(impsth) and set it to null, but that would mean\nbindcolumns() wouldn't work across result sets.\n\nStatement attributes\n\nThe main difference between dbh and sth attributes is, that you should\nimplement a lot of attributes here that are required by the DBI, such\nas NAME, NULLABLE, TYPE, etc. See \"Statement Handle Attributes\" in DBI\nfor a complete list.\n\nPay attention to attributes which are marked as read only, such as\nNUMOFPARAMS. These attributes can only be set the first time a\nstatement is executed. If a statement is prepared, then executed\nmultiple times, warnings may be generated.\n\nYou can protect against these warnings, and prevent the recalculation\nof attributes which might be expensive to calculate (such as the NAME\nand 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\n\"ATTRIBUTES COMMON TO ALL HANDLES\" in DBI is Active. Many DBI methods,\nincluding \"bindcolumns()\", depend on this attribute.\n\nBesides that the \"STORE()\" and \"FETCH()\" methods are mainly the same as\nabove for dbh's.\n\nOther statement methods\n\nA trivial \"finish()\" method to discard stored data, reset any\nattributes (such as Active) and do \"$sth->SUPER::finish()\".\n\nIf you've defined a \"parsetraceflag()\" method in ::db you'll also\nwant it in ::st, so just alias it in:\n\n*parsetraceflag = \\&DBD::foo:db::parsetraceflag;\n\nAnd perhaps some other methods that are not part of the DBI\nspecification, in particular to make metadata available.  Remember that\nthey must have names that begin with your drivers registered prefix so\nthey can be installed using \"installmethod()\".\n\nIf \"DESTROY()\" is called on a statement handle that's still active\n(\"$sth->{Active}\" is true) then it should effectively call \"finish()\".\n\nsub DESTROY {\nmy $sth = shift;\n$sth->finish if $sth->FETCH('Active');\n}\n\nTests\nThe test process should conform as closely as possibly to the Perl\nstandard test harness.\n\nIn particular, most (all) of the tests should be run in the t sub-\ndirectory, and should simply produce an \"ok\" when run under \"make\ntest\".  For details on how this is done, see the Camel book and the\nsection 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\nfor testing, and to the privileges of the user testing the driver. For\nexample, the DBD::Informix test code has to adapt in a number of places\nto the type of database to which it is connected as different Informix\ndatabases have different capabilities: some of the tests are for\ndatabases without transaction logs; others are for databases with a\ntransaction log; some versions of the server have support for blobs, or\nstored 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\nin 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\nDBD/Informix/TestHarness.pm which is used throughout the DBD::Informix\ntests in the t sub-directory.\n",
                "subsections": []
            },
            "CREATING A C/XS DRIVER": {
                "content": "Please also see the section under \"CREATING A PURE PERL DRIVER\"\nregarding the creation of the Makefile.PL.\n\nCreating a new C/XS driver from scratch will always be a daunting task.\nYou can and should greatly simplify your task by taking a good\nreference driver implementation and modifying that to match the\ndatabase product for which you are writing a driver.\n\nThe de facto reference driver has been the one for DBD::Oracle written\nby Tim Bunce, who is also the author of the DBI package. The\nDBD::Oracle module is a good example of a driver implemented around a\nC-level API.\n\nNowadays it it seems better to base on DBD::ODBC, another driver\nmaintained by Tim and Jeff Urlwin, because it offers a lot of metadata\nand seems to become the guideline for the future development. (Also as\nDBD::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\ninstead of a function-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\npure Perl modules - see above.  However, there are also some subtle\n(and not so subtle) differences, including:\n\no       The variables $DBD::Driver::{dr|db|st}::impdatasize are not\ndefined here, but in the XS code, because they declare the size\nof certain C structures.\n\no       Some methods are typically moved to the XS code, in particular\n\"prepare()\", \"execute()\", \"disconnect()\", \"disconnectall()\"\nand the \"STORE()\" and \"FETCH()\" methods.\n\no       Other methods are still part of Driver.pm, but have callbacks\nto the XS code.\n\no       If the driver-specific parts of the impdrht structure need to\nbe formally initialized (which does not seem to be a common\nrequirement), then you need to add a call to an appropriate XS\nfunction in the driver method of \"DBD::Driver::driver()\", and\nyou define the corresponding function in Driver.xs, and you\ndefine the C code in dbdimp.c and the prototype in dbdimp.h.\n\nFor example, DBD::Informix has such a requirement, and adds the\nfollowing call after the call 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\nchecking whether the private data part of the driver handle is\nall zeroed out, rather than add extra functions.\n\nNow let's take a closer look at an excerpt from Oracle.pm (revised\nheavily to remove idiosyncrasies) as an example, ignoring things that\nwere already discussed for pure Perl drivers.\n\nThe connect method\n\nThe connect method is the database handle constructor.  You could write\neither of two versions of this method: either one which takes\nconnection attributes (new code) and one which ignores them (old code\nonly).\n\nIf you ignore the connection attributes, then you omit all mention of\nthe $auth variable (which is a reference to a hash of attributes), and\nthe XS system manages the differences for you.\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\nthe use of the private \"login()\" callback, which is the function that\nwill really connect to the database. It is implemented in Driver.xst\n(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\nthe connect method and hence end up in $attr in \"dbddblogin6\" then it\nis best to delete any you process so DBI does not send them again via\nSTORE 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)\nDBDATTRIBDELETE segfaulted so if you cannot guarantee the DBI version\nwill 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\n*FIX ME* T.B.S\n\nThe datasources method\n\nIf your \"datasources()\" method can be implemented in pure Perl, then\ndo so because it is easier than doing it in XS code (see the section\nabove for pure Perl drivers).\n\nIf your \"datasources()\" method must call onto compiled functions, then\nyou will need to define dbddrdatasources in your dbdimp.h file,\nwhich will trigger Driver.xst (in DBI v1.33 or greater) to generate the\nXS 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\n\nThe prepare method is the statement handle constructor, and most of it\nis not new. Like the \"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\n*FIX ME* T.B.S\n\nThe fetchrowarrayref method\n\n*FIX ME* T.B.S\n\nOther methods?\n\n*FIX ME* T.B.S\n\nDriver.xs\nDriver.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\nfunctions for almost all private methods here which will typically do\nmuch work for you.\n\nWherever you really have to implement something, it will call a private\nfunction in dbdimp.c, and this is what you have to implement.\n\nYou need to set up an extra routine if your driver needs to export\nconstants of its own, analogous to the SQL types available when you\nsay:\n\nuse DBI qw(:sqltypes);\n\n*FIX ME* T.B.S\n\nDriver.h\nDriver.h is very simple and the operational contents should look like\nthis:\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\nwriter of a driver needs.\n\nThe file dbdxsh.h header provides prototype declarations for the C\nfunctions that you might decide to implement. Note that you should\nnormally only define one of \"dbddblogin()\", \"dbddblogin6()\" or\n\"dbddblogin6sv\" unless you are intent on supporting really old\nversions of DBI (prior to DBI 1.06) as well as modern versions. The\nonly standard, DBI-mandated functions that you need write are those\nspecified in the dbdxsh.h header. You might also add extra driver-\nspecific functions in Driver.xs.\n\nThe dbivport.h file should be copied from the latest DBI release into\nyour distribution each time you modify your driver. Its job is to allow\nyou to enhance your code to work with the latest DBI API while still\nallowing your driver to be compiled and used with older versions of the\nDBI (for example, when the \"DBIhSETERRCHAR()\" macro was added to DBI\n1.41, an emulation of it was added to dbivport.h). This makes users\nhappy and your life easier. Always read the notes in dbivport.h to\ncheck 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\nPERLNOGETCONTEXT before DBIXS.h is included. This can significantly\nimprove efficiency when running under a thread enabled perl. (Remember\nthat the standard perl in most Linux distributions is built with\nthreads enabled.  So is ActiveState perl for Windows, and perl built\nfor Apache modperl2.)  If you do this there are some things to keep in\nmind:\n\no   If PERLNOGETCONTEXT is defined, then every function that calls\nthe Perl API will need to start out with a \"dTHX;\" declaration.\n\no   You'll know which functions need this, because the C compiler will\ncomplain that the undeclared identifier \"myperl\" is used if and\nonly if the perl you are using to develop and test your driver has\nthreads enabled.\n\no   If you don't remember to test with a thread-enabled perl before\nmaking a release it's likely that you'll get failure reports from\nusers who are.\n\no   For driver private functions it is possible to gain even more\nefficiency by replacing \"dTHX;\" with \"pTHX\" prepended to the\nparameter list and then \"aTHX\" prepended to the argument list\nwhere the function is called.\n\nSee \"How multiple interpreters and concurrency are supported\" in\nperlguts for additional information about PERLNOGETCONTEXT.\n\nImplementation header dbdimp.h\nThis header file has two jobs:\n\nFirst it defines data structures for your private part of the handles.\nNote that the DBI provides many common fields for you. For example the\nstatement handle (impsth) already has a rowcount field with an IV\ntype that accessed via the DBIcROWCOUNT(impsth) macro. Using this is\nstrongly recommended as it's built in to some DBI internals so the DBI\ncan 'just work' in more cases and you'll have less driver-specific code\nto write.  Study DBIXS.h to see what's included with each type of\nhandle.\n\nSecond it defines macros that rename the generic names like\n\"dbddblogin()\" to database specific names like \"oradblogin()\". This\navoids name clashes and enables use of different drivers when you work\nwith a statically linked perl.\n\nIt also will have the important task of disabling XS methods that you\ndon't want to implement.\n\nFinally, the macros will also be used to select alternate\nimplementations of some functions. For example, the \"dbddblogin()\"\nfunction is not passed the attribute hash.\n\nSince DBI v1.06, if a \"dbddblogin6()\" macro is defined (for a\nfunction with 6 arguments), it will be used instead with the attribute\nhash passed as the sixth argument.\n\nSince DBI post v1.607, if a \"dbddblogin6sv()\" macro is defined (for\na function like dbddblogin6 but with scalar pointers for the dbname,\nusername and password), it will be used instead. This will allow your\nlogin6 function to see if there are any Unicode characters in the\ndbname.\n\nSimilarly defining dbddbdo4iv is preferred over dbddbdo4,\ndbdstrowsiv over dbdstrows, and dbdstexecuteiv over\ndbdstexecute. 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,\nstructures and types. I strongly recommend against that. At first\nglance this saves time, but your implementation will be less readable.\nIt was just hell when I had to separate DBI specific parts, Oracle\nspecific parts, mSQL specific parts and mysql specific parts in\nDBD::mysql's dbdimp.h and dbdimp.c. (DBD::mysql was a port of DBD::mSQL\nwhich was based on DBD::Oracle.) [Seconded, based on the experience\ntaking DBD::Informix apart, even though the version inherited in 1996\nwas only based on DBD::Oracle.]\n\nThis part of the driver is your exclusive part. Rewrite it from\nscratch, so it will be clean and short: in other words, a better piece\nof code. (Of course keep an eye on other people's work.)\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\nbe of type dbihdrct|dbct|stct and must be called \"com\".\n\nYou should never access these fields directly, except by using the\nDBIcxxx() macros below.\n\nImplementation source dbdimp.c\nConventionally, dbdimp.c is the main implementation file (but\nDBD::Informix calls the file dbdimp.ec). This section includes a short\nnote on each function that is used in the Driver.xsi template and thus\nhas to be implemented.\n\nOf course, you will probably also need to implement other support\nfunctions, which should usually be file static if they are placed in\ndbdimp.c. If they are placed in other files, you need to list those\nfiles in Makefile.PL (and MANIFEST) to handle them correctly.\n\nIt is wise to adhere to a namespace convention for your functions to\navoid conflicts. For example, for a driver with prefix drv, you might\ncall externally visible functions dbddrvxxxx. You should also avoid\nnon-constant global variables as much as possible to improve the\nsupport for threading.\n\nSince Perl requires support for function prototypes (ANSI or ISO or\nStandard C), you should write your code using function prototypes too.\n\nIt is possible to use either the unmapped names such as \"dbdinit()\" or\nthe mapped names such as \"dbdixdrinit()\" in the dbdimp.c file.\nDBD::Informix uses the mapped names which makes it easier to identify\nwhere to look for linkage problems at runtime (which will report errors\nusing the mapped names).\n\nMost other drivers, and in particular DBD::Oracle, use the unmapped\nnames in the source code which makes it a little easier to compare code\nbetween drivers and eases discussions on the dbi-dev mailing list.  The\nmajority of the code fragments here will use the unmapped names.\n\nUltimately, you should provide implementations for most of the\nfunctions listed in the dbdxsh.h header. The exceptions are optional\nfunctions (such as \"dbdstrows()\") and those functions with\nalternative signatures, such as \"dbddblogin6sv\", \"dbddblogin6()\"\nand dbddblogin(). Then you should only implement one of the\nalternatives, and generally the newer one of the alternatives.\n\nThe dbdinit method\n\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\nloaded; the bootstrap command in \"DBD::Driver::dr::driver()\" triggers\nthis, and the call is generated in the BOOT section of Driver.xst.\nThese statements are needed to allow your driver to use the DBI macros.\nThey will include your private header file dbdimp.h in turn.  Note that\nDBISTATEINIT requires the name of the argument to \"dbdinit()\" to be\ncalled \"dbistate()\".\n\nThe dbddrverror method\n\nYou need a function to record errors so DBI can access them properly.\nYou can call it whatever you like, but we'll call it \"dbddrverror()\"\nhere.\n\nThe argument list depends on your database software; different systems\nprovide different ways to get 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\nor a statement handle.\n\nDimpxxh(h);\n\nThis macro will declare and initialize a variable impxxh with a\npointer to your private handle pointer. You may cast this to to\nimpdrht, impdbht or impstht.\n\nTo record the error correctly, equivalent to the \"seterr()\" method,\nuse one of the \"DBIhSETERRCHAR(...)\" or \"DBIhSETERRSV(...)\"\nmacros, 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\n\"SV*\" (use &svundef instead of NULL).\n\nFor \"DBIhSETERRCHAR\" the errc, errstr, state, method parameters are\n\"char*\".\n\nThe erri parameter is an \"IV\" that's used instead of errc if errc is\n\"Null\".\n\nThe method parameter can be ignored.\n\nThe \"DBIhSETERRCHAR\" macro is usually the simplest to use when you\njust have an integer error code 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\n\"Null\".\n\nTo make drivers compatible with DBI < 1.41 you should be using\ndbivport.h as described in \"Driver.h\" above.\n\nThe (obsolete) macros such as \"DBIhEVENT2\" should be removed from\ndrivers.\n\nThe names \"dbis\" and \"DBIS\", which were used in previous versions of\nthis document, should be replaced with the \"DBIcDBISTATE(impxxh)\"\nmacro.\n\nThe name \"DBILOGFP\", which was also used in previous versions of this\ndocument, should be replaced by \"DBIcLOGPIO(impxxh)\".\n\nYour code should not call the C \"<stdio.h>\" I/O functions; you should\nuse \"PerlIOprintf()\" as shown:\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.\nMake use of this as often as you can, but don't output anything at a\ntrace level less than 3. Levels 1 and 2 are reserved for the DBI.\n\nYou can define up to 8 private trace flags using the top 8 bits of\n\"DBIcTRACEFLAGS(imp)\", that is: 0xFF000000. See the\n\"parsetraceflag()\" method elsewhere in this document.\n\nThe dbddrdatasources method\n\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\ndetermined by pure Perl code, do it that way. If, as in DBD::Informix,\nthe information is obtained by a C function call, then you need to\ndefine 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\n\"sqgetdbs()\" function call shown will return up to 100 databases names,\nwith the pointers to each name in the array dbsname and the name\nstrings 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\ncode, logs function entry and exit, reports the error from\n\"sqgetdbs()\", and uses \"#define\"'d constants for the array sizes.\n\nThe dbddblogin6 method\n\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\nthe database handle. impdbh is the pointer to the handles private\ndata, as is impxxx in \"dbddrverror()\" above. The arguments dbname,\nuser, auth and attr correspond to the arguments of the driver handle's\n\"connect()\" method.\n\nYou will quite often use database specific attributes here, that are\nspecified in the DSN. I recommend you parse the DSN (using Perl) within\nthe \"connect()\" method and pass the segments of the DSN via the\nattributes parameter through \"login()\" to \"dbddblogin6()\".\n\nHere's how you fetch them; as an example we use hostname attribute,\nwhich can be up to 12 characters 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\nmethod you probably want to delete them from \"attr\" (as above with\nDBDATTRIBDELETE). If you don't delete your handled attributes DBI\nwill call \"STORE\" for each attribute after the connect/login and this\nis at best redundant for attributes you have already processed.\n\nNote: Until revision 11605 (post DBI 1.607), there was a problem with\nDBDATTRIBUTEDELETE so unless you require a DBI version after 1.607\nyou need to replace each DBDATTRIBUTEDELETE call with:\n\nhvdelete((HV*)SvRV(attr), key, keylen, GDISCARD)\n\nNote that you can also obtain standard attributes such as AutoCommit\nand ChopBlanks from the attributes parameter, using \"DBDATTRIBGETIV\"\nfor integer attributes.\n\nIf, for example, your database does not support transactions but\nAutoCommit is set off (requesting transaction support), then you can\nemulate a 'failure to connect'.\n\nNow you should really connect to the database. In general, if the\nconnection fails, it is best to ensure that all allocated resources are\nreleased so that the handle does not need to be destroyed separately.\nIf 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\nthe impdbh structure and that the implementors private\n\"dbddbdestroy()\" function should be called when the handle is\ndestroyed.\n\nDBIcACTIVEon(impdbh);\n\nThis indicates that the handle has an active connection to the server\nand that the \"dbddbdisconnect()\" function should be called before the\nhandle is destroyed.\n\nNote that if you do need to fail, you should report errors via the drh\nor impdrh rather than via dbh or impdbh because impdbh will be\ndestroyed by the failure, so errors recorded in that handle will not be\nvisible to DBI, and hence not the user either.\n\nNote too, that the function is passed dbh and impdbh, and there is a\nmacro \"Dimpdrhfromdbh\" which can recover the impdrh from the\nimpdbh. However, there is no DBI macro to provide you with the drh\ngiven either the impdbh or the dbh or the impdrh (and there's no way\nto recover the dbh given just the impdbh).\n\nThis suggests that, despite the above notes about \"dbddrverror()\"\ntaking an \"SV *\", it may be better to have two error routines, one\ntaking impdbh and one taking impdrh instead. With care, you can\nfactor most of the formatting code out so that these are small routines\ncalling a common error formatter. See the code in DBD::Informix 1.05.00\nfor more information.\n\nThe \"dbddblogin6()\" function should return TRUE for success, FALSE\notherwise.\n\nDrivers implemented long ago may define the five-argument function\n\"dbddblogin()\" instead of \"dbddblogin6()\". The missing argument is\nthe attributes. There are ways to work around the missing attributes,\nbut they are ungainly; it is much better to use the 6-argument form.\nEven later drivers will use \"dbddblogin6sv()\" which provides the\ndbname, username and password as SVs.\n\nThe dbddbcommit and dbddbrollback methods\n\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\nsuccess, FALSE for error.\n\nThe arguments dbh and impdbh are the same as for \"dbddblogin6()\"\nabove; I will omit describing them in what follows, as they appear\nalways.\n\nThese functions should return TRUE for success, FALSE otherwise.\n\nThe dbddbdisconnect method\n\nThis is your private part of the \"disconnect()\" method. Any dbh with\nthe ACTIVE flag on must be disconnected. (Note that you have to set it\nin \"dbddbconnect()\" above.)\n\nint dbddbdisconnect(SV* dbh, impdbht* impdbh);\n\nThe database handle will return TRUE for success, FALSE otherwise.  In\nany case it should do a:\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\nstill have active children. If your database API reacts badly to trying\nto use an sth in this situation then you'll need to add code like this\nto all sth methods:\n\nif (!DBIcACTIVE(DBIcPARENTCOM(impsth)))\nreturn 0;\n\nAlternatively, you can add code to your driver to keep explicit track\nof the statement handles that exist for each database handle and\narrange to destroy those handles before disconnecting from the\ndatabase. There is code to do this in DBD::Informix. Similar comments\napply to the driver handle keeping track of all the database handles.\n\nNote that the code which destroys the subordinate handles should only\nrelease the associated database resources and mark the handles\ninactive; it does not attempt to free the actual handle structures.\n\nThis function should return TRUE for success, FALSE otherwise, but it\nis not clear what anything can do about a failure.\n\nThe dbddbdisconall method\n\nint dbddisconall (SV *drh, impdrht *impdrh);\n\nThis function may be called at shutdown time. It should make best-\nefforts to disconnect all database handles - if possible. Some\ndatabases don't support that, in which case you can do nothing but\nreturn 'success'.\n\nThis function should return TRUE for success, FALSE otherwise, but it\nis not clear what anything can do about a failure.\n\nThe dbddbdestroy method\n\nThis is your private part of the database handle destructor. Any dbh\nwith the IMPSET flag on must be destroyed, so that you can safely free\nresources. (Note that you have to set it in \"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,\nif the handle is still 'active', before calling \"dbddbdestroy()\".\n\nBefore returning the function must switch IMPSET to off, so DBI knows\nthat the destructor was called.\n\nA DBI handle doesn't keep references to its children. But children do\nkeep references to their parents. So a database handle won't be\n\"DESTROY\"'d until all its children have been \"DESTROY\"'d.\n\nThe dbddbSTOREattrib method\n\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\nhandle DBI attributes here: leave this to DBI. (There are two\nexceptions, AutoCommit and ChopBlanks, which you should care about.)\n\nThe return value is TRUE if you have handled the attribute or FALSE\notherwise. If you are handling an attribute and something fails, you\nshould call \"dbddrverror()\", so DBI can raise exceptions, if desired.\nIf \"dbddrverror()\" returns, however, you have a problem: the user\nwill never know about the error, because he typically will not check\n\"$dbh->errstr()\".\n\nI cannot recommend a general way of going on, if \"dbddrverror()\"\nreturns, but there are examples where even the DBI specification\nexpects that you \"croak()\". (See the AutoCommit method in DBI.)\n\nIf you have to store attributes, you should either use your private\ndata structure impxxx, the handle hash (via \"(HV*)SvRV(dbh)\"), or use\nthe private impdata.\n\nThe first is best for internal C values like integers or pointers and\nwhere speed is important within the driver. The handle hash is best for\nvalues the user may want to get/set via driver-specific attributes.\nThe private impdata is an additional \"SV\" attached to the handle. You\ncould think of it as an unnamed handle attribute. It's not normally\nused.\n\nThe dbddbFETCHattrib method\n\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\nthat you should normally execute \"sv2mortal()\", if you return a\nnonconstant value. (Constant values are &svundef, &svno and &svyes.)\n\nNote, that DBI implements a caching algorithm for attribute values.  If\nyou think, that an attribute may be fetched, you store it in the dbh\nitself:\n\nif (cacheit) /* cache value for later DBI 'quick' fetch? */\nhvstore((HV*)SvRV(dbh), key, kl, cachesv, 0);\n\nThe dbdstprepare method\n\nThis is the private part of the \"prepare()\" method. Note that you must\nnot really execute the statement here. You may, however, preparse and\nvalidate 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\n\"prepare()\" code that set the Statement attribute on the handle. This\nattribute can then be used by \"dbdstexecute()\".\n\nIf the driver supports placeholders then the NUMOFPARAMS attribute\nmust be set correctly by \"dbdstprepare()\":\n\nDBIcNUMPARAMS(impsth) = ...\n\nIf you can, you should also setup attributes like NUMOFFIELDS, NAME,\netc. here, but DBI doesn't require that - they can be deferred until\nexecute() is called. However, if you do, document it.\n\nIn any case you should set the IMPSET flag, as you did in\n\"dbddbconnect()\" above:\n\nDBIcIMPSETon(impsth);\n\nThe dbdstexecute method\n\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\nrows affected is unknown else it should be the number of affected\n(updated, inserted) rows.\n\nNote that you must be aware a statement may be executed repeatedly.\nAlso, you should not expect that \"finish()\" will be called between two\nexecutions, so you might need code, like the following, near the start\nof the function:\n\nif (DBIcACTIVE(impsth))\ndbdstfinish(h, impsth);\n\nIf your driver supports the binding of parameters (it should!), but the\ndatabase doesn't, you must 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\nstatement is successfully executed if the driver has not already done\nso: they may be used even before a potential \"fetchrow()\".  In\nparticular you have to tell DBI the number of fields that the statement\nhas, because it will be used by DBI internally. Thus the function will\ntypically ends with:\n\nif (isSelectStatement) {\nDBIcNUMFIELDS(impsth) = numFields;\nDBIcACTIVEon(impsth);\n}\n\nIt is important that the ACTIVE flag only be set for \"SELECT\"\nstatements (or any other statements that can return many values from\nthe database using a cursor-like mechanism). See \"dbddbconnect()\"\nabove for more explanations.\n\nThere plans for a preparse function to be provided by DBI, but this has\nnot reached fruition yet.  Meantime, if you want to know how ugly it\ncan get, try looking at the \"dbdixpreparse()\" in DBD::Informix\ndbdimp.ec and the related functions in iustoken.c and sqltoken.c.\n\nThe dbdstfetch method\n\nThis function fetches a row of data. The row is stored in in an array,\nof \"SV\"'s that DBI prepares for you. This has two advantages: it is\nfast (you even reuse the \"SV\"'s, so they don't have to be created after\nthe 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*\".\nIt's more common to use your database API functions to fetch the data\nas 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\"\notherwise.\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\nrows can't be fetched then Active should be turned off before the\nmethod returns.\n\nThe dbdstfinish3 method\n\nThe \"$sth->finish()\" method can be called if the user wishes to\nindicate that no more rows will be fetched even if the database has\nmore rows to offer, and the DBI code can call the function when handles\nare being destroyed. See the DBI specification for more background\ndetails.\n\nIn both circumstances, the DBI code ends up calling the\n\"dbdstfinish3()\" method (if you provide a mapping for\n\"dbdstfinish3()\" in dbdimp.h), or \"dbdstfinish()\" otherwise.  The\ndifference is that \"dbdstfinish3()\" takes a third argument which is\nan \"int\" with the value 1 if it is being called from a \"destroy()\"\nmethod and 0 otherwise.\n\nNote that DBI v1.32 and earlier test on \"dbddbfinish3()\" to call\n\"dbdstfinish3()\"; if you provide \"dbdstfinish3()\", either define\n\"dbddbfinish3()\" too, or insist on DBI v1.33 or later.\n\nAll it needs to do is turn off the Active flag for the sth.  It will\nonly be called by Driver.xst code, if the driver has set ACTIVE to on\nfor 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\ncalled from \"DESTROY()\" - and so the statement is about to be\ndestroyed.  For many drivers there is no point in doing anything more\nthan turning off the Active flag in this case.\n\nThe function returns TRUE for success, FALSE otherwise, but there isn't\na lot anyone can do to recover if there is an error.\n\nThe dbdstdestroy method\n\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\nhas the ACTIVE flag set, before calling \"dbdstdestroy()\".\n\nThe dbdstSTOREattrib and dbdstFETCHattrib methods\n\nThese functions correspond to \"dbddbSTORE()\" and \"dbddbFETCH()\"\nattrib above, except that they 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\n\nThis function is internally used by the \"bindparam()\" method, the\n\"bindparaminout()\" method and by the DBI Driver.xst code if\n\"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, ...).\nThe value argument is the parameter value and sqltype is its type.\n\nIf your driver does not support \"bindparaminout()\" then you should\nignore maxlen and croak if isinout is TRUE.\n\nIf your driver does support \"bindparaminout()\" then you should note\nthat value is the \"SV\" after dereferencing the reference passed to\n\"bindparaminout()\".\n\nIn drivers of simple databases the function will, for example, store\nthe value in a parameter array and use it later in \"dbdstexecute()\".\nSee the DBD::mysql driver for an example.\n\nImplementing bindparaminout support\n\nTo provide support for parameters bound by reference rather than by\nvalue, the driver must do a number of things.  First, and most\nimportantly, it must note the references and stash them in its own\ndriver structure.  Secondly, when a value is bound to a column, the\ndriver must discard any previous reference bound to the column.  On\neach execute, the driver must evaluate the references and internally\nbind the values resulting from the references.  This is only applicable\nif the user 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\n@values.  These calls are indistinguishable from explicit user calls to\n\"bindparam()\".\n\nC/XS version of Makefile.PL\nThe Makefile.PL file for a C/XS driver is similar to the code needed\nfor a pure Perl driver, but there are a number of extra bits of\ninformation needed by the build system.\n\nFor example, the attributes list passed to \"WriteMakefile()\" needs to\nspecify the object files that need to be compiled and built into the\nshared object (DLL). This is often, but not necessarily, just dbdimp.o\n(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\nfrom the $Config{objext} values, and there are many other useful\npieces of configuration information lurking in that hash.  You get\naccess to it with:\n\nuse Config;\n\nMethods which do not need to be written\nThe DBI code implements the majority of the methods which are accessed\nusing the notation \"DBI->function()\", the only exceptions being\n\"DBI->connect()\" and \"DBI->datasources()\" which require support from\nthe driver.\n\nThe DBI code implements the following documented driver, database and\nstatement functions which do not need to be written by the DBD driver\nwriter.\n\n$dbh->do()\nThe default implementation of this function prepares, executes and\ndestroys the statement.  This can be replaced if there is a better\nway to implement this, such as \"EXECUTE IMMEDIATE\" which can\nsometimes 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\ndoes not need to be handled 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()\"\nfunction (C drivers, see below), or the \"$sth->setfbav($data)\"\nmethod (Perl drivers) the driver does not need to do anything about\nthis routine.\n\n$sth->bindcolumns()\nRegardless of whether the driver uses\n\"DBIcDBISTATE(impxxh)->getfbav()\", the driver does not need to\ndo anything about this routine as it simply iteratively calls\n\"$sth->bindcol()\".\n\nThe DBI code implements a default implementation of the following\nfunctions which do not need to be written by the DBD driver writer\nunless the default implementation is incorrect for the Driver.\n\n$dbh->quote()\nThis should only be written if the database does not accept the\nANSI SQL standard for quoting strings, with the string enclosed in\nsingle quotes and any embedded single quotes replaced by two\nconsecutive single quotes.\n\nFor the two argument form of quote, you need to implement the\n\"typeinfo()\" method to provide the information that quote needs.\n\n$dbh->ping()\nThis should be implemented as a simple efficient way to determine\nwhether the connection to the database is still alive. Typically\ncode 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\nas a database system catalogue).\n\n$drh->defaultuser\nThe default implementation of defaultuser will get the database\nusername and password fields from $ENV{DBIUSER} and\n$ENV{DBIPASS}. You can override this method. It is called as\nfollows:\n\n($user, $pass) = $drh->defaultuser($user, $pass, $attr)\n",
                "subsections": []
            },
            "METADATA METHODS": {
                "content": "The exposition above ignores the DBI MetaData methods.  The metadata\nmethods are all associated with a database handle.\n\nUsing DBI::DBD::Metadata\nThe DBI::DBD::Metadata module is a good semi-automatic way for the\ndeveloper of a DBD module to write the \"getinfo()\" and \"typeinfo()\"\nfunctions quickly and accurately.\n\nGenerating the getinfo method\n\nPrior to DBI v1.33, this existed as the method \"writegetinfopm()\" in\nthe DBI::DBD module. From DBI v1.33, it exists as the method\n\"writegetinfopm()\" in the DBI::DBD::Metadata module. This discussion\nassumes 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\nimplements the \"getinfo()\" method. In practice, this means you need to\ninstall DBD::ODBC, an ODBC driver manager, and an ODBC driver for your\ndatabase.\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\nto your Driver.pm file and the code that should be written to\nlib/DBD/Driver/GetInfo.pm.\n\nYou should review the output to ensure that it is sensible.\n\nGenerating the typeinfo method\n\nGiven the idea of the \"writegetinfopm()\" method, it was not hard to\ndevise a parallel method, \"writetypeinfopm()\", which does the\nanalogous job for the DBI \"typeinfoall()\" metadata method. The\n\"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\n\"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\nto your Driver.pm file and the code that should be written to\nlib/DBD/Driver/TypeInfo.pm.\n\nYou should review the output to ensure that it is sensible.\n\nWriting DBD::Driver::db::getinfo\nIf you use the DBI::DBD::Metadata module, then the code you need is\ngenerated for you.\n\nIf you decide not to use the DBI::DBD::Metadata module, you should\nprobably borrow the code from a driver that has done so (eg\nDBD::Informix from version 1.05 onwards) and crib the code from there,\nor look at the code that generates that module and follow that. The\nmethod in Driver.pm will be very simple; the method in\nlib/DBD/Driver/GetInfo.pm is not very much more complex unless your\nDBMS itself is much more complex.\n\nNote that some of the DBI utility methods rely on information from the\n\"getinfo()\" method to perform their operations correctly. See, for\nexample, the \"quoteidentifier()\" and quote methods, discussed below.\n\nWriting DBD::Driver::db::typeinfoall\nIf you use the \"DBI::DBD::Metadata\" module, then the code you need is\ngenerated for you.\n\nIf you decide not to use the \"DBI::DBD::Metadata\" module, you should\nprobably borrow the code from a driver that has done so (eg\n\"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.\nThe method in Driver.pm will be very simple; the method in\nlib/DBD/Driver/TypeInfo.pm is not very much more complex unless your\nDBMS itself is much more complex.\n\nWriting DBD::Driver::db::typeinfo\nThe guidelines on writing this method are still not really clear.  No\nsample implementation is available.\n\nWriting DBD::Driver::db::tableinfo\n*FIX ME* The guidelines on writing this method have not been written yet.\nNo sample implementation is available.\n\nWriting DBD::Driver::db::columninfo\n*FIX ME* The guidelines on writing this method have not been written yet.\nNo sample implementation is available.\n\nWriting DBD::Driver::db::primarykeyinfo\n*FIX ME* The guidelines on writing this method have not been written yet.\nNo sample implementation is available.\n\nWriting DBD::Driver::db::primarykey\n*FIX ME* The guidelines on writing this method have not been written yet.\nNo sample implementation is available.\n\nWriting DBD::Driver::db::foreignkeyinfo\n*FIX ME* The guidelines on writing this method have not been written yet.\nNo sample implementation is available.\n\nWriting DBD::Driver::db::tables\nThis method generates an array of names in a format suitable for being\nembedded in SQL statements in places where a table name is expected.\n\nIf your database hews close enough to the SQL standard or if you have\nimplemented an appropriate \"tableinfo()\" function and and the\nappropriate \"quoteidentifier()\" function, then the DBI default version\nof 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\nWriting DBD::Driver::db::quote\nThis method takes a value and converts it into a string suitable for\nembedding in an SQL statement as a string literal.\n\nIf your DBMS accepts the SQL standard notation for strings (single\nquotes around the string as a whole with any embedded single quotes\ndoubled up), then you do not need to write this method as DBI provides\na default method that does it for you.\n\nIf your DBMS uses an alternative notation or escape mechanism, then you\nneed to provide an equivalent function. For example, suppose your DBMS\nused C notation with double quotes around the string and backslashes\nescaping both double quotes and backslashes themselves. Then you might\nwrite 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\nfor the reader.\n\nThis sample method ignores the $datatype indicator which is the\noptional second argument to the method.\n\nWriting DBD::Driver::db::quoteidentifier\nThis method is called to ensure that the name of the given table (or\nother database object) can be embedded into an SQL statement without\ndanger of misinterpretation. The result string should be usable in the\ntext of an SQL statement as the identifier for a table.\n\nIf your DBMS accepts the SQL standard notation for quoted identifiers\n(which uses double quotes around the identifier as a whole, with any\nembedded double quotes doubled up) and accepts \"schema\".\"identifier\"\n(and \"catalog\".\"schema\".\"identifier\" when a catalog is specified), then\nyou do not need to write this method as DBI provides a default method\nthat does it for you.\n\nIn fact, even if your DBMS does not handle exactly that notation but\nyou have implemented the \"getinfo()\" method and it gives the correct\nresponses, then it will work for you. If your database is fussier, then\nyou need to implement your own version of the function.\n\nFor example, DBD::Informix has to deal with an environment variable\nDELIMIDENT. If it is not set, then the DBMS treats names enclosed in\ndouble quotes as strings rather than names, which is usually a syntax\nerror. Additionally, the catalog portion of the name is separated from\nthe schema and table by a different delimiter (colon instead of dot),\nand the catalog portion is never enclosed in quotes. (Fortunately,\nvalid strings for the catalog will never contain weird characters that\nmight need to be escaped, unless you count dots, dashes, slashes and\nat-signs as weird.) Finally, an Informix database can contain objects\nthat cannot be accessed because they were created by a user with the\nDELIMIDENT environment variable set, but the current user does not have\nit set. By design choice, the \"quoteidentifier()\" method encloses\nthose identifiers in double quotes anyway, which generally triggers a\nsyntax error, and the metadata methods which generate lists of tables\netc 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\nfor the reader.\n\nNote that there is an optional fourth parameter to this function which\nis a reference to a hash of attributes; this sample implementation\nignores that.\n\nThis sample implementation also ignores the single-argument variant of\nthe method.\n",
                "subsections": []
            },
            "TRACING": {
                "content": "Tracing in DBI is controlled with a combination of a trace level and a\nset of flags which together are known as the trace settings. The trace\nsettings are stored in a single integer and divided into levels and\nflags 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\ncall a method the DBI merges the handles settings into its own for the\nduration of the call: the trace flags of the handle are OR'd into the\ntrace 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\nsettings are restored when the called method returns.\n\nTrace Level\nThe trace level is the first 4 bits of the trace settings (masked by\n\"DBIcTRACEFLAGSMASK\") and represents trace levels of 1 to 15. Do not\noutput anything at trace levels less than 3 as they are reserved for\nDBI.\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\nthis:\n\nif (DBIcTRACELEVEL(impxxh) >= 2) {\nPerlIOprintf(DBIcLOGPIO(impxxh), \"foobar\");\n}\n\nAlso note the use of PerlIOprintf which you should always use for\ntracing and never the C \"stdio.h\" I/O functions.\n\nTrace Flags\nTrace flags are used to enable tracing of specific activities within\nthe DBI and drivers. The DBI defines some trace flags and drivers can\ndefine others. DBI trace flag names begin with a capital letter and\ndriver 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\nto set them by name. Drivers are expected to override the\nparsetraceflag (note the singular) and check if $traceflagname is a\ndriver specific trace flags and, if not, then call the DBIs default\nparsetraceflag(). To do that you'll need to define a\nparsetraceflag() method like this:\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\nin the top 8 of the 32 bits of \"DBIcTRACEFLAGS(imp)\" i.e.,\n0xFF000000.\n\nIf you've defined a parsetraceflag() method in ::db you'll also want\nit in ::st, so just alias it in:\n\n*parsetraceflag = \\&DBD::foo:db::parsetraceflag;\n\nYou may want to act on the current 'SQL' trace flag that DBI defines to\noutput SQL prepared/executed as DBI currently does not do SQL tracing.\n\nTrace Macros\nAccess 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\nwith DBD::Ingres) and the corresponding dbdimp.c files for ideas.\n\nNote that the emulation code sets \"$dbh->{CompatMode} = 1;\" for each\nconnection so that the internals of the driver can implement behaviour\ncompatible with the old interface when dealing with those handles.\n\nSetting emulation perl variables\nFor example, ingperl has a $sqlrowcount variable. Rather than try to\nmanually update this in Ingperl.pm it can be done faster in C code.  In\n\"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",
                "subsections": []
            },
            "OTHER MISCELLANEOUS INFORMATION": {
                "content": "The impxyzt types\nAny handle has a corresponding C structure filled with private data.\nSome of this data is reserved for use by DBI (except for using the DBIc\nmacros below), some is for you. See the description of the dbdimp.h\nfile above for examples. Most functions in dbdimp.c are passed both the\nhandle \"xyz\" and a pointer to \"impxyz\". In rare cases, however, you\nmay use the following macros:\n\nDimpdbh(dbh)\nGiven a function argument dbh, declare a variable impdbh and\ninitialize it with a pointer to the handles private data. Note:\nThis must be a part of the function header, because it declares a\nvariable.\n\nDimpsth(sth)\nLikewise for statement handles.\n\nDimpxxx(h)\nGiven any handle, declare a variable impxxx and initialize it with\na pointer to the handles private data. It is safe, for example, to\ncast impxxx to \"impdbht*\", if \"DBIcTYPE(impxxx) == DBItDB\".\n(You can also call \"svderivedfrom(h, \"DBI::db\")\", but that's much\nslower.)\n\nDimpdbhfromsth\nGiven a impsth, declare a variable impdbh and initialize it with\na pointer to the parent database handle's implementors structure.\n\nUsing DBIcIMPSETon\nThe driver code which initializes a handle should use\n\"DBIcIMPSETon()\" as soon as its state is such that the cleanup code\nmust 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\nin the driver, and within each handle, a linked list of statements.\nOnce a statement is added to the linked list, it is crucial that it is\ncleaned up (removed from the list). When DBIcIMPSETon() was being\ncalled too 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\nboolean flags/attributes was 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,\nRaiseError and PrintError, and these do not have the full set of\nmacros. The approved method for handling these is now the four 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\ndeprecated and new drivers should avoid using them, even though the\nolder drivers will probably continue to do so for quite a while yet.\nHowever...\n\nThere is an important exception to that. The ACTIVE and IMPSET flags\nshould be set via the \"DBIcACTIVEon()\" and \"DBIcIMPSETon()\" macros,\nand unset via the \"DBIcACTIVEoff()\" and \"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\nspecification do not have to be implemented by the driver writer\nbecause DBI takes care of the details for you.\n\nHowever, the key to ensuring that bound columns work is to call the\nfunction \"DBIcDBISTATE(impxxh)->getfbav()\" in the code which fetches\na row of data.\n\nThis returns an \"AV\", and each element of the \"AV\" contains the \"SV\"\nwhich should be set to contain the returned data.\n\nThe pure Perl equivalent is the \"$sth->setfbav($data)\" method, as\ndescribed in the part on pure Perl drivers.\n\nCasting strings to Perl types based on a SQL type\nDBI from 1.611 (and DBIXSREVISION 13606) defines the\nsqltypecastsvpv method which may be used to cast a string\nrepresentation of a value to a more specific Perl type based on a SQL\ntype. You should consider using this method when processing bound\ncolumn data as it provides some support for the TYPE bindcol attribute\nwhich 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\nSQL types (e.g., \"SQLINTEGER\") and \"flags\" is a bitmask as follows:\n\nDBIstcfSTRICT\nIf set this indicates you want an error state returned if the cast\ncannot be performed.\n\nDBIstcfDISCARDSTRING\nIf set and the pv portion of the \"sv\" is cast then this will cause\nsv'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\n\"SQLINTEGER\", \"SQLDOUBLE\" and \"SQLNUMERIC\". \"SQLINTEGER\" uses\nsv2iv 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\nUV or NV.\n\nDBIstcfSTRICT should be implemented as the StrictlyTyped attribute and\nDBIstcfDISCARDSTRING implemented as the DiscardString attribute to\nthe bindcol method and both default to off.\n\nSee DBD::Oracle for an example of how this is used.\n",
                "subsections": []
            },
            "SUBCLASSING DBI DRIVERS": {
                "content": "This is definitely an open subject. It can be done, as demonstrated by\nthe DBD::File driver, but it is not as simple as one might think.\n\n(Note that this topic is different from subclassing the DBI. For an\nexample of that, see the t/subclass.t file supplied with the DBI.)\n\nThe main problem is that the dbh's and sth's that your \"connect()\" and\n\"prepare()\" methods return are not instances of your DBD::Driver::db or\nDBD::Driver::st packages, they are not even derived from it.  Instead\nthey 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.\nOf course you can instead to a\n\n$dbh->func('mymethod')\n\nand that will indeed work, even if \"mymethod()\" is inherited, but not\nwithout additional work. Setting @ISA is not sufficient.\n\nOverwriting methods\nThe first problem is, that the \"connect()\" method has no idea of\nsubclasses. For example, you cannot implement base class and subclass\nin the same file: The \"installdriver()\" method wants to do a\n\nrequire DBD::Driver;\n\nIn particular, your subclass has to be a separate driver, from the view\nof DBI, and you cannot share driver handles.\n\nOf course that's not much of a problem. You should even be able to\ninherit the base classes \"connect()\" method. But you cannot simply\noverwrite the method, unless you do something like this, quoted from\nDBD::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\ninstance of DBI::dr. And note, that the \"connect()\" method of DBD::File\nis able to handle subclass attributes. See the description of Pure Perl\ndrivers above.\n\nIt is essential that you always call superclass method in the above\nmanner. However, that should do.\n\nAttribute handling\nFortunately the DBI specifications allow a simple, but still performant\nway of handling attributes. The idea is based on the convention that\nany driver uses a prefix driver for its private methods. Thus it's\nalways clear whether to pass attributes to the super class or not. For\nexample, 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",
                "subsections": []
            },
            "AUTHORS": {
                "content": "Jonathan Leffler <jleffler@us.ibm.com> (previously\n<jleffler@informix.com>), Jochen Wiedmann <joe@ispsoft.de>, Steffen\nGoeldner <sgoeldner@cpan.org>, and Tim Bunce <dbi-users@perl.org>.\n\nperl v5.34.0                      2026-06-22                     DBI::DBD(3pm)",
                "subsections": []
            }
        }
    }
}