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,21 +4,17 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
-
|
|
8
7
|
var sql = _interopRequireWildcard(require("pg-sql2"));
|
|
9
|
-
|
|
10
8
|
var _isSafeInteger = _interopRequireDefault(require("lodash/isSafeInteger"));
|
|
11
|
-
|
|
12
9
|
var _chunk = _interopRequireDefault(require("lodash/chunk"));
|
|
13
|
-
|
|
14
10
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
|
-
|
|
16
11
|
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); }
|
|
17
|
-
|
|
18
12
|
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; }
|
|
19
|
-
|
|
13
|
+
// eslint-disable-next-line flowtype/no-weak-types
|
|
20
14
|
const isDev = process.env.POSTGRAPHILE_ENV === "development";
|
|
21
15
|
|
|
16
|
+
// Importantly, this cannot include a function
|
|
17
|
+
|
|
22
18
|
function callIfNecessary(o, context) {
|
|
23
19
|
if (typeof o === "function") {
|
|
24
20
|
return o(context);
|
|
@@ -26,7 +22,6 @@ function callIfNecessary(o, context) {
|
|
|
26
22
|
return o;
|
|
27
23
|
}
|
|
28
24
|
}
|
|
29
|
-
|
|
30
25
|
function callIfNecessaryArray(o, context) {
|
|
31
26
|
if (Array.isArray(o)) {
|
|
32
27
|
return o.map(v => callIfNecessary(v, context));
|
|
@@ -34,53 +29,21 @@ function callIfNecessaryArray(o, context) {
|
|
|
34
29
|
return o;
|
|
35
30
|
}
|
|
36
31
|
}
|
|
37
|
-
|
|
38
32
|
function escapeLarge(sqlFragment, type) {
|
|
39
33
|
const actualType = type.domainBaseType || type;
|
|
40
|
-
|
|
41
34
|
if (actualType.category === "N") {
|
|
42
|
-
if (["21"
|
|
43
|
-
/* int2 */
|
|
44
|
-
, "23"
|
|
45
|
-
/* int4 */
|
|
46
|
-
, "700"
|
|
47
|
-
/* float4 */
|
|
48
|
-
, "701"
|
|
49
|
-
/* float8 */
|
|
50
|
-
, "24"
|
|
51
|
-
/* regproc */
|
|
52
|
-
, "2202"
|
|
53
|
-
/* regprocedure */
|
|
54
|
-
, "2203"
|
|
55
|
-
/* regoper */
|
|
56
|
-
, "2204"
|
|
57
|
-
/* regoperator */
|
|
58
|
-
, "2205"
|
|
59
|
-
/* regclass */
|
|
60
|
-
, "2206"
|
|
61
|
-
/* regtype */
|
|
62
|
-
, "4096"
|
|
63
|
-
/* regrole */
|
|
64
|
-
, "4089"
|
|
65
|
-
/* regnamespace */
|
|
66
|
-
, "3734"
|
|
67
|
-
/* regconfig */
|
|
68
|
-
, "3769"
|
|
69
|
-
/* regdictionary */
|
|
70
|
-
].includes(actualType.id)) {
|
|
35
|
+
if (["21" /* int2 */, "23" /* int4 */, "700" /* float4 */, "701" /* float8 */, "24" /* regproc */, "2202" /* regprocedure */, "2203" /* regoper */, "2204" /* regoperator */, "2205" /* regclass */, "2206" /* regtype */, "4096" /* regrole */, "4089" /* regnamespace */, "3734" /* regconfig */, "3769" /* regdictionary */].includes(actualType.id)) {
|
|
71
36
|
// No need for special handling
|
|
72
37
|
return sqlFragment;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
|
|
38
|
+
}
|
|
39
|
+
// Otherwise force the id to be a string
|
|
76
40
|
return sql.fragment`((${sqlFragment})::numeric)::text`;
|
|
77
41
|
}
|
|
78
|
-
|
|
79
42
|
return sqlFragment;
|
|
80
43
|
}
|
|
81
|
-
|
|
82
44
|
class QueryBuilder {
|
|
83
45
|
// eslint-disable-line flowtype/no-weak-types
|
|
46
|
+
|
|
84
47
|
constructor(options = {}, context = {}, rootValue) {
|
|
85
48
|
this.context = context || {};
|
|
86
49
|
this.rootValue = rootValue;
|
|
@@ -168,12 +131,11 @@ class QueryBuilder {
|
|
|
168
131
|
this._children = new Map();
|
|
169
132
|
this.beforeLock("select", () => {
|
|
170
133
|
this.lock("selectCursor");
|
|
171
|
-
|
|
172
134
|
if (this.compiledData.selectCursor) {
|
|
173
135
|
this.select(this.compiledData.selectCursor, "__cursor");
|
|
174
136
|
}
|
|
175
|
-
});
|
|
176
|
-
|
|
137
|
+
});
|
|
138
|
+
// 'whereBound' and 'natural' order might set offset/limit
|
|
177
139
|
this.beforeLock("where", () => {
|
|
178
140
|
this.lock("whereBound");
|
|
179
141
|
});
|
|
@@ -194,57 +156,51 @@ class QueryBuilder {
|
|
|
194
156
|
this.lockContext = Object.freeze({
|
|
195
157
|
queryBuilder: this
|
|
196
158
|
});
|
|
197
|
-
}
|
|
198
|
-
// Helper function
|
|
159
|
+
}
|
|
199
160
|
|
|
161
|
+
// ----------------------------------------
|
|
200
162
|
|
|
163
|
+
// Helper function
|
|
201
164
|
jsonbBuildObject(fields) {
|
|
202
165
|
if (this.supportsJSONB && fields.length > 50) {
|
|
203
166
|
const fieldsChunks = (0, _chunk.default)(fields, 50);
|
|
204
|
-
|
|
205
167
|
const chunkToJson = fieldsChunk => sql.fragment`jsonb_build_object(${sql.join(fieldsChunk.map(([expr, alias]) => sql.fragment`${sql.literal(alias)}::text, ${expr}`), ", ")})`;
|
|
206
|
-
|
|
207
168
|
return sql.fragment`(${sql.join(fieldsChunks.map(chunkToJson), " || ")})::json`;
|
|
208
169
|
} else {
|
|
209
170
|
// PG9.4 will have issues with more than 100 parameters (50 keys)
|
|
210
171
|
return sql.fragment`json_build_object(${sql.join(fields.map(([expr, alias]) => sql.fragment`${sql.literal(alias)}::text, ${expr}`), ", ")})`;
|
|
211
172
|
}
|
|
212
|
-
}
|
|
173
|
+
}
|
|
213
174
|
|
|
175
|
+
// ----------------------------------------
|
|
214
176
|
|
|
215
177
|
beforeLock(field, fn) {
|
|
216
178
|
this.checkLock(field);
|
|
217
|
-
|
|
218
179
|
if (!this.data.beforeLock[field]) {
|
|
219
180
|
this.data.beforeLock[field] = [];
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
|
|
181
|
+
}
|
|
182
|
+
// $FlowFixMe: this is guaranteed to be set, due to the if statement above
|
|
223
183
|
this.data.beforeLock[field].push(fn);
|
|
224
184
|
}
|
|
225
|
-
|
|
226
|
-
|
|
185
|
+
makeLiveCollection(table,
|
|
186
|
+
// eslint-disable-next-line flowtype/no-weak-types
|
|
227
187
|
cb) {
|
|
228
188
|
/* the actual condition doesn't matter hugely, 'select' should work */
|
|
229
189
|
if (!this.rootValue || !this.rootValue.liveConditions) return;
|
|
230
190
|
const liveConditions = this.data.liveConditions;
|
|
231
|
-
|
|
232
191
|
const checkerGenerator = data => {
|
|
233
192
|
// Compute this once.
|
|
234
193
|
const checkers = liveConditions.map(([checkerGenerator]) => checkerGenerator(data));
|
|
235
194
|
return record => checkers.every(checker => checker(record));
|
|
236
195
|
};
|
|
237
|
-
|
|
238
196
|
if (this.parentQueryBuilder) {
|
|
239
197
|
const parentQueryBuilder = this.parentQueryBuilder;
|
|
240
|
-
|
|
241
198
|
if (cb) {
|
|
242
199
|
throw new Error("Either use parentQueryBuilder or pass callback, not both.");
|
|
243
200
|
}
|
|
244
|
-
|
|
245
201
|
parentQueryBuilder.beforeLock("select", () => {
|
|
246
|
-
const id = this.rootValue.liveConditions.push(checkerGenerator) - 1;
|
|
247
|
-
|
|
202
|
+
const id = this.rootValue.liveConditions.push(checkerGenerator) - 1;
|
|
203
|
+
// BEWARE: it's easy to override others' conditions, and that will cause issues. Be sensible.
|
|
248
204
|
const allRequirements = this.data.liveConditions.reduce((memo, [_checkerGenerator, requirements]) => requirements ? Object.assign(memo, requirements) : memo, {});
|
|
249
205
|
parentQueryBuilder.select(sql.fragment`\
|
|
250
206
|
json_build_object('__id', ${sql.value(id)}::int
|
|
@@ -256,56 +212,44 @@ ${sql.join(Object.keys(allRequirements).map(key => sql.fragment`, ${sql.literal(
|
|
|
256
212
|
throw new Error("makeLiveCollection was called without parentQueryBuilder and without callback");
|
|
257
213
|
}
|
|
258
214
|
}
|
|
259
|
-
|
|
260
|
-
|
|
215
|
+
addLiveCondition(
|
|
216
|
+
// eslint-disable-next-line flowtype/no-weak-types
|
|
261
217
|
checkerGenerator, requirements) {
|
|
262
218
|
if (requirements && !this.parentQueryBuilder) {
|
|
263
219
|
throw new Error("There's no parentQueryBuilder, so there cannot be requirements");
|
|
264
220
|
}
|
|
265
|
-
|
|
266
221
|
this.data.liveConditions.push([checkerGenerator, requirements]);
|
|
267
222
|
}
|
|
268
|
-
|
|
269
223
|
setCursorComparator(fn) {
|
|
270
224
|
this.checkLock("cursorComparator");
|
|
271
225
|
this.data.cursorComparator = fn;
|
|
272
226
|
this.lock("cursorComparator");
|
|
273
227
|
}
|
|
274
|
-
|
|
275
228
|
addCursorCondition(cursorValue, isAfter) {
|
|
276
229
|
this.beforeLock("whereBound", () => {
|
|
277
230
|
this.lock("cursorComparator");
|
|
278
|
-
|
|
279
231
|
if (!this.compiledData.cursorComparator) {
|
|
280
232
|
throw new Error("No cursor comparator was set!");
|
|
281
233
|
}
|
|
282
|
-
|
|
283
234
|
this.compiledData.cursorComparator(cursorValue, isAfter);
|
|
284
235
|
});
|
|
285
236
|
}
|
|
286
237
|
/** this method is experimental */
|
|
287
|
-
|
|
288
|
-
|
|
289
238
|
fixedSelectExpression(exprGen) {
|
|
290
239
|
this.checkLock("fixedSelectExpression");
|
|
291
240
|
this.lock("select");
|
|
292
241
|
this.lock("selectCursor");
|
|
293
|
-
|
|
294
242
|
if (this.data.select.length > 0) {
|
|
295
243
|
throw new Error("Cannot use .fixedSelectExpression() with .select()");
|
|
296
244
|
}
|
|
297
|
-
|
|
298
245
|
if (this.data.selectCursor) {
|
|
299
246
|
throw new Error("Cannot use .fixedSelectExpression() with .selectCursor()");
|
|
300
247
|
}
|
|
301
|
-
|
|
302
248
|
this.data.fixedSelectExpression = exprGen;
|
|
303
249
|
}
|
|
304
|
-
|
|
305
250
|
select(exprGen, alias) {
|
|
306
251
|
this.checkLock("select");
|
|
307
252
|
this.lock("fixedSelectExpression");
|
|
308
|
-
|
|
309
253
|
if (typeof alias === "string") {
|
|
310
254
|
// To protect against vulnerabilities such as
|
|
311
255
|
//
|
|
@@ -321,10 +265,8 @@ ${sql.join(Object.keys(allRequirements).map(key => sql.fragment`, ${sql.literal(
|
|
|
321
265
|
throw new Error(`Disallowed alias '${alias}'.`);
|
|
322
266
|
}
|
|
323
267
|
}
|
|
324
|
-
|
|
325
268
|
this.data.select.push([exprGen, alias]);
|
|
326
269
|
}
|
|
327
|
-
|
|
328
270
|
selectIdentifiers(table) {
|
|
329
271
|
if (this.selectedIdentifiers) return;
|
|
330
272
|
const primaryKey = table.primaryKeyConstraint;
|
|
@@ -333,69 +275,53 @@ ${sql.join(Object.keys(allRequirements).map(key => sql.fragment`, ${sql.literal(
|
|
|
333
275
|
this.select(sql.fragment`json_build_array(${sql.join(primaryKeys.map(key => escapeLarge(sql.fragment`${this.getTableAlias()}.${sql.identifier(key.name)}`, key.type)), ", ")})`, "__identifiers");
|
|
334
276
|
this.selectedIdentifiers = true;
|
|
335
277
|
}
|
|
336
|
-
|
|
337
278
|
selectCursor(exprGen) {
|
|
338
279
|
this.checkLock("selectCursor");
|
|
339
280
|
this.lock("fixedSelectExpression");
|
|
340
281
|
this.data.selectCursor = exprGen;
|
|
341
282
|
}
|
|
342
|
-
|
|
343
283
|
from(expr, alias = sql.identifier(Symbol())) {
|
|
344
284
|
this.checkLock("from");
|
|
345
|
-
|
|
346
285
|
if (!expr) {
|
|
347
286
|
throw new Error("No from table source!");
|
|
348
287
|
}
|
|
349
|
-
|
|
350
288
|
if (!alias) {
|
|
351
289
|
throw new Error("No from alias!");
|
|
352
290
|
}
|
|
353
|
-
|
|
354
291
|
this.data.from = [expr, alias];
|
|
355
292
|
this.lock("from");
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
|
|
293
|
+
}
|
|
294
|
+
// XXX: join
|
|
359
295
|
where(exprGen) {
|
|
360
296
|
this.checkLock("where");
|
|
361
297
|
this.data.where.push(exprGen);
|
|
362
298
|
}
|
|
363
|
-
|
|
364
299
|
whereBound(exprGen, isLower) {
|
|
365
300
|
if (typeof isLower !== "boolean") {
|
|
366
301
|
throw new Error("isLower must be specified as a boolean");
|
|
367
302
|
}
|
|
368
|
-
|
|
369
303
|
this.checkLock("whereBound");
|
|
370
304
|
this.data.whereBound[isLower ? "lower" : "upper"].push(exprGen);
|
|
371
305
|
}
|
|
372
|
-
|
|
373
306
|
setOrderIsUnique() {
|
|
374
307
|
this.data.orderIsUnique = true;
|
|
375
308
|
}
|
|
376
|
-
|
|
377
309
|
orderBy(exprGen, ascending = true, nullsFirst = null) {
|
|
378
310
|
this.checkLock("orderBy");
|
|
379
311
|
this.data.orderBy.push([exprGen, ascending, nullsFirst]);
|
|
380
312
|
}
|
|
381
|
-
|
|
382
313
|
limit(limitGen) {
|
|
383
314
|
this.checkLock("limit");
|
|
384
|
-
|
|
385
315
|
if (this.data.limit != null) {
|
|
386
316
|
throw new Error("Must only set limit once");
|
|
387
317
|
}
|
|
388
|
-
|
|
389
318
|
this.data.limit = limitGen;
|
|
390
319
|
}
|
|
391
|
-
|
|
392
320
|
offset(offsetGen) {
|
|
393
321
|
this.checkLock("offset");
|
|
394
|
-
|
|
395
322
|
if (this.data.offset != null) {
|
|
396
323
|
// Add the offsets together (this should be able to recurse)
|
|
397
324
|
const previous = this.data.offset;
|
|
398
|
-
|
|
399
325
|
this.data.offset = context => {
|
|
400
326
|
return callIfNecessary(previous, context) + callIfNecessary(offsetGen, context);
|
|
401
327
|
};
|
|
@@ -403,27 +329,22 @@ ${sql.join(Object.keys(allRequirements).map(key => sql.fragment`, ${sql.literal(
|
|
|
403
329
|
this.data.offset = offsetGen;
|
|
404
330
|
}
|
|
405
331
|
}
|
|
406
|
-
|
|
407
332
|
first(first) {
|
|
408
333
|
this.checkLock("first");
|
|
409
|
-
|
|
410
334
|
if (this.data.first != null) {
|
|
411
335
|
throw new Error("Must only set first once");
|
|
412
336
|
}
|
|
413
|
-
|
|
414
337
|
this.data.first = first;
|
|
415
338
|
}
|
|
416
|
-
|
|
417
339
|
last(last) {
|
|
418
340
|
this.checkLock("last");
|
|
419
|
-
|
|
420
341
|
if (this.data.last != null) {
|
|
421
342
|
throw new Error("Must only set last once");
|
|
422
343
|
}
|
|
423
|
-
|
|
424
344
|
this.data.last = last;
|
|
425
|
-
}
|
|
345
|
+
}
|
|
426
346
|
|
|
347
|
+
// ----------------------------------------
|
|
427
348
|
|
|
428
349
|
isOrderUnique(lock = true) {
|
|
429
350
|
if (lock) {
|
|
@@ -435,37 +356,28 @@ ${sql.join(Object.keys(allRequirements).map(key => sql.fragment`, ${sql.literal(
|
|
|
435
356
|
return this.data.orderIsUnique;
|
|
436
357
|
}
|
|
437
358
|
}
|
|
438
|
-
|
|
439
359
|
getTableExpression() {
|
|
440
360
|
this.lock("from");
|
|
441
|
-
|
|
442
361
|
if (!this.compiledData.from) {
|
|
443
362
|
throw new Error("No from table has been supplied");
|
|
444
363
|
}
|
|
445
|
-
|
|
446
364
|
return this.compiledData.from[0];
|
|
447
365
|
}
|
|
448
|
-
|
|
449
366
|
getTableAlias() {
|
|
450
367
|
this.lock("from");
|
|
451
|
-
|
|
452
368
|
if (!this.compiledData.from) {
|
|
453
369
|
throw new Error("No from table has been supplied");
|
|
454
370
|
}
|
|
455
|
-
|
|
456
371
|
return this.compiledData.from[1];
|
|
457
372
|
}
|
|
458
|
-
|
|
459
373
|
getSelectCursor() {
|
|
460
374
|
this.lock("selectCursor");
|
|
461
375
|
return this.compiledData.selectCursor;
|
|
462
376
|
}
|
|
463
|
-
|
|
464
377
|
getOffset() {
|
|
465
378
|
this.lock("offset");
|
|
466
379
|
return this.compiledData.offset || 0;
|
|
467
380
|
}
|
|
468
|
-
|
|
469
381
|
getFinalLimitAndOffset() {
|
|
470
382
|
this.lock("offset");
|
|
471
383
|
this.lock("limit");
|
|
@@ -474,7 +386,6 @@ ${sql.join(Object.keys(allRequirements).map(key => sql.fragment`, ${sql.literal(
|
|
|
474
386
|
let limit = this.compiledData.limit;
|
|
475
387
|
let offset = this.compiledData.offset || 0;
|
|
476
388
|
let flip = false;
|
|
477
|
-
|
|
478
389
|
if (this.compiledData.first != null) {
|
|
479
390
|
if (limit != null) {
|
|
480
391
|
limit = Math.min(limit, this.compiledData.first);
|
|
@@ -482,17 +393,16 @@ ${sql.join(Object.keys(allRequirements).map(key => sql.fragment`, ${sql.literal(
|
|
|
482
393
|
limit = this.compiledData.first;
|
|
483
394
|
}
|
|
484
395
|
}
|
|
485
|
-
|
|
486
396
|
if (this.compiledData.last != null) {
|
|
487
397
|
if (offset > 0 && limit != null) {
|
|
488
398
|
throw new Error("Issue within pagination, please report your query to graphile-build");
|
|
489
399
|
}
|
|
490
|
-
|
|
491
400
|
if (limit != null) {
|
|
492
401
|
if (this.compiledData.last < limit) {
|
|
493
402
|
offset = limit - this.compiledData.last;
|
|
494
403
|
limit = this.compiledData.last;
|
|
495
|
-
} else {
|
|
404
|
+
} else {
|
|
405
|
+
// no need to change anything
|
|
496
406
|
}
|
|
497
407
|
} else if (offset > 0) {
|
|
498
408
|
throw new Error("Cannot combine 'last' and 'offset'");
|
|
@@ -505,49 +415,39 @@ ${sql.join(Object.keys(allRequirements).map(key => sql.fragment`, ${sql.literal(
|
|
|
505
415
|
}
|
|
506
416
|
}
|
|
507
417
|
}
|
|
508
|
-
|
|
509
418
|
return {
|
|
510
419
|
limit,
|
|
511
420
|
offset,
|
|
512
421
|
flip
|
|
513
422
|
};
|
|
514
423
|
}
|
|
515
|
-
|
|
516
424
|
getFinalOffset() {
|
|
517
425
|
return this.getFinalLimitAndOffset().offset;
|
|
518
426
|
}
|
|
519
|
-
|
|
520
427
|
getFinalLimit() {
|
|
521
428
|
return this.getFinalLimitAndOffset().limit;
|
|
522
429
|
}
|
|
523
|
-
|
|
524
430
|
getOrderByExpressionsAndDirections() {
|
|
525
431
|
this.lock("orderBy");
|
|
526
432
|
return this.compiledData.orderBy;
|
|
527
433
|
}
|
|
528
|
-
|
|
529
434
|
getSelectFieldsCount() {
|
|
530
435
|
this.lockEverything();
|
|
531
436
|
return this.compiledData.select.length;
|
|
532
437
|
}
|
|
533
|
-
|
|
534
438
|
buildSelectFields() {
|
|
535
439
|
this.lockEverything();
|
|
536
|
-
|
|
537
440
|
if (this.compiledData.fixedSelectExpression) {
|
|
538
441
|
return this.compiledData.fixedSelectExpression;
|
|
539
442
|
}
|
|
540
|
-
|
|
541
443
|
return sql.join(this.compiledData.select.map(([sqlFragment, alias]) => sql.fragment`to_json(${sqlFragment}) as ${sql.identifier(alias)}`), ", ");
|
|
542
444
|
}
|
|
543
|
-
|
|
544
445
|
buildSelectJson({
|
|
545
446
|
addNullCase,
|
|
546
447
|
addNotDistinctFromNullCase
|
|
547
448
|
}) {
|
|
548
449
|
this.lockEverything();
|
|
549
450
|
let buildObject = this.compiledData.select.length ? this.jsonbBuildObject(this.compiledData.select) : sql.fragment`to_json(${this.getTableAlias()})`;
|
|
550
|
-
|
|
551
451
|
if (addNotDistinctFromNullCase) {
|
|
552
452
|
/*
|
|
553
453
|
* `is null` is not sufficient here because the record might exist but
|
|
@@ -565,21 +465,17 @@ ${sql.join(Object.keys(allRequirements).map(key => sql.fragment`, ${sql.literal(
|
|
|
565
465
|
*/
|
|
566
466
|
buildObject = sql.fragment`(case when (${this.getTableAlias()} is null) then null else ${buildObject} end)`;
|
|
567
467
|
}
|
|
568
|
-
|
|
569
468
|
return buildObject;
|
|
570
469
|
}
|
|
571
|
-
|
|
572
470
|
buildWhereBoundClause(isLower) {
|
|
573
471
|
this.lock("whereBound");
|
|
574
472
|
const clauses = this.compiledData.whereBound[isLower ? "lower" : "upper"];
|
|
575
|
-
|
|
576
473
|
if (clauses.length) {
|
|
577
474
|
return sql.fragment`(${sql.join(clauses, ") and (")})`;
|
|
578
475
|
} else {
|
|
579
476
|
return sql.literal(true);
|
|
580
477
|
}
|
|
581
478
|
}
|
|
582
|
-
|
|
583
479
|
buildWhereClause(includeLowerBound, includeUpperBound, {
|
|
584
480
|
addNullCase,
|
|
585
481
|
addNotDistinctFromNullCase
|
|
@@ -612,16 +508,13 @@ ${sql.join(Object.keys(allRequirements).map(key => sql.fragment`, ${sql.literal(
|
|
|
612
508
|
...(addNotDistinctFromNullCase ? [sql.fragment`(${this.getTableAlias()} is distinct from null)`] : addNullCase ? [sql.fragment`not (${this.getTableAlias()} is null)`] : []), ...this.compiledData.where, ...(includeLowerBound ? [this.buildWhereBoundClause(true)] : []), ...(includeUpperBound ? [this.buildWhereBoundClause(false)] : [])];
|
|
613
509
|
return clauses.length ? sql.fragment`(${sql.join(clauses, ") and (")})` : sql.fragment`1 = 1`;
|
|
614
510
|
}
|
|
615
|
-
|
|
616
511
|
build(options = {}) {
|
|
617
512
|
this.lockEverything();
|
|
618
|
-
|
|
619
513
|
if (this.compiledData.fixedSelectExpression) {
|
|
620
514
|
if (Object.keys(options).length > 0) {
|
|
621
515
|
throw new Error("Do not pass options to QueryBuilder.build() when using `buildNamedChildSelecting`");
|
|
622
516
|
}
|
|
623
517
|
}
|
|
624
|
-
|
|
625
518
|
const {
|
|
626
519
|
asJson = false,
|
|
627
520
|
asJsonAggregate = false,
|
|
@@ -630,14 +523,12 @@ ${sql.join(Object.keys(allRequirements).map(key => sql.fragment`, ${sql.literal(
|
|
|
630
523
|
addNotDistinctFromNullCase = false,
|
|
631
524
|
useAsterisk = false
|
|
632
525
|
} = options;
|
|
633
|
-
|
|
634
526
|
if (onlyJsonField) {
|
|
635
527
|
return this.buildSelectJson({
|
|
636
528
|
addNullCase,
|
|
637
529
|
addNotDistinctFromNullCase
|
|
638
530
|
});
|
|
639
531
|
}
|
|
640
|
-
|
|
641
532
|
const {
|
|
642
533
|
limit,
|
|
643
534
|
offset,
|
|
@@ -655,7 +546,6 @@ where ${this.buildWhereClause(true, true, options)}
|
|
|
655
546
|
${this.compiledData.orderBy.length ? sql.fragment`order by ${sql.join(this.compiledData.orderBy.map(([expr, ascending, nullsFirst]) => sql.fragment`${expr} ${Number(ascending) ^ Number(flip) ? sql.fragment`ASC` : sql.fragment`DESC`}${nullsFirst === true ? sql.fragment` NULLS FIRST` : nullsFirst === false ? sql.fragment` NULLS LAST` : null}`), ",")}` : ""}
|
|
656
547
|
${(0, _isSafeInteger.default)(limit) && sql.fragment`limit ${sql.literal(limit)}`}
|
|
657
548
|
${offset && sql.fragment`offset ${sql.literal(offset)}`}`;
|
|
658
|
-
|
|
659
549
|
if (flip) {
|
|
660
550
|
const flipAlias = Symbol();
|
|
661
551
|
fragment = sql.fragment`\
|
|
@@ -664,8 +554,7 @@ with ${sql.identifier(flipAlias)} as (
|
|
|
664
554
|
)
|
|
665
555
|
select *
|
|
666
556
|
from ${sql.identifier(flipAlias)}
|
|
667
|
-
order by (row_number() over (partition by 1)) desc`;
|
|
668
|
-
/* We don't need to factor useAsterisk into this row_number() usage */
|
|
557
|
+
order by (row_number() over (partition by 1)) desc`; /* We don't need to factor useAsterisk into this row_number() usage */
|
|
669
558
|
}
|
|
670
559
|
|
|
671
560
|
if (useAsterisk) {
|
|
@@ -676,21 +565,19 @@ order by (row_number() over (partition by 1)) desc`;
|
|
|
676
565
|
*/
|
|
677
566
|
fragment = sql.fragment`select ${fields} from (${fragment}) ${this.getTableAlias()}`;
|
|
678
567
|
}
|
|
679
|
-
|
|
680
568
|
if (asJsonAggregate) {
|
|
681
569
|
const aggAlias = Symbol();
|
|
682
570
|
fragment = sql.fragment`select json_agg(${sql.identifier(aggAlias, "object")}) from (${fragment}) as ${sql.identifier(aggAlias)}`;
|
|
683
571
|
fragment = sql.fragment`select coalesce((${fragment}), '[]'::json)`;
|
|
684
572
|
}
|
|
685
|
-
|
|
686
573
|
return fragment;
|
|
687
|
-
}
|
|
574
|
+
}
|
|
688
575
|
|
|
576
|
+
// ----------------------------------------
|
|
689
577
|
|
|
690
578
|
_finalize() {
|
|
691
579
|
this.finalized = true;
|
|
692
580
|
}
|
|
693
|
-
|
|
694
581
|
lock(type) {
|
|
695
582
|
if (this.locks[type]) return;
|
|
696
583
|
const context = this.lockContext;
|
|
@@ -698,19 +585,15 @@ order by (row_number() over (partition by 1)) desc`;
|
|
|
698
585
|
beforeLock
|
|
699
586
|
} = this.data;
|
|
700
587
|
let locks = beforeLock[type];
|
|
701
|
-
|
|
702
588
|
if (locks) {
|
|
703
589
|
beforeLock[type] = [];
|
|
704
|
-
|
|
705
590
|
for (let i = 0, l = locks.length; i < l; i++) {
|
|
706
591
|
locks[i]();
|
|
707
592
|
}
|
|
708
593
|
}
|
|
709
|
-
|
|
710
594
|
if (type !== "select") {
|
|
711
595
|
this.locks[type] = isDev ? new Error("Initally locked here").stack : true;
|
|
712
596
|
}
|
|
713
|
-
|
|
714
597
|
if (type === "cursorComparator") {
|
|
715
598
|
// It's meant to be a function
|
|
716
599
|
this.compiledData[type] = this.data[type];
|
|
@@ -726,30 +609,28 @@ order by (row_number() over (partition by 1)) desc`;
|
|
|
726
609
|
* length of this.data[type] may increase during the operation. This is
|
|
727
610
|
* why we handle this.locks[type] separately.
|
|
728
611
|
*/
|
|
612
|
+
|
|
729
613
|
// Assume that duplicate fields must be identical, don't output the same
|
|
730
614
|
// key multiple times
|
|
731
615
|
const seenFields = {};
|
|
732
616
|
const data = [];
|
|
733
|
-
const selects = this.data[type];
|
|
617
|
+
const selects = this.data[type];
|
|
734
618
|
|
|
619
|
+
// DELIBERATE slow loop, see NOTICE above
|
|
735
620
|
for (let i = 0; i < selects.length; i++) {
|
|
736
621
|
const [valueOrGenerator, columnName] = selects[i];
|
|
737
|
-
|
|
738
622
|
if (!seenFields[columnName]) {
|
|
739
623
|
seenFields[columnName] = true;
|
|
740
624
|
data.push([callIfNecessary(valueOrGenerator, context), columnName]);
|
|
741
625
|
locks = beforeLock[type];
|
|
742
|
-
|
|
743
626
|
if (locks) {
|
|
744
627
|
beforeLock[type] = [];
|
|
745
|
-
|
|
746
628
|
for (let i = 0, l = locks.length; i < l; i++) {
|
|
747
629
|
locks[i]();
|
|
748
630
|
}
|
|
749
631
|
}
|
|
750
632
|
}
|
|
751
633
|
}
|
|
752
|
-
|
|
753
634
|
this.locks[type] = isDev ? new Error("Initally locked here").stack : true;
|
|
754
635
|
this.compiledData[type] = data;
|
|
755
636
|
} else if (type === "orderBy") {
|
|
@@ -779,41 +660,35 @@ order by (row_number() over (partition by 1)) desc`;
|
|
|
779
660
|
throw new Error(`Wasn't expecting to lock '${type}'`);
|
|
780
661
|
}
|
|
781
662
|
}
|
|
782
|
-
|
|
783
663
|
checkLock(type) {
|
|
784
664
|
if (this.locks[type]) {
|
|
785
665
|
if (typeof this.locks[type] === "string") {
|
|
786
666
|
throw new Error(`'${type}' has already been locked\n ` + this.locks[type].replace(/\n/g, "\n ") + "\n");
|
|
787
667
|
}
|
|
788
|
-
|
|
789
668
|
throw new Error(`'${type}' has already been locked`);
|
|
790
669
|
}
|
|
791
670
|
}
|
|
792
|
-
|
|
793
671
|
lockEverything() {
|
|
794
|
-
this._finalize();
|
|
795
|
-
|
|
796
|
-
|
|
672
|
+
this._finalize();
|
|
673
|
+
// We must execute everything after `from` so we have the alias to reference
|
|
797
674
|
this.lock("from");
|
|
798
675
|
this.lock("join");
|
|
799
|
-
this.lock("orderBy");
|
|
800
|
-
|
|
676
|
+
this.lock("orderBy");
|
|
677
|
+
// We must execute where after orderBy because cursor queries require all orderBy columns
|
|
801
678
|
this.lock("cursorComparator");
|
|
802
679
|
this.lock("whereBound");
|
|
803
|
-
this.lock("where");
|
|
804
|
-
|
|
680
|
+
this.lock("where");
|
|
681
|
+
// 'where' -> 'whereBound' can affect 'offset'/'limit'
|
|
805
682
|
this.lock("offset");
|
|
806
683
|
this.lock("limit");
|
|
807
684
|
this.lock("first");
|
|
808
|
-
this.lock("last");
|
|
809
|
-
|
|
685
|
+
this.lock("last");
|
|
686
|
+
// We must execute select after orderBy otherwise we cannot generate a cursor
|
|
810
687
|
this.lock("fixedSelectExpression");
|
|
811
688
|
this.lock("selectCursor");
|
|
812
689
|
this.lock("select");
|
|
813
690
|
}
|
|
814
691
|
/** this method is experimental */
|
|
815
|
-
|
|
816
|
-
|
|
817
692
|
buildChild() {
|
|
818
693
|
const options = {
|
|
819
694
|
supportsJSONB: this.supportsJSONB
|
|
@@ -823,30 +698,21 @@ order by (row_number() over (partition by 1)) desc`;
|
|
|
823
698
|
return child;
|
|
824
699
|
}
|
|
825
700
|
/** this method is experimental */
|
|
826
|
-
|
|
827
|
-
|
|
828
701
|
buildNamedChildSelecting(name, from, selectExpression, alias) {
|
|
829
702
|
if (this._children.has(name)) {
|
|
830
703
|
throw new Error(`QueryBuilder already has a child named ${name.toString()}`);
|
|
831
704
|
}
|
|
832
|
-
|
|
833
705
|
const child = this.buildChild();
|
|
834
706
|
child.from(from, alias);
|
|
835
707
|
child.fixedSelectExpression(selectExpression);
|
|
836
|
-
|
|
837
708
|
this._children.set(name, child);
|
|
838
|
-
|
|
839
709
|
return child;
|
|
840
710
|
}
|
|
841
711
|
/** this method is experimental */
|
|
842
|
-
|
|
843
|
-
|
|
844
712
|
getNamedChild(name) {
|
|
845
713
|
return this._children.get(name);
|
|
846
714
|
}
|
|
847
|
-
|
|
848
715
|
}
|
|
849
|
-
|
|
850
716
|
var _default = QueryBuilder;
|
|
851
717
|
exports.default = _default;
|
|
852
718
|
//# sourceMappingURL=QueryBuilder.js.map
|