sqlspec 0.14.1__py3-none-any.whl → 0.16.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.
- sqlspec/__init__.py +50 -25
- sqlspec/__main__.py +1 -1
- sqlspec/__metadata__.py +1 -3
- sqlspec/_serialization.py +1 -2
- sqlspec/_sql.py +480 -121
- sqlspec/_typing.py +278 -142
- sqlspec/adapters/adbc/__init__.py +4 -3
- sqlspec/adapters/adbc/_types.py +12 -0
- sqlspec/adapters/adbc/config.py +115 -260
- sqlspec/adapters/adbc/driver.py +462 -367
- sqlspec/adapters/aiosqlite/__init__.py +18 -3
- sqlspec/adapters/aiosqlite/_types.py +13 -0
- sqlspec/adapters/aiosqlite/config.py +199 -129
- sqlspec/adapters/aiosqlite/driver.py +230 -269
- sqlspec/adapters/asyncmy/__init__.py +18 -3
- sqlspec/adapters/asyncmy/_types.py +12 -0
- sqlspec/adapters/asyncmy/config.py +80 -168
- sqlspec/adapters/asyncmy/driver.py +260 -225
- sqlspec/adapters/asyncpg/__init__.py +19 -4
- sqlspec/adapters/asyncpg/_types.py +17 -0
- sqlspec/adapters/asyncpg/config.py +82 -181
- sqlspec/adapters/asyncpg/driver.py +285 -383
- sqlspec/adapters/bigquery/__init__.py +17 -3
- sqlspec/adapters/bigquery/_types.py +12 -0
- sqlspec/adapters/bigquery/config.py +191 -258
- sqlspec/adapters/bigquery/driver.py +474 -646
- sqlspec/adapters/duckdb/__init__.py +14 -3
- sqlspec/adapters/duckdb/_types.py +12 -0
- sqlspec/adapters/duckdb/config.py +415 -351
- sqlspec/adapters/duckdb/driver.py +343 -413
- sqlspec/adapters/oracledb/__init__.py +19 -5
- sqlspec/adapters/oracledb/_types.py +14 -0
- sqlspec/adapters/oracledb/config.py +123 -379
- sqlspec/adapters/oracledb/driver.py +507 -560
- sqlspec/adapters/psqlpy/__init__.py +13 -3
- sqlspec/adapters/psqlpy/_types.py +11 -0
- sqlspec/adapters/psqlpy/config.py +93 -254
- sqlspec/adapters/psqlpy/driver.py +505 -234
- sqlspec/adapters/psycopg/__init__.py +19 -5
- sqlspec/adapters/psycopg/_types.py +17 -0
- sqlspec/adapters/psycopg/config.py +143 -403
- sqlspec/adapters/psycopg/driver.py +706 -872
- sqlspec/adapters/sqlite/__init__.py +14 -3
- sqlspec/adapters/sqlite/_types.py +11 -0
- sqlspec/adapters/sqlite/config.py +202 -118
- sqlspec/adapters/sqlite/driver.py +264 -303
- sqlspec/base.py +105 -9
- sqlspec/{statement/builder → builder}/__init__.py +12 -14
- sqlspec/{statement/builder → builder}/_base.py +120 -55
- sqlspec/{statement/builder → builder}/_column.py +17 -6
- sqlspec/{statement/builder → builder}/_ddl.py +46 -79
- sqlspec/{statement/builder → builder}/_ddl_utils.py +5 -10
- sqlspec/{statement/builder → builder}/_delete.py +6 -25
- sqlspec/{statement/builder → builder}/_insert.py +18 -65
- sqlspec/builder/_merge.py +56 -0
- sqlspec/{statement/builder → builder}/_parsing_utils.py +8 -11
- sqlspec/{statement/builder → builder}/_select.py +11 -56
- sqlspec/{statement/builder → builder}/_update.py +12 -18
- sqlspec/{statement/builder → builder}/mixins/__init__.py +10 -14
- sqlspec/{statement/builder → builder}/mixins/_cte_and_set_ops.py +48 -59
- sqlspec/{statement/builder → builder}/mixins/_insert_operations.py +34 -18
- sqlspec/{statement/builder → builder}/mixins/_join_operations.py +1 -3
- sqlspec/{statement/builder → builder}/mixins/_merge_operations.py +19 -9
- sqlspec/{statement/builder → builder}/mixins/_order_limit_operations.py +3 -3
- sqlspec/{statement/builder → builder}/mixins/_pivot_operations.py +4 -8
- sqlspec/{statement/builder → builder}/mixins/_select_operations.py +25 -38
- sqlspec/{statement/builder → builder}/mixins/_update_operations.py +15 -16
- sqlspec/{statement/builder → builder}/mixins/_where_clause.py +210 -137
- sqlspec/cli.py +4 -5
- sqlspec/config.py +180 -133
- sqlspec/core/__init__.py +63 -0
- sqlspec/core/cache.py +873 -0
- sqlspec/core/compiler.py +396 -0
- sqlspec/core/filters.py +830 -0
- sqlspec/core/hashing.py +310 -0
- sqlspec/core/parameters.py +1209 -0
- sqlspec/core/result.py +664 -0
- sqlspec/{statement → core}/splitter.py +321 -191
- sqlspec/core/statement.py +666 -0
- sqlspec/driver/__init__.py +7 -10
- sqlspec/driver/_async.py +387 -176
- sqlspec/driver/_common.py +527 -289
- sqlspec/driver/_sync.py +390 -172
- sqlspec/driver/mixins/__init__.py +2 -19
- sqlspec/driver/mixins/_result_tools.py +164 -0
- sqlspec/driver/mixins/_sql_translator.py +6 -3
- sqlspec/exceptions.py +5 -252
- sqlspec/extensions/aiosql/adapter.py +93 -96
- sqlspec/extensions/litestar/cli.py +1 -1
- sqlspec/extensions/litestar/config.py +0 -1
- sqlspec/extensions/litestar/handlers.py +15 -26
- sqlspec/extensions/litestar/plugin.py +18 -16
- sqlspec/extensions/litestar/providers.py +17 -52
- sqlspec/loader.py +424 -105
- sqlspec/migrations/__init__.py +12 -0
- sqlspec/migrations/base.py +92 -68
- sqlspec/migrations/commands.py +24 -106
- sqlspec/migrations/loaders.py +402 -0
- sqlspec/migrations/runner.py +49 -51
- sqlspec/migrations/tracker.py +31 -44
- sqlspec/migrations/utils.py +64 -24
- sqlspec/protocols.py +7 -183
- sqlspec/storage/__init__.py +1 -1
- sqlspec/storage/backends/base.py +37 -40
- sqlspec/storage/backends/fsspec.py +136 -112
- sqlspec/storage/backends/obstore.py +138 -160
- sqlspec/storage/capabilities.py +5 -4
- sqlspec/storage/registry.py +57 -106
- sqlspec/typing.py +136 -115
- sqlspec/utils/__init__.py +2 -3
- sqlspec/utils/correlation.py +0 -3
- sqlspec/utils/deprecation.py +6 -6
- sqlspec/utils/fixtures.py +6 -6
- sqlspec/utils/logging.py +0 -2
- sqlspec/utils/module_loader.py +7 -12
- sqlspec/utils/singleton.py +0 -1
- sqlspec/utils/sync_tools.py +17 -38
- sqlspec/utils/text.py +12 -51
- sqlspec/utils/type_guards.py +443 -232
- {sqlspec-0.14.1.dist-info → sqlspec-0.16.0.dist-info}/METADATA +7 -2
- sqlspec-0.16.0.dist-info/RECORD +134 -0
- sqlspec/adapters/adbc/transformers.py +0 -108
- sqlspec/driver/connection.py +0 -207
- sqlspec/driver/mixins/_cache.py +0 -114
- sqlspec/driver/mixins/_csv_writer.py +0 -91
- sqlspec/driver/mixins/_pipeline.py +0 -508
- sqlspec/driver/mixins/_query_tools.py +0 -796
- sqlspec/driver/mixins/_result_utils.py +0 -138
- sqlspec/driver/mixins/_storage.py +0 -912
- sqlspec/driver/mixins/_type_coercion.py +0 -128
- sqlspec/driver/parameters.py +0 -138
- sqlspec/statement/__init__.py +0 -21
- sqlspec/statement/builder/_merge.py +0 -95
- sqlspec/statement/cache.py +0 -50
- sqlspec/statement/filters.py +0 -625
- sqlspec/statement/parameters.py +0 -956
- sqlspec/statement/pipelines/__init__.py +0 -210
- sqlspec/statement/pipelines/analyzers/__init__.py +0 -9
- sqlspec/statement/pipelines/analyzers/_analyzer.py +0 -646
- sqlspec/statement/pipelines/context.py +0 -109
- sqlspec/statement/pipelines/transformers/__init__.py +0 -7
- sqlspec/statement/pipelines/transformers/_expression_simplifier.py +0 -88
- sqlspec/statement/pipelines/transformers/_literal_parameterizer.py +0 -1247
- sqlspec/statement/pipelines/transformers/_remove_comments_and_hints.py +0 -76
- sqlspec/statement/pipelines/validators/__init__.py +0 -23
- sqlspec/statement/pipelines/validators/_dml_safety.py +0 -290
- sqlspec/statement/pipelines/validators/_parameter_style.py +0 -370
- sqlspec/statement/pipelines/validators/_performance.py +0 -714
- sqlspec/statement/pipelines/validators/_security.py +0 -967
- sqlspec/statement/result.py +0 -435
- sqlspec/statement/sql.py +0 -1774
- sqlspec/utils/cached_property.py +0 -25
- sqlspec/utils/statement_hashing.py +0 -203
- sqlspec-0.14.1.dist-info/RECORD +0 -145
- /sqlspec/{statement/builder → builder}/mixins/_delete_operations.py +0 -0
- {sqlspec-0.14.1.dist-info → sqlspec-0.16.0.dist-info}/WHEEL +0 -0
- {sqlspec-0.14.1.dist-info → sqlspec-0.16.0.dist-info}/entry_points.txt +0 -0
- {sqlspec-0.14.1.dist-info → sqlspec-0.16.0.dist-info}/licenses/LICENSE +0 -0
- {sqlspec-0.14.1.dist-info → sqlspec-0.16.0.dist-info}/licenses/NOTICE +0 -0
|
@@ -1,4 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
from sqlspec.adapters.sqlite.driver import SqliteConnection, SqliteDriver
|
|
1
|
+
"""SQLite adapter for SQLSpec."""
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
from sqlspec.adapters.sqlite._types import SqliteConnection
|
|
4
|
+
from sqlspec.adapters.sqlite.config import SqliteConfig, SqliteConnectionParams
|
|
5
|
+
from sqlspec.adapters.sqlite.driver import SqliteCursor, SqliteDriver, SqliteExceptionHandler, sqlite_statement_config
|
|
6
|
+
|
|
7
|
+
__all__ = (
|
|
8
|
+
"SqliteConfig",
|
|
9
|
+
"SqliteConnection",
|
|
10
|
+
"SqliteConnectionParams",
|
|
11
|
+
"SqliteCursor",
|
|
12
|
+
"SqliteDriver",
|
|
13
|
+
"SqliteExceptionHandler",
|
|
14
|
+
"sqlite_statement_config",
|
|
15
|
+
)
|
|
@@ -1,156 +1,240 @@
|
|
|
1
|
-
"""SQLite database configuration with
|
|
1
|
+
"""SQLite database configuration with thread-local connections."""
|
|
2
2
|
|
|
3
|
-
import logging
|
|
4
3
|
import sqlite3
|
|
4
|
+
import threading
|
|
5
5
|
from contextlib import contextmanager
|
|
6
|
-
from typing import TYPE_CHECKING, Any, ClassVar, Optional, Union
|
|
6
|
+
from typing import TYPE_CHECKING, Any, ClassVar, Optional, TypedDict, Union, cast
|
|
7
7
|
|
|
8
|
-
from
|
|
9
|
-
|
|
10
|
-
from sqlspec.
|
|
11
|
-
from sqlspec.
|
|
8
|
+
from typing_extensions import NotRequired
|
|
9
|
+
|
|
10
|
+
from sqlspec.adapters.sqlite._types import SqliteConnection
|
|
11
|
+
from sqlspec.adapters.sqlite.driver import SqliteCursor, SqliteDriver, sqlite_statement_config
|
|
12
|
+
from sqlspec.config import SyncDatabaseConfig
|
|
12
13
|
|
|
13
14
|
if TYPE_CHECKING:
|
|
14
15
|
from collections.abc import Generator
|
|
15
16
|
|
|
17
|
+
from sqlspec.core.statement import StatementConfig
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class SqliteConnectionParams(TypedDict, total=False):
|
|
21
|
+
"""SQLite connection parameters."""
|
|
22
|
+
|
|
23
|
+
database: NotRequired[str]
|
|
24
|
+
timeout: NotRequired[float]
|
|
25
|
+
detect_types: NotRequired[int]
|
|
26
|
+
isolation_level: "NotRequired[Optional[str]]"
|
|
27
|
+
check_same_thread: NotRequired[bool]
|
|
28
|
+
factory: "NotRequired[Optional[type[SqliteConnection]]]"
|
|
29
|
+
cached_statements: NotRequired[int]
|
|
30
|
+
uri: NotRequired[bool]
|
|
16
31
|
|
|
17
|
-
logger = logging.getLogger(__name__)
|
|
18
32
|
|
|
19
|
-
|
|
20
|
-
{
|
|
21
|
-
"database",
|
|
22
|
-
"timeout",
|
|
23
|
-
"detect_types",
|
|
24
|
-
"isolation_level",
|
|
25
|
-
"check_same_thread",
|
|
26
|
-
"factory",
|
|
27
|
-
"cached_statements",
|
|
28
|
-
"uri",
|
|
29
|
-
}
|
|
30
|
-
)
|
|
33
|
+
__all__ = ("SqliteConfig", "SqliteConnectionParams", "SqliteConnectionPool")
|
|
31
34
|
|
|
32
|
-
__all__ = ("CONNECTION_FIELDS", "SqliteConfig", "sqlite3")
|
|
33
35
|
|
|
36
|
+
class SqliteConnectionPool:
|
|
37
|
+
"""Thread-local connection manager for SQLite.
|
|
34
38
|
|
|
35
|
-
|
|
36
|
-
|
|
39
|
+
SQLite connections aren't thread-safe, so we use thread-local storage
|
|
40
|
+
to ensure each thread has its own connection. This is simpler and more
|
|
41
|
+
efficient than a traditional pool for SQLite's constraints.
|
|
42
|
+
"""
|
|
37
43
|
|
|
38
|
-
|
|
39
|
-
connection_type: type[SqliteConnection] = SqliteConnection
|
|
40
|
-
supported_parameter_styles: ClassVar[tuple[str, ...]] = ("qmark", "named_colon")
|
|
41
|
-
default_parameter_style: ClassVar[str] = "qmark"
|
|
44
|
+
__slots__ = ("_connection_parameters", "_enable_optimizations", "_thread_local")
|
|
42
45
|
|
|
43
46
|
def __init__(
|
|
44
47
|
self,
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
48
|
+
connection_parameters: "dict[str, Any]",
|
|
49
|
+
enable_optimizations: bool = True,
|
|
50
|
+
**kwargs: Any, # Accept and ignore pool parameters for compatibility
|
|
51
|
+
) -> None:
|
|
52
|
+
"""Initialize the thread-local connection manager.
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
connection_parameters: SQLite connection parameters
|
|
56
|
+
enable_optimizations: Whether to apply performance PRAGMAs
|
|
57
|
+
**kwargs: Ignored pool parameters for compatibility
|
|
58
|
+
"""
|
|
59
|
+
self._connection_parameters = connection_parameters
|
|
60
|
+
self._thread_local = threading.local()
|
|
61
|
+
self._enable_optimizations = enable_optimizations
|
|
62
|
+
|
|
63
|
+
def _create_connection(self) -> SqliteConnection:
|
|
64
|
+
"""Create a new SQLite connection with optimizations."""
|
|
65
|
+
connection = sqlite3.connect(**self._connection_parameters)
|
|
66
|
+
|
|
67
|
+
# Only apply optimizations if requested and not in-memory
|
|
68
|
+
if self._enable_optimizations:
|
|
69
|
+
database = self._connection_parameters.get("database", ":memory:")
|
|
70
|
+
is_memory = database == ":memory:" or database.startswith("file::memory:")
|
|
71
|
+
|
|
72
|
+
if not is_memory:
|
|
73
|
+
# WAL mode doesn't work with in-memory databases
|
|
74
|
+
connection.execute("PRAGMA journal_mode = WAL")
|
|
75
|
+
# Set busy timeout for better concurrent access
|
|
76
|
+
connection.execute("PRAGMA busy_timeout = 5000")
|
|
77
|
+
connection.execute("PRAGMA optimize")
|
|
78
|
+
# These work for all database types
|
|
79
|
+
connection.execute("PRAGMA foreign_keys = ON")
|
|
80
|
+
connection.execute("PRAGMA synchronous = NORMAL")
|
|
81
|
+
|
|
82
|
+
return connection # type: ignore[no-any-return]
|
|
83
|
+
|
|
84
|
+
def _get_thread_connection(self) -> SqliteConnection:
|
|
85
|
+
"""Get or create a connection for the current thread."""
|
|
86
|
+
try:
|
|
87
|
+
return cast("SqliteConnection", self._thread_local.connection)
|
|
88
|
+
except AttributeError:
|
|
89
|
+
# Connection doesn't exist for this thread yet
|
|
90
|
+
connection = self._create_connection()
|
|
91
|
+
self._thread_local.connection = connection
|
|
92
|
+
return connection
|
|
93
|
+
|
|
94
|
+
def _close_thread_connection(self) -> None:
|
|
95
|
+
"""Close the connection for the current thread."""
|
|
96
|
+
try:
|
|
97
|
+
connection = self._thread_local.connection
|
|
98
|
+
connection.close()
|
|
99
|
+
del self._thread_local.connection
|
|
100
|
+
except AttributeError:
|
|
101
|
+
# No connection for this thread
|
|
102
|
+
pass
|
|
103
|
+
|
|
104
|
+
@contextmanager
|
|
105
|
+
def get_connection(self) -> "Generator[SqliteConnection, None, None]":
|
|
106
|
+
"""Get a thread-local connection.
|
|
107
|
+
|
|
108
|
+
Yields:
|
|
109
|
+
SqliteConnection: A thread-local connection.
|
|
110
|
+
"""
|
|
111
|
+
yield self._get_thread_connection()
|
|
112
|
+
|
|
113
|
+
def close(self) -> None:
|
|
114
|
+
"""Close the thread-local connection if it exists."""
|
|
115
|
+
self._close_thread_connection()
|
|
116
|
+
|
|
117
|
+
def acquire(self) -> SqliteConnection:
|
|
118
|
+
"""Acquire a thread-local connection.
|
|
119
|
+
|
|
120
|
+
Returns:
|
|
121
|
+
SqliteConnection: A thread-local connection
|
|
122
|
+
"""
|
|
123
|
+
return self._get_thread_connection()
|
|
124
|
+
|
|
125
|
+
def release(self, connection: SqliteConnection) -> None:
|
|
126
|
+
"""Release a connection (no-op for thread-local connections).
|
|
127
|
+
|
|
128
|
+
Args:
|
|
129
|
+
connection: The connection to release (ignored)
|
|
130
|
+
"""
|
|
131
|
+
# No-op: thread-local connections are managed per-thread
|
|
132
|
+
|
|
133
|
+
# Compatibility methods that return dummy values
|
|
134
|
+
def size(self) -> int:
|
|
135
|
+
"""Get pool size (always 1 for thread-local)."""
|
|
136
|
+
try:
|
|
137
|
+
_ = self._thread_local.connection
|
|
138
|
+
except AttributeError:
|
|
139
|
+
return 0
|
|
140
|
+
return 1
|
|
141
|
+
|
|
142
|
+
def checked_out(self) -> int:
|
|
143
|
+
"""Get number of checked out connections (always 0)."""
|
|
144
|
+
return 0
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
class SqliteConfig(SyncDatabaseConfig[SqliteConnection, SqliteConnectionPool, SqliteDriver]):
|
|
148
|
+
"""SQLite configuration with thread-local connections."""
|
|
149
|
+
|
|
150
|
+
driver_type: "ClassVar[type[SqliteDriver]]" = SqliteDriver
|
|
151
|
+
connection_type: "ClassVar[type[SqliteConnection]]" = SqliteConnection
|
|
152
|
+
|
|
153
|
+
def __init__(
|
|
154
|
+
self,
|
|
155
|
+
*,
|
|
156
|
+
pool_config: "Optional[Union[SqliteConnectionParams, dict[str, Any]]]" = None,
|
|
157
|
+
pool_instance: "Optional[SqliteConnectionPool]" = None,
|
|
158
|
+
statement_config: "Optional[StatementConfig]" = None,
|
|
159
|
+
migration_config: "Optional[dict[str, Any]]" = None,
|
|
57
160
|
) -> None:
|
|
58
161
|
"""Initialize SQLite configuration.
|
|
59
162
|
|
|
60
163
|
Args:
|
|
61
|
-
|
|
164
|
+
pool_config: Configuration parameters including connection settings
|
|
165
|
+
pool_instance: Pre-created pool instance
|
|
62
166
|
statement_config: Default SQL statement configuration
|
|
63
|
-
|
|
64
|
-
timeout: Connection timeout in seconds
|
|
65
|
-
detect_types: Type detection flags (sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES)
|
|
66
|
-
isolation_level: Transaction isolation level
|
|
67
|
-
check_same_thread: Whether to check that connection is used on same thread
|
|
68
|
-
factory: Custom Connection class factory
|
|
69
|
-
cached_statements: Number of statements to cache
|
|
70
|
-
uri: Whether to interpret database as URI
|
|
71
|
-
**kwargs: Additional parameters (stored in extras)
|
|
167
|
+
migration_config: Migration configuration
|
|
72
168
|
"""
|
|
73
|
-
if
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
#
|
|
90
|
-
|
|
91
|
-
self.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
"factory": self.factory,
|
|
104
|
-
"cached_statements": self.cached_statements,
|
|
105
|
-
"uri": self.uri,
|
|
106
|
-
}
|
|
107
|
-
# Filter out None values since sqlite3.connect doesn't accept them
|
|
108
|
-
return {k: v for k, v in config.items() if v is not None}
|
|
169
|
+
if pool_config is None:
|
|
170
|
+
pool_config = {}
|
|
171
|
+
if "database" not in pool_config or pool_config["database"] == ":memory:":
|
|
172
|
+
pool_config["database"] = "file::memory:?cache=shared"
|
|
173
|
+
pool_config["uri"] = True
|
|
174
|
+
|
|
175
|
+
super().__init__(
|
|
176
|
+
pool_instance=pool_instance,
|
|
177
|
+
pool_config=cast("dict[str, Any]", pool_config),
|
|
178
|
+
migration_config=migration_config,
|
|
179
|
+
statement_config=statement_config or sqlite_statement_config,
|
|
180
|
+
driver_features={},
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
def _get_connection_config_dict(self) -> "dict[str, Any]":
|
|
184
|
+
"""Get connection configuration as plain dict for pool creation."""
|
|
185
|
+
# Filter out pool-specific parameters that SQLite doesn't use
|
|
186
|
+
excluded_keys = {"pool_min_size", "pool_max_size", "pool_timeout", "pool_recycle_seconds", "extra"}
|
|
187
|
+
return {k: v for k, v in self.pool_config.items() if v is not None and k not in excluded_keys}
|
|
188
|
+
|
|
189
|
+
def _create_pool(self) -> SqliteConnectionPool:
|
|
190
|
+
"""Create connection pool from configuration."""
|
|
191
|
+
config_dict = self._get_connection_config_dict()
|
|
192
|
+
# Pass all pool_config as kwargs to be ignored by the pool
|
|
193
|
+
return SqliteConnectionPool(connection_parameters=config_dict, **self.pool_config)
|
|
194
|
+
|
|
195
|
+
def _close_pool(self) -> None:
|
|
196
|
+
"""Close the connection pool."""
|
|
197
|
+
if self.pool_instance:
|
|
198
|
+
self.pool_instance.close()
|
|
109
199
|
|
|
110
200
|
def create_connection(self) -> SqliteConnection:
|
|
111
|
-
"""
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
201
|
+
"""Get a SQLite connection from the pool.
|
|
202
|
+
|
|
203
|
+
Returns:
|
|
204
|
+
SqliteConnection: A connection from the pool
|
|
205
|
+
"""
|
|
206
|
+
pool = self.provide_pool()
|
|
207
|
+
return pool.acquire()
|
|
115
208
|
|
|
116
209
|
@contextmanager
|
|
117
|
-
def provide_connection(self, *args: Any, **kwargs: Any) -> "Generator[SqliteConnection, None, None]":
|
|
210
|
+
def provide_connection(self, *args: "Any", **kwargs: "Any") -> "Generator[SqliteConnection, None, None]":
|
|
118
211
|
"""Provide a SQLite connection context manager.
|
|
119
212
|
|
|
120
|
-
Args:
|
|
121
|
-
*args: Variable length argument list
|
|
122
|
-
**kwargs: Arbitrary keyword arguments
|
|
123
|
-
|
|
124
213
|
Yields:
|
|
125
|
-
SqliteConnection: A
|
|
126
|
-
|
|
214
|
+
SqliteConnection: A thread-local connection
|
|
127
215
|
"""
|
|
128
|
-
|
|
129
|
-
|
|
216
|
+
pool = self.provide_pool()
|
|
217
|
+
with pool.get_connection() as connection:
|
|
130
218
|
yield connection
|
|
131
|
-
finally:
|
|
132
|
-
connection.close()
|
|
133
219
|
|
|
134
220
|
@contextmanager
|
|
135
|
-
def provide_session(
|
|
136
|
-
""
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
*args: Variable length argument list
|
|
140
|
-
**kwargs: Arbitrary keyword arguments
|
|
221
|
+
def provide_session(
|
|
222
|
+
self, *args: "Any", statement_config: "Optional[StatementConfig]" = None, **kwargs: "Any"
|
|
223
|
+
) -> "Generator[SqliteDriver, None, None]":
|
|
224
|
+
"""Provide a SQLite driver session.
|
|
141
225
|
|
|
142
226
|
Yields:
|
|
143
|
-
SqliteDriver: A
|
|
227
|
+
SqliteDriver: A driver instance with thread-local connection
|
|
144
228
|
"""
|
|
145
229
|
with self.provide_connection(*args, **kwargs) as connection:
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
230
|
+
yield self.driver_type(connection=connection, statement_config=statement_config or self.statement_config)
|
|
231
|
+
|
|
232
|
+
def get_signature_namespace(self) -> "dict[str, type[Any]]":
|
|
233
|
+
"""Get the signature namespace for SQLite types.
|
|
234
|
+
|
|
235
|
+
Returns:
|
|
236
|
+
Dictionary mapping type names to types.
|
|
237
|
+
"""
|
|
238
|
+
namespace = super().get_signature_namespace()
|
|
239
|
+
namespace.update({"SqliteConnection": SqliteConnection, "SqliteCursor": SqliteCursor})
|
|
240
|
+
return namespace
|