Cleanup moose detection
Peter Rabbitson [Wed, 8 Sep 2010 12:51:45 +0000 (14:51 +0200)]
Changes
lib/DBIx/Class/Schema/Loader/Base.pm

diff --git a/Changes b/Changes
index 3501427..703e85d 100644 (file)
--- a/Changes
+++ b/Changes
@@ -6,6 +6,8 @@ Revision history for Perl extension DBIx::Class::Schema::Loader
           versions
         - Fix mssql common tests failures with MSSQL 2005 (skip test of
           datatypes found only on MSSQL 2008)
+        - Fix dangerous invocation of ->meta on classes during upgrade
+          (may be *non* moosified and contain a user-defined meta() )
 
 0.07001  2010-07-24 21:28:08
         - put is_deferrable => 1 back into default attributes for belongs_to
index ecd0ca7..b2e4d95 100644 (file)
@@ -1084,8 +1084,8 @@ sub _reload_classes {
             local *Class::C3::reinitialize = sub {};  # to speed things up, reinitialized below
             use warnings;
 
-            if ($class->can('meta') && try { $class->meta->isa('Moose::Meta::Class') }) {
-                $class->meta->make_mutable;
+            if (my $mc = $self->_moose_metaclass($class)) {
+                $mc->make_mutable;
             }
             Class::Unload->unload($class) if $unload;
             my ($source, $resultset_class);
@@ -1095,8 +1095,8 @@ sub _reload_classes {
                 && ($resultset_class ne 'DBIx::Class::ResultSet')
             ) {
                 my $has_file = Class::Inspector->loaded_filename($resultset_class);
-                if ($resultset_class->can('meta') && try { $resultset_class->meta->isa('Moose::Meta::Class') }) {
-                    $resultset_class->meta->make_mutable;
+                if (my $mc = $self->_moose_metaclass($resultset_class)) {
+                    $mc->make_mutable;
                 }
                 Class::Unload->unload($resultset_class) if $unload;
                 $self->_reload_class($resultset_class) if $has_file;
@@ -1112,6 +1112,15 @@ sub _reload_classes {
     }
 }
 
+sub _moose_metaclass {
+  return undef unless $INC{'Class/MOP.pm'};   # if CMOP is not loaded the class could not have loaded in the 1st place
+
+  my $mc = Class::MOP::class_of($_[1])
+    or return undef;
+
+  return $mc->isa('Moose::Meta::Class') ? $mc : undef;
+}
+
 # We use this instead of ensure_class_loaded when there are package symbols we
 # want to preserve.
 sub _reload_class {