busunsl has asked for the wisdom of the Perl Monks concerning the following question:

Hi folks!

I started working on a small web application that shows reports based on data in a Sybase database.

The application will run on Linux or Solaris, but development is on win32 ( :-( ) for the moment.

When the first script was ready, I tested it on the commandline. Easy piece thanks to CGI.
Ok, time to have it served by Apache: Server Error!

Ahh! Apache thinks it is clever not to pass environment variables to cgi scripts and that's perfectly ok! But I need the SYBASE variable.
Ok, there's the old hack: Place a BEGIN block at the start of the script, set the SYBASE variable in it, and everything's fine.

So I thought, but it didn't work.

I unset the SYBASE variable in a command window and stripped down the script to the smallest working piece and got this to prove the failure:

#!/perl/bin/perl -w BEGIN { $ENV{SYBASE} = 'c:\w03g\sybase\r120500'; } use strict; use warnings; use DBI; system('echo %SYBASE%'); my $dbh = DBI->connect('dbi:Sybase:server=myserver', 'user', 'password' ) or die "could not connect"; # die message cut down here for shortness.
This yields the error:

The context allocation routine failed when it tried to load localizati +on files!!<br> One or more following problems may caused the failure<p> Your sybase home directory is as. Check the environment variable SYBAS +E if it is not the one you want!<br> Cannot access file as\ini\objectid.dat<br> install_driver(Sybase) failed: DBD::Sybase initialize: cs_ctx_alloc() +failed at C:/Perl/lib/DynaLoader.pm line 225.<br> Compilation failed in require at (eval 1) line 3.

This is on WinNT SP6, ActiveState Perl 5.6.1 Build 626. DBD::Sybase 0.91

I knew that the BEGIN hack was working on Linux. Being too lazy to start the Linux box and the Sybase server on it, I tried the script on a Sun box running Solaris 2.8.

I unset the SYBASE variable, started the script and everything was fine.

So why doesn't the BEGIN hack work on win32?

p.s.: I managed to convince Apache to pass the SYBASE variable with 'PassEnv SYBASE' in the config file.

Replies are listed 'Best First'.
Re: DBD::Sybase and win32
by MZSanford (Curate) on Feb 01, 2002 at 09:04 UTC
    Using the BEGIN hack, and the message as you included it, it appears that 'c:\w03g\sybase\r120500' evaluates to 'as'. I suspect this is an issue with Perl trying to convert your \'s into escapes. "Win32 Perl Programming : The Standard Extensions" covers this. Try using forward-slashes and see if it works any better (or doubling all of your back-slashes). I am not sure this will work, but it might, so, worth a try. Unfortunatly, i am on a non-Perl machine, and cannot test :/
    from the frivolous to the serious
      Sorry to mislead you.

      I just changed the SYBASE variable to something, in that case 'as'.
      So the error message shows that the original setting of the variable is used by DBD::Sybase and not the one in the BEGIN block.

      I tried both in my BEGIN block, 'c:\w03g\sybase\r120500' as well as '/w03g/sybase/r120500'.

      Both led to the same error.
      The system('echo %SYBASE%'); shows that the variable is set correctly in the BEGIN block, DBD::Sybase just ignores this setting and uses the value set in the shell.

Re: DBD::Sybase and win32
by mpeppler (Vicar) on Feb 01, 2002 at 19:11 UTC
    First, you shouldn't need to use a BEGIN block to set the SYBASE env. variable - this needs to be set correctly before DBD::Sybase gets loaded, but in the case of DBI it doesn't get loaded until the first DBI->connect() call.

    Now there may be some other stuff going on, though.
    I'd take a quick look at the Sybase.pm file and see if there isn't something in there that overrides the SYBASE env. variable (there shouldn't be, but it doesn't hurt to look...)

    Michael

Re: DBD::Sybase and win32
by dmmiller2k (Chaplain) on Feb 01, 2002 at 18:43 UTC

    It sounds like DBD::Sybase is trying to load the Sybase DLLs and perhaps cannot find them all.

    On UNIX, this would be because the LD_LIBRARY_PATH variable needs to be set, as well as the SYBASE one.

    On WinNT, the analagous variable is PATH. It's possible that the order of directories in the Path is incorrect and a non-Sybase library with the same name as a Sybase one is being found first.

    On UNIX, for instance, the library name, libintl.so occurs in both /usr/lib and in $SYBASE/lib, so their order within LD_LIBRARY_PATH matters.

    If you run the webserver as LocalSystem, make sure that the sybase BIN directory is in the right location in the Global PATH; if you run it as an unpriviledged user, log in as that user and make sure it is in that user's User PATH (or just add it to the global PATH anyway).

    Update: I had another thought. Perhaps DBD::Sybase is loading earlier than you expect for some reason (like before the BEGIN block has a chance to change SYBASE)?

    dmm

    If you GIVE a man a fish you feed him for a day
    But,
    TEACH him to fish and you feed him for a lifetime