rewrite un-singularized classnames in custom and external content when upgrading
[dbsrgits/DBIx-Class-Schema-Loader.git] / lib / DBIx / Class / Schema / Loader / Base.pm
index 721816c..420728a 100644 (file)
@@ -460,7 +460,7 @@ EOF
             my ($v) = $real_ver =~ /([1-9])/;
             $v = "v$v";
 
-            last if $v eq CURRENT_V || $real_ver =~ /^0\.04999/;
+            last if $v eq CURRENT_V || $real_ver =~ /^0\.\d\d999/;
 
             if (not %{ $self->naming }) {
                 warn <<"EOF" unless $ENV{SCHEMA_LOADER_BACKCOMPAT};
@@ -518,6 +518,21 @@ sub _find_class_in_inc {
     return $self->_find_file_in_inc($self->_class_path($class));
 }
 
+sub _rewrite_old_classnames {
+    my ($self, $code) = @_;
+
+    return $code unless $self->_upgrading_from;
+
+    my %old_classes = reverse %{ $self->_upgrading_classes };
+
+    my $re = join '|', keys %old_classes;
+    $re = qr/\b($re)\b/;
+
+    $code =~ s/$re/$old_classes{$1}/eg;
+
+    return $code;
+}
+
 sub _load_external {
     my ($self, $class) = @_;
 
@@ -543,23 +558,10 @@ sub _load_external {
 
         open(my $fh, '<', $real_inc_path)
             or croak "Failed to open '$real_inc_path' for reading: $!";
-        $self->_ext_stmt($class,
-          qq|# These lines were loaded from '$real_inc_path' found in \@INC.\n|
-         .qq|# They are now part of the custom portion of this file\n|
-         .qq|# for you to hand-edit.  If you do not either delete\n|
-         .qq|# this section or remove that file from \@INC, this section\n|
-         .qq|# will be repeated redundantly when you re-create this\n|
-         .qq|# file again via Loader!\n|
-        );
-        while(<$fh>) {
-            chomp;
-            $self->_ext_stmt($class, $_);
-        }
-        $self->_ext_stmt($class,
-            qq|# End of lines loaded from '$real_inc_path' |
-        );
+        my $code = do { local $/; <$fh> };
         close($fh)
             or croak "Failed to close $real_inc_path: $!";
+        $code = $self->_rewrite_old_classnames($code);
 
         if ($self->dynamic) { # load the class too
             # kill redefined warnings
@@ -568,9 +570,23 @@ sub _load_external {
                 $warn_handler->(@_)
                     unless $_[0] =~ /^Subroutine \S+ redefined/;
             };
-            do $real_inc_path;
+            eval $code;
             die $@ if $@;
         }
+
+        $self->_ext_stmt($class,
+          qq|# These lines were loaded from '$real_inc_path' found in \@INC.\n|
+         .qq|# They are now part of the custom portion of this file\n|
+         .qq|# for you to hand-edit.  If you do not either delete\n|
+         .qq|# this section or remove that file from \@INC, this section\n|
+         .qq|# will be repeated redundantly when you re-create this\n|
+         .qq|# file again via Loader!\n|
+        );
+        chomp $code;
+        $self->_ext_stmt($class, $code);
+        $self->_ext_stmt($class,
+            qq|# End of lines loaded from '$real_inc_path' |
+        );
     }
 
     if ($old_real_inc_path) {
@@ -578,10 +594,17 @@ sub _load_external {
             or croak "Failed to open '$old_real_inc_path' for reading: $!";
         $self->_ext_stmt($class, <<"EOF");
 
-# These lines were loaded from '$old_real_inc_path', based on the Result class
-# name that would have been created by an 0.04006 version of the Loader. For a
-# static schema, this happens only once during upgrade.
+# These lines were loaded from '$old_real_inc_path',
+# based on the Result class name that would have been created by an 0.04006
+# version of the Loader. For a static schema, this happens only once during
+# upgrade.
 EOF
+
+        my $code = do {
+            local ($/, @ARGV) = (undef, $old_real_inc_path); <>
+        };
+        $code = $self->_rewrite_old_classnames($code);
+
         if ($self->dynamic) {
             warn <<"EOF";
 
@@ -597,24 +620,15 @@ EOF
                 $warn_handler->(@_)
                     unless $_[0] =~ /^Subroutine \S+ redefined/;
             };
-            my $code = do {
-                local ($/, @ARGV) = (undef, $old_real_inc_path); <>
-            };
-            $code =~ s/$old_class/$class/g;
             eval $code;
             die $@ if $@;
         }
 
-        while(<$fh>) {
-            chomp;
-            $self->_ext_stmt($class, $_);
-        }
+        chomp $code;
+        $self->_ext_stmt($class, $code);
         $self->_ext_stmt($class,
             qq|# End of lines loaded from '$old_real_inc_path' |
         );
-
-        close($fh)
-            or croak "Failed to close $old_real_inc_path: $!";
     }
 }
 
@@ -919,6 +933,8 @@ sub _write_classfile {
         }
     }
 
