sqlspec 0.14.1__py3-none-any.whl → 0.15.0__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 (158) hide show
  1. sqlspec/__init__.py +50 -25
  2. sqlspec/__main__.py +1 -1
  3. sqlspec/__metadata__.py +1 -3
  4. sqlspec/_serialization.py +1 -2
  5. sqlspec/_sql.py +256 -120
  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 +115 -260
  10. sqlspec/adapters/adbc/driver.py +462 -367
  11. sqlspec/adapters/aiosqlite/__init__.py +18 -3
  12. sqlspec/adapters/aiosqlite/_types.py +13 -0
  13. sqlspec/adapters/aiosqlite/config.py +199 -129
  14. sqlspec/adapters/aiosqlite/driver.py +230 -269
  15. sqlspec/adapters/asyncmy/__init__.py +18 -3
  16. sqlspec/adapters/asyncmy/_types.py +12 -0
  17. sqlspec/adapters/asyncmy/config.py +80 -168
  18. sqlspec/adapters/asyncmy/driver.py +260 -225
  19. sqlspec/adapters/asyncpg/__init__.py +19 -4
  20. sqlspec/adapters/asyncpg/_types.py +17 -0
  21. sqlspec/adapters/asyncpg/config.py +82 -181
  22. sqlspec/adapters/asyncpg/driver.py +285 -383
  23. sqlspec/adapters/bigquery/__init__.py +17 -3
  24. sqlspec/adapters/bigquery/_types.py +12 -0
  25. sqlspec/adapters/bigquery/config.py +191 -258
  26. sqlspec/adapters/bigquery/driver.py +474 -646
  27. sqlspec/adapters/duckdb/__init__.py +14 -3
  28. sqlspec/adapters/duckdb/_types.py +12 -0
  29. sqlspec/adapters/duckdb/config.py +415 -351
  30. sqlspec/adapters/duckdb/driver.py +343 -413
  31. sqlspec/adapters/oracledb/__init__.py +19 -5
  32. sqlspec/adapters/oracledb/_types.py +14 -0
  33. sqlspec/adapters/oracledb/config.py +123 -379
  34. sqlspec/adapters/oracledb/driver.py +507 -560
  35. sqlspec/adapters/psqlpy/__init__.py +13 -3
  36. sqlspec/adapters/psqlpy/_types.py +11 -0
  37. sqlspec/adapters/psqlpy/config.py +93 -254
  38. sqlspec/adapters/psqlpy/driver.py +505 -234
  39. sqlspec/adapters/psycopg/__init__.py +19 -5
  40. sqlspec/adapters/psycopg/_types.py +17 -0
  41. sqlspec/adapters/psycopg/config.py +143 -403
  42. sqlspec/adapters/psycopg/driver.py +706 -872
  43. sqlspec/adapters/sqlite/__init__.py +14 -3
  44. sqlspec/adapters/sqlite/_types.py +11 -0
  45. sqlspec/adapters/sqlite/config.py +202 -118
  46. sqlspec/adapters/sqlite/driver.py +264 -303
  47. sqlspec/base.py +105 -9
  48. sqlspec/{statement/builder → builder}/__init__.py +12 -14
  49. sqlspec/{statement/builder → builder}/_base.py +120 -55
  50. sqlspec/{statement/builder → builder}/_column.py +17 -6
  51. sqlspec/{statement/builder → builder}/_ddl.py +46 -79
  52. sqlspec/{statement/builder → builder}/_ddl_utils.py +5 -10
  53. sqlspec/{statement/builder → builder}/_delete.py +6 -25
  54. sqlspec/{statement/builder → builder}/_insert.py +6 -64
  55. sqlspec/builder/_merge.py +56 -0
  56. sqlspec/{statement/builder → builder}/_parsing_utils.py +3 -10
  57. sqlspec/{statement/builder → builder}/_select.py +11 -56
  58. sqlspec/{statement/builder → builder}/_update.py +12 -18
  59. sqlspec/{statement/builder → builder}/mixins/__init__.py +10 -14
  60. sqlspec/{statement/builder → builder}/mixins/_cte_and_set_ops.py +48 -59
  61. sqlspec/{statement/builder → builder}/mixins/_insert_operations.py +22 -16
  62. sqlspec/{statement/builder → builder}/mixins/_join_operations.py +1 -3
  63. sqlspec/{statement/builder → builder}/mixins/_merge_operations.py +3 -5
  64. sqlspec/{statement/builder → builder}/mixins/_order_limit_operations.py +3 -3
  65. sqlspec/{statement/builder → builder}/mixins/_pivot_operations.py +4 -8
  66. sqlspec/{statement/builder → builder}/mixins/_select_operations.py +21 -36
  67. sqlspec/{statement/builder → builder}/mixins/_update_operations.py +3 -14
  68. sqlspec/{statement/builder → builder}/mixins/_where_clause.py +52 -79
  69. sqlspec/cli.py +4 -5
  70. sqlspec/config.py +180 -133
  71. sqlspec/core/__init__.py +63 -0
  72. sqlspec/core/cache.py +873 -0
  73. sqlspec/core/compiler.py +396 -0
  74. sqlspec/core/filters.py +828 -0
  75. sqlspec/core/hashing.py +310 -0
  76. sqlspec/core/parameters.py +1209 -0
  77. sqlspec/core/result.py +664 -0
  78. sqlspec/{statement → core}/splitter.py +321 -191
  79. sqlspec/core/statement.py +651 -0
  80. sqlspec/driver/__init__.py +7 -10
  81. sqlspec/driver/_async.py +387 -176
  82. sqlspec/driver/_common.py +527 -289
  83. sqlspec/driver/_sync.py +390 -172
  84. sqlspec/driver/mixins/__init__.py +2 -19
  85. sqlspec/driver/mixins/_result_tools.py +168 -0
  86. sqlspec/driver/mixins/_sql_translator.py +6 -3
  87. sqlspec/exceptions.py +5 -252
  88. sqlspec/extensions/aiosql/adapter.py +93 -96
  89. sqlspec/extensions/litestar/config.py +0 -1
  90. sqlspec/extensions/litestar/handlers.py +15 -26
  91. sqlspec/extensions/litestar/plugin.py +16 -14
  92. sqlspec/extensions/litestar/providers.py +17 -52
  93. sqlspec/loader.py +424 -105
  94. sqlspec/migrations/__init__.py +12 -0
  95. sqlspec/migrations/base.py +92 -68
  96. sqlspec/migrations/commands.py +24 -106
  97. sqlspec/migrations/loaders.py +402 -0
  98. sqlspec/migrations/runner.py +49 -51
  99. sqlspec/migrations/tracker.py +31 -44
  100. sqlspec/migrations/utils.py +64 -24
  101. sqlspec/protocols.py +7 -183
  102. sqlspec/storage/__init__.py +1 -1
  103. sqlspec/storage/backends/base.py +37 -40
  104. sqlspec/storage/backends/fsspec.py +136 -112
  105. sqlspec/storage/backends/obstore.py +138 -160
  106. sqlspec/storage/capabilities.py +5 -4
  107. sqlspec/storage/registry.py +57 -106
  108. sqlspec/typing.py +136 -115
  109. sqlspec/utils/__init__.py +2 -3
  110. sqlspec/utils/correlation.py +0 -3
  111. sqlspec/utils/deprecation.py +6 -6
  112. sqlspec/utils/fixtures.py +6 -6
  113. sqlspec/utils/logging.py +0 -2
  114. sqlspec/utils/module_loader.py +7 -12
  115. sqlspec/utils/singleton.py +0 -1
  116. sqlspec/utils/sync_tools.py +16 -37
  117. sqlspec/utils/text.py +12 -51
  118. sqlspec/utils/type_guards.py +443 -232
  119. {sqlspec-0.14.1.dist-info → sqlspec-0.15.0.dist-info}/METADATA +7 -2
  120. sqlspec-0.15.0.dist-info/RECORD +134 -0
  121. sqlspec/adapters/adbc/transformers.py +0 -108
  122. sqlspec/driver/connection.py +0 -207
  123. sqlspec/driver/mixins/_cache.py +0 -114
  124. sqlspec/driver/mixins/_csv_writer.py +0 -91
  125. sqlspec/driver/mixins/_pipeline.py +0 -508
  126. sqlspec/driver/mixins/_query_tools.py +0 -796
  127. sqlspec/driver/mixins/_result_utils.py +0 -138
  128. sqlspec/driver/mixins/_storage.py +0 -912
  129. sqlspec/driver/mixins/_type_coercion.py +0 -128
  130. sqlspec/driver/parameters.py +0 -138
  131. sqlspec/statement/__init__.py +0 -21
  132. sqlspec/statement/builder/_merge.py +0 -95
  133. sqlspec/statement/cache.py +0 -50
  134. sqlspec/statement/filters.py +0 -625
  135. sqlspec/statement/parameters.py +0 -956
  136. sqlspec/statement/pipelines/__init__.py +0 -210
  137. sqlspec/statement/pipelines/analyzers/__init__.py +0 -9
  138. sqlspec/statement/pipelines/analyzers/_analyzer.py +0 -646
  139. sqlspec/statement/pipelines/context.py +0 -109
  140. sqlspec/statement/pipelines/transformers/__init__.py +0 -7
  141. sqlspec/statement/pipelines/transformers/_expression_simplifier.py +0 -88
  142. sqlspec/statement/pipelines/transformers/_literal_parameterizer.py +0 -1247
  143. sqlspec/statement/pipelines/transformers/_remove_comments_and_hints.py +0 -76
  144. sqlspec/statement/pipelines/validators/__init__.py +0 -23
  145. sqlspec/statement/pipelines/validators/_dml_safety.py +0 -290
  146. sqlspec/statement/pipelines/validators/_parameter_style.py +0 -370
  147. sqlspec/statement/pipelines/validators/_performance.py +0 -714
  148. sqlspec/statement/pipelines/validators/_security.py +0 -967
  149. sqlspec/statement/result.py +0 -435
  150. sqlspec/statement/sql.py +0 -1774
  151. sqlspec/utils/cached_property.py +0 -25
  152. sqlspec/utils/statement_hashing.py +0 -203
  153. sqlspec-0.14.1.dist-info/RECORD +0 -145
  154. /sqlspec/{statement/builder → builder}/mixins/_delete_operations.py +0 -0
  155. {sqlspec-0.14.1.dist-info → sqlspec-0.15.0.dist-info}/WHEEL +0 -0
  156. {sqlspec-0.14.1.dist-info → sqlspec-0.15.0.dist-info}/entry_points.txt +0 -0
  157. {sqlspec-0.14.1.dist-info → sqlspec-0.15.0.dist-info}/licenses/LICENSE +0 -0
  158. {sqlspec-0.14.1.dist-info → sqlspec-0.15.0.dist-info}/licenses/NOTICE +0 -0
