From 54f1a865fd48fed6aa812d325c0fde9bb0d0e9a9 Mon Sep 17 00:00:00 2001
From: Maxim Podosochnyy <podosochnyy@perx.ru>
Date: Thu, 14 Mar 2024 17:38:51 +0700
Subject: [PATCH] =?UTF-8?q?=D0=98=D0=B7=20PerxisDataProvider=20=D0=B2?=
 =?UTF-8?q?=D1=8B=D0=BD=D0=B5=D1=81=D0=B5=D0=BD=D0=B0=20=D0=BB=D0=BE=D0=B3?=
 =?UTF-8?q?=D0=B8=D0=BA=D0=B0=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B=20?=
 =?UTF-8?q?=D1=81=20item=20=D0=B8=20referrence?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 perxis/provider.py | 231 ++++++++++++++++++++++++++++++++++++---------
 1 file changed, 187 insertions(+), 44 deletions(-)

diff --git a/perxis/provider.py b/perxis/provider.py
index 213b8c4..39ec678 100644
--- a/perxis/provider.py
+++ b/perxis/provider.py
@@ -13,28 +13,50 @@ DEFAULT_PAGE_SIZE: int = 100
 DEFAULT_PART_SIZE: int = 1024 * 5
 
 
-class PerxisDataProvider:
+class PerxisReferencesWrapper:
+    __references: references_pb2_grpc.ReferencesStub
+
     def __init__(
-        self,
-        channel: GrpcChannel,
-        space_id: str,
-        env_id: str,
-    ) -> None:
-        self.channel = channel
-        self.space_id = space_id
-        self.env_id = env_id
-        self.items_stub = items_pb2_grpc.ItemsStub(self.channel.channel)
-        self.references_stub = references_pb2_grpc.ReferencesStub(self.channel.channel)
+            self,
+            references: references_pb2_grpc.ReferencesStub,
+    ):
+        self.__references = references
+
+    async def get_references(
+        self, references: list[Reference], space_id: str, env_id: str
+    ) -> items_pb2.GetResponse:
+        """Метод получения связей."""
+        result = await self.__references.Get(
+            references_pb2.GetRequest(
+                space_id=space_id,
+                env_id=env_id,
+                references=[
+                    references_pb2.Reference(id=ref.id, collection_id=ref.collection_id)
+                    for ref in references
+                ],
+            )
+        )
+        return result
+
+
+class PerxisItemsWrapper:
+    __items: items_pb2_grpc.ItemsStub
+
+    def __init__(
+            self,
+            items: items_pb2_grpc.ItemsStub,
+    ):
+        self.__items = items
 
     async def create(
-        self, data: Struct, collection_id: str
+        self, data: Struct, collection_id: str, space_id: str, env_id: str
     ) -> items_pb2.CreateResponse:
         """Сохранение данных формы в системе Perxis."""
