@strapi/database 4.15.0-alpha.0 → 4.15.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 (242) hide show
  1. package/README.md +3 -0
  2. package/dist/connection.d.ts +3 -0
  3. package/dist/connection.d.ts.map +1 -0
  4. package/dist/dialects/dialect.d.ts +27 -0
  5. package/dist/dialects/dialect.d.ts.map +1 -0
  6. package/dist/dialects/index.d.ts +5 -0
  7. package/dist/dialects/index.d.ts.map +1 -0
  8. package/dist/dialects/mysql/constants.d.ts +3 -0
  9. package/dist/dialects/mysql/constants.d.ts.map +1 -0
  10. package/dist/dialects/mysql/database-inspector.d.ts +12 -0
  11. package/dist/dialects/mysql/database-inspector.d.ts.map +1 -0
  12. package/dist/dialects/mysql/index.d.ts +20 -0
  13. package/dist/dialects/mysql/index.d.ts.map +1 -0
  14. package/dist/dialects/mysql/schema-inspector.d.ts +13 -0
  15. package/dist/dialects/mysql/schema-inspector.d.ts.map +1 -0
  16. package/dist/dialects/postgresql/index.d.ts +14 -0
  17. package/dist/dialects/postgresql/index.d.ts.map +1 -0
  18. package/dist/dialects/postgresql/schema-inspector.d.ts +14 -0
  19. package/dist/dialects/postgresql/schema-inspector.d.ts.map +1 -0
  20. package/dist/dialects/sqlite/index.d.ts +19 -0
  21. package/dist/dialects/sqlite/index.d.ts.map +1 -0
  22. package/dist/dialects/sqlite/schema-inspector.d.ts +13 -0
  23. package/dist/dialects/sqlite/schema-inspector.d.ts.map +1 -0
  24. package/dist/entity-manager/entity-repository.d.ts +4 -0
  25. package/dist/entity-manager/entity-repository.d.ts.map +1 -0
  26. package/dist/entity-manager/index.d.ts +5 -0
  27. package/dist/entity-manager/index.d.ts.map +1 -0
  28. package/dist/entity-manager/morph-relations.d.ts +13 -0
  29. package/dist/entity-manager/morph-relations.d.ts.map +1 -0
  30. package/dist/entity-manager/regular-relations.d.ts +83 -0
  31. package/dist/entity-manager/regular-relations.d.ts.map +1 -0
  32. package/dist/entity-manager/relations/cloning/regular-relations.d.ts +17 -0
  33. package/dist/entity-manager/relations/cloning/regular-relations.d.ts.map +1 -0
  34. package/dist/entity-manager/relations-orderer.d.ts +73 -0
  35. package/dist/entity-manager/relations-orderer.d.ts.map +1 -0
  36. package/dist/entity-manager/types.d.ts +97 -0
  37. package/dist/entity-manager/types.d.ts.map +1 -0
  38. package/dist/errors/database.d.ts +5 -0
  39. package/dist/errors/database.d.ts.map +1 -0
  40. package/dist/errors/index.d.ts +8 -0
  41. package/dist/errors/index.d.ts.map +1 -0
  42. package/dist/errors/invalid-date.d.ts +5 -0
  43. package/dist/errors/invalid-date.d.ts.map +1 -0
  44. package/dist/errors/invalid-datetime.d.ts +5 -0
  45. package/dist/errors/invalid-datetime.d.ts.map +1 -0
  46. package/dist/errors/invalid-relation.d.ts +5 -0
  47. package/dist/errors/invalid-relation.d.ts.map +1 -0
  48. package/dist/errors/invalid-time.d.ts +5 -0
  49. package/dist/errors/invalid-time.d.ts.map +1 -0
  50. package/dist/errors/not-null.d.ts +7 -0
  51. package/dist/errors/not-null.d.ts.map +1 -0
  52. package/dist/fields/biginteger.d.ts +4 -0
  53. package/dist/fields/biginteger.d.ts.map +1 -0
  54. package/dist/fields/boolean.d.ts +6 -0
  55. package/dist/fields/boolean.d.ts.map +1 -0
  56. package/dist/fields/date.d.ts +6 -0
  57. package/dist/fields/date.d.ts.map +1 -0
  58. package/dist/fields/datetime.d.ts +6 -0
  59. package/dist/fields/datetime.d.ts.map +1 -0
  60. package/dist/fields/field.d.ts +7 -0
  61. package/dist/fields/field.d.ts.map +1 -0
  62. package/dist/fields/index.d.ts +4 -0
  63. package/dist/fields/index.d.ts.map +1 -0
  64. package/dist/fields/json.d.ts +6 -0
  65. package/dist/fields/json.d.ts.map +1 -0
  66. package/dist/fields/number.d.ts +6 -0
  67. package/dist/fields/number.d.ts.map +1 -0
  68. package/dist/fields/shared/parsers.d.ts +4 -0
  69. package/dist/fields/shared/parsers.d.ts.map +1 -0
  70. package/dist/fields/string.d.ts +6 -0
  71. package/dist/fields/string.d.ts.map +1 -0
  72. package/dist/fields/time.d.ts +6 -0
  73. package/dist/fields/time.d.ts.map +1 -0
  74. package/dist/fields/timestamp.d.ts +6 -0
  75. package/dist/fields/timestamp.d.ts.map +1 -0
  76. package/dist/index.d.ts +46 -0
  77. package/dist/index.d.ts.map +1 -0
  78. package/dist/index.js +6189 -0
  79. package/dist/index.js.map +1 -0
  80. package/dist/index.mjs +6157 -0
  81. package/dist/index.mjs.map +1 -0
  82. package/dist/lifecycles/index.d.ts +17 -0
  83. package/dist/lifecycles/index.d.ts.map +1 -0
  84. package/dist/lifecycles/subscribers/index.d.ts +5 -0
  85. package/dist/lifecycles/subscribers/index.d.ts.map +1 -0
  86. package/dist/lifecycles/subscribers/models-lifecycles.d.ts +6 -0
  87. package/dist/lifecycles/subscribers/models-lifecycles.d.ts.map +1 -0
  88. package/dist/lifecycles/subscribers/timestamps.d.ts +3 -0
  89. package/dist/lifecycles/subscribers/timestamps.d.ts.map +1 -0
  90. package/dist/lifecycles/types.d.ts +25 -0
  91. package/dist/lifecycles/types.d.ts.map +1 -0
  92. package/dist/metadata/index.d.ts +10 -0
  93. package/dist/metadata/index.d.ts.map +1 -0
  94. package/dist/metadata/metadata.d.ts +22 -0
  95. package/dist/metadata/metadata.d.ts.map +1 -0
  96. package/dist/metadata/relations.d.ts +16 -0
  97. package/dist/metadata/relations.d.ts.map +1 -0
  98. package/dist/migrations/index.d.ts +12 -0
  99. package/dist/migrations/index.d.ts.map +1 -0
  100. package/dist/migrations/storage.d.ts +15 -0
  101. package/dist/migrations/storage.d.ts.map +1 -0
  102. package/dist/query/helpers/index.d.ts +8 -0
  103. package/dist/query/helpers/index.d.ts.map +1 -0
  104. package/dist/query/helpers/join.d.ts +30 -0
  105. package/dist/query/helpers/join.d.ts.map +1 -0
  106. package/dist/query/helpers/order-by.d.ts +14 -0
  107. package/dist/query/helpers/order-by.d.ts.map +1 -0
  108. package/dist/query/helpers/populate/apply.d.ts +11 -0
  109. package/dist/query/helpers/populate/apply.d.ts.map +1 -0
  110. package/dist/query/helpers/populate/index.d.ts +4 -0
  111. package/dist/query/helpers/populate/index.d.ts.map +1 -0
  112. package/dist/query/helpers/populate/process.d.ts +24 -0
  113. package/dist/query/helpers/populate/process.d.ts.map +1 -0
  114. package/dist/query/helpers/search.d.ts +4 -0
  115. package/dist/query/helpers/search.d.ts.map +1 -0
  116. package/dist/query/helpers/streams/index.d.ts +2 -0
  117. package/dist/query/helpers/streams/index.d.ts.map +1 -0
  118. package/dist/query/helpers/streams/readable.d.ts +39 -0
  119. package/dist/query/helpers/streams/readable.d.ts.map +1 -0
  120. package/dist/query/helpers/transform.d.ts +8 -0
  121. package/dist/query/helpers/transform.d.ts.map +1 -0
  122. package/dist/query/helpers/where.d.ts +19 -0
  123. package/dist/query/helpers/where.d.ts.map +1 -0
  124. package/dist/query/index.d.ts +3 -0
  125. package/dist/query/index.d.ts.map +1 -0
  126. package/dist/query/query-builder.d.ts +79 -0
  127. package/dist/query/query-builder.d.ts.map +1 -0
  128. package/dist/query/types.d.ts +8 -0
  129. package/dist/query/types.d.ts.map +1 -0
  130. package/dist/schema/builder.d.ts +33 -0
  131. package/dist/schema/builder.d.ts.map +1 -0
  132. package/dist/schema/diff.d.ts +7 -0
  133. package/dist/schema/diff.d.ts.map +1 -0
  134. package/dist/schema/index.d.ts +20 -0
  135. package/dist/schema/index.d.ts.map +1 -0
  136. package/dist/schema/schema.d.ts +4 -0
  137. package/dist/schema/schema.d.ts.map +1 -0
  138. package/dist/schema/storage.d.ts +10 -0
  139. package/dist/schema/storage.d.ts.map +1 -0
  140. package/dist/schema/types.d.ts +103 -0
  141. package/dist/schema/types.d.ts.map +1 -0
  142. package/dist/transaction-context.d.ts +22 -0
  143. package/dist/transaction-context.d.ts.map +1 -0
  144. package/dist/types/index.d.ts +169 -0
  145. package/dist/types/index.d.ts.map +1 -0
  146. package/dist/utils/content-types.d.ts +13 -0
  147. package/dist/utils/content-types.d.ts.map +1 -0
  148. package/dist/utils/knex.d.ts +12 -0
  149. package/dist/utils/knex.d.ts.map +1 -0
  150. package/dist/utils/types.d.ts +10 -0
  151. package/dist/utils/types.d.ts.map +1 -0
  152. package/dist/validations/index.d.ts +6 -0
  153. package/dist/validations/index.d.ts.map +1 -0
  154. package/dist/validations/relations/bidirectional.d.ts +12 -0
  155. package/dist/validations/relations/bidirectional.d.ts.map +1 -0
  156. package/dist/validations/relations/index.d.ts +7 -0
  157. package/dist/validations/relations/index.d.ts.map +1 -0
  158. package/package.json +21 -9
  159. package/.eslintignore +0 -2
  160. package/.eslintrc.js +0 -4
  161. package/jest.config.js +0 -6
  162. package/lib/__tests__/index.test.js +0 -93
  163. package/lib/__tests__/lifecycles.test.js +0 -55
  164. package/lib/connection.js +0 -64
  165. package/lib/dialects/dialect.js +0 -63
  166. package/lib/dialects/index.js +0 -53
  167. package/lib/dialects/mysql/constants.js +0 -6
  168. package/lib/dialects/mysql/database-inspector.js +0 -37
  169. package/lib/dialects/mysql/index.js +0 -92
  170. package/lib/dialects/mysql/schema-inspector.js +0 -234
  171. package/lib/dialects/postgresql/index.js +0 -65
  172. package/lib/dialects/postgresql/schema-inspector.js +0 -283
  173. package/lib/dialects/sqlite/index.js +0 -87
  174. package/lib/dialects/sqlite/schema-inspector.js +0 -151
  175. package/lib/entity-manager/__tests__/relations-orderer.test.js +0 -186
  176. package/lib/entity-manager/__tests__/sort-connect-array.test.js +0 -79
  177. package/lib/entity-manager/entity-repository.js +0 -164
  178. package/lib/entity-manager/index.js +0 -1385
  179. package/lib/entity-manager/morph-relations.js +0 -63
  180. package/lib/entity-manager/regular-relations.js +0 -506
  181. package/lib/entity-manager/relations/cloning/regular-relations.js +0 -76
  182. package/lib/entity-manager/relations-orderer.js +0 -225
  183. package/lib/errors/database.js +0 -12
  184. package/lib/errors/index.js +0 -17
  185. package/lib/errors/invalid-date.js +0 -14
  186. package/lib/errors/invalid-datetime.js +0 -14
  187. package/lib/errors/invalid-relation.js +0 -14
  188. package/lib/errors/invalid-time.js +0 -14
  189. package/lib/errors/not-null.js +0 -15
  190. package/lib/fields/biginteger.js +0 -17
  191. package/lib/fields/boolean.js +0 -39
  192. package/lib/fields/date.js +0 -16
  193. package/lib/fields/datetime.js +0 -19
  194. package/lib/fields/field.js +0 -17
  195. package/lib/fields/index.d.ts +0 -9
  196. package/lib/fields/index.js +0 -50
  197. package/lib/fields/json.js +0 -21
  198. package/lib/fields/number.js +0 -23
  199. package/lib/fields/shared/parsers.js +0 -71
  200. package/lib/fields/string.js +0 -17
  201. package/lib/fields/time.js +0 -17
  202. package/lib/fields/timestamp.js +0 -19
  203. package/lib/index.d.ts +0 -198
  204. package/lib/index.js +0 -129
  205. package/lib/lifecycles/index.d.ts +0 -51
  206. package/lib/lifecycles/index.js +0 -90
  207. package/lib/lifecycles/subscribers/index.d.ts +0 -11
  208. package/lib/lifecycles/subscribers/models-lifecycles.js +0 -19
  209. package/lib/lifecycles/subscribers/timestamps.js +0 -65
  210. package/lib/metadata/index.js +0 -244
  211. package/lib/metadata/relations.js +0 -578
  212. package/lib/migrations/index.d.ts +0 -9
  213. package/lib/migrations/index.js +0 -75
  214. package/lib/migrations/storage.js +0 -44
  215. package/lib/query/helpers/index.js +0 -11
  216. package/lib/query/helpers/join.js +0 -96
  217. package/lib/query/helpers/order-by.js +0 -70
  218. package/lib/query/helpers/populate/apply.js +0 -664
  219. package/lib/query/helpers/populate/index.js +0 -9
  220. package/lib/query/helpers/populate/process.js +0 -102
  221. package/lib/query/helpers/search.js +0 -84
  222. package/lib/query/helpers/streams/index.js +0 -5
  223. package/lib/query/helpers/streams/readable.js +0 -174
  224. package/lib/query/helpers/transform.js +0 -84
  225. package/lib/query/helpers/where.js +0 -365
  226. package/lib/query/index.js +0 -7
  227. package/lib/query/query-builder.js +0 -514
  228. package/lib/schema/__tests__/schema-diff.test.js +0 -231
  229. package/lib/schema/builder.js +0 -386
  230. package/lib/schema/diff.js +0 -399
  231. package/lib/schema/index.d.ts +0 -49
  232. package/lib/schema/index.js +0 -94
  233. package/lib/schema/schema.js +0 -202
  234. package/lib/schema/storage.js +0 -76
  235. package/lib/transaction-context.js +0 -68
  236. package/lib/types/index.d.ts +0 -6
  237. package/lib/types/index.js +0 -35
  238. package/lib/utils/content-types.js +0 -40
  239. package/lib/utils/knex.js +0 -22
  240. package/lib/validations/index.js +0 -20
  241. package/lib/validations/relations/bidirectional.js +0 -89
  242. package/lib/validations/relations/index.js +0 -14
