@ductape/sdk 0.0.4-v5 → 0.0.4-v51

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 (338) hide show
  1. package/README.md +1 -1
  2. package/dist/api/services/appApi.service.d.ts +48 -2
  3. package/dist/api/services/appApi.service.js +101 -2
  4. package/dist/api/services/appApi.service.js.map +1 -1
  5. package/dist/api/services/pricingApi.service.d.ts +10 -0
  6. package/dist/api/services/pricingApi.service.js +34 -0
  7. package/dist/api/services/pricingApi.service.js.map +1 -0
  8. package/dist/api/services/processorApi.service.d.ts +12 -2
  9. package/dist/api/services/processorApi.service.js +12 -2
  10. package/dist/api/services/processorApi.service.js.map +1 -1
  11. package/dist/api/services/productsApi.service.d.ts +40 -1
  12. package/dist/api/services/productsApi.service.js +105 -1
  13. package/dist/api/services/productsApi.service.js.map +1 -1
  14. package/dist/api/services/userApi.service.js +1 -0
  15. package/dist/api/services/userApi.service.js.map +1 -1
  16. package/dist/api/services/workspaceApi.service.js +1 -0
  17. package/dist/api/services/workspaceApi.service.js.map +1 -1
  18. package/dist/api/services/workspaceSecretsApi.service.d.ts +75 -0
  19. package/dist/api/services/workspaceSecretsApi.service.js +62 -0
  20. package/dist/api/services/workspaceSecretsApi.service.js.map +1 -0
  21. package/dist/api/urls.d.ts +6 -1
  22. package/dist/api/urls.js +12 -2
  23. package/dist/api/urls.js.map +1 -1
  24. package/dist/api/utils/cache.utils.d.ts +1 -1
  25. package/dist/api/utils/cache.utils.js +10 -4
  26. package/dist/api/utils/cache.utils.js.map +1 -1
  27. package/dist/api/utils/strings.utils.d.ts +2 -0
  28. package/dist/api/utils/strings.utils.js +14 -0
  29. package/dist/api/utils/strings.utils.js.map +1 -1
  30. package/dist/apps/services/app.service.d.ts +51 -33
  31. package/dist/apps/services/app.service.js +488 -244
  32. package/dist/apps/services/app.service.js.map +1 -1
  33. package/dist/apps/validators/joi-validators/create.appAction.validator.d.ts +1 -2
  34. package/dist/apps/validators/joi-validators/create.appAction.validator.js +21 -2
  35. package/dist/apps/validators/joi-validators/create.appAction.validator.js.map +1 -1
  36. package/dist/apps/validators/joi-validators/create.appWebhook.validator.d.ts +1 -2
  37. package/dist/apps/validators/joi-validators/create.appWebhook.validator.js +2 -15
  38. package/dist/apps/validators/joi-validators/create.appWebhook.validator.js.map +1 -1
  39. package/dist/apps/validators/joi-validators/update.appAction.validator.js +11 -1
  40. package/dist/apps/validators/joi-validators/update.appAction.validator.js.map +1 -1
  41. package/dist/apps/validators/joi-validators/update.appActionResponse.validator.d.ts +1 -1
  42. package/dist/apps/validators/joi-validators/update.appActionResponse.validator.js +34 -1
  43. package/dist/apps/validators/joi-validators/update.appActionResponse.validator.js.map +1 -1
  44. package/dist/apps/validators/joi-validators/update.appWebhook.validator.d.ts +1 -2
  45. package/dist/apps/validators/joi-validators/update.appWebhook.validator.js +2 -14
  46. package/dist/apps/validators/joi-validators/update.appWebhook.validator.js.map +1 -1
  47. package/dist/clients/pricing.client.d.ts +3 -0
  48. package/dist/clients/pricing.client.js +33 -0
  49. package/dist/clients/pricing.client.js.map +1 -0
  50. package/dist/database/adapters/base.adapter.d.ts +176 -0
  51. package/dist/database/adapters/base.adapter.js +31 -0
  52. package/dist/database/adapters/base.adapter.js.map +1 -0
  53. package/dist/database/adapters/dynamodb.adapter.d.ts +91 -0
  54. package/dist/database/adapters/dynamodb.adapter.js +1608 -0
  55. package/dist/database/adapters/dynamodb.adapter.js.map +1 -0
  56. package/dist/database/adapters/mongodb.adapter.d.ts +71 -0
  57. package/dist/database/adapters/mongodb.adapter.js +1072 -0
  58. package/dist/database/adapters/mongodb.adapter.js.map +1 -0
  59. package/dist/database/adapters/mysql.adapter.d.ts +146 -0
  60. package/dist/database/adapters/mysql.adapter.js +1492 -0
  61. package/dist/database/adapters/mysql.adapter.js.map +1 -0
  62. package/dist/database/adapters/postgresql.adapter.d.ts +147 -0
  63. package/dist/database/adapters/postgresql.adapter.js +1603 -0
  64. package/dist/database/adapters/postgresql.adapter.js.map +1 -0
  65. package/dist/database/database.service.d.ts +232 -0
  66. package/dist/database/database.service.js +802 -0
  67. package/dist/database/database.service.js.map +1 -0
  68. package/dist/database/index.d.ts +18 -0
  69. package/dist/database/index.js +98 -0
  70. package/dist/database/index.js.map +1 -0
  71. package/dist/database/types/aggregation.types.d.ts +261 -0
  72. package/dist/database/types/aggregation.types.js +21 -0
  73. package/dist/database/types/aggregation.types.js.map +1 -0
  74. package/dist/database/types/connection.types.d.ts +132 -0
  75. package/dist/database/types/connection.types.js +6 -0
  76. package/dist/database/types/connection.types.js.map +1 -0
  77. package/dist/database/types/database.types.d.ts +175 -0
  78. package/dist/database/types/database.types.js +75 -0
  79. package/dist/database/types/database.types.js.map +1 -0
  80. package/dist/database/types/index.d.ts +12 -0
  81. package/dist/database/types/index.js +37 -0
  82. package/dist/database/types/index.js.map +1 -0
  83. package/dist/database/types/index.types.d.ts +220 -0
  84. package/dist/database/types/index.types.js +27 -0
  85. package/dist/database/types/index.types.js.map +1 -0
  86. package/dist/database/types/migration.types.d.ts +205 -0
  87. package/dist/database/types/migration.types.js +44 -0
  88. package/dist/database/types/migration.types.js.map +1 -0
  89. package/dist/database/types/query.types.d.ts +305 -0
  90. package/dist/database/types/query.types.js +57 -0
  91. package/dist/database/types/query.types.js.map +1 -0
  92. package/dist/database/types/result.types.d.ts +220 -0
  93. package/dist/database/types/result.types.js +6 -0
  94. package/dist/database/types/result.types.js.map +1 -0
  95. package/dist/database/types/schema.types.d.ts +190 -0
  96. package/dist/database/types/schema.types.js +69 -0
  97. package/dist/database/types/schema.types.js.map +1 -0
  98. package/dist/database/utils/helpers.d.ts +66 -0
  99. package/dist/database/utils/helpers.js +501 -0
  100. package/dist/database/utils/helpers.js.map +1 -0
  101. package/dist/database/utils/migration.utils.d.ts +151 -0
  102. package/dist/database/utils/migration.utils.js +476 -0
  103. package/dist/database/utils/migration.utils.js.map +1 -0
  104. package/dist/database/utils/transaction.d.ts +64 -0
  105. package/dist/database/utils/transaction.js +130 -0
  106. package/dist/database/utils/transaction.js.map +1 -0
  107. package/dist/database/validators/connection.validator.d.ts +20 -0
  108. package/dist/database/validators/connection.validator.js +267 -0
  109. package/dist/database/validators/connection.validator.js.map +1 -0
  110. package/dist/database/validators/query.validator.d.ts +31 -0
  111. package/dist/database/validators/query.validator.js +305 -0
  112. package/dist/database/validators/query.validator.js.map +1 -0
  113. package/dist/database/validators/schema.validator.d.ts +31 -0
  114. package/dist/database/validators/schema.validator.js +334 -0
  115. package/dist/database/validators/schema.validator.js.map +1 -0
  116. package/dist/graph/adapters/arangodb.adapter.d.ts +80 -0
  117. package/dist/graph/adapters/arangodb.adapter.js +1393 -0
  118. package/dist/graph/adapters/arangodb.adapter.js.map +1 -0
  119. package/dist/graph/adapters/base.adapter.d.ts +228 -0
  120. package/dist/graph/adapters/base.adapter.js +38 -0
  121. package/dist/graph/adapters/base.adapter.js.map +1 -0
  122. package/dist/graph/adapters/index.d.ts +10 -0
  123. package/dist/graph/adapters/index.js +23 -0
  124. package/dist/graph/adapters/index.js.map +1 -0
  125. package/dist/graph/adapters/memgraph.adapter.d.ts +85 -0
  126. package/dist/graph/adapters/memgraph.adapter.js +1491 -0
  127. package/dist/graph/adapters/memgraph.adapter.js.map +1 -0
  128. package/dist/graph/adapters/neo4j.adapter.d.ts +88 -0
  129. package/dist/graph/adapters/neo4j.adapter.js +1861 -0
  130. package/dist/graph/adapters/neo4j.adapter.js.map +1 -0
  131. package/dist/graph/adapters/neptune.adapter.d.ts +87 -0
  132. package/dist/graph/adapters/neptune.adapter.js +1430 -0
  133. package/dist/graph/adapters/neptune.adapter.js.map +1 -0
  134. package/dist/graph/graph.service.d.ts +278 -0
  135. package/dist/graph/graph.service.js +687 -0
  136. package/dist/graph/graph.service.js.map +1 -0
  137. package/dist/graph/index.d.ts +11 -0
  138. package/dist/graph/index.js +42 -0
  139. package/dist/graph/index.js.map +1 -0
  140. package/dist/graph/types/connection.types.d.ts +158 -0
  141. package/dist/graph/types/connection.types.js +43 -0
  142. package/dist/graph/types/connection.types.js.map +1 -0
  143. package/dist/graph/types/graph.types.d.ts +144 -0
  144. package/dist/graph/types/graph.types.js +84 -0
  145. package/dist/graph/types/graph.types.js.map +1 -0
  146. package/dist/graph/types/index.d.ts +11 -0
  147. package/dist/graph/types/index.js +35 -0
  148. package/dist/graph/types/index.js.map +1 -0
  149. package/dist/graph/types/node.types.d.ts +193 -0
  150. package/dist/graph/types/node.types.js +49 -0
  151. package/dist/graph/types/node.types.js.map +1 -0
  152. package/dist/graph/types/path.types.d.ts +224 -0
  153. package/dist/graph/types/path.types.js +38 -0
  154. package/dist/graph/types/path.types.js.map +1 -0
  155. package/dist/graph/types/query.types.d.ts +247 -0
  156. package/dist/graph/types/query.types.js +23 -0
  157. package/dist/graph/types/query.types.js.map +1 -0
  158. package/dist/graph/types/relationship.types.d.ts +224 -0
  159. package/dist/graph/types/relationship.types.js +35 -0
  160. package/dist/graph/types/relationship.types.js.map +1 -0
  161. package/dist/graph/types/result.types.d.ts +237 -0
  162. package/dist/graph/types/result.types.js +7 -0
  163. package/dist/graph/types/result.types.js.map +1 -0
  164. package/dist/graph/validators/index.d.ts +81 -0
  165. package/dist/graph/validators/index.js +243 -0
  166. package/dist/graph/validators/index.js.map +1 -0
  167. package/dist/imports/imports.service.d.ts +3 -3
  168. package/dist/imports/imports.service.js +7 -7
  169. package/dist/imports/imports.service.js.map +1 -1
  170. package/dist/imports/imports.types.d.ts +8 -0
  171. package/dist/imports/repos/postmanV21.repo.d.ts +1 -1
  172. package/dist/imports/repos/postmanV21.repo.js +29 -2
  173. package/dist/imports/repos/postmanV21.repo.js.map +1 -1
  174. package/dist/index.d.ts +1244 -150
  175. package/dist/index.js +1309 -209
  176. package/dist/index.js.map +1 -1
  177. package/dist/inputs/inputs.service.js +2 -2
  178. package/dist/inputs/inputs.service.js.map +1 -1
  179. package/dist/inputs/utils/inputs.utils.create.js +1 -1
  180. package/dist/inputs/utils/inputs.utils.create.js.map +1 -1
  181. package/dist/logs/logs.types.d.ts +5 -0
  182. package/dist/logs/logs.types.js +1 -0
  183. package/dist/logs/logs.types.js.map +1 -1
  184. package/dist/parsers/index.d.ts +3 -0
  185. package/dist/parsers/index.js +27 -0
  186. package/dist/parsers/index.js.map +1 -0
  187. package/dist/parsers/pipelines/postman.pipelines.d.ts +15 -0
  188. package/dist/parsers/pipelines/postman.pipelines.js +103 -0
  189. package/dist/parsers/pipelines/postman.pipelines.js.map +1 -0
  190. package/dist/parsers/types/postman.types.d.ts +200 -0
  191. package/dist/parsers/types/postman.types.js +3 -0
  192. package/dist/parsers/types/postman.types.js.map +1 -0
  193. package/dist/parsers/utils/postman.utils.d.ts +12 -0
  194. package/dist/parsers/utils/postman.utils.js +116 -0
  195. package/dist/parsers/utils/postman.utils.js.map +1 -0
  196. package/dist/parsers/validators/postman-auth.validators.d.ts +10 -0
  197. package/dist/parsers/validators/postman-auth.validators.js +127 -0
  198. package/dist/parsers/validators/postman-auth.validators.js.map +1 -0
  199. package/dist/parsers/validators/postman-request.validators.d.ts +13 -0
  200. package/dist/parsers/validators/postman-request.validators.js +139 -0
  201. package/dist/parsers/validators/postman-request.validators.js.map +1 -0
  202. package/dist/parsers/validators/postman-response.validators.d.ts +13 -0
  203. package/dist/parsers/validators/postman-response.validators.js +150 -0
  204. package/dist/parsers/validators/postman-response.validators.js.map +1 -0
  205. package/dist/parsers/validators/postman-variable.validators.d.ts +14 -0
  206. package/dist/parsers/validators/postman-variable.validators.js +163 -0
  207. package/dist/parsers/validators/postman-variable.validators.js.map +1 -0
  208. package/dist/pricing/pricing.repo.d.ts +0 -0
  209. package/dist/pricing/pricing.repo.js +1 -0
  210. package/dist/pricing/pricing.repo.js.map +1 -0
  211. package/dist/pricing/pricing.service.d.ts +24 -0
  212. package/dist/pricing/pricing.service.js +51 -0
  213. package/dist/pricing/pricing.service.js.map +1 -0
  214. package/dist/pricing/pricing.types.d.ts +76 -0
  215. package/dist/pricing/pricing.types.js +21 -0
  216. package/dist/pricing/pricing.types.js.map +1 -0
  217. package/dist/pricing/utils/string.utils.d.ts +1 -0
  218. package/dist/pricing/utils/string.utils.js +9 -0
  219. package/dist/pricing/utils/string.utils.js.map +1 -0
  220. package/dist/processor/repos/sms.repo.d.ts +4 -4
  221. package/dist/processor/repos/sms.repo.js +23 -10
  222. package/dist/processor/repos/sms.repo.js.map +1 -1
  223. package/dist/processor/services/messagebrokers/kafka.service.js +0 -2
  224. package/dist/processor/services/messagebrokers/kafka.service.js.map +1 -1
  225. package/dist/processor/services/messagebrokers/rabbitmq.service.d.ts +9 -1
  226. package/dist/processor/services/messagebrokers/rabbitmq.service.js +40 -11
  227. package/dist/processor/services/messagebrokers/rabbitmq.service.js.map +1 -1
  228. package/dist/processor/services/processor.service.d.ts +38 -10
  229. package/dist/processor/services/processor.service.js +533 -248
  230. package/dist/processor/services/processor.service.js.map +1 -1
  231. package/dist/processor/services/request.service.d.ts +36 -0
  232. package/dist/processor/services/request.service.js +304 -0
  233. package/dist/processor/services/request.service.js.map +1 -0
  234. package/dist/processor/types/request.types.d.ts +14 -0
  235. package/dist/processor/types/request.types.js +3 -0
  236. package/dist/processor/types/request.types.js.map +1 -0
  237. package/dist/processor/utils/processor.utils.d.ts +3 -0
  238. package/dist/processor/utils/processor.utils.js +84 -22
  239. package/dist/processor/utils/processor.utils.js.map +1 -1
  240. package/dist/processor/utils/request.utils.d.ts +20 -0
  241. package/dist/processor/utils/request.utils.js +113 -0
  242. package/dist/processor/utils/request.utils.js.map +1 -0
  243. package/dist/products/services/products.service.d.ts +114 -77
  244. package/dist/products/services/products.service.js +805 -362
  245. package/dist/products/services/products.service.js.map +1 -1
  246. package/dist/products/services/utils/crypt.utils.d.ts +1 -0
  247. package/dist/products/services/utils/crypt.utils.js +17 -0
  248. package/dist/products/services/utils/crypt.utils.js.map +1 -0
  249. package/dist/products/services/utils/functions.utils.d.ts +13 -0
  250. package/dist/products/services/utils/functions.utils.js +289 -0
  251. package/dist/products/services/utils/functions.utils.js.map +1 -0
  252. package/dist/products/services/utils/objects.utils.d.ts +13 -0
  253. package/dist/products/services/utils/objects.utils.js +89 -0
  254. package/dist/products/services/utils/objects.utils.js.map +1 -0
  255. package/dist/products/services/utils/string.utils.d.ts +12 -0
  256. package/dist/products/services/utils/string.utils.js +168 -0
  257. package/dist/products/services/utils/string.utils.js.map +1 -0
  258. package/dist/products/utils/string.utils.d.ts +1 -1
  259. package/dist/products/utils/string.utils.js +14 -2
  260. package/dist/products/utils/string.utils.js.map +1 -1
  261. package/dist/products/validators/index.d.ts +4 -1
  262. package/dist/products/validators/index.js +7 -1
  263. package/dist/products/validators/index.js.map +1 -1
  264. package/dist/products/validators/joi-validators/create.productDatabaseAction.validator.d.ts +15 -4
  265. package/dist/products/validators/joi-validators/create.productDatabaseAction.validator.js +501 -109
  266. package/dist/products/validators/joi-validators/create.productDatabaseAction.validator.js.map +1 -1
  267. package/dist/products/validators/joi-validators/create.productEnv.validator.js +1 -0
  268. package/dist/products/validators/joi-validators/create.productEnv.validator.js.map +1 -1
  269. package/dist/products/validators/joi-validators/create.productGraph.validator.d.ts +3 -0
  270. package/dist/products/validators/joi-validators/create.productGraph.validator.js +82 -0
  271. package/dist/products/validators/joi-validators/create.productGraph.validator.js.map +1 -0
  272. package/dist/products/validators/joi-validators/create.productGraphAction.validator.d.ts +14 -0
  273. package/dist/products/validators/joi-validators/create.productGraphAction.validator.js +696 -0
  274. package/dist/products/validators/joi-validators/create.productGraphAction.validator.js.map +1 -0
  275. package/dist/products/validators/joi-validators/create.productHealthcheck.validator.d.ts +4 -0
  276. package/dist/products/validators/joi-validators/create.productHealthcheck.validator.js +58 -0
  277. package/dist/products/validators/joi-validators/create.productHealthcheck.validator.js.map +1 -0
  278. package/dist/products/validators/joi-validators/create.productMessageBrokerTopic.validator.js +1 -0
  279. package/dist/products/validators/joi-validators/create.productMessageBrokerTopic.validator.js.map +1 -1
  280. package/dist/products/validators/joi-validators/create.productMessageBrokers.validator.js +9 -4
  281. package/dist/products/validators/joi-validators/create.productMessageBrokers.validator.js.map +1 -1
  282. package/dist/products/validators/joi-validators/create.productNotification.validator.js +5 -2
  283. package/dist/products/validators/joi-validators/create.productNotification.validator.js.map +1 -1
  284. package/dist/products/validators/joi-validators/create.userAuth.validator.js +1 -0
  285. package/dist/products/validators/joi-validators/create.userAuth.validator.js.map +1 -1
  286. package/dist/products/validators/joi-validators/update.dataValue.validator.js +1 -0
  287. package/dist/products/validators/joi-validators/update.dataValue.validator.js.map +1 -1
  288. package/dist/products/validators/joi-validators/update.productDatabaseAction.validator.d.ts +6 -0
  289. package/dist/products/validators/joi-validators/update.productDatabaseAction.validator.js +28 -26
  290. package/dist/products/validators/joi-validators/update.productDatabaseAction.validator.js.map +1 -1
  291. package/dist/products/validators/joi-validators/update.productEnv.validator.js +3 -0
  292. package/dist/products/validators/joi-validators/update.productEnv.validator.js.map +1 -1
  293. package/dist/products/validators/joi-validators/update.productGraph.validator.d.ts +3 -0
  294. package/dist/products/validators/joi-validators/update.productGraph.validator.js +87 -0
  295. package/dist/products/validators/joi-validators/update.productGraph.validator.js.map +1 -0
  296. package/dist/products/validators/joi-validators/update.productGraphAction.validator.d.ts +7 -0
  297. package/dist/products/validators/joi-validators/update.productGraphAction.validator.js +72 -0
  298. package/dist/products/validators/joi-validators/update.productGraphAction.validator.js.map +1 -0
  299. package/dist/products/validators/joi-validators/update.productMessageBrokerTopic.validator.js +1 -0
  300. package/dist/products/validators/joi-validators/update.productMessageBrokerTopic.validator.js.map +1 -1
  301. package/dist/products/validators/joi-validators/update.userAuth.validator.js +1 -0
  302. package/dist/products/validators/joi-validators/update.userAuth.validator.js.map +1 -1
  303. package/dist/test/test.health.d.ts +1 -0
  304. package/dist/test/test.health.js +49 -0
  305. package/dist/test/test.health.js.map +1 -0
  306. package/dist/test/test.import.js +51 -4
  307. package/dist/test/test.import.js.map +1 -1
  308. package/dist/test/test.imports.js +22 -7
  309. package/dist/test/test.imports.js.map +1 -1
  310. package/dist/test/test.notifiers.d.ts +1 -0
  311. package/dist/test/test.notifiers.js +85 -0
  312. package/dist/test/test.notifiers.js.map +1 -0
  313. package/dist/test/test.processor.js +30 -115
  314. package/dist/test/test.processor.js.map +1 -1
  315. package/dist/test/test.products.d.ts +1 -0
  316. package/dist/test/test.products.js +49 -0
  317. package/dist/test/test.products.js.map +1 -0
  318. package/dist/tsconfig.tsbuildinfo +1 -0
  319. package/dist/types/appBuilder.types.d.ts +5 -12
  320. package/dist/types/enums.d.ts +4 -1
  321. package/dist/types/enums.js +3 -0
  322. package/dist/types/enums.js.map +1 -1
  323. package/dist/types/index.types.d.ts +4 -0
  324. package/dist/types/pricing.types.d.ts +4 -0
  325. package/dist/types/pricing.types.js +3 -0
  326. package/dist/types/pricing.types.js.map +1 -0
  327. package/dist/types/processor.types.d.ts +67 -11
  328. package/dist/types/processor.types.js.map +1 -1
  329. package/dist/types/productsBuilder.types.d.ts +132 -14
  330. package/dist/types/productsBuilder.types.js +69 -4
  331. package/dist/types/productsBuilder.types.js.map +1 -1
  332. package/dist/types/request-tracker.interface.d.ts +0 -0
  333. package/dist/types/request-tracker.interface.js +1 -0
  334. package/dist/types/request-tracker.interface.js.map +1 -0
  335. package/dist/utils/constants.d.ts +1 -0
  336. package/dist/utils/constants.js +5 -0
  337. package/dist/utils/constants.js.map +1 -0
  338. package/package.json +17 -3
