[DBIx-Class-Devel] [dbsrgits/dbix-class] set_cache should invalidate existing related_resultset (#110)

Daniel Perrett notifications at github.com
Wed Nov 9 13:42:33 GMT 2016


In `DBIx::Class::ResultSet::related_resultset`, if the current resultset has a cache of results, the rows in that cache are checked for related objects which can be used to populate the cache belonging to the related resultset which is going to be returned. 

However, the related resultset objects themselves are also stored on `$self` in a cache (`$self->{'related_resultsets'}`), so that this process is skipped if the related resultset has already been created in a previous call to `related_resultset`. 

This means that if the cache is set after a related resultset has been created, subsequent calls to `related_resultset` retrieve the existing resultset; because it was created before the cache existed, it either has no cache of its own, or has a cache which potentially contradicts the cache in set_cache. 

There is no user-facing way to 'undo' the creation of a cached related resultset, nor is it obvious from the docs that this might be useful or necessary (not to mention why it should be). In fact, the docs don't even mention that related resultsets are cached. 

For example: in this case `$artist` is an arrayref of one item: 

    $cd_rset->set_cache(\@cds);
    my $artist_rset_after = $cd_rset->related_resultset('artist');
    my $artist = $artist_rset_after->get_cache();

... whereas in this case `$artist` is `undef`:

    my $artist_rset_before = $cd_rset->related_resultset('artist');
    $cd_rset->set_cache(\@cds);
    my $artist_rset_after = $cd_rset->related_resultset('artist');
    my $artist = $artist_rset_after->get_cache();

I see two potential solutions:

1. When `$self->set_cache` is called, clear `$self->{'related_resultsets'}`. New calls to `related_resultset` would return new resultsets with the correct cache. Resultsets previously created would be unchanged.

2. When `$self->set_cache` is called, populate the cache for each resultset in `$self->{'related_resultsets'}`. This may be surprising if those resultsets have also previously populated a cache. Furthermore, what ought to happen if `\@cds` do not all have a populated cache in their `related_resultset` for a given relationship. Should the cache on the existing resultset be emptied, or should it be left alone?

I feel that option 1 is the cleanest solution.

This PR introduces:

- A currently-failing test which demonstrates the issue
- A one-line-plus-comments fix, following the first solution.

You can view, comment on, or merge this pull request online at:

  https://github.com/dbsrgits/dbix-class/pull/110

-- Commit Summary --

  * Test how related_resultset and set_cache interact
  * Clear related_resultsets after set_cache

-- File Changes --

    M lib/DBIx/Class/ResultSet.pm (8)
    A t/resultset/cache.t (56)

-- Patch Links --

https://github.com/dbsrgits/dbix-class/pull/110.patch
https://github.com/dbsrgits/dbix-class/pull/110.diff

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/dbsrgits/dbix-class/pull/110
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.scsys.co.uk/pipermail/dbix-class-devel/attachments/20161109/d460a170/attachment.htm>


More information about the DBIx-Class-Devel mailing list