sqlspec 0.13.1__py3-none-any.whl → 0.16.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of sqlspec might be problematic. Click here for more details.

Files changed (185) hide show
  1. sqlspec/__init__.py +71 -8
  2. sqlspec/__main__.py +12 -0
  3. sqlspec/__metadata__.py +1 -3
  4. sqlspec/_serialization.py +1 -2
  5. sqlspec/_sql.py +930 -136
  6. sqlspec/_typing.py +278 -142
  7. sqlspec/adapters/adbc/__init__.py +4 -3
  8. sqlspec/adapters/adbc/_types.py +12 -0
  9. sqlspec/adapters/adbc/config.py +116 -285
  10. sqlspec/adapters/adbc/driver.py +462 -340
  11. sqlspec/adapters/aiosqlite/__init__.py +18 -3
  12. sqlspec/adapters/aiosqlite/_types.py +13 -0
  13. sqlspec/adapters/aiosqlite/config.py +202 -150
  14. sqlspec/adapters/aiosqlite/driver.py +226 -247
  15. sqlspec/adapters/asyncmy/__init__.py +18 -3
  16. sqlspec/adapters/asyncmy/_types.py +12 -0
  17. sqlspec/adapters/asyncmy/config.py +80 -199
  18. sqlspec/adapters/asyncmy/driver.py +257 -215
  19. sqlspec/adapters/asyncpg/__init__.py +19 -4
  20. sqlspec/adapters/asyncpg/_types.py +17 -0
  21. sqlspec/adapters/asyncpg/config.py +81 -214
  22. sqlspec/adapters/asyncpg/driver.py +284 -359
  23. sqlspec/adapters/bigquery/__init__.py +17 -3
  24. sqlspec/adapters/bigquery/_types.py +12 -0
  25. sqlspec/adapters/bigquery/config.py +191 -299
  26. sqlspec/adapters/bigquery/driver.py +474 -634
  27. sqlspec/adapters/duckdb/__init__.py +14 -3
  28. sqlspec/adapters/duckdb/_types.py +12 -0
  29. sqlspec/adapters/duckdb/config.py +414 -397
  30. sqlspec/adapters/duckdb/driver.py +342 -393
  31. sqlspec/adapters/oracledb/__init__.py +19 -5
  32. sqlspec/adapters/oracledb/_types.py +14 -0
  33. sqlspec/adapters/oracledb/config.py +123 -458
  34. sqlspec/adapters/oracledb/driver.py +505 -531
  35. sqlspec/adapters/psqlpy/__init__.py +13 -3
  36. sqlspec/adapters/psqlpy/_types.py +11 -0
  37. sqlspec/adapters/psqlpy/config.py +93 -307
  38. sqlspec/adapters/psqlpy/driver.py +504 -213
  39. sqlspec/adapters/psycopg/__init__.py +19 -5
  40. sqlspec/adapters/psycopg/_types.py +17 -0
  41. sqlspec/adapters/psycopg/config.py +143 -472
  42. sqlspec/adapters/psycopg/driver.py +704 -825
  43. sqlspec/adapters/sqlite/__init__.py +14 -3
  44. sqlspec/adapters/sqlite/_types.py +11 -0
  45. sqlspec/adapters/sqlite/config.py +208 -142
  46. sqlspec/adapters/sqlite/driver.py +263 -278
  47. sqlspec/base.py +105 -9
  48. sqlspec/{statement/builder → builder}/__init__.py +12 -14
  49. sqlspec/{statement/builder/base.py → builder/_base.py} +184 -86
  50. sqlspec/{statement/builder/column.py → builder/_column.py} +97 -60
  51. sqlspec/{statement/builder/ddl.py → builder/_ddl.py} +61 -131
  52. sqlspec/{statement/builder → builder}/_ddl_utils.py +4 -10
  53. sqlspec/{statement/builder/delete.py → builder/_delete.py} +10 -30
  54. sqlspec/builder/_insert.py +421 -0
  55. sqlspec/builder/_merge.py +71 -0
  56. sqlspec/{statement/builder → builder}/_parsing_utils.py +49 -26
  57. sqlspec/builder/_select.py +170 -0
  58. sqlspec/{statement/builder/update.py → builder/_update.py} +16 -20
  59. sqlspec/builder/mixins/__init__.py +55 -0
  60. sqlspec/builder/mixins/_cte_and_set_ops.py +222 -0
  61. sqlspec/{statement/builder/mixins/_delete_from.py → builder/mixins/_delete_operations.py} +8 -1
  62. sqlspec/builder/mixins/_insert_operations.py +244 -0
  63. sqlspec/{statement/builder/mixins/_join.py → builder/mixins/_join_operations.py} +45 -13
  64. sqlspec/{statement/builder/mixins/_merge_clauses.py → builder/mixins/_merge_operations.py} +188 -30
  65. sqlspec/builder/mixins/_order_limit_operations.py +135 -0
  66. sqlspec/builder/mixins/_pivot_operations.py +153 -0
  67. sqlspec/builder/mixins/_select_operations.py +604 -0
  68. sqlspec/builder/mixins/_update_operations.py +202 -0
  69. sqlspec/builder/mixins/_where_clause.py +644 -0
  70. sqlspec/cli.py +247 -0
  71. sqlspec/config.py +183 -138
  72. sqlspec/core/__init__.py +63 -0
  73. sqlspec/core/cache.py +871 -0
  74. sqlspec/core/compiler.py +417 -0
  75. sqlspec/core/filters.py +830 -0
  76. sqlspec/core/hashing.py +310 -0
  77. sqlspec/core/parameters.py +1237 -0
  78. sqlspec/core/result.py +677 -0
  79. sqlspec/{statement → core}/splitter.py +321 -191
  80. sqlspec/core/statement.py +676 -0
  81. sqlspec/driver/__init__.py +7 -10
  82. sqlspec/driver/_async.py +422 -163
  83. sqlspec/driver/_common.py +545 -287
  84. sqlspec/driver/_sync.py +426 -160
  85. sqlspec/driver/mixins/__init__.py +2 -13
  86. sqlspec/driver/mixins/_result_tools.py +193 -0
  87. sqlspec/driver/mixins/_sql_translator.py +65 -14
  88. sqlspec/exceptions.py +5 -252
  89. sqlspec/extensions/aiosql/adapter.py +93 -96
  90. sqlspec/extensions/litestar/__init__.py +2 -1
  91. sqlspec/extensions/litestar/cli.py +48 -0
  92. sqlspec/extensions/litestar/config.py +0 -1
  93. sqlspec/extensions/litestar/handlers.py +15 -26
  94. sqlspec/extensions/litestar/plugin.py +21 -16
  95. sqlspec/extensions/litestar/providers.py +17 -52
  96. sqlspec/loader.py +423 -104
  97. sqlspec/migrations/__init__.py +35 -0
  98. sqlspec/migrations/base.py +414 -0
  99. sqlspec/migrations/commands.py +443 -0
  100. sqlspec/migrations/loaders.py +402 -0
  101. sqlspec/migrations/runner.py +213 -0
  102. sqlspec/migrations/tracker.py +140 -0
  103. sqlspec/migrations/utils.py +129 -0
  104. sqlspec/protocols.py +51 -186
  105. sqlspec/storage/__init__.py +1 -1
  106. sqlspec/storage/backends/base.py +37 -40
  107. sqlspec/storage/backends/fsspec.py +136 -112
  108. sqlspec/storage/backends/obstore.py +138 -160
  109. sqlspec/storage/capabilities.py +5 -4
  110. sqlspec/storage/registry.py +57 -106
  111. sqlspec/typing.py +136 -115
  112. sqlspec/utils/__init__.py +2 -2
  113. sqlspec/utils/correlation.py +0 -3
  114. sqlspec/utils/deprecation.py +6 -6
  115. sqlspec/utils/fixtures.py +6 -6
  116. sqlspec/utils/logging.py +0 -2
  117. sqlspec/utils/module_loader.py +7 -12
  118. sqlspec/utils/singleton.py +0 -1
  119. sqlspec/utils/sync_tools.py +17 -38
  120. sqlspec/utils/text.py +12 -51
  121. sqlspec/utils/type_guards.py +482 -235
  122. {sqlspec-0.13.1.dist-info → sqlspec-0.16.2.dist-info}/METADATA +7 -2
  123. sqlspec-0.16.2.dist-info/RECORD +134 -0
  124. sqlspec-0.16.2.dist-info/entry_points.txt +2 -0
  125. sqlspec/driver/connection.py +0 -207
  126. sqlspec/driver/mixins/_csv_writer.py +0 -91
  127. sqlspec/driver/mixins/_pipeline.py +0 -512
  128. sqlspec/driver/mixins/_result_utils.py +0 -140
  129. sqlspec/driver/mixins/_storage.py +0 -926
  130. sqlspec/driver/mixins/_type_coercion.py +0 -130
  131. sqlspec/driver/parameters.py +0 -138
  132. sqlspec/service/__init__.py +0 -4
  133. sqlspec/service/_util.py +0 -147
  134. sqlspec/service/base.py +0 -1131
  135. sqlspec/service/pagination.py +0 -26
  136. sqlspec/statement/__init__.py +0 -21
  137. sqlspec/statement/builder/insert.py +0 -288
  138. sqlspec/statement/builder/merge.py +0 -95
  139. sqlspec/statement/builder/mixins/__init__.py +0 -65
  140. sqlspec/statement/builder/mixins/_aggregate_functions.py +0 -250
  141. sqlspec/statement/builder/mixins/_case_builder.py +0 -91
  142. sqlspec/statement/builder/mixins/_common_table_expr.py +0 -90
  143. sqlspec/statement/builder/mixins/_from.py +0 -63
  144. sqlspec/statement/builder/mixins/_group_by.py +0 -118
  145. sqlspec/statement/builder/mixins/_having.py +0 -35
  146. sqlspec/statement/builder/mixins/_insert_from_select.py +0 -47
  147. sqlspec/statement/builder/mixins/_insert_into.py +0 -36
  148. sqlspec/statement/builder/mixins/_insert_values.py +0 -67
  149. sqlspec/statement/builder/mixins/_limit_offset.py +0 -53
  150. sqlspec/statement/builder/mixins/_order_by.py +0 -46
  151. sqlspec/statement/builder/mixins/_pivot.py +0 -79
  152. sqlspec/statement/builder/mixins/_returning.py +0 -37
  153. sqlspec/statement/builder/mixins/_select_columns.py +0 -61
  154. sqlspec/statement/builder/mixins/_set_ops.py +0 -122
  155. sqlspec/statement/builder/mixins/_unpivot.py +0 -77
  156. sqlspec/statement/builder/mixins/_update_from.py +0 -55
  157. sqlspec/statement/builder/mixins/_update_set.py +0 -94
  158. sqlspec/statement/builder/mixins/_update_table.py +0 -29
  159. sqlspec/statement/builder/mixins/_where.py +0 -401
  160. sqlspec/statement/builder/mixins/_window_functions.py +0 -86
  161. sqlspec/statement/builder/select.py +0 -221
  162. sqlspec/statement/filters.py +0 -596
  163. sqlspec/statement/parameter_manager.py +0 -220
  164. sqlspec/statement/parameters.py +0 -867
  165. sqlspec/statement/pipelines/__init__.py +0 -210
  166. sqlspec/statement/pipelines/analyzers/__init__.py +0 -9
  167. sqlspec/statement/pipelines/analyzers/_analyzer.py +0 -646
  168. sqlspec/statement/pipelines/context.py +0 -115
  169. sqlspec/statement/pipelines/transformers/__init__.py +0 -7
  170. sqlspec/statement/pipelines/transformers/_expression_simplifier.py +0 -88
  171. sqlspec/statement/pipelines/transformers/_literal_parameterizer.py +0 -1247
  172. sqlspec/statement/pipelines/transformers/_remove_comments_and_hints.py +0 -76
  173. sqlspec/statement/pipelines/validators/__init__.py +0 -23
  174. sqlspec/statement/pipelines/validators/_dml_safety.py +0 -290
  175. sqlspec/statement/pipelines/validators/_parameter_style.py +0 -370
  176. sqlspec/statement/pipelines/validators/_performance.py +0 -718
  177. sqlspec/statement/pipelines/validators/_security.py +0 -967
  178. sqlspec/statement/result.py +0 -435
  179. sqlspec/statement/sql.py +0 -1704
  180. sqlspec/statement/sql_compiler.py +0 -140
  181. sqlspec/utils/cached_property.py +0 -25
  182. sqlspec-0.13.1.dist-info/RECORD +0 -150
  183. {sqlspec-0.13.1.dist-info → sqlspec-0.16.2.dist-info}/WHEEL +0 -0
  184. {sqlspec-0.13.1.dist-info → sqlspec-0.16.2.dist-info}/licenses/LICENSE +0 -0
  185. {sqlspec-0.13.1.dist-info → sqlspec-0.16.2.dist-info}/licenses/NOTICE +0 -0
