sqlspec 0.36.0__cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (531) hide show
  1. ac8f31065839703b4e70__mypyc.cpython-310-aarch64-linux-gnu.so +0 -0
  2. sqlspec/__init__.py +140 -0
  3. sqlspec/__main__.py +12 -0
  4. sqlspec/__metadata__.py +14 -0
  5. sqlspec/_serialization.py +315 -0
  6. sqlspec/_typing.py +700 -0
  7. sqlspec/adapters/__init__.py +0 -0
  8. sqlspec/adapters/adbc/__init__.py +5 -0
  9. sqlspec/adapters/adbc/_typing.py +82 -0
  10. sqlspec/adapters/adbc/adk/__init__.py +5 -0
  11. sqlspec/adapters/adbc/adk/store.py +1273 -0
  12. sqlspec/adapters/adbc/config.py +295 -0
  13. sqlspec/adapters/adbc/core.cpython-310-aarch64-linux-gnu.so +0 -0
  14. sqlspec/adapters/adbc/core.py +735 -0
  15. sqlspec/adapters/adbc/data_dictionary.py +334 -0
  16. sqlspec/adapters/adbc/driver.py +529 -0
  17. sqlspec/adapters/adbc/events/__init__.py +5 -0
  18. sqlspec/adapters/adbc/events/store.py +285 -0
  19. sqlspec/adapters/adbc/litestar/__init__.py +5 -0
  20. sqlspec/adapters/adbc/litestar/store.py +502 -0
  21. sqlspec/adapters/adbc/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
  22. sqlspec/adapters/adbc/type_converter.py +140 -0
  23. sqlspec/adapters/aiosqlite/__init__.py +25 -0
  24. sqlspec/adapters/aiosqlite/_typing.py +82 -0
  25. sqlspec/adapters/aiosqlite/adk/__init__.py +5 -0
  26. sqlspec/adapters/aiosqlite/adk/store.py +818 -0
  27. sqlspec/adapters/aiosqlite/config.py +334 -0
  28. sqlspec/adapters/aiosqlite/core.cpython-310-aarch64-linux-gnu.so +0 -0
  29. sqlspec/adapters/aiosqlite/core.py +315 -0
  30. sqlspec/adapters/aiosqlite/data_dictionary.py +208 -0
  31. sqlspec/adapters/aiosqlite/driver.py +313 -0
  32. sqlspec/adapters/aiosqlite/events/__init__.py +5 -0
  33. sqlspec/adapters/aiosqlite/events/store.py +20 -0
  34. sqlspec/adapters/aiosqlite/litestar/__init__.py +5 -0
  35. sqlspec/adapters/aiosqlite/litestar/store.py +279 -0
  36. sqlspec/adapters/aiosqlite/pool.py +533 -0
  37. sqlspec/adapters/asyncmy/__init__.py +21 -0
  38. sqlspec/adapters/asyncmy/_typing.py +87 -0
  39. sqlspec/adapters/asyncmy/adk/__init__.py +5 -0
  40. sqlspec/adapters/asyncmy/adk/store.py +703 -0
  41. sqlspec/adapters/asyncmy/config.py +302 -0
  42. sqlspec/adapters/asyncmy/core.cpython-310-aarch64-linux-gnu.so +0 -0
  43. sqlspec/adapters/asyncmy/core.py +360 -0
  44. sqlspec/adapters/asyncmy/data_dictionary.py +124 -0
  45. sqlspec/adapters/asyncmy/driver.py +383 -0
  46. sqlspec/adapters/asyncmy/events/__init__.py +5 -0
  47. sqlspec/adapters/asyncmy/events/store.py +104 -0
  48. sqlspec/adapters/asyncmy/litestar/__init__.py +5 -0
  49. sqlspec/adapters/asyncmy/litestar/store.py +296 -0
  50. sqlspec/adapters/asyncpg/__init__.py +19 -0
  51. sqlspec/adapters/asyncpg/_typing.py +88 -0
  52. sqlspec/adapters/asyncpg/adk/__init__.py +5 -0
  53. sqlspec/adapters/asyncpg/adk/store.py +748 -0
  54. sqlspec/adapters/asyncpg/config.py +569 -0
  55. sqlspec/adapters/asyncpg/core.cpython-310-aarch64-linux-gnu.so +0 -0
  56. sqlspec/adapters/asyncpg/core.py +367 -0
  57. sqlspec/adapters/asyncpg/data_dictionary.py +162 -0
  58. sqlspec/adapters/asyncpg/driver.py +487 -0
  59. sqlspec/adapters/asyncpg/events/__init__.py +6 -0
  60. sqlspec/adapters/asyncpg/events/backend.py +286 -0
  61. sqlspec/adapters/asyncpg/events/store.py +40 -0
  62. sqlspec/adapters/asyncpg/litestar/__init__.py +5 -0
  63. sqlspec/adapters/asyncpg/litestar/store.py +251 -0
  64. sqlspec/adapters/bigquery/__init__.py +14 -0
  65. sqlspec/adapters/bigquery/_typing.py +86 -0
  66. sqlspec/adapters/bigquery/adk/__init__.py +5 -0
  67. sqlspec/adapters/bigquery/adk/store.py +827 -0
  68. sqlspec/adapters/bigquery/config.py +353 -0
  69. sqlspec/adapters/bigquery/core.cpython-310-aarch64-linux-gnu.so +0 -0
  70. sqlspec/adapters/bigquery/core.py +715 -0
  71. sqlspec/adapters/bigquery/data_dictionary.py +128 -0
  72. sqlspec/adapters/bigquery/driver.py +548 -0
  73. sqlspec/adapters/bigquery/events/__init__.py +5 -0
  74. sqlspec/adapters/bigquery/events/store.py +139 -0
  75. sqlspec/adapters/bigquery/litestar/__init__.py +5 -0
  76. sqlspec/adapters/bigquery/litestar/store.py +325 -0
  77. sqlspec/adapters/bigquery/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
  78. sqlspec/adapters/bigquery/type_converter.py +107 -0
  79. sqlspec/adapters/cockroach_asyncpg/__init__.py +24 -0
  80. sqlspec/adapters/cockroach_asyncpg/_typing.py +72 -0
  81. sqlspec/adapters/cockroach_asyncpg/adk/__init__.py +3 -0
  82. sqlspec/adapters/cockroach_asyncpg/adk/store.py +410 -0
  83. sqlspec/adapters/cockroach_asyncpg/config.py +238 -0
  84. sqlspec/adapters/cockroach_asyncpg/core.cpython-310-aarch64-linux-gnu.so +0 -0
  85. sqlspec/adapters/cockroach_asyncpg/core.py +55 -0
  86. sqlspec/adapters/cockroach_asyncpg/data_dictionary.py +107 -0
  87. sqlspec/adapters/cockroach_asyncpg/driver.py +144 -0
  88. sqlspec/adapters/cockroach_asyncpg/events/__init__.py +3 -0
  89. sqlspec/adapters/cockroach_asyncpg/events/store.py +20 -0
  90. sqlspec/adapters/cockroach_asyncpg/litestar/__init__.py +3 -0
  91. sqlspec/adapters/cockroach_asyncpg/litestar/store.py +142 -0
  92. sqlspec/adapters/cockroach_psycopg/__init__.py +38 -0
  93. sqlspec/adapters/cockroach_psycopg/_typing.py +129 -0
  94. sqlspec/adapters/cockroach_psycopg/adk/__init__.py +13 -0
  95. sqlspec/adapters/cockroach_psycopg/adk/store.py +868 -0
  96. sqlspec/adapters/cockroach_psycopg/config.py +484 -0
  97. sqlspec/adapters/cockroach_psycopg/core.cpython-310-aarch64-linux-gnu.so +0 -0
  98. sqlspec/adapters/cockroach_psycopg/core.py +63 -0
  99. sqlspec/adapters/cockroach_psycopg/data_dictionary.py +215 -0
  100. sqlspec/adapters/cockroach_psycopg/driver.py +284 -0
  101. sqlspec/adapters/cockroach_psycopg/events/__init__.py +6 -0
  102. sqlspec/adapters/cockroach_psycopg/events/store.py +34 -0
  103. sqlspec/adapters/cockroach_psycopg/litestar/__init__.py +3 -0
  104. sqlspec/adapters/cockroach_psycopg/litestar/store.py +325 -0
  105. sqlspec/adapters/duckdb/__init__.py +25 -0
  106. sqlspec/adapters/duckdb/_typing.py +81 -0
  107. sqlspec/adapters/duckdb/adk/__init__.py +14 -0
  108. sqlspec/adapters/duckdb/adk/store.py +850 -0
  109. sqlspec/adapters/duckdb/config.py +463 -0
  110. sqlspec/adapters/duckdb/core.cpython-310-aarch64-linux-gnu.so +0 -0
  111. sqlspec/adapters/duckdb/core.py +257 -0
  112. sqlspec/adapters/duckdb/data_dictionary.py +140 -0
  113. sqlspec/adapters/duckdb/driver.py +430 -0
  114. sqlspec/adapters/duckdb/events/__init__.py +5 -0
  115. sqlspec/adapters/duckdb/events/store.py +57 -0
  116. sqlspec/adapters/duckdb/litestar/__init__.py +5 -0
  117. sqlspec/adapters/duckdb/litestar/store.py +330 -0
  118. sqlspec/adapters/duckdb/pool.py +293 -0
  119. sqlspec/adapters/duckdb/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
  120. sqlspec/adapters/duckdb/type_converter.py +118 -0
  121. sqlspec/adapters/mock/__init__.py +72 -0
  122. sqlspec/adapters/mock/_typing.py +147 -0
  123. sqlspec/adapters/mock/config.py +483 -0
  124. sqlspec/adapters/mock/core.py +319 -0
  125. sqlspec/adapters/mock/data_dictionary.py +366 -0
  126. sqlspec/adapters/mock/driver.py +721 -0
  127. sqlspec/adapters/mysqlconnector/__init__.py +36 -0
  128. sqlspec/adapters/mysqlconnector/_typing.py +141 -0
  129. sqlspec/adapters/mysqlconnector/adk/__init__.py +15 -0
  130. sqlspec/adapters/mysqlconnector/adk/store.py +1060 -0
  131. sqlspec/adapters/mysqlconnector/config.py +394 -0
  132. sqlspec/adapters/mysqlconnector/core.cpython-310-aarch64-linux-gnu.so +0 -0
  133. sqlspec/adapters/mysqlconnector/core.py +303 -0
  134. sqlspec/adapters/mysqlconnector/data_dictionary.py +235 -0
  135. sqlspec/adapters/mysqlconnector/driver.py +483 -0
  136. sqlspec/adapters/mysqlconnector/events/__init__.py +8 -0
  137. sqlspec/adapters/mysqlconnector/events/store.py +98 -0
  138. sqlspec/adapters/mysqlconnector/litestar/__init__.py +5 -0
  139. sqlspec/adapters/mysqlconnector/litestar/store.py +426 -0
  140. sqlspec/adapters/oracledb/__init__.py +60 -0
  141. sqlspec/adapters/oracledb/_numpy_handlers.py +141 -0
  142. sqlspec/adapters/oracledb/_typing.py +182 -0
  143. sqlspec/adapters/oracledb/_uuid_handlers.py +166 -0
  144. sqlspec/adapters/oracledb/adk/__init__.py +10 -0
  145. sqlspec/adapters/oracledb/adk/store.py +2369 -0
  146. sqlspec/adapters/oracledb/config.py +550 -0
  147. sqlspec/adapters/oracledb/core.cpython-310-aarch64-linux-gnu.so +0 -0
  148. sqlspec/adapters/oracledb/core.py +543 -0
  149. sqlspec/adapters/oracledb/data_dictionary.py +536 -0
  150. sqlspec/adapters/oracledb/driver.py +1229 -0
  151. sqlspec/adapters/oracledb/events/__init__.py +16 -0
  152. sqlspec/adapters/oracledb/events/backend.py +347 -0
  153. sqlspec/adapters/oracledb/events/store.py +420 -0
  154. sqlspec/adapters/oracledb/litestar/__init__.py +5 -0
  155. sqlspec/adapters/oracledb/litestar/store.py +781 -0
  156. sqlspec/adapters/oracledb/migrations.py +535 -0
  157. sqlspec/adapters/oracledb/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
  158. sqlspec/adapters/oracledb/type_converter.py +211 -0
  159. sqlspec/adapters/psqlpy/__init__.py +17 -0
  160. sqlspec/adapters/psqlpy/_typing.py +79 -0
  161. sqlspec/adapters/psqlpy/adk/__init__.py +5 -0
  162. sqlspec/adapters/psqlpy/adk/store.py +766 -0
  163. sqlspec/adapters/psqlpy/config.py +304 -0
  164. sqlspec/adapters/psqlpy/core.cpython-310-aarch64-linux-gnu.so +0 -0
  165. sqlspec/adapters/psqlpy/core.py +480 -0
  166. sqlspec/adapters/psqlpy/data_dictionary.py +126 -0
  167. sqlspec/adapters/psqlpy/driver.py +438 -0
  168. sqlspec/adapters/psqlpy/events/__init__.py +6 -0
  169. sqlspec/adapters/psqlpy/events/backend.py +310 -0
  170. sqlspec/adapters/psqlpy/events/store.py +20 -0
  171. sqlspec/adapters/psqlpy/litestar/__init__.py +5 -0
  172. sqlspec/adapters/psqlpy/litestar/store.py +270 -0
  173. sqlspec/adapters/psqlpy/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
  174. sqlspec/adapters/psqlpy/type_converter.py +113 -0
  175. sqlspec/adapters/psycopg/__init__.py +32 -0
  176. sqlspec/adapters/psycopg/_typing.py +164 -0
  177. sqlspec/adapters/psycopg/adk/__init__.py +10 -0
  178. sqlspec/adapters/psycopg/adk/store.py +1387 -0
  179. sqlspec/adapters/psycopg/config.py +576 -0
  180. sqlspec/adapters/psycopg/core.cpython-310-aarch64-linux-gnu.so +0 -0
  181. sqlspec/adapters/psycopg/core.py +450 -0
  182. sqlspec/adapters/psycopg/data_dictionary.py +289 -0
  183. sqlspec/adapters/psycopg/driver.py +975 -0
  184. sqlspec/adapters/psycopg/events/__init__.py +20 -0
  185. sqlspec/adapters/psycopg/events/backend.py +458 -0
  186. sqlspec/adapters/psycopg/events/store.py +42 -0
  187. sqlspec/adapters/psycopg/litestar/__init__.py +5 -0
  188. sqlspec/adapters/psycopg/litestar/store.py +552 -0
  189. sqlspec/adapters/psycopg/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
  190. sqlspec/adapters/psycopg/type_converter.py +93 -0
  191. sqlspec/adapters/pymysql/__init__.py +21 -0
  192. sqlspec/adapters/pymysql/_typing.py +71 -0
  193. sqlspec/adapters/pymysql/adk/__init__.py +5 -0
  194. sqlspec/adapters/pymysql/adk/store.py +540 -0
  195. sqlspec/adapters/pymysql/config.py +195 -0
  196. sqlspec/adapters/pymysql/core.cpython-310-aarch64-linux-gnu.so +0 -0
  197. sqlspec/adapters/pymysql/core.py +299 -0
  198. sqlspec/adapters/pymysql/data_dictionary.py +122 -0
  199. sqlspec/adapters/pymysql/driver.py +259 -0
  200. sqlspec/adapters/pymysql/events/__init__.py +5 -0
  201. sqlspec/adapters/pymysql/events/store.py +50 -0
  202. sqlspec/adapters/pymysql/litestar/__init__.py +5 -0
  203. sqlspec/adapters/pymysql/litestar/store.py +232 -0
  204. sqlspec/adapters/pymysql/pool.py +137 -0
  205. sqlspec/adapters/spanner/__init__.py +40 -0
  206. sqlspec/adapters/spanner/_typing.py +86 -0
  207. sqlspec/adapters/spanner/adk/__init__.py +5 -0
  208. sqlspec/adapters/spanner/adk/store.py +732 -0
  209. sqlspec/adapters/spanner/config.py +352 -0
  210. sqlspec/adapters/spanner/core.cpython-310-aarch64-linux-gnu.so +0 -0
  211. sqlspec/adapters/spanner/core.py +188 -0
  212. sqlspec/adapters/spanner/data_dictionary.py +120 -0
  213. sqlspec/adapters/spanner/dialect/__init__.py +6 -0
  214. sqlspec/adapters/spanner/dialect/_spangres.py +57 -0
  215. sqlspec/adapters/spanner/dialect/_spanner.py +130 -0
  216. sqlspec/adapters/spanner/driver.py +373 -0
  217. sqlspec/adapters/spanner/events/__init__.py +5 -0
  218. sqlspec/adapters/spanner/events/store.py +187 -0
  219. sqlspec/adapters/spanner/litestar/__init__.py +5 -0
  220. sqlspec/adapters/spanner/litestar/store.py +291 -0
  221. sqlspec/adapters/spanner/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
  222. sqlspec/adapters/spanner/type_converter.py +331 -0
  223. sqlspec/adapters/sqlite/__init__.py +19 -0
  224. sqlspec/adapters/sqlite/_typing.py +80 -0
  225. sqlspec/adapters/sqlite/adk/__init__.py +5 -0
  226. sqlspec/adapters/sqlite/adk/store.py +958 -0
  227. sqlspec/adapters/sqlite/config.py +280 -0
  228. sqlspec/adapters/sqlite/core.cpython-310-aarch64-linux-gnu.so +0 -0
  229. sqlspec/adapters/sqlite/core.py +312 -0
  230. sqlspec/adapters/sqlite/data_dictionary.py +202 -0
  231. sqlspec/adapters/sqlite/driver.py +359 -0
  232. sqlspec/adapters/sqlite/events/__init__.py +5 -0
  233. sqlspec/adapters/sqlite/events/store.py +20 -0
  234. sqlspec/adapters/sqlite/litestar/__init__.py +5 -0
  235. sqlspec/adapters/sqlite/litestar/store.py +316 -0
  236. sqlspec/adapters/sqlite/pool.py +198 -0
  237. sqlspec/adapters/sqlite/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
  238. sqlspec/adapters/sqlite/type_converter.py +114 -0
  239. sqlspec/base.py +747 -0
  240. sqlspec/builder/__init__.py +179 -0
  241. sqlspec/builder/_base.cpython-310-aarch64-linux-gnu.so +0 -0
  242. sqlspec/builder/_base.py +1022 -0
  243. sqlspec/builder/_column.cpython-310-aarch64-linux-gnu.so +0 -0
  244. sqlspec/builder/_column.py +521 -0
  245. sqlspec/builder/_ddl.cpython-310-aarch64-linux-gnu.so +0 -0
  246. sqlspec/builder/_ddl.py +1642 -0
  247. sqlspec/builder/_delete.cpython-310-aarch64-linux-gnu.so +0 -0
  248. sqlspec/builder/_delete.py +95 -0
  249. sqlspec/builder/_dml.cpython-310-aarch64-linux-gnu.so +0 -0
  250. sqlspec/builder/_dml.py +365 -0
  251. sqlspec/builder/_explain.cpython-310-aarch64-linux-gnu.so +0 -0
  252. sqlspec/builder/_explain.py +579 -0
  253. sqlspec/builder/_expression_wrappers.cpython-310-aarch64-linux-gnu.so +0 -0
  254. sqlspec/builder/_expression_wrappers.py +46 -0
  255. sqlspec/builder/_factory.cpython-310-aarch64-linux-gnu.so +0 -0
  256. sqlspec/builder/_factory.py +1697 -0
  257. sqlspec/builder/_insert.cpython-310-aarch64-linux-gnu.so +0 -0
  258. sqlspec/builder/_insert.py +328 -0
  259. sqlspec/builder/_join.cpython-310-aarch64-linux-gnu.so +0 -0
  260. sqlspec/builder/_join.py +499 -0
  261. sqlspec/builder/_merge.cpython-310-aarch64-linux-gnu.so +0 -0
  262. sqlspec/builder/_merge.py +821 -0
  263. sqlspec/builder/_parsing_utils.cpython-310-aarch64-linux-gnu.so +0 -0
  264. sqlspec/builder/_parsing_utils.py +297 -0
  265. sqlspec/builder/_select.cpython-310-aarch64-linux-gnu.so +0 -0
  266. sqlspec/builder/_select.py +1660 -0
  267. sqlspec/builder/_temporal.cpython-310-aarch64-linux-gnu.so +0 -0
  268. sqlspec/builder/_temporal.py +139 -0
  269. sqlspec/builder/_update.cpython-310-aarch64-linux-gnu.so +0 -0
  270. sqlspec/builder/_update.py +173 -0
  271. sqlspec/builder/_vector_expressions.py +267 -0
  272. sqlspec/cli.py +911 -0
  273. sqlspec/config.py +1755 -0
  274. sqlspec/core/__init__.py +374 -0
  275. sqlspec/core/_correlation.cpython-310-aarch64-linux-gnu.so +0 -0
  276. sqlspec/core/_correlation.py +176 -0
  277. sqlspec/core/cache.cpython-310-aarch64-linux-gnu.so +0 -0
  278. sqlspec/core/cache.py +1069 -0
  279. sqlspec/core/compiler.cpython-310-aarch64-linux-gnu.so +0 -0
  280. sqlspec/core/compiler.py +954 -0
  281. sqlspec/core/explain.cpython-310-aarch64-linux-gnu.so +0 -0
  282. sqlspec/core/explain.py +275 -0
  283. sqlspec/core/filters.cpython-310-aarch64-linux-gnu.so +0 -0
  284. sqlspec/core/filters.py +952 -0
  285. sqlspec/core/hashing.cpython-310-aarch64-linux-gnu.so +0 -0
  286. sqlspec/core/hashing.py +262 -0
  287. sqlspec/core/metrics.cpython-310-aarch64-linux-gnu.so +0 -0
  288. sqlspec/core/metrics.py +83 -0
  289. sqlspec/core/parameters/__init__.py +71 -0
  290. sqlspec/core/parameters/_alignment.cpython-310-aarch64-linux-gnu.so +0 -0
  291. sqlspec/core/parameters/_alignment.py +270 -0
  292. sqlspec/core/parameters/_converter.cpython-310-aarch64-linux-gnu.so +0 -0
  293. sqlspec/core/parameters/_converter.py +543 -0
  294. sqlspec/core/parameters/_processor.cpython-310-aarch64-linux-gnu.so +0 -0
  295. sqlspec/core/parameters/_processor.py +505 -0
  296. sqlspec/core/parameters/_registry.cpython-310-aarch64-linux-gnu.so +0 -0
  297. sqlspec/core/parameters/_registry.py +206 -0
  298. sqlspec/core/parameters/_transformers.cpython-310-aarch64-linux-gnu.so +0 -0
  299. sqlspec/core/parameters/_transformers.py +292 -0
  300. sqlspec/core/parameters/_types.cpython-310-aarch64-linux-gnu.so +0 -0
  301. sqlspec/core/parameters/_types.py +499 -0
  302. sqlspec/core/parameters/_validator.cpython-310-aarch64-linux-gnu.so +0 -0
  303. sqlspec/core/parameters/_validator.py +180 -0
  304. sqlspec/core/pipeline.cpython-310-aarch64-linux-gnu.so +0 -0
  305. sqlspec/core/pipeline.py +319 -0
  306. sqlspec/core/query_modifiers.cpython-310-aarch64-linux-gnu.so +0 -0
  307. sqlspec/core/query_modifiers.py +437 -0
  308. sqlspec/core/result/__init__.py +23 -0
  309. sqlspec/core/result/_base.cpython-310-aarch64-linux-gnu.so +0 -0
  310. sqlspec/core/result/_base.py +1121 -0
  311. sqlspec/core/result/_io.cpython-310-aarch64-linux-gnu.so +0 -0
  312. sqlspec/core/result/_io.py +28 -0
  313. sqlspec/core/splitter.cpython-310-aarch64-linux-gnu.so +0 -0
  314. sqlspec/core/splitter.py +966 -0
  315. sqlspec/core/stack.cpython-310-aarch64-linux-gnu.so +0 -0
  316. sqlspec/core/stack.py +163 -0
  317. sqlspec/core/statement.cpython-310-aarch64-linux-gnu.so +0 -0
  318. sqlspec/core/statement.py +1503 -0
  319. sqlspec/core/type_converter.cpython-310-aarch64-linux-gnu.so +0 -0
  320. sqlspec/core/type_converter.py +339 -0
  321. sqlspec/data_dictionary/__init__.py +22 -0
  322. sqlspec/data_dictionary/_loader.py +123 -0
  323. sqlspec/data_dictionary/_registry.cpython-310-aarch64-linux-gnu.so +0 -0
  324. sqlspec/data_dictionary/_registry.py +74 -0
  325. sqlspec/data_dictionary/_types.cpython-310-aarch64-linux-gnu.so +0 -0
  326. sqlspec/data_dictionary/_types.py +121 -0
  327. sqlspec/data_dictionary/dialects/__init__.py +21 -0
  328. sqlspec/data_dictionary/dialects/bigquery.cpython-310-aarch64-linux-gnu.so +0 -0
  329. sqlspec/data_dictionary/dialects/bigquery.py +49 -0
  330. sqlspec/data_dictionary/dialects/cockroachdb.cpython-310-aarch64-linux-gnu.so +0 -0
  331. sqlspec/data_dictionary/dialects/cockroachdb.py +43 -0
  332. sqlspec/data_dictionary/dialects/duckdb.cpython-310-aarch64-linux-gnu.so +0 -0
  333. sqlspec/data_dictionary/dialects/duckdb.py +47 -0
  334. sqlspec/data_dictionary/dialects/mysql.cpython-310-aarch64-linux-gnu.so +0 -0
  335. sqlspec/data_dictionary/dialects/mysql.py +42 -0
  336. sqlspec/data_dictionary/dialects/oracle.cpython-310-aarch64-linux-gnu.so +0 -0
  337. sqlspec/data_dictionary/dialects/oracle.py +34 -0
  338. sqlspec/data_dictionary/dialects/postgres.cpython-310-aarch64-linux-gnu.so +0 -0
  339. sqlspec/data_dictionary/dialects/postgres.py +46 -0
  340. sqlspec/data_dictionary/dialects/spanner.cpython-310-aarch64-linux-gnu.so +0 -0
  341. sqlspec/data_dictionary/dialects/spanner.py +37 -0
  342. sqlspec/data_dictionary/dialects/sqlite.cpython-310-aarch64-linux-gnu.so +0 -0
  343. sqlspec/data_dictionary/dialects/sqlite.py +42 -0
  344. sqlspec/data_dictionary/sql/.gitkeep +0 -0
  345. sqlspec/data_dictionary/sql/bigquery/columns.sql +23 -0
  346. sqlspec/data_dictionary/sql/bigquery/foreign_keys.sql +34 -0
  347. sqlspec/data_dictionary/sql/bigquery/indexes.sql +19 -0
  348. sqlspec/data_dictionary/sql/bigquery/tables.sql +33 -0
  349. sqlspec/data_dictionary/sql/bigquery/version.sql +3 -0
  350. sqlspec/data_dictionary/sql/cockroachdb/columns.sql +34 -0
  351. sqlspec/data_dictionary/sql/cockroachdb/foreign_keys.sql +40 -0
  352. sqlspec/data_dictionary/sql/cockroachdb/indexes.sql +32 -0
  353. sqlspec/data_dictionary/sql/cockroachdb/tables.sql +44 -0
  354. sqlspec/data_dictionary/sql/cockroachdb/version.sql +3 -0
  355. sqlspec/data_dictionary/sql/duckdb/columns.sql +23 -0
  356. sqlspec/data_dictionary/sql/duckdb/foreign_keys.sql +36 -0
  357. sqlspec/data_dictionary/sql/duckdb/indexes.sql +19 -0
  358. sqlspec/data_dictionary/sql/duckdb/tables.sql +38 -0
  359. sqlspec/data_dictionary/sql/duckdb/version.sql +3 -0
  360. sqlspec/data_dictionary/sql/mysql/columns.sql +23 -0
  361. sqlspec/data_dictionary/sql/mysql/foreign_keys.sql +28 -0
  362. sqlspec/data_dictionary/sql/mysql/indexes.sql +26 -0
  363. sqlspec/data_dictionary/sql/mysql/tables.sql +33 -0
  364. sqlspec/data_dictionary/sql/mysql/version.sql +3 -0
  365. sqlspec/data_dictionary/sql/oracle/columns.sql +23 -0
  366. sqlspec/data_dictionary/sql/oracle/foreign_keys.sql +48 -0
  367. sqlspec/data_dictionary/sql/oracle/indexes.sql +44 -0
  368. sqlspec/data_dictionary/sql/oracle/tables.sql +25 -0
  369. sqlspec/data_dictionary/sql/oracle/version.sql +20 -0
  370. sqlspec/data_dictionary/sql/postgres/columns.sql +34 -0
  371. sqlspec/data_dictionary/sql/postgres/foreign_keys.sql +40 -0
  372. sqlspec/data_dictionary/sql/postgres/indexes.sql +56 -0
  373. sqlspec/data_dictionary/sql/postgres/tables.sql +44 -0
  374. sqlspec/data_dictionary/sql/postgres/version.sql +3 -0
  375. sqlspec/data_dictionary/sql/spanner/columns.sql +23 -0
  376. sqlspec/data_dictionary/sql/spanner/foreign_keys.sql +70 -0
  377. sqlspec/data_dictionary/sql/spanner/indexes.sql +30 -0
  378. sqlspec/data_dictionary/sql/spanner/tables.sql +9 -0
  379. sqlspec/data_dictionary/sql/spanner/version.sql +3 -0
  380. sqlspec/data_dictionary/sql/sqlite/columns.sql +23 -0
  381. sqlspec/data_dictionary/sql/sqlite/foreign_keys.sql +22 -0
  382. sqlspec/data_dictionary/sql/sqlite/indexes.sql +7 -0
  383. sqlspec/data_dictionary/sql/sqlite/tables.sql +28 -0
  384. sqlspec/data_dictionary/sql/sqlite/version.sql +3 -0
  385. sqlspec/driver/__init__.py +32 -0
  386. sqlspec/driver/_async.cpython-310-aarch64-linux-gnu.so +0 -0
  387. sqlspec/driver/_async.py +1737 -0
  388. sqlspec/driver/_common.cpython-310-aarch64-linux-gnu.so +0 -0
  389. sqlspec/driver/_common.py +1478 -0
  390. sqlspec/driver/_sql_helpers.cpython-310-aarch64-linux-gnu.so +0 -0
  391. sqlspec/driver/_sql_helpers.py +148 -0
  392. sqlspec/driver/_storage_helpers.cpython-310-aarch64-linux-gnu.so +0 -0
  393. sqlspec/driver/_storage_helpers.py +144 -0
  394. sqlspec/driver/_sync.cpython-310-aarch64-linux-gnu.so +0 -0
  395. sqlspec/driver/_sync.py +1710 -0
  396. sqlspec/exceptions.py +338 -0
  397. sqlspec/extensions/__init__.py +0 -0
  398. sqlspec/extensions/adk/__init__.py +70 -0
  399. sqlspec/extensions/adk/_types.py +51 -0
  400. sqlspec/extensions/adk/converters.py +172 -0
  401. sqlspec/extensions/adk/memory/__init__.py +69 -0
  402. sqlspec/extensions/adk/memory/_types.py +30 -0
  403. sqlspec/extensions/adk/memory/converters.py +149 -0
  404. sqlspec/extensions/adk/memory/service.py +217 -0
  405. sqlspec/extensions/adk/memory/store.py +569 -0
  406. sqlspec/extensions/adk/migrations/0001_create_adk_tables.py +246 -0
  407. sqlspec/extensions/adk/migrations/__init__.py +0 -0
  408. sqlspec/extensions/adk/service.py +225 -0
  409. sqlspec/extensions/adk/store.py +567 -0
  410. sqlspec/extensions/events/__init__.py +51 -0
  411. sqlspec/extensions/events/_channel.py +703 -0
  412. sqlspec/extensions/events/_hints.py +45 -0
  413. sqlspec/extensions/events/_models.py +23 -0
  414. sqlspec/extensions/events/_payload.py +69 -0
  415. sqlspec/extensions/events/_protocols.py +134 -0
  416. sqlspec/extensions/events/_queue.py +461 -0
  417. sqlspec/extensions/events/_store.py +209 -0
  418. sqlspec/extensions/events/migrations/0001_create_event_queue.py +59 -0
  419. sqlspec/extensions/events/migrations/__init__.py +3 -0
  420. sqlspec/extensions/fastapi/__init__.py +19 -0
  421. sqlspec/extensions/fastapi/extension.py +351 -0
  422. sqlspec/extensions/fastapi/providers.py +607 -0
  423. sqlspec/extensions/flask/__init__.py +37 -0
  424. sqlspec/extensions/flask/_state.py +76 -0
  425. sqlspec/extensions/flask/_utils.py +71 -0
  426. sqlspec/extensions/flask/extension.py +519 -0
  427. sqlspec/extensions/litestar/__init__.py +28 -0
  428. sqlspec/extensions/litestar/_utils.py +52 -0
  429. sqlspec/extensions/litestar/channels.py +165 -0
  430. sqlspec/extensions/litestar/cli.py +102 -0
  431. sqlspec/extensions/litestar/config.py +90 -0
  432. sqlspec/extensions/litestar/handlers.py +316 -0
  433. sqlspec/extensions/litestar/migrations/0001_create_session_table.py +137 -0
  434. sqlspec/extensions/litestar/migrations/__init__.py +3 -0
  435. sqlspec/extensions/litestar/plugin.py +671 -0
  436. sqlspec/extensions/litestar/providers.py +526 -0
  437. sqlspec/extensions/litestar/store.py +296 -0
  438. sqlspec/extensions/otel/__init__.py +58 -0
  439. sqlspec/extensions/prometheus/__init__.py +113 -0
  440. sqlspec/extensions/starlette/__init__.py +19 -0
  441. sqlspec/extensions/starlette/_state.py +30 -0
  442. sqlspec/extensions/starlette/_utils.py +96 -0
  443. sqlspec/extensions/starlette/extension.py +346 -0
  444. sqlspec/extensions/starlette/middleware.py +235 -0
  445. sqlspec/loader.cpython-310-aarch64-linux-gnu.so +0 -0
  446. sqlspec/loader.py +702 -0
  447. sqlspec/migrations/__init__.py +36 -0
  448. sqlspec/migrations/base.py +731 -0
  449. sqlspec/migrations/commands.py +1232 -0
  450. sqlspec/migrations/context.py +157 -0
  451. sqlspec/migrations/fix.py +204 -0
  452. sqlspec/migrations/loaders.py +443 -0
  453. sqlspec/migrations/runner.py +1172 -0
  454. sqlspec/migrations/templates.py +234 -0
  455. sqlspec/migrations/tracker.py +611 -0
  456. sqlspec/migrations/utils.py +256 -0
  457. sqlspec/migrations/validation.py +207 -0
  458. sqlspec/migrations/version.py +446 -0
  459. sqlspec/observability/__init__.py +55 -0
  460. sqlspec/observability/_common.cpython-310-aarch64-linux-gnu.so +0 -0
  461. sqlspec/observability/_common.py +77 -0
  462. sqlspec/observability/_config.cpython-310-aarch64-linux-gnu.so +0 -0
  463. sqlspec/observability/_config.py +348 -0
  464. sqlspec/observability/_diagnostics.cpython-310-aarch64-linux-gnu.so +0 -0
  465. sqlspec/observability/_diagnostics.py +74 -0
  466. sqlspec/observability/_dispatcher.cpython-310-aarch64-linux-gnu.so +0 -0
  467. sqlspec/observability/_dispatcher.py +152 -0
  468. sqlspec/observability/_formatters/__init__.py +13 -0
  469. sqlspec/observability/_formatters/_aws.cpython-310-aarch64-linux-gnu.so +0 -0
  470. sqlspec/observability/_formatters/_aws.py +102 -0
  471. sqlspec/observability/_formatters/_azure.cpython-310-aarch64-linux-gnu.so +0 -0
  472. sqlspec/observability/_formatters/_azure.py +96 -0
  473. sqlspec/observability/_formatters/_base.cpython-310-aarch64-linux-gnu.so +0 -0
  474. sqlspec/observability/_formatters/_base.py +57 -0
  475. sqlspec/observability/_formatters/_gcp.cpython-310-aarch64-linux-gnu.so +0 -0
  476. sqlspec/observability/_formatters/_gcp.py +131 -0
  477. sqlspec/observability/_formatting.py +58 -0
  478. sqlspec/observability/_observer.cpython-310-aarch64-linux-gnu.so +0 -0
  479. sqlspec/observability/_observer.py +357 -0
  480. sqlspec/observability/_runtime.cpython-310-aarch64-linux-gnu.so +0 -0
  481. sqlspec/observability/_runtime.py +420 -0
  482. sqlspec/observability/_sampling.cpython-310-aarch64-linux-gnu.so +0 -0
  483. sqlspec/observability/_sampling.py +188 -0
  484. sqlspec/observability/_spans.cpython-310-aarch64-linux-gnu.so +0 -0
  485. sqlspec/observability/_spans.py +161 -0
  486. sqlspec/protocols.py +916 -0
  487. sqlspec/py.typed +0 -0
  488. sqlspec/storage/__init__.py +48 -0
  489. sqlspec/storage/_utils.py +104 -0
  490. sqlspec/storage/backends/__init__.py +1 -0
  491. sqlspec/storage/backends/base.py +253 -0
  492. sqlspec/storage/backends/fsspec.py +529 -0
  493. sqlspec/storage/backends/local.py +441 -0
  494. sqlspec/storage/backends/obstore.py +916 -0
  495. sqlspec/storage/errors.py +104 -0
  496. sqlspec/storage/pipeline.py +582 -0
  497. sqlspec/storage/registry.py +301 -0
  498. sqlspec/typing.py +395 -0
  499. sqlspec/utils/__init__.py +7 -0
  500. sqlspec/utils/arrow_helpers.py +318 -0
  501. sqlspec/utils/config_tools.py +332 -0
  502. sqlspec/utils/correlation.cpython-310-aarch64-linux-gnu.so +0 -0
  503. sqlspec/utils/correlation.py +134 -0
  504. sqlspec/utils/deprecation.py +190 -0
  505. sqlspec/utils/fixtures.cpython-310-aarch64-linux-gnu.so +0 -0
  506. sqlspec/utils/fixtures.py +258 -0
  507. sqlspec/utils/logging.py +222 -0
  508. sqlspec/utils/module_loader.py +306 -0
  509. sqlspec/utils/portal.cpython-310-aarch64-linux-gnu.so +0 -0
  510. sqlspec/utils/portal.py +375 -0
  511. sqlspec/utils/schema.cpython-310-aarch64-linux-gnu.so +0 -0
  512. sqlspec/utils/schema.py +485 -0
  513. sqlspec/utils/serializers.cpython-310-aarch64-linux-gnu.so +0 -0
  514. sqlspec/utils/serializers.py +408 -0
  515. sqlspec/utils/singleton.cpython-310-aarch64-linux-gnu.so +0 -0
  516. sqlspec/utils/singleton.py +41 -0
  517. sqlspec/utils/sync_tools.cpython-310-aarch64-linux-gnu.so +0 -0
  518. sqlspec/utils/sync_tools.py +311 -0
  519. sqlspec/utils/text.cpython-310-aarch64-linux-gnu.so +0 -0
  520. sqlspec/utils/text.py +108 -0
  521. sqlspec/utils/type_converters.cpython-310-aarch64-linux-gnu.so +0 -0
  522. sqlspec/utils/type_converters.py +128 -0
  523. sqlspec/utils/type_guards.cpython-310-aarch64-linux-gnu.so +0 -0
  524. sqlspec/utils/type_guards.py +1360 -0
  525. sqlspec/utils/uuids.cpython-310-aarch64-linux-gnu.so +0 -0
  526. sqlspec/utils/uuids.py +225 -0
  527. sqlspec-0.36.0.dist-info/METADATA +205 -0
  528. sqlspec-0.36.0.dist-info/RECORD +531 -0
  529. sqlspec-0.36.0.dist-info/WHEEL +7 -0
  530. sqlspec-0.36.0.dist-info/entry_points.txt +2 -0
  531. sqlspec-0.36.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,20 @@
