Implement paging on library listings (#369)
authorMarcel van der Veldt <m.vanderveldt@outlook.com>
Thu, 16 Jun 2022 10:30:55 +0000 (12:30 +0200)
committerGitHub <noreply@github.com>
Thu, 16 Jun 2022 10:30:55 +0000 (12:30 +0200)
implement paging on library listings

music_assistant/helpers/database.py
music_assistant/models/media_controller.py

index dc44043396e61328ef9275e15b8d379aec21b315..329c6bda5eb07f7a3de8fc96f90c2938aecddb84 100755 (executable)
@@ -85,6 +85,8 @@ class Database:
         table: str,
         match: dict = None,
         order_by: str = None,
+        limit: int = 500,
+        offset: int = 0,
         db: Optional[Db] = None,
     ) -> List[Mapping]:
         """Get all rows for given table."""
@@ -97,7 +99,12 @@ class Database:
             return await _db.fetch_all(sql_query, match)
 
     async def get_rows_from_query(
-        self, query: str, params: Optional[dict] = None, db: Optional[Db] = None
+        self,
+        query: str,
+        params: Optional[dict] = None,
+        limit: int = 500,
+        offset: int = 0,
+        db: Optional[Db] = None,
     ) -> List[Mapping]:
         """Get all rows for given custom query."""
         async with self.get_db(db) as _db:
@@ -109,7 +116,7 @@ class Database:
         match: dict = None,
         db: Optional[Db] = None,
     ) -> AsyncGenerator[Mapping, None]:
-        """Iterate rows for given table."""
+        """Iterate (all) rows for given table."""
         async with self.get_db(db) as _db:
             sql_query = f"SELECT * FROM {table}"
             if match is not None:
index 08bffa3a624c24560b184aa2aea71eca8b32542e..0884ee03100bc2e8dc55d02321e88480826bba46 100644 (file)
@@ -64,12 +64,14 @@ class MediaControllerBase(Generic[ItemCls], metaclass=ABCMeta):
         """Update record in the database, merging data."""
         raise NotImplementedError
 
-    async def library(self) -> List[ItemCls]:
+    async def library(self, limit: int = 500, offset: int = 0) -> List[ItemCls]:
         """Get all in-library items."""
         match = {"in_library": True}
         return [
             self.item_cls.from_db_row(db_row)
-            for db_row in await self.mass.database.get_rows(self.db_table, match)
+            for db_row in await self.mass.database.get_rows(
+                self.db_table, match, limit=limit, offset=offset
+            )
         ]
 
     async def count(self) -> int:
@@ -231,13 +233,19 @@ class MediaControllerBase(Generic[ItemCls], metaclass=ABCMeta):
         self,
         query: Optional[str] = None,
         query_params: Optional[dict] = None,
+        limit: int = 500,
+        offset: int = 0,
         db: Optional[Db] = None,
     ) -> List[ItemCls]:
         """Fetch all records from database."""
         if query is not None:
-            func = self.mass.database.get_rows_from_query(query, query_params, db=db)
+            func = self.mass.database.get_rows_from_query(
+                query, query_params, limit=limit, offset=offset, db=db
+            )
         else:
-            func = self.mass.database.get_rows(self.db_table, db=db)
+            func = self.mass.database.get_rows(
+                self.db_table, limit=limit, offset=offset, db=db
+            )
         return [self.item_cls.from_db_row(db_row) for db_row in await func]
 
     async def get_db_item(self, item_id: int, db: Optional[Db] = None) -> ItemCls:
@@ -272,12 +280,14 @@ class MediaControllerBase(Generic[ItemCls], metaclass=ABCMeta):
         provider: Optional[ProviderType] = None,
         provider_id: Optional[str] = None,
         provider_item_ids: Optional[Tuple[str]] = None,
+        limit: int = 500,
+        offset: int = 0,
         db: Optional[Db] = None,
     ) -> List[ItemCls]:
         """Fetch all records from database for given provider."""
         assert provider or provider_id, "provider or provider_id must be supplied"
         if provider == ProviderType.DATABASE or provider_id == "database":
-            return await self.get_db_items(db=db)
+            return await self.get_db_items(limit=limit, offset=offset, db=db)
 
         query = f"SELECT * FROM {self.db_table}, json_each(provider_ids)"
         if provider_id is not None:
@@ -292,7 +302,7 @@ class MediaControllerBase(Generic[ItemCls], metaclass=ABCMeta):
                 prov_ids = prov_ids.replace(",)", ")")
             query += f" AND json_extract(json_each.value, '$.item_id') in {prov_ids}"
 
-        return await self.get_db_items(query, db=db)
+        return await self.get_db_items(query, limit=limit, offset=offset, db=db)
 
     async def iterate_db_items(
         self,