sqlspec/config.py CHANGED
@@ -1,21 +1,17 @@
1
1
  from abc import ABC, abstractmethod
2
- from dataclasses import dataclass, field
3
- from typing import TYPE_CHECKING, Any, ClassVar, Generic, Optional, TypeVar, Union
2
+ from typing import TYPE_CHECKING, Any, Callable, ClassVar, Generic, Optional, TypeVar, Union
4
3
 
5
- from sqlspec.typing import ConnectionT, PoolT # pyright: ignore
4
+ from typing_extensions import NotRequired, TypedDict
5
+
6
+ from sqlspec.core.parameters import ParameterStyle, ParameterStyleConfig
7
+ from sqlspec.core.statement import StatementConfig
6
8
  from sqlspec.utils.logging import get_logger
7
9
 
8
10
  if TYPE_CHECKING:
9
11
  from collections.abc import Awaitable
10
12
  from contextlib import AbstractAsyncContextManager, AbstractContextManager
11
13
 
12
- from sqlglot.dialects.dialect import DialectType
13
-
14
- from sqlspec.driver import AsyncDriverAdapterProtocol, SyncDriverAdapterProtocol
15
- from sqlspec.statement.result import StatementResult
16
-
17
-
18
- StatementResultType = Union["StatementResult[dict[str, Any]]", "StatementResult[Any]"]
14
+ from sqlspec.driver import AsyncDriverAdapterBase, SyncDriverAdapterBase
19
15
 