@@ -1,4 +1,19 @@
1
- from sqlspec.adapters.aiosqlite.config import CONNECTION_FIELDS, AiosqliteConfig
2
- from sqlspec.adapters.aiosqlite.driver import AiosqliteConnection, AiosqliteDriver
1
+ from sqlspec.adapters.aiosqlite._types import AiosqliteConnection
2
+ from sqlspec.adapters.aiosqlite.config import AiosqliteConfig, AiosqliteConnectionParams, AiosqliteConnectionPool
3
+ from sqlspec.adapters.aiosqlite.driver import (
4
+ AiosqliteCursor,
5
+ AiosqliteDriver,
6
+ AiosqliteExceptionHandler,
7
+ aiosqlite_statement_config,
8
+ )
3
9
 
4
- __all__ = ("CONNECTION_FIELDS", "AiosqliteConfig", "AiosqliteConnection", "AiosqliteDriver")
10
+ __all__ = (
11
+ "AiosqliteConfig",
12
+ "AiosqliteConnection",
13
+ "AiosqliteConnectionParams",
14
+ "AiosqliteConnectionPool",
15
+ "AiosqliteCursor",
16
+ "AiosqliteDriver",
17
+ "AiosqliteExceptionHandler",
18
+ "aiosqlite_statement_config",
19
+ )
@@ -0,0 +1,13 @@
1
+ # pyright: reportCallIssue=false, reportAttributeAccessIssue=false, reportArgumentType=false
2
+ from typing import TYPE_CHECKING
3
+
4
+ import aiosqlite
5
+
6
+ if TYPE_CHECKING:
7
+ from typing_extensions import TypeAlias
8
+
9
+ AiosqliteConnection: TypeAlias = aiosqlite.Connection
10
+ else:
11
+ AiosqliteConnection = aiosqlite.Connection
12
+
13
+ __all__ = ("AiosqliteConnection",)
@@ -1,183 +1,253 @@
1
- """Aiosqlite database configuration with direct field-based configuration."""
1
+ """Aiosqlite database configuration with optimized connection management."""
2
2
 
