1#!/usr/bin/env perl 2 3use strict; 4use warnings; 5 6our $home; 7 8BEGIN { 9 use FindBin; 10 FindBin::again(); 11 12 $home = ($ENV{NETDISCO_HOME} || $ENV{HOME}); 13 14 # try to find a localenv if one isn't already in place. 15 if (!exists $ENV{PERL_LOCAL_LIB_ROOT}) { 16 use File::Spec; 17 my $localenv = File::Spec->catfile($FindBin::RealBin, 'localenv'); 18 exec($localenv, $0, @ARGV) if -f $localenv; 19 $localenv = File::Spec->catfile($home, 'perl5', 'bin', 'localenv'); 20 exec($localenv, $0, @ARGV) if -f $localenv; 21 22 die "Sorry, can't find libs required for App::Netdisco.\n" 23 if !exists $ENV{PERLBREW_PERL}; 24 } 25} 26 27BEGIN { 28 use Path::Class; 29 30 # stuff useful locations into @INC and $PATH 31 unshift @INC, 32 dir($FindBin::RealBin)->parent->subdir('lib')->stringify, 33 dir($FindBin::RealBin, 'lib')->stringify; 34 35 use Config; 36 $ENV{PATH} = $FindBin::RealBin . $Config{path_sep} . $ENV{PATH}; 37} 38 39use App::Netdisco; 40use Dancer ':script'; 41use Dancer::Plugin::DBIC 'schema'; 42 43use Try::Tiny; 44 45=head1 NAME 46 47netdisco-db-deploy - Database deployment for Netdisco 48 49=head1 USAGE 50 51This script upgrades or initialises a Netdisco database schema. 52 53 ~/bin/netdisco-db-deploy [--redeploy-all] 54 55This script connects to the database and runs without user interaction. If 56there's no Nedisco schema, it is deployed. If there's an unversioned schema 57then versioning is added, and updates applied. Otherwise only necessary 58updates are applied to an already versioned schema. 59 60Pre-existing requirements are that there's a working database connection and a 61user with rights to create tables in that database. These settings are defined 62in your environment YAML file (default C<~/environments/deployment.yml>). 63 64If you wish to force the redeployment of all database configuration, pass the 65C<--redeploy-all> argument on the command line. This will reset your database 66version so the database scripts will run again, but no data will be deleted 67other than what's done via the upgrade scripts. 68 69For more database info see the 70L<netdisco wiki|https://github.com/netdisco/netdisco/wiki/Database-Tips>. 71 72=head1 VERSIONS 73 74=over 4 75 76=item * 77 78Version 1 is a completely empty database schema with no tables 79 80=item * 81 82Version 2 is the "classic" Netdisco database schema as of Netdisco 1.1 83 84=item * 85 86Versions 5 to 16 add patches for Netdisco 1.2 87 88=item * 89 90Version 17 onwards deploys schema upgrades for Netdisco 2 91 92=back 93 94=cut 95 96my $schema = schema('netdisco'); 97 98if (scalar @ARGV and $ARGV[0] and $ARGV[0] eq '--redeploy-all') { 99 $schema->storage->dbh_do( 100 sub { 101 my ($storage, $dbh, @args) = @_; 102 $dbh->do('DROP TABLE dbix_class_schema_versions'); 103 }, 104 ); 105} 106 107# installs the dbix_class_schema_versions table with version "1" 108# which corresponds to an empty schema 109if (not $schema->get_db_version) { 110 $schema->install(1); 111 $schema->storage->disconnect; 112} 113 114# test for existing schema at public release version, set v=2 if so 115try { 116 $schema->storage->dbh_do(sub { 117 my ($storage, $dbh) = @_; 118 $dbh->selectrow_arrayref("SELECT * FROM device WHERE 0 = 1"); 119 }); 120 121 $schema->_set_db_version({version => 2}) 122 if $schema->get_db_version == 1; 123 $schema->storage->disconnect; 124}; 125 126# upgrade from whatever dbix_class_schema_versions says, to $VERSION 127# except that get_db_version will be 0 at first deploy 128my $db_version = ($schema->get_db_version || 1); 129my $target_version = $schema->schema_version; 130 131# one step at a time, in case user has applied local changes already 132for (my $i = $db_version; $i < $target_version; $i++) { 133 my $next = $i + 1; 134 try { 135 $schema->upgrade_single_step($i, $next); 136 } 137 catch { 138 warn "Error: $_" 139 if $_ !~ m/(does not exist|already exists)/; 140 141 # set row in dbix_class_schema_versions table 142 $schema->_set_db_version({version => $next}) 143 if $schema->get_db_version < $next; 144 }; 145} 146 147exit 0; 148