sqlspec 0.16.1__cp310-cp310-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-310-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-310-aarch64-linux-gnu.so +0 -0
  76. sqlspec/core/cache.py +871 -0
  77. sqlspec/core/compiler.cpython-310-aarch64-linux-gnu.so +0 -0
  78. sqlspec/core/compiler.py +417 -0
  79. sqlspec/core/filters.cpython-310-aarch64-linux-gnu.so +0 -0
  80. sqlspec/core/filters.py +830 -0
  81. sqlspec/core/hashing.cpython-310-aarch64-linux-gnu.so +0 -0
  82. sqlspec/core/hashing.py +310 -0
  83. sqlspec/core/parameters.cpython-310-aarch64-linux-gnu.so +0 -0
  84. sqlspec/core/parameters.py +1237 -0
  85. sqlspec/core/result.cpython-310-aarch64-linux-gnu.so +0 -0
  86. sqlspec/core/result.py +677 -0
  87. sqlspec/core/splitter.cpython-310-aarch64-linux-gnu.so +0 -0
  88. sqlspec/core/splitter.py +819 -0
  89. sqlspec/core/statement.cpython-310-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-310-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-310-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-310-aarch64-linux-gnu.so +0 -0
  138. sqlspec/utils/sync_tools.py +237 -0
  139. sqlspec/utils/text.cpython-310-aarch64-linux-gnu.so +0 -0
  140. sqlspec/utils/text.py +96 -0
  141. sqlspec/utils/type_guards.cpython-310-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/cli.py ADDED