3
+ import asyncio
3
4
  import logging
4
- from collections.abc import AsyncGenerator
5
5
  from contextlib import asynccontextmanager
6
- from typing import TYPE_CHECKING, Any, ClassVar, Optional
6
+ from typing import TYPE_CHECKING, Any, ClassVar, Final, Optional, TypedDict
7
7
 
8
8
  import aiosqlite
9
+ from typing_extensions import NotRequired
9
10
 
10
- from sqlspec.adapters.aiosqlite.driver import AiosqliteConnection, AiosqliteDriver
11
+ from sqlspec.adapters.aiosqlite.driver import AiosqliteCursor, AiosqliteDriver, aiosqlite_statement_config
11
12
  from sqlspec.config import AsyncDatabaseConfig
12
- from sqlspec.exceptions import ImproperConfigurationError
13
- from sqlspec.statement.sql import SQLConfig
14
- from sqlspec.typing import DictRow, Empty
15
13
 
16
14
  if TYPE_CHECKING:
17
- from typing import Literal
15
+ from collections.abc import AsyncGenerator
18
16
 
17
+ from sqlspec.adapters.aiosqlite._types import AiosqliteConnection
18
+ from sqlspec.core.statement import StatementConfig
19
19
 
20
- __all__ = ("CONNECTION_FIELDS", "AiosqliteConfig")
20
+ __all__ = ("AiosqliteConfig", "AiosqliteConnectionParams", "AiosqliteConnectionPool")
21
21
 
