Source code for csql._.models.dialect

from __future__ import annotations

import enum
from dataclasses import dataclass
from enum import auto
from typing import TYPE_CHECKING

if TYPE_CHECKING:
	import csql.dialect

__all__ = ["DefaultDialect", "DuckDB", "ParamStyle", "SQLDialect", "Snowflake"]


[docs] class ParamStyle(enum.Enum): """ Enum to define how to render query parameter placeholders. """ numeric = auto() """ Use placeholders like ``:1``. :meta hide-value: """ numeric_dollar = auto() """ Use placeholders like ``$1``. :meta hide-value: """ qmark = auto() """ Use placeholders like ``?``. :meta hide-value: """ clickhouse = auto() """ Use placeholders like ``{MyParam:String}`` """ def __repr__(self) -> str: return "ParamStyle." + self.name
[docs] class Limit(enum.Enum): """ Enum to defines how to limit preview queries. """ limit = auto() """ Use a ``limit`` clause, e.g. ``select * from (query) limit 10``. :meta hide-value: """ top_n = auto() """ Use a ``top n`` clause, e.g. ``select top(10) * from (query)``.' :meta hide-value: """ ansi = auto() """ Use ANSI SQL ``fetch`` clause, e.g. ``select * from (query) fetch first 10 rows only``. :meta hide-value: """ def __repr__(self) -> str: return f"Limit.{self.name}"
[docs] @dataclass(frozen=True) class SQLDialect: """ Represents settings of a SQL Dialect. >>> import functools >>> from csql.dialect import SQLDialect, ParamStyle >>> my_dialect=SQLDialect(paramstyle=ParamStyle.qmark) >>> p = Parameters(value=123) To use as a once-off, pass to :meth:`csql.Query.build`: >>> q = Q(f"select {p['value']}") >>> q.build() # builds normally RenderedQuery('select :1', (123,)) >>> q.build(dialect=my_dialect) # builds with `my_dialect` RenderedQuery('select ?', (123,)) To set as a default, use ``functools.partial``: >>> Q = functools.partial(csql.Q, dialect=my_dialect) >>> q = Q('select ...') # builds with `my_dialect` """ paramstyle: csql.dialect.ParamStyle = ParamStyle.numeric limit: csql.dialect.Limit = Limit.limit
# experiments for doc gen Snowflake = SQLDialect(paramstyle=ParamStyle.numeric, limit=Limit.limit) """A dialect for Snowflake""" DuckDB = SQLDialect(paramstyle=ParamStyle.numeric_dollar, limit=Limit.limit) """A dialect for DuckDB""" MSSQL = SQLDialect(paramstyle=ParamStyle.numeric, limit=Limit.top_n) """A dialect for MS SQL Server""" SQLite = SQLDialect(paramstyle=ParamStyle.qmark, limit=Limit.limit) """A dialect for SQLite.""" ClickHouse = SQLDialect(paramstyle=ParamStyle.clickhouse, limit=Limit.limit) # def __repr__(self) -> str: # import inspect # mod = inspect.getmodule(self) # print('!!!') # if mod is None: # print('nomod') # return super().__repr__() # print('???') # name = next( # ( # name # for name, obj in vars(mod).items() # if obj is self # ), # None # ) # print('!!!!') # if name is None: # print('nolocal') # return super().__repr__() # print(f'{name=}') # return name DefaultDialect = SQLDialect(paramstyle=ParamStyle.numeric, limit=Limit.limit) """The default dialect for CSQL.""" import dataclasses
[docs] @dataclasses.dataclass(frozen=True) class InferOrDefault: """A wrapper to flag that this query should use a previous query\'s dialect if not otherwise specified.""" dialect: csql.dialect.SQLDialect