Also use Mojo::Pg for user_status and user_travels queries

This commit is contained in:
Daniel Friesel 2019-04-22 11:11:14 +02:00
parent fb3fda9736
commit 4ed24c5565

View file

@ -164,90 +164,6 @@ sub startup {
$user, $pw, { AutoCommit => 1 } ); $user, $pw, { AutoCommit => 1 } );
} }
); );
$self->attr(
get_all_actions_query => sub {
my ($self) = @_;
return $self->app->dbh->prepare(
qq{
select user_actions.id, action_id, extract(epoch from action_time),
stations.ds100, stations.name,
train_type, train_line, train_no, train_id,
extract(epoch from sched_time), extract(epoch from real_time),
route, messages, edited
from user_actions
left outer join stations on station_id = stations.id
where user_id = ?
order by action_time desc
}
);
}
);
$self->attr(
get_last_actions_query => sub {
my ($self) = @_;
return $self->app->dbh->prepare(
qq{
select user_actions.id, action_id, extract(epoch from action_time),
stations.ds100, stations.name,
train_type, train_line, train_no, train_id,
extract(epoch from sched_time), extract(epoch from real_time),
route, messages, edited
from user_actions
left outer join stations on station_id = stations.id
where user_id = ?
order by action_time desc
limit 10
}
);
}
);
$self->attr(
get_interval_actions_query => sub {
my ($self) = @_;
# Note: Selecting on real_time would be more intuitive, but is not
# possible at the moment -- non-realtime checkouts
# lack both sched_time and real_time.
return $self->app->dbh->prepare(
qq{
select user_actions.id, action_id, extract(epoch from action_time),
stations.ds100, stations.name,
train_type, train_line, train_no, train_id,
extract(epoch from sched_time), extract(epoch from real_time),
route, messages, edited
from user_actions
left outer join stations on station_id = stations.id
where user_id = ?
and action_time >= to_timestamp(?)
and action_time < to_timestamp(?)
order by action_time desc
}
);
}
);
$self->attr(
get_journey_actions_query => sub {
my ($self) = @_;
return $self->app->dbh->prepare(
qq{
select user_actions.id, action_id, extract(epoch from action_time),
stations.ds100, stations.name,
train_type, train_line, train_no, train_id,
extract(epoch from sched_time), extract(epoch from real_time),
route, messages, edited
from user_actions
left outer join stations on station_id = stations.id
where user_id = ?
and user_actions.id <= ?
order by action_time desc
limit 2
}
);
}
);
$self->attr( $self->attr(
get_api_tokens_query => sub { get_api_tokens_query => sub {
my ($self) = @_; my ($self) = @_;
@ -1213,14 +1129,31 @@ sub startup {
my ( $self, %opt ) = @_; my ( $self, %opt ) = @_;
my $uid = $opt{uid} || $self->current_user->{id}; my $uid = $opt{uid} || $self->current_user->{id};
my $query = $self->app->get_all_actions_query;
my $selection = qq{
user_actions.id as action_log_id, action_id,
extract(epoch from action_time) as action_time_ts,
stations.ds100 as ds100, stations.name as name,
train_type, train_line, train_no, train_id,
extract(epoch from sched_time) as sched_time_ts,
extract(epoch from real_time) as real_time_ts,
route, messages, edited
};
$selection =~ tr{\n}{}d;
my %where = ( user_id => $uid );
my %order = (
order_by => {
-desc => 'action_time',
}
);
if ( $opt{limit} ) { if ( $opt{limit} ) {
$query = $self->app->get_last_actions_query; $order{limit} = 10;
} }
if ( $opt{checkout_id} ) { if ( $opt{checkout_id} ) {
$query = $self->app->get_journey_actions_query; $where{action_log_id} = { '<=', $opt{checkout_id} };
$query->execute( $uid, $opt{checkout_id} ); $order{limit} = 2;
} }
elsif ( $opt{after} and $opt{before} ) { elsif ( $opt{after} and $opt{before} ) {
@ -1243,16 +1176,14 @@ sub startup {
# This works under the assumption that there are no DB trains whose # This works under the assumption that there are no DB trains whose
# journey takes more than 24 hours. If this no longer holds, # journey takes more than 24 hours. If this no longer holds,
# please adjust the intervals accordingly. # please adjust the intervals accordingly.
$query = $self->app->get_interval_actions_query; $where{action_time} = {
$query->execute( -between => [
$uid, $opt{after}->clone->subtract( days => 1 ),
$opt{after}->clone->subtract( days => 1 )->epoch, $opt{before}->clone->add( days => 1 )
$opt{before}->clone->add( days => 1 )->epoch ]
); };
}
else {
$query->execute($uid);
} }
my @match_actions = ( my @match_actions = (
$self->app->action_type->{checkout}, $self->app->action_type->{checkout},
$self->app->action_type->{checkin} $self->app->action_type->{checkin}
@ -1267,61 +1198,71 @@ sub startup {
my @travels; my @travels;
my $prev_action = 0; my $prev_action = 0;
while ( my @row = $query->fetchrow_array ) { my $res = $self->pg->db->select(
my ( [
$action_id, $action, $raw_ts, 'user_actions',
$ds100, $name, $train_type, [
$train_line, $train_no, $train_id, -left => 'stations',
$raw_sched_ts, $raw_real_ts, $raw_route, id => 'station_id'
$raw_messages, $edited ]
) = @row; ],
$selection,
\%where,
\%order
);
if ( $action == $match_actions[0] for my $entry ( $res->hashes->each ) {
if ( $entry->{action_id} == $match_actions[0]
or ( $opt{checkout_id} and not @travels ) ) or ( $opt{checkout_id} and not @travels ) )
{ {
push( push(
@travels, @travels,
{ {
ids => [ undef, $action_id ], ids => [ undef, $entry->{action_log_id} ],
to_name => $name, to_name => $entry->{name},
sched_arrival => epoch_to_dt($raw_sched_ts), sched_arrival =>
rt_arrival => epoch_to_dt($raw_real_ts), epoch_to_dt( $entry->{sched_time_ts} ),
checkout => epoch_to_dt($raw_ts), rt_arrival => epoch_to_dt( $entry->{real_time_ts} ),
type => $train_type, checkout => epoch_to_dt( $entry->{action_time_ts} ),
line => $train_line, type => $entry->{train_type},
no => $train_no, line => $entry->{train_line},
messages => $raw_messages no => $entry->{train_no},
? [ split( qr{[|]}, $raw_messages ) ] messages => $entry->{messages}
? [ split( qr{[|]}, $entry->{messages} ) ]
: undef, : undef,
route => $raw_route route => $entry->{route}
? [ split( qr{[|]}, $raw_route ) ] ? [ split( qr{[|]}, $entry->{route} ) ]
: undef, : undef,
completed => 0, completed => 0,
edited => $edited << 8, edited => $entry->{edited} << 8,
} }
); );
} }
elsif ( elsif (
( (
$action == $match_actions[1] $entry->{action_id} == $match_actions[1]
and $prev_action == $match_actions[0] and $prev_action == $match_actions[0]
) )
or $opt{checkout_id} or $opt{checkout_id}
) )
{ {
my $ref = $travels[-1]; my $ref = $travels[-1];
$ref->{ids}->[0] = $action_id; $ref->{ids}->[0] = $entry->{action_log_id};
$ref->{from_name} = $name; $ref->{from_name} = $entry->{name};
$ref->{completed} = 1; $ref->{completed} = 1;
$ref->{sched_departure} = epoch_to_dt($raw_sched_ts); $ref->{sched_departure}
$ref->{rt_departure} = epoch_to_dt($raw_real_ts); = epoch_to_dt( $entry->{sched_time_ts} );
$ref->{checkin} = epoch_to_dt($raw_ts); $ref->{rt_departure}
$ref->{type} //= $train_type; = epoch_to_dt( $entry->{real_time_ts} );
$ref->{line} //= $train_line; $ref->{checkin} = epoch_to_dt( $entry->{action_time_ts} );
$ref->{no} //= $train_no; $ref->{type} //= $entry->{train_type};
$ref->{messages} //= [ split( qr{[|]}, $raw_messages ) ]; $ref->{line} //= $entry->{train_line};
$ref->{route} //= [ split( qr{[|]}, $raw_route ) ]; $ref->{no} //= $entry->{train_no};
$ref->{edited} |= $edited; $ref->{messages}
//= [ split( qr{[|]}, $entry->{messages} ) ];
$ref->{route} //= [ split( qr{[|]}, $entry->{route} ) ];
$ref->{edited} |= $entry->{edited};
if ( $opt{verbose} ) { if ( $opt{verbose} ) {
my @parsed_messages; my @parsed_messages;
@ -1363,13 +1304,13 @@ sub startup {
: -1; : -1;
} }
if ( $opt{checkout_id} if ( $opt{checkout_id}
and $action and $entry->{action_id}
== $self->app->action_type->{cancelled_from} ) == $self->app->action_type->{cancelled_from} )
{ {
$ref->{cancelled} = 1; $ref->{cancelled} = 1;
} }
} }
$prev_action = $action; $prev_action = $entry->{action_id};
} }
if ( $opt{before} and $opt{after} ) { if ( $opt{before} and $opt{after} ) {
@ -1411,19 +1352,47 @@ sub startup {
my ( $self, $uid ) = @_; my ( $self, $uid ) = @_;
$uid //= $self->current_user->{id}; $uid //= $self->current_user->{id};
$self->app->get_last_actions_query->execute($uid);
my $rows = $self->app->get_last_actions_query->fetchall_arrayref;
if ( @{$rows} ) { my $selection = qq{
user_actions.id as action_log_id, action_id,
extract(epoch from action_time) as action_time_ts,
stations.ds100 as ds100, stations.name as name,
train_type, train_line, train_no, train_id,
extract(epoch from sched_time) as sched_time_ts,
extract(epoch from real_time) as real_time_ts,
route
};
$selection =~ tr{\n}{}d;
my $res = $self->pg->db->select(
[
'user_actions',
[
-left => 'stations',
id => 'station_id'
]
],
$selection,
{
user_id => $uid,
},
{
order_by => {
-desc => 'action_time',
},
limit => 1,
}
);
my $status = $res->hash;
if ($status) {
my $now = DateTime->now( time_zone => 'Europe/Berlin' ); my $now = DateTime->now( time_zone => 'Europe/Berlin' );
my @cols = @{ $rows->[0] }; my $action_ts = epoch_to_dt( $status->{action_time_ts} );
my $sched_ts = epoch_to_dt( $status->{sched_time_ts} );
my $action_ts = epoch_to_dt( $cols[2] ); my $real_ts = epoch_to_dt( $status->{real_time_ts} );
my $sched_ts = epoch_to_dt( $cols[9] ); my $checkin_station_name = $status->{name};
my $real_ts = epoch_to_dt( $cols[10] ); my @route = split( qr{[|]}, $status->{route} // q{} );
my $checkin_station_name = $cols[4];
my @route = split( qr{[|]}, $cols[11] // q{} );
my @route_after; my @route_after;
my $is_after = 0; my $is_after = 0;
for my $station (@route) { for my $station (@route) {
@ -1436,21 +1405,25 @@ sub startup {
} }
} }
return { return {
checked_in => checked_in => (
( $cols[1] == $self->app->action_type->{checkin} ), $status->{action_id}
cancelled => == $self->app->action_type->{checkin}
( $cols[1] == $self->app->action_type->{cancelled_from} ), ),
cancelled => (
$status->{action_id}
== $self->app->action_type->{cancelled_from}
),
timestamp => $action_ts, timestamp => $action_ts,
timestamp_delta => $now->epoch - $action_ts->epoch, timestamp_delta => $now->epoch - $action_ts->epoch,
action_id => $cols[0], action_id => $status->{action_log_id},
sched_ts => $sched_ts, sched_ts => $sched_ts,
real_ts => $real_ts, real_ts => $real_ts,
station_ds100 => $cols[3], station_ds100 => $status->{ds100},
station_name => $checkin_station_name, station_name => $checkin_station_name,
train_type => $cols[5], train_type => $status->{train_type},
train_line => $cols[6], train_line => $status->{train_line},
train_no => $cols[7], train_no => $status->{train_no},
train_id => $cols[8], train_id => $status->{train_id},
route => \@route, route => \@route,
route_after => \@route_after, route_after => \@route_after,
}; };