Beispiel #1
0
def test_simple_query_merge():
    book_id = SQLQuery(
        ["users", "books"], "books.id", {"users.id": 1, "books.user_id": sql_query_dict.mysql_col("user.id")}
    )

    combined = SQLQuery(["books"], "books.name", {"books.id": book_id})

    combined.flatten()

    assert combined == SQLQuery(
        "users, books", "books.name", {"users.id": 1, "books.user_id": sql_query_dict.mysql_col("user.id")}
    )
Beispiel #2
0
    def flatten(self):
        """ merge any SQLQuery objects on the rhs of a where clause
        into self. """

        self._assert_flattenable()

        for k, v in self.where.copy().items():
            if isinstance(v, SQLQuery):
                v._assert_flattenable()

                self.tables.update(v.tables)

                self._assert_no_overlapping_where(v.where)

                self.where.update(v.where)
                if len(v.selects) != 1:
                    raise ValueError((
                        'SQLQuery merging is only possible when '
                        'the embedded query has one select.  has: {}'
                    ).format(', '.join(v.selects)))
                self.where[k] = sql_query_dict.mysql_col(v.selects[0])

                # we just did a join, so definitely not just the first
                self.first = False

        self.cleanup()
def test_simple_query_merge():
    book_id = SQLQuery(['users', 'books'], 'books.id', {
        'users.id': 1,
        'books.user_id': sql_query_dict.mysql_col('user.id'),
    })

    combined = SQLQuery(['books'], 'books.name', {
        'books.id': book_id
    })

    combined.flatten()

    assert combined == SQLQuery(
        'users, books', 'books.name', {
            'users.id': 1,
            'books.user_id': sql_query_dict.mysql_col('user.id'),
        })
Beispiel #4
0
    def merge_parent_child(child, parent):
        """ NOTE: child and parent are switched here, it makes more sense """
        parent.function._assert_flattenable()
        child.function._assert_flattenable()

        function = parent.function.copy()
        for k, v in function.input_mapping.items():
            child_function = child.function.copy()

            # simply merge these parts of the SQLQuery
            function.tables.update(child_function.tables)
            function.where.update(child_function.where)
            function.selects.extend(child_function.selects)

            # join where clause and selects
            # the connecting path is the path which is set by the child and
            # read by the parent
            connecting_path = parent.input_path_by_property(k)
            # lookup the order that this path occurrs in the outputs so we can
            # match it up with the correct select
            i = child.outgoing_paths.index(connecting_path)

            # join in the where clause
            function.where[v] = sql_query_dict.mysql_col(
                child_function.selects[i]
            )

        # remove unnecessary complexity
        function.cleanup()

        # TODO: assumes that all inputs were from SQLQuery objects
        function.input_mapping = child.function.input_mapping

        # even if there is just one column, this also works so long as
        # Cardinality.many
        function.one_column = False
        function.first = False

        inputs = child.incoming_paths
        outputs = parent.outgoing_paths + child.outgoing_paths

        relations = parent.relations + child.relations

        return Node(
            None, inputs, outputs, function, Cardinality.many, relations
        )