2019-02-22 20:56:32 +00:00
|
|
|
#!/usr/bin/env perl
|
|
|
|
|
|
|
|
use strict;
|
|
|
|
use warnings;
|
|
|
|
use 5.020;
|
|
|
|
|
2019-03-04 17:17:03 +00:00
|
|
|
use DateTime;
|
2019-02-22 20:56:32 +00:00
|
|
|
use DBI;
|
|
|
|
|
|
|
|
my $dbname = $ENV{TRAVELYNX_DB_FILE} // 'travelynx.sqlite';
|
|
|
|
my $dbh = DBI->connect( "dbi:SQLite:dbname=${dbname}", q{}, q{} );
|
|
|
|
|
2019-03-04 17:17:03 +00:00
|
|
|
my $has_version_query = $dbh->prepare(
|
|
|
|
qq{
|
2019-02-22 20:56:32 +00:00
|
|
|
select name from sqlite_master
|
|
|
|
where type = 'table' and name = 'schema_version';
|
2019-03-04 17:17:03 +00:00
|
|
|
}
|
|
|
|
);
|
2019-02-22 20:56:32 +00:00
|
|
|
|
|
|
|
sub get_schema_version {
|
|
|
|
$has_version_query->execute();
|
|
|
|
my $rows = $has_version_query->fetchall_arrayref;
|
2019-03-04 17:17:03 +00:00
|
|
|
if ( @{$rows} == 1 ) {
|
|
|
|
my $get_version_query = $dbh->prepare(
|
|
|
|
qq{
|
2019-02-22 20:56:32 +00:00
|
|
|
select version from schema_version;
|
2019-03-04 17:17:03 +00:00
|
|
|
}
|
|
|
|
);
|
2019-02-22 20:56:32 +00:00
|
|
|
$get_version_query->execute();
|
|
|
|
my $rows = $get_version_query->fetchall_arrayref;
|
2019-03-04 17:17:03 +00:00
|
|
|
if ( @{$rows} == 0 ) {
|
2019-02-22 20:56:32 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return $rows->[0][0];
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
my @migrations = (
|
2019-03-04 17:17:03 +00:00
|
|
|
|
2019-02-22 20:56:32 +00:00
|
|
|
# v0 -> v1
|
|
|
|
sub {
|
2019-03-04 17:17:03 +00:00
|
|
|
$dbh->begin_work;
|
|
|
|
$dbh->do(
|
|
|
|
qq{
|
2019-02-22 20:56:32 +00:00
|
|
|
create table schema_version (
|
|
|
|
version integer primary key
|
|
|
|
);
|
2019-03-04 17:17:03 +00:00
|
|
|
}
|
|
|
|
);
|
|
|
|
$dbh->do(
|
|
|
|
qq{
|
2019-02-22 20:56:32 +00:00
|
|
|
insert into schema_version (version) values (1);
|
2019-03-04 17:17:03 +00:00
|
|
|
}
|
|
|
|
);
|
|
|
|
$dbh->do(
|
|
|
|
qq{
|
2019-02-22 20:56:32 +00:00
|
|
|
create table new_users (
|
|
|
|
id integer primary key,
|
|
|
|
name char(64) not null unique,
|
|
|
|
status int not null,
|
2019-03-04 17:17:03 +00:00
|
|
|
is_public bool not null,
|
2019-02-22 20:56:32 +00:00
|
|
|
email char(256),
|
|
|
|
password text,
|
2019-03-04 17:17:03 +00:00
|
|
|
registered_at datetime not null,
|
|
|
|
last_login datetime not null,
|
|
|
|
deletion_requested datetime
|
2019-02-22 20:56:32 +00:00
|
|
|
);
|
2019-03-04 17:17:03 +00:00
|
|
|
}
|
|
|
|
);
|
|
|
|
my $get_users_query = $dbh->prepare(
|
|
|
|
qq{
|
2019-02-22 20:56:32 +00:00
|
|
|
select * from users;
|
2019-03-04 17:17:03 +00:00
|
|
|
}
|
|
|
|
);
|
|
|
|
my $add_user_query = $dbh->prepare(
|
|
|
|
qq{
|
|
|
|
insert into new_users
|
|
|
|
(id, name, status, is_public, registered_at, last_login)
|
|
|
|
values
|
2019-03-06 17:11:26 +00:00
|
|
|
(?, ?, ?, ?, ?, ?);
|
2019-03-04 17:17:03 +00:00
|
|
|
}
|
|
|
|
);
|
|
|
|
$get_users_query->execute;
|
|
|
|
|
|
|
|
while ( my @row = $get_users_query->fetchrow_array ) {
|
|
|
|
my ( $id, $name ) = @row;
|
|
|
|
my $now = DateTime->now( time_zone => 'Europe/Berlin' )->epoch;
|
|
|
|
$add_user_query->execute( $id, $name, 0, 0, $now, $now );
|
|
|
|
}
|
|
|
|
$dbh->do(
|
|
|
|
qq{
|
|
|
|
drop table users;
|
|
|
|
}
|
|
|
|
);
|
|
|
|
$dbh->do(
|
|
|
|
qq{
|
|
|
|
alter table new_users rename to users;
|
|
|
|
}
|
|
|
|
);
|
|
|
|
$dbh->commit;
|
2019-02-22 20:56:32 +00:00
|
|
|
},
|
2019-03-06 17:11:26 +00:00
|
|
|
|
|
|
|
# v1 -> v2
|
|
|
|
sub {
|
|
|
|
$dbh->begin_work;
|
|
|
|
$dbh->do(
|
|
|
|
qq{
|
|
|
|
update schema_version set version = 2;
|
|
|
|
}
|
|
|
|
);
|
|
|
|
$dbh->do(
|
|
|
|
qq{
|
|
|
|
create table new_users (
|
|
|
|
id integer primary key,
|
|
|
|
name char(64) not null unique,
|
|
|
|
status int not null,
|
|
|
|
public_level int not null,
|
|
|
|
email char(256),
|
|
|
|
token char(80),
|
|
|
|
password text,
|
|
|
|
registered_at datetime not null,
|
|
|
|
last_login datetime not null,
|
|
|
|
deletion_requested datetime
|
|
|
|
);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
my $get_users_query = $dbh->prepare(
|
|
|
|
qq{
|
|
|
|
select * from users;
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
# At this point, some "users" fields were never used -> skip those
|
|
|
|
# during migration.
|
|
|
|
my $add_user_query = $dbh->prepare(
|
|
|
|
qq{
|
|
|
|
insert into new_users
|
|
|
|
(id, name, status, public_level, registered_at, last_login)
|
|
|
|
values
|
|
|
|
(?, ?, ?, ?, ?, ?);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
$get_users_query->execute;
|
|
|
|
|
|
|
|
while ( my @row = $get_users_query->fetchrow_array ) {
|
|
|
|
my (
|
|
|
|
$id, $name, $status,
|
|
|
|
$is_public, $email, $password,
|
|
|
|
$reg_at, $last_login, $del_requested
|
|
|
|
) = @row;
|
|
|
|
$add_user_query->execute( $id, $name, $status, $is_public, $reg_at,
|
|
|
|
$last_login );
|
|
|
|
}
|
|
|
|
$dbh->do(
|
|
|
|
qq{
|
|
|
|
drop table users;
|
|
|
|
}
|
|
|
|
);
|
|
|
|
$dbh->do(
|
|
|
|
qq{
|
|
|
|
alter table new_users rename to users;
|
|
|
|
}
|
|
|
|
);
|
|
|
|
$dbh->do(
|
|
|
|
qq{
|
|
|
|
create table pending_mails (
|
|
|
|
email char(256) not null primary key,
|
|
|
|
num_tries int not null,
|
|
|
|
last_try datetime not null
|
|
|
|
);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
$dbh->commit;
|
|
|
|
},
|
2019-02-22 20:56:32 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
my $schema_version = get_schema_version();
|
|
|
|
|
|
|
|
say "Found travelynx schema v${schema_version}";
|
|
|
|
|
2019-03-04 17:17:03 +00:00
|
|
|
if ( $schema_version == @migrations ) {
|
2019-02-22 20:56:32 +00:00
|
|
|
say "Database schema is up-to-date";
|
|
|
|
}
|
|
|
|
|
2019-03-04 17:17:03 +00:00
|
|
|
for my $i ( $schema_version .. $#migrations ) {
|
|
|
|
printf( "Updating to v%d\n", $i + 1 );
|
2019-02-22 20:56:32 +00:00
|
|
|
$migrations[$i]();
|
|
|
|
}
|
2019-03-04 17:17:03 +00:00
|
|
|
|
|
|
|
$dbh->disconnect;
|