move in_transit queries to an InTransit model class

This commit is contained in:
Daniel Friesel 2020-10-11 19:38:01 +02:00
parent b6330217f0
commit b1348c7d4a
7 changed files with 503 additions and 278 deletions

View file

@ -21,6 +21,7 @@ use Travelynx::Helper::HAFAS;
use Travelynx::Helper::IRIS; use Travelynx::Helper::IRIS;
use Travelynx::Helper::Sendmail; use Travelynx::Helper::Sendmail;
use Travelynx::Helper::Traewelling; use Travelynx::Helper::Traewelling;
use Travelynx::Model::InTransit;
use Travelynx::Model::Journeys; use Travelynx::Model::Journeys;
use Travelynx::Model::Traewelling; use Travelynx::Model::Traewelling;
use Travelynx::Model::Users; use Travelynx::Model::Users;
@ -314,6 +315,16 @@ sub startup {
} }
); );
$self->helper(
in_transit => sub {
my ($self) = @_;
state $in_transit = Travelynx::Model::InTransit->new(
log => $self->app->log,
pg => $self->pg,
);
}
);
$self->helper( $self->helper(
journeys => sub { journeys => sub {
my ($self) = @_; my ($self) = @_;
@ -454,34 +465,12 @@ sub startup {
} }
eval { eval {
my $json = JSON->new; $self->in_transit->add(
$db->insert( uid => $uid,
'in_transit', db => $db,
{ departure_eva => $status->{station_eva},
user_id => $uid, train => $train,
cancelled => $train->departure_is_cancelled route => [ $self->iris->route_diff($train) ],
? 1
: 0,
checkin_station_id => $status->{station_eva},
checkin_time =>
DateTime->now( time_zone => 'Europe/Berlin' ),
dep_platform => $train->platform,
train_type => $train->type,
train_line => $train->line_no,
train_no => $train->train_no,
train_id => $train->train_id,
sched_departure => $train->sched_departure,
real_departure => $train->departure,
route => $json->encode(
[ $self->route_diff($train) ]
),
messages => $json->encode(
[
map { [ $_->[0]->epoch, $_->[1] ] }
$train->messages
]
)
}
); );
}; };
if ($@) { if ($@) {
@ -507,9 +496,7 @@ sub startup {
$uid //= $self->current_user->{id}; $uid //= $self->current_user->{id};
if ( $journey_id eq 'in_transit' ) { if ( $journey_id eq 'in_transit' ) {
eval { eval { $self->in_transit->delete( uid => $uid ); };
$self->pg->db->delete( 'in_transit', { user_id => $uid } );
};
if ($@) { if ($@) {
$self->app->log->error("Undo($uid, $journey_id): $@"); $self->app->log->error("Undo($uid, $journey_id): $@");
return "Undo($journey_id): $@"; return "Undo($journey_id): $@";
@ -550,7 +537,10 @@ sub startup {
delete $journey->{edited}; delete $journey->{edited};
delete $journey->{id}; delete $journey->{id};
$db->insert( 'in_transit', $journey ); $self->in_transit->add_from_journey(
db => $db,
journey => $journey
);
my $cache_ts = DateTime->now( time_zone => 'Europe/Berlin' ); my $cache_ts = DateTime->now( time_zone => 'Europe/Berlin' );
if ( $journey->{real_departure} if ( $journey->{real_departure}
@ -603,10 +593,11 @@ sub startup {
return ( 1, $status->{errstr} ); return ( 1, $status->{errstr} );
} }
my $now = DateTime->now( time_zone => 'Europe/Berlin' ); my $now = DateTime->now( time_zone => 'Europe/Berlin' );
my $journey my $journey = $self->in_transit->get(
= $db->select( 'in_transit', '*', { user_id => $uid } ) uid => $uid,
->expand->hash; with_data => 1
);
# Note that a train may pass the same station several times. # Note that a train may pass the same station several times.
# Notable example: S41 / S42 ("Ringbahn") both starts and # Notable example: S41 / S42 ("Ringbahn") both starts and
@ -650,12 +641,10 @@ sub startup {
# Store the intended checkout station regardless of this operation's # Store the intended checkout station regardless of this operation's
# success. # success.
$db->update( $self->in_transit->set_arrival_eva(
'in_transit', uid => $uid,
{ db => $db,
checkout_station_id => $new_checkout_station_id, arrival_eva => $new_checkout_station_id
},
{ user_id => $uid }
); );
# If in_transit already contains arrival data for another estimated # If in_transit already contains arrival data for another estimated
@ -664,15 +653,9 @@ sub startup {
and $journey->{checkout_station_id} and $journey->{checkout_station_id}
!= $new_checkout_station_id ) != $new_checkout_station_id )
{ {
$db->update( $self->in_transit->unset_arrival_data(
'in_transit', uid => $uid,
{ db => $db
checkout_time => undef,
arr_platform => undef,
sched_arrival => undef,
real_arrival => undef,
},
{ user_id => $uid }
); );
} }
@ -697,13 +680,11 @@ sub startup {
{ {
$rt_arr->add( minutes => $station_data->{adelay} ); $rt_arr->add( minutes => $station_data->{adelay} );
} }
$db->update( $self->in_transit->set_arrival_times(
'in_transit', uid => $uid,
{ db => $db,
sched_arrival => $sched_arr, sched_arrival => $sched_arr,
real_arrival => $rt_arr rt_arrival => $rt_arr
},
{ user_id => $uid }
); );
} }
} }
@ -731,27 +712,14 @@ sub startup {
die("Train ${train_no} has no arrival timestamp\n"); die("Train ${train_no} has no arrival timestamp\n");
} }
elsif ( defined $train and $train->arrival ) { elsif ( defined $train and $train->arrival ) {
$self->in_transit->set_arrival(
uid => $uid,
db => $db,
train => $train,
route => [ $self->iris->route_diff($train) ]
);
$has_arrived = $train->arrival->epoch < $now->epoch ? 1 : 0; $has_arrived = $train->arrival->epoch < $now->epoch ? 1 : 0;
my $json = JSON->new;
$db->update(
'in_transit',
{
checkout_time => $now,
arr_platform => $train->platform,
sched_arrival => $train->sched_arrival,
real_arrival => $train->arrival,
route =>
$json->encode( [ $self->route_diff($train) ] ),
messages => $json->encode(
[
map { [ $_->[0]->epoch, $_->[1] ] }
$train->messages
]
)
},
{ user_id => $uid }
);
if ($has_arrived) { if ($has_arrived) {
my @unknown_stations my @unknown_stations
= $self->grep_unknown_stations( $train->route ); = $self->grep_unknown_stations( $train->route );
@ -770,15 +738,20 @@ sub startup {
} }
} }
$journey $journey = $self->in_transit->get(
= $db->select( 'in_transit', '*', { user_id => $uid } )->hash; uid => $uid,
db => $db
);
if ( $has_arrived or $force ) { if ( $has_arrived or $force ) {
delete $journey->{data}; delete $journey->{data};
$journey->{edited} = 0; $journey->{edited} = 0;
$journey->{checkout_time} = $now; $journey->{checkout_time} = $now;
$db->insert( 'journeys', $journey ); $db->insert( 'journeys', $journey );
$db->delete( 'in_transit', { user_id => $uid } ); $self->in_transit->delete(
uid => $uid,
db => $db
);
my $cache_ts = $now->clone; my $cache_ts = $now->clone;
if ( $journey->{real_departure} if ( $journey->{real_departure}
@ -810,22 +783,10 @@ sub startup {
delete $journey->{data}; delete $journey->{data};
$db->insert( 'journeys', $journey ); $db->insert( 'journeys', $journey );
$journey $self->in_transit->set_cancelled_destination(
= $db->select( 'in_transit', ['data'], uid => $uid,
{ user_id => $uid } )->expand->hash; db => $db,
$journey->{data}{cancelled_destination} = $train->station; cancelled_destination => $train->station,
$db->update(
'in_transit',
{
checkout_station_id => undef,
checkout_time => undef,
arr_platform => undef,
sched_arrival => undef,
real_arrival => undef,
data => JSON->new->encode( $journey->{data} ),
},
{ user_id => $uid }
); );
} }
@ -853,27 +814,6 @@ sub startup {
} }
); );
$self->helper(
'update_in_transit_comment' => sub {
my ( $self, $comment, $uid, $db ) = @_;
$uid //= $self->current_user->{id};
$db //= $self->pg->db;
my $status
= $db->select( 'in_transit', ['user_data'], { user_id => $uid } )
->expand->hash;
if ( not $status ) {
return;
}
$status->{user_data}{comment} = $comment;
$db->update(
'in_transit',
{ user_data => JSON->new->encode( $status->{user_data} ) },
{ user_id => $uid }
);
}
);
# This helper should only be called directly when also providing a user ID. # This helper should only be called directly when also providing a user ID.
# If you don't have one, use current_user() instead (get_user_data will # If you don't have one, use current_user() instead (get_user_data will
# delegate to it anyways). # delegate to it anyways).
@ -1180,52 +1120,6 @@ sub startup {
} }
); );
$self->helper(
'route_diff' => sub {
my ( $self, $train ) = @_;
my @json_route;
my @route = $train->route;
my @sched_route = $train->sched_route;
my $route_idx = 0;
my $sched_idx = 0;
while ( $route_idx <= $#route and $sched_idx <= $#sched_route ) {
if ( $route[$route_idx] eq $sched_route[$sched_idx] ) {
push( @json_route, [ $route[$route_idx], {}, undef ] );
$route_idx++;
$sched_idx++;
}
# this branch is inefficient, but won't be taken frequently
elsif ( not( grep { $_ eq $route[$route_idx] } @sched_route ) )
{
push( @json_route,
[ $route[$route_idx], {}, 'additional' ],
);
$route_idx++;
}
else {
push( @json_route,
[ $sched_route[$sched_idx], {}, 'cancelled' ],
);
$sched_idx++;
}
}
while ( $route_idx <= $#route ) {
push( @json_route, [ $route[$route_idx], {}, 'additional' ], );
$route_idx++;
}
while ( $sched_idx <= $#sched_route ) {
push( @json_route,
[ $sched_route[$sched_idx], {}, 'cancelled' ],
);
$sched_idx++;
}
return @json_route;
}
);
$self->helper( $self->helper(
'add_route_timestamps' => sub { 'add_route_timestamps' => sub {
my ( $self, $uid, $train, $is_departure ) = @_; my ( $self, $uid, $train, $is_departure ) = @_;
@ -1234,18 +1128,21 @@ sub startup {
my $db = $self->pg->db; my $db = $self->pg->db;
my $journey = $db->select( # TODO "with_timestamps" is misleading, there are more differences between in_transit and in_transit_str
'in_transit_str', # Here it's only needed because of dep_eva / arr_eva names
[ 'arr_eva', 'dep_eva', 'route', 'data' ], my $journey = $self->in_transit->get(
{ user_id => $uid } db => $db,
)->expand->hash; uid => $uid,
with_data => 1,
with_timestamps => 1
);
if ( not $journey ) { if ( not $journey ) {
return; return;
} }
if ( $journey->{data}{trip_id} if ( $journey->{data}{trip_id}
and not $journey->{data}{polyline_id} ) and not $journey->{polyline} )
{ {
my ( $origin_eva, $destination_eva, $polyline_str ); my ( $origin_eva, $destination_eva, $polyline_str );
$self->hafas->get_polyline_p( $train, $self->hafas->get_polyline_p( $train,
@ -1297,10 +1194,10 @@ sub startup {
} }
} }
if ($polyline_id) { if ($polyline_id) {
$db->update( $self->in_transit->set_polyline_id(
'in_transit', uid => $uid,
{ polyline_id => $polyline_id }, db => $db,
{ user_id => $uid } polyline_id => $polyline_id
); );
} }
return; return;
@ -1371,22 +1268,16 @@ sub startup {
# HAFAS is happy as long as the date part starts with a number. # HAFAS is happy as long as the date part starts with a number.
# HAFAS-internal tripIDs use this format (withouth leading zero # HAFAS-internal tripIDs use this format (withouth leading zero
# for day of month < 10) though, so let's stick with it. # for day of month < 10) though, so let's stick with it.
my $res = $db->select( 'in_transit', ['data'],
{ user_id => $uid } );
my $res_h = $res->expand->hash;
my $data = $res_h->{data} // {};
my $date_map = $date_yyyy; my $date_map = $date_yyyy;
$date_map =~ tr{.}{}d; $date_map =~ tr{.}{}d;
$data->{trip_id} = sprintf( '1|%d|%d|%d|%s', my $trip_id = sprintf( '1|%d|%d|%d|%s',
$result->{id}, $result->{cycle}, $result->{id}, $result->{cycle},
$result->{pool}, $date_map ); $result->{pool}, $date_map );
$db->update( $self->in_transit->update_data(
'in_transit', uid => $uid,
{ data => JSON->new->encode($data) }, db => $db,
{ user_id => $uid } data => { trip_id => $trip_id }
); );
my $base2 my $base2
@ -1449,25 +1340,19 @@ sub startup {
= $route_data->{ $station->[0] }; = $route_data->{ $station->[0] };
} }
my $res = $db->select( 'in_transit', ['data'], $self->in_transit->set_route_data(
{ user_id => $uid } ); uid => $uid,
my $res_h = $res->expand->hash; db => $db,
my $data = $res_h->{data} // {}; route => $route,
delay_messages => [
$data->{delay_msg} = [ map { [ $_->[0]->epoch, $_->[1] ] } map { [ $_->[0]->epoch, $_->[1] ] }
$train->delay_messages ]; $train->delay_messages
$data->{qos_msg} = [ map { [ $_->[0]->epoch, $_->[1] ] } ],
$train->qos_messages ]; qos_messages => [
map { [ $_->[0]->epoch, $_->[1] ] }
$data->{him_msg} = $traininfo2->{messages}; $train->qos_messages
],
$db->update( him_messages => $traininfo2->{messages},
'in_transit',
{
route => JSON->new->encode($route),
data => JSON->new->encode($data)
},
{ user_id => $uid }
); );
return; return;
} }
@ -1490,21 +1375,13 @@ sub startup {
sub { sub {
my ($wagonorder) = @_; my ($wagonorder) = @_;
my $res = $db->select( my $data = {};
'in_transit', my $user_data = {};
[ 'data', 'user_data' ],
{ user_id => $uid }
);
my $res_h = $res->expand->hash;
my $data = $res_h->{data} // {};
my $user_data = $res_h->{user_data} // {};
if ( $is_departure and not exists $wagonorder->{error} ) if ( $is_departure and not exists $wagonorder->{error} )
{ {
$data->{wagonorder_dep} = $wagonorder; $data->{wagonorder_dep} = $wagonorder;
if ( exists $user_data->{wagongroups} ) { $user_data->{wagongroups} = [];
$user_data->{wagongroups} = [];
}
for my $group ( for my $group (
@{ @{
$wagonorder->{data}{istformation} $wagonorder->{data}{istformation}
@ -1539,23 +1416,25 @@ sub startup {
} }
); );
} }
$db->update( $self->in_transit->update_data(
'in_transit', uid => $uid,
{ db => $db,
data => JSON->new->encode($data), data => $data
user_data => JSON->new->encode($user_data) );
}, $self->in_transit->update_user_data(
{ user_id => $uid } uid => $uid,
db => $db,
user_data => $user_data
); );
} }
elsif ( not $is_departure elsif ( not $is_departure
and not exists $wagonorder->{error} ) and not exists $wagonorder->{error} )
{ {
$data->{wagonorder_arr} = $wagonorder; $data->{wagonorder_arr} = $wagonorder;
$db->update( $self->in_transit->update_data(
'in_transit', uid => $uid,
{ data => JSON->new->encode($data) }, db => $db,
{ user_id => $uid } data => $data
); );
} }
return; return;
@ -1572,18 +1451,12 @@ sub startup {
$self->dbdb->get_stationinfo_p( $journey->{dep_eva} )->then( $self->dbdb->get_stationinfo_p( $journey->{dep_eva} )->then(
sub { sub {
my ($station_info) = @_; my ($station_info) = @_;
my $data = { stationinfo_dep => $station_info };
my $res = $db->select( 'in_transit', ['data'], $self->in_transit->update_data(
{ user_id => $uid } ); uid => $uid,
my $res_h = $res->expand->hash; db => $db,
my $data = $res_h->{data} // {}; data => $data
$data->{stationinfo_dep} = $station_info;
$db->update(
'in_transit',
{ data => JSON->new->encode($data) },
{ user_id => $uid }
); );
return; return;
} }
@ -1599,18 +1472,12 @@ sub startup {
$self->dbdb->get_stationinfo_p( $journey->{arr_eva} )->then( $self->dbdb->get_stationinfo_p( $journey->{arr_eva} )->then(
sub { sub {
my ($station_info) = @_; my ($station_info) = @_;
my $data = { stationinfo_arr => $station_info };
my $res = $db->select( 'in_transit', ['data'], $self->in_transit->update_data(
{ user_id => $uid } ); uid => $uid,
my $res_h = $res->expand->hash; db => $db,
my $data = $res_h->{data} // {}; data => $data
$data->{stationinfo_arr} = $station_info;
$db->update(
'in_transit',
{ data => JSON->new->encode($data) },
{ user_id => $uid }
); );
return; return;
} }
@ -1631,23 +1498,29 @@ sub startup {
my $uid = $opt{uid} // $self->current_user->{id}; my $uid = $opt{uid} // $self->current_user->{id};
my $db = $opt{db} // $self->pg->db; my $db = $opt{db} // $self->pg->db;
my $journey = $db->select( 'in_transit', ['checkout_station_id'], if (
{ user_id => $uid } )->hash; my $id = $self->in_transit->get_checkout_station_id(
if ( not $journey ) { uid => $uid,
$journey = $db->select( db => $db
'journeys', )
['checkout_station_id'], )
{ {
user_id => $uid, return $id;
cancelled => 0
},
{
limit => 1,
order_by => { -desc => 'real_departure' }
}
)->hash;
} }
my $journey = $db->select(
'journeys',
['checkout_station_id'],
{
user_id => $uid,
cancelled => 0
},
{
limit => 1,
order_by => { -desc => 'real_departure' }
}
)->hash;
if ( not $journey ) { if ( not $journey ) {
return; return;
} }
@ -1947,9 +1820,12 @@ sub startup {
my $now = DateTime->now( time_zone => 'Europe/Berlin' ); my $now = DateTime->now( time_zone => 'Europe/Berlin' );
my $epoch = $now->epoch; my $epoch = $now->epoch;
my $in_transit my $in_transit = $self->in_transit->get(
= $db->select( 'in_transit_str', '*', { user_id => $uid } ) uid => $uid,
->expand->hash; db => $db,
with_data => 1,
with_timestamps => 1
);
if ($in_transit) { if ($in_transit) {
@ -2491,9 +2367,12 @@ sub startup {
if ( not $err ) { if ( not $err ) {
$self->log->debug("... success!"); $self->log->debug("... success!");
if ( $traewelling->{message} ) { if ( $traewelling->{message} ) {
$self->update_in_transit_comment( $self->in_transit->update_user_data(
$traewelling->{message}, uid => $uid,
$uid, $db ); db => $db,
user_data =>
{ comment => $traewelling->{message} }
);
} }
$self->traewelling->log( $self->traewelling->log(
uid => $uid, uid => $uid,

View file

@ -111,6 +111,8 @@ sub run {
my $stats_res = $db->delete( 'journey_stats', { user_id => $uid } ); my $stats_res = $db->delete( 'journey_stats', { user_id => $uid } );
my $journeys_res = $db->delete( 'journeys', { user_id => $uid } ); my $journeys_res = $db->delete( 'journeys', { user_id => $uid } );
my $transit_res = $db->delete( 'in_transit', { user_id => $uid } ); my $transit_res = $db->delete( 'in_transit', { user_id => $uid } );
# TODO + traewelling, webhooks
my $password_res my $password_res
= $db->delete( 'pending_passwords', { user_id => $uid } ); = $db->delete( 'pending_passwords', { user_id => $uid } );
my $user_res = $db->delete( 'users', { id => $uid } ); my $user_res = $db->delete( 'users', { id => $uid } );

View file

@ -60,8 +60,9 @@ sub run {
{ {
dep_platform => $train->platform, dep_platform => $train->platform,
real_departure => $train->departure, real_departure => $train->departure,
route => route => $json->encode(
$json->encode( [ $self->app->route_diff($train) ] ), [ $self->app->iris->route_diff($train) ]
),
messages => $json->encode( messages => $json->encode(
[ [
map { [ $_->[0]->epoch, $_->[1] ] } map { [ $_->[0]->epoch, $_->[1] ] }
@ -170,8 +171,9 @@ sub run {
arr_platform => $train->platform, arr_platform => $train->platform,
sched_arrival => $train->sched_arrival, sched_arrival => $train->sched_arrival,
real_arrival => $train->arrival, real_arrival => $train->arrival,
route => route => $json->encode(
$json->encode( [ $self->app->route_diff($train) ] ), [ $self->app->iris->route_diff($train) ]
),
messages => $json->encode( messages => $json->encode(
[ [
map { [ $_->[0]->epoch, $_->[1] ] } map { [ $_->[0]->epoch, $_->[1] ] }

View file

@ -264,8 +264,10 @@ sub travel_v1 {
uid => $uid uid => $uid
); );
if ( $payload->{comment} and not $error ) { if ( $payload->{comment} and not $error ) {
$self->update_in_transit_comment( $self->in_transit->update_user_data(
sanitize( q{}, $payload->{comment} ), $uid ); uid => $uid,
user_data => { comment => sanitize( q{}, $payload->{comment} ) }
);
} }
if ( $to_station and not $error ) { if ( $to_station and not $error ) {
( $train, $error ) = $self->checkout( ( $train, $error ) = $self->checkout(
@ -310,8 +312,10 @@ sub travel_v1 {
} }
if ( $payload->{comment} ) { if ( $payload->{comment} ) {
$self->update_in_transit_comment( $self->in_transit->update_user_data(
sanitize( q{}, $payload->{comment} ), $uid ); uid => $uid,
user_data => { comment => sanitize( q{}, $payload->{comment} ) }
);
} }
my ( $train, $error ) = $self->checkout( my ( $train, $error ) = $self->checkout(

View file

@ -1091,7 +1091,10 @@ sub comment_form {
} }
else { else {
$self->app->log->debug("set comment"); $self->app->log->debug("set comment");
$self->update_in_transit_comment( $self->param('comment') ); $self->in_transit->update_user_data(
uid => $self->current_user->{id},
user_data => { comment => $self->param('comment') }
);
$self->redirect_to('/'); $self->redirect_to('/');
} }
} }

View file

@ -68,4 +68,41 @@ sub get_departures {
} }
} }
sub route_diff {
my ( $self, $train ) = @_;
my @json_route;
my @route = $train->route;
my @sched_route = $train->sched_route;
my $route_idx = 0;
my $sched_idx = 0;
while ( $route_idx <= $#route and $sched_idx <= $#sched_route ) {
if ( $route[$route_idx] eq $sched_route[$sched_idx] ) {
push( @json_route, [ $route[$route_idx], {}, undef ] );
$route_idx++;
$sched_idx++;
}
# this branch is inefficient, but won't be taken frequently
elsif ( not( grep { $_ eq $route[$route_idx] } @sched_route ) ) {
push( @json_route, [ $route[$route_idx], {}, 'additional' ], );
$route_idx++;
}
else {
push( @json_route, [ $sched_route[$sched_idx], {}, 'cancelled' ], );
$sched_idx++;
}
}
while ( $route_idx <= $#route ) {
push( @json_route, [ $route[$route_idx], {}, 'additional' ], );
$route_idx++;
}
while ( $sched_idx <= $#sched_route ) {
push( @json_route, [ $sched_route[$sched_idx], {}, 'cancelled' ], );
$sched_idx++;
}
return @json_route;
}
1; 1;

View file

@ -0,0 +1,298 @@
package Travelynx::Model::InTransit;
use strict;
use warnings;
use 5.020;
use DateTime;
use JSON;
sub new {
my ( $class, %opt ) = @_;
return bless( \%opt, $class );
}
sub add {
my ( $self, %opt ) = @_;
my $uid = $opt{uid};
my $db = $opt{db} // $self->{pg}->db;
my $train = $opt{train};
my $checkin_station_id = $opt{departure_eva};
my $route = $opt{route};
my $json = JSON->new;
$db->insert(
'in_transit',
{
user_id => $uid,
cancelled => $train->departure_is_cancelled
? 1
: 0,
checkin_station_id => $checkin_station_id,
checkin_time => DateTime->now( time_zone => 'Europe/Berlin' ),
dep_platform => $train->platform,
train_type => $train->type,
train_line => $train->line_no,
train_no => $train->train_no,
train_id => $train->train_id,
sched_departure => $train->sched_departure,
real_departure => $train->departure,
route => $json->encode($route),
messages => $json->encode(
[ map { [ $_->[0]->epoch, $_->[1] ] } $train->messages ]
)
}
);
}
sub add_from_journey {
my ( $self, %opt ) = @_;
my $journey = $opt{journey};
my $db = $opt{db} // $self->{pg}->db;
$db->insert( 'in_transit', $journey );
}
sub delete {
my ( $self, %opt ) = @_;
my $uid = $opt{uid};
my $db = $opt{db} // $self->{pg}->db;
$db->delete( 'in_transit', { user_id => $uid } );
}
sub get {
my ( $self, %opt ) = @_;
my $uid = $opt{uid};
my $db = $opt{db} // $self->{pg}->db;
my $table = 'in_transit';
if ( $opt{with_timestamps} ) {
$table = 'in_transit_str';
}
my $res = $db->select( $table, '*', { user_id => $uid } );
if ( $opt{with_data} ) {
return $res->expand->hash;
}
return $res->hash;
}
sub get_checkout_station_id {
my ( $self, %opt ) = @_;
my $uid = $opt{uid};
my $db = $opt{db} // $self->{pg}->db;
my $status = $db->select( 'in_transit', ['checkout_station_id'],
{ user_id => $uid } )->hash;
if ($status) {
return $status->{checkout_station_id};
}
return;
}
sub set_cancelled_destination {
my ( $self, %opt ) = @_;
my $uid = $opt{uid};
my $db = $opt{db} // $self->{pg}->db;
my $cancelled_destination = $opt{cancelled_destination};
my $res_h = $db->select( 'in_transit', ['data'], { user_id => $uid } )
->expand->hash;
my $data = $res_h ? $res_h->{data} : {};
$data->{cancelled_destination} = $cancelled_destination;
$db->update(
'in_transit',
{
checkout_station_id => undef,
checkout_time => undef,
arr_platform => undef,
sched_arrival => undef,
real_arrival => undef,
data => JSON->new->encode($data),
},
{ user_id => $uid }
);
}
sub set_arrival {
my ( $self, %opt ) = @_;
my $uid = $opt{uid};
my $db = $opt{db} // $self->{pg}->db;
my $train = $opt{train};
my $route = $opt{route};
my $json = JSON->new;
$db->update(
'in_transit',
{
checkout_time => DateTime->now( time_zone => 'Europe/Berlin' ),
arr_platform => $train->platform,
sched_arrival => $train->sched_arrival,
real_arrival => $train->arrival,
route => $json->encode($route),
messages => $json->encode(
[ map { [ $_->[0]->epoch, $_->[1] ] } $train->messages ]
)
},
{ user_id => $uid }
);
}
sub set_arrival_eva {
my ( $self, %opt ) = @_;
my $uid = $opt{uid};
my $db = $opt{db} // $self->{pg}->db;
my $checkout_station_id = $opt{arrival_eva};
$db->update(
'in_transit',
{
checkout_station_id => $checkout_station_id,
},
{ user_id => $uid }
);
}
sub set_arrival_times {
my ( $self, %opt ) = @_;
my $uid = $opt{uid};
my $db = $opt{db} // $self->{pg}->db;
my $sched_arr = $opt{sched_arrival};
my $rt_arr = $opt{rt_arrival};
$db->update(
'in_transit',
{
sched_arrival => $sched_arr,
real_arrival => $rt_arr
},
{ user_id => $uid }
);
}
sub set_polyline_id {
my ( $self, %opt ) = @_;
my $uid = $opt{uid};
my $db = $opt{db} // $self->{pg}->db;
my $polyline_id = $opt{polyline_id};
$db->update(
'in_transit',
{ polyline_id => $polyline_id },
{ user_id => $uid }
);
}
sub set_route_data {
my ( $self, %opt ) = @_;
my $uid = $opt{uid};
my $db = $opt{db} // $self->{pg}->db;
my $route = $opt{route};
my $delay_msg = $opt{delay_messages};
my $qos_msg = $opt{qos_messages};
my $him_msg = $opt{him_messages};
my $res_h = $db->select( 'in_transit', ['data'], { user_id => $uid } )
->expand->hash;
my $data = $res_h ? $res_h->{data} : {};
$data->{delay_msg} = $opt{delay_messages};
$data->{qos_msg} = $opt{qos_messages};
$data->{him_msg} = $opt{him_messages};
$db->update(
'in_transit',
{
route => JSON->new->encode($route),
data => JSON->new->encode($data)
},
{ user_id => $uid }
);
}
sub unset_arrival_data {
my ( $self, %opt ) = @_;
my $uid = $opt{uid};
my $db = $opt{db} // $self->{pg}->db;
$db->update(
'in_transit',
{
checkout_time => undef,
arr_platform => undef,
sched_arrival => undef,
real_arrival => undef,
},
{ user_id => $uid }
);
}
sub update_data {
my ( $self, %opt ) = @_;
my $uid = $opt{uid};
my $db = $opt{db} // $self->{pg}->db;
my $new_data = $opt{data} // {};
my $res_h = $db->select( 'in_transit', ['data'], { user_id => $uid } )
->expand->hash;
my $data = $res_h ? $res_h->{data} : {};
while ( my ( $k, $v ) = each %{$new_data} ) {
$data->{$k} = $v;
}
$db->update(
'in_transit',
{ data => JSON->new->encode($data) },
{ user_id => $uid }
);
}
sub update_user_data {
my ( $self, %opt ) = @_;
my $uid = $opt{uid};
my $db = $opt{db} // $self->{pg}->db;
my $new_data = $opt{user_data} // {};
my $res_h = $db->select( 'in_transit', ['user_data'], { user_id => $uid } )
->expand->hash;
my $data = $res_h ? $res_h->{user_data} : {};
while ( my ( $k, $v ) = each %{$new_data} ) {
$data->{$k} = $v;
}
$db->update(
'in_transit',
{ user_data => JSON->new->encode($data) },
{ user_id => $uid }
);
}
1;