added ensure_class_loaded method to Componentized, which should fix problems with...
Justin Guenther [Fri, 19 May 2006 20:50:55 +0000 (20:50 +0000)]
12 files changed:
lib/DBIx/Class/CDBICompat/HasA.pm
lib/DBIx/Class/Componentised.pm
lib/DBIx/Class/Relationship/BelongsTo.pm
lib/DBIx/Class/Relationship/HasMany.pm
lib/DBIx/Class/Relationship/HasOne.pm
lib/DBIx/Class/ResultSource.pm
lib/DBIx/Class/Schema.pm
t/basicrels/30ensure_class_loaded.t [new file with mode: 0644]
t/helperrels/30ensure_class_loaded.t [new file with mode: 0644]
t/lib/DBICTest/FakeComponent.pm [new file with mode: 0644]
t/lib/DBICTest/Schema/TreeLike.pm
t/run/30ensure_class_loaded.tl [new file with mode: 0644]

index 6930f3b..647674f 100644 (file)
@@ -7,7 +7,7 @@ use warnings;
 sub has_a {
   my ($self, $col, $f_class, %args) = @_;
   $self->throw_exception( "No such column ${col}" ) unless $self->has_column($col);
-  eval "require $f_class";
+  $self->ensure_class_loaded($f_class);
   if ($args{'inflate'} || $args{'deflate'}) { # Non-database has_a
     if (!ref $args{'inflate'}) {
       my $meth = $args{'inflate'};
index 560c374..e23a0b4 100644 (file)
@@ -5,6 +5,7 @@ use strict;
 use warnings;
 
 use Class::C3;
+use Class::Inspector;
 
 sub inject_base {
   my ($class, $target, @to_inject) = @_;
@@ -41,10 +42,20 @@ sub load_own_components {
 sub _load_components {
   my ($class, @comp) = @_;
   foreach my $comp (@comp) {
-    eval "use $comp";
-    die $@ if $@;
+    $class->ensure_class_loaded($comp);
   }
   $class->inject_base($class => @comp);
 }
 
+# TODO: handle ->has_many('rel', 'Class'...) instead of
+#              ->has_many('rel', 'Some::Schema::Class'...)
+sub ensure_class_loaded {
+  my ($class, $f_class) = @_;
+  eval "require $f_class";
+  my $err = $@;
+  Class::Inspector->loaded($f_class)
+      or die $err || "require $f_class was successful but the package".
+                     "is not defined";
+}
+
 1;
index 535fa75..8c8ceaa 100644 (file)
@@ -5,11 +5,7 @@ use warnings;
 
 sub belongs_to {
   my ($class, $rel, $f_class, $cond, $attrs) = @_;
-  eval "require $f_class";
-  if ($@) {
-    $class->throw_exception($@) unless $@ =~ /Can't locate/;
-  }
-  
+  $class->ensure_class_loaded($f_class);
   # no join condition or just a column name
   if (!ref $cond) {
     my %f_primaries = map { $_ => 1 } eval { $f_class->primary_columns };
index a709d6a..aa46486 100644 (file)
@@ -6,11 +6,8 @@ use warnings;
 
 sub has_many {
   my ($class, $rel, $f_class, $cond, $attrs) = @_;
-    
-  eval "require $f_class";
-  if ($@) {
-    $class->throw_exception($@) unless $@ =~ /Can't locate/;
-  }
+
+  $class->ensure_class_loaded($f_class);
 
   unless (ref $cond) {
     my ($pri, $too_many) = $class->primary_columns;
index 4efbec0..aa94a08 100644 (file)
@@ -14,11 +14,7 @@ sub has_one {
 
 sub _has_one {
   my ($class, $join_type, $rel, $f_class, $cond, $attrs) = @_;
-  eval "require $f_class";
-  if ($@) {
-    $class->throw_exception($@) unless $@ =~ /Can't locate/;
-  }
-
+  $class->ensure_class_loaded($f_class);
   unless (ref $cond) {
     my ($pri, $too_many) = $class->primary_columns;
     $class->throw_exception( "might_have/has_one can only infer join for a single primary key; ${class} has more" )
index 7b4c48c..eb58dd5 100644 (file)
@@ -456,10 +456,7 @@ sub add_relationship {
 
   my $f_source = $self->schema->source($f_source_name);
   unless ($f_source) {
-    eval "require $f_source_name;";
-    if ($@) {
-      die $@ unless $@ =~ /Can't locate/;
-    }
+    $self->ensure_class_loaded($f_source_name);
     $f_source = $f_source_name->result_source;
     #my $s_class = ref($self->schema);
     #$f_source_name =~ m/^${s_class}::(.*)$/;
index c1ea074..98387b4 100644 (file)
@@ -263,13 +263,7 @@ sub load_classes {
     foreach my $prefix (keys %comps_for) {
       foreach my $comp (@{$comps_for{$prefix}||[]}) {
         my $comp_class = "${prefix}::${comp}";
-        eval "use $comp_class"; # If it fails, assume the user fixed it
-        if ($@) {
-          $comp_class =~ s/::/\//g;
-          die $@ unless $@ =~ /Can't locate.+$comp_class\.pm\sin\s\@INC/;
-          warn $@ if $@;
-        }
-
+        $class->ensure_class_loaded($comp_class);
         $comp_class->source_name($comp) unless $comp_class->source_name;
 
         push(@to_register, [ $comp_class->source_name, $comp_class ]);
diff --git a/t/basicrels/30ensure_class_loaded.t b/t/basicrels/30ensure_class_loaded.t
new file mode 100644 (file)
index 0000000..67f2d6c
--- /dev/null
@@ -0,0 +1,7 @@
+use Test::More;
+use lib qw(t/lib);
+use DBICTest;
+use DBICTest::BasicRels;
+
+require "t/run/30ensure_class_loaded.tl";
+run_tests(DBICTest->schema);
diff --git a/t/helperrels/30ensure_class_loaded.t b/t/helperrels/30ensure_class_loaded.t
new file mode 100644 (file)
index 0000000..6edbe80
--- /dev/null
@@ -0,0 +1,7 @@
+use Test::More;
+use lib qw(t/lib);
+use DBICTest;
+use DBICTest::HelperRels;
+
+require "t/run/30ensure_class_loaded.tl";
+run_tests(DBICTest->schema);
diff --git a/t/lib/DBICTest/FakeComponent.pm b/t/lib/DBICTest/FakeComponent.pm
new file mode 100644 (file)
index 0000000..5fe3b66
--- /dev/null
@@ -0,0 +1,7 @@
+#   belongs to t/run/30ensure_class_loaded.tl
+package # hide from PAUSE 
+    DBICTest::FakeComponent;
+use warnings;
+use strict;
+
+1;
index 9fde9f3..1eca3e1 100644 (file)
@@ -14,7 +14,7 @@ __PACKAGE__->add_columns(
  },
 );
 __PACKAGE__->set_primary_key(qw/id/);
-__PACKAGE__->belongs_to('parent', 'TreeLike',
+__PACKAGE__->belongs_to('parent', 'DBICTest::Schema::TreeLike',
                           { 'foreign.id' => 'self.parent' });
 
 1;
diff --git a/t/run/30ensure_class_loaded.tl b/t/run/30ensure_class_loaded.tl
new file mode 100644 (file)
index 0000000..8602565
--- /dev/null
@@ -0,0 +1,40 @@
+use Class::Inspector;
+
+BEGIN {
+  package TestPackage::A;
+  sub some_method {}
+}
+
+sub run_tests {
+
+my $schema = shift;
+plan tests => 6;
+
+ok(Class::Inspector->loaded('TestPackage::A'),
+   'anon. package exists');
+eval {
+  $schema->ensure_class_loaded('TestPackage::A');
+};
+
+ok(!$@, 'ensure_class_loaded detected an anon. class');
+
+eval {
+  $schema->ensure_class_loaded('FakePackage::B');
+};
+
+like($@, qr/Can't locate/,
+     'ensure_class_loaded threw exception for nonexistent class');
+
+ok(!Class::Inspector->loaded('DBICTest::FakeComponent'),
+   'DBICTest::FakeComponent not loaded yet');
+
+eval {
+  $schema->ensure_class_loaded('DBICTest::FakeComponent');
+};
+
+ok(!$@, 'ensure_class_loaded detected an existing but non-loaded class');
+ok(Class::Inspector->loaded('DBICTest::FakeComponent'),
+   'DBICTest::FakeComponent now loaded');
+}
+
+1;