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,319 @@
|
|
|
1
|
+
"""Mock adapter compiled helpers.
|
|
2
|
+
|
|
3
|
+
This module provides utility functions for the mock adapter, reusing
|
|
4
|
+
SQLite-compatible helpers since mock uses SQLite as its execution backend.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from datetime import date, datetime
|
|
8
|
+
from decimal import Decimal
|
|
9
|
+
from typing import TYPE_CHECKING, Any, cast
|
|
10
|
+
|
|
11
|
+
from sqlspec.core import DriverParameterProfile, ParameterStyle, StatementConfig, build_statement_config_from_profile
|
|
12
|
+
from sqlspec.exceptions import (
|
|
13
|
+
CheckViolationError,
|
|
14
|
+
DatabaseConnectionError,
|
|
15
|
+
DataError,
|
|
16
|
+
ForeignKeyViolationError,
|
|
17
|
+
IntegrityError,
|
|
18
|
+
NotNullViolationError,
|
|
19
|
+
OperationalError,
|
|
20
|
+
SQLParsingError,
|
|
21
|
+
SQLSpecError,
|
|
22
|
+
UniqueViolationError,
|
|
23
|
+
)
|
|
24
|
+
from sqlspec.utils.serializers import from_json, to_json
|
|
25
|
+
from sqlspec.utils.type_converters import build_decimal_converter, build_time_iso_converter
|
|
26
|
+
from sqlspec.utils.type_guards import has_rowcount, has_sqlite_error
|
|
27
|
+
|
|
28
|
+
if TYPE_CHECKING:
|
|
29
|
+
from collections.abc import Callable, Mapping, Sequence
|
|
30
|
+
|
|
31
|
+
__all__ = (
|
|
32
|
+
"apply_driver_features",
|
|
33
|
+
"build_insert_statement",
|
|
34
|
+
"build_profile",
|
|
35
|
+
"build_statement_config",
|
|
36
|
+
"collect_rows",
|
|
37
|
+
"create_mapped_exception",
|
|
38
|
+
"default_statement_config",
|
|
39
|
+
"driver_profile",
|
|
40
|
+
"format_identifier",
|
|
41
|
+
"normalize_execute_many_parameters",
|
|
42
|
+
"normalize_execute_parameters",
|
|
43
|
+
"resolve_rowcount",
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
SQLITE_CONSTRAINT_UNIQUE_CODE = 2067
|
|
47
|
+
SQLITE_CONSTRAINT_FOREIGNKEY_CODE = 787
|
|
48
|
+
SQLITE_CONSTRAINT_NOTNULL_CODE = 1811
|
|
49
|
+
SQLITE_CONSTRAINT_CHECK_CODE = 531
|
|
50
|
+
SQLITE_CONSTRAINT_CODE = 19
|
|
51
|
+
SQLITE_CANTOPEN_CODE = 14
|
|
52
|
+
SQLITE_IOERR_CODE = 10
|
|
53
|
+
SQLITE_MISMATCH_CODE = 20
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
_TIME_TO_ISO = build_time_iso_converter()
|
|
57
|
+
_DECIMAL_TO_STRING = build_decimal_converter(mode="string")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _bool_to_int(value: bool) -> int:
|
|
61
|
+
return int(value)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _quote_sqlite_identifier(identifier: str) -> str:
|
|
65
|
+
normalized = identifier.replace('"', '""')
|
|
66
|
+
return f'"{normalized}"'
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def format_identifier(identifier: str) -> str:
|
|
70
|
+
"""Format an identifier for SQLite.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
identifier: Table or column name to format.
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
Properly quoted identifier.
|
|
77
|
+
|
|
78
|
+
Raises:
|
|
79
|
+
SQLSpecError: If identifier is empty.
|
|
80
|
+
"""
|
|
81
|
+
cleaned = identifier.strip()
|
|
82
|
+
if not cleaned:
|
|
83
|
+
msg = "Table name must not be empty"
|
|
84
|
+
raise SQLSpecError(msg)
|
|
85
|
+
|
|
86
|
+
if "." not in cleaned:
|
|
87
|
+
return _quote_sqlite_identifier(cleaned)
|
|
88
|
+
|
|
89
|
+
return ".".join(_quote_sqlite_identifier(part) for part in cleaned.split(".") if part)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def build_insert_statement(table: str, columns: "list[str]") -> str:
|
|
93
|
+
"""Build an INSERT statement for the given table and columns.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
table: Table name.
|
|
97
|
+
columns: List of column names.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
INSERT SQL statement.
|
|
101
|
+
"""
|
|
102
|
+
column_clause = ", ".join(_quote_sqlite_identifier(column) for column in columns)
|
|
103
|
+
placeholders = ", ".join("?" for _ in columns)
|
|
104
|
+
return f"INSERT INTO {format_identifier(table)} ({column_clause}) VALUES ({placeholders})"
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def collect_rows(
|
|
108
|
+
fetched_data: "list[Any]", description: "Sequence[Any] | None"
|
|
109
|
+
) -> "tuple[list[dict[str, Any]], list[str], int]":
|
|
110
|
+
"""Collect SQLite result rows into dictionaries.
|
|
111
|
+
|
|
112
|
+
Args:
|
|
113
|
+
fetched_data: Raw rows from cursor.fetchall()
|
|
114
|
+
description: Cursor description (tuple of tuples)
|
|
115
|
+
|
|
116
|
+
Returns:
|
|
117
|
+
Tuple of (data, column_names, row_count)
|
|
118
|
+
"""
|
|
119
|
+
if not description:
|
|
120
|
+
return [], [], 0
|
|
121
|
+
|
|
122
|
+
column_names = [col[0] for col in description]
|
|
123
|
+
data = [dict(zip(column_names, row, strict=False)) for row in fetched_data]
|
|
124
|
+
return data, column_names, len(data)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def resolve_rowcount(cursor: Any) -> int:
|
|
128
|
+
"""Resolve rowcount from a SQLite cursor.
|
|
129
|
+
|
|
130
|
+
Args:
|
|
131
|
+
cursor: SQLite cursor with optional rowcount metadata.
|
|
132
|
+
|
|
133
|
+
Returns:
|
|
134
|
+
Positive rowcount value or 0 when unknown.
|
|
135
|
+
"""
|
|
136
|
+
if not has_rowcount(cursor):
|
|
137
|
+
return 0
|
|
138
|
+
rowcount = cursor.rowcount
|
|
139
|
+
if isinstance(rowcount, int) and rowcount > 0:
|
|
140
|
+
return rowcount
|
|
141
|
+
return 0
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def normalize_execute_parameters(parameters: Any) -> Any:
|
|
145
|
+
"""Normalize parameters for SQLite execute calls.
|
|
146
|
+
|
|
147
|
+
Args:
|
|
148
|
+
parameters: Prepared parameters payload.
|
|
149
|
+
|
|
150
|
+
Returns:
|
|
151
|
+
Normalized parameters payload.
|
|
152
|
+
"""
|
|
153
|
+
return parameters or ()
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def normalize_execute_many_parameters(parameters: Any) -> Any:
|
|
157
|
+
"""Normalize parameters for SQLite executemany calls.
|
|
158
|
+
|
|
159
|
+
Args:
|
|
160
|
+
parameters: Prepared parameters payload.
|
|
161
|
+
|
|
162
|
+
Returns:
|
|
163
|
+
Normalized parameters payload.
|
|
164
|
+
|
|
165
|
+
Raises:
|
|
166
|
+
ValueError: When parameters are missing for executemany.
|
|
167
|
+
"""
|
|
168
|
+
if not parameters:
|
|
169
|
+
msg = "execute_many requires parameters"
|
|
170
|
+
raise ValueError(msg)
|
|
171
|
+
return parameters
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def _create_sqlite_error(
|
|
175
|
+
error: Any, code: "int | None", error_class: type[SQLSpecError], description: str
|
|
176
|
+
) -> SQLSpecError:
|
|
177
|
+
"""Create a SQLite error instance without raising it."""
|
|
178
|
+
code_str = f"[code {code}]" if code else ""
|
|
179
|
+
msg = f"SQLite {description} {code_str}: {error}" if code_str else f"SQLite {description}: {error}"
|
|
180
|
+
exc = error_class(msg)
|
|
181
|
+
exc.__cause__ = cast("BaseException", error)
|
|
182
|
+
return exc
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def create_mapped_exception(error: BaseException) -> SQLSpecError:
|
|
186
|
+
"""Map SQLite errors to SQLSpec exceptions.
|
|
187
|
+
|
|
188
|
+
This is a factory function that returns an exception instance rather than
|
|
189
|
+
raising. This pattern is more robust for use in __exit__ handlers and
|
|
190
|
+
avoids issues with exception control flow in different Python versions.
|
|
191
|
+
|
|
192
|
+
Args:
|
|
193
|
+
error: The SQLite exception to map
|
|
194
|
+
|
|
195
|
+
Returns:
|
|
196
|
+
A SQLSpec exception that wraps the original error
|
|
197
|
+
"""
|
|
198
|
+
if has_sqlite_error(error):
|
|
199
|
+
error_code = error.sqlite_errorcode
|
|
200
|
+
error_name = error.sqlite_errorname
|
|
201
|
+
else:
|
|
202
|
+
error_code = None
|
|
203
|
+
error_name = None
|
|
204
|
+
error_msg = str(error).lower()
|
|
205
|
+
|
|
206
|
+
if "locked" in error_msg:
|
|
207
|
+
return _create_sqlite_error(error, error_code or 0, OperationalError, "operational error")
|
|
208
|
+
|
|
209
|
+
if not error_code:
|
|
210
|
+
if "unique constraint" in error_msg:
|
|
211
|
+
return _create_sqlite_error(error, 0, UniqueViolationError, "unique constraint violation")
|
|
212
|
+
if "foreign key constraint" in error_msg:
|
|
213
|
+
return _create_sqlite_error(error, 0, ForeignKeyViolationError, "foreign key constraint violation")
|
|
214
|
+
if "not null constraint" in error_msg:
|
|
215
|
+
return _create_sqlite_error(error, 0, NotNullViolationError, "not-null constraint violation")
|
|
216
|
+
if "check constraint" in error_msg:
|
|
217
|
+
return _create_sqlite_error(error, 0, CheckViolationError, "check constraint violation")
|
|
218
|
+
if "syntax" in error_msg:
|
|
219
|
+
return _create_sqlite_error(error, None, SQLParsingError, "SQL syntax error")
|
|
220
|
+
return _create_sqlite_error(error, None, SQLSpecError, "database error")
|
|
221
|
+
|
|
222
|
+
if error_code == SQLITE_CONSTRAINT_UNIQUE_CODE or error_name == "SQLITE_CONSTRAINT_UNIQUE":
|
|
223
|
+
return _create_sqlite_error(error, error_code, UniqueViolationError, "unique constraint violation")
|
|
224
|
+
if error_code == SQLITE_CONSTRAINT_FOREIGNKEY_CODE or error_name == "SQLITE_CONSTRAINT_FOREIGNKEY":
|
|
225
|
+
return _create_sqlite_error(error, error_code, ForeignKeyViolationError, "foreign key constraint violation")
|
|
226
|
+
if error_code == SQLITE_CONSTRAINT_NOTNULL_CODE or error_name == "SQLITE_CONSTRAINT_NOTNULL":
|
|
227
|
+
return _create_sqlite_error(error, error_code, NotNullViolationError, "not-null constraint violation")
|
|
228
|
+
if error_code == SQLITE_CONSTRAINT_CHECK_CODE or error_name == "SQLITE_CONSTRAINT_CHECK":
|
|
229
|
+
return _create_sqlite_error(error, error_code, CheckViolationError, "check constraint violation")
|
|
230
|
+
if error_code == SQLITE_CONSTRAINT_CODE or error_name == "SQLITE_CONSTRAINT":
|
|
231
|
+
return _create_sqlite_error(error, error_code, IntegrityError, "integrity constraint violation")
|
|
232
|
+
if error_code == SQLITE_CANTOPEN_CODE or error_name == "SQLITE_CANTOPEN":
|
|
233
|
+
return _create_sqlite_error(error, error_code, DatabaseConnectionError, "connection error")
|
|
234
|
+
if error_code == SQLITE_IOERR_CODE or error_name == "SQLITE_IOERR":
|
|
235
|
+
return _create_sqlite_error(error, error_code, OperationalError, "operational error")
|
|
236
|
+
if error_code == SQLITE_MISMATCH_CODE or error_name == "SQLITE_MISMATCH":
|
|
237
|
+
return _create_sqlite_error(error, error_code, DataError, "data error")
|
|
238
|
+
if error_code == 1 or "syntax" in error_msg:
|
|
239
|
+
return _create_sqlite_error(error, error_code, SQLParsingError, "SQL syntax error")
|
|
240
|
+
return _create_sqlite_error(error, error_code, SQLSpecError, "database error")
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def build_profile() -> "DriverParameterProfile":
|
|
244
|
+
"""Create the Mock driver parameter profile.
|
|
245
|
+
|
|
246
|
+
Returns:
|
|
247
|
+
Driver parameter profile for Mock adapter.
|
|
248
|
+
"""
|
|
249
|
+
return DriverParameterProfile(
|
|
250
|
+
name="Mock",
|
|
251
|
+
default_style=ParameterStyle.QMARK,
|
|
252
|
+
supported_styles={ParameterStyle.QMARK, ParameterStyle.NAMED_COLON},
|
|
253
|
+
default_execution_style=ParameterStyle.QMARK,
|
|
254
|
+
supported_execution_styles={ParameterStyle.QMARK, ParameterStyle.NAMED_COLON},
|
|
255
|
+
has_native_list_expansion=False,
|
|
256
|
+
preserve_parameter_format=True,
|
|
257
|
+
needs_static_script_compilation=False,
|
|
258
|
+
allow_mixed_parameter_styles=False,
|
|
259
|
+
preserve_original_params_for_many=False,
|
|
260
|
+
json_serializer_strategy="helper",
|
|
261
|
+
custom_type_coercions={
|
|
262
|
+
bool: _bool_to_int,
|
|
263
|
+
datetime: _TIME_TO_ISO,
|
|
264
|
+
date: _TIME_TO_ISO,
|
|
265
|
+
Decimal: _DECIMAL_TO_STRING,
|
|
266
|
+
},
|
|
267
|
+
default_dialect="sqlite",
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
driver_profile = build_profile()
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
def build_statement_config(
|
|
275
|
+
*, json_serializer: "Callable[[Any], str] | None" = None, json_deserializer: "Callable[[str], Any] | None" = None
|
|
276
|
+
) -> "StatementConfig":
|
|
277
|
+
"""Construct the Mock statement configuration with optional JSON codecs.
|
|
278
|
+
|
|
279
|
+
Args:
|
|
280
|
+
json_serializer: Custom JSON serializer function.
|
|
281
|
+
json_deserializer: Custom JSON deserializer function.
|
|
282
|
+
|
|
283
|
+
Returns:
|
|
284
|
+
StatementConfig for Mock adapter.
|
|
285
|
+
"""
|
|
286
|
+
serializer = json_serializer or to_json
|
|
287
|
+
deserializer = json_deserializer or from_json
|
|
288
|
+
profile = driver_profile
|
|
289
|
+
return build_statement_config_from_profile(
|
|
290
|
+
profile, statement_overrides={"dialect": "sqlite"}, json_serializer=serializer, json_deserializer=deserializer
|
|
291
|
+
)
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
default_statement_config = build_statement_config()
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
def apply_driver_features(
|
|
298
|
+
statement_config: "StatementConfig", driver_features: "Mapping[str, Any] | None"
|
|
299
|
+
) -> "tuple[StatementConfig, dict[str, Any]]":
|
|
300
|
+
"""Apply Mock driver feature defaults to statement config.
|
|
301
|
+
|
|
302
|
+
Args:
|
|
303
|
+
statement_config: Base statement configuration.
|
|
304
|
+
driver_features: Driver feature overrides.
|
|
305
|
+
|
|
306
|
+
Returns:
|
|
307
|
+
Tuple of (updated statement config, driver features dict).
|
|
308
|
+
"""
|
|
309
|
+
features: dict[str, Any] = dict(driver_features) if driver_features else {}
|
|
310
|
+
json_serializer = features.setdefault("json_serializer", to_json)
|
|
311
|
+
json_deserializer = features.setdefault("json_deserializer", from_json)
|
|
312
|
+
|
|
313
|
+
if json_serializer is not None:
|
|
314
|
+
parameter_config = statement_config.parameter_config.with_json_serializers(
|
|
315
|
+
json_serializer, deserializer=json_deserializer
|
|
316
|
+
)
|
|
317
|
+
statement_config = statement_config.replace(parameter_config=parameter_config)
|
|
318
|
+
|
|
319
|
+
return statement_config, features
|
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
"""Mock-specific data dictionary for metadata queries.
|
|
2
|
+
|
|
3
|
+
This module provides data dictionary functionality for the mock adapter,
|
|
4
|
+
delegating to SQLite's catalog since mock uses SQLite as its execution backend.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import TYPE_CHECKING, ClassVar
|
|
8
|
+
|
|
9
|
+
from mypy_extensions import mypyc_attr
|
|
10
|
+
|
|
11
|
+
from sqlspec.adapters.mock.core import format_identifier
|
|
12
|
+
from sqlspec.driver import AsyncDataDictionaryBase, SyncDataDictionaryBase
|
|
13
|
+
from sqlspec.typing import ColumnMetadata, ForeignKeyMetadata, IndexMetadata, TableMetadata, VersionInfo
|
|
14
|
+
|
|
15
|
+
__all__ = ("MockAsyncDataDictionary", "MockDataDictionary")
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from sqlspec.adapters.mock.driver import MockAsyncDriver, MockSyncDriver
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@mypyc_attr(allow_interpreted_subclasses=True, native_class=False)
|
|
22
|
+
class MockDataDictionary(SyncDataDictionaryBase):
|
|
23
|
+
"""Mock-specific sync data dictionary.
|
|
24
|
+
|
|
25
|
+
Delegates metadata queries to SQLite's catalog (sqlite_master, PRAGMA table_info).
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
dialect: ClassVar[str] = "sqlite"
|
|
29
|
+
|
|
30
|
+
def __init__(self) -> None:
|
|
31
|
+
super().__init__()
|
|
32
|
+
|
|
33
|
+
def get_version(self, driver: "MockSyncDriver") -> "VersionInfo | None":
|
|
34
|
+
"""Get SQLite database version information.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
driver: Sync database driver instance.
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
SQLite version information or None if detection fails.
|
|
41
|
+
"""
|
|
42
|
+
driver_id = id(driver)
|
|
43
|
+
# Inline cache check to avoid cross-module method call that causes mypyc segfault
|
|
44
|
+
if driver_id in self._version_fetch_attempted:
|
|
45
|
+
return self._version_cache.get(driver_id)
|
|
46
|
+
# Not cached, fetch from database
|
|
47
|
+
|
|
48
|
+
version_value = driver.select_value_or_none(self.get_query("version"))
|
|
49
|
+
if not version_value:
|
|
50
|
+
self._log_version_unavailable(type(self).dialect, "missing")
|
|
51
|
+
self.cache_version(driver_id, None)
|
|
52
|
+
return None
|
|
53
|
+
|
|
54
|
+
version_info = self.parse_version_with_pattern(self.get_dialect_config().version_pattern, str(version_value))
|
|
55
|
+
if version_info is None:
|
|
56
|
+
self._log_version_unavailable(type(self).dialect, "parse_failed")
|
|
57
|
+
self.cache_version(driver_id, None)
|
|
58
|
+
return None
|
|
59
|
+
|
|
60
|
+
self._log_version_detected(type(self).dialect, version_info)
|
|
61
|
+
self.cache_version(driver_id, version_info)
|
|
62
|
+
return version_info
|
|
63
|
+
|
|
64
|
+
def get_feature_flag(self, driver: "MockSyncDriver", feature: str) -> bool:
|
|
65
|
+
"""Check if SQLite database supports a specific feature.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
driver: Sync database driver instance.
|
|
69
|
+
feature: Feature name to check.
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
True if feature is supported, False otherwise.
|
|
73
|
+
"""
|
|
74
|
+
version_info = self.get_version(driver)
|
|
75
|
+
return self.resolve_feature_flag(feature, version_info)
|
|
76
|
+
|
|
77
|
+
def get_optimal_type(self, driver: "MockSyncDriver", type_category: str) -> str:
|
|
78
|
+
"""Get optimal SQLite type for a category.
|
|
79
|
+
|
|
80
|
+
Args:
|
|
81
|
+
driver: Sync database driver instance.
|
|
82
|
+
type_category: Type category.
|
|
83
|
+
|
|
84
|
+
Returns:
|
|
85
|
+
SQLite-specific type name.
|
|
86
|
+
"""
|
|
87
|
+
config = self.get_dialect_config()
|
|
88
|
+
version_info = self.get_version(driver)
|
|
89
|
+
|
|
90
|
+
if type_category == "json":
|
|
91
|
+
json_version = config.get_feature_version("supports_json")
|
|
92
|
+
if version_info and json_version and version_info >= json_version:
|
|
93
|
+
return "JSON"
|
|
94
|
+
return "TEXT"
|
|
95
|
+
|
|
96
|
+
return config.get_optimal_type(type_category)
|
|
97
|
+
|
|
98
|
+
def get_tables(self, driver: "MockSyncDriver", schema: "str | None" = None) -> "list[TableMetadata]":
|
|
99
|
+
"""Get tables sorted by topological dependency order using SQLite catalog."""
|
|
100
|
+
schema_name = self.resolve_schema(schema)
|
|
101
|
+
self._log_schema_introspect(driver, schema_name=schema_name, table_name=None, operation="tables")
|
|
102
|
+
schema_prefix = f"{format_identifier(schema_name)}." if schema_name else ""
|
|
103
|
+
query_text = self.get_query_text("tables_by_schema").format(schema_prefix=schema_prefix)
|
|
104
|
+
return driver.select(query_text, schema_type=TableMetadata)
|
|
105
|
+
|
|
106
|
+
def get_columns(
|
|
107
|
+
self, driver: "MockSyncDriver", table: "str | None" = None, schema: "str | None" = None
|
|
108
|
+
) -> "list[ColumnMetadata]":
|
|
109
|
+
"""Get column information for a table or schema."""
|
|
110
|
+
schema_name = self.resolve_schema(schema)
|
|
111
|
+
schema_prefix = f"{format_identifier(schema_name)}." if schema_name else ""
|
|
112
|
+
if table is None:
|
|
113
|
+
self._log_schema_introspect(driver, schema_name=schema_name, table_name=None, operation="columns")
|
|
114
|
+
query_text = self.get_query_text("columns_by_schema").format(schema_prefix=schema_prefix)
|
|
115
|
+
return driver.select(query_text, schema_type=ColumnMetadata)
|
|
116
|
+
|
|
117
|
+
assert table is not None
|
|
118
|
+
self._log_table_describe(driver, schema_name=schema_name, table_name=table, operation="columns")
|
|
119
|
+
table_name = table
|
|
120
|
+
table_identifier = f"{schema_name}.{table_name}" if schema_name else table_name
|
|
121
|
+
query_text = self.get_query_text("columns_by_table").format(table_name=format_identifier(table_identifier))
|
|
122
|
+
return driver.select(query_text, schema_type=ColumnMetadata)
|
|
123
|
+
|
|
124
|
+
def get_indexes(
|
|
125
|
+
self, driver: "MockSyncDriver", table: "str | None" = None, schema: "str | None" = None
|
|
126
|
+
) -> "list[IndexMetadata]":
|
|
127
|
+
"""Get index metadata for a table or schema."""
|
|
128
|
+
schema_name = self.resolve_schema(schema)
|
|
129
|
+
indexes: list[IndexMetadata] = []
|
|
130
|
+
if table is None:
|
|
131
|
+
self._log_schema_introspect(driver, schema_name=schema_name, table_name=None, operation="indexes")
|
|
132
|
+
for table_info in self.get_tables(driver, schema=schema_name):
|
|
133
|
+
table_name = table_info.get("table_name")
|
|
134
|
+
if not table_name:
|
|
135
|
+
continue
|
|
136
|
+
indexes.extend(self.get_indexes(driver, table=table_name, schema=schema_name))
|
|
137
|
+
return indexes
|
|
138
|
+
|
|
139
|
+
assert table is not None
|
|
140
|
+
self._log_table_describe(driver, schema_name=schema_name, table_name=table, operation="indexes")
|
|
141
|
+
table_name = table
|
|
142
|
+
table_identifier = f"{schema_name}.{table_name}" if schema_name else table_name
|
|
143
|
+
index_list_sql = self.get_query_text("indexes_by_table").format(table_name=format_identifier(table_identifier))
|
|
144
|
+
index_rows = driver.select(index_list_sql)
|
|
145
|
+
for row in index_rows:
|
|
146
|
+
index_name = row.get("name")
|
|
147
|
+
if not index_name:
|
|
148
|
+
continue
|
|
149
|
+
index_identifier = f"{schema_name}.{index_name}" if schema_name else index_name
|
|
150
|
+
columns_sql = self.get_query_text("index_columns_by_index").format(
|
|
151
|
+
index_name=format_identifier(index_identifier)
|
|
152
|
+
)
|
|
153
|
+
columns_rows = driver.select(columns_sql)
|
|
154
|
+
columns: list[str] = []
|
|
155
|
+
for col in columns_rows:
|
|
156
|
+
column_name = col.get("name")
|
|
157
|
+
if column_name is None:
|
|
158
|
+
continue
|
|
159
|
+
columns.append(str(column_name))
|
|
160
|
+
is_primary = row.get("origin") == "pk"
|
|
161
|
+
index_metadata: IndexMetadata = {
|
|
162
|
+
"index_name": index_name,
|
|
163
|
+
"table_name": table_name,
|
|
164
|
+
"columns": columns,
|
|
165
|
+
"is_primary": is_primary,
|
|
166
|
+
}
|
|
167
|
+
if schema_name is not None:
|
|
168
|
+
index_metadata["schema_name"] = schema_name
|
|
169
|
+
unique_value = row.get("unique")
|
|
170
|
+
if unique_value is not None:
|
|
171
|
+
index_metadata["is_unique"] = unique_value
|
|
172
|
+
indexes.append(index_metadata)
|
|
173
|
+
return indexes
|
|
174
|
+
|
|
175
|
+
def get_foreign_keys(
|
|
176
|
+
self, driver: "MockSyncDriver", table: "str | None" = None, schema: "str | None" = None
|
|
177
|
+
) -> "list[ForeignKeyMetadata]":
|
|
178
|
+
"""Get foreign key metadata."""
|
|
179
|
+
schema_name = self.resolve_schema(schema)
|
|
180
|
+
schema_prefix = f"{format_identifier(schema_name)}." if schema_name else ""
|
|
181
|
+
if table is None:
|
|
182
|
+
self._log_schema_introspect(driver, schema_name=schema_name, table_name=None, operation="foreign_keys")
|
|
183
|
+
query_text = self.get_query_text("foreign_keys_by_schema").format(schema_prefix=schema_prefix)
|
|
184
|
+
return driver.select(query_text, schema_type=ForeignKeyMetadata)
|
|
185
|
+
|
|
186
|
+
self._log_table_describe(driver, schema_name=schema_name, table_name=table, operation="foreign_keys")
|
|
187
|
+
table_label = table.replace("'", "''")
|
|
188
|
+
table_identifier = f"{schema_name}.{table}" if schema_name else table
|
|
189
|
+
query_text = self.get_query_text("foreign_keys_by_table").format(
|
|
190
|
+
table_name=format_identifier(table_identifier), table_label=table_label
|
|
191
|
+
)
|
|
192
|
+
return driver.select(query_text, schema_type=ForeignKeyMetadata)
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
@mypyc_attr(allow_interpreted_subclasses=True, native_class=False)
|
|
196
|
+
class MockAsyncDataDictionary(AsyncDataDictionaryBase):
|
|
197
|
+
"""Mock-specific async data dictionary.
|
|
198
|
+
|
|
199
|
+
Delegates metadata queries to SQLite's catalog (sqlite_master, PRAGMA table_info).
|
|
200
|
+
"""
|
|
201
|
+
|
|
202
|
+
dialect: ClassVar[str] = "sqlite"
|
|
203
|
+
|
|
204
|
+
def __init__(self) -> None:
|
|
205
|
+
super().__init__()
|
|
206
|
+
|
|
207
|
+
async def get_version(self, driver: "MockAsyncDriver") -> "VersionInfo | None":
|
|
208
|
+
"""Get SQLite database version information.
|
|
209
|
+
|
|
210
|
+
Args:
|
|
211
|
+
driver: Async database driver instance.
|
|
212
|
+
|
|
213
|
+
Returns:
|
|
214
|
+
SQLite version information or None if detection fails.
|
|
215
|
+
"""
|
|
216
|
+
driver_id = id(driver)
|
|
217
|
+
# Inline cache check to avoid cross-module method call that causes mypyc segfault
|
|
218
|
+
if driver_id in self._version_fetch_attempted:
|
|
219
|
+
return self._version_cache.get(driver_id)
|
|
220
|
+
# Not cached, fetch from database
|
|
221
|
+
|
|
222
|
+
version_value = await driver.select_value_or_none(self.get_query("version"))
|
|
223
|
+
if not version_value:
|
|
224
|
+
self._log_version_unavailable(type(self).dialect, "missing")
|
|
225
|
+
self.cache_version(driver_id, None)
|
|
226
|
+
return None
|
|
227
|
+
|
|
228
|
+
version_info = self.parse_version_with_pattern(self.get_dialect_config().version_pattern, str(version_value))
|
|
229
|
+
if version_info is None:
|
|
230
|
+
self._log_version_unavailable(type(self).dialect, "parse_failed")
|
|
231
|
+
self.cache_version(driver_id, None)
|
|
232
|
+
return None
|
|
233
|
+
|
|
234
|
+
self._log_version_detected(type(self).dialect, version_info)
|
|
235
|
+
self.cache_version(driver_id, version_info)
|
|
236
|
+
return version_info
|
|
237
|
+
|
|
238
|
+
async def get_feature_flag(self, driver: "MockAsyncDriver", feature: str) -> bool:
|
|
239
|
+
"""Check if SQLite database supports a specific feature.
|
|
240
|
+
|
|
241
|
+
Args:
|
|
242
|
+
driver: Async database driver instance.
|
|
243
|
+
feature: Feature name to check.
|
|
244
|
+
|
|
245
|
+
Returns:
|
|
246
|
+
True if feature is supported, False otherwise.
|
|
247
|
+
"""
|
|
248
|
+
version_info = await self.get_version(driver)
|
|
249
|
+
return self.resolve_feature_flag(feature, version_info)
|
|
250
|
+
|
|
251
|
+
async def get_optimal_type(self, driver: "MockAsyncDriver", type_category: str) -> str:
|
|
252
|
+
"""Get optimal SQLite type for a category.
|
|
253
|
+
|
|
254
|
+
Args:
|
|
255
|
+
driver: Async database driver instance.
|
|
256
|
+
type_category: Type category.
|
|
257
|
+
|
|
258
|
+
Returns:
|
|
259
|
+
SQLite-specific type name.
|
|
260
|
+
"""
|
|
261
|
+
config = self.get_dialect_config()
|
|
262
|
+
version_info = await self.get_version(driver)
|
|
263
|
+
|
|
264
|
+
if type_category == "json":
|
|
265
|
+
json_version = config.get_feature_version("supports_json")
|
|
266
|
+
if version_info and json_version and version_info >= json_version:
|
|
267
|
+
return "JSON"
|
|
268
|
+
return "TEXT"
|
|
269
|
+
|
|
270
|
+
return config.get_optimal_type(type_category)
|
|
271
|
+
|
|
272
|
+
async def get_tables(self, driver: "MockAsyncDriver", schema: "str | None" = None) -> "list[TableMetadata]":
|
|
273
|
+
"""Get tables sorted by topological dependency order using SQLite catalog."""
|
|
274
|
+
schema_name = self.resolve_schema(schema)
|
|
275
|
+
self._log_schema_introspect(driver, schema_name=schema_name, table_name=None, operation="tables")
|
|
276
|
+
schema_prefix = f"{format_identifier(schema_name)}." if schema_name else ""
|
|
277
|
+
query_text = self.get_query_text("tables_by_schema").format(schema_prefix=schema_prefix)
|
|
278
|
+
return await driver.select(query_text, schema_type=TableMetadata)
|
|
279
|
+
|
|
280
|
+
async def get_columns(
|
|
281
|
+
self, driver: "MockAsyncDriver", table: "str | None" = None, schema: "str | None" = None
|
|
282
|
+
) -> "list[ColumnMetadata]":
|
|
283
|
+
"""Get column information for a table or schema."""
|
|
284
|
+
schema_name = self.resolve_schema(schema)
|
|
285
|
+
schema_prefix = f"{format_identifier(schema_name)}." if schema_name else ""
|
|
286
|
+
if table is None:
|
|
287
|
+
self._log_schema_introspect(driver, schema_name=schema_name, table_name=None, operation="columns")
|
|
288
|
+
query_text = self.get_query_text("columns_by_schema").format(schema_prefix=schema_prefix)
|
|
289
|
+
return await driver.select(query_text, schema_type=ColumnMetadata)
|
|
290
|
+
|
|
291
|
+
assert table is not None
|
|
292
|
+
self._log_table_describe(driver, schema_name=schema_name, table_name=table, operation="columns")
|
|
293
|
+
table_name = table
|
|
294
|
+
table_identifier = f"{schema_name}.{table_name}" if schema_name else table_name
|
|
295
|
+
query_text = self.get_query_text("columns_by_table").format(table_name=format_identifier(table_identifier))
|
|
296
|
+
return await driver.select(query_text, schema_type=ColumnMetadata)
|
|
297
|
+
|
|
298
|
+
async def get_indexes(
|
|
299
|
+
self, driver: "MockAsyncDriver", table: "str | None" = None, schema: "str | None" = None
|
|
300
|
+
) -> "list[IndexMetadata]":
|
|
301
|
+
"""Get index metadata for a table or schema."""
|
|
302
|
+
schema_name = self.resolve_schema(schema)
|
|
303
|
+
indexes: list[IndexMetadata] = []
|
|
304
|
+
if table is None:
|
|
305
|
+
self._log_schema_introspect(driver, schema_name=schema_name, table_name=None, operation="indexes")
|
|
306
|
+
for table_info in await self.get_tables(driver, schema=schema_name):
|
|
307
|
+
table_name = table_info.get("table_name")
|
|
308
|
+
if not table_name:
|
|
309
|
+
continue
|
|
310
|
+
indexes.extend(await self.get_indexes(driver, table=table_name, schema=schema_name))
|
|
311
|
+
return indexes
|
|
312
|
+
|
|
313
|
+
assert table is not None
|
|
314
|
+
self._log_table_describe(driver, schema_name=schema_name, table_name=table, operation="indexes")
|
|
315
|
+
table_name = table
|
|
316
|
+
table_identifier = f"{schema_name}.{table_name}" if schema_name else table_name
|
|
317
|
+
index_list_sql = self.get_query_text("indexes_by_table").format(table_name=format_identifier(table_identifier))
|
|
318
|
+
index_rows = await driver.select(index_list_sql)
|
|
319
|
+
for row in index_rows:
|
|
320
|
+
index_name = row.get("name")
|
|
321
|
+
if not index_name:
|
|
322
|
+
continue
|
|
323
|
+
index_identifier = f"{schema_name}.{index_name}" if schema_name else index_name
|
|
324
|
+
columns_sql = self.get_query_text("index_columns_by_index").format(
|
|
325
|
+
index_name=format_identifier(index_identifier)
|
|
326
|
+
)
|
|
327
|
+
columns_rows = await driver.select(columns_sql)
|
|
328
|
+
columns: list[str] = []
|
|
329
|
+
for col in columns_rows:
|
|
330
|
+
column_name = col.get("name")
|
|
331
|
+
if column_name is None:
|
|
332
|
+
continue
|
|
333
|
+
columns.append(str(column_name))
|
|
334
|
+
is_primary = row.get("origin") == "pk"
|
|
335
|
+
index_metadata: IndexMetadata = {
|
|
336
|
+
"index_name": index_name,
|
|
337
|
+
"table_name": table_name,
|
|
338
|
+
"columns": columns,
|
|
339
|
+
"is_primary": is_primary,
|
|
340
|
+
}
|
|
341
|
+
if schema_name is not None:
|
|
342
|
+
index_metadata["schema_name"] = schema_name
|
|
343
|
+
unique_value = row.get("unique")
|
|
344
|
+
if unique_value is not None:
|
|
345
|
+
index_metadata["is_unique"] = unique_value
|
|
346
|
+
indexes.append(index_metadata)
|
|
347
|
+
return indexes
|
|
348
|
+
|
|
349
|
+
async def get_foreign_keys(
|
|
350
|
+
self, driver: "MockAsyncDriver", table: "str | None" = None, schema: "str | None" = None
|
|
351
|
+
) -> "list[ForeignKeyMetadata]":
|
|
352
|
+
"""Get foreign key metadata."""
|
|
353
|
+
schema_name = self.resolve_schema(schema)
|
|
354
|
+
schema_prefix = f"{format_identifier(schema_name)}." if schema_name else ""
|
|
355
|
+
if table is None:
|
|
356
|
+
self._log_schema_introspect(driver, schema_name=schema_name, table_name=None, operation="foreign_keys")
|
|
357
|
+
query_text = self.get_query_text("foreign_keys_by_schema").format(schema_prefix=schema_prefix)
|
|
358
|
+
return await driver.select(query_text, schema_type=ForeignKeyMetadata)
|
|
359
|
+
|
|
360
|
+
self._log_table_describe(driver, schema_name=schema_name, table_name=table, operation="foreign_keys")
|
|
361
|
+
table_label = table.replace("'", "''")
|
|
362
|
+
table_identifier = f"{schema_name}.{table}" if schema_name else table
|
|
363
|
+
query_text = self.get_query_text("foreign_keys_by_table").format(
|
|
364
|
+
table_name=format_identifier(table_identifier), table_label=table_label
|
|
365
|
+
)
|
|
366
|
+
return await driver.select(query_text, schema_type=ForeignKeyMetadata)
|