af-db-ts 2.0.19 → 2.0.73

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 (307) hide show
  1. package/dist/cjs/__tests__/db/ms/@gen-types/test-table_schema.js +3 -0
  2. package/dist/cjs/__tests__/db/ms/@gen-types/test-table_schema.js.map +1 -0
  3. package/dist/cjs/__tests__/db/ms/ddl/column-schema-for-test-table-schema-ms.json +216 -0
  4. package/dist/cjs/__tests__/db/ms/ms-get-sql.spec.js +190 -0
  5. package/dist/cjs/__tests__/db/ms/ms-get-sql.spec.js.map +1 -0
  6. package/dist/cjs/__tests__/db/ms/ms-prepare-sql-value.spec.js +584 -0
  7. package/dist/cjs/__tests__/db/ms/ms-prepare-sql-value.spec.js.map +1 -0
  8. package/dist/cjs/__tests__/db/ms/ms-table-schema.spec.js +107 -0
  9. package/dist/cjs/__tests__/db/ms/ms-table-schema.spec.js.map +1 -0
  10. package/dist/cjs/__tests__/db/pg/@gen-types/test-hard_case.js +3 -0
  11. package/dist/cjs/__tests__/db/pg/@gen-types/test-hard_case.js.map +1 -0
  12. package/dist/cjs/__tests__/db/pg/@gen-types/test-only_one_serial.js +3 -0
  13. package/dist/cjs/__tests__/db/pg/@gen-types/test-only_one_serial.js.map +1 -0
  14. package/dist/cjs/__tests__/db/pg/@gen-types/test-only_one_uniq.js +3 -0
  15. package/dist/cjs/__tests__/db/pg/@gen-types/test-only_one_uniq.js.map +1 -0
  16. package/dist/cjs/__tests__/db/pg/@gen-types/test-serial_and_uniq.js +3 -0
  17. package/dist/cjs/__tests__/db/pg/@gen-types/test-serial_and_uniq.js.map +1 -0
  18. package/dist/cjs/__tests__/db/pg/@gen-types/test-table_schema.js +3 -0
  19. package/dist/cjs/__tests__/db/pg/@gen-types/test-table_schema.js.map +1 -0
  20. package/dist/cjs/__tests__/db/pg/ddl/column-schema-for-test-table-schema-pg.json +170 -0
  21. package/dist/cjs/__tests__/db/pg/gen-table-interfaces-4-test-pg.js +36 -0
  22. package/dist/cjs/__tests__/db/pg/gen-table-interfaces-4-test-pg.js.map +1 -0
  23. package/dist/cjs/__tests__/db/pg/pg-get-sql.spec.js +261 -0
  24. package/dist/cjs/__tests__/db/pg/pg-get-sql.spec.js.map +1 -0
  25. package/dist/cjs/__tests__/db/pg/pg-insert.spec.js +294 -0
  26. package/dist/cjs/__tests__/db/pg/pg-insert.spec.js.map +1 -0
  27. package/dist/cjs/__tests__/db/pg/pg-prepare-sql-value.spec.js +575 -0
  28. package/dist/cjs/__tests__/db/pg/pg-prepare-sql-value.spec.js.map +1 -0
  29. package/dist/cjs/__tests__/db/pg/pg-table-schema.spec.js +117 -0
  30. package/dist/cjs/__tests__/db/pg/pg-table-schema.spec.js.map +1 -0
  31. package/dist/cjs/src/@types/i-data-types-ms.js +3 -0
  32. package/dist/cjs/src/@types/i-data-types-ms.js.map +1 -0
  33. package/dist/cjs/src/@types/i-data-types-pg.js +7 -0
  34. package/dist/cjs/src/@types/i-data-types-pg.js.map +1 -0
  35. package/dist/cjs/src/@types/i-pg.js +0 -21
  36. package/dist/cjs/src/@types/i-pg.js.map +1 -1
  37. package/dist/cjs/src/common.js +6 -5
  38. package/dist/cjs/src/common.js.map +1 -1
  39. package/dist/cjs/src/index.js +75 -54
  40. package/dist/cjs/src/index.js.map +1 -1
  41. package/dist/cjs/src/ms/gen-table-interfaces-ms.js +64 -0
  42. package/dist/cjs/src/ms/gen-table-interfaces-ms.js.map +1 -0
  43. package/dist/cjs/src/ms/get-sql/insert.js +37 -0
  44. package/dist/cjs/src/ms/get-sql/insert.js.map +1 -0
  45. package/dist/cjs/src/ms/get-sql/merge.js +93 -0
  46. package/dist/cjs/src/ms/get-sql/merge.js.map +1 -0
  47. package/dist/cjs/src/ms/get-sql/update.js +32 -0
  48. package/dist/cjs/src/ms/get-sql/update.js.map +1 -0
  49. package/dist/cjs/src/{mssql → ms}/pool-ms.js +6 -23
  50. package/dist/cjs/src/ms/pool-ms.js.map +1 -0
  51. package/dist/cjs/src/ms/prepare-value.js +178 -0
  52. package/dist/cjs/src/ms/prepare-value.js.map +1 -0
  53. package/dist/cjs/src/{mssql → ms}/query-ms.js +1 -1
  54. package/dist/cjs/src/ms/query-ms.js.map +1 -0
  55. package/dist/cjs/src/ms/table-schema-ms.js +241 -0
  56. package/dist/cjs/src/ms/table-schema-ms.js.map +1 -0
  57. package/dist/cjs/src/ms/utils-ms.js +92 -0
  58. package/dist/cjs/src/ms/utils-ms.js.map +1 -0
  59. package/dist/cjs/src/ms/wrap-transaction-ms.js +32 -0
  60. package/dist/cjs/src/ms/wrap-transaction-ms.js.map +1 -0
  61. package/dist/cjs/src/pg/gen-table-interfaces-pg.js +83 -0
  62. package/dist/cjs/src/pg/gen-table-interfaces-pg.js.map +1 -0
  63. package/dist/cjs/src/pg/get-sql/insert.js +38 -0
  64. package/dist/cjs/src/pg/get-sql/insert.js.map +1 -0
  65. package/dist/cjs/src/pg/get-sql/merge.js +60 -0
  66. package/dist/cjs/src/pg/get-sql/merge.js.map +1 -0
  67. package/dist/cjs/src/pg/get-sql/update.js +32 -0
  68. package/dist/cjs/src/pg/get-sql/update.js.map +1 -0
  69. package/dist/cjs/src/pg/{insert.js → insert-pg.js} +10 -10
  70. package/dist/cjs/src/pg/insert-pg.js.map +1 -0
  71. package/dist/cjs/src/pg/is-table-or-view-exists.js +1 -2
  72. package/dist/cjs/src/pg/is-table-or-view-exists.js.map +1 -1
  73. package/dist/cjs/src/pg/{pg-pool.js → pool-pg.js} +6 -7
  74. package/dist/cjs/src/pg/pool-pg.js.map +1 -0
  75. package/dist/cjs/src/pg/prepare-value.js +116 -69
  76. package/dist/cjs/src/pg/prepare-value.js.map +1 -1
  77. package/dist/cjs/src/pg/query-pg.js +2 -2
  78. package/dist/cjs/src/pg/query-pg.js.map +1 -1
  79. package/dist/cjs/src/pg/table-schema-pg.js +183 -0
  80. package/dist/cjs/src/pg/table-schema-pg.js.map +1 -0
  81. package/dist/cjs/src/pg/utils-pg.js +99 -0
  82. package/dist/cjs/src/pg/utils-pg.js.map +1 -0
  83. package/dist/cjs/src/utils/utils-array.js +152 -0
  84. package/dist/cjs/src/utils/utils-array.js.map +1 -0
  85. package/dist/cjs/src/utils/utils-dt.js +121 -0
  86. package/dist/cjs/src/utils/utils-dt.js.map +1 -0
  87. package/dist/cjs/src/utils/utils-num.js +127 -0
  88. package/dist/cjs/src/utils/utils-num.js.map +1 -0
  89. package/dist/cjs/src/utils/utils.js +66 -0
  90. package/dist/cjs/src/utils/utils.js.map +1 -0
  91. package/dist/esm/src/@types/i-data-types-ms.js +2 -0
  92. package/dist/esm/src/@types/i-data-types-ms.js.map +1 -0
  93. package/dist/esm/src/@types/i-data-types-pg.js +6 -0
  94. package/dist/esm/src/@types/i-data-types-pg.js.map +1 -0
  95. package/dist/esm/src/@types/i-pg.js +1 -20
  96. package/dist/esm/src/@types/i-pg.js.map +1 -1
  97. package/dist/esm/src/common.js +3 -2
  98. package/dist/esm/src/common.js.map +1 -1
  99. package/dist/esm/src/index.js +24 -15
  100. package/dist/esm/src/index.js.map +1 -1
  101. package/dist/esm/src/ms/gen-table-interfaces-ms.js +36 -0
  102. package/dist/esm/src/ms/gen-table-interfaces-ms.js.map +1 -0
  103. package/dist/esm/src/ms/get-sql/insert.js +33 -0
  104. package/dist/esm/src/ms/get-sql/insert.js.map +1 -0
  105. package/dist/esm/src/ms/get-sql/merge.js +89 -0
  106. package/dist/esm/src/ms/get-sql/merge.js.map +1 -0
  107. package/dist/esm/src/ms/get-sql/update.js +28 -0
  108. package/dist/esm/src/ms/get-sql/update.js.map +1 -0
  109. package/dist/esm/src/{mssql → ms}/pool-ms.js +5 -20
  110. package/dist/esm/src/ms/pool-ms.js.map +1 -0
  111. package/dist/esm/src/ms/prepare-value.js +149 -0
  112. package/dist/esm/src/ms/prepare-value.js.map +1 -0
  113. package/dist/esm/src/{mssql → ms}/query-ms.js +1 -1
  114. package/dist/esm/src/ms/query-ms.js.map +1 -0
  115. package/dist/esm/src/ms/table-schema-ms.js +213 -0
  116. package/dist/esm/src/ms/table-schema-ms.js.map +1 -0
  117. package/dist/esm/src/ms/utils-ms.js +65 -0
  118. package/dist/esm/src/ms/utils-ms.js.map +1 -0
  119. package/dist/esm/src/ms/wrap-transaction-ms.js +28 -0
  120. package/dist/esm/src/ms/wrap-transaction-ms.js.map +1 -0
  121. package/dist/esm/src/pg/gen-table-interfaces-pg.js +55 -0
  122. package/dist/esm/src/pg/gen-table-interfaces-pg.js.map +1 -0
  123. package/dist/esm/src/pg/get-sql/insert.js +34 -0
  124. package/dist/esm/src/pg/get-sql/insert.js.map +1 -0
  125. package/dist/esm/src/pg/get-sql/merge.js +56 -0
  126. package/dist/esm/src/pg/get-sql/merge.js.map +1 -0
  127. package/dist/esm/src/pg/get-sql/update.js +28 -0
  128. package/dist/esm/src/pg/get-sql/update.js.map +1 -0
  129. package/dist/esm/src/pg/{insert.js → insert-pg.js} +10 -10
  130. package/dist/esm/src/pg/insert-pg.js.map +1 -0
  131. package/dist/esm/src/pg/is-table-or-view-exists.js +1 -2
  132. package/dist/esm/src/pg/is-table-or-view-exists.js.map +1 -1
  133. package/dist/esm/src/pg/{pg-pool.js → pool-pg.js} +6 -7
  134. package/dist/esm/src/pg/pool-pg.js.map +1 -0
  135. package/dist/esm/src/pg/prepare-value.js +113 -67
  136. package/dist/esm/src/pg/prepare-value.js.map +1 -1
  137. package/dist/esm/src/pg/query-pg.js +1 -1
  138. package/dist/esm/src/pg/query-pg.js.map +1 -1
  139. package/dist/esm/src/pg/table-schema-pg.js +178 -0
  140. package/dist/esm/src/pg/table-schema-pg.js.map +1 -0
  141. package/dist/esm/src/pg/utils-pg.js +93 -0
  142. package/dist/esm/src/pg/utils-pg.js.map +1 -0
  143. package/dist/esm/src/utils/utils-array.js +125 -0
  144. package/dist/esm/src/utils/utils-array.js.map +1 -0
  145. package/dist/esm/src/utils/utils-dt.js +114 -0
  146. package/dist/esm/src/utils/utils-dt.js.map +1 -0
  147. package/dist/esm/src/utils/utils-num.js +117 -0
  148. package/dist/esm/src/utils/utils-num.js.map +1 -0
  149. package/dist/esm/src/utils/utils.js +58 -0
  150. package/dist/esm/src/utils/utils.js.map +1 -0
  151. package/dist/types/src/@types/i-common.d.ts +35 -3
  152. package/dist/types/src/@types/i-common.d.ts.map +1 -1
  153. package/dist/types/src/@types/i-data-types-ms.d.ts +3 -0
  154. package/dist/types/src/@types/i-data-types-ms.d.ts.map +1 -0
  155. package/dist/types/src/@types/i-data-types-pg.d.ts +35 -0
  156. package/dist/types/src/@types/i-data-types-pg.d.ts.map +1 -0
  157. package/dist/types/src/@types/i-ms.d.ts +26 -126
  158. package/dist/types/src/@types/i-ms.d.ts.map +1 -1
  159. package/dist/types/src/@types/i-pg.d.ts +11 -35
  160. package/dist/types/src/@types/i-pg.d.ts.map +1 -1
  161. package/dist/types/src/common.d.ts +1 -0
  162. package/dist/types/src/common.d.ts.map +1 -1
  163. package/dist/types/src/index.d.ts +28 -16
  164. package/dist/types/src/index.d.ts.map +1 -1
  165. package/dist/types/src/ms/gen-table-interfaces-ms.d.ts +3 -0
  166. package/dist/types/src/ms/gen-table-interfaces-ms.d.ts.map +1 -0
  167. package/dist/types/src/ms/get-sql/insert.d.ts +9 -0
  168. package/dist/types/src/ms/get-sql/insert.d.ts.map +1 -0
  169. package/dist/types/src/ms/get-sql/merge.d.ts +14 -0
  170. package/dist/types/src/ms/get-sql/merge.d.ts.map +1 -0
  171. package/dist/types/src/ms/get-sql/update.d.ts +9 -0
  172. package/dist/types/src/ms/get-sql/update.d.ts.map +1 -0
  173. package/dist/types/src/{mssql → ms}/pool-ms.d.ts +0 -8
  174. package/dist/types/src/ms/pool-ms.d.ts.map +1 -0
  175. package/dist/types/src/ms/prepare-value.d.ts +12 -0
  176. package/dist/types/src/ms/prepare-value.d.ts.map +1 -0
  177. package/dist/types/src/ms/query-ms.d.ts +3 -0
  178. package/dist/types/src/ms/query-ms.d.ts.map +1 -0
  179. package/dist/types/src/ms/table-schema-ms.d.ts +9 -0
  180. package/dist/types/src/ms/table-schema-ms.d.ts.map +1 -0
  181. package/dist/types/src/ms/utils-ms.d.ts +3 -0
  182. package/dist/types/src/ms/utils-ms.d.ts.map +1 -0
  183. package/dist/types/src/ms/wrap-transaction-ms.d.ts +5 -0
  184. package/dist/types/src/ms/wrap-transaction-ms.d.ts.map +1 -0
  185. package/dist/types/src/pg/gen-table-interfaces-pg.d.ts +3 -0
  186. package/dist/types/src/pg/gen-table-interfaces-pg.d.ts.map +1 -0
  187. package/dist/types/src/pg/get-sql/insert.d.ts +9 -0
  188. package/dist/types/src/pg/get-sql/insert.d.ts.map +1 -0
  189. package/dist/types/src/pg/get-sql/merge.d.ts +10 -0
  190. package/dist/types/src/pg/get-sql/merge.d.ts.map +1 -0
  191. package/dist/types/src/pg/get-sql/update.d.ts +9 -0
  192. package/dist/types/src/pg/get-sql/update.d.ts.map +1 -0
  193. package/dist/types/src/pg/{insert.d.ts → insert-pg.d.ts} +3 -3
  194. package/dist/types/src/pg/insert-pg.d.ts.map +1 -0
  195. package/dist/types/src/pg/{pg-pool.d.ts → pool-pg.d.ts} +1 -1
  196. package/dist/types/src/pg/{pg-pool.d.ts.map → pool-pg.d.ts.map} +1 -1
  197. package/dist/types/src/pg/prepare-value.d.ts +3 -1
  198. package/dist/types/src/pg/prepare-value.d.ts.map +1 -1
  199. package/dist/types/src/pg/query-pg.d.ts +3 -2
  200. package/dist/types/src/pg/query-pg.d.ts.map +1 -1
  201. package/dist/types/src/pg/table-schema-pg.d.ts +12 -0
  202. package/dist/types/src/pg/table-schema-pg.d.ts.map +1 -0
  203. package/dist/types/src/pg/utils-pg.d.ts +5 -0
  204. package/dist/types/src/pg/utils-pg.d.ts.map +1 -0
  205. package/dist/types/src/utils/utils-array.d.ts +5 -0
  206. package/dist/types/src/utils/utils-array.d.ts.map +1 -0
  207. package/dist/types/src/utils/utils-dt.d.ts +15 -0
  208. package/dist/types/src/utils/utils-dt.d.ts.map +1 -0
  209. package/dist/types/src/utils/utils-num.d.ts +9 -0
  210. package/dist/types/src/utils/utils-num.d.ts.map +1 -0
  211. package/dist/types/src/utils/utils.d.ts +18 -0
  212. package/dist/types/src/utils/utils.d.ts.map +1 -0
  213. package/package.json +13 -13
  214. package/src/@types/i-common.ts +42 -4
  215. package/src/@types/i-data-types-ms.ts +81 -0
  216. package/src/@types/i-data-types-pg.ts +120 -0
  217. package/src/@types/i-ms.ts +29 -153
  218. package/src/@types/i-pg.ts +11 -36
  219. package/src/common.ts +4 -2
  220. package/src/index.ts +101 -59
  221. package/src/ms/gen-table-interfaces-ms.ts +52 -0
  222. package/src/ms/get-sql/insert.ts +45 -0
  223. package/src/ms/get-sql/merge.ts +118 -0
  224. package/src/ms/get-sql/update.ts +46 -0
  225. package/src/{mssql → ms}/pool-ms.ts +0 -16
  226. package/src/ms/prepare-value.ts +175 -0
  227. package/src/{mssql → ms}/query-ms.ts +2 -2
  228. package/src/ms/table-schema-ms.ts +231 -0
  229. package/src/ms/utils-ms.ts +72 -0
  230. package/src/ms/wrap-transaction-ms.ts +27 -0
  231. package/src/pg/gen-table-interfaces-pg.ts +74 -0
  232. package/src/pg/get-sql/insert.ts +46 -0
  233. package/src/pg/get-sql/merge.ts +70 -0
  234. package/src/pg/get-sql/update.ts +46 -0
  235. package/src/pg/{insert.ts → insert-pg.ts} +9 -9
  236. package/src/pg/prepare-value.ts +129 -67
  237. package/src/pg/query-pg.ts +4 -3
  238. package/src/pg/table-schema-pg.ts +196 -0
  239. package/src/pg/utils-pg.ts +97 -0
  240. package/src/utils/utils-array.ts +133 -0
  241. package/src/utils/utils-dt.ts +123 -0
  242. package/src/utils/utils-num.ts +131 -0
  243. package/src/utils/utils.ts +64 -0
  244. package/dist/cjs/__tests__/02_getValueForSqlMs.spec.js +0 -50
  245. package/dist/cjs/__tests__/02_getValueForSqlMs.spec.js.map +0 -1
  246. package/dist/cjs/src/mssql/get-value-for-sql.js +0 -277
  247. package/dist/cjs/src/mssql/get-value-for-sql.js.map +0 -1
  248. package/dist/cjs/src/mssql/pool-ms.js.map +0 -1
  249. package/dist/cjs/src/mssql/query-ms.js.map +0 -1
  250. package/dist/cjs/src/mssql/sql.js +0 -427
  251. package/dist/cjs/src/mssql/sql.js.map +0 -1
  252. package/dist/cjs/src/mssql/utils.js +0 -36
  253. package/dist/cjs/src/mssql/utils.js.map +0 -1
  254. package/dist/cjs/src/pg/get-merge-sql.js +0 -52
  255. package/dist/cjs/src/pg/get-merge-sql.js.map +0 -1
  256. package/dist/cjs/src/pg/get-update-sql.js +0 -30
  257. package/dist/cjs/src/pg/get-update-sql.js.map +0 -1
  258. package/dist/cjs/src/pg/insert.js.map +0 -1
  259. package/dist/cjs/src/pg/pg-pool.js.map +0 -1
  260. package/dist/cjs/src/pg/table-schema.js +0 -179
  261. package/dist/cjs/src/pg/table-schema.js.map +0 -1
  262. package/dist/cjs/src/utils.js +0 -17
  263. package/dist/cjs/src/utils.js.map +0 -1
  264. package/dist/esm/src/mssql/get-value-for-sql.js +0 -272
  265. package/dist/esm/src/mssql/get-value-for-sql.js.map +0 -1
  266. package/dist/esm/src/mssql/pool-ms.js.map +0 -1
  267. package/dist/esm/src/mssql/query-ms.js.map +0 -1
  268. package/dist/esm/src/mssql/sql.js +0 -390
  269. package/dist/esm/src/mssql/sql.js.map +0 -1
  270. package/dist/esm/src/mssql/utils.js +0 -31
  271. package/dist/esm/src/mssql/utils.js.map +0 -1
  272. package/dist/esm/src/pg/get-merge-sql.js +0 -48
  273. package/dist/esm/src/pg/get-merge-sql.js.map +0 -1
  274. package/dist/esm/src/pg/get-update-sql.js +0 -26
  275. package/dist/esm/src/pg/get-update-sql.js.map +0 -1
  276. package/dist/esm/src/pg/insert.js.map +0 -1
  277. package/dist/esm/src/pg/pg-pool.js.map +0 -1
  278. package/dist/esm/src/pg/table-schema.js +0 -174
  279. package/dist/esm/src/pg/table-schema.js.map +0 -1
  280. package/dist/esm/src/utils.js +0 -14
  281. package/dist/esm/src/utils.js.map +0 -1
  282. package/dist/types/src/mssql/get-value-for-sql.d.ts +0 -11
  283. package/dist/types/src/mssql/get-value-for-sql.d.ts.map +0 -1
  284. package/dist/types/src/mssql/pool-ms.d.ts.map +0 -1
  285. package/dist/types/src/mssql/query-ms.d.ts +0 -3
  286. package/dist/types/src/mssql/query-ms.d.ts.map +0 -1
  287. package/dist/types/src/mssql/sql.d.ts +0 -57
  288. package/dist/types/src/mssql/sql.d.ts.map +0 -1
  289. package/dist/types/src/mssql/utils.d.ts +0 -10
  290. package/dist/types/src/mssql/utils.d.ts.map +0 -1
  291. package/dist/types/src/pg/get-merge-sql.d.ts +0 -9
  292. package/dist/types/src/pg/get-merge-sql.d.ts.map +0 -1
  293. package/dist/types/src/pg/get-update-sql.d.ts +0 -3
  294. package/dist/types/src/pg/get-update-sql.d.ts.map +0 -1
  295. package/dist/types/src/pg/insert.d.ts.map +0 -1
  296. package/dist/types/src/pg/table-schema.d.ts +0 -12
  297. package/dist/types/src/pg/table-schema.d.ts.map +0 -1
  298. package/dist/types/src/utils.d.ts +0 -9
  299. package/dist/types/src/utils.d.ts.map +0 -1
  300. package/src/mssql/get-value-for-sql.ts +0 -325
  301. package/src/mssql/sql.ts +0 -430
  302. package/src/mssql/utils.ts +0 -31
  303. package/src/pg/get-merge-sql.ts +0 -62
  304. package/src/pg/get-update-sql.ts +0 -32
  305. package/src/pg/table-schema.ts +0 -189
  306. package/src/utils.ts +0 -14
  307. /package/src/pg/{pg-pool.ts → pool-pg.ts} +0 -0
