graphile-build-pg 4.13.0 → 4.14.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.
- package/README.md +4 -13
- package/node8plus/GraphQLJSON.js +0 -11
- package/node8plus/GraphQLJSON.js.map +1 -1
- package/node8plus/PgLiveProvider.js +4 -11
- package/node8plus/PgLiveProvider.js.map +1 -1
- package/node8plus/QueryBuilder.js +42 -176
- package/node8plus/QueryBuilder.js.map +1 -1
- package/node8plus/index.js +8 -47
- package/node8plus/index.js.map +1 -1
- package/node8plus/inflections.js +9 -61
- package/node8plus/inflections.js.map +1 -1
- package/node8plus/omit.js +7 -22
- package/node8plus/omit.js.map +1 -1
- package/node8plus/parseIdentifier.js +0 -1
- package/node8plus/parseIdentifier.js.map +1 -1
- package/node8plus/pgPrepareAndRun.js +2 -14
- package/node8plus/pgPrepareAndRun.js.map +1 -1
- package/node8plus/plugins/PageInfoStartEndCursor.js +0 -4
- package/node8plus/plugins/PageInfoStartEndCursor.js.map +1 -1
- package/node8plus/plugins/PgAllRows.js +0 -29
- package/node8plus/plugins/PgAllRows.js.map +1 -1
- package/node8plus/plugins/PgBackwardRelationPlugin.js +2 -41
- package/node8plus/plugins/PgBackwardRelationPlugin.js.map +1 -1
- package/node8plus/plugins/PgBasicsPlugin.js +20 -147
- package/node8plus/plugins/PgBasicsPlugin.js.map +1 -1
- package/node8plus/plugins/PgColumnDeprecationPlugin.js +2 -5
- package/node8plus/plugins/PgColumnDeprecationPlugin.js.map +1 -1
- package/node8plus/plugins/PgColumnsPlugin.js +4 -17
- package/node8plus/plugins/PgColumnsPlugin.js.map +1 -1
- package/node8plus/plugins/PgComputedColumnsPlugin.js +4 -19
- package/node8plus/plugins/PgComputedColumnsPlugin.js.map +1 -1
- package/node8plus/plugins/PgConditionComputedColumnPlugin.js +12 -23
- package/node8plus/plugins/PgConditionComputedColumnPlugin.js.map +1 -1
- package/node8plus/plugins/PgConnectionArgCondition.js +1 -9
- package/node8plus/plugins/PgConnectionArgCondition.js.map +1 -1
- package/node8plus/plugins/PgConnectionArgFirstLastBeforeAfter.js +0 -12
- package/node8plus/plugins/PgConnectionArgFirstLastBeforeAfter.js.map +1 -1
- package/node8plus/plugins/PgConnectionArgOrderBy.js +2 -19
- package/node8plus/plugins/PgConnectionArgOrderBy.js.map +1 -1
- package/node8plus/plugins/PgConnectionArgOrderByDefaultValue.js +0 -6
- package/node8plus/plugins/PgConnectionArgOrderByDefaultValue.js.map +1 -1
- package/node8plus/plugins/PgConnectionTotalCount.js +0 -8
- package/node8plus/plugins/PgConnectionTotalCount.js.map +1 -1
- package/node8plus/plugins/PgForwardRelationPlugin.js +2 -25
- package/node8plus/plugins/PgForwardRelationPlugin.js.map +1 -1
- package/node8plus/plugins/PgIntrospectionPlugin.js +91 -180
- package/node8plus/plugins/PgIntrospectionPlugin.js.flow +30 -2
- package/node8plus/plugins/PgIntrospectionPlugin.js.map +1 -1
- package/node8plus/plugins/PgJWTPlugin.js +2 -18
- package/node8plus/plugins/PgJWTPlugin.js.map +1 -1
- package/node8plus/plugins/PgMutationCreatePlugin.js +0 -18
- package/node8plus/plugins/PgMutationCreatePlugin.js.map +1 -1
- package/node8plus/plugins/PgMutationPayloadEdgePlugin.js +4 -25
- package/node8plus/plugins/PgMutationPayloadEdgePlugin.js.map +1 -1
- package/node8plus/plugins/PgMutationProceduresPlugin.js +0 -6
- package/node8plus/plugins/PgMutationProceduresPlugin.js.map +1 -1
- package/node8plus/plugins/PgMutationUpdateDeletePlugin.js +14 -49
- package/node8plus/plugins/PgMutationUpdateDeletePlugin.js.flow +5 -2
- package/node8plus/plugins/PgMutationUpdateDeletePlugin.js.map +1 -1
- package/node8plus/plugins/PgNodeAliasPostGraphile.js +0 -6
- package/node8plus/plugins/PgNodeAliasPostGraphile.js.map +1 -1
- package/node8plus/plugins/PgOrderAllColumnsPlugin.js +0 -4
- package/node8plus/plugins/PgOrderAllColumnsPlugin.js.map +1 -1
- package/node8plus/plugins/PgOrderByPrimaryKeyPlugin.js +0 -6
- package/node8plus/plugins/PgOrderByPrimaryKeyPlugin.js.map +1 -1
- package/node8plus/plugins/PgOrderComputedColumnsPlugin.js +10 -14
- package/node8plus/plugins/PgOrderComputedColumnsPlugin.js.map +1 -1
- package/node8plus/plugins/PgQueryProceduresPlugin.js +4 -16
- package/node8plus/plugins/PgQueryProceduresPlugin.js.map +1 -1
- package/node8plus/plugins/PgRecordFunctionConnectionPlugin.js +3 -20
- package/node8plus/plugins/PgRecordFunctionConnectionPlugin.js.map +1 -1
- package/node8plus/plugins/PgRecordReturnTypesPlugin.js +11 -16
- package/node8plus/plugins/PgRecordReturnTypesPlugin.js.map +1 -1
- package/node8plus/plugins/PgRowByUniqueConstraint.js +4 -25
- package/node8plus/plugins/PgRowByUniqueConstraint.js.map +1 -1
- package/node8plus/plugins/PgRowNode.js +0 -32
- package/node8plus/plugins/PgRowNode.js.map +1 -1
- package/node8plus/plugins/PgScalarFunctionConnectionPlugin.js +3 -17
- package/node8plus/plugins/PgScalarFunctionConnectionPlugin.js.map +1 -1
- package/node8plus/plugins/PgTablesPlugin.js +7 -59
- package/node8plus/plugins/PgTablesPlugin.js.map +1 -1
- package/node8plus/plugins/PgTypesPlugin.js +140 -240
- package/node8plus/plugins/PgTypesPlugin.js.flow +76 -23
- package/node8plus/plugins/PgTypesPlugin.js.map +1 -1
- package/node8plus/plugins/addStartEndCursor.js +2 -5
- package/node8plus/plugins/addStartEndCursor.js.map +1 -1
- package/node8plus/plugins/debugSql.js +1 -16
- package/node8plus/plugins/debugSql.js.map +1 -1
- package/node8plus/plugins/introspectionQuery.js +3 -4
- package/node8plus/plugins/introspectionQuery.js.flow +11 -3
- package/node8plus/plugins/introspectionQuery.js.map +1 -1
- package/node8plus/plugins/makeProcField.js +40 -90
- package/node8plus/plugins/makeProcField.js.map +1 -1
- package/node8plus/plugins/pgField.js +2 -7
- package/node8plus/plugins/pgField.js.map +1 -1
- package/node8plus/plugins/viaTemporaryTable.js +6 -12
- package/node8plus/plugins/viaTemporaryTable.js.map +1 -1
- package/node8plus/postgresInterval.js +4 -4
- package/node8plus/postgresInterval.js.map +1 -1
- package/node8plus/queryFromResolveDataFactory.js +33 -77
- package/node8plus/queryFromResolveDataFactory.js.map +1 -1
- package/node8plus/utils.js +8 -9
- package/node8plus/utils.js.map +1 -1
- package/node8plus/withPgClient.js +4 -26
- package/node8plus/withPgClient.js.map +1 -1
- package/package.json +4 -4
|
@@ -4,35 +4,24 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
-
|
|
8
7
|
var _QueryBuilder = _interopRequireDefault(require("./QueryBuilder"));
|
|
9
|
-
|
|
10
8
|
var sql = _interopRequireWildcard(require("pg-sql2"));
|
|
11
|
-
|
|
12
9
|
var _isSafeInteger = _interopRequireDefault(require("lodash/isSafeInteger"));
|
|
13
|
-
|
|
14
10
|
var _assert = _interopRequireDefault(require("assert"));
|
|
15
|
-
|
|
16
11
|
var _util = require("util");
|
|
17
|
-
|
|
18
12
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
19
|
-
|
|
20
13
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
21
|
-
|
|
22
14
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
23
|
-
|
|
15
|
+
// eslint-disable-next-line flowtype/no-weak-types
|
|
24
16
|
const identity = _ => _ !== null && _ !== undefined;
|
|
25
|
-
|
|
26
17
|
function assertSafeName(name) {
|
|
27
18
|
if (typeof name !== "string") {
|
|
28
19
|
throw new Error(`Expected name to be a string; instead received '${(0, _util.inspect)(name)}'`);
|
|
29
20
|
}
|
|
30
|
-
|
|
31
21
|
if (!/^[@a-zA-Z0-9_]{1,63}$/.test(name)) {
|
|
32
22
|
throw new Error(`Name '${name}' is not safe - either it is too long, too short, or has invalid characters`);
|
|
33
23
|
}
|
|
34
24
|
}
|
|
35
|
-
|
|
36
25
|
var _default = (queryBuilderOptions = {}) => (from, fromAlias, resolveData, inOptions, withBuilder, context = {}, rootValue) => {
|
|
37
26
|
const {
|
|
38
27
|
pgQuery,
|
|
@@ -45,8 +34,8 @@ var _default = (queryBuilderOptions = {}) => (from, fromAlias, resolveData, inOp
|
|
|
45
34
|
calculateHasNextPage,
|
|
46
35
|
calculateHasPreviousPage,
|
|
47
36
|
usesCursor: explicitlyUsesCursor
|
|
48
|
-
} = resolveData;
|
|
49
|
-
|
|
37
|
+
} = resolveData;
|
|
38
|
+
// Push a query container for aggregates
|
|
50
39
|
if (pgAggregateQuery && pgAggregateQuery.length || pgNamedQuery.length) {
|
|
51
40
|
pgNamedQueryContainer.push({
|
|
52
41
|
name: "aggregates",
|
|
@@ -63,9 +52,8 @@ var _default = (queryBuilderOptions = {}) => (from, fromAlias, resolveData, inOp
|
|
|
63
52
|
where ${queryBuilder.buildWhereClause(false, false, options)}
|
|
64
53
|
)`
|
|
65
54
|
});
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
|
|
55
|
+
}
|
|
56
|
+
// Convert pgAggregateQuery to pgNamedQueryContainer/pgNamedQuery combo
|
|
69
57
|
if (pgAggregateQuery && pgAggregateQuery.length) {
|
|
70
58
|
// And a query for each previous query
|
|
71
59
|
pgAggregateQuery.forEach(query => {
|
|
@@ -75,9 +63,9 @@ var _default = (queryBuilderOptions = {}) => (from, fromAlias, resolveData, inOp
|
|
|
75
63
|
});
|
|
76
64
|
});
|
|
77
65
|
}
|
|
78
|
-
|
|
79
66
|
const preventAsterisk = pgDontUseAsterisk ? pgDontUseAsterisk.length > 0 : false;
|
|
80
|
-
const options = {
|
|
67
|
+
const options = {
|
|
68
|
+
...inOptions,
|
|
81
69
|
// Allow pgDontUseAsterisk to override useAsterisk
|
|
82
70
|
useAsterisk: inOptions.useAsterisk && !preventAsterisk
|
|
83
71
|
};
|
|
@@ -85,17 +73,14 @@ var _default = (queryBuilderOptions = {}) => (from, fromAlias, resolveData, inOp
|
|
|
85
73
|
const rawCursorPrefix = reallyRawCursorPrefix && reallyRawCursorPrefix.filter(identity);
|
|
86
74
|
const queryBuilder = new _QueryBuilder.default(queryBuilderOptions, context, rootValue);
|
|
87
75
|
queryBuilder.from(from, fromAlias ? fromAlias : undefined);
|
|
88
|
-
|
|
89
76
|
if (withBuilder) {
|
|
90
77
|
withBuilder(queryBuilder);
|
|
91
78
|
}
|
|
92
|
-
|
|
93
79
|
if (pgQuery) {
|
|
94
80
|
for (let i = 0, l = pgQuery.length; i < l; i++) {
|
|
95
81
|
pgQuery[i](queryBuilder, resolveData);
|
|
96
82
|
}
|
|
97
83
|
}
|
|
98
|
-
|
|
99
84
|
function generateNextPrevPageSql(sqlQueryAlias, canHaveCursorInWhere, queryHasBefore, queryHasFirst, offset = 0, invert = false) {
|
|
100
85
|
/*
|
|
101
86
|
* Strap in, 'coz this function gets hairy!
|
|
@@ -164,6 +149,7 @@ var _default = (queryBuilderOptions = {}) => (from, fromAlias, resolveData, inOp
|
|
|
164
149
|
* hasNextPage we always pretend we're determining `hasNextPage`, and we
|
|
165
150
|
* just invert everything.
|
|
166
151
|
*/
|
|
152
|
+
|
|
167
153
|
const sqlCommonUnbounded = sql.fragment`\
|
|
168
154
|
select 1
|
|
169
155
|
from ${queryBuilder.getTableExpression()} as ${queryBuilder.getTableAlias()}`;
|
|
@@ -182,29 +168,26 @@ from ${queryBuilder.getTableExpression()} as ${queryBuilder.getTableAlias()}`;
|
|
|
182
168
|
* upper bound. In hasPreviousPage mode (invert === true), it represents
|
|
183
169
|
* everything from `(before || END)` backwards, with no lower bound.
|
|
184
170
|
*/
|
|
185
|
-
|
|
186
171
|
const sqlCommon = sql.fragment`\
|
|
187
172
|
${sqlCommonUnbounded}
|
|
188
173
|
where ${queryBuilder.buildWhereClause(!invert, invert, options)}`;
|
|
174
|
+
|
|
189
175
|
/*
|
|
190
176
|
* Since the offset makes the diagram asymmetric, if offset === 0
|
|
191
177
|
* then the diagram is symmetric and things are simplified a little.
|
|
192
178
|
*/
|
|
193
|
-
|
|
194
179
|
const isForwardOrSymmetric = !invert || offset === 0;
|
|
195
|
-
|
|
196
180
|
if (!isForwardOrSymmetric) {
|
|
197
181
|
(0, _assert.default)(invert);
|
|
198
|
-
(0, _assert.default)(offset > 0);
|
|
182
|
+
(0, _assert.default)(offset > 0);
|
|
183
|
+
// We're looking for a previous page, and there's an offset, so lets just
|
|
199
184
|
// assume there's a previous page where offset is smaller.
|
|
200
|
-
|
|
201
185
|
return sql.literal(true);
|
|
202
186
|
} else if (canHaveCursorInWhere) {
|
|
203
187
|
(0, _assert.default)(isForwardOrSymmetric);
|
|
204
|
-
|
|
205
188
|
if (!queryHasBefore && !queryHasFirst) {
|
|
206
|
-
(0, _assert.default)(isForwardOrSymmetric);
|
|
207
|
-
|
|
189
|
+
(0, _assert.default)(isForwardOrSymmetric);
|
|
190
|
+
// There can be no next page since there's no upper bound
|
|
208
191
|
return sql.literal(false);
|
|
209
192
|
} else if (queryHasBefore && !queryHasFirst) {
|
|
210
193
|
/*
|
|
@@ -224,8 +207,8 @@ exists(
|
|
|
224
207
|
and not (${queryBuilder.buildWhereBoundClause(invert)})
|
|
225
208
|
)`;
|
|
226
209
|
} else {
|
|
227
|
-
(0, _assert.default)(queryHasFirst);
|
|
228
|
-
|
|
210
|
+
(0, _assert.default)(queryHasFirst);
|
|
211
|
+
// queryHasBefore could be true or false.
|
|
229
212
|
/*
|
|
230
213
|
* There's a few ways that we could determine if there's a next page.
|
|
231
214
|
*
|
|
@@ -245,7 +228,6 @@ exists(
|
|
|
245
228
|
*/
|
|
246
229
|
// Drop the `first` limit, see if there are any records that aren't
|
|
247
230
|
// already in the list we've fetched.
|
|
248
|
-
|
|
249
231
|
return sql.fragment`\
|
|
250
232
|
exists(
|
|
251
233
|
${sqlCommon}
|
|
@@ -255,22 +237,20 @@ exists(
|
|
|
255
237
|
}
|
|
256
238
|
} else {
|
|
257
239
|
(0, _assert.default)(!invert || offset === 0); // isForwardOrSymmetric
|
|
258
|
-
|
|
259
|
-
|
|
240
|
+
(0, _assert.default)(!canHaveCursorInWhere);
|
|
241
|
+
// We're dealing with LIMIT/OFFSET pagination here, which means `natural`
|
|
260
242
|
// cursors, so the `queryBuilder` factors the before/after, first/last
|
|
261
243
|
// into the limit / offset.
|
|
262
|
-
|
|
263
244
|
const {
|
|
264
245
|
limit
|
|
265
246
|
} = queryBuilder.getFinalLimitAndOffset();
|
|
266
|
-
|
|
267
247
|
if (limit == null) {
|
|
268
248
|
// If paginating backwards, then offset > 0 has already been dealt
|
|
269
249
|
// with. Unbounded, so there's no next page.
|
|
270
250
|
return sql.fragment`false`;
|
|
271
251
|
} else if (invert) {
|
|
272
|
-
(0, _assert.default)(offset === 0);
|
|
273
|
-
|
|
252
|
+
(0, _assert.default)(offset === 0);
|
|
253
|
+
// Paginating backwards and there's no offset (which factors in before/after), so there's no previous page.
|
|
274
254
|
return sql.fragment`false`;
|
|
275
255
|
} else {
|
|
276
256
|
(0, _assert.default)(!invert);
|
|
@@ -280,7 +260,6 @@ exists(
|
|
|
280
260
|
*
|
|
281
261
|
* We want to see if there's more than limit+offset records in sqlCommon.
|
|
282
262
|
*/
|
|
283
|
-
|
|
284
263
|
return sql.fragment`\
|
|
285
264
|
exists(
|
|
286
265
|
${sqlCommon}
|
|
@@ -289,15 +268,12 @@ exists(
|
|
|
289
268
|
}
|
|
290
269
|
}
|
|
291
270
|
}
|
|
292
|
-
|
|
293
271
|
const getPgCursorPrefix = () => rawCursorPrefix && rawCursorPrefix.length > 0 ? rawCursorPrefix : queryBuilder.data.cursorPrefix.map(val => sql.literal(val));
|
|
294
|
-
|
|
295
272
|
if (options.withPagination || options.withPaginationAsFields || options.withCursor) {
|
|
296
273
|
// Sometimes we need a __cursor even if it's not a collection; e.g. to get the edge field on a mutation
|
|
297
274
|
if (usesCursor) {
|
|
298
275
|
queryBuilder.selectCursor(() => {
|
|
299
276
|
const orderBy = queryBuilder.getOrderByExpressionsAndDirections().map(([expr]) => expr);
|
|
300
|
-
|
|
301
277
|
if (queryBuilder.isOrderUnique() && orderBy.length > 0) {
|
|
302
278
|
return sql.fragment`json_build_array(${sql.join([...getPgCursorPrefix(), sql.fragment`json_build_array(${sql.join(orderBy, ", ")})`], ", ")})`;
|
|
303
279
|
} else {
|
|
@@ -307,46 +283,37 @@ exists(
|
|
|
307
283
|
* query with limit offset is in a subquery, so our row_number()
|
|
308
284
|
* call doesn't know about it. Here we add the offset back in
|
|
309
285
|
* again. See matching NOTE in QueryBuilder.js.
|
|
310
|
-
*/
|
|
311
|
-
options.useAsterisk ? sql.fragment`${sql.literal(queryBuilder.getFinalOffset() || 0)} + ` : sql.fragment``}(row_number() over (partition by 1)))`;
|
|
286
|
+
*/options.useAsterisk ? sql.fragment`${sql.literal(queryBuilder.getFinalOffset() || 0)} + ` : sql.fragment``}(row_number() over (partition by 1)))`;
|
|
312
287
|
}
|
|
313
288
|
});
|
|
314
289
|
}
|
|
315
290
|
}
|
|
316
|
-
|
|
317
291
|
if (options.withPagination || options.withPaginationAsFields) {
|
|
318
292
|
queryBuilder.setCursorComparator((cursorValue, isAfter) => {
|
|
319
293
|
function badCursor() {
|
|
320
294
|
queryBuilder.whereBound(sql.fragment`false`, isAfter);
|
|
321
295
|
}
|
|
322
|
-
|
|
323
296
|
const orderByExpressionsAndDirections = queryBuilder.getOrderByExpressionsAndDirections();
|
|
324
|
-
|
|
325
297
|
if (orderByExpressionsAndDirections.length > 0) {
|
|
326
298
|
if (!queryBuilder.isOrderUnique()) {
|
|
327
299
|
throw new Error("The order supplied is not unique, so before/after cursors cannot be used. Please ensure the supplied order includes all the columns from the primary key or a unique constraint.");
|
|
328
300
|
}
|
|
329
|
-
|
|
330
301
|
const rawPrefixes = cursorValue.slice(0, cursorValue.length - 1);
|
|
331
302
|
const rawCursors = cursorValue[cursorValue.length - 1];
|
|
332
|
-
|
|
333
303
|
if (rawPrefixes.length !== getPgCursorPrefix().length) {
|
|
334
304
|
badCursor();
|
|
335
305
|
return;
|
|
336
306
|
}
|
|
337
|
-
|
|
338
307
|
if (!Array.isArray(rawCursors)) {
|
|
339
308
|
badCursor();
|
|
340
309
|
return;
|
|
341
310
|
}
|
|
342
|
-
|
|
343
311
|
let sqlFilter = sql.fragment`false`;
|
|
344
312
|
const sqlCursors = rawCursors.map(val => sql.value(val));
|
|
345
|
-
|
|
346
313
|
for (let i = orderByExpressionsAndDirections.length - 1; i >= 0; i--) {
|
|
347
|
-
const [sqlExpression, ascending] = orderByExpressionsAndDirections[i];
|
|
314
|
+
const [sqlExpression, ascending] = orderByExpressionsAndDirections[i];
|
|
315
|
+
// If ascending and isAfter then >
|
|
348
316
|
// If ascending and isBefore then <
|
|
349
|
-
|
|
350
317
|
const comparison = Number(ascending) ^ Number(!isAfter) ? sql.fragment`>` : sql.fragment`<`;
|
|
351
318
|
const sqlOldFilter = sqlFilter;
|
|
352
319
|
sqlFilter = sql.fragment`\
|
|
@@ -359,17 +326,17 @@ OR\
|
|
|
359
326
|
${sqlOldFilter}\
|
|
360
327
|
)\
|
|
361
328
|
)`;
|
|
362
|
-
}
|
|
363
|
-
// TODO:v5: we should be able to do this in JS-land rather than SQL-land
|
|
364
|
-
|
|
329
|
+
}
|
|
365
330
|
|
|
331
|
+
// Check the cursor prefixes apply
|
|
332
|
+
// TODO:v5: we should be able to do this in JS-land rather than SQL-land
|
|
366
333
|
sqlFilter = sql.fragment`(((${sql.join(getPgCursorPrefix(), ", ")}) = (${sql.join(rawPrefixes.map(val => sql.value(val)), ", ")})) AND (${sqlFilter}))`;
|
|
367
334
|
queryBuilder.whereBound(sqlFilter, isAfter);
|
|
368
|
-
} else if (cursorValue[0] === "natural" && (0, _isSafeInteger.default)(cursorValue[1]) &&
|
|
335
|
+
} else if (cursorValue[0] === "natural" && (0, _isSafeInteger.default)(cursorValue[1]) &&
|
|
336
|
+
// $FlowFixMe: we know this is a number
|
|
369
337
|
cursorValue[1] >= 0) {
|
|
370
338
|
// $FlowFixMe: we know this is a number
|
|
371
339
|
const cursorValue1 = cursorValue[1];
|
|
372
|
-
|
|
373
340
|
if (isAfter) {
|
|
374
341
|
queryBuilder.offset(() => cursorValue1);
|
|
375
342
|
} else {
|
|
@@ -385,7 +352,8 @@ OR\
|
|
|
385
352
|
const query = queryBuilder.build(options);
|
|
386
353
|
const haveFields = queryBuilder.getSelectFieldsCount() > 0;
|
|
387
354
|
const sqlQueryAlias = sql.identifier(Symbol());
|
|
388
|
-
const sqlSummaryAlias = sql.identifier(Symbol());
|
|
355
|
+
const sqlSummaryAlias = sql.identifier(Symbol());
|
|
356
|
+
//
|
|
389
357
|
// Tables should ALWAYS push their PK onto the order stack, if this isn't
|
|
390
358
|
// present then we're either dealing with a view or a table without a PK.
|
|
391
359
|
// Either way, we don't have anything to guarantee uniqueness so we need to
|
|
@@ -394,7 +362,6 @@ OR\
|
|
|
394
362
|
// TODO: support unique keys in PgAllRows etc
|
|
395
363
|
// TODO: add a warning for cursor-based pagination when using the fallback
|
|
396
364
|
// TODO: if it is a view maybe add a warning encouraging pgViewUniqueKey
|
|
397
|
-
|
|
398
365
|
const canHaveCursorInWhere = queryBuilder.getOrderByExpressionsAndDirections().length > 0 && queryBuilder.isOrderUnique();
|
|
399
366
|
const queryHasBefore = queryBuilder.compiledData.whereBound.upper.length > 0;
|
|
400
367
|
const queryHasAfter = queryBuilder.compiledData.whereBound.lower.length > 0;
|
|
@@ -406,19 +373,15 @@ OR\
|
|
|
406
373
|
const sqlWith = haveFields ? sql.fragment`with ${sqlQueryAlias} as (${query}), ${sqlSummaryAlias} as (select json_agg(to_json(${sqlQueryAlias})) as data from ${sqlQueryAlias})` : sql.fragment``;
|
|
407
374
|
const sqlFrom = sql.fragment``;
|
|
408
375
|
const fields = [];
|
|
409
|
-
|
|
410
376
|
if (haveFields) {
|
|
411
377
|
fields.push([sql.fragment`coalesce((select ${sqlSummaryAlias}.data from ${sqlSummaryAlias}), '[]'::json)`, "data"]);
|
|
412
|
-
|
|
413
378
|
if (calculateHasNextPage) {
|
|
414
379
|
fields.push([hasNextPage, "hasNextPage"]);
|
|
415
380
|
}
|
|
416
|
-
|
|
417
381
|
if (calculateHasPreviousPage) {
|
|
418
382
|
fields.push([hasPreviousPage, "hasPreviousPage"]);
|
|
419
383
|
}
|
|
420
384
|
}
|
|
421
|
-
|
|
422
385
|
if (pgNamedQuery && pgNamedQuery.length) {
|
|
423
386
|
const groups = {};
|
|
424
387
|
pgNamedQuery.forEach(({
|
|
@@ -426,35 +389,30 @@ OR\
|
|
|
426
389
|
query
|
|
427
390
|
}) => {
|
|
428
391
|
assertSafeName(name);
|
|
429
|
-
|
|
430
392
|
if (!groups[name]) {
|
|
431
393
|
groups[name] = [];
|
|
432
394
|
}
|
|
433
|
-
|
|
434
395
|
groups[name].push(query);
|
|
435
396
|
});
|
|
436
397
|
Object.keys(groups).forEach(groupName => {
|
|
437
|
-
const queryCallbacks = groups[groupName];
|
|
398
|
+
const queryCallbacks = groups[groupName];
|
|
438
399
|
|
|
400
|
+
// Get container
|
|
439
401
|
const containers = pgNamedQueryContainer.filter(c => c.name === groupName);
|
|
440
|
-
|
|
441
402
|
if (containers.length === 0) {
|
|
442
403
|
throw new Error(`${queryCallbacks.length} pgNamedQuery entries with name: '${groupName}' existed, but there was no matching pgNamedQueryContainer.`);
|
|
443
404
|
}
|
|
444
|
-
|
|
445
405
|
if (containers.length > 1) {
|
|
446
406
|
throw new Error(`${containers.length} pgNamedQueryContainer entries with name: '${groupName}' existed, but there should be exactly one.`);
|
|
447
407
|
}
|
|
448
|
-
|
|
449
408
|
const container = containers[0];
|
|
450
409
|
const innerQueryBuilder = new _QueryBuilder.default(queryBuilderOptions, context, rootValue);
|
|
451
410
|
innerQueryBuilder.from(queryBuilder.getTableExpression(), queryBuilder.getTableAlias());
|
|
452
|
-
|
|
453
411
|
for (let i = 0, l = queryCallbacks.length; i < l; i++) {
|
|
454
412
|
queryCallbacks[i](innerQueryBuilder);
|
|
455
|
-
}
|
|
456
|
-
|
|
413
|
+
}
|
|
457
414
|
|
|
415
|
+
// Generate the SQL statement (e.g. `select ${innerQueryBuilder.build({onlyJsonField: true})} from ${queryBuilder.getTableExpression()} as ...`)
|
|
458
416
|
const aggregatesSql = container.query({
|
|
459
417
|
queryBuilder,
|
|
460
418
|
innerQueryBuilder,
|
|
@@ -463,7 +421,6 @@ OR\
|
|
|
463
421
|
fields.push([aggregatesSql, groupName]);
|
|
464
422
|
});
|
|
465
423
|
}
|
|
466
|
-
|
|
467
424
|
if (options.withPaginationAsFields) {
|
|
468
425
|
return sql.fragment`${sqlWith} select ${sql.join(fields.map(([expr, alias]) => sql.fragment`${expr} as ${sql.identifier(alias)}`), ", ")} ${sqlFrom}`;
|
|
469
426
|
} else {
|
|
@@ -474,6 +431,5 @@ OR\
|
|
|
474
431
|
return query;
|
|
475
432
|
}
|
|
476
433
|
};
|
|
477
|
-
|
|
478
434
|
exports.default = _default;
|
|
479
435
|
//# sourceMappingURL=queryFromResolveDataFactory.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/queryFromResolveDataFactory.js"],"names":["identity","_","undefined","assertSafeName","name","Error","test","queryBuilderOptions","from","fromAlias","resolveData","inOptions","withBuilder","context","rootValue","pgQuery","pgAggregateQuery","pgNamedQueryContainer","pgNamedQuery","pgCursorPrefix","reallyRawCursorPrefix","pgDontUseAsterisk","calculateHasNextPage","calculateHasPreviousPage","usesCursor","explicitlyUsesCursor","length","push","query","queryBuilder","options","innerQueryBuilder","sql","fragment","build","onlyJsonField","getTableExpression","getTableAlias","buildWhereClause","forEach","preventAsterisk","useAsterisk","rawCursorPrefix","filter","QueryBuilder","i","l","generateNextPrevPageSql","sqlQueryAlias","canHaveCursorInWhere","queryHasBefore","queryHasFirst","offset","invert","sqlCommonUnbounded","sqlCommon","isForwardOrSymmetric","literal","buildWhereBoundClause","getSelectCursor","blank","value","limit","getFinalLimitAndOffset","getPgCursorPrefix","data","cursorPrefix","map","val","withPagination","withPaginationAsFields","withCursor","selectCursor","orderBy","getOrderByExpressionsAndDirections","expr","isOrderUnique","join","getFinalOffset","setCursorComparator","cursorValue","isAfter","badCursor","whereBound","orderByExpressionsAndDirections","rawPrefixes","slice","rawCursors","Array","isArray","sqlFilter","sqlCursors","sqlExpression","ascending","comparison","Number","sqlOldFilter","null","cursorValue1","getOffset","Math","max","haveFields","getSelectFieldsCount","identifier","Symbol","sqlSummaryAlias","compiledData","upper","queryHasAfter","lower","queryHasZeroLimit","getFinalLimit","first","queryHasLast","last","hasNextPage","hasPreviousPage","sqlWith","sqlFrom","fields","groups","Object","keys","groupName","queryCallbacks","containers","c","container","aggregatesSql","alias","jsonbBuildObject"],"mappings":"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,EAKEC,MAAM,GAAG,CALX,EAMEC,MAAM,GAAG,KANX,EAOE;AACA;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEM,UAAMC,kBAAkB,GAAGtB,GAAG,CAACC,QAAS;AAC9C;AACA,OAAOJ,YAAY,CAACO,kBAAb,EAAkC,OAAMP,YAAY,CAACQ,aAAb,EAA6B,EAFtE;AAGA;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACM,UAAMkB,SAAS,GAAGvB,GAAG,CAACC,QAAS;AACrC,EAAEqB,kBAAmB;AACrB,QAAQzB,YAAY,CAACS,gBAAb,CAA8B,CAACe,MAA/B,EAAuCA,MAAvC,EAA+CvB,OAA/C,CAAwD,EAF1D;AAIA;AACN;AACA;AACA;;AACM,UAAM0B,oBAAoB,GAAG,CAACH,MAAD,IAAWD,MAAM,KAAK,CAAnD;;AAEA,QAAI,CAACI,oBAAL,EAA2B;AACzB,2BAAOH,MAAP;AACA,2BAAOD,MAAM,GAAG,CAAhB,EAFyB,CAGzB;AACA;;AACA,aAAOpB,GAAG,CAACyB,OAAJ,CAAY,IAAZ,CAAP;AACD,KAND,MAMO,IAAIR,oBAAJ,EAA0B;AAC/B,2BAAOO,oBAAP;;AACA,UAAI,CAACN,cAAD,IAAmB,CAACC,aAAxB,EAAuC;AACrC,6BAAOK,oBAAP,EADqC,CAErC;;AACA,eAAOxB,GAAG,CAACyB,OAAJ,CAAY,KAAZ,CAAP;AACD,OAJD,MAIO,IAAIP,cAAc,IAAI,CAACC,aAAvB,EAAsC;AAC3C;AACV;AACA;AACA;AACA;AACA;AACA;AACA;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","sourcesContent":["// @flow\nimport QueryBuilder from \"./QueryBuilder\";\nimport type { QueryBuilderOptions } from \"./QueryBuilder\";\nimport type { RawAlias } from \"./QueryBuilder\";\nimport * as sql from \"pg-sql2\";\nimport type { SQL } from \"pg-sql2\";\nimport type { DataForType } from \"graphile-build\";\nimport isSafeInteger from \"lodash/isSafeInteger\";\nimport assert from \"assert\";\nimport { inspect } from \"util\";\n\n// eslint-disable-next-line flowtype/no-weak-types\ntype GraphQLContext = any;\n\nconst identity = _ => _ !== null && _ !== undefined;\n\nfunction assertSafeName(name: mixed) {\n if (typeof name !== \"string\") {\n throw new Error(\n `Expected name to be a string; instead received '${inspect(name)}'`\n );\n }\n if (!/^[@a-zA-Z0-9_]{1,63}$/.test(name)) {\n throw new Error(\n `Name '${name}' is not safe - either it is too long, too short, or has invalid characters`\n );\n }\n}\n\nexport default (queryBuilderOptions: QueryBuilderOptions = {}) =>\n (\n from: SQL,\n fromAlias: ?SQL,\n resolveData: DataForType,\n inOptions: {\n withPagination?: boolean,\n withPaginationAsFields?: boolean,\n asJson?: boolean,\n asJsonAggregate?: boolean,\n addNullCase?: boolean,\n addNotDistinctFromNullCase?: boolean,\n onlyJsonField?: boolean,\n useAsterisk?: boolean,\n withCursor?: boolean,\n },\n // TODO:v5: context is not optional\n withBuilder?: ((builder: QueryBuilder) => void) | null | void,\n context?: GraphQLContext = {},\n rootValue?: any // eslint-disable-line flowtype/no-weak-types\n ) => {\n const {\n pgQuery,\n pgAggregateQuery, // Shorthand for using pgNamedQueryContainer/pgNamedQuery combo\n pgNamedQueryContainer = [],\n pgNamedQuery = [],\n pgCursorPrefix: reallyRawCursorPrefix,\n pgDontUseAsterisk,\n calculateHasNextPage,\n calculateHasPreviousPage,\n usesCursor: explicitlyUsesCursor,\n } = resolveData;\n // Push a query container for aggregates\n if ((pgAggregateQuery && pgAggregateQuery.length) || pgNamedQuery.length) {\n pgNamedQueryContainer.push({\n name: \"aggregates\",\n query: ({ queryBuilder, options, innerQueryBuilder }) => sql.fragment`\\\n(\n select ${innerQueryBuilder.build({ onlyJsonField: true })}\n from ${queryBuilder.getTableExpression()} as ${queryBuilder.getTableAlias()}\n where ${queryBuilder.buildWhereClause(false, false, options)}\n)`,\n });\n }\n // Convert pgAggregateQuery to pgNamedQueryContainer/pgNamedQuery combo\n if (pgAggregateQuery && pgAggregateQuery.length) {\n // And a query for each previous query\n pgAggregateQuery.forEach(query => {\n pgNamedQuery.push({ name: \"aggregates\", query });\n });\n }\n\n const preventAsterisk = pgDontUseAsterisk\n ? pgDontUseAsterisk.length > 0\n : false;\n const options = {\n ...inOptions,\n // Allow pgDontUseAsterisk to override useAsterisk\n useAsterisk: inOptions.useAsterisk && !preventAsterisk,\n };\n\n const usesCursor: boolean =\n (explicitlyUsesCursor && explicitlyUsesCursor.length > 0) ||\n (calculateHasNextPage && calculateHasNextPage.length > 0) ||\n (calculateHasPreviousPage && calculateHasPreviousPage.length > 0) ||\n false;\n const rawCursorPrefix =\n reallyRawCursorPrefix && reallyRawCursorPrefix.filter(identity);\n\n const queryBuilder = new QueryBuilder(\n queryBuilderOptions,\n context,\n rootValue\n );\n queryBuilder.from(from, fromAlias ? fromAlias : undefined);\n\n if (withBuilder) {\n withBuilder(queryBuilder);\n }\n if (pgQuery) {\n for (let i = 0, l = pgQuery.length; i < l; i++) {\n pgQuery[i](queryBuilder, resolveData);\n }\n }\n\n function generateNextPrevPageSql(\n sqlQueryAlias,\n canHaveCursorInWhere,\n queryHasBefore,\n queryHasFirst,\n offset = 0,\n invert = false\n ) {\n /*\n * Strap in, 'coz this function gets hairy!\n *\n * The point of this function is to return SQL which will resolve to a\n * boolean true/false depending on whether or not there is a (invert ?\n * \"previous\" : \"next\") page.\n *\n * Connections have before, after, first, last and offset.\n * - Users are forbidden from setting both first and last.\n * - Users are forbidden from setting both offset and last.\n *\n * Further there are two main modes of paginating, one works by adding a\n * where clause (this is preferred, but is not always possible, and is\n * indicated by `canHaveCursorInWhere === true`) and the other works using\n * standard LIMIT/OFFSET SQL pagination (and is indicated by\n * `canHaveCursorInWhere === false`).\n *\n * The following diagram shows a full collection of records, #, starting at\n * START and ending at END. The key after, before, offset, first and last\n * variables are shown. One thing not show is that it's possible to have\n * fewer records between before and after than requested by first or last.\n * Another detail not clearly show is that if there is no `after` then\n * `START` is used, similarly if there is no `before` then `END` is used.\n *\n * #################################################### < collection\n * ^ ^<-offset->^<-first->^ ^<-last->^ ^\n * | | | | | | |\n * | | +---------+ +--------+ |\n * | | | DATA1 DATA2 | |\n * | | | | |\n * | | | | |\n * | | +-------------------------+ |\n * | | DATA3 | |\n * | after before |\n * | |\n * START END\n *\n * We want one of the three DATA blocks:\n *\n * - If `first` is set, then we want DATA1.\n * - If `last` is set then we want DATA2.\n * - If neither is set then we want DATA3.\n *\n * (Remember: you cannot set both `first` and `last` at the same time.)\n *\n * When invert === false:\n *\n * Note that both DATA2 and DATA3 end at the same point, and we only care\n * if there's data *after* the relevant DATA block, so really we only\n * care if the query specified `first` (`queryHasFirst`) which makes\n * things complex (ending at the end of DATA1), otherwise we can use\n * `before` as the bound (end of DATA2/DATA3).\n *\n * When invert === true:\n *\n * Similarly, DATA1 and DATA3 start at the same point, and we're going\n * backwards so we only care if there's data *before* the DATA block, so\n * really we just need to know if the query set `last` or not, but since\n * this is inverted we call it `queryHasFirst`.\n *\n * When `invert` is false we're calculating `hasNextPage`, when true we're\n * calculating `hasPreviousPage`.\n *\n * Because of the near-symmetry of requesting hasPreviousPage vs\n * hasNextPage we always pretend we're determining `hasNextPage`, and we\n * just invert everything.\n */\n\n const sqlCommonUnbounded = sql.fragment`\\\nselect 1\nfrom ${queryBuilder.getTableExpression()} as ${queryBuilder.getTableAlias()}`;\n /*\n * This variable is a fragment to go into an `EXISTS(...)` call (after some tweaks).\n *\n * The buildWhereClause takes three arguments:\n *\n * - includeLowerBound (we want this for hasNextPage but not hasPreviousPage)\n * - includeUpperBound (we want this for hasPreviousPage but not hasNextPage)\n * - options (specifically `{addNullCase, addNotDistinctFromNullCase}`) -\n * we just pass this through.\n *\n * So in hasNextPage mode (invert === false), this common SQL ends up\n * representing the collection from `(after || START)` onwards with no\n * upper bound. In hasPreviousPage mode (invert === true), it represents\n * everything from `(before || END)` backwards, with no lower bound.\n */\n const sqlCommon = sql.fragment`\\\n${sqlCommonUnbounded}\nwhere ${queryBuilder.buildWhereClause(!invert, invert, options)}`;\n\n /*\n * Since the offset makes the diagram asymmetric, if offset === 0\n * then the diagram is symmetric and things are simplified a little.\n */\n const isForwardOrSymmetric = !invert || offset === 0;\n\n if (!isForwardOrSymmetric) {\n assert(invert);\n assert(offset > 0);\n // We're looking for a previous page, and there's an offset, so lets just\n // assume there's a previous page where offset is smaller.\n return sql.literal(true);\n } else if (canHaveCursorInWhere) {\n assert(isForwardOrSymmetric);\n if (!queryHasBefore && !queryHasFirst) {\n assert(isForwardOrSymmetric);\n // There can be no next page since there's no upper bound\n return sql.literal(false);\n } else if (queryHasBefore && !queryHasFirst) {\n /*\n * We invert the upper buildWhereBoundClause to only represent the data\n * after `before`, then check if there's at least one record in that set.\n *\n * This only works if the `before` cursor can be represented in the\n * SQL WHERE clause, otherwise we're doing limit/offset pagination\n * which requires different logic. It also only works if there's no\n * `first` clause, otherwise there could be a next page before the\n * `before` clause.\n */\n return sql.fragment`\\\nexists(\n ${sqlCommonUnbounded}\n where ${queryBuilder.buildWhereClause(false, false, options)}\n and not (${queryBuilder.buildWhereBoundClause(invert)})\n)`;\n } else {\n assert(queryHasFirst);\n // queryHasBefore could be true or false.\n /*\n * There's a few ways that we could determine if there's a next page.\n *\n * If !queryHasBefore, we could COUNT(*) the number of rows in\n * `sqlCommon` and see if it's larger than `first`:\n * `(select count(*) > ${first} from (${sqlCommon}) __random_table_alias__)`\n *\n * If !queryHasBefore, we could build a subquery table of offsetData\n * from sqlCommon and see if it contains any rows:\n * `EXISTS(select 1 from (${sqlCommon} OFFSET ${first}) __random_table_alias__)`.\n *\n * We could see if there's at least one row in sqlCommon that's not\n * already in our chosen result set.\n *\n * We've chosen the latter approach here because it doesn't place a limit\n * on queryHasBefore.\n */\n // Drop the `first` limit, see if there are any records that aren't\n // already in the list we've fetched.\n return sql.fragment`\\\nexists(\n ${sqlCommon}\n and (${queryBuilder.getSelectCursor()})::text not in (select __cursor::text from ${sqlQueryAlias})\n ${offset === 0 ? sql.blank : sql.fragment`offset ${sql.value(offset)}`}\n)`;\n }\n } else {\n assert(!invert || offset === 0); // isForwardOrSymmetric\n assert(!canHaveCursorInWhere);\n // We're dealing with LIMIT/OFFSET pagination here, which means `natural`\n // cursors, so the `queryBuilder` factors the before/after, first/last\n // into the limit / offset.\n const { limit } = queryBuilder.getFinalLimitAndOffset();\n\n if (limit == null) {\n // If paginating backwards, then offset > 0 has already been dealt\n // with. Unbounded, so there's no next page.\n return sql.fragment`false`;\n } else if (invert) {\n assert(offset === 0);\n // Paginating backwards and there's no offset (which factors in before/after), so there's no previous page.\n return sql.fragment`false`;\n } else {\n assert(!invert);\n /*\n * We're paginating forwards; either there's a before, there's a first,\n * or both.\n *\n * We want to see if there's more than limit+offset records in sqlCommon.\n */\n return sql.fragment`\\\nexists(\n ${sqlCommon}\n offset ${sql.literal(limit + offset)}\n)`;\n }\n }\n }\n const getPgCursorPrefix = () =>\n rawCursorPrefix && rawCursorPrefix.length > 0\n ? rawCursorPrefix\n : queryBuilder.data.cursorPrefix.map(val => sql.literal(val));\n if (\n options.withPagination ||\n options.withPaginationAsFields ||\n options.withCursor\n ) {\n // Sometimes we need a __cursor even if it's not a collection; e.g. to get the edge field on a mutation\n if (usesCursor) {\n queryBuilder.selectCursor((): SQL => {\n const orderBy = queryBuilder\n .getOrderByExpressionsAndDirections()\n .map(([expr]) => expr);\n if (queryBuilder.isOrderUnique() && orderBy.length > 0) {\n return sql.fragment`json_build_array(${sql.join(\n [\n ...getPgCursorPrefix(),\n sql.fragment`json_build_array(${sql.join(orderBy, \", \")})`,\n ],\n \", \"\n )})`;\n } else {\n return sql.fragment`json_build_array(${sql.join(\n getPgCursorPrefix(),\n \", \"\n )}, ${\n /*\n * NOTE[useAsterisk/row_number]: If we have useAsterisk then the\n * query with limit offset is in a subquery, so our row_number()\n * call doesn't know about it. Here we add the offset back in\n * again. See matching NOTE in QueryBuilder.js.\n */\n options.useAsterisk\n ? sql.fragment`${sql.literal(\n queryBuilder.getFinalOffset() || 0\n )} + `\n : sql.fragment``\n }(row_number() over (partition by 1)))`;\n }\n });\n }\n }\n if (options.withPagination || options.withPaginationAsFields) {\n queryBuilder.setCursorComparator((cursorValue, isAfter) => {\n function badCursor() {\n queryBuilder.whereBound(sql.fragment`false`, isAfter);\n }\n const orderByExpressionsAndDirections =\n queryBuilder.getOrderByExpressionsAndDirections();\n if (orderByExpressionsAndDirections.length > 0) {\n if (!queryBuilder.isOrderUnique()) {\n throw new Error(\n \"The order supplied is not unique, so before/after cursors cannot be used. Please ensure the supplied order includes all the columns from the primary key or a unique constraint.\"\n );\n }\n const rawPrefixes = cursorValue.slice(0, cursorValue.length - 1);\n const rawCursors = cursorValue[cursorValue.length - 1];\n if (rawPrefixes.length !== getPgCursorPrefix().length) {\n badCursor();\n return;\n }\n if (!Array.isArray(rawCursors)) {\n badCursor();\n return;\n }\n let sqlFilter = sql.fragment`false`;\n const sqlCursors = rawCursors.map(val => sql.value(val));\n for (\n let i = orderByExpressionsAndDirections.length - 1;\n i >= 0;\n i--\n ) {\n const [sqlExpression, ascending] =\n orderByExpressionsAndDirections[i];\n // If ascending and isAfter then >\n // If ascending and isBefore then <\n const comparison =\n Number(ascending) ^ Number(!isAfter)\n ? sql.fragment`>`\n : sql.fragment`<`;\n\n const sqlOldFilter = sqlFilter;\n sqlFilter = sql.fragment`\\\n(\\\n (${sqlExpression} ${comparison} ${sqlCursors[i] || sql.null})\nOR\\\n (\\\n ${sqlExpression} = ${sqlCursors[i] || sql.null}\\\n AND\\\n ${sqlOldFilter}\\\n )\\\n)`;\n }\n\n // Check the cursor prefixes apply\n // TODO:v5: we should be able to do this in JS-land rather than SQL-land\n sqlFilter = sql.fragment`(((${sql.join(\n getPgCursorPrefix(),\n \", \"\n )}) = (${sql.join(\n rawPrefixes.map(val => sql.value(val)),\n \", \"\n )})) AND (${sqlFilter}))`;\n queryBuilder.whereBound(sqlFilter, isAfter);\n } else if (\n cursorValue[0] === \"natural\" &&\n isSafeInteger(cursorValue[1]) &&\n // $FlowFixMe: we know this is a number\n cursorValue[1] >= 0\n ) {\n // $FlowFixMe: we know this is a number\n const cursorValue1: number = cursorValue[1];\n if (isAfter) {\n queryBuilder.offset(() => cursorValue1);\n } else {\n queryBuilder.limit(() => {\n const offset = queryBuilder.getOffset();\n return Math.max(0, cursorValue1 - offset - 1);\n });\n }\n } else {\n throw new Error(\n \"Cannot use 'before'/'after' without unique 'orderBy'\"\n );\n }\n });\n\n const query = queryBuilder.build(options);\n const haveFields = queryBuilder.getSelectFieldsCount() > 0;\n const sqlQueryAlias = sql.identifier(Symbol());\n const sqlSummaryAlias = sql.identifier(Symbol());\n //\n // Tables should ALWAYS push their PK onto the order stack, if this isn't\n // present then we're either dealing with a view or a table without a PK.\n // Either way, we don't have anything to guarantee uniqueness so we need to\n // fall back to limit/offset.\n //\n // TODO: support unique keys in PgAllRows etc\n // TODO: add a warning for cursor-based pagination when using the fallback\n // TODO: if it is a view maybe add a warning encouraging pgViewUniqueKey\n const canHaveCursorInWhere =\n queryBuilder.getOrderByExpressionsAndDirections().length > 0 &&\n queryBuilder.isOrderUnique();\n const queryHasBefore =\n queryBuilder.compiledData.whereBound.upper.length > 0;\n const queryHasAfter =\n queryBuilder.compiledData.whereBound.lower.length > 0;\n const queryHasZeroLimit = queryBuilder.getFinalLimit() === 0;\n const queryHasFirst = isSafeInteger(queryBuilder.compiledData.first);\n const queryHasLast = isSafeInteger(queryBuilder.compiledData.last);\n const hasNextPage = queryHasZeroLimit\n ? sql.literal(false)\n : generateNextPrevPageSql(\n sqlQueryAlias,\n canHaveCursorInWhere,\n queryHasBefore,\n queryHasFirst,\n queryBuilder.getFinalOffset() || 0\n );\n const hasPreviousPage = queryHasZeroLimit\n ? sql.literal(false)\n : generateNextPrevPageSql(\n sqlQueryAlias,\n canHaveCursorInWhere,\n queryHasAfter,\n queryHasLast,\n queryBuilder.getFinalOffset() || 0,\n true\n );\n\n const sqlWith = haveFields\n ? sql.fragment`with ${sqlQueryAlias} as (${query}), ${sqlSummaryAlias} as (select json_agg(to_json(${sqlQueryAlias})) as data from ${sqlQueryAlias})`\n : sql.fragment``;\n const sqlFrom = sql.fragment``;\n const fields: Array<[SQL, RawAlias]> = [];\n if (haveFields) {\n fields.push([\n sql.fragment`coalesce((select ${sqlSummaryAlias}.data from ${sqlSummaryAlias}), '[]'::json)`,\n \"data\",\n ]);\n if (calculateHasNextPage) {\n fields.push([hasNextPage, \"hasNextPage\"]);\n }\n if (calculateHasPreviousPage) {\n fields.push([hasPreviousPage, \"hasPreviousPage\"]);\n }\n }\n if (pgNamedQuery && pgNamedQuery.length) {\n const groups = {};\n pgNamedQuery.forEach(({ name, query }) => {\n assertSafeName(name);\n if (!groups[name]) {\n groups[name] = [];\n }\n groups[name].push(query);\n });\n Object.keys(groups).forEach(groupName => {\n const queryCallbacks = groups[groupName];\n\n // Get container\n const containers = pgNamedQueryContainer.filter(\n c => c.name === groupName\n );\n if (containers.length === 0) {\n throw new Error(\n `${queryCallbacks.length} pgNamedQuery entries with name: '${groupName}' existed, but there was no matching pgNamedQueryContainer.`\n );\n }\n if (containers.length > 1) {\n throw new Error(\n `${containers.length} pgNamedQueryContainer entries with name: '${groupName}' existed, but there should be exactly one.`\n );\n }\n const container = containers[0];\n\n const innerQueryBuilder = new QueryBuilder(\n queryBuilderOptions,\n context,\n rootValue\n );\n innerQueryBuilder.from(\n queryBuilder.getTableExpression(),\n queryBuilder.getTableAlias()\n );\n\n for (let i = 0, l = queryCallbacks.length; i < l; i++) {\n queryCallbacks[i](innerQueryBuilder);\n }\n\n // Generate the SQL statement (e.g. `select ${innerQueryBuilder.build({onlyJsonField: true})} from ${queryBuilder.getTableExpression()} as ...`)\n const aggregatesSql = container.query({\n queryBuilder,\n innerQueryBuilder,\n options,\n });\n\n fields.push([aggregatesSql, groupName]);\n });\n }\n if (options.withPaginationAsFields) {\n return sql.fragment`${sqlWith} select ${sql.join(\n fields.map(\n ([expr, alias]) => sql.fragment`${expr} as ${sql.identifier(alias)}`\n ),\n \", \"\n )} ${sqlFrom}`;\n } else {\n return sql.fragment`${sqlWith} select ${queryBuilder.jsonbBuildObject(\n fields\n )} ${sqlFrom}`;\n }\n } else {\n const query = queryBuilder.build(options);\n return query;\n }\n };\n"],"file":"queryFromResolveDataFactory.js"}
|
|
1
|
+
{"version":3,"file":"queryFromResolveDataFactory.js","names":["_QueryBuilder","_interopRequireDefault","require","sql","_interopRequireWildcard","_isSafeInteger","_assert","_util","_getRequireWildcardCache","nodeInterop","WeakMap","cacheBabelInterop","cacheNodeInterop","obj","__esModule","default","cache","has","get","newObj","hasPropertyDescriptor","Object","defineProperty","getOwnPropertyDescriptor","key","prototype","hasOwnProperty","call","desc","set","identity","_","undefined","assertSafeName","name","Error","inspect","test","_default","queryBuilderOptions","from","fromAlias","resolveData","inOptions","withBuilder","context","rootValue","pgQuery","pgAggregateQuery","pgNamedQueryContainer","pgNamedQuery","pgCursorPrefix","reallyRawCursorPrefix","pgDontUseAsterisk","calculateHasNextPage","calculateHasPreviousPage","usesCursor","explicitlyUsesCursor","length","push","query","queryBuilder","options","innerQueryBuilder","fragment","build","onlyJsonField","getTableExpression","getTableAlias","buildWhereClause","forEach","preventAsterisk","useAsterisk","rawCursorPrefix","filter","QueryBuilder","i","l","generateNextPrevPageSql","sqlQueryAlias","canHaveCursorInWhere","queryHasBefore","queryHasFirst","offset","invert","sqlCommonUnbounded","sqlCommon","isForwardOrSymmetric","assert","literal","buildWhereBoundClause","getSelectCursor","blank","value","limit","getFinalLimitAndOffset","getPgCursorPrefix","data","cursorPrefix","map","val","withPagination","withPaginationAsFields","withCursor","selectCursor","orderBy","getOrderByExpressionsAndDirections","expr","isOrderUnique","join","getFinalOffset","setCursorComparator","cursorValue","isAfter","badCursor","whereBound","orderByExpressionsAndDirections","rawPrefixes","slice","rawCursors","Array","isArray","sqlFilter","sqlCursors","sqlExpression","ascending","comparison","Number","sqlOldFilter","null","isSafeInteger","cursorValue1","getOffset","Math","max","haveFields","getSelectFieldsCount","identifier","Symbol","sqlSummaryAlias","compiledData","upper","queryHasAfter","lower","queryHasZeroLimit","getFinalLimit","first","queryHasLast","last","hasNextPage","hasPreviousPage","sqlWith","sqlFrom","fields","groups","keys","groupName","queryCallbacks","containers","c","container","aggregatesSql","alias","jsonbBuildObject","exports"],"sources":["../src/queryFromResolveDataFactory.js"],"sourcesContent":["// @flow\nimport QueryBuilder from \"./QueryBuilder\";\nimport type { QueryBuilderOptions } from \"./QueryBuilder\";\nimport type { RawAlias } from \"./QueryBuilder\";\nimport * as sql from \"pg-sql2\";\nimport type { SQL } from \"pg-sql2\";\nimport type { DataForType } from \"graphile-build\";\nimport isSafeInteger from \"lodash/isSafeInteger\";\nimport assert from \"assert\";\nimport { inspect } from \"util\";\n\n// eslint-disable-next-line flowtype/no-weak-types\ntype GraphQLContext = any;\n\nconst identity = _ => _ !== null && _ !== undefined;\n\nfunction assertSafeName(name: mixed) {\n if (typeof name !== \"string\") {\n throw new Error(\n `Expected name to be a string; instead received '${inspect(name)}'`\n );\n }\n if (!/^[@a-zA-Z0-9_]{1,63}$/.test(name)) {\n throw new Error(\n `Name '${name}' is not safe - either it is too long, too short, or has invalid characters`\n );\n }\n}\n\nexport default (queryBuilderOptions: QueryBuilderOptions = {}) =>\n (\n from: SQL,\n fromAlias: ?SQL,\n resolveData: DataForType,\n inOptions: {\n withPagination?: boolean,\n withPaginationAsFields?: boolean,\n asJson?: boolean,\n asJsonAggregate?: boolean,\n addNullCase?: boolean,\n addNotDistinctFromNullCase?: boolean,\n onlyJsonField?: boolean,\n useAsterisk?: boolean,\n withCursor?: boolean,\n },\n // TODO:v5: context is not optional\n withBuilder?: ((builder: QueryBuilder) => void) | null | void,\n context?: GraphQLContext = {},\n rootValue?: any // eslint-disable-line flowtype/no-weak-types\n ) => {\n const {\n pgQuery,\n pgAggregateQuery, // Shorthand for using pgNamedQueryContainer/pgNamedQuery combo\n pgNamedQueryContainer = [],\n pgNamedQuery = [],\n pgCursorPrefix: reallyRawCursorPrefix,\n pgDontUseAsterisk,\n calculateHasNextPage,\n calculateHasPreviousPage,\n usesCursor: explicitlyUsesCursor,\n } = resolveData;\n // Push a query container for aggregates\n if ((pgAggregateQuery && pgAggregateQuery.length) || pgNamedQuery.length) {\n pgNamedQueryContainer.push({\n name: \"aggregates\",\n query: ({ queryBuilder, options, innerQueryBuilder }) => sql.fragment`\\\n(\n select ${innerQueryBuilder.build({ onlyJsonField: true })}\n from ${queryBuilder.getTableExpression()} as ${queryBuilder.getTableAlias()}\n where ${queryBuilder.buildWhereClause(false, false, options)}\n)`,\n });\n }\n // Convert pgAggregateQuery to pgNamedQueryContainer/pgNamedQuery combo\n if (pgAggregateQuery && pgAggregateQuery.length) {\n // And a query for each previous query\n pgAggregateQuery.forEach(query => {\n pgNamedQuery.push({ name: \"aggregates\", query });\n });\n }\n\n const preventAsterisk = pgDontUseAsterisk\n ? pgDontUseAsterisk.length > 0\n : false;\n const options = {\n ...inOptions,\n // Allow pgDontUseAsterisk to override useAsterisk\n useAsterisk: inOptions.useAsterisk && !preventAsterisk,\n };\n\n const usesCursor: boolean =\n (explicitlyUsesCursor && explicitlyUsesCursor.length > 0) ||\n (calculateHasNextPage && calculateHasNextPage.length > 0) ||\n (calculateHasPreviousPage && calculateHasPreviousPage.length > 0) ||\n false;\n const rawCursorPrefix =\n reallyRawCursorPrefix && reallyRawCursorPrefix.filter(identity);\n\n const queryBuilder = new QueryBuilder(\n queryBuilderOptions,\n context,\n rootValue\n );\n queryBuilder.from(from, fromAlias ? fromAlias : undefined);\n\n if (withBuilder) {\n withBuilder(queryBuilder);\n }\n if (pgQuery) {\n for (let i = 0, l = pgQuery.length; i < l; i++) {\n pgQuery[i](queryBuilder, resolveData);\n }\n }\n\n function generateNextPrevPageSql(\n sqlQueryAlias,\n canHaveCursorInWhere,\n queryHasBefore,\n queryHasFirst,\n offset = 0,\n invert = false\n ) {\n /*\n * Strap in, 'coz this function gets hairy!\n *\n * The point of this function is to return SQL which will resolve to a\n * boolean true/false depending on whether or not there is a (invert ?\n * \"previous\" : \"next\") page.\n *\n * Connections have before, after, first, last and offset.\n * - Users are forbidden from setting both first and last.\n * - Users are forbidden from setting both offset and last.\n *\n * Further there are two main modes of paginating, one works by adding a\n * where clause (this is preferred, but is not always possible, and is\n * indicated by `canHaveCursorInWhere === true`) and the other works using\n * standard LIMIT/OFFSET SQL pagination (and is indicated by\n * `canHaveCursorInWhere === false`).\n *\n * The following diagram shows a full collection of records, #, starting at\n * START and ending at END. The key after, before, offset, first and last\n * variables are shown. One thing not show is that it's possible to have\n * fewer records between before and after than requested by first or last.\n * Another detail not clearly show is that if there is no `after` then\n * `START` is used, similarly if there is no `before` then `END` is used.\n *\n * #################################################### < collection\n * ^ ^<-offset->^<-first->^ ^<-last->^ ^\n * | | | | | | |\n * | | +---------+ +--------+ |\n * | | | DATA1 DATA2 | |\n * | | | | |\n * | | | | |\n * | | +-------------------------+ |\n * | | DATA3 | |\n * | after before |\n * | |\n * START END\n *\n * We want one of the three DATA blocks:\n *\n * - If `first` is set, then we want DATA1.\n * - If `last` is set then we want DATA2.\n * - If neither is set then we want DATA3.\n *\n * (Remember: you cannot set both `first` and `last` at the same time.)\n *\n * When invert === false:\n *\n * Note that both DATA2 and DATA3 end at the same point, and we only care\n * if there's data *after* the relevant DATA block, so really we only\n * care if the query specified `first` (`queryHasFirst`) which makes\n * things complex (ending at the end of DATA1), otherwise we can use\n * `before` as the bound (end of DATA2/DATA3).\n *\n * When invert === true:\n *\n * Similarly, DATA1 and DATA3 start at the same point, and we're going\n * backwards so we only care if there's data *before* the DATA block, so\n * really we just need to know if the query set `last` or not, but since\n * this is inverted we call it `queryHasFirst`.\n *\n * When `invert` is false we're calculating `hasNextPage`, when true we're\n * calculating `hasPreviousPage`.\n *\n * Because of the near-symmetry of requesting hasPreviousPage vs\n * hasNextPage we always pretend we're determining `hasNextPage`, and we\n * just invert everything.\n */\n\n const sqlCommonUnbounded = sql.fragment`\\\nselect 1\nfrom ${queryBuilder.getTableExpression()} as ${queryBuilder.getTableAlias()}`;\n /*\n * This variable is a fragment to go into an `EXISTS(...)` call (after some tweaks).\n *\n * The buildWhereClause takes three arguments:\n *\n * - includeLowerBound (we want this for hasNextPage but not hasPreviousPage)\n * - includeUpperBound (we want this for hasPreviousPage but not hasNextPage)\n * - options (specifically `{addNullCase, addNotDistinctFromNullCase}`) -\n * we just pass this through.\n *\n * So in hasNextPage mode (invert === false), this common SQL ends up\n * representing the collection from `(after || START)` onwards with no\n * upper bound. In hasPreviousPage mode (invert === true), it represents\n * everything from `(before || END)` backwards, with no lower bound.\n */\n const sqlCommon = sql.fragment`\\\n${sqlCommonUnbounded}\nwhere ${queryBuilder.buildWhereClause(!invert, invert, options)}`;\n\n /*\n * Since the offset makes the diagram asymmetric, if offset === 0\n * then the diagram is symmetric and things are simplified a little.\n */\n const isForwardOrSymmetric = !invert || offset === 0;\n\n if (!isForwardOrSymmetric) {\n assert(invert);\n assert(offset > 0);\n // We're looking for a previous page, and there's an offset, so lets just\n // assume there's a previous page where offset is smaller.\n return sql.literal(true);\n } else if (canHaveCursorInWhere) {\n assert(isForwardOrSymmetric);\n if (!queryHasBefore && !queryHasFirst) {\n assert(isForwardOrSymmetric);\n // There can be no next page since there's no upper bound\n return sql.literal(false);\n } else if (queryHasBefore && !queryHasFirst) {\n /*\n * We invert the upper buildWhereBoundClause to only represent the data\n * after `before`, then check if there's at least one record in that set.\n *\n * This only works if the `before` cursor can be represented in the\n * SQL WHERE clause, otherwise we're doing limit/offset pagination\n * which requires different logic. It also only works if there's no\n * `first` clause, otherwise there could be a next page before the\n * `before` clause.\n */\n return sql.fragment`\\\nexists(\n ${sqlCommonUnbounded}\n where ${queryBuilder.buildWhereClause(false, false, options)}\n and not (${queryBuilder.buildWhereBoundClause(invert)})\n)`;\n } else {\n assert(queryHasFirst);\n // queryHasBefore could be true or false.\n /*\n * There's a few ways that we could determine if there's a next page.\n *\n * If !queryHasBefore, we could COUNT(*) the number of rows in\n * `sqlCommon` and see if it's larger than `first`:\n * `(select count(*) > ${first} from (${sqlCommon}) __random_table_alias__)`\n *\n * If !queryHasBefore, we could build a subquery table of offsetData\n * from sqlCommon and see if it contains any rows:\n * `EXISTS(select 1 from (${sqlCommon} OFFSET ${first}) __random_table_alias__)`.\n *\n * We could see if there's at least one row in sqlCommon that's not\n * already in our chosen result set.\n *\n * We've chosen the latter approach here because it doesn't place a limit\n * on queryHasBefore.\n */\n // Drop the `first` limit, see if there are any records that aren't\n // already in the list we've fetched.\n return sql.fragment`\\\nexists(\n ${sqlCommon}\n and (${queryBuilder.getSelectCursor()})::text not in (select __cursor::text from ${sqlQueryAlias})\n ${offset === 0 ? sql.blank : sql.fragment`offset ${sql.value(offset)}`}\n)`;\n }\n } else {\n assert(!invert || offset === 0); // isForwardOrSymmetric\n assert(!canHaveCursorInWhere);\n // We're dealing with LIMIT/OFFSET pagination here, which means `natural`\n // cursors, so the `queryBuilder` factors the before/after, first/last\n // into the limit / offset.\n const { limit } = queryBuilder.getFinalLimitAndOffset();\n\n if (limit == null) {\n // If paginating backwards, then offset > 0 has already been dealt\n // with. Unbounded, so there's no next page.\n return sql.fragment`false`;\n } else if (invert) {\n assert(offset === 0);\n // Paginating backwards and there's no offset (which factors in before/after), so there's no previous page.\n return sql.fragment`false`;\n } else {\n assert(!invert);\n /*\n * We're paginating forwards; either there's a before, there's a first,\n * or both.\n *\n * We want to see if there's more than limit+offset records in sqlCommon.\n */\n return sql.fragment`\\\nexists(\n ${sqlCommon}\n offset ${sql.literal(limit + offset)}\n)`;\n }\n }\n }\n const getPgCursorPrefix = () =>\n rawCursorPrefix && rawCursorPrefix.length > 0\n ? rawCursorPrefix\n : queryBuilder.data.cursorPrefix.map(val => sql.literal(val));\n if (\n options.withPagination ||\n options.withPaginationAsFields ||\n options.withCursor\n ) {\n // Sometimes we need a __cursor even if it's not a collection; e.g. to get the edge field on a mutation\n if (usesCursor) {\n queryBuilder.selectCursor((): SQL => {\n const orderBy = queryBuilder\n .getOrderByExpressionsAndDirections()\n .map(([expr]) => expr);\n if (queryBuilder.isOrderUnique() && orderBy.length > 0) {\n return sql.fragment`json_build_array(${sql.join(\n [\n ...getPgCursorPrefix(),\n sql.fragment`json_build_array(${sql.join(orderBy, \", \")})`,\n ],\n \", \"\n )})`;\n } else {\n return sql.fragment`json_build_array(${sql.join(\n getPgCursorPrefix(),\n \", \"\n )}, ${\n /*\n * NOTE[useAsterisk/row_number]: If we have useAsterisk then the\n * query with limit offset is in a subquery, so our row_number()\n * call doesn't know about it. Here we add the offset back in\n * again. See matching NOTE in QueryBuilder.js.\n */\n options.useAsterisk\n ? sql.fragment`${sql.literal(\n queryBuilder.getFinalOffset() || 0\n )} + `\n : sql.fragment``\n }(row_number() over (partition by 1)))`;\n }\n });\n }\n }\n if (options.withPagination || options.withPaginationAsFields) {\n queryBuilder.setCursorComparator((cursorValue, isAfter) => {\n function badCursor() {\n queryBuilder.whereBound(sql.fragment`false`, isAfter);\n }\n const orderByExpressionsAndDirections =\n queryBuilder.getOrderByExpressionsAndDirections();\n if (orderByExpressionsAndDirections.length > 0) {\n if (!queryBuilder.isOrderUnique()) {\n throw new Error(\n \"The order supplied is not unique, so before/after cursors cannot be used. Please ensure the supplied order includes all the columns from the primary key or a unique constraint.\"\n );\n }\n const rawPrefixes = cursorValue.slice(0, cursorValue.length - 1);\n const rawCursors = cursorValue[cursorValue.length - 1];\n if (rawPrefixes.length !== getPgCursorPrefix().length) {\n badCursor();\n return;\n }\n if (!Array.isArray(rawCursors)) {\n badCursor();\n return;\n }\n let sqlFilter = sql.fragment`false`;\n const sqlCursors = rawCursors.map(val => sql.value(val));\n for (\n let i = orderByExpressionsAndDirections.length - 1;\n i >= 0;\n i--\n ) {\n const [sqlExpression, ascending] =\n orderByExpressionsAndDirections[i];\n // If ascending and isAfter then >\n // If ascending and isBefore then <\n const comparison =\n Number(ascending) ^ Number(!isAfter)\n ? sql.fragment`>`\n : sql.fragment`<`;\n\n const sqlOldFilter = sqlFilter;\n sqlFilter = sql.fragment`\\\n(\\\n (${sqlExpression} ${comparison} ${sqlCursors[i] || sql.null})\nOR\\\n (\\\n ${sqlExpression} = ${sqlCursors[i] || sql.null}\\\n AND\\\n ${sqlOldFilter}\\\n )\\\n)`;\n }\n\n // Check the cursor prefixes apply\n // TODO:v5: we should be able to do this in JS-land rather than SQL-land\n sqlFilter = sql.fragment`(((${sql.join(\n getPgCursorPrefix(),\n \", \"\n )}) = (${sql.join(\n rawPrefixes.map(val => sql.value(val)),\n \", \"\n )})) AND (${sqlFilter}))`;\n queryBuilder.whereBound(sqlFilter, isAfter);\n } else if (\n cursorValue[0] === \"natural\" &&\n isSafeInteger(cursorValue[1]) &&\n // $FlowFixMe: we know this is a number\n cursorValue[1] >= 0\n ) {\n // $FlowFixMe: we know this is a number\n const cursorValue1: number = cursorValue[1];\n if (isAfter) {\n queryBuilder.offset(() => cursorValue1);\n } else {\n queryBuilder.limit(() => {\n const offset = queryBuilder.getOffset();\n return Math.max(0, cursorValue1 - offset - 1);\n });\n }\n } else {\n throw new Error(\n \"Cannot use 'before'/'after' without unique 'orderBy'\"\n );\n }\n });\n\n const query = queryBuilder.build(options);\n const haveFields = queryBuilder.getSelectFieldsCount() > 0;\n const sqlQueryAlias = sql.identifier(Symbol());\n const sqlSummaryAlias = sql.identifier(Symbol());\n //\n // Tables should ALWAYS push their PK onto the order stack, if this isn't\n // present then we're either dealing with a view or a table without a PK.\n // Either way, we don't have anything to guarantee uniqueness so we need to\n // fall back to limit/offset.\n //\n // TODO: support unique keys in PgAllRows etc\n // TODO: add a warning for cursor-based pagination when using the fallback\n // TODO: if it is a view maybe add a warning encouraging pgViewUniqueKey\n const canHaveCursorInWhere =\n queryBuilder.getOrderByExpressionsAndDirections().length > 0 &&\n queryBuilder.isOrderUnique();\n const queryHasBefore =\n queryBuilder.compiledData.whereBound.upper.length > 0;\n const queryHasAfter =\n queryBuilder.compiledData.whereBound.lower.length > 0;\n const queryHasZeroLimit = queryBuilder.getFinalLimit() === 0;\n const queryHasFirst = isSafeInteger(queryBuilder.compiledData.first);\n const queryHasLast = isSafeInteger(queryBuilder.compiledData.last);\n const hasNextPage = queryHasZeroLimit\n ? sql.literal(false)\n : generateNextPrevPageSql(\n sqlQueryAlias,\n canHaveCursorInWhere,\n queryHasBefore,\n queryHasFirst,\n queryBuilder.getFinalOffset() || 0\n );\n const hasPreviousPage = queryHasZeroLimit\n ? sql.literal(false)\n : generateNextPrevPageSql(\n sqlQueryAlias,\n canHaveCursorInWhere,\n queryHasAfter,\n queryHasLast,\n queryBuilder.getFinalOffset() || 0,\n true\n );\n\n const sqlWith = haveFields\n ? sql.fragment`with ${sqlQueryAlias} as (${query}), ${sqlSummaryAlias} as (select json_agg(to_json(${sqlQueryAlias})) as data from ${sqlQueryAlias})`\n : sql.fragment``;\n const sqlFrom = sql.fragment``;\n const fields: Array<[SQL, RawAlias]> = [];\n if (haveFields) {\n fields.push([\n sql.fragment`coalesce((select ${sqlSummaryAlias}.data from ${sqlSummaryAlias}), '[]'::json)`,\n \"data\",\n ]);\n if (calculateHasNextPage) {\n fields.push([hasNextPage, \"hasNextPage\"]);\n }\n if (calculateHasPreviousPage) {\n fields.push([hasPreviousPage, \"hasPreviousPage\"]);\n }\n }\n if (pgNamedQuery && pgNamedQuery.length) {\n const groups = {};\n pgNamedQuery.forEach(({ name, query }) => {\n assertSafeName(name);\n if (!groups[name]) {\n groups[name] = [];\n }\n groups[name].push(query);\n });\n Object.keys(groups).forEach(groupName => {\n const queryCallbacks = groups[groupName];\n\n // Get container\n const containers = pgNamedQueryContainer.filter(\n c => c.name === groupName\n );\n if (containers.length === 0) {\n throw new Error(\n `${queryCallbacks.length} pgNamedQuery entries with name: '${groupName}' existed, but there was no matching pgNamedQueryContainer.`\n );\n }\n if (containers.length > 1) {\n throw new Error(\n `${containers.length} pgNamedQueryContainer entries with name: '${groupName}' existed, but there should be exactly one.`\n );\n }\n const container = containers[0];\n\n const innerQueryBuilder = new QueryBuilder(\n queryBuilderOptions,\n context,\n rootValue\n );\n innerQueryBuilder.from(\n queryBuilder.getTableExpression(),\n queryBuilder.getTableAlias()\n );\n\n for (let i = 0, l = queryCallbacks.length; i < l; i++) {\n queryCallbacks[i](innerQueryBuilder);\n }\n\n // Generate the SQL statement (e.g. `select ${innerQueryBuilder.build({onlyJsonField: true})} from ${queryBuilder.getTableExpression()} as ...`)\n const aggregatesSql = container.query({\n queryBuilder,\n innerQueryBuilder,\n options,\n });\n\n fields.push([aggregatesSql, groupName]);\n });\n }\n if (options.withPaginationAsFields) {\n return sql.fragment`${sqlWith} select ${sql.join(\n fields.map(\n ([expr, alias]) => sql.fragment`${expr} as ${sql.identifier(alias)}`\n ),\n \", \"\n )} ${sqlFrom}`;\n } else {\n return sql.fragment`${sqlWith} select ${queryBuilder.jsonbBuildObject(\n fields\n )} ${sqlFrom}`;\n }\n } else {\n const query = queryBuilder.build(options);\n return query;\n }\n };\n"],"mappings":"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"}
|
package/node8plus/utils.js
CHANGED
|
@@ -4,27 +4,27 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.parseTags = void 0;
|
|
7
|
-
|
|
8
7
|
const parseTags = str => {
|
|
9
8
|
return str.split(/\r?\n/).reduce((prev, curr) => {
|
|
10
9
|
if (prev.text !== "") {
|
|
11
|
-
return {
|
|
10
|
+
return {
|
|
11
|
+
...prev,
|
|
12
12
|
text: `${prev.text}\n${curr}`
|
|
13
13
|
};
|
|
14
14
|
}
|
|
15
|
-
|
|
16
15
|
const match = curr.match(/^@[a-zA-Z][a-zA-Z0-9_]*($|\s)/);
|
|
17
|
-
|
|
18
16
|
if (!match) {
|
|
19
|
-
return {
|
|
17
|
+
return {
|
|
18
|
+
...prev,
|
|
20
19
|
text: curr
|
|
21
20
|
};
|
|
22
21
|
}
|
|
23
|
-
|
|
24
22
|
const key = match[0].slice(1).trim();
|
|
25
23
|
const value = match[0] === curr ? true : curr.replace(match[0], "");
|
|
26
|
-
return {
|
|
27
|
-
|
|
24
|
+
return {
|
|
25
|
+
...prev,
|
|
26
|
+
tags: {
|
|
27
|
+
...prev.tags,
|
|
28
28
|
[key]: !Object.prototype.hasOwnProperty.call(prev.tags, key) ? value : Array.isArray(prev.tags[key]) ? [...prev.tags[key], value] : [prev.tags[key], value]
|
|
29
29
|
}
|
|
30
30
|
};
|
|
@@ -33,6 +33,5 @@ const parseTags = str => {
|
|
|
33
33
|
text: ""
|
|
34
34
|
});
|
|
35
35
|
};
|
|
36
|
-
|
|
37
36
|
exports.parseTags = parseTags;
|
|
38
37
|
//# sourceMappingURL=utils.js.map
|
package/node8plus/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"
|
|
1
|
+
{"version":3,"file":"utils.js","names":["parseTags","str","split","reduce","prev","curr","text","match","key","slice","trim","value","replace","tags","Object","prototype","hasOwnProperty","call","Array","isArray","exports"],"sources":["../src/utils.js"],"sourcesContent":["// @flow\nexport const parseTags = (str: string) => {\n return str.split(/\\r?\\n/).reduce(\n (prev, curr) => {\n if (prev.text !== \"\") {\n return { ...prev, text: `${prev.text}\\n${curr}` };\n }\n const match = curr.match(/^@[a-zA-Z][a-zA-Z0-9_]*($|\\s)/);\n if (!match) {\n return { ...prev, text: curr };\n }\n const key = match[0].slice(1).trim();\n const value = match[0] === curr ? true : curr.replace(match[0], \"\");\n return {\n ...prev,\n tags: {\n ...prev.tags,\n [key]: !Object.prototype.hasOwnProperty.call(prev.tags, key)\n ? value\n : Array.isArray(prev.tags[key])\n ? [...prev.tags[key], value]\n : [prev.tags[key], value],\n },\n };\n },\n {\n tags: {},\n text: \"\",\n }\n );\n};\n"],"mappings":";;;;;;AACO,MAAMA,SAAS,GAAIC,GAAW,IAAK;EACxC,OAAOA,GAAG,CAACC,KAAK,CAAC,OAAO,CAAC,CAACC,MAAM,CAC9B,CAACC,IAAI,EAAEC,IAAI,KAAK;IACd,IAAID,IAAI,CAACE,IAAI,KAAK,EAAE,EAAE;MACpB,OAAO;QAAE,GAAGF,IAAI;QAAEE,IAAI,EAAG,GAAEF,IAAI,CAACE,IAAK,KAAID,IAAK;MAAE,CAAC;IACnD;IACA,MAAME,KAAK,GAAGF,IAAI,CAACE,KAAK,CAAC,+BAA+B,CAAC;IACzD,IAAI,CAACA,KAAK,EAAE;MACV,OAAO;QAAE,GAAGH,IAAI;QAAEE,IAAI,EAAED;MAAK,CAAC;IAChC;IACA,MAAMG,GAAG,GAAGD,KAAK,CAAC,CAAC,CAAC,CAACE,KAAK,CAAC,CAAC,CAAC,CAACC,IAAI,CAAC,CAAC;IACpC,MAAMC,KAAK,GAAGJ,KAAK,CAAC,CAAC,CAAC,KAAKF,IAAI,GAAG,IAAI,GAAGA,IAAI,CAACO,OAAO,CAACL,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACnE,OAAO;MACL,GAAGH,IAAI;MACPS,IAAI,EAAE;QACJ,GAAGT,IAAI,CAACS,IAAI;QACZ,CAACL,GAAG,GAAG,CAACM,MAAM,CAACC,SAAS,CAACC,cAAc,CAACC,IAAI,CAACb,IAAI,CAACS,IAAI,EAAEL,GAAG,CAAC,GACxDG,KAAK,GACLO,KAAK,CAACC,OAAO,CAACf,IAAI,CAACS,IAAI,CAACL,GAAG,CAAC,CAAC,GAC7B,CAAC,GAAGJ,IAAI,CAACS,IAAI,CAACL,GAAG,CAAC,EAAEG,KAAK,CAAC,GAC1B,CAACP,IAAI,CAACS,IAAI,CAACL,GAAG,CAAC,EAAEG,KAAK;MAC5B;IACF,CAAC;EACH,CAAC,EACD;IACEE,IAAI,EAAE,CAAC,CAAC;IACRP,IAAI,EAAE;EACR,CACF,CAAC;AACH,CAAC;AAACc,OAAA,CAAApB,SAAA,GAAAA,SAAA"}
|