
## $Id: README.dev,v 1.27 2006/05/05 15:52:09 turnstep Exp $

This file is for those interested in developing DBD::Pg. It is hoped that it 
will be a good introduction as well as a continual reference. Suggestions 
are always welcome.

Note: most of this document assumes you are using a Unix-like system.

Sections:

* Overview
* File List
* Compiling
* Editing
* Heavy Testing
* Debugging
* Test Files
* Version Numbers
* New Files
* New Methods
* Making a New Release
* Tips and Tricks
* Resources


==============
== Overview ==
==============

How It All Works

DBD::Pg is a combination of Perl, C, and XS, using files from the dbdpg project, 
the DBI module, and libpq - the C library interface to the PostgreSQL server. 
There is a sometimes complex interweaving of files needed for each method.

Running "perl Makefile.PL" uses the ExtUtils::MakeMaker module to create a 
true Makefile. Then the "make" command compiles everything, after creating 
the Pg.c file from Pg.xs and DBI's Perl.xsi. The files Pg.pm and 
blib/arch/auto/DBD/Pg/Pg.so form the core of the module once installed.
(The above is oversimplified).


===============
== File List ==
===============

Here is what each file in the distribution does:

* Text files:

Changes - lists changes made to each version. Please be consistent and use 
  tabs, not spaces, to indent. Try to list who found the bug, and who 
  fixed it (if not the same person). Put the CPAN bug # in parenthesis, 
  and put the person who made the actual changes in brackets. This file 
  contains a version number.

README.dev - you are reading it.

README - the main file that explains the module, where to get it, and guides 
  people in installing it. A large portion of it is simply a list of common 
  gotchas and guides for various platforms. This is one of four files that lists 
  the version number.

README.win32 - the directions on how to install DBD::Pg on a Win32 box.

TODO - Rough list of upcoming tasks.


* Build files:

Makefile.PL - The main file that starts everything off. Used by ExtUtils::MakeMaker 
  to create the "Makefile"

Makefile - Generated automatically by Makefile.PL

META.yml - YAML description file.

* Distribution files:

MANIFEST - lists which files should be included in the release tarball. 
  Used by the "make dist*" set of commands.

MANIFEST.SKIP - files that are known to be safe to exclude from the release 
  tarball. Used by the "make distcheck" command

win32.mak - a helper file for the win32 build.


* Program files:

dbdimp.c - The main C file, which does most of the heavy lifting for the DBD::Pg 
  module (the rest is done by Pg.pm). Almost all of the complexity and power of 
  the module is here.

dbdimp.h - Helper file for dbdimp.c.

Pg.pm - The main perl file, which contains all the DBD::Pg packages and code 
  for the methods. Often times code here calls code from Pg.xs and dbdimp.c.
  This file contains a version number in two places (once in the code, once 
  in the POD). The main documentation for the module lives here, as POD information.

Pg.xs - The Perl "glue" file for DBD::Pg. This file basically tells Perl how 
  to handle various methods. It makes many calls to dbdimp.c

Pg.c - Not part of the distribution, but created from Pg.xs as part of the 
  build process. Never edit this directly.

Pg.h - Helper file for Pg.xs (or Pg.c)

quote.c - Various methods to help quote and dequote variables. Much of this is 
  now done on the backend, but it is still needed to support older versions 
  of PostgreSQL.

quote.h - Helper file for quote.c

types.c - Lists all known data types for PostgreSQL.
  Run as a perl script to check for new types.

types.h - Helper file for types.c

* Test files:

t/00basic.t - Very basic test to see if DBI and DBD::Pg load properly.

t/01connect.t - Basic connection tests, outputs detailed connection information.

t/01constants.t - Quick test of pg_types.

t/01setup.t - Create the database items needed by the other tests.

t/02attribs.t - Tests all attributes.

t/03dbmethod.t - Tests all database handle methods.

t/03smethod.t - Tests all statement handle methods.

t/04misc.t - Currently only tests the "data_sources" method.

