working downgrades!
Arthur Axel 'fREW' Schmidt [Sat, 27 Mar 2010 08:59:12 +0000 (03:59 -0500)]
lib/DBIx/Class/DeploymentHandler/HandlesVersionStorage.pm
lib/DBIx/Class/DeploymentHandler/HandlesVersioning.pm
lib/DBIx/Class/DeploymentHandler/VersionHandler/DatabaseToSchemaVersions.pm
lib/DBIx/Class/DeploymentHandler/VersionHandler/ExplicitVersions.pm
lib/DBIx/Class/DeploymentHandler/VersionStorage/Deprecated.pm
lib/DBIx/Class/DeploymentHandler/VersionStorage/Standard.pm
t/lib/DBICDHTest.pm
t/lib/DBICVersion_v4.pm [new file with mode: 0644]

index 87d1134..8f535b4 100644 (file)
@@ -3,6 +3,7 @@ use Moose::Role;
 
 requires 'database_version';
 requires 'add_database_version';
+requires 'delete_database_version';
 requires 'version_storage_is_installed';
 
 1;
index 7cfbd71..c3d15dd 100644 (file)
@@ -1,7 +1,9 @@
 package DBIx::Class::DeploymentHandler::HandlesVersioning;
 use Moose::Role;
 
+# note: the sets returned need to match!
 requires 'next_version_set';
+requires 'previous_version_set';
 
 1;
 
index 7be88f4..2a2e5fc 100644 (file)
@@ -41,6 +41,17 @@ sub next_version_set {
   return [$self->database_version, $self->to_version];
 }
 
+sub previous_version_set {
+  my $self = shift;
+  return undef
+    if $self->once;
+
+  $self->once(!$self->once);
+  return undef
+    if $self->database_version eq $self->to_version;
+  return [$self->database_version, $self->to_version];
+}
+
 
 __PACKAGE__->meta->make_immutable;
 
index c87b36e..396e934 100644 (file)
@@ -53,6 +53,7 @@ has _version_idx => (
 );
 
 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;
@@ -80,6 +81,21 @@ sub next_version_set {
   ];
 }
 
+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    ],
+  ];
+}
+
 __PACKAGE__->meta->make_immutable;
 
 1;
index 72ffb3c..282bf49 100644 (file)
@@ -31,6 +31,10 @@ sub add_database_version {
   $_[0]->version_rs->create({ version => $_[1]->{version} })
 }
 
+sub delete_database_version {
+  $_[0]->version_rs->search({ version => $_[1]->{version}})->delete
+}
+
 __PACKAGE__->meta->make_immutable;
 
 1;
index 78265aa..8acb6a8 100644 (file)
@@ -27,6 +27,10 @@ sub _build_version_rs {
 
 sub add_database_version { $_[0]->version_rs->create($_[1]) }
 
+sub delete_database_version {
+  $_[0]->version_rs->search({ version => $_[1]->{version}})->delete
+}
+
 __PACKAGE__->meta->make_immutable;
 
 1;
index 08a7db2..908b767 100644 (file)
@@ -26,6 +26,7 @@ sub test_bundle {
        VERSION1: {
                use_ok 'DBICVersion_v1';
                my $s = DBICVersion::Schema->connect(@connection);
+               is $s->schema_version, '1.0', 'schema version is at 1.0';
                ok($s, 'DBICVersion::Schema 1.0 instantiates correctly');
                my $handler = $bundle->new({
                        upgrade_directory => $sql_dir,
@@ -58,6 +59,7 @@ sub test_bundle {
        VERSION2: {
                use_ok 'DBICVersion_v2';
                my $s = DBICVersion::Schema->connect(@connection);
+               is $s->schema_version, '2.0', 'schema version is at 2.0';
                ok($s, 'DBICVersion::Schema 2.0 instantiates correctly');
                my $handler = $bundle->new({
                        upgrade_directory => $sql_dir,
@@ -70,7 +72,6 @@ sub test_bundle {
                my $version = $s->schema_version();
                $handler->prepare_install();
                $handler->prepare_upgrade('1.0', $version);
-               $handler->prepare_upgrade($version, '1.0');
                dies_ok {
                        $s->resultset('Foo')->create({
                                bar => 'frew',
@@ -95,6 +96,7 @@ sub test_bundle {
        VERSION3: {
                use_ok 'DBICVersion_v3';
                my $s = DBICVersion::Schema->connect(@connection);
+               is $s->schema_version, '3.0', 'schema version is at 3.0';
                ok($s, 'DBICVersion::Schema 3.0 instantiates correctly');
                my $handler = $bundle->new({
                        upgrade_directory => $sql_dir,
@@ -106,7 +108,6 @@ sub test_bundle {
 
                my $version = $s->schema_version();
                $handler->prepare_install;
-               $handler->prepare_upgrade( '1.0', $version );
                $handler->prepare_upgrade( '2.0', $version );
                dies_ok {
                        $s->resultset('Foo')->create({
@@ -124,6 +125,44 @@ sub test_bundle {
                        })
                } 'schema is deployed';
        }
+
+       DOWN2: {
+               use_ok 'DBICVersion_v4';
+               my $s = DBICVersion::Schema->connect(@connection);
+               is $s->schema_version, '2.0', 'schema version is at 2.0';
+               ok($s, 'DBICVersion::Schema 2.0 instantiates correctly');
+               my $handler = $bundle->new({
+                       upgrade_directory => $sql_dir,
+                       schema => $s,
+                       databases => 'SQLite',
+               });
+
+               ok($handler, 'DBIx::Class::DeploymentHandler w/2.0 instantiates correctly');
+
+               my $version = $s->schema_version();
+               $handler->prepare_downgrade('3.0', $version);
+               lives_ok {
+                       $s->resultset('Foo')->create({
+                               bar => 'frew',
+                               baz => 'frew',
+                               biff => 'frew',
+                       })
+               } 'schema at version 3';
+               $handler->downgrade;
+               dies_ok {
+                       $s->resultset('Foo')->create({
+                               bar => 'frew',
+                               baz => 'frew',
+                               biff => 'frew',
+                       })
+               } 'schema not at version 3';
+               lives_ok {
+                       $s->resultset('Foo')->create({
+                               bar => 'frew',
+                               baz => 'frew',
+                       })
+               } 'schema is at version 2';
+       }
 }
 
 
diff --git a/t/lib/DBICVersion_v4.pm b/t/lib/DBICVersion_v4.pm
new file mode 100644 (file)
index 0000000..602a1c3
--- /dev/null
@@ -0,0 +1,37 @@
+package DBICVersion::Foo;
+
+use base 'DBIx::Class::Core';
+use strict;
+use warnings;
+
+__PACKAGE__->table('Foo');
+
+__PACKAGE__->add_columns(
+       foo => {
+               data_type => 'INTEGER',
+               is_auto_increment => 1,
+       },
+       bar => {
+               data_type => 'VARCHAR',
+               size => '10'
+       },
+       baz => {
+               data_type => 'VARCHAR',
+               size => '10',
+               is_nullable => 1,
+       },
+);
+
+__PACKAGE__->set_primary_key('foo');
+
+package DBICVersion::Schema;
+use base 'DBIx::Class::Schema';
+use strict;
+use warnings;
+
+our $VERSION = '2.0';
+
+__PACKAGE__->register_class('Foo', 'DBICVersion::Foo');
+__PACKAGE__->load_components('DeploymentHandler::VersionStorage::Standard::Component');
+
+1;