aboutsummaryrefslogtreecommitdiffstats
path: root/perllib/FixMyStreet/DB/ResultSet
diff options
context:
space:
mode:
Diffstat (limited to 'perllib/FixMyStreet/DB/ResultSet')
-rw-r--r--perllib/FixMyStreet/DB/ResultSet/Body.pm87
-rw-r--r--perllib/FixMyStreet/DB/ResultSet/Nearby.pm23
-rw-r--r--perllib/FixMyStreet/DB/ResultSet/Problem.pm43
-rw-r--r--perllib/FixMyStreet/DB/ResultSet/ReportExtraField.pm (renamed from perllib/FixMyStreet/DB/ResultSet/ReportExtraFields.pm)2
4 files changed, 126 insertions, 29 deletions
diff --git a/perllib/FixMyStreet/DB/ResultSet/Body.pm b/perllib/FixMyStreet/DB/ResultSet/Body.pm
index 0aa3e8240..4e9661d2e 100644
--- a/perllib/FixMyStreet/DB/ResultSet/Body.pm
+++ b/perllib/FixMyStreet/DB/ResultSet/Body.pm
@@ -41,7 +41,7 @@ This restricts the ResultSet to bodies that are not marked as deleted.
sub active {
my $rs = shift;
- $rs->search({ deleted => 0 });
+ $rs->search({ 'me.deleted' => 0 });
}
=item translated
@@ -61,6 +61,22 @@ sub translated {
});
}
+=item with_parent_name
+
+This adds the parent name associated with each body to the ResultSet,
+in the parent_name column.
+
+=cut
+
+sub with_parent_name {
+ my $rs = shift;
+ $rs->search(undef, {
+ '+select' => [ 'parent.name' ],
+ '+as' => [ 'parent_name' ],
+ join => 'parent',
+ });
+}
+
=item with_area_count
This adds the number of areas associated with each body to the ResultSet,
@@ -78,10 +94,45 @@ sub with_area_count {
});
}
+=item with_defect_type_count
+
+This adds the number of defect types associated with each body to the
+ResultSet, in the defect_type_count column.
+
+=cut
+
+sub with_defect_type_count {
+ my $rs = shift;
+ $rs->search(undef, {
+ '+select' => [ { count => 'defect_types.name' } ],
+ '+as' => [ 'defect_type_count' ],
+ join => 'defect_types',
+ distinct => 1,
+ });
+}
+
+=item with_children_count
+
+This adds the number of children associated with each body to the
+ResultSet, in the children_count column.
+
+=cut
+
+sub with_children_count {
+ my $rs = shift;
+ $rs->search(undef, {
+ '+select' => [ { count => 'bodies.id' } ],
+ '+as' => [ 'children_count' ],
+ join => 'bodies',
+ distinct => 1,
+ });
+}
+
=item all_sorted
-This returns all results, as C<all()>, but sorted by their name column
-(which will be the translated names if present).
+This returns all results, as C<all()>, but sorted by their name (including
+the translated names, if present), and as simple hashrefs not objects, for
+performance reasons.
=back
@@ -89,8 +140,34 @@ This returns all results, as C<all()>, but sorted by their name column
sub all_sorted {
my $rs = shift;
- my @bodies = $rs->all;
- @bodies = sort { strcoll($a->name, $b->name) } @bodies;
+
+ # Use a HashRefInflator here to return simple hashrefs rather than full
+ # objects. This is quicker if you have a large number of bodies; note
+ # fetching only the columns you need provides even more of a speed up.
+ my @bodies = $rs->search(undef, {
+ result_class => 'DBIx::Class::ResultClass::HashRefInflator',
+ })->all;
+ @bodies = sort { strcoll($a->{msgstr} || $a->{name}, $b->{msgstr} || $b->{name}) } @bodies;
+
+ my $cobrand = $rs->result_source->schema->cobrand;
+
+ foreach my $body (@bodies) {
+ $body->{parent} = { id => $body->{parent}, name => $body->{parent_name} } if $body->{parent};
+
+ # DEPRECATED: url(c, query_params) -> url
+ $body->{url} = sub {
+ my ($c, $args) = @_;
+ return FixMyStreet::DB::Result::Body::_url($body, $cobrand, $args);
+ };
+
+ # DEPRECATED: get_column('area_count') -> area_count
+ next unless defined $body->{area_count};
+ $body->{get_column} = sub {
+ my $key = shift;
+ return $body->{$key};
+ };
+ }
+
return @bodies;
}
diff --git a/perllib/FixMyStreet/DB/ResultSet/Nearby.pm b/perllib/FixMyStreet/DB/ResultSet/Nearby.pm
index b075e3664..2ebe309e3 100644
--- a/perllib/FixMyStreet/DB/ResultSet/Nearby.pm
+++ b/perllib/FixMyStreet/DB/ResultSet/Nearby.pm
@@ -10,31 +10,34 @@ sub to_body {
}
sub nearby {
- my ( $rs, $c, $dist, $ids, $limit, $mid_lat, $mid_lon, $categories, $states, $extra_params ) = @_;
+ my ( $rs, $c, %args ) = @_;
- unless ( $states ) {
- $states = FixMyStreet::DB::Result::Problem->visible_states();
+ unless ( $args{states} ) {
+ $args{states} = FixMyStreet::DB::Result::Problem->visible_states();
}
my $params = {
- state => [ keys %$states ],
+ state => [ keys %{$args{states}} ],
};
- $params->{id} = { -not_in => $ids }
- if $ids;
- $params->{category} = $categories if $categories && @$categories;
+ $params->{id} = { -not_in => $args{ids} }
+ if $args{ids};
+ $params->{category} = $args{categories} if $args{categories} && @{$args{categories}};
+
+ $params->{$c->stash->{report_age_field}} = { '>=', \"current_timestamp-'$args{report_age}'::interval" }
+ if $args{report_age};
FixMyStreet::DB::ResultSet::Problem->non_public_if_possible($params, $c);
$rs = $c->cobrand->problems_restriction($rs);
# Add in any optional extra query parameters
- $params = { %$params, %$extra_params } if $extra_params;
+ $params = { %$params, %{$args{extra}} } if $args{extra};
my $attrs = {
prefetch => 'problem',
- bind => [ $mid_lat, $mid_lon, $dist ],
+ bind => [ $args{latitude}, $args{longitude}, $args{distance} ],
order_by => [ 'distance', { -desc => 'created' } ],
- rows => $limit,
+ rows => $args{limit},
};
my @problems = mySociety::Locale::in_gb_locale { $rs->search( $params, $attrs )->all };
diff --git a/perllib/FixMyStreet/DB/ResultSet/Problem.pm b/perllib/FixMyStreet/DB/ResultSet/Problem.pm
index ef078ed08..37fc34057 100644
--- a/perllib/FixMyStreet/DB/ResultSet/Problem.pm
+++ b/perllib/FixMyStreet/DB/ResultSet/Problem.pm
@@ -28,13 +28,23 @@ sub body_query {
sub non_public_if_possible {
my ($rs, $params, $c) = @_;
if ($c->user_exists) {
+ my $only_non_public = $c->stash->{only_non_public} ? 1 : 0;
if ($c->user->is_superuser) {
# See all reports, no restriction
- } elsif ($c->user->has_body_permission_to('report_inspect')) {
- $params->{'-or'} = [
- non_public => 0,
- $rs->body_query($c->user->from_body->id),
- ];
+ $params->{non_public} = 1 if $only_non_public;
+ } elsif ($c->user->has_body_permission_to('report_inspect') ||
+ $c->user->has_body_permission_to('report_mark_private')) {
+ if ($only_non_public) {
+ $params->{'-and'} = [
+ non_public => 1,
+ $rs->body_query($c->user->from_body->id),
+ ];
+ } else {
+ $params->{'-or'} = [
+ non_public => 0,
+ $rs->body_query($c->user->from_body->id),
+ ];
+ }
} else {
$params->{non_public} = 0;
}
@@ -57,6 +67,10 @@ sub to_body {
# Front page statistics
+sub _cache_timeout {
+ FixMyStreet->config('CACHE_TIMEOUT') // 3600;
+}
+
sub recent_fixed {
my $rs = shift;
my $key = "recent_fixed:$site_key";
@@ -66,7 +80,7 @@ sub recent_fixed {
state => [ FixMyStreet::DB::Result::Problem->fixed_states() ],
lastupdate => { '>', \"current_timestamp-'1 month'::interval" },
} )->count;
- Memcached::set($key, $result, 3600);
+ Memcached::set($key, $result, _cache_timeout());
}
return $result;
}
@@ -80,7 +94,7 @@ sub number_comments {
{ 'comments.state' => 'confirmed' },
{ join => 'comments' }
)->count;
- Memcached::set($key, $result, 3600);
+ Memcached::set($key, $result, _cache_timeout());
}
return $result;
}
@@ -95,7 +109,7 @@ sub recent_new {
state => [ FixMyStreet::DB::Result::Problem->visible_states() ],
confirmed => { '>', \"current_timestamp-'$interval'::interval" },
} )->count;
- Memcached::set($key, $result, 3600);
+ Memcached::set($key, $result, _cache_timeout());
}
return $result;
}
@@ -144,10 +158,10 @@ sub _recent {
# Need to reattach schema so that confirmed column gets reinflated.
$probs->[0]->result_source->schema( $rs->result_source->schema ) if $probs->[0];
# Catch any cached ones since hidden
- $probs = [ grep { ! $_->is_hidden } @$probs ];
+ $probs = [ grep { $_->photo && ! $_->is_hidden } @$probs ];
} else {
$probs = [ $rs->search( $query, $attrs )->all ];
- Memcached::set($key, $probs, 3600);
+ Memcached::set($key, $probs, _cache_timeout());
}
}
@@ -172,6 +186,9 @@ sub around_map {
latitude => { '>=', $p{min_lat}, '<', $p{max_lat} },
longitude => { '>=', $p{min_lon}, '<', $p{max_lon} },
};
+
+ $q->{$c->stash->{report_age_field}} = { '>=', \"current_timestamp-'$p{report_age}'::interval" } if
+ $p{report_age};
$q->{category} = $p{categories} if $p{categories} && @{$p{categories}};
$rs->non_public_if_possible($q, $c);
@@ -198,9 +215,9 @@ sub timeline {
return $rs->search(
{
-or => {
- created => { '>=', \"current_timestamp-'7 days'::interval" },
- confirmed => { '>=', \"current_timestamp-'7 days'::interval" },
- whensent => { '>=', \"current_timestamp-'7 days'::interval" },
+ 'me.created' => { '>=', \"current_timestamp-'7 days'::interval" },
+ 'me.confirmed' => { '>=', \"current_timestamp-'7 days'::interval" },
+ 'me.whensent' => { '>=', \"current_timestamp-'7 days'::interval" },
}
},
{
diff --git a/perllib/FixMyStreet/DB/ResultSet/ReportExtraFields.pm b/perllib/FixMyStreet/DB/ResultSet/ReportExtraField.pm
index 1348df3c2..9c47b1894 100644
--- a/perllib/FixMyStreet/DB/ResultSet/ReportExtraFields.pm
+++ b/perllib/FixMyStreet/DB/ResultSet/ReportExtraField.pm
@@ -1,4 +1,4 @@
-package FixMyStreet::DB::ResultSet::ReportExtraFields;
+package FixMyStreet::DB::ResultSet::ReportExtraField;
use base 'DBIx::Class::ResultSet';
use strict;