def find_one(self, specification: Specification) -> Optional[Entity]: for entity in filter(lambda i: specification.is_satisfied_by(i), self.entities.values()): return entity if self.object_not_found_exception: raise self.object_not_found_exception raise ObjectNotFoundException(f"{self.entity.__name__} not found!")
def build(specification: Specification = None) -> Optional[Collection]: if specification is None: return None elif isinstance(specification, AndSpecification): return { "$and": [ MongoSpecificationBuilder.build(spec) for spec in specification.to_collection() ] } elif isinstance(specification, OrSpecification): return { "$or": [ MongoSpecificationBuilder.build(spec) for spec in specification.to_collection() ] } elif isinstance(specification, InSpecification): return {specification.field: {"$in": specification.value}} elif isinstance(specification, EqualsSpecification): return {specification.field: {"$eq": specification.value}} elif isinstance(specification, LessThanSpecification): return {specification.field: {"$lt": specification.value}} elif isinstance(specification, LessThanEqualSpecification): return {specification.field: {"$lte": specification.value}} elif isinstance(specification, GreaterThanSpecification): return {specification.field: {"$gt": specification.value}} elif isinstance(specification, GreaterThanEqualSpecification): return {specification.field: {"$gte": specification.value}} elif isinstance(specification, RegexStringMatchSpecification): return { specification.field: { "$regex": f".*{re.escape(specification.value)}.*" } } elif isinstance(specification.to_collection(), dict): return { "$and": [{ key: { "$eq": value } } for key, value in dict(specification.to_collection()).items()] } raise SpecificationNotMappedToMongo( f"Specification '{specification}' not mapped to Mongo query.")
def build(specification: Specification = None) -> Optional[Union[Collection, Q]]: if specification is None: return None elif isinstance(specification, AndSpecification): return reduce( lambda x, y: x & y, [ DjangoOrmSpecificationBuilder.create_q( DjangoOrmSpecificationBuilder.build(spec) ) for spec in specification.to_collection() ], ) elif isinstance(specification, OrSpecification): return reduce( lambda x, y: x | y, [ DjangoOrmSpecificationBuilder.create_q( DjangoOrmSpecificationBuilder.build(spec) ) for spec in specification.to_collection() ], ) elif isinstance(specification, InSpecification): return {f"{specification.field}__in": specification.value} elif isinstance(specification, EqualsSpecification): return {specification.field: specification.value} elif isinstance(specification, LessThanSpecification): return {f"{specification.field}__lt": specification.value} elif isinstance(specification, LessThanEqualSpecification): return {f"{specification.field}__lte": specification.value} elif isinstance(specification, GreaterThanSpecification): return {f"{specification.field}__gt": specification.value} elif isinstance(specification, GreaterThanEqualSpecification): return {f"{specification.field}__gte": specification.value} elif isinstance(specification, RegexStringMatchSpecification): return { f"{specification.field}__regex": rf".*{re.escape(specification.value)}.*" } elif isinstance(specification.to_collection(), dict): return specification.to_collection() raise SpecificationNotMappedToDjangoOrm( f"Specification '{specification}' not mapped to Django Orm query." )
def _find_one_raw( self, specification: Specification, *, entity_dao_class: Optional[SqlAlchemyDao] = None, ) -> Optional[Entity]: entities = self._find_raw(specification, entity_dao_class=entity_dao_class) for entity in filter(lambda i: specification.is_satisfied_by(i), entities): return entity
def build(specification: Specification = None) -> Optional[Collection]: if specification is None: return None elif isinstance(specification, OrSpecification): return [ SqlAlchemyOrmSpecificationBuilder.build(spec) for spec in specification.to_collection() ] elif isinstance(specification, AndSpecification): return { k: v for spec in specification.to_collection() if (i := SqlAlchemyOrmSpecificationBuilder.build(spec)) for k, v in dict(i).items() if isinstance(i, dict) } elif isinstance(specification, EqualsSpecification): return {specification.field: specification.value} elif isinstance(specification.to_collection(), dict): return specification.to_collection() raise SpecificationNotMappedToSqlAlchemyOrm( f"Specification '{specification}' not mapped to SqlAlchemy Orm query." )
def find_one(self, specification: Specification) -> Optional[Entity]: _filter = FirestoreSpecificationBuilder.build(specification) collection = self.collection if _filter: if isinstance(_filter, list): for f in _filter: collection = collection.where(*f) else: collection = collection.where(*_filter) for doc in filter( lambda i: specification.is_satisfied_by(AttrDict(i.to_dict())), collection.stream(), ): return self.entity(**doc.to_dict())
def test_specification_not_or(): spec = Specification.Not( EqualsSpecification("id", 1).Or(EqualsSpecification("name", "a"))) DC = make_dataclass("DC", [("id", int), ("name", str)]) assert spec.is_satisfied_by(DC(**dict(id=2, name="b")))
def test_parse(): assert Specification.parse(id=1) == EqualsSpecification("id", 1) assert Specification.parse(id_x=1) == EqualsSpecification("id_x", 1) assert not Specification.parse(id__x=1) assert Specification.parse(id__equals=1) == EqualsSpecification("id", 1) assert Specification.parse(id__in=[1]) == InSpecification("id", [1]) assert Specification.parse(id__contains="a") == ContainsSpecification( "id", "a") assert Specification.parse(id__lt=1) == LessThanSpecification("id", 1) assert Specification.parse(id__lte=1) == LessThanEqualSpecification( "id", 1) assert Specification.parse(id__gt=1) == GreaterThanSpecification("id", 1) assert Specification.parse(id__gte=1) == GreaterThanEqualSpecification( "id", 1) assert Specification.parse(id=1, name="a") == AndSpecification( [EqualsSpecification("id", 1), EqualsSpecification("name", "a")]) assert Specification.parse(id__equals=1, name__equals="a") == AndSpecification([ EqualsSpecification("id", 1), EqualsSpecification("name", "a") ]) assert Specification.parse(id__equals=1, name="a") == AndSpecification( [EqualsSpecification("id", 1), EqualsSpecification("name", "a")]) assert Specification.parse(id=1, name__equals="a") == AndSpecification( [EqualsSpecification("id", 1), EqualsSpecification("name", "a")]) assert Specification.parse(id__gt=1, name__contains="a") == AndSpecification([ GreaterThanSpecification("id", 1), ContainsSpecification("name", "a") ])