Proxy the 'unsafe' attribute to the internal ::Versioned storage
Fabrice Gabolde [Wed, 13 Apr 2016 13:42:38 +0000 (15:42 +0200)]
( cherry-pick of e7dcdf69f )

Changes
lib/DBIx/Class/Schema/Versioned.pm
t/94versioning.t

diff --git a/Changes b/Changes
index 24732f7..85d3051 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,6 +1,8 @@
 Revision history for DBIx::Class
 
     * Fixes
+        - Fix use of ::Schema::Versioned combined with a user-supplied
+          $dbh->{HandleError} (GH#101)
         - Fix parsing of DSNs containing driver arguments (GH#99)
         - Work around unreliable $sth->finish() on INSERT ... RETURNING within
           DBD::Firebird on some compiler/driver combinations (RT#110979)
index 84a5851..c1bbd7b 100644 (file)
@@ -590,10 +590,15 @@ sub _on_connect
 {
   my ($self) = @_;
 
-  weaken (my $w_self = $self );
+  weaken (my $w_storage = $self->storage );
 
-  $self->{vschema} = DBIx::Class::Version->connect(sub { $w_self->storage->dbh });
-  my $conn_attrs = $self->storage->_dbic_connect_attributes || {};
+  $self->{vschema} = DBIx::Class::Version->connect(
+    sub { $w_storage->dbh },
+
+    # proxy some flags from the main storage
+    { map { $_ => $w_storage->$_ } qw( unsafe ) },
+  );
+  my $conn_attrs = $w_storage->_dbic_connect_attributes || {};
 
   my $vtable = $self->{vschema}->resultset('Table');
 
@@ -602,7 +607,7 @@ sub _on_connect
 
   # check for legacy versions table and move to new if exists
   unless ($self->_source_exists($vtable)) {
-    my $vtable_compat = DBIx::Class::VersionCompat->connect(sub { $w_self->storage->dbh })->resultset('TableCompat');
+    my $vtable_compat = DBIx::Class::VersionCompat->connect(sub { $w_storage->dbh })->resultset('TableCompat');
     if ($self->_source_exists($vtable_compat)) {
       $self->{vschema}->deploy;
       map { $vtable->new_result({ installed => $_->Installed, version => $_->Version })->insert } $vtable_compat->all;
index de45516..0e7b7fd 100644 (file)
@@ -301,6 +301,35 @@ is
   ), 3, "Expected number of connections at end of script"
 ;
 
+# Test custom HandleError setting on an in-memory instance
+{
+  my $custom_handler = sub { die $_[0] };
+
+  # try to setup a custom error handle without unsafe set -- should
+  # fail, same behavior as regular Schema
+  throws_ok {
+    DBICVersion::Schema->connect( 'dbi:SQLite::memory:', undef, undef, {
+      HandleError => $custom_handler,
+      ignore_version => 1,
+    })->deploy;
+  }
+    qr/Refusing clobbering of \{HandleError\} installed on externally supplied DBI handle/,
+    'HandleError with unsafe not set causes an exception'
+  ;
+
+  # now try it with unsafe set -- should work (see RT #113741)
+  my $s = DBICVersion::Schema->connect( 'dbi:SQLite::memory:', undef, undef, {
+    unsafe => 1,
+    HandleError => $custom_handler,
+    ignore_version => 1,
+  });
+
+  $s->deploy;
+
+  is $s->storage->dbh->{HandleError}, $custom_handler, 'Handler properly set on main schema';
+  is $s->{vschema}->storage->dbh->{HandleError}, $custom_handler, 'Handler properly set on version subschema';
+}
+
 END {
   unless ($ENV{DBICTEST_KEEP_VERSIONING_DDL}) {
     $ddl_dir->rmtree;