+    $custom_content = $self->_rewrite_old_classnames($custom_content);
+
     $text .= qq|$_\n|
         for @{$self->{_dump_storage}->{$class} || []};
 
@@ -1225,9 +1241,29 @@ sub _tables_list { croak "ABSTRACT METHOD" }
 
 # Execute a constructive DBIC class method, with debug/dump_to_dir hooks.
 sub _dbic_stmt {
-    my $self = shift;
-    my $class = shift;
+    my $self   = shift;
+    my $class  = shift;
+    my $method = shift;
+
+    # generate the pod for this statement, storing it with $self->_pod
+    $self->_make_pod( $class, $method, @_ );
+
+    my $args = dump(@_);
+    $args = '(' . $args . ')' if @_ < 2;
+    my $stmt = $method . $args . q{;};
+
+    warn qq|$class\->$stmt\n| if $self->debug;
+    $self->_raw_stmt($class, '__PACKAGE__->' . $stmt);
+    return;
+}
+
+# generates the accompanying pod for a DBIC class method statement,
+# storing it with $self->_pod
+sub _make_pod {
+    my $self   = shift;
+    my $class  = shift;
     my $method = shift;
+
     if ( $method eq 'table' ) {
         my ($table) = @_;
         $self->_pod( $class, "=head1 NAME" );
@@ -1241,14 +1277,27 @@ sub _dbic_stmt {
         $self->_pod_cut( $class );
     } elsif ( $method eq 'add_columns' ) {
         $self->_pod( $class, "=head1 ACCESSORS" );
-        my $i = 0;
-        foreach ( @_ ) {
-            $i++;
-            next unless $i % 2;
-            $self->_pod( $class, '=head2 ' . $_  );
-            my $comment;
-            $comment = $self->_column_comment( $self->{_class2table}{$class}, ($i - 1) / 2 + 1  ) if $self->can('_column_comment');
-            $self->_pod( $class, $comment ) if $comment;
+        my $col_counter = 0;
+       my @cols = @_;
+        while( my ($name,$attrs) = splice @cols,0,2 ) {
+           $col_counter++;
+            $self->_pod( $class, '=head2 ' . $name  );
+           $self->_pod( $class,
+                        join "\n", map {
+                            my $s = $attrs->{$_};
+                            $s = !defined $s      ? 'undef'          :
+                                 length($s) == 0  ? '(empty string)' :
+                                                     $s;
+
+                            "  $_: $s"
+                        } sort keys %$attrs,
+                      );
+
+           if( $self->can('_column_comment')
+               and my $comment = $self->_column_comment( $self->{_class2table}{$class}, $col_counter)
+             ) {
+               $self->_pod( $class, $comment );
+           }
         }
         $self->_pod_cut( $class );
     } elsif ( $method =~ /^(belongs_to|has_many|might_have)$/ ) {
@@ -1260,13 +1309,6 @@ sub _dbic_stmt {
         $self->_pod_cut( $class );
         $self->{_relations_started} { $class } = 1;
     }
-    my $args = dump(@_);
-    $args = '(' . $args . ')' if @_ < 2;
-    my $stmt = $method . $args . q{;};
-
-    warn qq|$class\->$stmt\n| if $self->debug;
-    $self->_raw_stmt($class, '__PACKAGE__->' . $stmt);
-    return;
 }
 
 # Stores a POD documentation