sqlspec 0.36.0__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.
- ac8f31065839703b4e70__mypyc.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/__init__.py +140 -0
- sqlspec/__main__.py +12 -0
- sqlspec/__metadata__.py +14 -0
- sqlspec/_serialization.py +315 -0
- sqlspec/_typing.py +700 -0
- sqlspec/adapters/__init__.py +0 -0
- sqlspec/adapters/adbc/__init__.py +5 -0
- sqlspec/adapters/adbc/_typing.py +82 -0
- sqlspec/adapters/adbc/adk/__init__.py +5 -0
- sqlspec/adapters/adbc/adk/store.py +1273 -0
- sqlspec/adapters/adbc/config.py +295 -0
- sqlspec/adapters/adbc/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/adbc/core.py +735 -0
- sqlspec/adapters/adbc/data_dictionary.py +334 -0
- sqlspec/adapters/adbc/driver.py +529 -0
- sqlspec/adapters/adbc/events/__init__.py +5 -0
- sqlspec/adapters/adbc/events/store.py +285 -0
- sqlspec/adapters/adbc/litestar/__init__.py +5 -0
- sqlspec/adapters/adbc/litestar/store.py +502 -0
- sqlspec/adapters/adbc/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/adbc/type_converter.py +140 -0
- sqlspec/adapters/aiosqlite/__init__.py +25 -0
- sqlspec/adapters/aiosqlite/_typing.py +82 -0
- sqlspec/adapters/aiosqlite/adk/__init__.py +5 -0
- sqlspec/adapters/aiosqlite/adk/store.py +818 -0
- sqlspec/adapters/aiosqlite/config.py +334 -0
- sqlspec/adapters/aiosqlite/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/aiosqlite/core.py +315 -0
- sqlspec/adapters/aiosqlite/data_dictionary.py +208 -0
- sqlspec/adapters/aiosqlite/driver.py +313 -0
- sqlspec/adapters/aiosqlite/events/__init__.py +5 -0
- sqlspec/adapters/aiosqlite/events/store.py +20 -0
- sqlspec/adapters/aiosqlite/litestar/__init__.py +5 -0
- sqlspec/adapters/aiosqlite/litestar/store.py +279 -0
- sqlspec/adapters/aiosqlite/pool.py +533 -0
- sqlspec/adapters/asyncmy/__init__.py +21 -0
- sqlspec/adapters/asyncmy/_typing.py +87 -0
- sqlspec/adapters/asyncmy/adk/__init__.py +5 -0
- sqlspec/adapters/asyncmy/adk/store.py +703 -0
- sqlspec/adapters/asyncmy/config.py +302 -0
- sqlspec/adapters/asyncmy/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/asyncmy/core.py +360 -0
- sqlspec/adapters/asyncmy/data_dictionary.py +124 -0
- sqlspec/adapters/asyncmy/driver.py +383 -0
- sqlspec/adapters/asyncmy/events/__init__.py +5 -0
- sqlspec/adapters/asyncmy/events/store.py +104 -0
- sqlspec/adapters/asyncmy/litestar/__init__.py +5 -0
- sqlspec/adapters/asyncmy/litestar/store.py +296 -0
- sqlspec/adapters/asyncpg/__init__.py +19 -0
- sqlspec/adapters/asyncpg/_typing.py +88 -0
- sqlspec/adapters/asyncpg/adk/__init__.py +5 -0
- sqlspec/adapters/asyncpg/adk/store.py +748 -0
- sqlspec/adapters/asyncpg/config.py +569 -0
- sqlspec/adapters/asyncpg/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/asyncpg/core.py +367 -0
- sqlspec/adapters/asyncpg/data_dictionary.py +162 -0
- sqlspec/adapters/asyncpg/driver.py +487 -0
- sqlspec/adapters/asyncpg/events/__init__.py +6 -0
- sqlspec/adapters/asyncpg/events/backend.py +286 -0
- sqlspec/adapters/asyncpg/events/store.py +40 -0
- sqlspec/adapters/asyncpg/litestar/__init__.py +5 -0
- sqlspec/adapters/asyncpg/litestar/store.py +251 -0
- sqlspec/adapters/bigquery/__init__.py +14 -0
- sqlspec/adapters/bigquery/_typing.py +86 -0
- sqlspec/adapters/bigquery/adk/__init__.py +5 -0
- sqlspec/adapters/bigquery/adk/store.py +827 -0
- sqlspec/adapters/bigquery/config.py +353 -0
- sqlspec/adapters/bigquery/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/bigquery/core.py +715 -0
- sqlspec/adapters/bigquery/data_dictionary.py +128 -0
- sqlspec/adapters/bigquery/driver.py +548 -0
- sqlspec/adapters/bigquery/events/__init__.py +5 -0
- sqlspec/adapters/bigquery/events/store.py +139 -0
- sqlspec/adapters/bigquery/litestar/__init__.py +5 -0
- sqlspec/adapters/bigquery/litestar/store.py +325 -0
- sqlspec/adapters/bigquery/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/bigquery/type_converter.py +107 -0
- sqlspec/adapters/cockroach_asyncpg/__init__.py +24 -0
- sqlspec/adapters/cockroach_asyncpg/_typing.py +72 -0
- sqlspec/adapters/cockroach_asyncpg/adk/__init__.py +3 -0
- sqlspec/adapters/cockroach_asyncpg/adk/store.py +410 -0
- sqlspec/adapters/cockroach_asyncpg/config.py +238 -0
- sqlspec/adapters/cockroach_asyncpg/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/cockroach_asyncpg/core.py +55 -0
- sqlspec/adapters/cockroach_asyncpg/data_dictionary.py +107 -0
- sqlspec/adapters/cockroach_asyncpg/driver.py +144 -0
- sqlspec/adapters/cockroach_asyncpg/events/__init__.py +3 -0
- sqlspec/adapters/cockroach_asyncpg/events/store.py +20 -0
- sqlspec/adapters/cockroach_asyncpg/litestar/__init__.py +3 -0
- sqlspec/adapters/cockroach_asyncpg/litestar/store.py +142 -0
- sqlspec/adapters/cockroach_psycopg/__init__.py +38 -0
- sqlspec/adapters/cockroach_psycopg/_typing.py +129 -0
- sqlspec/adapters/cockroach_psycopg/adk/__init__.py +13 -0
- sqlspec/adapters/cockroach_psycopg/adk/store.py +868 -0
- sqlspec/adapters/cockroach_psycopg/config.py +484 -0
- sqlspec/adapters/cockroach_psycopg/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/cockroach_psycopg/core.py +63 -0
- sqlspec/adapters/cockroach_psycopg/data_dictionary.py +215 -0
- sqlspec/adapters/cockroach_psycopg/driver.py +284 -0
- sqlspec/adapters/cockroach_psycopg/events/__init__.py +6 -0
- sqlspec/adapters/cockroach_psycopg/events/store.py +34 -0
- sqlspec/adapters/cockroach_psycopg/litestar/__init__.py +3 -0
- sqlspec/adapters/cockroach_psycopg/litestar/store.py +325 -0
- sqlspec/adapters/duckdb/__init__.py +25 -0
- sqlspec/adapters/duckdb/_typing.py +81 -0
- sqlspec/adapters/duckdb/adk/__init__.py +14 -0
- sqlspec/adapters/duckdb/adk/store.py +850 -0
- sqlspec/adapters/duckdb/config.py +463 -0
- sqlspec/adapters/duckdb/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/duckdb/core.py +257 -0
- sqlspec/adapters/duckdb/data_dictionary.py +140 -0
- sqlspec/adapters/duckdb/driver.py +430 -0
- sqlspec/adapters/duckdb/events/__init__.py +5 -0
- sqlspec/adapters/duckdb/events/store.py +57 -0
- sqlspec/adapters/duckdb/litestar/__init__.py +5 -0
- sqlspec/adapters/duckdb/litestar/store.py +330 -0
- sqlspec/adapters/duckdb/pool.py +293 -0
- sqlspec/adapters/duckdb/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/duckdb/type_converter.py +118 -0
- sqlspec/adapters/mock/__init__.py +72 -0
- sqlspec/adapters/mock/_typing.py +147 -0
- sqlspec/adapters/mock/config.py +483 -0
- sqlspec/adapters/mock/core.py +319 -0
- sqlspec/adapters/mock/data_dictionary.py +366 -0
- sqlspec/adapters/mock/driver.py +721 -0
- sqlspec/adapters/mysqlconnector/__init__.py +36 -0
- sqlspec/adapters/mysqlconnector/_typing.py +141 -0
- sqlspec/adapters/mysqlconnector/adk/__init__.py +15 -0
- sqlspec/adapters/mysqlconnector/adk/store.py +1060 -0
- sqlspec/adapters/mysqlconnector/config.py +394 -0
- sqlspec/adapters/mysqlconnector/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/mysqlconnector/core.py +303 -0
- sqlspec/adapters/mysqlconnector/data_dictionary.py +235 -0
- sqlspec/adapters/mysqlconnector/driver.py +483 -0
- sqlspec/adapters/mysqlconnector/events/__init__.py +8 -0
- sqlspec/adapters/mysqlconnector/events/store.py +98 -0
- sqlspec/adapters/mysqlconnector/litestar/__init__.py +5 -0
- sqlspec/adapters/mysqlconnector/litestar/store.py +426 -0
- sqlspec/adapters/oracledb/__init__.py +60 -0
- sqlspec/adapters/oracledb/_numpy_handlers.py +141 -0
- sqlspec/adapters/oracledb/_typing.py +182 -0
- sqlspec/adapters/oracledb/_uuid_handlers.py +166 -0
- sqlspec/adapters/oracledb/adk/__init__.py +10 -0
- sqlspec/adapters/oracledb/adk/store.py +2369 -0
- sqlspec/adapters/oracledb/config.py +550 -0
- sqlspec/adapters/oracledb/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/oracledb/core.py +543 -0
- sqlspec/adapters/oracledb/data_dictionary.py +536 -0
- sqlspec/adapters/oracledb/driver.py +1229 -0
- sqlspec/adapters/oracledb/events/__init__.py +16 -0
- sqlspec/adapters/oracledb/events/backend.py +347 -0
- sqlspec/adapters/oracledb/events/store.py +420 -0
- sqlspec/adapters/oracledb/litestar/__init__.py +5 -0
- sqlspec/adapters/oracledb/litestar/store.py +781 -0
- sqlspec/adapters/oracledb/migrations.py +535 -0
- sqlspec/adapters/oracledb/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/oracledb/type_converter.py +211 -0
- sqlspec/adapters/psqlpy/__init__.py +17 -0
- sqlspec/adapters/psqlpy/_typing.py +79 -0
- sqlspec/adapters/psqlpy/adk/__init__.py +5 -0
- sqlspec/adapters/psqlpy/adk/store.py +766 -0
- sqlspec/adapters/psqlpy/config.py +304 -0
- sqlspec/adapters/psqlpy/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/psqlpy/core.py +480 -0
- sqlspec/adapters/psqlpy/data_dictionary.py +126 -0
- sqlspec/adapters/psqlpy/driver.py +438 -0
- sqlspec/adapters/psqlpy/events/__init__.py +6 -0
- sqlspec/adapters/psqlpy/events/backend.py +310 -0
- sqlspec/adapters/psqlpy/events/store.py +20 -0
- sqlspec/adapters/psqlpy/litestar/__init__.py +5 -0
- sqlspec/adapters/psqlpy/litestar/store.py +270 -0
- sqlspec/adapters/psqlpy/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/psqlpy/type_converter.py +113 -0
- sqlspec/adapters/psycopg/__init__.py +32 -0
- sqlspec/adapters/psycopg/_typing.py +164 -0
- sqlspec/adapters/psycopg/adk/__init__.py +10 -0
- sqlspec/adapters/psycopg/adk/store.py +1387 -0
- sqlspec/adapters/psycopg/config.py +576 -0
- sqlspec/adapters/psycopg/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/psycopg/core.py +450 -0
- sqlspec/adapters/psycopg/data_dictionary.py +289 -0
- sqlspec/adapters/psycopg/driver.py +975 -0
- sqlspec/adapters/psycopg/events/__init__.py +20 -0
- sqlspec/adapters/psycopg/events/backend.py +458 -0
- sqlspec/adapters/psycopg/events/store.py +42 -0
- sqlspec/adapters/psycopg/litestar/__init__.py +5 -0
- sqlspec/adapters/psycopg/litestar/store.py +552 -0
- sqlspec/adapters/psycopg/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/psycopg/type_converter.py +93 -0
- sqlspec/adapters/pymysql/__init__.py +21 -0
- sqlspec/adapters/pymysql/_typing.py +71 -0
- sqlspec/adapters/pymysql/adk/__init__.py +5 -0
- sqlspec/adapters/pymysql/adk/store.py +540 -0
- sqlspec/adapters/pymysql/config.py +195 -0
- sqlspec/adapters/pymysql/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/pymysql/core.py +299 -0
- sqlspec/adapters/pymysql/data_dictionary.py +122 -0
- sqlspec/adapters/pymysql/driver.py +259 -0
- sqlspec/adapters/pymysql/events/__init__.py +5 -0
- sqlspec/adapters/pymysql/events/store.py +50 -0
- sqlspec/adapters/pymysql/litestar/__init__.py +5 -0
- sqlspec/adapters/pymysql/litestar/store.py +232 -0
- sqlspec/adapters/pymysql/pool.py +137 -0
- sqlspec/adapters/spanner/__init__.py +40 -0
- sqlspec/adapters/spanner/_typing.py +86 -0
- sqlspec/adapters/spanner/adk/__init__.py +5 -0
- sqlspec/adapters/spanner/adk/store.py +732 -0
- sqlspec/adapters/spanner/config.py +352 -0
- sqlspec/adapters/spanner/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/spanner/core.py +188 -0
- sqlspec/adapters/spanner/data_dictionary.py +120 -0
- sqlspec/adapters/spanner/dialect/__init__.py +6 -0
- sqlspec/adapters/spanner/dialect/_spangres.py +57 -0
- sqlspec/adapters/spanner/dialect/_spanner.py +130 -0
- sqlspec/adapters/spanner/driver.py +373 -0
- sqlspec/adapters/spanner/events/__init__.py +5 -0
- sqlspec/adapters/spanner/events/store.py +187 -0
- sqlspec/adapters/spanner/litestar/__init__.py +5 -0
- sqlspec/adapters/spanner/litestar/store.py +291 -0
- sqlspec/adapters/spanner/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/spanner/type_converter.py +331 -0
- sqlspec/adapters/sqlite/__init__.py +19 -0
- sqlspec/adapters/sqlite/_typing.py +80 -0
- sqlspec/adapters/sqlite/adk/__init__.py +5 -0
- sqlspec/adapters/sqlite/adk/store.py +958 -0
- sqlspec/adapters/sqlite/config.py +280 -0
- sqlspec/adapters/sqlite/core.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/sqlite/core.py +312 -0
- sqlspec/adapters/sqlite/data_dictionary.py +202 -0
- sqlspec/adapters/sqlite/driver.py +359 -0
- sqlspec/adapters/sqlite/events/__init__.py +5 -0
- sqlspec/adapters/sqlite/events/store.py +20 -0
- sqlspec/adapters/sqlite/litestar/__init__.py +5 -0
- sqlspec/adapters/sqlite/litestar/store.py +316 -0
- sqlspec/adapters/sqlite/pool.py +198 -0
- sqlspec/adapters/sqlite/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/adapters/sqlite/type_converter.py +114 -0
- sqlspec/base.py +747 -0
- sqlspec/builder/__init__.py +179 -0
- sqlspec/builder/_base.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_base.py +1022 -0
- sqlspec/builder/_column.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_column.py +521 -0
- sqlspec/builder/_ddl.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_ddl.py +1642 -0
- sqlspec/builder/_delete.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_delete.py +95 -0
- sqlspec/builder/_dml.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_dml.py +365 -0
- sqlspec/builder/_explain.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_explain.py +579 -0
- sqlspec/builder/_expression_wrappers.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_expression_wrappers.py +46 -0
- sqlspec/builder/_factory.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_factory.py +1697 -0
- sqlspec/builder/_insert.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_insert.py +328 -0
- sqlspec/builder/_join.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_join.py +499 -0
- sqlspec/builder/_merge.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_merge.py +821 -0
- sqlspec/builder/_parsing_utils.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_parsing_utils.py +297 -0
- sqlspec/builder/_select.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_select.py +1660 -0
- sqlspec/builder/_temporal.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_temporal.py +139 -0
- sqlspec/builder/_update.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/builder/_update.py +173 -0
- sqlspec/builder/_vector_expressions.py +267 -0
- sqlspec/cli.py +911 -0
- sqlspec/config.py +1755 -0
- sqlspec/core/__init__.py +374 -0
- sqlspec/core/_correlation.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/_correlation.py +176 -0
- sqlspec/core/cache.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/cache.py +1069 -0
- sqlspec/core/compiler.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/compiler.py +954 -0
- sqlspec/core/explain.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/explain.py +275 -0
- sqlspec/core/filters.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/filters.py +952 -0
- sqlspec/core/hashing.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/hashing.py +262 -0
- sqlspec/core/metrics.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/metrics.py +83 -0
- sqlspec/core/parameters/__init__.py +71 -0
- sqlspec/core/parameters/_alignment.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/parameters/_alignment.py +270 -0
- sqlspec/core/parameters/_converter.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/parameters/_converter.py +543 -0
- sqlspec/core/parameters/_processor.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/parameters/_processor.py +505 -0
- sqlspec/core/parameters/_registry.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/parameters/_registry.py +206 -0
- sqlspec/core/parameters/_transformers.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/parameters/_transformers.py +292 -0
- sqlspec/core/parameters/_types.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/parameters/_types.py +499 -0
- sqlspec/core/parameters/_validator.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/parameters/_validator.py +180 -0
- sqlspec/core/pipeline.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/pipeline.py +319 -0
- sqlspec/core/query_modifiers.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/query_modifiers.py +437 -0
- sqlspec/core/result/__init__.py +23 -0
- sqlspec/core/result/_base.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/result/_base.py +1121 -0
- sqlspec/core/result/_io.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/result/_io.py +28 -0
- sqlspec/core/splitter.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/splitter.py +966 -0
- sqlspec/core/stack.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/stack.py +163 -0
- sqlspec/core/statement.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/statement.py +1503 -0
- sqlspec/core/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/core/type_converter.py +339 -0
- sqlspec/data_dictionary/__init__.py +22 -0
- sqlspec/data_dictionary/_loader.py +123 -0
- sqlspec/data_dictionary/_registry.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/data_dictionary/_registry.py +74 -0
- sqlspec/data_dictionary/_types.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/data_dictionary/_types.py +121 -0
- sqlspec/data_dictionary/dialects/__init__.py +21 -0
- sqlspec/data_dictionary/dialects/bigquery.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/data_dictionary/dialects/bigquery.py +49 -0
- sqlspec/data_dictionary/dialects/cockroachdb.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/data_dictionary/dialects/cockroachdb.py +43 -0
- sqlspec/data_dictionary/dialects/duckdb.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/data_dictionary/dialects/duckdb.py +47 -0
- sqlspec/data_dictionary/dialects/mysql.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/data_dictionary/dialects/mysql.py +42 -0
- sqlspec/data_dictionary/dialects/oracle.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/data_dictionary/dialects/oracle.py +34 -0
- sqlspec/data_dictionary/dialects/postgres.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/data_dictionary/dialects/postgres.py +46 -0
- sqlspec/data_dictionary/dialects/spanner.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/data_dictionary/dialects/spanner.py +37 -0
- sqlspec/data_dictionary/dialects/sqlite.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/data_dictionary/dialects/sqlite.py +42 -0
- sqlspec/data_dictionary/sql/.gitkeep +0 -0
- sqlspec/data_dictionary/sql/bigquery/columns.sql +23 -0
- sqlspec/data_dictionary/sql/bigquery/foreign_keys.sql +34 -0
- sqlspec/data_dictionary/sql/bigquery/indexes.sql +19 -0
- sqlspec/data_dictionary/sql/bigquery/tables.sql +33 -0
- sqlspec/data_dictionary/sql/bigquery/version.sql +3 -0
- sqlspec/data_dictionary/sql/cockroachdb/columns.sql +34 -0
- sqlspec/data_dictionary/sql/cockroachdb/foreign_keys.sql +40 -0
- sqlspec/data_dictionary/sql/cockroachdb/indexes.sql +32 -0
- sqlspec/data_dictionary/sql/cockroachdb/tables.sql +44 -0
- sqlspec/data_dictionary/sql/cockroachdb/version.sql +3 -0
- sqlspec/data_dictionary/sql/duckdb/columns.sql +23 -0
- sqlspec/data_dictionary/sql/duckdb/foreign_keys.sql +36 -0
- sqlspec/data_dictionary/sql/duckdb/indexes.sql +19 -0
- sqlspec/data_dictionary/sql/duckdb/tables.sql +38 -0
- sqlspec/data_dictionary/sql/duckdb/version.sql +3 -0
- sqlspec/data_dictionary/sql/mysql/columns.sql +23 -0
- sqlspec/data_dictionary/sql/mysql/foreign_keys.sql +28 -0
- sqlspec/data_dictionary/sql/mysql/indexes.sql +26 -0
- sqlspec/data_dictionary/sql/mysql/tables.sql +33 -0
- sqlspec/data_dictionary/sql/mysql/version.sql +3 -0
- sqlspec/data_dictionary/sql/oracle/columns.sql +23 -0
- sqlspec/data_dictionary/sql/oracle/foreign_keys.sql +48 -0
- sqlspec/data_dictionary/sql/oracle/indexes.sql +44 -0
- sqlspec/data_dictionary/sql/oracle/tables.sql +25 -0
- sqlspec/data_dictionary/sql/oracle/version.sql +20 -0
- sqlspec/data_dictionary/sql/postgres/columns.sql +34 -0
- sqlspec/data_dictionary/sql/postgres/foreign_keys.sql +40 -0
- sqlspec/data_dictionary/sql/postgres/indexes.sql +56 -0
- sqlspec/data_dictionary/sql/postgres/tables.sql +44 -0
- sqlspec/data_dictionary/sql/postgres/version.sql +3 -0
- sqlspec/data_dictionary/sql/spanner/columns.sql +23 -0
- sqlspec/data_dictionary/sql/spanner/foreign_keys.sql +70 -0
- sqlspec/data_dictionary/sql/spanner/indexes.sql +30 -0
- sqlspec/data_dictionary/sql/spanner/tables.sql +9 -0
- sqlspec/data_dictionary/sql/spanner/version.sql +3 -0
- sqlspec/data_dictionary/sql/sqlite/columns.sql +23 -0
- sqlspec/data_dictionary/sql/sqlite/foreign_keys.sql +22 -0
- sqlspec/data_dictionary/sql/sqlite/indexes.sql +7 -0
- sqlspec/data_dictionary/sql/sqlite/tables.sql +28 -0
- sqlspec/data_dictionary/sql/sqlite/version.sql +3 -0
- sqlspec/driver/__init__.py +32 -0
- sqlspec/driver/_async.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/driver/_async.py +1737 -0
- sqlspec/driver/_common.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/driver/_common.py +1478 -0
- sqlspec/driver/_sql_helpers.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/driver/_sql_helpers.py +148 -0
- sqlspec/driver/_storage_helpers.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/driver/_storage_helpers.py +144 -0
- sqlspec/driver/_sync.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/driver/_sync.py +1710 -0
- sqlspec/exceptions.py +338 -0
- sqlspec/extensions/__init__.py +0 -0
- sqlspec/extensions/adk/__init__.py +70 -0
- sqlspec/extensions/adk/_types.py +51 -0
- sqlspec/extensions/adk/converters.py +172 -0
- sqlspec/extensions/adk/memory/__init__.py +69 -0
- sqlspec/extensions/adk/memory/_types.py +30 -0
- sqlspec/extensions/adk/memory/converters.py +149 -0
- sqlspec/extensions/adk/memory/service.py +217 -0
- sqlspec/extensions/adk/memory/store.py +569 -0
- sqlspec/extensions/adk/migrations/0001_create_adk_tables.py +246 -0
- sqlspec/extensions/adk/migrations/__init__.py +0 -0
- sqlspec/extensions/adk/service.py +225 -0
- sqlspec/extensions/adk/store.py +567 -0
- sqlspec/extensions/events/__init__.py +51 -0
- sqlspec/extensions/events/_channel.py +703 -0
- sqlspec/extensions/events/_hints.py +45 -0
- sqlspec/extensions/events/_models.py +23 -0
- sqlspec/extensions/events/_payload.py +69 -0
- sqlspec/extensions/events/_protocols.py +134 -0
- sqlspec/extensions/events/_queue.py +461 -0
- sqlspec/extensions/events/_store.py +209 -0
- sqlspec/extensions/events/migrations/0001_create_event_queue.py +59 -0
- sqlspec/extensions/events/migrations/__init__.py +3 -0
- sqlspec/extensions/fastapi/__init__.py +19 -0
- sqlspec/extensions/fastapi/extension.py +351 -0
- sqlspec/extensions/fastapi/providers.py +607 -0
- sqlspec/extensions/flask/__init__.py +37 -0
- sqlspec/extensions/flask/_state.py +76 -0
- sqlspec/extensions/flask/_utils.py +71 -0
- sqlspec/extensions/flask/extension.py +519 -0
- sqlspec/extensions/litestar/__init__.py +28 -0
- sqlspec/extensions/litestar/_utils.py +52 -0
- sqlspec/extensions/litestar/channels.py +165 -0
- sqlspec/extensions/litestar/cli.py +102 -0
- sqlspec/extensions/litestar/config.py +90 -0
- sqlspec/extensions/litestar/handlers.py +316 -0
- sqlspec/extensions/litestar/migrations/0001_create_session_table.py +137 -0
- sqlspec/extensions/litestar/migrations/__init__.py +3 -0
- sqlspec/extensions/litestar/plugin.py +671 -0
- sqlspec/extensions/litestar/providers.py +526 -0
- sqlspec/extensions/litestar/store.py +296 -0
- sqlspec/extensions/otel/__init__.py +58 -0
- sqlspec/extensions/prometheus/__init__.py +113 -0
- sqlspec/extensions/starlette/__init__.py +19 -0
- sqlspec/extensions/starlette/_state.py +30 -0
- sqlspec/extensions/starlette/_utils.py +96 -0
- sqlspec/extensions/starlette/extension.py +346 -0
- sqlspec/extensions/starlette/middleware.py +235 -0
- sqlspec/loader.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/loader.py +702 -0
- sqlspec/migrations/__init__.py +36 -0
- sqlspec/migrations/base.py +731 -0
- sqlspec/migrations/commands.py +1232 -0
- sqlspec/migrations/context.py +157 -0
- sqlspec/migrations/fix.py +204 -0
- sqlspec/migrations/loaders.py +443 -0
- sqlspec/migrations/runner.py +1172 -0
- sqlspec/migrations/templates.py +234 -0
- sqlspec/migrations/tracker.py +611 -0
- sqlspec/migrations/utils.py +256 -0
- sqlspec/migrations/validation.py +207 -0
- sqlspec/migrations/version.py +446 -0
- sqlspec/observability/__init__.py +55 -0
- sqlspec/observability/_common.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_common.py +77 -0
- sqlspec/observability/_config.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_config.py +348 -0
- sqlspec/observability/_diagnostics.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_diagnostics.py +74 -0
- sqlspec/observability/_dispatcher.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_dispatcher.py +152 -0
- sqlspec/observability/_formatters/__init__.py +13 -0
- sqlspec/observability/_formatters/_aws.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_formatters/_aws.py +102 -0
- sqlspec/observability/_formatters/_azure.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_formatters/_azure.py +96 -0
- sqlspec/observability/_formatters/_base.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_formatters/_base.py +57 -0
- sqlspec/observability/_formatters/_gcp.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_formatters/_gcp.py +131 -0
- sqlspec/observability/_formatting.py +58 -0
- sqlspec/observability/_observer.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_observer.py +357 -0
- sqlspec/observability/_runtime.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_runtime.py +420 -0
- sqlspec/observability/_sampling.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_sampling.py +188 -0
- sqlspec/observability/_spans.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/observability/_spans.py +161 -0
- sqlspec/protocols.py +916 -0
- sqlspec/py.typed +0 -0
- sqlspec/storage/__init__.py +48 -0
- sqlspec/storage/_utils.py +104 -0
- sqlspec/storage/backends/__init__.py +1 -0
- sqlspec/storage/backends/base.py +253 -0
- sqlspec/storage/backends/fsspec.py +529 -0
- sqlspec/storage/backends/local.py +441 -0
- sqlspec/storage/backends/obstore.py +916 -0
- sqlspec/storage/errors.py +104 -0
- sqlspec/storage/pipeline.py +582 -0
- sqlspec/storage/registry.py +301 -0
- sqlspec/typing.py +395 -0
- sqlspec/utils/__init__.py +7 -0
- sqlspec/utils/arrow_helpers.py +318 -0
- sqlspec/utils/config_tools.py +332 -0
- sqlspec/utils/correlation.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/utils/correlation.py +134 -0
- sqlspec/utils/deprecation.py +190 -0
- sqlspec/utils/fixtures.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/utils/fixtures.py +258 -0
- sqlspec/utils/logging.py +222 -0
- sqlspec/utils/module_loader.py +306 -0
- sqlspec/utils/portal.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/utils/portal.py +375 -0
- sqlspec/utils/schema.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/utils/schema.py +485 -0
- sqlspec/utils/serializers.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/utils/serializers.py +408 -0
- sqlspec/utils/singleton.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/utils/singleton.py +41 -0
- sqlspec/utils/sync_tools.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/utils/sync_tools.py +311 -0
- sqlspec/utils/text.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/utils/text.py +108 -0
- sqlspec/utils/type_converters.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/utils/type_converters.py +128 -0
- sqlspec/utils/type_guards.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/utils/type_guards.py +1360 -0
- sqlspec/utils/uuids.cpython-310-aarch64-linux-gnu.so +0 -0
- sqlspec/utils/uuids.py +225 -0
- sqlspec-0.36.0.dist-info/METADATA +205 -0
- sqlspec-0.36.0.dist-info/RECORD +531 -0
- sqlspec-0.36.0.dist-info/WHEEL +7 -0
- sqlspec-0.36.0.dist-info/entry_points.txt +2 -0
- sqlspec-0.36.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,533 @@
|
|
|
1
|
+
"""Multi-connection pool for aiosqlite."""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
import time
|
|
5
|
+
from contextlib import suppress
|
|
6
|
+
from typing import TYPE_CHECKING, Any
|
|
7
|
+
|
|
8
|
+
import aiosqlite
|
|
9
|
+
|
|
10
|
+
from sqlspec.exceptions import SQLSpecError
|
|
11
|
+
from sqlspec.utils.logging import get_logger
|
|
12
|
+
from sqlspec.utils.uuids import uuid4
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from types import TracebackType
|
|
16
|
+
|
|
17
|
+
from sqlspec.adapters.aiosqlite._typing import AiosqliteConnection
|
|
18
|
+
|
|
19
|
+
__all__ = (
|
|
20
|
+
"AiosqliteConnectTimeoutError",
|
|
21
|
+
"AiosqliteConnectionPool",
|
|
22
|
+
"AiosqlitePoolClosedError",
|
|
23
|
+
"AiosqlitePoolConnection",
|
|
24
|
+
"AiosqlitePoolConnectionContext",
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
logger = get_logger(__name__)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class AiosqlitePoolClosedError(SQLSpecError):
|
|
31
|
+
"""Pool has been closed and cannot accept new operations."""
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class AiosqliteConnectTimeoutError(SQLSpecError):
|
|
35
|
+
"""Connection could not be established within the specified timeout period."""
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class AiosqlitePoolConnection:
|
|
39
|
+
"""Wrapper for database connections in the pool."""
|
|
40
|
+
|
|
41
|
+
__slots__ = ("_closed", "_healthy", "connection", "id", "idle_since")
|
|
42
|
+
|
|
43
|
+
def __init__(self, connection: "AiosqliteConnection") -> None:
|
|
44
|
+
"""Initialize pool connection wrapper.
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
connection: The raw aiosqlite connection
|
|
48
|
+
"""
|
|
49
|
+
self.id = uuid4().hex
|
|
50
|
+
self.connection = connection
|
|
51
|
+
self.idle_since: float | None = None
|
|
52
|
+
self._closed = False
|
|
53
|
+
self._healthy = True
|
|
54
|
+
|
|
55
|
+
@property
|
|
56
|
+
def idle_time(self) -> float:
|
|
57
|
+
"""Get idle time in seconds.
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
Idle time in seconds, 0.0 if connection is in use
|
|
61
|
+
"""
|
|
62
|
+
if self.idle_since is None:
|
|
63
|
+
return 0.0
|
|
64
|
+
return time.time() - self.idle_since
|
|
65
|
+
|
|
66
|
+
@property
|
|
67
|
+
def is_closed(self) -> bool:
|
|
68
|
+
"""Check if connection is closed.
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
True if connection is closed
|
|
72
|
+
"""
|
|
73
|
+
return self._closed
|
|
74
|
+
|
|
75
|
+
@property
|
|
76
|
+
def is_healthy(self) -> bool:
|
|
77
|
+
"""Check if connection was healthy on last check.
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
True if connection is presumed healthy
|
|
81
|
+
"""
|
|
82
|
+
return self._healthy and not self._closed
|
|
83
|
+
|
|
84
|
+
def mark_as_in_use(self) -> None:
|
|
85
|
+
"""Mark connection as in use."""
|
|
86
|
+
self.idle_since = None
|
|
87
|
+
|
|
88
|
+
def mark_as_idle(self) -> None:
|
|
89
|
+
"""Mark connection as idle."""
|
|
90
|
+
self.idle_since = time.time()
|
|
91
|
+
|
|
92
|
+
def mark_unhealthy(self) -> None:
|
|
93
|
+
"""Mark connection as unhealthy."""
|
|
94
|
+
self._healthy = False
|
|
95
|
+
|
|
96
|
+
async def is_alive(self) -> bool:
|
|
97
|
+
"""Check if connection is alive and functional.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
True if connection is healthy
|
|
101
|
+
"""
|
|
102
|
+
if self._closed:
|
|
103
|
+
self._healthy = False
|
|
104
|
+
return False
|
|
105
|
+
try:
|
|
106
|
+
await self.connection.execute("SELECT 1")
|
|
107
|
+
except Exception:
|
|
108
|
+
self._healthy = False
|
|
109
|
+
return False
|
|
110
|
+
else:
|
|
111
|
+
self._healthy = True
|
|
112
|
+
return True
|
|
113
|
+
|
|
114
|
+
async def reset(self) -> None:
|
|
115
|
+
"""Reset connection to clean state."""
|
|
116
|
+
if self._closed:
|
|
117
|
+
return
|
|
118
|
+
with suppress(Exception):
|
|
119
|
+
await self.connection.rollback()
|
|
120
|
+
|
|
121
|
+
async def close(self) -> None:
|
|
122
|
+
"""Close the connection."""
|
|
123
|
+
if self._closed:
|
|
124
|
+
return
|
|
125
|
+
try:
|
|
126
|
+
with suppress(Exception):
|
|
127
|
+
await self.connection.rollback()
|
|
128
|
+
await self.connection.close()
|
|
129
|
+
except Exception:
|
|
130
|
+
logger.debug("Error closing connection %s", self.id)
|
|
131
|
+
finally:
|
|
132
|
+
self._closed = True
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
class AiosqlitePoolConnectionContext:
|
|
136
|
+
"""Async context manager for pooled aiosqlite connections."""
|
|
137
|
+
|
|
138
|
+
__slots__ = ("_connection", "_pool")
|
|
139
|
+
|
|
140
|
+
def __init__(self, pool: "AiosqliteConnectionPool") -> None:
|
|
141
|
+
"""Initialize the context manager.
|
|
142
|
+
|
|
143
|
+
Args:
|
|
144
|
+
pool: Connection pool instance.
|
|
145
|
+
"""
|
|
146
|
+
self._pool = pool
|
|
147
|
+
self._connection: AiosqlitePoolConnection | None = None
|
|
148
|
+
|
|
149
|
+
async def __aenter__(self) -> "AiosqliteConnection":
|
|
150
|
+
self._connection = await self._pool.acquire()
|
|
151
|
+
return self._connection.connection
|
|
152
|
+
|
|
153
|
+
async def __aexit__(
|
|
154
|
+
self, exc_type: "type[BaseException] | None", exc_val: "BaseException | None", exc_tb: "TracebackType | None"
|
|
155
|
+
) -> "bool | None":
|
|
156
|
+
if self._connection is None:
|
|
157
|
+
return False
|
|
158
|
+
await self._pool.release(self._connection)
|
|
159
|
+
self._connection = None
|
|
160
|
+
return False
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
class AiosqliteConnectionPool:
|
|
164
|
+
"""Multi-connection pool for aiosqlite."""
|
|
165
|
+
|
|
166
|
+
__slots__ = (
|
|
167
|
+
"_closed_event_instance",
|
|
168
|
+
"_connect_timeout",
|
|
169
|
+
"_connection_parameters",
|
|
170
|
+
"_connection_registry",
|
|
171
|
+
"_health_check_interval",
|
|
172
|
+
"_idle_timeout",
|
|
173
|
+
"_lock_instance",
|
|
174
|
+
"_min_size",
|
|
175
|
+
"_operation_timeout",
|
|
176
|
+
"_pool_size",
|
|
177
|
+
"_queue_instance",
|
|
178
|
+
"_wal_initialized",
|
|
179
|
+
"_warmed",
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
def __init__(
|
|
183
|
+
self,
|
|
184
|
+
connection_parameters: "dict[str, Any]",
|
|
185
|
+
pool_size: int = 5,
|
|
186
|
+
min_size: int = 0,
|
|
187
|
+
connect_timeout: float = 30.0,
|
|
188
|
+
idle_timeout: float = 24 * 60 * 60,
|
|
189
|
+
operation_timeout: float = 10.0,
|
|
190
|
+
health_check_interval: float = 30.0,
|
|
191
|
+
) -> None:
|
|
192
|
+
"""Initialize connection pool.
|
|
193
|
+
|
|
194
|
+
Args:
|
|
195
|
+
connection_parameters: SQLite connection parameters
|
|
196
|
+
pool_size: Maximum number of connections in the pool
|
|
197
|
+
min_size: Minimum connections to pre-create (pool warming)
|
|
198
|
+
connect_timeout: Maximum time to wait for connection acquisition
|
|
199
|
+
idle_timeout: Maximum time a connection can remain idle
|
|
200
|
+
operation_timeout: Maximum time for connection operations
|
|
201
|
+
health_check_interval: Seconds of idle time before running health check
|
|
202
|
+
"""
|
|
203
|
+
self._connection_parameters = connection_parameters
|
|
204
|
+
self._pool_size = pool_size
|
|
205
|
+
self._min_size = min(min_size, pool_size)
|
|
206
|
+
self._connect_timeout = connect_timeout
|
|
207
|
+
self._idle_timeout = idle_timeout
|
|
208
|
+
self._operation_timeout = operation_timeout
|
|
209
|
+
self._health_check_interval = health_check_interval
|
|
210
|
+
|
|
211
|
+
self._connection_registry: dict[str, AiosqlitePoolConnection] = {}
|
|
212
|
+
self._wal_initialized = False
|
|
213
|
+
self._warmed = False
|
|
214
|
+
|
|
215
|
+
self._queue_instance: asyncio.Queue[AiosqlitePoolConnection] | None = None
|
|
216
|
+
self._lock_instance: asyncio.Lock | None = None
|
|
217
|
+
self._closed_event_instance: asyncio.Event | None = None
|
|
218
|
+
|
|
219
|
+
@property
|
|
220
|
+
def _queue(self) -> "asyncio.Queue[AiosqlitePoolConnection]":
|
|
221
|
+
"""Lazy initialization of asyncio.Queue for Python 3.9 compatibility."""
|
|
222
|
+
if self._queue_instance is None:
|
|
223
|
+
self._queue_instance = asyncio.Queue(maxsize=self._pool_size)
|
|
224
|
+
return self._queue_instance
|
|
225
|
+
|
|
226
|
+
@property
|
|
227
|
+
def _lock(self) -> asyncio.Lock:
|
|
228
|
+
"""Lazy initialization of asyncio.Lock for Python 3.9 compatibility."""
|
|
229
|
+
if self._lock_instance is None:
|
|
230
|
+
self._lock_instance = asyncio.Lock()
|
|
231
|
+
return self._lock_instance
|
|
232
|
+
|
|
233
|
+
@property
|
|
234
|
+
def _closed_event(self) -> asyncio.Event:
|
|
235
|
+
"""Lazy initialization of asyncio.Event for Python 3.9 compatibility."""
|
|
236
|
+
if self._closed_event_instance is None:
|
|
237
|
+
self._closed_event_instance = asyncio.Event()
|
|
238
|
+
return self._closed_event_instance
|
|
239
|
+
|
|
240
|
+
@property
|
|
241
|
+
def is_closed(self) -> bool:
|
|
242
|
+
"""Check if pool is closed.
|
|
243
|
+
|
|
244
|
+
Returns:
|
|
245
|
+
True if pool is closed
|
|
246
|
+
"""
|
|
247
|
+
return self._closed_event_instance is not None and self._closed_event.is_set()
|
|
248
|
+
|
|
249
|
+
def size(self) -> int:
|
|
250
|
+
"""Get total number of connections in pool.
|
|
251
|
+
|
|
252
|
+
Returns:
|
|
253
|
+
Total connection count
|
|
254
|
+
"""
|
|
255
|
+
return len(self._connection_registry)
|
|
256
|
+
|
|
257
|
+
def checked_out(self) -> int:
|
|
258
|
+
"""Get number of checked out connections.
|
|
259
|
+
|
|
260
|
+
Returns:
|
|
261
|
+
Number of connections currently in use
|
|
262
|
+
"""
|
|
263
|
+
if self._queue_instance is None:
|
|
264
|
+
return len(self._connection_registry)
|
|
265
|
+
return len(self._connection_registry) - self._queue.qsize()
|
|
266
|
+
|
|
267
|
+
async def _create_connection(self) -> AiosqlitePoolConnection:
|
|
268
|
+
"""Create a new connection.
|
|
269
|
+
|
|
270
|
+
Returns:
|
|
271
|
+
New pool connection instance
|
|
272
|
+
"""
|
|
273
|
+
connection = await aiosqlite.connect(**self._connection_parameters)
|
|
274
|
+
|
|
275
|
+
database_path = str(self._connection_parameters.get("database", ""))
|
|
276
|
+
is_shared_cache = "cache=shared" in database_path
|
|
277
|
+
is_memory_db = ":memory:" in database_path or "mode=memory" in database_path
|
|
278
|
+
|
|
279
|
+
try:
|
|
280
|
+
if is_memory_db:
|
|
281
|
+
await connection.execute("PRAGMA journal_mode = MEMORY")
|
|
282
|
+
await connection.execute("PRAGMA synchronous = OFF")
|
|
283
|
+
await connection.execute("PRAGMA temp_store = MEMORY")
|
|
284
|
+
await connection.execute("PRAGMA cache_size = -16000")
|
|
285
|
+
else:
|
|
286
|
+
await connection.execute("PRAGMA journal_mode = WAL")
|
|
287
|
+
await connection.execute("PRAGMA synchronous = NORMAL")
|
|
288
|
+
|
|
289
|
+
await connection.execute("PRAGMA foreign_keys = ON")
|
|
290
|
+
await connection.execute("PRAGMA busy_timeout = 30000")
|
|
291
|
+
|
|
292
|
+
if is_shared_cache and is_memory_db:
|
|
293
|
+
await connection.execute("PRAGMA read_uncommitted = ON")
|
|
294
|
+
|
|
295
|
+
await connection.commit()
|
|
296
|
+
|
|
297
|
+
if is_shared_cache:
|
|
298
|
+
self._wal_initialized = True
|
|
299
|
+
|
|
300
|
+
except Exception:
|
|
301
|
+
logger.exception("Failed to configure connection")
|
|
302
|
+
await connection.execute("PRAGMA foreign_keys = ON")
|
|
303
|
+
await connection.execute("PRAGMA busy_timeout = 30000")
|
|
304
|
+
await connection.commit()
|
|
305
|
+
|
|
306
|
+
pool_connection = AiosqlitePoolConnection(connection)
|
|
307
|
+
pool_connection.mark_as_idle()
|
|
308
|
+
|
|
309
|
+
async with self._lock:
|
|
310
|
+
self._connection_registry[pool_connection.id] = pool_connection
|
|
311
|
+
|
|
312
|
+
return pool_connection
|
|
313
|
+
|
|
314
|
+
async def _claim_if_healthy(self, connection: AiosqlitePoolConnection) -> bool:
|
|
315
|
+
"""Check if connection is healthy and claim it.
|
|
316
|
+
|
|
317
|
+
Uses passive health checks: connections idle less than health_check_interval
|
|
318
|
+
are assumed healthy based on their last known state. Active health checks
|
|
319
|
+
(SELECT 1) are only performed on long-idle connections.
|
|
320
|
+
|
|
321
|
+
Args:
|
|
322
|
+
connection: Connection to check and claim
|
|
323
|
+
|
|
324
|
+
Returns:
|
|
325
|
+
True if connection was claimed
|
|
326
|
+
"""
|
|
327
|
+
if connection.idle_time > self._idle_timeout:
|
|
328
|
+
await self._retire_connection(connection, reason="idle_timeout")
|
|
329
|
+
return False
|
|
330
|
+
|
|
331
|
+
if not connection.is_healthy:
|
|
332
|
+
await self._retire_connection(connection, reason="unhealthy")
|
|
333
|
+
return False
|
|
334
|
+
|
|
335
|
+
if connection.idle_time > self._health_check_interval:
|
|
336
|
+
try:
|
|
337
|
+
is_alive = await asyncio.wait_for(connection.is_alive(), timeout=self._operation_timeout)
|
|
338
|
+
if not is_alive:
|
|
339
|
+
await self._retire_connection(connection, reason="health_check_failed")
|
|
340
|
+
return False
|
|
341
|
+
except asyncio.TimeoutError:
|
|
342
|
+
await self._retire_connection(connection, reason="health_check_timeout")
|
|
343
|
+
return False
|
|
344
|
+
|
|
345
|
+
connection.mark_as_in_use()
|
|
346
|
+
return True
|
|
347
|
+
|
|
348
|
+
async def _retire_connection(self, connection: AiosqlitePoolConnection, *, reason: str | None = None) -> None:
|
|
349
|
+
"""Retire a connection from the pool.
|
|
350
|
+
|
|
351
|
+
Args:
|
|
352
|
+
connection: Connection to retire
|
|
353
|
+
reason: Optional reason for retirement
|
|
354
|
+
"""
|
|
355
|
+
if reason:
|
|
356
|
+
logger.debug("Retiring connection %s", connection.id, extra={"reason": reason})
|
|
357
|
+
async with self._lock:
|
|
358
|
+
self._connection_registry.pop(connection.id, None)
|
|
359
|
+
|
|
360
|
+
try:
|
|
361
|
+
await asyncio.wait_for(connection.close(), timeout=self._operation_timeout)
|
|
362
|
+
except asyncio.TimeoutError:
|
|
363
|
+
logger.warning("Connection %s close timed out during retirement", connection.id)
|
|
364
|
+
|
|
365
|
+
async def _try_provision_new_connection(self) -> "AiosqlitePoolConnection | None":
|
|
366
|
+
"""Try to create a new connection if under capacity.
|
|
367
|
+
|
|
368
|
+
Returns:
|
|
369
|
+
New connection if successful, None if at capacity
|
|
370
|
+
"""
|
|
371
|
+
async with self._lock:
|
|
372
|
+
if len(self._connection_registry) >= self._pool_size:
|
|
373
|
+
return None
|
|
374
|
+
|
|
375
|
+
try:
|
|
376
|
+
connection = await self._create_connection()
|
|
377
|
+
except Exception:
|
|
378
|
+
logger.exception("Failed to create new connection")
|
|
379
|
+
return None
|
|
380
|
+
else:
|
|
381
|
+
connection.mark_as_in_use()
|
|
382
|
+
return connection
|
|
383
|
+
|
|
384
|
+
async def _wait_for_healthy_connection(self) -> AiosqlitePoolConnection:
|
|
385
|
+
"""Wait for a healthy connection to become available.
|
|
386
|
+
|
|
387
|
+
Returns:
|
|
388
|
+
Available healthy connection
|
|
389
|
+
|
|
390
|
+
Raises:
|
|
391
|
+
AiosqlitePoolClosedError: If pool is closed while waiting
|
|
392
|
+
"""
|
|
393
|
+
while True:
|
|
394
|
+
get_connection_task = asyncio.create_task(self._queue.get())
|
|
395
|
+
pool_closed_task = asyncio.create_task(self._closed_event.wait())
|
|
396
|
+
|
|
397
|
+
done, pending = await asyncio.wait(
|
|
398
|
+
{get_connection_task, pool_closed_task}, return_when=asyncio.FIRST_COMPLETED
|
|
399
|
+
)
|
|
400
|
+
|
|
401
|
+
try:
|
|
402
|
+
if pool_closed_task in done:
|
|
403
|
+
msg = "Pool closed during connection acquisition"
|
|
404
|
+
raise AiosqlitePoolClosedError(msg)
|
|
405
|
+
|
|
406
|
+
connection = get_connection_task.result()
|
|
407
|
+
if await self._claim_if_healthy(connection):
|
|
408
|
+
return connection
|
|
409
|
+
|
|
410
|
+
finally:
|
|
411
|
+
for task in pending:
|
|
412
|
+
task.cancel()
|
|
413
|
+
with suppress(asyncio.CancelledError):
|
|
414
|
+
await task
|
|
415
|
+
|
|
416
|
+
async def _warm_pool(self) -> None:
|
|
417
|
+
"""Pre-create minimum connections for pool warming.
|
|
418
|
+
|
|
419
|
+
Creates connections up to min_size to avoid cold-start latency
|
|
420
|
+
on first requests.
|
|
421
|
+
"""
|
|
422
|
+
if self._warmed or self._min_size <= 0:
|
|
423
|
+
return
|
|
424
|
+
|
|
425
|
+
self._warmed = True
|
|
426
|
+
connections_needed = self._min_size - len(self._connection_registry)
|
|
427
|
+
|
|
428
|
+
if connections_needed <= 0:
|
|
429
|
+
return
|
|
430
|
+
|
|
431
|
+
logger.debug("Warming pool with %d connections", connections_needed)
|
|
432
|
+
tasks = [self._create_connection() for _ in range(connections_needed)]
|
|
433
|
+
results = await asyncio.gather(*tasks, return_exceptions=True)
|
|
434
|
+
|
|
435
|
+
for result in results:
|
|
436
|
+
if isinstance(result, AiosqlitePoolConnection):
|
|
437
|
+
self._queue.put_nowait(result)
|
|
438
|
+
elif isinstance(result, Exception):
|
|
439
|
+
logger.warning("Failed to create warm connection: %s", result)
|
|
440
|
+
|
|
441
|
+
async def _get_connection(self) -> AiosqlitePoolConnection:
|
|
442
|
+
"""Run the three-phase connection acquisition cycle.
|
|
443
|
+
|
|
444
|
+
Returns:
|
|
445
|
+
Available connection
|
|
446
|
+
|
|
447
|
+
Raises:
|
|
448
|
+
AiosqlitePoolClosedError: If pool is closed
|
|
449
|
+
"""
|
|
450
|
+
if self.is_closed:
|
|
451
|
+
msg = "Cannot acquire connection from closed pool"
|
|
452
|
+
raise AiosqlitePoolClosedError(msg)
|
|
453
|
+
|
|
454
|
+
if not self._warmed and self._min_size > 0:
|
|
455
|
+
await self._warm_pool()
|
|
456
|
+
|
|
457
|
+
while not self._queue.empty():
|
|
458
|
+
connection = self._queue.get_nowait()
|
|
459
|
+
if await self._claim_if_healthy(connection):
|
|
460
|
+
return connection
|
|
461
|
+
|
|
462
|
+
new_connection = await self._try_provision_new_connection()
|
|
463
|
+
if new_connection is not None:
|
|
464
|
+
return new_connection
|
|
465
|
+
|
|
466
|
+
return await self._wait_for_healthy_connection()
|
|
467
|
+
|
|
468
|
+
async def acquire(self) -> AiosqlitePoolConnection:
|
|
469
|
+
"""Acquire a connection from the pool.
|
|
470
|
+
|
|
471
|
+
Returns:
|
|
472
|
+
Available connection
|
|
473
|
+
|
|
474
|
+
Raises:
|
|
475
|
+
AiosqliteConnectTimeoutError: If acquisition times out
|
|
476
|
+
"""
|
|
477
|
+
try:
|
|
478
|
+
connection = await asyncio.wait_for(self._get_connection(), timeout=self._connect_timeout)
|
|
479
|
+
if not self._wal_initialized and "cache=shared" in str(self._connection_parameters.get("database", "")):
|
|
480
|
+
await asyncio.sleep(0.01)
|
|
481
|
+
except asyncio.TimeoutError as e:
|
|
482
|
+
msg = f"Connection acquisition timed out after {self._connect_timeout}s"
|
|
483
|
+
raise AiosqliteConnectTimeoutError(msg) from e
|
|
484
|
+
else:
|
|
485
|
+
return connection
|
|
486
|
+
|
|
487
|
+
async def release(self, connection: AiosqlitePoolConnection) -> None:
|
|
488
|
+
"""Release a connection back to the pool.
|
|
489
|
+
|
|
490
|
+
Args:
|
|
491
|
+
connection: Connection to release
|
|
492
|
+
"""
|
|
493
|
+
if self.is_closed:
|
|
494
|
+
await self._retire_connection(connection)
|
|
495
|
+
return
|
|
496
|
+
|
|
497
|
+
if connection.id not in self._connection_registry:
|
|
498
|
+
logger.warning("Attempted to release unknown connection: %s", connection.id)
|
|
499
|
+
return
|
|
500
|
+
|
|
501
|
+
try:
|
|
502
|
+
await asyncio.wait_for(connection.reset(), timeout=self._operation_timeout)
|
|
503
|
+
connection.mark_as_idle()
|
|
504
|
+
self._queue.put_nowait(connection)
|
|
505
|
+
except Exception as e:
|
|
506
|
+
logger.warning("Failed to reset connection %s during release: %s", connection.id, e)
|
|
507
|
+
connection.mark_unhealthy()
|
|
508
|
+
await self._retire_connection(connection)
|
|
509
|
+
|
|
510
|
+
def get_connection(self) -> "AiosqlitePoolConnectionContext":
|
|
511
|
+
"""Get a connection with automatic release."""
|
|
512
|
+
return AiosqlitePoolConnectionContext(self)
|
|
513
|
+
|
|
514
|
+
async def close(self) -> None:
|
|
515
|
+
"""Close the connection pool."""
|
|
516
|
+
if self.is_closed:
|
|
517
|
+
return
|
|
518
|
+
self._closed_event.set()
|
|
519
|
+
|
|
520
|
+
while not self._queue.empty():
|
|
521
|
+
self._queue.get_nowait()
|
|
522
|
+
|
|
523
|
+
async with self._lock:
|
|
524
|
+
connections = list(self._connection_registry.values())
|
|
525
|
+
self._connection_registry.clear()
|
|
526
|
+
|
|
527
|
+
if connections:
|
|
528
|
+
close_tasks = [asyncio.wait_for(conn.close(), timeout=self._operation_timeout) for conn in connections]
|
|
529
|
+
results = await asyncio.gather(*close_tasks, return_exceptions=True)
|
|
530
|
+
|
|
531
|
+
for i, result in enumerate(results):
|
|
532
|
+
if isinstance(result, Exception):
|
|
533
|
+
logger.warning("Error closing connection %s: %s", connections[i].id, result)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from sqlspec.adapters.asyncmy._typing import AsyncmyConnection
|
|
2
|
+
from sqlspec.adapters.asyncmy.config import (
|
|
3
|
+
AsyncmyConfig,
|
|
4
|
+
AsyncmyConnectionParams,
|
|
5
|
+
AsyncmyDriverFeatures,
|
|
6
|
+
AsyncmyPoolParams,
|
|
7
|
+
)
|
|
8
|
+
from sqlspec.adapters.asyncmy.core import default_statement_config
|
|
9
|
+
from sqlspec.adapters.asyncmy.driver import AsyncmyCursor, AsyncmyDriver, AsyncmyExceptionHandler
|
|
10
|
+
|
|
11
|
+
__all__ = (
|
|
12
|
+
"AsyncmyConfig",
|
|
13
|
+
"AsyncmyConnection",
|
|
14
|
+
"AsyncmyConnectionParams",
|
|
15
|
+
"AsyncmyCursor",
|
|
16
|
+
"AsyncmyDriver",
|
|
17
|
+
"AsyncmyDriverFeatures",
|
|
18
|
+
"AsyncmyExceptionHandler",
|
|
19
|
+
"AsyncmyPoolParams",
|
|
20
|
+
"default_statement_config",
|
|
21
|
+
)
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""AsyncMy adapter type definitions.
|
|
2
|
+
|
|
3
|
+
This module contains type aliases and classes that are excluded from mypyc
|
|
4
|
+
compilation to avoid ABI boundary issues.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import TYPE_CHECKING, Any, TypeAlias
|
|
8
|
+
|
|
9
|
+
from asyncmy import Connection # pyright: ignore
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from collections.abc import Callable
|
|
13
|
+
from typing import Protocol
|
|
14
|
+
|
|
15
|
+
from sqlspec.adapters.asyncmy.driver import AsyncmyDriver
|
|
16
|
+
from sqlspec.core import StatementConfig
|
|
17
|
+
|
|
18
|
+
class AsyncmyConnectionProtocol(Protocol):
|
|
19
|
+
def cursor(self) -> Any: ...
|
|
20
|
+
|
|
21
|
+
async def commit(self) -> Any: ...
|
|
22
|
+
|
|
23
|
+
async def rollback(self) -> Any: ...
|
|
24
|
+
|
|
25
|
+
async def close(self) -> Any: ...
|
|
26
|
+
|
|
27
|
+
AsyncmyConnection: TypeAlias = AsyncmyConnectionProtocol
|
|
28
|
+
else:
|
|
29
|
+
AsyncmyConnection = Connection
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class AsyncmySessionContext:
|
|
33
|
+
"""Async context manager for AsyncMy sessions.
|
|
34
|
+
|
|
35
|
+
This class is intentionally excluded from mypyc compilation to avoid ABI
|
|
36
|
+
boundary issues. It receives callables from uncompiled config classes and
|
|
37
|
+
instantiates compiled Driver objects, acting as a bridge between compiled
|
|
38
|
+
and uncompiled code.
|
|
39
|
+
|
|
40
|
+
Uses callable-based connection management to decouple from config implementation.
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
__slots__ = (
|
|
44
|
+
"_acquire_connection",
|
|
45
|
+
"_connection",
|
|
46
|
+
"_driver",
|
|
47
|
+
"_driver_features",
|
|
48
|
+
"_prepare_driver",
|
|
49
|
+
"_release_connection",
|
|
50
|
+
"_statement_config",
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
def __init__(
|
|
54
|
+
self,
|
|
55
|
+
acquire_connection: "Callable[[], Any]",
|
|
56
|
+
release_connection: "Callable[[Any], Any]",
|
|
57
|
+
statement_config: "StatementConfig",
|
|
58
|
+
driver_features: "dict[str, Any]",
|
|
59
|
+
prepare_driver: "Callable[[AsyncmyDriver], AsyncmyDriver]",
|
|
60
|
+
) -> None:
|
|
61
|
+
self._acquire_connection = acquire_connection
|
|
62
|
+
self._release_connection = release_connection
|
|
63
|
+
self._statement_config = statement_config
|
|
64
|
+
self._driver_features = driver_features
|
|
65
|
+
self._prepare_driver = prepare_driver
|
|
66
|
+
self._connection: Any = None
|
|
67
|
+
self._driver: AsyncmyDriver | None = None
|
|
68
|
+
|
|
69
|
+
async def __aenter__(self) -> "AsyncmyDriver":
|
|
70
|
+
from sqlspec.adapters.asyncmy.driver import AsyncmyDriver
|
|
71
|
+
|
|
72
|
+
self._connection = await self._acquire_connection()
|
|
73
|
+
self._driver = AsyncmyDriver(
|
|
74
|
+
connection=self._connection, statement_config=self._statement_config, driver_features=self._driver_features
|
|
75
|
+
)
|
|
76
|
+
return self._prepare_driver(self._driver)
|
|
77
|
+
|
|
78
|
+
async def __aexit__(
|
|
79
|
+
self, exc_type: "type[BaseException] | None", exc_val: "BaseException | None", exc_tb: Any
|
|
80
|
+
) -> "bool | None":
|
|
81
|
+
if self._connection is not None:
|
|
82
|
+
await self._release_connection(self._connection)
|
|
83
|
+
self._connection = None
|
|
84
|
+
return None
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
__all__ = ("AsyncmyConnection", "AsyncmySessionContext")
|