downgrades for explicit version handler + tests
Arthur Axel 'fREW' Schmidt [Sun, 28 Mar 2010 16:14:50 +0000 (11:14 -0500)]
lib/DBIx/Class/DeploymentHandler/VersionHandler/ExplicitVersions.pm
t/version_handlers/explict_versions.t

index eb01339..4cf5472 100644 (file)
@@ -27,72 +27,73 @@ has ordered_versions => (
   is       => 'ro',
   isa      => 'ArrayRef',
   required => 1,
-  trigger  => sub {
-    my $to_version = $_[0]->to_version;
-    my $db_version = $_[0]->database_version;
-
-    croak 'to_version not in ordered_versions'
-      unless grep { $to_version eq $_ } @{ $_[1] };
-
-    croak 'database_version not in ordered_versions'
-      unless grep { $db_version eq $_ } @{ $_[1] };
-
-    for (@{ $_[1] }) {
-      return if $_ eq $db_version;
-      croak 'to_version is before database version in ordered_versions'
-        if $_ eq $to_version;
-    }
-  },
 );
 
+has _index_of_versions => (
+  is         => 'ro',
+  isa        => 'HashRef',
+  lazy_build => 1,
+);
+
+sub _build__index_of_versions {
+  my %ret;
+  my $i = 0;
+  for (@{ $_[0]->ordered_versions }) {
+    $ret{$_} = $i++;
+  }
+  \%ret;
+}
+
 has _version_idx => (
   is         => 'rw',
   isa        => 'Int',
   lazy_build => 1,
 );
 
+sub _build__version_idx { $_[0]->_index_of_versions->{$_[0]->database_version} }
+
 sub _inc_version_idx { $_[0]->_version_idx($_[0]->_version_idx + 1 ) }
 sub _dec_version_idx { $_[0]->_version_idx($_[0]->_version_idx - 1 ) }
 
-sub _build__version_idx {
-  my $self = shift;
-  my $start = $self->database_version;
-  my $idx = 0;
-  for (@{$self->ordered_versions}) {
-    return $idx
-      if $_ eq $self->database_version;
-    $idx++;
-  }
-}
 
 sub next_version_set {
   my $self = shift;
-  return undef
-    if $self->ordered_versions->[$self->_version_idx] eq $self->to_version;
-
-  # this should never get in infinite loops because we ensure
-  # that the database version is in the list in the version_idx
-  # builder
-  my $next_idx = $self->_inc_version_idx;
-  return [
-    $self->ordered_versions->[$next_idx - 1],
-    $self->ordered_versions->[$next_idx    ],
-  ];
+  if (
+    $self->_index_of_versions->{$self->to_version} <
+    $self->_version_idx
+  ) {
+    croak "you are trying to upgrade and your current version is greater\n".
+          "than the version you are trying to upgrade to.  Either downgrade\n".
+          "or update your schema"
+  } elsif ( $self->_version_idx == $self->_index_of_versions->{$self->to_version}) {
+    return undef
+  } else {
+    my $next_idx = $self->_inc_version_idx;
+    return [
+      $self->ordered_versions->[$next_idx - 1],
+      $self->ordered_versions->[$next_idx    ],
+    ];
+  }
 }
 
 sub previous_version_set {
   my $self = shift;
-  return undef
-    if $self->ordered_versions->[$self->_version_idx] eq $self->database_version;
-
-  # this should never get in infinite loops because we ensure
-  # that the database version is in the list in the version_idx
-  # builder
-  my $next_idx = $self->_dec_version_idx;
-  return [
-    $self->ordered_versions->[$next_idx - 1],
-    $self->ordered_versions->[$next_idx    ],
-  ];
+  if (
+    $self->_index_of_versions->{$self->to_version} >
+    $self->_version_idx
+  ) {
+    croak "you are trying to downgrade and your current version is less\n".
+          "than the version you are trying to downgrade to.  Either upgrade\n".
+          "or update your schema"
+  } elsif ( $self->_version_idx == $self->_index_of_versions->{$self->to_version}) {
+    return undef
+  } else {
+    my $next_idx = $self->_dec_version_idx;
+    return [
+      $self->ordered_versions->[$next_idx    ],
+      $self->ordered_versions->[$next_idx + 1],
+    ];
+  }
 }
 
 __PACKAGE__->meta->make_immutable;
index 4eb4b6a..de2a63f 100644 (file)
@@ -73,13 +73,42 @@ my $versions = [map "$_.0", 0..100];
   ok( !$vh->next_version_set, 'still no more versions after final pair' );
 }
 
+{
+  my $vh = ExplicitVersions->new({
+    ordered_versions => $versions,
+    to_version => '1.0',
+    schema_version => '5.0',
+    database_version => '5.0',
+  });
+
+  ok $vh, 'VersionHandler gets instantiated';
+  ok(
+    eq_array(::DwarnS($vh->previous_version_set), [qw( 4.0 5.0 )]),
+    'first version pair works'
+  );
+  ok(
+    eq_array($vh->previous_version_set, [qw( 3.0 4.0 )]),
+    'second version pair works'
+  );
+  ok(
+    eq_array($vh->previous_version_set, [qw( 2.0 3.0 )]),
+    'third version pair works'
+  );
+  ok(
+    eq_array($vh->previous_version_set, [qw( 1.0 2.0 )]),
+    'fourth version pair works'
+  );
+  ok( !$vh->previous_version_set, 'no more versions after final pair' );
+  ok( !$vh->previous_version_set, 'still no more versions after final pair' );
+}
+
 dies_ok {
   my $vh = ExplicitVersions->new({
     ordered_versions => $versions,
     schema_version => '2.0',
     database_version => '1.1',
   });
-  $vh->next_vesion_set
+  $vh->next_version_set
 } 'dies if database version not found in ordered_versions';
 
 dies_ok {
@@ -89,6 +118,7 @@ dies_ok {
     schema_version => '1.0',
     database_version => '1.0',
   });
+  $vh->next_version_set;
 } 'cannot request a version before the current version';
 
 done_testing;