2017-06-05 21:34:48 +00:00
|
|
|
package Pear::LocalLoop::Schema::ResultSet::Leaderboard;
|
|
|
|
|
|
|
|
use strict;
|
|
|
|
use warnings;
|
|
|
|
|
|
|
|
use base 'DBIx::Class::ResultSet';
|
|
|
|
|
2017-08-21 14:19:39 +00:00
|
|
|
use DateTime;
|
|
|
|
|
2017-06-05 21:34:48 +00:00
|
|
|
sub get_latest {
|
2021-03-20 12:09:50 +00:00
|
|
|
my $self = shift;
|
|
|
|
my $type = shift;
|
2017-06-05 21:34:48 +00:00
|
|
|
|
2021-03-20 12:09:50 +00:00
|
|
|
my $type_result = $self->find_by_type($type);
|
2017-06-05 21:34:48 +00:00
|
|
|
|
2021-03-20 12:09:50 +00:00
|
|
|
return unless defined $type_result;
|
2017-06-05 21:34:48 +00:00
|
|
|
|
2021-03-20 12:09:50 +00:00
|
|
|
my $latest = $type_result->search_related(
|
|
|
|
'sets',
|
|
|
|
{},
|
|
|
|
{
|
|
|
|
order_by => { -desc => 'date' },
|
|
|
|
}
|
|
|
|
)->first;
|
2017-06-05 21:34:48 +00:00
|
|
|
|
2021-03-20 12:09:50 +00:00
|
|
|
return $latest;
|
2017-06-05 21:34:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sub create_new {
|
2021-03-20 12:09:50 +00:00
|
|
|
my $self = shift;
|
|
|
|
my $type = shift;
|
|
|
|
my $date = shift;
|
2017-06-05 21:34:48 +00:00
|
|
|
|
2021-03-20 12:09:50 +00:00
|
|
|
my $type_result = $self->find_by_type($type);
|
2017-06-05 21:34:48 +00:00
|
|
|
|
2021-03-20 12:09:50 +00:00
|
|
|
return unless $type_result;
|
2017-06-05 21:34:48 +00:00
|
|
|
|
2021-03-20 12:09:50 +00:00
|
|
|
return $type_result->create_new($date);
|
2017-06-05 21:34:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sub find_by_type {
|
2021-03-20 12:09:50 +00:00
|
|
|
my $self = shift;
|
|
|
|
my $type = shift;
|
2017-06-05 21:34:48 +00:00
|
|
|
|
2021-03-20 12:09:50 +00:00
|
|
|
return $self->find( { type => $type } );
|
2017-06-05 21:34:48 +00:00
|
|
|
}
|
|
|
|
|
2017-08-21 14:19:39 +00:00
|
|
|
sub recalculate_all {
|
2021-03-20 12:09:50 +00:00
|
|
|
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";
|
|
|
|
}
|
2017-08-21 14:19:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sub _recalculate_leaderboard {
|
2021-03-20 12:09:50 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
);
|
2017-08-21 14:19:39 +00:00
|
|
|
}
|
|
|
|
|
2017-06-05 21:34:48 +00:00
|
|
|
1;
|