Example #1
0
    def end(self, element):
        super().end(element)

        if element.tag == self.tag:
            nursery = get_nursery()
            logger.info("cache size: %d", len(nursery.cache.keys()))
            nursery.clear_cache()
Example #2
0
def clear_workbasket(workbasket):
    """
    Deletes all objects connected to the workbasket while preserving the
    workbasket itself.

    Due to the DB relations this has to be done in a specific order.

    - First the Tracked Models must be deleted in reverse order.
        - As these are deleted their VersionGroups must be deleted
          or reset to have the previous version as current.
        - Also if any of these exist within the cache they must
          be removed from the cache.
    - Second Transactions are deleted.
    """
    nursery = get_nursery()

    for obj in workbasket.tracked_models.order_by("-pk"):
        version_group = obj.version_group
        obj.delete()
        nursery.remove_object_from_cache(obj)
        if version_group.versions.count() == 0:
            version_group.delete()
        else:
            version_group.current_version = version_group.versions.order_by(
                "-pk",
            ).first()
            version_group.save()

    workbasket.transactions.all().delete()
Example #3
0
def delete_workbasket(workbaset):
    """
    Deletes all objects connected to the workbasket and the workbasket itself.

    Due to the DB relations this has to be done in a specific order.

    - First the GoodsNomenclatureIndentNodes must be deleted.
    - Second the Tracked Models must be deleted in reverse order.
        - As these are deleted their VersionGroups must be deleted
          or reset to have the previous version as current.
        - Also if any of these exist within the cache they must
          be removed from the cache.
    - Third Transactions are deleted.
    - Fourth the WorkBasket is deleted
    """
    nursery = get_nursery()
    GoodsNomenclatureIndentNode.objects.filter(
        creating_transaction__workbasket=workbaset).delete()
    for obj in workbaset.tracked_models.order_by("-pk"):
        version_group = obj.version_group
        obj.delete()
        nursery.remove_object_from_cache(obj)
        if version_group.versions.count() == 0:
            version_group.delete()
        else:
            version_group.current_version = version_group.versions.order_by(
                "-pk").first()
            version_group.save()

    workbaset.transactions.all().delete()
    workbaset.delete()
Example #4
0
    def check(
        factory: Callable[[], TrackedModel],
        serializer: Type[TrackedModelSerializer],
        record_group: Sequence[str] = None,
        workflow_status: WorkflowStatus = WorkflowStatus.PUBLISHED,
    ) -> TrackedModel:
        get_nursery().cache.clear()
        settings.SKIP_WORKBASKET_VALIDATION = True

        model = factory()
        model_class = type(model)
        assert isinstance(
            model,
            TrackedModel,
        ), "A factory that returns an object instance needs to be provided"

        xml = generate_test_import_xml(
            [serializer(model, context={"format": "xml"}).data],
        )

        import_xml(xml, workflow_status, record_group)

        db_kwargs = model.get_identifying_fields()
        workbasket = WorkBasket.objects.last()
        assert workbasket is not None

        try:
            imported = model_class.objects.approved_up_to_transaction(
                workbasket.current_transaction,
            ).get(**db_kwargs)
        except model_class.DoesNotExist:
            if model.update_type == UpdateType.DELETE:
                imported = (
                    model_class.objects.versions_up_to(workbasket.current_transaction)
                    .filter(**db_kwargs)
                    .last()
                )
            else:
                raise

        assert_records_match(model, imported)
        return imported
Example #5
0
    def check(
        model: Union[TrackedModel, Type[DjangoModelFactory]],
        serializer: Type[TrackedModelSerializer],
    ) -> TrackedModel:
        get_nursery().cache.clear()
        settings.SKIP_WORKBASKET_VALIDATION = True
        if isinstance(model, type) and issubclass(model, DjangoModelFactory):
            model = model.build(update_type=UpdateType.CREATE)

        assert isinstance(
            model,
            TrackedModel,
        ), "Either a factory or an object instance needs to be provided"

        xml = generate_test_import_xml(
            serializer(model, context={"format": "xml"}).data,
        )

        process_taric_xml_stream(
            xml,
            username=valid_user.username,
            status=WorkflowStatus.PUBLISHED,
        )

        db_kwargs = model.get_identifying_fields()
        imported = model.__class__.objects.get_latest_version(**db_kwargs)

        checked_fields = (
            set(field.name for field in imported._meta.fields)
            - set(field.name for field in TrackedModel._meta.fields)
            - {"trackedmodel_ptr"}
        )

        for field in checked_fields:
            imported_value = getattr(imported, field)
            source_value = getattr(model, field)
            assert (
                imported_value == source_value
            ), f"imported '{field}' ({imported_value} - {type(imported_value)}) does not match source '{field}' ({source_value} - {type(source_value)})"

        return imported
Example #6
0
class Writable:
    """
    A parser which implements the Writable interface can write its changes to
    the database.

    Not all TARIC3 elements correspond to database entities (particularly simple
    text elements, but also envelopes and app.messages).
    """

    nursery = get_nursery()

    def create(self, data: Mapping[str, Any], transaction_id: int):
        """Preps the given data as a create record and submits it to the nursery
        for processing."""
        data.update(update_type=UpdateType.CREATE)

        dispatch_object = {
            "data": data,
            "tag": self.tag.name,
            "transaction_id": transaction_id,
        }

        self.nursery.submit(dispatch_object)

    def update(self, data: Mapping[str, Any], transaction_id: int):
        """Update a DB record with provided data."""
        data.update(update_type=UpdateType.UPDATE.value)

        dispatch_object = {
            "data": data,
            "tag": self.tag.name,
            "transaction_id": transaction_id,
        }

        self.nursery.submit(dispatch_object)

    def delete(self, data: Mapping[str, Any], transaction_id: int):
        """Delete a DB record with provided data."""
        data.update(update_type=UpdateType.DELETE.value)

        dispatch_object = {
            "data": data,
            "tag": self.tag.name,
            "transaction_id": transaction_id,
        }

        self.nursery.submit(dispatch_object)
Example #7
0
def object_nursery() -> TariffObjectNursery:
    nursery = get_nursery()
    yield nursery
    nursery.cache.clear()