relq 1.0.0

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 (305) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +862 -0
  3. package/dist/addons/buffer.js +1869 -0
  4. package/dist/addons/pg-cursor.js +1425 -0
  5. package/dist/addons/pg-format.js +2248 -0
  6. package/dist/addons/pg.js +4790 -0
  7. package/dist/bin/relq.js +2 -0
  8. package/dist/cjs/cache/index.cjs +9 -0
  9. package/dist/cjs/cache/query-cache.cjs +311 -0
  10. package/dist/cjs/cli/commands/add.cjs +82 -0
  11. package/dist/cjs/cli/commands/commit.cjs +145 -0
  12. package/dist/cjs/cli/commands/diff.cjs +84 -0
  13. package/dist/cjs/cli/commands/export.cjs +333 -0
  14. package/dist/cjs/cli/commands/fetch.cjs +59 -0
  15. package/dist/cjs/cli/commands/generate.cjs +242 -0
  16. package/dist/cjs/cli/commands/history.cjs +165 -0
  17. package/dist/cjs/cli/commands/import.cjs +524 -0
  18. package/dist/cjs/cli/commands/init.cjs +437 -0
  19. package/dist/cjs/cli/commands/introspect.cjs +142 -0
  20. package/dist/cjs/cli/commands/log.cjs +62 -0
  21. package/dist/cjs/cli/commands/migrate.cjs +167 -0
  22. package/dist/cjs/cli/commands/pull.cjs +410 -0
  23. package/dist/cjs/cli/commands/push.cjs +165 -0
  24. package/dist/cjs/cli/commands/rollback.cjs +169 -0
  25. package/dist/cjs/cli/commands/status.cjs +110 -0
  26. package/dist/cjs/cli/commands/sync.cjs +79 -0
  27. package/dist/cjs/cli/index.cjs +275 -0
  28. package/dist/cjs/cli/utils/change-tracker.cjs +446 -0
  29. package/dist/cjs/cli/utils/commit-manager.cjs +239 -0
  30. package/dist/cjs/cli/utils/config-loader.cjs +127 -0
  31. package/dist/cjs/cli/utils/env-loader.cjs +62 -0
  32. package/dist/cjs/cli/utils/fast-introspect.cjs +398 -0
  33. package/dist/cjs/cli/utils/git-utils.cjs +404 -0
  34. package/dist/cjs/cli/utils/migration-generator.cjs +269 -0
  35. package/dist/cjs/cli/utils/relqignore.cjs +114 -0
  36. package/dist/cjs/cli/utils/repo-manager.cjs +515 -0
  37. package/dist/cjs/cli/utils/schema-comparator.cjs +313 -0
  38. package/dist/cjs/cli/utils/schema-diff.cjs +284 -0
  39. package/dist/cjs/cli/utils/schema-hash.cjs +108 -0
  40. package/dist/cjs/cli/utils/schema-introspect.cjs +455 -0
  41. package/dist/cjs/cli/utils/snapshot-manager.cjs +223 -0
  42. package/dist/cjs/cli/utils/spinner.cjs +108 -0
  43. package/dist/cjs/cli/utils/sql-generator.cjs +520 -0
  44. package/dist/cjs/cli/utils/sql-parser.cjs +999 -0
  45. package/dist/cjs/cli/utils/type-generator.cjs +2061 -0
  46. package/dist/cjs/condition/array-condition-builder.cjs +503 -0
  47. package/dist/cjs/condition/array-numeric-condition-builder.cjs +186 -0
  48. package/dist/cjs/condition/array-specialized-condition-builder.cjs +206 -0
  49. package/dist/cjs/condition/array-string-condition-builder.cjs +146 -0
  50. package/dist/cjs/condition/base-condition-builder.cjs +2 -0
  51. package/dist/cjs/condition/condition-collector.cjs +284 -0
  52. package/dist/cjs/condition/fulltext-condition-builder.cjs +61 -0
  53. package/dist/cjs/condition/geometric-condition-builder.cjs +208 -0
  54. package/dist/cjs/condition/index.cjs +25 -0
  55. package/dist/cjs/condition/jsonb-condition-builder.cjs +160 -0
  56. package/dist/cjs/condition/network-condition-builder.cjs +230 -0
  57. package/dist/cjs/condition/range-condition-builder.cjs +82 -0
  58. package/dist/cjs/config/config.cjs +190 -0
  59. package/dist/cjs/config/index.cjs +9 -0
  60. package/dist/cjs/constants/pg-values.cjs +68 -0
  61. package/dist/cjs/copy/copy-builder.cjs +316 -0
  62. package/dist/cjs/copy/index.cjs +6 -0
  63. package/dist/cjs/core/query-builder.cjs +440 -0
  64. package/dist/cjs/core/relq-client.cjs +1831 -0
  65. package/dist/cjs/core/typed-kuery-client.cjs +2 -0
  66. package/dist/cjs/count/count-builder.cjs +88 -0
  67. package/dist/cjs/count/index.cjs +5 -0
  68. package/dist/cjs/cte/cte-builder.cjs +89 -0
  69. package/dist/cjs/cte/index.cjs +5 -0
  70. package/dist/cjs/ddl/function.cjs +48 -0
  71. package/dist/cjs/ddl/index.cjs +7 -0
  72. package/dist/cjs/ddl/sql.cjs +54 -0
  73. package/dist/cjs/delete/delete-builder.cjs +135 -0
  74. package/dist/cjs/delete/index.cjs +5 -0
  75. package/dist/cjs/errors/relq-errors.cjs +329 -0
  76. package/dist/cjs/examples/fulltext-search-test.cjs +122 -0
  77. package/dist/cjs/explain/explain-builder.cjs +99 -0
  78. package/dist/cjs/explain/index.cjs +5 -0
  79. package/dist/cjs/function/create-function-builder.cjs +196 -0
  80. package/dist/cjs/function/index.cjs +6 -0
  81. package/dist/cjs/functions/advanced-functions.cjs +241 -0
  82. package/dist/cjs/functions/case-builder.cjs +66 -0
  83. package/dist/cjs/functions/geometric-functions.cjs +104 -0
  84. package/dist/cjs/functions/index.cjs +184 -0
  85. package/dist/cjs/functions/network-functions.cjs +86 -0
  86. package/dist/cjs/functions/sql-functions.cjs +431 -0
  87. package/dist/cjs/index.cjs +164 -0
  88. package/dist/cjs/indexing/create-index-builder.cjs +187 -0
  89. package/dist/cjs/indexing/drop-index-builder.cjs +89 -0
  90. package/dist/cjs/indexing/index-types.cjs +2 -0
  91. package/dist/cjs/indexing/index.cjs +8 -0
  92. package/dist/cjs/insert/conflict-builder.cjs +173 -0
  93. package/dist/cjs/insert/index.cjs +5 -0
  94. package/dist/cjs/insert/insert-builder.cjs +254 -0
  95. package/dist/cjs/introspect/index.cjs +229 -0
  96. package/dist/cjs/maintenance/index.cjs +6 -0
  97. package/dist/cjs/maintenance/vacuum-builder.cjs +166 -0
  98. package/dist/cjs/pubsub/index.cjs +7 -0
  99. package/dist/cjs/pubsub/listen-notify-builder.cjs +57 -0
  100. package/dist/cjs/pubsub/listener-connection.cjs +180 -0
  101. package/dist/cjs/raw/index.cjs +5 -0
  102. package/dist/cjs/raw/raw-query-builder.cjs +27 -0
  103. package/dist/cjs/schema/index.cjs +15 -0
  104. package/dist/cjs/schema/schema-builder.cjs +1167 -0
  105. package/dist/cjs/schema-builder.cjs +21 -0
  106. package/dist/cjs/schema-definition/column-types.cjs +829 -0
  107. package/dist/cjs/schema-definition/index.cjs +62 -0
  108. package/dist/cjs/schema-definition/introspection.cjs +620 -0
  109. package/dist/cjs/schema-definition/partitions.cjs +129 -0
  110. package/dist/cjs/schema-definition/pg-enum.cjs +76 -0
  111. package/dist/cjs/schema-definition/pg-function.cjs +91 -0
  112. package/dist/cjs/schema-definition/pg-sequence.cjs +56 -0
  113. package/dist/cjs/schema-definition/pg-trigger.cjs +108 -0
  114. package/dist/cjs/schema-definition/relations.cjs +98 -0
  115. package/dist/cjs/schema-definition/sql-expressions.cjs +202 -0
  116. package/dist/cjs/schema-definition/table-definition.cjs +636 -0
  117. package/dist/cjs/select/aggregate-builder.cjs +179 -0
  118. package/dist/cjs/select/index.cjs +5 -0
  119. package/dist/cjs/select/select-builder.cjs +233 -0
  120. package/dist/cjs/sequence/index.cjs +7 -0
  121. package/dist/cjs/sequence/sequence-builder.cjs +264 -0
  122. package/dist/cjs/table/alter-table-builder.cjs +146 -0
  123. package/dist/cjs/table/constraint-builder.cjs +102 -0
  124. package/dist/cjs/table/create-table-builder.cjs +248 -0
  125. package/dist/cjs/table/index.cjs +17 -0
  126. package/dist/cjs/table/partition-builder.cjs +131 -0
  127. package/dist/cjs/table/truncate-builder.cjs +70 -0
  128. package/dist/cjs/transaction/index.cjs +6 -0
  129. package/dist/cjs/transaction/transaction-builder.cjs +78 -0
  130. package/dist/cjs/trigger/create-trigger-builder.cjs +174 -0
  131. package/dist/cjs/trigger/index.cjs +6 -0
  132. package/dist/cjs/types/aggregate-types.cjs +2 -0
  133. package/dist/cjs/types/config-types.cjs +40 -0
  134. package/dist/cjs/types/inference-types.cjs +18 -0
  135. package/dist/cjs/types/pagination-types.cjs +7 -0
  136. package/dist/cjs/types/result-types.cjs +2 -0
  137. package/dist/cjs/types/schema-types.cjs +2 -0
  138. package/dist/cjs/types/subscription-types.cjs +2 -0
  139. package/dist/cjs/types.cjs +2 -0
  140. package/dist/cjs/update/array-update-builder.cjs +205 -0
  141. package/dist/cjs/update/index.cjs +13 -0
  142. package/dist/cjs/update/update-builder.cjs +195 -0
  143. package/dist/cjs/utils/case-converter.cjs +58 -0
  144. package/dist/cjs/utils/environment-detection.cjs +120 -0
  145. package/dist/cjs/utils/index.cjs +10 -0
  146. package/dist/cjs/utils/pool-defaults.cjs +106 -0
  147. package/dist/cjs/utils/type-coercion.cjs +118 -0
  148. package/dist/cjs/view/create-view-builder.cjs +180 -0
  149. package/dist/cjs/view/index.cjs +7 -0
  150. package/dist/cjs/window/index.cjs +5 -0
  151. package/dist/cjs/window/window-builder.cjs +80 -0
  152. package/dist/config.cjs +1 -0
  153. package/dist/config.d.ts +655 -0
  154. package/dist/config.js +1 -0
  155. package/dist/esm/cache/index.js +1 -0
  156. package/dist/esm/cache/query-cache.js +303 -0
  157. package/dist/esm/cli/commands/add.js +78 -0
  158. package/dist/esm/cli/commands/commit.js +109 -0
  159. package/dist/esm/cli/commands/diff.js +81 -0
  160. package/dist/esm/cli/commands/export.js +297 -0
  161. package/dist/esm/cli/commands/fetch.js +56 -0
  162. package/dist/esm/cli/commands/generate.js +206 -0
  163. package/dist/esm/cli/commands/history.js +129 -0
  164. package/dist/esm/cli/commands/import.js +488 -0
  165. package/dist/esm/cli/commands/init.js +401 -0
  166. package/dist/esm/cli/commands/introspect.js +106 -0
  167. package/dist/esm/cli/commands/log.js +59 -0
  168. package/dist/esm/cli/commands/migrate.js +131 -0
  169. package/dist/esm/cli/commands/pull.js +374 -0
  170. package/dist/esm/cli/commands/push.js +129 -0
  171. package/dist/esm/cli/commands/rollback.js +133 -0
  172. package/dist/esm/cli/commands/status.js +107 -0
  173. package/dist/esm/cli/commands/sync.js +76 -0
  174. package/dist/esm/cli/index.js +240 -0
  175. package/dist/esm/cli/utils/change-tracker.js +405 -0
  176. package/dist/esm/cli/utils/commit-manager.js +191 -0
  177. package/dist/esm/cli/utils/config-loader.js +86 -0
  178. package/dist/esm/cli/utils/env-loader.js +57 -0
  179. package/dist/esm/cli/utils/fast-introspect.js +362 -0
  180. package/dist/esm/cli/utils/git-utils.js +347 -0
  181. package/dist/esm/cli/utils/migration-generator.js +263 -0
  182. package/dist/esm/cli/utils/relqignore.js +74 -0
  183. package/dist/esm/cli/utils/repo-manager.js +444 -0
  184. package/dist/esm/cli/utils/schema-comparator.js +307 -0
  185. package/dist/esm/cli/utils/schema-diff.js +276 -0
  186. package/dist/esm/cli/utils/schema-hash.js +69 -0
  187. package/dist/esm/cli/utils/schema-introspect.js +418 -0
  188. package/dist/esm/cli/utils/snapshot-manager.js +179 -0
  189. package/dist/esm/cli/utils/spinner.js +101 -0
  190. package/dist/esm/cli/utils/sql-generator.js +504 -0
  191. package/dist/esm/cli/utils/sql-parser.js +992 -0
  192. package/dist/esm/cli/utils/type-generator.js +2058 -0
  193. package/dist/esm/condition/array-condition-builder.js +495 -0
  194. package/dist/esm/condition/array-numeric-condition-builder.js +182 -0
  195. package/dist/esm/condition/array-specialized-condition-builder.js +200 -0
  196. package/dist/esm/condition/array-string-condition-builder.js +142 -0
  197. package/dist/esm/condition/base-condition-builder.js +1 -0
  198. package/dist/esm/condition/condition-collector.js +275 -0
  199. package/dist/esm/condition/fulltext-condition-builder.js +53 -0
  200. package/dist/esm/condition/geometric-condition-builder.js +200 -0
  201. package/dist/esm/condition/index.js +7 -0
  202. package/dist/esm/condition/jsonb-condition-builder.js +152 -0
  203. package/dist/esm/condition/network-condition-builder.js +222 -0
  204. package/dist/esm/condition/range-condition-builder.js +74 -0
  205. package/dist/esm/config/config.js +150 -0
  206. package/dist/esm/config/index.js +1 -0
  207. package/dist/esm/constants/pg-values.js +63 -0
  208. package/dist/esm/copy/copy-builder.js +308 -0
  209. package/dist/esm/copy/index.js +1 -0
  210. package/dist/esm/core/query-builder.js +426 -0
  211. package/dist/esm/core/relq-client.js +1791 -0
  212. package/dist/esm/core/typed-kuery-client.js +1 -0
  213. package/dist/esm/count/count-builder.js +81 -0
  214. package/dist/esm/count/index.js +1 -0
  215. package/dist/esm/cte/cte-builder.js +82 -0
  216. package/dist/esm/cte/index.js +1 -0
  217. package/dist/esm/ddl/function.js +45 -0
  218. package/dist/esm/ddl/index.js +2 -0
  219. package/dist/esm/ddl/sql.js +51 -0
  220. package/dist/esm/delete/delete-builder.js +128 -0
  221. package/dist/esm/delete/index.js +1 -0
  222. package/dist/esm/errors/relq-errors.js +310 -0
  223. package/dist/esm/examples/fulltext-search-test.js +117 -0
  224. package/dist/esm/explain/explain-builder.js +95 -0
  225. package/dist/esm/explain/index.js +1 -0
  226. package/dist/esm/function/create-function-builder.js +188 -0
  227. package/dist/esm/function/index.js +1 -0
  228. package/dist/esm/functions/advanced-functions.js +231 -0
  229. package/dist/esm/functions/case-builder.js +58 -0
  230. package/dist/esm/functions/geometric-functions.js +97 -0
  231. package/dist/esm/functions/index.js +171 -0
  232. package/dist/esm/functions/network-functions.js +79 -0
  233. package/dist/esm/functions/sql-functions.js +421 -0
  234. package/dist/esm/index.js +34 -0
  235. package/dist/esm/indexing/create-index-builder.js +180 -0
  236. package/dist/esm/indexing/drop-index-builder.js +81 -0
  237. package/dist/esm/indexing/index-types.js +1 -0
  238. package/dist/esm/indexing/index.js +2 -0
  239. package/dist/esm/insert/conflict-builder.js +162 -0
  240. package/dist/esm/insert/index.js +1 -0
  241. package/dist/esm/insert/insert-builder.js +247 -0
  242. package/dist/esm/introspect/index.js +224 -0
  243. package/dist/esm/maintenance/index.js +1 -0
  244. package/dist/esm/maintenance/vacuum-builder.js +158 -0
  245. package/dist/esm/pubsub/index.js +1 -0
  246. package/dist/esm/pubsub/listen-notify-builder.js +48 -0
  247. package/dist/esm/pubsub/listener-connection.js +173 -0
  248. package/dist/esm/raw/index.js +1 -0
  249. package/dist/esm/raw/raw-query-builder.js +20 -0
  250. package/dist/esm/schema/index.js +1 -0
  251. package/dist/esm/schema/schema-builder.js +1150 -0
  252. package/dist/esm/schema-builder.js +2 -0
  253. package/dist/esm/schema-definition/column-types.js +738 -0
  254. package/dist/esm/schema-definition/index.js +10 -0
  255. package/dist/esm/schema-definition/introspection.js +614 -0
  256. package/dist/esm/schema-definition/partitions.js +123 -0
  257. package/dist/esm/schema-definition/pg-enum.js +70 -0
  258. package/dist/esm/schema-definition/pg-function.js +85 -0
  259. package/dist/esm/schema-definition/pg-sequence.js +50 -0
  260. package/dist/esm/schema-definition/pg-trigger.js +102 -0
  261. package/dist/esm/schema-definition/relations.js +90 -0
  262. package/dist/esm/schema-definition/sql-expressions.js +193 -0
  263. package/dist/esm/schema-definition/table-definition.js +630 -0
  264. package/dist/esm/select/aggregate-builder.js +172 -0
  265. package/dist/esm/select/index.js +1 -0
  266. package/dist/esm/select/select-builder.js +226 -0
  267. package/dist/esm/sequence/index.js +1 -0
  268. package/dist/esm/sequence/sequence-builder.js +255 -0
  269. package/dist/esm/table/alter-table-builder.js +138 -0
  270. package/dist/esm/table/constraint-builder.js +95 -0
  271. package/dist/esm/table/create-table-builder.js +241 -0
  272. package/dist/esm/table/index.js +5 -0
  273. package/dist/esm/table/partition-builder.js +121 -0
  274. package/dist/esm/table/truncate-builder.js +63 -0
  275. package/dist/esm/transaction/index.js +1 -0
  276. package/dist/esm/transaction/transaction-builder.js +70 -0
  277. package/dist/esm/trigger/create-trigger-builder.js +166 -0
  278. package/dist/esm/trigger/index.js +1 -0
  279. package/dist/esm/types/aggregate-types.js +1 -0
  280. package/dist/esm/types/config-types.js +36 -0
  281. package/dist/esm/types/inference-types.js +12 -0
  282. package/dist/esm/types/pagination-types.js +4 -0
  283. package/dist/esm/types/result-types.js +1 -0
  284. package/dist/esm/types/schema-types.js +1 -0
  285. package/dist/esm/types/subscription-types.js +1 -0
  286. package/dist/esm/types.js +1 -0
  287. package/dist/esm/update/array-update-builder.js +192 -0
  288. package/dist/esm/update/index.js +2 -0
  289. package/dist/esm/update/update-builder.js +188 -0
  290. package/dist/esm/utils/case-converter.js +55 -0
  291. package/dist/esm/utils/environment-detection.js +113 -0
  292. package/dist/esm/utils/index.js +2 -0
  293. package/dist/esm/utils/pool-defaults.js +100 -0
  294. package/dist/esm/utils/type-coercion.js +110 -0
  295. package/dist/esm/view/create-view-builder.js +171 -0
  296. package/dist/esm/view/index.js +1 -0
  297. package/dist/esm/window/index.js +1 -0
  298. package/dist/esm/window/window-builder.js +73 -0
  299. package/dist/index.cjs +1 -0
  300. package/dist/index.d.ts +10341 -0
  301. package/dist/index.js +1 -0
  302. package/dist/schema-builder.cjs +1 -0
  303. package/dist/schema-builder.d.ts +2272 -0
  304. package/dist/schema-builder.js +1 -0
  305. package/package.json +55 -0
