27/07/2001 copyright 2001, munica corporation, 1 how to write a dbd driver daini xie strathy...
TRANSCRIPT
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
1
How to write a DBD driverHow to write a DBD driver
Daini Xie Strathy
PresidentMunica [email protected] for the
O’Reilly Open Source Convention 2001San Diego, CA, USA
AMDG
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
2
Introduction Introduction
You will learn the elements of a DBD driver and the process of developing one
Audience: DBMS developers and Perl developers
Prerequisite: Proficiency in Perl, C and SQL
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
3
AgendaAgenda
Introducing DBI 5 min
Dissecting DBD 10 min
Writing a DBD Driver 25 min
Questions 5 min
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
4
Overview Overview
Introducing DBI: Introduces DBI and prepares you for DBD driver development
Dissecting DBD: Explains DBD driver deliverables, objects and interfaces
Writing a DBD Driver: Details the driver development process
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
5
AcronymsAcronyms
Perl Practical Extraction and Report Language
DBI Perl Database Interface DBD Perl Database Driver SQL Structured Query Language XS Perl eXternal Subroutine API Application Programming
Interface POD Plain Old Documentation, a Perl
documentation format
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
6
What is DBI?What is DBI?
DBI is the Perl Database Interface module written by Tim Bunce
DBI provides Perl developers a standard interface for accessing databases
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
7
Life without DBILife without DBI
Postgres API
NetSQL API
OracleAPI
Postgresengine
NetSQLengine
Oracleengine
PerlScripts
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
8
Life with DBILife with DBI
PerlScripts
DBI
DBD::Pg
DBD::NetSQL
DBD::Oracle
Postgresengine
NetSQLengine
Oracleengine
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
9
What is a DBD Driver?What is a DBD Driver?
DBD stands for Database Driver
A DBD driver implements the methods defined in the DBI specification with DBMS specific API
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
10
DBI Sample CodeDBI Sample Code1: use DBI; # Load DBI module2: 3: my $dbh = DBI->connect('DBI:Pg:dbname=payroll‘, ‘’, ‘’) 4: or die "Couldn't connect to database: " . DBI->errstr; 5:6: my $sth = $dbh->prepare(‘SELECT * FROM people’) 7: or die “Couldn’t prepare statement: " . $dbh->errstr; 8:9: $sth->execute() or die "Couldn't execute statement: " . $sth->errstr;10:11: while ( @data = $sth->fetchrow_array ) { # fetch the selected row12: print “@data\n”;13: }14:15: $sth->finish;16: $dbh->disconnect;
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
11
Script/DBI/DBD InteractionScript/DBI/DBD Interaction
DBDDriver
DBIPerl
Scripts
DBI->connect
$dbh->prepare
$sth->execute
$sth->fetchrow_array
$sth->finish
$dbh->disconnect
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
12
Writing a DBD DriverWriting a DBD Driver
Before you start
Conventions and deliverables
Driver development to-do list
DBD driver objects and interface
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
13
Before you startBefore you start
Download and install the latest Perl, the DBI module and Unix utilities such as tar and gzip on your host computer.
Decide what kind of DBD driver you’d like to write:– Pure Perl DBD driver– C/XS DBD driver if you require C
libraries
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
14
DBD Driver PackageDBD Driver Package
The set of files that comprises a DBD driver distribution package
Perl Driver C/XS Driver
Driver.pmMakefile.PLREADMEMANIFEST
Driver.pm Makefile.PLDriver.xs Driver.hdbdimp.h dbdimp.cREADME MANIFEST
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
15
DBD Driver FilesDBD Driver Files
Driver.pm and Driver.so are the DBD driver files.
Pure Perl Driver C/XS Driver
Driver.pm Driver.pm
Driver.so or Driver.dll
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
16
DBD Directory StructureDBD Directory StructurePerl Lib
DBD
Driver.pm
auto
DBD
Driver.so
/usr/lib/perl5/site_perl/5.6.0/i386-linux
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
17
Driver Development To-do ListDriver Development To-do List
1. Prepare Makefile.PL2a. Write Driver.pm for a Perl DBD driver or2b. Write a C/XS DBD driver
2b.1 Write Driver.pm
2b.2 Write Driver.so or its Win32 equivalent Driver.dll2b.1.1 Write dbdimp.c and dbdimp.h
2b.1.2 Write Driver.xs and Driver.h
3. Finishing touch: README and MANIFEST4. Building a distribution package
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
18
Makefile.PLMakefile.PL
Makefile.PL is a Perl script that generates Makefile for a DBD driver.
• Checks the prerequisites of the host environment• Checks package integrity• Preprocesses, compiles, links and installs files
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
19
Makefile.PL SamplesMakefile.PL Samples
Pure Perl Driver C/XS Driver
DBD::CSV DBD::Pg orDBD::Oracle
Both drivers are available at http://www.cpan.org
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
20
Dissecting a DBD DriverDissecting a DBD Driver
package DBD::Driver;
package DBD::Driver:dr;
package DBD::Driver::db;
package DBD::Driver::st;
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
21
DBD::DriverDBD::DriverDBD::Driver is the class for DBD driver. It holds driver specific data and is responsible for the initialization of the DBD driver.
Private Data Members: $VERSION, $err, $errstr, $drh
Method: driver
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
22
DBD::Driver::drDBD::Driver::dr
DBD::Driver::dr is the class for DBD driver handle objects. It holds driver specific data and is responsible for connecting to a given DBMS engine.
Private Data Member: imp_data_size
Method: connect, disconnect_all,DESTROY
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
23
DBD::Driver::dbDBD::Driver::db
DBD::Driver::db is the class for database handle objects. It holds database specific data and controls the connection and transactions made with a given database.
Private Data Member: imp_data_size
Methods: prepare, _login, ping, FETCH, STORE, table_info, tables, table_attributes, commit, rollback, type_info_all, disconnect, DESTROY
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
24
DBD::Driver::stDBD::Driver::st
DBD::Driver::st is the class for statement handle objects. It holds SQL statement specific data and is responsible for parsing, executing and data retrieval of a given SQL statement
Private Data Member: imp_data_size
Methods: _prepare, FETCH, STORE, bind_param, execute, fetchrow_arrayref, rows, finish, DESTROY
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
25
Storing and Retrieving AttributesStoring and Retrieving Attributes
DBI attributes: Name, Statement, … Driver specific attributes
$sth->STORE(‘Statement’, $sqlstr);$sth->FETCH(‘Statement’);
Pure Perl Driver: $sth->{‘Statement’} = $sqlstr;C/XS Driver: stored in imp_xxh_t data structures
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
26
DBI/DBD Naming ConventionsDBI/DBD Naming ConventionsConvention Pertains toUPPER_CASE Standards, e.g. X/Open, ISO
SQL 92, etc. (portable)MixedCase DBI API (portable),
underscores are not usedlower_case Driver or database specific
(non-portable)_lower_case Internal DBD methods
Private attribute names are prefixed with the driver name or suitable abbreviation (e.g. ora_ for Oracle)
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
27
Writing a Pure Perl DriverWriting a Pure Perl Driver
Set imp_data_size of DBD::Driver::dr, DBD::Driver::db and DBD::Driver::st to zero.
Implement the required methods in DBD::Driver, DBD::Driver::dr, DBD::Driver::db and DBD::Driver::st packages. (See slides #21 - #24)
In Driver.pm:
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
28
Example: DBD::Driver::drExample: DBD::Driver::dr
1: package DBD::Driver::dr; # ==DRIVER===2: use strict;3: 4: $DBD::Driver::dr::imp_data_size = 0;5:6: sub connect ($$;$$$) {7: # insert code to create a $dbh handle8: }
In Driver.pm
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
29
C/XS Driver DevelopmentC/XS Driver DevelopmentDriver.xs
Driver.cxsubpp
dbdimp.c
driver.lib
Driver.so
Driver.pm
otherc.libFiles you implement
Files generated by Makefile
C libraries used by the driver
dbdimp.h
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
30
Writing a C/XS DriverWriting a C/XS Driver
DBD::Driver is usually implemented in Perl
Part or all of DBD::Driver::dr, DBD::Driver::db and DBD::Driver::st are implemented as Perl external subroutines (XS) and C code
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
31
Example: DBD::Pg::stExample: DBD::Pg::st
{ package DBD::Pg::st; # ===statement## all implemented in XS
}
When a Perl method is implemented in Driver.xs and dbdimp.c, it is absent from Driver.pm
In Driver.pm
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
32
Implementing Perl methods Implementing Perl methods with C/XSwith C/XSStep 1: Define private data structures for
DBD::Driver::dr, DBD::Driver::db and DBD::Driver::st
Step 2: Implement the required DBD methods in C and place them in dbdimp.c
Step 3: Provide an XS Perl wrapper for each method and place it in Driver.xs
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
33
Defining Private Data StructuresDefining Private Data Structures
1: struct imp_drh_t {2: dbih_drc_t com;3: /* insert your driver handle attributes here*/4: };5: struct imp_dbh_t {6: dbih_dbc_t com;7: /* insert your database handle attributes here*/8: };9: struct imp_sth_t {10: dbih_stc_t com;11: /* insert your statement handle attributes here*/12: };
In dbdimp.h
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
34
Example: DBD::Driver::st Example: DBD::Driver::st
1: int dbd_st_execute(SV * sth, 2: imp_sth_t * imp_sth)3: {4: /* insert your code here*/5: }
In dbdimp.c:
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
35
Example: DBD::Driver::stExample: DBD::Driver::st
1: MODULE = DBD::Driver PACKAGE = DBD::Driver::st2:3: void execute (sth, …)4: SV * sth;5: CODE: /*C code fragment*/6: D_imp_sth(sth); /*extract imp_sth_t*/7:8: ret = dbd_st_execute(sth, imp_sth);9:10: if (ret == 0) { XST_mPV(0, “0E0”);}11: else if (ret < -1) { XST_mUNDEF(0);}12: else { XST_mIV(0, ret);}
In Driver.xs
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
36
Passing data between C and Passing data between C and PerlPerl
How to pass Perl arguments to C functions
How to return data from C functions to Perl
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
37
Passing arguments between C Passing arguments between C and Perl in Driver.xsand Perl in Driver.xs
XSPerl$sth->execute($v1, $v2); void execute (sth, …)
SV * sth; CODE: /*C fragment*/
SV *v1, *v2; v1 = ST(1); v2 = ST(2);
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
38
Return data from C to Perl in Return data from C to Perl in Driver.xsDriver.xs$sth->fetchrow_arrayref();
1: void fetchrow_arrayref(sth)2: SV * sth;3: CODE:4: D_imp_sth(sth); /*get imp_data_t */5: AV *av = dbd_st_fetch(sth, imp_sth); /*get row array*/6: /* set the return value to array reference */7: ST(0) = (av) ? 8: sv_2mortal(newRV_inc((SV *)av)) :&sv_undef;
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
39
Return an array from C to PerlReturn an array from C to Perl$sth->fetchrow_array();
1: void fetchrow_arrayref(sth)2: SV * sth;3: PPCODE: /*because we need to extend
stack*/4: D_imp_sth(sth); /*get imp_data_t*/5: AV *av = dbd_st_fetch(sth, imp_sth); /*get row array*/6: int I, num_fields;7: if (av) { /*push an SV to the argument stack*/8: num_fields = AvFill(av) + 1;9: EXTEND(sp, num_fields);10: for (I = 0; I< num_fields; ++i) {11: PUSHs(AvARRAY(av)[I]);12: }13: }
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
40
Elements in Driver.xsElements in Driver.xsSlide 1Slide 1
1: DBISTATE_DECLARE;2: MODULE=DBD::Driver PACKAGE=DBD::Driver3: PROTOTYPES: DISABLE # disable Perl prototype4: BOOT: # initialization5: DBISTATE_INIT; # initialize DBI 6:7: DBI_IMP_SIZE(“DBD::Driver::dr::imp_data_size”,8: sizeof(imp_drh_t));9: DBI_IMP_SIZE(“DBD::Driver::dr::imp_data_size”,10: sizeof(imp_drh_t));11: DBI_IMP_SIZE(“DBD::Driver::dr::imp_data_size”,12: sizeof(imp_drh_t));13:14: dbd_init(DBIS); /*Initialize DBI state*/
… next slide
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
41
Elements in Driver.xsElements in Driver.xsSlide 2Slide 2
15: MODULE = DBD::Driver PACKAGE = DBD::Driver::dr16: # XS Perl wrappers for C methods, see slides #33 - #3817: 18: MODULE = DBD::Driver PACKAGE = DBD::Driver::db19: # XS Perl wrappers for C methods, see slides #33 - #3820:21: MODULE = DBD::Driver PACKAGE = DBD::Driver::st22: # XS Perl wrappers for C methods, see slides #33 - #38
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
42
Finishing TouchFinishing Touch
Document installation related information in the README file
Document your DBD driver in POD format and append it at the end of Driver.pm
List every file that comprises your driver distribution package, one per line, in the MANIFEST file
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
43
Building a distribution packageBuilding a distribution package
Place all the files that comprise your driver distribution package in a directory, say /mydriver
Change directory to /mydriver
Use the following command to create an archive:
make dist (for Unix) nmake dist (for Win32 with VC++)
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
44
Building and InstallingBuilding and Installing
Unpack the downloaded DBD driver with the following command: tar –zxvf DBD-Driver-1.0.tar.gz
Build and install the driver with the following commands:
UNIX Windows with VC++perl Makefile.PLmakemake install
perl Makefile.PLnmakenmake install
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
45
SummarySummary
You just learned:– the elements in a DBD driver– the process of developing one– using XS to develop Perl external
subroutines for your DBD driver
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
46
Where to Get More InformationWhere to Get More Information
Books (from O’Reilly Associates)
Programming Perl
Advanced Perl Programmingfor information about object oriented Perl programming and C/XS development
Perl DBI
for information about DBI programming
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
47
Where to Get More InformationWhere to Get More Information
Web sites: http://supportweb.cs.bham.ac.uk
/documentation/perl-modules/Informix/DBD.html for DBD Driver Writer’s Guide
http://www.munica.com/dbd/dbdtmpl.html for DBD driver development templates
http://www.symbolstone.org/technology/perl/DBI for DBI documentation
http://lists.perl.org for DBI mailing list
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
48
Where to Get More InformationWhere to Get More Information
http://www.perl.com/pub/doc/manual/html/pod/perlguts.html for information about Perl internal functions and how to exchange data between Perl and C.
http://www.perl.com/pub/doc/manual/html/pod/perlxs.html for Perl XS reference manual
http://www.perl.org for Perl http://www.activestate.com for Win32 Perl http://www.cpan.org for DBI and DBD modules http://www.weihenstephan.de/~syring/win32/UnxUtils
.html for Win32 Unix utilities such as tar, bison and gzip etc.
27/07/2001Copyright 2001, Munica Corporation, www.munica.com
49
Thank You for AttendingThank You for Attending