Subject: | Better way to overload ODBC drivers |
Because the ::DBI::ODBC driver automatically reblesses itself based on
the remote connection's type; specifying a loader_class when using an
ODBC connection doesn't do much - it gets effectively overridden when a
schema is accessed. In the git version this is kind of fixed for the
MSSQL driver in that I can just create a driver based on ::DBI::MSSQL
(as the inheritance structure has changed) and pass that as the
loader_class, but I imagine this is more of a general issue anyway. My
hack code to work around this in previous versions was:
use base 'DBIx::Class::Schema::Loader::DBI::ODBC::MSSQL';
# When the schema is requested, nuke the driver name. This is because
# DBIx::Class::Schema::Loader::DBI->new automatically tries to reclass us if
# there is a driver name that it can load...
sub schema {
my $self = shift;
my $ret = $self->next::method( @_ );
# If this is the first time through; then nuke the driver name as
it's from
# DBICSL::DBI->new and wants to be nasty and rebless us. Can't just
delete
# because it's probably a tied variable or something silly.
if( ! exists $self->{_saved_driver_name} and
! exists $self->{_can_avoid_being_reblessed} ) {
my $dbh = $ret->storage->dbh;
if( exists $dbh->{Driver}{Name} ) {
$self->{_saved_driver_name} = $dbh->{Driver}{Name}
}
$dbh->{Driver}{Name} = 'abc123'; # Or something equally silly
}
return $ret
}
sub new {
my $self = shift->next::method( @_ );
# After we've been loaded we dont need to hide the dbi driver name
any more
$self->{_can_avoid_being_reblessed} = 1;
if( $self->{_saved_driver_name} ) {
$self->schema->storage->dbh->{Driver}{Name} = delete
$self->{_saved_driver_name}
}
return $self
}