@@ -0,0 +1,1492 @@
1
+ "use strict";
2
+ /**
3
+ * MySQL Database Adapter
4
+ * Implements database operations for MySQL/MariaDB
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.MySQLAdapter = void 0;
41
+ const base_adapter_1 = require("./base.adapter");
42
+ const database_types_1 = require("../types/database.types");
43
+ const uuid_1 = require("uuid");
44
+ const schema_types_1 = require("../types/schema.types");
45
+ const migration_types_1 = require("../types/migration.types");
46
+ /**
47
+ * MySQL Connection wrapper
48
+ */
49
+ class MySQLConnection {
50
+ constructor(id, connection) {
51
+ this.id = id;
52
+ this.type = database_types_1.DatabaseType.MYSQL;
53
+ this.status = database_types_1.ConnectionStatus.CONNECTED;
54
+ this.connection = connection;
55
+ }
56
+ async connect() {
57
+ this.status = database_types_1.ConnectionStatus.CONNECTED;
58
+ }
59
+ async disconnect() {
60
+ if (this.connection) {
61
+ await this.connection.end();
62
+ this.status = database_types_1.ConnectionStatus.DISCONNECTED;
63
+ }
64
+ }
65
+ isConnected() {
66
+ return this.status === database_types_1.ConnectionStatus.CONNECTED;
67
+ }
68
+ getClient() {
69
+ return this.connection;
70
+ }
71
+ getType() {
72
+ return this.type;
73
+ }
74
+ getConfig() {
75
+ throw new Error('Config not stored in connection');
76
+ }
77
+ }
78
+ /**
79
+ * MySQL Savepoint implementation
80
+ */
81
+ class MySQLSavepoint {
82
+ constructor(name, transaction, client) {
83
+ this.name = name;
84
+ this.transaction = transaction;
85
+ this.createdAt = new Date();
86
+ this.client = client;
87
+ }
88
+ async rollback() {
89
+ await this.client.query(`ROLLBACK TO SAVEPOINT \`${this.name}\``);
90
+ }
91
+ async release() {
92
+ await this.client.query(`RELEASE SAVEPOINT \`${this.name}\``);
93
+ }
94
+ }
95
+ /**
96
+ * MySQL Transaction implementation
97
+ */
98
+ class MySQLTransaction {
99
+ constructor(connection, client, options) {
100
+ this.id = (0, uuid_1.v4)();
101
+ this.connection = connection;
102
+ this.status = database_types_1.TransactionStatus.ACTIVE;
103
+ this.isolationLevel = options === null || options === void 0 ? void 0 : options.isolationLevel;
104
+ this.createdAt = new Date();
105
+ this.client = client;
106
+ this.native = client;
107
+ }
108
+ async commit() {
109
+ if (this.status !== database_types_1.TransactionStatus.ACTIVE) {
110
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.TRANSACTION_ERROR, `Cannot commit transaction: status is ${this.status}`);
111
+ }
112
+ await this.client.commit();
113
+ this.status = database_types_1.TransactionStatus.COMMITTED;
114
+ }
115
+ async rollback() {
116
+ if (this.status !== database_types_1.TransactionStatus.ACTIVE) {
117
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.TRANSACTION_ERROR, `Cannot rollback transaction: status is ${this.status}`);
118
+ }
119
+ await this.client.rollback();
120
+ this.status = database_types_1.TransactionStatus.ROLLED_BACK;
121
+ }
122
+ async savepoint(name) {
123
+ if (this.status !== database_types_1.TransactionStatus.ACTIVE) {
124
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.TRANSACTION_ERROR, `Cannot create savepoint: transaction status is ${this.status}`);
125
+ }
126
+ await this.client.query(`SAVEPOINT \`${name}\``);
127
+ return new MySQLSavepoint(name, this, this.client);
128
+ }
129
+ isActive() {
130
+ return this.status === database_types_1.TransactionStatus.ACTIVE;
131
+ }
132
+ }
133
+ /**
134
+ * MySQL Database Adapter
135
+ */
136
+ class MySQLAdapter extends base_adapter_1.BaseDatabaseAdapter {
137
+ constructor() {
138
+ super(...arguments);
139
+ this.type = database_types_1.DatabaseType.MYSQL;
140
+ }
141
+ // ==================== Connection Methods ====================
142
+ async connect(config) {
143
+ var _a, _b, _c, _d, _e, _f;
144
+ try {
145
+ // Dynamic import of mysql2/promise
146
+ // @ts-ignore - mysql2 is an optional peer dependency
147
+ const mysql = await Promise.resolve().then(() => __importStar(require('mysql2/promise')));
148
+ const connection = await mysql.createConnection(Object.assign({ host: (_a = config.options) === null || _a === void 0 ? void 0 : _a.host, port: ((_b = config.options) === null || _b === void 0 ? void 0 : _b.port) || 3306, user: ((_c = config.options) === null || _c === void 0 ? void 0 : _c.username) || ((_d = config.options) === null || _d === void 0 ? void 0 : _d.user), password: (_e = config.options) === null || _e === void 0 ? void 0 : _e.password, database: config.database, ssl: (_f = config.options) === null || _f === void 0 ? void 0 : _f.ssl }, config.options));
149
+ return new MySQLConnection(`mysql-${Date.now()}`, connection);
150
+ }
151
+ catch (error) {
152
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.CONNECTION_ERROR, `Failed to connect to MySQL: ${error.message}`, error);
153
+ }
154
+ }
155
+ async disconnect(connection) {
156
+ await connection.disconnect();
157
+ }
158
+ async testConnection(connection) {
159
+ const startTime = Date.now();
160
+ try {
161
+ const conn = connection.getClient();
162
+ await conn.query('SELECT 1');
163
+ return {
164
+ connected: true,
165
+ message: 'MySQL connection successful',
166
+ databaseType: 'MySQL',
167
+ responseTime: Date.now() - startTime,
168
+ };
169
+ }
170
+ catch (error) {
171
+ return {
172
+ connected: false,
173
+ message: `MySQL connection failed: ${error.message}`,
174
+ databaseType: 'MySQL',
175
+ responseTime: Date.now() - startTime,
176
+ error: error.message,
177
+ };
178
+ }
179
+ }
180
+ // ==================== Transaction Methods ====================
181
+ async beginTransaction(connection, options) {
182
+ try {
183
+ const conn = connection.getClient();
184
+ // Set isolation level if specified
185
+ if (options === null || options === void 0 ? void 0 : options.isolationLevel) {
186
+ const isolationLevel = options.isolationLevel.replace('_', ' ');
187
+ await conn.query(`SET TRANSACTION ISOLATION LEVEL ${isolationLevel}`);
188
+ }
189
+ // Set read-only mode if specified
190
+ if (options === null || options === void 0 ? void 0 : options.readOnly) {
191
+ await conn.query('SET TRANSACTION READ ONLY');
192
+ }
193
+ await conn.beginTransaction();
194
+ return new MySQLTransaction(connection, conn, options);
195
+ }
196
+ catch (error) {
197
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.TRANSACTION_ERROR, `Failed to begin transaction: ${error.message}`, error);
198
+ }
199
+ }
200
+ async commitTransaction(connection, transaction) {
201
+ await transaction.commit();
202
+ }
203
+ async rollbackTransaction(connection, transaction) {
204
+ await transaction.rollback();
205
+ }
206
+ async createSavepoint(connection, transaction, savepointName) {
207
+ return transaction.savepoint(savepointName);
208
+ }
209
+ async rollbackToSavepoint(_connection, _transaction, savepoint) {
210
+ await savepoint.rollback();
211
+ }
212
+ async releaseSavepoint(_connection, _transaction, savepoint) {
213
+ await savepoint.release();
214
+ }
215
+ // ==================== Query Methods ====================
216
+ async query(connection, options) {
217
+ const startTime = Date.now();
218
+ try {
219
+ const { query, params } = this.buildSelectQuery(options);
220
+ const conn = connection.getClient();
221
+ const [rows] = await conn.query(query, params);
222
+ const executionTime = Date.now() - startTime;
223
+ return {
224
+ data: rows,
225
+ count: Array.isArray(rows) ? rows.length : 0,
226
+ executionTime,
227
+ };
228
+ }
229
+ catch (error) {
230
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.QUERY_ERROR, `MySQL query failed: ${error.message}`, error);
231
+ }
232
+ }
233
+ async insert(connection, options) {
234
+ const startTime = Date.now();
235
+ try {
236
+ const { query, params } = this.buildInsertQuery(options);
237
+ const conn = connection.getClient();
238
+ const [result] = await conn.query(query, params);
239
+ const executionTime = Date.now() - startTime;
240
+ return {
241
+ insertedCount: result.affectedRows,
242
+ insertedIds: [result.insertId],
243
+ data: undefined,
244
+ executionTime,
245
+ success: true,
246
+ };
247
+ }
248
+ catch (error) {
249
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.QUERY_ERROR, `MySQL insert failed: ${error.message}`, error);
250
+ }
251
+ }
252
+ async update(connection, options) {
253
+ const startTime = Date.now();
254
+ try {
255
+ const { query, params } = this.buildUpdateQuery(options);
256
+ const conn = connection.getClient();
257
+ const [result] = await conn.query(query, params);
258
+ const executionTime = Date.now() - startTime;
259
+ return {
260
+ updatedCount: result.affectedRows,
261
+ matchedCount: result.affectedRows,
262
+ data: undefined,
263
+ executionTime,
264
+ success: true,
265
+ };
266
+ }
267
+ catch (error) {
268
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.QUERY_ERROR, `MySQL update failed: ${error.message}`, error);
269
+ }
270
+ }
271
+ async delete(connection, options) {
272
+ const startTime = Date.now();
273
+ try {
274
+ const { query, params } = this.buildDeleteQuery(options);
275
+ const conn = connection.getClient();
276
+ const [result] = await conn.query(query, params);
277
+ const executionTime = Date.now() - startTime;
278
+ return {
279
+ deletedCount: result.affectedRows,
280
+ data: undefined,
281
+ executionTime,
282
+ success: true,
283
+ };
284
+ }
285
+ catch (error) {
286
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.QUERY_ERROR, `MySQL delete failed: ${error.message}`, error);
287
+ }
288
+ }
289
+ async upsert(connection, options) {
290
+ const startTime = Date.now();
291
+ try {
292
+ const { query, params } = this.buildUpsertQuery(options);
293
+ const conn = connection.getClient();
294
+ const [result] = await conn.query(query, params);
295
+ const executionTime = Date.now() - startTime;
296
+ return {
297
+ insertedCount: 0,
298
+ updatedCount: 0,
299
+ affectedCount: result.affectedRows,
300
+ data: undefined,
301
+ executionTime,
302
+ success: true,
303
+ };
304
+ }
305
+ catch (error) {
306
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.QUERY_ERROR, `MySQL upsert failed: ${error.message}`, error);
307
+ }
308
+ }
309
+ async executeRaw(connection, options) {
310
+ const startTime = Date.now();
311
+ try {
312
+ const conn = connection.getClient();
313
+ const [rows, fields] = await conn.query(options.query, options.params || []);
314
+ const executionTime = Date.now() - startTime;
315
+ return {
316
+ rows: rows,
317
+ rowCount: Array.isArray(rows) ? rows.length : 0,
318
+ fields: fields === null || fields === void 0 ? void 0 : fields.map((f) => ({
319
+ name: f.name,
320
+ type: f.type,
321
+ })),
322
+ executionTime,
323
+ };
324
+ }
325
+ catch (error) {
326
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.QUERY_ERROR, `MySQL raw query failed: ${error.message}`, error);
327
+ }
328
+ }
329
+ // ==================== Aggregation Methods ====================
330
+ async count(connection, options) {
331
+ try {
332
+ const { query, params } = this.buildCountQuery(options);
333
+ const conn = connection.getClient();
334
+ const [rows] = await conn.query(query, params);
335
+ return parseInt(rows[0].count, 10);
336
+ }
337
+ catch (error) {
338
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.QUERY_ERROR, `MySQL count failed: ${error.message}`, error);
339
+ }
340
+ }
341
+ async sum(connection, options) {
342
+ try {
343
+ const { query, params } = this.buildAggregateQuery('SUM', options.column, options);
344
+ const conn = connection.getClient();
345
+ const [rows] = await conn.query(query, params);
346
+ return parseFloat(rows[0].result) || 0;
347
+ }
348
+ catch (error) {
349
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.QUERY_ERROR, `MySQL sum failed: ${error.message}`, error);
350
+ }
351
+ }
352
+ async avg(connection, options) {
353
+ try {
354
+ const { query, params } = this.buildAggregateQuery('AVG', options.column, options);
355
+ const conn = connection.getClient();
356
+ const [rows] = await conn.query(query, params);
357
+ return parseFloat(rows[0].result) || 0;
358
+ }
359
+ catch (error) {
360
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.QUERY_ERROR, `MySQL avg failed: ${error.message}`, error);
361
+ }
362
+ }
363
+ async min(connection, options) {
364
+ try {
365
+ const { query, params } = this.buildAggregateQuery('MIN', options.column, options);
366
+ const conn = connection.getClient();
367
+ const [rows] = await conn.query(query, params);
368
+ return rows[0].result;
369
+ }
370
+ catch (error) {
371
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.QUERY_ERROR, `MySQL min failed: ${error.message}`, error);
372
+ }
373
+ }
374
+ async max(connection, options) {
375
+ try {
376
+ const { query, params } = this.buildAggregateQuery('MAX', options.column, options);
377
+ const conn = connection.getClient();
378
+ const [rows] = await conn.query(query, params);
379
+ return rows[0].result;
380
+ }
381
+ catch (error) {
382
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.QUERY_ERROR, `MySQL max failed: ${error.message}`, error);
383
+ }
384
+ }
385
+ async groupBy(connection, options) {
386
+ try {
387
+ const { query, params } = this.buildGroupByQuery(options);
388
+ const conn = connection.getClient();
389
+ const [rows] = await conn.query(query, params);
390
+ return rows;
391
+ }
392
+ catch (error) {
393
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.QUERY_ERROR, `MySQL groupBy failed: ${error.message}`, error);
394
+ }
395
+ }
396
+ async aggregate(connection, options) {
397
+ try {
398
+ const { query, params } = this.buildMultiAggregateQuery(options);
399
+ const conn = connection.getClient();
400
+ const [rows] = await conn.query(query, params);
401
+ return rows[0] || {};
402
+ }
403
+ catch (error) {
404
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.QUERY_ERROR, `MySQL aggregate failed: ${error.message}`, error);
405
+ }
406
+ }
407
+ // ==================== Schema Methods ====================
408
+ async createTable(connection, schema, options) {
409
+ const startTime = Date.now();
410
+ try {
411
+ const query = this.buildCreateTableQuery(schema, options);
412
+ const conn = connection.getClient();
413
+ await conn.query(query);
414
+ const executionTime = Date.now() - startTime;
415
+ return {
416
+ success: true,
417
+ operation: 'create',
418
+ table: schema.name,
419
+ executionTime,
420
+ };
421
+ }
422
+ catch (error) {
423
+ return {
424
+ success: false,
425
+ operation: 'create',
426
+ table: schema.name,
427
+ error: error.message,
428
+ executionTime: Date.now() - startTime,
429
+ };
430
+ }
431
+ }
432
+ async dropTable(connection, tableName) {
433
+ const startTime = Date.now();
434
+ try {
435
+ const conn = connection.getClient();
436
+ await conn.query(`DROP TABLE IF EXISTS \`${tableName}\``);
437
+ return {
438
+ success: true,
439
+ operation: 'drop',
440
+ table: tableName,
441
+ executionTime: Date.now() - startTime,
442
+ };
443
+ }
444
+ catch (error) {
445
+ return {
446
+ success: false,
447
+ operation: 'drop',
448
+ table: tableName,
449
+ error: error.message,
450
+ executionTime: Date.now() - startTime,
451
+ };
452
+ }
453
+ }
454
+ async alterTable(connection, tableName, alterations, options) {
455
+ const startTime = Date.now();
456
+ try {
457
+ const conn = connection.getClient();
458
+ const queries = this.buildAlterTableQueries(tableName, alterations);
459
+ for (const query of queries) {
460
+ await conn.query(query);
461
+ }
462
+ return {
463
+ success: true,
464
+ operation: 'alter',
465
+ table: tableName,
466
+ executionTime: Date.now() - startTime,
467
+ };
468
+ }
469
+ catch (error) {
470
+ return {
471
+ success: false,
472
+ operation: 'alter',
473
+ table: tableName,
474
+ error: error.message,
475
+ executionTime: Date.now() - startTime,
476
+ };
477
+ }
478
+ }
479
+ async getTableSchema(connection, tableName) {
480
+ try {
481
+ const conn = connection.getClient();
482
+ const query = `
483
+ SELECT
484
+ COLUMN_NAME as column_name,
485
+ DATA_TYPE as data_type,
486
+ IS_NULLABLE as is_nullable,
487
+ COLUMN_DEFAULT as column_default,
488
+ CHARACTER_MAXIMUM_LENGTH as character_maximum_length,
489
+ NUMERIC_PRECISION as numeric_precision,
490
+ NUMERIC_SCALE as numeric_scale,
491
+ COLUMN_KEY as column_key
492
+ FROM INFORMATION_SCHEMA.COLUMNS
493
+ WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?
494
+ ORDER BY ORDINAL_POSITION
495
+ `;
496
+ const [rows] = await conn.query(query, [tableName]);
497
+ const columns = rows.map((row) => ({
498
+ name: row.column_name,
499
+ type: this.mapMySQLTypeToColumnType(row.data_type),
500
+ nullable: row.is_nullable === 'YES',
501
+ primaryKey: row.column_key === 'PRI',
502
+ unique: row.column_key === 'UNI',
503
+ defaultValue: row.column_default,
504
+ length: row.character_maximum_length,
505
+ precision: row.numeric_precision,
506
+ scale: row.numeric_scale,
507
+ }));
508
+ return {
509
+ name: tableName,
510
+ columns,
511
+ };
512
+ }
513
+ catch (error) {
514
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.SCHEMA_ERROR, `Failed to get MySQL table schema: ${error.message}`, error);
515
+ }
516
+ }
517
+ async listTables(connection) {
518
+ try {
519
+ const conn = connection.getClient();
520
+ const [rows] = await conn.query('SHOW TABLES');
521
+ return rows.map((row) => Object.values(row)[0]);
522
+ }
523
+ catch (error) {
524
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.SCHEMA_ERROR, `Failed to list MySQL tables: ${error.message}`, error);
525
+ }
526
+ }
527
+ async tableExists(connection, tableName) {
528
+ try {
529
+ const conn = connection.getClient();
530
+ const query = `
531
+ SELECT COUNT(*) as count
532
+ FROM INFORMATION_SCHEMA.TABLES
533
+ WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?
534
+ `;
535
+ const [rows] = await conn.query(query, [tableName]);
536
+ return rows[0].count > 0;
537
+ }
538
+ catch (error) {
539
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.SCHEMA_ERROR, `Failed to check MySQL table existence: ${error.message}`, error);
540
+ }
541
+ }
542
+ // ==================== Index Methods ====================
543
+ async createIndex(connection, options) {
544
+ const startTime = Date.now();
545
+ try {
546
+ const query = this.buildCreateIndexQuery(options);
547
+ const conn = connection.getClient();
548
+ await conn.query(query);
549
+ return {
550
+ success: true,
551
+ operation: 'create',
552
+ indexName: options.index.name,
553
+ table: options.table,
554
+ executionTime: Date.now() - startTime,
555
+ };
556
+ }
557
+ catch (error) {
558
+ return {
559
+ success: false,
560
+ operation: 'create',
561
+ indexName: options.index.name,
562
+ table: options.table,
563
+ error: error.message,
564
+ executionTime: Date.now() - startTime,
565
+ };
566
+ }
567
+ }
568
+ async dropIndex(connection, options) {
569
+ const startTime = Date.now();
570
+ try {
571
+ const conn = connection.getClient();
572
+ await conn.query(`DROP INDEX \`${options.indexName}\` ON \`${options.table}\``);
573
+ return {
574
+ success: true,
575
+ operation: 'drop',
576
+ indexName: options.indexName,
577
+ table: options.table,
578
+ executionTime: Date.now() - startTime,
579
+ };
580
+ }
581
+ catch (error) {
582
+ return {
583
+ success: false,
584
+ operation: 'drop',
585
+ indexName: options.indexName,
586
+ table: options.table,
587
+ error: error.message,
588
+ executionTime: Date.now() - startTime,
589
+ };
590
+ }
591
+ }
592
+ async listIndexes(connection, options) {
593
+ try {
594
+ const conn = connection.getClient();
595
+ const query = `
596
+ SELECT
597
+ INDEX_NAME as index_name,
598
+ COLUMN_NAME as column_name,
599
+ NON_UNIQUE as non_unique,
600
+ INDEX_TYPE as index_type
601
+ FROM INFORMATION_SCHEMA.STATISTICS
602
+ WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?
603
+ ORDER BY INDEX_NAME, SEQ_IN_INDEX
604
+ `;
605
+ const [rows] = await conn.query(query, [options.table]);
606
+ const indexMap = new Map();
607
+ rows.forEach((row) => {
608
+ if (!indexMap.has(row.index_name)) {
609
+ indexMap.set(row.index_name, {
610
+ name: row.index_name,
611
+ table: options.table,
612
+ columns: [],
613
+ columnDetails: [],
614
+ unique: row.non_unique === 0,
615
+ primaryKey: row.index_name === 'PRIMARY',
616
+ type: row.index_type,
617
+ });
618
+ }
619
+ const indexInfo = indexMap.get(row.index_name);
620
+ indexInfo.columns.push(row.column_name);
621
+ indexInfo.columnDetails.push({
622
+ name: row.column_name,
623
+ order: 'ASC',
624
+ });
625
+ });
626
+ return Array.from(indexMap.values());
627
+ }
628
+ catch (error) {
629
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.INDEX_ERROR, `Failed to list MySQL indexes: ${error.message}`, error);
630
+ }
631
+ }
632
+ async getIndexStatistics(connection, tableName, indexName) {
633
+ try {
634
+ const conn = connection.getClient();
635
+ let query = `
636
+ SELECT
637
+ INDEX_NAME as index_name,
638
+ CARDINALITY as cardinality
639
+ FROM INFORMATION_SCHEMA.STATISTICS
640
+ WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ?
641
+ `;
642
+ const params = [tableName];
643
+ if (indexName) {
644
+ query += ' AND INDEX_NAME = ?';
645
+ params.push(indexName);
646
+ }
647
+ const [rows] = await conn.query(query, params);
648
+ return rows.map((row) => ({
649
+ indexName: row.index_name,
650
+ table: tableName,
651
+ size: 0, // MySQL doesn't provide this easily
652
+ tuplesRead: row.cardinality || 0,
653
+ }));
654
+ }
655
+ catch (error) {
656
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.INDEX_ERROR, `Failed to get MySQL index statistics: ${error.message}`, error);
657
+ }
658
+ }
659
+ // ==================== Migration Methods ====================
660
+ /**
661
+ * Build SQL for a migration operation
662
+ */
663
+ async buildMigrationOperationSQL(operation) {
664
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
665
+ switch (operation.type) {
666
+ case migration_types_1.MigrationOperationType.RAW_SQL:
667
+ return operation.sql || null;
668
+ case migration_types_1.MigrationOperationType.CREATE_TABLE:
669
+ if ((_a = operation.params) === null || _a === void 0 ? void 0 : _a.schema) {
670
+ const schema = operation.params.schema;
671
+ const columns = schema.columns
672
+ .map((col) => {
673
+ let def = `\`${col.name}\` ${this.mapColumnTypeToMySQL(col.type)}`;
674
+ if (col.primaryKey)
675
+ def += ' PRIMARY KEY';
676
+ if (col.autoIncrement)
677
+ def += ' AUTO_INCREMENT';
678
+ if (!col.nullable)
679
+ def += ' NOT NULL';
680
+ if (col.unique)
681
+ def += ' UNIQUE';
682
+ if (col.defaultValue !== undefined) {
683
+ def += ` DEFAULT ${this.escapeValue(col.defaultValue)}`;
684
+ }
685
+ return def;
686
+ })
687
+ .join(', ');
688
+ return `CREATE TABLE \`${schema.name}\` (${columns})`;
689
+ }
690
+ return null;
691
+ case migration_types_1.MigrationOperationType.DROP_TABLE:
692
+ return operation.table ? `DROP TABLE IF EXISTS \`${operation.table}\`` : null;
693
+ case migration_types_1.MigrationOperationType.ADD_COLUMN:
694
+ if (operation.table && ((_b = operation.params) === null || _b === void 0 ? void 0 : _b.column)) {
695
+ const col = operation.params.column;
696
+ let def = `ALTER TABLE \`${operation.table}\` ADD COLUMN \`${col.name}\` ${this.mapColumnTypeToMySQL(col.type)}`;
697
+ if (!col.nullable)
698
+ def += ' NOT NULL';
699
+ if (col.defaultValue !== undefined) {
700
+ def += ` DEFAULT ${this.escapeValue(col.defaultValue)}`;
701
+ }
702
+ return def;
703
+ }
704
+ return null;
705
+ case migration_types_1.MigrationOperationType.DROP_COLUMN:
706
+ return operation.table && ((_c = operation.params) === null || _c === void 0 ? void 0 : _c.columnName)
707
+ ? `ALTER TABLE \`${operation.table}\` DROP COLUMN \`${operation.params.columnName}\``
708
+ : null;
709
+ case migration_types_1.MigrationOperationType.MODIFY_COLUMN:
710
+ if (operation.table && ((_d = operation.params) === null || _d === void 0 ? void 0 : _d.column)) {
711
+ const col = operation.params.column;
712
+ return `ALTER TABLE \`${operation.table}\` MODIFY COLUMN \`${col.name}\` ${this.mapColumnTypeToMySQL(col.type)}`;
713
+ }
714
+ return null;
715
+ case migration_types_1.MigrationOperationType.RENAME_COLUMN:
716
+ return operation.table && ((_e = operation.params) === null || _e === void 0 ? void 0 : _e.oldName) && ((_f = operation.params) === null || _f === void 0 ? void 0 : _f.newName)
717
+ ? `ALTER TABLE \`${operation.table}\` RENAME COLUMN \`${operation.params.oldName}\` TO \`${operation.params.newName}\``
718
+ : null;
719
+ case migration_types_1.MigrationOperationType.ADD_INDEX:
720
+ if (operation.table && ((_g = operation.params) === null || _g === void 0 ? void 0 : _g.indexName) && ((_h = operation.params) === null || _h === void 0 ? void 0 : _h.columns)) {
721
+ const unique = operation.params.unique ? 'UNIQUE ' : '';
722
+ const columns = operation.params.columns.map((col) => `\`${col}\``).join(', ');
723
+ return `CREATE ${unique}INDEX \`${operation.params.indexName}\` ON \`${operation.table}\` (${columns})`;
724
+ }
725
+ return null;
726
+ case migration_types_1.MigrationOperationType.DROP_INDEX:
727
+ return ((_j = operation.params) === null || _j === void 0 ? void 0 : _j.indexName) && operation.table
728
+ ? `DROP INDEX \`${operation.params.indexName}\` ON \`${operation.table}\``
729
+ : null;
730
+ case migration_types_1.MigrationOperationType.ADD_CONSTRAINT:
731
+ if (operation.table && ((_k = operation.params) === null || _k === void 0 ? void 0 : _k.constraintName) && ((_l = operation.params) === null || _l === void 0 ? void 0 : _l.definition)) {
732
+ return `ALTER TABLE \`${operation.table}\` ADD CONSTRAINT \`${operation.params.constraintName}\` ${operation.params.definition}`;
733
+ }
734
+ return null;
735
+ case migration_types_1.MigrationOperationType.DROP_CONSTRAINT:
736
+ return operation.table && ((_m = operation.params) === null || _m === void 0 ? void 0 : _m.constraintName)
737
+ ? `ALTER TABLE \`${operation.table}\` DROP CONSTRAINT \`${operation.params.constraintName}\``
738
+ : null;
739
+ default:
740
+ return null;
741
+ }
742
+ }
743
+ async runMigration(connection, migration, options) {
744
+ const startTime = Date.now();
745
+ const statements = [];
746
+ try {
747
+ const conn = connection.getClient();
748
+ await conn.query('START TRANSACTION');
749
+ try {
750
+ // Execute migration operations
751
+ for (const operation of migration.up) {
752
+ const sql = await this.buildMigrationOperationSQL(operation);
753
+ if (sql) {
754
+ statements.push(sql);
755
+ await conn.query(sql);
756
+ }
757
+ }
758
+ // Record migration in history table
759
+ await this.recordMigration(conn, migration, migration_types_1.MigrationDirection.UP);
760
+ await conn.query('COMMIT');
761
+ return {
762
+ tag: migration.tag,
763
+ status: migration_types_1.MigrationStatus.COMPLETED,
764
+ direction: migration_types_1.MigrationDirection.UP,
765
+ executedAt: new Date(),
766
+ duration: Date.now() - startTime,
767
+ statements,
768
+ };
769
+ }
770
+ catch (error) {
771
+ await conn.query('ROLLBACK');
772
+ throw error;
773
+ }
774
+ }
775
+ catch (error) {
776
+ return {
777
+ tag: migration.tag,
778
+ status: migration_types_1.MigrationStatus.FAILED,
779
+ direction: migration_types_1.MigrationDirection.UP,
780
+ executedAt: new Date(),
781
+ duration: Date.now() - startTime,
782
+ error: error.message,
783
+ statements,
784
+ };
785
+ }
786
+ }
787
+ async rollbackMigration(connection, migration, options) {
788
+ const startTime = Date.now();
789
+ const statements = [];
790
+ try {
791
+ const conn = connection.getClient();
792
+ await conn.query('START TRANSACTION');
793
+ try {
794
+ // Execute rollback operations
795
+ for (const operation of migration.down) {
796
+ const sql = await this.buildMigrationOperationSQL(operation);
797
+ if (sql) {
798
+ statements.push(sql);
799
+ await conn.query(sql);
800
+ }
801
+ }
802
+ // Remove migration from history table
803
+ await this.removeMigration(conn, migration.tag);
804
+ await conn.query('COMMIT');
805
+ return {
806
+ tag: migration.tag,
807
+ status: migration_types_1.MigrationStatus.ROLLED_BACK,
808
+ direction: migration_types_1.MigrationDirection.DOWN,
809
+ executedAt: new Date(),
810
+ duration: Date.now() - startTime,
811
+ statements,
812
+ };
813
+ }
814
+ catch (error) {
815
+ await conn.query('ROLLBACK');
816
+ throw error;
817
+ }
818
+ }
819
+ catch (error) {
820
+ return {
821
+ tag: migration.tag,
822
+ status: migration_types_1.MigrationStatus.FAILED,
823
+ direction: migration_types_1.MigrationDirection.DOWN,
824
+ executedAt: new Date(),
825
+ duration: Date.now() - startTime,
826
+ error: error.message,
827
+ statements,
828
+ };
829
+ }
830
+ }
831
+ async getMigrationHistory(connection, options) {
832
+ try {
833
+ const conn = connection.getClient();
834
+ // Ensure migration table exists
835
+ await this.ensureMigrationTable(conn);
836
+ const query = `
837
+ SELECT tag, name, executed_at
838
+ FROM _ductape_migrations
839
+ ORDER BY executed_at DESC
840
+ `;
841
+ const [rows] = await conn.query(query);
842
+ return rows.map((row) => ({
843
+ tag: row.tag,
844
+ name: row.name,
845
+ env: options.env,
846
+ product: options.product,
847
+ database: options.database,
848
+ status: migration_types_1.MigrationStatus.COMPLETED,
849
+ direction: migration_types_1.MigrationDirection.UP,
850
+ appliedAt: row.executed_at,
851
+ }));
852
+ }
853
+ catch (error) {
854
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.MIGRATION_ERROR, `Failed to get MySQL migration history: ${error.message}`, error);
855
+ }
856
+ }
857
+ // ==================== Query Builder Helpers ====================
858
+ /**
859
+ * Build SELECT query from options
860
+ */
861
+ buildSelectQuery(options) {
862
+ const params = [];
863
+ // Handle includes
864
+ const hasIncludes = options.include && (Array.isArray(options.include) ? options.include.length > 0 : true);
865
+ // SELECT clause
866
+ let selectColumns;
867
+ if (options.select) {
868
+ const cols = Array.isArray(options.select) ? options.select : [options.select];
869
+ // Prefix main table columns with table name
870
+ selectColumns = cols.map((col) => `\`${options.table}\`.\`${col}\``).join(', ');
871
+ }
872
+ else {
873
+ // Select all from main table
874
+ selectColumns = hasIncludes ? `\`${options.table}\`.*` : '*';
875
+ }
876
+ // Add included relation columns
877
+ if (hasIncludes) {
878
+ const includes = Array.isArray(options.include) ? options.include : [options.include];
879
+ includes.forEach((include) => {
880
+ const relationAlias = include.relation;
881
+ if (include.select && include.select.length > 0) {
882
+ const relationCols = include.select.map((col) => `\`${relationAlias}\`.\`${col}\` as \`${relationAlias}_${col}\``).join(', ');
883
+ selectColumns += `, ${relationCols}`;
884
+ }
885
+ else {
886
+ // Use JSON aggregation for one-to-many
887
+ if (include.type === 'one-to-many') {
888
+ selectColumns += `, JSON_ARRAYAGG(JSON_OBJECT('*', \`${relationAlias}\`.*)) as \`${relationAlias}\``;
889
+ }
890
+ else {
891
+ selectColumns += `, JSON_OBJECT('*', \`${relationAlias}\`.*) as \`${relationAlias}\``;
892
+ }
893
+ }
894
+ });
895
+ }
896
+ let query = `SELECT ${options.distinct ? 'DISTINCT ' : ''}${selectColumns} FROM \`${options.table}\``;
897
+ // JOIN clauses for includes
898
+ if (hasIncludes) {
899
+ const includes = Array.isArray(options.include) ? options.include : [options.include];
900
+ includes.forEach((include) => {
901
+ const { joinClause } = this.buildIncludeJoin(options.table, include);
902
+ query += ` ${joinClause}`;
903
+ });
904
+ }
905
+ // WHERE clause
906
+ if (options.where) {
907
+ const { clause, values } = this.buildWhereClause(options.where);
908
+ query += ` WHERE ${clause}`;
909
+ params.push(...values);
910
+ }
911
+ // GROUP BY clause
912
+ if (options.groupBy && options.groupBy.length > 0) {
913
+ query += ` GROUP BY ${options.groupBy.map((col) => `\`${col}\``).join(', ')}`;
914
+ }
915
+ else if (hasIncludes) {
916
+ // Auto group by main table primary key for one-to-many relations
917
+ const includes = Array.isArray(options.include) ? options.include : [options.include];
918
+ const hasOneToMany = includes.some(inc => inc.type === 'one-to-many');
919
+ if (hasOneToMany) {
920
+ query += ` GROUP BY \`${options.table}\`.\`id\``;
921
+ }
922
+ }
923
+ // HAVING clause
924
+ if (options.having) {
925
+ const { clause, values } = this.buildWhereClause(options.having);
926
+ query += ` HAVING ${clause}`;
927
+ params.push(...values);
928
+ }
929
+ // ORDER BY clause
930
+ if (options.orderBy) {
931
+ const orderByArray = Array.isArray(options.orderBy) ? options.orderBy : [options.orderBy];
932
+ const orderClauses = orderByArray.map((order) => `\`${options.table}\`.\`${order.column}\` ${order.order || 'ASC'}`);
933
+ query += ` ORDER BY ${orderClauses.join(', ')}`;
934
+ }
935
+ // LIMIT clause
936
+ if (options.limit) {
937
+ query += ` LIMIT ?`;
938
+ params.push(options.limit);
939
+ }
940
+ // OFFSET clause
941
+ if (options.offset) {
942
+ query += ` OFFSET ?`;
943
+ params.push(options.offset);
944
+ }
945
+ return { query, params };
946
+ }
947
+ /**
948
+ * Build JOIN clause for include relationships
949
+ */
950
+ buildIncludeJoin(mainTable, include) {
951
+ const relationTable = include.relation;
952
+ const foreignKey = include.foreignKey || `${relationTable}_id`;
953
+ const primaryKey = include.primaryKey || 'id';
954
+ const joinType = include.type === 'one-to-many' || include.type === 'one-to-one' ? 'LEFT' : 'INNER';
955
+ let joinClause;
956
+ if (include.type === 'many-to-many' && include.through) {
957
+ // Many-to-many with junction table
958
+ const throughTable = include.through;
959
+ const throughForeignKey = include.throughForeignKey || `${mainTable}_id`;
960
+ const throughRelatedKey = include.throughRelatedKey || `${relationTable}_id`;
961
+ joinClause = `${joinType} JOIN \`${throughTable}\` ON \`${mainTable}\`.\`${primaryKey}\` = \`${throughTable}\`.\`${throughForeignKey}\` `;
962
+ joinClause += `${joinType} JOIN \`${relationTable}\` ON \`${throughTable}\`.\`${throughRelatedKey}\` = \`${relationTable}\`.\`${primaryKey}\``;
963
+ }
964
+ else if (include.type === 'one-to-many') {
965
+ // One-to-many: foreign key is in the related table
966
+ joinClause = `${joinType} JOIN \`${relationTable}\` ON \`${mainTable}\`.\`${primaryKey}\` = \`${relationTable}\`.\`${foreignKey}\``;
967
+ }
968
+ else {
969
+ // Many-to-one or one-to-one: foreign key is in the main table
970
+ joinClause = `${joinType} JOIN \`${relationTable}\` ON \`${mainTable}\`.\`${foreignKey}\` = \`${relationTable}\`.\`${primaryKey}\``;
971
+ }
972
+ // Add where clause for the relation if specified
973
+ if (include.where) {
974
+ const { clause } = this.buildWhereClause(include.where);
975
+ joinClause += ` AND ${clause}`;
976
+ }
977
+ return { joinClause };
978
+ }
979
+ /**
980
+ * Build WHERE clause from options
981
+ * Supports both simplified syntax (GT, LT, AND, OR) and legacy syntax ($gt, $lt, $and, $or)
982
+ */
983
+ buildWhereClause(where) {
984
+ const values = [];
985
+ const buildCondition = (condition) => {
986
+ if (typeof condition !== 'object' || condition === null) {
987
+ values.push(condition);
988
+ return '?';
989
+ }
990
+ // Handle logical operators (supports $AND, AND, and legacy $and)
991
+ if (condition.$AND || condition.AND || condition.$and) {
992
+ const andConditions = condition.$AND || condition.AND || condition.$and;
993
+ if (typeof andConditions === 'object' && !Array.isArray(andConditions)) {
994
+ // New syntax: { $AND: { col1: val1, col2: val2 } }
995
+ return buildCondition(andConditions);
996
+ }
997
+ else {
998
+ // Legacy syntax: { $and: [cond1, cond2] }
999
+ const subConditions = andConditions.map(buildCondition);
1000
+ return `(${subConditions.join(' AND ')})`;
1001
+ }
1002
+ }
1003
+ if (condition.$OR || condition.OR || condition.$or) {
1004
+ const orConditions = condition.$OR || condition.OR || condition.$or;
1005
+ if (typeof orConditions === 'object' && !Array.isArray(orConditions)) {
1006
+ // New syntax: { $OR: { col1: val1, col2: val2 } }
1007
+ const subClauses = [];
1008
+ for (const [key, value] of Object.entries(orConditions)) {
1009
+ if (key === '$AND' || key === 'AND' || key === '$and' || key === '$OR' || key === 'OR' || key === '$or') {
1010
+ subClauses.push(buildCondition({ [key]: value }));
1011
+ }
1012
+ else {
1013
+ subClauses.push(buildCondition({ [key]: value }));
1014
+ }
1015
+ }
1016
+ return `(${subClauses.join(' OR ')})`;
1017
+ }
1018
+ else {
1019
+ // Legacy syntax: { $or: [cond1, cond2] }
1020
+ const subConditions = orConditions.map(buildCondition);
1021
+ return `(${subConditions.join(' OR ')})`;
1022
+ }
1023
+ }
1024
+ // Handle column conditions
1025
+ const conditions = [];
1026
+ for (const [key, value] of Object.entries(condition)) {
1027
+ // Skip logical operators
1028
+ if (key === '$AND' || key === 'AND' || key === '$and' || key === '$OR' || key === 'OR' || key === '$or') {
1029
+ continue;
1030
+ }
1031
+ if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
1032
+ // Handle comparison operators
1033
+ for (const [op, opValue] of Object.entries(value)) {
1034
+ switch (op) {
1035
+ // Preferred $-prefixed syntax
1036
+ case '$GT':
1037
+ case 'GT':
1038
+ case '$gt':
1039
+ values.push(opValue);
1040
+ conditions.push(`\`${key}\` > ?`);
1041
+ break;
1042
+ case '$GTE':
1043
+ case 'GTE':
1044
+ case '$gte':
1045
+ values.push(opValue);
1046
+ conditions.push(`\`${key}\` >= ?`);
1047
+ break;
1048
+ case '$LT':
1049
+ case 'LT':
1050
+ case '$lt':
1051
+ values.push(opValue);
1052
+ conditions.push(`\`${key}\` < ?`);
1053
+ break;
1054
+ case '$LTE':
1055
+ case 'LTE':
1056
+ case '$lte':
1057
+ values.push(opValue);
1058
+ conditions.push(`\`${key}\` <= ?`);
1059
+ break;
1060
+ case '$NE':
1061
+ case '$NOT':
1062
+ case 'NE':
1063
+ case 'NOT':
1064
+ case '$ne':
1065
+ values.push(opValue);
1066
+ conditions.push(`\`${key}\` != ?`);
1067
+ break;
1068
+ case '$IN':
1069
+ case 'IN':
1070
+ case '$in':
1071
+ if (Array.isArray(opValue)) {
1072
+ const placeholders = opValue.map(() => '?').join(', ');
1073
+ values.push(...opValue);
1074
+ conditions.push(`\`${key}\` IN (${placeholders})`);
1075
+ }
1076
+ break;
1077
+ case '$NOT_IN':
1078
+ case 'NOT_IN':
1079
+ case '$nin':
1080
+ if (Array.isArray(opValue)) {
1081
+ const placeholders = opValue.map(() => '?').join(', ');
1082
+ values.push(...opValue);
1083
+ conditions.push(`\`${key}\` NOT IN (${placeholders})`);
1084
+ }
1085
+ break;
1086
+ case '$LIKE':
1087
+ case 'LIKE':
1088
+ case '$like':
1089
+ values.push(opValue);
1090
+ conditions.push(`\`${key}\` LIKE ?`);
1091
+ break;
1092
+ case '$IS_NULL':
1093
+ case 'IS_NULL':
1094
+ case '$null':
1095
+ conditions.push(`\`${key}\` IS NULL`);
1096
+ break;
1097
+ case '$IS_NOT_NULL':
1098
+ case 'IS_NOT_NULL':
1099
+ case '$notNull':
1100
+ conditions.push(`\`${key}\` IS NOT NULL`);
1101
+ break;
1102
+ case '$BETWEEN':
1103
+ case 'BETWEEN':
1104
+ case '$between':
1105
+ if (Array.isArray(opValue) && opValue.length === 2) {
1106
+ values.push(opValue[0], opValue[1]);
1107
+ conditions.push(`\`${key}\` BETWEEN ? AND ?`);
1108
+ }
1109
+ break;
1110
+ }
1111
+ }
1112
+ }
1113
+ else {
1114
+ // Simple equality
1115
+ values.push(value);
1116
+ conditions.push(`\`${key}\` = ?`);
1117
+ }
1118
+ }
1119
+ return conditions.join(' AND ');
1120
+ };
1121
+ const clause = buildCondition(where);
1122
+ return { clause, values };
1123
+ }
1124
+ /**
1125
+ * Build COUNT query
1126
+ */
1127
+ buildCountQuery(options) {
1128
+ const params = [];
1129
+ const column = options.column ? `\`${options.column}\`` : '*';
1130
+ let query = `SELECT COUNT(${column}) as count FROM \`${options.table}\``;
1131
+ if (options.where) {
1132
+ const { clause, values } = this.buildWhereClause(options.where);
1133
+ query += ` WHERE ${clause}`;
1134
+ params.push(...values);
1135
+ }
1136
+ return { query, params };
1137
+ }
1138
+ /**
1139
+ * Build aggregate query
1140
+ */
1141
+ buildAggregateQuery(fn, column, options) {
1142
+ const params = [];
1143
+ let query = `SELECT ${fn}(\`${column}\`) as result FROM \`${options.table}\``;
1144
+ if (options.where) {
1145
+ const { clause, values } = this.buildWhereClause(options.where);
1146
+ query += ` WHERE ${clause}`;
1147
+ params.push(...values);
1148
+ }
1149
+ return { query, params };
1150
+ }
1151
+ /**
1152
+ * Build INSERT query
1153
+ */
1154
+ buildInsertQuery(options) {
1155
+ const dataArray = Array.isArray(options.data) ? options.data : [options.data];
1156
+ const columns = Object.keys(dataArray[0]);
1157
+ const params = [];
1158
+ let query = `INSERT INTO \`${options.table}\` (${columns.map((col) => `\`${col}\``).join(', ')}) VALUES `;
1159
+ const valuesClauses = dataArray.map((data) => {
1160
+ const placeholders = columns.map(() => '?');
1161
+ params.push(...columns.map((col) => data[col]));
1162
+ return `(${placeholders.join(', ')})`;
1163
+ });
1164
+ query += valuesClauses.join(', ');
1165
+ return { query, params };
1166
+ }
1167
+ /**
1168
+ * Build UPDATE query
1169
+ */
1170
+ buildUpdateQuery(options) {
1171
+ const params = [];
1172
+ const setClauses = Object.keys(options.data).map((key) => {
1173
+ params.push(options.data[key]);
1174
+ return `\`${key}\` = ?`;
1175
+ });
1176
+ let query = `UPDATE \`${options.table}\` SET ${setClauses.join(', ')}`;
1177
+ if (options.where) {
1178
+ const { clause, values } = this.buildWhereClause(options.where);
1179
+ query += ` WHERE ${clause}`;
1180
+ params.push(...values);
1181
+ }
1182
+ return { query, params };
1183
+ }
1184
+ /**
1185
+ * Build DELETE query
1186
+ */
1187
+ buildDeleteQuery(options) {
1188
+ const params = [];
1189
+ let query = `DELETE FROM \`${options.table}\``;
1190
+ if (options.where) {
1191
+ const { clause, values } = this.buildWhereClause(options.where);
1192
+ query += ` WHERE ${clause}`;
1193
+ params.push(...values);
1194
+ }
1195
+ return { query, params };
1196
+ }
1197
+ /**
1198
+ * Build UPSERT query (INSERT ... ON DUPLICATE KEY UPDATE)
1199
+ */
1200
+ buildUpsertQuery(options) {
1201
+ const data = Array.isArray(options.data) ? options.data[0] : options.data;
1202
+ const columns = Object.keys(data);
1203
+ const params = [];
1204
+ let query = `INSERT INTO \`${options.table}\` (${columns.map((col) => `\`${col}\``).join(', ')}) VALUES (`;
1205
+ query += columns.map(() => '?').join(', ');
1206
+ params.push(...columns.map((col) => data[col]));
1207
+ query += ') ON DUPLICATE KEY UPDATE ';
1208
+ const updateClauses = columns
1209
+ .filter((col) => !options.uniqueColumns.includes(col))
1210
+ .map((col) => `\`${col}\` = VALUES(\`${col}\`)`);
1211
+ query += updateClauses.join(', ');
1212
+ return { query, params };
1213
+ }
1214
+ /**
1215
+ * Build GROUP BY query
1216
+ */
1217
+ buildGroupByQuery(options) {
1218
+ const params = [];
1219
+ const groupColumns = options.groupBy.map((col) => `\`${col}\``);
1220
+ const selectColumns = [...groupColumns];
1221
+ // Build aggregations
1222
+ if (options.aggregate) {
1223
+ Object.entries(options.aggregate).forEach(([alias, agg]) => {
1224
+ const aggObj = agg;
1225
+ if (aggObj.$COUNT !== undefined) {
1226
+ const column = aggObj.$COUNT === '*' ? '*' : `\`${aggObj.$COUNT}\``;
1227
+ selectColumns.push(`COUNT(${column}) as \`${alias}\``);
1228
+ }
1229
+ else if (aggObj.$SUM !== undefined) {
1230
+ selectColumns.push(`SUM(\`${aggObj.$SUM}\`) as \`${alias}\``);
1231
+ }
1232
+ else if (aggObj.$AVG !== undefined) {
1233
+ selectColumns.push(`AVG(\`${aggObj.$AVG}\`) as \`${alias}\``);
1234
+ }
1235
+ else if (aggObj.$MIN !== undefined) {
1236
+ selectColumns.push(`MIN(\`${aggObj.$MIN}\`) as \`${alias}\``);
1237
+ }
1238
+ else if (aggObj.$MAX !== undefined) {
1239
+ selectColumns.push(`MAX(\`${aggObj.$MAX}\`) as \`${alias}\``);
1240
+ }
1241
+ else if (aggObj.$GROUP_CONCAT !== undefined) {
1242
+ selectColumns.push(`GROUP_CONCAT(\`${aggObj.$GROUP_CONCAT}\`) as \`${alias}\``);
1243
+ }
1244
+ });
1245
+ }
1246
+ let query = `SELECT ${selectColumns.join(', ')} FROM \`${options.table}\``;
1247
+ if (options.where) {
1248
+ const { clause, values } = this.buildWhereClause(options.where);
1249
+ query += ` WHERE ${clause}`;
1250
+ params.push(...values);
1251
+ }
1252
+ query += ` GROUP BY ${groupColumns.join(', ')}`;
1253
+ return { query, params };
1254
+ }
1255
+ /**
1256
+ * Build multi-aggregate query
1257
+ */
1258
+ buildMultiAggregateQuery(options) {
1259
+ const params = [];
1260
+ const aggregations = Object.entries(options.operations).map(([alias, agg]) => {
1261
+ const aggObj = agg;
1262
+ if (aggObj.$COUNT !== undefined) {
1263
+ const column = aggObj.$COUNT === '*' ? '*' : `\`${aggObj.$COUNT}\``;
1264
+ return `COUNT(${column}) as \`${alias}\``;
1265
+ }
1266
+ if (aggObj.$SUM !== undefined) {
1267
+ return `SUM(\`${aggObj.$SUM}\`) as \`${alias}\``;
1268
+ }
1269
+ if (aggObj.$AVG !== undefined) {
1270
+ return `AVG(\`${aggObj.$AVG}\`) as \`${alias}\``;
1271
+ }
1272
+ if (aggObj.$MIN !== undefined) {
1273
+ return `MIN(\`${aggObj.$MIN}\`) as \`${alias}\``;
1274
+ }
1275
+ if (aggObj.$MAX !== undefined) {
1276
+ return `MAX(\`${aggObj.$MAX}\`) as \`${alias}\``;
1277
+ }
1278
+ if (aggObj.$GROUP_CONCAT !== undefined) {
1279
+ return `GROUP_CONCAT(\`${aggObj.$GROUP_CONCAT}\`) as \`${alias}\``;
1280
+ }
1281
+ throw new database_types_1.DatabaseError(database_types_1.DatabaseErrorType.VALIDATION_ERROR, `Invalid aggregation operation for alias "${alias}". Use format: { $COUNT: '*' }, { $SUM: 'column' }, etc.`);
1282
+ });
1283
+ let query = `SELECT ${aggregations.join(', ')} FROM \`${options.table}\``;
1284
+ if (options.where) {
1285
+ const { clause, values } = this.buildWhereClause(options.where);
1286
+ query += ` WHERE ${clause}`;
1287
+ params.push(...values);
1288
+ }
1289
+ return { query, params };
1290
+ }
1291
+ /**
1292
+ * Build CREATE TABLE query
1293
+ */
1294
+ buildCreateTableQuery(schema, options) {
1295
+ const columnDefs = schema.columns.map((col) => {
1296
+ let def = `\`${col.name}\` ${this.mapColumnTypeToMySQL(col.type)}`;
1297
+ if (col.length) {
1298
+ def += `(${col.length})`;
1299
+ }
1300
+ if (col.primaryKey) {
1301
+ def += ' PRIMARY KEY';
1302
+ }
1303
+ if (col.autoIncrement) {
1304
+ def += ' AUTO_INCREMENT';
1305
+ }
1306
+ if (!col.nullable) {
1307
+ def += ' NOT NULL';
1308
+ }
1309
+ if (col.unique) {
1310
+ def += ' UNIQUE';
1311
+ }
1312
+ if (col.defaultValue !== undefined) {
1313
+ def += ` DEFAULT ${this.escapeValue(col.defaultValue)}`;
1314
+ }
1315
+ return def;
1316
+ });
1317
+ let query = `CREATE TABLE ${(options === null || options === void 0 ? void 0 : options.ifNotExists) ? 'IF NOT EXISTS ' : ''}\`${schema.name}\` (${columnDefs.join(', ')})`;
1318
+ return query;
1319
+ }
1320
+ /**
1321
+ * Build ALTER TABLE queries
1322
+ */
1323
+ buildAlterTableQueries(tableName, alterations) {
1324
+ return alterations.map((alt) => {
1325
+ let query = `ALTER TABLE \`${tableName}\` `;
1326
+ switch (alt.type) {
1327
+ case schema_types_1.ColumnAlterationType.ADD:
1328
+ query += `ADD COLUMN \`${alt.column.name}\` ${this.mapColumnTypeToMySQL(alt.column.type)}`;
1329
+ if (!alt.column.nullable) {
1330
+ query += ' NOT NULL';
1331
+ }
1332
+ break;
1333
+ case schema_types_1.ColumnAlterationType.DROP:
1334
+ query += `DROP COLUMN \`${alt.oldName}\``;
1335
+ break;
1336
+ case schema_types_1.ColumnAlterationType.MODIFY:
1337
+ query += `MODIFY COLUMN \`${alt.column.name}\` ${this.mapColumnTypeToMySQL(alt.column.type)}`;
1338
+ break;
1339
+ case schema_types_1.ColumnAlterationType.RENAME:
1340
+ query += `RENAME COLUMN \`${alt.oldName}\` TO \`${alt.newName}\``;
1341
+ break;
1342
+ }
1343
+ return query;
1344
+ });
1345
+ }
1346
+ /**
1347
+ * Build CREATE INDEX query
1348
+ */
1349
+ buildCreateIndexQuery(options) {
1350
+ const unique = options.index.unique ? 'UNIQUE ' : '';
1351
+ const columns = options.index.columns.map((col) => `\`${col.name}\``).join(', ');
1352
+ return `CREATE ${unique}INDEX \`${options.index.name}\` ON \`${options.table}\` (${columns})`;
1353
+ }
1354
+ /**
1355
+ * Map ColumnType to MySQL type
1356
+ */
1357
+ mapColumnTypeToMySQL(type) {
1358
+ const typeMap = {
1359
+ [schema_types_1.ColumnType.STRING]: 'VARCHAR',
1360
+ [schema_types_1.ColumnType.TEXT]: 'TEXT',
1361
+ [schema_types_1.ColumnType.VARCHAR]: 'VARCHAR',
1362
+ [schema_types_1.ColumnType.CHAR]: 'CHAR',
1363
+ [schema_types_1.ColumnType.INTEGER]: 'INT',
1364
+ [schema_types_1.ColumnType.BIGINT]: 'BIGINT',
1365
+ [schema_types_1.ColumnType.SMALLINT]: 'SMALLINT',
1366
+ [schema_types_1.ColumnType.DECIMAL]: 'DECIMAL',
1367
+ [schema_types_1.ColumnType.NUMERIC]: 'DECIMAL',
1368
+ [schema_types_1.ColumnType.FLOAT]: 'FLOAT',
1369
+ [schema_types_1.ColumnType.DOUBLE]: 'DOUBLE',
1370
+ [schema_types_1.ColumnType.REAL]: 'FLOAT',
1371
+ [schema_types_1.ColumnType.BOOLEAN]: 'TINYINT',
1372
+ [schema_types_1.ColumnType.DATE]: 'DATE',
1373
+ [schema_types_1.ColumnType.TIME]: 'TIME',
1374
+ [schema_types_1.ColumnType.DATETIME]: 'DATETIME',
1375
+ [schema_types_1.ColumnType.TIMESTAMP]: 'TIMESTAMP',
1376
+ [schema_types_1.ColumnType.JSON]: 'JSON',
1377
+ [schema_types_1.ColumnType.JSONB]: 'JSON',
1378
+ [schema_types_1.ColumnType.UUID]: 'CHAR(36)',
1379
+ [schema_types_1.ColumnType.BLOB]: 'BLOB',
1380
+ [schema_types_1.ColumnType.BINARY]: 'BINARY',
1381
+ [schema_types_1.ColumnType.ARRAY]: 'JSON',
1382
+ [schema_types_1.ColumnType.OBJECT]: 'JSON',
1383
+ [schema_types_1.ColumnType.ENUM]: 'VARCHAR',
1384
+ };
1385
+ return typeMap[type] || 'TEXT';
1386
+ }
1387
+ /**
1388
+ * Map MySQL type to ColumnType
1389
+ */
1390
+ mapMySQLTypeToColumnType(mysqlType) {
1391
+ const typeMap = {
1392
+ varchar: schema_types_1.ColumnType.VARCHAR,
1393
+ text: schema_types_1.ColumnType.TEXT,
1394
+ char: schema_types_1.ColumnType.CHAR,
1395
+ int: schema_types_1.ColumnType.INTEGER,
1396
+ bigint: schema_types_1.ColumnType.BIGINT,
1397
+ smallint: schema_types_1.ColumnType.SMALLINT,
1398
+ decimal: schema_types_1.ColumnType.DECIMAL,
1399
+ float: schema_types_1.ColumnType.FLOAT,
1400
+ double: schema_types_1.ColumnType.DOUBLE,
1401
+ tinyint: schema_types_1.ColumnType.BOOLEAN,
1402
+ date: schema_types_1.ColumnType.DATE,
1403
+ time: schema_types_1.ColumnType.TIME,
1404
+ datetime: schema_types_1.ColumnType.DATETIME,
1405
+ timestamp: schema_types_1.ColumnType.TIMESTAMP,
1406
+ json: schema_types_1.ColumnType.JSON,
1407
+ blob: schema_types_1.ColumnType.BLOB,
1408
+ binary: schema_types_1.ColumnType.BINARY,
1409
+ };
1410
+ return typeMap[mysqlType.toLowerCase()] || schema_types_1.ColumnType.TEXT;
1411
+ }
1412
+ /**
1413
+ * Ensure migration table exists
1414
+ */
1415
+ async ensureMigrationTable(conn) {
1416
+ const query = `
1417
+ CREATE TABLE IF NOT EXISTS _ductape_migrations (
1418
+ tag VARCHAR(255) PRIMARY KEY,
1419
+ name VARCHAR(255) NOT NULL,
1420
+ executed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
1421
+ )
1422
+ `;
1423
+ await conn.query(query);
1424
+ }
1425
+ /**
1426
+ * Record migration execution
1427
+ */
1428
+ async recordMigration(conn, migration, direction) {
1429
+ await this.ensureMigrationTable(conn);
1430
+ const query = `
1431
+ INSERT INTO _ductape_migrations (tag, name, executed_at)
1432
+ VALUES (?, ?, CURRENT_TIMESTAMP)
1433
+ ON DUPLICATE KEY UPDATE executed_at = CURRENT_TIMESTAMP
1434
+ `;
1435
+ await conn.query(query, [migration.tag, migration.name]);
1436
+ }
1437
+ /**
1438
+ * Remove migration from history
1439
+ */
1440
+ async removeMigration(conn, tag) {
1441
+ await this.ensureMigrationTable(conn);
1442
+ const query = `DELETE FROM _ductape_migrations WHERE tag = ?`;
1443
+ await conn.query(query, [tag]);
1444
+ }
1445
+ // ==================== Utility Methods ====================
1446
+ /**
1447
+ * Escape identifier (table/column name)
1448
+ */
1449
+ escapeIdentifier(identifier) {
1450
+ return `\`${identifier.replace(/`/g, '``')}\``;
1451
+ }
1452
+ /**
1453
+ * Escape value for SQL
1454
+ */
1455
+ escapeValue(value) {
1456
+ if (value === null || value === undefined) {
1457
+ return 'NULL';
1458
+ }
1459
+ if (typeof value === 'string') {
1460
+ return `'${value.replace(/'/g, "''")}'`;
1461
+ }
1462
+ if (typeof value === 'boolean') {
1463
+ return value ? '1' : '0';
1464
+ }
1465
+ if (value instanceof Date) {
1466
+ return `'${value.toISOString().slice(0, 19).replace('T', ' ')}'`;
1467
+ }
1468
+ if (Array.isArray(value)) {
1469
+ return `'${JSON.stringify(value)}'`;
1470
+ }
1471
+ if (typeof value === 'object') {
1472
+ return `'${JSON.stringify(value)}'`;
1473
+ }
1474
+ return String(value);
1475
+ }
1476
+ /**
1477
+ * Get database version
1478
+ */
1479
+ async getDatabaseVersion(connection) {
1480
+ var _a;
1481
+ try {
1482
+ const conn = connection.getClient();
1483
+ const [rows] = await conn.query('SELECT VERSION() as version');
1484
+ return ((_a = rows[0]) === null || _a === void 0 ? void 0 : _a.version) || 'Unknown';
1485
+ }
1486
+ catch (error) {
1487
+ return 'Unknown';
1488
+ }
1489
+ }
1490
+ }
1491
+ exports.MySQLAdapter = MySQLAdapter;
1492
+ //# sourceMappingURL=mysql.adapter.js.map