Revision dd2cd96b
Von Moritz Bunkus vor fast 14 Jahren hinzugefügt
SL/DB/Helpers/Sorted.pm | ||
---|---|---|
1 |
package SL::DB::Helpers::Sorted; |
|
2 |
|
|
3 |
use strict; |
|
4 |
|
|
5 |
require Exporter; |
|
6 |
our @ISA = qw(Exporter); |
|
7 |
our @EXPORT = qw(get_all_sorted make_sort_string); |
|
8 |
|
|
9 |
my %sort_spec; |
|
10 |
|
|
11 |
sub make_sort_string { |
|
12 |
my ($class, %params) = @_; |
|
13 |
|
|
14 |
%sort_spec = $class->_sort_spec unless %sort_spec; |
|
15 |
|
|
16 |
my $sort_dir = defined($params{sort_dir}) ? $params{sort_dir} * 1 : $sort_spec{default}->[1]; |
|
17 |
my $sort_dir_str = $sort_dir ? 'ASC' : 'DESC'; |
|
18 |
|
|
19 |
my $sort_by = $params{sort_by}; |
|
20 |
$sort_by = $sort_spec{default}->[0] unless $sort_spec{columns}->{$sort_by}; |
|
21 |
|
|
22 |
my $nulls_str = ''; |
|
23 |
if ($sort_spec{nulls}) { |
|
24 |
$nulls_str = ref($sort_spec{nulls}) ? ($sort_spec{nulls}->{$sort_by} || $sort_spec{nulls}->{default}) : $sort_spec{nulls}; |
|
25 |
$nulls_str = " NULLS ${nulls_str}" if $nulls_str; |
|
26 |
} |
|
27 |
|
|
28 |
my $sort_by_str = $sort_spec{columns}->{$sort_by}; |
|
29 |
$sort_by_str = [ $sort_by_str ] unless ref($sort_by_str) eq 'ARRAY'; |
|
30 |
$sort_by_str = join(', ', map { "${_} ${sort_dir_str}${nulls_str}" } @{ $sort_by_str }); |
|
31 |
|
|
32 |
return wantarray ? ($sort_by, $sort_dir, $sort_by_str) : $sort_by_str; |
|
33 |
} |
|
34 |
|
|
35 |
sub get_all_sorted { |
|
36 |
my ($class, %params) = @_; |
|
37 |
my $sort_str = $class->make_sort_string(sort_by => delete($params{sort_by}), sort_dir => delete($params{sort_dir})); |
|
38 |
|
|
39 |
return $class->get_all(sort_by => $sort_str, %params); |
|
40 |
} |
|
41 |
|
|
42 |
1; |
|
43 |
|
|
44 |
__END__ |
|
45 |
|
|
46 |
=encoding utf8 |
|
47 |
|
|
48 |
=head1 NAME |
|
49 |
|
|
50 |
SL::DB::Helpers::Sorted - Mixin for a manager class that handles |
|
51 |
sorting of database records |
|
52 |
|
|
53 |
=head1 SYNOPSIS |
|
54 |
|
|
55 |
package SL::DB::Manager::Message; |
|
56 |
|
|
57 |
use SL::DB::Helpers::Sorted; |
|
58 |
|
|
59 |
sub _sort_spec { |
|
60 |
return ( columns => { recipient_id => [ 'CASE |
|
61 |
WHEN recipient_group_id IS NULL THEN lower(recipient.name) |
|
62 |
ELSE lower(recipient_group.name) |
|
63 |
END', ], |
|
64 |
sender_id => [ 'lower(sender.name)', ], |
|
65 |
created_at => [ 'created_at', ], |
|
66 |
subject => [ 'lower(subject)', ], |
|
67 |
status => [ 'NOT COALESCE(unread, FALSE)', 'created_at' ], |
|
68 |
}, |
|
69 |
default => [ 'status', 1 ], |
|
70 |
nulls => { default => 'LAST', |
|
71 |
subject => 'FIRST', |
|
72 |
} |
|
73 |
); |
|
74 |
} |
|
75 |
|
|
76 |
package SL::Controller::Message; |
|
77 |
|
|
78 |
sub action_list { |
|
79 |
my $messages = SL::DB::Manager::Message->get_all_sorted(sort_by => $::form->{sort_by}, |
|
80 |
sort_dir => $::form->{sort_dir}); |
|
81 |
} |
|
82 |
|
|
83 |
=head1 CLASS FUNCTIONS |
|
84 |
|
|
85 |
=over 4 |
|
86 |
|
|
87 |
=item C<make_sort_string %params> |
|
88 |
|
|
89 |
Evaluates C<$params{sort_by}> and C<$params{sort_dir}> and returns an |
|
90 |
SQL string suitable for sorting. The package this package is mixed |
|
91 |
into has to provide a method L</_sort_spec> that returns a hash whose |
|
92 |
structure is explained below. That hash is authoritive in which |
|
93 |
columns may be sorted, which column to sort by by default and how to |
|
94 |
handle C<NULL> values. |
|
95 |
|
|
96 |
Returns the SQL string in scalar context. In array context it returns |
|
97 |
three values: the actual column it sorts by (suitable for another call |
|
98 |
to L</make_sort_string>), the actual sort direction (either 0 or 1) |
|
99 |
and the SQL string. |
|
100 |
|
|
101 |
=item C<get_all_sorted %params> |
|
102 |
|
|
103 |
Returns C<< $class->get_all >> with C<sort_by> set to the value |
|
104 |
returned by c<< $class->make_sort_string(%params) >>. |
|
105 |
|
|
106 |
=back |
|
107 |
|
|
108 |
=head1 CLASS FUNCTIONS PROVIDED BY THE MIXING PACKAGE |
|
109 |
|
|
110 |
=over 4 |
|
111 |
|
|
112 |
=item C<_sort_spec> |
|
113 |
|
|
114 |
This method is actually not part of this package but must be provided |
|
115 |
by the package this helper is mixed into. |
|
116 |
|
|
117 |
Returns a has with the following keys: |
|
118 |
|
|
119 |
=over 2 |
|
120 |
|
|
121 |
=item C<default> |
|
122 |
|
|
123 |
A two-element array containing the name and direction by which to sort |
|
124 |
in default cases. Example: |
|
125 |
|
|
126 |
default => [ 'name', 1 ], |
|
127 |
|
|
128 |
=item C<columns> |
|
129 |
|
|
130 |
A hash reference. Its keys are column names, and its values are SQL |
|
131 |
strings by which to sort. Example: |
|
132 |
|
|
133 |
columns => { transaction_description => 'oe.transaction_description', |
|
134 |
customer_name => 'lower(customer.name)', |
|
135 |
}, |
|
136 |
|
|
137 |
If sorting by a column is requested that is not a key in this hash |
|
138 |
then the default column name will be used. |
|
139 |
|
|
140 |
The value can be either a scalar or an array reference. If it's the |
|
141 |
latter then both the sort direction as well as the null handling will |
|
142 |
be appended to each of its members. |
|
143 |
|
|
144 |
=item C<nulls> |
|
145 |
|
|
146 |
Either a scalar or a hash reference determining where C<NULL> values |
|
147 |
will be sorted. If undefined then the decision is left to the |
|
148 |
database. |
|
149 |
|
|
150 |
If it is a scalar then all the same value will be used for all |
|
151 |
classes. The value is either C<FIRST> or C<LAST>. |
|
152 |
|
|
153 |
If it is a hash reference then its keys are column names (not SQL |
|
154 |
names). The values are either C<FIRST> or C<LAST>. If a column name is |
|
155 |
not found in this hash then the special keu C<default> will be looked |
|
156 |
up and used if it is found. |
|
157 |
|
|
158 |
Example: |
|
159 |
|
|
160 |
nulls => { transaction_description => 'FIRST', |
|
161 |
customer_name => 'FIRST', |
|
162 |
default => 'LAST', |
|
163 |
}, |
|
164 |
|
|
165 |
=back |
|
166 |
|
|
167 |
=back |
|
168 |
|
|
169 |
=head1 BUGS |
|
170 |
|
|
171 |
Nothing here yet. |
|
172 |
|
|
173 |
=head1 AUTHOR |
|
174 |
|
|
175 |
Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt> |
|
176 |
|
|
177 |
=cut |
Auch abrufbar als: Unified diff
Helfer für Manager für das Sortieren von Datenbankergebnissen