# Path: virtool/dispatcher/operations.py
# INSERT: Operation = "insert"
# UPDATE: Operation = "update"
# DELETE: Operation = "delete"


from collections import defaultdict
from typing import Callable, List, Union
from sqlalchemy import event, inspect
from sqlalchemy.orm import Session
from virtool.dispatcher.operations import Operation
from virtool.pg.base import Base

def get_interface_from_model(obj: Base) -> str:
    """
    Transform the passed model object into an dispatcher interface name.

    For example, a :class:``Label`` model will result in a string with the value `labels` being
    returned.

    :param obj: the model object
    :return: the interface string

    """
    try:
        return obj.__tablename__
    except AttributeError:
        raise TypeError("Not a transformable model: ", obj)


class DispatcherSQLEvents:
    """
    Listens on SQLAlchemy session events to know what models have changes on transaction commits.

    Calls enqueue change with the correct dispatcher interface and list of modified IDs when a
    transaction is committed. Gracefully handles rollbacks.

    Inspired by signalling in [Flask-SQLAlchemy](https://github.com/pallets/flask-sqlalchemy).

    """

    def __init__(

# Path: virtool/dispatcher/operations.py
# INSERT: Operation = "insert"
# UPDATE: Operation = "update"
# DELETE: Operation = "delete"


# Path: virtool/dispatcher/events.py
from collections import defaultdict
from typing import Callable, List, Union
from sqlalchemy import event, inspect
from sqlalchemy.orm import Session
from virtool.dispatcher.operations import Operation
from virtool.pg.base import Base


def get_interface_from_model(obj: Base) -> str:
    """
    Transform the passed model object into an dispatcher interface name.

    For example, a :class:``Label`` model will result in a string with the value `labels` being
    returned.

    :param obj: the model object
    :return: the interface string

    """
    try:
        return obj.__tablename__
    except AttributeError:
        raise TypeError("Not a transformable model: ", obj)


class DispatcherSQLEvents:
    """
    Listens on SQLAlchemy session events to know what models have changes on transaction commits.

    Calls enqueue change with the correct dispatcher interface and list of modified IDs when a
    transaction is committed. Gracefully handles rollbacks.

    Inspired by signalling in [Flask-SQLAlchemy](https://github.com/pallets/flask-sqlalchemy).

    """

    def __init__(

        self, enqueue_change: Callable[[str, Operation, List[Union[str, int]]], None]