@@ -0,0 +1,247 @@
1
+ import sys
2
+ from collections.abc import Sequence
3
+ from typing import TYPE_CHECKING, Any, Optional, Union, cast
4
+
5
+ if TYPE_CHECKING:
6
+ from click import Group
7
+
8
+ from sqlspec.config import AsyncDatabaseConfig, SyncDatabaseConfig
9
+
10
+ __all__ = ("add_migration_commands", "get_sqlspec_group")
11
+
12
+
13
+ def get_sqlspec_group() -> "Group":
14
+ """Get the SQLSpec CLI group.
15
+
16
+ Raises:
17
+ MissingDependencyError: If the `click` package is not installed.
18
+
19
+ Returns:
20
+ The SQLSpec CLI group.
21
+ """
22
+ from sqlspec.exceptions import MissingDependencyError
23
+
24
+ try:
25
+ import rich_click as click
26
+ except ImportError:
27
+ try:
28
+ import click # type: ignore[no-redef]
29
+ except ImportError as e:
30
+ raise MissingDependencyError(package="click", install_package="cli") from e
31
+
32
+ @click.group(name="sqlspec")
33
+ @click.option(
34
+ "--config",
35
+ help="Dotted path to SQLSpec config(s) (e.g. 'myapp.config.sqlspec_configs')",
36
+ required=True,
37
+ type=str,
38
+ )
39
+ @click.pass_context
40
+ def sqlspec_group(ctx: "click.Context", config: str) -> None:
41
+ """SQLSpec CLI commands."""
42
+ from rich import get_console
43
+
44
+ from sqlspec.utils import module_loader
45
+
46
+ console = get_console()
47
+ ctx.ensure_object(dict)
48
+ try:
49
+ config_instance = module_loader.import_string(config)
50
+ if isinstance(config_instance, Sequence):
51
+ ctx.obj["configs"] = config_instance
52
+ else:
53
+ ctx.obj["configs"] = [config_instance]
54
+ except ImportError as e:
55
+ console.print(f"[red]Error loading config: {e}[/]")
56
+ ctx.exit(1)
57
+
58
+ return sqlspec_group
59
+
60
+
61
+ def add_migration_commands(database_group: Optional["Group"] = None) -> "Group":
62
+ """Add migration commands to the database group.
63
+
64
+ Args:
65
+ database_group: The database group to add the commands to.
66
+
67
+ Raises:
68
+ MissingDependencyError: If the `click` package is not installed.
69
+
70
+ Returns:
71
+ The database group with the migration commands added.
72
+ """
73
+ from sqlspec.exceptions import MissingDependencyError
74
+
75
+ try:
76
+ import rich_click as click
77
+ except ImportError:
78
+ try:
79
+ import click # type: ignore[no-redef]
80
+ except ImportError as e:
81
+ raise MissingDependencyError(package="click", install_package="cli") from e
82
+ from rich import get_console
83
+
84
+ console = get_console()
85
+
86
+ if database_group is None:
87
+ database_group = get_sqlspec_group()
88
+
89
+ bind_key_option = click.option(
90
+ "--bind-key", help="Specify which SQLSpec config to use by bind key", type=str, default=None
91
+ )
92
+ verbose_option = click.option("--verbose", help="Enable verbose output.", type=bool, default=False, is_flag=True)
93
+ no_prompt_option = click.option(
94
+ "--no-prompt",
95
+ help="Do not prompt for confirmation before executing the command.",
96
+ type=bool,
97
+ default=False,
98
+ required=False,
99
+ show_default=True,
100
+ is_flag=True,
101
+ )
102
+
103
+ def get_config_by_bind_key(
104
+ ctx: "click.Context", bind_key: Optional[str]
105
+ ) -> "Union[AsyncDatabaseConfig[Any, Any, Any], SyncDatabaseConfig[Any, Any, Any]]":
106
+ """Get the SQLSpec config for the specified bind key.
107
+
108
+ Args:
109
+ ctx: The click context.
110
+ bind_key: The bind key to get the config for.
111
+
112
+ Returns:
113
+ The SQLSpec config for the specified bind key.
114
+ """
115
+ configs = ctx.obj["configs"]
116
+ if bind_key is None:
117
+ return cast("Union[AsyncDatabaseConfig[Any, Any, Any], SyncDatabaseConfig[Any, Any, Any]]", configs[0])
118
+
119
+ for config in configs:
120
+ config_name = getattr(config, "name", None) or getattr(config, "bind_key", None)
121
+ if config_name == bind_key:
122
+ return cast("Union[AsyncDatabaseConfig[Any, Any, Any], SyncDatabaseConfig[Any, Any, Any]]", config)
123
+
124
+ console.print(f"[red]No config found for bind key: {bind_key}[/]")
125
+ sys.exit(1)
126
+
127
+ @database_group.command(name="show-current-revision", help="Shows the current revision for the database.")
128
+ @bind_key_option
129
+ @verbose_option
130
+ def show_database_revision(bind_key: Optional[str], verbose: bool) -> None: # pyright: ignore[reportUnusedFunction]
131
+ """Show current database revision."""
132
+ from sqlspec.migrations.commands import MigrationCommands
133
+
134
+ ctx = click.get_current_context()
135
+ console.rule("[yellow]Listing current revision[/]", align="left")
136
+ sqlspec_config = get_config_by_bind_key(ctx, bind_key)
137
+ migration_commands = MigrationCommands(config=sqlspec_config)
138
+ migration_commands.current(verbose=verbose)
139
+
140
+ @database_group.command(name="downgrade", help="Downgrade database to a specific revision.")
141
+ @bind_key_option
142
+ @no_prompt_option
143
+ @click.argument("revision", type=str, default="-1")
144
+ def downgrade_database( # pyright: ignore[reportUnusedFunction]
145
+ bind_key: Optional[str], revision: str, no_prompt: bool
146
+ ) -> None:
147
+ """Downgrade the database to the latest revision."""
148
+ from rich.prompt import Confirm
149
+
150
+ from sqlspec.migrations.commands import MigrationCommands
151
+
152
+ ctx = click.get_current_context()
153
+ console.rule("[yellow]Starting database downgrade process[/]", align="left")
154
+ input_confirmed = (
155
+ True
156
+ if no_prompt
157
+ else Confirm.ask(f"Are you sure you want to downgrade the database to the `{revision}` revision?")
158
+ )
159
+ if input_confirmed:
160
+ sqlspec_config = get_config_by_bind_key(ctx, bind_key)
161
+ migration_commands = MigrationCommands(config=sqlspec_config)
162
+ migration_commands.downgrade(revision=revision)
163
+
164
+ @database_group.command(name="upgrade", help="Upgrade database to a specific revision.")
165
+ @bind_key_option
166
+ @no_prompt_option
167
+ @click.argument("revision", type=str, default="head")
168
+ def upgrade_database( # pyright: ignore[reportUnusedFunction]
169
+ bind_key: Optional[str], revision: str, no_prompt: bool
170
+ ) -> None:
171
+ """Upgrade the database to the latest revision."""
172
+ from rich.prompt import Confirm
173
+
174
+ from sqlspec.migrations.commands import MigrationCommands
175
+
176
+ ctx = click.get_current_context()
177
+ console.rule("[yellow]Starting database upgrade process[/]", align="left")
178
+ input_confirmed = (
179
+ True
180
+ if no_prompt
181
+ else Confirm.ask(f"[bold]Are you sure you want migrate the database to the `{revision}` revision?[/]")
182
+ )
183
+ if input_confirmed:
184
+ sqlspec_config = get_config_by_bind_key(ctx, bind_key)
185
+ migration_commands = MigrationCommands(config=sqlspec_config)
186
+ migration_commands.upgrade(revision=revision)
187
+
188
+ @database_group.command(help="Stamp the revision table with the given revision")
189
+ @click.argument("revision", type=str)
190
+ @bind_key_option
191
+ def stamp(bind_key: Optional[str], revision: str) -> None: # pyright: ignore[reportUnusedFunction]
192
+ """Stamp the revision table with the given revision."""
193
+ from sqlspec.migrations.commands import MigrationCommands
194
+
195
+ ctx = click.get_current_context()
196
+ sqlspec_config = get_config_by_bind_key(ctx, bind_key)
197
+ migration_commands = MigrationCommands(config=sqlspec_config)
198
+ migration_commands.stamp(revision=revision)
199
+
200
+ @database_group.command(name="init", help="Initialize migrations for the project.")
201
+ @bind_key_option
202
+ @click.argument("directory", default=None, required=False)
203
+ @click.option("--package", is_flag=True, default=True, help="Create `__init__.py` for created folder")
204
+ @no_prompt_option
205
+ def init_sqlspec( # pyright: ignore[reportUnusedFunction]
206
+ bind_key: Optional[str], directory: Optional[str], package: bool, no_prompt: bool
207
+ ) -> None:
208
+ """Initialize the database migrations."""
209
+ from rich.prompt import Confirm
210
+
211
+ from sqlspec.migrations.commands import MigrationCommands
212
+
213
+ ctx = click.get_current_context()
214
+ console.rule("[yellow]Initializing database migrations.", align="left")
215
+ input_confirmed = (
216
+ True if no_prompt else Confirm.ask("[bold]Are you sure you want initialize migrations for the project?[/]")
217
+ )
218
+ if input_confirmed:
219
+ configs = [get_config_by_bind_key(ctx, bind_key)] if bind_key is not None else ctx.obj["configs"]
220
+ for config in configs:
221
+ migration_config = getattr(config, "migration_config", {})
222
+ directory = migration_config.get("script_location", "migrations") if directory is None else directory
223
+ migration_commands = MigrationCommands(config=config)
224
+ migration_commands.init(directory=cast("str", directory), package=package)
225
+
226
+ @database_group.command(name="make-migrations", help="Create a new migration revision.")
227
+ @bind_key_option
228
+ @click.option("-m", "--message", default=None, help="Revision message")
229
+ @no_prompt_option
230
+ def create_revision( # pyright: ignore[reportUnusedFunction]
231
+ bind_key: Optional[str], message: Optional[str], no_prompt: bool
232
+ ) -> None:
233
+ """Create a new database revision."""
234
+ from rich.prompt import Prompt
235
+
236
+ from sqlspec.migrations.commands import MigrationCommands
237
+
238
+ ctx = click.get_current_context()
239
+ console.rule("[yellow]Creating new migration revision[/]", align="left")
240
+ if message is None:
241
+ message = "new migration" if no_prompt else Prompt.ask("Please enter a message describing this revision")
242
+
243
+ sqlspec_config = get_config_by_bind_key(ctx, bind_key)
244
+ migration_commands = MigrationCommands(config=sqlspec_config)
245
+ migration_commands.revision(message=message)
246
+
247
+ return database_group
sqlspec/config.py ADDED
@@ -0,0 +1,395 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import TYPE_CHECKING, Any, Callable, ClassVar, Generic, Optional, TypeVar, Union
3
+
4
+ from typing_extensions import NotRequired, TypedDict
5
+
6
+ from sqlspec.core.parameters import ParameterStyle, ParameterStyleConfig
7
+ from sqlspec.core.statement import StatementConfig
8
+ from sqlspec.utils.logging import get_logger
9
+
10
+ if TYPE_CHECKING:
11
+ from collections.abc import Awaitable
12
+ from contextlib import AbstractAsyncContextManager, AbstractContextManager
13
+
14
+ from sqlspec.driver import AsyncDriverAdapterBase, SyncDriverAdapterBase
15
+
16
+
17
+ __all__ = (
18
+ "AsyncConfigT",
19
+ "AsyncDatabaseConfig",
20
+ "ConfigT",
21
+ "DatabaseConfigProtocol",
22
+ "DriverT",
23
+ "LifecycleConfig",
24
+ "NoPoolAsyncConfig",
25
+ "NoPoolSyncConfig",
26
+ "SyncConfigT",
27
+ "SyncDatabaseConfig",
28
+ )
29
+
30
+ AsyncConfigT = TypeVar("AsyncConfigT", bound="Union[AsyncDatabaseConfig[Any, Any, Any], NoPoolAsyncConfig[Any, Any]]")
31
+ SyncConfigT = TypeVar("SyncConfigT", bound="Union[SyncDatabaseConfig[Any, Any, Any], NoPoolSyncConfig[Any, Any]]")
32
+ ConfigT = TypeVar(
33
+ "ConfigT",
34
+ bound="Union[Union[AsyncDatabaseConfig[Any, Any, Any], NoPoolAsyncConfig[Any, Any]], SyncDatabaseConfig[Any, Any, Any], NoPoolSyncConfig[Any, Any]]",
35
+ )
36
+
37
+ # Define TypeVars for Generic classes
38
+ ConnectionT = TypeVar("ConnectionT")
39
+ PoolT = TypeVar("PoolT")
40
+ DriverT = TypeVar("DriverT", bound="Union[SyncDriverAdapterBase, AsyncDriverAdapterBase]")
41
+
42
+ logger = get_logger("config")
43
+
44
+
45
+ class LifecycleConfig(TypedDict, total=False):
46
+ """Universal lifecycle hooks for all adapters.
47
+
48
+ Each hook accepts a list of callables to support multiple handlers.
49
+ """
50
+
51
+ on_connection_create: NotRequired[list[Callable[[Any], None]]]
52
+ on_connection_destroy: NotRequired[list[Callable[[Any], None]]]
53
+ on_pool_create: NotRequired[list[Callable[[Any], None]]]
54
+ on_pool_destroy: NotRequired[list[Callable[[Any], None]]]
55
+ on_session_start: NotRequired[list[Callable[[Any], None]]]
56
+ on_session_end: NotRequired[list[Callable[[Any], None]]]
57
+ on_query_start: NotRequired[list[Callable[[str, dict], None]]]
58
+ on_query_complete: NotRequired[list[Callable[[str, dict, Any], None]]]
59
+ on_error: NotRequired[list[Callable[[Exception, str, dict], None]]]
60
+
61
+
62
+ class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
63
+ """Protocol defining the interface for database configurations."""
64
+
65
+ __slots__ = ("driver_features", "migration_config", "pool_instance", "statement_config")
66
+ driver_type: "ClassVar[type[Any]]"
67
+ connection_type: "ClassVar[type[Any]]"
68
+ is_async: "ClassVar[bool]" = False
69
+ supports_connection_pooling: "ClassVar[bool]" = False
70
+ supports_native_arrow_import: "ClassVar[bool]" = False
71
+ supports_native_arrow_export: "ClassVar[bool]" = False
72
+ supports_native_parquet_import: "ClassVar[bool]" = False
73
+ supports_native_parquet_export: "ClassVar[bool]" = False
74
+ statement_config: "StatementConfig"
75
+ pool_instance: "Optional[PoolT]"
76
+ migration_config: "dict[str, Any]"
77
+
78
+ def __hash__(self) -> int:
79
+ return id(self)
80
+
81
+ def __eq__(self, other: object) -> bool:
82
+ if not isinstance(other, type(self)):
83
+ return False
84
+ return bool(self.pool_instance == other.pool_instance and self.migration_config == other.migration_config)
85
+
86
+ def __repr__(self) -> str:
87
+ parts = ", ".join([f"pool_instance={self.pool_instance!r}", f"migration_config={self.migration_config!r}"])
88
+ return f"{type(self).__name__}({parts})"
89
+
90
+ @abstractmethod
91
+ def create_connection(self) -> "Union[ConnectionT, Awaitable[ConnectionT]]":
92
+ """Create and return a new database connection."""
93
+ raise NotImplementedError
94
+
95
+ @abstractmethod
96
+ def provide_connection(
97
+ self, *args: Any, **kwargs: Any
98
+ ) -> "Union[AbstractContextManager[ConnectionT], AbstractAsyncContextManager[ConnectionT]]":
99
+ """Provide a database connection context manager."""
100
+ raise NotImplementedError
101
+
102
+ @abstractmethod
103
+ def provide_session(
104
+ self, *args: Any, **kwargs: Any
105
+ ) -> "Union[AbstractContextManager[DriverT], AbstractAsyncContextManager[DriverT]]":
106
+ """Provide a database session context manager."""
107
+ raise NotImplementedError
108
+
109
+ @abstractmethod
110
+ def create_pool(self) -> "Union[PoolT, Awaitable[PoolT]]":
111
+ """Create and return connection pool."""
112
+ raise NotImplementedError
113
+
114
+ @abstractmethod
115
+ def close_pool(self) -> "Optional[Awaitable[None]]":
116
+ """Terminate the connection pool."""
117
+ raise NotImplementedError
118
+
119
+ @abstractmethod
120
+ def provide_pool(
121
+ self, *args: Any, **kwargs: Any
122
+ ) -> "Union[PoolT, Awaitable[PoolT], AbstractContextManager[PoolT], AbstractAsyncContextManager[PoolT]]":
123
+ """Provide pool instance."""
124
+ raise NotImplementedError
125
+
126
+ def get_signature_namespace(self) -> "dict[str, type[Any]]":
127
+ """Get the signature namespace for this database configuration.
128
+
129
+ This method returns a dictionary of type names to types that should be
130
+ registered with Litestar's signature namespace to prevent serialization
131
+ attempts on database-specific types.
132
+
133
+ Returns:
134
+ Dictionary mapping type names to types.
135
+ """
136
+ return {}
137
+
138
+
139
+ class NoPoolSyncConfig(DatabaseConfigProtocol[ConnectionT, None, DriverT]):
140
+ """Base class for a sync database configurations that do not implement a pool."""
141
+
142
+ __slots__ = ("connection_config",)
143
+ is_async: "ClassVar[bool]" = False
144
+ supports_connection_pooling: "ClassVar[bool]" = False
145
+
146
+ def __init__(
147
+ self,
148
+ *,
149
+ connection_config: Optional[dict[str, Any]] = None,
150
+ migration_config: "Optional[dict[str, Any]]" = None,
151
+ statement_config: "Optional[StatementConfig]" = None,
152
+ driver_features: "Optional[dict[str, Any]]" = None,
153
+ ) -> None:
154
+ self.pool_instance = None
155
+ self.connection_config = connection_config or {}
156
+ self.migration_config: dict[str, Any] = migration_config if migration_config is not None else {}
157
+
158
+ if statement_config is None:
159
+ default_parameter_config = ParameterStyleConfig(
160
+ default_parameter_style=ParameterStyle.QMARK, supported_parameter_styles={ParameterStyle.QMARK}
161
+ )
162
+ self.statement_config = StatementConfig(dialect="sqlite", parameter_config=default_parameter_config)
163
+ else:
164
+ self.statement_config = statement_config
165
+ self.driver_features = driver_features or {}
166
+
167
+ def create_connection(self) -> ConnectionT:
168
+ """Create a database connection."""
169
+ raise NotImplementedError
170
+
171
+ def provide_connection(self, *args: Any, **kwargs: Any) -> "AbstractContextManager[ConnectionT]":
172
+ """Provide a database connection context manager."""
173
+ raise NotImplementedError
174
+
175
+ def provide_session(
176
+ self, *args: Any, statement_config: "Optional[StatementConfig]" = None, **kwargs: Any
177
+ ) -> "AbstractContextManager[DriverT]":
178
+ """Provide a database session context manager."""
179
+ raise NotImplementedError
180
+
181
+ def create_pool(self) -> None:
182
+ return None
183
+
184
+ def close_pool(self) -> None:
185
+ return None
186
+
187
+ def provide_pool(self, *args: Any, **kwargs: Any) -> None:
188
+ return None
189
+
190
+
191
+ class NoPoolAsyncConfig(DatabaseConfigProtocol[ConnectionT, None, DriverT]):
192
+ """Base class for an async database configurations that do not implement a pool."""
193
+
194
+ __slots__ = ("connection_config",)
195
+
196
+ is_async: "ClassVar[bool]" = True
197
+ supports_connection_pooling: "ClassVar[bool]" = False
198
+
199
+ def __init__(
200
+ self,
201
+ *,
202
+ connection_config: "Optional[dict[str, Any]]" = None,
203
+ migration_config: "Optional[dict[str, Any]]" = None,
204
+ statement_config: "Optional[StatementConfig]" = None,
205
+ driver_features: "Optional[dict[str, Any]]" = None,
206
+ ) -> None:
207
+ self.pool_instance = None
208
+ self.connection_config = connection_config or {}
209
+ self.migration_config: dict[str, Any] = migration_config if migration_config is not None else {}
210
+
211
+ if statement_config is None:
212
+ default_parameter_config = ParameterStyleConfig(
213
+ default_parameter_style=ParameterStyle.QMARK, supported_parameter_styles={ParameterStyle.QMARK}
214
+ )
215
+ self.statement_config = StatementConfig(dialect="sqlite", parameter_config=default_parameter_config)
216
+ else:
217
+ self.statement_config = statement_config
218
+ self.driver_features = driver_features or {}
219
+
220
+ async def create_connection(self) -> ConnectionT:
221
+ """Create a database connection."""
222
+ raise NotImplementedError
223
+
224
+ def provide_connection(self, *args: Any, **kwargs: Any) -> "AbstractAsyncContextManager[ConnectionT]":
225
+ """Provide a database connection context manager."""
226
+ raise NotImplementedError
227
+
228
+ def provide_session(
229
+ self, *args: Any, statement_config: "Optional[StatementConfig]" = None, **kwargs: Any
230
+ ) -> "AbstractAsyncContextManager[DriverT]":
231
+ """Provide a database session context manager."""
232
+ raise NotImplementedError
233
+
234
+ async def create_pool(self) -> None:
235
+ return None
236
+
237
+ async def close_pool(self) -> None:
238
+ return None
239
+
240
+ def provide_pool(self, *args: Any, **kwargs: Any) -> None:
241
+ return None
242
+
243
+
244
+ class SyncDatabaseConfig(DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]):
245
+ """Generic Sync Database Configuration."""
246
+
247
+ __slots__ = ("pool_config",)
248
+
249
+ is_async: "ClassVar[bool]" = False
250
+ supports_connection_pooling: "ClassVar[bool]" = True
251
+
252
+ def __init__(
253
+ self,
254
+ *,
255
+ pool_config: "Optional[dict[str, Any]]" = None,
256
+ pool_instance: "Optional[PoolT]" = None,
257
+ migration_config: "Optional[dict[str, Any]]" = None,
258
+ statement_config: "Optional[StatementConfig]" = None,
259
+ driver_features: "Optional[dict[str, Any]]" = None,
260
+ ) -> None:
261
+ self.pool_instance = pool_instance
262
+ self.pool_config = pool_config or {}
263
+ self.migration_config: dict[str, Any] = migration_config if migration_config is not None else {}
264
+
265
+ if statement_config is None:
266
+ default_parameter_config = ParameterStyleConfig(
267
+ default_parameter_style=ParameterStyle.QMARK, supported_parameter_styles={ParameterStyle.QMARK}
268
+ )
269
+ self.statement_config = StatementConfig(dialect="postgres", parameter_config=default_parameter_config)
270
+ else:
271
+ self.statement_config = statement_config
272
+ self.driver_features = driver_features or {}
273
+
274
+ def create_pool(self) -> PoolT:
275
+ """Create and return the connection pool.
276
+
277
+ Returns:
278
+ The created pool.
279
+ """
280
+ if self.pool_instance is not None:
281
+ return self.pool_instance
282
+ self.pool_instance = self._create_pool()
283
+ return self.pool_instance
284
+
285
+ def close_pool(self) -> None:
286
+ """Close the connection pool."""
287
+ self._close_pool()
288
+
289
+ def provide_pool(self, *args: Any, **kwargs: Any) -> PoolT:
290
+ """Provide pool instance."""
291
+ if self.pool_instance is None:
292
+ self.pool_instance = self.create_pool()
293
+ return self.pool_instance
294
+
295
+ def create_connection(self) -> ConnectionT:
296
+ """Create a database connection."""
297
+ raise NotImplementedError
298
+
299
+ def provide_connection(self, *args: Any, **kwargs: Any) -> "AbstractContextManager[ConnectionT]":
300
+ """Provide a database connection context manager."""
301
+ raise NotImplementedError
302
+
303
+ def provide_session(
304
+ self, *args: Any, statement_config: "Optional[StatementConfig]" = None, **kwargs: Any
305
+ ) -> "AbstractContextManager[DriverT]":
306
+ """Provide a database session context manager."""
307
+ raise NotImplementedError
308
+
309
+ @abstractmethod
310
+ def _create_pool(self) -> PoolT:
311
+ """Actual pool creation implementation."""
312
+ raise NotImplementedError
313
+
314
+ @abstractmethod
315
+ def _close_pool(self) -> None:
316
+ """Actual pool destruction implementation."""
317
+ raise NotImplementedError
318
+
319
+
320
+ class AsyncDatabaseConfig(DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]):
321
+ """Generic Async Database Configuration."""
322
+
323
+ __slots__ = ("pool_config",)
324
+
325
+ is_async: "ClassVar[bool]" = True
326
+ supports_connection_pooling: "ClassVar[bool]" = True
327
+
328
+ def __init__(
329
+ self,
330
+ *,
331
+ pool_config: "Optional[dict[str, Any]]" = None,
332
+ pool_instance: "Optional[PoolT]" = None,
333
+ migration_config: "Optional[dict[str, Any]]" = None,
334
+ statement_config: "Optional[StatementConfig]" = None,
335
+ driver_features: "Optional[dict[str, Any]]" = None,
336
+ ) -> None:
337
+ self.pool_instance = pool_instance
338
+ self.pool_config = pool_config or {}
339
+ self.migration_config: dict[str, Any] = migration_config if migration_config is not None else {}
340
+
341
+ if statement_config is None:
342
+ self.statement_config = StatementConfig(
343
+ parameter_config=ParameterStyleConfig(
344
+ default_parameter_style=ParameterStyle.QMARK, supported_parameter_styles={ParameterStyle.QMARK}
345
+ ),
346
+ dialect="postgres",
347
+ )
348
+ else:
349
+ self.statement_config = statement_config
350
+ self.driver_features = driver_features or {}
351
+
352
+ async def create_pool(self) -> PoolT:
353
+ """Create and return the connection pool.
354
+
355
+ Returns:
356
+ The created pool.
357
+ """
358
+ if self.pool_instance is not None:
359
+ return self.pool_instance
360
+ self.pool_instance = await self._create_pool()
361
+ return self.pool_instance
362
+
363
+ async def close_pool(self) -> None:
364
+ """Close the connection pool."""
365
+ await self._close_pool()
366
+
367
+ async def provide_pool(self, *args: Any, **kwargs: Any) -> PoolT:
368
+ """Provide pool instance."""
369
+ if self.pool_instance is None:
370
+ self.pool_instance = await self.create_pool()
371
+ return self.pool_instance
372
+
373
+ async def create_connection(self) -> ConnectionT:
374
+ """Create a database connection."""
375
+ raise NotImplementedError
376
+
377
+ def provide_connection(self, *args: Any, **kwargs: Any) -> "AbstractAsyncContextManager[ConnectionT]":
378
+ """Provide a database connection context manager."""
379
+ raise NotImplementedError
380
+
381
+ def provide_session(
382
+ self, *args: Any, statement_config: "Optional[StatementConfig]" = None, **kwargs: Any
383
+ ) -> "AbstractAsyncContextManager[DriverT]":
384
+ """Provide a database session context manager."""
385
+ raise NotImplementedError
386
+
387
+ @abstractmethod
388
+ async def _create_pool(self) -> PoolT:
389
+ """Actual async pool creation implementation."""
390
+ raise NotImplementedError
391
+
392
+ @abstractmethod
393
+ async def _close_pool(self) -> None:
394
+ """Actual async pool destruction implementation."""
395
+ raise NotImplementedError