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,426 @@
|
|
|
1
|
+
"""MysqlConnector session store for Litestar integration."""
|
|
2
|
+
|
|
3
|
+
from datetime import datetime, timedelta, timezone
|
|
4
|
+
from typing import TYPE_CHECKING, Any, Final, cast
|
|
5
|
+
|
|
6
|
+
import mysql.connector
|
|
7
|
+
|
|
8
|
+
from sqlspec.extensions.litestar.store import BaseSQLSpecStore
|
|
9
|
+
from sqlspec.utils.logging import get_logger
|
|
10
|
+
from sqlspec.utils.sync_tools import async_
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from sqlspec.adapters.mysqlconnector.config import MysqlConnectorAsyncConfig, MysqlConnectorSyncConfig
|
|
14
|
+
|
|
15
|
+
logger = get_logger("sqlspec.adapters.mysqlconnector.litestar.store")
|
|
16
|
+
|
|
17
|
+
__all__ = ("MysqlConnectorAsyncStore", "MysqlConnectorSyncStore")
|
|
18
|
+
|
|
19
|
+
MYSQL_TABLE_NOT_FOUND_ERROR: Final = 1146
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class MysqlConnectorAsyncStore(BaseSQLSpecStore["MysqlConnectorAsyncConfig"]):
|
|
23
|
+
"""MySQL/MariaDB session store using mysql-connector async driver."""
|
|
24
|
+
|
|
25
|
+
__slots__ = ()
|
|
26
|
+
|
|
27
|
+
def __init__(self, config: "MysqlConnectorAsyncConfig") -> None:
|
|
28
|
+
super().__init__(config)
|
|
29
|
+
|
|
30
|
+
def _get_create_table_sql(self) -> str:
|
|
31
|
+
return f"""
|
|
32
|
+
CREATE TABLE IF NOT EXISTS {self._table_name} (
|
|
33
|
+
session_id VARCHAR(255) PRIMARY KEY,
|
|
34
|
+
data LONGBLOB NOT NULL,
|
|
35
|
+
expires_at DATETIME(6),
|
|
36
|
+
created_at DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6),
|
|
37
|
+
updated_at DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
|
38
|
+
INDEX idx_{self._table_name}_expires_at (expires_at)
|
|
39
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
def _get_drop_table_sql(self) -> "list[str]":
|
|
43
|
+
return [
|
|
44
|
+
f"DROP INDEX idx_{self._table_name}_expires_at ON {self._table_name}",
|
|
45
|
+
f"DROP TABLE IF EXISTS {self._table_name}",
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
async def create_table(self) -> None:
|
|
49
|
+
sql = self._get_create_table_sql()
|
|
50
|
+
async with self._config.provide_session() as driver:
|
|
51
|
+
await driver.execute_script(sql)
|
|
52
|
+
self._log_table_created()
|
|
53
|
+
|
|
54
|
+
async def get(self, key: str, renew_for: "int | timedelta | None" = None) -> "bytes | None":
|
|
55
|
+
sql = f"""
|
|
56
|
+
SELECT data, expires_at FROM {self._table_name}
|
|
57
|
+
WHERE session_id = %s
|
|
58
|
+
AND (expires_at IS NULL OR expires_at > UTC_TIMESTAMP(6))
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
try:
|
|
62
|
+
async with self._config.provide_connection() as conn:
|
|
63
|
+
cursor = await conn.cursor()
|
|
64
|
+
try:
|
|
65
|
+
await cursor.execute(sql, (key,))
|
|
66
|
+
row = await cursor.fetchone()
|
|
67
|
+
finally:
|
|
68
|
+
await cursor.close()
|
|
69
|
+
|
|
70
|
+
if row is None:
|
|
71
|
+
return None
|
|
72
|
+
|
|
73
|
+
data_value: Any = row[0]
|
|
74
|
+
expires_at: Any = row[1]
|
|
75
|
+
|
|
76
|
+
if renew_for is not None and expires_at is not None:
|
|
77
|
+
new_expires_at = self._calculate_expires_at(renew_for)
|
|
78
|
+
if new_expires_at is not None:
|
|
79
|
+
naive_expires_at = new_expires_at.replace(tzinfo=None)
|
|
80
|
+
update_sql = f"""
|
|
81
|
+
UPDATE {self._table_name}
|
|
82
|
+
SET expires_at = %s, updated_at = UTC_TIMESTAMP(6)
|
|
83
|
+
WHERE session_id = %s
|
|
84
|
+
"""
|
|
85
|
+
update_cursor = await conn.cursor()
|
|
86
|
+
try:
|
|
87
|
+
await update_cursor.execute(update_sql, (naive_expires_at, key))
|
|
88
|
+
finally:
|
|
89
|
+
await update_cursor.close()
|
|
90
|
+
await conn.commit()
|
|
91
|
+
|
|
92
|
+
return bytes(cast("bytes", data_value))
|
|
93
|
+
except mysql.connector.Error as exc:
|
|
94
|
+
if "doesn't exist" in str(exc) or getattr(exc, "errno", None) == MYSQL_TABLE_NOT_FOUND_ERROR:
|
|
95
|
+
return None
|
|
96
|
+
raise
|
|
97
|
+
|
|
98
|
+
async def set(self, key: str, value: "str | bytes", expires_in: "int | timedelta | None" = None) -> None:
|
|
99
|
+
data = self._value_to_bytes(value)
|
|
100
|
+
expires_at = self._calculate_expires_at(expires_in)
|
|
101
|
+
naive_expires_at = expires_at.replace(tzinfo=None) if expires_at else None
|
|
102
|
+
|
|
103
|
+
sql = f"""
|
|
104
|
+
INSERT INTO {self._table_name} (session_id, data, expires_at)
|
|
105
|
+
VALUES (%s, %s, %s) AS new
|
|
106
|
+
ON DUPLICATE KEY UPDATE
|
|
107
|
+
data = new.data,
|
|
108
|
+
expires_at = new.expires_at,
|
|
109
|
+
updated_at = UTC_TIMESTAMP(6)
|
|
110
|
+
"""
|
|
111
|
+
|
|
112
|
+
async with self._config.provide_connection() as conn:
|
|
113
|
+
cursor = await conn.cursor()
|
|
114
|
+
try:
|
|
115
|
+
await cursor.execute(sql, (key, data, naive_expires_at))
|
|
116
|
+
finally:
|
|
117
|
+
await cursor.close()
|
|
118
|
+
await conn.commit()
|
|
119
|
+
|
|
120
|
+
async def delete(self, key: str) -> None:
|
|
121
|
+
sql = f"DELETE FROM {self._table_name} WHERE session_id = %s"
|
|
122
|
+
|
|
123
|
+
async with self._config.provide_connection() as conn:
|
|
124
|
+
cursor = await conn.cursor()
|
|
125
|
+
try:
|
|
126
|
+
await cursor.execute(sql, (key,))
|
|
127
|
+
finally:
|
|
128
|
+
await cursor.close()
|
|
129
|
+
await conn.commit()
|
|
130
|
+
|
|
131
|
+
async def delete_all(self) -> None:
|
|
132
|
+
sql = f"DELETE FROM {self._table_name}"
|
|
133
|
+
|
|
134
|
+
try:
|
|
135
|
+
async with self._config.provide_connection() as conn:
|
|
136
|
+
cursor = await conn.cursor()
|
|
137
|
+
try:
|
|
138
|
+
await cursor.execute(sql)
|
|
139
|
+
finally:
|
|
140
|
+
await cursor.close()
|
|
141
|
+
await conn.commit()
|
|
142
|
+
self._log_delete_all()
|
|
143
|
+
except mysql.connector.Error as exc:
|
|
144
|
+
if "doesn't exist" in str(exc) or getattr(exc, "errno", None) == MYSQL_TABLE_NOT_FOUND_ERROR:
|
|
145
|
+
logger.debug("Table %s does not exist, skipping delete_all", self._table_name)
|
|
146
|
+
return
|
|
147
|
+
raise
|
|
148
|
+
|
|
149
|
+
async def exists(self, key: str) -> bool:
|
|
150
|
+
sql = f"""
|
|
151
|
+
SELECT 1 FROM {self._table_name}
|
|
152
|
+
WHERE session_id = %s
|
|
153
|
+
AND (expires_at IS NULL OR expires_at > UTC_TIMESTAMP(6))
|
|
154
|
+
"""
|
|
155
|
+
|
|
156
|
+
try:
|
|
157
|
+
async with self._config.provide_connection() as conn:
|
|
158
|
+
cursor = await conn.cursor()
|
|
159
|
+
try:
|
|
160
|
+
await cursor.execute(sql, (key,))
|
|
161
|
+
result = await cursor.fetchone()
|
|
162
|
+
finally:
|
|
163
|
+
await cursor.close()
|
|
164
|
+
return result is not None
|
|
165
|
+
except mysql.connector.Error as exc:
|
|
166
|
+
if "doesn't exist" in str(exc) or getattr(exc, "errno", None) == MYSQL_TABLE_NOT_FOUND_ERROR:
|
|
167
|
+
return False
|
|
168
|
+
raise
|
|
169
|
+
|
|
170
|
+
async def expires_in(self, key: str) -> "int | None":
|
|
171
|
+
sql = f"""
|
|
172
|
+
SELECT expires_at FROM {self._table_name}
|
|
173
|
+
WHERE session_id = %s
|
|
174
|
+
"""
|
|
175
|
+
|
|
176
|
+
async with self._config.provide_connection() as conn:
|
|
177
|
+
cursor = await conn.cursor()
|
|
178
|
+
try:
|
|
179
|
+
await cursor.execute(sql, (key,))
|
|
180
|
+
row = await cursor.fetchone()
|
|
181
|
+
finally:
|
|
182
|
+
await cursor.close()
|
|
183
|
+
|
|
184
|
+
if row is None or row[0] is None:
|
|
185
|
+
return None
|
|
186
|
+
|
|
187
|
+
expires_at_naive: datetime = cast("datetime", row[0])
|
|
188
|
+
expires_at_utc = expires_at_naive.replace(tzinfo=timezone.utc)
|
|
189
|
+
now = datetime.now(timezone.utc)
|
|
190
|
+
|
|
191
|
+
if expires_at_utc <= now:
|
|
192
|
+
return 0
|
|
193
|
+
|
|
194
|
+
delta = expires_at_utc - now
|
|
195
|
+
return int(delta.total_seconds())
|
|
196
|
+
|
|
197
|
+
async def delete_expired(self) -> int:
|
|
198
|
+
sql = f"DELETE FROM {self._table_name} WHERE expires_at <= UTC_TIMESTAMP(6)"
|
|
199
|
+
|
|
200
|
+
async with self._config.provide_connection() as conn:
|
|
201
|
+
cursor = await conn.cursor()
|
|
202
|
+
try:
|
|
203
|
+
await cursor.execute(sql)
|
|
204
|
+
await conn.commit()
|
|
205
|
+
count: int = cursor.rowcount
|
|
206
|
+
finally:
|
|
207
|
+
await cursor.close()
|
|
208
|
+
if count > 0:
|
|
209
|
+
self._log_delete_expired(count)
|
|
210
|
+
return count
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
class MysqlConnectorSyncStore(BaseSQLSpecStore["MysqlConnectorSyncConfig"]):
|
|
214
|
+
"""MySQL/MariaDB session store using mysql-connector sync driver."""
|
|
215
|
+
|
|
216
|
+
__slots__ = ()
|
|
217
|
+
|
|
218
|
+
def __init__(self, config: "MysqlConnectorSyncConfig") -> None:
|
|
219
|
+
super().__init__(config)
|
|
220
|
+
|
|
221
|
+
def _get_create_table_sql(self) -> str:
|
|
222
|
+
return f"""
|
|
223
|
+
CREATE TABLE IF NOT EXISTS {self._table_name} (
|
|
224
|
+
session_id VARCHAR(255) PRIMARY KEY,
|
|
225
|
+
data LONGBLOB NOT NULL,
|
|
226
|
+
expires_at DATETIME(6),
|
|
227
|
+
created_at DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6),
|
|
228
|
+
updated_at DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
|
229
|
+
INDEX idx_{self._table_name}_expires_at (expires_at)
|
|
230
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
231
|
+
"""
|
|
232
|
+
|
|
233
|
+
def _get_drop_table_sql(self) -> "list[str]":
|
|
234
|
+
return [
|
|
235
|
+
f"DROP INDEX idx_{self._table_name}_expires_at ON {self._table_name}",
|
|
236
|
+
f"DROP TABLE IF EXISTS {self._table_name}",
|
|
237
|
+
]
|
|
238
|
+
|
|
239
|
+
def _create_table(self) -> None:
|
|
240
|
+
sql = self._get_create_table_sql()
|
|
241
|
+
with self._config.provide_session() as driver:
|
|
242
|
+
driver.execute_script(sql)
|
|
243
|
+
driver.commit()
|
|
244
|
+
self._log_table_created()
|
|
245
|
+
|
|
246
|
+
async def create_table(self) -> None:
|
|
247
|
+
await async_(self._create_table)()
|
|
248
|
+
|
|
249
|
+
def _get(self, key: str, renew_for: "int | timedelta | None" = None) -> "bytes | None":
|
|
250
|
+
sql = f"""
|
|
251
|
+
SELECT data, expires_at FROM {self._table_name}
|
|
252
|
+
WHERE session_id = %s
|
|
253
|
+
AND (expires_at IS NULL OR expires_at > UTC_TIMESTAMP(6))
|
|
254
|
+
"""
|
|
255
|
+
|
|
256
|
+
try:
|
|
257
|
+
with self._config.provide_connection() as conn:
|
|
258
|
+
cursor = conn.cursor()
|
|
259
|
+
try:
|
|
260
|
+
cursor.execute(sql, (key,))
|
|
261
|
+
row = cursor.fetchone()
|
|
262
|
+
finally:
|
|
263
|
+
cursor.close()
|
|
264
|
+
|
|
265
|
+
if row is None:
|
|
266
|
+
return None
|
|
267
|
+
|
|
268
|
+
data_value: Any = row[0]
|
|
269
|
+
expires_at: Any = row[1]
|
|
270
|
+
|
|
271
|
+
if renew_for is not None and expires_at is not None:
|
|
272
|
+
new_expires_at = self._calculate_expires_at(renew_for)
|
|
273
|
+
if new_expires_at is not None:
|
|
274
|
+
naive_expires_at = new_expires_at.replace(tzinfo=None)
|
|
275
|
+
update_sql = f"""
|
|
276
|
+
UPDATE {self._table_name}
|
|
277
|
+
SET expires_at = %s, updated_at = UTC_TIMESTAMP(6)
|
|
278
|
+
WHERE session_id = %s
|
|
279
|
+
"""
|
|
280
|
+
update_cursor = conn.cursor()
|
|
281
|
+
try:
|
|
282
|
+
update_cursor.execute(update_sql, (naive_expires_at, key))
|
|
283
|
+
finally:
|
|
284
|
+
update_cursor.close()
|
|
285
|
+
conn.commit()
|
|
286
|
+
|
|
287
|
+
return bytes(cast("bytes", data_value))
|
|
288
|
+
except mysql.connector.Error as exc:
|
|
289
|
+
if "doesn't exist" in str(exc) or getattr(exc, "errno", None) == MYSQL_TABLE_NOT_FOUND_ERROR:
|
|
290
|
+
return None
|
|
291
|
+
raise
|
|
292
|
+
|
|
293
|
+
async def get(self, key: str, renew_for: "int | timedelta | None" = None) -> "bytes | None":
|
|
294
|
+
return await async_(self._get)(key, renew_for)
|
|
295
|
+
|
|
296
|
+
def _set(self, key: str, value: "str | bytes", expires_in: "int | timedelta | None" = None) -> None:
|
|
297
|
+
data = self._value_to_bytes(value)
|
|
298
|
+
expires_at = self._calculate_expires_at(expires_in)
|
|
299
|
+
naive_expires_at = expires_at.replace(tzinfo=None) if expires_at else None
|
|
300
|
+
|
|
301
|
+
sql = f"""
|
|
302
|
+
INSERT INTO {self._table_name} (session_id, data, expires_at)
|
|
303
|
+
VALUES (%s, %s, %s) AS new
|
|
304
|
+
ON DUPLICATE KEY UPDATE
|
|
305
|
+
data = new.data,
|
|
306
|
+
expires_at = new.expires_at,
|
|
307
|
+
updated_at = UTC_TIMESTAMP(6)
|
|
308
|
+
"""
|
|
309
|
+
|
|
310
|
+
with self._config.provide_connection() as conn:
|
|
311
|
+
cursor = conn.cursor()
|
|
312
|
+
try:
|
|
313
|
+
cursor.execute(sql, (key, data, naive_expires_at))
|
|
314
|
+
finally:
|
|
315
|
+
cursor.close()
|
|
316
|
+
conn.commit()
|
|
317
|
+
|
|
318
|
+
async def set(self, key: str, value: "str | bytes", expires_in: "int | timedelta | None" = None) -> None:
|
|
319
|
+
await async_(self._set)(key, value, expires_in)
|
|
320
|
+
|
|
321
|
+
def _delete(self, key: str) -> None:
|
|
322
|
+
sql = f"DELETE FROM {self._table_name} WHERE session_id = %s"
|
|
323
|
+
|
|
324
|
+
with self._config.provide_connection() as conn:
|
|
325
|
+
cursor = conn.cursor()
|
|
326
|
+
try:
|
|
327
|
+
cursor.execute(sql, (key,))
|
|
328
|
+
finally:
|
|
329
|
+
cursor.close()
|
|
330
|
+
conn.commit()
|
|
331
|
+
|
|
332
|
+
async def delete(self, key: str) -> None:
|
|
333
|
+
await async_(self._delete)(key)
|
|
334
|
+
|
|
335
|
+
def _delete_all(self) -> None:
|
|
336
|
+
sql = f"DELETE FROM {self._table_name}"
|
|
337
|
+
|
|
338
|
+
try:
|
|
339
|
+
with self._config.provide_connection() as conn:
|
|
340
|
+
cursor = conn.cursor()
|
|
341
|
+
try:
|
|
342
|
+
cursor.execute(sql)
|
|
343
|
+
finally:
|
|
344
|
+
cursor.close()
|
|
345
|
+
conn.commit()
|
|
346
|
+
self._log_delete_all()
|
|
347
|
+
except mysql.connector.Error as exc:
|
|
348
|
+
if "doesn't exist" in str(exc) or getattr(exc, "errno", None) == MYSQL_TABLE_NOT_FOUND_ERROR:
|
|
349
|
+
logger.debug("Table %s does not exist, skipping delete_all", self._table_name)
|
|
350
|
+
return
|
|
351
|
+
raise
|
|
352
|
+
|
|
353
|
+
async def delete_all(self) -> None:
|
|
354
|
+
await async_(self._delete_all)()
|
|
355
|
+
|
|
356
|
+
def _exists(self, key: str) -> bool:
|
|
357
|
+
sql = f"""
|
|
358
|
+
SELECT 1 FROM {self._table_name}
|
|
359
|
+
WHERE session_id = %s
|
|
360
|
+
AND (expires_at IS NULL OR expires_at > UTC_TIMESTAMP(6))
|
|
361
|
+
"""
|
|
362
|
+
|
|
363
|
+
try:
|
|
364
|
+
with self._config.provide_connection() as conn:
|
|
365
|
+
cursor = conn.cursor()
|
|
366
|
+
try:
|
|
367
|
+
cursor.execute(sql, (key,))
|
|
368
|
+
result = cursor.fetchone()
|
|
369
|
+
finally:
|
|
370
|
+
cursor.close()
|
|
371
|
+
return result is not None
|
|
372
|
+
except mysql.connector.Error as exc:
|
|
373
|
+
if "doesn't exist" in str(exc) or getattr(exc, "errno", None) == MYSQL_TABLE_NOT_FOUND_ERROR:
|
|
374
|
+
return False
|
|
375
|
+
raise
|
|
376
|
+
|
|
377
|
+
async def exists(self, key: str) -> bool:
|
|
378
|
+
return await async_(self._exists)(key)
|
|
379
|
+
|
|
380
|
+
def _expires_in(self, key: str) -> "int | None":
|
|
381
|
+
sql = f"""
|
|
382
|
+
SELECT expires_at FROM {self._table_name}
|
|
383
|
+
WHERE session_id = %s
|
|
384
|
+
"""
|
|
385
|
+
|
|
386
|
+
with self._config.provide_connection() as conn:
|
|
387
|
+
cursor = conn.cursor()
|
|
388
|
+
try:
|
|
389
|
+
cursor.execute(sql, (key,))
|
|
390
|
+
row = cursor.fetchone()
|
|
391
|
+
finally:
|
|
392
|
+
cursor.close()
|
|
393
|
+
|
|
394
|
+
if row is None or row[0] is None:
|
|
395
|
+
return None
|
|
396
|
+
|
|
397
|
+
expires_at_naive: datetime = cast("datetime", row[0])
|
|
398
|
+
expires_at_utc = expires_at_naive.replace(tzinfo=timezone.utc)
|
|
399
|
+
now = datetime.now(timezone.utc)
|
|
400
|
+
|
|
401
|
+
if expires_at_utc <= now:
|
|
402
|
+
return 0
|
|
403
|
+
|
|
404
|
+
delta = expires_at_utc - now
|
|
405
|
+
return int(delta.total_seconds())
|
|
406
|
+
|
|
407
|
+
async def expires_in(self, key: str) -> "int | None":
|
|
408
|
+
return await async_(self._expires_in)(key)
|
|
409
|
+
|
|
410
|
+
def _delete_expired(self) -> int:
|
|
411
|
+
sql = f"DELETE FROM {self._table_name} WHERE expires_at <= UTC_TIMESTAMP(6)"
|
|
412
|
+
|
|
413
|
+
with self._config.provide_connection() as conn:
|
|
414
|
+
cursor = conn.cursor()
|
|
415
|
+
try:
|
|
416
|
+
cursor.execute(sql)
|
|
417
|
+
conn.commit()
|
|
418
|
+
count: int = cursor.rowcount
|
|
419
|
+
finally:
|
|
420
|
+
cursor.close()
|
|
421
|
+
if count > 0:
|
|
422
|
+
self._log_delete_expired(count)
|
|
423
|
+
return count
|
|
424
|
+
|
|
425
|
+
async def delete_expired(self) -> int:
|
|
426
|
+
return await async_(self._delete_expired)()
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import sqlspec.adapters.oracledb._numpy_handlers as numpy_handlers
|
|
2
|
+
from sqlspec.adapters.oracledb._numpy_handlers import (
|
|
3
|
+
DTYPE_TO_ARRAY_CODE,
|
|
4
|
+
numpy_converter_in,
|
|
5
|
+
numpy_converter_out,
|
|
6
|
+
numpy_input_type_handler,
|
|
7
|
+
numpy_output_type_handler,
|
|
8
|
+
register_numpy_handlers,
|
|
9
|
+
)
|
|
10
|
+
from sqlspec.adapters.oracledb._typing import OracleAsyncConnection, OracleSyncConnection
|
|
11
|
+
from sqlspec.adapters.oracledb._uuid_handlers import (
|
|
12
|
+
register_uuid_handlers,
|
|
13
|
+
uuid_converter_in,
|
|
14
|
+
uuid_converter_out,
|
|
15
|
+
uuid_input_type_handler,
|
|
16
|
+
uuid_output_type_handler,
|
|
17
|
+
)
|
|
18
|
+
from sqlspec.adapters.oracledb.config import (
|
|
19
|
+
OracleAsyncConfig,
|
|
20
|
+
OracleConnectionParams,
|
|
21
|
+
OraclePoolParams,
|
|
22
|
+
OracleSyncConfig,
|
|
23
|
+
)
|
|
24
|
+
from sqlspec.adapters.oracledb.core import default_statement_config
|
|
25
|
+
from sqlspec.adapters.oracledb.driver import (
|
|
26
|
+
OracleAsyncCursor,
|
|
27
|
+
OracleAsyncDriver,
|
|
28
|
+
OracleAsyncExceptionHandler,
|
|
29
|
+
OracleSyncCursor,
|
|
30
|
+
OracleSyncDriver,
|
|
31
|
+
OracleSyncExceptionHandler,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
__all__ = (
|
|
35
|
+
"DTYPE_TO_ARRAY_CODE",
|
|
36
|
+
"OracleAsyncConfig",
|
|
37
|
+
"OracleAsyncConnection",
|
|
38
|
+
"OracleAsyncCursor",
|
|
39
|
+
"OracleAsyncDriver",
|
|
40
|
+
"OracleAsyncExceptionHandler",
|
|
41
|
+
"OracleConnectionParams",
|
|
42
|
+
"OraclePoolParams",
|
|
43
|
+
"OracleSyncConfig",
|
|
44
|
+
"OracleSyncConnection",
|
|
45
|
+
"OracleSyncCursor",
|
|
46
|
+
"OracleSyncDriver",
|
|
47
|
+
"OracleSyncExceptionHandler",
|
|
48
|
+
"default_statement_config",
|
|
49
|
+
"numpy_converter_in",
|
|
50
|
+
"numpy_converter_out",
|
|
51
|
+
"numpy_handlers",
|
|
52
|
+
"numpy_input_type_handler",
|
|
53
|
+
"numpy_output_type_handler",
|
|
54
|
+
"register_numpy_handlers",
|
|
55
|
+
"register_uuid_handlers",
|
|
56
|
+
"uuid_converter_in",
|
|
57
|
+
"uuid_converter_out",
|
|
58
|
+
"uuid_input_type_handler",
|
|
59
|
+
"uuid_output_type_handler",
|
|
60
|
+
)
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"""Oracle NumPy vector type handlers for VECTOR data type support.
|
|
2
|
+
|
|
3
|
+
Provides automatic conversion between NumPy arrays and Oracle VECTOR types
|
|
4
|
+
via connection type handlers. Requires Oracle Database 23ai or higher.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import array
|
|
8
|
+
from typing import TYPE_CHECKING, Any
|
|
9
|
+
|
|
10
|
+
from sqlspec.typing import NUMPY_INSTALLED
|
|
11
|
+
from sqlspec.utils.logging import get_logger
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from oracledb import AsyncConnection, AsyncCursor, Connection, Cursor
|
|
15
|
+
|
|
16
|
+
__all__ = (
|
|
17
|
+
"numpy_converter_in",
|
|
18
|
+
"numpy_converter_out",
|
|
19
|
+
"numpy_input_type_handler",
|
|
20
|
+
"numpy_output_type_handler",
|
|
21
|
+
"register_numpy_handlers",
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
logger = get_logger(__name__)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
DTYPE_TO_ARRAY_CODE: "dict[str, str]" = {"float64": "d", "float32": "f", "uint8": "B", "int8": "b"}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def numpy_converter_in(value: Any) -> "array.array[Any]":
|
|
32
|
+
"""Convert NumPy array to Oracle array for VECTOR insertion.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
value: NumPy ndarray to convert.
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
Python array.array compatible with Oracle VECTOR type.
|
|
39
|
+
|
|
40
|
+
Raises:
|
|
41
|
+
ImportError: If NumPy is not installed.
|
|
42
|
+
TypeError: If NumPy dtype is not supported for Oracle VECTOR.
|
|
43
|
+
"""
|
|
44
|
+
if not NUMPY_INSTALLED:
|
|
45
|
+
msg = "NumPy is not installed - cannot convert vectors"
|
|
46
|
+
raise ImportError(msg)
|
|
47
|
+
|
|
48
|
+
dtype_name = value.dtype.name
|
|
49
|
+
array_code = DTYPE_TO_ARRAY_CODE.get(dtype_name)
|
|
50
|
+
|
|
51
|
+
if not array_code:
|
|
52
|
+
supported = ", ".join(DTYPE_TO_ARRAY_CODE.keys())
|
|
53
|
+
msg = f"Unsupported NumPy dtype for Oracle VECTOR: {dtype_name}. Supported: {supported}"
|
|
54
|
+
raise TypeError(msg)
|
|
55
|
+
|
|
56
|
+
return array.array(array_code, value)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def numpy_converter_out(value: "array.array[Any]") -> Any:
|
|
60
|
+
"""Convert Oracle array to NumPy array for VECTOR retrieval.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
value: Oracle array.array from VECTOR column.
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
NumPy ndarray with appropriate dtype, or original value if NumPy not installed.
|
|
67
|
+
"""
|
|
68
|
+
if not NUMPY_INSTALLED:
|
|
69
|
+
return value
|
|
70
|
+
|
|
71
|
+
import numpy as np
|
|
72
|
+
|
|
73
|
+
return np.array(value, copy=True, dtype=value.typecode)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _input_type_handler(cursor: "Cursor | AsyncCursor", value: Any, arraysize: int) -> Any:
|
|
77
|
+
"""Oracle input type handler for NumPy arrays.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
cursor: Oracle cursor (sync or async).
|
|
81
|
+
value: Value being inserted.
|
|
82
|
+
arraysize: Array size for the cursor variable.
|
|
83
|
+
|
|
84
|
+
Returns:
|
|
85
|
+
Cursor variable with NumPy converter if value is ndarray, None otherwise.
|
|
86
|
+
"""
|
|
87
|
+
if not NUMPY_INSTALLED:
|
|
88
|
+
return None
|
|
89
|
+
|
|
90
|
+
import numpy as np
|
|
91
|
+
import oracledb
|
|
92
|
+
|
|
93
|
+
if isinstance(value, np.ndarray):
|
|
94
|
+
return cursor.var(oracledb.DB_TYPE_VECTOR, arraysize=arraysize, inconverter=numpy_converter_in)
|
|
95
|
+
return None
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def _output_type_handler(cursor: "Cursor | AsyncCursor", metadata: Any) -> Any:
|
|
99
|
+
"""Oracle output type handler for VECTOR columns.
|
|
100
|
+
|
|
101
|
+
Args:
|
|
102
|
+
cursor: Oracle cursor (sync or async).
|
|
103
|
+
metadata: Column metadata from Oracle.
|
|
104
|
+
|
|
105
|
+
Returns:
|
|
106
|
+
Cursor variable with NumPy converter if column is VECTOR, None otherwise.
|
|
107
|
+
"""
|
|
108
|
+
if not NUMPY_INSTALLED:
|
|
109
|
+
return None
|
|
110
|
+
|
|
111
|
+
import oracledb
|
|
112
|
+
|
|
113
|
+
if metadata.type_code is oracledb.DB_TYPE_VECTOR:
|
|
114
|
+
return cursor.var(metadata.type_code, arraysize=cursor.arraysize, outconverter=numpy_converter_out)
|
|
115
|
+
return None
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def numpy_input_type_handler(cursor: "Cursor | AsyncCursor", value: Any, arraysize: int) -> Any:
|
|
119
|
+
"""Public input type handler for NumPy arrays."""
|
|
120
|
+
return _input_type_handler(cursor, value, arraysize)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def numpy_output_type_handler(cursor: "Cursor | AsyncCursor", metadata: Any) -> Any:
|
|
124
|
+
"""Public output type handler for NumPy VECTOR columns."""
|
|
125
|
+
return _output_type_handler(cursor, metadata)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def register_numpy_handlers(connection: "Connection | AsyncConnection") -> None:
|
|
129
|
+
"""Register NumPy type handlers on Oracle connection.
|
|
130
|
+
|
|
131
|
+
Enables automatic conversion between NumPy arrays and Oracle VECTOR types.
|
|
132
|
+
Works for both sync and async connections.
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
connection: Oracle connection (sync or async).
|
|
136
|
+
"""
|
|
137
|
+
if not NUMPY_INSTALLED:
|
|
138
|
+
return
|
|
139
|
+
|
|
140
|
+
connection.inputtypehandler = numpy_input_type_handler
|
|
141
|
+
connection.outputtypehandler = numpy_output_type_handler
|