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.
Files changed (621) hide show
  1. f68e0789eb443ecb1c2c__mypyc.cp314-win_amd64.pyd +0 -0
  2. sqlspec/__init__.py +167 -0
  3. sqlspec/__main__.py +12 -0
  4. sqlspec/__metadata__.py +14 -0
  5. sqlspec/_typing.py +714 -0
  6. sqlspec/adapters/__init__.py +0 -0
  7. sqlspec/adapters/adbc/__init__.py +13 -0
  8. sqlspec/adapters/adbc/_typing.py +106 -0
  9. sqlspec/adapters/adbc/adk/__init__.py +5 -0
  10. sqlspec/adapters/adbc/adk/store.py +1280 -0
  11. sqlspec/adapters/adbc/config.py +378 -0
  12. sqlspec/adapters/adbc/core.cp314-win_amd64.pyd +0 -0
  13. sqlspec/adapters/adbc/core.py +922 -0
  14. sqlspec/adapters/adbc/data_dictionary.py +339 -0
  15. sqlspec/adapters/adbc/driver.py +534 -0
  16. sqlspec/adapters/adbc/events/__init__.py +5 -0
  17. sqlspec/adapters/adbc/events/store.py +285 -0
  18. sqlspec/adapters/adbc/litestar/__init__.py +5 -0
  19. sqlspec/adapters/adbc/litestar/store.py +534 -0
  20. sqlspec/adapters/adbc/type_converter.cp314-win_amd64.pyd +0 -0
  21. sqlspec/adapters/adbc/type_converter.py +142 -0
  22. sqlspec/adapters/aiomysql/__init__.py +21 -0
  23. sqlspec/adapters/aiomysql/_typing.py +137 -0
  24. sqlspec/adapters/aiomysql/adk/__init__.py +5 -0
  25. sqlspec/adapters/aiomysql/adk/store.py +678 -0
  26. sqlspec/adapters/aiomysql/config.py +305 -0
  27. sqlspec/adapters/aiomysql/core.cp314-win_amd64.pyd +0 -0
  28. sqlspec/adapters/aiomysql/core.py +536 -0
  29. sqlspec/adapters/aiomysql/data_dictionary.py +121 -0
  30. sqlspec/adapters/aiomysql/driver.py +386 -0
  31. sqlspec/adapters/aiomysql/events/__init__.py +5 -0
  32. sqlspec/adapters/aiomysql/events/store.py +104 -0
  33. sqlspec/adapters/aiomysql/litestar/__init__.py +5 -0
  34. sqlspec/adapters/aiomysql/litestar/store.py +314 -0
  35. sqlspec/adapters/aiosqlite/__init__.py +26 -0
  36. sqlspec/adapters/aiosqlite/_typing.py +109 -0
  37. sqlspec/adapters/aiosqlite/adk/__init__.py +5 -0
  38. sqlspec/adapters/aiosqlite/adk/store.py +829 -0
  39. sqlspec/adapters/aiosqlite/config.py +315 -0
  40. sqlspec/adapters/aiosqlite/core.cp314-win_amd64.pyd +0 -0
  41. sqlspec/adapters/aiosqlite/core.py +315 -0
  42. sqlspec/adapters/aiosqlite/data_dictionary.py +202 -0
  43. sqlspec/adapters/aiosqlite/driver.py +311 -0
  44. sqlspec/adapters/aiosqlite/events/__init__.py +5 -0
  45. sqlspec/adapters/aiosqlite/events/store.py +20 -0
  46. sqlspec/adapters/aiosqlite/litestar/__init__.py +5 -0
  47. sqlspec/adapters/aiosqlite/litestar/store.py +279 -0
  48. sqlspec/adapters/aiosqlite/pool.cp314-win_amd64.pyd +0 -0
  49. sqlspec/adapters/aiosqlite/pool.py +734 -0
  50. sqlspec/adapters/asyncmy/__init__.py +21 -0
  51. sqlspec/adapters/asyncmy/_typing.py +113 -0
  52. sqlspec/adapters/asyncmy/adk/__init__.py +5 -0
  53. sqlspec/adapters/asyncmy/adk/store.py +644 -0
  54. sqlspec/adapters/asyncmy/config.py +307 -0
  55. sqlspec/adapters/asyncmy/core.cp314-win_amd64.pyd +0 -0
  56. sqlspec/adapters/asyncmy/core.py +538 -0
  57. sqlspec/adapters/asyncmy/data_dictionary.py +122 -0
  58. sqlspec/adapters/asyncmy/driver.py +391 -0
  59. sqlspec/adapters/asyncmy/events/__init__.py +5 -0
  60. sqlspec/adapters/asyncmy/events/store.py +104 -0
  61. sqlspec/adapters/asyncmy/litestar/__init__.py +5 -0
  62. sqlspec/adapters/asyncmy/litestar/store.py +296 -0
  63. sqlspec/adapters/asyncpg/__init__.py +26 -0
  64. sqlspec/adapters/asyncpg/_typing.py +103 -0
  65. sqlspec/adapters/asyncpg/adk/__init__.py +5 -0
  66. sqlspec/adapters/asyncpg/adk/store.py +483 -0
  67. sqlspec/adapters/asyncpg/config.py +575 -0
  68. sqlspec/adapters/asyncpg/core.cp314-win_amd64.pyd +0 -0
  69. sqlspec/adapters/asyncpg/core.py +480 -0
  70. sqlspec/adapters/asyncpg/data_dictionary.py +157 -0
  71. sqlspec/adapters/asyncpg/driver.py +487 -0
  72. sqlspec/adapters/asyncpg/events/__init__.py +6 -0
  73. sqlspec/adapters/asyncpg/events/_hub.py +181 -0
  74. sqlspec/adapters/asyncpg/events/backend.py +210 -0
  75. sqlspec/adapters/asyncpg/events/store.py +40 -0
  76. sqlspec/adapters/asyncpg/litestar/__init__.py +5 -0
  77. sqlspec/adapters/asyncpg/litestar/store.py +251 -0
  78. sqlspec/adapters/bigquery/__init__.py +15 -0
  79. sqlspec/adapters/bigquery/_typing.py +108 -0
  80. sqlspec/adapters/bigquery/config.py +362 -0
  81. sqlspec/adapters/bigquery/core.cp314-win_amd64.pyd +0 -0
  82. sqlspec/adapters/bigquery/core.py +768 -0
  83. sqlspec/adapters/bigquery/data_dictionary.py +120 -0
  84. sqlspec/adapters/bigquery/driver.py +542 -0
  85. sqlspec/adapters/bigquery/events/__init__.py +5 -0
  86. sqlspec/adapters/bigquery/events/store.py +139 -0
  87. sqlspec/adapters/bigquery/litestar/__init__.py +5 -0
  88. sqlspec/adapters/bigquery/litestar/store.py +325 -0
  89. sqlspec/adapters/bigquery/type_converter.cp314-win_amd64.pyd +0 -0
  90. sqlspec/adapters/bigquery/type_converter.py +107 -0
  91. sqlspec/adapters/cockroach_asyncpg/__init__.py +26 -0
  92. sqlspec/adapters/cockroach_asyncpg/_typing.py +73 -0
  93. sqlspec/adapters/cockroach_asyncpg/adk/__init__.py +3 -0
  94. sqlspec/adapters/cockroach_asyncpg/adk/store.py +465 -0
  95. sqlspec/adapters/cockroach_asyncpg/config.py +248 -0
  96. sqlspec/adapters/cockroach_asyncpg/core.cp314-win_amd64.pyd +0 -0
  97. sqlspec/adapters/cockroach_asyncpg/core.py +55 -0
  98. sqlspec/adapters/cockroach_asyncpg/data_dictionary.py +110 -0
  99. sqlspec/adapters/cockroach_asyncpg/driver.py +142 -0
  100. sqlspec/adapters/cockroach_asyncpg/events/__init__.py +3 -0
  101. sqlspec/adapters/cockroach_asyncpg/events/store.py +20 -0
  102. sqlspec/adapters/cockroach_asyncpg/litestar/__init__.py +3 -0
  103. sqlspec/adapters/cockroach_asyncpg/litestar/store.py +142 -0
  104. sqlspec/adapters/cockroach_psycopg/__init__.py +39 -0
  105. sqlspec/adapters/cockroach_psycopg/_typing.py +137 -0
  106. sqlspec/adapters/cockroach_psycopg/adk/__init__.py +13 -0
  107. sqlspec/adapters/cockroach_psycopg/adk/store.py +1039 -0
  108. sqlspec/adapters/cockroach_psycopg/config.py +511 -0
  109. sqlspec/adapters/cockroach_psycopg/core.cp314-win_amd64.pyd +0 -0
  110. sqlspec/adapters/cockroach_psycopg/core.py +63 -0
  111. sqlspec/adapters/cockroach_psycopg/data_dictionary.py +220 -0
  112. sqlspec/adapters/cockroach_psycopg/driver.py +273 -0
  113. sqlspec/adapters/cockroach_psycopg/events/__init__.py +6 -0
  114. sqlspec/adapters/cockroach_psycopg/events/store.py +34 -0
  115. sqlspec/adapters/cockroach_psycopg/litestar/__init__.py +3 -0
  116. sqlspec/adapters/cockroach_psycopg/litestar/store.py +327 -0
  117. sqlspec/adapters/duckdb/__init__.py +29 -0
  118. sqlspec/adapters/duckdb/_typing.py +104 -0
  119. sqlspec/adapters/duckdb/adk/__init__.py +14 -0
  120. sqlspec/adapters/duckdb/adk/store.py +935 -0
  121. sqlspec/adapters/duckdb/config.py +386 -0
  122. sqlspec/adapters/duckdb/core.cp314-win_amd64.pyd +0 -0
  123. sqlspec/adapters/duckdb/core.py +332 -0
  124. sqlspec/adapters/duckdb/data_dictionary.py +140 -0
  125. sqlspec/adapters/duckdb/driver.py +426 -0
  126. sqlspec/adapters/duckdb/events/__init__.py +5 -0
  127. sqlspec/adapters/duckdb/events/store.py +57 -0
  128. sqlspec/adapters/duckdb/litestar/__init__.py +5 -0
  129. sqlspec/adapters/duckdb/litestar/store.py +330 -0
  130. sqlspec/adapters/duckdb/pool.cp314-win_amd64.pyd +0 -0
  131. sqlspec/adapters/duckdb/pool.py +350 -0
  132. sqlspec/adapters/duckdb/type_converter.cp314-win_amd64.pyd +0 -0
  133. sqlspec/adapters/duckdb/type_converter.py +118 -0
  134. sqlspec/adapters/mysqlconnector/__init__.py +39 -0
  135. sqlspec/adapters/mysqlconnector/_typing.py +186 -0
  136. sqlspec/adapters/mysqlconnector/adk/__init__.py +15 -0
  137. sqlspec/adapters/mysqlconnector/adk/store.py +1183 -0
  138. sqlspec/adapters/mysqlconnector/config.py +421 -0
  139. sqlspec/adapters/mysqlconnector/core.cp314-win_amd64.pyd +0 -0
  140. sqlspec/adapters/mysqlconnector/core.py +472 -0
  141. sqlspec/adapters/mysqlconnector/data_dictionary.py +230 -0
  142. sqlspec/adapters/mysqlconnector/driver.py +516 -0
  143. sqlspec/adapters/mysqlconnector/events/__init__.py +8 -0
  144. sqlspec/adapters/mysqlconnector/events/store.py +98 -0
  145. sqlspec/adapters/mysqlconnector/litestar/__init__.py +5 -0
  146. sqlspec/adapters/mysqlconnector/litestar/store.py +426 -0
  147. sqlspec/adapters/oracledb/__init__.py +39 -0
  148. sqlspec/adapters/oracledb/_json_handlers.cp314-win_amd64.pyd +0 -0
  149. sqlspec/adapters/oracledb/_json_handlers.py +196 -0
  150. sqlspec/adapters/oracledb/_param_types.cp314-win_amd64.pyd +0 -0
  151. sqlspec/adapters/oracledb/_param_types.py +46 -0
  152. sqlspec/adapters/oracledb/_typing.py +258 -0
  153. sqlspec/adapters/oracledb/_uuid_handlers.cp314-win_amd64.pyd +0 -0
  154. sqlspec/adapters/oracledb/_uuid_handlers.py +163 -0
  155. sqlspec/adapters/oracledb/_vector_handlers.cp314-win_amd64.pyd +0 -0
  156. sqlspec/adapters/oracledb/_vector_handlers.py +228 -0
  157. sqlspec/adapters/oracledb/adk/__init__.py +21 -0
  158. sqlspec/adapters/oracledb/adk/store.py +2453 -0
  159. sqlspec/adapters/oracledb/config.py +575 -0
  160. sqlspec/adapters/oracledb/core.cp314-win_amd64.pyd +0 -0
  161. sqlspec/adapters/oracledb/core.py +820 -0
  162. sqlspec/adapters/oracledb/data_dictionary.py +404 -0
  163. sqlspec/adapters/oracledb/driver.py +1277 -0
  164. sqlspec/adapters/oracledb/events/__init__.py +16 -0
  165. sqlspec/adapters/oracledb/events/_hub.py +345 -0
  166. sqlspec/adapters/oracledb/events/backend.py +300 -0
  167. sqlspec/adapters/oracledb/events/store.py +420 -0
  168. sqlspec/adapters/oracledb/litestar/__init__.py +5 -0
  169. sqlspec/adapters/oracledb/litestar/store.py +781 -0
  170. sqlspec/adapters/oracledb/migrations.py +539 -0
  171. sqlspec/adapters/oracledb/type_converter.cp314-win_amd64.pyd +0 -0
  172. sqlspec/adapters/oracledb/type_converter.py +211 -0
  173. sqlspec/adapters/psqlpy/__init__.py +18 -0
  174. sqlspec/adapters/psqlpy/_typing.py +121 -0
  175. sqlspec/adapters/psqlpy/adk/__init__.py +5 -0
  176. sqlspec/adapters/psqlpy/adk/store.py +591 -0
  177. sqlspec/adapters/psqlpy/config.py +376 -0
  178. sqlspec/adapters/psqlpy/core.cp314-win_amd64.pyd +0 -0
  179. sqlspec/adapters/psqlpy/core.py +694 -0
  180. sqlspec/adapters/psqlpy/data_dictionary.py +121 -0
  181. sqlspec/adapters/psqlpy/driver.py +411 -0
  182. sqlspec/adapters/psqlpy/events/__init__.py +6 -0
  183. sqlspec/adapters/psqlpy/events/_hub.py +204 -0
  184. sqlspec/adapters/psqlpy/events/backend.py +210 -0
  185. sqlspec/adapters/psqlpy/events/store.py +20 -0
  186. sqlspec/adapters/psqlpy/litestar/__init__.py +5 -0
  187. sqlspec/adapters/psqlpy/litestar/store.py +270 -0
  188. sqlspec/adapters/psqlpy/type_converter.cp314-win_amd64.pyd +0 -0
  189. sqlspec/adapters/psqlpy/type_converter.py +113 -0
  190. sqlspec/adapters/psycopg/__init__.py +38 -0
  191. sqlspec/adapters/psycopg/_typing.py +218 -0
  192. sqlspec/adapters/psycopg/adk/__init__.py +10 -0
  193. sqlspec/adapters/psycopg/adk/store.py +1106 -0
  194. sqlspec/adapters/psycopg/config.py +695 -0
  195. sqlspec/adapters/psycopg/core.cp314-win_amd64.pyd +0 -0
  196. sqlspec/adapters/psycopg/core.py +520 -0
  197. sqlspec/adapters/psycopg/data_dictionary.py +278 -0
  198. sqlspec/adapters/psycopg/driver.py +1033 -0
  199. sqlspec/adapters/psycopg/events/__init__.py +20 -0
  200. sqlspec/adapters/psycopg/events/_hub.py +388 -0
  201. sqlspec/adapters/psycopg/events/backend.py +398 -0
  202. sqlspec/adapters/psycopg/events/store.py +42 -0
  203. sqlspec/adapters/psycopg/litestar/__init__.py +5 -0
  204. sqlspec/adapters/psycopg/litestar/store.py +554 -0
  205. sqlspec/adapters/psycopg/type_converter.cp314-win_amd64.pyd +0 -0
  206. sqlspec/adapters/psycopg/type_converter.py +93 -0
  207. sqlspec/adapters/pymysql/__init__.py +21 -0
  208. sqlspec/adapters/pymysql/_typing.py +92 -0
  209. sqlspec/adapters/pymysql/adk/__init__.py +5 -0
  210. sqlspec/adapters/pymysql/adk/store.py +657 -0
  211. sqlspec/adapters/pymysql/config.py +176 -0
  212. sqlspec/adapters/pymysql/core.cp314-win_amd64.pyd +0 -0
  213. sqlspec/adapters/pymysql/core.py +469 -0
  214. sqlspec/adapters/pymysql/data_dictionary.py +120 -0
  215. sqlspec/adapters/pymysql/driver.py +271 -0
  216. sqlspec/adapters/pymysql/events/__init__.py +5 -0
  217. sqlspec/adapters/pymysql/events/store.py +50 -0
  218. sqlspec/adapters/pymysql/litestar/__init__.py +5 -0
  219. sqlspec/adapters/pymysql/litestar/store.py +232 -0
  220. sqlspec/adapters/pymysql/pool.cp314-win_amd64.pyd +0 -0
  221. sqlspec/adapters/pymysql/pool.py +184 -0
  222. sqlspec/adapters/spanner/__init__.py +33 -0
  223. sqlspec/adapters/spanner/_typing.py +102 -0
  224. sqlspec/adapters/spanner/adk/__init__.py +5 -0
  225. sqlspec/adapters/spanner/adk/store.py +758 -0
  226. sqlspec/adapters/spanner/config.py +355 -0
  227. sqlspec/adapters/spanner/core.cp314-win_amd64.pyd +0 -0
  228. sqlspec/adapters/spanner/core.py +263 -0
  229. sqlspec/adapters/spanner/data_dictionary.py +120 -0
  230. sqlspec/adapters/spanner/driver.py +407 -0
  231. sqlspec/adapters/spanner/events/__init__.py +5 -0
  232. sqlspec/adapters/spanner/events/store.py +187 -0
  233. sqlspec/adapters/spanner/litestar/__init__.py +5 -0
  234. sqlspec/adapters/spanner/litestar/store.py +291 -0
  235. sqlspec/adapters/spanner/type_converter.cp314-win_amd64.pyd +0 -0
  236. sqlspec/adapters/spanner/type_converter.py +342 -0
  237. sqlspec/adapters/sqlite/__init__.py +19 -0
  238. sqlspec/adapters/sqlite/_typing.py +123 -0
  239. sqlspec/adapters/sqlite/adk/__init__.py +5 -0
  240. sqlspec/adapters/sqlite/adk/store.py +992 -0
  241. sqlspec/adapters/sqlite/config.py +240 -0
  242. sqlspec/adapters/sqlite/core.cp314-win_amd64.pyd +0 -0
  243. sqlspec/adapters/sqlite/core.py +357 -0
  244. sqlspec/adapters/sqlite/data_dictionary.py +198 -0
  245. sqlspec/adapters/sqlite/driver.py +527 -0
  246. sqlspec/adapters/sqlite/events/__init__.py +5 -0
  247. sqlspec/adapters/sqlite/events/store.py +20 -0
  248. sqlspec/adapters/sqlite/litestar/__init__.py +5 -0
  249. sqlspec/adapters/sqlite/litestar/store.py +316 -0
  250. sqlspec/adapters/sqlite/pool.cp314-win_amd64.pyd +0 -0
  251. sqlspec/adapters/sqlite/pool.py +237 -0
  252. sqlspec/adapters/sqlite/type_converter.cp314-win_amd64.pyd +0 -0
  253. sqlspec/adapters/sqlite/type_converter.py +114 -0
  254. sqlspec/base.py +832 -0
  255. sqlspec/builder/__init__.py +181 -0
  256. sqlspec/builder/_base.cp314-win_amd64.pyd +0 -0
  257. sqlspec/builder/_base.py +1071 -0
  258. sqlspec/builder/_column.cp314-win_amd64.pyd +0 -0
  259. sqlspec/builder/_column.py +521 -0
  260. sqlspec/builder/_ddl.cp314-win_amd64.pyd +0 -0
  261. sqlspec/builder/_ddl.py +1691 -0
  262. sqlspec/builder/_delete.cp314-win_amd64.pyd +0 -0
  263. sqlspec/builder/_delete.py +95 -0
  264. sqlspec/builder/_dml.cp314-win_amd64.pyd +0 -0
  265. sqlspec/builder/_dml.py +386 -0
  266. sqlspec/builder/_explain.cp314-win_amd64.pyd +0 -0
  267. sqlspec/builder/_explain.py +579 -0
  268. sqlspec/builder/_expression_wrappers.cp314-win_amd64.pyd +0 -0
  269. sqlspec/builder/_expression_wrappers.py +46 -0
  270. sqlspec/builder/_factory.cp314-win_amd64.pyd +0 -0
  271. sqlspec/builder/_factory.py +1884 -0
  272. sqlspec/builder/_insert.cp314-win_amd64.pyd +0 -0
  273. sqlspec/builder/_insert.py +405 -0
  274. sqlspec/builder/_join.cp314-win_amd64.pyd +0 -0
  275. sqlspec/builder/_join.py +489 -0
  276. sqlspec/builder/_merge.cp314-win_amd64.pyd +0 -0
  277. sqlspec/builder/_merge.py +823 -0
  278. sqlspec/builder/_parsing_utils.cp314-win_amd64.pyd +0 -0
  279. sqlspec/builder/_parsing_utils.py +295 -0
  280. sqlspec/builder/_select.cp314-win_amd64.pyd +0 -0
  281. sqlspec/builder/_select.py +1666 -0
  282. sqlspec/builder/_temporal.cp314-win_amd64.pyd +0 -0
  283. sqlspec/builder/_temporal.py +167 -0
  284. sqlspec/builder/_update.cp314-win_amd64.pyd +0 -0
  285. sqlspec/builder/_update.py +173 -0
  286. sqlspec/builder/_vector_distance.cp314-win_amd64.pyd +0 -0
  287. sqlspec/builder/_vector_distance.py +330 -0
  288. sqlspec/cli.py +1095 -0
  289. sqlspec/config.py +2383 -0
  290. sqlspec/core/__init__.py +372 -0
  291. sqlspec/core/_correlation.cp314-win_amd64.pyd +0 -0
  292. sqlspec/core/_correlation.py +176 -0
  293. sqlspec/core/_pagination.py +42 -0
  294. sqlspec/core/_pool.cp314-win_amd64.pyd +0 -0
  295. sqlspec/core/_pool.py +76 -0
  296. sqlspec/core/cache.cp314-win_amd64.pyd +0 -0
  297. sqlspec/core/cache.py +1085 -0
  298. sqlspec/core/compiler.cp314-win_amd64.pyd +0 -0
  299. sqlspec/core/compiler.py +1090 -0
  300. sqlspec/core/config_runtime.cp314-win_amd64.pyd +0 -0
  301. sqlspec/core/config_runtime.py +174 -0
  302. sqlspec/core/explain.cp314-win_amd64.pyd +0 -0
  303. sqlspec/core/explain.py +275 -0
  304. sqlspec/core/filters.cp314-win_amd64.pyd +0 -0
  305. sqlspec/core/filters.py +969 -0
  306. sqlspec/core/hashing.cp314-win_amd64.pyd +0 -0
  307. sqlspec/core/hashing.py +266 -0
  308. sqlspec/core/metrics.cp314-win_amd64.pyd +0 -0
  309. sqlspec/core/metrics.py +83 -0
  310. sqlspec/core/parameters/__init__.py +72 -0
  311. sqlspec/core/parameters/_alignment.cp314-win_amd64.pyd +0 -0
  312. sqlspec/core/parameters/_alignment.py +283 -0
  313. sqlspec/core/parameters/_converter.cp314-win_amd64.pyd +0 -0
  314. sqlspec/core/parameters/_converter.py +554 -0
  315. sqlspec/core/parameters/_processor.cp314-win_amd64.pyd +0 -0
  316. sqlspec/core/parameters/_processor.py +1182 -0
  317. sqlspec/core/parameters/_registry.cp314-win_amd64.pyd +0 -0
  318. sqlspec/core/parameters/_registry.py +206 -0
  319. sqlspec/core/parameters/_transformers.cp314-win_amd64.pyd +0 -0
  320. sqlspec/core/parameters/_transformers.py +324 -0
  321. sqlspec/core/parameters/_types.cp314-win_amd64.pyd +0 -0
  322. sqlspec/core/parameters/_types.py +536 -0
  323. sqlspec/core/parameters/_validator.cp314-win_amd64.pyd +0 -0
  324. sqlspec/core/parameters/_validator.py +171 -0
  325. sqlspec/core/pipeline.cp314-win_amd64.pyd +0 -0
  326. sqlspec/core/pipeline.py +333 -0
  327. sqlspec/core/query_modifiers.cp314-win_amd64.pyd +0 -0
  328. sqlspec/core/query_modifiers.py +508 -0
  329. sqlspec/core/result/__init__.py +25 -0
  330. sqlspec/core/result/_base.cp314-win_amd64.pyd +0 -0
  331. sqlspec/core/result/_base.py +1232 -0
  332. sqlspec/core/result/_io.cp314-win_amd64.pyd +0 -0
  333. sqlspec/core/result/_io.py +28 -0
  334. sqlspec/core/splitter.cp314-win_amd64.pyd +0 -0
  335. sqlspec/core/splitter.py +1021 -0
  336. sqlspec/core/sqlcommenter.cp314-win_amd64.pyd +0 -0
  337. sqlspec/core/sqlcommenter.py +249 -0
  338. sqlspec/core/stack.cp314-win_amd64.pyd +0 -0
  339. sqlspec/core/stack.py +163 -0
  340. sqlspec/core/statement.cp314-win_amd64.pyd +0 -0
  341. sqlspec/core/statement.py +1865 -0
  342. sqlspec/core/type_converter.cp314-win_amd64.pyd +0 -0
  343. sqlspec/core/type_converter.py +340 -0
  344. sqlspec/data_dictionary/__init__.py +22 -0
  345. sqlspec/data_dictionary/_loader.cp314-win_amd64.pyd +0 -0
  346. sqlspec/data_dictionary/_loader.py +138 -0
  347. sqlspec/data_dictionary/_registry.cp314-win_amd64.pyd +0 -0
  348. sqlspec/data_dictionary/_registry.py +74 -0
  349. sqlspec/data_dictionary/_types.cp314-win_amd64.pyd +0 -0
  350. sqlspec/data_dictionary/_types.py +121 -0
  351. sqlspec/data_dictionary/dialects/__init__.py +21 -0
  352. sqlspec/data_dictionary/dialects/bigquery.cp314-win_amd64.pyd +0 -0
  353. sqlspec/data_dictionary/dialects/bigquery.py +81 -0
  354. sqlspec/data_dictionary/dialects/cockroachdb.cp314-win_amd64.pyd +0 -0
  355. sqlspec/data_dictionary/dialects/cockroachdb.py +54 -0
  356. sqlspec/data_dictionary/dialects/duckdb.cp314-win_amd64.pyd +0 -0
  357. sqlspec/data_dictionary/dialects/duckdb.py +47 -0
  358. sqlspec/data_dictionary/dialects/mysql.cp314-win_amd64.pyd +0 -0
  359. sqlspec/data_dictionary/dialects/mysql.py +53 -0
  360. sqlspec/data_dictionary/dialects/oracle.cp314-win_amd64.pyd +0 -0
  361. sqlspec/data_dictionary/dialects/oracle.py +197 -0
  362. sqlspec/data_dictionary/dialects/postgres.cp314-win_amd64.pyd +0 -0
  363. sqlspec/data_dictionary/dialects/postgres.py +69 -0
  364. sqlspec/data_dictionary/dialects/spanner.cp314-win_amd64.pyd +0 -0
  365. sqlspec/data_dictionary/dialects/spanner.py +37 -0
  366. sqlspec/data_dictionary/dialects/sqlite.cp314-win_amd64.pyd +0 -0
  367. sqlspec/data_dictionary/dialects/sqlite.py +59 -0
  368. sqlspec/data_dictionary/sql/.gitkeep +0 -0
  369. sqlspec/data_dictionary/sql/bigquery/columns.sql +23 -0
  370. sqlspec/data_dictionary/sql/bigquery/foreign_keys.sql +34 -0
  371. sqlspec/data_dictionary/sql/bigquery/indexes.sql +19 -0
  372. sqlspec/data_dictionary/sql/bigquery/tables.sql +33 -0
  373. sqlspec/data_dictionary/sql/bigquery/version.sql +3 -0
  374. sqlspec/data_dictionary/sql/cockroachdb/columns.sql +34 -0
  375. sqlspec/data_dictionary/sql/cockroachdb/foreign_keys.sql +40 -0
  376. sqlspec/data_dictionary/sql/cockroachdb/indexes.sql +32 -0
  377. sqlspec/data_dictionary/sql/cockroachdb/tables.sql +44 -0
  378. sqlspec/data_dictionary/sql/cockroachdb/version.sql +3 -0
  379. sqlspec/data_dictionary/sql/duckdb/columns.sql +23 -0
  380. sqlspec/data_dictionary/sql/duckdb/foreign_keys.sql +36 -0
  381. sqlspec/data_dictionary/sql/duckdb/indexes.sql +19 -0
  382. sqlspec/data_dictionary/sql/duckdb/tables.sql +38 -0
  383. sqlspec/data_dictionary/sql/duckdb/version.sql +3 -0
  384. sqlspec/data_dictionary/sql/mysql/columns.sql +23 -0
  385. sqlspec/data_dictionary/sql/mysql/foreign_keys.sql +28 -0
  386. sqlspec/data_dictionary/sql/mysql/indexes.sql +26 -0
  387. sqlspec/data_dictionary/sql/mysql/tables.sql +33 -0
  388. sqlspec/data_dictionary/sql/mysql/version.sql +3 -0
  389. sqlspec/data_dictionary/sql/oracle/columns.sql +23 -0
  390. sqlspec/data_dictionary/sql/oracle/foreign_keys.sql +48 -0
  391. sqlspec/data_dictionary/sql/oracle/indexes.sql +44 -0
  392. sqlspec/data_dictionary/sql/oracle/tables.sql +25 -0
  393. sqlspec/data_dictionary/sql/oracle/version.sql +20 -0
  394. sqlspec/data_dictionary/sql/postgres/columns.sql +34 -0
  395. sqlspec/data_dictionary/sql/postgres/foreign_keys.sql +40 -0
  396. sqlspec/data_dictionary/sql/postgres/indexes.sql +56 -0
  397. sqlspec/data_dictionary/sql/postgres/tables.sql +44 -0
  398. sqlspec/data_dictionary/sql/postgres/version.sql +3 -0
  399. sqlspec/data_dictionary/sql/spanner/columns.sql +23 -0
  400. sqlspec/data_dictionary/sql/spanner/foreign_keys.sql +70 -0
  401. sqlspec/data_dictionary/sql/spanner/indexes.sql +30 -0
  402. sqlspec/data_dictionary/sql/spanner/tables.sql +9 -0
  403. sqlspec/data_dictionary/sql/spanner/version.sql +3 -0
  404. sqlspec/data_dictionary/sql/sqlite/columns.sql +23 -0
  405. sqlspec/data_dictionary/sql/sqlite/foreign_keys.sql +22 -0
  406. sqlspec/data_dictionary/sql/sqlite/indexes.sql +7 -0
  407. sqlspec/data_dictionary/sql/sqlite/tables.sql +28 -0
  408. sqlspec/data_dictionary/sql/sqlite/version.sql +3 -0
  409. sqlspec/dialects/__init__.py +22 -0
  410. sqlspec/dialects/_compat.cp314-win_amd64.pyd +0 -0
  411. sqlspec/dialects/_compat.py +14 -0
  412. sqlspec/dialects/postgres/__init__.py +9 -0
  413. sqlspec/dialects/postgres/_generators.cp314-win_amd64.pyd +0 -0
  414. sqlspec/dialects/postgres/_generators.py +57 -0
  415. sqlspec/dialects/postgres/_operators.cp314-win_amd64.pyd +0 -0
  416. sqlspec/dialects/postgres/_operators.py +81 -0
  417. sqlspec/dialects/postgres/_paradedb.py +50 -0
  418. sqlspec/dialects/postgres/_pgvector.py +36 -0
  419. sqlspec/dialects/spanner/__init__.py +6 -0
  420. sqlspec/dialects/spanner/_generators.cp314-win_amd64.pyd +0 -0
  421. sqlspec/dialects/spanner/_generators.py +206 -0
  422. sqlspec/dialects/spanner/_spangres.py +77 -0
  423. sqlspec/dialects/spanner/_spanner.py +179 -0
  424. sqlspec/driver/__init__.py +49 -0
  425. sqlspec/driver/_async.cp314-win_amd64.pyd +0 -0
  426. sqlspec/driver/_async.py +1830 -0
  427. sqlspec/driver/_common.cp314-win_amd64.pyd +0 -0
  428. sqlspec/driver/_common.py +2292 -0
  429. sqlspec/driver/_exception_handler.cp314-win_amd64.pyd +0 -0
  430. sqlspec/driver/_exception_handler.py +108 -0
  431. sqlspec/driver/_query_cache.cp314-win_amd64.pyd +0 -0
  432. sqlspec/driver/_query_cache.py +96 -0
  433. sqlspec/driver/_sql_helpers.cp314-win_amd64.pyd +0 -0
  434. sqlspec/driver/_sql_helpers.py +139 -0
  435. sqlspec/driver/_storage_helpers.cp314-win_amd64.pyd +0 -0
  436. sqlspec/driver/_storage_helpers.py +153 -0
  437. sqlspec/driver/_sync.cp314-win_amd64.pyd +0 -0
  438. sqlspec/driver/_sync.py +1817 -0
  439. sqlspec/exceptions.cp314-win_amd64.pyd +0 -0
  440. sqlspec/exceptions.py +480 -0
  441. sqlspec/extensions/__init__.py +0 -0
  442. sqlspec/extensions/adk/__init__.py +84 -0
  443. sqlspec/extensions/adk/_config_utils.py +199 -0
  444. sqlspec/extensions/adk/_types.cp314-win_amd64.pyd +0 -0
  445. sqlspec/extensions/adk/_types.py +41 -0
  446. sqlspec/extensions/adk/artifact/__init__.py +57 -0
  447. sqlspec/extensions/adk/artifact/_types.cp314-win_amd64.pyd +0 -0
  448. sqlspec/extensions/adk/artifact/_types.py +32 -0
  449. sqlspec/extensions/adk/artifact/service.py +508 -0
  450. sqlspec/extensions/adk/artifact/store.py +361 -0
  451. sqlspec/extensions/adk/converters.py +212 -0
  452. sqlspec/extensions/adk/memory/__init__.py +69 -0
  453. sqlspec/extensions/adk/memory/_types.cp314-win_amd64.pyd +0 -0
  454. sqlspec/extensions/adk/memory/_types.py +30 -0
  455. sqlspec/extensions/adk/memory/converters.py +225 -0
  456. sqlspec/extensions/adk/memory/service.py +316 -0
  457. sqlspec/extensions/adk/memory/store.py +525 -0
  458. sqlspec/extensions/adk/migrations/0001_create_adk_tables.py +184 -0
  459. sqlspec/extensions/adk/migrations/__init__.py +0 -0
  460. sqlspec/extensions/adk/service.py +279 -0
  461. sqlspec/extensions/adk/store.py +590 -0
  462. sqlspec/extensions/events/__init__.py +51 -0
  463. sqlspec/extensions/events/_channel.py +703 -0
  464. sqlspec/extensions/events/_hints.cp314-win_amd64.pyd +0 -0
  465. sqlspec/extensions/events/_hints.py +45 -0
  466. sqlspec/extensions/events/_models.py +23 -0
  467. sqlspec/extensions/events/_payload.cp314-win_amd64.pyd +0 -0
  468. sqlspec/extensions/events/_payload.py +69 -0
  469. sqlspec/extensions/events/_protocols.py +134 -0
  470. sqlspec/extensions/events/_queue.py +462 -0
  471. sqlspec/extensions/events/_store.py +209 -0
  472. sqlspec/extensions/events/migrations/0001_create_event_queue.py +59 -0
  473. sqlspec/extensions/events/migrations/__init__.py +3 -0
  474. sqlspec/extensions/fastapi/__init__.py +22 -0
  475. sqlspec/extensions/fastapi/extension.py +391 -0
  476. sqlspec/extensions/fastapi/providers.cp314-win_amd64.pyd +0 -0
  477. sqlspec/extensions/fastapi/providers.py +712 -0
  478. sqlspec/extensions/flask/__init__.py +38 -0
  479. sqlspec/extensions/flask/_state.py +87 -0
  480. sqlspec/extensions/flask/_utils.py +71 -0
  481. sqlspec/extensions/flask/extension.py +539 -0
  482. sqlspec/extensions/litestar/__init__.py +31 -0
  483. sqlspec/extensions/litestar/_utils.py +52 -0
  484. sqlspec/extensions/litestar/channels.py +165 -0
  485. sqlspec/extensions/litestar/cli.py +102 -0
  486. sqlspec/extensions/litestar/config.py +90 -0
  487. sqlspec/extensions/litestar/handlers.py +316 -0
  488. sqlspec/extensions/litestar/migrations/0001_create_session_table.py +137 -0
  489. sqlspec/extensions/litestar/migrations/__init__.py +3 -0
  490. sqlspec/extensions/litestar/plugin.py +1066 -0
  491. sqlspec/extensions/litestar/providers.cp314-win_amd64.pyd +0 -0
  492. sqlspec/extensions/litestar/providers.py +784 -0
  493. sqlspec/extensions/litestar/store.py +298 -0
  494. sqlspec/extensions/otel/__init__.py +58 -0
  495. sqlspec/extensions/prometheus/__init__.py +113 -0
  496. sqlspec/extensions/sanic/__init__.py +19 -0
  497. sqlspec/extensions/sanic/_state.py +43 -0
  498. sqlspec/extensions/sanic/_utils.py +127 -0
  499. sqlspec/extensions/sanic/extension.py +647 -0
  500. sqlspec/extensions/starlette/__init__.py +22 -0
  501. sqlspec/extensions/starlette/_state.py +42 -0
  502. sqlspec/extensions/starlette/_utils.py +96 -0
  503. sqlspec/extensions/starlette/extension.py +374 -0
  504. sqlspec/extensions/starlette/middleware.py +281 -0
  505. sqlspec/loader.cp314-win_amd64.pyd +0 -0
  506. sqlspec/loader.py +727 -0
  507. sqlspec/migrations/__init__.py +39 -0
  508. sqlspec/migrations/base.cp314-win_amd64.pyd +0 -0
  509. sqlspec/migrations/base.py +862 -0
  510. sqlspec/migrations/commands.py +2151 -0
  511. sqlspec/migrations/context.cp314-win_amd64.pyd +0 -0
  512. sqlspec/migrations/context.py +157 -0
  513. sqlspec/migrations/fix.cp314-win_amd64.pyd +0 -0
  514. sqlspec/migrations/fix.py +204 -0
  515. sqlspec/migrations/loaders.cp314-win_amd64.pyd +0 -0
  516. sqlspec/migrations/loaders.py +443 -0
  517. sqlspec/migrations/runner.cp314-win_amd64.pyd +0 -0
  518. sqlspec/migrations/runner.py +1195 -0
  519. sqlspec/migrations/squash.cp314-win_amd64.pyd +0 -0
  520. sqlspec/migrations/squash.py +490 -0
  521. sqlspec/migrations/templates.cp314-win_amd64.pyd +0 -0
  522. sqlspec/migrations/templates.py +234 -0
  523. sqlspec/migrations/tracker.cp314-win_amd64.pyd +0 -0
  524. sqlspec/migrations/tracker.py +792 -0
  525. sqlspec/migrations/utils.cp314-win_amd64.pyd +0 -0
  526. sqlspec/migrations/utils.py +256 -0
  527. sqlspec/migrations/validation.cp314-win_amd64.pyd +0 -0
  528. sqlspec/migrations/validation.py +359 -0
  529. sqlspec/migrations/version.cp314-win_amd64.pyd +0 -0
  530. sqlspec/migrations/version.py +446 -0
  531. sqlspec/observability/__init__.py +57 -0
  532. sqlspec/observability/_common.cp314-win_amd64.pyd +0 -0
  533. sqlspec/observability/_common.py +77 -0
  534. sqlspec/observability/_config.cp314-win_amd64.pyd +0 -0
  535. sqlspec/observability/_config.py +364 -0
  536. sqlspec/observability/_diagnostics.cp314-win_amd64.pyd +0 -0
  537. sqlspec/observability/_diagnostics.py +74 -0
  538. sqlspec/observability/_dispatcher.cp314-win_amd64.pyd +0 -0
  539. sqlspec/observability/_dispatcher.py +200 -0
  540. sqlspec/observability/_formatters/__init__.py +13 -0
  541. sqlspec/observability/_formatters/_aws.cp314-win_amd64.pyd +0 -0
  542. sqlspec/observability/_formatters/_aws.py +102 -0
  543. sqlspec/observability/_formatters/_azure.cp314-win_amd64.pyd +0 -0
  544. sqlspec/observability/_formatters/_azure.py +96 -0
  545. sqlspec/observability/_formatters/_base.cp314-win_amd64.pyd +0 -0
  546. sqlspec/observability/_formatters/_base.py +57 -0
  547. sqlspec/observability/_formatters/_gcp.cp314-win_amd64.pyd +0 -0
  548. sqlspec/observability/_formatters/_gcp.py +131 -0
  549. sqlspec/observability/_formatting.py +58 -0
  550. sqlspec/observability/_observer.cp314-win_amd64.pyd +0 -0
  551. sqlspec/observability/_observer.py +361 -0
  552. sqlspec/observability/_runtime.cp314-win_amd64.pyd +0 -0
  553. sqlspec/observability/_runtime.py +461 -0
  554. sqlspec/observability/_sampling.cp314-win_amd64.pyd +0 -0
  555. sqlspec/observability/_sampling.py +188 -0
  556. sqlspec/observability/_spans.cp314-win_amd64.pyd +0 -0
  557. sqlspec/observability/_spans.py +161 -0
  558. sqlspec/protocols.py +955 -0
  559. sqlspec/py.typed +0 -0
  560. sqlspec/service.py +433 -0
  561. sqlspec/storage/__init__.py +48 -0
  562. sqlspec/storage/_arrow_payload.py +68 -0
  563. sqlspec/storage/_paths.cp314-win_amd64.pyd +0 -0
  564. sqlspec/storage/_paths.py +58 -0
  565. sqlspec/storage/_utils.py +46 -0
  566. sqlspec/storage/backends/__init__.py +1 -0
  567. sqlspec/storage/backends/base.cp314-win_amd64.pyd +0 -0
  568. sqlspec/storage/backends/base.py +374 -0
  569. sqlspec/storage/backends/fsspec.py +574 -0
  570. sqlspec/storage/backends/local.py +468 -0
  571. sqlspec/storage/backends/obstore.py +956 -0
  572. sqlspec/storage/errors.cp314-win_amd64.pyd +0 -0
  573. sqlspec/storage/errors.py +102 -0
  574. sqlspec/storage/pipeline.cp314-win_amd64.pyd +0 -0
  575. sqlspec/storage/pipeline.py +628 -0
  576. sqlspec/storage/registry.cp314-win_amd64.pyd +0 -0
  577. sqlspec/storage/registry.py +329 -0
  578. sqlspec/typing.py +405 -0
  579. sqlspec/utils/__init__.py +7 -0
  580. sqlspec/utils/arrow_helpers.py +384 -0
  581. sqlspec/utils/config_tools.cp314-win_amd64.pyd +0 -0
  582. sqlspec/utils/config_tools.py +314 -0
  583. sqlspec/utils/correlation.cp314-win_amd64.pyd +0 -0
  584. sqlspec/utils/correlation.py +134 -0
  585. sqlspec/utils/deprecation.cp314-win_amd64.pyd +0 -0
  586. sqlspec/utils/deprecation.py +157 -0
  587. sqlspec/utils/dispatch.cp314-win_amd64.pyd +0 -0
  588. sqlspec/utils/dispatch.py +101 -0
  589. sqlspec/utils/fixtures.cp314-win_amd64.pyd +0 -0
  590. sqlspec/utils/fixtures.py +260 -0
  591. sqlspec/utils/logging.cp314-win_amd64.pyd +0 -0
  592. sqlspec/utils/logging.py +251 -0
  593. sqlspec/utils/module_loader.py +306 -0
  594. sqlspec/utils/portal.cp314-win_amd64.pyd +0 -0
  595. sqlspec/utils/portal.py +377 -0
  596. sqlspec/utils/schema.cp314-win_amd64.pyd +0 -0
  597. sqlspec/utils/schema.py +1040 -0
  598. sqlspec/utils/serializers/__init__.py +30 -0
  599. sqlspec/utils/serializers/_json.cp314-win_amd64.pyd +0 -0
  600. sqlspec/utils/serializers/_json.py +415 -0
  601. sqlspec/utils/serializers/_numpy.cp314-win_amd64.pyd +0 -0
  602. sqlspec/utils/serializers/_numpy.py +65 -0
  603. sqlspec/utils/serializers/_schema.cp314-win_amd64.pyd +0 -0
  604. sqlspec/utils/serializers/_schema.py +285 -0
  605. sqlspec/utils/singleton.cp314-win_amd64.pyd +0 -0
  606. sqlspec/utils/singleton.py +41 -0
  607. sqlspec/utils/sync_tools.cp314-win_amd64.pyd +0 -0
  608. sqlspec/utils/sync_tools.py +316 -0
  609. sqlspec/utils/text.cp314-win_amd64.pyd +0 -0
  610. sqlspec/utils/text.py +109 -0
  611. sqlspec/utils/type_converters.cp314-win_amd64.pyd +0 -0
  612. sqlspec/utils/type_converters.py +216 -0
  613. sqlspec/utils/type_guards.cp314-win_amd64.pyd +0 -0
  614. sqlspec/utils/type_guards.py +1508 -0
  615. sqlspec/utils/uuids.cp314-win_amd64.pyd +0 -0
  616. sqlspec/utils/uuids.py +241 -0
  617. sqlspec-0.47.0.dist-info/METADATA +202 -0
  618. sqlspec-0.47.0.dist-info/RECORD +621 -0
  619. sqlspec-0.47.0.dist-info/WHEEL +4 -0
  620. sqlspec-0.47.0.dist-info/entry_points.txt +6 -0
  621. sqlspec-0.47.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,426 @@
