Thursday, November 22nd, 2007 at 7:01 pm
In my paper at last year’s Open Source Developers’ Conference I said that one of the negatives of Class::DBI was that it connects to the database at module load. If this fails an exception is thrown which can cause issues when the Class::DBI code is just one part, for example in a web server.
It looks like we were causing this behaviour, instead of it being how Class::DBI operates.
By default DATE fields in Oracle are formatted for year, month, and day even though the field includes hour, minute and second. In order to get the complete date and time our base class changes the default formatting with a line similar to:
__PACKAGE__->db_Main->do( "ALTER SESSION SET NLS_DATE_FORMAT = 'DD:MM:YYYY HH24:MI:SS'" );
It is this line that triggers a connection on module load. If it is removed then the classes can be loaded even if the database is dead. Connection is now only attempted on first action which is a much more approriate time.
I’m not sure what the documentation said about it when we put the line in, but Setting Session Globals and Working With Oracle Date Fields on the Class::DBI wiki warn about using it in a mod_perl environment and that it will initiate a connection when the modules is used.
Over the next few days the commercial product that this database is used with is being upgraded. During this time the database will be unavailable for use so we revisited the issue of how to get the classes to load cleanly. These investigations found the root cause and we now have a solution; alter the base class so that the date formatting is altered whenever a connection is initialized (using information from how to use multiple databases), not when the class is loaded.
Now, although we have solved this issue, having to solve it wasn’t trivial as we were required to dig through some of the Class::DBI and Ima::DBI internals to mimic its behaviour.