t/05arrays.t - Currently skipped until arrays are enabled.

t/06bytea.t - Tests bytea manipulation.

t/07copy.t - Tests COPY-related methods.

t/12placeholders.t - Tests placeholders.

t/20savepoints.t - Test savepoints. Requires a server version 8.0 or up.

t/99_pod.t - Verifies the POD of Pg.pm. Requires Test::POD version 0.95, and 
  Test::Pod::Coverage 1.04. Neither are mandatory for normal testing, but 
  developers are highly encouraged to install them.

t/99cleanup.t - Removes anything we have created for the tests (e.g. tables)


* Helper files

The module App::Info is inside the t/lib directory (we put it there to prevent CPAN 
from indexing it). It is used by Makefile.PL to determine the version of PostgreSQL 
we are compiling against (by calling pg_config). It consists of:
t/lib/App/Info.pm
t/lib/App/Info/Handler.pm
t/lib/App/Info/Handler/Prompt.pm
t/lib/App/Info/RDBMS.pm
t/lib/App/Info/RDBMS/PostgreSQL.pm
t/lib/App/Info/Request.pm
t/lib/App/Info/Util.pm


===============
== Compiling ==
===============

Compiling is generally done with gcc. However, we also need to support a wide variety 
of compilers. Things which may only cause a minor warning when using gcc may stop 
other compilers cold. One way to catch this early is to add some warning flags to gcc. 
This can be done by extending the $comp_opts string inside of the Makefile.PL file. 
There are many warnings that can be enabled (see the man page for gcc for the list). 
Some of these warnings trigger for things outside of our control, such as the code 
for DBI or Perl itself. You can define the environment variable DBDPG_GCCDEBUG to turn 
many of these options on automatically.

Within each section, the order is the same as found in man gcc.

## These are warnings that should only generate errors that we can fix:
$comp_opts .= " -Wchar-subscripts -Wcomment";
$comp_opts .= " -Wformat=2"; ## does -Wformat,-Wformat-y2k,-Wformat-nonliteral,-Wformat-security
$comp_opts .= " -Wnonnull";
$comp_opts .= " -Wuninitialized -Winit-self"; ## latter requires the former
$comp_opts .= " -Wimplicit"; ## does -Wimplicit-int and -Wimplicit-function-declaration
$comp_opts .= " -Wmain -Wmissing-braces -Wparentheses -Wsequence-point -Wreturn-type -Wswitch -Wswitch-enum -Wtrigraphs";
$comp_opts .= " -Wunused"; ## contains -Wunused- function,label,parameter,variable,value
$comp_opts .= " -Wunknown-pragmas -Wstrict-aliasing";
$comp_opts .= " -Wall"; ## all of above, but we enumerate anyway
$comp_opts .= " -Wextra -Wdeclaration-after-statement -Wendif-labels -Wpointer-arith";
$comp_opts .= " -Wbad-function-cast -Wcast-qual -Wcast-align -Wconversion -Wsign-compare -Waggregate-return";
$comp_opts .= " -Wmissing-prototypes -Wmissing-declarations -Wmissing-format-attribute -Wpacked -Winline -Winvalid-pch";
$comp_opts .= " -Wdisabled-optimization"; ## Not terribly useful
$comp_opts .= " -Wnested-externs"; ## Does not like Perl__notused (from DBIXS;)

## These options produce a few hits, but are still pretty useful:
$comp_opts .= " -Wswitch-default"; ## Complains on any Newz declaration
$comp_opts .= " -Wfloat-equal"; ## Some perl stuff we cannot catch from Pg.h -> DBIXS.h -> perl.h -> math.h -> bits/mathinline.h
$comp_opts .= " -Wstrict-prototypes"; ## Still hits a couple places in types.h that need fixing (then move to above)
$comp_opts .= " -Wmissing-noreturn"; ## Raises a few warnings for <=7.4 libraries, as we croak on purpose for some