@@ -0,0 +1,57 @@
1
+ export function loadEnvConfig() {
2
+ const connectionString = process.env.DATABASE_CONNECTION_STRING;
3
+ if (connectionString) {
4
+ return parseConnectionString(connectionString);
5
+ }
6
+ const host = process.env.DATABASE_HOST;
7
+ const database = process.env.DATABASE_NAME;
8
+ const user = process.env.DATABASE_USER;
9
+ const password = process.env.DATABASE_PASSWORD;
10
+ const port = process.env.DATABASE_PORT;
11
+ if (!host || !database) {
12
+ return null;
13
+ }
14
+ return {
15
+ host,
16
+ port: port ? parseInt(port, 10) : 5432,
17
+ database,
18
+ user: user || 'postgres',
19
+ password: password || '',
20
+ };
21
+ }
22
+ function parseConnectionString(url) {
23
+ try {
24
+ const parsed = new URL(url);
25
+ return {
26
+ url,
27
+ host: parsed.hostname,
28
+ port: parsed.port ? parseInt(parsed.port, 10) : 5432,
29
+ database: parsed.pathname.slice(1),
30
+ user: parsed.username || 'postgres',
31
+ password: parsed.password || '',
32
+ ssl: parsed.searchParams.get('sslmode'),
33
+ };
34
+ }
35
+ catch {
36
+ return { url };
37
+ }
38
+ }
39
+ export function hasEnvConfig() {
40
+ return !!(process.env.DATABASE_CONNECTION_STRING ||
41
+ process.env.DATABASE_HOST);
42
+ }
43
+ export function getConnectionDescription(config) {
44
+ if (config.url) {
45
+ try {
46
+ const url = new URL(config.url);
47
+ if (url.password) {
48
+ url.password = '***';
49
+ }
50
+ return url.toString();
51
+ }
52
+ catch {
53
+ return config.url.replace(/:([^:@]+)@/, ':***@');
54
+ }
55
+ }
56
+ return `${config.user || 'postgres'}@${config.host}:${config.port || 5432}/${config.database}`;
57
+ }
@@ -0,0 +1,362 @@
1
+ export async function fastIntrospectDatabase(connection, onProgress, options) {
2
+ const { includeFunctions = false, includeTriggers = false } = options || {};
3
+ const { Pool } = await import("../../addon/pg.js");
4
+ onProgress?.('connecting', connection.database);
5
+ const pool = new Pool({
6
+ host: connection.host,
7
+ port: connection.port || 5432,
8
+ database: connection.database,
9
+ user: connection.user,
10
+ password: connection.password,
11
+ connectionString: connection.url,
12
+ ssl: connection.ssl,
13
+ });
14
+ try {
15
+ onProgress?.('fetching_tables');
16
+ const tablesResult = await pool.query(`
17
+ SELECT
18
+ c.relname as table_name,
19
+ n.nspname as table_schema,
20
+ c.reltuples::bigint as row_count,
21
+ c.relispartition as is_partition,
22
+ c.relkind = 'p' as is_partitioned,
23
+ CASE
24
+ WHEN pt.partstrat = 'l' THEN 'LIST'
25
+ WHEN pt.partstrat = 'r' THEN 'RANGE'
26
+ WHEN pt.partstrat = 'h' THEN 'HASH'
27
+ END as partition_type,
28
+ -- Get partition key columns
29
+ (
30
+ SELECT array_agg(a.attname ORDER BY array_position(pt.partattrs, a.attnum))
31
+ FROM pg_attribute a
32
+ WHERE a.attrelid = c.oid
33
+ AND a.attnum = ANY(pt.partattrs)
34
+ ) as partition_key
35
+ FROM pg_class c
36
+ JOIN pg_namespace n ON n.oid = c.relnamespace
37
+ LEFT JOIN pg_partitioned_table pt ON pt.partrelid = c.oid
38
+ WHERE n.nspname = 'public'
39
+ AND c.relkind IN ('r', 'p') -- Regular and partitioned tables
40
+ AND NOT c.relispartition
41
+ ORDER BY c.relname;
42
+ `);
43
+ onProgress?.('fetching_columns');
44
+ const columnsResult = await pool.query(`
45
+ SELECT
46
+ c.table_name,
47
+ c.column_name,
48
+ c.data_type,
49
+ c.udt_name,
50
+ c.is_nullable = 'YES' as is_nullable,
51
+ c.column_default,
52
+ c.character_maximum_length,
53
+ c.numeric_precision,
54
+ c.numeric_scale,
55
+ c.is_generated = 'ALWAYS' as is_generated,
56
+ c.generation_expression,
57
+ c.identity_generation,
58
+ col_description(pgc.oid, c.ordinal_position::int) as column_comment
59
+ FROM information_schema.columns c
60
+ JOIN pg_class pgc ON pgc.relname = c.table_name
61
+ JOIN pg_namespace pgn ON pgn.oid = pgc.relnamespace AND pgn.nspname = c.table_schema
62
+ WHERE c.table_schema = 'public'
63
+ ORDER BY c.table_name, c.ordinal_position;
64
+ `);
65
+ const constraintsResult = await pool.query(`
66
+ SELECT
67
+ tc.table_name,
68
+ tc.constraint_name,
69
+ tc.constraint_type,
70
+ array_agg(DISTINCT kcu.column_name ORDER BY kcu.column_name) as columns,
71
+ ccu.table_name as referenced_table,
72
+ array_agg(DISTINCT ccu.column_name) as referenced_columns,
73
+ rc.update_rule as on_update,
74
+ rc.delete_rule as on_delete
75
+ FROM information_schema.table_constraints tc
76
+ JOIN information_schema.key_column_usage kcu
77
+ ON tc.constraint_name = kcu.constraint_name AND tc.table_schema = kcu.table_schema
78
+ LEFT JOIN information_schema.constraint_column_usage ccu
79
+ ON tc.constraint_name = ccu.constraint_name AND tc.constraint_type = 'FOREIGN KEY'
80
+ LEFT JOIN information_schema.referential_constraints rc
81
+ ON tc.constraint_name = rc.constraint_name AND tc.table_schema = rc.constraint_schema
82
+ WHERE tc.table_schema = 'public'
83
+ GROUP BY tc.table_name, tc.constraint_name, tc.constraint_type, ccu.table_name, rc.update_rule, rc.delete_rule;
84
+ `);
85
+ const indexesResult = await pool.query(`
86
+ SELECT
87
+ t.relname as table_name,
88
+ i.relname as index_name,
89
+ am.amname as index_type,
90
+ ix.indisunique as is_unique,
91
+ ix.indisprimary as is_primary,
92
+ pg_get_indexdef(ix.indexrelid) as index_definition,
93
+ pg_get_expr(ix.indpred, ix.indrelid) as where_clause,
94
+ pg_get_expr(ix.indexprs, ix.indrelid) as expression,
95
+ array_agg(a.attname ORDER BY array_position(ix.indkey, a.attnum)) FILTER (WHERE a.attnum > 0) as columns
96
+ FROM pg_index ix
97
+ JOIN pg_class t ON t.oid = ix.indrelid
98
+ JOIN pg_class i ON i.oid = ix.indexrelid
99
+ JOIN pg_namespace n ON n.oid = t.relnamespace
100
+ JOIN pg_am am ON am.oid = i.relam
101
+ LEFT JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = ANY(ix.indkey)
102
+ WHERE n.nspname = 'public'
103
+ AND NOT ix.indisprimary
104
+ GROUP BY t.relname, i.relname, am.amname, ix.indisunique, ix.indisprimary, ix.indexrelid, ix.indpred, ix.indexprs, ix.indrelid;
105
+ `);
106
+ const checksResult = await pool.query(`
107
+ SELECT
108
+ c.relname as table_name,
109
+ con.conname as constraint_name,
110
+ pg_get_constraintdef(con.oid) as definition
111
+ FROM pg_constraint con
112
+ JOIN pg_class c ON c.oid = con.conrelid
113
+ JOIN pg_namespace n ON n.oid = c.relnamespace
114
+ WHERE n.nspname = 'public' AND con.contype = 'c';
115
+ `);
116
+ onProgress?.('fetching_enums');
117
+ const enumsResult = await pool.query(`
118
+ SELECT
119
+ t.typname as enum_name,
120
+ n.nspname as enum_schema,
121
+ array_agg(e.enumlabel ORDER BY e.enumsortorder) as enum_values
122
+ FROM pg_type t
123
+ JOIN pg_enum e ON t.oid = e.enumtypid
124
+ JOIN pg_namespace n ON t.typnamespace = n.oid
125
+ WHERE n.nspname = 'public'
126
+ GROUP BY t.typname, n.nspname
127
+ ORDER BY t.typname;
128
+ `);
129
+ const enums = enumsResult.rows.map(row => ({
130
+ name: row.enum_name,
131
+ schema: row.enum_schema,
132
+ values: row.enum_values || [],
133
+ }));
134
+ onProgress?.('processing');
135
+ const columnsByTable = new Map();
136
+ const constraintsByTable = new Map();
137
+ const indexesByTable = new Map();
138
+ const checksByTable = new Map();
139
+ for (const col of columnsResult.rows) {
140
+ if (!columnsByTable.has(col.table_name)) {
141
+ columnsByTable.set(col.table_name, []);
142
+ }
143
+ columnsByTable.get(col.table_name).push({
144
+ name: col.column_name,
145
+ dataType: col.udt_name || col.data_type,
146
+ isNullable: col.is_nullable,
147
+ defaultValue: col.column_default,
148
+ isPrimaryKey: false,
149
+ isUnique: false,
150
+ maxLength: col.character_maximum_length,
151
+ precision: col.numeric_precision,
152
+ scale: col.numeric_scale,
153
+ references: null,
154
+ comment: col.column_comment,
155
+ isGenerated: col.is_generated || false,
156
+ generationExpression: col.generation_expression || null,
157
+ identityGeneration: col.identity_generation || null,
158
+ });
159
+ }
160
+ for (const con of constraintsResult.rows) {
161
+ if (!constraintsByTable.has(con.table_name)) {
162
+ constraintsByTable.set(con.table_name, new Map());
163
+ }
164
+ constraintsByTable.get(con.table_name).set(con.constraint_name, {
165
+ type: con.constraint_type,
166
+ columns: con.columns,
167
+ });
168
+ const columns = columnsByTable.get(con.table_name);
169
+ if (columns) {
170
+ for (const colName of con.columns) {
171
+ const col = columns.find(c => c.name === colName);
172
+ if (col) {
173
+ if (con.constraint_type === 'PRIMARY KEY')
174
+ col.isPrimaryKey = true;
175
+ if (con.constraint_type === 'UNIQUE')
176
+ col.isUnique = true;
177
+ if (con.constraint_type === 'FOREIGN KEY' && con.referenced_table) {
178
+ col.references = {
179
+ table: con.referenced_table,
180
+ column: con.referenced_columns?.[0] || 'id',
181
+ onDelete: con.on_delete || 'NO ACTION',
182
+ onUpdate: con.on_update || 'NO ACTION',
183
+ };
184
+ }
185
+ }
186
+ }
187
+ }
188
+ }
189
+ for (const idx of indexesResult.rows) {
190
+ if (!indexesByTable.has(idx.table_name)) {
191
+ indexesByTable.set(idx.table_name, []);
192
+ }
193
+ const opClassMatches = idx.index_definition?.match(/\b([a-z_]+_ops)\b/gi) ?? [];
194
+ const operatorClasses = Array.from(new Set(opClassMatches));
195
+ indexesByTable.get(idx.table_name).push({
196
+ name: idx.index_name,
197
+ columns: idx.columns || [],
198
+ isUnique: idx.is_unique,
199
+ isPrimary: idx.is_primary,
200
+ type: idx.index_type,
201
+ definition: idx.index_definition || undefined,
202
+ whereClause: idx.where_clause || null,
203
+ expression: idx.expression || null,
204
+ operatorClasses: operatorClasses.length > 0 ? operatorClasses : undefined,
205
+ });
206
+ }
207
+ for (const chk of checksResult.rows) {
208
+ if (!checksByTable.has(chk.table_name)) {
209
+ checksByTable.set(chk.table_name, []);
210
+ }
211
+ checksByTable.get(chk.table_name).push({
212
+ name: chk.constraint_name,
213
+ type: 'CHECK',
214
+ columns: [],
215
+ definition: chk.definition,
216
+ });
217
+ }
218
+ const tables = [];
219
+ for (const row of tablesResult.rows) {
220
+ const tableName = row.table_name;
221
+ if (tableName.startsWith('_relq'))
222
+ continue;
223
+ tables.push({
224
+ name: tableName,
225
+ schema: row.table_schema,
226
+ columns: columnsByTable.get(tableName) || [],
227
+ indexes: indexesByTable.get(tableName) || [],
228
+ constraints: checksByTable.get(tableName) || [],
229
+ rowCount: parseInt(row.row_count) || 0,
230
+ isPartitioned: row.is_partitioned || false,
231
+ partitionType: row.partition_type,
232
+ partitionKey: row.partition_key || [],
233
+ });
234
+ }
235
+ onProgress?.('fetching_partitions');
236
+ const partitionsResult = await pool.query(`
237
+ SELECT
238
+ child.relname as partition_name,
239
+ parent.relname as parent_table,
240
+ pg_get_expr(child.relpartbound, child.oid) as partition_bound
241
+ FROM pg_class child
242
+ JOIN pg_inherits inh ON child.oid = inh.inhrelid
243
+ JOIN pg_class parent ON inh.inhparent = parent.oid
244
+ JOIN pg_namespace n ON n.oid = child.relnamespace
245
+ WHERE n.nspname = 'public'
246
+ AND child.relispartition = true
247
+ ORDER BY parent.relname, child.relname;
248
+ `);
249
+ const partitions = partitionsResult.rows.map(row => ({
250
+ name: row.partition_name,
251
+ parentTable: row.parent_table,
252
+ partitionBound: row.partition_bound,
253
+ partitionType: 'LIST',
254
+ partitionKey: [],
255
+ }));
256
+ const partitionsByParent = new Map();
257
+ for (const partition of partitions) {
258
+ if (!partitionsByParent.has(partition.parentTable)) {
259
+ partitionsByParent.set(partition.parentTable, []);
260
+ }
261
+ partitionsByParent.get(partition.parentTable).push(partition);
262
+ }
263
+ for (const table of tables) {
264
+ if (table.isPartitioned) {
265
+ table.childPartitions = partitionsByParent.get(table.name) || [];
266
+ }
267
+ }
268
+ onProgress?.('fetching_extensions');
269
+ const extensionsResult = await pool.query(`
270
+ SELECT extname FROM pg_extension WHERE extname != 'plpgsql';
271
+ `);
272
+ const extensions = extensionsResult.rows.map(r => r.extname);
273
+ let functions = [];
274
+ if (includeFunctions) {
275
+ onProgress?.('fetching_functions');
276
+ const functionsResult = await pool.query(`
277
+ SELECT
278
+ p.proname as name,
279
+ n.nspname as schema,
280
+ pg_get_function_result(p.oid) as return_type,
281
+ pg_get_function_arguments(p.oid) as arg_types,
282
+ l.lanname as language,
283
+ pg_get_functiondef(p.oid) as definition,
284
+ p.prokind = 'a' as is_aggregate,
285
+ p.provolatile as volatility
286
+ FROM pg_proc p
287
+ JOIN pg_namespace n ON p.pronamespace = n.oid
288
+ JOIN pg_language l ON p.prolang = l.oid
289
+ WHERE n.nspname = 'public'
290
+ AND p.prokind IN ('f', 'a')
291
+ ORDER BY p.proname;
292
+ `);
293
+ functions = functionsResult.rows.map(f => ({
294
+ name: f.name,
295
+ schema: f.schema,
296
+ returnType: f.return_type,
297
+ argTypes: f.arg_types ? f.arg_types.split(', ') : [],
298
+ language: f.language,
299
+ definition: f.definition || '',
300
+ isAggregate: f.is_aggregate || false,
301
+ volatility: f.volatility === 'i' ? 'IMMUTABLE' : f.volatility === 's' ? 'STABLE' : 'VOLATILE',
302
+ }));
303
+ }
304
+ let triggers = [];
305
+ if (includeTriggers) {
306
+ onProgress?.('fetching_triggers');
307
+ const triggersResult = await pool.query(`
308
+ SELECT
309
+ t.tgname as name,
310
+ c.relname as table_name,
311
+ CASE
312
+ WHEN t.tgtype & 2 > 0 THEN 'BEFORE'
313
+ WHEN t.tgtype & 64 > 0 THEN 'INSTEAD OF'
314
+ ELSE 'AFTER'
315
+ END as timing,
316
+ CASE
317
+ WHEN t.tgtype & 4 > 0 THEN 'INSERT'
318
+ WHEN t.tgtype & 8 > 0 THEN 'DELETE'
319
+ WHEN t.tgtype & 16 > 0 THEN 'UPDATE'
320
+ ELSE 'UNKNOWN'
321
+ END as event,
322
+ p.proname as function_name,
323
+ pg_get_triggerdef(t.oid) as definition,
324
+ t.tgenabled != 'D' as is_enabled
325
+ FROM pg_trigger t
326
+ JOIN pg_class c ON t.tgrelid = c.oid
327
+ JOIN pg_namespace n ON c.relnamespace = n.oid
328
+ JOIN pg_proc p ON t.tgfoid = p.oid
329
+ WHERE n.nspname = 'public'
330
+ AND NOT t.tgisinternal
331
+ ORDER BY c.relname, t.tgname;
332
+ `);
333
+ triggers = triggersResult.rows.map(t => ({
334
+ name: t.name,
335
+ tableName: t.table_name,
336
+ timing: t.timing,
337
+ event: t.event,
338
+ functionName: t.function_name,
339
+ definition: t.definition || '',
340
+ isEnabled: t.is_enabled,
341
+ }));
342
+ }
343
+ onProgress?.('complete');
344
+ return {
345
+ tables,
346
+ enums,
347
+ domains: [],
348
+ compositeTypes: [],
349
+ sequences: [],
350
+ functions,
351
+ triggers,
352
+ policies: [],
353
+ partitions,
354
+ foreignServers: [],
355
+ foreignTables: [],
356
+ extensions,
357
+ };
358
+ }
359
+ finally {
360
+ await pool.end();
361
+ }
362
+ }