22
22
  logger = logging.getLogger(__name__)
23
23
 
24
- CONNECTION_FIELDS = frozenset(
25
- {"database", "timeout", "detect_types", "isolation_level", "check_same_thread", "cached_statements", "uri"}
26
- )
24
+ # Core PRAGMAs for SQLite performance optimization
25
+ WAL_PRAGMA_SQL: Final[str] = "PRAGMA journal_mode = WAL"
26
+ FOREIGN_KEYS_SQL: Final[str] = "PRAGMA foreign_keys = ON"
27
+ SYNC_NORMAL_SQL: Final[str] = "PRAGMA synchronous = NORMAL"
28
+ BUSY_TIMEOUT_SQL: Final[str] = "PRAGMA busy_timeout = 5000" # 5 seconds
27
29
 
28
30
 
29
- class AiosqliteConfig(AsyncDatabaseConfig[AiosqliteConnection, None, AiosqliteDriver]):
30
- """Configuration for Aiosqlite database connections with direct field-based configuration.
31
+ class AiosqliteConnectionPool:
32
+ """Connection pool for Aiosqlite using a single shared connection approach.
31
33
 
32
- Note: Aiosqlite doesn't support connection pooling, so pool_instance is always None.
34
+ Uses a single shared connection per database file since aiosqlite internally
35
+ handles queuing and serialization of operations.
33
36
  """
34
37
 
35
- is_async: ClassVar[bool] = True
36
- supports_connection_pooling: ClassVar[bool] = False
38
+ __slots__ = ("_closed", "_connection", "_connection_parameters", "_lock")
37
39
 
38
- driver_type: type[AiosqliteDriver] = AiosqliteDriver
39
- connection_type: type[AiosqliteConnection] = AiosqliteConnection
40
+ def __init__(self, connection_parameters: "dict[str, Any]") -> None:
41
+ """Initialize connection manager.
42
+
43
+ Args:
44
+ connection_parameters: SQLite connection parameters
45
+ """
46
+ self._connection: Optional[AiosqliteConnection] = None
47
+ self._connection_parameters = connection_parameters
48
+ self._lock = asyncio.Lock()
49
+ self._closed = False
50
+
51
+ async def _ensure_connection(self) -> "AiosqliteConnection":
52
+ """Ensure we have a valid connection, creating one if needed."""
53
+ async with self._lock:
54
+ if self._connection is None or self._closed:
55
+ self._connection = await aiosqlite.connect(**self._connection_parameters)
56
+
57
+ await self._connection.execute(WAL_PRAGMA_SQL)
58
+ await self._connection.execute(FOREIGN_KEYS_SQL)
59
+ await self._connection.execute(SYNC_NORMAL_SQL)
60
+ await self._connection.execute(BUSY_TIMEOUT_SQL)
61
+ await self._connection.commit()
62
+
63
+ self._closed = False
64
+ logger.debug("Created new aiosqlite connection")
65
+
66
+ return self._connection
67
+
68
+ @asynccontextmanager
69
+ async def get_connection(self) -> "AsyncGenerator[AiosqliteConnection, None]":
70
+ """Get the shared connection.
71
+
72
+ Yields:
73
+ The shared Aiosqlite connection instance.
74
+ """
75
+ connection = await self._ensure_connection()
76
+ yield connection
77
+
78
+ async def close(self) -> None:
79
+ """Close the shared connection."""
80
+ async with self._lock:
81
+ if self._connection is not None and not self._closed:
82
+ await self._connection.close()
83
+ self._connection = None
84
+ self._closed = True
85
+ logger.debug("Closed aiosqlite connection")
86
+
87
+ def size(self) -> int:
88
+ """Get connection count."""
89
+ return 0 if self._closed or self._connection is None else 1
90
+
91
+ def checked_out(self) -> int:
92
+ """Get number of checked out connections."""
93
+ return 0
94
+
95
+ async def acquire(self) -> "AiosqliteConnection":
96
+ """Get the shared connection directly.
97
+
98
+ Returns:
99
+ The shared connection instance.
100
+ """
101
+ return await self._ensure_connection()
102
+
103
+ async def release(self, connection: "AiosqliteConnection") -> None:
104
+ """No-op release for compatibility.
105
+
106
+ Args:
107
+ connection: Connection to release (ignored)
108
+ """
109
+ _ = connection
40
110
 
41
- # Parameter style support information
42
- supported_parameter_styles: ClassVar[tuple[str, ...]] = ("qmark", "named_colon")
43
- """AIOSQLite supports ? (qmark) and :name (named_colon) parameter styles."""
44
111
 
45
- default_parameter_style: ClassVar[str] = "qmark"
46
- """AIOSQLite's native parameter style is ? (qmark)."""
112
+ class AiosqliteConnectionParams(TypedDict, total=False):
113
+ """aiosqlite connection parameters."""
114
+
115
+ database: NotRequired[str]
116
+ timeout: NotRequired[float]
117
+ detect_types: NotRequired[int]
118
+ isolation_level: NotRequired[Optional[str]]
119
+ check_same_thread: NotRequired[bool]
120
+ cached_statements: NotRequired[int]
121
+ uri: NotRequired[bool]
122
+
123
+
124
+ class AiosqliteConfig(AsyncDatabaseConfig):
125
+ """Database configuration for AioSQLite engine."""
126
+
127
+ driver_type: ClassVar[type[AiosqliteDriver]] = AiosqliteDriver
128
+ cursor_type: ClassVar[type[AiosqliteCursor]] = AiosqliteCursor
47
129
 
