def generate_record_type_pseudo_tables(summary):
    """Generate fake table objects for purposes of dependency sorting, lookups and mapping generation"""
    record_types = {}
    for template in summary.templates:
        real_table_name = template.tablename
        record_type_field = find_record_type_field(template.fields,
                                                   real_table_name)
        if not record_type_field:
            continue

        real_table = summary.tables[real_table_name]
        record_type_name = record_type_field.definition.definition

        # generate a pretend table for purposes of dependency sorting,
        # lookups and mapping generation
        record_type_pseudo_table = record_types.setdefault(
            record_type_name, TableInfo(template.tablename))
        record_type_pseudo_table.register(template)
        record_type_pseudo_table.record_type = record_type_name

        # copy over the dependencies from the real table
        for dependency in sorted(summary.intertable_dependencies):
            if dependency.table_name_from == real_table_name:
                summary.intertable_dependencies.add(
                    Dependency(record_type_name, *dependency[1:]))

        # the record type field isn't helpful for the TableInfo of the real table anymore
        # need a conditional here to ensure its only deleted once
        if real_table.fields.get("RecordType"):
            del real_table.fields["RecordType"]
            real_table.has_record_types = True

    return record_types
def build_dependencies(
    intertable_dependencies,
    declarations: T.Sequence[SObjectRuleDeclaration] = None,
):
    """Figure out which tables depend on which other ones (through foreign keys)

    intertable_dependencies is a dict with values of Dependency objects.

    Returns two things:
        1. a dictionary allowing easy lookup of dependencies by parent table
        2. a dictionary allowing lookups by (tablename, fieldname) pairs
    """
    inferred_dependencies = defaultdict(set)
    declared_dependencies = defaultdict(set)
    reference_fields = {}
    declarations = declarations or ()

    for dep in intertable_dependencies:
        table_deps = inferred_dependencies[dep.table_name_from]
        table_deps.add(dep)
        reference_fields[(dep.table_name_from,
                          dep.field_name)] = dep.table_name_to
    for decl in declarations:
        assert isinstance(decl.load_after, list)
        for target in decl.load_after:
            declared_dependencies[decl.sf_object].add(
                Dependency(decl.sf_object, target, "(none)"))

    return inferred_dependencies, declared_dependencies, reference_fields
Ejemplo n.º 3
0
    def test_build_dependencies_simple(self):
        parent_deps = [
            Dependency("parent", "child", "son"),
            Dependency("parent", "child", "daughter"),
        ]
        child_deps = [
            Dependency("child", "grandchild", "son"),
            Dependency("child", "grandchild", "daughter"),
        ]
        deps = parent_deps + child_deps
        dependencies, reference_fields = build_dependencies(deps)
        assert dependencies == {"parent": set(parent_deps), "child": set(child_deps)}
        assert reference_fields == {
            ("parent", "daughter"): "child",
            ("parent", "son"): "child",
            ("child", "daughter"): "grandchild",
            ("child", "son"): "grandchild",
        }

        # test repr
        [repr(o) for o in deps]
    def test_table_is_free_simple(self):
        # Child depends on parent and parent hasn't been sorted out yet -> false
        assert not _table_is_free(
            "Child", {"Child": {Dependency("Child", "Parent", "parent")}}, [])

        # Child depends on parent and parent has been sorted out already -> ]true
        assert _table_is_free(
            "Child", {"Child": {Dependency("Child", "Parent", "parent")}},
            ["Parent"])

        # Child depends on parent and parent hasn't been sorted out yet. -> false
        assert not _table_is_free(
            "Child",
            {
                "Child": {
                    Dependency("Child", "Parent", "parent"),
                    Dependency("Parent", "Grandparent", "parent"),
                }
            },
            ["Grandparent"],
        )

        # Child depends on parent and parent has been sorted out already -> true
        assert _table_is_free(
            "Child",
            {
                "Child": {
                    Dependency("Child", "Parent", "parent"),
                    Dependency("Parent", "Grandparent", "parent"),
                }
            },
            ["Grandparent", "Parent"],
        )