-        result = await self.items_stub.Create(
+        result = await self.__items.Create(
             items_pb2.CreateRequest(
                 item=items_pb2.Item(
-                    space_id=self.space_id,
-                    env_id=self.env_id,
+                    space_id=space_id,
+                    env_id=env_id,
                     collection_id=collection_id,
                     data=data,
                 )
@@ -42,14 +64,14 @@ class PerxisDataProvider:
         )
         return result
 
-    async def update(self, item_id: str, data: Struct, collection_id: str) -> Empty:
+    async def update(self, item_id: str, data: Struct, collection_id: str, space_id: str, env_id: str) -> Empty:
         """Метод обновления записи в коллекции."""
-        result = await self.items_stub.Update(
+        result = await self.__items.Update(
             items_pb2.UpdateRequest(
                 item=items_pb2.Item(
                     id=item_id,
-                    space_id=self.space_id,
-                    env_id=self.env_id,
+                    space_id=space_id,
+                    env_id=env_id,
                     collection_id=collection_id,
                     data=data,
                 )
@@ -60,21 +82,24 @@ class PerxisDataProvider:
     async def find(
         self,
         collection_id: str,
+        space_id: str,
+        env_id: str,
         filters: list[str] | None = None,
         sort_by: list[str] | None = None,
+        fields: list[str] | None = None,
         page_num: int | None = None,
         page_size: int | None = DEFAULT_PAGE_SIZE,
     ) -> items_pb2.FindResponse:
         """Метод поиска записей в коллекции."""
-        result = await self.items_stub.Find(
+        result = await self.__items.Find(
             items_pb2.FindRequest(
-                space_id=self.space_id,
-                env_id=self.env_id,
+                space_id=space_id,
+                env_id=env_id,
                 collection_id=collection_id,
                 filter=items_pb2.Filter(q=filters or []),
                 options=items_pb2.FindOptions(
                     options=common_pb2.FindOptions(
-                        sort=sort_by, page_num=page_num, page_size=page_size
+                        sort=sort_by, page_num=page_num, page_size=page_size, fields=fields or []
                     )
                 ),
             )
@@ -84,6 +109,8 @@ class PerxisDataProvider:
     async def find_published(
         self,
         collection_id: str,
+        space_id: str,
+        env_id: str,
         filters: list[str] | None = None,
         fields: list[str] | None = None,
         sort_by: list[str] | None = None,
@@ -91,10 +118,10 @@ class PerxisDataProvider:
         page_size: int | None = DEFAULT_PAGE_SIZE,
     ) -> items_pb2.FindResponse:
         """Метод поиска опубликованных записей в коллекции."""
-        result = await self.items_stub.FindPublished(
+        result = await self.__items.FindPublished(
             items_pb2.FindPublishedRequest(
-                space_id=self.space_id,
-                env_id=self.env_id,
+                space_id=space_id,
+                env_id=env_id,
                 collection_id=collection_id,
                 filter=items_pb2.Filter(q=filters or []),
                 options=items_pb2.FindPublishedOptions(
@@ -112,6 +139,8 @@ class PerxisDataProvider:
     async def fetch_all_published(
         self,
         collection_id: str,
+        space_id: str,
+        env_id: str,
         filters: list[str] | None = None,
         fields: list[str] | None = None,
         sort_by: list[str] | None = None,
@@ -124,6 +153,8 @@ class PerxisDataProvider:
             "sort_by": sort_by,
             "fields": fields,
             "page_size": page_size,
+            "space_id": space_id,
+            "env_id": env_id
         }
         message = await self.find_published(**kwargs)
         yield message
@@ -137,28 +168,28 @@ class PerxisDataProvider:
         for page_num in range(1, pages + 1):
             yield await self.find_published(page_num=page_num, **kwargs)
 
-    async def unpublish(self, item_id: str, collection_id: str) -> Empty:
+    async def unpublish(self, item_id: str, collection_id: str, space_id: str, env_id: str) -> Empty:
         """Метод снятия с публикации записи в коллекции."""
-        result = await self.items_stub.Unpublish(
+        result = await self.__items.Unpublish(
             items_pb2.UnpublishRequest(
                 item=items_pb2.Item(
                     id=item_id,
-                    space_id=self.space_id,
-                    env_id=self.env_id,
+                    space_id=space_id,
+                    env_id=env_id,
                     collection_id=collection_id,
                 )
             )
         )
         return result
 
-    async def publish(self, item_id: str, collection_id: str) -> Empty:
+    async def publish(self, item_id: str, collection_id: str, space_id: str, env_id: str) -> Empty:
         """Метод публикации записи в коллекции."""
-        result = await self.items_stub.Publish(
+        result = await self.__items.Publish(
             items_pb2.PublishRequest(
                 item=items_pb2.Item(
                     id=item_id,
-                    space_id=self.space_id,
-                    env_id=self.env_id,
+                    space_id=space_id,
+                    env_id=env_id,
                     collection_id=collection_id,
                 )
             )
@@ -168,7 +199,10 @@ class PerxisDataProvider:
     async def fetch_all(
         self,
         collection_id: str,
+        space_id: str,
+        env_id: str,
         filters: list[str] | str = None,
+        fields: list[str] | None = None,
         sort_by: list[str] | str = None,
         page_size: int | None = DEFAULT_PAGE_SIZE,
     ) -> items_pb2.FindResponse:
@@ -176,8 +210,11 @@ class PerxisDataProvider:
         items = []
         storage_data = await self.find(
             collection_id=collection_id,
+            space_id=space_id,
+            env_id=env_id,
             page_size=page_size,
             filters=filters,
+            fields=fields,
         )
         items.extend(storage_data.items)
 
@@ -190,28 +227,134 @@ class PerxisDataProvider:
         for page_num in range(1, pages + 1):
             storage_data = await self.find(
                 collection_id=collection_id,
+                space_id=space_id,
+                env_id=env_id,
                 filters=filters,
                 sort_by=sort_by,
                 page_num=page_num,
                 page_size=page_size,
+                fields=fields,
             )
             items.extend(storage_data.items)
         return items_pb2.FindResponse(items=items, total=len(items))
 
+
+class PerxisDataProvider:
+    def __init__(
+        self,
+        channel: GrpcChannel,
+        space_id: str,
+        env_id: str,
+    ) -> None:
+        self.channel = channel
+        self.space_id = space_id
+        self.env_id = env_id
+        self.references_wrapper = PerxisReferencesWrapper(
+            references=references_pb2_grpc.ReferencesStub(self.channel.channel)
+        )
+        self.items_wrapper = PerxisItemsWrapper(
+            items=items_pb2_grpc.ItemsStub(self.channel.channel),
+        )
+
+    async def create(
+        self, data: Struct, collection_id: str
+    ) -> items_pb2.CreateResponse:
+        result = await self.items_wrapper.create(data, collection_id, self.space_id, self.env_id)
+
+        return result
+
+    async def update(self, item_id: str, data: Struct, collection_id: str) -> Empty:
+        result = await self.items_wrapper.update(item_id, data, collection_id, self.space_id, self.env_id)
+
+        return result
+
+    async def find(
+        self,
+        collection_id: str,
+        filters: list[str] | None = None,
+        sort_by: list[str] | None = None,
+        page_num: int | None = None,
+        page_size: int | None = DEFAULT_PAGE_SIZE,
+    ) -> items_pb2.FindResponse:
+        result = await self.items_wrapper.find(
+            collection_id, self.space_id, self.env_id, filters, sort_by, page_num, page_size
+        )
+
+        return result
+
+    async def find_published(
+        self,
+        collection_id: str,
+        filters: list[str] | None = None,
+        fields: list[str] | None = None,
+        sort_by: list[str] | None = None,
+        page_num: int | None = None,
+        page_size: int | None = DEFAULT_PAGE_SIZE,
+    ) -> items_pb2.FindResponse:
+        result = await self.items_wrapper.find_published(
+            collection_id, self.space_id, self.env_id, filters, fields, sort_by, page_num, page_size
+        )
+
+        return result
+
+    async def fetch_all_published(
+        self,
+        collection_id: str,
+        filters: list[str] | None = None,
+        fields: list[str] | None = None,
+        sort_by: list[str] | None = None,
+        page_size: int | None = DEFAULT_PAGE_SIZE,
+    ) -> items_pb2.FindResponse:
+        """Метод поиска всех опубликованных записей в коллекции."""
+        kwargs = {
+            "collection_id": collection_id,
+            "filters": filters,
+            "sort_by": sort_by,
+            "fields": fields,
+            "page_size": page_size,
+        }
+        message = await self.find_published(**kwargs)
+        yield message
+
+        if pages := message.total // page_size:
+            if message.total % page_size:
+                pages += 1
+        else:
+            pages = 1
+
+        for page_num in range(1, pages + 1):
+            yield await self.find_published(page_num=page_num, **kwargs)
+
+    async def unpublish(self, item_id: str, collection_id: str) -> Empty:
+        result = await self.items_wrapper.unpublish(item_id, collection_id, self.space_id, self.env_id)
+
+        return result
+
+    async def publish(self, item_id: str, collection_id: str) -> Empty:
+        result = await self.items_wrapper.publish(item_id, collection_id, self.space_id, self.env_id)
+
+        return result
+
+    async def fetch_all(
+        self,
+        collection_id: str,
+        filters: list[str] | str = None,
+        sort_by: list[str] | str = None,
+        page_size: int | None = DEFAULT_PAGE_SIZE,
+    ) -> items_pb2.FindResponse:
+        result = await self.items_wrapper.fetch_all(
+            collection_id, self.space_id, self.env_id, filters, sort_by, page_size
+        )
+
+        return result
+
     async def get_references(
         self, references: list[Reference]
     ) -> items_pb2.GetResponse:
-        """Метод получения связей."""
-        result = await self.references_stub.Get(
-            references_pb2.GetRequest(
-                space_id=self.space_id,
-                env_id=self.env_id,
-                references=[
-                    references_pb2.Reference(id=ref.id, collection_id=ref.collection_id)
-                    for ref in references
-                ],
-            )
+        result = await self.references_wrapper.get_references(
+            references, self.space_id, self.env_id
         )
+
         return result
 
 
-- 
GitLab