## These options tend to produce lots of hits outside of our code, but may still be useful:
$comp_opts .= " -Wsystem-headers"; ## when used with -Wconversion, creates a lot of hits 
$comp_opts .= " -pedantic"; ## Useful, but very verbose
$comp_opts .= " -Wundef"; ## Filter: grep warning wfile | grep -v unions | grep -v CORE | grep -v Pg.c | grep -v auto
$comp_opts .= " -Wshadow"; ## lots of bogus hits - not very useful Filter: grep warning wfile | grep -v "/usr"
$comp_opts .= " -Wwrite-strings";
$comp_opts .= " -Wpadded"; ## Use when adding/changing our structs
$comp_opts .= " -Wredundant-decls";

## These options are probably not very useful:
$comp_opts .= " -Wtraditional"; ## Lots and lots of junk
$comp_opts .= " -Wold-style-definition"; ## We use lots of these
$comp_opts .= " -Wunreachable-code"; ## Lots due to our multi-version ifdefs

Please feel free to add to and clarify the above lists.


=============
== Editing ==
=============

All the perl files should have a cperl pragma at the top of the file, for easy use in emacs. 
Please use tabs and not spaces everywhere, and keep the indenting to the cperl standard.
Use the traditional C mode for *.c files. Pg.xs is a special case: if you know of a good 
mode for editing this file, please let us know and update this paragraph!

Please follow the other syntax standards in place as much as possible. A few guidelines 
for xs files can be found in the xs perldocs.


===================
== Heavy Testing ==
===================

Testing should be done heavily and frequently, especially before a new release. 
The standard way to test is run "make test" which runs all the scripts in the 
"t" directory. If you find yourself making your own test, even if just for a 
minor or a temporary problem, please add it to the test suite. The more tests 
we have, the better.

Generally, we want to run make test on as wide a variety of configurations as 
possible. If you have different platforms of course, you should test all of those. 
Beyond that, you may find it helpful to set up some aliases to allow quick switching 
of versions. You should generally test each minor version of PostgreSQL that DBD::Pg 
currently supports. Keep in mind that there are two things to test for each version: 
the server that we are compiling against (e.g. which libraries we are linking to) 
and the version we are connecting to. You should test all variations.

One way is to keep multiple versions of PostgreSQL in standard directories, and use 
a standard port convention to keep things simple: the port is 5XXX where XXX is the 
version, so that PG 7.4.2 is listening on port 5742. Then set up two aliases for each 
version, like so:

alias dbd727='export DBI_DSN="dbi:Pg:dbname=greg;port=5727"'
alias dbd727m='export POSTGRES_LIB=/home/greg/pg727/lib POSTGRES_INCLUDE=/home/greg/pg727/include POSTGRES_DATA=/home/greg/pg727'

This allows for quick testing of each combination:

> dbd727m
> dbd727
> perl Makefile.PL
> make test (check output for any errors)
> dbd739
> make test
> dbd747
> make test
> dbd747
> make test
> dbd802
> make test
> dbd739m
> perl Makefile.PL
> make test
> dbd727
> make test
> dbd747
> make test
> dbd802
> make test

etc...

It's also a good idea to test the current cvs version of pg in your tests: this can detect 
changes nice and early.

In addition to different versions of Postgres, it's a good idea to test a few versions of 
DBI: this has caught problems in the past. You'll basically need to install the different 
versions of DBI into different directories, then adjust PERL5LIB with aliases:

alias dbi138='export PERL5LIB=/home/greg/perl/dbi138/lib/perl5/site_perl/5.8.7/i686-linux'
alias dbi139='export PERL5LIB=/home/greg/perl/dbi139/lib/perl5/site_perl/5.8.7/i686-linux'


* Using splint

Another great program to use is splint, which is a "tool for statically checking C programs for 
security vulnerabilities and common programming mistakes." It can be found at

http://www.splint.org/

It is typically run against a single C file, in our case, dbdimp.c and the generated Pg.c file. 
It will not work out of the box, as our dependencies tend to be scattered about. Here is a minimal 
file that should work:

