summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xlib/Travelynx.pm417
-rw-r--r--lib/Travelynx/Command/maintenance.pm2
-rw-r--r--lib/Travelynx/Command/work.pm10
-rwxr-xr-xlib/Travelynx/Controller/Api.pm12
-rwxr-xr-xlib/Travelynx/Controller/Traveling.pm5
-rw-r--r--lib/Travelynx/Helper/IRIS.pm37
-rw-r--r--lib/Travelynx/Model/InTransit.pm298
7 files changed, 503 insertions, 278 deletions
diff --git a/lib/Travelynx.pm b/lib/Travelynx.pm
index 7c7bb75..f446cda 100755
--- a/lib/Travelynx.pm
+++ b/lib/Travelynx.pm
@@ -21,6 +21,7 @@ use Travelynx::Helper::HAFAS;
use Travelynx::Helper::IRIS;
use Travelynx::Helper::Sendmail;
use Travelynx::Helper::Traewelling;
+use Travelynx::Model::InTransit;
use Travelynx::Model::Journeys;
use Travelynx::Model::Traewelling;
use Travelynx::Model::Users;
@@ -315,6 +316,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(
journeys => sub {
my ($self) = @_;
state $journeys = Travelynx::Model::Journeys->new(
@@ -454,34 +465,12 @@ sub startup {
}
eval {
- my $json = JSON->new;
- $db->insert(
- 'in_transit',
- {
- user_id => $uid,
- cancelled => $train->departure_is_cancelled
- ? 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
- ]
- )
- }
+ $self->in_transit->add(
+ uid => $uid,
+ db => $db,
+ departure_eva => $status->{station_eva},
+ train => $train,
+ route => [ $self->iris->route_diff($train) ],
);
};
if ($@) {
@@ -507,9 +496,7 @@ sub startup {
$uid //= $self->current_user->{id};
if ( $journey_id eq 'in_transit' ) {
- eval {
- $self->pg->db->delete( 'in_transit', { user_id => $uid } );
- };
+ eval { $self->in_transit->delete( uid => $uid ); };
if ($@) {
$self->app->log->error("Undo($uid, $journey_id): $@");
return "Undo($journey_id): $@";
@@ -550,7 +537,10 @@ sub startup {
delete $journey->{edited};
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' );
if ( $journey->{real_departure}
@@ -603,10 +593,11 @@ sub startup {
return ( 1, $status->{errstr} );
}
- my $now = DateTime->now( time_zone => 'Europe/Berlin' );
- my $journey
- = $db->select( 'in_transit', '*', { user_id => $uid } )
- ->expand->hash;
+ my $now = DateTime->now( time_zone => 'Europe/Berlin' );
+ my $journey = $self->in_transit->get(
+ uid => $uid,
+ with_data => 1
+ );
# Note that a train may pass the same station several times.
# Notable example: S41 / S42 ("Ringbahn") both starts and
@@ -650,12 +641,10 @@ sub startup {
# Store the intended checkout station regardless of this operation's
# success.
- $db->update(
- 'in_transit',
- {
- checkout_station_id => $new_checkout_station_id,
- },
- { user_id => $uid }
+ $self->in_transit->set_arrival_eva(
+ uid => $uid,
+ db => $db,
+ arrival_eva => $new_checkout_station_id
);
# If in_transit already contains arrival data for another estimated
@@ -664,15 +653,9 @@ sub startup {
and $journey->{checkout_station_id}
!= $new_checkout_station_id )
{
- $db->update(
- 'in_transit',
- {
- checkout_time => undef,
- arr_platform => undef,
- sched_arrival => undef,
- real_arrival => undef,
- },
- { user_id => $uid }
+ $self->in_transit->unset_arrival_data(
+ uid => $uid,
+ db => $db
);
}
@@ -697,13 +680,11 @@ sub startup {
{
$rt_arr->add( minutes => $station_data->{adelay} );
}
- $db->update(
- 'in_transit',
- {
- sched_arrival => $sched_arr,
- real_arrival => $rt_arr
- },
- { user_id => $uid }
+ $self->in_transit->set_arrival_times(
+ uid => $uid,
+ db => $db,
+ sched_arrival => $sched_arr,
+ rt_arrival => $rt_arr
);
}
}
@@ -731,27 +712,14 @@ sub startup {
die("Train ${train_no} has no arrival timestamp\n");
}
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;
- 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) {
my @unknown_stations
= $self->grep_unknown_stations( $train->route );
@@ -770,15 +738,20 @@ sub startup {
}
}
- $journey
- = $db->select( 'in_transit', '*', { user_id => $uid } )->hash;
+ $journey = $self->in_transit->get(
+ uid => $uid,
+ db => $db
+ );
if ( $has_arrived or $force ) {
delete $journey->{data};
$journey->{edited} = 0;
$journey->{checkout_time} = $now;
$db->insert( 'journeys', $journey );
- $db->delete( 'in_transit', { user_id => $uid } );
+ $self->in_transit->delete(
+ uid => $uid,
+ db => $db
+ );
my $cache_ts = $now->clone;
if ( $journey->{real_departure}
@@ -810,22 +783,10 @@ sub startup {
delete $journey->{data};
$db->insert( 'journeys', $journey );
- $journey
- = $db->select( 'in_transit', ['data'],
- { user_id => $uid } )->expand->hash;
- $journey->{data}{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 }
+ $self->in_transit->set_cancelled_destination(
+ uid => $uid,
+ db => $db,
+ cancelled_destination => $train->station,
);
}
@@ -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.
# If you don't have one, use current_user() instead (get_user_data will
# delegate to it anyways).
@@ -1181,52 +1121,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(
'add_route_timestamps' => sub {
my ( $self, $uid, $train, $is_departure ) = @_;
@@ -1234,18 +1128,21 @@ sub startup {
my $db = $self->pg->db;
- my $journey = $db->select(
- 'in_transit_str',
- [ 'arr_eva', 'dep_eva', 'route', 'data' ],
- { user_id => $uid }
- )->expand->hash;
+# TODO "with_timestamps" is misleading, there are more differences between in_transit and in_transit_str
+# Here it's only needed because of dep_eva / arr_eva names
+ my $journey = $self->in_transit->get(
+ db => $db,
+ uid => $uid,
+ with_data => 1,
+ with_timestamps => 1
+ );
if ( not $journey ) {
return;
}
if ( $journey->{data}{trip_id}
- and not $journey->{data}{polyline_id} )
+ and not $journey->{polyline} )
{
my ( $origin_eva, $destination_eva, $polyline_str );
$self->hafas->get_polyline_p( $train,
@@ -1297,10 +1194,10 @@ sub startup {
}
}
if ($polyline_id) {
- $db->update(
- 'in_transit',
- { polyline_id => $polyline_id },
- { user_id => $uid }
+ $self->in_transit->set_polyline_id(
+ uid => $uid,
+ db => $db,
+ polyline_id => $polyline_id
);
}
return;
@@ -1371,22 +1268,16 @@ sub startup {
# HAFAS is happy as long as the date part starts with a number.
# HAFAS-internal tripIDs use this format (withouth leading zero
# 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;
$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->{pool}, $date_map );
- $db->update(
- 'in_transit',
- { data => JSON->new->encode($data) },
- { user_id => $uid }
+ $self->in_transit->update_data(
+ uid => $uid,
+ db => $db,
+ data => { trip_id => $trip_id }
);
my $base2
@@ -1449,25 +1340,19 @@ sub startup {
= $route_data->{ $station->[0] };
}
- my $res = $db->select( 'in_transit', ['data'],
- { user_id => $uid } );
- my $res_h = $res->expand->hash;
- my $data = $res_h->{data} // {};
-
- $data->{delay_msg} = [ map { [ $_->[0]->epoch, $_->[1] ] }
- $train->delay_messages ];
- $data->{qos_msg} = [ map { [ $_->[0]->epoch, $_->[1] ] }
- $train->qos_messages ];
-
- $data->{him_msg} = $traininfo2->{messages};
-
- $db->update(
- 'in_transit',
- {
- route => JSON->new->encode($route),
- data => JSON->new->encode($data)
- },
- { user_id => $uid }
+ $self->in_transit->set_route_data(
+ uid => $uid,
+ db => $db,
+ route => $route,
+ delay_messages => [
+ map { [ $_->[0]->epoch, $_->[1] ] }
+ $train->delay_messages
+ ],
+ qos_messages => [
+ map { [ $_->[0]->epoch, $_->[1] ] }
+ $train->qos_messages
+ ],
+ him_messages => $traininfo2->{messages},
);
return;
}
@@ -1490,21 +1375,13 @@ sub startup {
sub {
my ($wagonorder) = @_;
- my $res = $db->select(
- 'in_transit',
- [ 'data', 'user_data' ],
- { user_id => $uid }
- );
- my $res_h = $res->expand->hash;
- my $data = $res_h->{data} // {};
- my $user_data = $res_h->{user_data} // {};
+ my $data = {};
+ my $user_data = {};
if ( $is_departure and not exists $wagonorder->{error} )
{
- $data->{wagonorder_dep} = $wagonorder;
- if ( exists $user_data->{wagongroups} ) {
- $user_data->{wagongroups} = [];
- }
+ $data->{wagonorder_dep} = $wagonorder;
+ $user_data->{wagongroups} = [];
for my $group (
@{
$wagonorder->{data}{istformation}
@@ -1539,23 +1416,25 @@ sub startup {
}
);
}
- $db->update(
- 'in_transit',
- {
- data => JSON->new->encode($data),
- user_data => JSON->new->encode($user_data)
- },
- { user_id => $uid }
+ $self->in_transit->update_data(
+ uid => $uid,
+ db => $db,
+ data => $data
+ );
+ $self->in_transit->update_user_data(
+ uid => $uid,
+ db => $db,
+ user_data => $user_data
);
}
elsif ( not $is_departure
and not exists $wagonorder->{error} )
{
$data->{wagonorder_arr} = $wagonorder;
- $db->update(
- 'in_transit',
- { data => JSON->new->encode($data) },
- { user_id => $uid }
+ $self->in_transit->update_data(
+ uid => $uid,
+ db => $db,
+ data => $data
);
}
return;
@@ -1572,18 +1451,12 @@ sub startup {
$self->dbdb->get_stationinfo_p( $journey->{dep_eva} )->then(
sub {
my ($station_info) = @_;
+ my $data = { stationinfo_dep => $station_info };
- my $res = $db->select( 'in_transit', ['data'],
- { user_id => $uid } );
- my $res_h = $res->expand->hash;
- my $data = $res_h->{data} // {};
-
- $data->{stationinfo_dep} = $station_info;
-
- $db->update(
- 'in_transit',
- { data => JSON->new->encode($data) },
- { user_id => $uid }
+ $self->in_transit->update_data(
+ uid => $uid,
+ db => $db,
+ data => $data
);
return;
}
@@ -1599,18 +1472,12 @@ sub startup {
$self->dbdb->get_stationinfo_p( $journey->{arr_eva} )->then(
sub {
my ($station_info) = @_;
+ my $data = { stationinfo_arr => $station_info };
- my $res = $db->select( 'in_transit', ['data'],
- { user_id => $uid } );
- my $res_h = $res->expand->hash;
- my $data = $res_h->{data} // {};
-
- $data->{stationinfo_arr} = $station_info;
-
- $db->update(
- 'in_transit',
- { data => JSON->new->encode($data) },
- { user_id => $uid }
+ $self->in_transit->update_data(
+ uid => $uid,
+ db => $db,
+ data => $data
);
return;
}
@@ -1631,23 +1498,29 @@ sub startup {
my $uid = $opt{uid} // $self->current_user->{id};
my $db = $opt{db} // $self->pg->db;
- my $journey = $db->select( 'in_transit', ['checkout_station_id'],
- { user_id => $uid } )->hash;
- if ( not $journey ) {
- $journey = $db->select(
- 'journeys',
- ['checkout_station_id'],
- {
- user_id => $uid,
- cancelled => 0
- },
- {
- limit => 1,
- order_by => { -desc => 'real_departure' }
- }
- )->hash;
+ if (
+ my $id = $self->in_transit->get_checkout_station_id(
+ uid => $uid,
+ db => $db
+ )
+ )
+ {
+ return $id;
}
+ my $journey = $db->select(
+ 'journeys',
+ ['checkout_station_id'],
+ {
+ user_id => $uid,
+ cancelled => 0
+ },
+ {
+ limit => 1,
+ order_by => { -desc => 'real_departure' }
+ }
+ )->hash;
+
if ( not $journey ) {
return;
}
@@ -1947,9 +1820,12 @@ sub startup {
my $now = DateTime->now( time_zone => 'Europe/Berlin' );
my $epoch = $now->epoch;
- my $in_transit
- = $db->select( 'in_transit_str', '*', { user_id => $uid } )
- ->expand->hash;
+ my $in_transit = $self->in_transit->get(
+ uid => $uid,
+ db => $db,
+ with_data => 1,
+ with_timestamps => 1
+ );
if ($in_transit) {
@@ -2491,9 +2367,12 @@ sub startup {
if ( not $err ) {
$self->log->debug("... success!");
if ( $traewelling->{message} ) {
- $self->update_in_transit_comment(
- $traewelling->{message},
- $uid, $db );
+ $self->in_transit->update_user_data(
+ uid => $uid,
+ db => $db,
+ user_data =>
+ { comment => $traewelling->{message} }
+ );
}
$self->traewelling->log(
uid => $uid,
diff --git a/lib/Travelynx/Command/maintenance.pm b/lib/Travelynx/Command/maintenance.pm
index e92018e..d9ce55a 100644
--- a/lib/Travelynx/Command/maintenance.pm
+++ b/lib/Travelynx/Command/maintenance.pm
@@ -111,6 +111,8 @@ sub run {
my $stats_res = $db->delete( 'journey_stats', { user_id => $uid } );
my $journeys_res = $db->delete( 'journeys', { user_id => $uid } );
my $transit_res = $db->delete( 'in_transit', { user_id => $uid } );
+
+ # TODO + traewelling, webhooks
my $password_res
= $db->delete( 'pending_passwords', { user_id => $uid } );
my $user_res = $db->delete( 'users', { id => $uid } );
diff --git a/lib/Travelynx/Command/work.pm b/lib/Travelynx/Command/work.pm
index a97dc62..a43a5b9 100644
--- a/lib/Travelynx/Command/work.pm
+++ b/lib/Travelynx/Command/work.pm
@@ -60,8 +60,9 @@ sub run {
{
dep_platform => $train->platform,
real_departure => $train->departure,
- route =>
- $json->encode( [ $self->app->route_diff($train) ] ),
+ route => $json->encode(
+ [ $self->app->iris->route_diff($train) ]
+ ),
messages => $json->encode(
[
map { [ $_->[0]->epoch, $_->[1] ] }
@@ -170,8 +171,9 @@ sub run {
arr_platform => $train->platform,
sched_arrival => $train->sched_arrival,
real_arrival => $train->arrival,
- route =>
- $json->encode( [ $self->app->route_diff($train) ] ),
+ route => $json->encode(
+ [ $self->app->iris->route_diff($train) ]
+ ),
messages => $json->encode(
[
map { [ $_->[0]->epoch, $_->[1] ] }
diff --git a/lib/Travelynx/Controller/Api.pm b/lib/Travelynx/Controller/Api.pm
index 8d2d2a7..74260c4 100755
--- a/lib/Travelynx/Controller/Api.pm
+++ b/lib/Travelynx/Controller/Api.pm
@@ -264,8 +264,10 @@ sub travel_v1 {
uid => $uid
);
if ( $payload->{comment} and not $error ) {
- $self->update_in_transit_comment(
- sanitize( q{}, $payload->{comment} ), $uid );
+ $self->in_transit->update_user_data(
+ uid => $uid,
+ user_data => { comment => sanitize( q{}, $payload->{comment} ) }
+ );
}
if ( $to_station and not $error ) {
( $train, $error ) = $self->checkout(
@@ -310,8 +312,10 @@ sub travel_v1 {
}
if ( $payload->{comment} ) {
- $self->update_in_transit_comment(
- sanitize( q{}, $payload->{comment} ), $uid );
+ $self->in_transit->update_user_data(
+ uid => $uid,
+ user_data => { comment => sanitize( q{}, $payload->{comment} ) }
+ );
}
my ( $train, $error ) = $self->checkout(
diff --git a/lib/Travelynx/Controller/Traveling.pm b/lib/Travelynx/Controller/Traveling.pm
index 4df1558..6a1d1e1 100755
--- a/lib/Travelynx/Controller/Traveling.pm
+++ b/lib/Travelynx/Controller/Traveling.pm
@@ -1091,7 +1091,10 @@ sub comment_form {
}
else {
$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('/');
}
}
diff --git a/lib/Travelynx/Helper/IRIS.pm b/lib/Travelynx/Helper/IRIS.pm
index 3b98a51..a8ca6c3 100644
--- a/lib/Travelynx/Helper/IRIS.pm
+++ b/lib/Travelynx/Helper/IRIS.pm
@@ -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;
diff --git a/lib/Travelynx/Model/InTransit.pm b/lib/Travelynx/Model/InTransit.pm
new file mode 100644
index 0000000..6aeab5f
--- /dev/null
+++ b/lib/Travelynx/Model/InTransit.pm
@@ -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;