20
16
 
21
17
  __all__ = (
@@ -24,10 +20,9 @@ __all__ = (
24
20
  "ConfigT",
25
21
  "DatabaseConfigProtocol",
26
22
  "DriverT",
27
- "GenericPoolConfig",
23
+ "LifecycleConfig",
28
24
  "NoPoolAsyncConfig",
29
25
  "NoPoolSyncConfig",
30
- "StatementResultType",
31
26
  "SyncConfigT",
32
27
  "SyncDatabaseConfig",
33
28
  )
@@ -38,66 +33,59 @@ ConfigT = TypeVar(
38
33
  "ConfigT",
39
34
  bound="Union[Union[AsyncDatabaseConfig[Any, Any, Any], NoPoolAsyncConfig[Any, Any]], SyncDatabaseConfig[Any, Any, Any], NoPoolSyncConfig[Any, Any]]",
40
35
  )
41
- DriverT = TypeVar("DriverT", bound="Union[SyncDriverAdapterProtocol[Any], AsyncDriverAdapterProtocol[Any]]")
36
+
37
+ # Define TypeVars for Generic classes
38
+ ConnectionT = TypeVar("ConnectionT")
39
+ PoolT = TypeVar("PoolT")
40
+ DriverT = TypeVar("DriverT", bound="Union[SyncDriverAdapterBase, AsyncDriverAdapterBase]")
42
41
 
43
42
  logger = get_logger("config")
44
43
 
45
44
 
46
- @dataclass
47
- class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
48
- """Protocol defining the interface for database configurations."""
45
+ class LifecycleConfig(TypedDict, total=False):
46
+ """Universal lifecycle hooks for all adapters.
47
+
48
+ Each hook accepts a list of callables to support multiple handlers.
49
+ """
49
50
 
50
- # Note: __slots__ cannot be used with dataclass fields in Python < 3.10
51
- # Concrete subclasses can still use __slots__ for any additional attributes
52
- __slots__ = ()
51
+ on_connection_create: NotRequired[list[Callable[[Any], None]]]
52
+ on_connection_destroy: NotRequired[list[Callable[[Any], None]]]
53
+ on_pool_create: NotRequired[list[Callable[[Any], None]]]
54
+ on_pool_destroy: NotRequired[list[Callable[[Any], None]]]
55
+ on_session_start: NotRequired[list[Callable[[Any], None]]]
56
+ on_session_end: NotRequired[list[Callable[[Any], None]]]
57
+ on_query_start: NotRequired[list[Callable[[str, dict], None]]]
58
+ on_query_complete: NotRequired[list[Callable[[str, dict, Any], None]]]
59
+ on_error: NotRequired[list[Callable[[Exception, str, dict], None]]]
53
60
 
54
- is_async: "ClassVar[bool]" = field(init=False, default=False)
55
- supports_connection_pooling: "ClassVar[bool]" = field(init=False, default=False)
56
- supports_native_arrow_import: "ClassVar[bool]" = field(init=False, default=False)
57
- supports_native_arrow_export: "ClassVar[bool]" = field(init=False, default=False)
58
- supports_native_parquet_import: "ClassVar[bool]" = field(init=False, default=False)
59
- supports_native_parquet_export: "ClassVar[bool]" = field(init=False, default=False)
60
- connection_type: "type[ConnectionT]" = field(init=False, repr=False, hash=False, compare=False)
61
- driver_type: "type[DriverT]" = field(init=False, repr=False, hash=False, compare=False)
62
- pool_instance: "Optional[PoolT]" = field(default=None)
63
- default_row_type: "type[Any]" = field(init=False)
64
- _dialect: "DialectType" = field(default=None, init=False, repr=False, hash=False, compare=False)
65
61
 
66
- supported_parameter_styles: "ClassVar[tuple[str, ...]]" = ()
67
- """Parameter styles supported by this database adapter (e.g., ('qmark', 'named_colon'))."""
62
+ class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
63
+ """Protocol defining the interface for database configurations."""
68
64
 
69
- preferred_parameter_style: "ClassVar[str]" = "none"
70
- """The preferred/native parameter style for this database."""
65
+ __slots__ = ("driver_features", "migration_config", "pool_instance", "statement_config")
66
+ driver_type: "ClassVar[type[Any]]"
67
+ connection_type: "ClassVar[type[Any]]"
68
+ is_async: "ClassVar[bool]" = False
69
+ supports_connection_pooling: "ClassVar[bool]" = False
70
+ supports_native_arrow_import: "ClassVar[bool]" = False
71
+ supports_native_arrow_export: "ClassVar[bool]" = False
72
+ supports_native_parquet_import: "ClassVar[bool]" = False
73
+ supports_native_parquet_export: "ClassVar[bool]" = False
74
+ statement_config: "StatementConfig"
75
+ pool_instance: "Optional[PoolT]"
76
+ migration_config: "dict[str, Any]"
71
77
 
72
78
  def __hash__(self) -> int:
73
79
  return id(self)
74
80
 
75
- @property
76
- def dialect(self) -> "DialectType":
77
- """Get the SQL dialect type lazily.
81
+ def __eq__(self, other: object) -> bool:
82
+ if not isinstance(other, type(self)):
83
+ return False
84
+ return bool(self.pool_instance == other.pool_instance and self.migration_config == other.migration_config)
78
85
 
79
- This property allows dialect to be set either statically as a class attribute
80
- or dynamically via the _get_dialect() method. If a specific adapter needs
81
- dynamic dialect detection (e.g., ADBC which supports multiple databases),
82
- it can override _get_dialect() to provide custom logic.
83
-
84
- Returns:
85
- The SQL dialect type for this database.
86
- """
87
- if self._dialect is None:
88
- self._dialect = self._get_dialect() # type: ignore[misc]
89
- return self._dialect
90
-
91
- def _get_dialect(self) -> "DialectType":
92
- """Get the dialect for this database configuration.
93
-
94
- This method should be overridden by configs that need dynamic dialect detection.
95
- By default, it looks for the dialect on the driver class.
96
-
97
- Returns:
98
- The SQL dialect type.
99
- """
100
- return self.driver_type.dialect
86
+ def __repr__(self) -> str:
87
+ parts = ", ".join([f"pool_instance={self.pool_instance!r}", f"migration_config={self.migration_config!r}"])
88
+ return f"{type(self).__name__}({parts})"
101
89
 
102
90
  @abstractmethod
103
91
  def create_connection(self) -> "Union[ConnectionT, Awaitable[ConnectionT]]":
@@ -118,12 +106,6 @@ class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
118
106
  """Provide a database session context manager."""
119
107
  raise NotImplementedError
120
108
 
121
- @property
122
- @abstractmethod
123
- def connection_config_dict(self) -> "dict[str, Any]":
124
- """Return the connection configuration as a dict."""
125
- raise NotImplementedError
126
-
127
109
  @abstractmethod
128
110
  def create_pool(self) -> "Union[PoolT, Awaitable[PoolT]]":
129
111
  """Create and return connection pool."""
@@ -151,48 +133,49 @@ class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
151
133
  Returns:
152
134
  Dictionary mapping type names to types.
153
135
  """
154
- namespace: dict[str, type[Any]] = {}
155
-
156
- if hasattr(self, "driver_type") and self.driver_type:
157
- namespace[self.driver_type.__name__] = self.driver_type
158
-
159
- namespace[self.__class__.__name__] = self.__class__
136
+ return {}
160
137
 
161
- if hasattr(self, "connection_type") and self.connection_type:
162
- connection_type = self.connection_type
163
138
 
164
- if hasattr(connection_type, "__args__"):
165
- # It's a generic type, extract the actual types
166
- for arg_type in connection_type.__args__: # type: ignore[attr-defined]
167
- if arg_type and hasattr(arg_type, "__name__"):
168
- namespace[arg_type.__name__] = arg_type
169
- elif hasattr(connection_type, "__name__"):
170
- # Regular type
171
- namespace[connection_type.__name__] = connection_type
172
-
173
- return namespace
174
-
175
-
176
- @dataclass
177
139
  class NoPoolSyncConfig(DatabaseConfigProtocol[ConnectionT, None, DriverT]):
178
140
  """Base class for a sync database configurations that do not implement a pool."""
179
141
 
180
- __slots__ = ()
181
-
182
- is_async: "ClassVar[bool]" = field(init=False, default=False)
183
- supports_connection_pooling: "ClassVar[bool]" = field(init=False, default=False)
184
- pool_instance: None = None
142
+ __slots__ = ("connection_config",)
143
+ is_async: "ClassVar[bool]" = False
144
+ supports_connection_pooling: "ClassVar[bool]" = False
145
+
146
+ def __init__(
147
+ self,
148
+ *,
149
+ connection_config: Optional[dict[str, Any]] = None,
150
+ migration_config: "Optional[dict[str, Any]]" = None,
151
+ statement_config: "Optional[StatementConfig]" = None,
152
+ driver_features: "Optional[dict[str, Any]]" = None,
153
+ ) -> None:
154
+ self.pool_instance = None
155
+ self.connection_config = connection_config or {}
156
+ self.migration_config: dict[str, Any] = migration_config if migration_config is not None else {}
157
+
158
+ if statement_config is None:
159
+ default_parameter_config = ParameterStyleConfig(
160
+ default_parameter_style=ParameterStyle.QMARK, supported_parameter_styles={ParameterStyle.QMARK}
161
+ )
162
+ self.statement_config = StatementConfig(dialect="sqlite", parameter_config=default_parameter_config)
163
+ else:
164
+ self.statement_config = statement_config
165
+ self.driver_features = driver_features or {}
185
166
 
186
167
  def create_connection(self) -> ConnectionT:
187
- """Create connection with instrumentation."""
168
+ """Create a database connection."""
188
169
  raise NotImplementedError
189
170
 
190
171
  def provide_connection(self, *args: Any, **kwargs: Any) -> "AbstractContextManager[ConnectionT]":
191
- """Provide connection with instrumentation."""
172
+ """Provide a database connection context manager."""
192
173
  raise NotImplementedError
193
174
 
194
- def provide_session(self, *args: Any, **kwargs: Any) -> "AbstractContextManager[DriverT]":
195
- """Provide session with instrumentation."""
175
+ def provide_session(
176
+ self, *args: Any, statement_config: "Optional[StatementConfig]" = None, **kwargs: Any
177
+ ) -> "AbstractContextManager[DriverT]":
178
+ """Provide a database session context manager."""
196
179
  raise NotImplementedError
197
180
 
198
181
  def create_pool(self) -> None:
@@ -205,26 +188,47 @@ class NoPoolSyncConfig(DatabaseConfigProtocol[ConnectionT, None, DriverT]):
205
188
  return None
206
189
 
207
190
 
208
- @dataclass
209
191
  class NoPoolAsyncConfig(DatabaseConfigProtocol[ConnectionT, None, DriverT]):
210
192
  """Base class for an async database configurations that do not implement a pool."""
211
193
 
212
- __slots__ = ()
213
-
214
- is_async: "ClassVar[bool]" = field(init=False, default=True)
215
- supports_connection_pooling: "ClassVar[bool]" = field(init=False, default=False)
216
- pool_instance: None = None
194
+ __slots__ = ("connection_config",)
195
+
196
+ is_async: "ClassVar[bool]" = True
197
+ supports_connection_pooling: "ClassVar[bool]" = False
198
+
199
+ def __init__(
200
+ self,
201
+ *,
202
+ connection_config: "Optional[dict[str, Any]]" = None,
203
+ migration_config: "Optional[dict[str, Any]]" = None,
204
+ statement_config: "Optional[StatementConfig]" = None,
205
+ driver_features: "Optional[dict[str, Any]]" = None,
206
+ ) -> None:
207
+ self.pool_instance = None
208
+ self.connection_config = connection_config or {}
209
+ self.migration_config: dict[str, Any] = migration_config if migration_config is not None else {}
210
+
211
+ if statement_config is None:
212
+ default_parameter_config = ParameterStyleConfig(
213
+ default_parameter_style=ParameterStyle.QMARK, supported_parameter_styles={ParameterStyle.QMARK}
214
+ )
215
+ self.statement_config = StatementConfig(dialect="sqlite", parameter_config=default_parameter_config)
216
+ else:
217
+ self.statement_config = statement_config
218
+ self.driver_features = driver_features or {}
217
219
 
218
220
  async def create_connection(self) -> ConnectionT:
219
- """Create connection with instrumentation."""
221
+ """Create a database connection."""
220
222
  raise NotImplementedError
221
223
 
222
224
  def provide_connection(self, *args: Any, **kwargs: Any) -> "AbstractAsyncContextManager[ConnectionT]":
223
- """Provide connection with instrumentation."""
225
+ """Provide a database connection context manager."""
224
226
  raise NotImplementedError
225
227
 
226
- def provide_session(self, *args: Any, **kwargs: Any) -> "AbstractAsyncContextManager[DriverT]":
227
- """Provide session with instrumentation."""
228
+ def provide_session(
229
+ self, *args: Any, statement_config: "Optional[StatementConfig]" = None, **kwargs: Any
230
+ ) -> "AbstractAsyncContextManager[DriverT]":
231
+ """Provide a database session context manager."""
228
232
  raise NotImplementedError
229
233
 
230
234
  async def create_pool(self) -> None:
@@ -237,53 +241,69 @@ class NoPoolAsyncConfig(DatabaseConfigProtocol[ConnectionT, None, DriverT]):
237
241
  return None
238
242
 
239
243
 
240
- @dataclass
241
- class GenericPoolConfig:
242
- """Generic Database Pool Configuration."""
243
-
244
- __slots__ = ()
245
-
246
-
247
- @dataclass
248
244
  class SyncDatabaseConfig(DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]):
249
245
  """Generic Sync Database Configuration."""
250
246
 
251
- __slots__ = ()
252
-
253
- is_async: "ClassVar[bool]" = field(init=False, default=False)
254
- supports_connection_pooling: "ClassVar[bool]" = field(init=False, default=True)
247
+ __slots__ = ("pool_config",)
248
+
249
+ is_async: "ClassVar[bool]" = False
250
+ supports_connection_pooling: "ClassVar[bool]" = True
251
+
252
+ def __init__(
253
+ self,
254
+ *,
255
+ pool_config: "Optional[dict[str, Any]]" = None,
256
+ pool_instance: "Optional[PoolT]" = None,
257
+ migration_config: "Optional[dict[str, Any]]" = None,
258
+ statement_config: "Optional[StatementConfig]" = None,
259
+ driver_features: "Optional[dict[str, Any]]" = None,
260
+ ) -> None:
261
+ self.pool_instance = pool_instance
262
+ self.pool_config = pool_config or {}
263
+ self.migration_config: dict[str, Any] = migration_config if migration_config is not None else {}
264
+
265
+ if statement_config is None:
266
+ default_parameter_config = ParameterStyleConfig(
267
+ default_parameter_style=ParameterStyle.QMARK, supported_parameter_styles={ParameterStyle.QMARK}
268
+ )
269
+ self.statement_config = StatementConfig(dialect="postgres", parameter_config=default_parameter_config)
270
+ else:
271
+ self.statement_config = statement_config
272
+ self.driver_features = driver_features or {}
255
273
 
256
274
  def create_pool(self) -> PoolT:
257
- """Create pool with instrumentation.
275
+ """Create and return the connection pool.
258
276
 
259
277
  Returns:
260
278
  The created pool.
261
279
  """
262
280
  if self.pool_instance is not None:
263
281
  return self.pool_instance
264
- self.pool_instance = self._create_pool() # type: ignore[misc]
282
+ self.pool_instance = self._create_pool()
265
283
  return self.pool_instance
266
284
 
267
285
  def close_pool(self) -> None:
268
- """Close pool with instrumentation."""
286
+ """Close the connection pool."""
269
287
  self._close_pool()
270
288
 
271
289
  def provide_pool(self, *args: Any, **kwargs: Any) -> PoolT:
272
290
  """Provide pool instance."""
273
291
  if self.pool_instance is None:
274
- self.pool_instance = self.create_pool() # type: ignore[misc]
292
+ self.pool_instance = self.create_pool()
275
293
  return self.pool_instance
276
294
 
277
295
  def create_connection(self) -> ConnectionT:
278
- """Create connection with instrumentation."""
296
+ """Create a database connection."""
279
297
  raise NotImplementedError
280
298
 
281
299
  def provide_connection(self, *args: Any, **kwargs: Any) -> "AbstractContextManager[ConnectionT]":
282
- """Provide connection with instrumentation."""
300
+ """Provide a database connection context manager."""
283
301
  raise NotImplementedError
284
302
 
285
- def provide_session(self, *args: Any, **kwargs: Any) -> "AbstractContextManager[DriverT]":
286
- """Provide session with instrumentation."""
303
+ def provide_session(
304
+ self, *args: Any, statement_config: "Optional[StatementConfig]" = None, **kwargs: Any
305
+ ) -> "AbstractContextManager[DriverT]":
306
+ """Provide a database session context manager."""
287
307
  raise NotImplementedError
288
308
 
289
309
  @abstractmethod
@@ -297,46 +317,71 @@ class SyncDatabaseConfig(DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]):
297
317
  raise NotImplementedError
