sub get_top_status { my %args = (start_point => 1, num_rows => 10, sort_by => ['result ascending'], @_); my $dbh = $args{dbh} or croak 'Missing DB handle'; # Define the valid sorts my %sorts = (id => 'T.id', name => 'T.name' ); # Build the SQL sort string my $sort = build_sort($args{sort_by}, \%sorts, ['name']); my $statement = "SELECT name, id, foo FROM FOO_TABLE ORDER BY $sort"; my $sth = $dbh->prepare($statement); $sth->execute(); my @results; while ($row = $sth->fetchrow_arrayref and $count-- > 0) { if ($offset > 0) { $offset--; $next; } push @results, $row; } $sth->finish; return \@results; } # Takes a sort order and a hash defining the legal sorts and produces # a string for embedding in SQL statements # - Order is an arrayref of all the sorts to use # - Sorts is a hashref keyed by the sort names mapping sorts to columns # - Fallback is an optional arrayref of the columns to append to ensure # the ordering is sane (if we are sorting by severity we still want to # sort by name where the severity is the same) sub build_sort { my ($order, $sorts, $fallback) = @_; $fallback = [] unless defined $fallback; my %done = (); my $sort = ''; foreach my $s (@$order, @$fallback) { # Skip ones we have already seen next if exists $done{$s}; $done{$s} = 1; # Build the sort string $sort .= ', ' unless $sort eq ''; my ($col, $order) = (split(/ /, $s), 'asc'); croak "Bad sort request '$s' (parsed '$col' '$order')." unless exists $sorts->{$col}; $sort .= "$sorts->{$col} $order"; } return $sort; }