X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=SL%2FDB%2FHelper%2FSorted.pm;h=c536ccd7be82499c8d5fc7d96fe88c6c82682f46;hb=f5e39f21bd5f9c5dd9a8bbbdfa34d0c17a2fc44d;hp=1b6c42a3cc8c7a7b6013ef10ac88896729cad339;hpb=45970e731c7e0c8a3d469a1c344af20c18987c20;p=kivitendo-erp.git diff --git a/SL/DB/Helper/Sorted.pm b/SL/DB/Helper/Sorted.pm index 1b6c42a3c..c536ccd7b 100644 --- a/SL/DB/Helper/Sorted.pm +++ b/SL/DB/Helper/Sorted.pm @@ -16,7 +16,7 @@ sub make_sort_string { my $sort_dir = defined($params{sort_dir}) ? $params{sort_dir} * 1 : $sort_spec->{default}->[1]; my $sort_dir_str = $sort_dir ? 'ASC' : 'DESC'; - my $sort_by = $params{sort_by}; + my $sort_by = $params{sort_by} || { }; $sort_by = $sort_spec->{default}->[0] unless $sort_spec->{columns}->{$sort_by}; my $nulls_str = ''; @@ -27,6 +27,10 @@ sub make_sort_string { my $sort_by_str = $sort_spec->{columns}->{$sort_by}; $sort_by_str = [ $sort_by_str ] unless ref($sort_by_str) eq 'ARRAY'; + + # generate tiebreaker + push @$sort_by_str, @{ $sort_spec->{tiebreaker} }; + $sort_by_str = join(', ', map { "${_} ${sort_dir_str}${nulls_str}" } @{ $sort_by_str }); return wantarray ? ($sort_by, $sort_dir, $sort_by_str) : $sort_by_str; @@ -50,6 +54,7 @@ sub _make_sort_spec { my %sort_spec = defined &{ "${class}::_sort_spec" } ? $class->_sort_spec : (); my $meta = $class->object_class->meta; + my $table = $meta->table; if (!$sort_spec{default}) { my @primary_keys = $meta->primary_key; @@ -59,8 +64,6 @@ sub _make_sort_spec { $sort_spec{columns} ||= { SIMPLE => [ map { "$_" } $meta->columns ] }; if ($sort_spec{columns}->{SIMPLE}) { - my $table = $meta->table; - if (!ref($sort_spec{columns}->{SIMPLE}) && ($sort_spec{columns}->{SIMPLE} eq 'ALL')) { map { $sort_spec{columns}->{"$_"} ||= "${table}.${_}"} @{ $meta->columns }; delete $sort_spec{columns}->{SIMPLE}; @@ -69,6 +72,8 @@ sub _make_sort_spec { } } + $sort_spec{tiebreaker} ||= [ map { "${table}.${_}" } $meta->primary_key ]; + return \%sort_spec; } @@ -122,7 +127,7 @@ sorting of database records Evaluates C<$params{sort_by}> and C<$params{sort_dir}> and returns an SQL string suitable for sorting. The package this package is mixed into has to provide a method L that returns a hash whose -structure is explained below. That hash is authoritive in which +structure is explained below. That hash is authoritative in which columns may be sorted, which column to sort by by default and how to handle C values. @@ -173,7 +178,7 @@ strings by which to sort. Example: customer_name => 'lower(customer.name)', }, -If sorting by a column is requested that is not a key in this hash +If sorting is requested for a column that is not a key in this hash then the default column name will be used. The value can be either a scalar or an array reference. If it's the @@ -196,12 +201,12 @@ Either a scalar or a hash reference determining where C values will be sorted. If undefined then the decision is left to the database. -If it is a scalar then all the same value will be used for all +If it is a scalar then the same value will be used for all classes. The value is either C or C. If it is a hash reference then its keys are column names (not SQL names). The values are either C or C. If a column name is -not found in this hash then the special keu C will be looked +not found in this hash then the special key C will be looked up and used if it is found. Example: @@ -211,6 +216,15 @@ Example: default => 'LAST', }, +=item C + +Optional tiebreaker sorting that gets appended to any user requested sorting. +Needed to make sorting by non unique columns deterministic. + +If present must be an arrayref of column sort specs (see C). + +Defaults to primary keys. + =back =back