sqlspec 0.16.1__cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.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 (148) hide show
  1. 51ff5a9eadfdefd49f98__mypyc.cpython-39-aarch64-linux-gnu.so +0 -0
  2. sqlspec/__init__.py +92 -0
  3. sqlspec/__main__.py +12 -0
  4. sqlspec/__metadata__.py +14 -0
  5. sqlspec/_serialization.py +77 -0
  6. sqlspec/_sql.py +1780 -0
  7. sqlspec/_typing.py +680 -0
  8. sqlspec/adapters/__init__.py +0 -0
  9. sqlspec/adapters/adbc/__init__.py +5 -0
  10. sqlspec/adapters/adbc/_types.py +12 -0
  11. sqlspec/adapters/adbc/config.py +361 -0
  12. sqlspec/adapters/adbc/driver.py +512 -0
  13. sqlspec/adapters/aiosqlite/__init__.py +19 -0
  14. sqlspec/adapters/aiosqlite/_types.py +13 -0
  15. sqlspec/adapters/aiosqlite/config.py +253 -0
  16. sqlspec/adapters/aiosqlite/driver.py +248 -0
  17. sqlspec/adapters/asyncmy/__init__.py +19 -0
  18. sqlspec/adapters/asyncmy/_types.py +12 -0
  19. sqlspec/adapters/asyncmy/config.py +180 -0
  20. sqlspec/adapters/asyncmy/driver.py +274 -0
  21. sqlspec/adapters/asyncpg/__init__.py +21 -0
  22. sqlspec/adapters/asyncpg/_types.py +17 -0
  23. sqlspec/adapters/asyncpg/config.py +229 -0
  24. sqlspec/adapters/asyncpg/driver.py +344 -0
  25. sqlspec/adapters/bigquery/__init__.py +18 -0
  26. sqlspec/adapters/bigquery/_types.py +12 -0
  27. sqlspec/adapters/bigquery/config.py +298 -0
  28. sqlspec/adapters/bigquery/driver.py +558 -0
  29. sqlspec/adapters/duckdb/__init__.py +22 -0
  30. sqlspec/adapters/duckdb/_types.py +12 -0
  31. sqlspec/adapters/duckdb/config.py +504 -0
  32. sqlspec/adapters/duckdb/driver.py +368 -0
  33. sqlspec/adapters/oracledb/__init__.py +32 -0
  34. sqlspec/adapters/oracledb/_types.py +14 -0
  35. sqlspec/adapters/oracledb/config.py +317 -0
  36. sqlspec/adapters/oracledb/driver.py +538 -0
  37. sqlspec/adapters/psqlpy/__init__.py +16 -0
  38. sqlspec/adapters/psqlpy/_types.py +11 -0
  39. sqlspec/adapters/psqlpy/config.py +214 -0
  40. sqlspec/adapters/psqlpy/driver.py +530 -0
  41. sqlspec/adapters/psycopg/__init__.py +32 -0
  42. sqlspec/adapters/psycopg/_types.py +17 -0
  43. sqlspec/adapters/psycopg/config.py +426 -0
  44. sqlspec/adapters/psycopg/driver.py +796 -0
  45. sqlspec/adapters/sqlite/__init__.py +15 -0
  46. sqlspec/adapters/sqlite/_types.py +11 -0
  47. sqlspec/adapters/sqlite/config.py +240 -0
  48. sqlspec/adapters/sqlite/driver.py +294 -0
  49. sqlspec/base.py +571 -0
  50. sqlspec/builder/__init__.py +62 -0
  51. sqlspec/builder/_base.py +473 -0
  52. sqlspec/builder/_column.py +320 -0
  53. sqlspec/builder/_ddl.py +1346 -0
  54. sqlspec/builder/_ddl_utils.py +103 -0
  55. sqlspec/builder/_delete.py +76 -0
  56. sqlspec/builder/_insert.py +256 -0
  57. sqlspec/builder/_merge.py +71 -0
  58. sqlspec/builder/_parsing_utils.py +140 -0
  59. sqlspec/builder/_select.py +170 -0
  60. sqlspec/builder/_update.py +188 -0
  61. sqlspec/builder/mixins/__init__.py +55 -0
  62. sqlspec/builder/mixins/_cte_and_set_ops.py +222 -0
  63. sqlspec/builder/mixins/_delete_operations.py +41 -0
  64. sqlspec/builder/mixins/_insert_operations.py +244 -0
  65. sqlspec/builder/mixins/_join_operations.py +122 -0
  66. sqlspec/builder/mixins/_merge_operations.py +476 -0
  67. sqlspec/builder/mixins/_order_limit_operations.py +135 -0
  68. sqlspec/builder/mixins/_pivot_operations.py +153 -0
  69. sqlspec/builder/mixins/_select_operations.py +603 -0
  70. sqlspec/builder/mixins/_update_operations.py +187 -0
  71. sqlspec/builder/mixins/_where_clause.py +621 -0
  72. sqlspec/cli.py +247 -0
  73. sqlspec/config.py +395 -0
  74. sqlspec/core/__init__.py +63 -0
  75. sqlspec/core/cache.cpython-39-aarch64-linux-gnu.so +0 -0
  76. sqlspec/core/cache.py +871 -0
  77. sqlspec/core/compiler.cpython-39-aarch64-linux-gnu.so +0 -0
  78. sqlspec/core/compiler.py +417 -0
  79. sqlspec/core/filters.cpython-39-aarch64-linux-gnu.so +0 -0
  80. sqlspec/core/filters.py +830 -0
  81. sqlspec/core/hashing.cpython-39-aarch64-linux-gnu.so +0 -0
  82. sqlspec/core/hashing.py +310 -0
  83. sqlspec/core/parameters.cpython-39-aarch64-linux-gnu.so +0 -0
  84. sqlspec/core/parameters.py +1237 -0
  85. sqlspec/core/result.cpython-39-aarch64-linux-gnu.so +0 -0
  86. sqlspec/core/result.py +677 -0
  87. sqlspec/core/splitter.cpython-39-aarch64-linux-gnu.so +0 -0
  88. sqlspec/core/splitter.py +819 -0
  89. sqlspec/core/statement.cpython-39-aarch64-linux-gnu.so +0 -0
  90. sqlspec/core/statement.py +676 -0
  91. sqlspec/driver/__init__.py +19 -0
  92. sqlspec/driver/_async.py +502 -0
  93. sqlspec/driver/_common.py +631 -0
  94. sqlspec/driver/_sync.py +503 -0
  95. sqlspec/driver/mixins/__init__.py +6 -0
  96. sqlspec/driver/mixins/_result_tools.py +193 -0
  97. sqlspec/driver/mixins/_sql_translator.py +86 -0
  98. sqlspec/exceptions.py +193 -0
  99. sqlspec/extensions/__init__.py +0 -0
  100. sqlspec/extensions/aiosql/__init__.py +10 -0
  101. sqlspec/extensions/aiosql/adapter.py +461 -0
  102. sqlspec/extensions/litestar/__init__.py +6 -0
  103. sqlspec/extensions/litestar/_utils.py +52 -0
  104. sqlspec/extensions/litestar/cli.py +48 -0
  105. sqlspec/extensions/litestar/config.py +92 -0
  106. sqlspec/extensions/litestar/handlers.py +260 -0
  107. sqlspec/extensions/litestar/plugin.py +145 -0
  108. sqlspec/extensions/litestar/providers.py +454 -0
  109. sqlspec/loader.cpython-39-aarch64-linux-gnu.so +0 -0
  110. sqlspec/loader.py +760 -0
  111. sqlspec/migrations/__init__.py +35 -0
  112. sqlspec/migrations/base.py +414 -0
  113. sqlspec/migrations/commands.py +443 -0
  114. sqlspec/migrations/loaders.py +402 -0
  115. sqlspec/migrations/runner.py +213 -0
  116. sqlspec/migrations/tracker.py +140 -0
  117. sqlspec/migrations/utils.py +129 -0
  118. sqlspec/protocols.py +407 -0
  119. sqlspec/py.typed +0 -0
  120. sqlspec/storage/__init__.py +23 -0
  121. sqlspec/storage/backends/__init__.py +0 -0
  122. sqlspec/storage/backends/base.py +163 -0
  123. sqlspec/storage/backends/fsspec.py +386 -0
  124. sqlspec/storage/backends/obstore.py +459 -0
  125. sqlspec/storage/capabilities.py +102 -0
  126. sqlspec/storage/registry.py +239 -0
  127. sqlspec/typing.py +299 -0
  128. sqlspec/utils/__init__.py +3 -0
  129. sqlspec/utils/correlation.py +150 -0
  130. sqlspec/utils/deprecation.py +106 -0
  131. sqlspec/utils/fixtures.cpython-39-aarch64-linux-gnu.so +0 -0
  132. sqlspec/utils/fixtures.py +58 -0
  133. sqlspec/utils/logging.py +127 -0
  134. sqlspec/utils/module_loader.py +89 -0
  135. sqlspec/utils/serializers.py +4 -0
  136. sqlspec/utils/singleton.py +32 -0
  137. sqlspec/utils/sync_tools.cpython-39-aarch64-linux-gnu.so +0 -0
  138. sqlspec/utils/sync_tools.py +237 -0
  139. sqlspec/utils/text.cpython-39-aarch64-linux-gnu.so +0 -0
  140. sqlspec/utils/text.py +96 -0
  141. sqlspec/utils/type_guards.cpython-39-aarch64-linux-gnu.so +0 -0
  142. sqlspec/utils/type_guards.py +1139 -0
  143. sqlspec-0.16.1.dist-info/METADATA +365 -0
  144. sqlspec-0.16.1.dist-info/RECORD +148 -0
  145. sqlspec-0.16.1.dist-info/WHEEL +7 -0
  146. sqlspec-0.16.1.dist-info/entry_points.txt +2 -0
  147. sqlspec-0.16.1.dist-info/licenses/LICENSE +21 -0
  148. sqlspec-0.16.1.dist-info/licenses/NOTICE +29 -0