splint \
+unixlib \
+single-include \
-I$DBIDIR \
-I$POSTGRES_INCLUDE \
-I$PERLDIR \
-I/source/bin/DBI-1.48 \
-I/source/pg801/include \
-I/usr/lib/perl5/5.8.5/i686-linux-ld/CORE \
Pg.c

You will need to define the environment variables and put the correct path to the DBI, 
Postgres, and Perl directories (the Perl one should end in "CORE"). Splint can be 
tempermental, so you may need to add more than that, and tweak a few things. It may 
take a few runs to get it to go without errors. Once you do get it running, it is very 
thorough and extremely verbose. Many of the items will be from DBI, so hunt carefully. 
You can start filtering out items you do not need to check. Here are a few common ones:

-nullpass \
-predboolint \
+charint \
+charintliteral \
-nullderef \
-branchstate \
-mustfreeonly \
-mustfreefresh \
-boolops \
-type \
-observertrans \
-globstate \
-nullstate \
-compdef \
-onlytrans \
-realcompare \
-nullret \
-bufferoverflowhigh \

Note that most, if not all, of the above, *should* be checked on the first pass, and then 
gradually added to make the output easier to read.


* Using Devel::Cover

Another handy tool is the module Devel::Cover. While not totally useful as it only tests 
direct perl modules, it is good at giving Pg.pm the once-over. To use, install it, then run:

cover -delete
HARNESS_PERL_SWITCHES=-Mdevel::Cover make test

The tests will take much longer than usual. When done, run a simple

cover

then check out the coverage.html file inside the cover_db directory.



===============
== Debugging ==
===============

In addition to the Heavy Testing section, there are some simple aids to debugging.

* Testing file

It is helpful to have a standard file (e.g. ping.test.tmp) which contains some connection 
information and allows to easily stick in a piece of code for testing. It should run 
"make" to make sure everything is up to date. Here's the top of one such file:

#!perl -w

BEGIN {
	my $out = `make 2>&1`;
	if ($out =~ /^\w+\.[cx]s?:\d+:/ms or $out =~ /^Error/ms) {
		for (split /\n/ => $out) {
			print "MAKE ERROR: $_\n" if /^[\w\.]+:/;
		}
		exit;
	}

	use lib ".", "blib/lib", "blib/arch";
}
END {	print "End ping.test\n"; } BEGIN {	print "Begin ping.test\n"; }

use strict; use warnings; use Data::Dumper; $Data::Dumper::Deepcopy=1; use DBD::Pg; use DBI qw(:sql_types);
$|=1; select((select(STDERR),$|=1)[0]);
use vars qw($dbh $SQL $sql $sth $count $version $info $result $id $val);
my $trace = shift || 0;
my $dv = $DBI::VERSION; print "DBI version: $dv\n";
my $pv = $DBD::Pg::VERSION; print "DBD::Pg version: $pv\n";
my $DSN = $ENV{DBI_DSN};
$dbh = DBI->connect($DSN, $ENV{DBI_USER}, '', {AutoCommit=>0, RaiseError=>1, PrintError=>1});
my $VER = $dbh->{pg_server_version}; my $pgver = $dbh->{pg_lib_version};
print "Connected to $DSN\nServer version: $VER\nCompiled version: $pgver\n";
$dbh->trace($trace);

__END__

Once you have completed a test, just put it below the __END__ line in case you ever need to 
use it again someday. Note that the first argument to this script is the trace level. 
Bumping the trace level to 10 can be very helpful. If it is not helpful, consider adding 
some debugging statements to dbdimp.c to make it so!

* Coredumps

If you get a coredump, you can use the "gdb" utility to see what happened. Here's a 10-second 
tutorial. If "core" is the name of the core file, just use "gdb perl core", then issue a 
"bt" command at the gdb prompt. This will run a backtrace and give you an idea of what is 
causing the problem.

* For really low-level debugging, you can use pg_server_trace() function.

