Dear Jeff and Tim, Here's a patch which more or less got DBD::ODBC 1.01 up and running using Informix CLI as the ODBC driver (and driver manager) on Solaris.
What did I have to fix? First of all, for some reason I don't understand fully, my system was initially diagnosed as being a udbc system. So, I had to hack Makefile.PL to avoid that mis-diagnosis. In doing so, I cleaned up the testing for other drivers and made it all more consistent. Then I added a test which heads off trouble when no valid ODBC system is detected. There's now a list of the ODBC drivers which are supported; this is printed when no valid system is detected. Then I had to fiddle the definitions for use with Informix CLI, which was no worse than any other driver. I made sure that the detailed version and platform information for Informix is in the file. It will gently get out of date, but can be brought up to date again as necessary. It at least tells people where it was originally thought to work. I'm using a butchered DBI 1.32 that is masquerading as 1.33, and it showed up a couple of minor problems in dbdimp.h -- no #define for dbd_discon_all and a stray #define for dbd_db_do. Tim may yet decide those changes are too radical for DBI 1.33, but this change will allow your driver to work with both existing DBI versions and the future version where all the functions in Driver.xst are guarded with #ifdef's. Note that DBI 1.32 and earlier does not ever call dbd_db_do. I modified one (of three) calls to SQLDescribeCols() so that GCC didn't witter at me about incompatible pointer types. I used an effective but crude technique; I declared a local variable of the correct type and passed that to the function, and then assigned the variable to the original source of trouble. It was the ColumnSize parameter (7), which was being given a U32 pointer but the ODBC specs say it should be an SQLUINTEGER pointer. I ran into a problem with t/02simple.t; there was no newline at the end of the output from test 9, so the 'not ok 9' was getting lost. That was easy to fix. With that fix in place, I was getting two test failures, numbers 6 and 9 in t/02simple.t. I wondered if it was my slightly unusual setting of the (Informix-specific) DBDATE variable that was throwing things for a wobbly, but it does not appear to be that. I'm not sure how much time to spend debugging that - get back to me on it. The verbose output from the test that is failing (with the extra newline in place) is in the second attachment. I wrote README.informix with much of the same information in it. Feel free to remove the first paragraph if you accept the patches I'm sending. Amongst other things, it documents that DBD::ODBC does not manage to handle Informix's non-transactional databases -- I got many more failures until I used a logged database. I also hacked the README (carefully preserving the DOS line endings) to update the rather archaic URLs and instructions for joining the mailing lists. With luck, I can now generate a GetInfo module for DBD::Informix! -- Jonathan Leffler #include <disclaimer.h> STSM, Informix Database Engineering, IBM Data Management Phone: +1 650-926-6921 Fax: +1 650-926-6971 Tie-line: 630-6921 Email: [EMAIL PROTECTED] Guardian of DBD::Informix v1.04.PC1 -- http://dbi.perl.org
--- dbdimp.h.old 2002-12-07 23:10:41.000000000 -0800 +++ dbdimp.h 2002-12-16 14:40:25.051675000 -0800 @@ -147,9 +147,11 @@ /* These defines avoid name clashes for multiple statically linked DBD's */ #define dbd_init odbc_init +#define dbd_discon_all odbc_dr_disconnect_all + #define dbd_db_login odbc_db_login #define dbd_db_login6 odbc_db_login6 -#define dbd_db_do odbc_db_do +/*#define dbd_db_do odbc_db_do*/ #define dbd_db_commit odbc_db_commit #define dbd_db_rollback odbc_db_rollback #define dbd_db_disconnect odbc_db_disconnect --- dbdimp.c.old 2002-12-08 20:01:06.000000000 -0800 +++ dbdimp.c 2002-12-16 14:45:23.197921000 -0800 @@ -3635,14 +3635,16 @@ I16 *Nullable; { D_imp_sth(sth); + SQLUINTEGER ColSize; RETCODE rc; rc = SQLDescribeCol(imp_sth->hstmt, colno, ColumnName, BufferLength, NameLength, - DataType, ColumnSize, DecimalDigits, Nullable); + DataType, &ColSize, DecimalDigits, Nullable); if (!SQL_ok(rc)) { dbd_error(sth, rc, "DescribeCol/SQLDescribeCol"); return 0; } + *ColumnSize = ColSize; return 1; } --- Makefile.PL.old 2002-12-10 06:11:30.000000000 -0800 +++ Makefile.PL 2002-12-16 14:40:16.782601000 -0800 @@ -16,7 +16,7 @@ use DBI::DBD; use strict; -my %opts = +my %opts = ( NAME => 'DBD::ODBC', VERSION_FROM => 'ODBC.pm', @@ -109,7 +109,7 @@ # cygwin patch $opts{INC} .= " -I/usr/include/w32api" if $^O eq 'cygwin'; - + # Try to work out which driver manager is being used. # Feel free to come up with neat (or un-neat) hacks to get your's to build! @@ -118,41 +118,78 @@ my $libs = "odbc"; $opts{LIBS} = " -L$lib_d1 -R$lib_d1 -L$lib_d2 -R$lib_d2 -l$libs"; + my (@known_drivers) = sort ( + 'Microsoft ODBC', + 'unixodbc', + 'iodbc', + 'esodbc', + 'empress', + 'intersolve', + 'sapdb', + 'adabas', + 'udbc', + 'easysoft', + 'solid', + 'informix', + ); + my $myodbc =''; # edit and hack to suit! $myodbc = 'Microsoft ODBC' if ( -e "$odbchome/system/odbc32.dll" or -e "$odbchome/system32/odbc32.dll" or -e "$odbchome/odbc32.dll"); + + my $dlext = $Config{dlext}; + my $arext = $Config{lib_ext}; + # per patches from Nick Gorham $myodbc = 'unixodbc' - if <$odbchome/lib/libodbc.*>; + if !$myodbc && <$odbchome/lib/libodbc.*>; $myodbc = 'iodbc' - if (!$myodbc && (<$odbchome/*iodbc*> || <$odbchome/lib/*iodbc*>)); + if !$myodbc && (<$odbchome/*iodbc*> || <$odbchome/lib/*iodbc*>); $myodbc = 'esodbc' - if <$odbchome/*esoobclient*>; + if !$myodbc && <$odbchome/*esoobclient*>; $myodbc = 'empress' - if <$odbchome/lib/libempodbc.*>; + if !$myodbc && <$odbchome/lib/libempodbc.*>; $myodbc = 'intersolve' - if -f "$odbchome/include/qeodbc.h"; + if !$myodbc && -f "$odbchome/include/qeodbc.h"; $myodbc = 'sapdb' - if -f "$odbchome/lib/libsqlod.a"; + if !$myodbc && -f "$odbchome/lib/libsqlod.$arext"; $myodbc = 'adabas' - if $ENV{DBROOT} && $odbchome eq $ENV{DBROOT} && -f "$odbchome/lib/odbclib.a"; + if !$myodbc && $ENV{DBROOT} && $odbchome eq $ENV{DBROOT} && -f +"$odbchome/lib/odbclib.$arext"; $myodbc = 'udbc' - if ($myodbc eq '' && <$odbchome/lib/libudbc.a>); + if !$myodbc && -f "$odbchome/lib/libudbc.$arext"; $myodbc = 'easysoft' - if ($myodbc eq '' && -f "$odbchome/lib/libesoobclient.so"); + if !$myodbc && -f "$odbchome/lib/libesoobclient.$dlext"; $myodbc = 'solid' - if ($myodbc eq '' && -f "$odbchome/lib/libsolcli.so"); + if !$myodbc && -f "$odbchome/lib/libsolcli.$dlext"; + + # JL 2002-12-16: This test is accurate on Unix (Solaris 7) with IBM + # Informix ClientSDK 2.80.UC1, which includes IBM Informix CLI + # v3.81.000, an ODBC 3.x driver. + # NB: The correct value for $ODBCHOME is $INFORMIXDIR. + $myodbc = 'informix' + if !$myodbc && -f "$odbchome/lib/cli/libifcli.$dlext"; + + if (!$myodbc) { + local($") = ", "; + my($list) = "@known_drivers"; + $list =~ s%^(.{30,70})\s%$1\n\t%gmo; + die qq% +Hmm...I cannot find an ODBC driver manager that I recognize. +...And I know about these drivers: + $list +%; + } warn "\nUmm, this looks like a $myodbc type of driver manager.\n"; @@ -167,7 +204,7 @@ $opts{dynamic_lib} = {OTHERLDFLAGS => "-lodbc32"}; } elsif ($myodbc eq 'iodbc') { - my $ilibdir = "$odbchome/lib"; + my $ilibdir = "$odbchome/lib"; my @ilibs = <$ilibdir/*iodbc*.*>; @ilibs = grep { /\.($Config{so}|$Config{dlext}|a)$/ } @ilibs; die "That's odd, I can't see any iodbc libs in $ilibdir" unless @ilibs; @@ -271,7 +308,7 @@ print SQLH qq{#include <sqlucode.h>\n}; print SQLH qq{#include <sql.h>\n}; print SQLH qq{#include <sqltypes.h>\n}; - } + } elsif ($myodbc eq 'intersolve') { $opts{DEFINE} = ""; print SQLH qq{#include <qeodbc.h>\n}; @@ -337,6 +374,14 @@ print SQLH qq{#define DBD_ODBC_NO_SQLDRIVERCONNECT\n}; print SQLH qq{#include <cli0cli.h>\n}; } + elsif ($myodbc eq 'informix') { + # JL 2002-12-16: See comments above for environment details. + $opts{INC} = "-I$odbchome/incl/cli $opts{INC}"; + $opts{LIBS} = "-L$odbchome/lib/cli -lifcli -lifdmr"; + $opts{DEFINE} .= "-DNO_WIN32"; # Applies to Unix only, of course + print SQLH qq{#include <stddef.h>\n}; + print SQLH qq{#include <infxcli.h>\n}; + } else { print "\n*** WARNING ***\a\n"; print "Unknown driver manager. Using default build process.\n"; @@ -384,7 +429,7 @@ $(NOECHO) $(RM_F) $(changes_pm) $(CP) Changes $(changes_pm) '; - + } # ==================================================================== --- t/02simple.t.old 2002-08-13 18:33:15.000000000 -0700 +++ t/02simple.t 2002-12-16 14:51:55.793309000 -0800 @@ -83,6 +83,7 @@ ++$is_ok if grep { $coltype == $_ } @{$ODBCTEST::TestFieldInfo{$colname}}; print " yes\n" if grep { $coltype == $_ } @{$ODBCTEST::TestFieldInfo{$colname}}; } + print "\n"; Test($is_ok == $colcount); # print "not " unless $is_ok == $colcount; # print "ok 9\n"; --- README.informix.old 2002-12-16 15:09:24.614236000 -0800 +++ README.informix 2002-12-16 15:09:30.000000000 -0800 @@ -0,0 +1,30 @@ +README for Informix CLI on Unix +=============================== + +To get DBD::ODBC 1.01 to work on Solaris 7, there were a number of +changes. + +To build DBD::ODBC 1.01 with the changes in place, the compilation +sequence was: + +perl Makefile.PL -o $INFORMIXDIR + +This locates the CLI (ODBC) libraries in $INFORMIXDIR/lib/cli and the +header files in $INFORMIXDIR/incl/cli. + +When testing, ensure that your database is a logged database; DBD::ODBC +does not seem to be happy with unlogged databases with no transactional +support. If you need to access such databases, you probably need to use +DBD::Informix, which is acquainted with the peculiarities of Informix's +different database logging modes. Non-Informix drivers such as +DBD::ODBC probably can't be expected to oblige with the detailed changes +necessary to handle them. + +Jonathan Leffler <[EMAIL PROTECTED]> +Date: 2002-12-16 + +Platform: Sun Sparc Ultra 10, Solaris 7. +Perl: 5.8.0 +GCC: 3.2.1 +DBI: 1.32 hacked to mimic 1.33 +ODBC: IBM Informix ClientSDK 2.80.UC1, CLI 3.81.0000. --- README.old 2002-12-08 20:16:04.000000000 -0800 +++ README 2002-12-16 15:15:52.220331000 -0800 @@ -96,7 +96,7 @@ This software is supported via the dbi-users mailing list. For more information and to keep informed about progress you can join the a -mailing list via http://www.fugue.com/dbi (if you are unable to use the +mailing list via http://dbi.perl.org/ (if you are unable to use the web you can subscribe by sending a message to [EMAIL PROTECTED], it may take a few days to be processed). @@ -129,7 +129,8 @@ =============================================================================== Other info: -DBI 'home page': http://www.arcana.co.uk/technologia/perl/DBI/index.html +DBI 'home page': http://dbi.perl.org/ +DBI FAQS: http://xmlproj.com/fom-serve/cache/1.html perldoc DBI perldoc DBD::ODBC (which will include the DBD::ODBC FAQ list)
dbd-odbc-1.01-02simple.failure
Description: Test output for t/02simple.t; failing tests 6 and 9