sqlspec/base.py ADDED
@@ -0,0 +1,571 @@
1
+ import asyncio
2
+ import atexit
3
+ from collections.abc import Awaitable, Coroutine
4
+ from typing import TYPE_CHECKING, Any, Optional, Union, cast, overload
5
+
6
+ from sqlspec.config import (
7
+ AsyncConfigT,
8
+ AsyncDatabaseConfig,
9
+ DatabaseConfigProtocol,
10
+ DriverT,
11
+ NoPoolAsyncConfig,
12
+ NoPoolSyncConfig,
13
+ SyncConfigT,
14
+ SyncDatabaseConfig,
15
+ )
16
+ from sqlspec.core.cache import (
17
+ CacheConfig,
18
+ CacheStatsAggregate,
19
+ get_cache_config,
20
+ get_cache_stats,
21
+ log_cache_stats,
22
+ reset_cache_stats,
23
+ update_cache_config,
24
+ )
25
+ from sqlspec.utils.logging import get_logger
26
+
27
+ if TYPE_CHECKING:
28
+ from contextlib import AbstractAsyncContextManager, AbstractContextManager
29
+
30
+ from sqlspec.typing import ConnectionT, PoolT
31
+
32
+
33
+ __all__ = ("SQLSpec",)
34
+
35
+ logger = get_logger()
36
+
37
+
38
+ class SQLSpec:
39
+ """Configuration manager and registry for database connections and pools."""
40
+
41
+ __slots__ = ("_cleanup_tasks", "_configs", "_instance_cache_config")
42
+
43
+ def __init__(self) -> None:
44
+ self._configs: dict[Any, DatabaseConfigProtocol[Any, Any, Any]] = {}
45
+ atexit.register(self._cleanup_pools)
46
+ self._instance_cache_config: Optional[CacheConfig] = None
47
+ self._cleanup_tasks: list[asyncio.Task[None]] = []
48
+
49
+ @staticmethod
50
+ def _get_config_name(obj: Any) -> str:
51
+ """Get display name for configuration object."""
52
+ return getattr(obj, "__name__", str(obj))
53
+
54
+ def _cleanup_pools(self) -> None:
55
+ """Clean up all registered connection pools."""
56
+ cleaned_count = 0
57
+
58
+ for config_type, config in self._configs.items():
59
+ if config.supports_connection_pooling:
60
+ try:
61
+ if config.is_async:
62
+ close_pool_awaitable = config.close_pool()
63
+ if close_pool_awaitable is not None:
64
+ try:
65
+ loop = asyncio.get_running_loop()
66
+ if loop.is_running():
67
+ task = asyncio.create_task(cast("Coroutine[Any, Any, None]", close_pool_awaitable))
68
+ self._cleanup_tasks.append(task)
69
+ else:
70
+ asyncio.run(cast("Coroutine[Any, Any, None]", close_pool_awaitable))
71
+ except RuntimeError:
72
+ asyncio.run(cast("Coroutine[Any, Any, None]", close_pool_awaitable))
73
+ else:
74
+ config.close_pool()
75
+ cleaned_count += 1
76
+ except Exception as e:
77
+ logger.warning("Failed to clean up pool for config %s: %s", config_type.__name__, e)
78
+
79
+ if self._cleanup_tasks:
80
+ try:
81
+ loop = asyncio.get_running_loop()
82
+ if loop.is_running():
83
+ asyncio.gather(*self._cleanup_tasks, return_exceptions=True)
84
+ except RuntimeError:
85
+ pass
86
+
87
+ self._configs.clear()
88
+ logger.info("Pool cleanup completed. Cleaned %d pools.", cleaned_count)
89
+
90
+ @overload
91
+ def add_config(self, config: "SyncConfigT") -> "type[SyncConfigT]": # pyright: ignore[reportInvalidTypeVarUse]
92
+ ...
93
+
94
+ @overload
95
+ def add_config(self, config: "AsyncConfigT") -> "type[AsyncConfigT]": # pyright: ignore[reportInvalidTypeVarUse]
96
+ ...
97
+
98
+ def add_config(self, config: "Union[SyncConfigT, AsyncConfigT]") -> "type[Union[SyncConfigT, AsyncConfigT]]": # pyright: ignore[reportInvalidTypeVarUse]
99
+ """Add a configuration instance to the registry.
100
+
101
+ Args:
102
+ config: The configuration instance to add.
103
+
104
+ Returns:
105
+ The type of the added configuration, annotated with its ID for potential use in type systems.
106
+ """
107
+ config_type = type(config)
108
+ if config_type in self._configs:
109
+ logger.warning("Configuration for %s already exists. Overwriting.", config_type.__name__)
110
+ self._configs[config_type] = config
111
+ return config_type
112
+
113
+ @overload
114
+ def get_config(self, name: "type[SyncConfigT]") -> "SyncConfigT": ...
115
+
116
+ @overload
117
+ def get_config(self, name: "type[AsyncConfigT]") -> "AsyncConfigT": ...
118
+
119
+ def get_config(
120
+ self, name: "Union[type[DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]], Any]"
121
+ ) -> "DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]":
122
+ """Retrieve a configuration instance by its type or a key.
123
+
124
+ Args:
125
+ name: The type of the configuration or a key associated with it.
126
+
127
+ Returns:
128
+ The configuration instance.
129
+
130
+ Raises:
131
+ KeyError: If the configuration is not found.
132
+ """
133
+ config = self._configs.get(name)
134
+ if not config:
135
+ logger.error("No configuration found for %s", name)
136
+ msg = f"No configuration found for {name}"
137
+ raise KeyError(msg)
138
+
139
+ logger.debug("Retrieved configuration: %s", self._get_config_name(name))
140
+ return config
141
+
142
+ @overload
143
+ def get_connection(
144
+ self,
145
+ name: Union[
146
+ "type[NoPoolSyncConfig[ConnectionT, DriverT]]",
147
+ "type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
148
+ "NoPoolSyncConfig[ConnectionT, DriverT]",
149
+ "SyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
150
+ ],
151
+ ) -> "ConnectionT": ...
152
+
153
+ @overload
154
+ def get_connection(
155
+ self,
156
+ name: Union[
157
+ "type[NoPoolAsyncConfig[ConnectionT, DriverT]]",
158
+ "type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
159
+ "NoPoolAsyncConfig[ConnectionT, DriverT]",
160
+ "AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
161
+ ],
162
+ ) -> "Awaitable[ConnectionT]": ...
163
+
164
+ def get_connection(
165
+ self,
166
+ name: Union[
167
+ "type[NoPoolSyncConfig[ConnectionT, DriverT]]",
168
+ "type[NoPoolAsyncConfig[ConnectionT, DriverT]]",
169
+ "type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
170
+ "type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
171
+ "NoPoolSyncConfig[ConnectionT, DriverT]",
172
+ "SyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
173
+ "NoPoolAsyncConfig[ConnectionT, DriverT]",
174
+ "AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
175
+ ],
176
+ ) -> "Union[ConnectionT, Awaitable[ConnectionT]]":
177
+ """Get a database connection for the specified configuration.
178
+
179
+ Args:
180
+ name: The configuration name or instance.
181
+
182
+ Returns:
183
+ A database connection or an awaitable yielding a connection.
184
+ """
185
+ if isinstance(name, (NoPoolSyncConfig, NoPoolAsyncConfig, SyncDatabaseConfig, AsyncDatabaseConfig)):
186
+ config = name
187
+ config_name = config.__class__.__name__
188
+ else:
189
+ config = self.get_config(name)
190
+ config_name = self._get_config_name(name)
191
+
192
+ logger.debug("Getting connection for config: %s", config_name, extra={"config_type": config_name})
193
+ return config.create_connection()
194
+
195
+ @overload
196
+ def get_session(
197
+ self,
198
+ name: Union[
199
+ "type[NoPoolSyncConfig[ConnectionT, DriverT]]",
200
+ "type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
201
+ "NoPoolSyncConfig[ConnectionT, DriverT]",
202
+ "SyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
203
+ ],
204
+ ) -> "DriverT": ...
205
+
206
+ @overload
207
+ def get_session(
208
+ self,
209
+ name: Union[
210
+ "type[NoPoolAsyncConfig[ConnectionT, DriverT]]",
211
+ "type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
212
+ "NoPoolAsyncConfig[ConnectionT, DriverT]",
213
+ "AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
214
+ ],
215
+ ) -> "Awaitable[DriverT]": ...
216
+
217
+ def get_session(
218
+ self,
219
+ name: Union[
220
+ "type[NoPoolSyncConfig[ConnectionT, DriverT]]",
221
+ "type[NoPoolAsyncConfig[ConnectionT, DriverT]]",
222
+ "type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
223
+ "type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
224
+ "NoPoolSyncConfig[ConnectionT, DriverT]",
225
+ "NoPoolAsyncConfig[ConnectionT, DriverT]",
226
+ "SyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
227
+ "AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
228
+ ],
229
+ ) -> "Union[DriverT, Awaitable[DriverT]]":
230
+ """Get a database session (driver adapter) for the specified configuration.
231
+
232
+ Args:
233
+ name: The configuration name or instance.
234
+
235
+ Returns:
236
+ A driver adapter instance or an awaitable yielding one.
237
+ """
238
+ if isinstance(name, (NoPoolSyncConfig, NoPoolAsyncConfig, SyncDatabaseConfig, AsyncDatabaseConfig)):
239
+ config = name
240
+ config_name = config.__class__.__name__
241
+ else:
242
+ config = self.get_config(name)
243
+ config_name = self._get_config_name(name)
244
+
245
+ logger.debug("Getting session for config: %s", config_name, extra={"config_type": config_name})
246
+
247
+ connection_obj = self.get_connection(name)
248
+
249
+ if isinstance(connection_obj, Awaitable):
250
+
251
+ async def _create_driver_async() -> "DriverT":
252
+ resolved_connection = await connection_obj # pyright: ignore
253
+ return cast( # pyright: ignore
254
+ "DriverT", config.driver_type(connection=resolved_connection)
255
+ )
256
+
257
+ return _create_driver_async()
258
+
259
+ return cast( # pyright: ignore
260
+ "DriverT", config.driver_type(connection=connection_obj)
261
+ )
262
+
263
+ @overload
264
+ def provide_connection(
265
+ self,
266
+ name: Union[
267
+ "type[NoPoolSyncConfig[ConnectionT, DriverT]]",
268
+ "type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
269
+ "NoPoolSyncConfig[ConnectionT, DriverT]",
270
+ "SyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
271
+ ],
272
+ *args: Any,
273
+ **kwargs: Any,
274
+ ) -> "AbstractContextManager[ConnectionT]": ...
275
+
276
+ @overload
277
+ def provide_connection(
278
+ self,
279
+ name: Union[
280
+ "type[NoPoolAsyncConfig[ConnectionT, DriverT]]",
281
+ "type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
282
+ "NoPoolAsyncConfig[ConnectionT, DriverT]",
283
+ "AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
284
+ ],
285
+ *args: Any,
286
+ **kwargs: Any,
287
+ ) -> "AbstractAsyncContextManager[ConnectionT]": ...
288
+
289
+ def provide_connection(
290
+ self,
291
+ name: Union[
292
+ "type[NoPoolSyncConfig[ConnectionT, DriverT]]",
293
+ "type[NoPoolAsyncConfig[ConnectionT, DriverT]]",
294
+ "type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
295
+ "type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
296
+ "NoPoolSyncConfig[ConnectionT, DriverT]",
297
+ "NoPoolAsyncConfig[ConnectionT, DriverT]",
298
+ "SyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
299
+ "AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
300
+ ],
301
+ *args: Any,
302
+ **kwargs: Any,
303
+ ) -> "Union[AbstractContextManager[ConnectionT], AbstractAsyncContextManager[ConnectionT]]":
304
+ """Create and provide a database connection from the specified configuration.
305
+
306
+ Args:
307
+ name: The configuration name or instance.
308
+ *args: Positional arguments to pass to the config's provide_connection.
309
+ **kwargs: Keyword arguments to pass to the config's provide_connection.
310
+
311
+
312
+ Returns:
313
+ A sync or async context manager yielding a connection.
314
+ """
315
+ if isinstance(name, (NoPoolSyncConfig, NoPoolAsyncConfig, SyncDatabaseConfig, AsyncDatabaseConfig)):
316
+ config = name
317
+ config_name = config.__class__.__name__
318
+ else:
319
+ config = self.get_config(name)
320
+ config_name = self._get_config_name(name)
321
+
322
+ logger.debug("Providing connection context for config: %s", config_name, extra={"config_type": config_name})
323
+ return config.provide_connection(*args, **kwargs)
324
+
325
+ @overload
326
+ def provide_session(
327
+ self,
328
+ name: Union[
329
+ "type[NoPoolSyncConfig[ConnectionT, DriverT]]",
330
+ "type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
331
+ "NoPoolSyncConfig[ConnectionT, DriverT]",
332
+ "SyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
333
+ ],
334
+ *args: Any,
335
+ **kwargs: Any,
336
+ ) -> "AbstractContextManager[DriverT]": ...
337
+
338
+ @overload
339
+ def provide_session(
340
+ self,
341
+ name: Union[
342
+ "type[NoPoolAsyncConfig[ConnectionT, DriverT]]",
343
+ "type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
344
+ "NoPoolAsyncConfig[ConnectionT, DriverT]",
345
+ "AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
346
+ ],
347
+ *args: Any,
348
+ **kwargs: Any,
349
+ ) -> "AbstractAsyncContextManager[DriverT]": ...
350
+
351
+ def provide_session(
352
+ self,
353
+ name: Union[
354
+ "type[NoPoolSyncConfig[ConnectionT, DriverT]]",
355
+ "type[NoPoolAsyncConfig[ConnectionT, DriverT]]",
356
+ "type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
357
+ "type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
358
+ "NoPoolSyncConfig[ConnectionT, DriverT]",
359
+ "NoPoolAsyncConfig[ConnectionT, DriverT]",
360
+ "SyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
361
+ "AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
362
+ ],
363
+ *args: Any,
364
+ **kwargs: Any,
365
+ ) -> "Union[AbstractContextManager[DriverT], AbstractAsyncContextManager[DriverT]]":
366
+ """Create and provide a database session from the specified configuration.
367
+
368
+ Args:
369
+ name: The configuration name or instance.
370
+ *args: Positional arguments to pass to the config's provide_session.
371
+ **kwargs: Keyword arguments to pass to the config's provide_session.
372
+
373
+ Returns:
374
+ A sync or async context manager yielding a driver adapter instance.
375
+ """
376
+ if isinstance(name, (NoPoolSyncConfig, NoPoolAsyncConfig, SyncDatabaseConfig, AsyncDatabaseConfig)):
377
+ config = name
378
+ config_name = config.__class__.__name__
379
+ else:
380
+ config = self.get_config(name)
381
+ config_name = self._get_config_name(name)
382
+
383
+ logger.debug("Providing session context for config: %s", config_name, extra={"config_type": config_name})
384
+ return config.provide_session(*args, **kwargs)
385
+
386
+ @overload
387
+ def get_pool(
388
+ self,
389
+ name: "Union[type[Union[NoPoolSyncConfig[ConnectionT, DriverT], NoPoolAsyncConfig[ConnectionT, DriverT]]], NoPoolSyncConfig[ConnectionT, DriverT], NoPoolAsyncConfig[ConnectionT, DriverT]]",
390
+ ) -> "None": ...
391
+ @overload
392
+ def get_pool(
393
+ self,
394
+ name: "Union[type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]], SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
395
+ ) -> "type[PoolT]": ...
396
+ @overload
397
+ def get_pool(
398
+ self,
399
+ name: "Union[type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]],AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
400
+ ) -> "Awaitable[type[PoolT]]": ...
401
+
402
+ def get_pool(
403
+ self,
404
+ name: Union[
405
+ "type[NoPoolSyncConfig[ConnectionT, DriverT]]",
406
+ "type[NoPoolAsyncConfig[ConnectionT, DriverT]]",
407
+ "type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
408
+ "type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
409
+ "NoPoolSyncConfig[ConnectionT, DriverT]",
410
+ "NoPoolAsyncConfig[ConnectionT, DriverT]",
411
+ "SyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
412
+ "AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
413
+ ],
414
+ ) -> "Union[type[PoolT], Awaitable[type[PoolT]], None]":
415
+ """Get the connection pool for the specified configuration.
416
+
417
+ Args:
418
+ name: The configuration name or instance.
419
+
420
+ Returns:
421
+ The connection pool, an awaitable yielding the pool, or None if not supported.
422
+ """
423
+ config = (
424
+ name
425
+ if isinstance(name, (NoPoolSyncConfig, NoPoolAsyncConfig, SyncDatabaseConfig, AsyncDatabaseConfig))
426
+ else self.get_config(name)
427
+ )
428
+ config_name = config.__class__.__name__
429
+
430
+ if config.supports_connection_pooling:
431
+ logger.debug("Getting pool for config: %s", config_name, extra={"config_type": config_name})
432
+ return cast("Union[type[PoolT], Awaitable[type[PoolT]]]", config.create_pool())
433
+
434
+ logger.debug("Config %s does not support connection pooling", config_name)
435
+ return None
436
+
437
+ @overload
438
+ def close_pool(
439
+ self,
440
+ name: Union[
441
+ "type[NoPoolSyncConfig[ConnectionT, DriverT]]",
442
+ "type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
443
+ "NoPoolSyncConfig[ConnectionT, DriverT]",
444
+ "SyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
445
+ ],
446
+ ) -> "None": ...
447
+
448
+ @overload
449
+ def close_pool(
450
+ self,
451
+ name: Union[
452
+ "type[NoPoolAsyncConfig[ConnectionT, DriverT]]",
453
+ "type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
454
+ "NoPoolAsyncConfig[ConnectionT, DriverT]",
455
+ "AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
456
+ ],
457
+ ) -> "Awaitable[None]": ...
458
+
459
+ def close_pool(
460
+ self,
461
+ name: Union[
462
+ "type[NoPoolSyncConfig[ConnectionT, DriverT]]",
463
+ "type[NoPoolAsyncConfig[ConnectionT, DriverT]]",
464
+ "type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
465
+ "type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
466
+ "NoPoolSyncConfig[ConnectionT, DriverT]",
467
+ "SyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
468
+ "NoPoolAsyncConfig[ConnectionT, DriverT]",
469
+ "AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
470
+ ],
471
+ ) -> "Optional[Awaitable[None]]":
472
+ """Close the connection pool for the specified configuration.
473
+
474
+ Args:
475
+ name: The configuration name or instance.
476
+
477
+ Returns:
478
+ None, or an awaitable if closing an async pool.
479
+ """
480
+ if isinstance(name, (NoPoolSyncConfig, NoPoolAsyncConfig, SyncDatabaseConfig, AsyncDatabaseConfig)):
481
+ config = name
482
+ config_name = config.__class__.__name__
483
+ else:
484
+ config = self.get_config(name)
485
+ config_name = self._get_config_name(name)
486
+
487
+ if config.supports_connection_pooling:
488
+ logger.debug("Closing pool for config: %s", config_name, extra={"config_type": config_name})
489
+ return config.close_pool()
490
+
491
+ logger.debug("Config %s does not support connection pooling - nothing to close", config_name)
492
+ return None
493
+
494
+ @staticmethod
495
+ def get_cache_config() -> CacheConfig:
496
+ """Get the current global cache configuration.
497
+
498
+ Returns:
499
+ The current cache configuration.
500
+ """
501
+ return get_cache_config()
502
+
503
+ @staticmethod
504
+ def update_cache_config(config: CacheConfig) -> None:
505
+ """Update the global cache configuration.
506
+
507
+ Args:
508
+ config: The new cache configuration to apply.
509
+ """
510
+ update_cache_config(config)
511
+
512
+ @staticmethod
513
+ def get_cache_stats() -> CacheStatsAggregate:
514
+ """Get current cache statistics.
515
+
516
+ Returns:
517
+ Cache statistics object with detailed metrics.
518
+ """
519
+ return get_cache_stats()
520
+
521
+ @staticmethod
522
+ def reset_cache_stats() -> None:
523
+ """Reset all cache statistics to zero."""
524
+ reset_cache_stats()
525
+
526
+ @staticmethod
527
+ def log_cache_stats() -> None:
528
+ """Log current cache statistics using the configured logger."""
529
+ log_cache_stats()
530
+
531
+ @staticmethod
532
+ def configure_cache(
533
+ *,
534
+ sql_cache_size: Optional[int] = None,
535
+ fragment_cache_size: Optional[int] = None,
536
+ optimized_cache_size: Optional[int] = None,
537
+ sql_cache_enabled: Optional[bool] = None,
538
+ fragment_cache_enabled: Optional[bool] = None,
539
+ optimized_cache_enabled: Optional[bool] = None,
540
+ ) -> None:
541
+ """Update cache configuration with partial values.
542
+
543
+ Args:
544
+ sql_cache_size: Size of the SQL statement cache
545
+ fragment_cache_size: Size of the AST fragment cache
546
+ optimized_cache_size: Size of the optimized expression cache
547
+ sql_cache_enabled: Enable/disable SQL cache
548
+ fragment_cache_enabled: Enable/disable fragment cache
549
+ optimized_cache_enabled: Enable/disable optimized cache
550
+ """
551
+ current_config = get_cache_config()
552
+ update_cache_config(
553
+ CacheConfig(
554
+ sql_cache_size=sql_cache_size if sql_cache_size is not None else current_config.sql_cache_size,
555
+ fragment_cache_size=fragment_cache_size
556
+ if fragment_cache_size is not None
557
+ else current_config.fragment_cache_size,
558
+ optimized_cache_size=optimized_cache_size
559
+ if optimized_cache_size is not None
560
+ else current_config.optimized_cache_size,
561
+ sql_cache_enabled=sql_cache_enabled
562
+ if sql_cache_enabled is not None
563
+ else current_config.sql_cache_enabled,
564
+ fragment_cache_enabled=fragment_cache_enabled
565
+ if fragment_cache_enabled is not None
566
+ else current_config.fragment_cache_enabled,
567
+ optimized_cache_enabled=optimized_cache_enabled
568
+ if optimized_cache_enabled is not None
569
+ else current_config.optimized_cache_enabled,
570
+ )
571
+ )
@@ -0,0 +1,62 @@
1
+ """SQL query builders for safe SQL construction.
2
+
3
+ This package provides fluent interfaces for building SQL queries with automatic
4
+ parameter binding and validation.
5
+ """
6
+
7
+ from sqlspec.builder._base import QueryBuilder, SafeQuery
8
+ from sqlspec.builder._column import Column, ColumnExpression, FunctionColumn
9
+ from sqlspec.builder._ddl import (
10
+ AlterTable,
11
+ CommentOn,
12
+ CreateIndex,
13
+ CreateMaterializedView,
14
+ CreateSchema,
15
+ CreateTable,
16
+ CreateTableAsSelect,
17
+ CreateView,
18
+ DDLBuilder,
19
+ DropIndex,
20
+ DropSchema,
21
+ DropTable,
22
+ DropView,
23
+ RenameTable,
24
+ Truncate,
25
+ )
26
+ from sqlspec.builder._delete import Delete
27
+ from sqlspec.builder._insert import Insert
28
+ from sqlspec.builder._merge import Merge
29
+ from sqlspec.builder._select import Select
30
+ from sqlspec.builder._update import Update
31
+ from sqlspec.builder.mixins import WhereClauseMixin
32
+ from sqlspec.exceptions import SQLBuilderError
33
+
34
+ __all__ = (
35
+ "AlterTable",
36
+ "Column",
37
+ "ColumnExpression",
38
+ "CommentOn",
39
+ "CreateIndex",
40
+ "CreateMaterializedView",
41
+ "CreateSchema",
42
+ "CreateTable",
43
+ "CreateTableAsSelect",
44
+ "CreateView",
45
+ "DDLBuilder",
46
+ "Delete",
47
+ "DropIndex",
48
+ "DropSchema",
49
+ "DropTable",
50
+ "DropView",
51
+ "FunctionColumn",
52
+ "Insert",
53
+ "Merge",
54
+ "QueryBuilder",
55
+ "RenameTable",
56
+ "SQLBuilderError",
57
+ "SafeQuery",
58
+ "Select",
59
+ "Truncate",
60
+ "Update",
61
+ "WhereClauseMixin",
62
+ )