298
318
 
299
319
 
300
- @dataclass
301
320
  class AsyncDatabaseConfig(DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]):
302
321
  """Generic Async Database Configuration."""
303
322
 
304
- __slots__ = ()
305
-
306
- is_async: "ClassVar[bool]" = field(init=False, default=True)
307
- supports_connection_pooling: "ClassVar[bool]" = field(init=False, default=True)
323
+ __slots__ = ("pool_config",)
324
+
325
+ is_async: "ClassVar[bool]" = True
326
+ supports_connection_pooling: "ClassVar[bool]" = True
327
+
328
+ def __init__(
329
+ self,
330
+ *,
331
+ pool_config: "Optional[dict[str, Any]]" = None,
332
+ pool_instance: "Optional[PoolT]" = None,
333
+ migration_config: "Optional[dict[str, Any]]" = None,
334
+ statement_config: "Optional[StatementConfig]" = None,
335
+ driver_features: "Optional[dict[str, Any]]" = None,
336
+ ) -> None:
337
+ self.pool_instance = pool_instance
338
+ self.pool_config = pool_config or {}
339
+ self.migration_config: dict[str, Any] = migration_config if migration_config is not None else {}
340
+
341
+ if statement_config is None:
342
+ self.statement_config = StatementConfig(
343
+ parameter_config=ParameterStyleConfig(
344
+ default_parameter_style=ParameterStyle.QMARK, supported_parameter_styles={ParameterStyle.QMARK}
345
+ ),
346
+ dialect="postgres",
347
+ )
348
+ else:
349
+ self.statement_config = statement_config
350
+ self.driver_features = driver_features or {}
308
351
 
