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
@@ -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,201 +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
 
19
- from sqlglot.dialects.dialect import DialectType
17
+ from sqlspec.adapters.aiosqlite._types import AiosqliteConnection
18
+ from sqlspec.core.statement import StatementConfig
20
19
 
21
-
22
- __all__ = ("CONNECTION_FIELDS", "AiosqliteConfig")
20
+ __all__ = ("AiosqliteConfig", "AiosqliteConnectionParams", "AiosqliteConnectionPool")
23
21
 
24
22
  logger = logging.getLogger(__name__)
25
23
 
26
- CONNECTION_FIELDS = frozenset(
27
- {"database", "timeout", "detect_types", "isolation_level", "check_same_thread", "cached_statements", "uri"}
28
- )
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
29
29
 
30
30
 
31
- class AiosqliteConfig(AsyncDatabaseConfig[AiosqliteConnection, None, AiosqliteDriver]):
32
- """Configuration for Aiosqlite database connections with direct field-based configuration.
31
+ class AiosqliteConnectionPool:
32
+ """Connection pool for Aiosqlite using a single shared connection approach.
33
33
 
34
- 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.
35
36
  """
36
37
 
37
- __slots__ = (
38
- "_dialect",
39
- "cached_statements",
40
- "check_same_thread",
41
- "database",
42
- "default_row_type",
43
- "detect_types",
44
- "extras",
45
- "isolation_level",
46
- "pool_instance",
47
- "statement_config",
48
- "timeout",
49
- "uri",
50
- )
51
-
52
- is_async: ClassVar[bool] = True
53
- supports_connection_pooling: ClassVar[bool] = False
54
-
55
- driver_type: type[AiosqliteDriver] = AiosqliteDriver
56
- connection_type: type[AiosqliteConnection] = AiosqliteConnection
57
-
58
- # Parameter style support information
59
- supported_parameter_styles: ClassVar[tuple[str, ...]] = ("qmark", "named_colon")
60
- """AIOSQLite supports ? (qmark) and :name (named_colon) parameter styles."""
61
-
62
- preferred_parameter_style: ClassVar[str] = "qmark"
63
- """AIOSQLite's native parameter style is ? (qmark)."""
38
+ __slots__ = ("_closed", "_connection", "_connection_parameters", "_lock")
39
+
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
110
+
111
+
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
64
129
 
65
130
  def __init__(
66
131
  self,
67
- database: str = ":memory:",
68
- statement_config: Optional[SQLConfig] = None,
69
- default_row_type: type[DictRow] = DictRow,
70
- # Connection parameters
71
- timeout: Optional[float] = None,
72
- detect_types: Optional[int] = None,
73
- isolation_level: Optional["Optional[Literal['DEFERRED', 'IMMEDIATE', 'EXCLUSIVE']]"] = None,
74
- check_same_thread: Optional[bool] = None,
75
- cached_statements: Optional[int] = None,
76
- 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,
77
137
  **kwargs: Any,
78
138
  ) -> None:
79
- """Initialize Aiosqlite configuration.
139
+ """Initialize AioSQLite configuration.
80
140
 
81
141
  Args:
82
- database: The path to the database file to be opened. Pass ":memory:" for in-memory database
83
- statement_config: Default SQL statement configuration
84
- default_row_type: Default row type for results
85
- timeout: How many seconds the connection should wait before raising an OperationalError when a table is locked
86
- detect_types: Control whether and how data types are detected. It can be 0 (default) or a combination of PARSE_DECLTYPES and PARSE_COLNAMES
87
- isolation_level: The isolation_level of the connection. This can be None for autocommit mode or one of "DEFERRED", "IMMEDIATE" or "EXCLUSIVE"
88
- 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
89
- cached_statements: The number of statements that SQLite will cache for this connection. The default is 128
90
- uri: If set to True, database is interpreted as a URI with supported options
91
- **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.
92
147
  """
93
- # Store connection parameters as instance attributes
94
- self.database = database
95
- self.timeout = timeout
96
- self.detect_types = detect_types
97
- self.isolation_level = isolation_level
98
- self.check_same_thread = check_same_thread
99
- self.cached_statements = cached_statements
100
- self.uri = uri
101
- self.extras = kwargs or {}
102
- # Store other config
103
- self.statement_config = statement_config or SQLConfig()
104
- self.default_row_type = default_row_type
105
- self._dialect: DialectType = None
106
-
107
- super().__init__()
108
-
109
- @property
110
- def connection_config_dict(self) -> dict[str, Any]:
111
- """Return the connection configuration as a dict for aiosqlite.connect()."""
112
- # Gather non-None connection parameters
113
- config = {
114
- field: getattr(self, field)
115
- for field in CONNECTION_FIELDS
116
- if getattr(self, field, None) is not None and getattr(self, field) is not Empty
117
- }
118
-
119
- # Merge extras parameters
120
- config.update(self.extras)
121
-
122
- return config
123
-
124
- async def _create_pool(self) -> None:
125
- """Aiosqlite doesn't support pooling."""
126
- return
148
+ connection_params = {}
149
+ if pool_config:
150
+ connection_params.update(pool_config)
151
+ connection_params.update(kwargs)
127
152
 
