@snowtop/ent 0.1.0-alpha149 → 0.1.0-alpha150
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/core/ent.js
CHANGED
|
@@ -627,17 +627,18 @@ function buildQuery(options) {
|
|
|
627
627
|
const fields = options.fields.join(", ");
|
|
628
628
|
// always start at 1
|
|
629
629
|
const whereClause = options.clause.clause(1);
|
|
630
|
-
|
|
630
|
+
const parts = [];
|
|
631
|
+
parts.push(`SELECT ${fields} FROM ${options.tableName} WHERE ${whereClause}`);
|
|
631
632
|
if (options.groupby) {
|
|
632
|
-
|
|
633
|
+
parts.push(`GROUP BY ${options.groupby}`);
|
|
633
634
|
}
|
|
634
635
|
if (options.orderby) {
|
|
635
|
-
|
|
636
|
+
parts.push(`ORDER BY ${options.orderby}`);
|
|
636
637
|
}
|
|
637
638
|
if (options.limit) {
|
|
638
|
-
|
|
639
|
+
parts.push(`LIMIT ${options.limit}`);
|
|
639
640
|
}
|
|
640
|
-
return
|
|
641
|
+
return parts.join(" ");
|
|
641
642
|
}
|
|
642
643
|
exports.buildQuery = buildQuery;
|
|
643
644
|
// this is used for queries when we select multiple ids at once
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { Data, EdgeQueryableDataOptions, Ent, ID, LoadEntOptions, Viewer } from "../base";
|
|
2
2
|
import { Clause } from "../clause";
|
|
3
3
|
import { BaseEdgeQuery, IDInfo } from "./query";
|
|
4
|
-
interface CustomClauseQueryOptions<TDest extends Ent<TViewer>, TViewer extends Viewer = Viewer> {
|
|
4
|
+
export interface CustomClauseQueryOptions<TDest extends Ent<TViewer>, TViewer extends Viewer = Viewer> {
|
|
5
5
|
loadEntOptions: LoadEntOptions<TDest, TViewer>;
|
|
6
6
|
clause: Clause;
|
|
7
7
|
name: string;
|
|
8
8
|
sortColumn?: string;
|
|
9
9
|
sortColumnUnique?: boolean;
|
|
10
10
|
orderByDirection?: "asc" | "desc";
|
|
11
|
+
nullsPlacement?: "first" | "last";
|
|
11
12
|
disableTransformations?: boolean;
|
|
12
13
|
}
|
|
13
14
|
export declare class CustomClauseQuery<TDest extends Ent<TViewer>, TViewer extends Viewer = Viewer> extends BaseEdgeQuery<any, TDest, Data> {
|
|
@@ -24,4 +25,3 @@ export declare class CustomClauseQuery<TDest extends Ent<TViewer>, TViewer exten
|
|
|
24
25
|
dataToID(edge: Data): ID;
|
|
25
26
|
protected loadEntsFromEdges(id: ID, rows: Data[]): Promise<TDest[]>;
|
|
26
27
|
}
|
|
27
|
-
export {};
|
|
@@ -30,7 +30,11 @@ class CustomClauseQuery extends query_1.BaseEdgeQuery {
|
|
|
30
30
|
if (options.orderByDirection) {
|
|
31
31
|
sortCol = `${sortCol} ${options.orderByDirection}`;
|
|
32
32
|
}
|
|
33
|
-
super(viewer,
|
|
33
|
+
super(viewer, {
|
|
34
|
+
sortCol,
|
|
35
|
+
cursorCol: unique,
|
|
36
|
+
nullsPlacement: options.nullsPlacement,
|
|
37
|
+
});
|
|
34
38
|
this.viewer = viewer;
|
|
35
39
|
this.options = options;
|
|
36
40
|
this.clause = getClause(options);
|
package/core/query/query.d.ts
CHANGED
|
@@ -29,6 +29,11 @@ export interface PaginationInfo {
|
|
|
29
29
|
startCursor: string;
|
|
30
30
|
endCursor: string;
|
|
31
31
|
}
|
|
32
|
+
interface EdgeQueryOptions {
|
|
33
|
+
cursorCol: string;
|
|
34
|
+
sortCol: string;
|
|
35
|
+
nullsPlacement?: "first" | "last";
|
|
36
|
+
}
|
|
32
37
|
export declare abstract class BaseEdgeQuery<TSource extends Ent, TDest extends Ent, TEdge extends Data> implements EdgeQuery<TSource, TDest, TEdge> {
|
|
33
38
|
viewer: Viewer;
|
|
34
39
|
private filters;
|
|
@@ -42,7 +47,9 @@ export declare abstract class BaseEdgeQuery<TSource extends Ent, TDest extends E
|
|
|
42
47
|
private sortCol;
|
|
43
48
|
private cursorCol;
|
|
44
49
|
private defaultDirection?;
|
|
50
|
+
private edgeQueryOptions;
|
|
45
51
|
constructor(viewer: Viewer, sortCol: string, cursorCol: string);
|
|
52
|
+
constructor(viewer: Viewer, options: EdgeQueryOptions);
|
|
46
53
|
protected getSortCol(): string;
|
|
47
54
|
getPrivacyPolicy(): PrivacyPolicy<Ent<Viewer<Ent<any> | null, ID | null>>, Viewer<Ent<any> | null, ID | null>>;
|
|
48
55
|
abstract sourceEnt(id: ID): Promise<Ent | null>;
|
|
@@ -76,3 +83,4 @@ export interface IDInfo {
|
|
|
76
83
|
id: ID;
|
|
77
84
|
invalidated?: boolean;
|
|
78
85
|
}
|
|
86
|
+
export {};
|
package/core/query/query.js
CHANGED
|
@@ -99,9 +99,19 @@ class FirstFilter {
|
|
|
99
99
|
// we sort by most recent first
|
|
100
100
|
// so when paging, we fetch afterCursor X
|
|
101
101
|
const less = orderby === "DESC";
|
|
102
|
+
let nullsPlacement = "";
|
|
103
|
+
if (this.options.nullsPlacement) {
|
|
104
|
+
if (this.options.nullsPlacement === "first") {
|
|
105
|
+
nullsPlacement = " NULLS FIRST";
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
nullsPlacement = " NULLS LAST";
|
|
109
|
+
}
|
|
110
|
+
}
|
|
102
111
|
if (this.options.cursorCol !== this.sortCol) {
|
|
103
112
|
// we also sort unique col in same direction since it doesn't matter...
|
|
104
|
-
|
|
113
|
+
// nulls placement only affects sortCol. assumption is cursorCol will not be null and no need for that
|
|
114
|
+
options.orderby = `${this.sortCol} ${orderby}${nullsPlacement}, ${this.options.cursorCol} ${orderby}`;
|
|
105
115
|
if (this.offset) {
|
|
106
116
|
const res = this.edgeQuery.getTableName();
|
|
107
117
|
const tableName = util_1.types.isPromise(res) ? await res : res;
|
|
@@ -110,7 +120,7 @@ class FirstFilter {
|
|
|
110
120
|
}
|
|
111
121
|
}
|
|
112
122
|
else {
|
|
113
|
-
options.orderby = `${this.sortCol} ${orderby}`;
|
|
123
|
+
options.orderby = `${this.sortCol}${nullsPlacement} ${orderby}`;
|
|
114
124
|
if (this.offset) {
|
|
115
125
|
let clauseFn = less ? clause.Less : clause.Greater;
|
|
116
126
|
let val = this.options.sortColTime
|
|
@@ -205,7 +215,7 @@ class LastFilter {
|
|
|
205
215
|
}
|
|
206
216
|
}
|
|
207
217
|
class BaseEdgeQuery {
|
|
208
|
-
constructor(viewer,
|
|
218
|
+
constructor(viewer, sortColOrOptions, cursorColMaybe) {
|
|
209
219
|
this.viewer = viewer;
|
|
210
220
|
this.filters = [];
|
|
211
221
|
this.edges = new Map();
|
|
@@ -262,6 +272,21 @@ class BaseEdgeQuery {
|
|
|
262
272
|
await Promise.all(promises);
|
|
263
273
|
return results;
|
|
264
274
|
};
|
|
275
|
+
let sortCol;
|
|
276
|
+
let cursorCol;
|
|
277
|
+
if (typeof sortColOrOptions === "string") {
|
|
278
|
+
sortCol = sortColOrOptions;
|
|
279
|
+
cursorCol = cursorColMaybe;
|
|
280
|
+
this.edgeQueryOptions = {
|
|
281
|
+
cursorCol,
|
|
282
|
+
sortCol,
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
sortCol = sortColOrOptions.sortCol;
|
|
287
|
+
cursorCol = sortColOrOptions.cursorCol;
|
|
288
|
+
this.edgeQueryOptions = sortColOrOptions;
|
|
289
|
+
}
|
|
265
290
|
let m = orderbyRegex.exec(sortCol);
|
|
266
291
|
if (!m) {
|
|
267
292
|
throw new Error(`invalid sort column ${sortCol}`);
|
|
@@ -294,6 +319,7 @@ class BaseEdgeQuery {
|
|
|
294
319
|
sortCol: this.sortCol,
|
|
295
320
|
cursorCol: this.cursorCol,
|
|
296
321
|
defaultDirection: this.defaultDirection,
|
|
322
|
+
nullsPlacement: this.edgeQueryOptions.nullsPlacement,
|
|
297
323
|
query: this,
|
|
298
324
|
}));
|
|
299
325
|
return this;
|
|
@@ -306,6 +332,7 @@ class BaseEdgeQuery {
|
|
|
306
332
|
sortCol: this.sortCol,
|
|
307
333
|
cursorCol: this.cursorCol,
|
|
308
334
|
defaultDirection: this.defaultDirection,
|
|
335
|
+
nullsPlacement: this.edgeQueryOptions.nullsPlacement,
|
|
309
336
|
query: this,
|
|
310
337
|
}));
|
|
311
338
|
return this;
|
package/package.json
CHANGED
|
@@ -257,7 +257,7 @@ async function createAllEvents(opts) {
|
|
|
257
257
|
const input = opts.eventInputs?.[idx];
|
|
258
258
|
const builder = (0, fake_event_1.getEventBuilder)(user.viewer, getEventInput(user, input));
|
|
259
259
|
await builder.saveX();
|
|
260
|
-
return
|
|
260
|
+
return builder.editedEntX();
|
|
261
261
|
}));
|
|
262
262
|
expect(events.length).toBe(opts.howMany);
|
|
263
263
|
return [user, events];
|