@contember/schema-migrations 2.1.0-beta.2 → 2.2.0-alpha.1

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 (555) hide show
  1. package/dist/development/index.cjs +3 -0
  2. package/dist/development/index.cjs.map +1 -1
  3. package/dist/development/index.js +3 -0
  4. package/dist/development/index.js.map +1 -1
  5. package/dist/development/src/MigrationDescriber.cjs.map +1 -1
  6. package/dist/development/src/MigrationDescriber.js.map +1 -1
  7. package/dist/development/src/SchemaDiffer.cjs +27 -12
  8. package/dist/development/src/SchemaDiffer.cjs.map +1 -1
  9. package/dist/development/src/SchemaDiffer.js +27 -12
  10. package/dist/development/src/SchemaDiffer.js.map +1 -1
  11. package/dist/development/src/SchemaMigrator.cjs.map +1 -1
  12. package/dist/development/src/SchemaMigrator.js.map +1 -1
  13. package/dist/development/src/modifications/ModificationHandler.cjs.map +1 -1
  14. package/dist/development/src/modifications/ModificationHandler.js.map +1 -1
  15. package/dist/development/src/modifications/ModificationHandlerFactory.cjs +2 -0
  16. package/dist/development/src/modifications/ModificationHandlerFactory.cjs.map +1 -1
  17. package/dist/development/src/modifications/ModificationHandlerFactory.js +2 -0
  18. package/dist/development/src/modifications/ModificationHandlerFactory.js.map +1 -1
  19. package/dist/development/src/modifications/NoopModification.cjs.map +1 -1
  20. package/dist/development/src/modifications/NoopModification.js.map +1 -1
  21. package/dist/development/src/modifications/acl/PatchAclSchemaModification.cjs.map +1 -1
  22. package/dist/development/src/modifications/acl/PatchAclSchemaModification.js.map +1 -1
  23. package/dist/development/src/modifications/acl/UpdateAclSchemaModification.cjs.map +1 -1
  24. package/dist/development/src/modifications/acl/UpdateAclSchemaModification.js.map +1 -1
  25. package/dist/development/src/modifications/actions/CreateTargetModification.cjs.map +1 -1
  26. package/dist/development/src/modifications/actions/CreateTargetModification.js.map +1 -1
  27. package/dist/development/src/modifications/actions/CreateTriggerModification.cjs.map +1 -1
  28. package/dist/development/src/modifications/actions/CreateTriggerModification.js.map +1 -1
  29. package/dist/development/src/modifications/actions/PatchTriggerModification.cjs.map +1 -1
  30. package/dist/development/src/modifications/actions/PatchTriggerModification.js.map +1 -1
  31. package/dist/development/src/modifications/actions/RemoveTargetModification.cjs.map +1 -1
  32. package/dist/development/src/modifications/actions/RemoveTargetModification.js.map +1 -1
  33. package/dist/development/src/modifications/actions/RemoveTriggerModification.cjs.map +1 -1
  34. package/dist/development/src/modifications/actions/RemoveTriggerModification.js.map +1 -1
  35. package/dist/development/src/modifications/actions/UpdateTargetModification.cjs.map +1 -1
  36. package/dist/development/src/modifications/actions/UpdateTargetModification.js.map +1 -1
  37. package/dist/development/src/modifications/actions/UpdateTriggerModification.cjs.map +1 -1
  38. package/dist/development/src/modifications/actions/UpdateTriggerModification.js.map +1 -1
  39. package/dist/development/src/modifications/columns/CreateColumnModification.cjs.map +1 -1
  40. package/dist/development/src/modifications/columns/CreateColumnModification.js.map +1 -1
  41. package/dist/development/src/modifications/columns/UpdateColumnDefinitionModification.cjs.map +1 -1
  42. package/dist/development/src/modifications/columns/UpdateColumnDefinitionModification.js.map +1 -1
  43. package/dist/development/src/modifications/columns/UpdateColumnNameModification.cjs.map +1 -1
  44. package/dist/development/src/modifications/columns/UpdateColumnNameModification.js.map +1 -1
  45. package/dist/development/src/modifications/columns/columnUtils.cjs.map +1 -1
  46. package/dist/development/src/modifications/columns/columnUtils.js.map +1 -1
  47. package/dist/development/src/modifications/constraints/CreateUniqueConstraintModification.cjs.map +1 -1
  48. package/dist/development/src/modifications/constraints/CreateUniqueConstraintModification.js.map +1 -1
  49. package/dist/development/src/modifications/constraints/RemoveUniqueConstraintModification.cjs.map +1 -1
  50. package/dist/development/src/modifications/constraints/RemoveUniqueConstraintModification.js.map +1 -1
  51. package/dist/development/src/modifications/differs/RemoveChangedFieldDiffer.cjs.map +1 -1
  52. package/dist/development/src/modifications/differs/RemoveChangedFieldDiffer.js.map +1 -1
  53. package/dist/development/src/modifications/differs/RemoveViewDiffer.cjs +4 -1
  54. package/dist/development/src/modifications/differs/RemoveViewDiffer.cjs.map +1 -1
  55. package/dist/development/src/modifications/differs/RemoveViewDiffer.js +5 -2
  56. package/dist/development/src/modifications/differs/RemoveViewDiffer.js.map +1 -1
  57. package/dist/development/src/modifications/differs/UpdateViewDiffer.cjs +45 -0
  58. package/dist/development/src/modifications/differs/UpdateViewDiffer.cjs.map +1 -0
  59. package/dist/development/src/modifications/differs/UpdateViewDiffer.js +45 -0
  60. package/dist/development/src/modifications/differs/UpdateViewDiffer.js.map +1 -0
  61. package/dist/development/src/modifications/entities/CreateEntityModification.cjs.map +1 -1
  62. package/dist/development/src/modifications/entities/CreateEntityModification.js.map +1 -1
  63. package/dist/development/src/modifications/entities/CreateViewModification.cjs.map +1 -1
  64. package/dist/development/src/modifications/entities/CreateViewModification.js.map +1 -1
  65. package/dist/development/src/modifications/entities/RemoveEntityModification.cjs.map +1 -1
  66. package/dist/development/src/modifications/entities/RemoveEntityModification.js.map +1 -1
  67. package/dist/development/src/modifications/entities/ToggleEventLogModification.cjs.map +1 -1
  68. package/dist/development/src/modifications/entities/ToggleEventLogModification.js.map +1 -1
  69. package/dist/development/src/modifications/entities/UpdateEntityNameModification.cjs.map +1 -1
  70. package/dist/development/src/modifications/entities/UpdateEntityNameModification.js.map +1 -1
  71. package/dist/development/src/modifications/entities/UpdateEntityOrderByModification.cjs.map +1 -1
  72. package/dist/development/src/modifications/entities/UpdateEntityOrderByModification.js.map +1 -1
  73. package/dist/development/src/modifications/entities/UpdateEntityTableNameModification.cjs.map +1 -1
  74. package/dist/development/src/modifications/entities/UpdateEntityTableNameModification.js.map +1 -1
  75. package/dist/development/src/modifications/entities/UpdateViewModification.cjs.map +1 -1
  76. package/dist/development/src/modifications/entities/UpdateViewModification.js.map +1 -1
  77. package/dist/development/src/modifications/enums/CreateEnumModification.cjs.map +1 -1
  78. package/dist/development/src/modifications/enums/CreateEnumModification.js.map +1 -1
  79. package/dist/development/src/modifications/enums/RemoveEnumModification.cjs.map +1 -1
  80. package/dist/development/src/modifications/enums/RemoveEnumModification.js.map +1 -1
  81. package/dist/development/src/modifications/enums/UpdateEnumModification.cjs.map +1 -1
  82. package/dist/development/src/modifications/enums/UpdateEnumModification.js.map +1 -1
  83. package/dist/development/src/modifications/enums/enumUtils.cjs.map +1 -1
  84. package/dist/development/src/modifications/enums/enumUtils.js.map +1 -1
  85. package/dist/development/src/modifications/fields/RemoveFieldModification.cjs.map +1 -1
  86. package/dist/development/src/modifications/fields/RemoveFieldModification.js.map +1 -1
  87. package/dist/development/src/modifications/fields/UpdateFieldNameModification.cjs +10 -4
  88. package/dist/development/src/modifications/fields/UpdateFieldNameModification.cjs.map +1 -1
  89. package/dist/development/src/modifications/fields/UpdateFieldNameModification.js +10 -4
  90. package/dist/development/src/modifications/fields/UpdateFieldNameModification.js.map +1 -1
  91. package/dist/development/src/modifications/indexes/CreateIndexModification.cjs +23 -7
  92. package/dist/development/src/modifications/indexes/CreateIndexModification.cjs.map +1 -1
  93. package/dist/development/src/modifications/indexes/CreateIndexModification.js +23 -7
  94. package/dist/development/src/modifications/indexes/CreateIndexModification.js.map +1 -1
  95. package/dist/development/src/modifications/indexes/RemoveIndexModification.cjs +52 -17
  96. package/dist/development/src/modifications/indexes/RemoveIndexModification.cjs.map +1 -1
  97. package/dist/development/src/modifications/indexes/RemoveIndexModification.js +52 -17
  98. package/dist/development/src/modifications/indexes/RemoveIndexModification.js.map +1 -1
  99. package/dist/development/src/modifications/relations/ConvertManyHasManyToJoiningEntityModification.cjs +140 -0
  100. package/dist/development/src/modifications/relations/ConvertManyHasManyToJoiningEntityModification.cjs.map +1 -0
  101. package/dist/development/src/modifications/relations/ConvertManyHasManyToJoiningEntityModification.js +140 -0
  102. package/dist/development/src/modifications/relations/ConvertManyHasManyToJoiningEntityModification.js.map +1 -0
  103. package/dist/development/src/modifications/relations/ConvertOneHasManyToManyHasManyRelationModification.cjs.map +1 -1
  104. package/dist/development/src/modifications/relations/ConvertOneHasManyToManyHasManyRelationModification.js.map +1 -1
  105. package/dist/development/src/modifications/relations/ConvertOneHasManyToOneHasOneRelationModification.cjs.map +1 -1
  106. package/dist/development/src/modifications/relations/ConvertOneHasManyToOneHasOneRelationModification.js.map +1 -1
  107. package/dist/development/src/modifications/relations/ConvertOneToManyRelationModification.cjs.map +1 -1
  108. package/dist/development/src/modifications/relations/ConvertOneToManyRelationModification.js.map +1 -1
  109. package/dist/development/src/modifications/relations/CreateRelationInverseSideModification.cjs.map +1 -1
  110. package/dist/development/src/modifications/relations/CreateRelationInverseSideModification.js.map +1 -1
  111. package/dist/development/src/modifications/relations/CreateRelationModification.cjs.map +1 -1
  112. package/dist/development/src/modifications/relations/CreateRelationModification.js.map +1 -1
  113. package/dist/development/src/modifications/relations/DisableOrphanRemovalModification.cjs.map +1 -1
  114. package/dist/development/src/modifications/relations/DisableOrphanRemovalModification.js.map +1 -1
  115. package/dist/development/src/modifications/relations/EnableOrphanRemovalModification.cjs.map +1 -1
  116. package/dist/development/src/modifications/relations/EnableOrphanRemovalModification.js.map +1 -1
  117. package/dist/development/src/modifications/relations/MakeRelationNotNullModification.cjs.map +1 -1
  118. package/dist/development/src/modifications/relations/MakeRelationNotNullModification.js.map +1 -1
  119. package/dist/development/src/modifications/relations/MakeRelationNullableModification.cjs.map +1 -1
  120. package/dist/development/src/modifications/relations/MakeRelationNullableModification.js.map +1 -1
  121. package/dist/development/src/modifications/relations/ToggleJunctionEventLogModification.cjs.map +1 -1
  122. package/dist/development/src/modifications/relations/ToggleJunctionEventLogModification.js.map +1 -1
  123. package/dist/development/src/modifications/relations/UpdateRelationOnDeleteModification.cjs.map +1 -1
  124. package/dist/development/src/modifications/relations/UpdateRelationOnDeleteModification.js.map +1 -1
  125. package/dist/development/src/modifications/relations/UpdateRelationOrderByModification.cjs.map +1 -1
  126. package/dist/development/src/modifications/relations/UpdateRelationOrderByModification.js.map +1 -1
  127. package/dist/development/src/modifications/relations/helpers.cjs.map +1 -1
  128. package/dist/development/src/modifications/relations/helpers.js.map +1 -1
  129. package/dist/development/src/modifications/settings/UpdateSettingsModification.cjs.map +1 -1
  130. package/dist/development/src/modifications/settings/UpdateSettingsModification.js.map +1 -1
  131. package/dist/development/src/modifications/upgrade/RemoveIndexNamesModification.cjs.map +1 -1
  132. package/dist/development/src/modifications/upgrade/RemoveIndexNamesModification.js.map +1 -1
  133. package/dist/development/src/modifications/utils/createJunctionTable.cjs.map +1 -1
  134. package/dist/development/src/modifications/utils/createJunctionTable.js.map +1 -1
  135. package/dist/development/src/modifications/utils/diffUtils.cjs.map +1 -1
  136. package/dist/development/src/modifications/utils/diffUtils.js.map +1 -1
  137. package/dist/development/src/modifications/utils/schemaUpdateUtils.cjs.map +1 -1
  138. package/dist/development/src/modifications/utils/schemaUpdateUtils.js.map +1 -1
  139. package/dist/development/src/modifications/utils/viewDependencies.cjs +15 -1
  140. package/dist/development/src/modifications/utils/viewDependencies.cjs.map +1 -1
  141. package/dist/development/src/modifications/utils/viewDependencies.js +16 -2
  142. package/dist/development/src/modifications/utils/viewDependencies.js.map +1 -1
  143. package/dist/development/src/modifications/validation/PatchValidationSchemaModification.cjs.map +1 -1
  144. package/dist/development/src/modifications/validation/PatchValidationSchemaModification.js.map +1 -1
  145. package/dist/development/src/modifications/validation/UpdateValidationSchemaModification.cjs.map +1 -1
  146. package/dist/development/src/modifications/validation/UpdateValidationSchemaModification.js.map +1 -1
  147. package/dist/production/index.cjs +3 -0
  148. package/dist/production/index.cjs.map +1 -1
  149. package/dist/production/index.js +3 -0
  150. package/dist/production/index.js.map +1 -1
  151. package/dist/production/src/MigrationDescriber.cjs.map +1 -1
  152. package/dist/production/src/MigrationDescriber.js.map +1 -1
  153. package/dist/production/src/SchemaDiffer.cjs +27 -12
  154. package/dist/production/src/SchemaDiffer.cjs.map +1 -1
  155. package/dist/production/src/SchemaDiffer.js +27 -12
  156. package/dist/production/src/SchemaDiffer.js.map +1 -1
  157. package/dist/production/src/SchemaMigrator.cjs.map +1 -1
  158. package/dist/production/src/SchemaMigrator.js.map +1 -1
  159. package/dist/production/src/modifications/ModificationHandler.cjs.map +1 -1
  160. package/dist/production/src/modifications/ModificationHandler.js.map +1 -1
  161. package/dist/production/src/modifications/ModificationHandlerFactory.cjs +2 -0
  162. package/dist/production/src/modifications/ModificationHandlerFactory.cjs.map +1 -1
  163. package/dist/production/src/modifications/ModificationHandlerFactory.js +2 -0
  164. package/dist/production/src/modifications/ModificationHandlerFactory.js.map +1 -1
  165. package/dist/production/src/modifications/NoopModification.cjs.map +1 -1
  166. package/dist/production/src/modifications/NoopModification.js.map +1 -1
  167. package/dist/production/src/modifications/acl/PatchAclSchemaModification.cjs.map +1 -1
  168. package/dist/production/src/modifications/acl/PatchAclSchemaModification.js.map +1 -1
  169. package/dist/production/src/modifications/acl/UpdateAclSchemaModification.cjs.map +1 -1
  170. package/dist/production/src/modifications/acl/UpdateAclSchemaModification.js.map +1 -1
  171. package/dist/production/src/modifications/actions/CreateTargetModification.cjs.map +1 -1
  172. package/dist/production/src/modifications/actions/CreateTargetModification.js.map +1 -1
  173. package/dist/production/src/modifications/actions/CreateTriggerModification.cjs.map +1 -1
  174. package/dist/production/src/modifications/actions/CreateTriggerModification.js.map +1 -1
  175. package/dist/production/src/modifications/actions/PatchTriggerModification.cjs.map +1 -1
  176. package/dist/production/src/modifications/actions/PatchTriggerModification.js.map +1 -1
  177. package/dist/production/src/modifications/actions/RemoveTargetModification.cjs.map +1 -1
  178. package/dist/production/src/modifications/actions/RemoveTargetModification.js.map +1 -1
  179. package/dist/production/src/modifications/actions/RemoveTriggerModification.cjs.map +1 -1
  180. package/dist/production/src/modifications/actions/RemoveTriggerModification.js.map +1 -1
  181. package/dist/production/src/modifications/actions/UpdateTargetModification.cjs.map +1 -1
  182. package/dist/production/src/modifications/actions/UpdateTargetModification.js.map +1 -1
  183. package/dist/production/src/modifications/actions/UpdateTriggerModification.cjs.map +1 -1
  184. package/dist/production/src/modifications/actions/UpdateTriggerModification.js.map +1 -1
  185. package/dist/production/src/modifications/columns/CreateColumnModification.cjs.map +1 -1
  186. package/dist/production/src/modifications/columns/CreateColumnModification.js.map +1 -1
  187. package/dist/production/src/modifications/columns/UpdateColumnDefinitionModification.cjs.map +1 -1
  188. package/dist/production/src/modifications/columns/UpdateColumnDefinitionModification.js.map +1 -1
  189. package/dist/production/src/modifications/columns/UpdateColumnNameModification.cjs.map +1 -1
  190. package/dist/production/src/modifications/columns/UpdateColumnNameModification.js.map +1 -1
  191. package/dist/production/src/modifications/columns/columnUtils.cjs.map +1 -1
  192. package/dist/production/src/modifications/columns/columnUtils.js.map +1 -1
  193. package/dist/production/src/modifications/constraints/CreateUniqueConstraintModification.cjs.map +1 -1
  194. package/dist/production/src/modifications/constraints/CreateUniqueConstraintModification.js.map +1 -1
  195. package/dist/production/src/modifications/constraints/RemoveUniqueConstraintModification.cjs.map +1 -1
  196. package/dist/production/src/modifications/constraints/RemoveUniqueConstraintModification.js.map +1 -1
  197. package/dist/production/src/modifications/differs/RemoveChangedFieldDiffer.cjs.map +1 -1
  198. package/dist/production/src/modifications/differs/RemoveChangedFieldDiffer.js.map +1 -1
  199. package/dist/production/src/modifications/differs/RemoveViewDiffer.cjs +4 -1
  200. package/dist/production/src/modifications/differs/RemoveViewDiffer.cjs.map +1 -1
  201. package/dist/production/src/modifications/differs/RemoveViewDiffer.js +5 -2
  202. package/dist/production/src/modifications/differs/RemoveViewDiffer.js.map +1 -1
  203. package/dist/production/src/modifications/differs/UpdateViewDiffer.cjs +45 -0
  204. package/dist/production/src/modifications/differs/UpdateViewDiffer.cjs.map +1 -0
  205. package/dist/production/src/modifications/differs/UpdateViewDiffer.js +45 -0
  206. package/dist/production/src/modifications/differs/UpdateViewDiffer.js.map +1 -0
  207. package/dist/production/src/modifications/entities/CreateEntityModification.cjs.map +1 -1
  208. package/dist/production/src/modifications/entities/CreateEntityModification.js.map +1 -1
  209. package/dist/production/src/modifications/entities/CreateViewModification.cjs.map +1 -1
  210. package/dist/production/src/modifications/entities/CreateViewModification.js.map +1 -1
  211. package/dist/production/src/modifications/entities/RemoveEntityModification.cjs.map +1 -1
  212. package/dist/production/src/modifications/entities/RemoveEntityModification.js.map +1 -1
  213. package/dist/production/src/modifications/entities/ToggleEventLogModification.cjs.map +1 -1
  214. package/dist/production/src/modifications/entities/ToggleEventLogModification.js.map +1 -1
  215. package/dist/production/src/modifications/entities/UpdateEntityNameModification.cjs.map +1 -1
  216. package/dist/production/src/modifications/entities/UpdateEntityNameModification.js.map +1 -1
  217. package/dist/production/src/modifications/entities/UpdateEntityOrderByModification.cjs.map +1 -1
  218. package/dist/production/src/modifications/entities/UpdateEntityOrderByModification.js.map +1 -1
  219. package/dist/production/src/modifications/entities/UpdateEntityTableNameModification.cjs.map +1 -1
  220. package/dist/production/src/modifications/entities/UpdateEntityTableNameModification.js.map +1 -1
  221. package/dist/production/src/modifications/entities/UpdateViewModification.cjs.map +1 -1
  222. package/dist/production/src/modifications/entities/UpdateViewModification.js.map +1 -1
  223. package/dist/production/src/modifications/enums/CreateEnumModification.cjs.map +1 -1
  224. package/dist/production/src/modifications/enums/CreateEnumModification.js.map +1 -1
  225. package/dist/production/src/modifications/enums/RemoveEnumModification.cjs.map +1 -1
  226. package/dist/production/src/modifications/enums/RemoveEnumModification.js.map +1 -1
  227. package/dist/production/src/modifications/enums/UpdateEnumModification.cjs.map +1 -1
  228. package/dist/production/src/modifications/enums/UpdateEnumModification.js.map +1 -1
  229. package/dist/production/src/modifications/enums/enumUtils.cjs.map +1 -1
  230. package/dist/production/src/modifications/enums/enumUtils.js.map +1 -1
  231. package/dist/production/src/modifications/fields/RemoveFieldModification.cjs.map +1 -1
  232. package/dist/production/src/modifications/fields/RemoveFieldModification.js.map +1 -1
  233. package/dist/production/src/modifications/fields/UpdateFieldNameModification.cjs +10 -4
  234. package/dist/production/src/modifications/fields/UpdateFieldNameModification.cjs.map +1 -1
  235. package/dist/production/src/modifications/fields/UpdateFieldNameModification.js +10 -4
  236. package/dist/production/src/modifications/fields/UpdateFieldNameModification.js.map +1 -1
  237. package/dist/production/src/modifications/indexes/CreateIndexModification.cjs +23 -7
  238. package/dist/production/src/modifications/indexes/CreateIndexModification.cjs.map +1 -1
  239. package/dist/production/src/modifications/indexes/CreateIndexModification.js +23 -7
  240. package/dist/production/src/modifications/indexes/CreateIndexModification.js.map +1 -1
  241. package/dist/production/src/modifications/indexes/RemoveIndexModification.cjs +52 -17
  242. package/dist/production/src/modifications/indexes/RemoveIndexModification.cjs.map +1 -1
  243. package/dist/production/src/modifications/indexes/RemoveIndexModification.js +52 -17
  244. package/dist/production/src/modifications/indexes/RemoveIndexModification.js.map +1 -1
  245. package/dist/production/src/modifications/relations/ConvertManyHasManyToJoiningEntityModification.cjs +140 -0
  246. package/dist/production/src/modifications/relations/ConvertManyHasManyToJoiningEntityModification.cjs.map +1 -0
  247. package/dist/production/src/modifications/relations/ConvertManyHasManyToJoiningEntityModification.js +140 -0
  248. package/dist/production/src/modifications/relations/ConvertManyHasManyToJoiningEntityModification.js.map +1 -0
  249. package/dist/production/src/modifications/relations/ConvertOneHasManyToManyHasManyRelationModification.cjs.map +1 -1
  250. package/dist/production/src/modifications/relations/ConvertOneHasManyToManyHasManyRelationModification.js.map +1 -1
  251. package/dist/production/src/modifications/relations/ConvertOneHasManyToOneHasOneRelationModification.cjs.map +1 -1
  252. package/dist/production/src/modifications/relations/ConvertOneHasManyToOneHasOneRelationModification.js.map +1 -1
  253. package/dist/production/src/modifications/relations/ConvertOneToManyRelationModification.cjs.map +1 -1
  254. package/dist/production/src/modifications/relations/ConvertOneToManyRelationModification.js.map +1 -1
  255. package/dist/production/src/modifications/relations/CreateRelationInverseSideModification.cjs.map +1 -1
  256. package/dist/production/src/modifications/relations/CreateRelationInverseSideModification.js.map +1 -1
  257. package/dist/production/src/modifications/relations/CreateRelationModification.cjs.map +1 -1
  258. package/dist/production/src/modifications/relations/CreateRelationModification.js.map +1 -1
  259. package/dist/production/src/modifications/relations/DisableOrphanRemovalModification.cjs.map +1 -1
  260. package/dist/production/src/modifications/relations/DisableOrphanRemovalModification.js.map +1 -1
  261. package/dist/production/src/modifications/relations/EnableOrphanRemovalModification.cjs.map +1 -1
  262. package/dist/production/src/modifications/relations/EnableOrphanRemovalModification.js.map +1 -1
  263. package/dist/production/src/modifications/relations/MakeRelationNotNullModification.cjs.map +1 -1
  264. package/dist/production/src/modifications/relations/MakeRelationNotNullModification.js.map +1 -1
  265. package/dist/production/src/modifications/relations/MakeRelationNullableModification.cjs.map +1 -1
  266. package/dist/production/src/modifications/relations/MakeRelationNullableModification.js.map +1 -1
  267. package/dist/production/src/modifications/relations/ToggleJunctionEventLogModification.cjs.map +1 -1
  268. package/dist/production/src/modifications/relations/ToggleJunctionEventLogModification.js.map +1 -1
  269. package/dist/production/src/modifications/relations/UpdateRelationOnDeleteModification.cjs.map +1 -1
  270. package/dist/production/src/modifications/relations/UpdateRelationOnDeleteModification.js.map +1 -1
  271. package/dist/production/src/modifications/relations/UpdateRelationOrderByModification.cjs.map +1 -1
  272. package/dist/production/src/modifications/relations/UpdateRelationOrderByModification.js.map +1 -1
  273. package/dist/production/src/modifications/relations/helpers.cjs.map +1 -1
  274. package/dist/production/src/modifications/relations/helpers.js.map +1 -1
  275. package/dist/production/src/modifications/settings/UpdateSettingsModification.cjs.map +1 -1
  276. package/dist/production/src/modifications/settings/UpdateSettingsModification.js.map +1 -1
  277. package/dist/production/src/modifications/upgrade/RemoveIndexNamesModification.cjs.map +1 -1
  278. package/dist/production/src/modifications/upgrade/RemoveIndexNamesModification.js.map +1 -1
  279. package/dist/production/src/modifications/utils/createJunctionTable.cjs.map +1 -1
  280. package/dist/production/src/modifications/utils/createJunctionTable.js.map +1 -1
  281. package/dist/production/src/modifications/utils/diffUtils.cjs.map +1 -1
  282. package/dist/production/src/modifications/utils/diffUtils.js.map +1 -1
  283. package/dist/production/src/modifications/utils/schemaUpdateUtils.cjs.map +1 -1
  284. package/dist/production/src/modifications/utils/schemaUpdateUtils.js.map +1 -1
  285. package/dist/production/src/modifications/utils/viewDependencies.cjs +15 -1
  286. package/dist/production/src/modifications/utils/viewDependencies.cjs.map +1 -1
  287. package/dist/production/src/modifications/utils/viewDependencies.js +16 -2
  288. package/dist/production/src/modifications/utils/viewDependencies.js.map +1 -1
  289. package/dist/production/src/modifications/validation/PatchValidationSchemaModification.cjs.map +1 -1
  290. package/dist/production/src/modifications/validation/PatchValidationSchemaModification.js.map +1 -1
  291. package/dist/production/src/modifications/validation/UpdateValidationSchemaModification.cjs.map +1 -1
  292. package/dist/production/src/modifications/validation/UpdateValidationSchemaModification.js.map +1 -1
  293. package/dist/tests/cases/integration/convertManyHasManyToJoiningEntity.test.d.ts +2 -0
  294. package/dist/tests/cases/integration/convertManyHasManyToJoiningEntity.test.d.ts.map +1 -0
  295. package/dist/tests/cases/integration/skipNonModelDiffers.test.d.ts +2 -0
  296. package/dist/tests/cases/integration/skipNonModelDiffers.test.d.ts.map +1 -0
  297. package/dist/tests/src/tests.d.ts +4 -3
  298. package/dist/tests/src/tests.d.ts.map +1 -1
  299. package/dist/tests/tsconfig.tsbuildinfo +1 -1
  300. package/dist/types/MigrationDescriber.d.ts +2 -2
  301. package/dist/types/MigrationDescriber.d.ts.map +1 -1
  302. package/dist/types/SchemaDiffer.d.ts +12 -5
  303. package/dist/types/SchemaDiffer.d.ts.map +1 -1
  304. package/dist/types/SchemaMigrator.d.ts +2 -2
  305. package/dist/types/SchemaMigrator.d.ts.map +1 -1
  306. package/dist/types/index.d.ts +6 -6
  307. package/dist/types/index.d.ts.map +1 -1
  308. package/dist/types/modifications/ModificationHandler.d.ts +2 -2
  309. package/dist/types/modifications/ModificationHandler.d.ts.map +1 -1
  310. package/dist/types/modifications/ModificationHandlerFactory.d.ts +1 -1
  311. package/dist/types/modifications/ModificationHandlerFactory.d.ts.map +1 -1
  312. package/dist/types/modifications/NoopModification.d.ts +2 -2
  313. package/dist/types/modifications/NoopModification.d.ts.map +1 -1
  314. package/dist/types/modifications/acl/PatchAclSchemaModification.d.ts +3 -3
  315. package/dist/types/modifications/acl/PatchAclSchemaModification.d.ts.map +1 -1
  316. package/dist/types/modifications/acl/UpdateAclSchemaModification.d.ts +4 -4
  317. package/dist/types/modifications/acl/UpdateAclSchemaModification.d.ts.map +1 -1
  318. package/dist/types/modifications/acl/index.d.ts +2 -2
  319. package/dist/types/modifications/acl/index.d.ts.map +1 -1
  320. package/dist/types/modifications/actions/CreateTargetModification.d.ts +4 -4
  321. package/dist/types/modifications/actions/CreateTargetModification.d.ts.map +1 -1
  322. package/dist/types/modifications/actions/CreateTriggerModification.d.ts +4 -4
  323. package/dist/types/modifications/actions/CreateTriggerModification.d.ts.map +1 -1
  324. package/dist/types/modifications/actions/PatchTriggerModification.d.ts +3 -3
  325. package/dist/types/modifications/actions/PatchTriggerModification.d.ts.map +1 -1
  326. package/dist/types/modifications/actions/RemoveTargetModification.d.ts +4 -4
  327. package/dist/types/modifications/actions/RemoveTargetModification.d.ts.map +1 -1
  328. package/dist/types/modifications/actions/RemoveTriggerModification.d.ts +4 -4
  329. package/dist/types/modifications/actions/RemoveTriggerModification.d.ts.map +1 -1
  330. package/dist/types/modifications/actions/UpdateTargetModification.d.ts +4 -4
  331. package/dist/types/modifications/actions/UpdateTargetModification.d.ts.map +1 -1
  332. package/dist/types/modifications/actions/UpdateTriggerModification.d.ts +4 -4
  333. package/dist/types/modifications/actions/UpdateTriggerModification.d.ts.map +1 -1
  334. package/dist/types/modifications/actions/index.d.ts +4 -4
  335. package/dist/types/modifications/actions/index.d.ts.map +1 -1
  336. package/dist/types/modifications/columns/CreateColumnModification.d.ts +4 -4
  337. package/dist/types/modifications/columns/CreateColumnModification.d.ts.map +1 -1
  338. package/dist/types/modifications/columns/UpdateColumnDefinitionModification.d.ts +4 -4
  339. package/dist/types/modifications/columns/UpdateColumnDefinitionModification.d.ts.map +1 -1
  340. package/dist/types/modifications/columns/UpdateColumnNameModification.d.ts +4 -4
  341. package/dist/types/modifications/columns/UpdateColumnNameModification.d.ts.map +1 -1
  342. package/dist/types/modifications/columns/index.d.ts +3 -3
  343. package/dist/types/modifications/columns/index.d.ts.map +1 -1
  344. package/dist/types/modifications/constraints/CreateUniqueConstraintModification.d.ts +4 -4
  345. package/dist/types/modifications/constraints/CreateUniqueConstraintModification.d.ts.map +1 -1
  346. package/dist/types/modifications/constraints/RemoveUniqueConstraintModification.d.ts +4 -4
  347. package/dist/types/modifications/constraints/RemoveUniqueConstraintModification.d.ts.map +1 -1
  348. package/dist/types/modifications/constraints/index.d.ts +3 -3
  349. package/dist/types/modifications/constraints/index.d.ts.map +1 -1
  350. package/dist/types/modifications/differs/RemoveChangedFieldDiffer.d.ts +2 -2
  351. package/dist/types/modifications/differs/RemoveChangedFieldDiffer.d.ts.map +1 -1
  352. package/dist/types/modifications/differs/RemoveViewDiffer.d.ts +14 -3
  353. package/dist/types/modifications/differs/RemoveViewDiffer.d.ts.map +1 -1
  354. package/dist/types/modifications/differs/UpdateViewDiffer.d.ts +19 -0
  355. package/dist/types/modifications/differs/UpdateViewDiffer.d.ts.map +1 -0
  356. package/dist/types/modifications/differs/index.d.ts +3 -2
  357. package/dist/types/modifications/differs/index.d.ts.map +1 -1
  358. package/dist/types/modifications/entities/CreateEntityModification.d.ts +4 -4
  359. package/dist/types/modifications/entities/CreateEntityModification.d.ts.map +1 -1
  360. package/dist/types/modifications/entities/CreateViewModification.d.ts +4 -4
  361. package/dist/types/modifications/entities/CreateViewModification.d.ts.map +1 -1
  362. package/dist/types/modifications/entities/RemoveEntityModification.d.ts +4 -4
  363. package/dist/types/modifications/entities/RemoveEntityModification.d.ts.map +1 -1
  364. package/dist/types/modifications/entities/ToggleEventLogModification.d.ts +4 -4
  365. package/dist/types/modifications/entities/ToggleEventLogModification.d.ts.map +1 -1
  366. package/dist/types/modifications/entities/UpdateEntityNameModification.d.ts +3 -3
  367. package/dist/types/modifications/entities/UpdateEntityNameModification.d.ts.map +1 -1
  368. package/dist/types/modifications/entities/UpdateEntityOrderByModification.d.ts +4 -4
  369. package/dist/types/modifications/entities/UpdateEntityOrderByModification.d.ts.map +1 -1
  370. package/dist/types/modifications/entities/UpdateEntityTableNameModification.d.ts +4 -4
  371. package/dist/types/modifications/entities/UpdateEntityTableNameModification.d.ts.map +1 -1
  372. package/dist/types/modifications/entities/UpdateViewModification.d.ts +3 -3
  373. package/dist/types/modifications/entities/UpdateViewModification.d.ts.map +1 -1
  374. package/dist/types/modifications/entities/index.d.ts +7 -7
  375. package/dist/types/modifications/entities/index.d.ts.map +1 -1
  376. package/dist/types/modifications/enums/CreateEnumModification.d.ts +4 -4
  377. package/dist/types/modifications/enums/CreateEnumModification.d.ts.map +1 -1
  378. package/dist/types/modifications/enums/RemoveEnumModification.d.ts +4 -4
  379. package/dist/types/modifications/enums/RemoveEnumModification.d.ts.map +1 -1
  380. package/dist/types/modifications/enums/UpdateEnumModification.d.ts +4 -4
  381. package/dist/types/modifications/enums/UpdateEnumModification.d.ts.map +1 -1
  382. package/dist/types/modifications/enums/index.d.ts +3 -3
  383. package/dist/types/modifications/enums/index.d.ts.map +1 -1
  384. package/dist/types/modifications/fields/RemoveFieldModification.d.ts +4 -4
  385. package/dist/types/modifications/fields/RemoveFieldModification.d.ts.map +1 -1
  386. package/dist/types/modifications/fields/UpdateFieldNameModification.d.ts +3 -3
  387. package/dist/types/modifications/fields/UpdateFieldNameModification.d.ts.map +1 -1
  388. package/dist/types/modifications/fields/index.d.ts +2 -2
  389. package/dist/types/modifications/fields/index.d.ts.map +1 -1
  390. package/dist/types/modifications/index.d.ts +13 -13
  391. package/dist/types/modifications/index.d.ts.map +1 -1
  392. package/dist/types/modifications/indexes/CreateIndexModification.d.ts +4 -4
  393. package/dist/types/modifications/indexes/CreateIndexModification.d.ts.map +1 -1
  394. package/dist/types/modifications/indexes/RemoveIndexModification.d.ts +18 -6
  395. package/dist/types/modifications/indexes/RemoveIndexModification.d.ts.map +1 -1
  396. package/dist/types/modifications/indexes/index.d.ts +2 -2
  397. package/dist/types/modifications/indexes/index.d.ts.map +1 -1
  398. package/dist/types/modifications/relations/ConvertManyHasManyToJoiningEntityModification.d.ts +52 -0
  399. package/dist/types/modifications/relations/ConvertManyHasManyToJoiningEntityModification.d.ts.map +1 -0
  400. package/dist/types/modifications/relations/ConvertOneHasManyToManyHasManyRelationModification.d.ts +5 -5
  401. package/dist/types/modifications/relations/ConvertOneHasManyToManyHasManyRelationModification.d.ts.map +1 -1
  402. package/dist/types/modifications/relations/ConvertOneHasManyToOneHasOneRelationModification.d.ts +4 -4
  403. package/dist/types/modifications/relations/ConvertOneHasManyToOneHasOneRelationModification.d.ts.map +1 -1
  404. package/dist/types/modifications/relations/ConvertOneToManyRelationModification.d.ts +4 -4
  405. package/dist/types/modifications/relations/ConvertOneToManyRelationModification.d.ts.map +1 -1
  406. package/dist/types/modifications/relations/CreateRelationInverseSideModification.d.ts +4 -4
  407. package/dist/types/modifications/relations/CreateRelationInverseSideModification.d.ts.map +1 -1
  408. package/dist/types/modifications/relations/CreateRelationModification.d.ts +5 -5
  409. package/dist/types/modifications/relations/CreateRelationModification.d.ts.map +1 -1
  410. package/dist/types/modifications/relations/DisableOrphanRemovalModification.d.ts +4 -4
  411. package/dist/types/modifications/relations/DisableOrphanRemovalModification.d.ts.map +1 -1
  412. package/dist/types/modifications/relations/EnableOrphanRemovalModification.d.ts +4 -4
  413. package/dist/types/modifications/relations/EnableOrphanRemovalModification.d.ts.map +1 -1
  414. package/dist/types/modifications/relations/MakeRelationNotNullModification.d.ts +4 -4
  415. package/dist/types/modifications/relations/MakeRelationNotNullModification.d.ts.map +1 -1
  416. package/dist/types/modifications/relations/MakeRelationNullableModification.d.ts +4 -4
  417. package/dist/types/modifications/relations/MakeRelationNullableModification.d.ts.map +1 -1
  418. package/dist/types/modifications/relations/ToggleJunctionEventLogModification.d.ts +4 -4
  419. package/dist/types/modifications/relations/ToggleJunctionEventLogModification.d.ts.map +1 -1
  420. package/dist/types/modifications/relations/UpdateRelationOnDeleteModification.d.ts +4 -4
  421. package/dist/types/modifications/relations/UpdateRelationOnDeleteModification.d.ts.map +1 -1
  422. package/dist/types/modifications/relations/UpdateRelationOrderByModification.d.ts +4 -4
  423. package/dist/types/modifications/relations/UpdateRelationOrderByModification.d.ts.map +1 -1
  424. package/dist/types/modifications/relations/index.d.ts +12 -11
  425. package/dist/types/modifications/relations/index.d.ts.map +1 -1
  426. package/dist/types/modifications/settings/UpdateSettingsModification.d.ts +4 -4
  427. package/dist/types/modifications/settings/UpdateSettingsModification.d.ts.map +1 -1
  428. package/dist/types/modifications/settings/index.d.ts +1 -1
  429. package/dist/types/modifications/settings/index.d.ts.map +1 -1
  430. package/dist/types/modifications/upgrade/RemoveIndexNamesModification.d.ts +3 -3
  431. package/dist/types/modifications/upgrade/RemoveIndexNamesModification.d.ts.map +1 -1
  432. package/dist/types/modifications/utils/diffUtils.d.ts +1 -1
  433. package/dist/types/modifications/utils/diffUtils.d.ts.map +1 -1
  434. package/dist/types/modifications/utils/viewDependencies.d.ts +11 -1
  435. package/dist/types/modifications/utils/viewDependencies.d.ts.map +1 -1
  436. package/dist/types/modifications/validation/PatchValidationSchemaModification.d.ts +3 -3
  437. package/dist/types/modifications/validation/PatchValidationSchemaModification.d.ts.map +1 -1
  438. package/dist/types/modifications/validation/UpdateValidationSchemaModification.d.ts +4 -4
  439. package/dist/types/modifications/validation/UpdateValidationSchemaModification.d.ts.map +1 -1
  440. package/dist/types/modifications/validation/index.d.ts +2 -2
  441. package/dist/types/modifications/validation/index.d.ts.map +1 -1
  442. package/dist/types/tsconfig.tsbuildinfo +1 -1
  443. package/package.json +7 -7
  444. package/src/MigrationDescriber.ts +2 -2
  445. package/src/SchemaDiffer.ts +52 -25
  446. package/src/SchemaMigrator.ts +2 -2
  447. package/src/index.ts +6 -6
  448. package/src/modifications/ModificationHandler.ts +2 -2
  449. package/src/modifications/ModificationHandlerFactory.ts +21 -19
  450. package/src/modifications/NoopModification.ts +2 -2
  451. package/src/modifications/acl/PatchAclSchemaModification.ts +3 -3
  452. package/src/modifications/acl/UpdateAclSchemaModification.ts +3 -3
  453. package/src/modifications/acl/index.ts +2 -2
  454. package/src/modifications/actions/CreateTargetModification.ts +2 -2
  455. package/src/modifications/actions/CreateTriggerModification.ts +2 -2
  456. package/src/modifications/actions/PatchTriggerModification.ts +3 -3
  457. package/src/modifications/actions/RemoveTargetModification.ts +2 -2
  458. package/src/modifications/actions/RemoveTriggerModification.ts +2 -2
  459. package/src/modifications/actions/UpdateTargetModification.ts +2 -2
  460. package/src/modifications/actions/UpdateTriggerModification.ts +3 -3
  461. package/src/modifications/actions/index.ts +4 -4
  462. package/src/modifications/columns/CreateColumnModification.ts +5 -5
  463. package/src/modifications/columns/UpdateColumnDefinitionModification.ts +6 -6
  464. package/src/modifications/columns/UpdateColumnNameModification.ts +3 -3
  465. package/src/modifications/columns/columnUtils.ts +1 -1
  466. package/src/modifications/columns/index.ts +3 -3
  467. package/src/modifications/constraints/CreateUniqueConstraintModification.ts +4 -4
  468. package/src/modifications/constraints/RemoveUniqueConstraintModification.ts +4 -4
  469. package/src/modifications/constraints/index.ts +3 -3
  470. package/src/modifications/differs/RemoveChangedFieldDiffer.ts +3 -3
  471. package/src/modifications/differs/RemoveViewDiffer.ts +17 -5
  472. package/src/modifications/differs/UpdateViewDiffer.ts +58 -0
  473. package/src/modifications/differs/index.ts +3 -2
  474. package/src/modifications/entities/CreateEntityModification.ts +5 -5
  475. package/src/modifications/entities/CreateViewModification.ts +3 -3
  476. package/src/modifications/entities/RemoveEntityModification.ts +4 -4
  477. package/src/modifications/entities/ToggleEventLogModification.ts +3 -3
  478. package/src/modifications/entities/UpdateEntityNameModification.ts +12 -7
  479. package/src/modifications/entities/UpdateEntityOrderByModification.ts +2 -2
  480. package/src/modifications/entities/UpdateEntityTableNameModification.ts +2 -2
  481. package/src/modifications/entities/UpdateViewModification.ts +2 -2
  482. package/src/modifications/entities/index.ts +7 -7
  483. package/src/modifications/enums/CreateEnumModification.ts +3 -3
  484. package/src/modifications/enums/RemoveEnumModification.ts +2 -2
  485. package/src/modifications/enums/UpdateEnumModification.ts +4 -4
  486. package/src/modifications/enums/enumUtils.ts +1 -1
  487. package/src/modifications/enums/index.ts +3 -3
  488. package/src/modifications/fields/RemoveFieldModification.ts +3 -3
  489. package/src/modifications/fields/UpdateFieldNameModification.ts +26 -10
  490. package/src/modifications/fields/index.ts +2 -2
  491. package/src/modifications/index.ts +13 -13
  492. package/src/modifications/indexes/CreateIndexModification.ts +47 -11
  493. package/src/modifications/indexes/RemoveIndexModification.ts +92 -23
  494. package/src/modifications/indexes/index.ts +2 -2
  495. package/src/modifications/relations/ConvertManyHasManyToJoiningEntityModification.ts +218 -0
  496. package/src/modifications/relations/ConvertOneHasManyToManyHasManyRelationModification.ts +7 -7
  497. package/src/modifications/relations/ConvertOneHasManyToOneHasOneRelationModification.ts +6 -6
  498. package/src/modifications/relations/ConvertOneToManyRelationModification.ts +6 -6
  499. package/src/modifications/relations/CreateRelationInverseSideModification.ts +3 -3
  500. package/src/modifications/relations/CreateRelationModification.ts +9 -9
  501. package/src/modifications/relations/DisableOrphanRemovalModification.ts +3 -3
  502. package/src/modifications/relations/EnableOrphanRemovalModification.ts +3 -3
  503. package/src/modifications/relations/MakeRelationNotNullModification.ts +4 -4
  504. package/src/modifications/relations/MakeRelationNullableModification.ts +4 -4
  505. package/src/modifications/relations/ToggleJunctionEventLogModification.ts +5 -5
  506. package/src/modifications/relations/UpdateRelationOnDeleteModification.ts +5 -5
  507. package/src/modifications/relations/UpdateRelationOrderByModification.ts +3 -3
  508. package/src/modifications/relations/helpers.ts +1 -1
  509. package/src/modifications/relations/index.ts +12 -11
  510. package/src/modifications/settings/UpdateSettingsModification.ts +2 -2
  511. package/src/modifications/settings/index.ts +1 -1
  512. package/src/modifications/upgrade/RemoveIndexNamesModification.ts +2 -2
  513. package/src/modifications/utils/createJunctionTable.ts +3 -3
  514. package/src/modifications/utils/diffUtils.ts +2 -2
  515. package/src/modifications/utils/schemaUpdateUtils.ts +3 -3
  516. package/src/modifications/utils/viewDependencies.ts +26 -2
  517. package/src/modifications/validation/PatchValidationSchemaModification.ts +3 -3
  518. package/src/modifications/validation/UpdateValidationSchemaModification.ts +3 -3
  519. package/src/modifications/validation/index.ts +2 -2
  520. package/tests/cases/integration/convertManyHasManyToJoiningEntity.test.ts +339 -0
  521. package/tests/cases/integration/convertManyHasOneToOneHasOneRelation.test.ts +2 -2
  522. package/tests/cases/integration/convertOneHasManyToManyHasManyRelation.test.ts +2 -2
  523. package/tests/cases/integration/convertOneToManyRelation.test.ts +2 -2
  524. package/tests/cases/integration/createAndDropIndex.test.ts +482 -3
  525. package/tests/cases/integration/createColumn.test.ts +29 -2
  526. package/tests/cases/integration/createEntity.test.ts +2 -2
  527. package/tests/cases/integration/createEnum.test.ts +2 -2
  528. package/tests/cases/integration/createManyHasMany.test.ts +2 -2
  529. package/tests/cases/integration/createManyHasOne.test.ts +2 -2
  530. package/tests/cases/integration/createOneHasMany.test.ts +2 -2
  531. package/tests/cases/integration/createOneHasOne.test.ts +2 -2
  532. package/tests/cases/integration/createRelationInverseSide.test.ts +2 -2
  533. package/tests/cases/integration/createUnique.test.ts +3 -3
  534. package/tests/cases/integration/disableOrphanRemoval.test.ts +2 -2
  535. package/tests/cases/integration/enableOrphanRemoval.test.ts +2 -2
  536. package/tests/cases/integration/makeColumnNotNull.test.ts +2 -2
  537. package/tests/cases/integration/makeRelationNotNull.test.ts +2 -2
  538. package/tests/cases/integration/makeRelationNullable.test.ts +2 -2
  539. package/tests/cases/integration/patchAclSchema.test.ts +2 -2
  540. package/tests/cases/integration/patchTrigger.test.ts +1 -1
  541. package/tests/cases/integration/removeEntity.test.ts +2 -2
  542. package/tests/cases/integration/removeEnum.test.ts +2 -2
  543. package/tests/cases/integration/removeField.test.ts +3 -3
  544. package/tests/cases/integration/skipNonModelDiffers.test.ts +97 -0
  545. package/tests/cases/integration/toggleEventLog.test.ts +2 -2
  546. package/tests/cases/integration/toggleJunctionEventLog.test.ts +2 -2
  547. package/tests/cases/integration/updateColumnDefinition.test.ts +3 -3
  548. package/tests/cases/integration/updateEntityName.test.ts +2 -2
  549. package/tests/cases/integration/updateEntityOrderBy.test.ts +2 -2
  550. package/tests/cases/integration/updateEnum.test.ts +2 -2
  551. package/tests/cases/integration/updateFieldName.test.ts +38 -3
  552. package/tests/cases/integration/updateRelationOnDelete.test.ts +2 -2
  553. package/tests/cases/integration/updateRelationOrderBy.test.ts +2 -2
  554. package/tests/cases/integration/updateView.test.ts +221 -233
  555. package/tests/src/tests.ts +6 -4
