Source code for csql._.models.dialect

from __future__ import annotations
import abc
import enum
from enum import auto
from typing import *
from dataclasses import dataclass
if TYPE_CHECKING:
	import csql.dialect

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

[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: ''' 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''' # 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