summaryrefslogtreecommitdiff
path: root/lib/Travelynx.pm
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2019-04-07 16:55:35 +0200
committerDaniel Friesel <derf@finalrewind.org>2019-04-07 16:55:35 +0200
commitd0b6b7e0523cbee6c5902b53e993cfecc7cb5843 (patch)
tree27a2d6d7f118b81757d2f9a7dc39cee6bc2971b3 /lib/Travelynx.pm
parent9225a82c669079f09b29f68296f273630f274ec9 (diff)
Cache journey stats
Diffstat (limited to 'lib/Travelynx.pm')
-rwxr-xr-xlib/Travelynx.pm106
1 files changed, 106 insertions, 0 deletions
diff --git a/lib/Travelynx.pm b/lib/Travelynx.pm
index b9132f3..df27684 100755
--- a/lib/Travelynx.pm
+++ b/lib/Travelynx.pm
@@ -8,6 +8,7 @@ use DateTime;
use DBI;
use Encode qw(decode encode);
use Geo::Distance;
+use JSON;
use List::Util qw(first);
use List::MoreUtils qw(after_incl before_incl);
use Travel::Status::DE::IRIS;
@@ -228,6 +229,44 @@ sub startup {
}
);
$self->attr(
+ get_stats_query => sub {
+ my ($self) = @_;
+
+ return $self->app->dbh->prepare(
+ qq{
+ select data from journey_stats
+ where user_id = ? and year = ? and month = ?
+ }
+ );
+ }
+ );
+ $self->attr(
+ add_stats_query => sub {
+ my ($self) = @_;
+
+ return $self->app->dbh->prepare(
+ qq{
+ insert into journey_stats
+ (user_id, year, month, data)
+ values
+ (?, ?, ?, ?)
+ }
+ );
+ }
+ );
+ $self->attr(
+ drop_stats_query => sub {
+ my ($self) = @_;
+
+ return $self->app->dbh->prepare(
+ qq{
+ delete from journey_stats
+ where user_id = ? and year = ? and month = ?
+ }
+ );
+ }
+ );
+ $self->attr(
action_query => sub {
my ($self) = @_;
@@ -959,6 +998,73 @@ qq{select * from pending_mails where email = ? and num_tries > 1;}
);
$self->helper(
+ 'get_journey_stats' => sub {
+ my ( $self, %opt ) = @_;
+
+ if ( $opt{cancelled} ) {
+ $self->app->log->warning(
+'get_journey_stats called with illegal option cancelled => 1'
+ );
+ return {};
+ }
+
+ my $uid = $self->current_user->{id};
+ my $year = $opt{year} // 0;
+ my $month = $opt{month} // 0;
+
+ # Assumption: If the stats cache contains an entry it is up-to-date.
+ # -> Cache entries must be explicitly invalidated whenever the user
+ # checks out of a train or manually edits/adds a journey.
+
+ $self->app->get_stats_query->execute( $uid, $year, $month );
+ my $rows = $self->app->get_stats_query->fetchall_arrayref;
+
+ if ( @{$rows} == 1 ) {
+ return JSON->new->decode( $rows->[0][0] );
+ }
+
+ my $interval_start = DateTime->new(
+ time_zone => 'Europe/Berlin',
+ year => 2000,
+ month => 1,
+ day => 1,
+ hour => 0,
+ minute => 0,
+ second => 0,
+ );
+
+ # I wonder if people will still be traveling by train in the year 3000
+ my $interval_end = $interval_start->clone->add( years => 1000 );
+
+ if ( $opt{year} and $opt{month} ) {
+ $interval_start->set(
+ year => $opt{year},
+ month => $opt{month}
+ );
+ $interval_end = $interval_start->clone->add( months => 1 );
+ }
+ elsif ( $opt{year} ) {
+ $interval_start->set( year => $opt{year} );
+ $interval_end = $interval_start->clone->add( years => 1 );
+ }
+
+ my @journeys = $self->get_user_travels(
+ cancelled => $opt{cancelled} ? 1 : 0,
+ verbose => 1,
+ after => $interval_start,
+ before => $interval_end
+ );
+ my $stats = $self->compute_journey_stats(@journeys);
+
+ $self->app->drop_stats_query->execute( $uid, $year, $month );
+ $self->app->add_stats_query->execute( $uid, $year, $month,
+ JSON->new->encode($stats) );
+
+ return $stats;
+ }
+ );
+
+ $self->helper(
'get_user_travels' => sub {
my ( $self, %opt ) = @_;