1
+ """Events helpers for the psycopg adapter."""
2
+
3
+ from sqlspec.adapters.psycopg.events.backend import (
4
+ PsycopgAsyncEventsBackend,
5
+ PsycopgAsyncHybridEventsBackend,
6
+ PsycopgSyncEventsBackend,
7
+ PsycopgSyncHybridEventsBackend,
8
+ create_event_backend,
9
+ )
10
+ from sqlspec.adapters.psycopg.events.store import PsycopgAsyncEventQueueStore, PsycopgSyncEventQueueStore
11
+
12
+ __all__ = (
13
+ "PsycopgAsyncEventQueueStore",
14
+ "PsycopgAsyncEventsBackend",
15
+ "PsycopgAsyncHybridEventsBackend",
16
+ "PsycopgSyncEventQueueStore",
17
+ "PsycopgSyncEventsBackend",
18
+ "PsycopgSyncHybridEventsBackend",
19
+ "create_event_backend",
20
+ )
@@ -0,0 +1,458 @@
1
+ # pyright: reportPrivateUsage=false
2
+ """Psycopg LISTEN/NOTIFY and hybrid event backends."""
3
+
4
+ import contextlib
5
+ import logging
6
+ from datetime import datetime, timezone
7
+ from typing import TYPE_CHECKING, Any, cast
8
+
9
+ from sqlspec.core import SQL
10
+ from sqlspec.exceptions import ImproperConfigurationError
11
+ from sqlspec.extensions.events import (
12
+ AsyncTableEventQueue,
13
+ EventMessage,
14
+ SyncTableEventQueue,
15
+ build_queue_backend,
16
+ decode_notify_payload,
17
+ encode_notify_payload,
18
+ normalize_event_channel_name,
19
+ )
20
+ from sqlspec.utils.logging import get_logger, log_with_context
21
+ from sqlspec.utils.serializers import from_json, to_json
22
+ from sqlspec.utils.uuids import uuid4
23
+
24
+ if TYPE_CHECKING:
25
+ from sqlspec.adapters.psycopg.config import PsycopgAsyncConfig, PsycopgSyncConfig
26
+
27
+ logger = get_logger("sqlspec.events.psycopg")
28
+
29
+ __all__ = (
30
+ "PsycopgAsyncEventsBackend",
31
+ "PsycopgAsyncHybridEventsBackend",
32
+ "PsycopgSyncEventsBackend",
33
+ "PsycopgSyncHybridEventsBackend",
34
+ "create_event_backend",
35
+ )
36
+
37
+
38
+ def _extract_event_id(payload: str | None) -> "str | None":
39
+ if not payload:
40
+ return None
41
+ raw = from_json(payload)
42
+ if isinstance(raw, dict):
43
+ event_id = raw.get("event_id")
44
+ return event_id if isinstance(event_id, str) else None
45
+ return None
46
+
47
+
48
+ class PsycopgSyncEventsBackend:
49
+ """Native LISTEN/NOTIFY backend for sync psycopg adapters."""
50
+
51
+ __slots__ = ("_config", "_listen_connection", "_listen_connection_cm", "_runtime")
52
+
53
+ supports_sync = True
54
+ supports_async = False
55
+ backend_name = "listen_notify"
56
+
57
+ def __init__(self, config: "PsycopgSyncConfig") -> None:
58
+ if "psycopg" not in type(config).__module__:
59
+ msg = "Psycopg events backend requires a Psycopg adapter"
60
+ raise ImproperConfigurationError(msg)
61
+ if config.is_async:
62
+ msg = "PsycopgSyncEventsBackend requires a sync adapter"
63
+ raise ImproperConfigurationError(msg)
64
+ self._config = config
65
+ self._runtime = config.get_observability_runtime()
66
+ self._listen_connection: Any | None = None
67
+ self._listen_connection_cm: Any | None = None
68
+ log_with_context(
69
+ logger,
70
+ logging.DEBUG,
71
+ "event.listen",
72
+ adapter_name="psycopg",
73
+ backend_name=self.backend_name,
74
+ mode="async",
75
+ status="backend_ready",
76
+ )
77
+ log_with_context(
78
+ logger,
79
+ logging.DEBUG,
80
+ "event.listen",
81
+ adapter_name="psycopg",
82
+ backend_name=self.backend_name,
83
+ mode="sync",
84
+ status="backend_ready",
85
+ )
86
+
87
+ def publish(self, channel: str, payload: "dict[str, Any]", metadata: "dict[str, Any] | None" = None) -> str:
88
+ event_id = uuid4().hex
89
+ session_cm = self._config.provide_session()
90
+ with session_cm as driver:
91
+ driver.execute(
92
+ SQL(
93
+ "SELECT pg_notify(:channel, :payload)",
94
+ {"channel": channel, "payload": encode_notify_payload(event_id, payload, metadata)},
95
+ )
96
+ )
97
+ driver.commit()
98
+ self._runtime.increment_metric("events.publish.native")
99
+ return event_id
100
+
101
+ def dequeue(self, channel: str, poll_interval: float) -> EventMessage | None:
102
+ connection = self._ensure_listener(channel)
103
+ notify_iter = connection.notifies(timeout=poll_interval, stop_after=1)
104
+ with contextlib.suppress(StopIteration):
105
+ notify = next(notify_iter)
106
+ if notify.channel == channel:
107
+ return decode_notify_payload(channel, notify.payload)
108
+ return None
109
+
110
+ def ack(self, _event_id: str) -> None:
111
+ self._runtime.increment_metric("events.ack")
112
+
113
+ def nack(self, _event_id: str) -> None:
114
+ """Return an event to the queue (no-op for native LISTEN/NOTIFY)."""
115
+
116
+ def shutdown(self) -> None:
117
+ """Shutdown the listener and release resources."""
118
+ if self._listen_connection_cm is not None:
119
+ with contextlib.suppress(Exception):
120
+ self._listen_connection_cm.__exit__(None, None, None)
121
+ self._listen_connection = None
122
+ self._listen_connection_cm = None
123
+
124
+ def _ensure_listener(self, channel: str) -> Any:
125
+ """Ensure listener connection is established for the channel."""
126
+ if self._listen_connection is None:
127
+ validated_channel = normalize_event_channel_name(channel)
128
+ self._listen_connection_cm = self._config.provide_connection()
129
+ self._listen_connection = self._listen_connection_cm.__enter__()
130
+ if self._listen_connection is not None:
131
+ self._listen_connection.autocommit = True
132
+ self._listen_connection.execute(f"LISTEN {validated_channel}")
133
+ return self._listen_connection
134
+
135
+
136
+ class PsycopgAsyncEventsBackend:
137
+ """Native LISTEN/NOTIFY backend for async psycopg adapters."""
138
+
139
+ __slots__ = ("_config", "_listen_connection", "_listen_connection_cm", "_runtime")
140
+
141
+ supports_sync = False
142
+ supports_async = True
143
+ backend_name = "listen_notify"
144
+
145
+ def __init__(self, config: "PsycopgAsyncConfig") -> None:
146
+ if "psycopg" not in type(config).__module__:
147
+ msg = "Psycopg events backend requires a Psycopg adapter"
148
+ raise ImproperConfigurationError(msg)
149
+ if not config.is_async:
150
+ msg = "PsycopgAsyncEventsBackend requires an async adapter"
151
+ raise ImproperConfigurationError(msg)
152
+ self._config = config
153
+ self._runtime = config.get_observability_runtime()
154
+ self._listen_connection: Any | None = None
155
+ self._listen_connection_cm: Any | None = None
156
+
157
+ async def publish(self, channel: str, payload: "dict[str, Any]", metadata: "dict[str, Any] | None" = None) -> str:
158
+ event_id = uuid4().hex
159
+ session_cm = self._config.provide_session()
160
+ async with session_cm as driver:
161
+ await driver.execute(
162
+ SQL(
163
+ "SELECT pg_notify(:channel, :payload)",
164
+ {"channel": channel, "payload": encode_notify_payload(event_id, payload, metadata)},
165
+ )
166
+ )
167
+ await driver.commit()
168
+ self._runtime.increment_metric("events.publish.native")
169
+ return event_id
170
+
171
+ async def dequeue(self, channel: str, poll_interval: float) -> EventMessage | None:
172
+ connection = await self._ensure_listener(channel)
173
+ async for notify in connection.notifies(timeout=poll_interval, stop_after=1):
174
+ if notify.channel == channel:
175
+ return decode_notify_payload(channel, notify.payload)
176
+ return None
177
+
178
+ async def ack(self, _event_id: str) -> None:
179
+ self._runtime.increment_metric("events.ack")
180
+
181
+ async def nack(self, _event_id: str) -> None:
182
+ """Return an event to the queue (no-op for native LISTEN/NOTIFY)."""
183
+
184
+ async def shutdown(self) -> None:
185
+ """Shutdown the listener and release resources."""
186
+ if self._listen_connection_cm is not None:
187
+ with contextlib.suppress(Exception):
188
+ await self._listen_connection_cm.__aexit__(None, None, None)
189
+ self._listen_connection = None
190
+ self._listen_connection_cm = None
191
+
192
+ async def _ensure_listener(self, channel: str) -> Any:
193
+ """Ensure listener connection is established for the channel."""
194
+ if self._listen_connection is None:
195
+ validated_channel = normalize_event_channel_name(channel)
196
+ self._listen_connection_cm = self._config.provide_connection()
197
+ self._listen_connection = await self._listen_connection_cm.__aenter__()
198
+ if self._listen_connection is not None:
199
+ await self._listen_connection.set_autocommit(True)
200
+ await self._listen_connection.execute(f"LISTEN {validated_channel}")
201
+ return self._listen_connection
202
+
203
+
204
+ class PsycopgSyncHybridEventsBackend:
205
+ """Durable hybrid backend for sync psycopg adapters."""
206
+
207
+ __slots__ = ("_config", "_listen_connection", "_listen_connection_cm", "_queue", "_runtime")
208
+
209
+ supports_sync = True
210
+ supports_async = False
211
+ backend_name = "listen_notify_durable"
212
+
213
+ def __init__(self, config: "PsycopgSyncConfig", queue: "SyncTableEventQueue") -> None:
214
+ if "psycopg" not in type(config).__module__:
215
+ msg = "Psycopg hybrid backend requires a Psycopg adapter"
216
+ raise ImproperConfigurationError(msg)
217
+ if config.is_async:
218
+ msg = "PsycopgSyncHybridEventsBackend requires a sync adapter"
219
+ raise ImproperConfigurationError(msg)
220
+ self._config = config
221
+ self._queue = queue
222
+ self._runtime = config.get_observability_runtime()
223
+ self._listen_connection: Any | None = None
224
+ self._listen_connection_cm: Any | None = None
225
+ log_with_context(
226
+ logger,
227
+ logging.DEBUG,
228
+ "event.listen",
229
+ adapter_name="psycopg",
230
+ backend_name=self.backend_name,
231
+ mode="async",
232
+ status="backend_ready",
233
+ )
234
+ log_with_context(
235
+ logger,
236
+ logging.DEBUG,
237
+ "event.listen",
238
+ adapter_name="psycopg",
239
+ backend_name=self.backend_name,
240
+ mode="sync",
241
+ status="backend_ready",
242
+ )
243
+
244
+ def publish(self, channel: str, payload: "dict[str, Any]", metadata: "dict[str, Any] | None" = None) -> str:
245
+ event_id = uuid4().hex
246
+ self._publish_durable(channel, event_id, payload, metadata)
247
+ self._runtime.increment_metric("events.publish.native")
248
+ return event_id
249
+
250
+ def dequeue(self, channel: str, poll_interval: float) -> EventMessage | None:
251
+ connection = self._ensure_listener(channel)
252
+ notify_iter = connection.notifies(timeout=poll_interval, stop_after=1)
253
+ with contextlib.suppress(StopIteration):
254
+ notify = next(notify_iter)
255
+ event_id = _extract_event_id(notify.payload)
256
+ if event_id:
257
+ event = self._queue.dequeue_by_event_id(event_id)
258
+ if event is not None:
259
+ return event
260
+ return self._queue.dequeue(channel, poll_interval)
261
+
262
+ def ack(self, event_id: str) -> None:
263
+ self._queue.ack(event_id)
264
+ self._runtime.increment_metric("events.ack")
265
+
266
+ def nack(self, event_id: str) -> None:
267
+ self._queue.nack(event_id)
268
+ self._runtime.increment_metric("events.nack")
269
+
270
+ def shutdown(self) -> None:
271
+ """Shutdown the listener and release resources."""
272
+ if self._listen_connection_cm is not None:
273
+ with contextlib.suppress(Exception):
274
+ self._listen_connection_cm.__exit__(None, None, None)
275
+ self._listen_connection = None
276
+ self._listen_connection_cm = None
277
+
278
+ def _ensure_listener(self, channel: str) -> Any:
279
+ """Ensure listener connection is established for the channel."""
280
+ if self._listen_connection is None:
281
+ validated_channel = normalize_event_channel_name(channel)
282
+ self._listen_connection_cm = self._config.provide_connection()
283
+ self._listen_connection = self._listen_connection_cm.__enter__()
284
+ if self._listen_connection is not None:
285
+ self._listen_connection.autocommit = True
286
+ self._listen_connection.execute(f"LISTEN {validated_channel}")
287
+ return self._listen_connection
288
+
289
+ def _publish_durable(
290
+ self, channel: str, event_id: str, payload: "dict[str, Any]", metadata: "dict[str, Any] | None"
291
+ ) -> None:
292
+ """Publish event to durable queue and send NOTIFY."""
293
+ now = datetime.now(timezone.utc)
294
+ with self._config.provide_session() as driver:
295
+ driver.execute(
296
+ SQL(
297
+ self._queue._upsert_sql,
298
+ {
299
+ "event_id": event_id,
300
+ "channel": channel,
301
+ "payload_json": to_json(payload),
302
+ "metadata_json": to_json(metadata) if metadata else None,
303
+ "status": "pending",
304
+ "available_at": now,
305
+ "lease_expires_at": None,
306
+ "attempts": 0,
307
+ "created_at": now,
308
+ },
309
+ statement_config=self._queue._statement_config,
310
+ )
311
+ )
312
+ driver.execute(
313
+ SQL(
314
+ "SELECT pg_notify(:channel, :payload)",
315
+ {"channel": channel, "payload": to_json({"event_id": event_id})},
316
+ )
317
+ )
318
+ driver.commit()
319
+
320
+
321
+ class PsycopgAsyncHybridEventsBackend:
322
+ """Durable hybrid backend for async psycopg adapters."""
323
+
324
+ __slots__ = ("_config", "_listen_connection", "_listen_connection_cm", "_queue", "_runtime")
325
+
326
+ supports_sync = False
327
+ supports_async = True
328
+ backend_name = "listen_notify_durable"
329
+
330
+ def __init__(self, config: "PsycopgAsyncConfig", queue: "AsyncTableEventQueue") -> None:
331
+ if "psycopg" not in type(config).__module__:
332
+ msg = "Psycopg hybrid backend requires a Psycopg adapter"
333
+ raise ImproperConfigurationError(msg)
334
+ if not config.is_async:
335
+ msg = "PsycopgAsyncHybridEventsBackend requires an async adapter"
336
+ raise ImproperConfigurationError(msg)
337
+ self._config = config
338
+ self._queue = queue
339
+ self._runtime = config.get_observability_runtime()
340
+ self._listen_connection: Any | None = None
341
+ self._listen_connection_cm: Any | None = None
342
+
343
+ async def publish(self, channel: str, payload: "dict[str, Any]", metadata: "dict[str, Any] | None" = None) -> str:
344
+ event_id = uuid4().hex
345
+ await self._publish_durable(channel, event_id, payload, metadata)
346
+ self._runtime.increment_metric("events.publish.native")
347
+ return event_id
348
+
349
+ async def dequeue(self, channel: str, poll_interval: float) -> EventMessage | None:
350
+ connection = await self._ensure_listener(channel)
351
+ async for notify in connection.notifies(timeout=poll_interval, stop_after=1):
352
+ event_id = _extract_event_id(notify.payload)
353
+ if event_id:
354
+ event = await self._queue.dequeue_by_event_id(event_id)
355
+ if event is not None:
356
+ return event
357
+ break
358
+ return await self._queue.dequeue(channel, poll_interval)
359
+
360
+ async def ack(self, event_id: str) -> None:
361
+ await self._queue.ack(event_id)
362
+ self._runtime.increment_metric("events.ack")
363
+
364
+ async def nack(self, event_id: str) -> None:
365
+ await self._queue.nack(event_id)
366
+ self._runtime.increment_metric("events.nack")
367
+
368
+ async def shutdown(self) -> None:
369
+ """Shutdown the listener and release resources."""
370
+ if self._listen_connection_cm is not None:
371
+ with contextlib.suppress(Exception):
372
+ await self._listen_connection_cm.__aexit__(None, None, None)
373
+ self._listen_connection = None
374
+ self._listen_connection_cm = None
375
+
376
+ async def _ensure_listener(self, channel: str) -> Any:
377
+ """Ensure listener connection is established for the channel."""
378
+ if self._listen_connection is None:
379
+ validated_channel = normalize_event_channel_name(channel)
380
+ self._listen_connection_cm = self._config.provide_connection()
381
+ self._listen_connection = await self._listen_connection_cm.__aenter__()
382
+ if self._listen_connection is not None:
383
+ await self._listen_connection.set_autocommit(True)
384
+ await self._listen_connection.execute(f"LISTEN {validated_channel}")
385
+ return self._listen_connection
386
+
387
+ async def _publish_durable(
388
+ self, channel: str, event_id: str, payload: "dict[str, Any]", metadata: "dict[str, Any] | None"
389
+ ) -> None:
390
+ """Publish event to durable queue and send NOTIFY."""
391
+ now = datetime.now(timezone.utc)
392
+ async with self._config.provide_session() as driver:
393
+ await driver.execute(
394
+ SQL(
395
+ self._queue._upsert_sql,
396
+ {
397
+ "event_id": event_id,
398
+ "channel": channel,
399
+ "payload_json": to_json(payload),
400
+ "metadata_json": to_json(metadata) if metadata else None,
401
+ "status": "pending",
402
+ "available_at": now,
403
+ "lease_expires_at": None,
404
+ "attempts": 0,
405
+ "created_at": now,
406
+ },
407
+ statement_config=self._queue._statement_config,
408
+ )
409
+ )
410
+ await driver.execute(
411
+ SQL(
412
+ "SELECT pg_notify(:channel, :payload)",
413
+ {"channel": channel, "payload": to_json({"event_id": event_id})},
414
+ )
415
+ )
416
+ await driver.commit()
417
+
418
+
419
+ def create_event_backend(
420
+ config: "PsycopgAsyncConfig | PsycopgSyncConfig", backend_name: str, extension_settings: "dict[str, Any]"
421
+ ) -> (
422
+ PsycopgSyncEventsBackend
423
+ | PsycopgAsyncEventsBackend
424
+ | PsycopgSyncHybridEventsBackend
425
+ | PsycopgAsyncHybridEventsBackend
426
+ | None
427
+ ):
428
+ """Factory used by EventChannel to create the native psycopg backend."""
429
+ is_async = config.is_async
430
+ match (backend_name, is_async):
431
+ case ("listen_notify", False):
432
+ try:
433
+ return PsycopgSyncEventsBackend(config) # type: ignore[arg-type]
434
+ except ImproperConfigurationError:
435
+ return None
436
+ case ("listen_notify", True):
437
+ try:
438
+ return PsycopgAsyncEventsBackend(config) # type: ignore[arg-type]
439
+ except ImproperConfigurationError:
440
+ return None
441
+ case ("listen_notify_durable", False):
442
+ sync_queue = cast(
443
+ "SyncTableEventQueue", build_queue_backend(config, extension_settings, adapter_name="psycopg")
444
+ )
445
+ try:
446
+ return PsycopgSyncHybridEventsBackend(config, sync_queue) # type: ignore[arg-type]
447
+ except ImproperConfigurationError:
448
+ return None
449
+ case ("listen_notify_durable", True):
450
+ async_queue = cast(
451
+ "AsyncTableEventQueue", build_queue_backend(config, extension_settings, adapter_name="psycopg")
452
+ )
453
+ try:
454
+ return PsycopgAsyncHybridEventsBackend(config, async_queue) # type: ignore[arg-type]
455
+ except ImproperConfigurationError:
456
+ return None
457
+ case _:
458
+ return None
@@ -0,0 +1,42 @@
1
+ """Psycopg event queue stores for sync and async drivers."""
2
+
3
+ from sqlspec.adapters.psycopg.config import PsycopgAsyncConfig, PsycopgSyncConfig
4
+ from sqlspec.extensions.events import BaseEventQueueStore
5
+
6
+ __all__ = ("PsycopgAsyncEventQueueStore", "PsycopgSyncEventQueueStore")
7
+
8
+
9
+ class PsycopgSyncEventQueueStore(BaseEventQueueStore[PsycopgSyncConfig]):
10
+ """Queue DDL for psycopg synchronous configs.
11
+
12
+ PostgreSQL uses JSONB for efficient binary JSON storage with indexing support,
13
+ and TIMESTAMPTZ for timezone-aware timestamps.
14
+ """
15
+
16
+ __slots__ = ()
17
+
18
+ def _column_types(self) -> "tuple[str, str, str]":
19
+ """Return PostgreSQL-optimized column types for the event queue.
20
+
21
+ Returns:
22
+ Tuple of (payload_type, metadata_type, timestamp_type).
23
+ """
24
+ return "JSONB", "JSONB", "TIMESTAMPTZ"
25
+
26
+
27
+ class PsycopgAsyncEventQueueStore(BaseEventQueueStore[PsycopgAsyncConfig]):
28
+ """Queue DDL for psycopg async configs.
29
+
30
+ PostgreSQL uses JSONB for efficient binary JSON storage with indexing support,
31
+ and TIMESTAMPTZ for timezone-aware timestamps.
32
+ """
33
+
34
+ __slots__ = ()
35
+
36
+ def _column_types(self) -> "tuple[str, str, str]":
37
+ """Return PostgreSQL-optimized column types for the event queue.
38
+
39
+ Returns:
40
+ Tuple of (payload_type, metadata_type, timestamp_type).
41
+ """
42
+ return "JSONB", "JSONB", "TIMESTAMPTZ"
@@ -0,0 +1,5 @@
1
+ """Litestar integration for Psycopg adapter."""
2
+
3
+ from sqlspec.adapters.psycopg.litestar.store import PsycopgAsyncStore, PsycopgSyncStore
4
+
5
+ __all__ = ("PsycopgAsyncStore", "PsycopgSyncStore")