From 62a58bf356f55f2b88155c6df4cf6c7e4daacde1 Mon Sep 17 00:00:00 2001 From: Marius Gavrilescu Date: Mon, 30 Mar 2015 15:38:33 +0300 Subject: [PATCH] Remove object oriented elements --- lib/Gruntmaster/Data.pm | 141 ++++++++++++++++++---------------------- 1 file changed, 63 insertions(+), 78 deletions(-) diff --git a/lib/Gruntmaster/Data.pm b/lib/Gruntmaster/Data.pm index 44ea4b4..846d772 100644 --- a/lib/Gruntmaster/Data.pm +++ b/lib/Gruntmaster/Data.pm @@ -4,7 +4,7 @@ use warnings; use parent qw/Exporter/; our $VERSION = '5999.000_013'; -our @EXPORT = qw/purge/; ## no critic (ProhibitAutomaticExportation) +our @EXPORT = qw/purge user_list user_entry problem_list problem_entry contest_list contest_entry contest_full contest_has_problem job_list job_entry job_full create_job standings update_status/; ## no critic (ProhibitAutomaticExportation) use JSON::MaybeXS qw/decode_json/; use HTTP::Tiny; @@ -42,71 +42,63 @@ my %statements = ( job_full_sth => 'SELECT * FROM jobs WHERE id = ?', ); -sub connect { - my ($class, @args) = @_; +my $db; - my $self = { - dbis => DBIx::Simple->new(@args), - }; - $self->{dbis}->keep_statements = 100; - bless $self, $class +sub init { + $db = DBIx::Simple->new(@_); + $db->keep_statements = 100; }; sub purge; sub query { - my ($self, $stat, @extra) = @_; - $self->{dbis}->query($statements{$stat} // $stat, @extra) + my ($stat, @extra) = @_; + $db->query($statements{$stat} // $stat, @extra) } my (%name_cache, %name_cache_time); use constant NAME_CACHE_MAX_AGE => 5; sub object_name { - my ($self, $table, $id) = @_; + my ($table, $id) = @_; $name_cache_time{$table} //= 0; if (time - $name_cache_time{$table} > NAME_CACHE_MAX_AGE) { $name_cache_time{$table} = time; $name_cache{$table} = {}; - $name_cache{$table} = $self->{dbis}->select($table, 'id,name')->map; + $name_cache{$table} = $db->select($table, 'id,name')->map; } $name_cache{$table}{$id} } -sub add_names { - my ($self, $el) = @_; +sub add_names ($) { + my ($el) = @_; if (ref $el eq 'ARRAY') { - $self->add_names($_) for @$el + &add_names ($_) for @$el } else { for my $object (qw/contest owner problem/) { my $table = $object eq 'owner' ? 'users' : "${object}s"; - $el->{"${object}_name"} = $self->object_name($table, $el->{$object}) if defined $el->{$object} + $el->{"${object}_name"} = object_name $table, $el->{$object} if defined $el->{$object} } } $el } -sub user_list { - my ($self) = @_; - scalar $self->query('user_list_sth')->hashes -} +sub user_list { scalar query('user_list_sth')->hashes } sub user_entry { - my ($self, $id) = @_; - my $ret = $self->query('user_entry_sth', $id)->hash; - $ret->{problems} = $self->query('problem_status_sth', $id)->hashes; - $ret->{contests} = $self->query('contest_status_sth', $id)->hashes; + my ($id) = @_; + my $ret = query('user_entry_sth', $id)->hash; + $ret->{problems} = add_names query('problem_status_sth', $id)->hashes; + $ret->{contests} = add_names query('contest_status_sth', $id)->hashes; - $self->add_names($ret->{problems}); - $self->add_names($ret->{contests}); $ret; } sub problem_list { - my ($self, %args) = @_; + my (%args) = @_; my @columns = @{PROBLEM_PUBLIC_COLUMNS()}; push @columns, 'solution' if $args{solution}; my %where; @@ -115,8 +107,7 @@ sub problem_list { $where{owner} = $args{owner} if $args{owner}; my $table = $args{contest} ? 'problems JOIN contest_problems cp ON cp.problem = id' : 'problems'; - my $ret = $self->{dbis}->select(\$table, \@columns, \%where, 'name')->hashes; - $self->add_names($ret); + my $ret = add_names $db->select(\$table, \@columns, \%where, 'name')->hashes; my %params; for (@$ret) { @@ -127,11 +118,10 @@ sub problem_list { } sub problem_entry { - my ($self, $id, $contest, $user) = @_; - $contest &&= $self->contest_entry($contest); - my $ret = $self->query(problem_entry_sth => $id)->hash; - $self->add_names($ret); - my $limits = $self->query(limits_sth => $id)->hashes; + my ($id, $contest, $user) = @_; + $contest &&= contest_entry $contest; + my $ret = add_names query(problem_entry_sth => $id)->hash; + my $limits = query(limits_sth => $id)->hashes; $ret->{limits} = $limits if @$limits; if ($contest) { @@ -143,9 +133,7 @@ sub problem_entry { } sub contest_list { - my ($self) = @_; - my $ret = $self->query('contest_list_sth')->hashes; - $self->add_names($ret); + my $ret = add_names query('contest_list_sth')->hashes; my %ret; for (@$ret) { @@ -158,23 +146,22 @@ sub contest_list { } sub contest_entry { - my ($self, $id) = @_; - my $ret = $self->query(contest_entry_sth => $id)->hash; - $self->add_names($ret); + my ($id) = @_; + add_names query(contest_entry_sth => $id)->hash; } sub contest_full { - my ($self, $id) = @_; - scalar $self->query(contest_full_sth => $id)->hash; + my ($id) = @_; + scalar query(contest_full_sth => $id)->hash; } sub contest_has_problem { - my ($self, $contest, $problem) = @_; - $self->query('contest_has_problem_sth')->flat + my ($contest, $problem) = @_; + query('contest_has_problem_sth', $contest, $problem)->flat } sub job_list { - my ($self, %args) = @_; + my (%args) = @_; $args{page} //= 1; my %where = ( maybe contest => $args{contest}, @@ -184,16 +171,15 @@ sub job_list { ); $where{private} = 0 unless $args{private}; - my $rows = $self->{dbis}->select('job_entry', 'COUNT(*)', \%where)->list; + my $rows = $db->select('job_entry', 'COUNT(*)', \%where)->list; my $pages = int (($rows + JOBS_PER_PAGE - 1) / JOBS_PER_PAGE); - my ($stmt, @bind) = $self->{dbis}->abstract->select('job_entry', '*', \%where, {-desc => 'id'}); - my $jobs = $self->{dbis}->query("$stmt LIMIT " . JOBS_PER_PAGE . ' OFFSET ' . ($args{page} - 1) * JOBS_PER_PAGE, @bind)->hashes; + my ($stmt, @bind) = $db->abstract->select('job_entry', '*', \%where, {-desc => 'id'}); + my $jobs = $db->query("$stmt LIMIT " . JOBS_PER_PAGE . ' OFFSET ' . ($args{page} - 1) * JOBS_PER_PAGE, @bind)->hashes; my %ret = ( - log => $jobs, + log => add_names $jobs, current_page => $args{page}, last_page => $pages, ); - $self->add_names($ret{log}); $ret{previous_page} = $args{page} - 1 if $args{page} - 1; $ret{next_page} = $args{page} + 1 if $args{page} < $pages; @@ -201,22 +187,22 @@ sub job_list { } sub job_entry { - my ($self, $id) = @_; - my $ret = $self->query(job_entry_sth => $id)->hash; + my ($id) = @_; + my $ret = add_names query(job_entry_sth => $id)->hash; $ret->{results} &&= decode_json $ret->{results}; - $self->add_names($ret); + $ret } sub job_full { - my ($self, $id) = @_; - scalar $self->query(job_full_sth => $id)->hash + my ($id) = @_; + scalar query(job_full_sth => $id)->hash } sub create_job { - my ($self, %args) = @_; - $self->{dbis}->update('users', {lastjob => time}); + my (%args) = @_; + $db->update('users', {lastjob => time}); purge '/log/'; - scalar $self->{dbis}->insert('jobs', \%args, {returning => 'id'})->list + scalar $db->insert('jobs', \%args, {returning => 'id'})->list } sub calc_score { @@ -231,21 +217,21 @@ sub calc_score { } sub standings { - my ($self, $ct) = @_; - $ct = $self->contest_entry($ct); + my ($ct) = @_; + $ct = contest_entry $ct; - my @problems = $self->query(contest_problems_sth => $ct->{id})->flat; - my $pblist = $self->problem_list; - my %values = $self->query('problem_values_sth')->map; + my @problems = query(contest_problems_sth => $ct->{id})->flat; + my $pblist = problem_list; + my %values = query('problem_values_sth')->map; # $values{$_} = $values{$_}->{value} for keys %values; my (%scores, %tries, %opens); - my $opens = $self->query(opens_sth => $ct->{id}); + my $opens = query(opens_sth => $ct->{id}); while ($opens->into(my ($problem, $owner, $time))) { $opens{$problem, $owner} = $time; } - my $jobs = $self->{dbis}->select('job_entry', '*', {contest => $ct->{id}}, 'id'); + my $jobs = $db->select('job_entry', '*', {contest => $ct->{id}}, 'id'); while (my $job = $jobs->hash) { my $open = $opens{$job->{problem}, $job->{owner}} // $ct->{start}; @@ -261,7 +247,7 @@ sub standings { my $user = $_; +{ user => $user, - user_name => $self->object_name(users => $user), + user_name => object_name(users => $user), score => sum (values %{$scores{$user}}), scores => [map { $scores{$user}{$_} // '-'} @problems], } @@ -271,13 +257,12 @@ sub standings { $st[$_]->{rank} = $st[$_ - 1]->{rank} + ($st[$_]->{score} < $st[$_ - 1]->{score}) for 1 .. $#st; +{ st => \@st, - problems => [map { [ $_, $self->object_name(problems => $_)] } @problems], + problems => [map { [ $_, object_name(problems => $_)] } @problems], } } sub update_status { - my ($self) = @_; - my $jobs = $self->{dbis}->select('jobs', 'id,owner,problem,result', {}, 'id'); + my $jobs = $db->select('jobs', 'id,owner,problem,result', {}, 'id'); my %hash; while ($jobs->into(my ($id, $owner, $problem, $result))) { @@ -288,15 +273,15 @@ sub update_status { my @contest_statuses = map { my $ct = $_; - map { [$ct, $_->{user}, $_->{score}, $_->{rank}] } @{$self->standings($ct)->{st}} - } $self->{dbis}->select('contests', 'id')->flat; - - $self->{dbis}->begin; - $self->{dbis}->delete('problem_status'); - $self->{dbis}->query('INSERT INTO problem_status (problem,owner,job,solved) VALUES (??)', @$_) for @problem_statuses; - $self->{dbis}->delete('contest_status'); - $self->{dbis}->query('INSERT INTO contest_status (contest,owner,score,rank) VALUES (??)', @$_) for @contest_statuses; - $self->{dbis}->commit + map { [$ct, $_->{user}, $_->{score}, $_->{rank}] } @{standings($ct)->{st}} + } $db->select('contests', 'id')->flat; + + $db->begin; + $db->delete('problem_status'); + $db->query('INSERT INTO problem_status (problem,owner,job,solved) VALUES (??)', @$_) for @problem_statuses; + $db->delete('contest_status'); + $db->query('INSERT INTO contest_status (contest,owner,score,rank) VALUES (??)', @$_) for @contest_statuses; + $db->commit } my @PURGE_HOSTS = exists $ENV{PURGE_HOSTS} ? split ' ', $ENV{PURGE_HOSTS} : (); -- 2.39.2