@snowtop/ent 0.1.0-alpha54 → 0.1.0-alpha59
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/orchestrator.js +21 -0
- package/core/base.d.ts +1 -1
- package/core/clause.d.ts +36 -7
- package/core/clause.js +133 -32
- package/core/config.d.ts +5 -2
- package/core/ent.d.ts +16 -3
- package/core/ent.js +147 -35
- package/core/loaders/assoc_count_loader.js +6 -1
- package/core/query/shared_assoc_test.d.ts +1 -1
- package/core/query/shared_assoc_test.js +17 -5
- package/core/query/shared_test.d.ts +3 -0
- package/core/query/shared_test.js +95 -17
- package/index.d.ts +5 -5
- package/index.js +7 -6
- package/package.json +1 -1
- package/parse_schema/parse.d.ts +8 -2
- package/parse_schema/parse.js +35 -2
- package/schema/index.d.ts +1 -1
- package/schema/schema.d.ts +20 -1
- package/scripts/custom_graphql.js +2 -0
- package/scripts/read_schema.js +10 -1
- package/testutils/db/{test_db.d.ts → temp_db.d.ts} +15 -3
- package/testutils/db/{test_db.js → temp_db.js} +62 -15
- package/testutils/fake_data/fake_contact.d.ts +1 -1
- package/testutils/fake_data/fake_contact.js +2 -2
- package/testutils/fake_data/fake_event.d.ts +1 -1
- package/testutils/fake_data/fake_event.js +3 -3
- package/testutils/fake_data/fake_user.d.ts +1 -1
- package/testutils/fake_data/fake_user.js +2 -2
- package/testutils/fake_data/test_helpers.d.ts +2 -2
- package/testutils/fake_data/test_helpers.js +5 -5
- package/testutils/parse_sql.js +4 -0
- package/testutils/test_edge_global_schema.d.ts +15 -0
- package/testutils/test_edge_global_schema.js +58 -0
- package/testutils/write.d.ts +2 -2
- package/testutils/write.js +3 -3
- package/tsc/ast.d.ts +1 -0
- package/tsc/ast.js +3 -0
package/index.js
CHANGED
|
@@ -25,8 +25,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
25
25
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
26
26
|
};
|
|
27
27
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
28
|
-
exports.
|
|
29
|
-
exports.setLogLevels = exports.loadConfig = exports.LoggedOutViewer = exports.IDViewer = exports.ContextCache = exports.query = exports.AllowIfViewerHasIdentityPrivacyPolicy = exports.AllowIfViewerPrivacyPolicy = exports.AllowIfSubPolicyAllowsRule = exports.AllowIfConditionAppliesRule = exports.AlwaysDenyPrivacyPolicy = exports.AlwaysAllowPrivacyPolicy = exports.applyPrivacyPolicyX = exports.applyPrivacyPolicy = exports.DelayedResultRule = exports.DenyIfEntIsVisiblePolicy = exports.AllowIfEntIsVisiblePolicy = exports.DenyIfEntIsNotVisibleRule = exports.DenyIfEntIsVisibleRule = exports.AllowIfEntIsNotVisibleRule = exports.AllowIfEntIsVisibleRule = exports.DenyIfViewerOutboundEdgeDoesNotExistRule = void 0;
|
|
28
|
+
exports.DenyIfEdgeDoesNotExistRule = exports.DenyIfViewerOutboundEdgeExistsRule = exports.DenyIfViewerInboundEdgeExistsRule = exports.DenyIfEdgeExistsRule = exports.AllowIfViewerOutboundEdgeExistsRule = exports.AllowIfViewerInboundEdgeExistsRule = exports.AllowIfEdgeExistsRule = exports.DenyIfViewerEqualsRule = exports.AllowIfViewerEqualsRule = exports.DenyIfEntPropertyIsRule = exports.AllowIfEntPropertyIsRule = exports.AllowIfViewerIsEntPropertyRule = exports.AllowIfViewerIsRule = exports.AllowIfFuncRule = exports.AllowIfViewerRule = exports.AllowIfHasIdentity = exports.DenyIfLoggedOutRule = exports.DenyIfLoggedInRule = exports.AlwaysDenyRule = exports.AlwaysAllowRule = exports.EntPrivacyError = exports.DB = exports.setGlobalSchema = exports.getEdgeTypeInGroup = exports.loadNodesByEdge = exports.loadEdgeForID2 = exports.loadRawEdgeCountX = exports.loadUniqueNode = exports.loadUniqueEdge = exports.loadEdges = exports.loadEdgeDatas = exports.loadEdgeData = exports.AssocEdgeData = exports.AssocEdge = exports.DeleteNodeOperation = exports.EdgeOperation = exports.EditNodeOperation = exports.loadRows = exports.loadRow = exports.loadRowX = exports.performRawQuery = exports.loadEntXViaKey = exports.loadEntViaKey = exports.loadDerivedEntX = exports.loadDerivedEnt = exports.loadEnts = exports.loadEntX = exports.loadCustomEnts = exports.loadCustomData = exports.loadEnt = void 0;
|
|
29
|
+
exports.setLogLevels = exports.loadConfig = exports.LoggedOutViewer = exports.IDViewer = exports.ContextCache = exports.query = exports.AllowIfViewerHasIdentityPrivacyPolicy = exports.AllowIfViewerPrivacyPolicy = exports.AllowIfSubPolicyAllowsRule = exports.AllowIfConditionAppliesRule = exports.AlwaysDenyPrivacyPolicy = exports.AlwaysAllowPrivacyPolicy = exports.applyPrivacyPolicyX = exports.applyPrivacyPolicy = exports.DelayedResultRule = exports.DenyIfEntIsVisiblePolicy = exports.AllowIfEntIsVisiblePolicy = exports.DenyIfEntIsNotVisibleRule = exports.DenyIfEntIsVisibleRule = exports.AllowIfEntIsNotVisibleRule = exports.AllowIfEntIsVisibleRule = exports.DenyIfViewerOutboundEdgeDoesNotExistRule = exports.DenyIfViewerInboundEdgeDoesNotExistRule = void 0;
|
|
30
30
|
__exportStar(require("./core/base"), exports);
|
|
31
31
|
var ent_1 = require("./core/ent");
|
|
32
32
|
Object.defineProperty(exports, "loadEnt", { enumerable: true, get: function () { return ent_1.loadEnt; } });
|
|
@@ -57,6 +57,7 @@ Object.defineProperty(exports, "loadRawEdgeCountX", { enumerable: true, get: fun
|
|
|
57
57
|
Object.defineProperty(exports, "loadEdgeForID2", { enumerable: true, get: function () { return ent_1.loadEdgeForID2; } });
|
|
58
58
|
Object.defineProperty(exports, "loadNodesByEdge", { enumerable: true, get: function () { return ent_1.loadNodesByEdge; } });
|
|
59
59
|
Object.defineProperty(exports, "getEdgeTypeInGroup", { enumerable: true, get: function () { return ent_1.getEdgeTypeInGroup; } });
|
|
60
|
+
Object.defineProperty(exports, "setGlobalSchema", { enumerable: true, get: function () { return ent_1.setGlobalSchema; } });
|
|
60
61
|
const db_1 = __importDefault(require("./core/db"));
|
|
61
62
|
exports.DB = db_1.default;
|
|
62
63
|
__exportStar(require("./core/loaders"), exports);
|
|
@@ -116,10 +117,10 @@ const query = {
|
|
|
116
117
|
LessEq: q.LessEq,
|
|
117
118
|
ArrayEq: q.ArrayEq,
|
|
118
119
|
ArrayNotEq: q.ArrayNotEq,
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
120
|
+
PostgresArrayContainsValue: q.PostgresArrayContainsValue,
|
|
121
|
+
PostgresArrayContains: q.PostgresArrayContains,
|
|
122
|
+
PostgresArrayNotContainsValue: q.PostgresArrayNotContainsValue,
|
|
123
|
+
PostgresArrayNotContains: q.PostgresArrayNotContains,
|
|
123
124
|
TsQuery: q.TsQuery,
|
|
124
125
|
PlainToTsQuery: q.PlainToTsQuery,
|
|
125
126
|
PhraseToTsQuery: q.PhraseToTsQuery,
|
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 } from "../schema/schema";
|
|
2
|
+
import { ActionField, Type, GlobalSchema } from "../schema/schema";
|
|
3
3
|
declare enum NullableResult {
|
|
4
4
|
CONTENTS = "contents",
|
|
5
5
|
CONTENTS_AND_LIST = "contentsAndList",
|
|
@@ -61,9 +61,15 @@ interface patternsDict {
|
|
|
61
61
|
interface Result {
|
|
62
62
|
schemas: schemasDict;
|
|
63
63
|
patterns: patternsDict;
|
|
64
|
+
globalSchema?: ProcessedGlobalSchema;
|
|
64
65
|
}
|
|
65
66
|
declare type PotentialSchemas = {
|
|
66
67
|
[key: string]: any;
|
|
67
68
|
};
|
|
68
|
-
export declare function parseSchema(potentialSchemas: PotentialSchemas): Result;
|
|
69
|
+
export declare function parseSchema(potentialSchemas: PotentialSchemas, globalSchema?: GlobalSchema): Result;
|
|
70
|
+
interface ProcessedGlobalSchema {
|
|
71
|
+
globalEdges: ProcessedAssocEdge[];
|
|
72
|
+
extraEdgeFields: ProcessedField[];
|
|
73
|
+
initForEdges?: boolean;
|
|
74
|
+
}
|
|
69
75
|
export {};
|
package/parse_schema/parse.js
CHANGED
|
@@ -36,6 +36,19 @@ function processFields(src, patternName) {
|
|
|
36
36
|
else {
|
|
37
37
|
delete f.polymorphic;
|
|
38
38
|
}
|
|
39
|
+
if (field.private) {
|
|
40
|
+
// convert boolean into object
|
|
41
|
+
// we keep boolean as an option to keep API simple
|
|
42
|
+
if (typeof field.private === "boolean") {
|
|
43
|
+
f.private = {};
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
f.private = field.private;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
delete f.private;
|
|
51
|
+
}
|
|
39
52
|
// convert string to object to make API consumed by go simple
|
|
40
53
|
if (f.fieldEdge && f.fieldEdge.inverseEdge) {
|
|
41
54
|
if (typeof f.fieldEdge.inverseEdge === "string") {
|
|
@@ -172,9 +185,13 @@ function processAction(action) {
|
|
|
172
185
|
ret.actionOnlyFields = actionOnlyFields;
|
|
173
186
|
return ret;
|
|
174
187
|
}
|
|
175
|
-
function parseSchema(potentialSchemas) {
|
|
188
|
+
function parseSchema(potentialSchemas, globalSchema) {
|
|
176
189
|
let schemas = {};
|
|
177
190
|
let patterns = {};
|
|
191
|
+
let parsedGlobalSchema;
|
|
192
|
+
if (globalSchema) {
|
|
193
|
+
parsedGlobalSchema = parseGlobalSchema(globalSchema);
|
|
194
|
+
}
|
|
178
195
|
for (const key in potentialSchemas) {
|
|
179
196
|
const value = potentialSchemas[key];
|
|
180
197
|
let schema;
|
|
@@ -234,6 +251,22 @@ function parseSchema(potentialSchemas) {
|
|
|
234
251
|
}
|
|
235
252
|
schemas[key] = processedSchema;
|
|
236
253
|
}
|
|
237
|
-
return { schemas, patterns };
|
|
254
|
+
return { schemas, patterns, globalSchema: parsedGlobalSchema };
|
|
238
255
|
}
|
|
239
256
|
exports.parseSchema = parseSchema;
|
|
257
|
+
function parseGlobalSchema(s) {
|
|
258
|
+
const ret = {
|
|
259
|
+
globalEdges: [],
|
|
260
|
+
extraEdgeFields: [],
|
|
261
|
+
initForEdges: !!s.extraEdgeFields ||
|
|
262
|
+
s.transformEdgeRead !== undefined ||
|
|
263
|
+
s.transformEdgeWrite !== undefined,
|
|
264
|
+
};
|
|
265
|
+
if (s.extraEdgeFields) {
|
|
266
|
+
ret.extraEdgeFields = processFields(s.extraEdgeFields);
|
|
267
|
+
}
|
|
268
|
+
if (s.edges) {
|
|
269
|
+
ret.globalEdges = processEdges(s.edges);
|
|
270
|
+
}
|
|
271
|
+
return ret;
|
|
272
|
+
}
|
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, getStorageKey, ActionOperation, Action, EdgeAction, NoFields, FieldMap, Constraint, Index, ConstraintType, ForeignKeyInfo, requiredField, optionalField, UpdateOperation, TransformedUpdateOperation, SQLStatementOperation, getTransformedReadClause, getObjectLoaderProperties, } from "./schema";
|
|
3
|
+
export { Field, AssocEdge, AssocEdgeGroup, InverseAssocEdge, Edge, Pattern, DBType, Type, FieldOptions, SchemaConstructor, SchemaInputType, getFields, getFieldsWithPrivacy, getStorageKey, ActionOperation, Action, EdgeAction, NoFields, FieldMap, Constraint, Index, ConstraintType, ForeignKeyInfo, requiredField, optionalField, UpdateOperation, TransformedUpdateOperation, SQLStatementOperation, EdgeUpdateOperation, TransformedEdgeUpdateOperation, getTransformedReadClause, getObjectLoaderProperties, GlobalSchema, } 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
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Data, Ent, LoaderInfo, PrivacyPolicy, Viewer } from "../core/base";
|
|
2
2
|
import { Builder } from "../action/action";
|
|
3
3
|
import { Clause } from "../core/clause";
|
|
4
|
+
import { AssocEdgeInput } from "../core/ent";
|
|
4
5
|
export declare type FieldMap = {
|
|
5
6
|
[key: string]: Field;
|
|
6
7
|
};
|
|
@@ -11,6 +12,12 @@ interface FieldInfo {
|
|
|
11
12
|
export declare type FieldInfoMap = {
|
|
12
13
|
[key: string]: FieldInfo;
|
|
13
14
|
};
|
|
15
|
+
export interface GlobalSchema {
|
|
16
|
+
edges?: Edge[];
|
|
17
|
+
extraEdgeFields?: FieldMap;
|
|
18
|
+
transformEdgeRead?: () => Clause;
|
|
19
|
+
transformEdgeWrite?: (stmt: EdgeUpdateOperation) => TransformedEdgeUpdateOperation | null;
|
|
20
|
+
}
|
|
14
21
|
export default interface Schema {
|
|
15
22
|
fields: FieldMap | Field[];
|
|
16
23
|
tableName?: string;
|
|
@@ -82,6 +89,14 @@ export declare enum SQLStatementOperation {
|
|
|
82
89
|
Update = "update",
|
|
83
90
|
Delete = "delete"
|
|
84
91
|
}
|
|
92
|
+
export interface EdgeUpdateOperation {
|
|
93
|
+
op: SQLStatementOperation;
|
|
94
|
+
edge: AssocEdgeInput;
|
|
95
|
+
}
|
|
96
|
+
export interface TransformedEdgeUpdateOperation {
|
|
97
|
+
op: SQLStatementOperation;
|
|
98
|
+
data?: Data;
|
|
99
|
+
}
|
|
85
100
|
export interface UpdateOperation<TEnt extends Ent<TViewer>, TViewer extends Viewer = Viewer> {
|
|
86
101
|
op: SQLStatementOperation;
|
|
87
102
|
builder: Builder<TEnt, TViewer>;
|
|
@@ -158,13 +173,16 @@ export interface FieldEdge {
|
|
|
158
173
|
getLoaderInfoFromSchema?: getLoaderInfoFn;
|
|
159
174
|
disableBuilderType?: boolean;
|
|
160
175
|
}
|
|
176
|
+
interface PrivateOptions {
|
|
177
|
+
exposeToActions?: boolean;
|
|
178
|
+
}
|
|
161
179
|
export interface FieldOptions {
|
|
162
180
|
nullable?: boolean;
|
|
163
181
|
storageKey?: string;
|
|
164
182
|
serverDefault?: any;
|
|
165
183
|
unique?: boolean;
|
|
166
184
|
hideFromGraphQL?: boolean;
|
|
167
|
-
private?: boolean;
|
|
185
|
+
private?: boolean | PrivateOptions;
|
|
168
186
|
sensitive?: boolean;
|
|
169
187
|
graphqlName?: string;
|
|
170
188
|
index?: boolean;
|
|
@@ -271,6 +289,7 @@ export interface Index {
|
|
|
271
289
|
columns: string[];
|
|
272
290
|
unique?: boolean;
|
|
273
291
|
fulltext?: FullText;
|
|
292
|
+
indexType?: "gin" | "btree";
|
|
274
293
|
}
|
|
275
294
|
export interface ForeignKeyInfo {
|
|
276
295
|
tableName: string;
|
|
@@ -237,6 +237,8 @@ async function main() {
|
|
|
237
237
|
(0, graphql_1.addCustomType)({
|
|
238
238
|
importPath: MODULE_PATH,
|
|
239
239
|
// for go tests...
|
|
240
|
+
// TODO need a flag that only does this for go tests
|
|
241
|
+
// breaks when running locally sometimes...
|
|
240
242
|
secondaryImportPath: "../graphql/scalars/time",
|
|
241
243
|
type: "GraphQLTime",
|
|
242
244
|
});
|
package/scripts/read_schema.js
CHANGED
|
@@ -28,18 +28,27 @@ const pascal_case_1 = require("pascal-case");
|
|
|
28
28
|
const minimist_1 = __importDefault(require("minimist"));
|
|
29
29
|
const process_1 = require("process");
|
|
30
30
|
const parse_1 = require("../parse_schema/parse");
|
|
31
|
+
const ast_1 = require("../tsc/ast");
|
|
31
32
|
function main() {
|
|
32
33
|
const options = (0, minimist_1.default)(process.argv.slice(2));
|
|
33
34
|
if (!options.path) {
|
|
34
35
|
throw new Error("path required");
|
|
35
36
|
}
|
|
37
|
+
const customInfo = (0, ast_1.getCustomInfo)();
|
|
38
|
+
const globalSchemaPath = customInfo.globalSchemaPath || "__global__schema.ts";
|
|
39
|
+
let globalSchema;
|
|
36
40
|
const r = /(\w+).ts/;
|
|
41
|
+
// do we still even need this...
|
|
37
42
|
const paths = glob_1.default.sync(path.join(options.path, "*.ts"), {
|
|
38
43
|
ignore: [`\d+_read_schema.ts`],
|
|
39
44
|
});
|
|
40
45
|
let potentialSchemas = {};
|
|
41
46
|
for (const p of paths) {
|
|
42
47
|
const basename = path.basename(p);
|
|
48
|
+
if (basename === globalSchemaPath) {
|
|
49
|
+
globalSchema = require(p).default;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
43
52
|
const match = r.exec(basename);
|
|
44
53
|
if (!match) {
|
|
45
54
|
throw new Error(`non-typescript file ${p} returned by glob`);
|
|
@@ -61,7 +70,7 @@ function main() {
|
|
|
61
70
|
potentialSchemas[(0, pascal_case_1.pascalCase)(schema)] = s;
|
|
62
71
|
}
|
|
63
72
|
// console.log(potentialSchemas);
|
|
64
|
-
const result = (0, parse_1.parseSchema)(potentialSchemas);
|
|
73
|
+
const result = (0, parse_1.parseSchema)(potentialSchemas, globalSchema);
|
|
65
74
|
console.log(JSON.stringify(result));
|
|
66
75
|
}
|
|
67
76
|
try {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Client as PGClient } from "pg";
|
|
2
2
|
import { Dialect } from "../../core/db";
|
|
3
3
|
import { Database as SqliteDatabase } from "better-sqlite3";
|
|
4
|
+
import { Field } from "../../schema";
|
|
4
5
|
import { BuilderSchema } from "../builder";
|
|
5
6
|
import { Ent } from "../../core/base";
|
|
6
7
|
interface SchemaItem {
|
|
@@ -12,6 +13,7 @@ interface Column extends SchemaItem {
|
|
|
12
13
|
primaryKey?: boolean;
|
|
13
14
|
unique?: boolean;
|
|
14
15
|
default?: string;
|
|
16
|
+
index?: boolean | indexOptions;
|
|
15
17
|
foreignKey?: {
|
|
16
18
|
table: string;
|
|
17
19
|
col: string;
|
|
@@ -20,21 +22,29 @@ interface Column extends SchemaItem {
|
|
|
20
22
|
interface Constraint extends SchemaItem {
|
|
21
23
|
generate(): string;
|
|
22
24
|
}
|
|
25
|
+
interface Index extends SchemaItem {
|
|
26
|
+
generate(): string;
|
|
27
|
+
}
|
|
23
28
|
export interface CoreConcept {
|
|
24
29
|
name: string;
|
|
25
30
|
create(): string;
|
|
31
|
+
postCreate?(): string[];
|
|
26
32
|
drop(): string;
|
|
27
33
|
}
|
|
28
34
|
export interface Table extends CoreConcept {
|
|
29
35
|
columns: Column[];
|
|
30
36
|
constraints?: Constraint[];
|
|
31
37
|
}
|
|
32
|
-
declare type options = Pick<Column, "nullable" | "primaryKey" | "default" | "foreignKey" | "unique">;
|
|
38
|
+
declare type options = Pick<Column, "nullable" | "primaryKey" | "default" | "foreignKey" | "unique" | "index">;
|
|
33
39
|
export declare function primaryKey(name: string, cols: string[]): Constraint;
|
|
34
40
|
export declare function foreignKey(name: string, cols: string[], fkey: {
|
|
35
41
|
table: string;
|
|
36
42
|
cols: string[];
|
|
37
43
|
}): Constraint;
|
|
44
|
+
interface indexOptions {
|
|
45
|
+
type: string;
|
|
46
|
+
}
|
|
47
|
+
export declare function index(tableName: string, cols: string[], opts?: indexOptions): Index;
|
|
38
48
|
export declare function uniqueIndex(name: string): Constraint;
|
|
39
49
|
export declare function uuid(name: string, opts?: options): Column;
|
|
40
50
|
export declare function text(name: string, opts?: options): Column;
|
|
@@ -72,6 +82,7 @@ export declare class TempDB {
|
|
|
72
82
|
getDialect(): Dialect;
|
|
73
83
|
getTables(): Map<string, CoreConcept>;
|
|
74
84
|
beforeAll(setupConnString?: boolean): Promise<void>;
|
|
85
|
+
createImpl(table: CoreConcept): Promise<void>;
|
|
75
86
|
getSqliteClient(): SqliteDatabase;
|
|
76
87
|
getPostgresClient(): PGClient;
|
|
77
88
|
afterAll(): Promise<void>;
|
|
@@ -81,10 +92,11 @@ export declare class TempDB {
|
|
|
81
92
|
create(...tables: CoreConcept[]): Promise<void>;
|
|
82
93
|
}
|
|
83
94
|
export declare function assoc_edge_config_table(): Table;
|
|
84
|
-
export declare function assoc_edge_table(name: string): Table;
|
|
95
|
+
export declare function assoc_edge_table(name: string, global?: boolean): Table;
|
|
85
96
|
interface sqliteSetupOptions {
|
|
86
97
|
disableDeleteAfterEachTest?: boolean;
|
|
87
98
|
}
|
|
88
|
-
export declare function setupSqlite(connString: string, tables: () => Table[], opts?: sqliteSetupOptions):
|
|
99
|
+
export declare function setupSqlite(connString: string, tables: () => Table[], opts?: sqliteSetupOptions): TempDB;
|
|
89
100
|
export declare function getSchemaTable(schema: BuilderSchema<Ent>, dialect: Dialect): Table;
|
|
101
|
+
export declare function getColumnFromField(fieldName: string, f: Field, dialect: Dialect): Column;
|
|
90
102
|
export {};
|
|
@@ -22,7 +22,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
22
22
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
23
23
|
};
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
exports.getSchemaTable = exports.setupSqlite = exports.assoc_edge_table = exports.assoc_edge_config_table = exports.TempDB = exports.enumType = exports.table = exports.boolList = exports.dateList = exports.timetzList = exports.timeList = exports.timestamptzList = exports.timestampList = exports.uuidList = exports.integerList = exports.textList = exports.jsonb = exports.json = exports.float = exports.integer = exports.bool = exports.date = exports.timetz = exports.time = exports.timestamptz = exports.timestamp = exports.enumCol = exports.text = exports.uuid = exports.uniqueIndex = exports.foreignKey = exports.primaryKey = void 0;
|
|
25
|
+
exports.getColumnFromField = exports.getSchemaTable = exports.setupSqlite = exports.assoc_edge_table = exports.assoc_edge_config_table = exports.TempDB = exports.enumType = exports.table = exports.boolList = exports.dateList = exports.timetzList = exports.timeList = exports.timestamptzList = exports.timestampList = exports.uuidList = exports.integerList = exports.textList = exports.jsonb = exports.json = exports.float = exports.integer = exports.bool = exports.date = exports.timetz = exports.time = exports.timestamptz = exports.timestamp = exports.enumCol = exports.text = exports.uuid = exports.uniqueIndex = exports.index = exports.foreignKey = exports.primaryKey = void 0;
|
|
26
26
|
const pg_1 = require("pg");
|
|
27
27
|
const db_1 = __importStar(require("../../core/db"));
|
|
28
28
|
// this should only be used in tests so we expect to be able to import without shenanigans
|
|
@@ -32,6 +32,7 @@ const fs = __importStar(require("fs"));
|
|
|
32
32
|
const schema_1 = require("../../schema");
|
|
33
33
|
const snake_case_1 = require("snake-case");
|
|
34
34
|
const builder_1 = require("../builder");
|
|
35
|
+
const test_edge_global_schema_1 = require("../test_edge_global_schema");
|
|
35
36
|
function primaryKey(name, cols) {
|
|
36
37
|
return {
|
|
37
38
|
name: name,
|
|
@@ -50,6 +51,16 @@ function foreignKey(name, cols, fkey) {
|
|
|
50
51
|
};
|
|
51
52
|
}
|
|
52
53
|
exports.foreignKey = foreignKey;
|
|
54
|
+
function index(tableName, cols, opts) {
|
|
55
|
+
const name = `${tableName}_${cols.join("_")}_idx`;
|
|
56
|
+
return {
|
|
57
|
+
name,
|
|
58
|
+
generate() {
|
|
59
|
+
return `CREATE INDEX ${name} ON ${tableName} USING ${opts?.type || "btree"} (${cols.join(",")});`;
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
exports.index = index;
|
|
53
64
|
function uniqueIndex(name) {
|
|
54
65
|
return {
|
|
55
66
|
name: "",
|
|
@@ -248,9 +259,24 @@ exports.boolList = boolList;
|
|
|
248
259
|
function table(name, ...items) {
|
|
249
260
|
let cols = [];
|
|
250
261
|
let constraints = [];
|
|
262
|
+
let indexes = [];
|
|
251
263
|
for (const item of items) {
|
|
252
264
|
if (item.datatype !== undefined) {
|
|
253
265
|
const col = item;
|
|
266
|
+
if (col.index) {
|
|
267
|
+
let opts = {
|
|
268
|
+
type: "btree",
|
|
269
|
+
};
|
|
270
|
+
if (col.index === true) {
|
|
271
|
+
opts = {
|
|
272
|
+
type: "btree",
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
opts = col.index;
|
|
277
|
+
}
|
|
278
|
+
indexes.push(index(name, [col.name], opts));
|
|
279
|
+
}
|
|
254
280
|
// add it as a constraint
|
|
255
281
|
if (col.foreignKey) {
|
|
256
282
|
constraints.push(foreignKey(`${name}_${col.name}_fkey`, [col.name], {
|
|
@@ -288,6 +314,9 @@ function table(name, ...items) {
|
|
|
288
314
|
constraints.forEach((constraint) => schemaStr.push(constraint.generate()));
|
|
289
315
|
return `CREATE TABLE IF NOT EXISTS ${name} (\n ${schemaStr})`;
|
|
290
316
|
},
|
|
317
|
+
postCreate() {
|
|
318
|
+
return indexes.map((index) => index.generate());
|
|
319
|
+
},
|
|
291
320
|
drop() {
|
|
292
321
|
return `DROP TABLE IF EXISTS ${name}`;
|
|
293
322
|
},
|
|
@@ -376,11 +405,24 @@ class TempDB {
|
|
|
376
405
|
this.sqlite = (0, better_sqlite3_1.default)(filePath);
|
|
377
406
|
}
|
|
378
407
|
for (const [_, table] of this.tables) {
|
|
379
|
-
|
|
380
|
-
|
|
408
|
+
await this.createImpl(table);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
async createImpl(table) {
|
|
412
|
+
if (this.dialect == db_1.Dialect.Postgres) {
|
|
413
|
+
await this.dbClient.query(table.create());
|
|
414
|
+
if (table.postCreate) {
|
|
415
|
+
for (const q of table.postCreate()) {
|
|
416
|
+
await this.dbClient.query(q);
|
|
417
|
+
}
|
|
381
418
|
}
|
|
382
|
-
|
|
383
|
-
|
|
419
|
+
}
|
|
420
|
+
else {
|
|
421
|
+
this.sqlite.exec(table.create());
|
|
422
|
+
if (table.postCreate) {
|
|
423
|
+
for (const q of table.postCreate()) {
|
|
424
|
+
this.sqlite.exec(q);
|
|
425
|
+
}
|
|
384
426
|
}
|
|
385
427
|
}
|
|
386
428
|
}
|
|
@@ -431,12 +473,7 @@ class TempDB {
|
|
|
431
473
|
if (this.tables.has(table.name)) {
|
|
432
474
|
throw new Error(`table with name ${table.name} already exists`);
|
|
433
475
|
}
|
|
434
|
-
|
|
435
|
-
await this.dbClient.query(table.create());
|
|
436
|
-
}
|
|
437
|
-
else {
|
|
438
|
-
this.sqlite.exec(table.create());
|
|
439
|
-
}
|
|
476
|
+
await this.createImpl(table);
|
|
440
477
|
this.tables.set(table.name, table);
|
|
441
478
|
}
|
|
442
479
|
}
|
|
@@ -448,18 +485,26 @@ function assoc_edge_config_table() {
|
|
|
448
485
|
text("edge_type", { primaryKey: true }), text("edge_name"), bool("symmetric_edge", { default: "FALSE" }), text("inverse_edge_type", { nullable: true }), text("edge_table"), timestamptz("created_at"), timestamptz("updated_at"));
|
|
449
486
|
}
|
|
450
487
|
exports.assoc_edge_config_table = assoc_edge_config_table;
|
|
451
|
-
|
|
452
|
-
|
|
488
|
+
// if global flag is true, add any column from testEdgeGlobalSchema
|
|
489
|
+
// up to caller to set/clear that as needed
|
|
490
|
+
function assoc_edge_table(name, global) {
|
|
491
|
+
const t = table(name, uuid("id1"), text("id1_type"),
|
|
453
492
|
// same as in assoc_edge_config_table
|
|
454
493
|
text("edge_type"), uuid("id2"), text("id2_type"), timestamptz("time"), text("data", { nullable: true }), primaryKey(`${name}_pkey`, ["id1", "id2", "edge_type"]));
|
|
494
|
+
if (global) {
|
|
495
|
+
for (const k in test_edge_global_schema_1.testEdgeGlobalSchema.extraEdgeFields) {
|
|
496
|
+
const col = getColumnFromField(k, test_edge_global_schema_1.testEdgeGlobalSchema.extraEdgeFields[k], db_1.Dialect.Postgres);
|
|
497
|
+
t.columns.push(col);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
return t;
|
|
455
501
|
}
|
|
456
502
|
exports.assoc_edge_table = assoc_edge_table;
|
|
457
503
|
function setupSqlite(connString, tables, opts) {
|
|
458
|
-
let tdb;
|
|
504
|
+
let tdb = new TempDB(db_1.Dialect.SQLite, tables());
|
|
459
505
|
beforeAll(async () => {
|
|
460
506
|
process.env.DB_CONNECTION_STRING = connString;
|
|
461
507
|
(0, config_1.loadConfig)();
|
|
462
|
-
tdb = new TempDB(db_1.Dialect.SQLite, tables());
|
|
463
508
|
await tdb.beforeAll();
|
|
464
509
|
const conn = db_1.default.getInstance().getConnection();
|
|
465
510
|
expect(conn.db.memory).toBe(false);
|
|
@@ -483,6 +528,7 @@ function setupSqlite(connString, tables, opts) {
|
|
|
483
528
|
await tdb.afterAll();
|
|
484
529
|
fs.rmSync(tdb.getSqliteClient().name);
|
|
485
530
|
});
|
|
531
|
+
return tdb;
|
|
486
532
|
}
|
|
487
533
|
exports.setupSqlite = setupSqlite;
|
|
488
534
|
function getSchemaTable(schema, dialect) {
|
|
@@ -549,6 +595,7 @@ function getColumnFromField(fieldName, f, dialect) {
|
|
|
549
595
|
return getColumn(fieldName, f, fn);
|
|
550
596
|
}
|
|
551
597
|
}
|
|
598
|
+
exports.getColumnFromField = getColumnFromField;
|
|
552
599
|
function getColumn(fieldName, f, col) {
|
|
553
600
|
return col(storageKey(fieldName, f), buildOpts(f));
|
|
554
601
|
}
|
|
@@ -16,7 +16,7 @@ export declare class FakeContact implements Ent {
|
|
|
16
16
|
getPrivacyPolicy(): PrivacyPolicy<this>;
|
|
17
17
|
constructor(viewer: Viewer, data: Data);
|
|
18
18
|
static getFields(): string[];
|
|
19
|
-
static getTestTable(): import("../db/
|
|
19
|
+
static getTestTable(): import("../db/temp_db").Table;
|
|
20
20
|
static loaderOptions(): LoadEntOptions<FakeContact>;
|
|
21
21
|
static load(v: Viewer, id: ID): Promise<FakeContact | null>;
|
|
22
22
|
static loadX(v: Viewer, id: ID): Promise<FakeContact>;
|
|
@@ -6,7 +6,7 @@ const privacy_1 = require("../../core/privacy");
|
|
|
6
6
|
const builder_1 = require("../builder");
|
|
7
7
|
const schema_1 = require("../../schema");
|
|
8
8
|
const const_1 = require("./const");
|
|
9
|
-
const
|
|
9
|
+
const temp_db_1 = require("../db/temp_db");
|
|
10
10
|
const loaders_1 = require("../../core/loaders");
|
|
11
11
|
const convert_1 = require("../../core/convert");
|
|
12
12
|
const action_1 = require("../../action");
|
|
@@ -40,7 +40,7 @@ class FakeContact {
|
|
|
40
40
|
];
|
|
41
41
|
}
|
|
42
42
|
static getTestTable() {
|
|
43
|
-
return (0,
|
|
43
|
+
return (0, temp_db_1.table)("fake_contacts", (0, temp_db_1.uuid)("id", { primaryKey: true }), (0, temp_db_1.timestamptz)("created_at"), (0, temp_db_1.timestamptz)("updated_at"), (0, temp_db_1.text)("first_name"), (0, temp_db_1.text)("last_name"), (0, temp_db_1.text)("email_address"), (0, temp_db_1.uuid)("user_id"));
|
|
44
44
|
}
|
|
45
45
|
static loaderOptions() {
|
|
46
46
|
return {
|
|
@@ -17,7 +17,7 @@ export declare class FakeEvent implements Ent {
|
|
|
17
17
|
getPrivacyPolicy(): PrivacyPolicy<this>;
|
|
18
18
|
constructor(viewer: Viewer, data: Data);
|
|
19
19
|
private static getFields;
|
|
20
|
-
static getTestTable(): import("../db/
|
|
20
|
+
static getTestTable(): import("../db/temp_db").Table;
|
|
21
21
|
static loaderOptions(): LoadEntOptions<FakeEvent>;
|
|
22
22
|
static load(v: Viewer, id: ID): Promise<FakeEvent | null>;
|
|
23
23
|
static loadX(v: Viewer, id: ID): Promise<FakeEvent>;
|
|
@@ -6,7 +6,7 @@ const privacy_1 = require("../../core/privacy");
|
|
|
6
6
|
const builder_1 = require("../builder");
|
|
7
7
|
const schema_1 = require("../../schema");
|
|
8
8
|
const const_1 = require("./const");
|
|
9
|
-
const
|
|
9
|
+
const temp_db_1 = require("../db/temp_db");
|
|
10
10
|
const loaders_1 = require("../../core/loaders");
|
|
11
11
|
const convert_1 = require("../../core/convert");
|
|
12
12
|
const action_1 = require("../../action");
|
|
@@ -42,9 +42,9 @@ class FakeEvent {
|
|
|
42
42
|
];
|
|
43
43
|
}
|
|
44
44
|
static getTestTable() {
|
|
45
|
-
return (0,
|
|
45
|
+
return (0, temp_db_1.table)("fake_events", (0, temp_db_1.uuid)("id", { primaryKey: true }), (0, temp_db_1.timestamptz)("created_at"), (0, temp_db_1.timestamptz)("updated_at"),
|
|
46
46
|
// TODO index:true
|
|
47
|
-
(0,
|
|
47
|
+
(0, temp_db_1.timestamptz)("start_time"), (0, temp_db_1.timestamptz)("end_time", { nullable: true }), (0, temp_db_1.text)("location"), (0, temp_db_1.text)("title"), (0, temp_db_1.text)("description", { nullable: true }), (0, temp_db_1.uuid)("user_id"));
|
|
48
48
|
}
|
|
49
49
|
static loaderOptions() {
|
|
50
50
|
return {
|
|
@@ -26,7 +26,7 @@ export declare class FakeUser implements Ent {
|
|
|
26
26
|
getPrivacyPolicy(): PrivacyPolicy<this>;
|
|
27
27
|
constructor(viewer: Viewer, data: Data);
|
|
28
28
|
static getFields(): string[];
|
|
29
|
-
static getTestTable(): import("../db/
|
|
29
|
+
static getTestTable(): import("../db/temp_db").Table;
|
|
30
30
|
static loaderOptions(): LoadEntOptions<FakeUser>;
|
|
31
31
|
static load(v: Viewer, id: ID): Promise<FakeUser | null>;
|
|
32
32
|
static loadX(v: Viewer, id: ID): Promise<FakeUser>;
|
|
@@ -8,7 +8,7 @@ const schema_1 = require("../../schema");
|
|
|
8
8
|
const internal_1 = require("./internal");
|
|
9
9
|
const const_1 = require("./const");
|
|
10
10
|
const viewer_1 = require("../../core/viewer");
|
|
11
|
-
const
|
|
11
|
+
const temp_db_1 = require("../db/temp_db");
|
|
12
12
|
const loaders_1 = require("../../core/loaders");
|
|
13
13
|
const convert_1 = require("../../core/convert");
|
|
14
14
|
const action_1 = require("../../action");
|
|
@@ -74,7 +74,7 @@ class FakeUser {
|
|
|
74
74
|
];
|
|
75
75
|
}
|
|
76
76
|
static getTestTable() {
|
|
77
|
-
return (0,
|
|
77
|
+
return (0, temp_db_1.table)("fake_users", (0, temp_db_1.uuid)("id", { primaryKey: true }), (0, temp_db_1.timestamptz)("created_at"), (0, temp_db_1.timestamptz)("updated_at"), (0, temp_db_1.text)("first_name"), (0, temp_db_1.text)("last_name"), (0, temp_db_1.text)("email_address"), (0, temp_db_1.text)("phone_number"), (0, temp_db_1.text)("password"));
|
|
78
78
|
}
|
|
79
79
|
static loaderOptions() {
|
|
80
80
|
return {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Data, Ent } from "../../core/base";
|
|
2
2
|
import { AssocEdge } from "../../core/ent";
|
|
3
|
-
import { TempDB } from "../db/
|
|
3
|
+
import { TempDB } from "../db/temp_db";
|
|
4
4
|
import { FakeUser, UserCreateInput, ContactCreateInput, FakeContact } from ".";
|
|
5
5
|
import { EventCreateInput, FakeEvent } from "./fake_event";
|
|
6
6
|
import { BuilderSchema } from "../builder";
|
|
@@ -20,7 +20,7 @@ export declare function createEdges(): Promise<void>;
|
|
|
20
20
|
export declare function edgeTableNames(): string[];
|
|
21
21
|
export declare function createTestEvent(user: FakeUser, input?: Partial<EventCreateInput>): Promise<FakeEvent>;
|
|
22
22
|
export declare function setupTempDB(): Promise<TempDB>;
|
|
23
|
-
export declare function tempDBTables(): import("../db/
|
|
23
|
+
export declare function tempDBTables(global?: boolean): import("../db/temp_db").Table[];
|
|
24
24
|
interface options {
|
|
25
25
|
howMany: number;
|
|
26
26
|
interval: number;
|
|
@@ -6,7 +6,7 @@ const viewer_1 = require("../../core/viewer");
|
|
|
6
6
|
const ent_1 = require("../../core/ent");
|
|
7
7
|
const snake_case_1 = require("snake-case");
|
|
8
8
|
const write_1 = require("../write");
|
|
9
|
-
const
|
|
9
|
+
const temp_db_1 = require("../db/temp_db");
|
|
10
10
|
const _1 = require(".");
|
|
11
11
|
const fake_event_1 = require("./fake_event");
|
|
12
12
|
const const_1 = require("./const");
|
|
@@ -209,21 +209,21 @@ async function createTestEvent(user, input) {
|
|
|
209
209
|
}
|
|
210
210
|
exports.createTestEvent = createTestEvent;
|
|
211
211
|
async function setupTempDB() {
|
|
212
|
-
const tdb = new
|
|
212
|
+
const tdb = new temp_db_1.TempDB(tempDBTables());
|
|
213
213
|
await tdb.beforeAll();
|
|
214
214
|
// create once
|
|
215
215
|
await createEdges();
|
|
216
216
|
return tdb;
|
|
217
217
|
}
|
|
218
218
|
exports.setupTempDB = setupTempDB;
|
|
219
|
-
function tempDBTables() {
|
|
219
|
+
function tempDBTables(global = false) {
|
|
220
220
|
const tables = [
|
|
221
221
|
_1.FakeUser.getTestTable(),
|
|
222
222
|
_1.FakeContact.getTestTable(),
|
|
223
223
|
fake_event_1.FakeEvent.getTestTable(),
|
|
224
|
-
(0,
|
|
224
|
+
(0, temp_db_1.assoc_edge_config_table)(),
|
|
225
225
|
];
|
|
226
|
-
edgeTableNames().forEach((tableName) => tables.push((0,
|
|
226
|
+
edgeTableNames().forEach((tableName) => tables.push((0, temp_db_1.assoc_edge_table)(tableName, global)));
|
|
227
227
|
return tables;
|
|
228
228
|
}
|
|
229
229
|
exports.tempDBTables = tempDBTables;
|
package/testutils/parse_sql.js
CHANGED
|
@@ -307,6 +307,10 @@ function getOp(where, values) {
|
|
|
307
307
|
return new AndOp([getOp(where.left, values), getOp(where.right, values)]);
|
|
308
308
|
case "OR":
|
|
309
309
|
return new OrOp([getOp(where.left, values), getOp(where.right, values)]);
|
|
310
|
+
case "IS":
|
|
311
|
+
if (where.right?.value === null) {
|
|
312
|
+
return new EqOp(getColumnFromRef(where.left), null);
|
|
313
|
+
}
|
|
310
314
|
default:
|
|
311
315
|
console.log(where);
|
|
312
316
|
throw new Error(`unsupported op ${where.operator}`);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { EdgeUpdateOperation, TransformedEdgeUpdateOperation } from "../schema";
|
|
2
|
+
import * as clause from "../core/clause";
|
|
3
|
+
import { AssocEdge } from "../core/ent";
|
|
4
|
+
import { Data } from "../core/base";
|
|
5
|
+
export declare class EdgeWithDeletedAt extends AssocEdge {
|
|
6
|
+
deletedAt: Date | null;
|
|
7
|
+
constructor(data: Data);
|
|
8
|
+
}
|
|
9
|
+
export declare const testEdgeGlobalSchema: {
|
|
10
|
+
extraEdgeFields: {
|
|
11
|
+
deletedAt: import("../schema").TimestampField;
|
|
12
|
+
};
|
|
13
|
+
transformEdgeRead(): clause.Clause;
|
|
14
|
+
transformEdgeWrite(stmt: EdgeUpdateOperation): TransformedEdgeUpdateOperation | null;
|
|
15
|
+
};
|