Skip Menu |

This queue is for tickets about the DBIx-Class-Schema-Loader CPAN distribution.

Report information
The Basics
Id: 55928
Status: resolved
Priority: 0/
Queue: DBIx-Class-Schema-Loader

People
Owner: Nobody in particular
Requestors: mark.zealey [...] webfusion.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in:
  • 0.04999_10
  • 0.05003
Fixed in: (no value)



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 }
Subject: Re: [rt.cpan.org #55928] Better way to overload ODBC drivers
Date: Fri, 26 Mar 2010 14:31:22 -0400
To: Mark Zealey via RT <bug-DBIx-Class-Schema-Loader [...] rt.cpan.org>
From: Rafael Kitover <rkitover [...] cpan.org>
Fixed in git, now when you specify a custom loader_class, there will be no attempt to detect the driver and rebless. On Thu, Mar 25, 2010 at 06:11:15AM -0400, Mark Zealey via RT wrote: Show quoted text
> Thu Mar 25 06:11:15 2010: Request 55928 was acted upon. > Transaction: Ticket created by mzealey > Queue: DBIx-Class-Schema-Loader > Subject: Better way to overload ODBC drivers > Broken in: 0.04999_10, 0.05003 > Severity: (no value) > Owner: Nobody > Requestors: mark.zealey@webfusion.com > Status: new > Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=55928 > > > > 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 > } >
Fixed in 0.06000, does not rebless with custom loader_class.