128
- async def _close_pool(self) -> None:
129
- """Aiosqlite doesn't support pooling."""
130
- 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
+ )
131
159
 
132
- async def create_connection(self) -> AiosqliteConnection:
133
- """Create a single async connection.
160
+ self._connection_parameters = self._parse_connection_parameters(connection_params)
161
+
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.
134
170
 
135
171
  Returns:
136
- An Aiosqlite connection instance.
172
+ Processed connection parameters dict.
137
173
  """
138
- try:
139
- config = self.connection_config_dict
140
- return await aiosqlite.connect(**config)
141
- except Exception as e:
142
- msg = f"Could not configure the Aiosqlite connection. Error: {e!s}"
143
- raise ImproperConfigurationError(msg) from e
174
+ result = params.copy()
144
175
 
145
- @asynccontextmanager
146
- async def provide_connection(self, *args: Any, **kwargs: Any) -> AsyncGenerator[AiosqliteConnection, None]:
147
- """Provide an async connection context manager.
176
+ if "database" not in result:
177
+ # Default to in-memory database
178
+ result["database"] = ":memory:"
148
179
 
149
- Args:
150
- *args: Additional arguments.
151
- **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.
152
193
 
153
194
  Yields:
154
- An Aiosqlite connection instance.
195
+ AiosqliteConnection: Database connection instance.
155
196
  """
156
- connection = await self.create_connection()
157
- try:
197
+ async with self.pool_instance.get_connection() as connection:
158
198
  yield connection
159
- finally:
160
- await connection.close()
161
199
 
162
200
  @asynccontextmanager
163
- async def provide_session(self, *args: Any, **kwargs: Any) -> AsyncGenerator[AiosqliteDriver, None]:
164
- """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.
165
205
 
166
206
  Args:
167
- *args: Additional arguments.
207
+ *args: Additional positional arguments.
208
+ statement_config: Optional statement configuration override.
168
209
  **kwargs: Additional keyword arguments.
169
210
 
170
211
  Yields:
171
- An AiosqliteDriver instance.
212
+ AiosqliteDriver: Database session instance.
172
213
  """
173
- async with self.provide_connection(*args, **kwargs) as connection:
174
- statement_config = self.statement_config
175
- # Inject parameter style info if not already set
176
- if statement_config.allowed_parameter_styles is None:
177
- from dataclasses import replace
178
-
179
- statement_config = replace(
180
- statement_config,
181
- allowed_parameter_styles=self.supported_parameter_styles,
182
- target_parameter_style=self.preferred_parameter_style,
183
- )
184
- yield self.driver_type(connection=connection, config=statement_config)
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.
185
230
 
186
- async def provide_pool(self, *args: Any, **kwargs: Any) -> None:
187
- """Aiosqlite doesn't support pooling."""
188
- return
189
-
190
- def get_signature_namespace(self) -> "dict[str, type[Any]]":
191
- """Get the signature namespace for Aiosqlite types.
231
+ Returns:
232
+ Connection parameters for creating connections.
233
+ """
234
+ return self._connection_parameters.copy()
192
235
 
193
- This provides all Aiosqlite-specific types that Litestar needs to recognize
194
- to avoid serialization attempts.
236
+ async def _create_pool(self) -> "AiosqliteConnectionPool":
237
+ """Create the connection manager instance.
195
238
 
196
239
  Returns:
197
- Dictionary mapping type names to types.
240
+ AiosqliteConnectionPool: The connection manager instance.
198
241
  """
199
- namespace = super().get_signature_namespace()
200
- namespace.update({"AiosqliteConnection": AiosqliteConnection})
201
- 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()