@@ -15,16 +15,25 @@ class CreateIndexModificationHandler {
15
15
  if (entity.view && !entity.view.materialized) {
16
16
  return;
17
17
  }
18
- const fields = this.data.index.fields;
18
+ const index = this.data.index;
19
19
  const columns = utils.getIndexColumns({
20
- fields,
20
+ fields: index.fields,
21
21
  entity,
22
22
  model: this.schema.model
23
23
  });
24
24
  const tableNameId = dbHelpers.wrapIdentifier(entity.tableName);
25
- const columnNameIds = columns.map(dbHelpers.wrapIdentifier);
26
- const methodClause = this.data.index.method ? ` USING ${this.data.index.method}` : "";
27
- builder.sql(`CREATE INDEX ON ${tableNameId}${methodClause} (${columnNameIds.join(", ")})`);
25
+ const columnNameIds = index.fields.map((field, i) => {
26
+ const options = index.columnOptions?.[field];
27
+ const opClass = options?.opClass ?? index.opClass;
28
+ const opClassSuffix = opClass ? ` ${opClass}` : "";
29
+ const orderSuffix = options?.order === "desc" ? " DESC" : "";
30
+ const nullsSuffix = options?.nulls === "first" ? " NULLS FIRST" : options?.nulls === "last" ? " NULLS LAST" : "";
31
+ return dbHelpers.wrapIdentifier(columns[i]) + opClassSuffix + orderSuffix + nullsSuffix;
32
+ });
33
+ const methodClause = index.method ? ` USING ${index.method}` : "";
34
+ const includeClause = index.include?.length ? ` INCLUDE (${utils.getIndexColumns({ fields: index.include, entity, model: this.schema.model }).map(dbHelpers.wrapIdentifier).join(", ")})` : "";
35
+ const whereClause = index.where ? ` WHERE (${index.where})` : "";
36
+ builder.sql(`CREATE INDEX ON ${tableNameId}${methodClause} (${columnNameIds.join(", ")})${includeClause}${whereClause}`);
28
37
  invalidateDatabaseMetadata();
29
38
  }