@@ -0,0 +1,70 @@
1
+ import { getTableSchemaPg } from '../table-schema-pg';
2
+ import { prepareSqlValuePg } from '../prepare-value';
3
+ import { ITableSchemaPg } from '../../@types/i-pg';
4
+ import { schemaTable } from '../../utils/utils';
5
+ import { TDBRecord, TRecordSet } from '../../@types/i-common';
6
+
7
+ export const getMergeSqlPg = async <U extends TDBRecord = TDBRecord> (arg: {
8
+ connectionId: string,
9
+ commonSchemaAndTable: string,
10
+ recordset: TRecordSet<U>,
11
+ omitFields?: string[],
12
+ noUpdateIfNull?: boolean,
13
+ mergeCorrection?: (_sql: string) => string,
14
+ }): Promise<string> => {
15
+ const { connectionId, commonSchemaAndTable, recordset, omitFields = [], noUpdateIfNull } = arg;
16
+ if (!recordset?.length) {
17
+ return '';
18
+ }
19
+ const schemaTableStr = schemaTable.to.pg(commonSchemaAndTable);
20
+ const tableSchema: ITableSchemaPg = await getTableSchemaPg(connectionId, commonSchemaAndTable);
21
+ const { columnsSchema, pk, fieldsWoSerialsAndRO, defaults } = tableSchema;
22
+
23
+ let mergeFieldsArr: string[] = fieldsWoSerialsAndRO;
24
+ if (omitFields.length) {
25
+ const set = new Set(omitFields);
26
+ mergeFieldsArr = fieldsWoSerialsAndRO.filter((fieldName) => !set.has(fieldName));
27
+ }
28
+
29
+ const mergeValues = recordset.map((record: U) => {
30
+ const preparedValues: (string | number)[] = [];
31
+
32
+ mergeFieldsArr.forEach((f) => {
33
+ const value = record[f];
34
+ let sqlValue = prepareSqlValuePg({ value, fieldDef: columnsSchema[f] });
35
+ if (defaults[f] != null && (sqlValue == null || sqlValue === 'null')) {
36
+ sqlValue = defaults[f];
37
+ }
38
+ preparedValues.push(sqlValue);
39
+ });
40
+ return `(${preparedValues.join(', ')})`;
41
+ }).join(',\n ').trim();
42
+
43
+ const updateSetStr = mergeFieldsArr.map((f) => {
44
+ const vArr = [`EXCLUDED."${f}"`];
45
+ if (noUpdateIfNull) {
46
+ vArr.push(`${schemaTableStr}."${f}"`);
47
+ }
48
+ if (defaults[f]) {
49
+ vArr.push(defaults[f]);
50
+ }
51
+ return `"${f}" = ${vArr.length > 1 ? `COALESCE(${vArr.join(', ')})` : vArr[0]}`;
52
+ }).join(',\n ');
53
+
54
+ const mergeFieldsList = mergeFieldsArr.map((f) => `"${f}"`).join(',\n ');
55
+ // noinspection UnnecessaryLocalVariableJS
56
+ let mergeSQL = `--
57
+ INSERT INTO ${schemaTableStr} (
58
+ ${mergeFieldsList}
59
+ )
60
+ VALUES
61
+ ${mergeValues}
62
+ ON CONFLICT (${pk.map((f) => `"${f}"`).join(', ')})
63
+ DO UPDATE SET
64
+ ${updateSetStr}
65
+ ;`;
66
+ if (typeof arg.mergeCorrection === 'function') {
67
+ mergeSQL = arg.mergeCorrection(mergeSQL);
68
+ }
69
+ return mergeSQL;
70
+ };
@@ -0,0 +1,46 @@
1
+ import { getTableSchemaPg } from '../table-schema-pg';
2
+ import { prepareSqlValuePg } from '../prepare-value';
3
+ import { ITableSchemaPg } from '../../@types/i-pg';
4
+ import { TDBRecord } from '../../@types/i-common';
5
+ import { schemaTable } from '../../utils/utils';
6
+
7
+ export const getUpdateSqlPg = async <U extends TDBRecord = TDBRecord>(arg: {
8
+ connectionId: string,
9
+ commonSchemaAndTable: string,
10
+ record: U,
11
+ customSets: TDBRecord,
12
+ updateIdentity?: string[],
13
+ }): Promise<string> => {
14
+ const {
15
+ connectionId,
16
+ commonSchemaAndTable,
17
+ record,
18
+ customSets = {},
19
+ } = arg;
20
+ const tableSchema: ITableSchemaPg = await getTableSchemaPg(connectionId, commonSchemaAndTable);
21
+ const { columnsSchema, pk, fieldsWoSerialsAndRO } = tableSchema;
22
+
23
+ const { updateIdentity = pk } = arg;
24
+
25
+ const updateFields = fieldsWoSerialsAndRO.filter((f) => (!updateIdentity.includes(f)));
26
+
27
+ const getPreparedSqlValue = (f: string) => prepareSqlValuePg({ value: record[f], fieldDef: columnsSchema[f] });
28
+
29
+ const preparedRecord: TDBRecord = {};
30
+ updateFields.forEach((f) => {
31
+ if (customSets[f] !== undefined) {
32
+ preparedRecord[f] = customSets[f];
33
+ } else if (record[f] !== undefined) {
34
+ preparedRecord[f] = getPreparedSqlValue(f);
35
+ }
36
+ });
37
+ const sets = Object.entries(preparedRecord).map(([f, v]) => `"${f}" = ${v}`).join(', ');
38
+
39
+ const where = updateIdentity.map((f) => `"${f}" = ${getPreparedSqlValue(f)}`).join(' AND ');
40
+
41
+ // noinspection UnnecessaryLocalVariableJS
42
+ const updateSql = `${'UPDATE'} ${schemaTable.to.pg(commonSchemaAndTable)} SET
43
+ ${sets}
44
+ WHERE ${where};`;
45
+ return updateSql;
46
+ };
@@ -1,9 +1,9 @@
1
1
  // noinspection SqlResolve
