예제 #1
0
    def test_window(self):
        t = Table('t')
        function = Rank(t.c, window=Window([]))

        with AliasManager():
            self.assertEqual(str(function), 'RANK("a"."c") OVER "b"')
        self.assertEqual(function.params, ())
예제 #2
0
    def currency_rate_sql(cls):
        "Return a SQL query with currency, rate, start_date and end_date"
        pool = Pool()
        Rate = pool.get('currency.currency.rate')
        transaction = Transaction()
        database = transaction.database

        rate = Rate.__table__()
        if database.has_window_functions():
            window = Window([rate.currency],
                            order_by=[rate.date.asc],
                            frame='ROWS',
                            start=0,
                            end=1)
            # Use NthValue instead of LastValue to get NULL for the last row
            end_date = NthValue(rate.date, 2, window=window)
        else:
            next_rate = Rate.__table__()
            end_date = next_rate.select(
                next_rate.date,
                where=(next_rate.currency == rate.currency)
                & (next_rate.date > rate.date),
                order_by=[next_rate.date.asc],
                limit=1)

        query = (rate.select(
            rate.currency.as_('currency'),
            rate.rate.as_('rate'),
            rate.date.as_('start_date'),
            end_date.as_('end_date'),
        ))
        return query
예제 #3
0
    def test_window_rows(self):
        t = Table('t')
        window = Window([t.c], frame='ROWS')

        self.assertEqual(
            str(window), 'PARTITION BY "c" ROWS '
            'BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW')
        self.assertEqual(window.params, ())
예제 #4
0
    def test_window_range(self):
        t = Table('t')
        window = Window([t.c], frame='RANGE')

        self.assertEqual(
            str(window), 'PARTITION BY "c" RANGE '
            'BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW')
        self.assertEqual(window.params, ())

        window.start = -1
        self.assertEqual(
            str(window), 'PARTITION BY "c" RANGE '
            'BETWEEN 1 PRECEDING AND CURRENT ROW')
        self.assertEqual(window.params, ())

        window.start = 0
        window.end = 1
        self.assertEqual(
            str(window), 'PARTITION BY "c" RANGE '
            'BETWEEN CURRENT ROW AND 1 FOLLOWING')
        self.assertEqual(window.params, ())

        window.start = 1
        window.end = None
        self.assertEqual(
            str(window), 'PARTITION BY "c" RANGE '
            'BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING')
        self.assertEqual(window.params, ())
예제 #5
0
    def test_filter(self):
        t = Table('t')
        function = Rank(t.c, filter_=t.c > 0, window=Window([]))

        with AliasManager():
            self.assertEqual(
                str(function),
                'RANK("a"."c") FILTER (WHERE ("a"."c" > %s)) OVER "b"')
        self.assertEqual(function.params, (0, ))
예제 #6
0
 def test_order_params(self):
     with_ = With(
         query=self.table.select(self.table.c, where=(self.table.c > 1)))
     w = Window([Literal(8)])
     query = Select([Literal(2), Min(self.table.c, window=w)],
                    from_=self.table.select(where=self.table.c > 3),
                    with_=with_,
                    where=self.table.c > 4,
                    group_by=[Literal(5)],
                    order_by=[Literal(6)],
                    having=Literal(7))
     self.assertEqual(query.params, (1, 2, 3, 4, 5, 6, 7, 8))
예제 #7
0
    def test_window_range(self):
        t = Table('t')
        window = Window([t.c], frame='RANGE')

        self.assertEqual(str(window),
            'PARTITION BY "c" RANGE '
            'BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW')
        self.assertEqual(window.params, ())

        window.start = -1
        self.assertEqual(str(window),
            'PARTITION BY "c" RANGE '
            'BETWEEN 1 PRECEDING AND CURRENT ROW')
        self.assertEqual(window.params, ())

        window.start = 0
        window.end = 1
        self.assertEqual(str(window),
            'PARTITION BY "c" RANGE '
            'BETWEEN CURRENT ROW AND 1 FOLLOWING')
        self.assertEqual(window.params, ())

        window.start = 1
        window.end = None
        self.assertEqual(str(window),
            'PARTITION BY "c" RANGE '
            'BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING')
        self.assertEqual(window.params, ())
예제 #8
0
    def getter_latest_book(cls, authors, name):
        result = {x.id: None for x in authors}
        Book = Pool().get('library.book')
        book = Book.__table__()
        sub_book = Book.__table__()
        cursor = Transaction().connection.cursor()

        sub_query = sub_book.select(
            sub_book.author,
            Max(Coalesce(sub_book.publishing_date, datetime.date.min),
                window=Window([sub_book.author])).as_('max_date'),
            where=sub_book.author.in_([x.id for x in authors]))

        cursor.execute(
            *book.join(sub_query,
                       condition=(book.author == sub_query.author)
                       & (Coalesce(book.publishing_date, datetime.date.min) ==
                          sub_query.max_date)).select(book.author, book.id))
        for author_id, book in cursor.fetchall():
            result[author_id] = book
        return result
예제 #9
0
 def test_window(self):
     avg = Avg(self.table.c, window=Window([]))
     with AliasManager():
         self.assertEqual(str(avg), 'AVG("a"."c") OVER "b"')
     self.assertEqual(avg.params, ())