@@ -1,664 +0,0 @@
1
- 'use strict';
2
-
3
- const _ = require('lodash/fp');
4
-
5
- const { fromRow } = require('../transform');
6
-
7
- /**
8
- * Populate oneToOne and manyToOne relation
9
- * @param {*} input
10
- * @param {*} ctx
11
- * @returns
12
- */
13
- const XtoOne = async (input, ctx) => {
14
- const { attribute, attributeName, results, populateValue, targetMeta, isCount } = input;
15
- const { db, qb } = ctx;
16
-
17
- const fromTargetRow = (rowOrRows) => fromRow(targetMeta, rowOrRows);
18
-
19
- if (attribute.joinColumn) {
20
- const { name: joinColumnName, referencedColumn: referencedColumnName } = attribute.joinColumn;
21
-
22
- const referencedValues = _.uniq(
23
- results.map((r) => r[joinColumnName]).filter((value) => !_.isNil(value))
24
- );
25
-
26
- if (_.isEmpty(referencedValues)) {
27
- results.forEach((result) => {
28
- result[attributeName] = null;
29
- });
30
-
31
- return;
32
- }
33
-
34
- const rows = await db.entityManager
35
- .createQueryBuilder(targetMeta.uid)
36
- .init(populateValue)
37
- .addSelect(`${qb.alias}.${referencedColumnName}`)
38
- .where({ [referencedColumnName]: referencedValues })
39
- .execute({ mapResults: false });
40
-
41
- const map = _.groupBy(referencedColumnName, rows);
42
-
43
- results.forEach((result) => {
44
- result[attributeName] = fromTargetRow(_.first(map[result[joinColumnName]]));
45
- });
46
-
47
- return;
48
- }
49
-
50
- if (attribute.joinTable) {
51
- const { joinTable } = attribute;
52
-
53
- const qb = db.entityManager.createQueryBuilder(targetMeta.uid);
54
-
55
- const { name: joinColumnName, referencedColumn: referencedColumnName } = joinTable.joinColumn;
56
-
57
- const alias = qb.getAlias();
58
- const joinColAlias = `${alias}.${joinColumnName}`;
59
-
60
- const referencedValues = _.uniq(
61
- results.map((r) => r[referencedColumnName]).filter((value) => !_.isNil(value))
62
- );
63
-
64
- if (isCount) {
65
- if (_.isEmpty(referencedValues)) {
66
- results.forEach((result) => {
67
- result[attributeName] = { count: 0 };
68
- });
69
- return;
70
- }
71
-
72
- const rows = await qb
73
- .init(populateValue)
74
- .join({
75
- alias,
76
- referencedTable: joinTable.name,
77
- referencedColumn: joinTable.inverseJoinColumn.name,
78
- rootColumn: joinTable.inverseJoinColumn.referencedColumn,
79
- rootTable: qb.alias,
80
- on: joinTable.on,
81
- })
82
- .select([joinColAlias, qb.raw('count(*) AS count')])
83
- .where({ [joinColAlias]: referencedValues })
84
- .groupBy(joinColAlias)
85
- .execute({ mapResults: false });
86
-
87
- const map = rows.reduce((map, row) => {
88
- map[row[joinColumnName]] = { count: Number(row.count) };
89
- return map;
90
- }, {});
91
-
92
- results.forEach((result) => {
93
- result[attributeName] = map[result[referencedColumnName]] || { count: 0 };
94
- });
95
-
96
- return;
97
- }
98
-
99
- if (_.isEmpty(referencedValues)) {
100
- results.forEach((result) => {
101
- result[attributeName] = null;
102
- });
103
-
104
- return;
105
- }
106
-
107
- const rows = await qb
108
- .init(populateValue)
109
- .join({
110
- alias,
111
- referencedTable: joinTable.name,
112
- referencedColumn: joinTable.inverseJoinColumn.name,
113
- rootColumn: joinTable.inverseJoinColumn.referencedColumn,
114
- rootTable: qb.alias,
115
- on: joinTable.on,
116
- orderBy: joinTable.orderBy,
117
- })
118
- .addSelect(joinColAlias)
119
- .where({ [joinColAlias]: referencedValues })
120
- .execute({ mapResults: false });
121
-
122
- const map = _.groupBy(joinColumnName, rows);
123
-
124
- results.forEach((result) => {
125
- result[attributeName] = fromTargetRow(_.first(map[result[referencedColumnName]]));
126
- });
127
- }
128
- };
129
-
130
- const oneToMany = async (input, ctx) => {
131
- const { attribute, attributeName, results, populateValue, targetMeta, isCount } = input;
132
- const { db, qb } = ctx;
133
-
134
- const fromTargetRow = (rowOrRows) => fromRow(targetMeta, rowOrRows);
135
-
136
- if (attribute.joinColumn) {
137
- const { name: joinColumnName, referencedColumn: referencedColumnName } = attribute.joinColumn;
138
-
139
- const referencedValues = _.uniq(
140
- results.map((r) => r[joinColumnName]).filter((value) => !_.isNil(value))
141
- );
142
-
143
- if (_.isEmpty(referencedValues)) {
144
- results.forEach((result) => {
145
- result[attributeName] = null;
146
- });
147
- return;
148
- }
149
-
150
- const rows = await db.entityManager
151
- .createQueryBuilder(targetMeta.uid)
152
- .init(populateValue)
153
- .addSelect(`${qb.alias}.${referencedColumnName}`)
154
- .where({ [referencedColumnName]: referencedValues })
155
- .execute({ mapResults: false });
156
-
157
- const map = _.groupBy(referencedColumnName, rows);
158
-
159
- results.forEach((result) => {
160
- result[attributeName] = fromTargetRow(map[result[joinColumnName]] || []);
161
- });
162
-
163
- return;
164
- }
165
-
166
- if (attribute.joinTable) {
167
- const { joinTable } = attribute;
168
-
169
- const qb = db.entityManager.createQueryBuilder(targetMeta.uid);
170
-
171
- const { name: joinColumnName, referencedColumn: referencedColumnName } = joinTable.joinColumn;
172
-
173
- const alias = qb.getAlias();
174
- const joinColAlias = `${alias}.${joinColumnName}`;
175
-
176
- const referencedValues = _.uniq(
177
- results.map((r) => r[referencedColumnName]).filter((value) => !_.isNil(value))
178
- );
179
-
180
- if (isCount) {
181
- if (_.isEmpty(referencedValues)) {
182
- results.forEach((result) => {
183
- result[attributeName] = { count: 0 };
184
- });
185
- return;
186
- }
187
-
188
- const rows = await qb
189
- .init(populateValue)
190
- .join({
191
- alias,
192
- referencedTable: joinTable.name,
193
- referencedColumn: joinTable.inverseJoinColumn.name,
194
- rootColumn: joinTable.inverseJoinColumn.referencedColumn,
195
- rootTable: qb.alias,
196
- on: joinTable.on,
197
- })
198
- .select([joinColAlias, qb.raw('count(*) AS count')])
199
- .where({ [joinColAlias]: referencedValues })
200
- .groupBy(joinColAlias)
201
- .execute({ mapResults: false });
202
-
203
- const map = rows.reduce((map, row) => {
204
- map[row[joinColumnName]] = { count: Number(row.count) };
205
- return map;
206
- }, {});
207
-
208
- results.forEach((result) => {
209
- result[attributeName] = map[result[referencedColumnName]] || { count: 0 };
210
- });
211
-
212
- return;
213
- }
214
-
215
- if (_.isEmpty(referencedValues)) {
216
- results.forEach((result) => {
217
- result[attributeName] = [];
218
- });
219
- return;
220
- }
221
-
222
- const rows = await qb
223
- .init(populateValue)
224
- .join({
225
- alias,
226
- referencedTable: joinTable.name,
227
- referencedColumn: joinTable.inverseJoinColumn.name,
228
- rootColumn: joinTable.inverseJoinColumn.referencedColumn,
229
- rootTable: qb.alias,
230
- on: joinTable.on,
231
- orderBy: _.mapValues((v) => populateValue.ordering || v, joinTable.orderBy),
232
- })
233
- .addSelect(joinColAlias)
234
- .where({ [joinColAlias]: referencedValues })
235
- .execute({ mapResults: false });
236
-
237
- const map = _.groupBy(joinColumnName, rows);
238
-
239
- results.forEach((r) => {
240
- r[attributeName] = fromTargetRow(map[r[referencedColumnName]] || []);
241
- });
242
- }
243
- };
244
-
245
- const manyToMany = async (input, ctx) => {
246
- const { attribute, attributeName, results, populateValue, targetMeta, isCount } = input;
247
- const { db } = ctx;
248
-
249
- const fromTargetRow = (rowOrRows) => fromRow(targetMeta, rowOrRows);
250
-
251
- const { joinTable } = attribute;
252
-
253
- const populateQb = db.entityManager.createQueryBuilder(targetMeta.uid);
254
-
255
- const { name: joinColumnName, referencedColumn: referencedColumnName } = joinTable.joinColumn;
256
-
257
- const alias = populateQb.getAlias();
258
- const joinColAlias = `${alias}.${joinColumnName}`;
259
- const referencedValues = _.uniq(
260
- results.map((r) => r[referencedColumnName]).filter((value) => !_.isNil(value))
261
- );
262
-
263
- if (isCount) {
264
- if (_.isEmpty(referencedValues)) {
265
- results.forEach((result) => {
266
- result[attributeName] = { count: 0 };
267
- });
268
- return;
269
- }
270
-
271
- const rows = await populateQb
272
- .init(populateValue)
273
- .join({
274
- alias,
275
- referencedTable: joinTable.name,
276
- referencedColumn: joinTable.inverseJoinColumn.name,
277
- rootColumn: joinTable.inverseJoinColumn.referencedColumn,
278
- rootTable: populateQb.alias,
279
- on: joinTable.on,
280
- })
281
- .select([joinColAlias, populateQb.raw('count(*) AS count')])
282
- .where({ [joinColAlias]: referencedValues })
283
- .groupBy(joinColAlias)
284
- .execute({ mapResults: false });
285
-
286
- const map = rows.reduce((map, row) => {
287
- map[row[joinColumnName]] = { count: Number(row.count) };
288
- return map;
289
- }, {});
290
-
291
- results.forEach((result) => {
292
- result[attributeName] = map[result[referencedColumnName]] || { count: 0 };
293
- });
294
-
295
- return;
296
- }
297
-
298
- if (_.isEmpty(referencedValues)) {
299
- results.forEach((result) => {
300
- result[attributeName] = [];
301
- });
302
- return;
303
- }
304
-
305
- const rows = await populateQb
306
- .init(populateValue)
307
- .join({
308
- alias,
309
- referencedTable: joinTable.name,
310
- referencedColumn: joinTable.inverseJoinColumn.name,
311
- rootColumn: joinTable.inverseJoinColumn.referencedColumn,
312
- rootTable: populateQb.alias,
313
- on: joinTable.on,
314
- orderBy: _.mapValues((v) => populateValue.ordering || v, joinTable.orderBy),
315
- })
316
- .addSelect(joinColAlias)
317
- .where({ [joinColAlias]: referencedValues })
318
- .execute({ mapResults: false });
319
-
320
- const map = _.groupBy(joinColumnName, rows);
321
-
322
- results.forEach((result) => {
323
- result[attributeName] = fromTargetRow(map[result[referencedColumnName]] || []);
324
- });
325
- };
326
-
327
- const morphX = async (input, ctx) => {
328
- const { attribute, attributeName, results, populateValue, targetMeta } = input;
329
- const { db, uid } = ctx;
330
-
331
- const fromTargetRow = (rowOrRows) => fromRow(targetMeta, rowOrRows);
332
-
333
- const { target, morphBy } = attribute;
334
-
335
- const targetAttribute = db.metadata.get(target).attributes[morphBy];
336
-
337
- if (targetAttribute.relation === 'morphToOne') {
338
- const { idColumn, typeColumn } = targetAttribute.morphColumn;
339
-
340
- const referencedValues = _.uniq(
341
- results.map((r) => r[idColumn.referencedColumn]).filter((value) => !_.isNil(value))
342
- );
343
-
344
- if (_.isEmpty(referencedValues)) {
345
- results.forEach((result) => {
346
- result[attributeName] = null;
347
- });
348
-
349
- return;
350
- }
351
-
352
- const rows = await db.entityManager
353
- .createQueryBuilder(target)
354
- .init(populateValue)
355
- // .addSelect(`${qb.alias}.${idColumn.referencedColumn}`)
356
- .where({ [idColumn.name]: referencedValues, [typeColumn.name]: uid })
357
- .execute({ mapResults: false });
358
-
359
- const map = _.groupBy(idColumn.name, rows);
360
-
361
- results.forEach((result) => {
362
- const matchingRows = map[result[idColumn.referencedColumn]];
363
-
364
- const matchingValue =
365
- attribute.relation === 'morphOne' ? _.first(matchingRows) : matchingRows;
366
-
367
- result[attributeName] = fromTargetRow(matchingValue);
368
- });
369
- } else if (targetAttribute.relation === 'morphToMany') {
370
- const { joinTable } = targetAttribute;
371
-
372
- const { joinColumn, morphColumn } = joinTable;
373
-
374
- const { idColumn, typeColumn } = morphColumn;
375
-
376
- const referencedValues = _.uniq(
377
- results.map((r) => r[idColumn.referencedColumn]).filter((value) => !_.isNil(value))
378
- );
379
-
380
- if (_.isEmpty(referencedValues)) {
381
- results.forEach((result) => {
382
- result[attributeName] = attribute.relation === 'morphOne' ? null : [];
383
- });
384
-
385
- return;
386
- }
387
-
388
- // find with join table
389
- const qb = db.entityManager.createQueryBuilder(target);
390
-
391
- const alias = qb.getAlias();
392
-
393
- const rows = await qb
394
- .init(populateValue)
395
- .join({
396
- alias,
397
- referencedTable: joinTable.name,
398
- referencedColumn: joinColumn.name,
399
- rootColumn: joinColumn.referencedColumn,
400
- rootTable: qb.alias,
401
- on: {
402
- ...(joinTable.on || {}),
403
- field: attributeName,
404
- },
405
- orderBy: _.mapValues((v) => populateValue.ordering || v, joinTable.orderBy),
406
- })
407
- .addSelect([`${alias}.${idColumn.name}`, `${alias}.${typeColumn.name}`])
408
- .where({
409
- [`${alias}.${idColumn.name}`]: referencedValues,
410
- [`${alias}.${typeColumn.name}`]: uid,
411
- })
412
- .execute({ mapResults: false });
413
-
414
- const map = _.groupBy(idColumn.name, rows);
415
-
416
- results.forEach((result) => {
417
- const matchingRows = map[result[idColumn.referencedColumn]];
418
-
419
- const matchingValue =
420
- attribute.relation === 'morphOne' ? _.first(matchingRows) : matchingRows;
421
-
422
- result[attributeName] = fromTargetRow(matchingValue);
423
- });
424
- }
425
- };
426
-
427
- const morphToMany = async (input, ctx) => {
428
- const { attribute, attributeName, results, populateValue } = input;
429
- const { db } = ctx;
430
-
431
- // find with join table
432
- const { joinTable } = attribute;
433
-
434
- const { joinColumn, morphColumn } = joinTable;
435
- const { idColumn, typeColumn, typeField = '__type' } = morphColumn;
436
-
437
- // fetch join table to create the ids map then do the same as morphToOne without the first
438
-
439
- const referencedValues = _.uniq(
440
- results.map((r) => r[joinColumn.referencedColumn]).filter((value) => !_.isNil(value))
441
- );
442
-
443
- const qb = db.entityManager.createQueryBuilder(joinTable.name);
444
-
445
- const joinRows = await qb
446
- .where({
447
- [joinColumn.name]: referencedValues,
448
- ...(joinTable.on || {}),
449
- // If the populateValue contains an "on" property,
450
- // only populate the types defined in it
451
- ...('on' in populateValue
452
- ? { [morphColumn.typeColumn.name]: Object.keys(populateValue.on) }
453
- : {}),
454
- })
455
- .orderBy([joinColumn.name, 'order'])
456
- .execute({ mapResults: false });
457
-
458
- const joinMap = _.groupBy(joinColumn.name, joinRows);
459
-
460
- const idsByType = joinRows.reduce((acc, result) => {
461
- const idValue = result[morphColumn.idColumn.name];
462
- const typeValue = result[morphColumn.typeColumn.name];
463
-
464
- if (!idValue || !typeValue) {
465
- return acc;
466
- }
467
-
468
- if (!_.has(typeValue, acc)) {
469
- acc[typeValue] = [];
470
- }
471
-
472
- acc[typeValue].push(idValue);
473
-
474
- return acc;
475
- }, {});
476
-
477
- const map = {};
478
- const { on, ...typePopulate } = populateValue;
479
-
480
- for (const type of Object.keys(idsByType)) {
481
- const ids = idsByType[type];
482
-
483
- // type was removed but still in morph relation
484
- if (!db.metadata.get(type)) {
485
- map[type] = {};
486
-
487
- continue;
488
- }
489
-
490
- const qb = db.entityManager.createQueryBuilder(type);
491
-
492
- const rows = await qb
493
- .init(on?.[type] ?? typePopulate)
494
- .addSelect(`${qb.alias}.${idColumn.referencedColumn}`)
495
- .where({ [idColumn.referencedColumn]: ids })
496
- .execute({ mapResults: false });
497
-
498
- map[type] = _.groupBy(idColumn.referencedColumn, rows);
499
- }
500
-
501
- results.forEach((result) => {
502
- const joinResults = joinMap[result[joinColumn.referencedColumn]] || [];
503
-
504
- const matchingRows = joinResults.flatMap((joinResult) => {
505
- const id = joinResult[idColumn.name];
506
- const type = joinResult[typeColumn.name];
507
-
508
- const fromTargetRow = (rowOrRows) => fromRow(db.metadata.get(type), rowOrRows);
509
-
510
- return (map[type][id] || []).map((row) => {
511
- return {
512
- [typeField]: type,
513
- ...fromTargetRow(row),
514
- };
515
- });
516
- });
517
-
518
- result[attributeName] = matchingRows;
519
- });
520
- };
521
-
522
- const morphToOne = async (input, ctx) => {
523
- const { attribute, attributeName, results, populateValue } = input;
524
- const { db } = ctx;
525
-
526
- const { morphColumn } = attribute;
527
- const { idColumn, typeColumn } = morphColumn;
528
-
529
- // make a map for each type what ids to return
530
- // make a nested map per id
531
-
532
- const idsByType = results.reduce((acc, result) => {
533
- const idValue = result[morphColumn.idColumn.name];
534
- const typeValue = result[morphColumn.typeColumn.name];
535
-
536
- if (!idValue || !typeValue) {
537
- return acc;
538
- }
539
-
540
- if (!_.has(typeValue, acc)) {
541
- acc[typeValue] = [];
542
- }
543
-
544
- acc[typeValue].push(idValue);
545
-
546
- return acc;
547
- }, {});
548
-
549
- const map = {};
550
- const { on, ...typePopulate } = populateValue;
551
-
552
- for (const type of Object.keys(idsByType)) {
553
- const ids = idsByType[type];
554
-
555
- // type was removed but still in morph relation
556
- if (!db.metadata.get(type)) {
557
- map[type] = {};
558
- return;
559
- }
560
-
561
- const qb = db.entityManager.createQueryBuilder(type);
562
-
563
- const rows = await qb
564
- .init(on?.[type] ?? typePopulate)
565
- .addSelect(`${qb.alias}.${idColumn.referencedColumn}`)
566
- .where({ [idColumn.referencedColumn]: ids })
567
- .execute({ mapResults: false });
568
-
569
- map[type] = _.groupBy(idColumn.referencedColumn, rows);
570
- }
571
-
572
- results.forEach((result) => {
573
- const id = result[idColumn.name];
574
- const type = result[typeColumn.name];
575
-
576
- if (!type || !id) {
577
- result[attributeName] = null;
578
- return;
579
- }
580
-
581
- const matchingRows = map[type][id];
582
-
583
- const fromTargetRow = (rowOrRows) => fromRow(db.metadata.get(type), rowOrRows);
584
-
585
- result[attributeName] = fromTargetRow(_.first(matchingRows));
586
- });
587
- };
588
-
589
- // TODO: Omit limit & offset to avoid needing a query per result to avoid making too many queries
590
- const pickPopulateParams = (populate) => {
591
- const fieldsToPick = [
592
- 'select',
593
- 'count',
594
- 'where',
595
- 'populate',
596
- 'orderBy',
597
- 'filters',
598
- 'ordering',
599
- 'on',
600
- ];
601
-
602
- if (populate.count !== true) {
603
- fieldsToPick.push('limit', 'offset');
604
- }
605
-
606
- return _.pick(fieldsToPick, populate);
607
- };
608
-
609
- const applyPopulate = async (results, populate, ctx) => {
610
- const { db, uid, qb } = ctx;
611
- const meta = db.metadata.get(uid);
612
-
613
- if (_.isEmpty(results)) {
614
- return results;
615
- }
616
-
617
- for (const attributeName of Object.keys(populate)) {
618
- const attribute = meta.attributes[attributeName];
619
- const targetMeta = db.metadata.get(attribute.target);
620
-
621
- const populateValue = {
622
- filters: qb.state.filters,
623
- ...pickPopulateParams(populate[attributeName]),
624
- };
625
-
626
- const isCount = populateValue.count === true;
627
-
628
- const input = { attribute, attributeName, results, populateValue, targetMeta, isCount };
629
-
630
- switch (attribute.relation) {
631
- case 'oneToOne':
632
- case 'manyToOne': {
633
- await XtoOne(input, ctx);
634
- break;
635
- }
636
- case 'oneToMany': {
637
- await oneToMany(input, ctx);
638
- break;
639
- }
640
- case 'manyToMany': {
641
- await manyToMany(input, ctx);
642
- break;
643
- }
644
- case 'morphOne':
645
- case 'morphMany': {
646
- await morphX(input, ctx);
647
- break;
648
- }
649
- case 'morphToMany': {
650
- await morphToMany(input, ctx);
651
- break;
652
- }
653
- case 'morphToOne': {
654
- await morphToOne(input, ctx);
655
- break;
656
- }
657
- default: {
658
- break;
659
- }
660
- }
661
- }
662
- };
663
-
664
- module.exports = applyPopulate;
@@ -1,9 +0,0 @@
1
- 'use strict';
2
-
3
- const applyPopulate = require('./apply');
4
- const processPopulate = require('./process');
5
-
6
- module.exports = {
7
- applyPopulate,
8
- processPopulate,
9
- };