sqlspec 0.47.0__cp314-cp314-win_amd64.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.
- f68e0789eb443ecb1c2c__mypyc.cp314-win_amd64.pyd +0 -0
- sqlspec/__init__.py +167 -0
- sqlspec/__main__.py +12 -0
- sqlspec/__metadata__.py +14 -0
- sqlspec/_typing.py +714 -0
- sqlspec/adapters/__init__.py +0 -0
- sqlspec/adapters/adbc/__init__.py +13 -0
- sqlspec/adapters/adbc/_typing.py +106 -0
- sqlspec/adapters/adbc/adk/__init__.py +5 -0
- sqlspec/adapters/adbc/adk/store.py +1280 -0
- sqlspec/adapters/adbc/config.py +378 -0
- sqlspec/adapters/adbc/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/adbc/core.py +922 -0
- sqlspec/adapters/adbc/data_dictionary.py +339 -0
- sqlspec/adapters/adbc/driver.py +534 -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 +534 -0
- sqlspec/adapters/adbc/type_converter.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/adbc/type_converter.py +142 -0
- sqlspec/adapters/aiomysql/__init__.py +21 -0
- sqlspec/adapters/aiomysql/_typing.py +137 -0
- sqlspec/adapters/aiomysql/adk/__init__.py +5 -0
- sqlspec/adapters/aiomysql/adk/store.py +678 -0
- sqlspec/adapters/aiomysql/config.py +305 -0
- sqlspec/adapters/aiomysql/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/aiomysql/core.py +536 -0
- sqlspec/adapters/aiomysql/data_dictionary.py +121 -0
- sqlspec/adapters/aiomysql/driver.py +386 -0
- sqlspec/adapters/aiomysql/events/__init__.py +5 -0
- sqlspec/adapters/aiomysql/events/store.py +104 -0
- sqlspec/adapters/aiomysql/litestar/__init__.py +5 -0
- sqlspec/adapters/aiomysql/litestar/store.py +314 -0
- sqlspec/adapters/aiosqlite/__init__.py +26 -0
- sqlspec/adapters/aiosqlite/_typing.py +109 -0
- sqlspec/adapters/aiosqlite/adk/__init__.py +5 -0
- sqlspec/adapters/aiosqlite/adk/store.py +829 -0
- sqlspec/adapters/aiosqlite/config.py +315 -0
- sqlspec/adapters/aiosqlite/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/aiosqlite/core.py +315 -0
- sqlspec/adapters/aiosqlite/data_dictionary.py +202 -0
- sqlspec/adapters/aiosqlite/driver.py +311 -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.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/aiosqlite/pool.py +734 -0
- sqlspec/adapters/asyncmy/__init__.py +21 -0
- sqlspec/adapters/asyncmy/_typing.py +113 -0
- sqlspec/adapters/asyncmy/adk/__init__.py +5 -0
- sqlspec/adapters/asyncmy/adk/store.py +644 -0
- sqlspec/adapters/asyncmy/config.py +307 -0
- sqlspec/adapters/asyncmy/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/asyncmy/core.py +538 -0
- sqlspec/adapters/asyncmy/data_dictionary.py +122 -0
- sqlspec/adapters/asyncmy/driver.py +391 -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 +26 -0
- sqlspec/adapters/asyncpg/_typing.py +103 -0
- sqlspec/adapters/asyncpg/adk/__init__.py +5 -0
- sqlspec/adapters/asyncpg/adk/store.py +483 -0
- sqlspec/adapters/asyncpg/config.py +575 -0
- sqlspec/adapters/asyncpg/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/asyncpg/core.py +480 -0
- sqlspec/adapters/asyncpg/data_dictionary.py +157 -0
- sqlspec/adapters/asyncpg/driver.py +487 -0
- sqlspec/adapters/asyncpg/events/__init__.py +6 -0
- sqlspec/adapters/asyncpg/events/_hub.py +181 -0
- sqlspec/adapters/asyncpg/events/backend.py +210 -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 +15 -0
- sqlspec/adapters/bigquery/_typing.py +108 -0
- sqlspec/adapters/bigquery/config.py +362 -0
- sqlspec/adapters/bigquery/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/bigquery/core.py +768 -0
- sqlspec/adapters/bigquery/data_dictionary.py +120 -0
- sqlspec/adapters/bigquery/driver.py +542 -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.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/bigquery/type_converter.py +107 -0
- sqlspec/adapters/cockroach_asyncpg/__init__.py +26 -0
- sqlspec/adapters/cockroach_asyncpg/_typing.py +73 -0
- sqlspec/adapters/cockroach_asyncpg/adk/__init__.py +3 -0
- sqlspec/adapters/cockroach_asyncpg/adk/store.py +465 -0
- sqlspec/adapters/cockroach_asyncpg/config.py +248 -0
- sqlspec/adapters/cockroach_asyncpg/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/cockroach_asyncpg/core.py +55 -0
- sqlspec/adapters/cockroach_asyncpg/data_dictionary.py +110 -0
- sqlspec/adapters/cockroach_asyncpg/driver.py +142 -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 +39 -0
- sqlspec/adapters/cockroach_psycopg/_typing.py +137 -0
- sqlspec/adapters/cockroach_psycopg/adk/__init__.py +13 -0
- sqlspec/adapters/cockroach_psycopg/adk/store.py +1039 -0
- sqlspec/adapters/cockroach_psycopg/config.py +511 -0
- sqlspec/adapters/cockroach_psycopg/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/cockroach_psycopg/core.py +63 -0
- sqlspec/adapters/cockroach_psycopg/data_dictionary.py +220 -0
- sqlspec/adapters/cockroach_psycopg/driver.py +273 -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 +327 -0
- sqlspec/adapters/duckdb/__init__.py +29 -0
- sqlspec/adapters/duckdb/_typing.py +104 -0
- sqlspec/adapters/duckdb/adk/__init__.py +14 -0
- sqlspec/adapters/duckdb/adk/store.py +935 -0
- sqlspec/adapters/duckdb/config.py +386 -0
- sqlspec/adapters/duckdb/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/duckdb/core.py +332 -0
- sqlspec/adapters/duckdb/data_dictionary.py +140 -0
- sqlspec/adapters/duckdb/driver.py +426 -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.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/duckdb/pool.py +350 -0
- sqlspec/adapters/duckdb/type_converter.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/duckdb/type_converter.py +118 -0
- sqlspec/adapters/mysqlconnector/__init__.py +39 -0
- sqlspec/adapters/mysqlconnector/_typing.py +186 -0
- sqlspec/adapters/mysqlconnector/adk/__init__.py +15 -0
- sqlspec/adapters/mysqlconnector/adk/store.py +1183 -0
- sqlspec/adapters/mysqlconnector/config.py +421 -0
- sqlspec/adapters/mysqlconnector/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/mysqlconnector/core.py +472 -0
- sqlspec/adapters/mysqlconnector/data_dictionary.py +230 -0
- sqlspec/adapters/mysqlconnector/driver.py +516 -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 +39 -0
- sqlspec/adapters/oracledb/_json_handlers.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/oracledb/_json_handlers.py +196 -0
- sqlspec/adapters/oracledb/_param_types.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/oracledb/_param_types.py +46 -0
- sqlspec/adapters/oracledb/_typing.py +258 -0
- sqlspec/adapters/oracledb/_uuid_handlers.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/oracledb/_uuid_handlers.py +163 -0
- sqlspec/adapters/oracledb/_vector_handlers.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/oracledb/_vector_handlers.py +228 -0
- sqlspec/adapters/oracledb/adk/__init__.py +21 -0
- sqlspec/adapters/oracledb/adk/store.py +2453 -0
- sqlspec/adapters/oracledb/config.py +575 -0
- sqlspec/adapters/oracledb/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/oracledb/core.py +820 -0
- sqlspec/adapters/oracledb/data_dictionary.py +404 -0
- sqlspec/adapters/oracledb/driver.py +1277 -0
- sqlspec/adapters/oracledb/events/__init__.py +16 -0
- sqlspec/adapters/oracledb/events/_hub.py +345 -0
- sqlspec/adapters/oracledb/events/backend.py +300 -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 +539 -0
- sqlspec/adapters/oracledb/type_converter.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/oracledb/type_converter.py +211 -0
- sqlspec/adapters/psqlpy/__init__.py +18 -0
- sqlspec/adapters/psqlpy/_typing.py +121 -0
- sqlspec/adapters/psqlpy/adk/__init__.py +5 -0
- sqlspec/adapters/psqlpy/adk/store.py +591 -0
- sqlspec/adapters/psqlpy/config.py +376 -0
- sqlspec/adapters/psqlpy/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/psqlpy/core.py +694 -0
- sqlspec/adapters/psqlpy/data_dictionary.py +121 -0
- sqlspec/adapters/psqlpy/driver.py +411 -0
- sqlspec/adapters/psqlpy/events/__init__.py +6 -0
- sqlspec/adapters/psqlpy/events/_hub.py +204 -0
- sqlspec/adapters/psqlpy/events/backend.py +210 -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.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/psqlpy/type_converter.py +113 -0
- sqlspec/adapters/psycopg/__init__.py +38 -0
- sqlspec/adapters/psycopg/_typing.py +218 -0
- sqlspec/adapters/psycopg/adk/__init__.py +10 -0
- sqlspec/adapters/psycopg/adk/store.py +1106 -0
- sqlspec/adapters/psycopg/config.py +695 -0
- sqlspec/adapters/psycopg/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/psycopg/core.py +520 -0
- sqlspec/adapters/psycopg/data_dictionary.py +278 -0
- sqlspec/adapters/psycopg/driver.py +1033 -0
- sqlspec/adapters/psycopg/events/__init__.py +20 -0
- sqlspec/adapters/psycopg/events/_hub.py +388 -0
- sqlspec/adapters/psycopg/events/backend.py +398 -0
- sqlspec/adapters/psycopg/events/store.py +42 -0
- sqlspec/adapters/psycopg/litestar/__init__.py +5 -0
- sqlspec/adapters/psycopg/litestar/store.py +554 -0
- sqlspec/adapters/psycopg/type_converter.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/psycopg/type_converter.py +93 -0
- sqlspec/adapters/pymysql/__init__.py +21 -0
- sqlspec/adapters/pymysql/_typing.py +92 -0
- sqlspec/adapters/pymysql/adk/__init__.py +5 -0
- sqlspec/adapters/pymysql/adk/store.py +657 -0
- sqlspec/adapters/pymysql/config.py +176 -0
- sqlspec/adapters/pymysql/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/pymysql/core.py +469 -0
- sqlspec/adapters/pymysql/data_dictionary.py +120 -0
- sqlspec/adapters/pymysql/driver.py +271 -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.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/pymysql/pool.py +184 -0
- sqlspec/adapters/spanner/__init__.py +33 -0
- sqlspec/adapters/spanner/_typing.py +102 -0
- sqlspec/adapters/spanner/adk/__init__.py +5 -0
- sqlspec/adapters/spanner/adk/store.py +758 -0
- sqlspec/adapters/spanner/config.py +355 -0
- sqlspec/adapters/spanner/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/spanner/core.py +263 -0
- sqlspec/adapters/spanner/data_dictionary.py +120 -0
- sqlspec/adapters/spanner/driver.py +407 -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.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/spanner/type_converter.py +342 -0
- sqlspec/adapters/sqlite/__init__.py +19 -0
- sqlspec/adapters/sqlite/_typing.py +123 -0
- sqlspec/adapters/sqlite/adk/__init__.py +5 -0
- sqlspec/adapters/sqlite/adk/store.py +992 -0
- sqlspec/adapters/sqlite/config.py +240 -0
- sqlspec/adapters/sqlite/core.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/sqlite/core.py +357 -0
- sqlspec/adapters/sqlite/data_dictionary.py +198 -0
- sqlspec/adapters/sqlite/driver.py +527 -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.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/sqlite/pool.py +237 -0
- sqlspec/adapters/sqlite/type_converter.cp314-win_amd64.pyd +0 -0
- sqlspec/adapters/sqlite/type_converter.py +114 -0
- sqlspec/base.py +832 -0
- sqlspec/builder/__init__.py +181 -0
- sqlspec/builder/_base.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_base.py +1071 -0
- sqlspec/builder/_column.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_column.py +521 -0
- sqlspec/builder/_ddl.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_ddl.py +1691 -0
- sqlspec/builder/_delete.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_delete.py +95 -0
- sqlspec/builder/_dml.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_dml.py +386 -0
- sqlspec/builder/_explain.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_explain.py +579 -0
- sqlspec/builder/_expression_wrappers.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_expression_wrappers.py +46 -0
- sqlspec/builder/_factory.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_factory.py +1884 -0
- sqlspec/builder/_insert.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_insert.py +405 -0
- sqlspec/builder/_join.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_join.py +489 -0
- sqlspec/builder/_merge.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_merge.py +823 -0
- sqlspec/builder/_parsing_utils.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_parsing_utils.py +295 -0
- sqlspec/builder/_select.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_select.py +1666 -0
- sqlspec/builder/_temporal.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_temporal.py +167 -0
- sqlspec/builder/_update.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_update.py +173 -0
- sqlspec/builder/_vector_distance.cp314-win_amd64.pyd +0 -0
- sqlspec/builder/_vector_distance.py +330 -0
- sqlspec/cli.py +1095 -0
- sqlspec/config.py +2383 -0
- sqlspec/core/__init__.py +372 -0
- sqlspec/core/_correlation.cp314-win_amd64.pyd +0 -0
- sqlspec/core/_correlation.py +176 -0
- sqlspec/core/_pagination.py +42 -0
- sqlspec/core/_pool.cp314-win_amd64.pyd +0 -0
- sqlspec/core/_pool.py +76 -0
- sqlspec/core/cache.cp314-win_amd64.pyd +0 -0
- sqlspec/core/cache.py +1085 -0
- sqlspec/core/compiler.cp314-win_amd64.pyd +0 -0
- sqlspec/core/compiler.py +1090 -0
- sqlspec/core/config_runtime.cp314-win_amd64.pyd +0 -0
- sqlspec/core/config_runtime.py +174 -0
- sqlspec/core/explain.cp314-win_amd64.pyd +0 -0
- sqlspec/core/explain.py +275 -0
- sqlspec/core/filters.cp314-win_amd64.pyd +0 -0
- sqlspec/core/filters.py +969 -0
- sqlspec/core/hashing.cp314-win_amd64.pyd +0 -0
- sqlspec/core/hashing.py +266 -0
- sqlspec/core/metrics.cp314-win_amd64.pyd +0 -0
- sqlspec/core/metrics.py +83 -0
- sqlspec/core/parameters/__init__.py +72 -0
- sqlspec/core/parameters/_alignment.cp314-win_amd64.pyd +0 -0
- sqlspec/core/parameters/_alignment.py +283 -0
- sqlspec/core/parameters/_converter.cp314-win_amd64.pyd +0 -0
- sqlspec/core/parameters/_converter.py +554 -0
- sqlspec/core/parameters/_processor.cp314-win_amd64.pyd +0 -0
- sqlspec/core/parameters/_processor.py +1182 -0
- sqlspec/core/parameters/_registry.cp314-win_amd64.pyd +0 -0
- sqlspec/core/parameters/_registry.py +206 -0
- sqlspec/core/parameters/_transformers.cp314-win_amd64.pyd +0 -0
- sqlspec/core/parameters/_transformers.py +324 -0
- sqlspec/core/parameters/_types.cp314-win_amd64.pyd +0 -0
- sqlspec/core/parameters/_types.py +536 -0
- sqlspec/core/parameters/_validator.cp314-win_amd64.pyd +0 -0
- sqlspec/core/parameters/_validator.py +171 -0
- sqlspec/core/pipeline.cp314-win_amd64.pyd +0 -0
- sqlspec/core/pipeline.py +333 -0
- sqlspec/core/query_modifiers.cp314-win_amd64.pyd +0 -0
- sqlspec/core/query_modifiers.py +508 -0
- sqlspec/core/result/__init__.py +25 -0
- sqlspec/core/result/_base.cp314-win_amd64.pyd +0 -0
- sqlspec/core/result/_base.py +1232 -0
- sqlspec/core/result/_io.cp314-win_amd64.pyd +0 -0
- sqlspec/core/result/_io.py +28 -0
- sqlspec/core/splitter.cp314-win_amd64.pyd +0 -0
- sqlspec/core/splitter.py +1021 -0
- sqlspec/core/sqlcommenter.cp314-win_amd64.pyd +0 -0
- sqlspec/core/sqlcommenter.py +249 -0
- sqlspec/core/stack.cp314-win_amd64.pyd +0 -0
- sqlspec/core/stack.py +163 -0
- sqlspec/core/statement.cp314-win_amd64.pyd +0 -0
- sqlspec/core/statement.py +1865 -0
- sqlspec/core/type_converter.cp314-win_amd64.pyd +0 -0
- sqlspec/core/type_converter.py +340 -0
- sqlspec/data_dictionary/__init__.py +22 -0
- sqlspec/data_dictionary/_loader.cp314-win_amd64.pyd +0 -0
- sqlspec/data_dictionary/_loader.py +138 -0
- sqlspec/data_dictionary/_registry.cp314-win_amd64.pyd +0 -0
- sqlspec/data_dictionary/_registry.py +74 -0
- sqlspec/data_dictionary/_types.cp314-win_amd64.pyd +0 -0
- sqlspec/data_dictionary/_types.py +121 -0
- sqlspec/data_dictionary/dialects/__init__.py +21 -0
- sqlspec/data_dictionary/dialects/bigquery.cp314-win_amd64.pyd +0 -0
- sqlspec/data_dictionary/dialects/bigquery.py +81 -0
- sqlspec/data_dictionary/dialects/cockroachdb.cp314-win_amd64.pyd +0 -0
- sqlspec/data_dictionary/dialects/cockroachdb.py +54 -0
- sqlspec/data_dictionary/dialects/duckdb.cp314-win_amd64.pyd +0 -0
- sqlspec/data_dictionary/dialects/duckdb.py +47 -0
- sqlspec/data_dictionary/dialects/mysql.cp314-win_amd64.pyd +0 -0
- sqlspec/data_dictionary/dialects/mysql.py +53 -0
- sqlspec/data_dictionary/dialects/oracle.cp314-win_amd64.pyd +0 -0
- sqlspec/data_dictionary/dialects/oracle.py +197 -0
- sqlspec/data_dictionary/dialects/postgres.cp314-win_amd64.pyd +0 -0
- sqlspec/data_dictionary/dialects/postgres.py +69 -0
- sqlspec/data_dictionary/dialects/spanner.cp314-win_amd64.pyd +0 -0
- sqlspec/data_dictionary/dialects/spanner.py +37 -0
- sqlspec/data_dictionary/dialects/sqlite.cp314-win_amd64.pyd +0 -0
- sqlspec/data_dictionary/dialects/sqlite.py +59 -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/dialects/__init__.py +22 -0
- sqlspec/dialects/_compat.cp314-win_amd64.pyd +0 -0
- sqlspec/dialects/_compat.py +14 -0
- sqlspec/dialects/postgres/__init__.py +9 -0
- sqlspec/dialects/postgres/_generators.cp314-win_amd64.pyd +0 -0
- sqlspec/dialects/postgres/_generators.py +57 -0
- sqlspec/dialects/postgres/_operators.cp314-win_amd64.pyd +0 -0
- sqlspec/dialects/postgres/_operators.py +81 -0
- sqlspec/dialects/postgres/_paradedb.py +50 -0
- sqlspec/dialects/postgres/_pgvector.py +36 -0
- sqlspec/dialects/spanner/__init__.py +6 -0
- sqlspec/dialects/spanner/_generators.cp314-win_amd64.pyd +0 -0
- sqlspec/dialects/spanner/_generators.py +206 -0
- sqlspec/dialects/spanner/_spangres.py +77 -0
- sqlspec/dialects/spanner/_spanner.py +179 -0
- sqlspec/driver/__init__.py +49 -0
- sqlspec/driver/_async.cp314-win_amd64.pyd +0 -0
- sqlspec/driver/_async.py +1830 -0
- sqlspec/driver/_common.cp314-win_amd64.pyd +0 -0
- sqlspec/driver/_common.py +2292 -0
- sqlspec/driver/_exception_handler.cp314-win_amd64.pyd +0 -0
- sqlspec/driver/_exception_handler.py +108 -0
- sqlspec/driver/_query_cache.cp314-win_amd64.pyd +0 -0
- sqlspec/driver/_query_cache.py +96 -0
- sqlspec/driver/_sql_helpers.cp314-win_amd64.pyd +0 -0
- sqlspec/driver/_sql_helpers.py +139 -0
- sqlspec/driver/_storage_helpers.cp314-win_amd64.pyd +0 -0
- sqlspec/driver/_storage_helpers.py +153 -0
- sqlspec/driver/_sync.cp314-win_amd64.pyd +0 -0
- sqlspec/driver/_sync.py +1817 -0
- sqlspec/exceptions.cp314-win_amd64.pyd +0 -0
- sqlspec/exceptions.py +480 -0
- sqlspec/extensions/__init__.py +0 -0
- sqlspec/extensions/adk/__init__.py +84 -0
- sqlspec/extensions/adk/_config_utils.py +199 -0
- sqlspec/extensions/adk/_types.cp314-win_amd64.pyd +0 -0
- sqlspec/extensions/adk/_types.py +41 -0
- sqlspec/extensions/adk/artifact/__init__.py +57 -0
- sqlspec/extensions/adk/artifact/_types.cp314-win_amd64.pyd +0 -0
- sqlspec/extensions/adk/artifact/_types.py +32 -0
- sqlspec/extensions/adk/artifact/service.py +508 -0
- sqlspec/extensions/adk/artifact/store.py +361 -0
- sqlspec/extensions/adk/converters.py +212 -0
- sqlspec/extensions/adk/memory/__init__.py +69 -0
- sqlspec/extensions/adk/memory/_types.cp314-win_amd64.pyd +0 -0
- sqlspec/extensions/adk/memory/_types.py +30 -0
- sqlspec/extensions/adk/memory/converters.py +225 -0
- sqlspec/extensions/adk/memory/service.py +316 -0
- sqlspec/extensions/adk/memory/store.py +525 -0
- sqlspec/extensions/adk/migrations/0001_create_adk_tables.py +184 -0
- sqlspec/extensions/adk/migrations/__init__.py +0 -0
- sqlspec/extensions/adk/service.py +279 -0
- sqlspec/extensions/adk/store.py +590 -0
- sqlspec/extensions/events/__init__.py +51 -0
- sqlspec/extensions/events/_channel.py +703 -0
- sqlspec/extensions/events/_hints.cp314-win_amd64.pyd +0 -0
- sqlspec/extensions/events/_hints.py +45 -0
- sqlspec/extensions/events/_models.py +23 -0
- sqlspec/extensions/events/_payload.cp314-win_amd64.pyd +0 -0
- sqlspec/extensions/events/_payload.py +69 -0
- sqlspec/extensions/events/_protocols.py +134 -0
- sqlspec/extensions/events/_queue.py +462 -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 +22 -0
- sqlspec/extensions/fastapi/extension.py +391 -0
- sqlspec/extensions/fastapi/providers.cp314-win_amd64.pyd +0 -0
- sqlspec/extensions/fastapi/providers.py +712 -0
- sqlspec/extensions/flask/__init__.py +38 -0
- sqlspec/extensions/flask/_state.py +87 -0
- sqlspec/extensions/flask/_utils.py +71 -0
- sqlspec/extensions/flask/extension.py +539 -0
- sqlspec/extensions/litestar/__init__.py +31 -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 +1066 -0
- sqlspec/extensions/litestar/providers.cp314-win_amd64.pyd +0 -0
- sqlspec/extensions/litestar/providers.py +784 -0
- sqlspec/extensions/litestar/store.py +298 -0
- sqlspec/extensions/otel/__init__.py +58 -0
- sqlspec/extensions/prometheus/__init__.py +113 -0
- sqlspec/extensions/sanic/__init__.py +19 -0
- sqlspec/extensions/sanic/_state.py +43 -0
- sqlspec/extensions/sanic/_utils.py +127 -0
- sqlspec/extensions/sanic/extension.py +647 -0
- sqlspec/extensions/starlette/__init__.py +22 -0
- sqlspec/extensions/starlette/_state.py +42 -0
- sqlspec/extensions/starlette/_utils.py +96 -0
- sqlspec/extensions/starlette/extension.py +374 -0
- sqlspec/extensions/starlette/middleware.py +281 -0
- sqlspec/loader.cp314-win_amd64.pyd +0 -0
- sqlspec/loader.py +727 -0
- sqlspec/migrations/__init__.py +39 -0
- sqlspec/migrations/base.cp314-win_amd64.pyd +0 -0
- sqlspec/migrations/base.py +862 -0
- sqlspec/migrations/commands.py +2151 -0
- sqlspec/migrations/context.cp314-win_amd64.pyd +0 -0
- sqlspec/migrations/context.py +157 -0
- sqlspec/migrations/fix.cp314-win_amd64.pyd +0 -0
- sqlspec/migrations/fix.py +204 -0
- sqlspec/migrations/loaders.cp314-win_amd64.pyd +0 -0
- sqlspec/migrations/loaders.py +443 -0
- sqlspec/migrations/runner.cp314-win_amd64.pyd +0 -0
- sqlspec/migrations/runner.py +1195 -0
- sqlspec/migrations/squash.cp314-win_amd64.pyd +0 -0
- sqlspec/migrations/squash.py +490 -0
- sqlspec/migrations/templates.cp314-win_amd64.pyd +0 -0
- sqlspec/migrations/templates.py +234 -0
- sqlspec/migrations/tracker.cp314-win_amd64.pyd +0 -0
- sqlspec/migrations/tracker.py +792 -0
- sqlspec/migrations/utils.cp314-win_amd64.pyd +0 -0
- sqlspec/migrations/utils.py +256 -0
- sqlspec/migrations/validation.cp314-win_amd64.pyd +0 -0
- sqlspec/migrations/validation.py +359 -0
- sqlspec/migrations/version.cp314-win_amd64.pyd +0 -0
- sqlspec/migrations/version.py +446 -0
- sqlspec/observability/__init__.py +57 -0
- sqlspec/observability/_common.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_common.py +77 -0
- sqlspec/observability/_config.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_config.py +364 -0
- sqlspec/observability/_diagnostics.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_diagnostics.py +74 -0
- sqlspec/observability/_dispatcher.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_dispatcher.py +200 -0
- sqlspec/observability/_formatters/__init__.py +13 -0
- sqlspec/observability/_formatters/_aws.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_formatters/_aws.py +102 -0
- sqlspec/observability/_formatters/_azure.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_formatters/_azure.py +96 -0
- sqlspec/observability/_formatters/_base.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_formatters/_base.py +57 -0
- sqlspec/observability/_formatters/_gcp.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_formatters/_gcp.py +131 -0
- sqlspec/observability/_formatting.py +58 -0
- sqlspec/observability/_observer.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_observer.py +361 -0
- sqlspec/observability/_runtime.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_runtime.py +461 -0
- sqlspec/observability/_sampling.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_sampling.py +188 -0
- sqlspec/observability/_spans.cp314-win_amd64.pyd +0 -0
- sqlspec/observability/_spans.py +161 -0
- sqlspec/protocols.py +955 -0
- sqlspec/py.typed +0 -0
- sqlspec/service.py +433 -0
- sqlspec/storage/__init__.py +48 -0
- sqlspec/storage/_arrow_payload.py +68 -0
- sqlspec/storage/_paths.cp314-win_amd64.pyd +0 -0
- sqlspec/storage/_paths.py +58 -0
- sqlspec/storage/_utils.py +46 -0
- sqlspec/storage/backends/__init__.py +1 -0
- sqlspec/storage/backends/base.cp314-win_amd64.pyd +0 -0
- sqlspec/storage/backends/base.py +374 -0
- sqlspec/storage/backends/fsspec.py +574 -0
- sqlspec/storage/backends/local.py +468 -0
- sqlspec/storage/backends/obstore.py +956 -0
- sqlspec/storage/errors.cp314-win_amd64.pyd +0 -0
- sqlspec/storage/errors.py +102 -0
- sqlspec/storage/pipeline.cp314-win_amd64.pyd +0 -0
- sqlspec/storage/pipeline.py +628 -0
- sqlspec/storage/registry.cp314-win_amd64.pyd +0 -0
- sqlspec/storage/registry.py +329 -0
- sqlspec/typing.py +405 -0
- sqlspec/utils/__init__.py +7 -0
- sqlspec/utils/arrow_helpers.py +384 -0
- sqlspec/utils/config_tools.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/config_tools.py +314 -0
- sqlspec/utils/correlation.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/correlation.py +134 -0
- sqlspec/utils/deprecation.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/deprecation.py +157 -0
- sqlspec/utils/dispatch.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/dispatch.py +101 -0
- sqlspec/utils/fixtures.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/fixtures.py +260 -0
- sqlspec/utils/logging.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/logging.py +251 -0
- sqlspec/utils/module_loader.py +306 -0
- sqlspec/utils/portal.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/portal.py +377 -0
- sqlspec/utils/schema.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/schema.py +1040 -0
- sqlspec/utils/serializers/__init__.py +30 -0
- sqlspec/utils/serializers/_json.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/serializers/_json.py +415 -0
- sqlspec/utils/serializers/_numpy.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/serializers/_numpy.py +65 -0
- sqlspec/utils/serializers/_schema.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/serializers/_schema.py +285 -0
- sqlspec/utils/singleton.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/singleton.py +41 -0
- sqlspec/utils/sync_tools.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/sync_tools.py +316 -0
- sqlspec/utils/text.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/text.py +109 -0
- sqlspec/utils/type_converters.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/type_converters.py +216 -0
- sqlspec/utils/type_guards.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/type_guards.py +1508 -0
- sqlspec/utils/uuids.cp314-win_amd64.pyd +0 -0
- sqlspec/utils/uuids.py +241 -0
- sqlspec-0.47.0.dist-info/METADATA +202 -0
- sqlspec-0.47.0.dist-info/RECORD +621 -0
- sqlspec-0.47.0.dist-info/WHEEL +4 -0
- sqlspec-0.47.0.dist-info/entry_points.txt +6 -0
- sqlspec-0.47.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,820 @@
|
|
|
1
|
+
"""OracleDB adapter compiled helpers."""
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
from collections.abc import Sized
|
|
5
|
+
from typing import TYPE_CHECKING, Any, cast
|
|
6
|
+
|
|
7
|
+
from sqlspec.adapters.oracledb._param_types import OracleBlob, OracleClob, OracleJson
|
|
8
|
+
from sqlspec.adapters.oracledb.type_converter import OracleOutputConverter
|
|
9
|
+
from sqlspec.core import (
|
|
10
|
+
DriverParameterProfile,
|
|
11
|
+
ParameterStyle,
|
|
12
|
+
StackResult,
|
|
13
|
+
StatementConfig,
|
|
14
|
+
build_statement_config_from_profile,
|
|
15
|
+
create_sql_result,
|
|
16
|
+
)
|
|
17
|
+
from sqlspec.exceptions import (
|
|
18
|
+
CheckViolationError,
|
|
19
|
+
ConnectionTimeoutError,
|
|
20
|
+
DatabaseConnectionError,
|
|
21
|
+
DataError,
|
|
22
|
+
DeadlockError,
|
|
23
|
+
ForeignKeyViolationError,
|
|
24
|
+
IntegrityError,
|
|
25
|
+
NotNullViolationError,
|
|
26
|
+
OperationalError,
|
|
27
|
+
PermissionDeniedError,
|
|
28
|
+
QueryTimeoutError,
|
|
29
|
+
SQLParsingError,
|
|
30
|
+
SQLSpecError,
|
|
31
|
+
TransactionError,
|
|
32
|
+
UniqueViolationError,
|
|
33
|
+
)
|
|
34
|
+
from sqlspec.typing import NUMPY_INSTALLED
|
|
35
|
+
from sqlspec.utils.serializers import to_json
|
|
36
|
+
from sqlspec.utils.type_converters import build_uuid_coercions
|
|
37
|
+
from sqlspec.utils.type_guards import has_rowcount, is_readable
|
|
38
|
+
|
|
39
|
+
if TYPE_CHECKING:
|
|
40
|
+
from collections.abc import Callable, Mapping
|
|
41
|
+
|
|
42
|
+
from sqlspec.core import SQL
|
|
43
|
+
|
|
44
|
+
__all__ = (
|
|
45
|
+
"apply_driver_features",
|
|
46
|
+
"build_insert_statement",
|
|
47
|
+
"build_pipeline_stack_result",
|
|
48
|
+
"build_profile",
|
|
49
|
+
"build_statement_config",
|
|
50
|
+
"build_truncate_statement",
|
|
51
|
+
"coerce_large_parameters_async",
|
|
52
|
+
"coerce_large_parameters_sync",
|
|
53
|
+
"collect_async_rows",
|
|
54
|
+
"collect_sync_rows",
|
|
55
|
+
"create_mapped_exception",
|
|
56
|
+
"default_statement_config",
|
|
57
|
+
"driver_profile",
|
|
58
|
+
"normalize_column_names",
|
|
59
|
+
"normalize_execute_many_parameters_async",
|
|
60
|
+
"normalize_execute_many_parameters_sync",
|
|
61
|
+
"requires_session_callback",
|
|
62
|
+
"resolve_row_metadata",
|
|
63
|
+
"resolve_rowcount",
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
IMPLICIT_UPPER_COLUMN_PATTERN: "re.Pattern[str]" = re.compile(r"^(?!\d)(?:[A-Z0-9_]+)$")
|
|
68
|
+
_VERSION_COMPONENTS: int = 3
|
|
69
|
+
TYPE_CONVERTER = OracleOutputConverter()
|
|
70
|
+
_LOB_TYPE_NAME_MARKERS: "tuple[str, ...]" = ("LOB", "BFILE")
|
|
71
|
+
_SCALAR_PASSTHROUGH_TYPES: "tuple[type[Any], ...]" = (bool, int, float, str, bytes, bytearray, type(None))
|
|
72
|
+
ROW_CACHE_MAX_SIZE: int = 256
|
|
73
|
+
|
|
74
|
+
# Oracle ORA error code ranges for category detection
|
|
75
|
+
ORA_CHECK_CONSTRAINT = 2290
|
|
76
|
+
ORA_INTEGRITY_RANGE_START = 2200
|
|
77
|
+
ORA_INTEGRITY_RANGE_END = 2300
|
|
78
|
+
ORA_PARSING_RANGE_START = 900
|
|
79
|
+
ORA_PARSING_RANGE_END = 1000
|
|
80
|
+
ORA_TABLESPACE_FULL = 1652
|
|
81
|
+
|
|
82
|
+
# Oracle error codes for specific exception mappings
|
|
83
|
+
_ERROR_CODE_MAPPING: "dict[int, tuple[type[SQLSpecError], str]]" = {
|
|
84
|
+
# Integrity constraint violations
|
|
85
|
+
1: (UniqueViolationError, "unique constraint violation"),
|
|
86
|
+
2291: (ForeignKeyViolationError, "foreign key constraint violation"),
|
|
87
|
+
2292: (ForeignKeyViolationError, "foreign key constraint violation"),
|
|
88
|
+
ORA_CHECK_CONSTRAINT: (CheckViolationError, "check constraint violation"),
|
|
89
|
+
1400: (NotNullViolationError, "not-null constraint violation"),
|
|
90
|
+
1407: (NotNullViolationError, "not-null constraint violation"),
|
|
91
|
+
# Permission/access errors
|
|
92
|
+
1017: (PermissionDeniedError, "invalid username/password"),
|
|
93
|
+
1031: (PermissionDeniedError, "insufficient privileges"),
|
|
94
|
+
942: (PermissionDeniedError, "table or view does not exist"),
|
|
95
|
+
# Connection errors
|
|
96
|
+
12154: (DatabaseConnectionError, "TNS resolution failed"),
|
|
97
|
+
12541: (ConnectionTimeoutError, "no listener"),
|
|
98
|
+
12545: (ConnectionTimeoutError, "connect failed"),
|
|
99
|
+
12514: (DatabaseConnectionError, "service not known"),
|
|
100
|
+
12505: (DatabaseConnectionError, "listener rejected"),
|
|
101
|
+
12170: (ConnectionTimeoutError, "connect timeout"),
|
|
102
|
+
# Transaction errors
|
|
103
|
+
60: (DeadlockError, "deadlock detected"),
|
|
104
|
+
8176: (TransactionError, "consistent read failure"),
|
|
105
|
+
# Query timeout/cancellation
|
|
106
|
+
1013: (QueryTimeoutError, "user requested cancel"),
|
|
107
|
+
# Data errors
|
|
108
|
+
1722: (DataError, "invalid number"),
|
|
109
|
+
1858: (DataError, "invalid character"),
|
|
110
|
+
1840: (DataError, "data conversion error"),
|
|
111
|
+
# Operational errors
|
|
112
|
+
ORA_TABLESPACE_FULL: (OperationalError, "tablespace full"),
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def _parse_version_tuple(version: str) -> "tuple[int, int, int]":
|
|
117
|
+
parts = [int(part) for part in version.split(".") if part.isdigit()]
|
|
118
|
+
while len(parts) < _VERSION_COMPONENTS:
|
|
119
|
+
parts.append(0)
|
|
120
|
+
return parts[0], parts[1], parts[2]
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def _resolve_oracledb_version() -> "tuple[int, int, int]":
|
|
124
|
+
try:
|
|
125
|
+
import oracledb
|
|
126
|
+
except ImportError:
|
|
127
|
+
return (0, 0, 0)
|
|
128
|
+
try:
|
|
129
|
+
version = oracledb.__version__
|
|
130
|
+
except AttributeError:
|
|
131
|
+
version = "0.0.0"
|
|
132
|
+
return _parse_version_tuple(version)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
ORACLEDB_VERSION: "tuple[int, int, int]" = _resolve_oracledb_version()
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def normalize_column_names(column_names: "list[str]", driver_features: "dict[str, Any]") -> "list[str]":
|
|
139
|
+
should_lowercase = driver_features.get("enable_lowercase_column_names", False)
|
|
140
|
+
if not should_lowercase:
|
|
141
|
+
return column_names
|
|
142
|
+
normalized: list[str] = []
|
|
143
|
+
for name in column_names:
|
|
144
|
+
if name and IMPLICIT_UPPER_COLUMN_PATTERN.fullmatch(name):
|
|
145
|
+
normalized.append(name.lower())
|
|
146
|
+
else:
|
|
147
|
+
normalized.append(name)
|
|
148
|
+
return normalized
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def normalize_execute_many_parameters_sync(parameters: Any) -> Any:
|
|
152
|
+
"""Normalize parameters for Oracle executemany calls.
|
|
153
|
+
|
|
154
|
+
Args:
|
|
155
|
+
parameters: Prepared parameters payload.
|
|
156
|
+
|
|
157
|
+
Returns:
|
|
158
|
+
Normalized parameters payload.
|
|
159
|
+
|
|
160
|
+
Raises:
|
|
161
|
+
ValueError: When parameters are missing for executemany.
|
|
162
|
+
"""
|
|
163
|
+
if not parameters:
|
|
164
|
+
msg = "execute_many requires parameters"
|
|
165
|
+
raise ValueError(msg)
|
|
166
|
+
if isinstance(parameters, tuple):
|
|
167
|
+
return list(parameters)
|
|
168
|
+
return parameters
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def normalize_execute_many_parameters_async(parameters: Any) -> Any:
|
|
172
|
+
"""Normalize parameters for Oracle async executemany calls.
|
|
173
|
+
|
|
174
|
+
Args:
|
|
175
|
+
parameters: Prepared parameters payload.
|
|
176
|
+
|
|
177
|
+
Returns:
|
|
178
|
+
Normalized parameters payload.
|
|
179
|
+
|
|
180
|
+
Raises:
|
|
181
|
+
ValueError: When parameters are missing for executemany.
|
|
182
|
+
"""
|
|
183
|
+
if not parameters:
|
|
184
|
+
msg = "execute_many requires parameters"
|
|
185
|
+
raise ValueError(msg)
|
|
186
|
+
return parameters
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def _coerce_value_sync(
|
|
190
|
+
connection: Any, value: Any, *, clob_type: Any, blob_type: Any, varchar2_byte_limit: int, raw_byte_limit: int
|
|
191
|
+
) -> Any:
|
|
192
|
+
"""Route a single parameter value through wrapper-aware coercion (sync)."""
|
|
193
|
+
if isinstance(value, OracleClob):
|
|
194
|
+
inner = value.value
|
|
195
|
+
if isinstance(inner, bytes):
|
|
196
|
+
inner = inner.decode("utf-8")
|
|
197
|
+
return connection.createlob(clob_type, inner)
|
|
198
|
+
if isinstance(value, OracleBlob):
|
|
199
|
+
inner = value.value
|
|
200
|
+
if isinstance(inner, str):
|
|
201
|
+
inner = inner.encode("utf-8")
|
|
202
|
+
return connection.createlob(blob_type, inner)
|
|
203
|
+
if isinstance(value, OracleJson):
|
|
204
|
+
return value.value
|
|
205
|
+
if isinstance(value, str) and len(value.encode("utf-8")) > varchar2_byte_limit:
|
|
206
|
+
return connection.createlob(clob_type, value)
|
|
207
|
+
if isinstance(value, (bytes, bytearray)) and len(value) > raw_byte_limit:
|
|
208
|
+
return connection.createlob(blob_type, bytes(value))
|
|
209
|
+
return value
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
async def _coerce_value_async(
|
|
213
|
+
connection: Any, value: Any, *, clob_type: Any, blob_type: Any, varchar2_byte_limit: int, raw_byte_limit: int
|
|
214
|
+
) -> Any:
|
|
215
|
+
"""Async mirror of :func:`_coerce_value_sync`."""
|
|
216
|
+
if isinstance(value, OracleClob):
|
|
217
|
+
inner = value.value
|
|
218
|
+
if isinstance(inner, bytes):
|
|
219
|
+
inner = inner.decode("utf-8")
|
|
220
|
+
return await connection.createlob(clob_type, inner)
|
|
221
|
+
if isinstance(value, OracleBlob):
|
|
222
|
+
inner = value.value
|
|
223
|
+
if isinstance(inner, str):
|
|
224
|
+
inner = inner.encode("utf-8")
|
|
225
|
+
return await connection.createlob(blob_type, inner)
|
|
226
|
+
if isinstance(value, OracleJson):
|
|
227
|
+
return value.value
|
|
228
|
+
if isinstance(value, str) and len(value.encode("utf-8")) > varchar2_byte_limit:
|
|
229
|
+
return await connection.createlob(clob_type, value)
|
|
230
|
+
if isinstance(value, (bytes, bytearray)) and len(value) > raw_byte_limit:
|
|
231
|
+
return await connection.createlob(blob_type, bytes(value))
|
|
232
|
+
return value
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
def coerce_large_parameters_sync(
|
|
236
|
+
connection: Any, parameters: Any, *, clob_type: Any, blob_type: Any, varchar2_byte_limit: int, raw_byte_limit: int
|
|
237
|
+
) -> Any:
|
|
238
|
+
"""Coerce large string/bytes parameters into CLOBs/BLOBs with wrapper-aware routing.
|
|
239
|
+
|
|
240
|
+
Routing order:
|
|
241
|
+
1. ``OracleClob`` / ``OracleBlob`` / ``OracleJson`` wrappers — explicit user
|
|
242
|
+
intent, length-thresholds bypassed.
|
|
243
|
+
2. Plain ``str`` whose UTF-8 encoding exceeds ``varchar2_byte_limit`` → CLOB.
|
|
244
|
+
3. Plain ``bytes``/``bytearray`` longer than ``raw_byte_limit`` → BLOB.
|
|
245
|
+
|
|
246
|
+
Handles ``dict`` (named binds), ``tuple`` and ``list`` (positional binds).
|
|
247
|
+
Tuples are returned as new lists when any value is rewritten so the driver's
|
|
248
|
+
``cast(... | tuple | list | dict)`` contract is preserved.
|
|
249
|
+
|
|
250
|
+
Args:
|
|
251
|
+
connection: Oracle database connection.
|
|
252
|
+
parameters: Prepared parameters payload.
|
|
253
|
+
clob_type: Oracle CLOB DB type (``oracledb.DB_TYPE_CLOB``).
|
|
254
|
+
blob_type: Oracle BLOB DB type (``oracledb.DB_TYPE_BLOB``).
|
|
255
|
+
varchar2_byte_limit: Byte-length threshold for implicit CLOB conversion.
|
|
256
|
+
raw_byte_limit: Byte-length threshold for implicit BLOB conversion.
|
|
257
|
+
|
|
258
|
+
Returns:
|
|
259
|
+
Parameters payload with values routed to the correct LOB / native type.
|
|
260
|
+
"""
|
|
261
|
+
if not parameters:
|
|
262
|
+
return parameters
|
|
263
|
+
if isinstance(parameters, dict):
|
|
264
|
+
for param_name, param_value in parameters.items():
|
|
265
|
+
parameters[param_name] = _coerce_value_sync(
|
|
266
|
+
connection,
|
|
267
|
+
param_value,
|
|
268
|
+
clob_type=clob_type,
|
|
269
|
+
blob_type=blob_type,
|
|
270
|
+
varchar2_byte_limit=varchar2_byte_limit,
|
|
271
|
+
raw_byte_limit=raw_byte_limit,
|
|
272
|
+
)
|
|
273
|
+
return parameters
|
|
274
|
+
if isinstance(parameters, (list, tuple)):
|
|
275
|
+
return [
|
|
276
|
+
_coerce_value_sync(
|
|
277
|
+
connection,
|
|
278
|
+
value,
|
|
279
|
+
clob_type=clob_type,
|
|
280
|
+
blob_type=blob_type,
|
|
281
|
+
varchar2_byte_limit=varchar2_byte_limit,
|
|
282
|
+
raw_byte_limit=raw_byte_limit,
|
|
283
|
+
)
|
|
284
|
+
for value in parameters
|
|
285
|
+
]
|
|
286
|
+
return parameters
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
async def coerce_large_parameters_async(
|
|
290
|
+
connection: Any, parameters: Any, *, clob_type: Any, blob_type: Any, varchar2_byte_limit: int, raw_byte_limit: int
|
|
291
|
+
) -> Any:
|
|
292
|
+
"""Async mirror of :func:`coerce_large_parameters_sync`.
|
|
293
|
+
|
|
294
|
+
Identical routing order; ``connection.createlob`` is awaited for the async
|
|
295
|
+
Oracle driver.
|
|
296
|
+
"""
|
|
297
|
+
if not parameters:
|
|
298
|
+
return parameters
|
|
299
|
+
if isinstance(parameters, dict):
|
|
300
|
+
for param_name, param_value in parameters.items():
|
|
301
|
+
parameters[param_name] = await _coerce_value_async(
|
|
302
|
+
connection,
|
|
303
|
+
param_value,
|
|
304
|
+
clob_type=clob_type,
|
|
305
|
+
blob_type=blob_type,
|
|
306
|
+
varchar2_byte_limit=varchar2_byte_limit,
|
|
307
|
+
raw_byte_limit=raw_byte_limit,
|
|
308
|
+
)
|
|
309
|
+
return parameters
|
|
310
|
+
if isinstance(parameters, (list, tuple)):
|
|
311
|
+
return [
|
|
312
|
+
await _coerce_value_async(
|
|
313
|
+
connection,
|
|
314
|
+
value,
|
|
315
|
+
clob_type=clob_type,
|
|
316
|
+
blob_type=blob_type,
|
|
317
|
+
varchar2_byte_limit=varchar2_byte_limit,
|
|
318
|
+
raw_byte_limit=raw_byte_limit,
|
|
319
|
+
)
|
|
320
|
+
for value in parameters
|
|
321
|
+
]
|
|
322
|
+
return parameters
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
def build_insert_statement(table: str, columns: "list[str]") -> str:
|
|
326
|
+
column_list = ", ".join(columns)
|
|
327
|
+
placeholders = ", ".join(f":{idx + 1}" for idx in range(len(columns)))
|
|
328
|
+
return f"INSERT INTO {table} ({column_list}) VALUES ({placeholders})"
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
def build_truncate_statement(table: str) -> str:
|
|
332
|
+
return f"TRUNCATE TABLE {table}"
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
def build_pipeline_stack_result(
|
|
336
|
+
statement: "SQL",
|
|
337
|
+
method: str,
|
|
338
|
+
returns_rows: bool,
|
|
339
|
+
parameters: Any,
|
|
340
|
+
pipeline_result: Any,
|
|
341
|
+
driver_features: "dict[str, Any]",
|
|
342
|
+
) -> "StackResult":
|
|
343
|
+
"""Build StackResult from Oracle pipeline output.
|
|
344
|
+
|
|
345
|
+
Args:
|
|
346
|
+
statement: Statement executed in the pipeline.
|
|
347
|
+
method: Pipeline execution method name.
|
|
348
|
+
returns_rows: Whether the operation returns rows.
|
|
349
|
+
parameters: Prepared parameters used for execution.
|
|
350
|
+
pipeline_result: Raw pipeline execution result.
|
|
351
|
+
driver_features: Driver feature configuration for normalization.
|
|
352
|
+
|
|
353
|
+
Returns:
|
|
354
|
+
StackResult for the pipeline operation.
|
|
355
|
+
"""
|
|
356
|
+
try:
|
|
357
|
+
rows = pipeline_result.rows
|
|
358
|
+
except AttributeError:
|
|
359
|
+
rows = None
|
|
360
|
+
try:
|
|
361
|
+
columns = pipeline_result.columns
|
|
362
|
+
except AttributeError:
|
|
363
|
+
columns = None
|
|
364
|
+
|
|
365
|
+
data: list[dict[str, Any]] | None = None
|
|
366
|
+
if returns_rows:
|
|
367
|
+
if not rows:
|
|
368
|
+
data = []
|
|
369
|
+
else:
|
|
370
|
+
if columns:
|
|
371
|
+
names = []
|
|
372
|
+
for index, column in enumerate(columns):
|
|
373
|
+
try:
|
|
374
|
+
name = column.name
|
|
375
|
+
except AttributeError:
|
|
376
|
+
name = f"column_{index}"
|
|
377
|
+
names.append(name)
|
|
378
|
+
else:
|
|
379
|
+
first = rows[0]
|
|
380
|
+
names = [f"column_{index}" for index in range(len(first) if isinstance(first, Sized) else 0)]
|
|
381
|
+
names = normalize_column_names(names, driver_features)
|
|
382
|
+
normalized_rows: list[dict[str, Any]] = []
|
|
383
|
+
for row in rows:
|
|
384
|
+
if isinstance(row, dict):
|
|
385
|
+
normalized_rows.append(row)
|
|
386
|
+
else:
|
|
387
|
+
normalized_rows.append(dict(zip(names, row, strict=False)))
|
|
388
|
+
data = normalized_rows
|
|
389
|
+
|
|
390
|
+
metadata: dict[str, Any] = {"pipeline_operation": method}
|
|
391
|
+
try:
|
|
392
|
+
warning = pipeline_result.warning
|
|
393
|
+
except AttributeError:
|
|
394
|
+
warning = None
|
|
395
|
+
if warning is not None:
|
|
396
|
+
metadata["warning"] = warning
|
|
397
|
+
|
|
398
|
+
try:
|
|
399
|
+
return_value = pipeline_result.return_value
|
|
400
|
+
except AttributeError:
|
|
401
|
+
return_value = None
|
|
402
|
+
if return_value is not None:
|
|
403
|
+
metadata["return_value"] = return_value
|
|
404
|
+
|
|
405
|
+
try:
|
|
406
|
+
rowcount = pipeline_result.rowcount
|
|
407
|
+
except AttributeError:
|
|
408
|
+
rowcount = None
|
|
409
|
+
|
|
410
|
+
if isinstance(rowcount, int) and rowcount >= 0:
|
|
411
|
+
rows_affected = rowcount
|
|
412
|
+
elif method == "execute_many":
|
|
413
|
+
try:
|
|
414
|
+
rows_affected = len(parameters or ())
|
|
415
|
+
except TypeError:
|
|
416
|
+
rows_affected = 0
|
|
417
|
+
elif method == "execute" and not returns_rows:
|
|
418
|
+
rows_affected = 1
|
|
419
|
+
elif returns_rows:
|
|
420
|
+
rows_affected = len(data or [])
|
|
421
|
+
else:
|
|
422
|
+
rows_affected = 0
|
|
423
|
+
|
|
424
|
+
sql_result = create_sql_result(statement, data=data, rows_affected=rows_affected, metadata=metadata)
|
|
425
|
+
return StackResult.from_sql_result(sql_result)
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
def resolve_rowcount(cursor: Any) -> int:
|
|
429
|
+
"""Resolve rowcount from an Oracle cursor.
|
|
430
|
+
|
|
431
|
+
Args:
|
|
432
|
+
cursor: Oracle cursor with optional rowcount metadata.
|
|
433
|
+
|
|
434
|
+
Returns:
|
|
435
|
+
Rowcount value or 0 when unavailable.
|
|
436
|
+
"""
|
|
437
|
+
if not has_rowcount(cursor):
|
|
438
|
+
return 0
|
|
439
|
+
rowcount = cursor.rowcount
|
|
440
|
+
if isinstance(rowcount, int):
|
|
441
|
+
return rowcount
|
|
442
|
+
return 0
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
def apply_driver_features(driver_features: "Mapping[str, Any] | None") -> "dict[str, Any]":
|
|
446
|
+
"""Apply OracleDB driver feature defaults."""
|
|
447
|
+
features: dict[str, Any] = dict(driver_features) if driver_features else {}
|
|
448
|
+
features.setdefault("enable_numpy_vectors", NUMPY_INSTALLED)
|
|
449
|
+
features.setdefault("enable_lowercase_column_names", True)
|
|
450
|
+
features.setdefault("enable_uuid_binary", True)
|
|
451
|
+
if "vector_return_format" not in features:
|
|
452
|
+
if not NUMPY_INSTALLED:
|
|
453
|
+
features["vector_return_format"] = "list"
|
|
454
|
+
elif features["enable_numpy_vectors"]:
|
|
455
|
+
features["vector_return_format"] = "numpy"
|
|
456
|
+
else:
|
|
457
|
+
features["vector_return_format"] = "array"
|
|
458
|
+
features.setdefault("oracle_varchar2_byte_limit", 4000)
|
|
459
|
+
features.setdefault("oracle_raw_byte_limit", 2000)
|
|
460
|
+
return features
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
def requires_session_callback(driver_features: "dict[str, Any]") -> bool:
|
|
464
|
+
"""Return True when the session callback should be installed.
|
|
465
|
+
|
|
466
|
+
The JSON input/output handlers are always-on (no driver-feature flag), so
|
|
467
|
+
the session callback is always required for an Oracle pool to bind ``dict``
|
|
468
|
+
/ ``list`` parameters via the native ``DB_TYPE_JSON`` / OSON-encoded BLOB /
|
|
469
|
+
JSON-string CLOB paths and to cache ``connection._sqlspec_oracle_major``.
|
|
470
|
+
"""
|
|
471
|
+
del driver_features # always-on; preserved for signature compatibility
|
|
472
|
+
return True
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
def _description_requires_lob_coercion(description: "list[Any]") -> bool:
|
|
476
|
+
"""Return True when cursor metadata indicates LOB-compatible columns."""
|
|
477
|
+
for column in description:
|
|
478
|
+
try:
|
|
479
|
+
type_code = column[1]
|
|
480
|
+
except (TypeError, IndexError, KeyError):
|
|
481
|
+
type_code = getattr(column, "type_code", None)
|
|
482
|
+
if type_code is None:
|
|
483
|
+
# Unknown metadata shape: keep conservative behavior.
|
|
484
|
+
return True
|
|
485
|
+
|
|
486
|
+
type_name = getattr(type_code, "name", None)
|
|
487
|
+
if isinstance(type_name, str):
|
|
488
|
+
upper_name = type_name.upper()
|
|
489
|
+
if any(marker in upper_name for marker in _LOB_TYPE_NAME_MARKERS):
|
|
490
|
+
return True
|
|
491
|
+
continue
|
|
492
|
+
|
|
493
|
+
type_text = str(type_code).upper()
|
|
494
|
+
if any(marker in type_text for marker in _LOB_TYPE_NAME_MARKERS):
|
|
495
|
+
return True
|
|
496
|
+
return False
|
|
497
|
+
|
|
498
|
+
|
|
499
|
+
def resolve_row_metadata(
|
|
500
|
+
description: "list[Any] | None", driver_features: "dict[str, Any]", cache: "dict[int, tuple[Any, list[str], bool]]"
|
|
501
|
+
) -> "tuple[list[str], bool]":
|
|
502
|
+
"""Resolve and cache Oracle row metadata for hot row materialization paths.
|
|
503
|
+
|
|
504
|
+
Args:
|
|
505
|
+
description: Cursor description metadata.
|
|
506
|
+
driver_features: Driver feature configuration.
|
|
507
|
+
cache: Driver-local metadata cache keyed by ``id(description)``.
|
|
508
|
+
|
|
509
|
+
Returns:
|
|
510
|
+
Tuple of (normalized column names, requires_lob_coercion).
|
|
511
|
+
"""
|
|
512
|
+
if not description:
|
|
513
|
+
return [], False
|
|
514
|
+
|
|
515
|
+
cache_key = id(description)
|
|
516
|
+
cached = cache.get(cache_key)
|
|
517
|
+
if cached is not None and cached[0] is description:
|
|
518
|
+
return cached[1], cached[2]
|
|
519
|
+
|
|
520
|
+
column_names = [col[0] for col in description]
|
|
521
|
+
normalized_column_names = normalize_column_names(column_names, driver_features)
|
|
522
|
+
requires_lob_coercion = _description_requires_lob_coercion(description)
|
|
523
|
+
|
|
524
|
+
if len(cache) >= ROW_CACHE_MAX_SIZE:
|
|
525
|
+
cache.pop(next(iter(cache)))
|
|
526
|
+
cache[cache_key] = (description, normalized_column_names, requires_lob_coercion)
|
|
527
|
+
return normalized_column_names, requires_lob_coercion
|
|
528
|
+
|
|
529
|
+
|
|
530
|
+
def _row_requires_lob_coercion(row: "tuple[Any, ...]") -> bool:
|
|
531
|
+
"""Return True when a row contains readable values that need LOB coercion."""
|
|
532
|
+
for value in row:
|
|
533
|
+
value_type = type(value)
|
|
534
|
+
if value_type in _SCALAR_PASSTHROUGH_TYPES:
|
|
535
|
+
continue
|
|
536
|
+
if is_readable(value):
|
|
537
|
+
return True
|
|
538
|
+
return False
|
|
539
|
+
|
|
540
|
+
|
|
541
|
+
def _coerce_sync_row_values(row: "tuple[Any, ...]") -> "tuple[Any, ...]":
|
|
542
|
+
"""Coerce LOB handles to concrete values for synchronous execution.
|
|
543
|
+
|
|
544
|
+
Processes each value in the row, reading LOB objects and applying
|
|
545
|
+
type detection for JSON values stored in CLOBs.
|
|
546
|
+
|
|
547
|
+
Args:
|
|
548
|
+
row: Tuple of column values from database fetch.
|
|
549
|
+
|
|
550
|
+
Returns:
|
|
551
|
+
Tuple of coerced values with LOBs read to strings/bytes.
|
|
552
|
+
|
|
553
|
+
"""
|
|
554
|
+
coerced_values: list[Any] | None = None
|
|
555
|
+
for index, value in enumerate(row):
|
|
556
|
+
value_type = type(value)
|
|
557
|
+
if value_type in _SCALAR_PASSTHROUGH_TYPES:
|
|
558
|
+
if coerced_values is not None:
|
|
559
|
+
coerced_values.append(value)
|
|
560
|
+
continue
|
|
561
|
+
|
|
562
|
+
if is_readable(value):
|
|
563
|
+
try:
|
|
564
|
+
processed_value = value.read()
|
|
565
|
+
except Exception:
|
|
566
|
+
if coerced_values is not None:
|
|
567
|
+
coerced_values.append(value)
|
|
568
|
+
continue
|
|
569
|
+
if isinstance(processed_value, str):
|
|
570
|
+
processed_value = TYPE_CONVERTER.convert_if_detected(processed_value)
|
|
571
|
+
|
|
572
|
+
if coerced_values is None:
|
|
573
|
+
if processed_value is value:
|
|
574
|
+
continue
|
|
575
|
+
coerced_values = list(row[:index])
|
|
576
|
+
coerced_values.append(processed_value)
|
|
577
|
+
continue
|
|
578
|
+
|
|
579
|
+
if coerced_values is not None:
|
|
580
|
+
coerced_values.append(value)
|
|
581
|
+
|
|
582
|
+
if coerced_values is None:
|
|
583
|
+
return row
|
|
584
|
+
return tuple(coerced_values)
|
|
585
|
+
|
|
586
|
+
|
|
587
|
+
async def _coerce_async_row_values(row: "tuple[Any, ...]") -> "tuple[Any, ...]":
|
|
588
|
+
"""Coerce LOB handles to concrete values for asynchronous execution.
|
|
589
|
+
|
|
590
|
+
Processes each value in the row, reading LOB objects asynchronously
|
|
591
|
+
and applying type detection for JSON values stored in CLOBs.
|
|
592
|
+
|
|
593
|
+
Args:
|
|
594
|
+
row: Tuple of column values from database fetch.
|
|
595
|
+
|
|
596
|
+
Returns:
|
|
597
|
+
Tuple of coerced values with LOBs read to strings/bytes.
|
|
598
|
+
|
|
599
|
+
"""
|
|
600
|
+
coerced_values: list[Any] | None = None
|
|
601
|
+
for index, value in enumerate(row):
|
|
602
|
+
value_type = type(value)
|
|
603
|
+
if value_type in _SCALAR_PASSTHROUGH_TYPES:
|
|
604
|
+
if coerced_values is not None:
|
|
605
|
+
coerced_values.append(value)
|
|
606
|
+
continue
|
|
607
|
+
|
|
608
|
+
if is_readable(value):
|
|
609
|
+
try:
|
|
610
|
+
processed_value = await TYPE_CONVERTER.process_lob(value)
|
|
611
|
+
except Exception:
|
|
612
|
+
if coerced_values is not None:
|
|
613
|
+
coerced_values.append(value)
|
|
614
|
+
continue
|
|
615
|
+
if isinstance(processed_value, str):
|
|
616
|
+
processed_value = TYPE_CONVERTER.convert_if_detected(processed_value)
|
|
617
|
+
|
|
618
|
+
if coerced_values is None:
|
|
619
|
+
if processed_value is value:
|
|
620
|
+
continue
|
|
621
|
+
coerced_values = list(row[:index])
|
|
622
|
+
coerced_values.append(processed_value)
|
|
623
|
+
continue
|
|
624
|
+
|
|
625
|
+
if coerced_values is not None:
|
|
626
|
+
coerced_values.append(value)
|
|
627
|
+
|
|
628
|
+
if coerced_values is None:
|
|
629
|
+
return row
|
|
630
|
+
return tuple(coerced_values)
|
|
631
|
+
|
|
632
|
+
|
|
633
|
+
def collect_sync_rows(
|
|
634
|
+
fetched_data: "list[Any] | None",
|
|
635
|
+
description: "list[Any] | None",
|
|
636
|
+
driver_features: "dict[str, Any]",
|
|
637
|
+
*,
|
|
638
|
+
column_names: "list[str] | None" = None,
|
|
639
|
+
requires_lob_coercion: "bool | None" = None,
|
|
640
|
+
) -> "tuple[list[tuple[Any, ...]], list[str]]":
|
|
641
|
+
"""Collect OracleDB sync rows as tuples with normalized column names.
|
|
642
|
+
|
|
643
|
+
LOB coercion is still applied to each row. The raw coerced tuples are
|
|
644
|
+
returned instead of dicts so that ``SQLResult`` can handle lazy dict
|
|
645
|
+
materialization based on ``row_format``.
|
|
646
|
+
|
|
647
|
+
Args:
|
|
648
|
+
fetched_data: Rows returned from cursor.fetchall().
|
|
649
|
+
description: Cursor description metadata.
|
|
650
|
+
driver_features: Driver feature configuration.
|
|
651
|
+
column_names: Optional precomputed normalized column names.
|
|
652
|
+
requires_lob_coercion: Optional precomputed LOB-coercion flag.
|
|
653
|
+
|
|
654
|
+
Returns:
|
|
655
|
+
Tuple of (rows, column_names).
|
|
656
|
+
"""
|
|
657
|
+
if not description:
|
|
658
|
+
return [], []
|
|
659
|
+
resolved_column_names = (
|
|
660
|
+
normalize_column_names([col[0] for col in description], driver_features)
|
|
661
|
+
if column_names is None
|
|
662
|
+
else column_names
|
|
663
|
+
)
|
|
664
|
+
if not fetched_data:
|
|
665
|
+
return [], resolved_column_names
|
|
666
|
+
|
|
667
|
+
if requires_lob_coercion is None:
|
|
668
|
+
requires_lob_coercion = _description_requires_lob_coercion(description)
|
|
669
|
+
if not requires_lob_coercion:
|
|
670
|
+
first_row = fetched_data[0]
|
|
671
|
+
first_row_tuple = first_row if isinstance(first_row, tuple) else tuple(first_row)
|
|
672
|
+
if not _row_requires_lob_coercion(first_row_tuple):
|
|
673
|
+
return cast("list[tuple[Any, ...]]", fetched_data), resolved_column_names
|
|
674
|
+
|
|
675
|
+
data: list[tuple[Any, ...]] = []
|
|
676
|
+
for row in fetched_data:
|
|
677
|
+
row_tuple = row if isinstance(row, tuple) else tuple(row)
|
|
678
|
+
data.append(_coerce_sync_row_values(row_tuple))
|
|
679
|
+
return data, resolved_column_names
|
|
680
|
+
|
|
681
|
+
|
|
682
|
+
async def collect_async_rows(
|
|
683
|
+
fetched_data: "list[Any] | None",
|
|
684
|
+
description: "list[Any] | None",
|
|
685
|
+
driver_features: "dict[str, Any]",
|
|
686
|
+
*,
|
|
687
|
+
column_names: "list[str] | None" = None,
|
|
688
|
+
requires_lob_coercion: "bool | None" = None,
|
|
689
|
+
) -> "tuple[list[tuple[Any, ...]], list[str]]":
|
|
690
|
+
"""Collect OracleDB async rows as tuples with normalized column names.
|
|
691
|
+
|
|
692
|
+
LOB coercion is still applied to each row. The raw coerced tuples are
|
|
693
|
+
returned instead of dicts so that ``SQLResult`` can handle lazy dict
|
|
694
|
+
materialization based on ``row_format``.
|
|
695
|
+
|
|
696
|
+
Args:
|
|
697
|
+
fetched_data: Rows returned from cursor.fetchall().
|
|
698
|
+
description: Cursor description metadata.
|
|
699
|
+
driver_features: Driver feature configuration.
|
|
700
|
+
column_names: Optional precomputed normalized column names.
|
|
701
|
+
requires_lob_coercion: Optional precomputed LOB-coercion flag.
|
|
702
|
+
|
|
703
|
+
Returns:
|
|
704
|
+
Tuple of (rows, column_names).
|
|
705
|
+
"""
|
|
706
|
+
if not description:
|
|
707
|
+
return [], []
|
|
708
|
+
resolved_column_names = (
|
|
709
|
+
normalize_column_names([col[0] for col in description], driver_features)
|
|
710
|
+
if column_names is None
|
|
711
|
+
else column_names
|
|
712
|
+
)
|
|
713
|
+
if not fetched_data:
|
|
714
|
+
return [], resolved_column_names
|
|
715
|
+
|
|
716
|
+
if requires_lob_coercion is None:
|
|
717
|
+
requires_lob_coercion = _description_requires_lob_coercion(description)
|
|
718
|
+
if not requires_lob_coercion:
|
|
719
|
+
first_row = fetched_data[0]
|
|
720
|
+
first_row_tuple = first_row if isinstance(first_row, tuple) else tuple(first_row)
|
|
721
|
+
if not _row_requires_lob_coercion(first_row_tuple):
|
|
722
|
+
return cast("list[tuple[Any, ...]]", fetched_data), resolved_column_names
|
|
723
|
+
|
|
724
|
+
data: list[tuple[Any, ...]] = []
|
|
725
|
+
for row in fetched_data:
|
|
726
|
+
row_tuple = row if isinstance(row, tuple) else tuple(row)
|
|
727
|
+
data.append(await _coerce_async_row_values(row_tuple))
|
|
728
|
+
return data, resolved_column_names
|
|
729
|
+
|
|
730
|
+
|
|
731
|
+
def _create_oracle_error(
|
|
732
|
+
error: Any, code: "int | None", error_class: type[SQLSpecError], description: str
|
|
733
|
+
) -> SQLSpecError:
|
|
734
|
+
"""Create a SQLSpec exception from an Oracle error.
|
|
735
|
+
|
|
736
|
+
Args:
|
|
737
|
+
error: The original Oracle exception
|
|
738
|
+
code: Oracle error code
|
|
739
|
+
error_class: The SQLSpec exception class to instantiate
|
|
740
|
+
description: Human-readable description of the error type
|
|
741
|
+
|
|
742
|
+
Returns:
|
|
743
|
+
A new SQLSpec exception instance with the original as its cause
|
|
744
|
+
"""
|
|
745
|
+
msg = f"Oracle {description} [ORA-{code:05d}]: {error}" if code else f"Oracle {description}: {error}"
|
|
746
|
+
exc = error_class(msg)
|
|
747
|
+
exc.__cause__ = error
|
|
748
|
+
return exc
|
|
749
|
+
|
|
750
|
+
|
|
751
|
+
def create_mapped_exception(error: Any) -> SQLSpecError:
|
|
752
|
+
"""Map Oracle exceptions to SQLSpec exceptions.
|
|
753
|
+
|
|
754
|
+
This is a factory function that returns an exception instance rather than
|
|
755
|
+
raising. This pattern is more robust for use in __exit__ handlers and
|
|
756
|
+
avoids issues with exception control flow in different Python versions.
|
|
757
|
+
|
|
758
|
+
Args:
|
|
759
|
+
error: The Oracle exception to map
|
|
760
|
+
|
|
761
|
+
Returns:
|
|
762
|
+
A SQLSpec exception that wraps the original error
|
|
763
|
+
"""
|
|
764
|
+
error_obj = error.args[0] if getattr(error, "args", None) else None
|
|
765
|
+
if not error_obj:
|
|
766
|
+
return _create_oracle_error(error, None, SQLSpecError, "database error")
|
|
767
|
+
|
|
768
|
+
try:
|
|
769
|
+
error_code = error_obj.code
|
|
770
|
+
except AttributeError:
|
|
771
|
+
error_code = None
|
|
772
|
+
if not error_code:
|
|
773
|
+
return _create_oracle_error(error, None, SQLSpecError, "database error")
|
|
774
|
+
|
|
775
|
+
mapping = _ERROR_CODE_MAPPING.get(error_code)
|
|
776
|
+
if mapping:
|
|
777
|
+
error_class, error_desc = mapping
|
|
778
|
+
return _create_oracle_error(error, error_code, error_class, error_desc)
|
|
779
|
+
|
|
780
|
+
if ORA_INTEGRITY_RANGE_START <= error_code < ORA_INTEGRITY_RANGE_END:
|
|
781
|
+
return _create_oracle_error(error, error_code, IntegrityError, "integrity constraint violation")
|
|
782
|
+
|
|
783
|
+
if ORA_PARSING_RANGE_START <= error_code < ORA_PARSING_RANGE_END:
|
|
784
|
+
return _create_oracle_error(error, error_code, SQLParsingError, "SQL syntax error")
|
|
785
|
+
|
|
786
|
+
return _create_oracle_error(error, error_code, SQLSpecError, "database error")
|
|
787
|
+
|
|
788
|
+
|
|
789
|
+
def build_profile() -> "DriverParameterProfile":
|
|
790
|
+
"""Create the OracleDB driver parameter profile."""
|
|
791
|
+
return DriverParameterProfile(
|
|
792
|
+
name="OracleDB",
|
|
793
|
+
default_style=ParameterStyle.NAMED_COLON,
|
|
794
|
+
supported_styles={ParameterStyle.NAMED_COLON, ParameterStyle.NUMERIC, ParameterStyle.QMARK},
|
|
795
|
+
default_execution_style=ParameterStyle.NAMED_COLON,
|
|
796
|
+
supported_execution_styles={ParameterStyle.NAMED_COLON, ParameterStyle.POSITIONAL_COLON},
|
|
797
|
+
has_native_list_expansion=False,
|
|
798
|
+
preserve_parameter_format=True,
|
|
799
|
+
needs_static_script_compilation=False,
|
|
800
|
+
allow_mixed_parameter_styles=False,
|
|
801
|
+
preserve_original_params_for_many=False,
|
|
802
|
+
json_serializer_strategy="driver",
|
|
803
|
+
custom_type_coercions={**build_uuid_coercions(native=True)},
|
|
804
|
+
default_dialect="oracle",
|
|
805
|
+
)
|
|
806
|
+
|
|
807
|
+
|
|
808
|
+
driver_profile = build_profile()
|
|
809
|
+
|
|
810
|
+
|
|
811
|
+
def build_statement_config(*, json_serializer: "Callable[[Any], str] | None" = None) -> StatementConfig:
|
|
812
|
+
"""Construct the OracleDB statement configuration with optional JSON serializer."""
|
|
813
|
+
serializer = json_serializer or to_json
|
|
814
|
+
profile = driver_profile
|
|
815
|
+
return build_statement_config_from_profile(
|
|
816
|
+
profile, statement_overrides={"dialect": "oracle"}, json_serializer=serializer
|
|
817
|
+
)
|
|
818
|
+
|
|
819
|
+
|
|
820
|
+
default_statement_config = build_statement_config()
|