* The perl debugger can also be helpful (perl -d ping.test.tmp).

* Don't forget about the PostgreSQL server logs either, when investigating matters.


================
== Test Files ==
================

The test files are an important part of the module. Much work has gone into making 
the tests as complete, thorough, and clean as possible. Please try to follow these 
guidelines when developing:

* Whenever you add a new feature, no matter how minor, add a test. Better yet, add 
many tests to make sure that it not only works correctly, but that it breaks when 
it is supposed to (e.g. when it is fed the wrong output). Try to conceive of every 
possible way your feature will be used and mis-used.

* If someone files a bug report that is not revealed by a test, please add one in, 
no matter how simple the fix maybe, or how stupid the bug is.

* Don't create a new test file unless necessary - use the existing ones whenever possible. 
Most things can fit in 03dbmethod.t (database handle methods) or 03smethod.t (statement 
handle methods). If all else fails, consider using the 04misc.t test. New files should 
generally be created for a bunch of related tests that do not easily fit into the current 
listings.

* If you do create a new test, keep the name short, start it with a number, and use an 
existing test as a template.

* Tests should be as "standalone" as possible. The only exception is that most of them 
will need 01setup.t to be run first, to create the testing table. However, once this 
has been run, and before 99cleanup.t has been run, each test file should run flawlessly 
multiple times. Tests should remove any objects they create at the end of the script, 
and should be able to silently recreate objects as needed (see 07copy.t for an example).
Objects should be created as "temporary" whenever possible.

* Use the standard format for tests, and always provide an appropriate output text. 
Abbreviations are encouraged, but be consistent throughout the file.

* Make sure to test on different versions of PostgreSQL, DBI, and Perl. Use the SKIP 
tag with an appropriate message if a test does not work on a particular version of 
something (see 20savepoints.t for an example).


=====================
== Version Numbers ==
=====================

Version numbers are constrained by the Perl CPAN system, in which there is a major 
and a minor number. Generally, we increment the minor version by one for each new 
release. More major releases can bump up to the next "tens" place, e.g. from 1.33 
to 1.40. Very major releases can bump the major number, but this should be an 
extremely rare event. When in doubt, ask on the list. Any bump other than a single 
increment should always be discussed there first anyways.

Beta versions are simply the number *before* the new anticipated number, plus an 
underscore to indicate the beta version. For example, if the current version is 
1.41 and you are making betas for an upcoming 1.42 version, you should name the 
beta version as 1.41_1. A second beta would be 1.41_2, etc.

Version numbers are currently set in five files:

README
Pg.pm (two places!)
Changes
Makefile.PL
META.yml


===============
== New Files ==
===============

If you are adding a new file to the distribution (and this should be a rare event), 
please check that you have done the following items:

* Created a standard header for the file, with a (dollar sign)Id(dollar sign)

* Added it to cvs via 'cvs add filename' and 'cvs commit filename'

* Added it to the MANIFEST file

* Added to Makefile.PL if needed, to make sure all build dependencies are met

* Updated/created necessary tests for it


=================
== New Methods ==
=================


New methods and attribute names should be short and descriptive. If they are "visible", 
please make sure they begin with a "pg_" prefix. If you feel they should not have this 
prefix, make your case on the dbi-dev list.


==========================
== Making a New Release ==
==========================

This is a comprehensive checklist of all the steps required to release a 
new version, whether beta or regular. It is assumed you are very familiar with the 
other sections referenced herein (indicated with **)

* Test on variety of versions (see ** Heavy Testing)

* Make sure everything is up to date in cvs

* Update the versions (see ** Version Numbers) in README, Pg.pm (2 places!), Makefile.PL, 
  META.yml, and Changes.

* If a beta version, please put a large warning at the top of the README file. Here is a sample:

===================================================
WARNING!!

THIS IS A TEST VERSION (1.43_2) AND SHOULD BE USED 
FOR TESTING PURPOSES ONLY. PLEASE USE A STABLE 
VERSION (no underscore) BY VISITING:

