Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision dd2cd96b

Von Moritz Bunkus vor fast 14 Jahren hinzugefügt

  • ID dd2cd96b9396e8fc63c5bd4ee43d88c77923dc17
  • Vorgänger a1124f72
  • Nachfolger b04c9926

Helfer für Manager für das Sortieren von Datenbankergebnissen

Unterschiede anzeigen:

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