"""DuckDB database configuration with connection pooling."""
from collections.abc import Callable, Sequence
from typing import TYPE_CHECKING, Any, ClassVar, Literal, TypedDict, cast
from typing_extensions import NotRequired
from sqlspec.adapters.duckdb._typing import DuckDBConnection, DuckDBCursor, DuckDBSessionContext
from sqlspec.adapters.duckdb.core import (
apply_driver_features,
build_connection_config,
build_statement_config,
default_statement_config,
)
from sqlspec.adapters.duckdb.driver import DuckDBDriver, DuckDBExceptionHandler
from sqlspec.adapters.duckdb.pool import DuckDBConnectionPool
from sqlspec.config import ExtensionConfigs, SyncDatabaseConfig
from sqlspec.driver._sync import SyncPoolConnectionContext, SyncPoolSessionFactory
from sqlspec.extensions.events import EventRuntimeHints
from sqlspec.utils.config_tools import normalize_connection_config
from sqlspec.utils.serializers import to_json
if TYPE_CHECKING:
from sqlspec.core import StatementConfig
from sqlspec.observability import ObservabilityConfig
__all__ = (
"DuckDBConfig",
"DuckDBConnectionParams",
"DuckDBDriverFeatures",
"DuckDBExtensionConfig",
"DuckDBPoolParams",
"DuckDBSecretConfig",
)
EXTENSION_FLAG_KEYS: "tuple[str, ...]" = (
"allow_community_extensions",
"allow_unsigned_extensions",
"enable_external_access",
)
class DuckDBConnectionParams(TypedDict):
"""DuckDB connection parameters.
Mirrors the keyword arguments accepted by duckdb.connect so callers can drive every DuckDB
configuration switch directly through SQLSpec. All keys are optional and forwarded verbatim
to DuckDB, either as top-level parameters or via the nested ``config`` dictionary when DuckDB
expects them there.
"""
database: NotRequired[str]
read_only: NotRequired[bool]
config: NotRequired["dict[str, Any]"]
memory_limit: NotRequired[str]
threads: NotRequired[int]
temp_directory: NotRequired[str]
max_temp_directory_size: NotRequired[str]
autoload_known_extensions: NotRequired[bool]
autoinstall_known_extensions: NotRequired[bool]
allow_community_extensions: NotRequired[bool]
allow_unsigned_extensions: NotRequired[bool]
extension_directory: NotRequired[str]
custom_extension_repository: NotRequired[str]
autoinstall_extension_repository: NotRequired[str]
allow_persistent_secrets: NotRequired[bool]
enable_external_access: NotRequired[bool]
secret_directory: NotRequired[str]
enable_object_cache: NotRequired[bool]
parquet_metadata_cache: NotRequired[bool]
enable_external_file_cache: NotRequired[bool]
checkpoint_threshold: NotRequired[str]
enable_progress_bar: NotRequired[bool]
progress_bar_time: NotRequired[int]
enable_logging: NotRequired[bool]
log_query_path: NotRequired[str]
logging_level: NotRequired[str]
preserve_insertion_order: NotRequired[bool]
default_null_order: NotRequired[str]
default_order: NotRequired[str]
ieee_floating_point_ops: NotRequired[bool]
binary_as_string: NotRequired[bool]
arrow_large_buffer_size: NotRequired[bool]
errors_as_json: NotRequired[bool]
extra: NotRequired["dict[str, Any]"]
class DuckDBPoolParams(DuckDBConnectionParams):
"""Complete pool configuration for DuckDB adapter.
Extends DuckDBConnectionParams with lifecycle settings consumed by SQLSpec's
thread-local DuckDB connection manager.
"""
pool_recycle_seconds: NotRequired[int]
health_check_interval: NotRequired[float]
class DuckDBExtensionConfig(TypedDict):
"""DuckDB extension configuration for auto-management."""
name: str
"""Name of the extension to install/load."""
version: NotRequired[str]
"""Specific version of the extension."""
repository: NotRequired[str]
"""Repository for the extension (core, community, or custom URL)."""
repository_url: NotRequired[str]
"""Custom repository URL for the extension."""
force_install: NotRequired[bool]
"""Force reinstallation of the extension."""
install: NotRequired[bool]
"""Force an explicit install_extension() call even for a name-only config."""
required: NotRequired[bool]
"""When True, install/load failure raises instead of best-effort WARNING."""