http://search.cpan.org/~dbdpg/
===================================================

* If not a beta version, remove the warning from the README.

* Update the Changes file

The best way to do this (other than doing it as you go along) is to check the cvs logs. 
For example, to grab all changes made since revision 1.43 and save it to a file:

cvs log -rRel-1_43: * > all_logs.tmp

* Update the documentation

Make sure that anything new has been documented properly, usually as pod inside of Pg.pm
A good way to do this is to use the tests in 99_pod.t - they will run automatically as 
part of the test suite if the right modules are installed. You can do this to test:

prove -v t/99_pod.t

* Run "perl Makefile.PL"

* Run "make dist". Double check that the tarball created has the correct version name.

* Run "make distcheck". This will show you a list of all files that are in the current directory 
but not inside the MANIFEST file (or the MANIFEST.SKIP file). If there are any new files here 
that should be part of the distribution, add them to the MANIFEST file, commit your changes, 
and then re-run. Note that files ending in ".tmp" are currently skipped, so this is a good 
extension for any miscellaneous files you have that use often (e.g. libpq-fe.h.tmp)

* Run "make skipcheck". This will show you a list of files that will not be packed into the 
release tarball. Make sure there is nothing important here.

* Run "make disttest". This unpacks the tarball, then runs "make" and "make test" on it.
You may also want to remove the directory it creates later. "make realclean"

* Now that everything works, set a symbolic name for this version. 
Remember to use underscores (see the ** Version Numbers section)

For example, to tag all of the current file as the first beta of 1.43, use:

cvs rtag Rel-1_42_1 dbdpg

If you ever need to remove a symbolic tag, you can use:

cvs admin -nRel-1_42_1 filename

To add a symbolic tag to a particular version of a file use:

cvs admin -nRel-1_42_1:1.19 filename

To add a symbolic tag to the latest version of a file use:

cvs admin -nRel-1_42_1: filename

To reposition a symbolic tag to the latest version of a file use:

cvs admin -NRel-1_42_1: filename

* Make checksums

Generate md5 and sha1 checksums of the tarball. Include this in your emails.

* Update the SIGNATURE file with Module::Signature

* Test it out

Download the tarball to a completely different system, unpack and test it.

* Announce to the "internal" lists

dbdpg-general
pgsql-interfaces

* Upload to CPAN and test.

You'll need the pause account password. The interface is fairly straightforward. Once it 
is loaded, wait for it to appear on the main DBD::Pg page and then test that the file 
has the same checksums.

* Announce to the "public" lists

dbdpg-general
pgsql-interfaces
dbi-users, dbi-dev, dbi-announce

The format for DBI announcements:
To: dbi-announce@perl.org
Cc: dbi-users@perl.org
Reply-to: dbi-users@perl.org

Subject line: Name of module, version

Short note of changes, link to CPAN directory.

Checksums for the file.

* Post to pgsql-announce if this is a major or important version.

* Post to the "PostgreSQL news"

On the main page, there is a link named "Submit News" which points to:

http://www.postgresql.org/about/submitnews

The content should be roughly the same as the announcement.

* PostgreSQL weekly news summary

The maintainers of the weekly news are usually pretty good about catching the update 
and adding it in. If not, bug them.

http://www.postgresql.org/community/weeklynews/

* Tell Greg to post on PlanetPostgresql.

* If a non-beta, clean out any CPAN bugs, including going back and marking resolved 
bugs with this new version, once it appears in the choices.

* Update this file based on your experiences!!

* Wait for the bugs or accolades to pour in.


=====================
== Tips and Tricks ==
=====================

Also known as, the section to put things that don't fit anywhere else. Anything 
that may make life easier for other developers can go here.

* To change a cvs comment, use the "cvs admin" command, a dash m, the version number, 
a colon, and the new text, then the file name. Example:

cvs admin -m1.118:"Memory leak patch by hertzog@debian.org" dbdimp.c

* Temporary tables

