Exemple #1
0
def get_object(class_name, module_name, uid, max_depth=None):
    """Create a model object instance from the relevant data table row"""
    if security.has_read_permission(class_name, uid):
        module = import_module(module_name)
        cls = getattr(module, class_name)
        instance = cls._from_row(_get_row(class_name, uid),
                                 max_depth=max_depth)
        if security.has_update_permission(class_name, uid):
            instance.update_capability = Capability([class_name, uid])
        if security.has_delete_permission(class_name, uid):
            instance.delete_capability = Capability([class_name, uid])
        return instance
Exemple #2
0
def delete_object(instance):
    """Delete the data tables row for the given model instance"""
    class_name = type(instance).__name__
    Capability.require(instance.delete_capability, [class_name, instance.uid])
    table = get_table(type(instance).__name__)
    table.get(uid=instance.uid).delete()
Exemple #3
0
def save_object(instance):
    """Persist an instance to the database by adding or updating a row"""
    class_name = type(instance).__name__
    table = get_table(class_name)

    attributes = {
        name: getattr(instance, name)
        for name, attribute in instance._attributes.items()
    }
    single_relationships = {
        name: _get_row(relationship.cls.__name__,
                       getattr(instance, name).uid)
        for name, relationship in instance._relationships.items()
        if not relationship.with_many and getattr(instance, name) is not None
    }
    multi_relationships = {
        name: list(
            _search_rows(
                relationship.cls.__name__,
                [
                    member.uid
                    for member in getattr(instance, name) if member is not None
                ],
            ))
        for name, relationship in instance._relationships.items()
        if relationship.with_many
    }

    members = {**attributes, **single_relationships, **multi_relationships}
    cross_references = [{
        "name": name,
        "relationship": relationship
    } for name, relationship in instance._relationships.items()
                        if relationship.cross_reference is not None]

    has_permission = False
    if instance.uid is not None:
        if getattr(instance, "update_capability") is not None:
            Capability.require(instance.update_capability,
                               [class_name, instance.uid])
            has_permission = True
            row = table.get(uid=instance.uid)
            row.update(**members)
        else:
            raise ValueError(
                "You do not have permission to update this object")
    else:
        if security.has_create_permission(class_name):
            has_permission = True
            uid = uuid4().hex
            instance = copy(instance)
            instance.uid = uid
            row = table.add_row(uid=uid, **members)
            if security.has_update_permission(class_name, uid):
                instance.update_capability = Capability([class_name, uid])
            if security.has_delete_permission(class_name, uid):
                instance.delete_capability = Capability([class_name, uid])
        else:
            raise ValueError("You do not have permission to save this object")

    if has_permission:
        # Very simple cross reference update
        for xref in cross_references:

            # We only update the 'many' side of a cross reference
            if not xref["relationship"].with_many:
                xref_row = single_relationships[xref["name"]]
                column_name = xref["relationship"].cross_reference

                # We simply ensure that the 'one' side is included in the 'many' side.
                # We don't cleanup any possibly redundant entries on the 'many' side.
                if row not in xref_row[column_name]:
                    xref_row[column_name] += [row]

    return instance