2
- import { QueryResultRow } from 'pg';
3
2
  import { omitBy } from 'af-tools-ts';
4
- import { getFieldsAndValuesPg, getTableSchemaPg } from './table-schema';
3
+ import { getFieldsAndValuesPg, getTableSchemaPg } from './table-schema-pg';
5
4
  import { queryPg } from './query-pg';
6
5
  import { logger } from '../logger-error';
6
+ import { TDBRecord } from '../@types/i-common';
7
7
 
8
8
  export enum EUpdateLevel {
9
9
  NEVER_UPDATE,
@@ -11,9 +11,9 @@ export enum EUpdateLevel {
11
11
  UPDATE_ALWAYS
12
12
  }
13
13
 
14
- const hasAllValues = <T extends QueryResultRow> (fieldList: string[] | undefined, record: T) => fieldList?.length && fieldList.every((f) => record[f] !== undefined);
14
+ const hasAllValues = <T extends TDBRecord> (fieldList: string[] | undefined, record: T) => fieldList?.length && fieldList.every((f) => record[f] !== undefined);
15
15
 
16
- const selectByAnyIdentity = async <T extends QueryResultRow, R extends QueryResultRow = T> (
16
+ const selectByAnyIdentity = async <T extends TDBRecord, R extends TDBRecord = T> (
17
17
  connectionId: string,
18
18
  identities: string[][],
19
19
  record: T,
@@ -40,7 +40,7 @@ const selectByAnyIdentity = async <T extends QueryResultRow, R extends QueryResu
40
40
  }
41
41
  };
42
42
 
43
- export const insertPg = async <T extends QueryResultRow, R extends QueryResultRow = T> (
43
+ export const insertPg = async <T extends TDBRecord, R extends TDBRecord = T> (
44
44
  {
45
45
  connectionId,
46
46
  record,
@@ -57,13 +57,13 @@ export const insertPg = async <T extends QueryResultRow, R extends QueryResultRo
57
57
  updateLevel?: EUpdateLevel, // Flag: Update entry when unique constraints conflict.
58
58
  },
59
59
  ): Promise<R | undefined> => {
60
- const { recordSchema, pk = [], serials = [], uc = [] } = await getTableSchemaPg(connectionId, target);
60
+ const { columnsSchema, pk = [], serialsFields = [], uc = [] } = await getTableSchemaPg(connectionId, target);
61
61
  // Cleaning the record: deleting properties not included in the set of fields, with the value undefined and auto-incrementing fields
62
- const recordWoSerials: T = omitBy(record, (fieldValue: any, fieldName: string) => !recordSchema[fieldName] || fieldValue === undefined || serials.includes(fieldName)) as T;
62
+ const recordWoSerials: T = omitBy(record, (fieldValue: any, fieldName: string) => !columnsSchema[fieldName] || fieldValue === undefined || serialsFields.includes(fieldName)) as T;
63
63
 
64
64
  // We form all possible sets of fields, which we then use to search for an added (or already existing) record
65
65
  // Normalize (sort) sets
66
- let identities: string[][] = [pk, ...serials.map((f) => [f]), ...Object.values(uc)].filter((a) => a.length).map((a) => a.sort());
66
+ let identities: string[][] = [pk, ...serialsFields.map((f) => [f]), ...Object.values(uc)].filter((a) => a.length).map((a) => a.sort());
67
67
  // Removing duplicates
68
68
  identities = [...(new Set(identities.map((a) => a.join('|'))))].map((s) => s.split('|'));
69
69
  source = source || target;
@@ -85,7 +85,7 @@ export const insertPg = async <T extends QueryResultRow, R extends QueryResultRo
85
85
  }
86
86
 
87
87
  // There is no suitable record in the database, we insert it
88
- const { values, positionsList, fieldsList, upsertFields } = getFieldsAndValuesPg(recordWoSerials, recordSchema);
88
+ const { values, positionsList, fieldsList, upsertFields } = getFieldsAndValuesPg(recordWoSerials, columnsSchema);
89
89
  const insertSQL = `INSERT INTO ${target} (${fieldsList})
90
90
  VALUES (${positionsList}) ON CONFLICT ${
91
91
  updateLevel === EUpdateLevel.NEVER_UPDATE
@@ -1,92 +1,154 @@
1
1
  // noinspection SqlResolve
2
2
  import { DateTime } from 'luxon';
3
- import { EDataTypePg, IFieldDefPg } from '../@types/i-pg';
3
+ import { getBool } from 'af-tools-ts';
4
+ import { IFieldDefPg } from '../@types/i-pg';
5
+ import { NULL } from '../common';
6
+ import { dateTimeValue, getDatetimeWithPrecisionAndOffset } from '../utils/utils-dt';
7
+ import { prepareBigIntNumber, prepareFloatNumber, prepareIntNumber, prepareNumeric } from '../utils/utils-num';
8
+ import { IFieldDef } from '../@types/i-common';
9
+ import { binToHexString, prepareJSON, prepareUUID, q } from '../utils/utils';
10
+ import { arrayToJsonList } from '../utils/utils-array';
4
11
 
5
- const NULL = 'null';
6
- const utc$ = (millis?: number): DateTime => DateTime.fromMillis(millis == null ? Date.now() : millis).setZone('UTC');
12
+ export const quoteStringPg = (value: string): string => {
13
+ if (value == null) {
14
+ return NULL;
15
+ }
16
+ return /['\\]|\${2,}/.test(value) ? `$s$${value}$s$` : `'${value}'`;
17
+ };
7
18
 
8
- export const prepareSqlStringPg = (s: any): string => {
9
- s = String(s);
10
- if (/['\\]|\${2,}/.test(s)) {
11
- return `$s$${s}$s$`;
19
+ export const prepareSqlStringPg = (value: any, fieldDef: IFieldDefPg): string | typeof NULL => {
20
+ if (value == null) {
21
+ return NULL;
12
22
  }
13
- return `'${s}'`;
23
+ let v = String(value);
24
+ const { length = 0, noQuotes } = fieldDef;
25
+ if (length > 0 && v.length > length) {
26
+ v = v.substring(0, length);
27
+ }
28
+ if (noQuotes) {
29
+ return v;
30
+ }
31
+ return quoteStringPg(v);
14
32
  };
15
33
 
16
- export const prepareSqlValuePg = (arg: {
34
+ const prepareDateTimeOffset = (
17
35
  value: any,
18
- fieldDef: IFieldDefPg,
19
- }): any => {
36
+ fieldDef: IFieldDef,
37
+ ): string | typeof NULL => getDatetimeWithPrecisionAndOffset({ value, fieldDef, defaultDtPrecision: 6 });
38
+
39
+ const prepareTimeOffset = (value: any, fieldDefOriginal: IFieldDefPg): string | typeof NULL => {
40
+ const fieldDef: IFieldDefPg = { ...fieldDefOriginal, noQuotes: true };
41
+ fieldDef.dateTimeOptions = fieldDef.dateTimeOptions || {};
42
+ const { includeOffset = fieldDef.dataType === 'timetz' } = fieldDef.dateTimeOptions;
43
+ fieldDef.dateTimeOptions.includeOffset = includeOffset;
44
+ const dts = getDatetimeWithPrecisionAndOffset({ value, fieldDef, defaultDtPrecision: 6, stripTrailingZeros: true });
45
+ return dts === NULL ? NULL : `'${dts.substring(11, dts.length)}'::${fieldDef.dataType}`;
46
+ };
47
+
48
+ const prepareJsonPg = (value: any, dataType: 'json' | 'jsonb'): string | typeof NULL => {
49
+ const v = prepareJSON(value);
50
+ if (v === NULL) {
51
+ return NULL;
52
+ }
53
+ return `${quoteStringPg(v)}::${dataType}`;
54
+ };
55
+
56
+ export const prepareSqlValuePg = (arg: { value: any, fieldDef: IFieldDefPg }): any => {
20
57
  const { value, fieldDef } = arg;
21
- if (value == null && fieldDef.isNullable) {
58
+ if (value == null) {
22
59
  return NULL;
23
60
  }
24
- switch (fieldDef.dataType) {
25
- case EDataTypePg.boolean: {
26
- return value ? 'true' : 'false';
27
- }
61
+ const fieldDefWithNoQuotes = { ...fieldDef, noQuotes: true };
28
62
 
29
- case EDataTypePg.bigint: {
30
- return `'${value}'`;
31
- }
63
+ let v = value;
64
+ const { noQuotes, dataType } = fieldDef;
32
65
 
33
- case EDataTypePg.numeric:
34
- case EDataTypePg.real: {
35
- const v: string | number = Number(value);
36
- return Number.isNaN(v) ? NULL : v;
37
- }
66
+ switch (dataType) {
67
+ case 'bit':
68
+ return getBool(value) ? '1' : '0';
38
69
 
39
- case EDataTypePg.integer:
40
- case EDataTypePg.smallint: {
41
- const v: string | number = Number(value);
42
- return Number.isNaN(v) ? NULL : Math.floor(v);
43
- }
70
+ case 'bool':
71
+ case 'boolean':
72
+ return getBool(value) ? 'true' : 'false';
44
73
 
45
- case EDataTypePg.text:
46
- case EDataTypePg.character:
47
- case EDataTypePg.varchar:
48
- case EDataTypePg.uuid: {
49
- return prepareSqlStringPg(value);
50
- }
74
+ case 'smallint':
75
+ case 'int2':
76
+ return prepareIntNumber(value, -32768, 32767);
77
+ case 'int':
78
+ case 'integer':
79
+ case 'int4':
80
+ return prepareIntNumber(value, -2147483648, 2147483647);
81
+ case 'bigint':
82
+ case 'int8':
83
+ return prepareBigIntNumber(value);
84
+
85
+ case 'numeric':
86
+ case 'decimal':
87
+ return prepareNumeric(value, fieldDef.precision, fieldDef.scale);
88
+
89
+ case 'real':
90
+ case 'float4':
91
+ case 'money':
92
+ case 'double precision':
93
+ case 'float8':
94
+ return prepareFloatNumber(value);
95
+
96
+ case 'json':
97
+ case 'jsonb':
98
+ return prepareJsonPg(value, dataType);
51
99
 
52
- case EDataTypePg.json:
53
- case EDataTypePg.jsonb: {
54
- return prepareSqlStringPg(JSON.stringify(value));
100
+ case 'uuid':
101
+ return prepareUUID(v, true, fieldDef.noQuotes);
102
+
103
+ case 'string':
104
+ case 'text':
105
+ case 'character':
106
+ case 'char':
107
+ case 'varchar':
108
+ case 'character varying':
109
+ return prepareSqlStringPg(value, fieldDef);
110
+
111
+ case 'timestamp':
112
+ case 'timestamp without time zone': {
113
+ // '2023-09-05T02:23:54.105+03:00'::timestamp
114
+ // '2023-09-05T02:23:54.105'::timestamp
115
+ const { includeOffset = false } = fieldDef.dateTimeOptions || {}; // По умолчанию для timestamp includeOffset = false
116
+ const str = prepareDateTimeOffset(value, { ...fieldDef, noQuotes: true, dateTimeOptions: { ...(fieldDef.dateTimeOptions || {}), includeOffset } });
117
+ return str === NULL ? NULL : `'${str}'::timestamp`;
55
118
  }
56
119
 
57
- case EDataTypePg.date:
58
- case EDataTypePg.timestamp:
59
- case EDataTypePg.timestamptz: {
60
- let v = value;
61
- if (value instanceof Date) {
62
- v = +value;
63
- } else if (value instanceof DateTime) {
64
- v = value.toMillis();
65
- } else if (typeof value === 'string') {
66
- v = DateTime.fromISO(value).toMillis();
67
- }
68
- switch (fieldDef.dataType) {
69
- case EDataTypePg.date: {
70
- return `'${typeof v === 'number' ? utc$(v).toISODate() : v}'::date`;
71
- }
72
- case EDataTypePg.timestamp:
73
- case EDataTypePg.timestamptz: {
74
- return `'${typeof v === 'number' ? utc$(v).toISO() : v}'::timestamptz`;
75
- }
76
- default:
77
- return `'${v}'`;
78
- }
120
+ case 'timestamptz':
121
+ case 'timestamp with time zone': {
122
+ // '2023-09-05T02:23:54.105'::timestamptz
123
+ // '2023-09-05T02:23:54.105+03:00'::timestamptz
124
+ const str = prepareDateTimeOffset(value, fieldDefWithNoQuotes);
125
+ return str === NULL ? NULL : `'${str}'::timestamptz`;
79
126
  }
80
127
 
81
- case EDataTypePg.USER_DEFINED:
82
- return prepareSqlStringPg(value);
128
+ case 'date':
129
+ // '2023-09-05'::date
130
+ return dateTimeValue(value, fieldDefWithNoQuotes, (dt: DateTime) => `'${dt.toISODate()}'::date`);
83
131
 
84
- case EDataTypePg.ARRAY: {
85
- let v = JSON.stringify(value);
86
- v = v.replace(/^\[(.*?)]$/, '{$1}');
87
- return prepareSqlStringPg(v);
132
+ case 'timetz': // '02:22:17.368+03:00'::time
133
+ case 'time with time zone':
134
+ case 'time': // '02:22:17.368'::time
135
+ case 'time without time zone':
136
+ return prepareTimeOffset(value, fieldDef);
137
+
138
+ case 'bytea':
139
+ v = binToHexString(value);
140
+ return v ? q(v, noQuotes) : NULL;
141
+
142
+ case 'ARRAY': {
143
+ v = arrayToJsonList(value, fieldDef.arrayType);
144
+ if (v === NULL) {
145
+ return NULL;
146
+ }
147
+ v = `{${v}}`;
148
+ return fieldDef.noQuotes ? v : quoteStringPg(v);
88
149
  }
150
+ // 'USER_DEFINED'
89
151
  default:
90
- return prepareSqlStringPg(value);
152
+ return prepareSqlStringPg(value, fieldDef);
91
153
  }
92
154
  };
@@ -1,9 +1,10 @@
1
- import { QueryResult, QueryResultRow } from 'pg';
2
- import { getPoolPg } from './pg-pool';
1
+ import { QueryResult } from 'pg';
2
+ import { getPoolPg } from './pool-pg';
3
3
  import { logSqlError } from '../common';
4
4
  import { IPoolPg } from '../@types/i-pg';
5
+ import { TDBRecord } from '../@types/i-common';
5
6
 
6
- export const queryPg = async <R extends QueryResultRow = any> (
7
+ export const queryPg = async <R extends TDBRecord = any> (
7
8
  connectionId: string,
8
9
  sqlText: string,
9
10
  sqlValues?: any[],
@@ -0,0 +1,196 @@
1
+ // noinspection SqlResolve
2
+ import { queryPg } from './query-pg';
3
+ import { logger } from '../logger-error';
4
+ import { graceExit } from '../common';
5
+ import { IFieldDefPg, ITableSchemaPg, TColumnsSchemaPg, TUniqueConstraintsPg } from '../@types/i-pg';
6
+ import { schemaTable } from '../utils/utils';
7
+ import { TDBRecord } from '../@types/i-common';
8
+ import { TDataTypePg } from '../@types/i-data-types-pg';
9
+ import { getNormalizedTypePg, getTypeByUdtNamePg } from './utils-pg';
10
+
11
+ // commonSchemaAndTable: <schema>.<table> : Staff.nnPersones-personGuid
12
+ // schemaAndTablePg: "<schema>"."<table>" : "Staff"."nnPersones-personGuid"
13
+
14
+ const tableSchemaHash: { [commonSchemaAndTable: string]: ITableSchemaPg } = {};
15
+
16
+ const getColumnsSchemaPg_ = async (connectionId: string, commonSchemaAndTable: string): Promise<TColumnsSchemaPg> => {
17
+ const [schema, table] = schemaTable.to.common(commonSchemaAndTable).split('.');
18
+ const sql = `SELECT column_name,
19
+ column_default,
20
+ is_nullable,
21
+ data_type,
22
+ character_maximum_length,
23
+ numeric_precision,
24
+ numeric_precision_radix,
25
+ numeric_scale,
26
+ datetime_precision,
27
+ udt_name,
28
+ is_generated
29
+ FROM information_schema.columns
30
+ WHERE table_name = '${table}'
31
+ AND table_schema = '${schema}';`;
32
+ const result = await queryPg(connectionId, sql);
33
+ const fields = result?.rows || [];
34
+ const columnsSchema: TColumnsSchemaPg = {};
35
+ fields.forEach((fieldDef) => {
36
+ const columnDefault = fieldDef.column_default != null ? fieldDef.column_default : undefined;
37
+ const name = fieldDef.column_name;
38
+ const dataType: TDataTypePg = getNormalizedTypePg(fieldDef.data_type);
39
+ const fieldSchema: IFieldDefPg = {
40
+ name,
41
+ isNullable: /yes/i.test(fieldDef.is_nullable || ''),
42
+ columnDefault: fieldDef.column_default,
43
+ hasDefault: columnDefault != null,
44
+ dataType,
45
+ length: fieldDef.character_maximum_length,
46
+ precision: fieldDef.numeric_precision,
47
+ scale: fieldDef.numeric_scale,
48
+ radix: fieldDef.numeric_precision_radix,
49
+ dtPrecision: fieldDef.datetime_precision,
50
+ arrayType: dataType === 'ARRAY' ? getTypeByUdtNamePg(fieldDef.udt_name) : undefined,
51
+ readOnly: fieldDef.is_generated === 'ALWAYS', // boolean;
52
+ };
53
+ Object.entries(fieldSchema).forEach(([prop, value]) => {
54
+ if (value == null) {
55
+ delete fieldSchema[prop as keyof IFieldDefPg];
56
+ }
57
+ });
58
+ columnsSchema[name] = fieldSchema;
59
+ });
60
+ return columnsSchema;
61
+ };
62
+
63
+ const getPrimaryKey = async (connectionId: string, commonSchemaAndTable: string): Promise<string[]> => {
64
+ const schemaTablePg = schemaTable.to.pg(commonSchemaAndTable);
65
+ const sql = `
66
+ SELECT a.attname as f
67
+ FROM pg_index i
68
+ JOIN pg_attribute a
69
+ ON a.attrelid = i.indrelid AND a.attnum = ANY (i.indkey)
70
+ WHERE i.indrelid = '${schemaTablePg}'::regclass
71
+ AND i.indisprimary;`;
72
+ const result = await queryPg(connectionId, sql);
73
+
74
+ return (result?.rows || []).map(({ f }) => f);
75
+ };
76
+
77
+ const getUniqueConstraints = async (connectionId: string, commonSchemaAndTable: string): Promise<TUniqueConstraintsPg> => {
78
+ const schemaTablePg = schemaTable.to.pg(commonSchemaAndTable);
79
+ const [schema, table] = schemaTable.to.common(commonSchemaAndTable).split('.');
80
+ const sql = `
81
+ SELECT UI.cn as cn, UI.cols as cols, CASE WHEN UC.cn IS NULL THEN 'UX' ELSE 'UC' END AS typ
82
+ FROM (SELECT c.relname as cn, array_to_json(array_agg(a.attname ORDER BY a.attname)) AS cols
83
+ FROM pg_index i
84
+ JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY (i.indkey)
85
+ JOIN pg_class AS c ON c.oid = i.indexrelid
86
+ WHERE i.indrelid = '${schemaTablePg}'::regclass
87
+ AND i.indisunique
88
+ AND NOT i.indisprimary
89
+ GROUP BY c.relname) AS UI
90
+ LEFT OUTER JOIN (SELECT ccu.constraint_name AS cn
91
+ FROM information_schema.table_constraints tc
92
+ JOIN information_schema.constraint_column_usage AS ccu USING (constraint_schema, constraint_name)
93
+ JOIN information_schema.columns AS c ON c.table_schema = tc.constraint_schema
94
+ AND tc.table_name = c.table_name AND ccu.column_name = c.column_name
95
+ WHERE tc.table_schema = '${schema}'
96
+ AND tc.table_name = '${table}'
97
+ AND tc.constraint_type = 'UNIQUE'
98
+ GROUP BY ccu.constraint_name) AS UC ON UC.cn = UI.cn
99
+ ORDER BY CASE WHEN UC.cn IS NULL THEN 2 ELSE 1 END
100
+ `;
101
+ const result = await queryPg(connectionId, sql);
102
+ const uc: TUniqueConstraintsPg = {};
103
+ result?.rows?.forEach(({ cn, cols }) => {
104
+ uc[cn] = cols;
105
+ });
106
+ return uc;
107
+ };
108
+
109
+ const getSerials = async (connectionId: string, commonSchemaAndTable: string): Promise<string[]> => {
110
+ const fqName = schemaTable.to.common(commonSchemaAndTable);
111
+ const sql = `
112
+ WITH fq_objects AS (SELECT c.oid,
113
+ n.nspname || '.' || c.relname AS fqname,
114
+ c.relkind,
115
+ c.relname AS relation
116
+ FROM pg_class c
117
+ JOIN pg_namespace n ON n.oid = c.relnamespace),
118
+ sequences AS (SELECT oid, fqname FROM fq_objects WHERE relkind = 'S'),
119
+ tables AS (SELECT oid, fqname FROM fq_objects WHERE relkind = 'r')
120
+ SELECT t.fqname AS tbl, array_to_json(array_agg(a.attname ORDER BY a.attname)) AS cols
121
+ FROM pg_depend d
122
+ JOIN sequences s ON s.oid = d.objid
123
+ JOIN tables t ON t.oid = d.refobjid
124
+ JOIN pg_attribute a ON a.attrelid = d.refobjid and a.attnum = d.refobjsubid
125
+ WHERE d.deptype = 'a'
126
+ AND t.fqname = '${fqName}'
127
+ GROUP BY t.fqname
128
+ `;
129
+ const result = await queryPg(connectionId, sql);
130
+ return result?.rows?.[0]?.cols || [];
131
+ };
132
+
133
+ export const getTableSchemaPg = async (connectionId: string, commonSchemaAndTable: string): Promise<ITableSchemaPg> => {
134
+ let tableSchema = tableSchemaHash[commonSchemaAndTable];
135
+ if (tableSchema) {
136
+ return tableSchema;
137
+ }
138
+ try {
139
+ const columnsSchema = await getColumnsSchemaPg_(connectionId, commonSchemaAndTable);
140
+ const pk = await getPrimaryKey(connectionId, commonSchemaAndTable);
141
+ const uc = await getUniqueConstraints(connectionId, commonSchemaAndTable);
142
+ const serialsFields = await getSerials(connectionId, commonSchemaAndTable);
143
+ const defaults: { [fieldName: string]: string } = {};
144
+ Object.values(columnsSchema).forEach((fieldDef) => {
145
+ const { name: f = '', columnDefault, hasDefault } = fieldDef;
146
+ if (hasDefault && !serialsFields.includes(f)) {
147
+ defaults[f] = `${columnDefault}`;
148
+ }
149
+ });
150
+ const fieldsArray: string[] = Object.keys(columnsSchema);
151
+ const readOnlyFields: string[] = Object.values(columnsSchema).filter((s) => s.readOnly).map((s) => s.name as string);
152
+ const fieldsWoSerialsAndRO: string[] = fieldsArray.filter((f) => !serialsFields.includes(f) && !readOnlyFields.includes(f));
153
+
154
+ tableSchema = {
155
+ columnsSchema, pk, uc, defaults, serialsFields, fieldsArray, fieldsWoSerialsAndRO, readOnlyFields,
156
+ };
157
+ tableSchemaHash[commonSchemaAndTable] = tableSchema;
158
+ } catch (err) {
159
+ logger.error(`Failed to get schema for table ${commonSchemaAndTable}`);
160
+ logger.error(err);
161
+ await graceExit();
162
+ }
163
+ return tableSchema;
164
+ };
165
+
166
+ export const getFieldsAndValuesPg = <U extends TDBRecord = TDBRecord> (record: U, columnsSchema: TColumnsSchemaPg):
167
+ {
168
+ fields: string[],
169
+ fieldsList: string,
170
+ values: any[],
171
+ positionsList: string,
172
+ setFields: string,
173
+ upsertFields: string
174
+ } => {
175
+ const recordNormalized: TDBRecord = {};
176
+ Object.entries(record).forEach(([f, v]) => {
177
+ const { dataType } = columnsSchema[f] || {};
178
+ if (!dataType) {
179
+ return;
180
+ }
181
+ if ((dataType === 'jsonb' || dataType === 'json') && Array.isArray(v)) {
182
+ recordNormalized[f] = JSON.stringify(v);
183
+ } else {
184
+ recordNormalized[f] = v;
185
+ }
186
+ });
187
+ const fields: string[] = Object.keys(recordNormalized);
188
+ const fieldsList: string = fields.join(', ');
189
+ const values: any[] = Object.values(recordNormalized);
190
+ const positionsList: string = fields.map((__, i) => `$${++i}`).join(', ');
191
+ const setFields: string = fields.map((f, i) => `${f} = $${++i}`).join(', ');
192
+ const upsertFields: string = fields.map((f) => `${f} = EXCLUDED.${f}`).join(',\n');
193
+ return {
194
+ fields, fieldsList, values, positionsList, setFields, upsertFields,
195
+ };
196
+ };