1
+ """MysqlConnector session store for Litestar integration."""
2
+
3
+ from datetime import datetime, timedelta, timezone
4
+ from typing import TYPE_CHECKING, Any, Final, cast
5
+
6
+ import mysql.connector
7
+
8
+ from sqlspec.extensions.litestar.store import BaseSQLSpecStore
9
+ from sqlspec.utils.logging import get_logger
10
+ from sqlspec.utils.sync_tools import async_
11
+
12
+ if TYPE_CHECKING:
13
+ from sqlspec.adapters.mysqlconnector.config import MysqlConnectorAsyncConfig, MysqlConnectorSyncConfig
14
+
15
+ logger = get_logger("sqlspec.adapters.mysqlconnector.litestar.store")
16
+
17
+ __all__ = ("MysqlConnectorAsyncStore", "MysqlConnectorSyncStore")
18
+
19
+ MYSQL_TABLE_NOT_FOUND_ERROR: Final = 1146
20
+
21
+
22
+ class MysqlConnectorAsyncStore(BaseSQLSpecStore["MysqlConnectorAsyncConfig"]):
23
+ """MySQL/MariaDB session store using mysql-connector async driver."""
24
+
25
+ __slots__ = ()
26
+
27
+ def __init__(self, config: "MysqlConnectorAsyncConfig") -> None:
28
+ super().__init__(config)
29
+
30
+ def _get_create_table_sql(self) -> str:
31
+ return f"""
32
+ CREATE TABLE IF NOT EXISTS {self._table_name} (
33
+ session_id VARCHAR(255) PRIMARY KEY,
34
+ data LONGBLOB NOT NULL,
35
+ expires_at DATETIME(6),
36
+ created_at DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6),
37
+ updated_at DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
38
+ INDEX idx_{self._table_name}_expires_at (expires_at)
39
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
40
+ """
41
+
42
+ def _get_drop_table_sql(self) -> "list[str]":
43
+ return [
44
+ f"DROP INDEX idx_{self._table_name}_expires_at ON {self._table_name}",
45
+ f"DROP TABLE IF EXISTS {self._table_name}",
46
+ ]
47
+
48
+ async def create_table(self) -> None:
49
+ sql = self._get_create_table_sql()
50
+ async with self._config.provide_session() as driver:
51
+ await driver.execute_script(sql)
52
+ self._log_table_created()
53
+
54
+ async def get(self, key: str, renew_for: "int | timedelta | None" = None) -> "bytes | None":
55
+ sql = f"""
56
+ SELECT data, expires_at FROM {self._table_name}
57
+ WHERE session_id = %s
58
+ AND (expires_at IS NULL OR expires_at > UTC_TIMESTAMP(6))
59
+ """
60
+
61
+ try:
62
+ async with self._config.provide_connection() as conn:
63
+ cursor = await conn.cursor()
64
+ try:
65
+ await cursor.execute(sql, (key,))
66
+ row = await cursor.fetchone()
67
+ finally:
68
+ await cursor.close()
69
+
70
+ if row is None:
71
+ return None
72
+
73
+ data_value: Any = row[0]
74
+ expires_at: Any = row[1]
75
+
76
+ if renew_for is not None and expires_at is not None:
77
+ new_expires_at = self._calculate_expires_at(renew_for)
78
+ if new_expires_at is not None:
79
+ naive_expires_at = new_expires_at.replace(tzinfo=None)
80
+ update_sql = f"""
81
+ UPDATE {self._table_name}
82
+ SET expires_at = %s, updated_at = UTC_TIMESTAMP(6)
83
+ WHERE session_id = %s
84
+ """
85
+ update_cursor = await conn.cursor()
86
+ try:
87
+ await update_cursor.execute(update_sql, (naive_expires_at, key))
88
+ finally:
89
+ await update_cursor.close()
90
+ await conn.commit()
91
+
92
+ return bytes(cast("bytes", data_value))
93
+ except mysql.connector.Error as exc:
94
+ if "doesn't exist" in str(exc) or getattr(exc, "errno", None) == MYSQL_TABLE_NOT_FOUND_ERROR:
95
+ return None
96
+ raise
97
+
98
+ async def set(self, key: str, value: "str | bytes", expires_in: "int | timedelta | None" = None) -> None:
99
+ data = self._value_to_bytes(value)
100
+ expires_at = self._calculate_expires_at(expires_in)
101
+ naive_expires_at = expires_at.replace(tzinfo=None) if expires_at else None
102
+
103
+ sql = f"""
104
+ INSERT INTO {self._table_name} (session_id, data, expires_at)
105
+ VALUES (%s, %s, %s) AS new
106
+ ON DUPLICATE KEY UPDATE
107
+ data = new.data,
108
+ expires_at = new.expires_at,
109
+ updated_at = UTC_TIMESTAMP(6)
110
+ """
111
+
112
+ async with self._config.provide_connection() as conn:
113
+ cursor = await conn.cursor()
114
+ try:
115
+ await cursor.execute(sql, (key, data, naive_expires_at))
116
+ finally:
117
+ await cursor.close()
118
+ await conn.commit()
119
+
120
+ async def delete(self, key: str) -> None:
121
+ sql = f"DELETE FROM {self._table_name} WHERE session_id = %s"
122
+
123
+ async with self._config.provide_connection() as conn:
124
+ cursor = await conn.cursor()
125
+ try:
126
+ await cursor.execute(sql, (key,))
127
+ finally:
128
+ await cursor.close()
129
+ await conn.commit()
130
+
131
+ async def delete_all(self) -> None:
132
+ sql = f"DELETE FROM {self._table_name}"
133
+
134
+ try:
135
+ async with self._config.provide_connection() as conn:
136
+ cursor = await conn.cursor()
137
+ try:
138
+ await cursor.execute(sql)
139
+ finally:
140
+ await cursor.close()
141
+ await conn.commit()
142
+ self._log_delete_all()
143
+ except mysql.connector.Error as exc:
144
+ if "doesn't exist" in str(exc) or getattr(exc, "errno", None) == MYSQL_TABLE_NOT_FOUND_ERROR:
145
+ logger.debug("Table %s does not exist, skipping delete_all", self._table_name)
146
+ return
147
+ raise
148
+
149
+ async def exists(self, key: str) -> bool:
150
+ sql = f"""
151
+ SELECT 1 FROM {self._table_name}
152
+ WHERE session_id = %s
153
+ AND (expires_at IS NULL OR expires_at > UTC_TIMESTAMP(6))
154
+ """
155
+
156
+ try:
157
+ async with self._config.provide_connection() as conn:
158
+ cursor = await conn.cursor()
159
+ try:
160
+ await cursor.execute(sql, (key,))
161
+ result = await cursor.fetchone()
162
+ finally:
163
+ await cursor.close()
164
+ return result is not None
165
+ except mysql.connector.Error as exc:
166
+ if "doesn't exist" in str(exc) or getattr(exc, "errno", None) == MYSQL_TABLE_NOT_FOUND_ERROR:
167
+ return False
168
+ raise
169
+
170
+ async def expires_in(self, key: str) -> "int | None":
171
+ sql = f"""
172
+ SELECT expires_at FROM {self._table_name}
173
+ WHERE session_id = %s
174
+ """
175
+
176
+ async with self._config.provide_connection() as conn:
177
+ cursor = await conn.cursor()
178
+ try:
179
+ await cursor.execute(sql, (key,))
180
+ row = await cursor.fetchone()
181
+ finally:
182
+ await cursor.close()
183
+
184
+ if row is None or row[0] is None:
185
+ return None
186
+
187
+ expires_at_naive: datetime = cast("datetime", row[0])
188
+ expires_at_utc = expires_at_naive.replace(tzinfo=timezone.utc)
189
+ now = datetime.now(timezone.utc)
190
+
191
+ if expires_at_utc <= now:
192
+ return 0
193
+
194
+ delta = expires_at_utc - now
195
+ return int(delta.total_seconds())
196
+
197
+ async def delete_expired(self) -> int:
198
+ sql = f"DELETE FROM {self._table_name} WHERE expires_at <= UTC_TIMESTAMP(6)"
199
+
200
+ async with self._config.provide_connection() as conn:
201
+ cursor = await conn.cursor()
202
+ try:
203
+ await cursor.execute(sql)
204
+ await conn.commit()
205
+ count: int = cursor.rowcount
206
+ finally:
207
+ await cursor.close()
208
+ if count > 0:
209
+ self._log_delete_expired(count)
210
+ return count
211
+
212
+
213
+ class MysqlConnectorSyncStore(BaseSQLSpecStore["MysqlConnectorSyncConfig"]):
214
+ """MySQL/MariaDB session store using mysql-connector sync driver."""
215
+
216
+ __slots__ = ()
217
+
218
+ def __init__(self, config: "MysqlConnectorSyncConfig") -> None:
219
+ super().__init__(config)
220
+
221
+ def _get_create_table_sql(self) -> str:
222
+ return f"""
223
+ CREATE TABLE IF NOT EXISTS {self._table_name} (
224
+ session_id VARCHAR(255) PRIMARY KEY,
225
+ data LONGBLOB NOT NULL,
226
+ expires_at DATETIME(6),
227
+ created_at DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6),
228
+ updated_at DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
229
+ INDEX idx_{self._table_name}_expires_at (expires_at)
230
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
231
+ """
232
+
233
+ def _get_drop_table_sql(self) -> "list[str]":
234
+ return [
235
+ f"DROP INDEX idx_{self._table_name}_expires_at ON {self._table_name}",
236
+ f"DROP TABLE IF EXISTS {self._table_name}",
237
+ ]
238
+
239
+ def _create_table(self) -> None:
240
+ sql = self._get_create_table_sql()
241
+ with self._config.provide_session() as driver:
242
+ driver.execute_script(sql)
243
+ driver.commit()
244
+ self._log_table_created()
245
+
246
+ async def create_table(self) -> None:
247
+ await async_(self._create_table)()
248
+
249
+ def _get(self, key: str, renew_for: "int | timedelta | None" = None) -> "bytes | None":
250
+ sql = f"""
251
+ SELECT data, expires_at FROM {self._table_name}
252
+ WHERE session_id = %s
253
+ AND (expires_at IS NULL OR expires_at > UTC_TIMESTAMP(6))
254
+ """
255
+
256
+ try:
257
+ with self._config.provide_connection() as conn:
258
+ cursor = conn.cursor()
259
+ try:
260
+ cursor.execute(sql, (key,))
261
+ row = cursor.fetchone()
262
+ finally:
263
+ cursor.close()
264
+
265
+ if row is None:
266
+ return None
267
+
268
+ data_value: Any = row[0]
269
+ expires_at: Any = row[1]
270
+
271
+ if renew_for is not None and expires_at is not None:
272
+ new_expires_at = self._calculate_expires_at(renew_for)
273
+ if new_expires_at is not None:
274
+ naive_expires_at = new_expires_at.replace(tzinfo=None)
275
+ update_sql = f"""
276
+ UPDATE {self._table_name}
277
+ SET expires_at = %s, updated_at = UTC_TIMESTAMP(6)
278
+ WHERE session_id = %s
279
+ """
280
+ update_cursor = conn.cursor()
281
+ try:
282
+ update_cursor.execute(update_sql, (naive_expires_at, key))
283
+ finally:
284
+ update_cursor.close()
285
+ conn.commit()
286
+
287
+ return bytes(cast("bytes", data_value))
288
+ except mysql.connector.Error as exc:
289
+ if "doesn't exist" in str(exc) or getattr(exc, "errno", None) == MYSQL_TABLE_NOT_FOUND_ERROR:
290
+ return None
291
+ raise
292
+
293
+ async def get(self, key: str, renew_for: "int | timedelta | None" = None) -> "bytes | None":
294
+ return await async_(self._get)(key, renew_for)
295
+
296
+ def _set(self, key: str, value: "str | bytes", expires_in: "int | timedelta | None" = None) -> None:
297
+ data = self._value_to_bytes(value)
298
+ expires_at = self._calculate_expires_at(expires_in)
299
+ naive_expires_at = expires_at.replace(tzinfo=None) if expires_at else None
300
+
301
+ sql = f"""
302
+ INSERT INTO {self._table_name} (session_id, data, expires_at)
303
+ VALUES (%s, %s, %s) AS new
304
+ ON DUPLICATE KEY UPDATE
305
+ data = new.data,
306
+ expires_at = new.expires_at,
307
+ updated_at = UTC_TIMESTAMP(6)
308
+ """
309
+
310
+ with self._config.provide_connection() as conn:
311
+ cursor = conn.cursor()
312
+ try:
313
+ cursor.execute(sql, (key, data, naive_expires_at))
314
+ finally:
315
+ cursor.close()
316
+ conn.commit()
317
+
318
+ async def set(self, key: str, value: "str | bytes", expires_in: "int | timedelta | None" = None) -> None:
319
+ await async_(self._set)(key, value, expires_in)
320
+
321
+ def _delete(self, key: str) -> None:
322
+ sql = f"DELETE FROM {self._table_name} WHERE session_id = %s"
323
+
324
+ with self._config.provide_connection() as conn:
325
+ cursor = conn.cursor()
326
+ try:
327
+ cursor.execute(sql, (key,))
328
+ finally:
329
+ cursor.close()
330
+ conn.commit()
331
+
332
+ async def delete(self, key: str) -> None:
333
+ await async_(self._delete)(key)
334
+
335
+ def _delete_all(self) -> None:
336
+ sql = f"DELETE FROM {self._table_name}"
337
+
338
+ try:
339
+ with self._config.provide_connection() as conn:
340
+ cursor = conn.cursor()
341
+ try:
342
+ cursor.execute(sql)
343
+ finally:
344
+ cursor.close()
345
+ conn.commit()
346
+ self._log_delete_all()
347
+ except mysql.connector.Error as exc:
348
+ if "doesn't exist" in str(exc) or getattr(exc, "errno", None) == MYSQL_TABLE_NOT_FOUND_ERROR:
349
+ logger.debug("Table %s does not exist, skipping delete_all", self._table_name)
350
+ return
351
+ raise
352
+
353
+ async def delete_all(self) -> None:
354
+ await async_(self._delete_all)()
355
+
356
+ def _exists(self, key: str) -> bool:
357
+ sql = f"""
358
+ SELECT 1 FROM {self._table_name}
359
+ WHERE session_id = %s
360
+ AND (expires_at IS NULL OR expires_at > UTC_TIMESTAMP(6))
361
+ """
362
+
363
+ try:
364
+ with self._config.provide_connection() as conn:
365
+ cursor = conn.cursor()
366
+ try:
367
+ cursor.execute(sql, (key,))
368
+ result = cursor.fetchone()
369
+ finally:
370
+ cursor.close()
371
+ return result is not None
372
+ except mysql.connector.Error as exc:
373
+ if "doesn't exist" in str(exc) or getattr(exc, "errno", None) == MYSQL_TABLE_NOT_FOUND_ERROR:
374
+ return False
375
+ raise
376
+
377
+ async def exists(self, key: str) -> bool:
378
+ return await async_(self._exists)(key)
379
+
380
+ def _expires_in(self, key: str) -> "int | None":
381
+ sql = f"""
382
+ SELECT expires_at FROM {self._table_name}
383
+ WHERE session_id = %s
384
+ """
385
+
386
+ with self._config.provide_connection() as conn:
387
+ cursor = conn.cursor()
388
+ try:
389
+ cursor.execute(sql, (key,))
390
+ row = cursor.fetchone()
391
+ finally:
392
+ cursor.close()
393
+
394
+ if row is None or row[0] is None:
395
+ return None
396
+
397
+ expires_at_naive: datetime = cast("datetime", row[0])
398
+ expires_at_utc = expires_at_naive.replace(tzinfo=timezone.utc)
399
+ now = datetime.now(timezone.utc)
400
+
401
+ if expires_at_utc <= now:
402
+ return 0
403
+
404
+ delta = expires_at_utc - now
405
+ return int(delta.total_seconds())
406
+
407
+ async def expires_in(self, key: str) -> "int | None":
408
+ return await async_(self._expires_in)(key)
409
+
410
+ def _delete_expired(self) -> int:
411
+ sql = f"DELETE FROM {self._table_name} WHERE expires_at <= UTC_TIMESTAMP(6)"
412
+
413
+ with self._config.provide_connection() as conn:
414
+ cursor = conn.cursor()
415
+ try:
416
+ cursor.execute(sql)
417
+ conn.commit()
418
+ count: int = cursor.rowcount
419
+ finally:
420
+ cursor.close()
421
+ if count > 0:
422
+ self._log_delete_expired(count)
423
+ return count
424
+
425
+ async def delete_expired(self) -> int:
426
+ return await async_(self._delete_expired)()
@@ -0,0 +1,39 @@
1
+ from sqlspec.adapters.oracledb._param_types import OracleBlob, OracleClob, OracleJson
2
+ from sqlspec.adapters.oracledb.config import (
3
+ OracleAsyncConfig,
4
+ OracleConnectionParams,
5
+ OracleDriverFeatures,
6
+ OraclePoolParams,
7
+ OracleSyncConfig,
8
+ )
9
+ from sqlspec.adapters.oracledb.core import default_statement_config
10
+ from sqlspec.adapters.oracledb.data_dictionary import (
11
+ OracledbAsyncDataDictionary,
12
+ OracledbSyncDataDictionary,
13
+ OracleVersionInfo,
14
+ )
15
+ from sqlspec.adapters.oracledb.driver import (
16
+ OracleAsyncDriver,
17
+ OracleAsyncExceptionHandler,
18
+ OracleSyncDriver,
19
+ OracleSyncExceptionHandler,
20
+ )
21
+
22
+ __all__ = (
23
+ "OracleAsyncConfig",
24
+ "OracleAsyncDriver",
25
+ "OracleAsyncExceptionHandler",
26
+ "OracleBlob",
27
+ "OracleClob",
28
+ "OracleConnectionParams",
29
+ "OracleDriverFeatures",
30
+ "OracleJson",
31
+ "OraclePoolParams",
32
+ "OracleSyncConfig",
33
+ "OracleSyncDriver",
34
+ "OracleSyncExceptionHandler",
35
+ "OracleVersionInfo",
36
+ "OracledbAsyncDataDictionary",
37
+ "OracledbSyncDataDictionary",
38
+ "default_statement_config",
39
+ )
@@ -0,0 +1,196 @@
1
+ """Oracle native JSON type handlers.
2
+
3
+ Provides automatic conversion between Python ``dict`` / ``list`` / ``tuple`` values
4
+ and Oracle's JSON storage types via connection type handlers.
5
+
6
+ Routing matrix (input):
7
+
8
+ * Oracle 21c+ native ``JSON``: bind via ``DB_TYPE_JSON`` (binary OSON).
9
+ * Oracle 19c-20c with ``BLOB CHECK (... IS JSON)``: bind via ``DB_TYPE_BLOB`` with
10
+ UTF-8 JSON bytes.
11
+ * Oracle 12c-18c with ``CLOB CHECK (... IS JSON)``: bind via ``DB_TYPE_CLOB`` with
12
+ serialized JSON string.
13
+ * Server major version is read from ``connection._sqlspec_oracle_major`` (set in
14
+ ``OracleSyncConfig._init_connection`` / ``OracleAsyncConfig._init_connection``).
15
+ When unknown, default to 21c+ behavior.
16
+
17
+ Routing matrix (output):
18
+
19
+ * ``DB_TYPE_JSON``: passthrough (python-oracledb already returns ``dict``).
20
+ * ``DB_TYPE_BLOB`` with ``JSON`` in column ``type_name``: parse via
21
+ ``json_converter_out_blob``.
22
+ * ``DB_TYPE_CLOB`` with ``JSON`` in column ``type_name``: parse via
23
+ ``json_converter_out_clob``.
24
+
25
+ Handlers chain to any pre-existing ``inputtypehandler`` / ``outputtypehandler``
26
+ registered on the connection (e.g. NumPy vector, UUID), so registration order
27
+ matters: register JSON after numpy, before UUID is also safe because each
28
+ handler returns ``None`` for values it does not own.
29
+ """
30
+
31
+ from typing import TYPE_CHECKING, Any
32
+
33
+ from sqlspec.adapters.oracledb._typing import DB_TYPE_BLOB, DB_TYPE_CLOB, DB_TYPE_JSON
34
+ from sqlspec.utils.serializers import from_json, to_json
35
+
36
+ if TYPE_CHECKING:
37
+ from oracledb import AsyncConnection, AsyncCursor, Connection, Cursor
38
+
39
+ __all__ = (
40
+ "json_converter_in_blob",
41
+ "json_converter_in_clob",
42
+ "json_converter_out_blob",
43
+ "json_converter_out_clob",
44
+ "json_input_type_handler",
45
+ "json_output_type_handler",
46
+ "register_json_handlers",
47
+ )
48
+
49
+
50
+ _JSON_TYPE_NAME_MARKER = "JSON"
51
+
52
+ # Server-version thresholds for JSON binding strategy selection.
53
+ # 21c+ supports DB_TYPE_JSON (binary OSON); 19c-20c uses BLOB CHECK (... IS JSON);
54
+ # pre-19c uses CLOB CHECK (... IS JSON).
55
+ _NATIVE_JSON_MIN_MAJOR = 21
56
+ _BLOB_IS_JSON_MIN_MAJOR = 19
57
+
58
+
59
+ def json_converter_in_clob(value: Any) -> str:
60
+ """Serialize a Python value to a JSON string for CLOB binding."""
61
+ return to_json(value)
62
+
63
+
64
+ def json_converter_in_blob(value: Any) -> bytes:
65
+ """Serialize a Python value to UTF-8 JSON bytes for BLOB binding."""
66
+ return to_json(value, as_bytes=True)
67
+
68
+
69
+ def json_converter_out_clob(value: "str | None") -> Any:
70
+ """Parse a JSON string from a CLOB read back into a Python value."""
71
+ if value is None:
72
+ return None
73
+ return from_json(value)
74
+
75
+
76
+ def json_converter_out_blob(value: "bytes | None") -> Any:
77
+ """Parse JSON bytes from a BLOB read back into a Python value."""
78
+ if value is None:
79
+ return None
80
+ return from_json(value)
81
+
82
+
83
+ def _is_json_payload(value: Any) -> bool:
84
+ """Return True if the value should be claimed by the JSON input handler.
85
+
86
+ ``dict`` and ``tuple``/``list`` of dicts are claimed. Sequences whose first
87
+ element is a number are NOT claimed — those are vector embeddings and
88
+ belong to the vector handler.
89
+ """
90
+ if isinstance(value, dict):
91
+ return True
92
+ if isinstance(value, (list, tuple)):
93
+ if not value:
94
+ # Empty sequence: ambiguous (could be empty vector or empty list).
95
+ # Defer to the next handler in the chain.
96
+ return False
97
+ first = value[0]
98
+ # Reject sequences of numbers (vector embeddings).
99
+ return not (isinstance(first, (int, float)) and not isinstance(first, bool))
100
+ return False
101
+
102
+
103
+ def _input_type_handler(cursor: "Cursor | AsyncCursor", value: Any, arraysize: int) -> Any:
104
+ """Oracle input type handler for JSON-shaped Python values."""
105
+ if not _is_json_payload(value):
106
+ return None
107
+
108
+ server_major = getattr(cursor.connection, "_sqlspec_oracle_major", None)
109
+
110
+ if server_major is None or server_major >= _NATIVE_JSON_MIN_MAJOR:
111
+ return cursor.var(DB_TYPE_JSON, arraysize=arraysize)
112
+ if server_major >= _BLOB_IS_JSON_MIN_MAJOR:
113
+ return cursor.var(DB_TYPE_BLOB, arraysize=arraysize, inconverter=json_converter_in_blob)
114
+ return cursor.var(DB_TYPE_CLOB, arraysize=arraysize, inconverter=json_converter_in_clob)
115
+
116
+
117
+ def _output_type_handler(cursor: "Cursor | AsyncCursor", metadata: Any) -> Any:
118
+ """Oracle output type handler for JSON-bearing column reads."""
119
+ type_code = getattr(metadata, "type_code", None)
120
+
121
+ if type_code is DB_TYPE_JSON:
122
+ # Native JSON: python-oracledb returns dict/list directly. No conversion.
123
+ return None
124
+
125
+ type_name = (getattr(metadata, "type_name", "") or "").upper()
126
+ if _JSON_TYPE_NAME_MARKER not in type_name:
127
+ return None
128
+
129
+ if type_code is DB_TYPE_BLOB:
130
+ return cursor.var(DB_TYPE_BLOB, arraysize=cursor.arraysize, outconverter=json_converter_out_blob)
131
+ if type_code is DB_TYPE_CLOB:
132
+ return cursor.var(DB_TYPE_CLOB, arraysize=cursor.arraysize, outconverter=json_converter_out_clob)
133
+ return None
134
+
135
+
136
+ def json_input_type_handler(cursor: "Cursor | AsyncCursor", value: Any, arraysize: int) -> Any:
137
+ """Public input type handler entry point."""
138
+ return _input_type_handler(cursor, value, arraysize)
139
+
140
+
141
+ def json_output_type_handler(cursor: "Cursor | AsyncCursor", metadata: Any) -> Any:
142
+ """Public output type handler entry point."""
143
+ return _output_type_handler(cursor, metadata)
144
+
145
+
146
+ def register_json_handlers(connection: "Connection | AsyncConnection") -> None:
147
+ """Register JSON type handlers on an Oracle connection.
148
+
149
+ Chains to any existing handlers via ``_JsonInputHandler`` / ``_JsonOutputHandler``
150
+ wrapper classes so vector / UUID handlers continue to fire for non-JSON values.
151
+ """
152
+ try:
153
+ existing_input = connection.inputtypehandler
154
+ except AttributeError:
155
+ existing_input = None
156
+ try:
157
+ existing_output = connection.outputtypehandler
158
+ except AttributeError:
159
+ existing_output = None
160
+
161
+ connection.inputtypehandler = _JsonInputHandler(existing_input)
162
+ connection.outputtypehandler = _JsonOutputHandler(existing_output)
163
+
164
+
165
+ class _JsonInputHandler:
166
+ """Chaining wrapper that claims dict/list/tuple values, falling back otherwise."""
167
+
168
+ __slots__ = ("_fallback",)
169
+
170
+ def __init__(self, fallback: "Any | None") -> None:
171
+ self._fallback = fallback
172
+
173
+ def __call__(self, cursor: "Cursor | AsyncCursor", value: Any, arraysize: int) -> Any:
174
+ result = _input_type_handler(cursor, value, arraysize)
175
+ if result is not None:
176
+ return result
177
+ if self._fallback is not None:
178
+ return self._fallback(cursor, value, arraysize)
179
+ return None
180
+
181
+
182
+ class _JsonOutputHandler:
183
+ """Chaining wrapper that claims JSON-bearing columns, falling back otherwise."""
184
+
185
+ __slots__ = ("_fallback",)
186
+
187
+ def __init__(self, fallback: "Any | None") -> None:
188
+ self._fallback = fallback
189
+
190
+ def __call__(self, cursor: "Cursor | AsyncCursor", metadata: Any) -> Any:
191
+ result = _output_type_handler(cursor, metadata)
192
+ if result is not None:
193
+ return result
194
+ if self._fallback is not None:
195
+ return self._fallback(cursor, metadata)
196
+ return None