We do not use temporary tables in most of our test because they are 
not persistent across tests, they mess up the schema testing, and they 
are compatible with the foreign key testing. But do try and use them 
whenever possible.

* "turnstep" in the cvs logs is Greg Sabino Mullane, greg@turnstep.com.

* Use a "tmp" extension for files you keep around in the dbdpg directory, but 
don't want to show up when you do a "cvs up". They are also ignored by make dist.

* Commit each file individually, unless the log message is *really* identical 
across all committed files (which is rare). Always give a good description 
of the exact changes made : assume that the log will be read independently 
of a diff.

* Don't forget to test for memory leaks, particularly if you are working with 
the more complicated sections of dbdimp.c. For a quick check, enter a loop, 
then watch the memory size using the top tool. Here's a quick checker:

$dbh->{pg_server_prepare} = 1;
$dbh->{pg_direct} = 1;

$dbh->do("CREATE TEMP TABLE leaktester(a int, b numeric(10,2), c text)");
$sth{'plain'} = $dbh->prepare("SELECT * from leaktester");
$sth{'place'} = $dbh->prepare("INSERT INTO leaktester(a,b,c) VALUES (?,?,?)");
my $loop = 1;
while (1)
{

	$sth{plain}->execute;
	$dbh->do("SELECT 123");
	$dbh->quote(qq{Pi''zza!!"abc});
	$sth->{pg_server_prepare}=1;
	$sth{place}->execute(1,2,"abc");
	$sth->{pg_server_prepare}=0;
	$sth{place}->execute(1,2,"abc");
	$sth->{pg_server_prepare}=1;

	$sth = $dbh->prepare("SELECT 123, ?");
	$sth->bind_param(1,1,SQL_INTEGER);
	$sth->execute(1);
	$sth->finish();

	$info = $dbh->selectall_arrayref("SELECT 123,456");
	select(undef,undef,undef,0.1);
	exit if $loop++ > 10000;
}


===============
== Resources ==
===============

The primary resource is the dbdpg-general mailing list, where the developers live. Other 
resources depend on the subject:

* DBD::Pg

The canonical URL:
http://search.cpan.org/~dbdpg/DBD-Pg-1.41/

* DBI

The DBI developers list:
http://lists.perl.org/showlist.cgi?name=dbi-dev

The DBI users list:
http://lists.perl.org/showlist.cgi?name=dbi-users

The DBI announcement list:
http://lists.perl.org/showlist.cgi?name=dbi-announce

The latest DBI:
http://search.cpan.org/~timb/DBI/

The source code of other DBDs can be a useful tool as well. In other words, the "competition" :)

* PostgreSQL

A good source for general questions on libpq and similar things is the pgsql-interfaces list. Another 
good source for more generic questions (and perhaps better for all questions, as it tends to be more 
active) is the pgsql-hackers list. Having a copy of the source code is invaluable as well. Using a 
tool like glimpse is handy to find those obscure libpq functions quickly. You also may want to keep 
the libpq documentation handy.

All PG mailing lists:
http://www.postgresql.org/community/lists/

A great source for searching the pg documentation and mailing lists is:

http://www.pgsql.ru/db/pgsearch/

which allows you to limit the search by version: very helpful as we support multiple versions of PostgreSQL.


* Perl

Besides a good general understanding of Perl, it helps to learn a little bit about xs:

perldoc perlapi
perldoc perlclib
perldoc perlguts
perldoc perlxstut
perldoc perlxs

This is the module that does all the introductory magic:

perldoc ExtUtils::MakeMaker


The all important testing suite:

perldoc Test;
perldoc Test::Harness;
perldoc Test::Simple;
perldoc Test::More;
perldoc Test::Pod;
perldoc Test::Pod::Coverage;


Othjer important modules:

perldoc Devel::Cover;
perldoc Module::Signature;


This is a guide for DBD authors. It's fairly old and incomplete however, but listed here for 
completeness:

perldoc DBI::DBD


A handy module to know about:

perldoc DBI::Profile

