|
1 | 1 | from __future__ import annotations |
2 | 2 |
|
3 | | -from typing import TYPE_CHECKING, Literal, Protocol, TypedDict, TypeVar, runtime_checkable |
| 3 | +import dataclasses |
| 4 | +from typing import TYPE_CHECKING, Literal, Protocol, TypeVar, runtime_checkable |
4 | 5 |
|
5 | 6 | if TYPE_CHECKING: |
6 | 7 | from collections.abc import Iterable, Iterator, Sequence |
|
18 | 19 | ] |
19 | 20 |
|
20 | 21 |
|
21 | | -class CompiledSql(TypedDict): |
| 22 | +@dataclasses.dataclass(frozen=True) |
| 23 | +class CompiledSql: |
22 | 24 | """Represents a compiled SQL statement, with the final SQL string and a list of Params to be passed to duckdb.""" |
23 | 25 |
|
24 | 26 | sql: str |
25 | | - params: list[Param] |
| 27 | + params: tuple[Param, ...] |
26 | 28 |
|
| 29 | + # def __init__(self, sql: str, params: Iterable[Param]) -> None: |
| 30 | + # self.sql = sql |
| 31 | + # self.params = tuple(params) |
27 | 32 |
|
28 | | -class Param(TypedDict): |
| 33 | + |
| 34 | +@dataclasses.dataclass(frozen=True) |
| 35 | +class Param: |
29 | 36 | """Represents a parameter to be passed to duckdb, with a name and a value.""" |
30 | 37 |
|
31 | 38 | value: object |
32 | 39 | name: str |
33 | 40 |
|
34 | 41 |
|
35 | | -# class IntoParam(TypedDict): |
36 | | -# """A Param with a name that is None, which can be used as input to the template engine, which will assign it a name based on its position and optionally an expression.""" |
37 | | - |
38 | | -# value: object |
39 | | -# name: NotRequired[str | None] |
40 | | - |
41 | | - |
42 | | -# def is_into_param(thing: object) -> TypeIs[IntoParam]: |
43 | | -# try: |
44 | | -# value = thing["value"] # ty:ignore[not-subscriptable] |
45 | | -# except (TypeError, KeyError): |
46 | | -# return False |
47 | | -# try: |
48 | | -# name = thing["name"] # ty:ignore[not-subscriptable] |
49 | | -# except KeyError: |
50 | | -# name = None |
51 | | - |
52 | | -# return isinstance(value, object) and isinstance(name, (str, type(None))) |
53 | | - |
54 | | - |
55 | 42 | def is_into_interpolation(thing: object) -> TypeIs[IntoInterpolation]: |
56 | 43 | return isinstance(thing, IntoInterpolation) |
57 | 44 |
|
@@ -211,11 +198,9 @@ def compile_parts(parts: Iterable[str | IntoInterpolation], /) -> CompiledSql: |
211 | 198 | if passed_name := part.expression: |
212 | 199 | param_name += f"_{passed_name}" |
213 | 200 | sql_parts.append(f"${param_name}") |
214 | | - params.append({"name": param_name, "value": part.value}) |
215 | | - return { |
216 | | - "sql": "".join(sql_parts), |
217 | | - "params": params, |
218 | | - } |
| 201 | + # params.append({"name": param_name, "value": part.value}) |
| 202 | + params.append(Param(name=param_name, value=part.value)) |
| 203 | + return CompiledSql(sql="".join(sql_parts), params=tuple(params)) |
219 | 204 |
|
220 | 205 |
|
221 | 206 | @runtime_checkable |
|
0 commit comments