from itertools import count import pymongo from json import loads from bson import ObjectId, json_util from pydantic import BaseModel from api_configs import MongoConfig from pymongo import MongoClient from pymongo.collection import Collection from pymongo.results import InsertManyResult # from configs import TestMongo as MongoConfig class Paginate(BaseModel): pageSize: int = 10 pageNumber: int = 1 sortField: str = "_id" sortOrder: str = "desc" def grab_paginates(self): size_ = self.pageSize return ( size_, size_ * (self.pageNumber - 1), self.sortField, -1 if self.sortOrder == "desc" else 1, ) class MongoResponse: def __init__( self, status: bool, message: str, message_code: str = None, data: dict = None, mongo=None, count: int = 1, ): self.status = status self.message = message self.data = data self.mongo = mongo self.message_code = message_code self.count = count def as_dict(self): return { "status": self.status, "count": self.count, "message": self.message, "message_code": self.message_code, "data": self.data, } class MongoQuery: def __init__(self, table_name: str, database_name: str): database = MongoClient(MongoConfig.url)[database_name] self.table: Collection = database[table_name] @staticmethod def grab_paginates(paginate): return ( paginate.size, paginate.size * (paginate.page - 1), paginate.order_field, -1 if paginate.order_type == "desc" else 1, ) @staticmethod def parse_json(data): return loads(json_util.dumps(data)) def insert(self, payload) -> MongoResponse: insert = self.table.insert_one(document=payload) if insert.acknowledged: return MongoResponse( status=True, message="The document has been created", message_code="CREATED", data=payload, mongo=insert, ) return MongoResponse( status=False, message="The document has not been created", message_code="NOT_CREATED", data=None, mongo=insert, count=0, ) def insert_many(self, payload) -> MongoResponse: insert_many = self.table.insert_many(documents=payload) if insert_many.acknowledged: return MongoResponse( status=True, message="The documents have been created", message_code="CREATED", data=payload, mongo=insert_many, count=len(payload), ) return MongoResponse( status=False, message="The documents have not been created", message_code="NOT_CREATED", data=None, mongo=insert_many, count=0, ) def find_or_insert(self, payload, field: str = "id") -> MongoResponse: if field == "id": found_row = self.get_one(match=payload["_id"], field="_id") if found_row.status: return MongoResponse( status=False, message="The document already exists", data=found_row.data, mongo=found_row.mongo, ) if mongo := self.table.insert_one(document=payload).acknowledged: return MongoResponse( status=True, message="The document has been created", data=payload, mongo=mongo, ) found_row = self.get_one(match=payload[field], field=field) if found_row.status: return MongoResponse( status=False, message_code="ALREADY_EXISTS", message="The document already exists", data=found_row.data, mongo=found_row.mongo, ) insert_row = self.table.insert_one(document=payload) return MongoResponse( status=True, message="The document has been created", message_code="CREATED", data=payload, mongo=insert_row, ) def update(self, match, payload, field: str = "id"): if field == "id": filter_ = {"_id": ObjectId(match)} update_one = self.table.update_one(filter=filter_, update={"$set": payload}) return MongoResponse( status=True, message="The document has been updated", message_code="UPDATED", data=self.get_one(match=match, field=field).data, mongo=update_one, ) update_one = self.table.update_one( filter={field: match}, update={"$set": payload} ) return MongoResponse( status=True, message="The document has been updated", message_code="UPDATED", data=self.get_one(match=match, field=field).data, mongo=update_one, ) def get_one(self, match, field: str = "id"): if field == "id": if get_one := self.table.find_one(filter={"_id": ObjectId(match)}): return MongoResponse( status=True, message="The document has been found", message_code="FOUND", data=self.parse_json(data=get_one), mongo=get_one, ) if get_one := self.table.find_one(filter={field: match}): return MongoResponse( status=True, message="The document has been found", message_code="FOUND", data=self.parse_json(data=get_one), mongo=get_one, ) return MongoResponse( status=False, message="The document has not been found", message_code="NOT_FOUND", data={}, mongo=None, ) def filter_by(self, payload, sort_by: str = "_id", sort_direction: str = "asc"): sort_direction = ( pymongo.ASCENDING if str(sort_direction).lower() == "asc" else pymongo.DESCENDING ) return_ = self.table.find(payload).sort(sort_by, sort_direction) data = self.parse_json(data=return_) if len(data) == 0: return MongoResponse( status=False, message="The documents have not been found", message_code="NOT_FOUND", data=[], mongo=return_, count=0, ) return MongoResponse( status=True, message="The documents have been found", message_code="FOUND", count=self.table.count_documents(payload), data=data, ) def delete_one(self, match, field: str = "id"): if field == "id": delete_one = self.table.delete_one(filter={"_id": ObjectId(match)}) if delete_one.deleted_count: return MongoResponse( status=True, message="The document has been deleted", message_code="DELETED", data=None, count=delete_one.deleted_count, mongo=delete_one, ) delete_one = self.table.delete_one(filter={field: match}) if delete_one.deleted_count: return MongoResponse( status=True, message="The document has been deleted", message_code="DELETED", data=None, count=delete_one.deleted_count, mongo=delete_one, ) return MongoResponse( status=False, message="The document has not been deleted", message_code="NOT_DELETED", data=None, mongo=None, count=0, ) def delete_all(self, match, field: str = "id"): if field == "id": delete_many = self.table.delete_many(filter={"_id": ObjectId(match)}) if delete_many.deleted_count: return MongoResponse( status=True, message="The document has been deleted", message_code="DELETED", data=None, count=delete_many.deleted_count, mongo=delete_many, ) delete_many = self.table.delete_many(filter={field: match}) if delete_many.deleted_count: return MongoResponse( status=True, message="The document has been deleted", message_code="DELETED", data=None, count=delete_many.deleted_count, mongo=delete_many, ) return MongoResponse( status=False, message="The document has not been deleted", message_code="NOT_DELETED", data=None, mongo=None, count=0, ) def list_all(self, paginate: Paginate): size, skip, field, order = paginate.grab_paginates() return_ = self.table.find().sort([(field, order)]).skip(skip).limit(size) self.table.count_documents({}), self.parse_json(data=return_) data = self.parse_json(data=return_) if len(data) == 0: return MongoResponse( status=False, message="The documents have not been found", message_code="NOT_FOUND", data=None, mongo=return_, count=0, ) return MongoResponse( status=True, message="The documents have been found", message_code="FOUND", count=self.table.count_documents({}), data=data, mongo=return_, ) def get_all(self): return_ = self.table.find() return MongoResponse( status=True, message="The documents have been found", message_code="FOUND", count=self.table.count_documents({}), data=self.parse_json(data=return_), mongo=return_, ) # Mongo = MongoQuery(table_name="XcompanyConfig", database_name="mongo_database")