예제 #10
0
    def table_query(cls):
        pool = Pool()
        Attendance = pool.get('attendance.line')

        transaction = Transaction()
        database = transaction.database

        attendance = Attendance.__table__()

        if database.has_window_functions():
            window = Window([attendance.employee],
                            order_by=[attendance.at.asc],
                            frame='ROWS',
                            start=0,
                            end=1)
            type = NthValue(attendance.type, 1, window=window)
            from_ = NthValue(attendance.at, 1, window=window)
            to = NthValue(attendance.at, 2, window=window)
            date = NthValue(attendance.date, 1, window=window)
            query = attendance.select(attendance.id.as_('id'),
                                      attendance.company.as_('company'),
                                      attendance.employee.as_('employee'),
                                      type.as_('type'), from_.as_('from_'),
                                      to.as_('to'), date.as_('date'))

            sheet = (Min(query.id * 2,
                         window=Window([query.employee, query.date])))
        else:
            next_attendance = Attendance.__table__()
            to = next_attendance.select(
                next_attendance.at,
                where=(next_attendance.employee == attendance.employee)
                & (next_attendance.at > attendance.at),
                order_by=[next_attendance.at.asc],
                limit=1)
            query = attendance.select(attendance.id.as_('id'),
                                      attendance.company.as_('company'),
                                      attendance.employee.as_('employee'),
                                      attendance.type.as_('type'),
                                      attendance.at.as_('from_'), to.as_('to'),
                                      attendance.date.as_('date'))

            query2 = copy.copy(query)
            sheet = query2.select(Min(query2.id * 2),
                                  where=(query2.employee == query.employee)
                                  & (query2.date == query.date))

        from_ = Column(query, 'from_')
        if backend.name == 'sqlite':
            # As SQLite does not support operation on datetime
            # we convert datetime into seconds
            duration = (SQLiteStrftime('%s', query.to) -
                        SQLiteStrftime('%s', from_))
        else:
            duration = query.to - from_
        return query.select(
            query.id.as_('id'),
            Literal(0).as_('create_uid'),
            CurrentTimestamp().as_('create_date'),
            cls.write_uid.sql_cast(Literal(Null)).as_('write_uid'),
            cls.write_date.sql_cast(Literal(Null)).as_('write_date'),
            query.company.as_('company'),
            query.employee.as_('employee'),
            from_.as_('from_'),
            query.to.as_('to'),
            query.date.as_('date'),
            duration.as_('duration'),
            sheet.as_('sheet'),
            where=query.type == 'in')
예제 #11
0
    def table_query(cls):
        pool = Pool()
        Date = pool.get('ir.date')
        Location = pool.get('stock.location')
        Move = pool.get('stock.move')
        Product = pool.get('product.product')
        move = from_ = Move.__table__()
        transaction = Transaction()
        context = transaction.context
        database = transaction.database
        today = Date.today()

        if context.get('product_template') is not None:
            product_template = context['product_template']
            if isinstance(product_template, int):
                product_template = [product_template]
            product = Product.__table__()
            from_ = move.join(product, condition=move.product == product.id)
            product_clause = product.template.in_(product_template or [-1])
            product_column = Concat('product.template,', product.template)
        else:
            product = context.get('product', -1)
            if product is None:
                product = -1
            if isinstance(product, int):
                product = [product]
            product_clause = move.product.in_(product or [-1])
            product_column = Concat('product.product,', move.product)

        if 'warehouse' in context:
            warehouse = Location(context.get('warehouse'))
            if context.get('stock_skip_warehouse'):
                location_id = warehouse.storage_location.id
            else:
                location_id = warehouse.id
        else:
            location_id = -1
        warehouse = With('id',
                         query=Location.search([
                             ('parent', 'child_of', [location_id]),
                         ],
                                               query=True,
                                               order=[]))
        date_column = Coalesce(move.effective_date, move.planned_date)
        quantity = Case((move.to_location.in_(warehouse.select(
            warehouse.id)), move.internal_quantity),
                        else_=-move.internal_quantity)
        if database.has_window_functions():
            cumulative_quantity_delta = Sum(quantity,
                                            window=Window(
                                                [product_column, date_column],
                                                order_by=[move.id.asc]))
        else:
            cumulative_quantity_delta = Literal(0)
        return (from_.select(
            move.id.as_('id'),
            Literal(0).as_('create_uid'),
            CurrentTimestamp().as_('create_date'),
            Literal(None).as_('write_uid'),
            Literal(None).as_('write_date'),
            product_column.as_('product'),
            date_column.as_('date'),
            move.id.as_('move'),
            move.origin.as_('origin'),
            quantity.as_('quantity'),
            cumulative_quantity_delta.as_('cumulative_quantity_delta'),
            move.company.as_('company'),
            where=product_clause
            & ((move.from_location.in_(warehouse.select(warehouse.id))
                & ~move.to_location.in_(warehouse.select(warehouse.id)))
               | (~move.from_location.in_(warehouse.select(warehouse.id))
                  & move.to_location.in_(warehouse.select(warehouse.id))))
            & ((date_column < today) & (move.state == 'done')
               | (date_column >= today)),
            with_=warehouse))
예제 #12
0
    def test_window_order(self):
        t = Table('t')
        window = Window([t.c], order_by=t.c)

        self.assertEqual(str(window), 'PARTITION BY "c" ORDER BY "c"')
        self.assertEqual(window.params, ())
예제 #13
0
    def test_window(self):
        t = Table('t')
        window = Window([t.c1, t.c2])

        self.assertEqual(str(window), 'PARTITION BY "c1", "c2"')
        self.assertEqual(window.params, ())