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,1360 @@
|
|
|
1
|
+
"""Type guard functions for runtime type checking in SQLSpec.
|
|
2
|
+
|
|
3
|
+
This module provides type-safe runtime checks that help the type checker
|
|
4
|
+
understand type narrowing, replacing defensive hasattr() and duck typing patterns.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from collections.abc import Sequence
|
|
8
|
+
from collections.abc import Set as AbstractSet
|
|
9
|
+
from dataclasses import Field
|
|
10
|
+
from dataclasses import fields as dataclasses_fields
|
|
11
|
+
from dataclasses import is_dataclass as dataclasses_is_dataclass
|
|
12
|
+
from functools import lru_cache
|
|
13
|
+
from typing import TYPE_CHECKING, Any, cast
|
|
14
|
+
|
|
15
|
+
from sqlglot import exp
|
|
16
|
+
from typing_extensions import is_typeddict
|
|
17
|
+
|
|
18
|
+
from sqlspec._typing import Empty
|
|
19
|
+
from sqlspec.protocols import (
|
|
20
|
+
ArrowTableStatsProtocol,
|
|
21
|
+
AsyncDeleteProtocol,
|
|
22
|
+
AsyncReadableProtocol,
|
|
23
|
+
AsyncReadBytesProtocol,
|
|
24
|
+
AsyncWriteBytesProtocol,
|
|
25
|
+
CursorMetadataProtocol,
|
|
26
|
+
DictProtocol,
|
|
27
|
+
HasAddListenerProtocol,
|
|
28
|
+
HasConfigProtocol,
|
|
29
|
+
HasConnectionConfigProtocol,
|
|
30
|
+
HasDatabaseUrlAndBindKeyProtocol,
|
|
31
|
+
HasErrorsProtocol,
|
|
32
|
+
HasExpressionAndParametersProtocol,
|
|
33
|
+
HasExpressionAndSQLProtocol,
|
|
34
|
+
HasExpressionProtocol,
|
|
35
|
+
HasExtensionConfigProtocol,
|
|
36
|
+
HasFieldNameProtocol,
|
|
37
|
+
HasFilterAttributesProtocol,
|
|
38
|
+
HasGetDataProtocol,
|
|
39
|
+
HasLastRowIdProtocol,
|
|
40
|
+
HasMigrationConfigProtocol,
|
|
41
|
+
HasNameProtocol,
|
|
42
|
+
HasNotifiesProtocol,
|
|
43
|
+
HasParameterBuilderProtocol,
|
|
44
|
+
HasRowcountProtocol,
|
|
45
|
+
HasSQLGlotExpressionProtocol,
|
|
46
|
+
HasSqliteErrorProtocol,
|
|
47
|
+
HasSqlStateProtocol,
|
|
48
|
+
HasStatementConfigFactoryProtocol,
|
|
49
|
+
HasStatementTypeProtocol,
|
|
50
|
+
HasTracerProviderProtocol,
|
|
51
|
+
HasTypeCodeProtocol,
|
|
52
|
+
HasTypecodeProtocol,
|
|
53
|
+
HasTypecodeSizedProtocol,
|
|
54
|
+
HasValueProtocol,
|
|
55
|
+
HasWhereProtocol,
|
|
56
|
+
NotificationProtocol,
|
|
57
|
+
PipelineCapableProtocol,
|
|
58
|
+
QueryResultProtocol,
|
|
59
|
+
ReadableProtocol,
|
|
60
|
+
SpanAttributeProtocol,
|
|
61
|
+
SupportsArrayProtocol,
|
|
62
|
+
SupportsArrowResults,
|
|
63
|
+
SupportsCloseProtocol,
|
|
64
|
+
SupportsDtypeStrProtocol,
|
|
65
|
+
SupportsJsonTypeProtocol,
|
|
66
|
+
WithMethodProtocol,
|
|
67
|
+
)
|
|
68
|
+
from sqlspec.typing import (
|
|
69
|
+
ATTRS_INSTALLED,
|
|
70
|
+
LITESTAR_INSTALLED,
|
|
71
|
+
MSGSPEC_INSTALLED,
|
|
72
|
+
PYDANTIC_INSTALLED,
|
|
73
|
+
BaseModel,
|
|
74
|
+
DataclassProtocol,
|
|
75
|
+
DTOData,
|
|
76
|
+
Struct,
|
|
77
|
+
attrs_fields,
|
|
78
|
+
attrs_has,
|
|
79
|
+
)
|
|
80
|
+
from sqlspec.utils.text import camelize, kebabize, pascalize
|
|
81
|
+
|
|
82
|
+
if TYPE_CHECKING:
|
|
83
|
+
from typing import TypeGuard
|
|
84
|
+
|
|
85
|
+
from sqlspec._typing import AttrsInstanceStub, BaseModelStub, DTODataStub, StructStub
|
|
86
|
+
from sqlspec.core import StatementFilter
|
|
87
|
+
from sqlspec.core.parameters import TypedParameter
|
|
88
|
+
from sqlspec.typing import SupportedSchemaModel
|
|
89
|
+
|
|
90
|
+
__all__ = (
|
|
91
|
+
"dataclass_to_dict",
|
|
92
|
+
"expression_has_limit",
|
|
93
|
+
"extract_dataclass_fields",
|
|
94
|
+
"extract_dataclass_items",
|
|
95
|
+
"get_initial_expression",
|
|
96
|
+
"get_literal_parent",
|
|
97
|
+
"get_msgspec_rename_config",
|
|
98
|
+
"get_node_expressions",
|
|
99
|
+
"get_node_this",
|
|
100
|
+
"get_param_style_and_name",
|
|
101
|
+
"get_value_attribute",
|
|
102
|
+
"has_add_listener",
|
|
103
|
+
"has_array_interface",
|
|
104
|
+
"has_arrow_table_stats",
|
|
105
|
+
"has_config_attribute",
|
|
106
|
+
"has_connection_config",
|
|
107
|
+
"has_cursor_metadata",
|
|
108
|
+
"has_database_url_and_bind_key",
|
|
109
|
+
"has_dict_attribute",
|
|
110
|
+
"has_dtype_str",
|
|
111
|
+
"has_errors",
|
|
112
|
+
"has_expression_and_parameters",
|
|
113
|
+
"has_expression_and_sql",
|
|
114
|
+
"has_expression_attr",
|
|
115
|
+
"has_expressions_attribute",
|
|
116
|
+
"has_extension_config",
|
|
117
|
+
"has_field_name",
|
|
118
|
+
"has_filter_attributes",
|
|
119
|
+
"has_get_data",
|
|
120
|
+
"has_lastrowid",
|
|
121
|
+
"has_migration_config",
|
|
122
|
+
"has_name",
|
|
123
|
+
"has_notifies",
|
|
124
|
+
"has_parameter_builder",
|
|
125
|
+
"has_parent_attribute",
|
|
126
|
+
"has_pipeline_capability",
|
|
127
|
+
"has_query_result_metadata",
|
|
128
|
+
"has_rowcount",
|
|
129
|
+
"has_span_attribute",
|
|
130
|
+
"has_sqlglot_expression",
|
|
131
|
+
"has_sqlite_error",
|
|
132
|
+
"has_sqlstate",
|
|
133
|
+
"has_statement_config_factory",
|
|
134
|
+
"has_statement_type",
|
|
135
|
+
"has_this_attribute",
|
|
136
|
+
"has_tracer_provider",
|
|
137
|
+
"has_type_code",
|
|
138
|
+
"has_typecode",
|
|
139
|
+
"has_typecode_and_len",
|
|
140
|
+
"has_value_attribute",
|
|
141
|
+
"has_with_method",
|
|
142
|
+
"is_async_readable",
|
|
143
|
+
"is_attrs_instance",
|
|
144
|
+
"is_attrs_instance_with_field",
|
|
145
|
+
"is_attrs_instance_without_field",
|
|
146
|
+
"is_attrs_schema",
|
|
147
|
+
"is_copy_statement",
|
|
148
|
+
"is_dataclass",
|
|
149
|
+
"is_dataclass_instance",
|
|
150
|
+
"is_dataclass_with_field",
|
|
151
|
+
"is_dataclass_without_field",
|
|
152
|
+
"is_dict",
|
|
153
|
+
"is_dict_row",
|
|
154
|
+
"is_dict_with_field",
|
|
155
|
+
"is_dict_without_field",
|
|
156
|
+
"is_dto_data",
|
|
157
|
+
"is_expression",
|
|
158
|
+
"is_iterable_parameters",
|
|
159
|
+
"is_local_path",
|
|
160
|
+
"is_msgspec_struct",
|
|
161
|
+
"is_msgspec_struct_with_field",
|
|
162
|
+
"is_msgspec_struct_without_field",
|
|
163
|
+
"is_notification",
|
|
164
|
+
"is_number_literal",
|
|
165
|
+
"is_pydantic_model",
|
|
166
|
+
"is_pydantic_model_with_field",
|
|
167
|
+
"is_pydantic_model_without_field",
|
|
168
|
+
"is_readable",
|
|
169
|
+
"is_schema",
|
|
170
|
+
"is_schema_or_dict",
|
|
171
|
+
"is_schema_or_dict_with_field",
|
|
172
|
+
"is_schema_or_dict_without_field",
|
|
173
|
+
"is_schema_with_field",
|
|
174
|
+
"is_schema_without_field",
|
|
175
|
+
"is_statement_filter",
|
|
176
|
+
"is_string_literal",
|
|
177
|
+
"is_typed_dict",
|
|
178
|
+
"is_typed_parameter",
|
|
179
|
+
"supports_arrow_results",
|
|
180
|
+
"supports_async_delete",
|
|
181
|
+
"supports_async_read_bytes",
|
|
182
|
+
"supports_async_write_bytes",
|
|
183
|
+
"supports_close",
|
|
184
|
+
"supports_json_type",
|
|
185
|
+
"supports_where",
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def is_readable(obj: Any) -> "TypeGuard[ReadableProtocol]":
|
|
190
|
+
"""Check if an object is readable (has a read method)."""
|
|
191
|
+
return isinstance(obj, ReadableProtocol)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def is_async_readable(obj: Any) -> "TypeGuard[AsyncReadableProtocol]":
|
|
195
|
+
"""Check if an object exposes an async read method."""
|
|
196
|
+
return isinstance(obj, AsyncReadableProtocol)
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def is_notification(obj: Any) -> "TypeGuard[NotificationProtocol]":
|
|
200
|
+
"""Check if an object is a database notification with channel and payload."""
|
|
201
|
+
return isinstance(obj, NotificationProtocol)
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def has_pipeline_capability(obj: Any) -> "TypeGuard[PipelineCapableProtocol]":
|
|
205
|
+
"""Check if a connection supports pipeline execution."""
|
|
206
|
+
return isinstance(obj, PipelineCapableProtocol)
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def has_query_result_metadata(obj: Any) -> "TypeGuard[QueryResultProtocol]":
|
|
210
|
+
"""Check if an object has query result metadata (tag/status)."""
|
|
211
|
+
return isinstance(obj, QueryResultProtocol)
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def has_array_interface(obj: Any) -> "TypeGuard[SupportsArrayProtocol]":
|
|
215
|
+
"""Check if an object supports the array interface (like NumPy arrays)."""
|
|
216
|
+
return isinstance(obj, SupportsArrayProtocol)
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
def has_cursor_metadata(obj: Any) -> "TypeGuard[CursorMetadataProtocol]":
|
|
220
|
+
"""Check if an object has cursor metadata (description)."""
|
|
221
|
+
return isinstance(obj, CursorMetadataProtocol)
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
def has_add_listener(obj: Any) -> "TypeGuard[HasAddListenerProtocol]":
|
|
225
|
+
"""Check if an object exposes add_listener()."""
|
|
226
|
+
return isinstance(obj, HasAddListenerProtocol)
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def has_notifies(obj: Any) -> "TypeGuard[HasNotifiesProtocol]":
|
|
230
|
+
"""Check if an object exposes notifies."""
|
|
231
|
+
return isinstance(obj, HasNotifiesProtocol)
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
def has_extension_config(obj: Any) -> "TypeGuard[HasExtensionConfigProtocol]":
|
|
235
|
+
"""Check if an object exposes extension_config mapping."""
|
|
236
|
+
return isinstance(obj, HasExtensionConfigProtocol)
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
def has_config_attribute(obj: Any) -> "TypeGuard[HasConfigProtocol]":
|
|
240
|
+
"""Check if an object exposes config attribute."""
|
|
241
|
+
return isinstance(obj, HasConfigProtocol)
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
def has_connection_config(obj: Any) -> "TypeGuard[HasConnectionConfigProtocol]":
|
|
245
|
+
"""Check if an object exposes connection_config mapping."""
|
|
246
|
+
return isinstance(obj, HasConnectionConfigProtocol)
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
def has_database_url_and_bind_key(obj: Any) -> "TypeGuard[HasDatabaseUrlAndBindKeyProtocol]":
|
|
250
|
+
"""Check if an object exposes database_url and bind_key."""
|
|
251
|
+
return isinstance(obj, HasDatabaseUrlAndBindKeyProtocol)
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
def has_name(obj: Any) -> "TypeGuard[HasNameProtocol]":
|
|
255
|
+
"""Check if an object exposes __name__."""
|
|
256
|
+
return isinstance(obj, HasNameProtocol)
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
def has_field_name(obj: Any) -> "TypeGuard[HasFieldNameProtocol]":
|
|
260
|
+
"""Check if an object exposes field_name attribute."""
|
|
261
|
+
return isinstance(obj, HasFieldNameProtocol)
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
def has_filter_attributes(obj: Any) -> "TypeGuard[HasFilterAttributesProtocol]":
|
|
265
|
+
"""Check if an object exposes filter attribute set."""
|
|
266
|
+
return isinstance(obj, HasFilterAttributesProtocol)
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
def has_get_data(obj: Any) -> "TypeGuard[HasGetDataProtocol]":
|
|
270
|
+
"""Check if an object exposes get_data()."""
|
|
271
|
+
return isinstance(obj, HasGetDataProtocol)
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
def has_arrow_table_stats(obj: Any) -> "TypeGuard[ArrowTableStatsProtocol]":
|
|
275
|
+
"""Check if an object exposes Arrow row/byte stats."""
|
|
276
|
+
return isinstance(obj, ArrowTableStatsProtocol)
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
def has_rowcount(obj: Any) -> "TypeGuard[HasRowcountProtocol]":
|
|
280
|
+
"""Check if a cursor exposes rowcount metadata."""
|
|
281
|
+
return isinstance(obj, HasRowcountProtocol)
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
def has_lastrowid(obj: Any) -> "TypeGuard[HasLastRowIdProtocol]":
|
|
285
|
+
"""Check if a cursor exposes lastrowid metadata."""
|
|
286
|
+
return isinstance(obj, HasLastRowIdProtocol)
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
def has_dtype_str(obj: Any) -> "TypeGuard[SupportsDtypeStrProtocol]":
|
|
290
|
+
"""Check if a dtype exposes string descriptor."""
|
|
291
|
+
return isinstance(obj, SupportsDtypeStrProtocol)
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
def has_statement_type(obj: Any) -> "TypeGuard[HasStatementTypeProtocol]":
|
|
295
|
+
"""Check if a cursor exposes statement_type metadata."""
|
|
296
|
+
return isinstance(obj, HasStatementTypeProtocol)
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
def has_typecode(obj: Any) -> "TypeGuard[HasTypecodeProtocol]":
|
|
300
|
+
"""Check if an array-like object exposes typecode."""
|
|
301
|
+
return isinstance(obj, HasTypecodeProtocol)
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
def has_typecode_and_len(obj: Any) -> "TypeGuard[HasTypecodeSizedProtocol]":
|
|
305
|
+
"""Check if an array-like object exposes typecode and length."""
|
|
306
|
+
return isinstance(obj, HasTypecodeSizedProtocol)
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
def has_type_code(obj: Any) -> "TypeGuard[HasTypeCodeProtocol]":
|
|
310
|
+
"""Check if an object exposes type_code."""
|
|
311
|
+
return isinstance(obj, HasTypeCodeProtocol)
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
def has_sqlstate(obj: Any) -> "TypeGuard[HasSqlStateProtocol]":
|
|
315
|
+
"""Check if an exception exposes sqlstate."""
|
|
316
|
+
return isinstance(obj, HasSqlStateProtocol)
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
def has_sqlite_error(obj: Any) -> "TypeGuard[HasSqliteErrorProtocol]":
|
|
320
|
+
"""Check if an exception exposes sqlite error details."""
|
|
321
|
+
return isinstance(obj, HasSqliteErrorProtocol)
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
def has_value_attribute(obj: Any) -> "TypeGuard[HasValueProtocol]":
|
|
325
|
+
"""Check if an object exposes a value attribute."""
|
|
326
|
+
return isinstance(obj, HasValueProtocol)
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
def has_errors(obj: Any) -> "TypeGuard[HasErrorsProtocol]":
|
|
330
|
+
"""Check if an exception exposes errors."""
|
|
331
|
+
return isinstance(obj, HasErrorsProtocol)
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
def has_span_attribute(obj: Any) -> "TypeGuard[SpanAttributeProtocol]":
|
|
335
|
+
"""Check if a span exposes set_attribute."""
|
|
336
|
+
return isinstance(obj, SpanAttributeProtocol)
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
def has_tracer_provider(obj: Any) -> "TypeGuard[HasTracerProviderProtocol]":
|
|
340
|
+
"""Check if an object exposes get_tracer."""
|
|
341
|
+
return isinstance(obj, HasTracerProviderProtocol)
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
def supports_async_read_bytes(obj: Any) -> "TypeGuard[AsyncReadBytesProtocol]":
|
|
345
|
+
"""Check if backend supports async read_bytes."""
|
|
346
|
+
return isinstance(obj, AsyncReadBytesProtocol)
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
def supports_async_write_bytes(obj: Any) -> "TypeGuard[AsyncWriteBytesProtocol]":
|
|
350
|
+
"""Check if backend supports async write_bytes."""
|
|
351
|
+
return isinstance(obj, AsyncWriteBytesProtocol)
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
def supports_json_type(obj: Any) -> "TypeGuard[SupportsJsonTypeProtocol]":
|
|
355
|
+
"""Check if an object exposes JSON type support."""
|
|
356
|
+
return isinstance(obj, SupportsJsonTypeProtocol)
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
def supports_close(obj: Any) -> "TypeGuard[SupportsCloseProtocol]":
|
|
360
|
+
"""Check if an object exposes close()."""
|
|
361
|
+
return isinstance(obj, SupportsCloseProtocol)
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
def supports_async_delete(obj: Any) -> "TypeGuard[AsyncDeleteProtocol]":
|
|
365
|
+
"""Check if backend supports async delete."""
|
|
366
|
+
return isinstance(obj, AsyncDeleteProtocol)
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
def supports_where(obj: Any) -> "TypeGuard[HasWhereProtocol]":
|
|
370
|
+
"""Check if an SQL expression supports WHERE clauses."""
|
|
371
|
+
return isinstance(obj, HasWhereProtocol)
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
def is_typed_dict(obj: Any) -> "TypeGuard[type]":
|
|
375
|
+
"""Check if an object is a TypedDict class.
|
|
376
|
+
|
|
377
|
+
Args:
|
|
378
|
+
obj: The object to check
|
|
379
|
+
|
|
380
|
+
Returns:
|
|
381
|
+
True if the object is a TypedDict class, False otherwise
|
|
382
|
+
"""
|
|
383
|
+
return is_typeddict(obj)
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
def is_statement_filter(obj: Any) -> "TypeGuard[StatementFilter]":
|
|
387
|
+
"""Check if an object implements the StatementFilter protocol.
|
|
388
|
+
|
|
389
|
+
Args:
|
|
390
|
+
obj: The object to check
|
|
391
|
+
|
|
392
|
+
Returns:
|
|
393
|
+
True if the object is a StatementFilter, False otherwise
|
|
394
|
+
"""
|
|
395
|
+
from sqlspec.core.filters import StatementFilter as FilterProtocol
|
|
396
|
+
|
|
397
|
+
return isinstance(obj, FilterProtocol)
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
def is_dict_row(row: Any) -> "TypeGuard[dict[str, Any]]":
|
|
401
|
+
"""Check if a row is a dictionary.
|
|
402
|
+
|
|
403
|
+
Args:
|
|
404
|
+
row: The row to check
|
|
405
|
+
|
|
406
|
+
Returns:
|
|
407
|
+
True if the row is a dictionary, False otherwise
|
|
408
|
+
"""
|
|
409
|
+
return isinstance(row, dict)
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
def is_iterable_parameters(parameters: Any) -> "TypeGuard[Sequence[Any]]":
|
|
413
|
+
"""Check if parameters are iterable (but not string or dict).
|
|
414
|
+
|
|
415
|
+
Args:
|
|
416
|
+
parameters: The parameters to check
|
|
417
|
+
|
|
418
|
+
Returns:
|
|
419
|
+
True if the parameters are iterable, False otherwise
|
|
420
|
+
"""
|
|
421
|
+
return isinstance(parameters, Sequence) and not isinstance(parameters, (str, bytes, dict))
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
def has_with_method(obj: Any) -> "TypeGuard[WithMethodProtocol]":
|
|
425
|
+
"""Check if an object has a callable 'with_' method.
|
|
426
|
+
|
|
427
|
+
This is a more specific check than hasattr for SQLGlot expressions.
|
|
428
|
+
|
|
429
|
+
Args:
|
|
430
|
+
obj: The object to check
|
|
431
|
+
|
|
432
|
+
Returns:
|
|
433
|
+
True if the object has a callable with_ method, False otherwise
|
|
434
|
+
"""
|
|
435
|
+
return isinstance(obj, WithMethodProtocol)
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
def is_dataclass_instance(obj: Any) -> "TypeGuard[DataclassProtocol]":
|
|
439
|
+
"""Check if an object is a dataclass instance.
|
|
440
|
+
|
|
441
|
+
Args:
|
|
442
|
+
obj: An object to check.
|
|
443
|
+
|
|
444
|
+
Returns:
|
|
445
|
+
True if the object is a dataclass instance.
|
|
446
|
+
"""
|
|
447
|
+
if isinstance(obj, type):
|
|
448
|
+
return False
|
|
449
|
+
return dataclasses_is_dataclass(obj)
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
def is_dataclass(obj: Any) -> "TypeGuard[DataclassProtocol]":
|
|
453
|
+
"""Check if an object is a dataclass.
|
|
454
|
+
|
|
455
|
+
Args:
|
|
456
|
+
obj: Value to check.
|
|
457
|
+
|
|
458
|
+
Returns:
|
|
459
|
+
bool
|
|
460
|
+
"""
|
|
461
|
+
return dataclasses_is_dataclass(obj)
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
def is_dataclass_with_field(obj: Any, field_name: str) -> "TypeGuard[DataclassProtocol]":
|
|
465
|
+
"""Check if an object is a dataclass and has a specific field.
|
|
466
|
+
|
|
467
|
+
Args:
|
|
468
|
+
obj: Value to check.
|
|
469
|
+
field_name: Field name to check for.
|
|
470
|
+
|
|
471
|
+
Returns:
|
|
472
|
+
bool
|
|
473
|
+
"""
|
|
474
|
+
if not is_dataclass(obj):
|
|
475
|
+
return False
|
|
476
|
+
return any(field.name == field_name for field in dataclasses_fields(obj))
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
def is_dataclass_without_field(obj: Any, field_name: str) -> "TypeGuard[DataclassProtocol]":
|
|
480
|
+
"""Check if an object is a dataclass and does not have a specific field.
|
|
481
|
+
|
|
482
|
+
Args:
|
|
483
|
+
obj: Value to check.
|
|
484
|
+
field_name: Field name to check for.
|
|
485
|
+
|
|
486
|
+
Returns:
|
|
487
|
+
bool
|
|
488
|
+
"""
|
|
489
|
+
if not is_dataclass(obj):
|
|
490
|
+
return False
|
|
491
|
+
return all(field.name != field_name for field in dataclasses_fields(obj))
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
def is_pydantic_model(obj: Any) -> "TypeGuard[BaseModelStub]":
|
|
495
|
+
"""Check if a value is a pydantic model class or instance.
|
|
496
|
+
|
|
497
|
+
Args:
|
|
498
|
+
obj: Value to check.
|
|
499
|
+
|
|
500
|
+
Returns:
|
|
501
|
+
bool
|
|
502
|
+
"""
|
|
503
|
+
if not PYDANTIC_INSTALLED:
|
|
504
|
+
return False
|
|
505
|
+
if isinstance(obj, type):
|
|
506
|
+
try:
|
|
507
|
+
return issubclass(obj, BaseModel)
|
|
508
|
+
except TypeError:
|
|
509
|
+
return False
|
|
510
|
+
return isinstance(obj, BaseModel)
|
|
511
|
+
|
|
512
|
+
|
|
513
|
+
def is_pydantic_model_with_field(obj: Any, field_name: str) -> "TypeGuard[BaseModelStub]":
|
|
514
|
+
"""Check if a pydantic model has a specific field.
|
|
515
|
+
|
|
516
|
+
Args:
|
|
517
|
+
obj: Value to check.
|
|
518
|
+
field_name: Field name to check for.
|
|
519
|
+
|
|
520
|
+
Returns:
|
|
521
|
+
bool
|
|
522
|
+
"""
|
|
523
|
+
if not is_pydantic_model(obj):
|
|
524
|
+
return False
|
|
525
|
+
try:
|
|
526
|
+
fields = obj.model_fields
|
|
527
|
+
except AttributeError:
|
|
528
|
+
try:
|
|
529
|
+
fields = obj.__fields__ # type: ignore[attr-defined]
|
|
530
|
+
except AttributeError:
|
|
531
|
+
return False
|
|
532
|
+
return field_name in fields
|
|
533
|
+
|
|
534
|
+
|
|
535
|
+
def is_pydantic_model_without_field(obj: Any, field_name: str) -> "TypeGuard[BaseModelStub]":
|
|
536
|
+
"""Check if a pydantic model does not have a specific field.
|
|
537
|
+
|
|
538
|
+
Args:
|
|
539
|
+
obj: Value to check.
|
|
540
|
+
field_name: Field name to check for.
|
|
541
|
+
|
|
542
|
+
Returns:
|
|
543
|
+
bool
|
|
544
|
+
"""
|
|
545
|
+
if not is_pydantic_model(obj):
|
|
546
|
+
return False
|
|
547
|
+
try:
|
|
548
|
+
fields = obj.model_fields
|
|
549
|
+
except AttributeError:
|
|
550
|
+
try:
|
|
551
|
+
fields = obj.__fields__ # type: ignore[attr-defined]
|
|
552
|
+
except AttributeError:
|
|
553
|
+
return True
|
|
554
|
+
return field_name not in fields
|
|
555
|
+
|
|
556
|
+
|
|
557
|
+
def is_msgspec_struct(obj: Any) -> "TypeGuard[StructStub]":
|
|
558
|
+
"""Check if a value is a msgspec struct class or instance.
|
|
559
|
+
|
|
560
|
+
Args:
|
|
561
|
+
obj: Value to check.
|
|
562
|
+
|
|
563
|
+
Returns:
|
|
564
|
+
bool
|
|
565
|
+
"""
|
|
566
|
+
if not MSGSPEC_INSTALLED:
|
|
567
|
+
return False
|
|
568
|
+
if isinstance(obj, type):
|
|
569
|
+
try:
|
|
570
|
+
return issubclass(obj, Struct)
|
|
571
|
+
except TypeError:
|
|
572
|
+
return False
|
|
573
|
+
return isinstance(obj, Struct)
|
|
574
|
+
|
|
575
|
+
|
|
576
|
+
def is_msgspec_struct_with_field(obj: Any, field_name: str) -> "TypeGuard[StructStub]":
|
|
577
|
+
"""Check if a msgspec struct has a specific field.
|
|
578
|
+
|
|
579
|
+
Args:
|
|
580
|
+
obj: Value to check.
|
|
581
|
+
field_name: Field name to check for.
|
|
582
|
+
|
|
583
|
+
Returns:
|
|
584
|
+
bool
|
|
585
|
+
"""
|
|
586
|
+
if not is_msgspec_struct(obj):
|
|
587
|
+
return False
|
|
588
|
+
from msgspec import structs
|
|
589
|
+
|
|
590
|
+
struct_type = obj if isinstance(obj, type) else type(obj)
|
|
591
|
+
fields = structs.fields(cast("Any", struct_type))
|
|
592
|
+
return any(field.name == field_name for field in fields)
|
|
593
|
+
|
|
594
|
+
|
|
595
|
+
def is_msgspec_struct_without_field(obj: Any, field_name: str) -> "TypeGuard[StructStub]":
|
|
596
|
+
"""Check if a msgspec struct does not have a specific field.
|
|
597
|
+
|
|
598
|
+
Args:
|
|
599
|
+
obj: Value to check.
|
|
600
|
+
field_name: Field name to check for.
|
|
601
|
+
|
|
602
|
+
Returns:
|
|
603
|
+
bool
|
|
604
|
+
"""
|
|
605
|
+
if not is_msgspec_struct(obj):
|
|
606
|
+
return False
|
|
607
|
+
from msgspec import structs
|
|
608
|
+
|
|
609
|
+
struct_type = obj if isinstance(obj, type) else type(obj)
|
|
610
|
+
fields = structs.fields(cast("Any", struct_type))
|
|
611
|
+
return all(field.name != field_name for field in fields)
|
|
612
|
+
|
|
613
|
+
|
|
614
|
+
@lru_cache(maxsize=500)
|
|
615
|
+
def _detect_rename_pattern(field_name: str, encode_name: str) -> "str | None":
|
|
616
|
+
"""Detect the rename pattern by comparing field name transformations.
|
|
617
|
+
|
|
618
|
+
Args:
|
|
619
|
+
field_name: Original field name (e.g., "user_id")
|
|
620
|
+
encode_name: Encoded field name (e.g., "userId")
|
|
621
|
+
|
|
622
|
+
Returns:
|
|
623
|
+
The detected rename pattern ("camel", "kebab", "pascal") or None
|
|
624
|
+
"""
|
|
625
|
+
if encode_name == camelize(field_name) and encode_name != field_name:
|
|
626
|
+
return "camel"
|
|
627
|
+
|
|
628
|
+
if encode_name == kebabize(field_name) and encode_name != field_name:
|
|
629
|
+
return "kebab"
|
|
630
|
+
|
|
631
|
+
if encode_name == pascalize(field_name) and encode_name != field_name:
|
|
632
|
+
return "pascal"
|
|
633
|
+
return None
|
|
634
|
+
|
|
635
|
+
|
|
636
|
+
def get_msgspec_rename_config(schema_type: type) -> "str | None":
|
|
637
|
+
"""Extract msgspec rename configuration from a struct type.
|
|
638
|
+
|
|
639
|
+
Analyzes field name transformations to detect the rename pattern used by msgspec.
|
|
640
|
+
Since msgspec doesn't store the original rename parameter directly, we infer it
|
|
641
|
+
by comparing field names with their encode_name values.
|
|
642
|
+
|
|
643
|
+
Args:
|
|
644
|
+
schema_type: The msgspec struct type to inspect.
|
|
645
|
+
|
|
646
|
+
Returns:
|
|
647
|
+
The rename configuration value ("camel", "kebab", "pascal", etc.) if detected,
|
|
648
|
+
None if no rename configuration exists or if not a msgspec struct.
|
|
649
|
+
|
|
650
|
+
Examples:
|
|
651
|
+
>>> class User(msgspec.Struct, rename="camel"):
|
|
652
|
+
... user_id: int
|
|
653
|
+
>>> get_msgspec_rename_config(User)
|
|
654
|
+
"camel"
|
|
655
|
+
|
|
656
|
+
>>> class Product(msgspec.Struct):
|
|
657
|
+
... product_id: int
|
|
658
|
+
>>> get_msgspec_rename_config(Product)
|
|
659
|
+
None
|
|
660
|
+
"""
|
|
661
|
+
if not MSGSPEC_INSTALLED:
|
|
662
|
+
return None
|
|
663
|
+
|
|
664
|
+
if not is_msgspec_struct(schema_type):
|
|
665
|
+
return None
|
|
666
|
+
|
|
667
|
+
from msgspec import structs
|
|
668
|
+
|
|
669
|
+
fields: tuple[Any, ...] = structs.fields(cast("Any", schema_type))
|
|
670
|
+
if not fields:
|
|
671
|
+
return None
|
|
672
|
+
|
|
673
|
+
for field in fields:
|
|
674
|
+
if field.name != field.encode_name:
|
|
675
|
+
return _detect_rename_pattern(field.name, field.encode_name)
|
|
676
|
+
|
|
677
|
+
return None
|
|
678
|
+
|
|
679
|
+
|
|
680
|
+
def is_attrs_instance(obj: Any) -> "TypeGuard[AttrsInstanceStub]":
|
|
681
|
+
"""Check if a value is an attrs class instance.
|
|
682
|
+
|
|
683
|
+
Args:
|
|
684
|
+
obj: Value to check.
|
|
685
|
+
|
|
686
|
+
Returns:
|
|
687
|
+
bool
|
|
688
|
+
"""
|
|
689
|
+
return bool(ATTRS_INSTALLED) and attrs_has(obj.__class__)
|
|
690
|
+
|
|
691
|
+
|
|
692
|
+
def is_attrs_schema(cls: Any) -> "TypeGuard[type[AttrsInstanceStub]]":
|
|
693
|
+
"""Check if a class type is an attrs schema.
|
|
694
|
+
|
|
695
|
+
Args:
|
|
696
|
+
cls: Class to check.
|
|
697
|
+
|
|
698
|
+
Returns:
|
|
699
|
+
bool
|
|
700
|
+
"""
|
|
701
|
+
return bool(ATTRS_INSTALLED) and attrs_has(cls)
|
|
702
|
+
|
|
703
|
+
|
|
704
|
+
def is_attrs_instance_with_field(obj: Any, field_name: str) -> "TypeGuard[AttrsInstanceStub]":
|
|
705
|
+
"""Check if an attrs instance has a specific field.
|
|
706
|
+
|
|
707
|
+
Args:
|
|
708
|
+
obj: Value to check.
|
|
709
|
+
field_name: Field name to check for.
|
|
710
|
+
|
|
711
|
+
Returns:
|
|
712
|
+
bool
|
|
713
|
+
"""
|
|
714
|
+
if not is_attrs_instance(obj):
|
|
715
|
+
return False
|
|
716
|
+
return any(field.name == field_name for field in attrs_fields(obj.__class__))
|
|
717
|
+
|
|
718
|
+
|
|
719
|
+
def is_attrs_instance_without_field(obj: Any, field_name: str) -> "TypeGuard[AttrsInstanceStub]":
|
|
720
|
+
"""Check if an attrs instance does not have a specific field.
|
|
721
|
+
|
|
722
|
+
Args:
|
|
723
|
+
obj: Value to check.
|
|
724
|
+
field_name: Field name to check for.
|
|
725
|
+
|
|
726
|
+
Returns:
|
|
727
|
+
bool
|
|
728
|
+
"""
|
|
729
|
+
if not is_attrs_instance(obj):
|
|
730
|
+
return False
|
|
731
|
+
return all(field.name != field_name for field in attrs_fields(obj.__class__))
|
|
732
|
+
|
|
733
|
+
|
|
734
|
+
def is_dict(obj: Any) -> "TypeGuard[dict[str, Any]]":
|
|
735
|
+
"""Check if a value is a dictionary.
|
|
736
|
+
|
|
737
|
+
Args:
|
|
738
|
+
obj: Value to check.
|
|
739
|
+
|
|
740
|
+
Returns:
|
|
741
|
+
bool
|
|
742
|
+
"""
|
|
743
|
+
return isinstance(obj, dict)
|
|
744
|
+
|
|
745
|
+
|
|
746
|
+
def is_dict_with_field(obj: Any, field_name: str) -> "TypeGuard[dict[str, Any]]":
|
|
747
|
+
"""Check if a dictionary has a specific field.
|
|
748
|
+
|
|
749
|
+
Args:
|
|
750
|
+
obj: Value to check.
|
|
751
|
+
field_name: Field name to check for.
|
|
752
|
+
|
|
753
|
+
Returns:
|
|
754
|
+
bool
|
|
755
|
+
"""
|
|
756
|
+
return is_dict(obj) and field_name in obj
|
|
757
|
+
|
|
758
|
+
|
|
759
|
+
def is_dict_without_field(obj: Any, field_name: str) -> "TypeGuard[dict[str, Any]]":
|
|
760
|
+
"""Check if a dictionary does not have a specific field.
|
|
761
|
+
|
|
762
|
+
Args:
|
|
763
|
+
obj: Value to check.
|
|
764
|
+
field_name: Field name to check for.
|
|
765
|
+
|
|
766
|
+
Returns:
|
|
767
|
+
bool
|
|
768
|
+
"""
|
|
769
|
+
return is_dict(obj) and field_name not in obj
|
|
770
|
+
|
|
771
|
+
|
|
772
|
+
def is_schema(obj: Any) -> "TypeGuard[SupportedSchemaModel]":
|
|
773
|
+
"""Check if a value is a msgspec Struct, Pydantic model, attrs instance, or schema class.
|
|
774
|
+
|
|
775
|
+
Args:
|
|
776
|
+
obj: Value to check.
|
|
777
|
+
|
|
778
|
+
Returns:
|
|
779
|
+
bool
|
|
780
|
+
"""
|
|
781
|
+
return (
|
|
782
|
+
is_msgspec_struct(obj)
|
|
783
|
+
or is_pydantic_model(obj)
|
|
784
|
+
or is_attrs_instance(obj)
|
|
785
|
+
or is_attrs_schema(obj)
|
|
786
|
+
or is_dataclass(obj)
|
|
787
|
+
)
|
|
788
|
+
|
|
789
|
+
|
|
790
|
+
def is_schema_or_dict(obj: Any) -> "TypeGuard[SupportedSchemaModel | dict[str, Any]]":
|
|
791
|
+
"""Check if a value is a msgspec Struct, Pydantic model, or dict.
|
|
792
|
+
|
|
793
|
+
Args:
|
|
794
|
+
obj: Value to check.
|
|
795
|
+
|
|
796
|
+
Returns:
|
|
797
|
+
bool
|
|
798
|
+
"""
|
|
799
|
+
return is_schema(obj) or is_dict(obj)
|
|
800
|
+
|
|
801
|
+
|
|
802
|
+
def is_schema_with_field(obj: Any, field_name: str) -> "TypeGuard[SupportedSchemaModel]":
|
|
803
|
+
"""Check if a value is a msgspec Struct or Pydantic model with a specific field.
|
|
804
|
+
|
|
805
|
+
Args:
|
|
806
|
+
obj: Value to check.
|
|
807
|
+
field_name: Field name to check for.
|
|
808
|
+
|
|
809
|
+
Returns:
|
|
810
|
+
bool
|
|
811
|
+
"""
|
|
812
|
+
return is_msgspec_struct_with_field(obj, field_name) or is_pydantic_model_with_field(obj, field_name)
|
|
813
|
+
|
|
814
|
+
|
|
815
|
+
def is_schema_without_field(obj: Any, field_name: str) -> "TypeGuard[SupportedSchemaModel]":
|
|
816
|
+
"""Check if a value is a msgspec Struct or Pydantic model without a specific field.
|
|
817
|
+
|
|
818
|
+
Args:
|
|
819
|
+
obj: Value to check.
|
|
820
|
+
field_name: Field name to check for.
|
|
821
|
+
|
|
822
|
+
Returns:
|
|
823
|
+
bool
|
|
824
|
+
"""
|
|
825
|
+
return not is_schema_with_field(obj, field_name)
|
|
826
|
+
|
|
827
|
+
|
|
828
|
+
def is_schema_or_dict_with_field(obj: Any, field_name: str) -> "TypeGuard[SupportedSchemaModel | dict[str, Any]]":
|
|
829
|
+
"""Check if a value is a msgspec Struct, Pydantic model, or dict with a specific field.
|
|
830
|
+
|
|
831
|
+
Args:
|
|
832
|
+
obj: Value to check.
|
|
833
|
+
field_name: Field name to check for.
|
|
834
|
+
|
|
835
|
+
Returns:
|
|
836
|
+
bool
|
|
837
|
+
"""
|
|
838
|
+
return is_schema_with_field(obj, field_name) or is_dict_with_field(obj, field_name)
|
|
839
|
+
|
|
840
|
+
|
|
841
|
+
def is_schema_or_dict_without_field(obj: Any, field_name: str) -> "TypeGuard[SupportedSchemaModel | dict[str, Any]]":
|
|
842
|
+
"""Check if a value is a msgspec Struct, Pydantic model, or dict without a specific field.
|
|
843
|
+
|
|
844
|
+
Args:
|
|
845
|
+
obj: Value to check.
|
|
846
|
+
field_name: Field name to check for.
|
|
847
|
+
|
|
848
|
+
Returns:
|
|
849
|
+
bool
|
|
850
|
+
"""
|
|
851
|
+
return not is_schema_or_dict_with_field(obj, field_name)
|
|
852
|
+
|
|
853
|
+
|
|
854
|
+
def is_dto_data(v: Any) -> "TypeGuard[DTODataStub[Any]]":
|
|
855
|
+
"""Check if a value is a Litestar DTOData object.
|
|
856
|
+
|
|
857
|
+
Args:
|
|
858
|
+
v: Value to check.
|
|
859
|
+
|
|
860
|
+
Returns:
|
|
861
|
+
bool
|
|
862
|
+
"""
|
|
863
|
+
return bool(LITESTAR_INSTALLED) and isinstance(v, DTOData)
|
|
864
|
+
|
|
865
|
+
|
|
866
|
+
def is_expression(obj: Any) -> "TypeGuard[exp.Expression]":
|
|
867
|
+
"""Check if a value is a sqlglot Expression.
|
|
868
|
+
|
|
869
|
+
Args:
|
|
870
|
+
obj: Value to check.
|
|
871
|
+
|
|
872
|
+
Returns:
|
|
873
|
+
bool
|
|
874
|
+
"""
|
|
875
|
+
return isinstance(obj, exp.Expression)
|
|
876
|
+
|
|
877
|
+
|
|
878
|
+
def has_dict_attribute(obj: Any) -> "TypeGuard[DictProtocol]":
|
|
879
|
+
"""Check if an object has a __dict__ attribute.
|
|
880
|
+
|
|
881
|
+
Args:
|
|
882
|
+
obj: Value to check.
|
|
883
|
+
|
|
884
|
+
Returns:
|
|
885
|
+
bool
|
|
886
|
+
"""
|
|
887
|
+
return isinstance(obj, DictProtocol)
|
|
888
|
+
|
|
889
|
+
|
|
890
|
+
def extract_dataclass_fields(
|
|
891
|
+
obj: "DataclassProtocol",
|
|
892
|
+
exclude_none: bool = False,
|
|
893
|
+
exclude_empty: bool = False,
|
|
894
|
+
include: "AbstractSet[str] | None" = None,
|
|
895
|
+
exclude: "AbstractSet[str] | None" = None,
|
|
896
|
+
) -> "tuple[Field[Any], ...]":
|
|
897
|
+
"""Extract dataclass fields.
|
|
898
|
+
|
|
899
|
+
Args:
|
|
900
|
+
obj: A dataclass instance.
|
|
901
|
+
exclude_none: Whether to exclude None values.
|
|
902
|
+
exclude_empty: Whether to exclude Empty values.
|
|
903
|
+
include: An iterable of fields to include.
|
|
904
|
+
exclude: An iterable of fields to exclude.
|
|
905
|
+
|
|
906
|
+
Raises:
|
|
907
|
+
ValueError: If there are fields that are both included and excluded.
|
|
908
|
+
|
|
909
|
+
Returns:
|
|
910
|
+
A tuple of dataclass fields.
|
|
911
|
+
"""
|
|
912
|
+
include = include or set()
|
|
913
|
+
exclude = exclude or set()
|
|
914
|
+
|
|
915
|
+
if common := (include & exclude):
|
|
916
|
+
msg = f"Fields {common} are both included and excluded."
|
|
917
|
+
raise ValueError(msg)
|
|
918
|
+
|
|
919
|
+
dataclass_fields: list[Field[Any]] = list(dataclasses_fields(obj))
|
|
920
|
+
if exclude_none:
|
|
921
|
+
dataclass_fields = [field for field in dataclass_fields if object.__getattribute__(obj, field.name) is not None]
|
|
922
|
+
if exclude_empty:
|
|
923
|
+
dataclass_fields = [
|
|
924
|
+
field for field in dataclass_fields if object.__getattribute__(obj, field.name) is not Empty
|
|
925
|
+
]
|
|
926
|
+
if include:
|
|
927
|
+
dataclass_fields = [field for field in dataclass_fields if field.name in include]
|
|
928
|
+
if exclude:
|
|
929
|
+
dataclass_fields = [field for field in dataclass_fields if field.name not in exclude]
|
|
930
|
+
|
|
931
|
+
return tuple(dataclass_fields)
|
|
932
|
+
|
|
933
|
+
|
|
934
|
+
def extract_dataclass_items(
|
|
935
|
+
obj: "DataclassProtocol",
|
|
936
|
+
exclude_none: bool = False,
|
|
937
|
+
exclude_empty: bool = False,
|
|
938
|
+
include: "AbstractSet[str] | None" = None,
|
|
939
|
+
exclude: "AbstractSet[str] | None" = None,
|
|
940
|
+
) -> "tuple[tuple[str, Any], ...]":
|
|
941
|
+
"""Extract name-value pairs from a dataclass instance.
|
|
942
|
+
|
|
943
|
+
Args:
|
|
944
|
+
obj: A dataclass instance.
|
|
945
|
+
exclude_none: Whether to exclude None values.
|
|
946
|
+
exclude_empty: Whether to exclude Empty values.
|
|
947
|
+
include: An iterable of fields to include.
|
|
948
|
+
exclude: An iterable of fields to exclude.
|
|
949
|
+
|
|
950
|
+
Returns:
|
|
951
|
+
A tuple of key/value pairs.
|
|
952
|
+
"""
|
|
953
|
+
dataclass_fields = extract_dataclass_fields(obj, exclude_none, exclude_empty, include, exclude)
|
|
954
|
+
return tuple((field.name, object.__getattribute__(obj, field.name)) for field in dataclass_fields)
|
|
955
|
+
|
|
956
|
+
|
|
957
|
+
def dataclass_to_dict(
|
|
958
|
+
obj: "DataclassProtocol",
|
|
959
|
+
exclude_none: bool = False,
|
|
960
|
+
exclude_empty: bool = False,
|
|
961
|
+
convert_nested: bool = True,
|
|
962
|
+
exclude: "AbstractSet[str] | None" = None,
|
|
963
|
+
) -> "dict[str, Any]":
|
|
964
|
+
"""Convert a dataclass instance to a dictionary.
|
|
965
|
+
|
|
966
|
+
Args:
|
|
967
|
+
obj: A dataclass instance.
|
|
968
|
+
exclude_none: Whether to exclude None values.
|
|
969
|
+
exclude_empty: Whether to exclude Empty values.
|
|
970
|
+
convert_nested: Whether to recursively convert nested dataclasses.
|
|
971
|
+
exclude: An iterable of fields to exclude.
|
|
972
|
+
|
|
973
|
+
Returns:
|
|
974
|
+
A dictionary of key/value pairs.
|
|
975
|
+
"""
|
|
976
|
+
ret = {}
|
|
977
|
+
for field in extract_dataclass_fields(obj, exclude_none, exclude_empty, exclude=exclude):
|
|
978
|
+
value = object.__getattribute__(obj, field.name)
|
|
979
|
+
if is_dataclass_instance(value) and convert_nested:
|
|
980
|
+
ret[field.name] = dataclass_to_dict(value, exclude_none, exclude_empty)
|
|
981
|
+
else:
|
|
982
|
+
ret[field.name] = value
|
|
983
|
+
return cast("dict[str, Any]", ret)
|
|
984
|
+
|
|
985
|
+
|
|
986
|
+
def get_node_this(node: "exp.Expression", default: Any | None = None) -> Any:
|
|
987
|
+
"""Safely get the 'this' attribute from a SQLGlot node.
|
|
988
|
+
|
|
989
|
+
Args:
|
|
990
|
+
node: The SQLGlot expression node
|
|
991
|
+
default: Default value if 'this' attribute doesn't exist
|
|
992
|
+
|
|
993
|
+
Returns:
|
|
994
|
+
The value of node.this or the default value
|
|
995
|
+
"""
|
|
996
|
+
try:
|
|
997
|
+
return node.this
|
|
998
|
+
except AttributeError:
|
|
999
|
+
return default
|
|
1000
|
+
|
|
1001
|
+
|
|
1002
|
+
def has_this_attribute(node: "exp.Expression") -> bool:
|
|
1003
|
+
"""Check if a node has the 'this' attribute without using hasattr().
|
|
1004
|
+
|
|
1005
|
+
Args:
|
|
1006
|
+
node: The SQLGlot expression node
|
|
1007
|
+
|
|
1008
|
+
Returns:
|
|
1009
|
+
True if the node has a 'this' attribute, False otherwise
|
|
1010
|
+
"""
|
|
1011
|
+
try:
|
|
1012
|
+
_ = node.this
|
|
1013
|
+
except AttributeError:
|
|
1014
|
+
return False
|
|
1015
|
+
return True
|
|
1016
|
+
|
|
1017
|
+
|
|
1018
|
+
def get_node_expressions(node: "exp.Expression", default: Any | None = None) -> Any:
|
|
1019
|
+
"""Safely get the 'expressions' attribute from a SQLGlot node.
|
|
1020
|
+
|
|
1021
|
+
Args:
|
|
1022
|
+
node: The SQLGlot expression node
|
|
1023
|
+
default: Default value if 'expressions' attribute doesn't exist
|
|
1024
|
+
|
|
1025
|
+
Returns:
|
|
1026
|
+
The value of node.expressions or the default value
|
|
1027
|
+
"""
|
|
1028
|
+
try:
|
|
1029
|
+
return node.expressions
|
|
1030
|
+
except AttributeError:
|
|
1031
|
+
return default
|
|
1032
|
+
|
|
1033
|
+
|
|
1034
|
+
def has_expressions_attribute(node: "exp.Expression") -> bool:
|
|
1035
|
+
"""Check if a node has the 'expressions' attribute without using hasattr().
|
|
1036
|
+
|
|
1037
|
+
Args:
|
|
1038
|
+
node: The SQLGlot expression node
|
|
1039
|
+
|
|
1040
|
+
Returns:
|
|
1041
|
+
True if the node has an 'expressions' attribute, False otherwise
|
|
1042
|
+
"""
|
|
1043
|
+
try:
|
|
1044
|
+
_ = node.expressions
|
|
1045
|
+
except AttributeError:
|
|
1046
|
+
return False
|
|
1047
|
+
return True
|
|
1048
|
+
|
|
1049
|
+
|
|
1050
|
+
def get_literal_parent(literal: "exp.Expression", default: Any | None = None) -> Any:
|
|
1051
|
+
"""Safely get the 'parent' attribute from a SQLGlot literal.
|
|
1052
|
+
|
|
1053
|
+
Args:
|
|
1054
|
+
literal: The SQLGlot expression
|
|
1055
|
+
default: Default value if 'parent' attribute doesn't exist
|
|
1056
|
+
|
|
1057
|
+
Returns:
|
|
1058
|
+
The value of literal.parent or the default value
|
|
1059
|
+
"""
|
|
1060
|
+
try:
|
|
1061
|
+
return literal.parent
|
|
1062
|
+
except AttributeError:
|
|
1063
|
+
return default
|
|
1064
|
+
|
|
1065
|
+
|
|
1066
|
+
def has_parent_attribute(literal: "exp.Expression") -> bool:
|
|
1067
|
+
"""Check if a literal has the 'parent' attribute without using hasattr().
|
|
1068
|
+
|
|
1069
|
+
Args:
|
|
1070
|
+
literal: The SQLGlot expression
|
|
1071
|
+
|
|
1072
|
+
Returns:
|
|
1073
|
+
True if the literal has a 'parent' attribute, False otherwise
|
|
1074
|
+
"""
|
|
1075
|
+
try:
|
|
1076
|
+
_ = literal.parent
|
|
1077
|
+
except AttributeError:
|
|
1078
|
+
return False
|
|
1079
|
+
return True
|
|
1080
|
+
|
|
1081
|
+
|
|
1082
|
+
def is_string_literal(literal: "exp.Literal") -> bool:
|
|
1083
|
+
"""Check if a literal is a string literal without using hasattr().
|
|
1084
|
+
|
|
1085
|
+
Args:
|
|
1086
|
+
literal: The SQLGlot Literal expression
|
|
1087
|
+
|
|
1088
|
+
Returns:
|
|
1089
|
+
True if the literal is a string, False otherwise
|
|
1090
|
+
"""
|
|
1091
|
+
try:
|
|
1092
|
+
return bool(literal.is_string)
|
|
1093
|
+
except AttributeError:
|
|
1094
|
+
try:
|
|
1095
|
+
return isinstance(literal.this, str)
|
|
1096
|
+
except AttributeError:
|
|
1097
|
+
return False
|
|
1098
|
+
|
|
1099
|
+
|
|
1100
|
+
def is_number_literal(literal: "exp.Literal") -> bool:
|
|
1101
|
+
"""Check if a literal is a number literal without using hasattr().
|
|
1102
|
+
|
|
1103
|
+
Args:
|
|
1104
|
+
literal: The SQLGlot Literal expression
|
|
1105
|
+
|
|
1106
|
+
Returns:
|
|
1107
|
+
True if the literal is a number, False otherwise
|
|
1108
|
+
"""
|
|
1109
|
+
try:
|
|
1110
|
+
return bool(literal.is_number)
|
|
1111
|
+
except AttributeError:
|
|
1112
|
+
try:
|
|
1113
|
+
if literal.this is not None:
|
|
1114
|
+
float(str(literal.this))
|
|
1115
|
+
return True
|
|
1116
|
+
except (AttributeError, ValueError, TypeError):
|
|
1117
|
+
pass
|
|
1118
|
+
return False
|
|
1119
|
+
|
|
1120
|
+
|
|
1121
|
+
def get_initial_expression(context: Any) -> "exp.Expression | None":
|
|
1122
|
+
"""Safely get initial_expression from context.
|
|
1123
|
+
|
|
1124
|
+
Args:
|
|
1125
|
+
context: SQL processing context
|
|
1126
|
+
|
|
1127
|
+
Returns:
|
|
1128
|
+
The initial expression or None if not available
|
|
1129
|
+
"""
|
|
1130
|
+
try:
|
|
1131
|
+
return context.initial_expression # type: ignore[no-any-return]
|
|
1132
|
+
except AttributeError:
|
|
1133
|
+
return None
|
|
1134
|
+
|
|
1135
|
+
|
|
1136
|
+
def expression_has_limit(expr: "exp.Expression | None") -> bool:
|
|
1137
|
+
"""Check if an expression has a limit clause.
|
|
1138
|
+
|
|
1139
|
+
Args:
|
|
1140
|
+
expr: SQLGlot expression to check
|
|
1141
|
+
|
|
1142
|
+
Returns:
|
|
1143
|
+
True if expression has limit in args, False otherwise
|
|
1144
|
+
"""
|
|
1145
|
+
if expr is None:
|
|
1146
|
+
return False
|
|
1147
|
+
try:
|
|
1148
|
+
return "limit" in expr.args
|
|
1149
|
+
except AttributeError:
|
|
1150
|
+
return False
|
|
1151
|
+
|
|
1152
|
+
|
|
1153
|
+
def get_value_attribute(obj: Any) -> Any:
|
|
1154
|
+
"""Safely get the 'value' attribute from an object.
|
|
1155
|
+
|
|
1156
|
+
Args:
|
|
1157
|
+
obj: Object to get value from
|
|
1158
|
+
|
|
1159
|
+
Returns:
|
|
1160
|
+
The value attribute or the object itself if no value attribute
|
|
1161
|
+
"""
|
|
1162
|
+
if isinstance(obj, HasValueProtocol):
|
|
1163
|
+
return obj.value
|
|
1164
|
+
return obj
|
|
1165
|
+
|
|
1166
|
+
|
|
1167
|
+
def get_param_style_and_name(param: Any) -> "tuple[str | None, str | None]":
|
|
1168
|
+
"""Safely get style and name attributes from a parameter.
|
|
1169
|
+
|
|
1170
|
+
Args:
|
|
1171
|
+
param: Parameter object
|
|
1172
|
+
|
|
1173
|
+
Returns:
|
|
1174
|
+
Tuple of (style, name) or (None, None) if attributes don't exist
|
|
1175
|
+
"""
|
|
1176
|
+
try:
|
|
1177
|
+
style = param.style
|
|
1178
|
+
name = param.name
|
|
1179
|
+
except AttributeError:
|
|
1180
|
+
return None, None
|
|
1181
|
+
return style, name
|
|
1182
|
+
|
|
1183
|
+
|
|
1184
|
+
def is_copy_statement(expression: Any) -> "TypeGuard[exp.Expression]":
|
|
1185
|
+
"""Check if the SQL expression is a PostgreSQL COPY statement.
|
|
1186
|
+
|
|
1187
|
+
Args:
|
|
1188
|
+
expression: The SQL expression to check
|
|
1189
|
+
|
|
1190
|
+
Returns:
|
|
1191
|
+
True if this is a COPY statement, False otherwise
|
|
1192
|
+
"""
|
|
1193
|
+
if expression is None:
|
|
1194
|
+
return False
|
|
1195
|
+
|
|
1196
|
+
try:
|
|
1197
|
+
copy_expr = exp.Copy
|
|
1198
|
+
except AttributeError:
|
|
1199
|
+
copy_expr = None
|
|
1200
|
+
if copy_expr is not None and isinstance(expression, copy_expr):
|
|
1201
|
+
return True
|
|
1202
|
+
|
|
1203
|
+
if isinstance(expression, (exp.Command, exp.Anonymous)):
|
|
1204
|
+
sql_text = str(expression).strip().upper()
|
|
1205
|
+
return sql_text.startswith("COPY ")
|
|
1206
|
+
|
|
1207
|
+
return False
|
|
1208
|
+
|
|
1209
|
+
|
|
1210
|
+
def is_typed_parameter(obj: Any) -> "TypeGuard[TypedParameter]":
|
|
1211
|
+
"""Check if an object is a typed parameter.
|
|
1212
|
+
|
|
1213
|
+
Args:
|
|
1214
|
+
obj: The object to check
|
|
1215
|
+
|
|
1216
|
+
Returns:
|
|
1217
|
+
True if the object is a TypedParameter, False otherwise
|
|
1218
|
+
"""
|
|
1219
|
+
from sqlspec.core.parameters import TypedParameter
|
|
1220
|
+
|
|
1221
|
+
return isinstance(obj, TypedParameter)
|
|
1222
|
+
|
|
1223
|
+
|
|
1224
|
+
def has_expression_and_sql(obj: Any) -> "TypeGuard[HasExpressionAndSQLProtocol]":
|
|
1225
|
+
"""Check if an object has both 'expression' and 'sql' attributes.
|
|
1226
|
+
|
|
1227
|
+
This is commonly used to identify SQL objects in the builder system.
|
|
1228
|
+
|
|
1229
|
+
Args:
|
|
1230
|
+
obj: The object to check
|
|
1231
|
+
|
|
1232
|
+
Returns:
|
|
1233
|
+
True if the object has both attributes, False otherwise
|
|
1234
|
+
"""
|
|
1235
|
+
return isinstance(obj, HasExpressionAndSQLProtocol)
|
|
1236
|
+
|
|
1237
|
+
|
|
1238
|
+
def has_expression_and_parameters(obj: Any) -> "TypeGuard[HasExpressionAndParametersProtocol]":
|
|
1239
|
+
"""Check if an object has both 'expression' and 'parameters' attributes.
|
|
1240
|
+
|
|
1241
|
+
This is used to identify objects that contain both SQL expressions
|
|
1242
|
+
and parameter mappings.
|
|
1243
|
+
|
|
1244
|
+
Args:
|
|
1245
|
+
obj: The object to check
|
|
1246
|
+
|
|
1247
|
+
Returns:
|
|
1248
|
+
True if the object has both attributes, False otherwise
|
|
1249
|
+
"""
|
|
1250
|
+
return isinstance(obj, HasExpressionAndParametersProtocol)
|
|
1251
|
+
|
|
1252
|
+
|
|
1253
|
+
WINDOWS_DRIVE_PATTERN_LENGTH = 3
|
|
1254
|
+
|
|
1255
|
+
|
|
1256
|
+
def is_local_path(uri: str) -> bool:
|
|
1257
|
+
r"""Check if URI represents a local filesystem path.
|
|
1258
|
+
|
|
1259
|
+
Detects local paths including:
|
|
1260
|
+
- file:// URIs
|
|
1261
|
+
- Absolute paths (Unix: /, Windows: C:\\)
|
|
1262
|
+
- Relative paths (., .., ~)
|
|
1263
|
+
|
|
1264
|
+
Args:
|
|
1265
|
+
uri: URI or path string to check.
|
|
1266
|
+
|
|
1267
|
+
Returns:
|
|
1268
|
+
True if uri is a local path, False for remote URIs.
|
|
1269
|
+
|
|
1270
|
+
Examples:
|
|
1271
|
+
>>> is_local_path("file:///data/file.txt")
|
|
1272
|
+
True
|
|
1273
|
+
>>> is_local_path("/absolute/path")
|
|
1274
|
+
True
|
|
1275
|
+
>>> is_local_path("s3://bucket/key")
|
|
1276
|
+
False
|
|
1277
|
+
"""
|
|
1278
|
+
if not uri:
|
|
1279
|
+
return False
|
|
1280
|
+
|
|
1281
|
+
if "://" in uri and not uri.startswith("file://"):
|
|
1282
|
+
return False
|
|
1283
|
+
|
|
1284
|
+
if uri.startswith("file://"):
|
|
1285
|
+
return True
|
|
1286
|
+
|
|
1287
|
+
if uri.startswith("/"):
|
|
1288
|
+
return True
|
|
1289
|
+
|
|
1290
|
+
if uri.startswith((".", "~")):
|
|
1291
|
+
return True
|
|
1292
|
+
|
|
1293
|
+
if len(uri) >= WINDOWS_DRIVE_PATTERN_LENGTH and uri[1:3] == ":\\":
|
|
1294
|
+
return True
|
|
1295
|
+
|
|
1296
|
+
return "/" in uri or "\\" in uri
|
|
1297
|
+
|
|
1298
|
+
|
|
1299
|
+
def supports_arrow_results(obj: Any) -> "TypeGuard[SupportsArrowResults]":
|
|
1300
|
+
"""Check if object supports Arrow result format.
|
|
1301
|
+
|
|
1302
|
+
Use this type guard to check if a driver or adapter supports returning
|
|
1303
|
+
query results in Apache Arrow format via select_to_arrow() method.
|
|
1304
|
+
|
|
1305
|
+
Args:
|
|
1306
|
+
obj: Object to check for Arrow results support.
|
|
1307
|
+
|
|
1308
|
+
Returns:
|
|
1309
|
+
True if object implements SupportsArrowResults protocol.
|
|
1310
|
+
|
|
1311
|
+
Examples:
|
|
1312
|
+
>>> from sqlspec.adapters.duckdb import DuckDBDriver
|
|
1313
|
+
>>> driver = DuckDBDriver(...)
|
|
1314
|
+
>>> supports_arrow_results(driver)
|
|
1315
|
+
True
|
|
1316
|
+
"""
|
|
1317
|
+
return isinstance(obj, SupportsArrowResults)
|
|
1318
|
+
|
|
1319
|
+
|
|
1320
|
+
def has_parameter_builder(obj: Any) -> "TypeGuard[HasParameterBuilderProtocol]":
|
|
1321
|
+
"""Check if an object has an add_parameter method."""
|
|
1322
|
+
return isinstance(obj, HasParameterBuilderProtocol)
|
|
1323
|
+
|
|
1324
|
+
|
|
1325
|
+
def has_expression_attr(obj: Any) -> "TypeGuard[HasExpressionProtocol]":
|
|
1326
|
+
"""Check if an object has an _expression attribute."""
|
|
1327
|
+
return isinstance(obj, HasExpressionProtocol)
|
|
1328
|
+
|
|
1329
|
+
|
|
1330
|
+
def has_sqlglot_expression(obj: Any) -> "TypeGuard[HasSQLGlotExpressionProtocol]":
|
|
1331
|
+
"""Check if an object has a sqlglot_expression property."""
|
|
1332
|
+
return isinstance(obj, HasSQLGlotExpressionProtocol)
|
|
1333
|
+
|
|
1334
|
+
|
|
1335
|
+
def has_statement_config_factory(obj: Any) -> "TypeGuard[HasStatementConfigFactoryProtocol]":
|
|
1336
|
+
"""Check if an object has a _create_statement_config method.
|
|
1337
|
+
|
|
1338
|
+
Used to check if a config object can create statement configs dynamically.
|
|
1339
|
+
|
|
1340
|
+
Args:
|
|
1341
|
+
obj: The object to check.
|
|
1342
|
+
|
|
1343
|
+
Returns:
|
|
1344
|
+
True if the object has a _create_statement_config method.
|
|
1345
|
+
"""
|
|
1346
|
+
return isinstance(obj, HasStatementConfigFactoryProtocol)
|
|
1347
|
+
|
|
1348
|
+
|
|
1349
|
+
def has_migration_config(obj: Any) -> "TypeGuard[HasMigrationConfigProtocol]":
|
|
1350
|
+
"""Check if an object has a migration_config attribute.
|
|
1351
|
+
|
|
1352
|
+
Used to check if a database config supports migrations.
|
|
1353
|
+
|
|
1354
|
+
Args:
|
|
1355
|
+
obj: The object to check.
|
|
1356
|
+
|
|
1357
|
+
Returns:
|
|
1358
|
+
True if the object has a migration_config attribute.
|
|
1359
|
+
"""
|
|
1360
|
+
return isinstance(obj, HasMigrationConfigProtocol)
|