48
130
  def __init__(
49
131
  self,
50
- database: str = ":memory:",
51
- statement_config: Optional[SQLConfig] = None,
52
- default_row_type: type[DictRow] = DictRow,
53
- # Connection parameters
54
- timeout: Optional[float] = None,
55
- detect_types: Optional[int] = None,
56
- isolation_level: Optional["Optional[Literal['DEFERRED', 'IMMEDIATE', 'EXCLUSIVE']]"] = None,
57
- check_same_thread: Optional[bool] = None,
58
- cached_statements: Optional[int] = None,
59
- uri: Optional[bool] = None,
132
+ *,
133
+ pool_instance: "Optional[AiosqliteConnectionPool]" = None,
134
+ pool_config: "Optional[dict[str, Any]]" = None,
135
+ migration_config: "Optional[dict[str, Any]]" = None,
136
+ statement_config: "Optional[StatementConfig]" = None,
60
137
  **kwargs: Any,
61
138
  ) -> None:
62
- """Initialize Aiosqlite configuration.
139
+ """Initialize AioSQLite configuration.
63
140
 
64
141
  Args:
65
- database: The path to the database file to be opened. Pass ":memory:" for in-memory database
66
- statement_config: Default SQL statement configuration
67
- default_row_type: Default row type for results
68
- timeout: How many seconds the connection should wait before raising an OperationalError when a table is locked
69
- detect_types: Control whether and how data types are detected. It can be 0 (default) or a combination of PARSE_DECLTYPES and PARSE_COLNAMES
70
- isolation_level: The isolation_level of the connection. This can be None for autocommit mode or one of "DEFERRED", "IMMEDIATE" or "EXCLUSIVE"
71
- check_same_thread: If True (default), ProgrammingError is raised if the database connection is used by a thread other than the one that created it
72
- cached_statements: The number of statements that SQLite will cache for this connection. The default is 128
73
- uri: If set to True, database is interpreted as a URI with supported options
74
- **kwargs: Additional parameters (stored in extras)
142
+ pool_instance: Optional pre-configured connection pool instance.
143
+ pool_config: Optional pool configuration dict (AiosqliteConnectionParams).
144
+ migration_config: Optional migration configuration.
145
+ statement_config: Optional statement configuration.
146
+ **kwargs: Additional connection parameters.
75
147
  """
76
- # Store connection parameters as instance attributes
77
- self.database = database
78
- self.timeout = timeout
79
- self.detect_types = detect_types
80
- self.isolation_level = isolation_level
81
- self.check_same_thread = check_same_thread
82
- self.cached_statements = cached_statements
83
- self.uri = uri
84
- self.extras = kwargs or {}
85
- # Store other config
86
- self.statement_config = statement_config or SQLConfig()
87
- self.default_row_type = default_row_type
88
-
89
- super().__init__()
90
-
91
- @property
92
- def connection_config_dict(self) -> dict[str, Any]:
93
- """Return the connection configuration as a dict for aiosqlite.connect()."""
94
- # Gather non-None connection parameters
95
- config = {
96
- field: getattr(self, field)
97
- for field in CONNECTION_FIELDS
98
- if getattr(self, field, None) is not None and getattr(self, field) is not Empty
99
- }
100
-
101
- # Merge extras parameters
102
- config.update(self.extras)
103
-
104
- return config
105
-
106
- async def _create_pool(self) -> None:
107
- """Aiosqlite doesn't support pooling."""
108
- return
148
+ connection_params = {}
149
+ if pool_config:
150
+ connection_params.update(pool_config)
151
+ connection_params.update(kwargs)
109
152
 
