1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
|
package DBIx::Class::DeploymentHandler::Dad;
$DBIx::Class::DeploymentHandler::Dad::VERSION = '0.002233';
# ABSTRACT: Parent class for DeploymentHandlers
use Moose;
require DBIx::Class::Schema; # loaded for type constraint
use Carp::Clan '^DBIx::Class::DeploymentHandler';
use DBIx::Class::DeploymentHandler::LogImporter ':log';
use DBIx::Class::DeploymentHandler::Types;
has schema => (
is => 'ro',
required => 1,
);
has backup_directory => (
isa => 'Str',
is => 'ro',
predicate => 'has_backup_directory',
);
has to_version => (
is => 'ro',
isa => 'Str',
lazy_build => 1,
);
sub _build_to_version {
my $version = $_[0]->schema_version;
ref($version) ? $version->numify : $version;
}
has schema_version => (
is => 'ro',
lazy_build => 1,
);
sub _build_schema_version { $_[0]->schema->schema_version }
sub install {
my $self = shift;
my $version = (shift @_ || {})->{version} || $self->to_version;
log_info { "installing version $version" };
croak 'Install not possible as versions table already exists in database'
if $self->version_storage_is_installed;
$self->txn_do(sub {
my $ddl = $self->deploy({ version=> $version });
$self->add_database_version({
version => $version,
ddl => $ddl,
});
});
}
sub upgrade {
log_info { 'upgrading' };
my $self = shift;
my $ran_once = 0;
$self->txn_do(sub {
while ( my $version_list = $self->next_version_set ) {
$ran_once = 1;
my ($ddl, $upgrade_sql) = @{
$self->upgrade_single_step({ version_set => $version_list })
||[]};
$self->add_database_version({
version => $version_list->[-1],
ddl => $ddl,
upgrade_sql => $upgrade_sql,
});
}
});
log_warn { 'no need to run upgrade' } unless $ran_once;
}
sub downgrade {
log_info { 'downgrading' };
my $self = shift;
my $ran_once = 0;
$self->txn_do(sub {
while ( my $version_list = $self->previous_version_set ) {
$ran_once = 1;
$self->downgrade_single_step({ version_set => $version_list });
# do we just delete a row here? I think so but not sure
$self->delete_database_version({ version => $version_list->[0] });
}
});
log_warn { 'no version to run downgrade' } unless $ran_once;
}
sub backup {
my $self = shift;
log_info { 'backing up' };
$self->schema->storage->backup($self->backup_directory)
}
__PACKAGE__->meta->make_immutable;
1;
# vim: ts=2 sw=2 expandtab
__END__
=pod
=head1 NAME
DBIx::Class::DeploymentHandler::Dad - Parent class for DeploymentHandlers
=head1 METHODS THAT ARE REQUIRED IN SUBCLASSES
=head2 deploy
See L<DBIx::Class::DeploymentHandler::HandlesDeploy/deploy>.
=head2 version_storage_is_installed
See L<DBIx::Class::DeploymentHandler::HandlesVersionStorage/version_storage_is_installed>.
=head2 add_database_version
See L<DBIx::Class::DeploymentHandler::HandlesVersionStorage/add_database_version>.
=head2 delete_database_version
See L<DBIx::Class::DeploymentHandler::HandlesVersionStorage/delete_database_version>.
=head2 next_version_set
See L<DBIx::Class::DeploymentHandler::HandlesVersioning/next_version_set>.
=head2 previous_version_set
See L<DBIx::Class::DeploymentHandler::HandlesVersioning/previous_version_set>.
=head2 upgrade_single_step
See L<DBIx::Class::DeploymentHandler::HandlesDeploy/upgrade_single_step>.
=head2 downgrade_single_step
See L<DBIx::Class::DeploymentHandler::HandlesDeploy/downgrade_single_step>.
=head2 txn_do
See L<DBIx::Class::DeploymentHandler::HandlesDeploy/txn_do>.
=head1 ORTHODOX METHODS
These methods are not actually B<required> as things will probably still work
if you don't implement them, but if you want your subclass to get along with
other subclasses (or more likely, tools made to use another subclass), you
should probably implement these too, even if they are no-ops.
=head2 database_version
see L<DBIx::Class::DeploymentHandler::HandlesVersionStorage/database_version>
=head2 prepare_deploy
see L<DBIx::Class::DeploymentHandler::HandlesDeploy/prepare_deploy>
=head2 prepare_resultsource_install
see L<DBIx::Class::DeploymentHandler::HandlesDeploy/prepare_resultsource_install>
=head2 install_resultsource
see L<DBIx::Class::DeploymentHandler::HandlesDeploy/install_resultsource>
=head2 prepare_upgrade
see L<DBIx::Class::DeploymentHandler::HandlesDeploy/prepare_upgrade>
=head2 prepare_downgrade
see L<DBIx::Class::DeploymentHandler::HandlesDeploy/prepare_downgrade>
=head2 SUBCLASSING
All of the methods mentioned in L</METHODS THAT ARE REQUIRED IN SUBCLASSES> and
L</ORTHODOX METHODS> can be implemented in any fashion you choose. In the
spirit of code reuse I have used roles to implement them in my two subclasses,
L<DBIx::Class::DeploymentHandler> and
L<DBIx::Class::DeploymentHandler::Deprecated>, but you are free to implement
them entirely in a subclass if you so choose to.
For in-depth documentation on how methods are supposed to work, see the roles
L<DBIx::Class::DeploymentHandler::HandlesDeploy>,
L<DBIx::Class::DeploymentHandler::HandlesVersioning>, and
L<DBIx::Class::DeploymentHandler::HandlesVersionStorage>.
=head1 ATTRIBUTES
=head2 schema
The L<DBIx::Class::Schema> (B<required>) that is used to talk to the database
and generate the DDL.
=head2 schema_version
The version that the schema is currently at. Defaults to
C<< $self->schema->schema_version >>.
=head2 backup_directory
The directory where backups are stored
=head2 to_version
The version (defaults to schema's version) to migrate the database to
=head1 METHODS
=head2 install
$dh->install
or
$dh->install({ version => 1 })
Deploys the requested version into the database Version defaults to
L</schema_version>. Populates C<version_storage> with C<version> and C<ddl>.
B<Note>: you typically need to call C<< $dh->prepare_deploy >> before you call
this method.
B<Note>: you cannot install on top of an already installed database
=head2 upgrade
$dh->upgrade
Upgrades the database one step at a time till L</next_version_set>
returns C<undef>. Each upgrade step will add a C<version>, C<ddl>, and
C<upgrade_sql> to the version storage (if C<ddl> and/or C<upgrade_sql> are
returned from L</upgrade_single_step>.
=head2 downgrade
$dh->downgrade
Downgrades the database one step at a time till L</previous_version_set>
returns C<undef>. Each downgrade step will delete a C<version> from the
version storage.
=head2 backup
$dh->backup
Simply calls backup on the C<< $schema->storage >>, passing in
C<< $self->backup_directory >> as an argument. Please test yourself before
assuming it will work.
=head1 AUTHOR
Arthur Axel "fREW" Schmidt <frioux+cpan@gmail.com>
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2019 by Arthur Axel "fREW" Schmidt.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut
|