30
39
  getSchemaUpdater() {
@@ -39,9 +48,16 @@ class CreateIndexModificationHandler {
39
48
  );
40
49
  }
41
50
  describe() {
42
- const methodText = this.data.index.method ? ` using ${this.data.index.method}` : "";
51
+ const index = this.data.index;
52
+ const methodText = index.method ? ` using ${index.method}` : "";
53
+ const includeText = index.include?.length ? ` include (${index.include.join(", ")})` : "";
54
+ const whereText = index.where ? ` where ${index.where}` : "";
55
+ const columnOptionsText = index.columnOptions && Object.keys(index.columnOptions).length > 0 ? ` options (${Object.entries(index.columnOptions).map(([field, opts]) => {
56
+ const parts = [opts.order, opts.nulls ? `nulls ${opts.nulls}` : "", opts.opClass ? `opclass ${opts.opClass}` : ""].filter(Boolean);
57
+ return `${field}: ${parts.join(" ")}`;
58
+ }).join(", ")})` : "";
43
59
  return {
44
- message: `Create index(${this.data.index.fields.join(", ")})${methodText} on entity ${this.data.entityName}`
60
+ message: `Create index(${index.fields.join(", ")})${methodText}${includeText}${whereText}${columnOptionsText} on entity ${this.data.entityName}`
45
61
  };
46
62
  }