110
- async def _close_pool(self) -> None:
111
- """Aiosqlite doesn't support pooling."""
112
- return
153
+ super().__init__(
154
+ pool_config=connection_params,
155
+ pool_instance=pool_instance,
156
+ migration_config=migration_config or {},
157
+ statement_config=statement_config or aiosqlite_statement_config,
158
+ )
159
+
160
+ self._connection_parameters = self._parse_connection_parameters(connection_params)
113
161
 
114
- async def create_connection(self) -> AiosqliteConnection:
115
- """Create a single async connection.
162
+ if pool_instance is None:
163
+ self.pool_instance: AiosqliteConnectionPool = AiosqliteConnectionPool(self._connection_parameters)
164
+
165
+ def _parse_connection_parameters(self, params: "dict[str, Any]") -> "dict[str, Any]":
166
+ """Parse connection parameters for AioSQLite.
167
+
168
+ Args:
169
+ params: Connection parameters dict.
116
170
 
117
171
  Returns:
118
- An Aiosqlite connection instance.
172
+ Processed connection parameters dict.
119
173
  """
120
- try:
121
- config = self.connection_config_dict
122
- return await aiosqlite.connect(**config)
123
- except Exception as e:
124
- msg = f"Could not configure the Aiosqlite connection. Error: {e!s}"
125
- raise ImproperConfigurationError(msg) from e
174
+ result = params.copy()
126
175
 
127
- @asynccontextmanager
128
- async def provide_connection(self, *args: Any, **kwargs: Any) -> AsyncGenerator[AiosqliteConnection, None]:
129
- """Provide an async connection context manager.
176
+ if "database" not in result:
177
+ # Default to in-memory database
178
+ result["database"] = ":memory:"
130
179
 
