} @bind;
}
+sub _flatten_bind_params {
+ my ($self, @bind) = @_;
+
+ ### Turn @bind from something like this:
+ ### ( [ "artist", 1 ], [ "cdid", 1, 3 ] )
+ ### to this:
+ ### ( 1, 1, 3 )
+ return
+ map {
+ if ( defined( $_ && $_->[1] ) ) {
+ @{$_}[ 1 .. $#$_ ];
+ }
+ else { undef; }
+ } @bind;
+}
+
sub _query_start {
my ( $self, $sql, @bind ) = @_;
return @args;
}
-sub count {
+sub _trim_attributes_for_count {
my ($self, $source, $attrs) = @_;
-
- my $tmp_attrs = { %$attrs };
+ my %attrs = %$attrs;
# take off any column specs, any pagers, record_filter is cdbi, and no point of ordering a count
- delete $attrs{$_} for (qw/columns +columns select +select as +as rows offset page pager order_by record_filter/);
- delete $tmp_attrs->{$_} for (qw/columns +columns select +select as +as rows offset page pager order_by record_filter/);
++ delete @attrs{qw/
++ columns +columns select +select as +as rows offset page pager order_by
++ record_filter/)};
+
+ return \%attrs;
+}
+
+sub count {
+ my ($self, $source, $attrs) = @_;
+
+ my $new_attrs = $self->_trim_attributes_for_count($source, $attrs);
- $tmp_attrs->{select} = { count => '*' };
- $tmp_attrs->{as} = [qw/count/];
+ $new_attrs->{select} = { count => '*' };
+ $new_attrs->{as} = [qw/count/];
- my $tmp_rs = $source->resultset_class->new($source, $tmp_attrs);
+ my $tmp_rs = $source->resultset_class->new($source, $new_attrs);
my ($count) = $tmp_rs->cursor->next;
+ # if the offset/rows attributes are still present, we did not use
+ # a subquery, so we need to make the calculations in software
+ $count -= $attrs->{offset} if $attrs->{offset};
+ $count = $attrs->{rows} if $attrs->{rows} and $attrs->{rows} < $count;
+ $count = 0 if ($count < 0);
+
return $count;
}
+ sub count_grouped {
+ my ($self, $source, $attrs) = @_;
+
+ # copy for the subquery, we need to do some adjustments to it too
+ my $sub_attrs = { %$attrs };
+
+ # these can not go in the subquery, and there is no point of ordering it
+ delete $sub_attrs->{$_} for qw/prefetch collapse select +select as +as columns +columns order_by/;
+
+ # if we prefetch, we group_by primary keys only as this is what we would get out of the rs via ->next/->all
+ # simply deleting group_by suffices, as the code below will re-fill it
+ # Note: we check $attrs, as $sub_attrs has collapse deleted
+ if (ref $attrs->{collapse} and keys %{$attrs->{collapse}} ) {
+ delete $sub_attrs->{group_by};
+ }
+
+ $sub_attrs->{columns} = $sub_attrs->{group_by} ||= [ map { "$attrs->{alias}.$_" } ($source->primary_columns) ];
+
+ $attrs->{from} = [{
+ count_subq => $source->resultset_class->new ($source, $sub_attrs )->as_query
+ }];
+
+ # the subquery replaces this
+ delete $attrs->{$_} for qw/where bind prefetch collapse distinct group_by having having_bind rows offset page pager/;
+
+ return $self->count ($source, $attrs);
+ }
+
sub source_bind_attributes {
my ($self, $source) = @_;