@snowtop/ent 0.1.0-alpha14 → 0.1.0-alpha141
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/action.d.ts +27 -16
- package/action/action.js +22 -7
- package/action/executor.d.ts +16 -3
- package/action/executor.js +88 -21
- package/action/experimental_action.d.ts +25 -16
- package/action/experimental_action.js +35 -9
- package/action/index.d.ts +3 -1
- package/action/index.js +7 -1
- package/action/operations.d.ts +125 -0
- package/action/operations.js +684 -0
- package/action/orchestrator.d.ts +34 -11
- package/action/orchestrator.js +355 -92
- package/action/relative_value.d.ts +47 -0
- package/action/relative_value.js +125 -0
- package/action/transaction.d.ts +10 -0
- package/action/transaction.js +23 -0
- package/auth/auth.d.ts +1 -1
- package/core/base.d.ts +51 -21
- package/core/base.js +7 -1
- package/core/clause.d.ts +85 -40
- package/core/clause.js +375 -64
- package/core/config.d.ts +12 -1
- package/core/config.js +7 -1
- package/core/const.d.ts +3 -0
- package/core/const.js +6 -0
- package/core/context.d.ts +4 -2
- package/core/context.js +20 -2
- package/core/convert.d.ts +1 -1
- package/core/date.js +1 -5
- package/core/db.d.ts +12 -8
- package/core/db.js +18 -8
- package/core/ent.d.ts +66 -93
- package/core/ent.js +517 -577
- package/core/global_schema.d.ts +7 -0
- package/core/global_schema.js +51 -0
- package/core/loaders/assoc_count_loader.d.ts +1 -0
- package/core/loaders/assoc_count_loader.js +10 -2
- package/core/loaders/assoc_edge_loader.d.ts +1 -1
- package/core/loaders/assoc_edge_loader.js +8 -11
- package/core/loaders/index.d.ts +1 -1
- package/core/loaders/index.js +1 -3
- package/core/loaders/index_loader.d.ts +3 -3
- package/core/loaders/loader.d.ts +2 -2
- package/core/loaders/loader.js +5 -5
- package/core/loaders/object_loader.d.ts +30 -9
- package/core/loaders/object_loader.js +225 -78
- package/core/loaders/query_loader.d.ts +6 -12
- package/core/loaders/query_loader.js +52 -11
- package/core/loaders/raw_count_loader.js +5 -1
- package/core/logger.d.ts +1 -1
- package/core/logger.js +1 -0
- package/core/privacy.d.ts +7 -6
- package/core/privacy.js +21 -25
- package/core/query/assoc_query.d.ts +3 -2
- package/core/query/assoc_query.js +9 -1
- package/core/query/custom_clause_query.d.ts +27 -0
- package/core/query/custom_clause_query.js +84 -0
- package/core/query/custom_query.d.ts +17 -2
- package/core/query/custom_query.js +87 -12
- package/core/query/index.d.ts +1 -0
- package/core/query/index.js +3 -1
- package/core/query/query.d.ts +7 -3
- package/core/query/query.js +101 -53
- package/core/query/shared_assoc_test.d.ts +2 -1
- package/core/query/shared_assoc_test.js +35 -45
- package/core/query/shared_test.d.ts +8 -1
- package/core/query/shared_test.js +470 -236
- package/core/viewer.js +1 -1
- package/graphql/graphql.d.ts +52 -19
- package/graphql/graphql.js +174 -136
- package/graphql/graphql_field_helpers.d.ts +7 -1
- package/graphql/graphql_field_helpers.js +21 -1
- package/graphql/index.d.ts +2 -2
- package/graphql/index.js +3 -5
- package/graphql/query/connection_type.d.ts +9 -9
- package/graphql/query/shared_assoc_test.js +1 -1
- package/graphql/query/shared_edge_connection.js +1 -19
- package/graphql/scalars/orderby_direction.d.ts +2 -0
- package/graphql/scalars/orderby_direction.js +15 -0
- package/imports/dataz/example1/_auth.js +128 -47
- package/imports/dataz/example1/_viewer.js +87 -39
- package/imports/index.d.ts +6 -1
- package/imports/index.js +19 -4
- package/index.d.ts +14 -5
- package/index.js +26 -10
- package/package.json +18 -17
- package/parse_schema/parse.d.ts +31 -9
- package/parse_schema/parse.js +156 -13
- package/schema/base_schema.d.ts +9 -3
- package/schema/base_schema.js +12 -0
- package/schema/field.d.ts +78 -21
- package/schema/field.js +231 -71
- package/schema/index.d.ts +2 -2
- package/schema/index.js +5 -1
- package/schema/json_field.d.ts +16 -4
- package/schema/json_field.js +32 -2
- package/schema/schema.d.ts +96 -19
- package/schema/schema.js +11 -13
- package/schema/struct_field.d.ts +15 -3
- package/schema/struct_field.js +117 -22
- package/schema/union_field.d.ts +1 -1
- package/scripts/custom_compiler.js +10 -6
- package/scripts/custom_graphql.js +142 -31
- package/scripts/migrate_v0.1.js +36 -0
- package/scripts/move_types.js +120 -0
- package/scripts/read_schema.js +20 -5
- package/testutils/action/complex_schemas.d.ts +69 -0
- package/testutils/action/complex_schemas.js +405 -0
- package/testutils/builder.d.ts +39 -43
- package/testutils/builder.js +75 -49
- package/testutils/db/fixture.d.ts +10 -0
- package/testutils/db/fixture.js +26 -0
- package/testutils/db/{test_db.d.ts → temp_db.d.ts} +25 -8
- package/testutils/db/{test_db.js → temp_db.js} +224 -47
- package/testutils/db/value.d.ts +7 -0
- package/testutils/db/value.js +251 -0
- package/testutils/db_mock.d.ts +16 -4
- package/testutils/db_mock.js +52 -7
- package/testutils/db_time_zone.d.ts +4 -0
- package/testutils/db_time_zone.js +41 -0
- package/testutils/ent-graphql-tests/index.d.ts +7 -1
- package/testutils/ent-graphql-tests/index.js +52 -23
- package/testutils/fake_comms.js +1 -1
- package/testutils/fake_data/const.d.ts +2 -1
- package/testutils/fake_data/const.js +3 -0
- package/testutils/fake_data/fake_contact.d.ts +7 -3
- package/testutils/fake_data/fake_contact.js +13 -7
- package/testutils/fake_data/fake_event.d.ts +4 -1
- package/testutils/fake_data/fake_event.js +7 -6
- package/testutils/fake_data/fake_tag.d.ts +36 -0
- package/testutils/fake_data/fake_tag.js +89 -0
- package/testutils/fake_data/fake_user.d.ts +8 -5
- package/testutils/fake_data/fake_user.js +16 -15
- package/testutils/fake_data/index.js +5 -1
- package/testutils/fake_data/internal.d.ts +2 -0
- package/testutils/fake_data/internal.js +7 -1
- package/testutils/fake_data/tag_query.d.ts +13 -0
- package/testutils/fake_data/tag_query.js +43 -0
- package/testutils/fake_data/test_helpers.d.ts +11 -4
- package/testutils/fake_data/test_helpers.js +28 -12
- package/testutils/fake_data/user_query.d.ts +11 -4
- package/testutils/fake_data/user_query.js +54 -22
- package/testutils/fake_log.js +1 -1
- package/testutils/parse_sql.d.ts +6 -0
- package/testutils/parse_sql.js +16 -2
- package/testutils/test_edge_global_schema.d.ts +15 -0
- package/testutils/test_edge_global_schema.js +62 -0
- package/testutils/write.d.ts +2 -2
- package/testutils/write.js +33 -7
- package/tsc/ast.d.ts +25 -2
- package/tsc/ast.js +141 -17
- package/tsc/compilerOptions.js +5 -1
- package/tsc/move_generated.d.ts +1 -0
- package/tsc/move_generated.js +164 -0
- package/tsc/transform.d.ts +22 -0
- package/tsc/transform.js +181 -0
- package/tsc/transform_action.d.ts +22 -0
- package/tsc/transform_action.js +183 -0
- package/tsc/transform_ent.d.ts +17 -0
- package/tsc/transform_ent.js +60 -0
- package/tsc/transform_schema.d.ts +27 -0
- package/{scripts → tsc}/transform_schema.js +146 -117
- package/graphql/enums.d.ts +0 -3
- package/graphql/enums.js +0 -25
- package/scripts/move_generated.js +0 -142
- package/scripts/transform_code.js +0 -113
- package/scripts/transform_schema.d.ts +0 -1
- /package/scripts/{move_generated.d.ts → migrate_v0.1.d.ts} +0 -0
- /package/scripts/{transform_code.d.ts → move_types.d.ts} +0 -0
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
3
|
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
5
9
|
}) : (function(o, m, k, k2) {
|
|
6
10
|
if (k2 === undefined) k2 = k;
|
|
7
11
|
o[k2] = m[k];
|
|
@@ -22,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
22
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
23
27
|
};
|
|
24
28
|
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.
|
|
29
|
+
exports.getColumnFromField = exports.getSchemaTable = exports.doSQLiteTestFromSchemas = exports.setupPostgres = 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.index = exports.check = exports.foreignKey = exports.primaryKey = void 0;
|
|
26
30
|
const pg_1 = require("pg");
|
|
27
31
|
const db_1 = __importStar(require("../../core/db"));
|
|
28
32
|
// this should only be used in tests so we expect to be able to import without shenanigans
|
|
@@ -32,6 +36,7 @@ const fs = __importStar(require("fs"));
|
|
|
32
36
|
const schema_1 = require("../../schema");
|
|
33
37
|
const snake_case_1 = require("snake-case");
|
|
34
38
|
const builder_1 = require("../builder");
|
|
39
|
+
const test_edge_global_schema_1 = require("../test_edge_global_schema");
|
|
35
40
|
function primaryKey(name, cols) {
|
|
36
41
|
return {
|
|
37
42
|
name: name,
|
|
@@ -50,15 +55,49 @@ function foreignKey(name, cols, fkey) {
|
|
|
50
55
|
};
|
|
51
56
|
}
|
|
52
57
|
exports.foreignKey = foreignKey;
|
|
53
|
-
function
|
|
58
|
+
function check(name, condition) {
|
|
59
|
+
return {
|
|
60
|
+
name,
|
|
61
|
+
generate() {
|
|
62
|
+
return `CONSTRAINT ${name} CHECK(${condition})`;
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
exports.check = check;
|
|
67
|
+
function unique(name, cols, tableName) {
|
|
68
|
+
return {
|
|
69
|
+
name,
|
|
70
|
+
generate() {
|
|
71
|
+
if (db_1.Dialect.SQLite === db_1.default.getDialect()) {
|
|
72
|
+
return `UNIQUE (${cols.join(",")})`;
|
|
73
|
+
}
|
|
74
|
+
return `ALTER TABLE ${tableName} ADD CONSTRAINT ${name} UNIQUE (${cols.join(", ")});`;
|
|
75
|
+
},
|
|
76
|
+
postCreate() {
|
|
77
|
+
return db_1.Dialect.Postgres === db_1.default.getDialect();
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function isPostCreateIndex(s) {
|
|
82
|
+
return (s.postCreate !== undefined &&
|
|
83
|
+
s.postCreate());
|
|
84
|
+
}
|
|
85
|
+
function index(tableName, cols, opts) {
|
|
86
|
+
const name = `${tableName}_${cols.join("_")}_idx`;
|
|
54
87
|
return {
|
|
55
|
-
name
|
|
88
|
+
name,
|
|
56
89
|
generate() {
|
|
57
|
-
|
|
90
|
+
if (opts?.unique && db_1.Dialect.SQLite === db_1.default.getDialect()) {
|
|
91
|
+
return `UNIQUE (${cols.join(",")})`;
|
|
92
|
+
}
|
|
93
|
+
return `CREATE ${opts?.unique ? "UNIQUE " : ""}INDEX ${name} ON ${tableName} USING ${opts?.type || "btree"} (${cols.join(",")});`;
|
|
94
|
+
},
|
|
95
|
+
postCreate() {
|
|
96
|
+
return db_1.Dialect.Postgres === db_1.default.getDialect() && !!opts?.unique;
|
|
58
97
|
},
|
|
59
98
|
};
|
|
60
99
|
}
|
|
61
|
-
exports.
|
|
100
|
+
exports.index = index;
|
|
62
101
|
function uuid(name, opts) {
|
|
63
102
|
return {
|
|
64
103
|
name,
|
|
@@ -248,9 +287,24 @@ exports.boolList = boolList;
|
|
|
248
287
|
function table(name, ...items) {
|
|
249
288
|
let cols = [];
|
|
250
289
|
let constraints = [];
|
|
290
|
+
let indexes = [];
|
|
251
291
|
for (const item of items) {
|
|
252
292
|
if (item.datatype !== undefined) {
|
|
253
293
|
const col = item;
|
|
294
|
+
if (col.index) {
|
|
295
|
+
let opts = {
|
|
296
|
+
type: "btree",
|
|
297
|
+
};
|
|
298
|
+
if (col.index === true) {
|
|
299
|
+
opts = {
|
|
300
|
+
type: "btree",
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
opts = col.index;
|
|
305
|
+
}
|
|
306
|
+
indexes.push(index(name, [col.name], opts));
|
|
307
|
+
}
|
|
254
308
|
// add it as a constraint
|
|
255
309
|
if (col.foreignKey) {
|
|
256
310
|
constraints.push(foreignKey(`${name}_${col.name}_fkey`, [col.name], {
|
|
@@ -261,7 +315,12 @@ function table(name, ...items) {
|
|
|
261
315
|
cols.push(item);
|
|
262
316
|
}
|
|
263
317
|
else if (item.generate !== undefined) {
|
|
264
|
-
|
|
318
|
+
if (isPostCreateIndex(item) && item.postCreate()) {
|
|
319
|
+
indexes.push(item);
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
constraints.push(item);
|
|
323
|
+
}
|
|
265
324
|
}
|
|
266
325
|
}
|
|
267
326
|
return {
|
|
@@ -278,7 +337,12 @@ function table(name, ...items) {
|
|
|
278
337
|
parts.push("PRIMARY KEY");
|
|
279
338
|
}
|
|
280
339
|
if (col.default !== undefined) {
|
|
281
|
-
|
|
340
|
+
if (db_1.Dialect.SQLite === db_1.default.getDialect()) {
|
|
341
|
+
parts.push(`DEFAULT "${col.default}"`);
|
|
342
|
+
}
|
|
343
|
+
else {
|
|
344
|
+
parts.push(`DEFAULT ${col.default}`);
|
|
345
|
+
}
|
|
282
346
|
}
|
|
283
347
|
if (col.unique) {
|
|
284
348
|
parts.push("UNIQUE");
|
|
@@ -288,6 +352,9 @@ function table(name, ...items) {
|
|
|
288
352
|
constraints.forEach((constraint) => schemaStr.push(constraint.generate()));
|
|
289
353
|
return `CREATE TABLE IF NOT EXISTS ${name} (\n ${schemaStr})`;
|
|
290
354
|
},
|
|
355
|
+
postCreate() {
|
|
356
|
+
return indexes.map((index) => index.generate());
|
|
357
|
+
},
|
|
291
358
|
drop() {
|
|
292
359
|
return `DROP TABLE IF EXISTS ${name}`;
|
|
293
360
|
},
|
|
@@ -311,29 +378,18 @@ function randomDB() {
|
|
|
311
378
|
// always ensure it starts with an alpha character
|
|
312
379
|
return "abcdefghijklmnopqrstuvwxyz"[Math.floor(Math.random() * 26)] + str;
|
|
313
380
|
}
|
|
314
|
-
function isDialect(dialect) {
|
|
315
|
-
return !Array.isArray(dialect);
|
|
316
|
-
}
|
|
317
381
|
class TempDB {
|
|
318
382
|
constructor(dialect, tables) {
|
|
319
383
|
this.tables = new Map();
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
this.dialect = dialect;
|
|
323
|
-
if (tables) {
|
|
324
|
-
tbles = tables;
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
else {
|
|
328
|
-
this.dialect = db_1.Dialect.Postgres;
|
|
329
|
-
tbles = dialect;
|
|
330
|
-
}
|
|
331
|
-
tbles.forEach((table) => this.tables.set(table.name, table));
|
|
384
|
+
this.dialect = dialect;
|
|
385
|
+
this.setTables = tables;
|
|
332
386
|
}
|
|
333
387
|
getDialect() {
|
|
334
388
|
return this.dialect;
|
|
335
389
|
}
|
|
336
|
-
|
|
390
|
+
// NB: this won't be set until after beforeAll() is called since it depends on
|
|
391
|
+
// dialect being correctly set
|
|
392
|
+
__getTables() {
|
|
337
393
|
return this.tables;
|
|
338
394
|
}
|
|
339
395
|
async beforeAll(setupConnString = true) {
|
|
@@ -349,12 +405,21 @@ class TempDB {
|
|
|
349
405
|
this.db = randomDB();
|
|
350
406
|
await this.client.query(`CREATE DATABASE ${this.db}`);
|
|
351
407
|
if (setupConnString) {
|
|
408
|
+
delete process.env.DB_CONNECTION_STRING;
|
|
409
|
+
let connStr = "";
|
|
352
410
|
if (user && password) {
|
|
353
|
-
|
|
411
|
+
connStr = `postgres://${user}:${password}@localhost:5432/${this.db}`;
|
|
354
412
|
}
|
|
355
413
|
else {
|
|
356
|
-
|
|
414
|
+
connStr = `postgres://localhost/${this.db}?`;
|
|
357
415
|
}
|
|
416
|
+
db_1.default.initDB({
|
|
417
|
+
connectionString: connStr,
|
|
418
|
+
cfg: {
|
|
419
|
+
max: 100,
|
|
420
|
+
idleTimeoutMillis: 100,
|
|
421
|
+
},
|
|
422
|
+
});
|
|
358
423
|
}
|
|
359
424
|
else {
|
|
360
425
|
// will probably be setup via loadConfig
|
|
@@ -375,12 +440,35 @@ class TempDB {
|
|
|
375
440
|
const filePath = process.env.DB_CONNECTION_STRING.substr(10);
|
|
376
441
|
this.sqlite = (0, better_sqlite3_1.default)(filePath);
|
|
377
442
|
}
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
443
|
+
if (this.setTables) {
|
|
444
|
+
let tables = [];
|
|
445
|
+
if (typeof this.setTables === "function") {
|
|
446
|
+
tables = this.setTables();
|
|
381
447
|
}
|
|
382
448
|
else {
|
|
383
|
-
this.
|
|
449
|
+
tables = this.setTables;
|
|
450
|
+
}
|
|
451
|
+
tables.forEach((table) => this.tables.set(table.name, table));
|
|
452
|
+
}
|
|
453
|
+
for (const [_, table] of this.tables) {
|
|
454
|
+
await this.createImpl(table);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
async createImpl(table) {
|
|
458
|
+
if (this.dialect == db_1.Dialect.Postgres) {
|
|
459
|
+
await this.dbClient.query(table.create());
|
|
460
|
+
if (table.postCreate) {
|
|
461
|
+
for (const q of table.postCreate()) {
|
|
462
|
+
await this.dbClient.query(q);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
else {
|
|
467
|
+
this.sqlite.exec(table.create());
|
|
468
|
+
if (table.postCreate) {
|
|
469
|
+
for (const q of table.postCreate()) {
|
|
470
|
+
this.sqlite.exec(q);
|
|
471
|
+
}
|
|
384
472
|
}
|
|
385
473
|
}
|
|
386
474
|
}
|
|
@@ -393,6 +481,9 @@ class TempDB {
|
|
|
393
481
|
async afterAll() {
|
|
394
482
|
if (this.dialect === db_1.Dialect.SQLite) {
|
|
395
483
|
this.sqlite.close();
|
|
484
|
+
if (!this.sqlite.memory) {
|
|
485
|
+
fs.rmSync(this.getSqliteClient().name);
|
|
486
|
+
}
|
|
396
487
|
return;
|
|
397
488
|
}
|
|
398
489
|
// end our connection to db
|
|
@@ -401,6 +492,7 @@ class TempDB {
|
|
|
401
492
|
await db_1.default.getInstance().endPool();
|
|
402
493
|
// drop db
|
|
403
494
|
await this.client.query(`DROP DATABASE ${this.db}`);
|
|
495
|
+
// console.log(this.db);
|
|
404
496
|
await this.client.end();
|
|
405
497
|
}
|
|
406
498
|
getDB() {
|
|
@@ -431,12 +523,7 @@ class TempDB {
|
|
|
431
523
|
if (this.tables.has(table.name)) {
|
|
432
524
|
throw new Error(`table with name ${table.name} already exists`);
|
|
433
525
|
}
|
|
434
|
-
|
|
435
|
-
await this.dbClient.query(table.create());
|
|
436
|
-
}
|
|
437
|
-
else {
|
|
438
|
-
this.sqlite.exec(table.create());
|
|
439
|
-
}
|
|
526
|
+
await this.createImpl(table);
|
|
440
527
|
this.tables.set(table.name, table);
|
|
441
528
|
}
|
|
442
529
|
}
|
|
@@ -448,18 +535,38 @@ function assoc_edge_config_table() {
|
|
|
448
535
|
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
536
|
}
|
|
450
537
|
exports.assoc_edge_config_table = assoc_edge_config_table;
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
538
|
+
// if global flag is true, add any column from testEdgeGlobalSchema
|
|
539
|
+
// up to caller to set/clear that as needed
|
|
540
|
+
function assoc_edge_table(name, global, unique_edge) {
|
|
541
|
+
const items = [
|
|
542
|
+
uuid("id1"),
|
|
543
|
+
text("id1_type"),
|
|
544
|
+
// same as in assoc_edge_config_table
|
|
545
|
+
text("edge_type"),
|
|
546
|
+
uuid("id2"),
|
|
547
|
+
text("id2_type"),
|
|
548
|
+
timestamptz("time"),
|
|
549
|
+
text("data", { nullable: true }),
|
|
550
|
+
primaryKey(`${name}_pkey`, ["id1", "id2", "edge_type"]),
|
|
551
|
+
];
|
|
552
|
+
if (unique_edge) {
|
|
553
|
+
items.push(unique(`${name}_unique_id1_edge_type`, ["id1", "edge_type"], name));
|
|
554
|
+
}
|
|
555
|
+
const t = table(name, ...items);
|
|
556
|
+
if (global) {
|
|
557
|
+
for (const k in test_edge_global_schema_1.testEdgeGlobalSchema.extraEdgeFields) {
|
|
558
|
+
const col = getColumnFromField(k, test_edge_global_schema_1.testEdgeGlobalSchema.extraEdgeFields[k], db_1.Dialect.Postgres);
|
|
559
|
+
t.columns.push(col);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
return t;
|
|
455
563
|
}
|
|
456
564
|
exports.assoc_edge_table = assoc_edge_table;
|
|
457
565
|
function setupSqlite(connString, tables, opts) {
|
|
458
|
-
let tdb;
|
|
566
|
+
let tdb = new TempDB(db_1.Dialect.SQLite, tables);
|
|
459
567
|
beforeAll(async () => {
|
|
460
568
|
process.env.DB_CONNECTION_STRING = connString;
|
|
461
569
|
(0, config_1.loadConfig)();
|
|
462
|
-
tdb = new TempDB(db_1.Dialect.SQLite, tables());
|
|
463
570
|
await tdb.beforeAll();
|
|
464
571
|
const conn = db_1.default.getInstance().getConnection();
|
|
465
572
|
expect(conn.db.memory).toBe(false);
|
|
@@ -467,7 +574,7 @@ function setupSqlite(connString, tables, opts) {
|
|
|
467
574
|
if (!opts?.disableDeleteAfterEachTest) {
|
|
468
575
|
afterEach(async () => {
|
|
469
576
|
const client = await db_1.default.getInstance().getNewClient();
|
|
470
|
-
for (const [key, _] of tdb.
|
|
577
|
+
for (const [key, _] of tdb.__getTables()) {
|
|
471
578
|
const query = `delete from ${key}`;
|
|
472
579
|
if (isSyncClient(client))
|
|
473
580
|
if (client.execSync) {
|
|
@@ -481,17 +588,83 @@ function setupSqlite(connString, tables, opts) {
|
|
|
481
588
|
}
|
|
482
589
|
afterAll(async () => {
|
|
483
590
|
await tdb.afterAll();
|
|
484
|
-
|
|
591
|
+
delete process.env.DB_CONNECTION_STRING;
|
|
485
592
|
});
|
|
593
|
+
return tdb;
|
|
486
594
|
}
|
|
487
595
|
exports.setupSqlite = setupSqlite;
|
|
596
|
+
function setupPostgres(tables, opts) {
|
|
597
|
+
let tdb;
|
|
598
|
+
beforeAll(async () => {
|
|
599
|
+
tdb = new TempDB(db_1.Dialect.Postgres, tables());
|
|
600
|
+
await tdb.beforeAll();
|
|
601
|
+
});
|
|
602
|
+
// TODO need to fix this implementation...
|
|
603
|
+
if (!opts?.disableDeleteAfterEachTest) {
|
|
604
|
+
afterEach(async () => {
|
|
605
|
+
const client = await db_1.default.getInstance().getNewClient();
|
|
606
|
+
for (const [key, _] of tdb.__getTables()) {
|
|
607
|
+
const query = `delete from ${key}`;
|
|
608
|
+
await client.exec(query);
|
|
609
|
+
}
|
|
610
|
+
client.release();
|
|
611
|
+
});
|
|
612
|
+
}
|
|
613
|
+
afterAll(async () => {
|
|
614
|
+
await tdb.afterAll();
|
|
615
|
+
});
|
|
616
|
+
}
|
|
617
|
+
exports.setupPostgres = setupPostgres;
|
|
618
|
+
async function doSQLiteTestFromSchemas(schemas, doTest, db) {
|
|
619
|
+
const connString = `sqlite:///${db || randomDB()}.db`;
|
|
620
|
+
const tables = schemas.map((schema) => getSchemaTable(schema, db_1.Dialect.SQLite));
|
|
621
|
+
let tdb = new TempDB(db_1.Dialect.SQLite, tables);
|
|
622
|
+
process.env.DB_CONNECTION_STRING = connString;
|
|
623
|
+
(0, config_1.loadConfig)();
|
|
624
|
+
await tdb.beforeAll();
|
|
625
|
+
await doTest();
|
|
626
|
+
await tdb.afterAll();
|
|
627
|
+
delete process.env.DB_CONNECTION_STRING;
|
|
628
|
+
return tdb;
|
|
629
|
+
}
|
|
630
|
+
exports.doSQLiteTestFromSchemas = doSQLiteTestFromSchemas;
|
|
488
631
|
function getSchemaTable(schema, dialect) {
|
|
489
632
|
const fields = (0, schema_1.getFields)(schema);
|
|
490
|
-
const
|
|
633
|
+
const items = [];
|
|
491
634
|
for (const [fieldName, field] of fields) {
|
|
492
|
-
|
|
635
|
+
items.push(getColumnFromField(fieldName, field, dialect));
|
|
493
636
|
}
|
|
494
|
-
|
|
637
|
+
const tableName = (0, builder_1.getTableName)(schema);
|
|
638
|
+
if (schema.constraints) {
|
|
639
|
+
for (const constraint of schema.constraints) {
|
|
640
|
+
switch (constraint.type) {
|
|
641
|
+
case schema_1.ConstraintType.PrimaryKey:
|
|
642
|
+
items.push(primaryKey(constraint.name, constraint.columns));
|
|
643
|
+
break;
|
|
644
|
+
case schema_1.ConstraintType.ForeignKey:
|
|
645
|
+
if (!constraint.fkey) {
|
|
646
|
+
throw new Error(`need 'fkey' field for foreign key constraint`);
|
|
647
|
+
}
|
|
648
|
+
items.push(foreignKey(constraint.name, constraint.columns, {
|
|
649
|
+
table: constraint.fkey.tableName,
|
|
650
|
+
cols: constraint.fkey.columns,
|
|
651
|
+
}));
|
|
652
|
+
break;
|
|
653
|
+
case schema_1.ConstraintType.Check:
|
|
654
|
+
if (!constraint.condition) {
|
|
655
|
+
throw new Error(`need 'condition' field for check constraint`);
|
|
656
|
+
}
|
|
657
|
+
items.push(check(constraint.name, constraint.condition));
|
|
658
|
+
break;
|
|
659
|
+
case schema_1.ConstraintType.Unique:
|
|
660
|
+
items.push(unique(constraint.name, constraint.columns, tableName));
|
|
661
|
+
break;
|
|
662
|
+
default:
|
|
663
|
+
throw new Error(`unknown constraint type ${constraint.type}`);
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
return table(tableName, ...items);
|
|
495
668
|
}
|
|
496
669
|
exports.getSchemaTable = getSchemaTable;
|
|
497
670
|
function getColumnForDbType(t, dialect) {
|
|
@@ -549,6 +722,7 @@ function getColumnFromField(fieldName, f, dialect) {
|
|
|
549
722
|
return getColumn(fieldName, f, fn);
|
|
550
723
|
}
|
|
551
724
|
}
|
|
725
|
+
exports.getColumnFromField = getColumnFromField;
|
|
552
726
|
function getColumn(fieldName, f, col) {
|
|
553
727
|
return col(storageKey(fieldName, f), buildOpts(f));
|
|
554
728
|
}
|
|
@@ -567,6 +741,9 @@ function buildOpts(f) {
|
|
|
567
741
|
if (f.serverDefault) {
|
|
568
742
|
ret.default = f.serverDefault;
|
|
569
743
|
}
|
|
744
|
+
if (f.unique) {
|
|
745
|
+
ret.unique = true;
|
|
746
|
+
}
|
|
570
747
|
return ret;
|
|
571
748
|
}
|
|
572
749
|
function storageKey(fieldName, f) {
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getDefaultValue = exports.randomEmail = void 0;
|
|
4
|
+
const uuid_1 = require("uuid");
|
|
5
|
+
const schema_1 = require("../../schema");
|
|
6
|
+
const schema_2 = require("../../schema");
|
|
7
|
+
function random() {
|
|
8
|
+
return Math.random().toString(16).substring(2);
|
|
9
|
+
}
|
|
10
|
+
function randomEmail(domain) {
|
|
11
|
+
domain = domain || "email.com";
|
|
12
|
+
return `test+${random()}@${domain}`;
|
|
13
|
+
}
|
|
14
|
+
exports.randomEmail = randomEmail;
|
|
15
|
+
function randomPhoneNumber() {
|
|
16
|
+
return `+1${Math.random().toString(10).substring(2, 11)}`;
|
|
17
|
+
}
|
|
18
|
+
function coinFlip() {
|
|
19
|
+
return Math.floor(Math.random() * 10) >= 5;
|
|
20
|
+
}
|
|
21
|
+
function specialType(typ, col) {
|
|
22
|
+
let list = m.get(typ.dbType);
|
|
23
|
+
if (list?.length) {
|
|
24
|
+
for (const l of list) {
|
|
25
|
+
let regex = [];
|
|
26
|
+
if (Array.isArray(l.regex)) {
|
|
27
|
+
regex = l.regex;
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
regex = [l.regex];
|
|
31
|
+
}
|
|
32
|
+
for (const r of regex) {
|
|
33
|
+
if (r.test(col)) {
|
|
34
|
+
return l.newValue();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
function getDefaultValue(f, col, infos) {
|
|
42
|
+
if (f.defaultValueOnCreate) {
|
|
43
|
+
// @ts-ignore
|
|
44
|
+
return f.defaultValueOnCreate();
|
|
45
|
+
}
|
|
46
|
+
// half the time, return null for nullable
|
|
47
|
+
if (f.nullable && coinFlip()) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
const specialVal = specialType(f.type, col);
|
|
51
|
+
if (specialVal !== undefined) {
|
|
52
|
+
return specialVal;
|
|
53
|
+
}
|
|
54
|
+
return getValueForType(f.type, f, infos);
|
|
55
|
+
}
|
|
56
|
+
exports.getDefaultValue = getDefaultValue;
|
|
57
|
+
function getValueForType(typ, f, infos) {
|
|
58
|
+
switch (typ.dbType) {
|
|
59
|
+
case schema_1.DBType.UUID:
|
|
60
|
+
return (0, uuid_1.v4)();
|
|
61
|
+
case schema_1.DBType.Boolean:
|
|
62
|
+
return coinFlip();
|
|
63
|
+
case schema_1.DBType.Date:
|
|
64
|
+
return (0, schema_2.DateType)().format(new Date());
|
|
65
|
+
case schema_1.DBType.Time:
|
|
66
|
+
return (0, schema_2.TimeType)().format(new Date());
|
|
67
|
+
case schema_1.DBType.Timetz:
|
|
68
|
+
return (0, schema_2.TimetzType)().format(new Date());
|
|
69
|
+
case schema_1.DBType.Timestamp:
|
|
70
|
+
return (0, schema_2.TimestampType)().format(new Date());
|
|
71
|
+
case schema_1.DBType.Timestamptz:
|
|
72
|
+
return (0, schema_2.TimestamptzType)().format(new Date());
|
|
73
|
+
case schema_1.DBType.String:
|
|
74
|
+
return random();
|
|
75
|
+
case schema_1.DBType.Int:
|
|
76
|
+
return Math.floor(Math.random() * 100000000);
|
|
77
|
+
case schema_1.DBType.Float:
|
|
78
|
+
return Math.random() * 100000000;
|
|
79
|
+
case schema_1.DBType.Enum:
|
|
80
|
+
case schema_1.DBType.StringEnum:
|
|
81
|
+
if (typ.values) {
|
|
82
|
+
const idx = Math.floor(Math.random() * typ.values.length);
|
|
83
|
+
return typ.values[idx];
|
|
84
|
+
}
|
|
85
|
+
if (typ.enumMap) {
|
|
86
|
+
const vals = Object.values(typ.enumMap);
|
|
87
|
+
const idx = Math.floor(Math.random() * vals.length);
|
|
88
|
+
return vals[idx];
|
|
89
|
+
}
|
|
90
|
+
if (f.foreignKey) {
|
|
91
|
+
const schema = f.foreignKey.schema;
|
|
92
|
+
const col = f.foreignKey.column;
|
|
93
|
+
if (!infos) {
|
|
94
|
+
throw new Error(`infos required for enum with foreignKey`);
|
|
95
|
+
}
|
|
96
|
+
const info = infos.get(schema);
|
|
97
|
+
if (!info) {
|
|
98
|
+
throw new Error(`couldn't load data for schema ${schema}`);
|
|
99
|
+
}
|
|
100
|
+
if (!info.schema.dbRows) {
|
|
101
|
+
throw new Error(`no dbRows for schema ${schema}`);
|
|
102
|
+
}
|
|
103
|
+
const idx = Math.floor(Math.random() * info.schema.dbRows.length);
|
|
104
|
+
return info.schema.dbRows[idx][col];
|
|
105
|
+
}
|
|
106
|
+
throw new Error("TODO: enum without values not currently supported");
|
|
107
|
+
case schema_1.DBType.IntEnum:
|
|
108
|
+
const vals = Object.values(typ.intEnumMap);
|
|
109
|
+
const idx = Math.floor(Math.random() * vals.length);
|
|
110
|
+
return vals[idx];
|
|
111
|
+
case schema_1.DBType.BigInt:
|
|
112
|
+
return BigInt(Math.floor(Math.random() * 100000000));
|
|
113
|
+
case schema_1.DBType.JSONB:
|
|
114
|
+
// type as list
|
|
115
|
+
if (typ.listElemType?.dbType === schema_1.DBType.JSONB) {
|
|
116
|
+
const values = [];
|
|
117
|
+
for (let i = 0; i < 10; i++) {
|
|
118
|
+
values.push(getValueForType(typ.listElemType, f, infos));
|
|
119
|
+
}
|
|
120
|
+
if (!f.format) {
|
|
121
|
+
throw new Error("invalid format");
|
|
122
|
+
}
|
|
123
|
+
return f.format(values);
|
|
124
|
+
}
|
|
125
|
+
return (0, schema_2.JSONBType)().format({});
|
|
126
|
+
case schema_1.DBType.JSON:
|
|
127
|
+
return (0, schema_2.JSONType)().format({});
|
|
128
|
+
case schema_1.DBType.List:
|
|
129
|
+
// just do 10
|
|
130
|
+
const values = [];
|
|
131
|
+
for (let i = 0; i < 10; i++) {
|
|
132
|
+
values.push(getValueForType(f.type.listElemType, f.__getElemField(), infos));
|
|
133
|
+
}
|
|
134
|
+
if (!f.format) {
|
|
135
|
+
throw new Error("invalid format");
|
|
136
|
+
}
|
|
137
|
+
return f.format(values);
|
|
138
|
+
default:
|
|
139
|
+
throw new Error(`unsupported type ${typ.dbType}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
const emailType = {
|
|
143
|
+
dbType: schema_1.DBType.String,
|
|
144
|
+
newValue: () => {
|
|
145
|
+
return (0, schema_2.StringType)().format(randomEmail().toLowerCase());
|
|
146
|
+
},
|
|
147
|
+
regex: /^email(_address)|_email$/,
|
|
148
|
+
};
|
|
149
|
+
const phoneType = {
|
|
150
|
+
dbType: schema_1.DBType.String,
|
|
151
|
+
newValue: () => {
|
|
152
|
+
return randomPhoneNumber();
|
|
153
|
+
},
|
|
154
|
+
regex: /^phone(_number)?|_phone$|_phone_number$/,
|
|
155
|
+
};
|
|
156
|
+
const passwordType = {
|
|
157
|
+
dbType: schema_1.DBType.String,
|
|
158
|
+
newValue: () => {
|
|
159
|
+
// we don't use password type because when we're generating so many rows, it's too slow...
|
|
160
|
+
return random();
|
|
161
|
+
},
|
|
162
|
+
regex: /^password/,
|
|
163
|
+
};
|
|
164
|
+
const firstNames = [
|
|
165
|
+
"Daenerys",
|
|
166
|
+
"Jon",
|
|
167
|
+
"Arya",
|
|
168
|
+
"Sansa",
|
|
169
|
+
"Eddard",
|
|
170
|
+
"Khal",
|
|
171
|
+
"Robb",
|
|
172
|
+
"Joffrey",
|
|
173
|
+
"Ramsay",
|
|
174
|
+
"Cersei",
|
|
175
|
+
"Bolton",
|
|
176
|
+
"Oberyn",
|
|
177
|
+
"Jojen",
|
|
178
|
+
"Petyr",
|
|
179
|
+
"Brienne",
|
|
180
|
+
"Ygritte",
|
|
181
|
+
"Missandei",
|
|
182
|
+
"Shae",
|
|
183
|
+
"Sandor",
|
|
184
|
+
"Theon",
|
|
185
|
+
"Catelyn",
|
|
186
|
+
"Gilly",
|
|
187
|
+
"Samwell",
|
|
188
|
+
"Jaime",
|
|
189
|
+
"Stannis",
|
|
190
|
+
"Tyene",
|
|
191
|
+
"Obara",
|
|
192
|
+
"Nymeria",
|
|
193
|
+
"Elia",
|
|
194
|
+
"Ellaria",
|
|
195
|
+
"Myrcella",
|
|
196
|
+
"Hodor",
|
|
197
|
+
"Osha",
|
|
198
|
+
"Meera",
|
|
199
|
+
"Davos",
|
|
200
|
+
"Gendry",
|
|
201
|
+
];
|
|
202
|
+
const lastNames = [
|
|
203
|
+
"Stark",
|
|
204
|
+
"Targaryen",
|
|
205
|
+
"Lannister",
|
|
206
|
+
"Drogo",
|
|
207
|
+
"Baratheon",
|
|
208
|
+
"Reed",
|
|
209
|
+
"Martell",
|
|
210
|
+
"Tyrell",
|
|
211
|
+
"Clegane",
|
|
212
|
+
"Baelish",
|
|
213
|
+
"Greyjoy",
|
|
214
|
+
"Tarly",
|
|
215
|
+
"Sand",
|
|
216
|
+
"Snow",
|
|
217
|
+
"Bolton",
|
|
218
|
+
"Frey",
|
|
219
|
+
"Tarth",
|
|
220
|
+
"Payne",
|
|
221
|
+
"Seaworth",
|
|
222
|
+
];
|
|
223
|
+
const firstNameType = {
|
|
224
|
+
dbType: schema_1.DBType.String,
|
|
225
|
+
newValue: () => {
|
|
226
|
+
let idx = Math.floor(firstNames.length * Math.random());
|
|
227
|
+
return firstNames[idx];
|
|
228
|
+
},
|
|
229
|
+
regex: /^first_?(name)?/,
|
|
230
|
+
};
|
|
231
|
+
const lastNameType = {
|
|
232
|
+
dbType: schema_1.DBType.String,
|
|
233
|
+
newValue: () => {
|
|
234
|
+
let idx = Math.floor(lastNames.length * Math.random());
|
|
235
|
+
return lastNames[idx];
|
|
236
|
+
},
|
|
237
|
+
regex: /^last_?(name)?/,
|
|
238
|
+
};
|
|
239
|
+
let types = [
|
|
240
|
+
phoneType,
|
|
241
|
+
emailType,
|
|
242
|
+
passwordType,
|
|
243
|
+
firstNameType,
|
|
244
|
+
lastNameType,
|
|
245
|
+
];
|
|
246
|
+
let m = new Map();
|
|
247
|
+
for (const type of types) {
|
|
248
|
+
let list = m.get(type.dbType) || [];
|
|
249
|
+
list.push(type);
|
|
250
|
+
m.set(type.dbType, list);
|
|
251
|
+
}
|