diff --git a/postgrestutils/client/postgrestclient.py b/postgrestutils/client/postgrestclient.py index 79dbfde3c5c2abb7f9f57d0cb7f2f8629894f35f..0c087535a9a6fb2638a8c8982906dabf076c4052 100644 --- a/postgrestutils/client/postgrestclient.py +++ b/postgrestutils/client/postgrestclient.py @@ -130,10 +130,15 @@ class LazyPostgrestJsonResult: if isinstance(key, slice) and key.step is not None: raise ValueError("{self.__class__.__name__} does not support stepping".format(self=self)) + # cache is not populated and unbounded slice is requested, i.e. res[:] + if isinstance(key, slice) and all(e is None for e in (self._result_cache, key.start, key.stop)): + self._fetch_all() + if self._result_cache is not None: return self._result_cache[key] if isinstance(key, slice): + range = '{start}-{stop}'.format( start=key.start or 0, stop=key.stop and key.stop - 1 or '' diff --git a/tests/test_postgrestclient.py b/tests/test_postgrestclient.py index 1cb39c891ee0a1ed738ef9a48af9b38b25952be0..99e2d48d09f32676e14e0997de6861f42bbb830c 100644 --- a/tests/test_postgrestclient.py +++ b/tests/test_postgrestclient.py @@ -226,6 +226,29 @@ class TestPgrestClientFilterStrategyNone(TestCase): self.assertListEqual(list(res), self.data) # should utilize cache self.assertTrue(mock.called_once) # should not have been called again + def test_cache_fetching_unbounded_slice(self, mock): + mock.register_uri( + 'GET', + 'http://example.com/superhero', + request_headers=DEFAULT_HEADERS, + status_code=200, + reason='OK', + json=self.data + ) + res = self.pgrest_client.filter('superhero') + + self.assertIsInstance(res, LazyPostgrestJsonResult) # should return lazy object + self.assertFalse(mock.called) # no request should have been made yet + + self.assertListEqual(res[:], self.data) # fetch data + self.assertTrue(mock.called_once) # should have been called once + self.assertListEqual(res._result_cache, self.data) # fetched data should be cached + self.assertEqual(res._len_cache, len(self.data)) # len of fetched data should be cached + self.assertListEqual(res[:], self.data) # should utilize cache + self.assertListEqual(res[2:], self.data[2:]) # should utilize cache + self.assertDictEqual(res[0], self.data[0]) # should utilize cache + self.assertTrue(mock.called_once) # should not have been called again + @Mocker() class TestPgrestClientFilterStrategyExact(TestCase):