-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathreports.py
More file actions
49 lines (36 loc) · 1.65 KB
/
Copy pathreports.py
File metadata and controls
49 lines (36 loc) · 1.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
"""Analytics queries, each staged through the builder and run for real.
The builder assembles a frozen ``Query``; sqlite executes it with the
parameters kept separate from the SQL text — the same discipline as any
production database layer.
"""
from __future__ import annotations
import sqlite3
from patterns.creational.builder.pattern import SelectBuilder
def _run(conn: sqlite3.Connection, builder: SelectBuilder) -> list[tuple[object, ...]]:
query = builder.build()
return [tuple(row) for row in conn.execute(query.sql(), query.params)]
def top_orders(conn: sqlite3.Connection, count: int) -> list[tuple[object, ...]]:
"""The biggest orders, largest first."""
builder = SelectBuilder("orders").columns("id", "amount").order_by("amount DESC").limit(count)
return _run(conn, builder)
def big_orders(conn: sqlite3.Connection, minimum: int) -> list[tuple[object, ...]]:
"""Orders at or above a spend threshold."""
builder = (
SelectBuilder("orders")
.columns("id", "region", "amount")
.where("amount >= ?", minimum)
.order_by("id")
)
return _run(conn, builder)
def orders_in_region(
conn: sqlite3.Connection, region: str, product: str | None = None
) -> list[tuple[object, ...]]:
"""Orders for a region — optionally narrowed to one product.
The builder's win over a one-shot call: the second condition is added
only when the caller asked for it.
"""
builder = SelectBuilder("orders").columns("id", "product", "amount")
builder.where("region = ?", region)
if product is not None:
builder.where("product = ?", product)
return _run(conn, builder.order_by("id"))