@contember/engine-content-api 1.2.0-alpha.9 → 1.2.0-beta.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 (378) hide show
  1. package/dist/src/acl/EvaluatedPredicateReplacer.d.ts +2 -3
  2. package/dist/src/acl/EvaluatedPredicateReplacer.d.ts.map +1 -1
  3. package/dist/src/acl/EvaluatedPredicateReplacer.js +5 -14
  4. package/dist/src/acl/EvaluatedPredicateReplacer.js.map +1 -1
  5. package/dist/src/acl/PredicateFactory.d.ts +9 -3
  6. package/dist/src/acl/PredicateFactory.d.ts.map +1 -1
  7. package/dist/src/acl/PredicateFactory.js +47 -36
  8. package/dist/src/acl/PredicateFactory.js.map +1 -1
  9. package/dist/src/acl/PredicatesInjector.d.ts +1 -1
  10. package/dist/src/acl/PredicatesInjector.d.ts.map +1 -1
  11. package/dist/src/acl/PredicatesInjector.js +13 -18
  12. package/dist/src/acl/PredicatesInjector.js.map +1 -1
  13. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducerExecutionHandler.d.ts +0 -1
  14. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducerExecutionHandler.d.ts.map +1 -1
  15. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducerExecutionHandler.js +26 -23
  16. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducerExecutionHandler.js.map +1 -1
  17. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.d.ts +1 -1
  18. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.d.ts.map +1 -1
  19. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.js +1 -1
  20. package/dist/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.js.map +1 -1
  21. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyCountVisitor.d.ts +5 -4
  22. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyCountVisitor.d.ts.map +1 -1
  23. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyCountVisitor.js +11 -14
  24. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyCountVisitor.js.map +1 -1
  25. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyExecutionHandler.d.ts.map +1 -1
  26. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyExecutionHandler.js +18 -14
  27. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyExecutionHandler.js.map +1 -1
  28. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.d.ts +3 -3
  29. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.d.ts.map +1 -1
  30. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.js +3 -3
  31. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.js.map +1 -1
  32. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyNodesVisitor.d.ts +5 -4
  33. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyNodesVisitor.d.ts.map +1 -1
  34. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyNodesVisitor.js +11 -15
  35. package/dist/src/extensions/paginatedHasMany/PaginatedHasManyNodesVisitor.js.map +1 -1
  36. package/dist/src/input-validation/ColumnValueResolver.d.ts +4 -3
  37. package/dist/src/input-validation/ColumnValueResolver.d.ts.map +1 -1
  38. package/dist/src/input-validation/ColumnValueResolver.js.map +1 -1
  39. package/dist/src/input-validation/EntityRulesResolver.js +4 -4
  40. package/dist/src/input-validation/EntityRulesResolver.js.map +1 -1
  41. package/dist/src/input-validation/QueryAstFactory.js +1 -1
  42. package/dist/src/input-validation/QueryAstFactory.js.map +1 -1
  43. package/dist/src/input-validation/ValidationDataSelector.js +1 -1
  44. package/dist/src/input-validation/ValidationDataSelector.js.map +1 -1
  45. package/dist/src/input-validation/preValidation/CreateInputPreValidationProcessor.d.ts +7 -8
  46. package/dist/src/input-validation/preValidation/CreateInputPreValidationProcessor.d.ts.map +1 -1
  47. package/dist/src/input-validation/preValidation/CreateInputPreValidationProcessor.js.map +1 -1
  48. package/dist/src/input-validation/preValidation/InputPreValidator.js +4 -4
  49. package/dist/src/input-validation/preValidation/InputPreValidator.js.map +1 -1
  50. package/dist/src/input-validation/preValidation/UpdateInputPreValidationProcessor.d.ts +7 -8
  51. package/dist/src/input-validation/preValidation/UpdateInputPreValidationProcessor.d.ts.map +1 -1
  52. package/dist/src/input-validation/preValidation/UpdateInputPreValidationProcessor.js.map +1 -1
  53. package/dist/src/inputProcessing/CreateInputProcessor.d.ts +8 -9
  54. package/dist/src/inputProcessing/CreateInputProcessor.d.ts.map +1 -1
  55. package/dist/src/inputProcessing/CreateInputVisitor.d.ts +7 -7
  56. package/dist/src/inputProcessing/CreateInputVisitor.d.ts.map +1 -1
  57. package/dist/src/inputProcessing/CreateInputVisitor.js +15 -46
  58. package/dist/src/inputProcessing/CreateInputVisitor.js.map +1 -1
  59. package/dist/src/inputProcessing/UpdateInputProcessor.d.ts +8 -9
  60. package/dist/src/inputProcessing/UpdateInputProcessor.d.ts.map +1 -1
  61. package/dist/src/inputProcessing/UpdateInputVisitor.d.ts +7 -7
  62. package/dist/src/inputProcessing/UpdateInputVisitor.d.ts.map +1 -1
  63. package/dist/src/inputProcessing/UpdateInputVisitor.js +13 -28
  64. package/dist/src/inputProcessing/UpdateInputVisitor.js.map +1 -1
  65. package/dist/src/inputProcessing/index.d.ts +0 -1
  66. package/dist/src/inputProcessing/index.d.ts.map +1 -1
  67. package/dist/src/inputProcessing/index.js +0 -1
  68. package/dist/src/inputProcessing/index.js.map +1 -1
  69. package/dist/src/introspection/IntrospectionSchemaFactory.js +7 -7
  70. package/dist/src/introspection/IntrospectionSchemaFactory.js.map +1 -1
  71. package/dist/src/mapper/ErrorUtils.d.ts.map +1 -1
  72. package/dist/src/mapper/ErrorUtils.js +2 -2
  73. package/dist/src/mapper/ErrorUtils.js.map +1 -1
  74. package/dist/src/mapper/JunctionTableManager.js.map +1 -1
  75. package/dist/src/mapper/Mapper.d.ts +6 -6
  76. package/dist/src/mapper/Mapper.d.ts.map +1 -1
  77. package/dist/src/mapper/Mapper.js +26 -21
  78. package/dist/src/mapper/Mapper.js.map +1 -1
  79. package/dist/src/mapper/MapperContainer.d.ts.map +1 -1
  80. package/dist/src/mapper/MapperContainer.js +4 -4
  81. package/dist/src/mapper/MapperContainer.js.map +1 -1
  82. package/dist/src/mapper/Result.d.ts.map +1 -1
  83. package/dist/src/mapper/Result.js +2 -4
  84. package/dist/src/mapper/Result.js.map +1 -1
  85. package/dist/src/mapper/delete/DeleteExecutor.js +6 -6
  86. package/dist/src/mapper/delete/DeleteExecutor.js.map +1 -1
  87. package/dist/src/mapper/insert/InsertBuilder.d.ts +1 -1
  88. package/dist/src/mapper/insert/InsertBuilder.d.ts.map +1 -1
  89. package/dist/src/mapper/insert/InsertBuilder.js.map +1 -1
  90. package/dist/src/mapper/insert/SqlCreateInputProcessor.d.ts +4 -2
  91. package/dist/src/mapper/insert/SqlCreateInputProcessor.d.ts.map +1 -1
  92. package/dist/src/mapper/insert/SqlCreateInputProcessor.js.map +1 -1
  93. package/dist/src/mapper/select/JoinVisitor.d.ts +6 -6
  94. package/dist/src/mapper/select/JoinVisitor.d.ts.map +1 -1
  95. package/dist/src/mapper/select/JoinVisitor.js +6 -6
  96. package/dist/src/mapper/select/JoinVisitor.js.map +1 -1
  97. package/dist/src/mapper/select/Path.d.ts +1 -0
  98. package/dist/src/mapper/select/Path.d.ts.map +1 -1
  99. package/dist/src/mapper/select/Path.js +4 -1
  100. package/dist/src/mapper/select/Path.js.map +1 -1
  101. package/dist/src/mapper/select/RelationFetcher.d.ts +11 -19
  102. package/dist/src/mapper/select/RelationFetcher.d.ts.map +1 -1
  103. package/dist/src/mapper/select/RelationFetcher.js +34 -25
  104. package/dist/src/mapper/select/RelationFetcher.js.map +1 -1
  105. package/dist/src/mapper/select/SelectBuilder.d.ts +4 -1
  106. package/dist/src/mapper/select/SelectBuilder.d.ts.map +1 -1
  107. package/dist/src/mapper/select/SelectBuilder.js +52 -12
  108. package/dist/src/mapper/select/SelectBuilder.js.map +1 -1
  109. package/dist/src/mapper/select/SelectBuilderFactory.d.ts +2 -1
  110. package/dist/src/mapper/select/SelectBuilderFactory.d.ts.map +1 -1
  111. package/dist/src/mapper/select/SelectExecutionHandler.d.ts +16 -4
  112. package/dist/src/mapper/select/SelectExecutionHandler.d.ts.map +1 -1
  113. package/dist/src/mapper/select/SelectHydrator.d.ts +3 -2
  114. package/dist/src/mapper/select/SelectHydrator.d.ts.map +1 -1
  115. package/dist/src/mapper/select/SelectHydrator.js +6 -9
  116. package/dist/src/mapper/select/SelectHydrator.js.map +1 -1
  117. package/dist/src/mapper/select/WhereBuilder.d.ts +8 -4
  118. package/dist/src/mapper/select/WhereBuilder.d.ts.map +1 -1
  119. package/dist/src/mapper/select/WhereBuilder.js +137 -35
  120. package/dist/src/mapper/select/WhereBuilder.js.map +1 -1
  121. package/dist/src/mapper/select/handlers/FieldsVisitor.d.ts +10 -8
  122. package/dist/src/mapper/select/handlers/FieldsVisitor.d.ts.map +1 -1
  123. package/dist/src/mapper/select/handlers/FieldsVisitor.js +129 -94
  124. package/dist/src/mapper/select/handlers/FieldsVisitor.js.map +1 -1
  125. package/dist/src/mapper/select/handlers/FieldsVisitorFactory.d.ts.map +1 -1
  126. package/dist/src/mapper/select/handlers/FieldsVisitorFactory.js +1 -1
  127. package/dist/src/mapper/select/handlers/FieldsVisitorFactory.js.map +1 -1
  128. package/dist/src/mapper/select/handlers/MetaHandler.d.ts.map +1 -1
  129. package/dist/src/mapper/select/handlers/MetaHandler.js +6 -11
  130. package/dist/src/mapper/select/handlers/MetaHandler.js.map +1 -1
  131. package/dist/src/mapper/select/optimizer/ConditionOptimizer.d.ts.map +1 -1
  132. package/dist/src/mapper/select/optimizer/ConditionOptimizer.js +6 -0
  133. package/dist/src/mapper/select/optimizer/ConditionOptimizer.js.map +1 -1
  134. package/dist/src/mapper/select/optimizer/WhereOptimizer.d.ts +9 -1
  135. package/dist/src/mapper/select/optimizer/WhereOptimizer.d.ts.map +1 -1
  136. package/dist/src/mapper/select/optimizer/WhereOptimizer.js +127 -13
  137. package/dist/src/mapper/select/optimizer/WhereOptimizer.js.map +1 -1
  138. package/dist/src/mapper/select/optimizer/WhereReplacer.d.ts +3 -0
  139. package/dist/src/mapper/select/optimizer/WhereReplacer.d.ts.map +1 -0
  140. package/dist/src/mapper/select/optimizer/WhereReplacer.js +46 -0
  141. package/dist/src/mapper/select/optimizer/WhereReplacer.js.map +1 -0
  142. package/dist/src/mapper/select/optimizer/helpers.d.ts +1 -1
  143. package/dist/src/mapper/select/optimizer/helpers.js +1 -1
  144. package/dist/src/mapper/select/optimizer/helpers.js.map +1 -1
  145. package/dist/src/mapper/update/SqlUpdateInputProcessor.d.ts +2 -3
  146. package/dist/src/mapper/update/SqlUpdateInputProcessor.d.ts.map +1 -1
  147. package/dist/src/mapper/update/SqlUpdateInputProcessor.js +3 -4
  148. package/dist/src/mapper/update/SqlUpdateInputProcessor.js.map +1 -1
  149. package/dist/src/mapper/update/UpdateBuilder.js +3 -3
  150. package/dist/src/mapper/update/UpdateBuilder.js.map +1 -1
  151. package/dist/src/resolvers/ExecutionContainerFactory.d.ts +1 -1
  152. package/dist/src/resolvers/ExecutionContainerFactory.d.ts.map +1 -1
  153. package/dist/src/resolvers/GraphQlQueryAstFactory.d.ts +1 -2
  154. package/dist/src/resolvers/GraphQlQueryAstFactory.d.ts.map +1 -1
  155. package/dist/src/resolvers/GraphQlQueryAstFactory.js +2 -2
  156. package/dist/src/resolvers/GraphQlQueryAstFactory.js.map +1 -1
  157. package/dist/src/resolvers/MutationResolver.d.ts.map +1 -1
  158. package/dist/src/resolvers/MutationResolver.js +13 -2
  159. package/dist/src/resolvers/MutationResolver.js.map +1 -1
  160. package/dist/src/resolvers/ReadHelpers.js +3 -3
  161. package/dist/src/resolvers/ReadHelpers.js.map +1 -1
  162. package/dist/src/resolvers/ReadResolver.js +2 -2
  163. package/dist/src/resolvers/ReadResolver.js.map +1 -1
  164. package/dist/src/schema/EnumsProvider.d.ts.map +1 -1
  165. package/dist/src/schema/EnumsProvider.js +1 -2
  166. package/dist/src/schema/EnumsProvider.js.map +1 -1
  167. package/dist/src/schema/FieldAccessVisitor.d.ts +2 -2
  168. package/dist/src/schema/FieldAccessVisitor.d.ts.map +1 -1
  169. package/dist/src/schema/FieldAccessVisitor.js +2 -2
  170. package/dist/src/schema/FieldAccessVisitor.js.map +1 -1
  171. package/dist/src/schema/OrderByTypeProvider.d.ts +1 -1
  172. package/dist/src/schema/OrderByTypeProvider.d.ts.map +1 -1
  173. package/dist/src/schema/OrderByTypeProvider.js +2 -2
  174. package/dist/src/schema/OrderByTypeProvider.js.map +1 -1
  175. package/dist/src/schema/WhereTypeProvider.d.ts +1 -2
  176. package/dist/src/schema/WhereTypeProvider.d.ts.map +1 -1
  177. package/dist/src/schema/WhereTypeProvider.js +4 -4
  178. package/dist/src/schema/WhereTypeProvider.js.map +1 -1
  179. package/dist/src/schema/entities/FieldArgsVisitor.d.ts +4 -5
  180. package/dist/src/schema/entities/FieldArgsVisitor.d.ts.map +1 -1
  181. package/dist/src/schema/entities/FieldArgsVisitor.js +3 -3
  182. package/dist/src/schema/entities/FieldArgsVisitor.js.map +1 -1
  183. package/dist/src/schema/entities/FieldTypeVisitor.d.ts +3 -3
  184. package/dist/src/schema/entities/FieldTypeVisitor.d.ts.map +1 -1
  185. package/dist/src/schema/entities/FieldTypeVisitor.js +3 -3
  186. package/dist/src/schema/entities/FieldTypeVisitor.js.map +1 -1
  187. package/dist/src/schema/mutations/CreateEntityInputFieldVisitor.d.ts +3 -3
  188. package/dist/src/schema/mutations/CreateEntityInputFieldVisitor.d.ts.map +1 -1
  189. package/dist/src/schema/mutations/CreateEntityInputFieldVisitor.js +3 -3
  190. package/dist/src/schema/mutations/CreateEntityInputFieldVisitor.js.map +1 -1
  191. package/dist/src/schema/mutations/CreateEntityRelationAllowedOperationsVisitor.d.ts +6 -6
  192. package/dist/src/schema/mutations/CreateEntityRelationAllowedOperationsVisitor.d.ts.map +1 -1
  193. package/dist/src/schema/mutations/CreateEntityRelationAllowedOperationsVisitor.js +6 -6
  194. package/dist/src/schema/mutations/CreateEntityRelationAllowedOperationsVisitor.js.map +1 -1
  195. package/dist/src/schema/mutations/CreateEntityRelationInputFieldVisitor.d.ts +3 -3
  196. package/dist/src/schema/mutations/CreateEntityRelationInputFieldVisitor.d.ts.map +1 -1
  197. package/dist/src/schema/mutations/CreateEntityRelationInputFieldVisitor.js +5 -5
  198. package/dist/src/schema/mutations/CreateEntityRelationInputFieldVisitor.js.map +1 -1
  199. package/dist/src/schema/mutations/UpdateEntityInputFieldVisitor.d.ts +10 -4
  200. package/dist/src/schema/mutations/UpdateEntityInputFieldVisitor.d.ts.map +1 -1
  201. package/dist/src/schema/mutations/UpdateEntityInputFieldVisitor.js +3 -3
  202. package/dist/src/schema/mutations/UpdateEntityInputFieldVisitor.js.map +1 -1
  203. package/dist/src/schema/mutations/UpdateEntityRelationAllowedOperationsVisitor.d.ts +6 -6
  204. package/dist/src/schema/mutations/UpdateEntityRelationAllowedOperationsVisitor.d.ts.map +1 -1
  205. package/dist/src/schema/mutations/UpdateEntityRelationAllowedOperationsVisitor.js +6 -6
  206. package/dist/src/schema/mutations/UpdateEntityRelationAllowedOperationsVisitor.js.map +1 -1
  207. package/dist/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.d.ts +2 -2
  208. package/dist/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.d.ts.map +1 -1
  209. package/dist/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.js +2 -2
  210. package/dist/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.js.map +1 -1
  211. package/dist/src/schema/utils.d.ts +1 -1
  212. package/dist/src/schema/utils.d.ts.map +1 -1
  213. package/dist/src/tsconfig.tsbuildinfo +1 -1
  214. package/dist/src/utils/uniqueWhereFields.js +3 -3
  215. package/dist/src/utils/uniqueWhereFields.js.map +1 -1
  216. package/dist/tests/cases/bugs/bug102.test.js +6 -6
  217. package/dist/tests/cases/bugs/bug102.test.js.map +1 -1
  218. package/dist/tests/cases/integration/graphQlRequests/delete/aclDelete.test.js +5 -5
  219. package/dist/tests/cases/integration/graphQlRequests/delete/aclDelete.test.js.map +1 -1
  220. package/dist/tests/cases/integration/graphQlRequests/delete/additionalDeleteFilter.test.js +5 -5
  221. package/dist/tests/cases/integration/graphQlRequests/delete/additionalDeleteFilter.test.js.map +1 -1
  222. package/dist/tests/cases/integration/graphQlRequests/delete/cascadeDelete.test.js +5 -5
  223. package/dist/tests/cases/integration/graphQlRequests/delete/cascadeDelete.test.js.map +1 -1
  224. package/dist/tests/cases/integration/graphQlRequests/delete/deleteById.test.js +5 -5
  225. package/dist/tests/cases/integration/graphQlRequests/delete/deleteById.test.js.map +1 -1
  226. package/dist/tests/cases/integration/graphQlRequests/delete/orphanRemoval.test.js +5 -5
  227. package/dist/tests/cases/integration/graphQlRequests/delete/orphanRemoval.test.js.map +1 -1
  228. package/dist/tests/cases/integration/graphQlRequests/delete/setNullOnDelete.test.js +5 -5
  229. package/dist/tests/cases/integration/graphQlRequests/delete/setNullOnDelete.test.js.map +1 -1
  230. package/dist/tests/cases/integration/graphQlRequests/query/acl/differentRowAndFieldPredicate.test.js +51 -4
  231. package/dist/tests/cases/integration/graphQlRequests/query/acl/differentRowAndFieldPredicate.test.js.map +1 -1
  232. package/dist/tests/cases/integration/graphQlRequests/query/acl/fieldRestrictedByLocale.test.js +26 -25
  233. package/dist/tests/cases/integration/graphQlRequests/query/acl/fieldRestrictedByLocale.test.js.map +1 -1
  234. package/dist/tests/cases/integration/graphQlRequests/query/acl/nestedPredicate.test.js +9 -6
  235. package/dist/tests/cases/integration/graphQlRequests/query/acl/nestedPredicate.test.js.map +1 -1
  236. package/dist/tests/cases/integration/graphQlRequests/query/acl/rowPredicateSubset.test.d.ts +2 -0
  237. package/dist/tests/cases/integration/graphQlRequests/query/acl/rowPredicateSubset.test.d.ts.map +1 -0
  238. package/dist/tests/cases/integration/graphQlRequests/query/acl/rowPredicateSubset.test.js +109 -0
  239. package/dist/tests/cases/integration/graphQlRequests/query/acl/rowPredicateSubset.test.js.map +1 -0
  240. package/dist/tests/cases/integration/graphQlRequests/query/filter/manyHasManyOwnerRelation.test.js +17 -15
  241. package/dist/tests/cases/integration/graphQlRequests/query/filter/manyHasManyOwnerRelation.test.js.map +1 -1
  242. package/dist/tests/cases/integration/graphQlRequests/query/filter/oneHasManyRelation.test.js +4 -5
  243. package/dist/tests/cases/integration/graphQlRequests/query/filter/oneHasManyRelation.test.js.map +1 -1
  244. package/dist/tests/cases/integration/graphQlRequests/query/graphqlFeatures/alias.test.js +9 -13
  245. package/dist/tests/cases/integration/graphQlRequests/query/graphqlFeatures/alias.test.js.map +1 -1
  246. package/dist/tests/cases/integration/graphQlRequests/query/unique/oneHasManyUnique.test.js +5 -3
  247. package/dist/tests/cases/integration/graphQlRequests/query/unique/oneHasManyUnique.test.js.map +1 -1
  248. package/dist/tests/cases/integration/graphQlRequests/update/manyHasManyInverse/delete.test.js +5 -5
  249. package/dist/tests/cases/integration/graphQlRequests/update/manyHasManyInverse/delete.test.js.map +1 -1
  250. package/dist/tests/cases/integration/graphQlRequests/update/manyHasManyOwning/delete.test.js +5 -5
  251. package/dist/tests/cases/integration/graphQlRequests/update/manyHasManyOwning/delete.test.js.map +1 -1
  252. package/dist/tests/cases/integration/graphQlRequests/update/manyHasOne/delete.test.js +10 -10
  253. package/dist/tests/cases/integration/graphQlRequests/update/manyHasOne/delete.test.js.map +1 -1
  254. package/dist/tests/cases/integration/graphQlRequests/update/oneHasMany/combination.test.js +5 -5
  255. package/dist/tests/cases/integration/graphQlRequests/update/oneHasMany/combination.test.js.map +1 -1
  256. package/dist/tests/cases/integration/graphQlRequests/update/oneHasMany/delete.test.js +5 -5
  257. package/dist/tests/cases/integration/graphQlRequests/update/oneHasMany/delete.test.js.map +1 -1
  258. package/dist/tests/cases/integration/graphQlRequests/update/oneHasOneInverse/delete.test.js +5 -5
  259. package/dist/tests/cases/integration/graphQlRequests/update/oneHasOneInverse/delete.test.js.map +1 -1
  260. package/dist/tests/cases/integration/graphQlSchema/graphQlSchemaBuilder.test.js +4 -4
  261. package/dist/tests/cases/integration/graphQlSchema/graphQlSchemaBuilder.test.js.map +1 -1
  262. package/dist/tests/cases/unit/predicatesFactory.test.js +7 -1
  263. package/dist/tests/cases/unit/predicatesFactory.test.js.map +1 -1
  264. package/dist/tests/cases/unit/predicatesInjector.test.js +105 -0
  265. package/dist/tests/cases/unit/predicatesInjector.test.js.map +1 -1
  266. package/dist/tests/cases/unit/whereBuilder.test.d.ts +2 -0
  267. package/dist/tests/cases/unit/whereBuilder.test.d.ts.map +1 -0
  268. package/dist/tests/cases/unit/whereBuilder.test.js +131 -0
  269. package/dist/tests/cases/unit/whereBuilder.test.js.map +1 -0
  270. package/dist/tests/cases/unit/whereOptimizer.test.js +173 -0
  271. package/dist/tests/cases/unit/whereOptimizer.test.js.map +1 -1
  272. package/dist/tests/src/test.js +2 -2
  273. package/dist/tests/src/test.js.map +1 -1
  274. package/dist/tests/src/testGraphql.d.ts.map +1 -1
  275. package/dist/tests/src/testGraphql.js +9 -5
  276. package/dist/tests/src/testGraphql.js.map +1 -1
  277. package/dist/tests/tsconfig.tsbuildinfo +1 -1
  278. package/package.json +12 -10
  279. package/src/acl/EvaluatedPredicateReplacer.ts +9 -15
  280. package/src/acl/PredicateFactory.ts +64 -40
  281. package/src/acl/PredicatesInjector.ts +18 -17
  282. package/src/extensions/hasManyToHasOneReducer/HasManyToHasOneReducerExecutionHandler.ts +21 -28
  283. package/src/extensions/hasManyToHasOneReducer/HasManyToHasOneRelationReducerVisitor.ts +1 -6
  284. package/src/extensions/paginatedHasMany/PaginatedHasManyCountVisitor.ts +10 -28
  285. package/src/extensions/paginatedHasMany/PaginatedHasManyExecutionHandler.ts +11 -8
  286. package/src/extensions/paginatedHasMany/PaginatedHasManyFieldProviderVisitor.ts +4 -22
  287. package/src/extensions/paginatedHasMany/PaginatedHasManyNodesVisitor.ts +10 -29
  288. package/src/input-validation/ColumnValueResolver.ts +2 -3
  289. package/src/input-validation/EntityRulesResolver.ts +4 -4
  290. package/src/input-validation/QueryAstFactory.ts +1 -1
  291. package/src/input-validation/ValidationDataSelector.ts +1 -1
  292. package/src/input-validation/preValidation/CreateInputPreValidationProcessor.ts +7 -8
  293. package/src/input-validation/preValidation/InputPreValidator.ts +4 -4
  294. package/src/input-validation/preValidation/UpdateInputPreValidationProcessor.ts +7 -8
  295. package/src/inputProcessing/CreateInputProcessor.ts +8 -9
  296. package/src/inputProcessing/CreateInputVisitor.ts +27 -89
  297. package/src/inputProcessing/UpdateInputProcessor.ts +8 -9
  298. package/src/inputProcessing/UpdateInputVisitor.ts +25 -71
  299. package/src/inputProcessing/index.ts +0 -1
  300. package/src/introspection/IntrospectionSchemaFactory.ts +7 -7
  301. package/src/mapper/ErrorUtils.ts +2 -2
  302. package/src/mapper/JunctionTableManager.ts +3 -3
  303. package/src/mapper/Mapper.ts +34 -31
  304. package/src/mapper/MapperContainer.ts +7 -5
  305. package/src/mapper/Result.ts +2 -4
  306. package/src/mapper/delete/DeleteExecutor.ts +6 -6
  307. package/src/mapper/insert/InsertBuilder.ts +2 -2
  308. package/src/mapper/insert/SqlCreateInputProcessor.ts +3 -3
  309. package/src/mapper/select/JoinVisitor.ts +6 -33
  310. package/src/mapper/select/Path.ts +4 -1
  311. package/src/mapper/select/RelationFetcher.ts +49 -50
  312. package/src/mapper/select/SelectBuilder.ts +71 -13
  313. package/src/mapper/select/SelectBuilderFactory.ts +2 -1
  314. package/src/mapper/select/SelectExecutionHandler.ts +16 -8
  315. package/src/mapper/select/SelectHydrator.ts +15 -11
  316. package/src/mapper/select/WhereBuilder.ts +168 -61
  317. package/src/mapper/select/handlers/FieldsVisitor.ts +80 -111
  318. package/src/mapper/select/handlers/FieldsVisitorFactory.ts +1 -0
  319. package/src/mapper/select/handlers/MetaHandler.ts +6 -17
  320. package/src/mapper/select/optimizer/ConditionOptimizer.ts +6 -0
  321. package/src/mapper/select/optimizer/WhereOptimizer.ts +148 -21
  322. package/src/mapper/select/optimizer/WhereReplacer.ts +39 -0
  323. package/src/mapper/select/optimizer/helpers.ts +2 -2
  324. package/src/mapper/update/SqlUpdateInputProcessor.ts +4 -10
  325. package/src/mapper/update/UpdateBuilder.ts +3 -3
  326. package/src/resolvers/ExecutionContainerFactory.ts +1 -1
  327. package/src/resolvers/GraphQlQueryAstFactory.ts +5 -4
  328. package/src/resolvers/MutationResolver.ts +14 -4
  329. package/src/resolvers/ReadHelpers.ts +3 -3
  330. package/src/resolvers/ReadResolver.ts +2 -2
  331. package/src/schema/EnumsProvider.ts +2 -4
  332. package/src/schema/FieldAccessVisitor.ts +2 -2
  333. package/src/schema/OrderByTypeProvider.ts +10 -3
  334. package/src/schema/WhereTypeProvider.ts +5 -6
  335. package/src/schema/entities/FieldArgsVisitor.ts +4 -5
  336. package/src/schema/entities/FieldTypeVisitor.ts +3 -3
  337. package/src/schema/mutations/CreateEntityInputFieldVisitor.ts +3 -6
  338. package/src/schema/mutations/CreateEntityRelationAllowedOperationsVisitor.ts +6 -20
  339. package/src/schema/mutations/CreateEntityRelationInputFieldVisitor.ts +6 -20
  340. package/src/schema/mutations/UpdateEntityInputFieldVisitor.ts +3 -6
  341. package/src/schema/mutations/UpdateEntityRelationAllowedOperationsVisitor.ts +6 -20
  342. package/src/schema/mutations/UpdateEntityRelationInputFieldVisitor.ts +9 -14
  343. package/src/schema/utils.ts +1 -1
  344. package/src/tsconfig.json +6 -6
  345. package/src/utils/uniqueWhereFields.ts +3 -3
  346. package/tests/cases/bugs/bug102.test.ts +6 -6
  347. package/tests/cases/integration/graphQlRequests/delete/aclDelete.test.ts +5 -5
  348. package/tests/cases/integration/graphQlRequests/delete/additionalDeleteFilter.test.ts +5 -5
  349. package/tests/cases/integration/graphQlRequests/delete/cascadeDelete.test.ts +5 -5
  350. package/tests/cases/integration/graphQlRequests/delete/deleteById.test.ts +5 -5
  351. package/tests/cases/integration/graphQlRequests/delete/orphanRemoval.test.ts +5 -5
  352. package/tests/cases/integration/graphQlRequests/delete/setNullOnDelete.test.ts +5 -5
  353. package/tests/cases/integration/graphQlRequests/query/acl/differentRowAndFieldPredicate.test.ts +54 -4
  354. package/tests/cases/integration/graphQlRequests/query/acl/fieldRestrictedByLocale.test.ts +26 -25
  355. package/tests/cases/integration/graphQlRequests/query/acl/nestedPredicate.test.ts +9 -6
  356. package/tests/cases/integration/graphQlRequests/query/acl/rowPredicateSubset.test.ts +104 -0
  357. package/tests/cases/integration/graphQlRequests/query/filter/manyHasManyOwnerRelation.test.ts +17 -15
  358. package/tests/cases/integration/graphQlRequests/query/filter/oneHasManyRelation.test.ts +4 -5
  359. package/tests/cases/integration/graphQlRequests/query/graphqlFeatures/alias.test.ts +9 -13
  360. package/tests/cases/integration/graphQlRequests/query/unique/oneHasManyUnique.test.ts +5 -3
  361. package/tests/cases/integration/graphQlRequests/update/manyHasManyInverse/delete.test.ts +5 -5
  362. package/tests/cases/integration/graphQlRequests/update/manyHasManyOwning/delete.test.ts +5 -5
  363. package/tests/cases/integration/graphQlRequests/update/manyHasOne/delete.test.ts +10 -10
  364. package/tests/cases/integration/graphQlRequests/update/oneHasMany/combination.test.ts +5 -5
  365. package/tests/cases/integration/graphQlRequests/update/oneHasMany/delete.test.ts +5 -5
  366. package/tests/cases/integration/graphQlRequests/update/oneHasOneInverse/delete.test.ts +5 -5
  367. package/tests/cases/integration/graphQlSchema/graphQlSchemaBuilder.test.ts +2 -3
  368. package/tests/cases/unit/predicatesFactory.test.ts +8 -2
  369. package/tests/cases/unit/predicatesInjector.test.ts +97 -2
  370. package/tests/cases/unit/whereBuilder.test.ts +148 -0
  371. package/tests/cases/unit/whereOptimizer.test.ts +199 -0
  372. package/tests/src/test.ts +2 -2
  373. package/tests/src/testGraphql.ts +9 -5
  374. package/dist/src/inputProcessing/InputContext.d.ts +0 -43
  375. package/dist/src/inputProcessing/InputContext.d.ts.map +0 -1
  376. package/dist/src/inputProcessing/InputContext.js +0 -3
  377. package/dist/src/inputProcessing/InputContext.js.map +0 -1
  378. package/src/inputProcessing/InputContext.ts +0 -49
