fix ExplicitVersions to downgrade in a sensible order
[dbsrgits/DBIx-Class-DeploymentHandler.git] / lib / DBIx / Class / DeploymentHandler / VersionHandler / ExplicitVersions.pm
1 package DBIx::Class::DeploymentHandler::VersionHandler::ExplicitVersions;
2 use Moose;
3
4 # ABSTRACT: Define your own list of versions to use for migrations
5
6 use Carp 'croak';
7
8 with 'DBIx::Class::DeploymentHandler::HandlesVersioning';
9
10 has schema_version => (
11   isa      => 'Str',
12   is       => 'ro',
13   required => 1,
14 );
15
16 has database_version => (
17   isa      => 'Str',
18   is       => 'ro',
19   required => 1,
20 );
21
22 has to_version => (
23   is         => 'ro',
24   lazy_build => 1,
25 );
26
27 sub _build_to_version { $_[0]->schema_version }
28
29 has ordered_versions => (
30   is       => 'ro',
31   isa      => 'ArrayRef',
32   required => 1,
33 );
34
35 has _index_of_versions => (
36   is         => 'ro',
37   isa        => 'HashRef',
38   lazy_build => 1,
39 );
40
41 sub _build__index_of_versions {
42   my %ret;
43   my $i = 0;
44   for (@{ $_[0]->ordered_versions }) {
45     $ret{$_} = $i++;
46   }
47   \%ret;
48 }
49
50 has _version_idx => (
51   is         => 'rw',
52   isa        => 'Int',
53   lazy_build => 1,
54 );
55
56 sub _build__version_idx { $_[0]->_index_of_versions->{$_[0]->database_version} }
57
58 sub _inc_version_idx { $_[0]->_version_idx($_[0]->_version_idx + 1 ) }
59 sub _dec_version_idx { $_[0]->_version_idx($_[0]->_version_idx - 1 ) }
60
61
62 sub next_version_set {
63   my $self = shift;
64   if (
65     $self->_index_of_versions->{$self->to_version} <
66     $self->_version_idx
67   ) {
68     croak "you are trying to upgrade and your current version is greater\n".
69           "than the version you are trying to upgrade to.  Either downgrade\n".
70           "or update your schema"
71   } elsif ( $self->_version_idx == $self->_index_of_versions->{$self->to_version}) {
72     return undef
73   } else {
74     my $next_idx = $self->_inc_version_idx;
75     return [
76       $self->ordered_versions->[$next_idx - 1],
77       $self->ordered_versions->[$next_idx    ],
78     ];
79   }
80 }
81
82 sub previous_version_set {
83   my $self = shift;
84   if (
85     $self->_index_of_versions->{$self->to_version} >
86     $self->_version_idx
87   ) {
88     croak "you are trying to downgrade and your current version is less\n".
89           "than the version you are trying to downgrade to.  Either upgrade\n".
90           "or update your schema"
91   } elsif ( $self->_version_idx == $self->_index_of_versions->{$self->to_version}) {
92     return undef
93   } else {
94     my $next_idx = $self->_dec_version_idx;
95     return [
96       $self->ordered_versions->[$next_idx + 1],
97       $self->ordered_versions->[$next_idx    ],
98     ];
99   }
100 }
101
102 __PACKAGE__->meta->make_immutable;
103
104 1;
105
106 # vim: ts=2 sw=2 expandtab
107
108 __END__
109