Enabled recalculation of leaderboards at any point

This commit is contained in:
Tom Bloor 2017-08-21 15:19:39 +01:00
parent 3f743f0b5f
commit 9b9b2bd322
3 changed files with 80 additions and 2 deletions

View file

@ -0,0 +1,26 @@
package Pear::LocalLoop::Command::recalc_leaderboards;
use Mojo::Base 'Mojolicious::Command';
use Mojo::Util 'getopt';
has description => 'Build All leaderboards';
has usage => sub { shift->extract_usage };
sub run {
my ( $self, @args ) = @_;
my $leaderboard_rs = $self->app->schema->resultset('Leaderboard');
$leaderboard_rs->recalculate_all;
}
=head1 SYNOPSIS
Usage: APPLICATION recalc_leaderboards
Recalculates ALL leaderboards.
=cut
1;

View file

@ -184,7 +184,7 @@ sub _create_total_all_time {
my @leaderboard; my @leaderboard;
while ( my $user_result = $user_rs->next ) { while ( my $user_result = $user_rs->next ) {
my $transaction_rs = $user_result->transactions; my $transaction_rs = $user_result->transactions->search_before( $end );
my $transaction_sum = $transaction_rs->get_column('value')->sum; my $transaction_sum = $transaction_rs->get_column('value')->sum;
@ -215,7 +215,7 @@ sub _create_count_all_time {
my @leaderboard; my @leaderboard;
while ( my $user_result = $user_rs->next ) { while ( my $user_result = $user_rs->next ) {
my $transaction_rs = $user_result->transactions; my $transaction_rs = $user_result->transactions->search_before( $end );
my $transaction_count = $transaction_rs->count; my $transaction_count = $transaction_rs->count;

View file

@ -5,6 +5,8 @@ use warnings;
use base 'DBIx::Class::ResultSet'; use base 'DBIx::Class::ResultSet';
use DateTime;
sub get_latest { sub get_latest {
my $self = shift; my $self = shift;
my $type = shift; my $type = shift;
@ -39,4 +41,54 @@ sub find_by_type {
return $self->find({ type => $type }); return $self->find({ type => $type });
} }
sub recalculate_all {
my $self = shift;
for my $leaderboard_result ( $self->all ) {
my $lb_type = $leaderboard_result->type;
if ( $lb_type =~ /^daily/ ) {
# Recalculating a daily set. This is calculated from the start of the
# day, so we need yesterdays date:
my $date = DateTime->today->subtract( days => 1 );
$self->_recalculate_leaderboard( $leaderboard_result, $date, 'days' );
} elsif ( $lb_type =~ /^weekly/ ) {
# Recalculating a weekly set. This is calculated from a Monday, of the
# week before.
my $date = DateTime->today->truncate( to => 'week' )->subtract( weeks => 1 );
$self->_recalculate_leaderboard( $leaderboard_result, $date, 'weeks' );
} elsif ( $lb_type =~ /^monthly/ ) {
# Recalculate a monthly set. This is calculated from the first of the
# month, for the month before.
my $date = DateTime->today->truncate( to => 'month' )->subtract( months => 1);
$self->_recalculate_leaderboard( $leaderboard_result, $date, 'months' );
} elsif ( $lb_type =~ /^all_time/ ) {
# Recalculate for an all time set. This is calculated similarly to
# daily, but is calculated from an end time.
my $date = DateTime->today;
$self->_recalculate_leaderboard( $leaderboard_result, $date, 'days' );
} else {
warn "Unrecognised Set";
}
}
}
sub _recalculate_leaderboard {
my ( $self, $lb_result, $date, $diff ) = @_;
$self->result_source->schema->txn_do( sub {
$lb_result->sets->related_resultset('values')->delete_all;
$lb_result->sets->delete_all;
$lb_result->create_new($date->clone->subtract( $diff => 1 ));
$lb_result->create_new($date);
});
}
1; 1;