309
352
  async def create_pool(self) -> PoolT:
310
- """Create pool with instrumentation.
353
+ """Create and return the connection pool.
311
354
 
312
355
  Returns:
313
356
  The created pool.
314
357
  """
315
358
  if self.pool_instance is not None:
316
359
  return self.pool_instance
317
- self.pool_instance = await self._create_pool() # type: ignore[misc]
360
+ self.pool_instance = await self._create_pool()
318
361
  return self.pool_instance
319
362
 
320
363
  async def close_pool(self) -> None:
321
- """Close pool with instrumentation."""
364
+ """Close the connection pool."""
322
365
  await self._close_pool()
323
366
 
324
367
  async def provide_pool(self, *args: Any, **kwargs: Any) -> PoolT:
325
368
  """Provide pool instance."""
326
369
  if self.pool_instance is None:
327
- self.pool_instance = await self.create_pool() # type: ignore[misc]
370
+ self.pool_instance = await self.create_pool()
328
371
  return self.pool_instance
329
372
 
330
373
  async def create_connection(self) -> ConnectionT:
331
- """Create connection with instrumentation."""
374
+ """Create a database connection."""
332
375
  raise NotImplementedError
333
376
 
334
377
  def provide_connection(self, *args: Any, **kwargs: Any) -> "AbstractAsyncContextManager[ConnectionT]":
335
- """Provide connection with instrumentation."""
378
+ """Provide a database connection context manager."""
336
379
  raise NotImplementedError
337
380
 
338
- def provide_session(self, *args: Any, **kwargs: Any) -> "AbstractAsyncContextManager[DriverT]":
339
- """Provide session with instrumentation."""
381
+ def provide_session(
382
+ self, *args: Any, statement_config: "Optional[StatementConfig]" = None, **kwargs: Any
383
+ ) -> "AbstractAsyncContextManager[DriverT]":
384
+ """Provide a database session context manager."""
340
385
  raise NotImplementedError
341
386
 
342
387
  @abstractmethod
@@ -0,0 +1,63 @@
1
+ """SQLSpec Core Module - SQL Processing System.
2
+
3
+ This module provides the core SQL processing components including statement handling,
4
+ parameter processing, compilation, and result management.
5
+
6
+ Components:
7
+ - statement.py: SQL class with StatementConfig
8
+ - parameters.py: Parameter processing pipeline
9
+ - compiler.py: SQL compilation with caching
10
+ - result.py: Result classes for query execution
11
+ - filters.py: Statement filter system
12
+ - cache.py: Unified caching system
13
+ - splitter.py: SQL statement splitter
14
+ - hashing.py: Cache key generation
15
+ """
16
+
17
+ from sqlspec.core import filters
18
+ from sqlspec.core.cache import CacheConfig, CacheStats, UnifiedCache, get_statement_cache
19
+ from sqlspec.core.compiler import OperationType, SQLProcessor
20
+ from sqlspec.core.filters import StatementFilter
21
+ from sqlspec.core.hashing import (
22
+ hash_expression,
23
+ hash_expression_node,
24
+ hash_optimized_expression,
25
+ hash_parameters,
26
+ hash_sql_statement,
27
+ )
28
+ from sqlspec.core.parameters import (
29
+ ParameterConverter,
30
+ ParameterProcessor,
31
+ ParameterStyle,
32
+ ParameterStyleConfig,
33
+ TypedParameter,
34
+ )
35
+ from sqlspec.core.result import ArrowResult, SQLResult, StatementResult
36
+ from sqlspec.core.statement import SQL, Statement, StatementConfig
37
+
38
+ __all__ = (
39
+ "SQL",
40
+ "ArrowResult",
41
+ "CacheConfig",
42
+ "CacheStats",
43
+ "OperationType",
44
+ "ParameterConverter",
45
+ "ParameterProcessor",
46
+ "ParameterStyle",
47
+ "ParameterStyleConfig",
48
+ "SQLProcessor",
49
+ "SQLResult",
50
+ "Statement",
51
+ "StatementConfig",
52
+ "StatementFilter",
53
+ "StatementResult",
54
+ "TypedParameter",
55
+ "UnifiedCache",
56
+ "filters",
57
+ "get_statement_cache",
58
+ "hash_expression",
59
+ "hash_expression_node",
60
+ "hash_optimized_expression",
61
+ "hash_parameters",
62
+ "hash_sql_statement",
63
+ )