@@ -1,6 +1,6 @@
1
- import { Input, Model } from '@contember/schema'
1
+ import { Acl, Input, Model } from '@contember/schema'
2
2
  import { acceptFieldVisitor, getColumnName } from '@contember/schema-utils'
3
- import { SelectHydrator, SelectRow } from './SelectHydrator'
3
+ import { ColumnValueGetter, SelectHydrator, SelectRow } from './SelectHydrator'
4
4
  import { Path, PathFactory } from './Path'
5
5
  import { WhereBuilder } from './WhereBuilder'
6
6
  import { Client, LimitByGroupWrapper, SelectBuilder as DbSelectBuilder } from '@contember/database'
@@ -11,6 +11,7 @@ import { MetaHandler } from './handlers'
11
11
  import { Mapper } from '../Mapper'
12
12
  import { FieldNode, ObjectNode } from '../../inputProcessing'
13
13
  import { assertNever } from '../../utils'
14
+ import { PredicateFactory } from '../../acl'
14
15
 
15
16
  export class SelectBuilder {
16
17
  private resolver: (value: SelectRow[]) => void = () => {
@@ -30,6 +31,8 @@ export class SelectBuilder {
30
31
  private readonly fieldsVisitorFactory: FieldsVisitorFactory,
31
32
  private readonly selectHandlers: { [key: string]: SelectExecutionHandler<any> },
32
33
  private readonly pathFactory: PathFactory,
34
+ private readonly relationPath: Model.AnyRelationContext[],
35
+ private readonly predicateFactory: PredicateFactory,
33
36
  ) {}
34
37
 
35
38
  public async execute(db: Client): Promise<SelectRow[]> {
@@ -53,7 +56,7 @@ export class SelectBuilder {
53
56
  this.selectInternal(mapper, entity, path, input)
54
57
  const where = input.args.filter
55
58
  if (where) {
56
- this.qb = this.whereBuilder.build(this.qb, entity, path, where)
59
+ this.qb = this.whereBuilder.build(this.qb, entity, path, where, { relationPath: this.relationPath })
57
60
  }
58
61
  const orderBy = input.args.orderBy || []
59
62
 
@@ -83,6 +86,40 @@ export class SelectBuilder {
83
86
  input = input.withField(new FieldNode(entity.primary, entity.primary, {}))
84
87
  }
85
88
 
89
+ const fetchedPredicates = new Set()
90
+ const addPredicate = (predicate: Acl.Predicate): ColumnValueGetter<boolean> => {
91
+ if (typeof predicate === 'boolean') {
92
+ return () => predicate
93
+ }
94
+ const predicatePath = path.for('__predicate').for(predicate)
95
+
96
+ if (!fetchedPredicates.has(predicate)) {
97
+ const relationContext = this.relationPath[this.relationPath.length - 1]
98
+
99
+ const primaryPredicate = this.predicateFactory.create(entity, Acl.Operation.read, undefined, relationContext)
100
+ const fieldPredicate = this.predicateFactory.buildPredicates(entity, [predicate], relationContext)
101
+
102
+ this.qb = this.whereBuilder.buildAdvanced(
103
+ entity,
104
+ path.back(),
105
+ fieldPredicate,
106
+ apply => this.qb.select(expr =>
107
+ expr.selectCondition(condition => {
108
+ condition = apply(condition)
109
+ if (condition.isEmpty()) {
110
+ return condition.raw('true')
111
+ }
112
+ return condition
113
+ }),
114
+ predicatePath.alias,
115
+ ),
116
+ { relationPath: this.relationPath, evaluatedPredicates: [primaryPredicate] },
117
+ )
118
+ fetchedPredicates.add(predicate)
119
+ }
120
+ return row => row[predicatePath.alias] === true
121
+ }
122
+
86
123
  for (let field of input.fields) {
87
124
  const fieldPath = path.for(field.alias)
88
125
  const fieldProperty = (() => {
@@ -94,19 +131,38 @@ export class SelectBuilder {
94
131
  }
95
132
  return assertNever(field)
96
133
  })()
134
+
135
+
97
136
  const executionContext: SelectExecutionHandlerContext = {
98
137
  mapper,
99
- addData: async (fieldName, cb, defaultValue = null) => {
100
- const columnName = getColumnName(this.schema, entity, fieldName)
101
- const ids = (await this.getColumnValues(path.for(fieldName), columnName)).filter(it => it !== null)
138
+ relationPath: this.relationPath,
139
+ addData: async ({ field, dataProvider, defaultValue, predicate }) => {
140
+ if (predicate === false) {
141
+ this.hydrator.addPromise(fieldPath, path.for(field), Promise.resolve({}), defaultValue ?? null)
142
+ return
143
+ }
144
+ const predicateGetter = predicate !== undefined && predicate !== true ? addPredicate(predicate) : null
145
+ const columnName = getColumnName(this.schema, entity, field)
146
+ let ids = await this.getColumnValues(path.for(field), columnName, predicateGetter)
102
147
 
103
- const data = (async () => (ids.length > 0 ? cb(ids) : {}))()
104
- this.hydrator.addPromise(fieldPath, path.for(fieldName), data, defaultValue)
148
+ const data = ids.length > 0 ? dataProvider(ids) : Promise.resolve({})
149
+ this.hydrator.addPromise(fieldPath, path.for(field), data, defaultValue ?? null)
105
150
  },
106
- addColumn: (qbCallback, path) => {
107
- this.qb = qbCallback(this.qb)
108
- this.hydrator.addColumn(path || fieldPath)
151
+ addColumn: ({ path = fieldPath, predicate, query, valueGetter }) => {
152
+ if (predicate === false) {
153
+ this.hydrator.addColumn(path, () => null)
154
+ return
155
+ }
156
+ const predicateGetter = predicate !== undefined && predicate !== true ? addPredicate(predicate) : null
157
+ if (query) {
158
+ this.qb = query(this.qb)
159
+ }
160
+ this.hydrator.addColumn(
161
+ path,
162
+ valueGetter ?? (row => predicateGetter === null || predicateGetter(row) ? row[path.alias] : null),
163
+ )
109
164
  },
165
+ addPredicate: addPredicate,
110
166
  path: fieldPath,
111
167
  entity: entity,
112
168
  ...fieldProperty,
@@ -136,10 +192,12 @@ export class SelectBuilder {
136
192
  }
137
193
  }
138
194
 
139
- private async getColumnValues(columnPath: Path, columnName: string): Promise<Input.PrimaryValue[]> {
195
+ private async getColumnValues(columnPath: Path, columnName: string, predicateGetter: null | ColumnValueGetter<boolean>): Promise<Input.PrimaryValue[]> {
140
196
  this.qb = this.qb.select([columnPath.back().alias, columnName], columnPath.alias)
141
197
  const rows = await this.rows
198
+ const filteredRows = predicateGetter === null ? rows : rows.filter(predicateGetter)
142
199
  const columnAlias = columnPath.alias
143
- return Array.from(new Set(rows.map((it): Input.PrimaryValue => it[columnAlias] as Input.PrimaryValue)))
200
+ const ids = filteredRows.map((it): Input.PrimaryValue => it[columnAlias] as Input.PrimaryValue).filter(it => it !== null)
201
+ return Array.from(new Set(ids))
144
202
  }
145
203
  }
@@ -1,7 +1,8 @@
1
1
  import { SelectBuilder } from './SelectBuilder'
2
2
  import { SelectHydrator } from './SelectHydrator'
3
3
  import { SelectBuilder as DbSelectBuilder } from '@contember/database'
4
+ import { Model } from '@contember/schema'
4
5
 
5
6
  export interface SelectBuilderFactory {
6
- create(qb: DbSelectBuilder<DbSelectBuilder.Result>, hydrator: SelectHydrator): SelectBuilder
7
+ create(qb: DbSelectBuilder<DbSelectBuilder.Result>, hydrator: SelectHydrator, relationPath: Model.AnyRelationContext[]): SelectBuilder
7
8
  }
@@ -1,6 +1,6 @@
1
1
  import { Path } from './Path'
2
- import { Input, Model } from '@contember/schema'
3
- import { SelectNestedData, SelectNestedDefaultValue } from './SelectHydrator'
2
+ import { Acl, Input, Model } from '@contember/schema'
3
+ import { ColumnValueGetter, SelectNestedData, SelectNestedDefaultValue, SelectRow } from './SelectHydrator'
4
4
  import { SelectBuilder } from '@contember/database'
5
5
  import { Mapper } from '../Mapper'
6
6
  import { FieldNode, ObjectNode } from '../../inputProcessing'
@@ -21,12 +21,20 @@ export type SelectExecutionHandlerContext<
21
21
  mapper: Mapper
22
22
  path: Path
23
23
  entity: Model.Entity
24
-
25
- addColumn: (
26
- queryCallback: (qb: SelectBuilder<SelectBuilder.Result>) => SelectBuilder<SelectBuilder.Result>,
27
- path?: Path,
28
- ) => void
29
- addData: (parentField: string, cb: DataCallback, defaultValue?: SelectNestedDefaultValue) => void
24
+ relationPath: Model.AnyRelationContext[]
25
+ addPredicate: (predicate: Acl.Predicate) => (row: SelectRow) => boolean
26
+ addColumn: (args: {
27
+ predicate?: Acl.Predicate
28
+ query?: (qb: SelectBuilder<SelectBuilder.Result>) => SelectBuilder<SelectBuilder.Result>
29
+ path?: Path
30
+ valueGetter?: ColumnValueGetter
31
+ }) => void
32
+ addData: (args: {
33
+ field: string
34
+ dataProvider: DataCallback
35
+ predicate?: Acl.Predicate
36
+ defaultValue?: SelectNestedDefaultValue
37
+ }) => void
30
38
  } & (
31
39
  | {
32
40
  fieldNode: FieldNode<FieldExtensions>
@@ -1,6 +1,7 @@
1
1
  import { Path } from './Path'
2
2
  import { Value } from '@contember/schema'
3
3
  import { getFulfilledValues, getRejections } from '../../utils'
4
+ import { logger } from '@contember/logger'
4
5
 
5
6
  type DataPromises = {
6
7
  path: Path
@@ -16,12 +17,19 @@ type ResolvedData = {
16
17
  defaultValue: SelectNestedDefaultValue
17
18
  }
18
19
 
20
+ export type ColumnValueGetter<T extends Value.FieldValue = Value.FieldValue> = (row: SelectRow) => T
21
+
22
+ type Column = {
23
+ path: Path
24
+ getValue: ColumnValueGetter
25
+ }
26
+
19
27
  export class SelectHydrator {
20
- private columns: Path[] = []
28
+ private columns: Column[] = []
21
29
  private promises: DataPromises[] = []
22
30
 
23
- public addColumn(path: Path) {
24
- this.columns.push(path)
31
+ public addColumn(path: Path, getValue: ColumnValueGetter) {
32
+ this.columns.push({ path, getValue })
25
33
  }
26
34
 
27
35
  public addPromise(
@@ -72,12 +80,11 @@ export class SelectHydrator {
72
80
  const result: SelectResultObject = {}
73
81
 
74
82
  for (let columnPath of this.columns) {
75
- const path = [...columnPath.path]
83
+ const path = [...columnPath.path.path]
76
84
  const last: string = path.pop() as string
77
85
  const currentObject = path.reduce<any>((obj, part) => (obj[part] = obj[part] || {}), result)
78
86
 
79
- const field = row[columnPath.alias]
80
- currentObject[last] = this.formatValue(field)
87
+ currentObject[last] = this.formatValue(columnPath.getValue(row))
81
88
  }
82
89
 
83
90
  for (let { path, parentKeyPath, data, defaultValue } of resolvedData) {
@@ -103,10 +110,7 @@ export class SelectHydrator {
103
110
  const failures = getRejections(results)
104
111
  if (failures.length > 0) {
105
112
  if (failures.length > 1) {
106
- // eslint-disable-next-line no-console
107
- console.error('Multiple error has occurred, printing them & rethrowing the first one')
108
- // eslint-disable-next-line no-console
109
- failures.slice(1).map(e => console.error(e))
113
+ failures.slice(1).map(e => logger.error(e, { loc: 'SelectHydrator' }))
110
114
  }
111
115
  throw failures[0]
112
116
  }
@@ -122,7 +126,7 @@ export class SelectHydrator {
122
126
  }
123
127
  }
124
128
 
125
- export type SelectRow = { [key: string]: Value.AtomicValue }
129
+ export type SelectRow = { [key: string]: Value.FieldValue }
126
130
  export type SelectResultObject = Value.Object
127
131
  export type SelectIndexedResultObjects = { [key: string]: SelectResultObject }
128
132
  export type SelectGroupedObjects = { [groupingKey: string]: SelectResultObject[] }
@@ -1,11 +1,17 @@
1
1
  import { isIt } from '../../utils'
2
- import { acceptFieldVisitor } from '@contember/schema-utils'
2
+ import { acceptFieldVisitor, isColumn } from '@contember/schema-utils'
3
3
  import { Input, Model } from '@contember/schema'
4
4
  import { Path, PathFactory } from './Path'
5
5
  import { JoinBuilder } from './JoinBuilder'
6
6
  import { ConditionBuilder } from './ConditionBuilder'
7
- import { ConditionBuilder as SqlConditionBuilder, Operator, QueryBuilder, SelectBuilder } from '@contember/database'
8
- import { WhereOptimizer } from './optimizer/WhereOptimizer'
7
+ import {
8
+ ConditionBuilder as SqlConditionBuilder,
9
+ Literal,
10
+ Operator,
11
+ QueryBuilder,
12
+ SelectBuilder, wrapIdentifier,
13
+ } from '@contember/database'
14
+ import { WhereOptimizationHints, WhereOptimizer } from './optimizer/WhereOptimizer'
9
15
 
10
16
  export class WhereBuilder {
11
17
  constructor(
@@ -14,6 +20,7 @@ export class WhereBuilder {
14
20
  private readonly conditionBuilder: ConditionBuilder,
15
21
  private readonly pathFactory: PathFactory,
16
22
  private readonly whereOptimizer: WhereOptimizer,
23
+ private readonly useExistsInHasManyFilter: boolean,
17
24
  ) {}
18
25
 
19
26
  public build(
@@ -21,35 +28,62 @@ export class WhereBuilder {
21
28
  entity: Model.Entity,
22
29
  path: Path,
23
30
  where: Input.OptionalWhere,
24
- allowManyJoin: boolean = false,
31
+ optimizationHints: WhereOptimizationHints = {},
25
32
  ) {
26
- return this.buildAdvanced(entity, path, where, cb => qb.where(clause => cb(clause)), allowManyJoin)
33
+ const optimizedWhere = this.whereOptimizer.optimize(where, entity, optimizationHints)
34
+ return this.buildInternal({
35
+ entity,
36
+ path,
37
+ where: optimizedWhere,
38
+ callback: cb => qb.where(clause => cb(clause)),
39
+ allowManyJoin: false,
40
+ })
27
41
  }
28
42
 
43
+
29
44
  public buildAdvanced(
30
45
  entity: Model.Entity,
31
46
  path: Path,
32
47
  where: Input.OptionalWhere,
33
48
  callback: (clauseCb: (clause: SqlConditionBuilder) => SqlConditionBuilder) => SelectBuilder<SelectBuilder.Result>,
34
- allowManyJoin: boolean = false,
49
+ optimizationHints: WhereOptimizationHints = {},
50
+ ) {
51
+ const optimizedWhere = this.whereOptimizer.optimize(where, entity, optimizationHints)
52
+ return this.buildInternal({
53
+ entity,
54
+ path,
55
+ where: optimizedWhere,
56
+ callback,
57
+ allowManyJoin: false,
58
+ })
59
+ }
60
+
61
+ private buildInternal({
62
+ callback,
63
+ ...args
64
+ }: { entity: Model.Entity; path: Path; where: Input.OptionalWhere; callback: (clauseCb: (clause: SqlConditionBuilder) => SqlConditionBuilder) => SelectBuilder<SelectBuilder.Result>; allowManyJoin: boolean },
35
65
  ) {
36
- const optimizedWhere = this.whereOptimizer.optimize(where, entity)
37
66
  const joinList: WhereJoinDefinition[] = []
38
67
 
39
- const qbWithWhere = callback(clause => this.buildInternal(clause, entity, path, optimizedWhere, allowManyJoin, joinList))
68
+ const qbWithWhere = callback(clause => this.buildRecursive({
69
+ conditionBuilder: clause,
70
+ joinList: joinList,
71
+ ...args,
72
+ }))
40
73
  return joinList.reduce<SelectBuilder<SelectBuilder.Result>>(
41
74
  (qb, { path, entity, relationName }) => this.joinBuilder.join(qb, path, entity, relationName),
42
75
  qbWithWhere,
43
76
  )
44
77
  }
45
78
 
46
- private buildInternal(
47
- conditionBuilder: SqlConditionBuilder,
48
- entity: Model.Entity,
49
- path: Path,
50
- where: Input.Where,
51
- allowManyJoin: boolean,
52
- joinList: WhereJoinDefinition[],
79
+ private buildRecursive({
80
+ conditionBuilder,
81
+ entity,
82
+ path,
83
+ where,
84
+ joinList,
85
+ allowManyJoin,
86
+ }: { conditionBuilder: SqlConditionBuilder; entity: Model.Entity; path: Path; where: Input.OptionalWhere; joinList: WhereJoinDefinition[]; allowManyJoin: boolean },
53
87
  ): SqlConditionBuilder {
54
88
  const tableName = path.alias
55
89
 
@@ -58,7 +92,14 @@ export class WhereBuilder {
58
92
  conditionBuilder = conditionBuilder.and(clause =>
59
93
  expr.reduce(
60
94
  (clause2, where) =>
61
- !where ? clause2 : this.buildInternal(clause2, entity, path, where, allowManyJoin, joinList),
95
+ !where ? clause2 : this.buildRecursive({
96
+ conditionBuilder: clause2,
97
+ entity,
98
+ path,
99
+ where,
100
+ joinList,
101
+ allowManyJoin,
102
+ }),
62
103
  clause,
63
104
  ),
64
105
  )
@@ -70,7 +111,14 @@ export class WhereBuilder {
70
111
  (clause2, where) =>
71
112
  !where
72
113
  ? clause2
73
- : clause2.and(clause3 => this.buildInternal(clause3, entity, path, where, allowManyJoin, joinList)),
114
+ : clause2.and(clause3 => this.buildRecursive({
115
+ conditionBuilder: clause3,
116
+ entity,
117
+ path,
118
+ where,
119
+ joinList,
120
+ allowManyJoin,
121
+ })),
74
122
  clause,
75
123
  ),
76
124
  )
@@ -78,7 +126,14 @@ export class WhereBuilder {
78
126
  if (where.not !== undefined) {
79
127
  const expr = where.not
80
128
  conditionBuilder = conditionBuilder.not(clause =>
81
- this.buildInternal(clause, entity, path, expr, allowManyJoin, joinList),
129
+ this.buildRecursive({
130
+ conditionBuilder: clause,
131
+ entity,
132
+ path,
133
+ where: expr,
134
+ joinList,
135
+ allowManyJoin,
136
+ }),
82
137
  )
83
138
  }
84
139
 
@@ -87,12 +142,9 @@ export class WhereBuilder {
87
142
  continue
88
143
  }
89
144
 
90
- const joinedWhere = (
91
- entity: Model.Entity,
92
- relation: Model.Relation,
93
- targetEntity: Model.Entity,
94
- ): SqlConditionBuilder => {
95
- const targetPath = path.for(fieldName)
145
+ const targetPath = path.for(fieldName)
146
+
147
+ const joinedWhere = ({ targetEntity, relation, entity }: Model.AnyRelationContext): SqlConditionBuilder => {
96
148
  const relationWhere = where[fieldName] as Input.Where
97
149
  if (Object.keys(relationWhere).length === 0) {
98
150
  return conditionBuilder
@@ -112,36 +164,45 @@ export class WhereBuilder {
112
164
 
113
165
  joinList.push({ path: targetPath, entity, relationName: relation.name })
114
166
 
115
- return this.buildInternal(conditionBuilder, targetEntity, targetPath, relationWhere, allowManyJoin, joinList)
167
+ return this.buildRecursive({
168
+ conditionBuilder,
169
+ entity: targetEntity,
170
+ path: targetPath,
171
+ where: relationWhere,
172
+ joinList,
173
+ allowManyJoin,
174
+ })
116
175
  }
117
176
 
118
177
  conditionBuilder = acceptFieldVisitor<SqlConditionBuilder>(this.schema, entity, fieldName, {
119
- visitColumn: (entity, column) => {
178
+ visitColumn: ({ entity, column }) => {
120
179
  const subWhere: Input.Condition<Input.ColumnValue> = where[column.name] as Input.Condition<Input.ColumnValue>
121
180
  return this.conditionBuilder.build(conditionBuilder, tableName, column.columnName, column.columnType, subWhere)
122
181
  },
123
182
  visitOneHasOneInverse: joinedWhere,
124
183
  visitOneHasOneOwning: joinedWhere,
125
184
  visitManyHasOne: joinedWhere,
126
- visitManyHasManyInverse: (entity, relation, targetEntity, targetRelation) => {
127
- if (allowManyJoin) {
128
- return joinedWhere(entity, relation, targetEntity)
185
+ visitManyHasManyInverse: context => {
186
+ if (allowManyJoin && !this.useExistsInHasManyFilter) {
187
+ return joinedWhere(context)
129
188
  }
189
+
130
190
  const relationWhere = where[fieldName] as Input.Where
131
191
 
132
192
  return conditionBuilder.exists(
133
193
  this.createManyHasManySubquery(
134
194
  [tableName, entity.primaryColumn],
135
195
  relationWhere,
136
- targetEntity,
137
- targetRelation.joiningTable,
196
+ context.targetEntity,
197
+ context.targetRelation.joiningTable,
138
198
  'inverse',
199
+ targetPath,
139
200
  ),
140
201
  )
141
202
  },
142
- visitManyHasManyOwning: (entity, relation, targetEntity) => {
143
- if (allowManyJoin) {
144
- return joinedWhere(entity, relation, targetEntity)
203
+ visitManyHasManyOwning: context => {
204
+ if (allowManyJoin && !this.useExistsInHasManyFilter) {
205
+ return joinedWhere(context)
145
206
  }
146
207
 
147
208
  const relationWhere = where[fieldName] as Input.Where
@@ -150,30 +211,40 @@ export class WhereBuilder {
150
211
  this.createManyHasManySubquery(
151
212
  [tableName, entity.primaryColumn],
152
213
  relationWhere,
153
- targetEntity,
154
- relation.joiningTable,
214
+ context.targetEntity,
215
+ context.relation.joiningTable,
155
216
  'owning',
217
+ targetPath,
156
218
  ),
157
219
  )
158
220
  },
159
- visitOneHasMany: (entity, relation, targetEntity, targetRelation) => {
160
- if (allowManyJoin) {
161
- return joinedWhere(entity, relation, targetEntity)
221
+ visitOneHasMany: context => {
222
+ if (allowManyJoin && !this.useExistsInHasManyFilter) {
223
+ return joinedWhere(context)
162
224
  }
163
225
 
164
226
  const relationWhere = where[fieldName] as Input.Where
165
227
 
228
+ const qb = this.hasRootIsNull(relationWhere, context.targetEntity)
229
+ ? SelectBuilder.create()
230
+ .select(it => it.raw('1'))
231
+ .from(new Literal(`(select ${wrapIdentifier(tableName)}.${wrapIdentifier(entity.primaryColumn)})`), targetPath.for('tmp_').alias)
232
+ .leftJoin(context.targetEntity.tableName, targetPath.alias, it =>
233
+ it.columnsEq([targetPath.for('tmp_').alias, entity.primaryColumn], [targetPath.alias, context.targetRelation.joiningColumn.columnName]),
234
+ )
235
+ : SelectBuilder.create()
236
+ .select(it => it.raw('1'))
237
+ .from(context.targetEntity.tableName, targetPath.alias)
238
+ .where(it => it.columnsEq([tableName, entity.primaryColumn], [targetPath.alias, context.targetRelation.joiningColumn.columnName]))
239
+
166
240
  return conditionBuilder.exists(
167
- this.build(
168
- SelectBuilder.create()
169
- .select(it => it.raw('1'))
170
- .from(targetEntity.tableName, 'sub_')
171
- .where(it => it.columnsEq([tableName, entity.primaryColumn], ['sub_', targetRelation.joiningColumn.columnName])),
172
- targetEntity,
173
- this.pathFactory.create([], 'sub_'),
174
- relationWhere,
175
- true,
176
- ),
241
+ this.buildInternal({
242
+ entity: context.targetEntity,
243
+ path: targetPath,
244
+ where: relationWhere,
245
+ callback: cb => qb.where(clause => cb(clause)),
246
+ allowManyJoin: true,
247
+ }),
177
248
  )
178
249
  },
179
250
  })
@@ -181,19 +252,22 @@ export class WhereBuilder {
181
252
  return conditionBuilder
182
253
  }
183
254
 
255
+
184
256
  private createManyHasManySubquery(
185
257
  outerColumn: QueryBuilder.ColumnIdentifier,
186
258
  relationWhere: Input.Where,
187
259
  targetEntity: Model.Entity,
188
260
  joiningTable: Model.JoiningTable,
189
261
  fromSide: 'owning' | 'inverse',
262
+ path: Path,
190
263
  ) {
191
264
  const fromColumn = fromSide === 'owning' ? joiningTable.joiningColumn.columnName : joiningTable.inverseJoiningColumn.columnName
192
265
  const toColumn = fromSide === 'owning' ? joiningTable.inverseJoiningColumn.columnName : joiningTable.joiningColumn.columnName
266
+ const junctionPath = path.for('junction_')
193
267
  const qb = SelectBuilder.create<SelectBuilder.Result>()
194
- .from(joiningTable.tableName, 'junction_')
268
+ .from(joiningTable.tableName, junctionPath.alias)
195
269
  .select(it => it.raw('1'))
196
- .where(it => it.columnsEq(outerColumn, ['junction_', fromColumn]))
270
+ .where(it => it.columnsEq(outerColumn, [junctionPath.alias, fromColumn]))
197
271
 
198
272
  const primaryCondition = this.transformWhereToPrimaryCondition(relationWhere, targetEntity.primary)
199
273
  if (primaryCondition !== null) {
@@ -201,20 +275,20 @@ export class WhereBuilder {
201
275
  const columnType = (targetEntity.fields[targetEntity.primary] as Model.AnyColumn).columnType
202
276
 
203
277
  return qb.where(condition =>
204
- this.conditionBuilder.build(condition, 'junction_', toColumn, columnType, primaryCondition),
278
+ this.conditionBuilder.build(condition, junctionPath.alias, toColumn, columnType, primaryCondition),
205
279
  )
206
280
  }
207
281
 
208
- const qbJoined = qb.join(targetEntity.tableName, 'sub_', clause =>
209
- clause.compareColumns(['junction_', toColumn], Operator.eq, ['sub_', targetEntity.primary]),
210
- )
211
- return this.buildAdvanced(
212
- targetEntity,
213
- this.pathFactory.create([], 'sub_'),
214
- relationWhere,
215
- cb => qbJoined.where(clause => cb(clause)),
216
- true,
282
+ const qbJoined = qb.join(targetEntity.tableName, path.alias, clause =>
283
+ clause.compareColumns([junctionPath.alias, toColumn], Operator.eq, [path.alias, targetEntity.primary]),
217
284
  )
285
+ return this.buildInternal({
286
+ entity: targetEntity,
287
+ path: this.pathFactory.create([], path.fullAlias),
288
+ where: relationWhere,
289
+ callback: cb => qbJoined.where(clause => cb(clause)),
290
+ allowManyJoin: true,
291
+ })
218
292
  }
219
293
 
220
294
  private transformWhereToPrimaryCondition(where: Input.Where, primaryField: string): Input.Condition<never> | null {
@@ -260,6 +334,39 @@ export class WhereBuilder {
260
334
  }
261
335
  return condition
262
336
  }
337
+
338
+ private hasRootIsNull(where: Input.Where, entity: Model.Entity): boolean {
339
+ for (const key in where) {
340
+ if (key === 'and' || key === 'or') {
341
+ if (where[key]?.some(it => this.hasRootIsNull(it, entity))) {
342
+ return true
343
+ }
344
+ } else if (key === 'not') {
345
+ if (where.not && this.hasRootIsNull(where.not, entity)) {
346
+ return true
347
+ }
348
+ } else if (isColumn(entity.fields[key]) && this.conditionHasIsNull(where[key] as Input.Condition)) {
349
+ return true
350
+ }
351
+ }
352
+ return false
353
+ }
354
+
355
+ private conditionHasIsNull(cond: Input.Condition): boolean {
356
+ if (cond.isNull !== undefined) {
357
+ return true
358
+ }
359
+ if (cond.and && cond.and.some(it => this.conditionHasIsNull(it))) {
360
+ return true
361
+ }
362
+ if (cond.or && cond.or.some(it => this.conditionHasIsNull(it))) {
363
+ return true
364
+ }
365
+ if (cond.not && this.conditionHasIsNull(cond.not)) {
366
+ return true
367
+ }
368
+ return false
369
+ }
263
370
  }
264
371
 
265
372
  export type WhereJoinDefinition = { path: Path; entity: Model.Entity; relationName: string }