47
63
  }
@@ -1 +1 @@
1
- {"version":3,"file":"CreateIndexModification.cjs","sources":["../../../../../../packages/schema-migrations/src/modifications/indexes/CreateIndexModification.ts"],"sourcesContent":["import { MigrationBuilder } from '@contember/database-migrations'\nimport { Model, Schema } from '@contember/schema'\nimport { SchemaUpdater, updateEntity, updateModel } from '../utils/schemaUpdateUtils'\nimport { createModificationType, Differ, ModificationHandler, ModificationHandlerCreateSqlOptions } from '../ModificationHandler'\nimport { wrapIdentifier } from '../../utils/dbHelpers'\nimport { getIndexColumns } from './utils'\nimport deepEqual from 'fast-deep-equal'\n\nexport class CreateIndexModificationHandler implements ModificationHandler<CreateIndexModificationData> {\n\tconstructor(private readonly data: CreateIndexModificationData, private readonly schema: Schema) {}\n\n\tpublic createSql(builder: MigrationBuilder, { databaseMetadata, invalidateDatabaseMetadata }: ModificationHandlerCreateSqlOptions): void {\n\t\tconst entity = this.schema.model.entities[this.data.entityName]\n\t\tif (entity.view && !entity.view.materialized) {\n\t\t\treturn\n\t\t}\n\t\tconst fields = this.data.index.fields\n\t\tconst columns = getIndexColumns({\n\t\t\tfields,\n\t\t\tentity,\n\t\t\tmodel: this.schema.model,\n\t\t})\n\n\t\tconst tableNameId = wrapIdentifier(entity.tableName)\n\t\tconst columnNameIds = columns.map(wrapIdentifier)\n\t\tconst methodClause = this.data.index.method ? ` USING ${this.data.index.method}` : ''\n\n\t\tbuilder.sql(`CREATE INDEX ON ${tableNameId}${methodClause} (${columnNameIds.join(', ')})`)\n\n\t\tinvalidateDatabaseMetadata()\n\t}\n\n\tpublic getSchemaUpdater(): SchemaUpdater {\n\t\treturn updateModel(\n\t\t\tupdateEntity(this.data.entityName, ({ entity }) => ({\n\t\t\t\t...entity,\n\t\t\t\tindexes: [\n\t\t\t\t\t...entity.indexes,\n\t\t\t\t\tthis.data.index,\n\t\t\t\t],\n\t\t\t})),\n\t\t)\n\t}\n\n\tdescribe() {\n\t\tconst methodText = this.data.index.method ? ` using ${this.data.index.method}` : ''\n\t\treturn {\n\t\t\tmessage: `Create index(${this.data.index.fields.join(', ')})${methodText} on entity ${this.data.entityName}`,\n\t\t}\n\t}\n}\n\nexport const createIndexModification = createModificationType({\n\tid: 'createIndex',\n\thandler: CreateIndexModificationHandler,\n})\n\nexport interface CreateIndexModificationData {\n\tentityName: string\n\tindex: Model.Index\n}\n\nexport class CreateIndexDiffer implements Differ {\n\tcreateDiff(originalSchema: Schema, updatedSchema: Schema) {\n\t\treturn Object.values(updatedSchema.model.entities).flatMap(entity =>\n\t\t\tentity.indexes\n\t\t\t\t.filter(it => !originalSchema.model.entities[entity.name].indexes.find(idx => deepEqual(idx, it)))\n\t\t\t\t.map(index =>\n\t\t\t\t\tcreateIndexModification.createModification({\n\t\t\t\t\t\tentityName: entity.name,\n\t\t\t\t\t\tindex,\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t)\n\t}\n}\n"],"names":["getIndexColumns","wrapIdentifier","updateModel","updateEntity","createModificationType"],"mappings":";;;;;;;AAQO,MAAM,+BAA2F;AAAA,EACvG,YAA6B,MAAoD,QAAgB;AAApE,SAAA,OAAA;AAAoD,SAAA,SAAA;AAAA,EAAiB;AAAA,EAE3F,UAAU,SAA2B,EAAE,kBAAkB,8BAAyE;AACxI,UAAM,SAAS,KAAK,OAAO,MAAM,SAAS,KAAK,KAAK,UAAU;AAC9D,QAAI,OAAO,QAAQ,CAAC,OAAO,KAAK,cAAc;AAC7C;AAAA,IACD;AACA,UAAM,SAAS,KAAK,KAAK,MAAM;AAC/B,UAAM,UAAUA,MAAAA,gBAAgB;AAAA,MAC/B;AAAA,MACA;AAAA,MACA,OAAO,KAAK,OAAO;AAAA,IAAA,CACnB;AAED,UAAM,cAAcC,UAAAA,eAAe,OAAO,SAAS;AACnD,UAAM,gBAAgB,QAAQ,IAAIA,wBAAc;AAChD,UAAM,eAAe,KAAK,KAAK,MAAM,SAAS,UAAU,KAAK,KAAK,MAAM,MAAM,KAAK;AAEnF,YAAQ,IAAI,mBAAmB,WAAW,GAAG,YAAY,KAAK,cAAc,KAAK,IAAI,CAAC,GAAG;AAEzF,+BAAA;AAAA,EACD;AAAA,EAEO,mBAAkC;AACxC,WAAOC,kBAAAA;AAAAA,MACNC,kBAAAA,aAAa,KAAK,KAAK,YAAY,CAAC,EAAE,cAAc;AAAA,QACnD,GAAG;AAAA,QACH,SAAS;AAAA,UACR,GAAG,OAAO;AAAA,UACV,KAAK,KAAK;AAAA,QAAA;AAAA,MACX,EACC;AAAA,IAAA;AAAA,EAEJ;AAAA,EAEA,WAAW;AACV,UAAM,aAAa,KAAK,KAAK,MAAM,SAAS,UAAU,KAAK,KAAK,MAAM,MAAM,KAAK;AACjF,WAAO;AAAA,MACN,SAAS,gBAAgB,KAAK,KAAK,MAAM,OAAO,KAAK,IAAI,CAAC,IAAI,UAAU,cAAc,KAAK,KAAK,UAAU;AAAA,IAAA;AAAA,EAE5G;AACD;AAEO,MAAM,0BAA0BC,oBAAAA,uBAAuB;AAAA,EAC7D,IAAI;AAAA,EACJ,SAAS;AACV,CAAC;AAOM,MAAM,kBAAoC;AAAA,EAChD,WAAW,gBAAwB,eAAuB;AACzD,WAAO,OAAO,OAAO,cAAc,MAAM,QAAQ,EAAE;AAAA,MAAQ,CAAA,WAC1D,OAAO,QACL,OAAO,QAAM,CAAC,eAAe,MAAM,SAAS,OAAO,IAAI,EAAE,QAAQ,KAAK,CAAA,QAAO,UAAU,KAAK,EAAE,CAAC,CAAC,EAChG;AAAA,QAAI,CAAA,UACJ,wBAAwB,mBAAmB;AAAA,UAC1C,YAAY,OAAO;AAAA,UACnB;AAAA,QAAA,CACA;AAAA,MAAA;AAAA,IACF;AAAA,EAEH;AACD;;;;"}
1
+ {"version":3,"file":"CreateIndexModification.cjs","sources":["../../../../../../packages/schema-migrations/src/modifications/indexes/CreateIndexModification.ts"],"sourcesContent":["import { MigrationBuilder } from '@contember/database-migrations'\nimport { Model, Schema } from '@contember/schema'\nimport { SchemaUpdater, updateEntity, updateModel } from '../utils/schemaUpdateUtils.js'\nimport { createModificationType, Differ, ModificationHandler, ModificationHandlerCreateSqlOptions } from '../ModificationHandler.js'\nimport { wrapIdentifier } from '../../utils/dbHelpers.js'\nimport { getIndexColumns } from './utils.js'\nimport deepEqual from 'fast-deep-equal'\n\nexport class CreateIndexModificationHandler implements ModificationHandler<CreateIndexModificationData> {\n\tconstructor(private readonly data: CreateIndexModificationData, private readonly schema: Schema) {}\n\n\tpublic createSql(builder: MigrationBuilder, { databaseMetadata, invalidateDatabaseMetadata }: ModificationHandlerCreateSqlOptions): void {\n\t\tconst entity = this.schema.model.entities[this.data.entityName]\n\t\tif (entity.view && !entity.view.materialized) {\n\t\t\treturn\n\t\t}\n\t\tconst index = this.data.index\n\t\tconst columns = getIndexColumns({\n\t\t\tfields: index.fields,\n\t\t\tentity,\n\t\t\tmodel: this.schema.model,\n\t\t})\n\n\t\tconst tableNameId = wrapIdentifier(entity.tableName)\n\t\t// Each key column may carry its own operator class (falling back to the global opClass),\n\t\t// sort direction (ASC is the default and omitted) and NULLS placement. Postgres expects\n\t\t// the parts in this order: column [opclass] [ASC|DESC] [NULLS {FIRST|LAST}].\n\t\t// The opclass is emitted verbatim (validated to an identifier shape in ModelValidator). Migrations\n\t\t// run with search_path set to the stage schema, so the value must already carry any needed schema\n\t\t// qualifier: an extension's class as \"public.gin_trgm_ops\", a built-in one (in pg_catalog) as\n\t\t// plain \"text_pattern_ops\".\n\t\tconst columnNameIds = index.fields.map((field, i) => {\n\t\t\tconst options = index.columnOptions?.[field]\n\t\t\tconst opClass = options?.opClass ?? index.opClass\n\t\t\tconst opClassSuffix = opClass ? ` ${opClass}` : ''\n\t\t\tconst orderSuffix = options?.order === 'desc' ? ' DESC' : ''\n\t\t\tconst nullsSuffix = options?.nulls === 'first' ? ' NULLS FIRST' : options?.nulls === 'last' ? ' NULLS LAST' : ''\n\t\t\treturn wrapIdentifier(columns[i]) + opClassSuffix + orderSuffix + nullsSuffix\n\t\t})\n\t\tconst methodClause = index.method ? ` USING ${index.method}` : ''\n\n\t\tconst includeClause = index.include?.length\n\t\t\t? ` INCLUDE (${getIndexColumns({ fields: index.include, entity, model: this.schema.model }).map(wrapIdentifier).join(', ')})`\n\t\t\t: ''\n\t\t// `where` is a raw, developer-authored SQL predicate. Its trust boundary is identical to\n\t\t// @c.View's raw body — committed to a migration and gated by code review, not end-user input.\n\t\t// Its shape is validated in ModelValidator (non-empty, no statement terminator); here we only\n\t\t// wrap it in parentheses so it stays a self-contained boolean expression.\n\t\tconst whereClause = index.where ? ` WHERE (${index.where})` : ''\n\n\t\tbuilder.sql(`CREATE INDEX ON ${tableNameId}${methodClause} (${columnNameIds.join(', ')})${includeClause}${whereClause}`)\n\n\t\tinvalidateDatabaseMetadata()\n\t}\n\n\tpublic getSchemaUpdater(): SchemaUpdater {\n\t\treturn updateModel(\n\t\t\tupdateEntity(this.data.entityName, ({ entity }) => ({\n\t\t\t\t...entity,\n\t\t\t\tindexes: [\n\t\t\t\t\t...entity.indexes,\n\t\t\t\t\tthis.data.index,\n\t\t\t\t],\n\t\t\t})),\n\t\t)\n\t}\n\n\tdescribe() {\n\t\tconst index = this.data.index\n\t\tconst methodText = index.method ? ` using ${index.method}` : ''\n\t\tconst includeText = index.include?.length ? ` include (${index.include.join(', ')})` : ''\n\t\tconst whereText = index.where ? ` where ${index.where}` : ''\n\t\t// columnOptions is part of index identity, so surface it in the description too — otherwise two\n\t\t// indexes on the same columns differing only by sort order / NULLS / opClass render identically.\n\t\tconst columnOptionsText = index.columnOptions && Object.keys(index.columnOptions).length > 0\n\t\t\t? ` options (${\n\t\t\t\tObject.entries(index.columnOptions).map(([field, opts]) => {\n\t\t\t\t\tconst parts = [opts.order, opts.nulls ? `nulls ${opts.nulls}` : '', opts.opClass ? `opclass ${opts.opClass}` : ''].filter(Boolean)\n\t\t\t\t\treturn `${field}: ${parts.join(' ')}`\n\t\t\t\t}).join(', ')\n\t\t\t})`\n\t\t\t: ''\n\t\treturn {\n\t\t\tmessage: `Create index(${index.fields.join(', ')})${methodText}${includeText}${whereText}${columnOptionsText} on entity ${this.data.entityName}`,\n\t\t}\n\t}\n}\n\nexport const createIndexModification = createModificationType({\n\tid: 'createIndex',\n\thandler: CreateIndexModificationHandler,\n})\n\nexport interface CreateIndexModificationData {\n\tentityName: string\n\tindex: Model.Index\n}\n\nexport class CreateIndexDiffer implements Differ {\n\tcreateDiff(originalSchema: Schema, updatedSchema: Schema) {\n\t\treturn Object.values(updatedSchema.model.entities).flatMap(entity =>\n\t\t\tentity.indexes\n\t\t\t\t.filter(it => !originalSchema.model.entities[entity.name].indexes.find(idx => deepEqual(idx, it)))\n\t\t\t\t.map(index =>\n\t\t\t\t\tcreateIndexModification.createModification({\n\t\t\t\t\t\tentityName: entity.name,\n\t\t\t\t\t\tindex,\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t)\n\t}\n}\n"],"names":["getIndexColumns","wrapIdentifier","updateModel","updateEntity","createModificationType"],"mappings":"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"}
@@ -13,16 +13,25 @@ class CreateIndexModificationHandler {
13
13
  if (entity.view && !entity.view.materialized) {
14
14
  return;
15
15
  }
16
- const fields = this.data.index.fields;
16
+ const index = this.data.index;
17
17
  const columns = getIndexColumns({
18
- fields,
18
+ fields: index.fields,
19
19
  entity,
20
20
  model: this.schema.model
21
21
  });
22
22
  const tableNameId = wrapIdentifier(entity.tableName);
23
- const columnNameIds = columns.map(wrapIdentifier);
24
- const methodClause = this.data.index.method ? ` USING ${this.data.index.method}` : "";
25
- builder.sql(`CREATE INDEX ON ${tableNameId}${methodClause} (${columnNameIds.join(", ")})`);
23
+ const columnNameIds = index.fields.map((field, i) => {
24
+ const options = index.columnOptions?.[field];
25
+ const opClass = options?.opClass ?? index.opClass;
26
+ const opClassSuffix = opClass ? ` ${opClass}` : "";
27
+ const orderSuffix = options?.order === "desc" ? " DESC" : "";
28
+ const nullsSuffix = options?.nulls === "first" ? " NULLS FIRST" : options?.nulls === "last" ? " NULLS LAST" : "";
29
+ return wrapIdentifier(columns[i]) + opClassSuffix + orderSuffix + nullsSuffix;
30
+ });
31
+ const methodClause = index.method ? ` USING ${index.method}` : "";
32
+ const includeClause = index.include?.length ? ` INCLUDE (${getIndexColumns({ fields: index.include, entity, model: this.schema.model }).map(wrapIdentifier).join(", ")})` : "";
33
+ const whereClause = index.where ? ` WHERE (${index.where})` : "";
34
+ builder.sql(`CREATE INDEX ON ${tableNameId}${methodClause} (${columnNameIds.join(", ")})${includeClause}${whereClause}`);
26
35
  invalidateDatabaseMetadata();
27
36
  }