131
- Args:
132
- *args: Additional arguments.
133
- **kwargs: Additional keyword arguments.
180
+ # Convert regular :memory: to shared memory for multi-connection access
181
+ if result.get("database") == ":memory:":
182
+ result["database"] = "file::memory:?cache=shared"
183
+ result["uri"] = True
184
+
185
+ for pool_param in ["pool_min_size", "pool_max_size", "pool_timeout", "pool_recycle_seconds"]:
186
+ result.pop(pool_param, None)
187
+
188
+ return result
189
+
190
+ @asynccontextmanager
191
+ async def provide_connection(self) -> "AsyncGenerator[AiosqliteConnection, None]":
192
+ """Provide a database connection.
134
193
 
135
194
  Yields:
136
- An Aiosqlite connection instance.
195
+ AiosqliteConnection: Database connection instance.
137
196
  """
138
- connection = await self.create_connection()
139
- try:
197
+ async with self.pool_instance.get_connection() as connection:
140
198
  yield connection
141
- finally:
142
- await connection.close()
143
199
 
144
200
  @asynccontextmanager
145
- async def provide_session(self, *args: Any, **kwargs: Any) -> AsyncGenerator[AiosqliteDriver, None]:
146
- """Provide an async driver session context manager.
201
+ async def provide_session(
202
+ self, *args: Any, statement_config: "Optional[StatementConfig]" = None, **kwargs: Any
203
+ ) -> "AsyncGenerator[AiosqliteDriver, None]":
204
+ """Provide an async database session.
147
205
 
148
206
  Args:
149
- *args: Additional arguments.
207
+ *args: Additional positional arguments.
208
+ statement_config: Optional statement configuration override.
150
209
  **kwargs: Additional keyword arguments.
151
210
 
152
211
  Yields:
153
- An AiosqliteDriver instance.
212
+ AiosqliteDriver: Database session instance.
154
213
  """
155
- async with self.provide_connection(*args, **kwargs) as connection:
156
- statement_config = self.statement_config
157
- # Inject parameter style info if not already set
158
- if statement_config.allowed_parameter_styles is None:
159
- from dataclasses import replace
160
-
161
- statement_config = replace(
162
- statement_config,
163
- allowed_parameter_styles=self.supported_parameter_styles,
164
- default_parameter_style=self.default_parameter_style,
165
- )
166
- yield self.driver_type(connection=connection, config=statement_config)
167
-
168
- async def provide_pool(self, *args: Any, **kwargs: Any) -> None:
169
- """Aiosqlite doesn't support pooling."""
170
- return
214
+ _ = args, kwargs
215
+ effective_statement_config = statement_config or self.statement_config
216
+ async with self.pool_instance.get_connection() as connection:
217
+ session = self.driver_type(connection, statement_config=effective_statement_config)
218
+ try:
219
+ yield session
220
+ finally:
221
+ pass
222
+
223
+ async def close(self) -> None:
224
+ """Close the connection manager."""
225
+ if self.pool_instance:
226
+ await self.pool_instance.close()
227
+
228
+ def _get_connection_config_dict(self) -> "dict[str, Any]":
229
+ """Get connection configuration dictionary.
171
230
 
172
- def get_signature_namespace(self) -> "dict[str, type[Any]]":
173
- """Get the signature namespace for Aiosqlite types.
231
+ Returns:
232
+ Connection parameters for creating connections.
233
+ """
234
+ return self._connection_parameters.copy()
174
235
 
175
- This provides all Aiosqlite-specific types that Litestar needs to recognize
176
- to avoid serialization attempts.
236
+ async def _create_pool(self) -> "AiosqliteConnectionPool":
237
+ """Create the connection manager instance.
177
238
 
178
239
  Returns:
179
- Dictionary mapping type names to types.
240
+ AiosqliteConnectionPool: The connection manager instance.
180
241
  """
181
- namespace = super().get_signature_namespace()
182
- namespace.update({"AiosqliteConnection": AiosqliteConnection})
183
- return namespace
242
+ if self.pool_instance is None:
243
+ self.pool_instance = AiosqliteConnectionPool(self._connection_parameters)
244
+ return self.pool_instance
245
+
246
+ async def _close_pool(self) -> None:
247
+ """Close the connection manager."""
248
+ if self.pool_instance:
249
+ await self.pool_instance.close()
250
+
251
+ async def close_pool(self) -> None:
252
+ """Close the connection pool (delegates to _close_pool)."""
253
+ await self._close_pool()