diff --git a/lbry/lbry/extras/daemon/Daemon.py b/lbry/lbry/extras/daemon/Daemon.py index ba8e2ad62..f19d62d28 100644 --- a/lbry/lbry/extras/daemon/Daemon.py +++ b/lbry/lbry/extras/daemon/Daemon.py @@ -1816,6 +1816,8 @@ class Daemon(metaclass=JSONRPCServerType): 'publish_time', 'amount', 'effective_amount', 'support_amount', 'trending_group', 'trending_mixed', 'trending_local', 'trending_global', 'activation_height' + --no_totals : (bool) do not calculate the total number of pages and items in result set + (significant performance boost) Returns: {Paginated[Output]} """ @@ -1826,11 +1828,11 @@ class Daemon(metaclass=JSONRPCServerType): page_num, page_size = abs(kwargs.pop('page', 1)), min(abs(kwargs.pop('page_size', 10)), 50) kwargs.update({'offset': page_size * (page_num-1), 'limit': page_size}) txos, offset, total = await self.ledger.claim_search(**kwargs) - return { - "items": txos, "page": page_num, "page_size": page_size, - "total_pages": int((total + (page_size-1)) / page_size), - "total_items": total - } + result = {"items": txos, "page": page_num, "page_size": page_size} + if not kwargs.pop('no_totals', False): + result['total_pages'] = int((total + (page_size-1)) / page_size) + result['total_items'] = total + return result CHANNEL_DOC = """ Create, update, abandon and list your channel claims. diff --git a/lbry/lbry/schema/result.py b/lbry/lbry/schema/result.py index c91392b13..f8fef7b29 100644 --- a/lbry/lbry/schema/result.py +++ b/lbry/lbry/schema/result.py @@ -77,7 +77,8 @@ class Outputs: def to_bytes(cls, txo_rows, extra_txo_rows, offset=0, total=None) -> bytes: page = OutputsMessage() page.offset = offset - page.total = total or len(txo_rows) + if total is not None: + page.total = total for row in txo_rows: cls.row_to_message(row, page.txos.add()) for row in extra_txo_rows: diff --git a/lbry/lbry/wallet/server/db.py b/lbry/lbry/wallet/server/db.py index 044820d63..dae79af60 100644 --- a/lbry/lbry/wallet/server/db.py +++ b/lbry/lbry/wallet/server/db.py @@ -923,7 +923,8 @@ class SQLDB: 'any_tags', 'all_tags', 'not_tags', 'any_locations', 'all_locations', 'not_locations', 'any_languages', 'all_languages', 'not_languages', - 'is_controlling', 'limit', 'offset', 'order_by' + 'is_controlling', 'limit', 'offset', 'order_by', + 'no_totals', } | INTEGER_PARAMS ORDER_FIELDS = { @@ -933,7 +934,9 @@ class SQLDB: def search(self, constraints) -> Tuple[List, List, int, int]: assert set(constraints).issubset(self.SEARCH_PARAMS), \ f"Search query contains invalid arguments: {set(constraints).difference(self.SEARCH_PARAMS)}" - total = self.get_claims_count(**constraints) + total = None + if not constraints.pop('no_totals', False): + total = self.get_claims_count(**constraints) constraints['offset'] = abs(constraints.get('offset', 0)) constraints['limit'] = min(abs(constraints.get('limit', 10)), 50) if 'order_by' not in constraints: diff --git a/lbry/tests/integration/test_claim_commands.py b/lbry/tests/integration/test_claim_commands.py index 1ce02aa6d..24685e8d1 100644 --- a/lbry/tests/integration/test_claim_commands.py +++ b/lbry/tests/integration/test_claim_commands.py @@ -180,6 +180,14 @@ class ClaimSearchCommand(ClaimTestCase): out_of_bounds = await self.claim_search(page=2, page_size=20, channel='@abc') self.assertEqual(out_of_bounds, []) + results = await self.daemon.jsonrpc_claim_search() + self.assertEqual(results['total_pages'], 2) + self.assertEqual(results['total_items'], 13) + + results = await self.daemon.jsonrpc_claim_search(no_totals=True) + self.assertNotIn('total_pages', results) + self.assertNotIn('total_items', results) + async def test_tag_search(self): claim1 = await self.stream_create('claim1', tags=['aBc']) claim2 = await self.stream_create('claim2', tags=['#abc', 'def'])