X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits%2FDBIx-Class-DeploymentHandler.git;a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FDeploymentHandler.pm;h=d1050c6a4693f493edacf605419d15f1a49fef10;hp=76d48e0d8dca65a0e5ed3cad80b8aff070648891;hb=704577c75e5c38317c495466d15571cc904623eb;hpb=973d060d37345288521092cf85a080bd3e16e1a0 diff --git a/lib/DBIx/Class/DeploymentHandler.pm b/lib/DBIx/Class/DeploymentHandler.pm index 76d48e0..d1050c6 100644 --- a/lib/DBIx/Class/DeploymentHandler.pm +++ b/lib/DBIx/Class/DeploymentHandler.pm @@ -1,100 +1,218 @@ package DBIx::Class::DeploymentHandler; +# ABSTRACT: Extensible DBIx::Class deployment + use Moose; -use Method::Signatures::Simple; -require DBIx::Class::Schema; # loaded for type constraint -require DBIx::Class::ResultSet; # loaded for type constraint -use Carp::Clan '^DBIx::Class::DeploymentHandler'; - -with 'DBIx::Class::DeploymentHandler::WithSqltDeployMethod', - 'DBIx::Class::DeploymentHandler::WithDatabaseToSchemaVersions', - 'DBIx::Class::DeploymentHandler::WithStandardVersionStorage'; - -BEGIN { - use Moose::Util::TypeConstraints; - subtype 'DBIx::Class::DeploymentHandler::Databases' - => as 'ArrayRef[Str]'; - - coerce 'DBIx::Class::DeploymentHandler::Databases' - => from 'Str' - => via { [$_] }; - no Moose::Util::TypeConstraints; -} -has schema => ( - isa => 'DBIx::Class::Schema', - is => 'ro', - required => 1, -); - -has upgrade_directory => ( # configuration - isa => 'Str', - is => 'ro', - required => 1, - default => 'sql', -); - -has backup_directory => ( # configuration - isa => 'Str', - is => 'ro', - predicate => 'has_backup_directory', -); - -has to_version => ( # configuration - is => 'ro', - lazy_build => 1, # builder comes from another role... - # which is... probably not how we want it -); - -has databases => ( # configuration - coerce => 1, - isa => 'DBIx::Class::DeploymentHandler::Databases', - is => 'ro', - default => sub { [qw( MySQL SQLite PostgreSQL )] }, -); - -has sqltargs => ( # configuration - isa => 'HashRef', - is => 'ro', - default => sub { {} }, -); - -method install { - carp 'Install not possible as versions table already exists in database' - if $self->version_storage_is_installed; - - my $new_version = $self->to_version; - - if ($new_version) { - $self->_deploy; - - $self->add_database_version({ - version => $new_version, - # ddl => $ddl, - # upgrade_sql => $upgrade_sql, - }); - } +extends 'DBIx::Class::DeploymentHandler::Dad'; +# a single with would be better, but we can't do that +# see: http://rt.cpan.org/Public/Bug/Display.html?id=46347 +with 'DBIx::Class::DeploymentHandler::WithApplicatorDumple' => { + interface_role => 'DBIx::Class::DeploymentHandler::HandlesDeploy', + class_name => 'DBIx::Class::DeploymentHandler::DeployMethod::SQL::Translator', + delegate_name => 'deploy_method', + attributes_to_assume => [qw(schema schema_version)], + attributes_to_copy => [qw( + ignore_ddl databases script_directory sql_translator_args force_overwrite + )], + }, + 'DBIx::Class::DeploymentHandler::WithApplicatorDumple' => { + interface_role => 'DBIx::Class::DeploymentHandler::HandlesVersioning', + class_name => 'DBIx::Class::DeploymentHandler::VersionHandler::Monotonic', + delegate_name => 'version_handler', + attributes_to_assume => [qw( database_version schema_version to_version )], + }, + 'DBIx::Class::DeploymentHandler::WithApplicatorDumple' => { + interface_role => 'DBIx::Class::DeploymentHandler::HandlesVersionStorage', + class_name => 'DBIx::Class::DeploymentHandler::VersionStorage::Standard', + delegate_name => 'version_storage', + attributes_to_assume => ['schema'], + }; +with 'DBIx::Class::DeploymentHandler::WithReasonableDefaults'; + +sub prepare_version_storage_install { + my $self = shift; + + $self->prepare_resultsource_install({ + result_source => $self->version_storage->version_rs->result_source + }); } -sub upgrade { +sub install_version_storage { my $self = shift; - while ( my $version_list = $self->next_version_set ) { - $self->_upgrade_single_step($version_list); - - $self->add_database_version({ - version => $version_list->[-1], - # ddl => $ddl, - # upgrade_sql => $upgrade_sql, - }); - } + + my $version = (shift||{})->{version} || $self->schema_version; + + $self->install_resultsource({ + result_source => $self->version_storage->version_rs->result_source, + version => $version, + }); } -method backup { $self->storage->backup($self->backup_directory) } +sub prepare_install { + $_[0]->prepare_deploy; + $_[0]->prepare_version_storage_install; +} +# the following is just a hack so that ->version_storage +# won't be lazy +sub BUILD { $_[0]->version_storage } __PACKAGE__->meta->make_immutable; 1; +#vim: ts=2 sw=2 expandtab + __END__ -vim: ts=2 sw=2 expandtab +=head1 SYNOPSIS + + use aliased 'DBIx::Class::DeploymentHandler' => 'DH'; + my $s = My::Schema->connect(...); + + my $dh = DH->new({ + schema => $s, + databases => 'SQLite', + sql_translator_args => { add_drop_table => 0 }, + }); + + $dh->prepare_install; + + $dh->install; + +or for upgrades: + + use aliased 'DBIx::Class::DeploymentHandler' => 'DH'; + my $s = My::Schema->connect(...); + + my $dh = DH->new({ + schema => $s, + databases => 'SQLite', + sql_translator_args => { add_drop_table => 0 }, + }); + + $dh->prepare_upgrade(1, 2); + + $dh->upgrade; + +=head1 DESCRIPTION + +C is, as it's name suggests, a tool for +deploying and upgrading databases with L. It is designed to be +much more flexible than L, hence the use of +L and lots of roles. + +C itself is just a recommended set of roles +that we think will not only work well for everyone, but will also yeild the +best overall mileage. Each role it uses has it's own nuances and +documentation, so I won't describe all of them here, but here are a few of the +major benefits over how L worked (and +L tries to maintain compatibility +with): + +=over + +=item * + +Downgrades in addition to upgrades. + +=item * + +Multiple sql files files per upgrade/downgrade/install. + +=item * + +Perl scripts allowed for upgrade/downgrade/install. + +=item * + +Just one set of files needed for upgrade, unlike before where one might need +to generate C, which is just silly. + +=item * + +And much, much more! + +=back + +That's really just a taste of some of the differences. Check out each role for +all the details. + +=head1 WHERE IS ALL THE DOC?! + +C extends +L, so that's probably the first place to +look when you are trying to figure out how everything works. + +Next would be to look at all the pieces that fill in the blanks that +L expects to be filled. They would be +L, +L, +L, and +L. + +=method prepare_version_storage_install + + $dh->prepare_version_storage_install + +Creates the needed C<.sql> file to install the version storage and not the rest +of the tables + +=method prepare_install + + $dh->prepare_install + +First prepare all the tables to be installed and the prepare just the version +storage + +=method install_version_storage + + $dh->install_version_storage + +Install the version storage and not the rest of the tables + +=head1 THIS SUCKS + +You started your project and weren't using C? +Lucky for you I had you in mind when I wrote this doc. + +First off, you'll want to just install the C: + + my $s = My::Schema->connect(...); + my $dh = DBIx::Class::DeploymentHandler->({ schema => $s }); + + $dh->prepare_version_storage_install; + $dh->install_version_storage; + +Then set your database version: + + $dh->add_database_version({ version => $s->version }); + +Now you should be able to use C like normal! + +=head1 LOGGING + +This is a complex tool, and because of that sometimes you'll want to see +what exactly is happening. The best way to do that is to use the built in +logging functionality. It the standard six log levels; C, C, +C, C, C, and C. Most of those are pretty self +explanatory. Generally a safe level to see what all is going on is debug, +which will give you everything except for the exact SQL being run. + +To enable the various logging levels all you need to do is set an environment +variables: C, C, C, C, +C, and C. Each level can be set on it's own, +but the default is the first three on and the last three off, and the levels +cascade, so if you turn on trace the rest will turn on automatically. + +=head1 DONATIONS + +If you'd like to thank me for the work I've done on this module, don't give me +a donation. I spend a lot of free time creating free software, but I do it +because I love it. + +Instead, consider donating to someone who might actually need it. Obviously +you should do research when donating to a charity, so don't just take my word +on this. I like Children's Survival Fund: +L, but there are a host of other +charities that can do much more good than I will with your money.