Using legacy db handles
If you have a legacy app using DBI (unchangeable code for political reasons, let's say) into which you are putting Class::DBI additions, it appears that you must open two connections; one for your legacy stuff with DBI and one via Class::DBI using the Ima::DBI magic.
If you take a normal DBI handle and try to set it as the handle for a Class::DBI class with db_Main(), you get method not found errors since Class::DBI seems to expect special Ima::DBI methods to be present. e.g. 'can't locate object method "select_val" ...' errors. This is because Class:DBI/Ima::DBI expects the database handles it uses to inherit from DBIx::ContextualFetch.
Just to be explicit, the DBI handles normally created by Class::DBI have the following attributes:
RaiseError => 1, PrintError => 0, Taint => 1, RootClass => 'DBIx::ContextualFetch', FetchHashKeyName => 'NAME_lc', ShowErrorStatement => 1, ChopBlanks => 1, AutoCommit => 1 (unless you are using Oracle or PostgreSQL, then 0)
You can probably get away with not setting Taint and ShowErrorStatement. RootClass, RaiseError, FetchHashKeyName, and ChopBlanks are most surely required. CDBI will work with either AutoCommit setting, regardless of whether you are using Oracle/PostgreSQL or not.
If you do override db_Main() to provide your own database handle, don't forget to do the following:
so that dbi_commit() and dbi_rollback() will work correctly.
It would be nice if CDBI and/or Ima::DBI had a plan for dealing with DBI-only handles (such as an Ima::DBI constructor to wrap an Ima::DBI around a DBI handle, and a corresponding check in CDBI that did that for you). Apparently, this is non-trivial according to Tony.
Alternatively, you can go in the opposite direction. You can get your $dbh by calling Class->db_Main, and then use it just as it were a normal DBI handle.
In many applications the database user name, password etc. are provided from a config file rather than coding it in the script. This can be accomplished with Class::DBI in any number of ways. One possibility is creating a package which reads and parses the config file at import time and then export the connection parameters as variables. Your CDBI base class could then use this package and then set up the connection using these variables.