@snowtop/ent 0.2.2 → 0.2.3-alpha2
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/base.d.ts +1 -0
- package/core/clause.d.ts +49 -49
- package/core/clause.js +4 -0
- package/core/db.js +16 -0
- package/core/ent.d.ts +3 -0
- package/core/ent.js +4 -0
- package/core/query_impl.js +4 -1
- package/graphql/index.d.ts +1 -0
- package/graphql/index.js +3 -1
- package/graphql/scalars/date.d.ts +2 -0
- package/graphql/scalars/date.js +45 -0
- package/package.json +1 -1
- package/parse_schema/parse.d.ts +2 -1
- package/parse_schema/parse.js +4 -0
- package/schema/field.d.ts +2 -0
- package/schema/field.js +5 -3
- package/schema/index.d.ts +1 -1
- package/schema/schema.d.ts +9 -1
- package/scripts/custom_graphql.js +5 -0
- package/testutils/db/value.js +7 -1
- package/testutils/parse_sql.js +52 -12
- package/testutils/test_edge_global_schema.d.ts +3 -0
- package/testutils/test_edge_global_schema.js +5 -1
package/core/base.d.ts
CHANGED
package/core/clause.d.ts
CHANGED
|
@@ -19,7 +19,7 @@ export declare class inClause<T extends Data, K = keyof T> implements Clause<T,
|
|
|
19
19
|
private overrideAlias?;
|
|
20
20
|
protected op: InClauseOperator;
|
|
21
21
|
static getPostgresInClauseValuesThreshold(): number;
|
|
22
|
-
constructor(col: K, value: any[], type?: string, overrideAlias?: string | undefined);
|
|
22
|
+
constructor(col: K, value: any[], type?: string, overrideAlias?: string | null | undefined);
|
|
23
23
|
clause(idx: number, alias?: string): string;
|
|
24
24
|
columns(): K[];
|
|
25
25
|
values(): any[];
|
|
@@ -34,37 +34,37 @@ export declare class notInClause<T extends Data, K = keyof T> extends inClause<T
|
|
|
34
34
|
* only works with postgres gin indexes
|
|
35
35
|
* https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPES-GIN
|
|
36
36
|
*/
|
|
37
|
-
export declare function PostgresArrayContainsValue<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string): Clause<T, K>;
|
|
37
|
+
export declare function PostgresArrayContainsValue<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string | null): Clause<T, K>;
|
|
38
38
|
/**
|
|
39
39
|
* creates a clause to determine if every item in the list is stored in the array stored in the column in the db
|
|
40
40
|
* only works with postgres gin indexes
|
|
41
41
|
* https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPES-GIN
|
|
42
42
|
*/
|
|
43
|
-
export declare function PostgresArrayContains<T extends Data, K = keyof T>(col: K, value: any[], overrideAlias?: string): Clause<T, K>;
|
|
43
|
+
export declare function PostgresArrayContains<T extends Data, K = keyof T>(col: K, value: any[], overrideAlias?: string | null): Clause<T, K>;
|
|
44
44
|
/**
|
|
45
45
|
* creates a clause to determine if the given value is NOT contained in the array stored in the column in the db
|
|
46
46
|
* only works with postgres gin indexes
|
|
47
47
|
* https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPES-GIN
|
|
48
48
|
*/
|
|
49
|
-
export declare function PostgresArrayNotContainsValue<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string): Clause<T, K>;
|
|
49
|
+
export declare function PostgresArrayNotContainsValue<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string | null): Clause<T, K>;
|
|
50
50
|
/**
|
|
51
51
|
* creates a clause to determine if every item in the list is NOT stored in the array stored in the column in the db
|
|
52
52
|
* only works with postgres gin indexes
|
|
53
53
|
* https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPES-GIN
|
|
54
54
|
*/
|
|
55
|
-
export declare function PostgresArrayNotContains<T extends Data, K = keyof T>(col: K, value: any[], overrideAlias?: string): Clause<T, K>;
|
|
55
|
+
export declare function PostgresArrayNotContains<T extends Data, K = keyof T>(col: K, value: any[], overrideAlias?: string | null): Clause<T, K>;
|
|
56
56
|
/**
|
|
57
57
|
* creates a clause to determine if the arrays overlap, that is, do they have any elements in common
|
|
58
58
|
* only works with postgres gin indexes
|
|
59
59
|
* https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPES-GIN
|
|
60
60
|
*/
|
|
61
|
-
export declare function PostgresArrayOverlaps<T extends Data, K = keyof T>(col: K, value: any[], overrideAlias?: string): Clause<T, K>;
|
|
61
|
+
export declare function PostgresArrayOverlaps<T extends Data, K = keyof T>(col: K, value: any[], overrideAlias?: string | null): Clause<T, K>;
|
|
62
62
|
/**
|
|
63
63
|
* creates a clause to determine if the arrays do not overlap, that is, do they have any elements in common
|
|
64
64
|
* only works with postgres gin indexes
|
|
65
65
|
* https://www.postgresql.org/docs/current/indexes-types.html#INDEXES-TYPES-GIN
|
|
66
66
|
*/
|
|
67
|
-
export declare function PostgresArrayNotOverlaps<T extends Data, K = keyof T>(col: K, value: any[], overrideAlias?: string): Clause<T, K>;
|
|
67
|
+
export declare function PostgresArrayNotOverlaps<T extends Data, K = keyof T>(col: K, value: any[], overrideAlias?: string | null): Clause<T, K>;
|
|
68
68
|
/**
|
|
69
69
|
* @deprecated use PostgresArrayContainsValue
|
|
70
70
|
*/
|
|
@@ -73,18 +73,18 @@ export declare function ArrayEq<T extends Data, K = keyof T>(col: K, value: any)
|
|
|
73
73
|
* @deprecated use PostgresNotArrayContains
|
|
74
74
|
*/
|
|
75
75
|
export declare function ArrayNotEq<T extends Data, K = keyof T>(col: K, value: any): Clause<T, K>;
|
|
76
|
-
export declare function Eq<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string): Clause<T, K>;
|
|
77
|
-
export declare function StartsWith<T extends Data, K = keyof T>(col: K, value: string, overrideAlias?: string): Clause<T, K>;
|
|
78
|
-
export declare function EndsWith<T extends Data, K = keyof T>(col: K, value: string, overrideAlias?: string): Clause<T, K>;
|
|
79
|
-
export declare function Contains<T extends Data, K = keyof T>(col: K, value: string, overrideAlias?: string): Clause<T, K>;
|
|
80
|
-
export declare function StartsWithIgnoreCase<T extends Data, K = keyof T>(col: K, value: string, overrideAlias?: string): Clause<T, K>;
|
|
81
|
-
export declare function EndsWithIgnoreCase<T extends Data, K = keyof T>(col: K, value: string, overrideAlias?: string): Clause<T, K>;
|
|
82
|
-
export declare function ContainsIgnoreCase<T extends Data, K = keyof T>(col: K, value: string, overrideAlias?: string): Clause<T, K>;
|
|
83
|
-
export declare function NotEq<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string): Clause<T, K>;
|
|
84
|
-
export declare function Greater<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string): Clause<T, K>;
|
|
85
|
-
export declare function Less<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string): Clause<T, K>;
|
|
86
|
-
export declare function GreaterEq<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string): Clause<T, K>;
|
|
87
|
-
export declare function LessEq<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string): Clause<T, K>;
|
|
76
|
+
export declare function Eq<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string | null): Clause<T, K>;
|
|
77
|
+
export declare function StartsWith<T extends Data, K = keyof T>(col: K, value: string, overrideAlias?: string | null): Clause<T, K>;
|
|
78
|
+
export declare function EndsWith<T extends Data, K = keyof T>(col: K, value: string, overrideAlias?: string | null): Clause<T, K>;
|
|
79
|
+
export declare function Contains<T extends Data, K = keyof T>(col: K, value: string, overrideAlias?: string | null): Clause<T, K>;
|
|
80
|
+
export declare function StartsWithIgnoreCase<T extends Data, K = keyof T>(col: K, value: string, overrideAlias?: string | null): Clause<T, K>;
|
|
81
|
+
export declare function EndsWithIgnoreCase<T extends Data, K = keyof T>(col: K, value: string, overrideAlias?: string | null): Clause<T, K>;
|
|
82
|
+
export declare function ContainsIgnoreCase<T extends Data, K = keyof T>(col: K, value: string, overrideAlias?: string | null): Clause<T, K>;
|
|
83
|
+
export declare function NotEq<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string | null): Clause<T, K>;
|
|
84
|
+
export declare function Greater<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string | null): Clause<T, K>;
|
|
85
|
+
export declare function Less<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string | null): Clause<T, K>;
|
|
86
|
+
export declare function GreaterEq<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string | null): Clause<T, K>;
|
|
87
|
+
export declare function LessEq<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string | null): Clause<T, K>;
|
|
88
88
|
export declare function And<T extends Data, K = keyof T>(...args: Clause<T, K>[]): Clause<T, K>;
|
|
89
89
|
export declare function AndOptional<T extends Data, K = keyof T>(...args: (Clause<T, K> | undefined)[]): Clause<T, K>;
|
|
90
90
|
export declare function Or<T extends Data, K = keyof T>(...args: Clause<T, K>[]): Clause<T, K>;
|
|
@@ -97,41 +97,41 @@ export declare function In<T extends Data, K = keyof T>(col: K, ...values: any):
|
|
|
97
97
|
* @deprecated use UUidIn, TextIn, IntegerIn, or TypeIn
|
|
98
98
|
*/
|
|
99
99
|
export declare function In<T extends Data, K = keyof T>(col: K, values: any[], type?: string): Clause<T, K>;
|
|
100
|
-
export declare function UuidIn<T extends Data, K = keyof T>(col: K, values: ID[], overrideAlias?: string): Clause<T, K>;
|
|
101
|
-
export declare function IntegerIn<T extends Data, K = keyof T>(col: K, values: number[], overrideAlias?: string): Clause<T, K>;
|
|
102
|
-
export declare function TextIn<T extends Data, K = keyof T>(col: K, values: any[], overrideAlias?: string): Clause<T, K>;
|
|
103
|
-
export declare function DBTypeIn<T extends Data, K = keyof T>(col: K, values: any[], typ: string, overrideAlias?: string): Clause<T, K>;
|
|
104
|
-
export declare function UuidNotIn<T extends Data, K = keyof T>(col: K, values: ID[], overrideAlias?: string): Clause<T, K>;
|
|
105
|
-
export declare function IntegerNotIn<T extends Data, K = keyof T>(col: K, values: number[], overrideAlias?: string): Clause<T, K>;
|
|
106
|
-
export declare function TextNotIn<T extends Data, K = keyof T>(col: K, values: any[], overrideAlias?: string): Clause<T, K>;
|
|
107
|
-
export declare function DBTypeNotIn<T extends Data, K = keyof T>(col: K, values: any[], typ: string, overrideAlias?: string): Clause<T, K>;
|
|
100
|
+
export declare function UuidIn<T extends Data, K = keyof T>(col: K, values: ID[], overrideAlias?: string | null): Clause<T, K>;
|
|
101
|
+
export declare function IntegerIn<T extends Data, K = keyof T>(col: K, values: number[], overrideAlias?: string | null): Clause<T, K>;
|
|
102
|
+
export declare function TextIn<T extends Data, K = keyof T>(col: K, values: any[], overrideAlias?: string | null): Clause<T, K>;
|
|
103
|
+
export declare function DBTypeIn<T extends Data, K = keyof T>(col: K, values: any[], typ: string, overrideAlias?: string | null): Clause<T, K>;
|
|
104
|
+
export declare function UuidNotIn<T extends Data, K = keyof T>(col: K, values: ID[], overrideAlias?: string | null): Clause<T, K>;
|
|
105
|
+
export declare function IntegerNotIn<T extends Data, K = keyof T>(col: K, values: number[], overrideAlias?: string | null): Clause<T, K>;
|
|
106
|
+
export declare function TextNotIn<T extends Data, K = keyof T>(col: K, values: any[], overrideAlias?: string | null): Clause<T, K>;
|
|
107
|
+
export declare function DBTypeNotIn<T extends Data, K = keyof T>(col: K, values: any[], typ: string, overrideAlias?: string | null): Clause<T, K>;
|
|
108
108
|
interface TsQuery {
|
|
109
109
|
language: "english" | "french" | "german" | "simple";
|
|
110
110
|
value: string;
|
|
111
111
|
}
|
|
112
|
-
export declare function TsQuery<T extends Data, K = keyof T>(col: K, val: string | TsQuery, overrideAlias?: string): Clause<T, K>;
|
|
113
|
-
export declare function PlainToTsQuery<T extends Data, K = keyof T>(col: K, val: string | TsQuery, overrideAlias?: string): Clause<T, K>;
|
|
114
|
-
export declare function PhraseToTsQuery<T extends Data, K = keyof T>(col: K, val: string | TsQuery, overrideAlias?: string): Clause<T, K>;
|
|
115
|
-
export declare function WebsearchToTsQuery<T extends Data, K = keyof T>(col: K, val: string | TsQuery, overrideAlias?: string): Clause<T, K>;
|
|
116
|
-
export declare function TsVectorColTsQuery<T extends Data, K = keyof T>(col: K, val: string | TsQuery, overrideAlias?: string): Clause<T, K>;
|
|
117
|
-
export declare function TsVectorPlainToTsQuery<T extends Data, K = keyof T>(col: K, val: string | TsQuery, overrideAlias?: string): Clause<T, K>;
|
|
118
|
-
export declare function TsVectorPhraseToTsQuery<T extends Data, K = keyof T>(col: K, val: string | TsQuery, overrideAlias?: string): Clause<T, K>;
|
|
119
|
-
export declare function TsVectorWebsearchToTsQuery<T extends Data, K = keyof T>(col: K, val: string | TsQuery, overrideAlias?: string): Clause<T, K>;
|
|
112
|
+
export declare function TsQuery<T extends Data, K = keyof T>(col: K, val: string | TsQuery, overrideAlias?: string | null): Clause<T, K>;
|
|
113
|
+
export declare function PlainToTsQuery<T extends Data, K = keyof T>(col: K, val: string | TsQuery, overrideAlias?: string | null): Clause<T, K>;
|
|
114
|
+
export declare function PhraseToTsQuery<T extends Data, K = keyof T>(col: K, val: string | TsQuery, overrideAlias?: string | null): Clause<T, K>;
|
|
115
|
+
export declare function WebsearchToTsQuery<T extends Data, K = keyof T>(col: K, val: string | TsQuery, overrideAlias?: string | null): Clause<T, K>;
|
|
116
|
+
export declare function TsVectorColTsQuery<T extends Data, K = keyof T>(col: K, val: string | TsQuery, overrideAlias?: string | null): Clause<T, K>;
|
|
117
|
+
export declare function TsVectorPlainToTsQuery<T extends Data, K = keyof T>(col: K, val: string | TsQuery, overrideAlias?: string | null): Clause<T, K>;
|
|
118
|
+
export declare function TsVectorPhraseToTsQuery<T extends Data, K = keyof T>(col: K, val: string | TsQuery, overrideAlias?: string | null): Clause<T, K>;
|
|
119
|
+
export declare function TsVectorWebsearchToTsQuery<T extends Data, K = keyof T>(col: K, val: string | TsQuery, overrideAlias?: string | null): Clause<T, K>;
|
|
120
120
|
export declare function sensitiveValue(val: any): SensitiveValue;
|
|
121
|
-
export declare function JSONObjectFieldKeyASJSON<T extends Data, K = keyof T>(col: K, field: string, overrideAlias?: string): keyof T;
|
|
122
|
-
export declare function JSONObjectFieldKeyAsText<T extends Data, K = keyof T>(col: K, field: string, overrideAlias?: string): keyof T;
|
|
121
|
+
export declare function JSONObjectFieldKeyASJSON<T extends Data, K = keyof T>(col: K, field: string, overrideAlias?: string | null): keyof T;
|
|
122
|
+
export declare function JSONObjectFieldKeyAsText<T extends Data, K = keyof T>(col: K, field: string, overrideAlias?: string | null): keyof T;
|
|
123
123
|
type predicate = "==" | ">" | "<" | "!=" | ">=" | "<=";
|
|
124
|
-
export declare function JSONPathValuePredicate<T extends Data, K = keyof T>(dbCol: K, path: string, val: any, pred: predicate, overrideAlias?: string): Clause<T, K>;
|
|
125
|
-
export declare function JSONKeyExists<T extends Data, K = keyof T>(dbCol: K, val: any, overrideAlias?: string): Clause<T, K>;
|
|
126
|
-
export declare function JSONBKeyInList<T extends Data, K = keyof T>(dbCol: K, jsonCol: string, val: any, overrideAlias?: string): Clause<T, K>;
|
|
127
|
-
export declare function JSONKeyInList<T extends Data, K = keyof T>(dbCol: K, jsonCol: string, val: any, overrideAlias?: string): Clause<T, K>;
|
|
128
|
-
export declare function PaginationMultipleColsSubQuery<T extends Data, K = keyof T>(col: K, op: string, tableName: string, uniqueCol: K, val: any, overrideAlias?: string): Clause<T, K>;
|
|
124
|
+
export declare function JSONPathValuePredicate<T extends Data, K = keyof T>(dbCol: K, path: string, val: any, pred: predicate, overrideAlias?: string | null): Clause<T, K>;
|
|
125
|
+
export declare function JSONKeyExists<T extends Data, K = keyof T>(dbCol: K, val: any, overrideAlias?: string | null): Clause<T, K>;
|
|
126
|
+
export declare function JSONBKeyInList<T extends Data, K = keyof T>(dbCol: K, jsonCol: string, val: any, overrideAlias?: string | null): Clause<T, K>;
|
|
127
|
+
export declare function JSONKeyInList<T extends Data, K = keyof T>(dbCol: K, jsonCol: string, val: any, overrideAlias?: string | null): Clause<T, K>;
|
|
128
|
+
export declare function PaginationMultipleColsSubQuery<T extends Data, K = keyof T>(col: K, op: string, tableName: string, uniqueCol: K, val: any, overrideAlias?: string | null): Clause<T, K>;
|
|
129
129
|
export type PaginationUnboundColsQueryOrdering<T extends Data, K = keyof T> = {
|
|
130
130
|
sortCol: K;
|
|
131
131
|
direction: "ASC" | "DESC";
|
|
132
132
|
sortValue: string | number | null;
|
|
133
133
|
nullsPlacement?: "first" | "last";
|
|
134
|
-
overrideAlias?: string;
|
|
134
|
+
overrideAlias?: string | null;
|
|
135
135
|
};
|
|
136
136
|
/**
|
|
137
137
|
* When paginating over multiple ordered columns, we need to construct a nested
|
|
@@ -171,12 +171,12 @@ export type PaginationUnboundColsQueryOrdering<T extends Data, K = keyof T> = {
|
|
|
171
171
|
*/
|
|
172
172
|
export declare function PaginationUnboundColsQuery<T extends Data, K = keyof T>(ordering: PaginationUnboundColsQueryOrdering<T, K>[]): Clause<T, K> | undefined;
|
|
173
173
|
export declare function PaginationMultipleColsQuery<T extends Data, K = keyof T>(sortCol: K, cursorCol: K, less: boolean, // if true, <, if false, >
|
|
174
|
-
sortValue: any, cursorValue: any, overrideAlias?: string): Clause<T, K>;
|
|
175
|
-
export declare function Add<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string): Clause<T, K>;
|
|
176
|
-
export declare function Subtract<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string): Clause<T, K>;
|
|
177
|
-
export declare function Multiply<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string): Clause<T, K>;
|
|
178
|
-
export declare function Divide<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string): Clause<T, K>;
|
|
179
|
-
export declare function Modulo<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string): Clause<T, K>;
|
|
174
|
+
sortValue: any, cursorValue: any, overrideAlias?: string | null): Clause<T, K>;
|
|
175
|
+
export declare function Add<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string | null): Clause<T, K>;
|
|
176
|
+
export declare function Subtract<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string | null): Clause<T, K>;
|
|
177
|
+
export declare function Multiply<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string | null): Clause<T, K>;
|
|
178
|
+
export declare function Divide<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string | null): Clause<T, K>;
|
|
179
|
+
export declare function Modulo<T extends Data, K = keyof T>(col: K, value: any, overrideAlias?: string | null): Clause<T, K>;
|
|
180
180
|
export declare function getCombinedClause<V extends Data = Data, K = keyof V>(options: Pick<SelectDataOptions, "clause">, cls: Clause<V, K>, checkIntersection?: boolean): Clause<V, K>;
|
|
181
181
|
export declare function getCombinedClause<V extends Data = Data, K = keyof V>(options: Pick<SelectDataOptions, "clause">, cls: Clause<V, K> | undefined, checkIntersection?: boolean): Clause<V, K> | undefined;
|
|
182
182
|
export declare function Expression<T extends Data, K = keyof T>(expression: string): Clause<T, K>;
|
package/core/clause.js
CHANGED
|
@@ -39,6 +39,10 @@ function rawValue(val) {
|
|
|
39
39
|
return val;
|
|
40
40
|
}
|
|
41
41
|
function renderCol(col, overrideAlias, alias) {
|
|
42
|
+
// null explicitly disables aliasing for this column.
|
|
43
|
+
if (overrideAlias === null) {
|
|
44
|
+
return `${col}`;
|
|
45
|
+
}
|
|
42
46
|
if (overrideAlias) {
|
|
43
47
|
return `${overrideAlias}.${col}`;
|
|
44
48
|
}
|
package/core/db.js
CHANGED
|
@@ -205,6 +205,22 @@ exports.defaultTimestampParser = pg_1.default.types.getTypeParser(pg_1.default.t
|
|
|
205
205
|
pg_1.default.types.setTypeParser(pg_1.default.types.builtins.TIMESTAMP, function (val) {
|
|
206
206
|
return luxon_1.DateTime.fromSQL(val + "Z").toJSDate();
|
|
207
207
|
});
|
|
208
|
+
pg_1.default.types.setTypeParser(pg_1.default.types.builtins.DATE, function (val) {
|
|
209
|
+
return val;
|
|
210
|
+
});
|
|
211
|
+
// pg-types only exposes scalar OIDs, so we have to hard-code the array
|
|
212
|
+
// OIDs we care about (DATE[] and TEXT[]). If these ever change upstream,
|
|
213
|
+
// update the constants below.
|
|
214
|
+
const TEXT_ARRAY_OID = 1009;
|
|
215
|
+
const DATE_ARRAY_OID = 1182;
|
|
216
|
+
// TEXT[] already parses to string[], so reuse that parser for DATE[]
|
|
217
|
+
const parseTextArray = pg_1.default.types.getTypeParser(TEXT_ARRAY_OID);
|
|
218
|
+
pg_1.default.types.setTypeParser(DATE_ARRAY_OID, function (val) {
|
|
219
|
+
if (val === null) {
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
222
|
+
return parseTextArray(val);
|
|
223
|
+
});
|
|
208
224
|
class Sqlite {
|
|
209
225
|
constructor(db) {
|
|
210
226
|
this.db = db;
|
package/core/ent.d.ts
CHANGED
|
@@ -74,6 +74,7 @@ export type CustomQuery<T extends Data = Data, K = keyof T> = string | parameter
|
|
|
74
74
|
* Foo.loadCustom(opts, {
|
|
75
75
|
* clause: query.LessEq('time', Date.now()),
|
|
76
76
|
* limit: 100,
|
|
77
|
+
* offset: 200,
|
|
77
78
|
* orderby: 'time',
|
|
78
79
|
* }) // changes the query
|
|
79
80
|
* Foo.loadCustom(opts, {
|
|
@@ -88,6 +89,8 @@ export type CustomQuery<T extends Data = Data, K = keyof T> = string | parameter
|
|
|
88
89
|
*
|
|
89
90
|
* If a raw or parameterized query is passed in, we don't attempt to batch them together and they're executed as is.
|
|
90
91
|
* If you end up with a scenario where you may need to coalesce or batch (non-clause) queries here, you should use some kind of memoization here.
|
|
92
|
+
*
|
|
93
|
+
* Note: QueryDataOptions limit/offset are applied before privacy filtering, so the final ent list may be shorter.
|
|
91
94
|
*/
|
|
92
95
|
export declare function loadCustomData<TQueryData extends Data = Data, TResultData extends Data = TQueryData, K = keyof TQueryData>(options: SelectCustomDataOptions<TResultData>, query: CustomQuery<TQueryData, K>, context: Context | undefined): Promise<TResultData[]>;
|
|
93
96
|
export declare function loadCustomCount<T extends Data = Data, K = keyof T>(options: SelectCustomDataOptions<T>, query: CustomQuery<T, K>, context: Context | undefined): Promise<number>;
|
package/core/ent.js
CHANGED
|
@@ -379,6 +379,7 @@ function isParameterizedQuery(opts) {
|
|
|
379
379
|
* Foo.loadCustom(opts, {
|
|
380
380
|
* clause: query.LessEq('time', Date.now()),
|
|
381
381
|
* limit: 100,
|
|
382
|
+
* offset: 200,
|
|
382
383
|
* orderby: 'time',
|
|
383
384
|
* }) // changes the query
|
|
384
385
|
* Foo.loadCustom(opts, {
|
|
@@ -393,6 +394,8 @@ function isParameterizedQuery(opts) {
|
|
|
393
394
|
*
|
|
394
395
|
* If a raw or parameterized query is passed in, we don't attempt to batch them together and they're executed as is.
|
|
395
396
|
* If you end up with a scenario where you may need to coalesce or batch (non-clause) queries here, you should use some kind of memoization here.
|
|
397
|
+
*
|
|
398
|
+
* Note: QueryDataOptions limit/offset are applied before privacy filtering, so the final ent list may be shorter.
|
|
396
399
|
*/
|
|
397
400
|
async function loadCustomData(options, query, context) {
|
|
398
401
|
const rows = await loadCustomDataImpl(options, query, context);
|
|
@@ -418,6 +421,7 @@ async function loadCustomCount(options, query, context) {
|
|
|
418
421
|
const rows = await loadCustomDataImpl({
|
|
419
422
|
...options,
|
|
420
423
|
fields: ["count(1) as count"],
|
|
424
|
+
disableFieldsAlias: true,
|
|
421
425
|
}, query, context);
|
|
422
426
|
if (rows.length) {
|
|
423
427
|
return parseInt(rows[0].count);
|
package/core/query_impl.js
CHANGED
|
@@ -102,9 +102,12 @@ function buildQuery(options) {
|
|
|
102
102
|
if (options.orderby) {
|
|
103
103
|
parts.push(`ORDER BY ${getOrderByPhrase(options.orderby, options.disableDefaultOrderByAlias ? undefined : fieldsAlias)}`);
|
|
104
104
|
}
|
|
105
|
-
if (options.limit) {
|
|
105
|
+
if (options.limit !== undefined) {
|
|
106
106
|
parts.push(`LIMIT ${options.limit}`);
|
|
107
107
|
}
|
|
108
|
+
if (options.offset !== undefined) {
|
|
109
|
+
parts.push(`OFFSET ${options.offset}`);
|
|
110
|
+
}
|
|
108
111
|
return parts.join(" ");
|
|
109
112
|
}
|
|
110
113
|
exports.buildQuery = buildQuery;
|
package/graphql/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { gqlFieldOptions, gqlObjectOptions, gqlField, gqlArgType, gqlInputObjectType, gqlObjectType, gqlQuery, gqlMutation, gqlContextType, gqlConnection, GraphQLConnection, GQLCapture, gqlFileUpload, CustomType, gqlInterfaceType, gqlUnionType, } from "./graphql";
|
|
2
2
|
export { GraphQLTime } from "./scalars/time";
|
|
3
|
+
export { GraphQLDate } from "./scalars/date";
|
|
3
4
|
export { GraphQLOrderByDirection } from "./scalars/orderby_direction";
|
|
4
5
|
export { GraphQLPageInfo } from "./query/page_info";
|
|
5
6
|
export { GraphQLEdge, GraphQLEdgeConnection } from "./query/edge_connection";
|
package/graphql/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.transformUnionTypes = exports.encodeGQLID = exports.mustDecodeNullableIDFromGQLID = exports.mustDecodeIDFromGQLID = exports.nodeIDEncoder = exports.resolveID = exports.clearResolvers = exports.registerResolver = exports.EntNodeResolver = exports.GraphQLEdgeInterface = exports.GraphQLConnectionInterface = exports.GraphQLNodeInterface = exports.GraphQLConnectionType = exports.GraphQLEdgeType = exports.GraphQLEdgeConnection = exports.GraphQLPageInfo = exports.GraphQLOrderByDirection = exports.GraphQLTime = exports.gqlUnionType = exports.gqlInterfaceType = exports.gqlFileUpload = exports.GQLCapture = exports.gqlConnection = exports.gqlContextType = exports.gqlMutation = exports.gqlQuery = exports.gqlObjectType = exports.gqlInputObjectType = exports.gqlArgType = exports.gqlField = void 0;
|
|
3
|
+
exports.transformUnionTypes = exports.encodeGQLID = exports.mustDecodeNullableIDFromGQLID = exports.mustDecodeIDFromGQLID = exports.nodeIDEncoder = exports.resolveID = exports.clearResolvers = exports.registerResolver = exports.EntNodeResolver = exports.GraphQLEdgeInterface = exports.GraphQLConnectionInterface = exports.GraphQLNodeInterface = exports.GraphQLConnectionType = exports.GraphQLEdgeType = exports.GraphQLEdgeConnection = exports.GraphQLPageInfo = exports.GraphQLOrderByDirection = exports.GraphQLDate = exports.GraphQLTime = exports.gqlUnionType = exports.gqlInterfaceType = exports.gqlFileUpload = exports.GQLCapture = exports.gqlConnection = exports.gqlContextType = exports.gqlMutation = exports.gqlQuery = exports.gqlObjectType = exports.gqlInputObjectType = exports.gqlArgType = exports.gqlField = void 0;
|
|
4
4
|
var graphql_1 = require("./graphql");
|
|
5
5
|
Object.defineProperty(exports, "gqlField", { enumerable: true, get: function () { return graphql_1.gqlField; } });
|
|
6
6
|
Object.defineProperty(exports, "gqlArgType", { enumerable: true, get: function () { return graphql_1.gqlArgType; } });
|
|
@@ -16,6 +16,8 @@ Object.defineProperty(exports, "gqlInterfaceType", { enumerable: true, get: func
|
|
|
16
16
|
Object.defineProperty(exports, "gqlUnionType", { enumerable: true, get: function () { return graphql_1.gqlUnionType; } });
|
|
17
17
|
var time_1 = require("./scalars/time");
|
|
18
18
|
Object.defineProperty(exports, "GraphQLTime", { enumerable: true, get: function () { return time_1.GraphQLTime; } });
|
|
19
|
+
var date_1 = require("./scalars/date");
|
|
20
|
+
Object.defineProperty(exports, "GraphQLDate", { enumerable: true, get: function () { return date_1.GraphQLDate; } });
|
|
19
21
|
var orderby_direction_1 = require("./scalars/orderby_direction");
|
|
20
22
|
Object.defineProperty(exports, "GraphQLOrderByDirection", { enumerable: true, get: function () { return orderby_direction_1.GraphQLOrderByDirection; } });
|
|
21
23
|
var page_info_1 = require("./query/page_info");
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GraphQLDate = void 0;
|
|
4
|
+
const graphql_1 = require("graphql");
|
|
5
|
+
const language_1 = require("graphql/language");
|
|
6
|
+
const luxon_1 = require("luxon");
|
|
7
|
+
const DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/;
|
|
8
|
+
function normalizeDate(input, throwErr) {
|
|
9
|
+
if (typeof input === "string") {
|
|
10
|
+
if (!DATE_REGEX.test(input)) {
|
|
11
|
+
throw throwErr(`Date must be in YYYY-MM-DD format: ${input}`);
|
|
12
|
+
}
|
|
13
|
+
const dt = luxon_1.DateTime.fromISO(input, { zone: "UTC" });
|
|
14
|
+
if (!dt.isValid) {
|
|
15
|
+
throw throwErr(`Invalid Date value ${input}`);
|
|
16
|
+
}
|
|
17
|
+
return dt.toISODate();
|
|
18
|
+
}
|
|
19
|
+
if (input instanceof Date) {
|
|
20
|
+
return luxon_1.DateTime.fromJSDate(input).toISODate();
|
|
21
|
+
}
|
|
22
|
+
if (input instanceof luxon_1.DateTime) {
|
|
23
|
+
if (!input.isValid) {
|
|
24
|
+
throw throwErr(`Invalid Date value ${input.toISO()}`);
|
|
25
|
+
}
|
|
26
|
+
return input.toISODate();
|
|
27
|
+
}
|
|
28
|
+
throw throwErr(`Date cannot represent value: ${input}`);
|
|
29
|
+
}
|
|
30
|
+
exports.GraphQLDate = new graphql_1.GraphQLScalarType({
|
|
31
|
+
name: "Date",
|
|
32
|
+
description: "Date scalar type with format YYYY-MM-DD",
|
|
33
|
+
serialize(value) {
|
|
34
|
+
return normalizeDate(value, (msg) => new graphql_1.GraphQLError(msg));
|
|
35
|
+
},
|
|
36
|
+
parseValue(value) {
|
|
37
|
+
return normalizeDate(value, (msg) => new graphql_1.GraphQLError(msg));
|
|
38
|
+
},
|
|
39
|
+
parseLiteral(ast) {
|
|
40
|
+
if (ast.kind !== language_1.Kind.STRING) {
|
|
41
|
+
throw new graphql_1.GraphQLError(`Date cannot represent literal: ${ast.kind}`);
|
|
42
|
+
}
|
|
43
|
+
return normalizeDate(ast.value, (msg) => new graphql_1.GraphQLError(msg));
|
|
44
|
+
},
|
|
45
|
+
});
|
package/package.json
CHANGED
package/parse_schema/parse.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Schema, Field, AssocEdge, AssocEdgeGroup, Action } from "../schema";
|
|
2
|
-
import { ActionField, Type, FieldMap, GlobalSchema, TransformReadBetaResult, CanViewerDo } from "../schema/schema";
|
|
2
|
+
import { ActionField, Type, FieldMap, GlobalSchema, EdgeIndex, TransformReadBetaResult, CanViewerDo } from "../schema/schema";
|
|
3
3
|
export declare function processFields(src: FieldMap | Field[], patternName?: string): Promise<ProcessedField[]>;
|
|
4
4
|
declare enum NullableResult {
|
|
5
5
|
CONTENTS = "contents",
|
|
@@ -87,6 +87,7 @@ interface BiomeConfig {
|
|
|
87
87
|
interface ProcessedGlobalSchema {
|
|
88
88
|
globalEdges: ProcessedAssocEdge[];
|
|
89
89
|
extraEdgeFields: ProcessedField[];
|
|
90
|
+
edgeIndices?: EdgeIndex[];
|
|
90
91
|
init?: boolean;
|
|
91
92
|
transformsEdges?: boolean;
|
|
92
93
|
globalFields?: ProcessedField[];
|
package/parse_schema/parse.js
CHANGED
|
@@ -502,6 +502,7 @@ async function parseGlobalSchema(s) {
|
|
|
502
502
|
globalEdges: [],
|
|
503
503
|
extraEdgeFields: [],
|
|
504
504
|
init: !!s.extraEdgeFields ||
|
|
505
|
+
!!s.edgeIndices ||
|
|
505
506
|
s.transformEdgeRead !== undefined ||
|
|
506
507
|
s.transformEdgeWrite !== undefined ||
|
|
507
508
|
s.fields !== undefined,
|
|
@@ -510,6 +511,9 @@ async function parseGlobalSchema(s) {
|
|
|
510
511
|
if (s.extraEdgeFields) {
|
|
511
512
|
ret.extraEdgeFields = await processFields(s.extraEdgeFields);
|
|
512
513
|
}
|
|
514
|
+
if (s.edgeIndices) {
|
|
515
|
+
ret.edgeIndices = s.edgeIndices;
|
|
516
|
+
}
|
|
513
517
|
if (s.edges) {
|
|
514
518
|
ret.globalEdges = processEdges(s.edges);
|
|
515
519
|
}
|
package/schema/field.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ export declare abstract class BaseField {
|
|
|
11
11
|
sensitive?: boolean;
|
|
12
12
|
graphqlName?: string;
|
|
13
13
|
index?: boolean;
|
|
14
|
+
indexConcurrently?: boolean;
|
|
15
|
+
indexWhere?: string;
|
|
14
16
|
foreignKey?: ForeignKey;
|
|
15
17
|
polymorphic?: boolean | PolymorphicOptions;
|
|
16
18
|
derivedWhenEmbedded?: boolean;
|
package/schema/field.js
CHANGED
|
@@ -499,11 +499,13 @@ class DateField extends BaseField {
|
|
|
499
499
|
return val;
|
|
500
500
|
}
|
|
501
501
|
val = new Date(val);
|
|
502
|
-
|
|
502
|
+
// interpret as UTC to avoid timezone drift when the Date
|
|
503
|
+
// represents a midnight UTC value
|
|
504
|
+
let yy = (0, exports.leftPad)(val.getUTCFullYear());
|
|
503
505
|
// lol this API
|
|
504
506
|
// for some reason this is 0-index
|
|
505
|
-
let mm = (0, exports.leftPad)(val.
|
|
506
|
-
let dd = (0, exports.leftPad)(val.
|
|
507
|
+
let mm = (0, exports.leftPad)(val.getUTCMonth() + 1);
|
|
508
|
+
let dd = (0, exports.leftPad)(val.getUTCDate());
|
|
507
509
|
let ret = `${yy}-${mm}-${dd}`;
|
|
508
510
|
return ret;
|
|
509
511
|
}
|
package/schema/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import Schema from "./schema";
|
|
2
2
|
export { Schema };
|
|
3
|
-
export { Field, AssocEdge, AssocEdgeGroup, InverseAssocEdge, Edge, Pattern, DBType, Type, FieldOptions, SchemaConstructor, SchemaInputType, getFields, getFieldsWithPrivacy, getFieldsWithEditPrivacy, getStorageKey, ActionOperation, Action, EdgeAction, NoFields, FieldMap, Constraint, Index, ConstraintType, ForeignKeyInfo, requiredField, optionalField, UpdateOperation, TransformedUpdateOperation, SQLStatementOperation, EdgeUpdateOperation, TransformedEdgeUpdateOperation, getTransformedReadClause, getObjectLoaderProperties, GlobalSchema, ActionField, } from "./schema";
|
|
3
|
+
export { Field, AssocEdge, AssocEdgeGroup, InverseAssocEdge, Edge, Pattern, DBType, Type, FieldOptions, SchemaConstructor, SchemaInputType, getFields, getFieldsWithPrivacy, getFieldsWithEditPrivacy, getStorageKey, ActionOperation, Action, EdgeAction, NoFields, FieldMap, Constraint, Index, EdgeIndex, ConstraintType, ForeignKeyInfo, requiredField, optionalField, UpdateOperation, TransformedUpdateOperation, SQLStatementOperation, EdgeUpdateOperation, TransformedEdgeUpdateOperation, getTransformedReadClause, getObjectLoaderProperties, GlobalSchema, ActionField, } from "./schema";
|
|
4
4
|
export { Timestamps, Node, BaseEntSchema, BaseEntSchemaWithTZ, EntSchema, EntSchemaWithTZ, SchemaConfig, } from "./base_schema";
|
|
5
5
|
export * from "./field";
|
|
6
6
|
export * from "./json_field";
|
package/schema/schema.d.ts
CHANGED
|
@@ -16,11 +16,12 @@ export type FieldInfoMap = {
|
|
|
16
16
|
export interface GlobalSchema {
|
|
17
17
|
edges?: Edge[];
|
|
18
18
|
extraEdgeFields?: FieldMap;
|
|
19
|
+
edgeIndices?: EdgeIndex[];
|
|
19
20
|
transformEdgeRead?: () => Clause;
|
|
20
21
|
transformEdgeWrite?: (stmt: EdgeUpdateOperation) => TransformedEdgeUpdateOperation | null;
|
|
21
22
|
fields?: FieldMap;
|
|
22
23
|
}
|
|
23
|
-
type FieldOverride = Pick<FieldOptions, "nullable" | "storageKey" | "serverDefault" | "unique" | "hideFromGraphQL" | "graphqlName" | "index">;
|
|
24
|
+
type FieldOverride = Pick<FieldOptions, "nullable" | "storageKey" | "serverDefault" | "unique" | "hideFromGraphQL" | "graphqlName" | "index" | "indexConcurrently" | "indexWhere">;
|
|
24
25
|
export type FieldOverrideMap = {
|
|
25
26
|
[key: string]: FieldOverride;
|
|
26
27
|
};
|
|
@@ -233,6 +234,8 @@ export interface FieldOptions {
|
|
|
233
234
|
sensitive?: boolean;
|
|
234
235
|
graphqlName?: string;
|
|
235
236
|
index?: boolean;
|
|
237
|
+
indexConcurrently?: boolean;
|
|
238
|
+
indexWhere?: string;
|
|
236
239
|
foreignKey?: ForeignKey;
|
|
237
240
|
fieldEdge?: FieldEdge;
|
|
238
241
|
primaryKey?: boolean;
|
|
@@ -359,8 +362,13 @@ export interface Index {
|
|
|
359
362
|
unique?: boolean;
|
|
360
363
|
fulltext?: FullText;
|
|
361
364
|
indexType?: "gin" | "btree";
|
|
365
|
+
concurrently?: boolean;
|
|
366
|
+
where?: string;
|
|
362
367
|
[x: string]: any;
|
|
363
368
|
}
|
|
369
|
+
export interface EdgeIndex extends Omit<Index, "name"> {
|
|
370
|
+
name?: string;
|
|
371
|
+
}
|
|
364
372
|
export interface ForeignKeyInfo {
|
|
365
373
|
tableName: string;
|
|
366
374
|
ondelete?: OnDeleteFkey;
|
|
@@ -359,6 +359,11 @@ async function main() {
|
|
|
359
359
|
secondaryImportPath: "../graphql/scalars/time",
|
|
360
360
|
type: "GraphQLTime",
|
|
361
361
|
}, gqlCapture);
|
|
362
|
+
(0, graphql_1.addCustomType)({
|
|
363
|
+
importPath: MODULE_PATH,
|
|
364
|
+
secondaryImportPath: "../graphql/scalars/date",
|
|
365
|
+
type: "GraphQLDate",
|
|
366
|
+
}, gqlCapture);
|
|
362
367
|
(0, graphql_1.addCustomType)({
|
|
363
368
|
importPath: "graphql-type-json",
|
|
364
369
|
type: "GraphQLJSON",
|
package/testutils/db/value.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.getDefaultValue = exports.randomPhoneNumber = exports.randomEmail = void
|
|
|
4
4
|
const uuid_1 = require("uuid");
|
|
5
5
|
const schema_1 = require("../../schema");
|
|
6
6
|
const schema_2 = require("../../schema");
|
|
7
|
+
const crypto_1 = require("crypto");
|
|
7
8
|
function random() {
|
|
8
9
|
return Math.random().toString(16).substring(2);
|
|
9
10
|
}
|
|
@@ -13,7 +14,12 @@ function randomEmail(domain) {
|
|
|
13
14
|
}
|
|
14
15
|
exports.randomEmail = randomEmail;
|
|
15
16
|
function randomPhoneNumber() {
|
|
16
|
-
|
|
17
|
+
// generate 12 digits from random bytes so we can safely carve out a NANP number
|
|
18
|
+
const raw = (0, crypto_1.randomBytes)(5).readUIntBE(0, 5).toString().padStart(12, "0");
|
|
19
|
+
const first = (parseInt(raw[0], 10) % 8) + 2; // ensure 2-9 for NANP area codes
|
|
20
|
+
const areaCode = `${first}${raw[1]}${raw[2]}`;
|
|
21
|
+
const localNumber = raw.slice(3, 10);
|
|
22
|
+
return `+1${areaCode}${localNumber}`;
|
|
17
23
|
}
|
|
18
24
|
exports.randomPhoneNumber = randomPhoneNumber;
|
|
19
25
|
function coinFlip() {
|
package/testutils/parse_sql.js
CHANGED
|
@@ -354,11 +354,46 @@ map) {
|
|
|
354
354
|
const colsInfo = getColumns(ast.columns);
|
|
355
355
|
// console.log(tableName, columns, allColumns);
|
|
356
356
|
let limit = null;
|
|
357
|
+
let offset = null;
|
|
357
358
|
if (ast.limit !== null) {
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
assert(
|
|
361
|
-
|
|
359
|
+
const limitInfo = ast.limit;
|
|
360
|
+
const values = limitInfo.value || [];
|
|
361
|
+
assert(values.length >= 1 && values.length <= 2, "ast limit not as expected");
|
|
362
|
+
const parsedValues = values.map((value) => {
|
|
363
|
+
assert(value.type == "number", "limit type was not 0");
|
|
364
|
+
return value.value;
|
|
365
|
+
});
|
|
366
|
+
const separator = limitInfo.seperator || "";
|
|
367
|
+
if (parsedValues.length === 1) {
|
|
368
|
+
limit = parsedValues[0];
|
|
369
|
+
}
|
|
370
|
+
else if (separator === ",") {
|
|
371
|
+
offset = parsedValues[0];
|
|
372
|
+
limit = parsedValues[1];
|
|
373
|
+
}
|
|
374
|
+
else if (separator === "offset") {
|
|
375
|
+
limit = parsedValues[0];
|
|
376
|
+
offset = parsedValues[1];
|
|
377
|
+
}
|
|
378
|
+
else {
|
|
379
|
+
throw new Error(`unsupported limit separator: ${separator}`);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
const astOffset = ast.offset;
|
|
383
|
+
if (astOffset !== undefined && astOffset !== null && offset === null) {
|
|
384
|
+
if (typeof astOffset === "number") {
|
|
385
|
+
offset = astOffset;
|
|
386
|
+
}
|
|
387
|
+
else if (typeof astOffset === "object") {
|
|
388
|
+
const offsetValue = astOffset.value ?? astOffset;
|
|
389
|
+
if (typeof offsetValue === "number") {
|
|
390
|
+
offset = offsetValue;
|
|
391
|
+
}
|
|
392
|
+
else if (Array.isArray(offsetValue) && offsetValue.length) {
|
|
393
|
+
assert(offsetValue[0].type == "number", "offset type was not 0");
|
|
394
|
+
offset = offsetValue[0].value;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
362
397
|
}
|
|
363
398
|
let orderings = [];
|
|
364
399
|
if (ast.orderby !== null) {
|
|
@@ -374,11 +409,18 @@ map) {
|
|
|
374
409
|
let where = buildWhereStatement(ast, values);
|
|
375
410
|
const list = map.get(tableName) || [];
|
|
376
411
|
let results = [];
|
|
412
|
+
const canLimitEarly = orderings.length === 0 && !colsInfo.count;
|
|
377
413
|
let limitApplied = false;
|
|
414
|
+
const offsetAppliedEarly = canLimitEarly && offset !== null;
|
|
415
|
+
let offsetRemaining = offsetAppliedEarly ? offset || 0 : 0;
|
|
378
416
|
for (const data of list) {
|
|
379
417
|
if (where && !where.apply(data)) {
|
|
380
418
|
continue;
|
|
381
419
|
}
|
|
420
|
+
if (canLimitEarly && offsetRemaining > 0) {
|
|
421
|
+
offsetRemaining--;
|
|
422
|
+
continue;
|
|
423
|
+
}
|
|
382
424
|
if (colsInfo.allCols) {
|
|
383
425
|
results.push(getDataToReturn(data, undefined, true));
|
|
384
426
|
}
|
|
@@ -389,11 +431,7 @@ map) {
|
|
|
389
431
|
}
|
|
390
432
|
results.push(getDataToReturn(data, cols));
|
|
391
433
|
}
|
|
392
|
-
|
|
393
|
-
if (orderings.length === 0 &&
|
|
394
|
-
!colsInfo.count &&
|
|
395
|
-
limit !== null &&
|
|
396
|
-
limit == results.length) {
|
|
434
|
+
if (canLimitEarly && limit !== null && limit == results.length) {
|
|
397
435
|
limitApplied = true;
|
|
398
436
|
break;
|
|
399
437
|
}
|
|
@@ -424,9 +462,11 @@ map) {
|
|
|
424
462
|
return 0;
|
|
425
463
|
});
|
|
426
464
|
}
|
|
427
|
-
// apply limit after if not applied e.g. there was an ordering or no where clause
|
|
428
|
-
if (limit !== null
|
|
429
|
-
|
|
465
|
+
// apply limit/offset after if not applied e.g. there was an ordering or no where clause
|
|
466
|
+
if (!limitApplied && (limit !== null || offset !== null)) {
|
|
467
|
+
const start = offsetAppliedEarly ? 0 : offset || 0;
|
|
468
|
+
const end = limit !== null ? start + limit : undefined;
|
|
469
|
+
results = results.slice(start, end);
|
|
430
470
|
}
|
|
431
471
|
return results;
|
|
432
472
|
}
|
|
@@ -10,6 +10,9 @@ export declare const testEdgeGlobalSchema: {
|
|
|
10
10
|
extraEdgeFields: {
|
|
11
11
|
deletedAt: import("../schema").TimestampField;
|
|
12
12
|
};
|
|
13
|
+
edgeIndices: {
|
|
14
|
+
columns: string[];
|
|
15
|
+
}[];
|
|
13
16
|
transformEdgeRead(): clause.Clause;
|
|
14
17
|
transformEdgeWrite(stmt: EdgeUpdateOperation): TransformedEdgeUpdateOperation | null;
|
|
15
18
|
};
|
|
@@ -38,10 +38,14 @@ exports.testEdgeGlobalSchema = {
|
|
|
38
38
|
extraEdgeFields: {
|
|
39
39
|
deletedAt: (0, schema_1.TimestampType)({
|
|
40
40
|
nullable: true,
|
|
41
|
-
index: true,
|
|
42
41
|
defaultValueOnCreate: () => null,
|
|
43
42
|
}),
|
|
44
43
|
},
|
|
44
|
+
edgeIndices: [
|
|
45
|
+
{
|
|
46
|
+
columns: ["id1", "edge_type", "deleted_at"],
|
|
47
|
+
},
|
|
48
|
+
],
|
|
45
49
|
transformEdgeRead() {
|
|
46
50
|
return clause.Eq("deleted_at", null);
|
|
47
51
|
},
|