Use Mojo::Pg for migrations
This commit is contained in:
parent
2aece36803
commit
c65232904f
1 changed files with 61 additions and 58 deletions
|
@ -8,35 +8,22 @@ has description => 'Initialize or upgrade database layout';
|
||||||
has usage => sub { shift->extract_usage };
|
has usage => sub { shift->extract_usage };
|
||||||
|
|
||||||
sub get_schema_version {
|
sub get_schema_version {
|
||||||
my ($dbh) = @_;
|
my ($db) = @_;
|
||||||
|
my $version;
|
||||||
|
|
||||||
# We do not want DBD to print an SQL error if schema_version does not
|
eval {
|
||||||
# exist, as this is not an error in this case. Setting $dbh->{PrintError} =
|
$version = $db->select( 'schema_version', ['version'] )->hash->{version};
|
||||||
# 0 would disable error printing for all subsequent SQL operations, however,
|
};
|
||||||
# we only want to disable it for this specific query. Hence we use a
|
if ($@) {
|
||||||
# prepared statement and only disable error printing only there.
|
# If it failed, the version table does not exist -> run setup first.
|
||||||
my $sth = $dbh->prepare(qq{select version from schema_version});
|
|
||||||
$sth->{PrintError} = 0;
|
|
||||||
my $success = $sth->execute;
|
|
||||||
|
|
||||||
if ( not defined $success ) {
|
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
return $version;
|
||||||
my $rows = $sth->fetchall_arrayref;
|
|
||||||
|
|
||||||
if ( @{$rows} == 1 ) {
|
|
||||||
return $rows->[0][0];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
printf( "Found multiple schema versions: %s", @{$rows} );
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub initialize_db {
|
sub initialize_db {
|
||||||
my ($dbh) = @_;
|
my ($db) = @_;
|
||||||
return $dbh->do(
|
$db->query(
|
||||||
qq{
|
qq{
|
||||||
create table schema_version (
|
create table schema_version (
|
||||||
version integer primary key
|
version integer primary key
|
||||||
|
@ -93,8 +80,8 @@ my @migrations = (
|
||||||
|
|
||||||
# v0 -> v1
|
# v0 -> v1
|
||||||
sub {
|
sub {
|
||||||
my ($dbh) = @_;
|
my ($db) = @_;
|
||||||
return $dbh->do(
|
$db->query(
|
||||||
qq{
|
qq{
|
||||||
alter table user_actions
|
alter table user_actions
|
||||||
add column edited smallint;
|
add column edited smallint;
|
||||||
|
@ -113,8 +100,8 @@ my @migrations = (
|
||||||
|
|
||||||
# v1 -> v2
|
# v1 -> v2
|
||||||
sub {
|
sub {
|
||||||
my ($dbh) = @_;
|
my ($db) = @_;
|
||||||
return $dbh->do(
|
$db->query(
|
||||||
qq{
|
qq{
|
||||||
update user_actions set edited = 0;
|
update user_actions set edited = 0;
|
||||||
alter table user_actions
|
alter table user_actions
|
||||||
|
@ -129,8 +116,8 @@ my @migrations = (
|
||||||
# reported for routes covering stations without GPS coordinates. Ensure
|
# reported for routes covering stations without GPS coordinates. Ensure
|
||||||
# all caches are rebuilt.
|
# all caches are rebuilt.
|
||||||
sub {
|
sub {
|
||||||
my ($dbh) = @_;
|
my ($db) = @_;
|
||||||
return $dbh->do(
|
$db->query(
|
||||||
qq{
|
qq{
|
||||||
truncate journey_stats;
|
truncate journey_stats;
|
||||||
update schema_version set version = 3;
|
update schema_version set version = 3;
|
||||||
|
@ -140,57 +127,73 @@ my @migrations = (
|
||||||
);
|
);
|
||||||
|
|
||||||
sub setup_db {
|
sub setup_db {
|
||||||
my ($dbh) = @_;
|
my ($db) = @_;
|
||||||
$dbh->begin_work;
|
my $tx = $db->begin;
|
||||||
if ( initialize_db($dbh) ) {
|
eval {
|
||||||
$dbh->commit;
|
initialize_db($db);
|
||||||
}
|
$tx->commit;
|
||||||
else {
|
};
|
||||||
$dbh->rollback;
|
if ($@) {
|
||||||
printf( "Database initialization was not successful: %s",
|
say "Database initialization failed: $@";
|
||||||
$DBI::errstr );
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub migrate_db {
|
sub migrate_db {
|
||||||
my ($dbh) = @_;
|
my ($db) = @_;
|
||||||
$dbh->begin_work;
|
my $tx = $db->begin;
|
||||||
my $schema_version = get_schema_version($dbh);
|
|
||||||
|
my $schema_version = get_schema_version($db);
|
||||||
say "Found travelynx schema v${schema_version}";
|
say "Found travelynx schema v${schema_version}";
|
||||||
|
|
||||||
if ( $schema_version == @migrations ) {
|
if ( $schema_version == @migrations ) {
|
||||||
say "Database layout is up-to-date";
|
say "Database layout is up-to-date";
|
||||||
}
|
}
|
||||||
for my $i ( $schema_version .. $#migrations ) {
|
|
||||||
printf( "Updating to v%d ...\n", $i + 1 );
|
eval {
|
||||||
if ( not $migrations[$i]($dbh) ) {
|
for my $i ( $schema_version .. $#migrations ) {
|
||||||
say "Aborting migration; rollback to v${schema_version}";
|
printf( "Updating to v%d ...\n", $i + 1 );
|
||||||
$dbh->rollback;
|
$migrations[$i]($db);
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
if ($@) {
|
||||||
|
say STDERR "Migration failed: $@";
|
||||||
|
say STDERR "Rolling back to v${schema_version}";
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
if ( get_schema_version($dbh) == @migrations ) {
|
|
||||||
$dbh->commit;
|
if ( get_schema_version($db) == @migrations ) {
|
||||||
|
$tx->commit;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf STDERR (
|
||||||
|
"Database schema mismatch after migrations: Expected %d, got %d\n",
|
||||||
|
scalar @migrations,
|
||||||
|
get_schema_version($db)
|
||||||
|
);
|
||||||
|
say STDERR "Rolling back to v${schema_version}";
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub run {
|
sub run {
|
||||||
my ( $self, $command ) = @_;
|
my ( $self, $command ) = @_;
|
||||||
|
|
||||||
my $dbh = $self->app->dbh;
|
my $db = $self->app->pg->db;
|
||||||
|
|
||||||
if ( not defined $dbh ) {
|
#if ( not defined $dbh ) {
|
||||||
printf( "Can't connect to the database: %s\n", $DBI::errstr );
|
# printf( "Can't connect to the database: %s\n", $DBI::errstr );
|
||||||
exit(1);
|
# exit(1);
|
||||||
}
|
#}
|
||||||
|
|
||||||
if ( $command eq 'migrate' ) {
|
if ( $command eq 'migrate' ) {
|
||||||
if ( not defined get_schema_version($dbh) ) {
|
if ( not defined get_schema_version($db) ) {
|
||||||
setup_db($dbh);
|
setup_db($db);
|
||||||
}
|
}
|
||||||
migrate_db($dbh);
|
migrate_db($db);
|
||||||
}
|
}
|
||||||
elsif ( $command eq 'has-current-schema' ) {
|
elsif ( $command eq 'has-current-schema' ) {
|
||||||
if ( get_schema_version($dbh) == @migrations ) {
|
if ( get_schema_version($db) == @migrations ) {
|
||||||
say "yes";
|
say "yes";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
Loading…
Reference in a new issue