28
37
  getSchemaUpdater() {
@@ -37,9 +46,16 @@ class CreateIndexModificationHandler {
37
46
  );
38
47
  }
39
48
  describe() {
40
- const methodText = this.data.index.method ? ` using ${this.data.index.method}` : "";
49
+ const index = this.data.index;
50
+ const methodText = index.method ? ` using ${index.method}` : "";
51
+ const includeText = index.include?.length ? ` include (${index.include.join(", ")})` : "";
52
+ const whereText = index.where ? ` where ${index.where}` : "";
53
+ const columnOptionsText = index.columnOptions && Object.keys(index.columnOptions).length > 0 ? ` options (${Object.entries(index.columnOptions).map(([field, opts]) => {
54
+ const parts = [opts.order, opts.nulls ? `nulls ${opts.nulls}` : "", opts.opClass ? `opclass ${opts.opClass}` : ""].filter(Boolean);
55
+ return `${field}: ${parts.join(" ")}`;
56
+ }).join(", ")})` : "";
41
57
  return {
42
- message: `Create index(${this.data.index.fields.join(", ")})${methodText} on entity ${this.data.entityName}`
58
+ message: `Create index(${index.fields.join(", ")})${methodText}${includeText}${whereText}${columnOptionsText} on entity ${this.data.entityName}`
43
59
  };
44
60
  }
45
61
  }
@@ -1 +1 @@
1
- {"version":3,"file":"CreateIndexModification.js","sources":["../../../../../../packages/schema-migrations/src/modifications/indexes/CreateIndexModification.ts"],"sourcesContent":["import { MigrationBuilder } from '@contember/database-migrations'\nimport { Model, Schema } from '@contember/schema'\nimport { SchemaUpdater, updateEntity, updateModel } from '../utils/schemaUpdateUtils'\nimport { createModificationType, Differ, ModificationHandler, ModificationHandlerCreateSqlOptions } from '../ModificationHandler'\nimport { wrapIdentifier } from '../../utils/dbHelpers'\nimport { getIndexColumns } from './utils'\nimport deepEqual from 'fast-deep-equal'\n\nexport class CreateIndexModificationHandler implements ModificationHandler<CreateIndexModificationData> {\n\tconstructor(private readonly data: CreateIndexModificationData, private readonly schema: Schema) {}\n\n\tpublic createSql(builder: MigrationBuilder, { databaseMetadata, invalidateDatabaseMetadata }: ModificationHandlerCreateSqlOptions): void {\n\t\tconst entity = this.schema.model.entities[this.data.entityName]\n\t\tif (entity.view && !entity.view.materialized) {\n\t\t\treturn\n\t\t}\n\t\tconst fields = this.data.index.fields\n\t\tconst columns = getIndexColumns({\n\t\t\tfields,\n\t\t\tentity,\n\t\t\tmodel: this.schema.model,\n\t\t})\n\n\t\tconst tableNameId = wrapIdentifier(entity.tableName)\n\t\tconst columnNameIds = columns.map(wrapIdentifier)\n\t\tconst methodClause = this.data.index.method ? ` USING ${this.data.index.method}` : ''\n\n\t\tbuilder.sql(`CREATE INDEX ON ${tableNameId}${methodClause} (${columnNameIds.join(', ')})`)\n\n\t\tinvalidateDatabaseMetadata()\n\t}\n\n\tpublic getSchemaUpdater(): SchemaUpdater {\n\t\treturn updateModel(\n\t\t\tupdateEntity(this.data.entityName, ({ entity }) => ({\n\t\t\t\t...entity,\n\t\t\t\tindexes: [\n\t\t\t\t\t...entity.indexes,\n\t\t\t\t\tthis.data.index,\n\t\t\t\t],\n\t\t\t})),\n\t\t)\n\t}\n\n\tdescribe() {\n\t\tconst methodText = this.data.index.method ? ` using ${this.data.index.method}` : ''\n\t\treturn {\n\t\t\tmessage: `Create index(${this.data.index.fields.join(', ')})${methodText} on entity ${this.data.entityName}`,\n\t\t}\n\t}\n}\n\nexport const createIndexModification = createModificationType({\n\tid: 'createIndex',\n\thandler: CreateIndexModificationHandler,\n})\n\nexport interface CreateIndexModificationData {\n\tentityName: string\n\tindex: Model.Index\n}\n\nexport class CreateIndexDiffer implements Differ {\n\tcreateDiff(originalSchema: Schema, updatedSchema: Schema) {\n\t\treturn Object.values(updatedSchema.model.entities).flatMap(entity =>\n\t\t\tentity.indexes\n\t\t\t\t.filter(it => !originalSchema.model.entities[entity.name].indexes.find(idx => deepEqual(idx, it)))\n\t\t\t\t.map(index =>\n\t\t\t\t\tcreateIndexModification.createModification({\n\t\t\t\t\t\tentityName: entity.name,\n\t\t\t\t\t\tindex,\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t)\n\t}\n}\n"],"names":[],"mappings":";;;;;AAQO,MAAM,+BAA2F;AAAA,EACvG,YAA6B,MAAoD,QAAgB;AAApE,SAAA,OAAA;AAAoD,SAAA,SAAA;AAAA,EAAiB;AAAA,EAE3F,UAAU,SAA2B,EAAE,kBAAkB,8BAAyE;AACxI,UAAM,SAAS,KAAK,OAAO,MAAM,SAAS,KAAK,KAAK,UAAU;AAC9D,QAAI,OAAO,QAAQ,CAAC,OAAO,KAAK,cAAc;AAC7C;AAAA,IACD;AACA,UAAM,SAAS,KAAK,KAAK,MAAM;AAC/B,UAAM,UAAU,gBAAgB;AAAA,MAC/B;AAAA,MACA;AAAA,MACA,OAAO,KAAK,OAAO;AAAA,IAAA,CACnB;AAED,UAAM,cAAc,eAAe,OAAO,SAAS;AACnD,UAAM,gBAAgB,QAAQ,IAAI,cAAc;AAChD,UAAM,eAAe,KAAK,KAAK,MAAM,SAAS,UAAU,KAAK,KAAK,MAAM,MAAM,KAAK;AAEnF,YAAQ,IAAI,mBAAmB,WAAW,GAAG,YAAY,KAAK,cAAc,KAAK,IAAI,CAAC,GAAG;AAEzF,+BAAA;AAAA,EACD;AAAA,EAEO,mBAAkC;AACxC,WAAO;AAAA,MACN,aAAa,KAAK,KAAK,YAAY,CAAC,EAAE,cAAc;AAAA,QACnD,GAAG;AAAA,QACH,SAAS;AAAA,UACR,GAAG,OAAO;AAAA,UACV,KAAK,KAAK;AAAA,QAAA;AAAA,MACX,EACC;AAAA,IAAA;AAAA,EAEJ;AAAA,EAEA,WAAW;AACV,UAAM,aAAa,KAAK,KAAK,MAAM,SAAS,UAAU,KAAK,KAAK,MAAM,MAAM,KAAK;AACjF,WAAO;AAAA,MACN,SAAS,gBAAgB,KAAK,KAAK,MAAM,OAAO,KAAK,IAAI,CAAC,IAAI,UAAU,cAAc,KAAK,KAAK,UAAU;AAAA,IAAA;AAAA,EAE5G;AACD;AAEO,MAAM,0BAA0B,uBAAuB;AAAA,EAC7D,IAAI;AAAA,EACJ,SAAS;AACV,CAAC;AAOM,MAAM,kBAAoC;AAAA,EAChD,WAAW,gBAAwB,eAAuB;AACzD,WAAO,OAAO,OAAO,cAAc,MAAM,QAAQ,EAAE;AAAA,MAAQ,CAAA,WAC1D,OAAO,QACL,OAAO,QAAM,CAAC,eAAe,MAAM,SAAS,OAAO,IAAI,EAAE,QAAQ,KAAK,CAAA,QAAO,UAAU,KAAK,EAAE,CAAC,CAAC,EAChG;AAAA,QAAI,CAAA,UACJ,wBAAwB,mBAAmB;AAAA,UAC1C,YAAY,OAAO;AAAA,UACnB;AAAA,QAAA,CACA;AAAA,MAAA;AAAA,IACF;AAAA,EAEH;AACD;"}
1
+ {"version":3,"file":"CreateIndexModification.js","sources":["../../../../../../packages/schema-migrations/src/modifications/indexes/CreateIndexModification.ts"],"sourcesContent":["import { MigrationBuilder } from '@contember/database-migrations'\nimport { Model, Schema } from '@contember/schema'\nimport { SchemaUpdater, updateEntity, updateModel } from '../utils/schemaUpdateUtils.js'\nimport { createModificationType, Differ, ModificationHandler, ModificationHandlerCreateSqlOptions } from '../ModificationHandler.js'\nimport { wrapIdentifier } from '../../utils/dbHelpers.js'\nimport { getIndexColumns } from './utils.js'\nimport deepEqual from 'fast-deep-equal'\n\nexport class CreateIndexModificationHandler implements ModificationHandler<CreateIndexModificationData> {\n\tconstructor(private readonly data: CreateIndexModificationData, private readonly schema: Schema) {}\n\n\tpublic createSql(builder: MigrationBuilder, { databaseMetadata, invalidateDatabaseMetadata }: ModificationHandlerCreateSqlOptions): void {\n\t\tconst entity = this.schema.model.entities[this.data.entityName]\n\t\tif (entity.view && !entity.view.materialized) {\n\t\t\treturn\n\t\t}\n\t\tconst index = this.data.index\n\t\tconst columns = getIndexColumns({\n\t\t\tfields: index.fields,\n\t\t\tentity,\n\t\t\tmodel: this.schema.model,\n\t\t})\n\n\t\tconst tableNameId = wrapIdentifier(entity.tableName)\n\t\t// Each key column may carry its own operator class (falling back to the global opClass),\n\t\t// sort direction (ASC is the default and omitted) and NULLS placement. Postgres expects\n\t\t// the parts in this order: column [opclass] [ASC|DESC] [NULLS {FIRST|LAST}].\n\t\t// The opclass is emitted verbatim (validated to an identifier shape in ModelValidator). Migrations\n\t\t// run with search_path set to the stage schema, so the value must already carry any needed schema\n\t\t// qualifier: an extension's class as \"public.gin_trgm_ops\", a built-in one (in pg_catalog) as\n\t\t// plain \"text_pattern_ops\".\n\t\tconst columnNameIds = index.fields.map((field, i) => {\n\t\t\tconst options = index.columnOptions?.[field]\n\t\t\tconst opClass = options?.opClass ?? index.opClass\n\t\t\tconst opClassSuffix = opClass ? ` ${opClass}` : ''\n\t\t\tconst orderSuffix = options?.order === 'desc' ? ' DESC' : ''\n\t\t\tconst nullsSuffix = options?.nulls === 'first' ? ' NULLS FIRST' : options?.nulls === 'last' ? ' NULLS LAST' : ''\n\t\t\treturn wrapIdentifier(columns[i]) + opClassSuffix + orderSuffix + nullsSuffix\n\t\t})\n\t\tconst methodClause = index.method ? ` USING ${index.method}` : ''\n\n\t\tconst includeClause = index.include?.length\n\t\t\t? ` INCLUDE (${getIndexColumns({ fields: index.include, entity, model: this.schema.model }).map(wrapIdentifier).join(', ')})`\n\t\t\t: ''\n\t\t// `where` is a raw, developer-authored SQL predicate. Its trust boundary is identical to\n\t\t// @c.View's raw body — committed to a migration and gated by code review, not end-user input.\n\t\t// Its shape is validated in ModelValidator (non-empty, no statement terminator); here we only\n\t\t// wrap it in parentheses so it stays a self-contained boolean expression.\n\t\tconst whereClause = index.where ? ` WHERE (${index.where})` : ''\n\n\t\tbuilder.sql(`CREATE INDEX ON ${tableNameId}${methodClause} (${columnNameIds.join(', ')})${includeClause}${whereClause}`)\n\n\t\tinvalidateDatabaseMetadata()\n\t}\n\n\tpublic getSchemaUpdater(): SchemaUpdater {\n\t\treturn updateModel(\n\t\t\tupdateEntity(this.data.entityName, ({ entity }) => ({\n\t\t\t\t...entity,\n\t\t\t\tindexes: [\n\t\t\t\t\t...entity.indexes,\n\t\t\t\t\tthis.data.index,\n\t\t\t\t],\n\t\t\t})),\n\t\t)\n\t}\n\n\tdescribe() {\n\t\tconst index = this.data.index\n\t\tconst methodText = index.method ? ` using ${index.method}` : ''\n\t\tconst includeText = index.include?.length ? ` include (${index.include.join(', ')})` : ''\n\t\tconst whereText = index.where ? ` where ${index.where}` : ''\n\t\t// columnOptions is part of index identity, so surface it in the description too — otherwise two\n\t\t// indexes on the same columns differing only by sort order / NULLS / opClass render identically.\n\t\tconst columnOptionsText = index.columnOptions && Object.keys(index.columnOptions).length > 0\n\t\t\t? ` options (${\n\t\t\t\tObject.entries(index.columnOptions).map(([field, opts]) => {\n\t\t\t\t\tconst parts = [opts.order, opts.nulls ? `nulls ${opts.nulls}` : '', opts.opClass ? `opclass ${opts.opClass}` : ''].filter(Boolean)\n\t\t\t\t\treturn `${field}: ${parts.join(' ')}`\n\t\t\t\t}).join(', ')\n\t\t\t})`\n\t\t\t: ''\n\t\treturn {\n\t\t\tmessage: `Create index(${index.fields.join(', ')})${methodText}${includeText}${whereText}${columnOptionsText} on entity ${this.data.entityName}`,\n\t\t}\n\t}\n}\n\nexport const createIndexModification = createModificationType({\n\tid: 'createIndex',\n\thandler: CreateIndexModificationHandler,\n})\n\nexport interface CreateIndexModificationData {\n\tentityName: string\n\tindex: Model.Index\n}\n\nexport class CreateIndexDiffer implements Differ {\n\tcreateDiff(originalSchema: Schema, updatedSchema: Schema) {\n\t\treturn Object.values(updatedSchema.model.entities).flatMap(entity =>\n\t\t\tentity.indexes\n\t\t\t\t.filter(it => !originalSchema.model.entities[entity.name].indexes.find(idx => deepEqual(idx, it)))\n\t\t\t\t.map(index =>\n\t\t\t\t\tcreateIndexModification.createModification({\n\t\t\t\t\t\tentityName: entity.name,\n\t\t\t\t\t\tindex,\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t)\n\t}\n}\n"],"names":[],"mappings":"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"}
@@ -5,6 +5,7 @@ const ModificationHandler = require("../ModificationHandler.cjs");
5
5
  const deepEqual = require("fast-deep-equal");
6
6
  const utils = require("./utils.cjs");
7
7
  const dbHelpers = require("../../utils/dbHelpers.cjs");
