@@ -1321,14 +1321,14 @@ sub single
13211321
13221322 my $next_id = $self -> _next_single_id;
13231323
1324- # Check return if limiting to a set number of results
1325- return if $self -> max_results && $self -> records_retrieved_count >= $self -> max_results;
1326-
13271324 if (!$self -> is_group) # Don't retrieve in chunks for group records
13281325 {
13291326 if (
13301327 ($next_id == 0 && $self -> _single_page == 0) # First run
1331- || $next_id >= $chunk # retrieved all of current chunk
1328+ # Retrieved all of current chunk. Make sure there aren't more
1329+ # results than the chunk (possible with
1330+ # separate_records_for_multicol)
1331+ || ($next_id >= $chunk && $next_id >= @{$self -> results})
13321332 )
13331333 {
13341334 $self -> _single_page($self -> _single_page + 1) # increase to next page
@@ -1561,6 +1561,7 @@ sub clear
15611561 $self -> clear_aggregate_results;
15621562 $self -> clear_search;
15631563 $self -> _set__next_single_id(0);
1564+ $self -> _single_page(0);
15641565 $self -> _set_current_ids(undef );
15651566 $self -> _clear_all_cids_store;
15661567 $self -> _clear_cid_search_query_cache
@@ -2510,20 +2511,48 @@ sub data_timeline
25102511 # E.g. if a day is subtracted from 26th March 2018 01:00 London then it will be an
25112512 # invalid time and DateTime will bork.
25122513 $min = min map $_ -> {dt }, @items ;
2513- $min -> set_time_zone(' UTC' )-> subtract(days => 1) if $min ;
2514+ if ($min )
2515+ {
2516+ # There is a chance that $min will be the same object as $max.
2517+ # Clone it to ensure we don't change both below
2518+ $min = $min -> clone;
2519+ $min -> set_time_zone(' UTC' ); # ->subtract(days => 1);
2520+ }
25142521
25152522 # Fix the max to no longer be where we retrieved to, but actually the
25162523 # max value of the finalised items array. Then add some padding.
25172524 $max = max map $_ -> {dt }, @items ;
2518- # one day already added to show period to end of day
2519- $max -> set_time_zone(' UTC' )-> add(days => 2) if $max ;
2520- }
2521- elsif ($original_from && $original_to )
2522- { @items = @{$timeline -> items};
2523- ($min , $max ) = ($original_from , $original_to );
2524- }
2525- else
2526- { @items = @{$timeline -> items};
2525+ if ($max )
2526+ {
2527+ $max = $max -> clone;
2528+ $max -> set_time_zone(' UTC' );
2529+ }
2530+
2531+ # Set from and to so that a re-retrieval retrieves the same results
2532+ $self -> to($max -> clone-> add(days => 1)) # one day already added to show period to end of day
2533+ if $max ;
2534+ $self -> from($min -> clone)
2535+ if $min ;
2536+
2537+ # Set the display range of the timeline
2538+ $original_from = $min && $min -> subtract(days => 1);
2539+ $max -> add(days => 2) if $max ;
2540+ $original_to = $max ;
2541+ }
2542+ # If the $limit_qty routine above was used, re-retrieve all of the items to
2543+ # ensure correct sorting (in the case of grouping). XXX This only needs to
2544+ # be done if there was a grouping, but at the moment it is done for all
2545+ # conditions, to ensure they are all fully tested in the tests. What is
2546+ # needed is for the tests to be run twice, once for no re-retrieval and
2547+ # once for re-retrieval. The performance hit is probably quite low, as the
2548+ # above routine is only used when initially looking at the timeline, before
2549+ # a range has been selected by the user.
2550+ if (!$limit_qty || @items )
2551+ {
2552+ @items = @{$timeline -> items};
2553+ my $m = min map $_ -> {dt }, @items ;
2554+ ($min , $max ) = ($original_from , $original_to )
2555+ if $original_from && $original_to ;
25272556 }
25282557
25292558 # Remove dt (DateTime) value, otherwise JSON encoding borks
0 commit comments