@snowtop/ent 0.1.0-alpha151 → 0.1.0-alpha153
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/action/index.d.ts +1 -0
- package/action/operations.d.ts +3 -2
- package/action/operations.js +8 -6
- package/action/orchestrator.d.ts +5 -0
- package/action/orchestrator.js +37 -5
- package/core/base.d.ts +5 -3
- package/core/context.d.ts +2 -1
- package/core/context.js +2 -1
- package/core/ent.d.ts +3 -3
- package/core/ent.js +10 -4
- package/core/loaders/assoc_count_loader.d.ts +4 -2
- package/core/loaders/assoc_count_loader.js +10 -2
- package/core/loaders/assoc_edge_loader.d.ts +2 -3
- package/core/loaders/assoc_edge_loader.js +14 -4
- package/core/loaders/index_loader.d.ts +2 -1
- package/core/loaders/index_loader.js +1 -1
- package/core/loaders/query_loader.d.ts +3 -3
- package/core/loaders/query_loader.js +11 -16
- package/core/privacy.d.ts +19 -10
- package/core/privacy.js +33 -21
- package/core/query/assoc_query.js +1 -1
- package/core/query/custom_clause_query.d.ts +4 -2
- package/core/query/custom_clause_query.js +32 -15
- package/core/query/custom_query.d.ts +3 -1
- package/core/query/custom_query.js +28 -5
- package/core/query/query.d.ts +6 -4
- package/core/query/query.js +51 -46
- package/core/query/shared_assoc_test.js +142 -1
- package/core/query/shared_test.d.ts +2 -2
- package/core/query/shared_test.js +26 -29
- package/core/query_impl.d.ts +8 -0
- package/core/query_impl.js +28 -0
- package/graphql/index.d.ts +1 -1
- package/graphql/index.js +3 -1
- package/graphql/scalars/orderby_direction.js +2 -2
- package/package.json +1 -1
- package/parse_schema/parse.d.ts +1 -0
- package/parse_schema/parse.js +1 -0
- package/testutils/fake_data/fake_user.js +15 -4
- package/testutils/fake_data/tag_query.js +8 -3
- package/testutils/fake_data/test_helpers.d.ts +3 -2
- package/testutils/fake_data/test_helpers.js +3 -3
- package/testutils/fake_data/user_query.d.ts +5 -2
- package/testutils/fake_data/user_query.js +19 -2
package/action/index.d.ts
CHANGED
|
@@ -3,3 +3,4 @@ export { OrchestratorOptions, Orchestrator, EntChangeset, EdgeInputData, } from
|
|
|
3
3
|
export { DenyIfBuilder, AllowIfBuilder } from "./privacy";
|
|
4
4
|
export { RelativeFieldValue, RelativeNumberValue, NumberOps, convertRelativeInput, maybeConvertRelativeInputPlusExpressions, } from "./relative_value";
|
|
5
5
|
export { Transaction } from "./transaction";
|
|
6
|
+
export { AssocEdgeOptions } from "./operations";
|
package/action/operations.d.ts
CHANGED
|
@@ -68,6 +68,7 @@ export interface AssocEdgeInputOptions extends AssocEdgeOptions {
|
|
|
68
68
|
}
|
|
69
69
|
export interface AssocEdgeOptions {
|
|
70
70
|
conditional?: boolean;
|
|
71
|
+
disableTransformations?: boolean;
|
|
71
72
|
}
|
|
72
73
|
export interface AssocEdgeInput extends AssocEdgeInputOptions {
|
|
73
74
|
id1: ID;
|
|
@@ -100,8 +101,8 @@ export declare class EdgeOperation implements DataOperation {
|
|
|
100
101
|
private static resolveData;
|
|
101
102
|
static inboundEdge<T extends Ent, T2 extends Ent>(builder: Builder<T>, edgeType: string, id1: Builder<T2> | ID, nodeType: string, options?: AssocEdgeInputOptions): EdgeOperation;
|
|
102
103
|
static outboundEdge<T extends Ent, T2 extends Ent>(builder: Builder<T>, edgeType: string, id2: Builder<T2> | ID, nodeType: string, options?: AssocEdgeInputOptions): EdgeOperation;
|
|
103
|
-
static removeInboundEdge<T extends Ent>(builder: Builder<T>, edgeType: string, id1: ID): EdgeOperation;
|
|
104
|
-
static removeOutboundEdge<T extends Ent>(builder: Builder<T>, edgeType: string, id2: ID): EdgeOperation;
|
|
104
|
+
static removeInboundEdge<T extends Ent>(builder: Builder<T>, edgeType: string, id1: ID, options?: AssocEdgeInputOptions): EdgeOperation;
|
|
105
|
+
static removeOutboundEdge<T extends Ent>(builder: Builder<T>, edgeType: string, id2: ID, options?: AssocEdgeInputOptions): EdgeOperation;
|
|
105
106
|
}
|
|
106
107
|
export declare class ConditionalOperation<T extends Ent = Ent> implements DataOperation<T> {
|
|
107
108
|
protected op: DataOperation<T>;
|
package/action/operations.js
CHANGED
|
@@ -311,9 +311,8 @@ class EdgeOperation {
|
|
|
311
311
|
let transformed = null;
|
|
312
312
|
let op = schema_1.SQLStatementOperation.Delete;
|
|
313
313
|
let updateData = null;
|
|
314
|
-
// TODO respect disableTransformations
|
|
315
314
|
const transformedEdgeWrite = (0, global_schema_1.__getGlobalSchema)()?.transformEdgeWrite;
|
|
316
|
-
if (transformedEdgeWrite) {
|
|
315
|
+
if (transformedEdgeWrite && !edge.disableTransformations) {
|
|
317
316
|
transformed = transformedEdgeWrite({
|
|
318
317
|
op: schema_1.SQLStatementOperation.Delete,
|
|
319
318
|
edge,
|
|
@@ -405,10 +404,9 @@ class EdgeOperation {
|
|
|
405
404
|
}
|
|
406
405
|
}
|
|
407
406
|
}
|
|
408
|
-
// TODO respect disableTransformations
|
|
409
407
|
let transformed = null;
|
|
410
408
|
const transformEdgeWrite = (0, global_schema_1.__getGlobalSchema)()?.transformEdgeWrite;
|
|
411
|
-
if (transformEdgeWrite) {
|
|
409
|
+
if (transformEdgeWrite && !edge.disableTransformations) {
|
|
412
410
|
transformed = transformEdgeWrite({
|
|
413
411
|
op: schema_1.SQLStatementOperation.Insert,
|
|
414
412
|
edge,
|
|
@@ -471,6 +469,7 @@ class EdgeOperation {
|
|
|
471
469
|
edgeType: this.edgeInput.edgeType,
|
|
472
470
|
time: this.edgeInput.time,
|
|
473
471
|
data: this.edgeInput.data,
|
|
472
|
+
disableTransformations: this.edgeInput.disableTransformations,
|
|
474
473
|
}, {
|
|
475
474
|
operation: this.options.operation,
|
|
476
475
|
id1Placeholder: this.options.id2Placeholder,
|
|
@@ -487,6 +486,7 @@ class EdgeOperation {
|
|
|
487
486
|
edgeType: edgeData.inverseEdgeType,
|
|
488
487
|
time: this.edgeInput.time,
|
|
489
488
|
data: this.edgeInput.data,
|
|
489
|
+
disableTransformations: this.edgeInput.disableTransformations,
|
|
490
490
|
}, {
|
|
491
491
|
operation: this.options.operation,
|
|
492
492
|
id1Placeholder: this.options.id2Placeholder,
|
|
@@ -575,7 +575,7 @@ class EdgeOperation {
|
|
|
575
575
|
dataPlaceholder,
|
|
576
576
|
});
|
|
577
577
|
}
|
|
578
|
-
static removeInboundEdge(builder, edgeType, id1) {
|
|
578
|
+
static removeInboundEdge(builder, edgeType, id1, options) {
|
|
579
579
|
if (!builder.existingEnt) {
|
|
580
580
|
throw new Error("cannot remove an edge from a non-existing ent");
|
|
581
581
|
}
|
|
@@ -585,12 +585,13 @@ class EdgeOperation {
|
|
|
585
585
|
id2: builder.existingEnt.id,
|
|
586
586
|
id2Type: "",
|
|
587
587
|
id1Type: "",
|
|
588
|
+
disableTransformations: options?.disableTransformations,
|
|
588
589
|
};
|
|
589
590
|
return new EdgeOperation(builder, edge, {
|
|
590
591
|
operation: action_1.WriteOperation.Delete,
|
|
591
592
|
});
|
|
592
593
|
}
|
|
593
|
-
static removeOutboundEdge(builder, edgeType, id2) {
|
|
594
|
+
static removeOutboundEdge(builder, edgeType, id2, options) {
|
|
594
595
|
if (!builder.existingEnt) {
|
|
595
596
|
throw new Error("cannot remove an edge from a non-existing ent");
|
|
596
597
|
}
|
|
@@ -600,6 +601,7 @@ class EdgeOperation {
|
|
|
600
601
|
id1: builder.existingEnt.id,
|
|
601
602
|
id2Type: "",
|
|
602
603
|
id1Type: "",
|
|
604
|
+
disableTransformations: options?.disableTransformations,
|
|
603
605
|
};
|
|
604
606
|
return new EdgeOperation(builder, edge, {
|
|
605
607
|
operation: action_1.WriteOperation.Delete,
|
package/action/orchestrator.d.ts
CHANGED
|
@@ -121,6 +121,11 @@ export declare class EntChangeset<T extends Ent> implements Changeset {
|
|
|
121
121
|
constructor(viewer: Viewer, builder: Builder<T>, placeholderID: ID, conditionalOverride: boolean, operations: DataOperation[], dependencies?: Map<ID, Builder<Ent<Viewer<Ent<any> | null, ID | null>>, Viewer<Ent<any> | null, ID | null>, Ent<Viewer<Ent<any> | null, ID | null>> | null>> | undefined, changesets?: Changeset[] | undefined, options?: OrchestratorOptions<T, Data, Viewer<Ent<any> | null, ID | null>, MaybeNull<T>> | undefined);
|
|
122
122
|
static changesetFrom(builder: Builder<any, any, any>, ops: DataOperation[]): EntChangeset<any>;
|
|
123
123
|
static changesetFromQueries(builder: Builder<any, any, any>, queries: Array<string | parameterizedQueryOptions>): EntChangeset<any>;
|
|
124
|
+
private static changesetFromEdgeOp;
|
|
125
|
+
static changesetFromOutboundEdge(builder: Builder<any, any, any>, edgeType: string, id2: Builder<any> | ID, nodeType: string, options?: AssocEdgeInputOptions): Promise<EntChangeset<any>>;
|
|
126
|
+
static changesetFromInboundEdge(builder: Builder<any, any, any>, edgeType: string, id1: Builder<any> | ID, nodeType: string, options?: AssocEdgeInputOptions): Promise<EntChangeset<any>>;
|
|
127
|
+
static changesetRemoveFromOutboundEdge(builder: Builder<any, any, any>, edgeType: string, id2: ID, options?: AssocEdgeInputOptions): Promise<EntChangeset<any>>;
|
|
128
|
+
static changesetRemoveFromInboundEdge(builder: Builder<any, any, any>, edgeType: string, id1: ID, options?: AssocEdgeInputOptions): Promise<EntChangeset<any>>;
|
|
124
129
|
executor(): Executor;
|
|
125
130
|
}
|
|
126
131
|
export {};
|
package/action/orchestrator.js
CHANGED
|
@@ -161,6 +161,7 @@ class Orchestrator {
|
|
|
161
161
|
id: id1,
|
|
162
162
|
edgeType,
|
|
163
163
|
direction: edgeDirection.inboundEdge,
|
|
164
|
+
options,
|
|
164
165
|
}), action_1.WriteOperation.Delete, options?.conditional);
|
|
165
166
|
}
|
|
166
167
|
removeOutboundEdge(id2, edgeType, options) {
|
|
@@ -168,6 +169,7 @@ class Orchestrator {
|
|
|
168
169
|
id: id2,
|
|
169
170
|
edgeType,
|
|
170
171
|
direction: edgeDirection.outboundEdge,
|
|
172
|
+
options,
|
|
171
173
|
}), action_1.WriteOperation.Delete, options?.conditional);
|
|
172
174
|
}
|
|
173
175
|
// this doesn't take a direction as that's an implementation detail
|
|
@@ -255,10 +257,10 @@ class Orchestrator {
|
|
|
255
257
|
}
|
|
256
258
|
let id2 = edge.id;
|
|
257
259
|
if (edge.direction === edgeDirection.outboundEdge) {
|
|
258
|
-
return operations_1.EdgeOperation.removeOutboundEdge(this.options.builder, edgeType, id2);
|
|
260
|
+
return operations_1.EdgeOperation.removeOutboundEdge(this.options.builder, edgeType, id2, edge.options);
|
|
259
261
|
}
|
|
260
262
|
else {
|
|
261
|
-
return operations_1.EdgeOperation.removeInboundEdge(this.options.builder, edgeType, id2);
|
|
263
|
+
return operations_1.EdgeOperation.removeInboundEdge(this.options.builder, edgeType, id2, edge.options);
|
|
262
264
|
}
|
|
263
265
|
}
|
|
264
266
|
throw new Error("could not find an edge operation from the given parameters");
|
|
@@ -288,6 +290,8 @@ class Orchestrator {
|
|
|
288
290
|
if (!edgeData) {
|
|
289
291
|
throw new Error(`could not load edge data for '${edgeType}'`);
|
|
290
292
|
}
|
|
293
|
+
// similar logic in EntChangeset.changesetFromEdgeOp
|
|
294
|
+
// doesn't support conditional edges
|
|
291
295
|
if (edgeData.symmetricEdge) {
|
|
292
296
|
let symmetric = edgeOp.symmetricEdge();
|
|
293
297
|
if (conditional) {
|
|
@@ -941,9 +945,37 @@ class EntChangeset {
|
|
|
941
945
|
`$ent.idPlaceholderID$ ${randomNum()}-${builder.ent.name}`, false, ops);
|
|
942
946
|
}
|
|
943
947
|
static changesetFromQueries(builder, queries) {
|
|
944
|
-
return
|
|
945
|
-
|
|
946
|
-
|
|
948
|
+
return EntChangeset.changesetFrom(builder, [
|
|
949
|
+
new operations_2.RawQueryOperation(builder, queries),
|
|
950
|
+
]);
|
|
951
|
+
}
|
|
952
|
+
static async changesetFromEdgeOp(builder, op, edgeType) {
|
|
953
|
+
const edgeData = await (0, ent_1.loadEdgeData)(edgeType);
|
|
954
|
+
const ops = [op];
|
|
955
|
+
if (!edgeData) {
|
|
956
|
+
throw new Error(`could not load edge data for '${edgeType}'`);
|
|
957
|
+
}
|
|
958
|
+
// similar logic in Orchestrator.buildEdgeOps
|
|
959
|
+
// doesn't support conditional edges
|
|
960
|
+
if (edgeData.symmetricEdge) {
|
|
961
|
+
ops.push(op.symmetricEdge());
|
|
962
|
+
}
|
|
963
|
+
if (edgeData.inverseEdgeType) {
|
|
964
|
+
ops.push(op.inverseEdge(edgeData));
|
|
965
|
+
}
|
|
966
|
+
return EntChangeset.changesetFrom(builder, ops);
|
|
967
|
+
}
|
|
968
|
+
static async changesetFromOutboundEdge(builder, edgeType, id2, nodeType, options) {
|
|
969
|
+
return EntChangeset.changesetFromEdgeOp(builder, operations_1.EdgeOperation.outboundEdge(builder, edgeType, id2, nodeType, options), edgeType);
|
|
970
|
+
}
|
|
971
|
+
static async changesetFromInboundEdge(builder, edgeType, id1, nodeType, options) {
|
|
972
|
+
return EntChangeset.changesetFromEdgeOp(builder, operations_1.EdgeOperation.inboundEdge(builder, edgeType, id1, nodeType, options), edgeType);
|
|
973
|
+
}
|
|
974
|
+
static changesetRemoveFromOutboundEdge(builder, edgeType, id2, options) {
|
|
975
|
+
return EntChangeset.changesetFromEdgeOp(builder, operations_1.EdgeOperation.removeOutboundEdge(builder, edgeType, id2, options), edgeType);
|
|
976
|
+
}
|
|
977
|
+
static changesetRemoveFromInboundEdge(builder, edgeType, id1, options) {
|
|
978
|
+
return EntChangeset.changesetFromEdgeOp(builder, operations_1.EdgeOperation.removeInboundEdge(builder, edgeType, id1, options), edgeType);
|
|
947
979
|
}
|
|
948
980
|
executor() {
|
|
949
981
|
if (this._executor) {
|
package/core/base.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as clause from "./clause";
|
|
2
2
|
import { ObjectLoaderFactory } from "./loaders";
|
|
3
|
+
import { OrderBy } from "./query_impl";
|
|
3
4
|
export interface Loader<K, V> {
|
|
4
5
|
context?: Context;
|
|
5
6
|
load(key: K): Promise<V>;
|
|
@@ -19,7 +20,8 @@ interface LoaderFactoryWithLoaderMany<T, V> extends LoaderFactory<T, V> {
|
|
|
19
20
|
export interface ConfigurableLoaderFactory<T, V> extends LoaderFactory<T, V> {
|
|
20
21
|
createConfigurableLoader(options: EdgeQueryableDataOptions, context?: Context): Loader<T, V>;
|
|
21
22
|
}
|
|
22
|
-
export type EdgeQueryableDataOptions = Partial<Pick<QueryableDataOptions, "limit" | "orderby" | "clause">>;
|
|
23
|
+
export type EdgeQueryableDataOptions = Partial<Pick<QueryableDataOptions, "limit" | "orderby" | "clause" | "disableTransformations">>;
|
|
24
|
+
export type EdgeQueryableDataOptionsConfigureLoader = Pick<EdgeQueryableDataOptions, "disableTransformations">;
|
|
23
25
|
export interface PrimableLoader<K, V> extends Loader<K, V> {
|
|
24
26
|
prime(d: V): void;
|
|
25
27
|
primeAll?(d: V): void;
|
|
@@ -37,7 +39,7 @@ interface queryOptions {
|
|
|
37
39
|
fields: string[];
|
|
38
40
|
tableName: string;
|
|
39
41
|
clause: clause.Clause;
|
|
40
|
-
orderby?:
|
|
42
|
+
orderby?: OrderBy;
|
|
41
43
|
}
|
|
42
44
|
export interface Context<TViewer extends Viewer = Viewer> {
|
|
43
45
|
getViewer(): TViewer;
|
|
@@ -80,7 +82,7 @@ export interface QueryableDataOptions extends SelectBaseDataOptions, QueryDataOp
|
|
|
80
82
|
export interface QueryDataOptions<T extends Data = Data, K = keyof T> {
|
|
81
83
|
distinct?: boolean;
|
|
82
84
|
clause: clause.Clause<T, K>;
|
|
83
|
-
orderby?:
|
|
85
|
+
orderby?: OrderBy;
|
|
84
86
|
groupby?: K;
|
|
85
87
|
limit?: number;
|
|
86
88
|
disableTransformations?: boolean;
|
package/core/context.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { Viewer, Data, Loader, LoaderWithLoadMany } from "./base";
|
|
|
3
3
|
import { IncomingMessage, ServerResponse } from "http";
|
|
4
4
|
import * as clause from "./clause";
|
|
5
5
|
import { Context } from "./base";
|
|
6
|
+
import { OrderBy } from "./query_impl";
|
|
6
7
|
export interface RequestContext<TViewer extends Viewer = Viewer> extends Context<TViewer> {
|
|
7
8
|
authViewer(viewer: TViewer): Promise<void>;
|
|
8
9
|
logout(): Promise<void>;
|
|
@@ -27,6 +28,6 @@ interface queryOptions {
|
|
|
27
28
|
fields: string[];
|
|
28
29
|
tableName: string;
|
|
29
30
|
clause: clause.Clause;
|
|
30
|
-
orderby?:
|
|
31
|
+
orderby?: OrderBy;
|
|
31
32
|
}
|
|
32
33
|
export {};
|
package/core/context.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ContextCache = void 0;
|
|
4
4
|
const logger_1 = require("./logger");
|
|
5
|
+
const query_impl_1 = require("./query_impl");
|
|
5
6
|
class ContextCache {
|
|
6
7
|
constructor() {
|
|
7
8
|
this.loaders = new Map();
|
|
@@ -39,7 +40,7 @@ class ContextCache {
|
|
|
39
40
|
options.clause.instanceKey(),
|
|
40
41
|
];
|
|
41
42
|
if (options.orderby) {
|
|
42
|
-
parts.push(options.orderby);
|
|
43
|
+
parts.push((0, query_impl_1.getOrderByPhrase)(options.orderby));
|
|
43
44
|
}
|
|
44
45
|
return parts.join(",");
|
|
45
46
|
}
|
package/core/ent.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { Queryer, SyncQueryer } from "./db";
|
|
|
2
2
|
import { Viewer, Ent, ID, LoadRowsOptions, LoadRowOptions, Data, DataOptions, QueryableDataOptions, EditRowOptions, LoadEntOptions, LoadCustomEntOptions, EdgeQueryableDataOptions, Context, CreateRowOptions, QueryDataOptions, SelectCustomDataOptions } from "./base";
|
|
3
3
|
import * as clause from "./clause";
|
|
4
4
|
import DataLoader from "dataloader";
|
|
5
|
+
import { OrderBy } from "./query_impl";
|
|
5
6
|
export declare function getEntKey<TEnt extends Ent<TViewer>, TViewer extends Viewer>(viewer: TViewer, id: ID, options: LoadEntOptions<TEnt, TViewer>): string;
|
|
6
7
|
export declare function loadEnt<TEnt extends Ent<TViewer>, TViewer extends Viewer>(viewer: TViewer, id: ID, options: LoadEntOptions<TEnt, TViewer>): Promise<TEnt | null>;
|
|
7
8
|
export declare function loadEntViaKey<TEnt extends Ent<TViewer>, TViewer extends Viewer>(viewer: TViewer, key: any, options: LoadEntOptions<TEnt, TViewer>): Promise<TEnt | null>;
|
|
@@ -75,7 +76,7 @@ interface GroupQueryOptions<T extends Data, K = keyof T> {
|
|
|
75
76
|
groupColumn: K;
|
|
76
77
|
fields: K[];
|
|
77
78
|
values: any[];
|
|
78
|
-
orderby?:
|
|
79
|
+
orderby?: OrderBy;
|
|
79
80
|
limit: number;
|
|
80
81
|
}
|
|
81
82
|
export declare function buildGroupQuery<T extends Data = Data, K = keyof T>(options: GroupQueryOptions<T, K>): [string, clause.Clause<T, K>];
|
|
@@ -126,7 +127,6 @@ interface loadEdgesOptions {
|
|
|
126
127
|
edgeType: string;
|
|
127
128
|
context?: Context;
|
|
128
129
|
queryOptions?: EdgeQueryableDataOptions;
|
|
129
|
-
disableTransformations?: boolean;
|
|
130
130
|
}
|
|
131
131
|
interface loadCustomEdgesOptions<T extends AssocEdge> extends loadEdgesOptions {
|
|
132
132
|
ctr: AssocEdgeConstructor<T>;
|
|
@@ -134,7 +134,7 @@ interface loadCustomEdgesOptions<T extends AssocEdge> extends loadEdgesOptions {
|
|
|
134
134
|
export declare function setDefaultLimit(limit: number): void;
|
|
135
135
|
export declare function getDefaultLimit(): number;
|
|
136
136
|
export declare function loadEdges(options: loadEdgesOptions): Promise<AssocEdge[]>;
|
|
137
|
-
export declare function getEdgeClauseAndFields(cls: clause.Clause, options: Pick<loadEdgesOptions, "
|
|
137
|
+
export declare function getEdgeClauseAndFields(cls: clause.Clause, options: Pick<loadEdgesOptions, "queryOptions">): {
|
|
138
138
|
cls: clause.Clause<Data, string | number>;
|
|
139
139
|
fields: string[];
|
|
140
140
|
};
|
package/core/ent.js
CHANGED
|
@@ -33,6 +33,7 @@ const clause = __importStar(require("./clause"));
|
|
|
33
33
|
const logger_1 = require("./logger");
|
|
34
34
|
const dataloader_1 = __importDefault(require("dataloader"));
|
|
35
35
|
const global_schema_1 = require("./global_schema");
|
|
36
|
+
const query_impl_1 = require("./query_impl");
|
|
36
37
|
// TODO kill this and createDataLoader
|
|
37
38
|
class cacheMap {
|
|
38
39
|
constructor(options) {
|
|
@@ -635,7 +636,7 @@ function buildQuery(options) {
|
|
|
635
636
|
parts.push(`GROUP BY ${options.groupby}`);
|
|
636
637
|
}
|
|
637
638
|
if (options.orderby) {
|
|
638
|
-
parts.push(`ORDER BY ${options.orderby}`);
|
|
639
|
+
parts.push(`ORDER BY ${(0, query_impl_1.getOrderByPhrase)(options.orderby)}`);
|
|
639
640
|
}
|
|
640
641
|
if (options.limit) {
|
|
641
642
|
parts.push(`LIMIT ${options.limit}`);
|
|
@@ -652,7 +653,7 @@ function buildGroupQuery(options) {
|
|
|
652
653
|
}
|
|
653
654
|
let orderby = "";
|
|
654
655
|
if (options.orderby) {
|
|
655
|
-
orderby = `ORDER BY ${options.orderby}`;
|
|
656
|
+
orderby = `ORDER BY ${(0, query_impl_1.getOrderByPhrase)(options.orderby)}`;
|
|
656
657
|
}
|
|
657
658
|
// window functions work in sqlite!
|
|
658
659
|
// https://www.sqlite.org/windowfunctions.html
|
|
@@ -975,7 +976,12 @@ function defaultEdgeQueryOptions(id1, edgeType, id2) {
|
|
|
975
976
|
}
|
|
976
977
|
return {
|
|
977
978
|
clause: cls,
|
|
978
|
-
orderby:
|
|
979
|
+
orderby: [
|
|
980
|
+
{
|
|
981
|
+
column: "time",
|
|
982
|
+
direction: "DESC",
|
|
983
|
+
},
|
|
984
|
+
],
|
|
979
985
|
limit: defaultLimit,
|
|
980
986
|
};
|
|
981
987
|
}
|
|
@@ -988,7 +994,7 @@ function getEdgeClauseAndFields(cls, options) {
|
|
|
988
994
|
const transformEdgeRead = (0, global_schema_1.__getGlobalSchema)()?.transformEdgeRead;
|
|
989
995
|
if (transformEdgeRead) {
|
|
990
996
|
const transformClause = transformEdgeRead();
|
|
991
|
-
if (!options.disableTransformations) {
|
|
997
|
+
if (!options.queryOptions?.disableTransformations) {
|
|
992
998
|
cls = clause.And(cls, transformClause);
|
|
993
999
|
}
|
|
994
1000
|
fields = edgeFields.concat(transformClause.columns());
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { ID, Context, Loader, LoaderFactory } from "../base";
|
|
1
|
+
import { ID, Context, Loader, LoaderFactory, EdgeQueryableDataOptionsConfigureLoader } from "../base";
|
|
2
2
|
export declare class AssocEdgeCountLoader implements Loader<ID, number> {
|
|
3
3
|
private edgeType;
|
|
4
4
|
context?: Context<import("../base").Viewer<import("../base").Ent<any> | null, ID | null>> | undefined;
|
|
5
|
+
private options?;
|
|
5
6
|
private loaderFn;
|
|
6
7
|
private loader;
|
|
7
|
-
constructor(edgeType: string, context?: Context<import("../base").Viewer<import("../base").Ent<any> | null, ID | null>> | undefined);
|
|
8
|
+
constructor(edgeType: string, context?: Context<import("../base").Viewer<import("../base").Ent<any> | null, ID | null>> | undefined, options?: EdgeQueryableDataOptionsConfigureLoader | undefined);
|
|
8
9
|
private getLoader;
|
|
9
10
|
load(id: ID): Promise<number>;
|
|
10
11
|
clearAll(): void;
|
|
@@ -15,4 +16,5 @@ export declare class AssocEdgeCountLoaderFactory implements LoaderFactory<ID, nu
|
|
|
15
16
|
constructor(edgeType: string);
|
|
16
17
|
getEdgeType(): string;
|
|
17
18
|
createLoader(context?: Context): AssocEdgeCountLoader;
|
|
19
|
+
createConfigurableLoader(options: EdgeQueryableDataOptionsConfigureLoader, context?: Context): AssocEdgeCountLoader;
|
|
18
20
|
}
|
|
@@ -33,9 +33,10 @@ const loader_1 = require("./loader");
|
|
|
33
33
|
const raw_count_loader_1 = require("./raw_count_loader");
|
|
34
34
|
const memoizee_1 = __importDefault(require("memoizee"));
|
|
35
35
|
class AssocEdgeCountLoader {
|
|
36
|
-
constructor(edgeType, context) {
|
|
36
|
+
constructor(edgeType, context, options) {
|
|
37
37
|
this.edgeType = edgeType;
|
|
38
38
|
this.context = context;
|
|
39
|
+
this.options = options;
|
|
39
40
|
if (context) {
|
|
40
41
|
this.loaderFn = (0, memoizee_1.default)(this.getLoader);
|
|
41
42
|
}
|
|
@@ -45,7 +46,9 @@ class AssocEdgeCountLoader {
|
|
|
45
46
|
if (!edgeData) {
|
|
46
47
|
throw new Error(`error loading edge data for ${this.edgeType}`);
|
|
47
48
|
}
|
|
48
|
-
const { cls } = (0, ent_1.getEdgeClauseAndFields)(clause.Eq("edge_type", this.edgeType), {
|
|
49
|
+
const { cls } = (0, ent_1.getEdgeClauseAndFields)(clause.Eq("edge_type", this.edgeType), {
|
|
50
|
+
queryOptions: this.options,
|
|
51
|
+
});
|
|
49
52
|
this.loader = (0, raw_count_loader_1.createCountDataLoader)({
|
|
50
53
|
tableName: edgeData.edgeTable,
|
|
51
54
|
groupCol: "id1",
|
|
@@ -58,6 +61,7 @@ class AssocEdgeCountLoader {
|
|
|
58
61
|
return (0, ent_1.loadRawEdgeCountX)({
|
|
59
62
|
id1: id,
|
|
60
63
|
edgeType: this.edgeType,
|
|
64
|
+
queryOptions: this.options,
|
|
61
65
|
});
|
|
62
66
|
}
|
|
63
67
|
const loader = await this.loaderFn();
|
|
@@ -79,5 +83,9 @@ class AssocEdgeCountLoaderFactory {
|
|
|
79
83
|
createLoader(context) {
|
|
80
84
|
return (0, loader_1.getLoader)(this, () => new AssocEdgeCountLoader(this.edgeType, context), context);
|
|
81
85
|
}
|
|
86
|
+
createConfigurableLoader(options, context) {
|
|
87
|
+
const key = `${this.name}:disableTransformations:${options.disableTransformations}`;
|
|
88
|
+
return (0, loader_1.getCustomLoader)(key, () => new AssocEdgeCountLoader(this.edgeType, context, options), context);
|
|
89
|
+
}
|
|
82
90
|
}
|
|
83
91
|
exports.AssocEdgeCountLoaderFactory = AssocEdgeCountLoaderFactory;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Context, ID, EdgeQueryableDataOptions, Loader, LoaderFactory } from "../base";
|
|
2
2
|
import { AssocEdge, AssocEdgeConstructor } from "../ent";
|
|
3
|
-
interface AssocLoader<T extends AssocEdge> extends Loader<ID, T[]> {
|
|
3
|
+
export interface AssocLoader<T extends AssocEdge> extends Loader<ID, T[]> {
|
|
4
4
|
loadEdgeForID2(id: ID, id2: ID): Promise<T | undefined>;
|
|
5
5
|
}
|
|
6
6
|
export declare class AssocEdgeLoader<T extends AssocEdge> implements Loader<ID, T[]> {
|
|
@@ -21,7 +21,7 @@ export declare class AssocDirectEdgeLoader<T extends AssocEdge> implements Loade
|
|
|
21
21
|
private edgeCtr;
|
|
22
22
|
private options?;
|
|
23
23
|
context?: Context<import("../base").Viewer<import("../base").Ent<any> | null, ID | null>> | undefined;
|
|
24
|
-
constructor(edgeType: string, edgeCtr: AssocEdgeConstructor<T>, options?: Partial<Pick<import("../base").QueryableDataOptions, "clause" | "limit" | "orderby">> | undefined, context?: Context<import("../base").Viewer<import("../base").Ent<any> | null, ID | null>> | undefined);
|
|
24
|
+
constructor(edgeType: string, edgeCtr: AssocEdgeConstructor<T>, options?: Partial<Pick<import("../base").QueryableDataOptions, "clause" | "limit" | "orderby" | "disableTransformations">> | undefined, context?: Context<import("../base").Viewer<import("../base").Ent<any> | null, ID | null>> | undefined);
|
|
25
25
|
load(id: ID): Promise<T[]>;
|
|
26
26
|
loadEdgeForID2(id: ID, id2: ID): Promise<T | undefined>;
|
|
27
27
|
clearAll(): void;
|
|
@@ -35,4 +35,3 @@ export declare class AssocEdgeLoaderFactory<T extends AssocEdge> implements Load
|
|
|
35
35
|
private isConstructor;
|
|
36
36
|
createConfigurableLoader(options: EdgeQueryableDataOptions, context?: Context): AssocLoader<T>;
|
|
37
37
|
}
|
|
38
|
-
export {};
|
|
@@ -59,11 +59,18 @@ function createLoader(options, edgeType, edgeCtr, edgeData) {
|
|
|
59
59
|
// store the index....
|
|
60
60
|
m.set(keys[i], i);
|
|
61
61
|
}
|
|
62
|
-
options.orderby = options.orderby ||
|
|
62
|
+
options.orderby = options.orderby || [
|
|
63
|
+
{
|
|
64
|
+
column: "time",
|
|
65
|
+
direction: "DESC",
|
|
66
|
+
},
|
|
67
|
+
];
|
|
63
68
|
// TODO defaultEdgeQueryOptions
|
|
64
69
|
options.limit = options.limit || (0, ent_1.getDefaultLimit)();
|
|
65
70
|
const tableName = edgeData.edgeTable;
|
|
66
|
-
const { cls: cls1, fields } = (0, ent_1.getEdgeClauseAndFields)(clause.Eq("edge_type", edgeType), {
|
|
71
|
+
const { cls: cls1, fields } = (0, ent_1.getEdgeClauseAndFields)(clause.Eq("edge_type", edgeType), {
|
|
72
|
+
queryOptions: options,
|
|
73
|
+
});
|
|
67
74
|
const [query, cls] = (0, ent_1.buildGroupQuery)({
|
|
68
75
|
tableName: tableName,
|
|
69
76
|
fields,
|
|
@@ -114,6 +121,7 @@ class AssocEdgeLoader {
|
|
|
114
121
|
id2,
|
|
115
122
|
context: this.context,
|
|
116
123
|
ctr: this.edgeCtr,
|
|
124
|
+
queryOptions: this.options,
|
|
117
125
|
});
|
|
118
126
|
}
|
|
119
127
|
clearAll() {
|
|
@@ -129,7 +137,7 @@ class AssocDirectEdgeLoader {
|
|
|
129
137
|
this.context = context;
|
|
130
138
|
}
|
|
131
139
|
async load(id) {
|
|
132
|
-
return
|
|
140
|
+
return (0, ent_1.loadCustomEdges)({
|
|
133
141
|
id1: id,
|
|
134
142
|
edgeType: this.edgeType,
|
|
135
143
|
context: this.context,
|
|
@@ -137,12 +145,14 @@ class AssocDirectEdgeLoader {
|
|
|
137
145
|
ctr: this.edgeCtr,
|
|
138
146
|
});
|
|
139
147
|
}
|
|
148
|
+
// TODO should this have a disableTransformations flag to get these rows
|
|
140
149
|
async loadEdgeForID2(id, id2) {
|
|
141
150
|
return (0, ent_1.loadEdgeForID2)({
|
|
142
151
|
id1: id,
|
|
143
152
|
edgeType: this.edgeType,
|
|
144
153
|
id2,
|
|
145
154
|
context: this.context,
|
|
155
|
+
queryOptions: this.options,
|
|
146
156
|
ctr: this.edgeCtr,
|
|
147
157
|
});
|
|
148
158
|
}
|
|
@@ -181,7 +191,7 @@ class AssocEdgeLoaderFactory {
|
|
|
181
191
|
return new AssocDirectEdgeLoader(this.edgeType, edgeCtr, options, context);
|
|
182
192
|
}
|
|
183
193
|
// we create a loader which can combine first X queries in the same fetch
|
|
184
|
-
const key = `${this.name}:limit:${options.limit}:orderby:${options.orderby}`;
|
|
194
|
+
const key = `${this.name}:limit:${options.limit}:orderby:${options.orderby}:disableTransformations:${options.disableTransformations}`;
|
|
185
195
|
return (0, loader_1.getCustomLoader)(key, () => new AssocEdgeLoader(this.edgeType, ctr, options, context), context);
|
|
186
196
|
}
|
|
187
197
|
}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { ID, SelectBaseDataOptions, Context, Data, LoaderFactory, EdgeQueryableDataOptions, Loader } from "../base";
|
|
2
2
|
import * as clause from "../clause";
|
|
3
|
+
import { OrderBy } from "../query_impl";
|
|
3
4
|
import { ObjectLoaderFactory } from "./object_loader";
|
|
4
5
|
export declare class IndexLoaderFactory implements LoaderFactory<ID, Data[]> {
|
|
5
6
|
name: string;
|
|
6
7
|
private factory;
|
|
7
8
|
constructor(options: SelectBaseDataOptions, col: string, opts?: {
|
|
8
9
|
extraClause?: clause.Clause;
|
|
9
|
-
|
|
10
|
+
orderby?: OrderBy;
|
|
10
11
|
toPrime?: ObjectLoaderFactory<Data>[];
|
|
11
12
|
});
|
|
12
13
|
createLoader(context?: Context): any;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { Context, ID, EdgeQueryableDataOptions, Loader, LoaderFactory, Data } from "../base";
|
|
2
2
|
import * as clause from "../clause";
|
|
3
3
|
import { ObjectLoaderFactory } from "./object_loader";
|
|
4
|
-
|
|
4
|
+
import { OrderBy } from "../query_impl";
|
|
5
5
|
declare class QueryDirectLoader<K extends any> implements Loader<K, Data[]> {
|
|
6
6
|
private options;
|
|
7
7
|
private queryOptions?;
|
|
8
8
|
context?: Context<import("../base").Viewer<import("../base").Ent<any> | null, ID | null>> | undefined;
|
|
9
9
|
private memoizedInitPrime;
|
|
10
10
|
private primedLoaders;
|
|
11
|
-
constructor(options: QueryOptions, queryOptions?: Partial<Pick<import("../base").QueryableDataOptions, "clause" | "limit" | "orderby">> | undefined, context?: Context<import("../base").Viewer<import("../base").Ent<any> | null, ID | null>> | undefined);
|
|
11
|
+
constructor(options: QueryOptions, queryOptions?: Partial<Pick<import("../base").QueryableDataOptions, "clause" | "limit" | "orderby" | "disableTransformations">> | undefined, context?: Context<import("../base").Viewer<import("../base").Ent<any> | null, ID | null>> | undefined);
|
|
12
12
|
private initPrime;
|
|
13
13
|
load(id: K): Promise<Data[]>;
|
|
14
14
|
clearAll(): void;
|
|
@@ -18,7 +18,7 @@ interface QueryOptions {
|
|
|
18
18
|
tableName: string;
|
|
19
19
|
groupCol?: string;
|
|
20
20
|
clause?: clause.Clause;
|
|
21
|
-
|
|
21
|
+
orderby?: OrderBy;
|
|
22
22
|
toPrime?: ObjectLoaderFactory<Data>[];
|
|
23
23
|
}
|
|
24
24
|
export declare class QueryLoaderFactory<K extends any> implements LoaderFactory<K, Data[]> {
|
|
@@ -26,25 +26,22 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
26
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.QueryLoaderFactory =
|
|
29
|
+
exports.QueryLoaderFactory = void 0;
|
|
30
30
|
const dataloader_1 = __importDefault(require("dataloader"));
|
|
31
31
|
const ent_1 = require("../ent");
|
|
32
32
|
const clause = __importStar(require("../clause"));
|
|
33
33
|
const logger_1 = require("../logger");
|
|
34
34
|
const loader_1 = require("./loader");
|
|
35
35
|
const memoizee_1 = __importDefault(require("memoizee"));
|
|
36
|
-
function
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
return `${sortCol}${orderbyDirection}`;
|
|
36
|
+
function getOrderByLocal(options, queryOptions) {
|
|
37
|
+
return (options.orderby ??
|
|
38
|
+
queryOptions?.orderby ?? [
|
|
39
|
+
{
|
|
40
|
+
column: "created_at",
|
|
41
|
+
direction: "DESC",
|
|
42
|
+
},
|
|
43
|
+
]);
|
|
46
44
|
}
|
|
47
|
-
exports.getOrderBy = getOrderBy;
|
|
48
45
|
async function simpleCase(options, id, queryOptions) {
|
|
49
46
|
let cls;
|
|
50
47
|
if (options.groupCol) {
|
|
@@ -62,16 +59,14 @@ async function simpleCase(options, id, queryOptions) {
|
|
|
62
59
|
if (queryOptions?.clause) {
|
|
63
60
|
cls = clause.And(cls, queryOptions.clause);
|
|
64
61
|
}
|
|
65
|
-
let sortCol = options.sortColumn || "created_at";
|
|
66
62
|
return await (0, ent_1.loadRows)({
|
|
67
63
|
...options,
|
|
68
64
|
clause: cls,
|
|
69
|
-
orderby:
|
|
65
|
+
orderby: getOrderByLocal(options, queryOptions),
|
|
70
66
|
limit: queryOptions?.limit || (0, ent_1.getDefaultLimit)(),
|
|
71
67
|
});
|
|
72
68
|
}
|
|
73
69
|
function createLoader(options, queryOptions) {
|
|
74
|
-
let sortCol = options.sortColumn || "created_at";
|
|
75
70
|
const loaderOptions = {};
|
|
76
71
|
// if query logging is enabled, we should log what's happening with loader
|
|
77
72
|
if ((0, logger_1.logEnabled)("query")) {
|
|
@@ -109,7 +104,7 @@ function createLoader(options, queryOptions) {
|
|
|
109
104
|
tableName: options.tableName,
|
|
110
105
|
fields: options.fields,
|
|
111
106
|
values: keys,
|
|
112
|
-
orderby:
|
|
107
|
+
orderby: getOrderByLocal(options, queryOptions),
|
|
113
108
|
limit: queryOptions?.limit || (0, ent_1.getDefaultLimit)(),
|
|
114
109
|
groupColumn: col,
|
|
115
110
|
clause: extraClause,
|