8
+ const indexIdentityEquals = (a, b) => deepEqual(a.fields, b.fields) && (a.where ?? void 0) === (b.where ?? void 0) && deepEqual(a.include ?? void 0, b.include ?? void 0) && deepEqual(a.columnOptions ?? void 0, b.columnOptions ?? void 0) && (a.method ?? void 0) === (b.method ?? void 0) && (a.opClass ?? void 0) === (b.opClass ?? void 0);
8
9
  class RemoveIndexModificationHandler {
9
10
  constructor(data, schema) {
10
11
  this.data = data;
@@ -15,23 +16,27 @@ class RemoveIndexModificationHandler {
15
16
  if (entity.view && !entity.view.materialized) {
16
17
  return;
17
18
  }
18
- const fields = this.getFields();
19
- const columns = utils.getIndexColumns({
20
- entity,
21
- fields,
22
- model: this.schema.model
23
- });
19
+ const index = this.getIndex();
20
+ const columns = [
21
+ ...utils.getIndexColumns({ entity, fields: index.fields, model: this.schema.model }),
22
+ ...index.include ? utils.getIndexColumns({ entity, fields: index.include, model: this.schema.model }) : []
23
+ ];
24
24
  const indexNames = databaseMetadata.indexes.filter({ tableName: entity.tableName, columnNames: columns, unique: false }).getNames();
25
+ if (indexNames.length > 1) {
26
+ throw new Error(
27
+ `Cannot unambiguously drop index on entity ${this.data.entityName} (${index.fields.join(", ")}): ${indexNames.length} indexes match these columns and the database metadata does not expose the predicate (where), per-column options (sort order / NULLS / operator class), column order, index method or index-level operator class that distinguish them. Drop the obsolete index manually.`
28
+ );
29
+ }
25
30
  for (const name of indexNames) {
26
31
  builder.sql(`DROP INDEX ${dbHelpers.wrapIdentifier(name)}`);
27
32
  }
28
33
  invalidateDatabaseMetadata();
29
34
  }
30
35
  getSchemaUpdater() {
31
- const fields = this.getFields();
36
+ const index = this.getIndex();
32
37
  return schemaUpdateUtils.updateModel(
33
38
  schemaUpdateUtils.updateEntity(this.data.entityName, ({ entity }) => {
34
- const indexes = entity.indexes.filter((it) => !deepEqual(it.fields, fields));
39
+ const indexes = entity.indexes.filter((it) => !indexIdentityEquals(it, index));
35
40
  return {
36
41
  ...entity,
37
42
  indexes
@@ -40,16 +45,37 @@ class RemoveIndexModificationHandler {
40
45
  );
41
46
  }
42
47
  describe() {
43
- const fields = this.getFields();
44
- return { message: `Remove index (${fields.join(", ")}) on entity ${this.data.entityName}` };
48
+ const index = this.getIndex();
49
+ return { message: `Remove index (${index.fields.join(", ")}) on entity ${this.data.entityName}` };
45
50
  }
46
- getFields() {
47
- const entity = this.schema.model.entities[this.data.entityName];
48
- const fields = "indexName" in this.data ? entity.indexes.find((it) => it.name === this.data.indexName)?.fields : this.data.fields;
49
- if (!fields) {
50
- throw new Error();
51
+ getIndex() {
52
+ const { entityName } = this.data;
53
+ const entity = this.schema.model.entities[entityName];
54
+ if ("indexName" in this.data && this.data.indexName !== void 0) {
55
+ const index = entity.indexes.find((it) => it.name === this.data.indexName);
56
+ if (!index) {
57
+ throw new Error(`Index named "${this.data.indexName}" not found on entity ${entityName}`);
58
+ }
59
+ return {
60
+ fields: index.fields,
61
+ where: index.where,
62
+ include: index.include,
63
+ columnOptions: index.columnOptions,
64
+ method: index.method,
65
+ opClass: index.opClass
66
+ };
67
+ }
68
+ if (!this.data.fields) {
69
+ throw new Error(`removeIndex modification on entity ${entityName} requires either "indexName" or "fields"`);
51
70
  }
52
- return fields;
71
+ return {
72
+ fields: this.data.fields,
73
+ where: this.data.where,
74
+ include: this.data.include,
75
+ columnOptions: this.data.columnOptions,
76
+ method: this.data.method,
77
+ opClass: this.data.opClass
78
+ };
53
79
  }
54
80
  }
55
81
  const removeIndexModification = ModificationHandler.createModificationType({
@@ -70,7 +96,16 @@ class RemoveIndexDiffer {
70
96
  ).map(
71
97
  (index) => removeIndexModification.createModification({
72
98
  entityName: entity.name,
73
- fields: index.fields
99
+ fields: index.fields,
100
+ // keep every identity-bearing option (WHERE/INCLUDE/columnOptions/method/opClass) in the
101
+ // modification so indexes that share the same key columns but differ by any of them are
102
+ // removed individually; omit the keys when absent to keep legacy migration JSON
103
+ // byte-for-byte identical.
104
+ ...index.where !== void 0 ? { where: index.where } : {},
105
+ ...index.include !== void 0 ? { include: index.include } : {},
106
+ ...index.columnOptions !== void 0 ? { columnOptions: index.columnOptions } : {},
107
+ ...index.method !== void 0 ? { method: index.method } : {},
108
+ ...index.opClass !== void 0 ? { opClass: index.opClass } : {}
74
109
  })
75
110
  )
76
111
  );
@@ -1 +1 @@
1
- {"version":3,"file":"RemoveIndexModification.cjs","sources":["../../../../../../packages/schema-migrations/src/modifications/indexes/RemoveIndexModification.ts"],"sourcesContent":["import { MigrationBuilder } from '@contember/database-migrations'\nimport { Schema } from '@contember/schema'\nimport { SchemaUpdater, updateEntity, updateModel } from '../utils/schemaUpdateUtils'\nimport { createModificationType, Differ, ModificationHandler, ModificationHandlerCreateSqlOptions } from '../ModificationHandler'\nimport deepEqual from 'fast-deep-equal'\nimport { getIndexColumns } from './utils'\nimport { wrapIdentifier } from '../../utils/dbHelpers'\n\nexport class RemoveIndexModificationHandler implements ModificationHandler<RemoveIndexModificationData> {\n\tconstructor(private readonly data: RemoveIndexModificationData, private readonly schema: Schema) {}\n\n\tpublic createSql(builder: MigrationBuilder, { databaseMetadata, invalidateDatabaseMetadata }: ModificationHandlerCreateSqlOptions): void {\n\t\tconst entity = this.schema.model.entities[this.data.entityName]\n\t\tif (entity.view && !entity.view.materialized) {\n\t\t\treturn\n\t\t}\n\t\tconst fields = this.getFields()\n\n\t\tconst columns = getIndexColumns({\n\t\t\tentity,\n\t\t\tfields,\n\t\t\tmodel: this.schema.model,\n\t\t})\n\n\t\tconst indexNames = databaseMetadata.indexes.filter({ tableName: entity.tableName, columnNames: columns, unique: false }).getNames()\n\n\t\tfor (const name of indexNames) {\n\t\t\tbuilder.sql(`DROP INDEX ${wrapIdentifier(name)}`)\n\t\t}\n\t\tinvalidateDatabaseMetadata()\n\t}\n\n\tpublic getSchemaUpdater(): SchemaUpdater {\n\t\tconst fields = this.getFields()\n\t\treturn updateModel(\n\t\t\tupdateEntity(this.data.entityName, ({ entity }) => {\n\t\t\t\tconst indexes = entity.indexes.filter(it => !deepEqual(it.fields, fields))\n\t\t\t\treturn {\n\t\t\t\t\t...entity,\n\t\t\t\t\tindexes,\n\t\t\t\t}\n\t\t\t}),\n\t\t)\n\t}\n\n\tdescribe() {\n\t\tconst fields = this.getFields()\n\t\treturn { message: `Remove index (${fields.join(', ')}) on entity ${this.data.entityName}` }\n\t}\n\n\tgetFields() {\n\t\tconst entity = this.schema.model.entities[this.data.entityName]\n\t\tconst fields = 'indexName' in this.data\n\t\t\t? entity.indexes.find(it => it.name === this.data.indexName)?.fields\n\t\t\t: this.data.fields\n\t\tif (!fields) {\n\t\t\tthrow new Error()\n\t\t}\n\t\treturn fields\n\t}\n}\n\nexport const removeIndexModification = createModificationType({\n\tid: 'removeIndex',\n\thandler: RemoveIndexModificationHandler,\n})\n\nexport type RemoveIndexModificationData =\n\t| {\n\t\tentityName: string\n\t\tindexName: string\n\t\tfields?: never\n\t}\n\t| {\n\t\tentityName: string\n\t\tfields: readonly string[]\n\t\tindexName?: never\n\t}\n\nexport class RemoveIndexDiffer implements Differ {\n\tcreateDiff(originalSchema: Schema, updatedSchema: Schema) {\n\t\treturn Object.values(originalSchema.model.entities).flatMap(entity =>\n\t\t\tentity.indexes\n\t\t\t\t.filter(\n\t\t\t\t\tit => {\n\t\t\t\t\t\tconst updatedEntity = updatedSchema.model.entities[entity.name]\n\t\t\t\t\t\tif (!updatedEntity) {\n\t\t\t\t\t\t\treturn false\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn !updatedEntity.indexes.find(index => deepEqual(index, it))\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t\t.map(index =>\n\t\t\t\t\tremoveIndexModification.createModification({\n\t\t\t\t\t\tentityName: entity.name,\n\t\t\t\t\t\tfields: index.fields,\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t)\n\t}\n}\n"],"names":["getIndexColumns","wrapIdentifier","updateModel","updateEntity","createModificationType"],"mappings":";;;;;;;AAQO,MAAM,+BAA2F;AAAA,EACvG,YAA6B,MAAoD,QAAgB;AAApE,SAAA,OAAA;AAAoD,SAAA,SAAA;AAAA,EAAiB;AAAA,EAE3F,UAAU,SAA2B,EAAE,kBAAkB,8BAAyE;AACxI,UAAM,SAAS,KAAK,OAAO,MAAM,SAAS,KAAK,KAAK,UAAU;AAC9D,QAAI,OAAO,QAAQ,CAAC,OAAO,KAAK,cAAc;AAC7C;AAAA,IACD;AACA,UAAM,SAAS,KAAK,UAAA;AAEpB,UAAM,UAAUA,MAAAA,gBAAgB;AAAA,MAC/B;AAAA,MACA;AAAA,MACA,OAAO,KAAK,OAAO;AAAA,IAAA,CACnB;AAED,UAAM,aAAa,iBAAiB,QAAQ,OAAO,EAAE,WAAW,OAAO,WAAW,aAAa,SAAS,QAAQ,MAAA,CAAO,EAAE,SAAA;AAEzH,eAAW,QAAQ,YAAY;AAC9B,cAAQ,IAAI,cAAcC,UAAAA,eAAe,IAAI,CAAC,EAAE;AAAA,IACjD;AACA,+BAAA;AAAA,EACD;AAAA,EAEO,mBAAkC;AACxC,UAAM,SAAS,KAAK,UAAA;AACpB,WAAOC,kBAAAA;AAAAA,MACNC,kBAAAA,aAAa,KAAK,KAAK,YAAY,CAAC,EAAE,aAAa;AAClD,cAAM,UAAU,OAAO,QAAQ,OAAO,CAAA,OAAM,CAAC,UAAU,GAAG,QAAQ,MAAM,CAAC;AACzE,eAAO;AAAA,UACN,GAAG;AAAA,UACH;AAAA,QAAA;AAAA,MAEF,CAAC;AAAA,IAAA;AAAA,EAEH;AAAA,EAEA,WAAW;AACV,UAAM,SAAS,KAAK,UAAA;AACpB,WAAO,EAAE,SAAS,iBAAiB,OAAO,KAAK,IAAI,CAAC,eAAe,KAAK,KAAK,UAAU,GAAA;AAAA,EACxF;AAAA,EAEA,YAAY;AACX,UAAM,SAAS,KAAK,OAAO,MAAM,SAAS,KAAK,KAAK,UAAU;AAC9D,UAAM,SAAS,eAAe,KAAK,OAChC,OAAO,QAAQ,KAAK,CAAA,OAAM,GAAG,SAAS,KAAK,KAAK,SAAS,GAAG,SAC5D,KAAK,KAAK;AACb,QAAI,CAAC,QAAQ;AACZ,YAAM,IAAI,MAAA;AAAA,IACX;AACA,WAAO;AAAA,EACR;AACD;AAEO,MAAM,0BAA0BC,oBAAAA,uBAAuB;AAAA,EAC7D,IAAI;AAAA,EACJ,SAAS;AACV,CAAC;AAcM,MAAM,kBAAoC;AAAA,EAChD,WAAW,gBAAwB,eAAuB;AACzD,WAAO,OAAO,OAAO,eAAe,MAAM,QAAQ,EAAE;AAAA,MAAQ,CAAA,WAC3D,OAAO,QACL;AAAA,QACA,CAAA,OAAM;AACL,gBAAM,gBAAgB,cAAc,MAAM,SAAS,OAAO,IAAI;AAC9D,cAAI,CAAC,eAAe;AACnB,mBAAO;AAAA,UACR;AACA,iBAAO,CAAC,cAAc,QAAQ,KAAK,WAAS,UAAU,OAAO,EAAE,CAAC;AAAA,QACjE;AAAA,MAAA,EAEA;AAAA,QAAI,CAAA,UACJ,wBAAwB,mBAAmB;AAAA,UAC1C,YAAY,OAAO;AAAA,UACnB,QAAQ,MAAM;AAAA,QAAA,CACd;AAAA,MAAA;AAAA,IACF;AAAA,EAEH;AACD;;;;"}
1
+ {"version":3,"file":"RemoveIndexModification.cjs","sources":["../../../../../../packages/schema-migrations/src/modifications/indexes/RemoveIndexModification.ts"],"sourcesContent":["import { MigrationBuilder } from '@contember/database-migrations'\nimport { Model, Schema } from '@contember/schema'\nimport { SchemaUpdater, updateEntity, updateModel } from '../utils/schemaUpdateUtils.js'\nimport { createModificationType, Differ, ModificationHandler, ModificationHandlerCreateSqlOptions } from '../ModificationHandler.js'\nimport deepEqual from 'fast-deep-equal'\nimport { getIndexColumns } from './utils.js'\nimport { wrapIdentifier } from '../../utils/dbHelpers.js'\n\ntype IndexIdentity = Pick<Model.Index, 'fields' | 'where' | 'include' | 'columnOptions' | 'method' | 'opClass'>\nconst indexIdentityEquals = (a: IndexIdentity, b: IndexIdentity) =>\n\tdeepEqual(a.fields, b.fields)\n\t&& (a.where ?? undefined) === (b.where ?? undefined)\n\t&& deepEqual(a.include ?? undefined, b.include ?? undefined)\n\t&& deepEqual(a.columnOptions ?? undefined, b.columnOptions ?? undefined)\n\t&& (a.method ?? undefined) === (b.method ?? undefined)\n\t&& (a.opClass ?? undefined) === (b.opClass ?? undefined)\n\nexport class RemoveIndexModificationHandler implements ModificationHandler<RemoveIndexModificationData> {\n\tconstructor(private readonly data: RemoveIndexModificationData, private readonly schema: Schema) {}\n\n\tpublic createSql(builder: MigrationBuilder, { databaseMetadata, invalidateDatabaseMetadata }: ModificationHandlerCreateSqlOptions): void {\n\t\tconst entity = this.schema.model.entities[this.data.entityName]\n\t\tif (entity.view && !entity.view.materialized) {\n\t\t\treturn\n\t\t}\n\t\tconst index = this.getIndex()\n\n\t\t// The DB-metadata layer (DatabaseMetadataResolver) exposes only table + columns (as an unordered\n\t\t// set) + uniqueness, so the physical DROP is matched by table + columns. Postgres' pg_index.indkey\n\t\t// includes the INCLUDE columns alongside the key columns, so a covering index's metadata lists both —\n\t\t// we match the same combined set here. Everything else that distinguishes two indexes on the same\n\t\t// column set — the partial WHERE predicate, per-column options (sort order / NULLS / operator class),\n\t\t// key-column ORDER (the set comparison is order-insensitive), the index method, and the index-level\n\t\t// operator class — is invisible to the metadata, so such siblings are indistinguishable here. We\n\t\t// detect that ambiguity below and fail loudly rather than DROP a sibling the schema still expects to\n\t\t// keep. Schema-level identity (see getSchemaUpdater) IS fully aware of these discriminators, so the\n\t\t// diff itself never conflates them.\n\t\tconst columns = [\n\t\t\t...getIndexColumns({ entity, fields: index.fields, model: this.schema.model }),\n\t\t\t...(index.include ? getIndexColumns({ entity, fields: index.include, model: this.schema.model }) : []),\n\t\t]\n\n\t\tconst indexNames = databaseMetadata.indexes.filter({ tableName: entity.tableName, columnNames: columns, unique: false }).getNames()\n\n\t\t// If more than one physical index matches these columns we cannot tell which one this modification\n\t\t// targets (the metadata hides the predicate / per-column options / column order / index method /\n\t\t// index-level operator class that distinguish them). Dropping every match would silently take out an\n\t\t// index the schema still expects — refuse instead, so the obsolete one can be dropped by hand.\n\t\tif (indexNames.length > 1) {\n\t\t\tthrow new Error(\n\t\t\t\t`Cannot unambiguously drop index on entity ${this.data.entityName} (${index.fields.join(', ')}): `\n\t\t\t\t\t+ `${indexNames.length} indexes match these columns and the database metadata does not expose the predicate (where), `\n\t\t\t\t\t+ `per-column options (sort order / NULLS / operator class), column order, index method or index-level operator class that distinguish them. `\n\t\t\t\t\t+ `Drop the obsolete index manually.`,\n\t\t\t)\n\t\t}\n\n\t\tfor (const name of indexNames) {\n\t\t\tbuilder.sql(`DROP INDEX ${wrapIdentifier(name)}`)\n\t\t}\n\t\tinvalidateDatabaseMetadata()\n\t}\n\n\tpublic getSchemaUpdater(): SchemaUpdater {\n\t\tconst index = this.getIndex()\n\t\treturn updateModel(\n\t\t\tupdateEntity(this.data.entityName, ({ entity }) => {\n\t\t\t\tconst indexes = entity.indexes.filter(it => !indexIdentityEquals(it, index))\n\t\t\t\treturn {\n\t\t\t\t\t...entity,\n\t\t\t\t\tindexes,\n\t\t\t\t}\n\t\t\t}),\n\t\t)\n\t}\n\n\tdescribe() {\n\t\tconst index = this.getIndex()\n\t\treturn { message: `Remove index (${index.fields.join(', ')}) on entity ${this.data.entityName}` }\n\t}\n\n\tprivate getIndex(): IndexIdentity {\n\t\tconst { entityName } = this.data\n\t\tconst entity = this.schema.model.entities[entityName]\n\t\tif ('indexName' in this.data && this.data.indexName !== undefined) {\n\t\t\tconst index = entity.indexes.find(it => it.name === this.data.indexName)\n\t\t\tif (!index) {\n\t\t\t\tthrow new Error(`Index named \"${this.data.indexName}\" not found on entity ${entityName}`)\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tfields: index.fields,\n\t\t\t\twhere: index.where,\n\t\t\t\tinclude: index.include,\n\t\t\t\tcolumnOptions: index.columnOptions,\n\t\t\t\tmethod: index.method,\n\t\t\t\topClass: index.opClass,\n\t\t\t}\n\t\t}\n\t\tif (!this.data.fields) {\n\t\t\tthrow new Error(`removeIndex modification on entity ${entityName} requires either \"indexName\" or \"fields\"`)\n\t\t}\n\t\treturn {\n\t\t\tfields: this.data.fields,\n\t\t\twhere: this.data.where,\n\t\t\tinclude: this.data.include,\n\t\t\tcolumnOptions: this.data.columnOptions,\n\t\t\tmethod: this.data.method,\n\t\t\topClass: this.data.opClass,\n\t\t}\n\t}\n}\n\nexport const removeIndexModification = createModificationType({\n\tid: 'removeIndex',\n\thandler: RemoveIndexModificationHandler,\n})\n\nexport type RemoveIndexModificationData =\n\t| {\n\t\tentityName: string\n\t\tindexName: string\n\t\tfields?: never\n\t\twhere?: never\n\t\tinclude?: never\n\t\tcolumnOptions?: never\n\t\tmethod?: never\n\t\topClass?: never\n\t}\n\t| {\n\t\tentityName: string\n\t\tfields: readonly string[]\n\t\twhere?: string\n\t\tinclude?: readonly string[]\n\t\tcolumnOptions?: { readonly [field: string]: Model.IndexColumnOptions }\n\t\tmethod?: Model.IndexMethod\n\t\topClass?: string\n\t\tindexName?: never\n\t}\n\nexport class RemoveIndexDiffer implements Differ {\n\tcreateDiff(originalSchema: Schema, updatedSchema: Schema) {\n\t\treturn Object.values(originalSchema.model.entities).flatMap(entity =>\n\t\t\tentity.indexes\n\t\t\t\t.filter(\n\t\t\t\t\tit => {\n\t\t\t\t\t\tconst updatedEntity = updatedSchema.model.entities[entity.name]\n\t\t\t\t\t\tif (!updatedEntity) {\n\t\t\t\t\t\t\treturn false\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn !updatedEntity.indexes.find(index => deepEqual(index, it))\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t\t.map(index =>\n\t\t\t\t\tremoveIndexModification.createModification({\n\t\t\t\t\t\tentityName: entity.name,\n\t\t\t\t\t\tfields: index.fields,\n\t\t\t\t\t\t// keep every identity-bearing option (WHERE/INCLUDE/columnOptions/method/opClass) in the\n\t\t\t\t\t\t// modification so indexes that share the same key columns but differ by any of them are\n\t\t\t\t\t\t// removed individually; omit the keys when absent to keep legacy migration JSON\n\t\t\t\t\t\t// byte-for-byte identical.\n\t\t\t\t\t\t...(index.where !== undefined ? { where: index.where } : {}),\n\t\t\t\t\t\t...(index.include !== undefined ? { include: index.include } : {}),\n\t\t\t\t\t\t...(index.columnOptions !== undefined ? { columnOptions: index.columnOptions } : {}),\n\t\t\t\t\t\t...(index.method !== undefined ? { method: index.method } : {}),\n\t\t\t\t\t\t...(index.opClass !== undefined ? { opClass: index.opClass } : {}),\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t)\n\t}\n}\n"],"names":["getIndexColumns","wrapIdentifier","updateModel","updateEntity","createModificationType"],"mappings":"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"}
@@ -3,6 +3,7 @@ import { createModificationType } from "../ModificationHandler.js";
3
3
  import deepEqual from "fast-deep-equal";
4
4
  import { getIndexColumns } from "./utils.js";
5
5
  import { wrapIdentifier } from "../../utils/dbHelpers.js";
6
+ const indexIdentityEquals = (a, b) => deepEqual(a.fields, b.fields) && (a.where ?? void 0) === (b.where ?? void 0) && deepEqual(a.include ?? void 0, b.include ?? void 0) && deepEqual(a.columnOptions ?? void 0, b.columnOptions ?? void 0) && (a.method ?? void 0) === (b.method ?? void 0) && (a.opClass ?? void 0) === (b.opClass ?? void 0);
6
7
  class RemoveIndexModificationHandler {
7
8
  constructor(data, schema) {
8
9
  this.data = data;
@@ -13,23 +14,27 @@ class RemoveIndexModificationHandler {
13
14
  if (entity.view && !entity.view.materialized) {
14
15
  return;
15
16
  }
16
- const fields = this.getFields();
17
- const columns = getIndexColumns({
18
- entity,
19
- fields,
20
- model: this.schema.model
21
- });
17
+ const index = this.getIndex();
18
+ const columns = [
19
+ ...getIndexColumns({ entity, fields: index.fields, model: this.schema.model }),
20
+ ...index.include ? getIndexColumns({ entity, fields: index.include, model: this.schema.model }) : []
21
+ ];
22
22
  const indexNames = databaseMetadata.indexes.filter({ tableName: entity.tableName, columnNames: columns, unique: false }).getNames();
23
+ if (indexNames.length > 1) {
24
+ throw new Error(
25
+ `Cannot unambiguously drop index on entity ${this.data.entityName} (${index.fields.join(", ")}): ${indexNames.length} indexes match these columns and the database metadata does not expose the predicate (where), per-column options (sort order / NULLS / operator class), column order, index method or index-level operator class that distinguish them. Drop the obsolete index manually.`
26
+ );
27
+ }
23
28
  for (const name of indexNames) {
24
29
  builder.sql(`DROP INDEX ${wrapIdentifier(name)}`);
25
30
  }
26
31
  invalidateDatabaseMetadata();
27
32
  }
28
33
  getSchemaUpdater() {
29
- const fields = this.getFields();
34
+ const index = this.getIndex();
30
35
  return updateModel(
31
36
  updateEntity(this.data.entityName, ({ entity }) => {
32
- const indexes = entity.indexes.filter((it) => !deepEqual(it.fields, fields));
37
+ const indexes = entity.indexes.filter((it) => !indexIdentityEquals(it, index));
33
38
  return {
34
39
  ...entity,
35
40
  indexes
@@ -38,16 +43,37 @@ class RemoveIndexModificationHandler {
38
43
  );
39
44
  }
40
45
  describe() {
41
- const fields = this.getFields();
42
- return { message: `Remove index (${fields.join(", ")}) on entity ${this.data.entityName}` };
46
+ const index = this.getIndex();
47
+ return { message: `Remove index (${index.fields.join(", ")}) on entity ${this.data.entityName}` };
43
48
  }
44
- getFields() {
45
- const entity = this.schema.model.entities[this.data.entityName];
46
- const fields = "indexName" in this.data ? entity.indexes.find((it) => it.name === this.data.indexName)?.fields : this.data.fields;
47
- if (!fields) {
48
- throw new Error();
49
+ getIndex() {
50
+ const { entityName } = this.data;
51
+ const entity = this.schema.model.entities[entityName];
52
+ if ("indexName" in this.data && this.data.indexName !== void 0) {
53
+ const index = entity.indexes.find((it) => it.name === this.data.indexName);
54
+ if (!index) {
55
+ throw new Error(`Index named "${this.data.indexName}" not found on entity ${entityName}`);
56
+ }
57
+ return {
58
+ fields: index.fields,
59
+ where: index.where,
60
+ include: index.include,
61
+ columnOptions: index.columnOptions,
62
+ method: index.method,
63
+ opClass: index.opClass
64
+ };
65
+ }
66
+ if (!this.data.fields) {
67
+ throw new Error(`removeIndex modification on entity ${entityName} requires either "indexName" or "fields"`);
49
68
  }
50
- return fields;
69
+ return {
70
+ fields: this.data.fields,
71
+ where: this.data.where,
72
+ include: this.data.include,
73
+ columnOptions: this.data.columnOptions,
74
+ method: this.data.method,
75
+ opClass: this.data.opClass
76
+ };
51
77
  }
52
78
  }
53
79
  const removeIndexModification = createModificationType({
@@ -68,7 +94,16 @@ class RemoveIndexDiffer {
68
94
  ).map(
69
95
  (index) => removeIndexModification.createModification({
70
96
  entityName: entity.name,
71
- fields: index.fields
97
+ fields: index.fields,
98
+ // keep every identity-bearing option (WHERE/INCLUDE/columnOptions/method/opClass) in the
99
+ // modification so indexes that share the same key columns but differ by any of them are
100
+ // removed individually; omit the keys when absent to keep legacy migration JSON
101
+ // byte-for-byte identical.
102
+ ...index.where !== void 0 ? { where: index.where } : {},
103
+ ...index.include !== void 0 ? { include: index.include } : {},
104
+ ...index.columnOptions !== void 0 ? { columnOptions: index.columnOptions } : {},
105
+ ...index.method !== void 0 ? { method: index.method } : {},
106
+ ...index.opClass !== void 0 ? { opClass: index.opClass } : {}
72
107
  })
73
108
  )
74
109
  );
@@ -1 +1 @@
1
- {"version":3,"file":"RemoveIndexModification.js","sources":["../../../../../../packages/schema-migrations/src/modifications/indexes/RemoveIndexModification.ts"],"sourcesContent":["import { MigrationBuilder } from '@contember/database-migrations'\nimport { Schema } from '@contember/schema'\nimport { SchemaUpdater, updateEntity, updateModel } from '../utils/schemaUpdateUtils'\nimport { createModificationType, Differ, ModificationHandler, ModificationHandlerCreateSqlOptions } from '../ModificationHandler'\nimport deepEqual from 'fast-deep-equal'\nimport { getIndexColumns } from './utils'\nimport { wrapIdentifier } from '../../utils/dbHelpers'\n\nexport class RemoveIndexModificationHandler implements ModificationHandler<RemoveIndexModificationData> {\n\tconstructor(private readonly data: RemoveIndexModificationData, private readonly schema: Schema) {}\n\n\tpublic createSql(builder: MigrationBuilder, { databaseMetadata, invalidateDatabaseMetadata }: ModificationHandlerCreateSqlOptions): void {\n\t\tconst entity = this.schema.model.entities[this.data.entityName]\n\t\tif (entity.view && !entity.view.materialized) {\n\t\t\treturn\n\t\t}\n\t\tconst fields = this.getFields()\n\n\t\tconst columns = getIndexColumns({\n\t\t\tentity,\n\t\t\tfields,\n\t\t\tmodel: this.schema.model,\n\t\t})\n\n\t\tconst indexNames = databaseMetadata.indexes.filter({ tableName: entity.tableName, columnNames: columns, unique: false }).getNames()\n\n\t\tfor (const name of indexNames) {\n\t\t\tbuilder.sql(`DROP INDEX ${wrapIdentifier(name)}`)\n\t\t}\n\t\tinvalidateDatabaseMetadata()\n\t}\n\n\tpublic getSchemaUpdater(): SchemaUpdater {\n\t\tconst fields = this.getFields()\n\t\treturn updateModel(\n\t\t\tupdateEntity(this.data.entityName, ({ entity }) => {\n\t\t\t\tconst indexes = entity.indexes.filter(it => !deepEqual(it.fields, fields))\n\t\t\t\treturn {\n\t\t\t\t\t...entity,\n\t\t\t\t\tindexes,\n\t\t\t\t}\n\t\t\t}),\n\t\t)\n\t}\n\n\tdescribe() {\n\t\tconst fields = this.getFields()\n\t\treturn { message: `Remove index (${fields.join(', ')}) on entity ${this.data.entityName}` }\n\t}\n\n\tgetFields() {\n\t\tconst entity = this.schema.model.entities[this.data.entityName]\n\t\tconst fields = 'indexName' in this.data\n\t\t\t? entity.indexes.find(it => it.name === this.data.indexName)?.fields\n\t\t\t: this.data.fields\n\t\tif (!fields) {\n\t\t\tthrow new Error()\n\t\t}\n\t\treturn fields\n\t}\n}\n\nexport const removeIndexModification = createModificationType({\n\tid: 'removeIndex',\n\thandler: RemoveIndexModificationHandler,\n})\n\nexport type RemoveIndexModificationData =\n\t| {\n\t\tentityName: string\n\t\tindexName: string\n\t\tfields?: never\n\t}\n\t| {\n\t\tentityName: string\n\t\tfields: readonly string[]\n\t\tindexName?: never\n\t}\n\nexport class RemoveIndexDiffer implements Differ {\n\tcreateDiff(originalSchema: Schema, updatedSchema: Schema) {\n\t\treturn Object.values(originalSchema.model.entities).flatMap(entity =>\n\t\t\tentity.indexes\n\t\t\t\t.filter(\n\t\t\t\t\tit => {\n\t\t\t\t\t\tconst updatedEntity = updatedSchema.model.entities[entity.name]\n\t\t\t\t\t\tif (!updatedEntity) {\n\t\t\t\t\t\t\treturn false\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn !updatedEntity.indexes.find(index => deepEqual(index, it))\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t\t.map(index =>\n\t\t\t\t\tremoveIndexModification.createModification({\n\t\t\t\t\t\tentityName: entity.name,\n\t\t\t\t\t\tfields: index.fields,\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t)\n\t}\n}\n"],"names":[],"mappings":";;;;;AAQO,MAAM,+BAA2F;AAAA,EACvG,YAA6B,MAAoD,QAAgB;AAApE,SAAA,OAAA;AAAoD,SAAA,SAAA;AAAA,EAAiB;AAAA,EAE3F,UAAU,SAA2B,EAAE,kBAAkB,8BAAyE;AACxI,UAAM,SAAS,KAAK,OAAO,MAAM,SAAS,KAAK,KAAK,UAAU;AAC9D,QAAI,OAAO,QAAQ,CAAC,OAAO,KAAK,cAAc;AAC7C;AAAA,IACD;AACA,UAAM,SAAS,KAAK,UAAA;AAEpB,UAAM,UAAU,gBAAgB;AAAA,MAC/B;AAAA,MACA;AAAA,MACA,OAAO,KAAK,OAAO;AAAA,IAAA,CACnB;AAED,UAAM,aAAa,iBAAiB,QAAQ,OAAO,EAAE,WAAW,OAAO,WAAW,aAAa,SAAS,QAAQ,MAAA,CAAO,EAAE,SAAA;AAEzH,eAAW,QAAQ,YAAY;AAC9B,cAAQ,IAAI,cAAc,eAAe,IAAI,CAAC,EAAE;AAAA,IACjD;AACA,+BAAA;AAAA,EACD;AAAA,EAEO,mBAAkC;AACxC,UAAM,SAAS,KAAK,UAAA;AACpB,WAAO;AAAA,MACN,aAAa,KAAK,KAAK,YAAY,CAAC,EAAE,aAAa;AAClD,cAAM,UAAU,OAAO,QAAQ,OAAO,CAAA,OAAM,CAAC,UAAU,GAAG,QAAQ,MAAM,CAAC;AACzE,eAAO;AAAA,UACN,GAAG;AAAA,UACH;AAAA,QAAA;AAAA,MAEF,CAAC;AAAA,IAAA;AAAA,EAEH;AAAA,EAEA,WAAW;AACV,UAAM,SAAS,KAAK,UAAA;AACpB,WAAO,EAAE,SAAS,iBAAiB,OAAO,KAAK,IAAI,CAAC,eAAe,KAAK,KAAK,UAAU,GAAA;AAAA,EACxF;AAAA,EAEA,YAAY;AACX,UAAM,SAAS,KAAK,OAAO,MAAM,SAAS,KAAK,KAAK,UAAU;AAC9D,UAAM,SAAS,eAAe,KAAK,OAChC,OAAO,QAAQ,KAAK,CAAA,OAAM,GAAG,SAAS,KAAK,KAAK,SAAS,GAAG,SAC5D,KAAK,KAAK;AACb,QAAI,CAAC,QAAQ;AACZ,YAAM,IAAI,MAAA;AAAA,IACX;AACA,WAAO;AAAA,EACR;AACD;AAEO,MAAM,0BAA0B,uBAAuB;AAAA,EAC7D,IAAI;AAAA,EACJ,SAAS;AACV,CAAC;AAcM,MAAM,kBAAoC;AAAA,EAChD,WAAW,gBAAwB,eAAuB;AACzD,WAAO,OAAO,OAAO,eAAe,MAAM,QAAQ,EAAE;AAAA,MAAQ,CAAA,WAC3D,OAAO,QACL;AAAA,QACA,CAAA,OAAM;AACL,gBAAM,gBAAgB,cAAc,MAAM,SAAS,OAAO,IAAI;AAC9D,cAAI,CAAC,eAAe;AACnB,mBAAO;AAAA,UACR;AACA,iBAAO,CAAC,cAAc,QAAQ,KAAK,WAAS,UAAU,OAAO,EAAE,CAAC;AAAA,QACjE;AAAA,MAAA,EAEA;AAAA,QAAI,CAAA,UACJ,wBAAwB,mBAAmB;AAAA,UAC1C,YAAY,OAAO;AAAA,UACnB,QAAQ,MAAM;AAAA,QAAA,CACd;AAAA,MAAA;AAAA,IACF;AAAA,EAEH;AACD;"}
1
+ {"version":3,"file":"RemoveIndexModification.js","sources":["../../../../../../packages/schema-migrations/src/modifications/indexes/RemoveIndexModification.ts"],"sourcesContent":["import { MigrationBuilder } from '@contember/database-migrations'\nimport { Model, Schema } from '@contember/schema'\nimport { SchemaUpdater, updateEntity, updateModel } from '../utils/schemaUpdateUtils.js'\nimport { createModificationType, Differ, ModificationHandler, ModificationHandlerCreateSqlOptions } from '../ModificationHandler.js'\nimport deepEqual from 'fast-deep-equal'\nimport { getIndexColumns } from './utils.js'\nimport { wrapIdentifier } from '../../utils/dbHelpers.js'\n\ntype IndexIdentity = Pick<Model.Index, 'fields' | 'where' | 'include' | 'columnOptions' | 'method' | 'opClass'>\nconst indexIdentityEquals = (a: IndexIdentity, b: IndexIdentity) =>\n\tdeepEqual(a.fields, b.fields)\n\t&& (a.where ?? undefined) === (b.where ?? undefined)\n\t&& deepEqual(a.include ?? undefined, b.include ?? undefined)\n\t&& deepEqual(a.columnOptions ?? undefined, b.columnOptions ?? undefined)\n\t&& (a.method ?? undefined) === (b.method ?? undefined)\n\t&& (a.opClass ?? undefined) === (b.opClass ?? undefined)\n\nexport class RemoveIndexModificationHandler implements ModificationHandler<RemoveIndexModificationData> {\n\tconstructor(private readonly data: RemoveIndexModificationData, private readonly schema: Schema) {}\n\n\tpublic createSql(builder: MigrationBuilder, { databaseMetadata, invalidateDatabaseMetadata }: ModificationHandlerCreateSqlOptions): void {\n\t\tconst entity = this.schema.model.entities[this.data.entityName]\n\t\tif (entity.view && !entity.view.materialized) {\n\t\t\treturn\n\t\t}\n\t\tconst index = this.getIndex()\n\n\t\t// The DB-metadata layer (DatabaseMetadataResolver) exposes only table + columns (as an unordered\n\t\t// set) + uniqueness, so the physical DROP is matched by table + columns. Postgres' pg_index.indkey\n\t\t// includes the INCLUDE columns alongside the key columns, so a covering index's metadata lists both —\n\t\t// we match the same combined set here. Everything else that distinguishes two indexes on the same\n\t\t// column set — the partial WHERE predicate, per-column options (sort order / NULLS / operator class),\n\t\t// key-column ORDER (the set comparison is order-insensitive), the index method, and the index-level\n\t\t// operator class — is invisible to the metadata, so such siblings are indistinguishable here. We\n\t\t// detect that ambiguity below and fail loudly rather than DROP a sibling the schema still expects to\n\t\t// keep. Schema-level identity (see getSchemaUpdater) IS fully aware of these discriminators, so the\n\t\t// diff itself never conflates them.\n\t\tconst columns = [\n\t\t\t...getIndexColumns({ entity, fields: index.fields, model: this.schema.model }),\n\t\t\t...(index.include ? getIndexColumns({ entity, fields: index.include, model: this.schema.model }) : []),\n\t\t]\n\n\t\tconst indexNames = databaseMetadata.indexes.filter({ tableName: entity.tableName, columnNames: columns, unique: false }).getNames()\n\n\t\t// If more than one physical index matches these columns we cannot tell which one this modification\n\t\t// targets (the metadata hides the predicate / per-column options / column order / index method /\n\t\t// index-level operator class that distinguish them). Dropping every match would silently take out an\n\t\t// index the schema still expects — refuse instead, so the obsolete one can be dropped by hand.\n\t\tif (indexNames.length > 1) {\n\t\t\tthrow new Error(\n\t\t\t\t`Cannot unambiguously drop index on entity ${this.data.entityName} (${index.fields.join(', ')}): `\n\t\t\t\t\t+ `${indexNames.length} indexes match these columns and the database metadata does not expose the predicate (where), `\n\t\t\t\t\t+ `per-column options (sort order / NULLS / operator class), column order, index method or index-level operator class that distinguish them. `\n\t\t\t\t\t+ `Drop the obsolete index manually.`,\n\t\t\t)\n\t\t}\n\n\t\tfor (const name of indexNames) {\n\t\t\tbuilder.sql(`DROP INDEX ${wrapIdentifier(name)}`)\n\t\t}\n\t\tinvalidateDatabaseMetadata()\n\t}\n\n\tpublic getSchemaUpdater(): SchemaUpdater {\n\t\tconst index = this.getIndex()\n\t\treturn updateModel(\n\t\t\tupdateEntity(this.data.entityName, ({ entity }) => {\n\t\t\t\tconst indexes = entity.indexes.filter(it => !indexIdentityEquals(it, index))\n\t\t\t\treturn {\n\t\t\t\t\t...entity,\n\t\t\t\t\tindexes,\n\t\t\t\t}\n\t\t\t}),\n\t\t)\n\t}\n\n\tdescribe() {\n\t\tconst index = this.getIndex()\n\t\treturn { message: `Remove index (${index.fields.join(', ')}) on entity ${this.data.entityName}` }\n\t}\n\n\tprivate getIndex(): IndexIdentity {\n\t\tconst { entityName } = this.data\n\t\tconst entity = this.schema.model.entities[entityName]\n\t\tif ('indexName' in this.data && this.data.indexName !== undefined) {\n\t\t\tconst index = entity.indexes.find(it => it.name === this.data.indexName)\n\t\t\tif (!index) {\n\t\t\t\tthrow new Error(`Index named \"${this.data.indexName}\" not found on entity ${entityName}`)\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tfields: index.fields,\n\t\t\t\twhere: index.where,\n\t\t\t\tinclude: index.include,\n\t\t\t\tcolumnOptions: index.columnOptions,\n\t\t\t\tmethod: index.method,\n\t\t\t\topClass: index.opClass,\n\t\t\t}\n\t\t}\n\t\tif (!this.data.fields) {\n\t\t\tthrow new Error(`removeIndex modification on entity ${entityName} requires either \"indexName\" or \"fields\"`)\n\t\t}\n\t\treturn {\n\t\t\tfields: this.data.fields,\n\t\t\twhere: this.data.where,\n\t\t\tinclude: this.data.include,\n\t\t\tcolumnOptions: this.data.columnOptions,\n\t\t\tmethod: this.data.method,\n\t\t\topClass: this.data.opClass,\n\t\t}\n\t}\n}\n\nexport const removeIndexModification = createModificationType({\n\tid: 'removeIndex',\n\thandler: RemoveIndexModificationHandler,\n})\n\nexport type RemoveIndexModificationData =\n\t| {\n\t\tentityName: string\n\t\tindexName: string\n\t\tfields?: never\n\t\twhere?: never\n\t\tinclude?: never\n\t\tcolumnOptions?: never\n\t\tmethod?: never\n\t\topClass?: never\n\t}\n\t| {\n\t\tentityName: string\n\t\tfields: readonly string[]\n\t\twhere?: string\n\t\tinclude?: readonly string[]\n\t\tcolumnOptions?: { readonly [field: string]: Model.IndexColumnOptions }\n\t\tmethod?: Model.IndexMethod\n\t\topClass?: string\n\t\tindexName?: never\n\t}\n\nexport class RemoveIndexDiffer implements Differ {\n\tcreateDiff(originalSchema: Schema, updatedSchema: Schema) {\n\t\treturn Object.values(originalSchema.model.entities).flatMap(entity =>\n\t\t\tentity.indexes\n\t\t\t\t.filter(\n\t\t\t\t\tit => {\n\t\t\t\t\t\tconst updatedEntity = updatedSchema.model.entities[entity.name]\n\t\t\t\t\t\tif (!updatedEntity) {\n\t\t\t\t\t\t\treturn false\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn !updatedEntity.indexes.find(index => deepEqual(index, it))\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t\t.map(index =>\n\t\t\t\t\tremoveIndexModification.createModification({\n\t\t\t\t\t\tentityName: entity.name,\n\t\t\t\t\t\tfields: index.fields,\n\t\t\t\t\t\t// keep every identity-bearing option (WHERE/INCLUDE/columnOptions/method/opClass) in the\n\t\t\t\t\t\t// modification so indexes that share the same key columns but differ by any of them are\n\t\t\t\t\t\t// removed individually; omit the keys when absent to keep legacy migration JSON\n\t\t\t\t\t\t// byte-for-byte identical.\n\t\t\t\t\t\t...(index.where !== undefined ? { where: index.where } : {}),\n\t\t\t\t\t\t...(index.include !== undefined ? { include: index.include } : {}),\n\t\t\t\t\t\t...(index.columnOptions !== undefined ? { columnOptions: index.columnOptions } : {}),\n\t\t\t\t\t\t...(index.method !== undefined ? { method: index.method } : {}),\n\t\t\t\t\t\t...(index.opClass !== undefined ? { opClass: index.opClass } : {}),\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t)\n\t}\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,140 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const schema = require("@contember/schema");
4
+ const schemaUpdateUtils = require("../utils/schemaUpdateUtils.cjs");
5
+ const ModificationHandler = require("../ModificationHandler.cjs");
6
+ const sqlUpdateUtils = require("../utils/sqlUpdateUtils.cjs");
7
+ const columnUtils = require("../utils/columnUtils.cjs");
8
+ const dbHelpers = require("../../utils/dbHelpers.cjs");
9
+ const ModificationVersions = require("../ModificationVersions.cjs");
10
+ class ConvertManyHasManyToJoiningEntityModificationHandler {
11
+ constructor(data, schema2, options) {
12
+ this.data = data;
13
+ this.schema = schema2;
14
+ this.options = options;
15
+ }
16
+ createSql(builder, { systemSchema }) {
17
+ const { relation } = this.getRelation();
18
+ const joiningTable = relation.joiningTable;
19
+ const tableName = joiningTable.tableName;
20
+ const tableNameId = dbHelpers.wrapIdentifier(tableName);
21
+ const joiningEntity = this.data.joiningEntity;
22
+ const primaryColumn = joiningEntity.fields[joiningEntity.primary];
23
+ const primaryColumnName = primaryColumn.columnName;
24
+ const primaryColumnNameId = dbHelpers.wrapIdentifier(primaryColumnName);
25
+ const primaryColumnType = columnUtils.getColumnSqlType(primaryColumn);
26
+ if (joiningTable.eventLog.enabled) {
27
+ sqlUpdateUtils.dropEventTrigger(builder, tableName);
28
+ sqlUpdateUtils.dropEventTrxTrigger(builder, tableName);
29
+ }
30
+ builder.sql(`ALTER TABLE ${tableNameId} ADD COLUMN ${primaryColumnNameId} ${primaryColumnType}`);
31
+ builder.sql(ensureUuidGenerator(systemSchema));
32
+ builder.sql(`UPDATE ${tableNameId} SET ${primaryColumnNameId} = ${uuidGenerator(systemSchema)}`);
33
+ builder.sql(`ALTER TABLE ${tableNameId} ALTER COLUMN ${primaryColumnNameId} SET NOT NULL`);
34
+ builder.sql(`ALTER TABLE ${tableNameId} DROP CONSTRAINT ${dbHelpers.wrapIdentifier(`${tableName}_pkey`)}`);
35
+ builder.sql(`ALTER TABLE ${tableNameId} ADD PRIMARY KEY (${primaryColumnNameId})`);
36
+ builder.sql(
37
+ `ALTER TABLE ${tableNameId} ADD UNIQUE (${dbHelpers.wrapIdentifier(joiningTable.joiningColumn.columnName)}, ${dbHelpers.wrapIdentifier(joiningTable.inverseJoiningColumn.columnName)})`
38
+ );
39
+ if (joiningEntity.eventLog?.enabled !== false) {
40
+ sqlUpdateUtils.createEventTrigger(builder, systemSchema, tableName, [primaryColumnName]);
41
+ sqlUpdateUtils.createEventTrxTrigger(builder, systemSchema, tableName);
42
+ }
43
+ }
44
+ getSchemaUpdater() {
45
+ const { entity, relation } = this.getRelation();
46
+ const version = this.options.formatVersion ?? ModificationVersions.VERSION_LATEST;
47
+ const joiningEntity = this.data.joiningEntity;
48
+ const joinUniqueConstraint = this.getJoinUniqueConstraint();
49
+ return schemaUpdateUtils.updateSchema(
50
+ // remove the original many-has-many (owning side + inverse side)
51
+ schemaUpdateUtils.removeField(entity.name, relation.name, version),
52
+ // register the new joining entity reusing the junction table
53
+ schemaUpdateUtils.updateModel(({ model }) => ({
54
+ ...model,
55
+ entities: {
56
+ ...model.entities,
57
+ [joiningEntity.name]: {
58
+ eventLog: { enabled: true },
59
+ ...joiningEntity,
60
+ // Keep the schema in sync with the join-uniqueness constraint emitted by createSql.
61
+ unique: [...Object.values(joiningEntity.unique ?? []), joinUniqueConstraint],
62
+ indexes: Object.values(joiningEntity.indexes ?? [])
63
+ }
64
+ }
65
+ })),
66
+ // add inverse one-has-many relations on both connected entities
67
+ this.data.sourceInverseSide ? schemaUpdateUtils.updateModel(schemaUpdateUtils.updateEntity(entity.name, schemaUpdateUtils.addField(this.data.sourceInverseSide))) : void 0,
68
+ this.data.targetInverseSide ? schemaUpdateUtils.updateModel(schemaUpdateUtils.updateEntity(relation.target, schemaUpdateUtils.addField(this.data.targetInverseSide))) : void 0
69
+ );
70
+ }
71
+ describe() {
72
+ return {
73
+ message: `Converts ManyHasMany relation ${this.data.entityName}.${this.data.fieldName} to a joining entity ${this.data.joiningEntity.name}`
74
+ };
75
+ }
76
+ /**
77
+ * The join-uniqueness constraint (relationA, relationB) that replaces the dropped composite
78
+ * primary key. The field names are resolved from the joining entity's two many-has-one relations
79
+ * by matching their joining columns against the original junction columns, so the constraint
80
+ * references schema field names (not raw column names).
81
+ */
82
+ getJoinUniqueConstraint() {
83
+ const { relation } = this.getRelation();
84
+ const joiningTable = relation.joiningTable;
85
+ const joiningEntity = this.data.joiningEntity;
86
+ const findRelationField = (columnName) => {
87
+ const field = Object.values(joiningEntity.fields).find(
88
+ (it) => "joiningColumn" in it && it.joiningColumn.columnName === columnName
89
+ );
90
+ if (!field) {
91
+ throw new Error(
92
+ `Joining entity ${joiningEntity.name} has no many-has-one relation mapped to column ${columnName}`
93
+ );
94
+ }
95
+ return field.name;
96
+ };
97
+ return {
98
+ fields: [
99
+ findRelationField(joiningTable.joiningColumn.columnName),
100
+ findRelationField(joiningTable.inverseJoiningColumn.columnName)
101
+ ]
102
+ };
103
+ }
104
+ getRelation() {
105
+ const entity = this.schema.model.entities[this.data.entityName];
106
+ const relation = entity.fields[this.data.fieldName];
107
+ if (!relation || relation.type !== schema.Model.RelationType.ManyHasMany || !("joiningTable" in relation)) {
108
+ throw new Error(`${this.data.entityName}.${this.data.fieldName} is not a many-has-many owning relation`);
109
+ }
110
+ return { entity, relation };
111
+ }
112
+ }
113
+ const uuidGenerator = (systemSchema) => `${dbHelpers.wrapIdentifier(systemSchema)}."uuid_generate_v4"()`;
114
+ const ensureUuidGenerator = (systemSchema) => {
115
+ const systemSchemaId = dbHelpers.wrapIdentifier(systemSchema);
116
+ return `DO $ensure_uuid$
117
+ BEGIN
118
+ IF NOT EXISTS(
119
+ SELECT FROM pg_proc
120
+ JOIN pg_namespace ON pg_proc.pronamespace = pg_namespace.oid
121
+ WHERE pg_namespace.nspname = ${quoteLiteral(systemSchema)} AND pg_proc.proname = 'uuid_generate_v4'
122
+ ) THEN
123
+ CREATE FUNCTION ${systemSchemaId}."uuid_generate_v4"() RETURNS "uuid"
124
+ LANGUAGE "sql"
125
+ AS $ensure_uuid_body$
126
+ SELECT OVERLAY(OVERLAY(md5(random()::TEXT || ':' || clock_timestamp()::TEXT) PLACING '4' FROM 13) PLACING
127
+ to_hex(floor(random() * (11 - 8 + 1) + 8)::INT)::TEXT FROM 17)::UUID;
128
+ $ensure_uuid_body$;
129
+ END IF;
130
+ END
131
+ $ensure_uuid$;`;
132
+ };
133
+ const quoteLiteral = (value) => `'${value.replace(/'/g, "''")}'`;
134
+ const convertManyHasManyToJoiningEntityModification = ModificationHandler.createModificationType({
135
+ id: "convertManyHasManyToJoiningEntity",
136
+ handler: ConvertManyHasManyToJoiningEntityModificationHandler
137
+ });
138
+ exports.ConvertManyHasManyToJoiningEntityModificationHandler = ConvertManyHasManyToJoiningEntityModificationHandler;
139
+ exports.convertManyHasManyToJoiningEntityModification = convertManyHasManyToJoiningEntityModification;
140
+ //# sourceMappingURL=ConvertManyHasManyToJoiningEntityModification.cjs.map