joist-orm 0.1.536 → 1.0.0
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/build/{BaseEntity.d.ts → src/BaseEntity.d.ts} +2 -1
- package/build/{BaseEntity.js → src/BaseEntity.js} +13 -9
- package/build/src/BaseEntity.js.map +1 -0
- package/build/{EntityManager.d.ts → src/EntityManager.d.ts} +139 -110
- package/build/{EntityManager.js → src/EntityManager.js} +281 -262
- package/build/src/EntityManager.js.map +1 -0
- package/build/{QueryBuilder.d.ts → src/QueryBuilder.d.ts} +53 -3
- package/build/src/QueryBuilder.js +341 -0
- package/build/src/QueryBuilder.js.map +1 -0
- package/build/src/Todo.d.ts +25 -0
- package/build/src/Todo.js +52 -0
- package/build/src/Todo.js.map +1 -0
- package/build/src/changes.d.ts +34 -0
- package/build/src/changes.js +37 -0
- package/build/src/changes.js.map +1 -0
- package/build/src/config.d.ts +43 -0
- package/build/src/config.js +114 -0
- package/build/src/config.js.map +1 -0
- package/build/{createOrUpdatePartial.d.ts → src/createOrUpdatePartial.d.ts} +2 -1
- package/build/{createOrUpdatePartial.js → src/createOrUpdatePartial.js} +42 -10
- package/build/src/createOrUpdatePartial.js.map +1 -0
- package/build/src/dataloaders/findDataLoader.d.ts +5 -0
- package/build/src/dataloaders/findDataLoader.js +28 -0
- package/build/src/dataloaders/findDataLoader.js.map +1 -0
- package/build/src/dataloaders/loadDataLoader.d.ts +3 -0
- package/build/src/dataloaders/loadDataLoader.js +37 -0
- package/build/src/dataloaders/loadDataLoader.js.map +1 -0
- package/build/src/dataloaders/manyToManyDataLoader.d.ts +5 -0
- package/build/src/dataloaders/manyToManyDataLoader.js +78 -0
- package/build/src/dataloaders/manyToManyDataLoader.js.map +1 -0
- package/build/src/dataloaders/manyToManyFindDataLoader.d.ts +5 -0
- package/build/src/dataloaders/manyToManyFindDataLoader.js +33 -0
- package/build/src/dataloaders/manyToManyFindDataLoader.js.map +1 -0
- package/build/src/dataloaders/oneToManyDataLoader.d.ts +4 -0
- package/build/src/dataloaders/oneToManyDataLoader.js +40 -0
- package/build/src/dataloaders/oneToManyDataLoader.js.map +1 -0
- package/build/src/dataloaders/oneToManyFindDataLoader.d.ts +5 -0
- package/build/src/dataloaders/oneToManyFindDataLoader.js +32 -0
- package/build/src/dataloaders/oneToManyFindDataLoader.js.map +1 -0
- package/build/src/dataloaders/oneToOneDataLoader.d.ts +4 -0
- package/build/src/dataloaders/oneToOneDataLoader.js +40 -0
- package/build/src/dataloaders/oneToOneDataLoader.js.map +1 -0
- package/build/src/drivers/IdAssigner.d.ts +33 -0
- package/build/src/drivers/IdAssigner.js +106 -0
- package/build/src/drivers/IdAssigner.js.map +1 -0
- package/build/src/drivers/InMemoryDriver.d.ts +29 -0
- package/build/src/drivers/InMemoryDriver.js +306 -0
- package/build/src/drivers/InMemoryDriver.js.map +1 -0
- package/build/src/drivers/PostgresDriver.d.ts +40 -0
- package/build/src/drivers/PostgresDriver.js +376 -0
- package/build/src/drivers/PostgresDriver.js.map +1 -0
- package/build/src/drivers/driver.d.ts +23 -0
- package/build/src/drivers/driver.js +3 -0
- package/build/src/drivers/driver.js.map +1 -0
- package/build/src/drivers/index.d.ts +4 -0
- package/build/src/drivers/index.js +17 -0
- package/build/src/drivers/index.js.map +1 -0
- package/build/{getProperties.d.ts → src/getProperties.d.ts} +0 -0
- package/build/{getProperties.js → src/getProperties.js} +1 -1
- package/build/src/getProperties.js.map +1 -0
- package/build/src/index.d.ts +62 -0
- package/build/src/index.js +263 -0
- package/build/src/index.js.map +1 -0
- package/build/src/keys.d.ts +30 -0
- package/build/{keys.js → src/keys.js} +48 -16
- package/build/src/keys.js.map +1 -0
- package/build/{loadLens.d.ts → src/loadLens.d.ts} +2 -2
- package/build/{loadLens.js → src/loadLens.js} +1 -1
- package/build/src/loadLens.js.map +1 -0
- package/build/src/loaded.d.ts +49 -0
- package/build/src/loaded.js +9 -0
- package/build/src/loaded.js.map +1 -0
- package/build/{newTestInstance.d.ts → src/newTestInstance.d.ts} +37 -3
- package/build/src/newTestInstance.js +342 -0
- package/build/src/newTestInstance.js.map +1 -0
- package/build/{collections → src/relations}/AbstractRelationImpl.d.ts +6 -5
- package/build/{collections → src/relations}/AbstractRelationImpl.js +0 -0
- package/build/src/relations/AbstractRelationImpl.js.map +1 -0
- package/build/src/relations/Collection.d.ts +26 -0
- package/build/src/relations/Collection.js +19 -0
- package/build/src/relations/Collection.js.map +1 -0
- package/build/{collections → src/relations}/CustomCollection.d.ts +6 -2
- package/build/{collections → src/relations}/CustomCollection.js +17 -9
- package/build/src/relations/CustomCollection.js.map +1 -0
- package/build/{collections → src/relations}/CustomReference.d.ts +7 -2
- package/build/{collections → src/relations}/CustomReference.js +16 -9
- package/build/src/relations/CustomReference.js.map +1 -0
- package/build/src/relations/LargeCollection.d.ts +17 -0
- package/build/src/relations/LargeCollection.js +3 -0
- package/build/src/relations/LargeCollection.js.map +1 -0
- package/build/{collections → src/relations}/ManyToManyCollection.d.ts +9 -2
- package/build/src/relations/ManyToManyCollection.js +249 -0
- package/build/src/relations/ManyToManyCollection.js.map +1 -0
- package/build/src/relations/ManyToManyLargeCollection.d.ts +25 -0
- package/build/src/relations/ManyToManyLargeCollection.js +97 -0
- package/build/src/relations/ManyToManyLargeCollection.js.map +1 -0
- package/build/src/relations/ManyToOneReference.d.ts +77 -0
- package/build/{collections → src/relations}/ManyToOneReference.js +101 -48
- package/build/src/relations/ManyToOneReference.js.map +1 -0
- package/build/{collections → src/relations}/OneToManyCollection.d.ts +10 -2
- package/build/{collections → src/relations}/OneToManyCollection.js +54 -59
- package/build/src/relations/OneToManyCollection.js.map +1 -0
- package/build/src/relations/OneToManyLargeCollection.d.ts +25 -0
- package/build/src/relations/OneToManyLargeCollection.js +83 -0
- package/build/src/relations/OneToManyLargeCollection.js.map +1 -0
- package/build/src/relations/OneToOneReference.d.ts +82 -0
- package/build/src/relations/OneToOneReference.js +168 -0
- package/build/src/relations/OneToOneReference.js.map +1 -0
- package/build/src/relations/PolymorphicReference.d.ts +69 -0
- package/build/src/relations/PolymorphicReference.js +210 -0
- package/build/src/relations/PolymorphicReference.js.map +1 -0
- package/build/src/relations/Reference.d.ts +29 -0
- package/build/src/relations/Reference.js +23 -0
- package/build/src/relations/Reference.js.map +1 -0
- package/build/src/relations/Relation.d.ts +10 -0
- package/build/src/relations/Relation.js +13 -0
- package/build/src/relations/Relation.js.map +1 -0
- package/build/src/relations/hasAsyncProperty.d.ts +36 -0
- package/build/src/relations/hasAsyncProperty.js +55 -0
- package/build/src/relations/hasAsyncProperty.js.map +1 -0
- package/build/{collections → src/relations}/hasManyDerived.d.ts +2 -1
- package/build/{collections → src/relations}/hasManyDerived.js +1 -1
- package/build/src/relations/hasManyDerived.js.map +1 -0
- package/build/{collections → src/relations}/hasManyThrough.d.ts +0 -0
- package/build/{collections → src/relations}/hasManyThrough.js +2 -2
- package/build/src/relations/hasManyThrough.js.map +1 -0
- package/build/{collections → src/relations}/hasOneDerived.d.ts +3 -2
- package/build/{collections → src/relations}/hasOneDerived.js +1 -1
- package/build/src/relations/hasOneDerived.js.map +1 -0
- package/build/{collections → src/relations}/hasOneThrough.d.ts +0 -0
- package/build/{collections → src/relations}/hasOneThrough.js +2 -2
- package/build/src/relations/hasOneThrough.js.map +1 -0
- package/build/src/relations/index.d.ts +18 -0
- package/build/src/relations/index.js +53 -0
- package/build/src/relations/index.js.map +1 -0
- package/build/{reverseHint.d.ts → src/reverseHint.d.ts} +2 -1
- package/build/{reverseHint.js → src/reverseHint.js} +13 -9
- package/build/src/reverseHint.js.map +1 -0
- package/build/src/rules.d.ts +23 -0
- package/build/src/rules.js +23 -0
- package/build/src/rules.js.map +1 -0
- package/build/src/serde.d.ts +121 -0
- package/build/src/serde.js +190 -0
- package/build/src/serde.js.map +1 -0
- package/build/{utils.d.ts → src/utils.d.ts} +2 -0
- package/build/{utils.js → src/utils.js} +10 -1
- package/build/src/utils.js.map +1 -0
- package/build/tsconfig.tsbuildinfo +1 -0
- package/package.json +30 -15
- package/build/BaseEntity.js.map +0 -1
- package/build/EntityManager.js.map +0 -1
- package/build/EntityPersister.d.ts +0 -30
- package/build/EntityPersister.js +0 -197
- package/build/EntityPersister.js.map +0 -1
- package/build/QueryBuilder.js +0 -195
- package/build/QueryBuilder.js.map +0 -1
- package/build/changes.d.ts +0 -23
- package/build/changes.js +0 -14
- package/build/changes.js.map +0 -1
- package/build/collections/AbstractRelationImpl.js.map +0 -1
- package/build/collections/CustomCollection.js.map +0 -1
- package/build/collections/CustomReference.js.map +0 -1
- package/build/collections/ManyToManyCollection.js +0 -288
- package/build/collections/ManyToManyCollection.js.map +0 -1
- package/build/collections/ManyToOneReference.d.ts +0 -50
- package/build/collections/ManyToOneReference.js.map +0 -1
- package/build/collections/OneToManyCollection.js.map +0 -1
- package/build/collections/OneToOneReference.d.ts +0 -51
- package/build/collections/OneToOneReference.js +0 -132
- package/build/collections/OneToOneReference.js.map +0 -1
- package/build/collections/hasManyDerived.js.map +0 -1
- package/build/collections/hasManyThrough.js.map +0 -1
- package/build/collections/hasOneDerived.js.map +0 -1
- package/build/collections/hasOneThrough.js.map +0 -1
- package/build/collections/index.d.ts +0 -19
- package/build/collections/index.js +0 -49
- package/build/collections/index.js.map +0 -1
- package/build/createOrUpdatePartial.js.map +0 -1
- package/build/getProperties.js.map +0 -1
- package/build/index.d.ts +0 -140
- package/build/index.js +0 -278
- package/build/index.js.map +0 -1
- package/build/keys.d.ts +0 -21
- package/build/keys.js.map +0 -1
- package/build/loadLens.js.map +0 -1
- package/build/newTestInstance.js +0 -153
- package/build/newTestInstance.js.map +0 -1
- package/build/reverseHint.js.map +0 -1
- package/build/serde.d.ts +0 -47
- package/build/serde.js +0 -93
- package/build/serde.js.map +0 -1
- package/build/utils.js.map +0 -1
- package/package.json.bak +0 -27
- package/src/BaseEntity.ts +0 -104
- package/src/EntityManager.ts +0 -1263
- package/src/EntityPersister.ts +0 -240
- package/src/QueryBuilder.ts +0 -289
- package/src/changes.ts +0 -40
- package/src/collections/AbstractRelationImpl.ts +0 -28
- package/src/collections/CustomCollection.ts +0 -152
- package/src/collections/CustomReference.ts +0 -138
- package/src/collections/ManyToManyCollection.ts +0 -346
- package/src/collections/ManyToOneReference.ts +0 -215
- package/src/collections/OneToManyCollection.ts +0 -254
- package/src/collections/OneToOneReference.ts +0 -153
- package/src/collections/hasManyDerived.ts +0 -29
- package/src/collections/hasManyThrough.ts +0 -20
- package/src/collections/hasOneDerived.ts +0 -26
- package/src/collections/hasOneThrough.ts +0 -20
- package/src/collections/index.ts +0 -74
- package/src/createOrUpdatePartial.ts +0 -144
- package/src/getProperties.ts +0 -27
- package/src/index.ts +0 -400
- package/src/keys.ts +0 -75
- package/src/loadLens.ts +0 -126
- package/src/newTestInstance.ts +0 -205
- package/src/reverseHint.ts +0 -43
- package/src/serde.ts +0 -97
- package/src/utils.ts +0 -63
- package/tsconfig.json +0 -21
- package/tsconfig.tsbuildinfo +0 -2646
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Knex } from "knex";
|
|
2
|
+
import { Entity, EntityConstructor, EntityManager, EntityMetadata, FilterAndSettings, OneToManyCollection } from "../index";
|
|
3
|
+
import { ManyToManyCollection, OneToOneReferenceImpl } from "../relations";
|
|
4
|
+
import { JoinRow } from "../relations/ManyToManyCollection";
|
|
5
|
+
import { JoinRowTodo, Todo } from "../Todo";
|
|
6
|
+
import { Driver } from "./driver";
|
|
7
|
+
import { IdAssigner } from "./IdAssigner";
|
|
8
|
+
export interface PostgresDriverOpts {
|
|
9
|
+
idAssigner?: IdAssigner;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Implements the `Driver` interface for Postgres.
|
|
13
|
+
*
|
|
14
|
+
* This is the canonical driver implementation and leverages several aspects of
|
|
15
|
+
* Postgres for the best performance, i.e.:
|
|
16
|
+
*
|
|
17
|
+
* - Deferred foreign key constraints are used to allow bulk inserting/updating
|
|
18
|
+
* all entities without any topographic sorting/ordering issues.
|
|
19
|
+
*
|
|
20
|
+
* - Sequences are used to bulk-assign + then bulk-insert all entities, to again
|
|
21
|
+
* avoid issues with ordering issues (cannot bulk insert A w/o knowing the id of B).
|
|
22
|
+
*
|
|
23
|
+
* - We use a pg-specific bulk update syntax.
|
|
24
|
+
*/
|
|
25
|
+
export declare class PostgresDriver implements Driver {
|
|
26
|
+
private readonly knex;
|
|
27
|
+
private readonly idAssigner;
|
|
28
|
+
constructor(knex: Knex, opts?: PostgresDriverOpts);
|
|
29
|
+
load<T extends Entity>(em: EntityManager, meta: EntityMetadata<T>, untaggedIds: readonly string[]): Promise<unknown[]>;
|
|
30
|
+
loadManyToMany<T extends Entity, U extends Entity>(em: EntityManager, collection: ManyToManyCollection<T, U>, keys: readonly string[]): Promise<JoinRow[]>;
|
|
31
|
+
findManyToMany<T extends Entity, U extends Entity>(em: EntityManager, collection: ManyToManyCollection<T, U>, keys: readonly string[]): Promise<JoinRow[]>;
|
|
32
|
+
loadOneToMany<T extends Entity, U extends Entity>(em: EntityManager, collection: OneToManyCollection<T, U>, untaggedIds: readonly string[]): Promise<U[]>;
|
|
33
|
+
findOneToMany<T extends Entity, U extends Entity>(em: EntityManager, collection: OneToManyCollection<T, U>, keys: readonly string[]): Promise<U[]>;
|
|
34
|
+
loadOneToOne<T extends Entity, U extends Entity>(em: EntityManager, reference: OneToOneReferenceImpl<T, U>, untaggedIds: readonly string[]): Promise<unknown[]>;
|
|
35
|
+
find<T extends Entity>(em: EntityManager, type: EntityConstructor<T>, queries: FilterAndSettings<T>[]): Promise<unknown[][]>;
|
|
36
|
+
transaction<T>(em: EntityManager, fn: (txn: Knex.Transaction) => Promise<T>, isolationLevel?: "serializable"): Promise<T>;
|
|
37
|
+
flushEntities(em: EntityManager, todos: Record<string, Todo>): Promise<void>;
|
|
38
|
+
flushJoinTables(em: EntityManager, joinRows: Record<string, JoinRowTodo>): Promise<void>;
|
|
39
|
+
private getMaybeInTxnKnex;
|
|
40
|
+
}
|
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PostgresDriver = void 0;
|
|
4
|
+
const findDataLoader_1 = require("../dataloaders/findDataLoader");
|
|
5
|
+
const index_1 = require("../index");
|
|
6
|
+
const utils_1 = require("../utils");
|
|
7
|
+
const IdAssigner_1 = require("./IdAssigner");
|
|
8
|
+
/**
|
|
9
|
+
* Implements the `Driver` interface for Postgres.
|
|
10
|
+
*
|
|
11
|
+
* This is the canonical driver implementation and leverages several aspects of
|
|
12
|
+
* Postgres for the best performance, i.e.:
|
|
13
|
+
*
|
|
14
|
+
* - Deferred foreign key constraints are used to allow bulk inserting/updating
|
|
15
|
+
* all entities without any topographic sorting/ordering issues.
|
|
16
|
+
*
|
|
17
|
+
* - Sequences are used to bulk-assign + then bulk-insert all entities, to again
|
|
18
|
+
* avoid issues with ordering issues (cannot bulk insert A w/o knowing the id of B).
|
|
19
|
+
*
|
|
20
|
+
* - We use a pg-specific bulk update syntax.
|
|
21
|
+
*/
|
|
22
|
+
class PostgresDriver {
|
|
23
|
+
constructor(knex, opts) {
|
|
24
|
+
this.knex = knex;
|
|
25
|
+
this.idAssigner = opts?.idAssigner ?? new IdAssigner_1.SequenceIdAssigner();
|
|
26
|
+
}
|
|
27
|
+
load(em, meta, untaggedIds) {
|
|
28
|
+
const knex = this.getMaybeInTxnKnex(em);
|
|
29
|
+
return knex.select("*").from(meta.tableName).whereIn("id", untaggedIds);
|
|
30
|
+
}
|
|
31
|
+
loadManyToMany(em, collection, keys) {
|
|
32
|
+
const knex = this.getMaybeInTxnKnex(em);
|
|
33
|
+
// Break out `column_id=string` keys out
|
|
34
|
+
const columns = {};
|
|
35
|
+
keys.forEach((key) => {
|
|
36
|
+
const [columnId, id] = key.split("=");
|
|
37
|
+
(0, utils_1.getOrSet)(columns, columnId, []).push(id);
|
|
38
|
+
});
|
|
39
|
+
// Or together `where tag_id in (...)` or `book_id in (...)`
|
|
40
|
+
let query = knex.select("*").from(collection.joinTableName);
|
|
41
|
+
Object.entries(columns).forEach(([columnId, values]) => {
|
|
42
|
+
// Pick the right meta i.e. tag_id --> TagMeta or book_id --> BookMeta
|
|
43
|
+
const meta = collection.columnName == columnId ? (0, index_1.getMetadata)(collection.entity) : collection.otherMeta;
|
|
44
|
+
query = query.orWhereIn(columnId, values.map((id) => (0, index_1.keyToNumber)(meta, id)));
|
|
45
|
+
});
|
|
46
|
+
return query.orderBy("id");
|
|
47
|
+
}
|
|
48
|
+
findManyToMany(em, collection, keys) {
|
|
49
|
+
const knex = this.getMaybeInTxnKnex(em);
|
|
50
|
+
// Or together `where (tag_id = X and book_id = Y)` or `(book_id = B and tag_id = A)`
|
|
51
|
+
let query = knex.select("*").from(collection.joinTableName);
|
|
52
|
+
keys.forEach((key) => {
|
|
53
|
+
const [one, two] = key.split(",");
|
|
54
|
+
const [columnOne, idOne] = one.split("=");
|
|
55
|
+
const [columnTwo, idTwo] = two.split("=");
|
|
56
|
+
const [meta1, meta2] = collection.columnName === columnOne
|
|
57
|
+
? [collection.meta, collection.otherMeta]
|
|
58
|
+
: [collection.otherMeta, collection.meta];
|
|
59
|
+
// Pick the right meta i.e. tag_id --> TagMeta or book_id --> BookMeta
|
|
60
|
+
query = query.orWhere((q) => {
|
|
61
|
+
q.where(columnOne, (0, index_1.keyToNumber)(meta1, idOne)).andWhere(columnTwo, (0, index_1.keyToNumber)(meta2, idTwo));
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
return query.orderBy("id");
|
|
65
|
+
}
|
|
66
|
+
loadOneToMany(em, collection, untaggedIds) {
|
|
67
|
+
const knex = this.getMaybeInTxnKnex(em);
|
|
68
|
+
return knex
|
|
69
|
+
.select("*")
|
|
70
|
+
.from(collection.otherMeta.tableName)
|
|
71
|
+
.whereIn(collection.otherColumnName, untaggedIds)
|
|
72
|
+
.orderBy("id");
|
|
73
|
+
}
|
|
74
|
+
findOneToMany(em, collection, keys) {
|
|
75
|
+
const knex = this.getMaybeInTxnKnex(em);
|
|
76
|
+
let query = knex.select("*").from(collection.otherMeta.tableName);
|
|
77
|
+
// Or together `where (id = X and book_id = Y)`
|
|
78
|
+
keys.forEach((key) => {
|
|
79
|
+
const [one, two] = key.split(",");
|
|
80
|
+
// columnOne is the `id=`, so is really the "other" side of the o2m
|
|
81
|
+
const [columnOne, idOne] = one.split("=");
|
|
82
|
+
const [columnTwo, idTwo] = two.split("=");
|
|
83
|
+
const [meta1, meta2] = [collection.otherMeta, collection.meta];
|
|
84
|
+
// Pick the right meta i.e. tag_id --> TagMeta or book_id --> BookMeta
|
|
85
|
+
query = query.orWhere((q) => {
|
|
86
|
+
q.where(columnOne, (0, index_1.keyToNumber)(meta1, idOne)).andWhere(columnTwo, (0, index_1.keyToNumber)(meta2, idTwo));
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
return query.orderBy("id");
|
|
90
|
+
}
|
|
91
|
+
loadOneToOne(em, reference, untaggedIds) {
|
|
92
|
+
const knex = this.getMaybeInTxnKnex(em);
|
|
93
|
+
return knex
|
|
94
|
+
.select("*")
|
|
95
|
+
.from(reference.otherMeta.tableName)
|
|
96
|
+
.whereIn(reference.otherColumnName, untaggedIds)
|
|
97
|
+
.orderBy("id");
|
|
98
|
+
}
|
|
99
|
+
async find(em, type, queries) {
|
|
100
|
+
const knex = this.getMaybeInTxnKnex(em);
|
|
101
|
+
// If there is only 1 query, we can skip the tagging step.
|
|
102
|
+
if (queries.length === 1) {
|
|
103
|
+
return [ensureUnderLimit(await (0, index_1.buildQuery)(knex, type, queries[0]))];
|
|
104
|
+
}
|
|
105
|
+
// Map each incoming query[i] to itself or a previous dup
|
|
106
|
+
const uniqueQueries = [];
|
|
107
|
+
const queryToUnique = {};
|
|
108
|
+
queries.forEach((q, i) => {
|
|
109
|
+
let j = uniqueQueries.findIndex((uq) => (0, findDataLoader_1.whereFilterHash)(uq) === (0, findDataLoader_1.whereFilterHash)(q));
|
|
110
|
+
if (j === -1) {
|
|
111
|
+
uniqueQueries.push(q);
|
|
112
|
+
j = uniqueQueries.length - 1;
|
|
113
|
+
}
|
|
114
|
+
queryToUnique[i] = j;
|
|
115
|
+
});
|
|
116
|
+
// There are duplicate queries, but only one unique query, so we can execute just it w/o tagging.
|
|
117
|
+
if (uniqueQueries.length === 1) {
|
|
118
|
+
const rows = ensureUnderLimit(await (0, index_1.buildQuery)(knex, type, queries[0]));
|
|
119
|
+
// Reuse this same result for however many callers asked for it.
|
|
120
|
+
return queries.map(() => rows);
|
|
121
|
+
}
|
|
122
|
+
// TODO: Instead of this tagged approach, we could probably check if the each
|
|
123
|
+
// where cause: a) has the same structure for joins, and b) has conditions that
|
|
124
|
+
// we can evaluate client-side, and then combine it into a query like:
|
|
125
|
+
//
|
|
126
|
+
// SELECT entity.*, t1.foo as condition1, t2.bar as condition2 FROM ...
|
|
127
|
+
// WHERE t1.foo (union of each queries condition)
|
|
128
|
+
//
|
|
129
|
+
// And then use the `condition1` and `condition2` to tease the combined result set
|
|
130
|
+
// back apart into each condition's result list.
|
|
131
|
+
// For each query, add an additional `__tag` column that will identify that query's
|
|
132
|
+
// corresponding rows in the combined/UNION ALL'd result set.
|
|
133
|
+
//
|
|
134
|
+
// We also add a `__row` column with that queries order, so that after we `UNION ALL`,
|
|
135
|
+
// we can order by `__tag` + `__row` and ensure we're getting back the combined rows
|
|
136
|
+
// exactly as they would be in done individually (i.e. per the docs `UNION ALL` does
|
|
137
|
+
// not guarantee order).
|
|
138
|
+
const tagged = uniqueQueries.map((queryAndSettings, i) => {
|
|
139
|
+
const query = (0, index_1.buildQuery)(knex, type, queryAndSettings);
|
|
140
|
+
return query.select(knex.raw(`${i} as __tag`), knex.raw("row_number() over () as __row"));
|
|
141
|
+
});
|
|
142
|
+
const meta = (0, index_1.getMetadata)(type);
|
|
143
|
+
// Kind of dumb, but make a dummy row to start our query with
|
|
144
|
+
let query = knex
|
|
145
|
+
.select("*", knex.raw("-1 as __tag"), knex.raw("-1 as __row"))
|
|
146
|
+
.from(meta.tableName)
|
|
147
|
+
.orderBy("__tag", "__row")
|
|
148
|
+
.where({ id: -1 });
|
|
149
|
+
// Use the dummy query as a base, then `UNION ALL` in all the rest
|
|
150
|
+
tagged.forEach((add) => {
|
|
151
|
+
query = query.unionAll(add, true);
|
|
152
|
+
});
|
|
153
|
+
// Issue a single SQL statement for all of them
|
|
154
|
+
const rows = ensureUnderLimit(await query);
|
|
155
|
+
const resultForUniques = [];
|
|
156
|
+
uniqueQueries.forEach((q, i) => {
|
|
157
|
+
resultForUniques[i] = [];
|
|
158
|
+
});
|
|
159
|
+
rows.forEach((row) => {
|
|
160
|
+
resultForUniques[row["__tag"]].push(row);
|
|
161
|
+
});
|
|
162
|
+
// We return an array-of-arrays, where result[i] is the rows for queries[i]
|
|
163
|
+
const result = [];
|
|
164
|
+
queries.forEach((q, i) => {
|
|
165
|
+
result[i] = resultForUniques[queryToUnique[i]];
|
|
166
|
+
});
|
|
167
|
+
return result;
|
|
168
|
+
}
|
|
169
|
+
async transaction(em, fn, isolationLevel) {
|
|
170
|
+
const knex = this.getMaybeInTxnKnex(em);
|
|
171
|
+
const alreadyInTxn = "commit" in knex;
|
|
172
|
+
if (alreadyInTxn) {
|
|
173
|
+
return fn(knex);
|
|
174
|
+
}
|
|
175
|
+
return await knex.transaction(async (txn) => {
|
|
176
|
+
em.currentTxnKnex = txn;
|
|
177
|
+
try {
|
|
178
|
+
if (isolationLevel) {
|
|
179
|
+
await txn.raw("set transaction isolation level serializable;");
|
|
180
|
+
}
|
|
181
|
+
await (0, index_1.beforeTransaction)(em, txn);
|
|
182
|
+
const result = await fn(txn);
|
|
183
|
+
await (0, index_1.afterTransaction)(em, txn);
|
|
184
|
+
return result;
|
|
185
|
+
}
|
|
186
|
+
finally {
|
|
187
|
+
em.currentTxnKnex = undefined;
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
async flushEntities(em, todos) {
|
|
192
|
+
const knex = this.getMaybeInTxnKnex(em);
|
|
193
|
+
const updatedAt = new Date();
|
|
194
|
+
await this.idAssigner.assignNewIds(knex, todos);
|
|
195
|
+
for await (const todo of Object.values(todos)) {
|
|
196
|
+
if (todo) {
|
|
197
|
+
const meta = todo.metadata;
|
|
198
|
+
if (todo.inserts.length > 0) {
|
|
199
|
+
await batchInsert(knex, meta, todo.inserts);
|
|
200
|
+
}
|
|
201
|
+
if (todo.updates.length > 0) {
|
|
202
|
+
todo.updates.forEach((e) => {
|
|
203
|
+
// Should we just go through a setter?
|
|
204
|
+
e.__orm.originalData["updatedAt"] = e.__orm.data["updatedAt"];
|
|
205
|
+
e.__orm.data["updatedAt"] = updatedAt;
|
|
206
|
+
});
|
|
207
|
+
await batchUpdate(knex, meta, todo.updates);
|
|
208
|
+
}
|
|
209
|
+
if (todo.deletes.length > 0) {
|
|
210
|
+
await batchDelete(knex, meta, todo.deletes);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
async flushJoinTables(em, joinRows) {
|
|
216
|
+
const knex = this.getMaybeInTxnKnex(em);
|
|
217
|
+
for await (const [joinTableName, { m2m, newRows, deletedRows }] of Object.entries(joinRows)) {
|
|
218
|
+
if (newRows.length > 0) {
|
|
219
|
+
const sql = cleanSql(`
|
|
220
|
+
INSERT INTO ${joinTableName} (${m2m.columnName}, ${m2m.otherColumnName})
|
|
221
|
+
VALUES ${(0, utils_1.zeroTo)(newRows.length)
|
|
222
|
+
.map(() => "(?, ?) ")
|
|
223
|
+
.join(", ")}
|
|
224
|
+
ON CONFLICT (${m2m.columnName}, ${m2m.otherColumnName}) DO UPDATE SET id = ${joinTableName}.id
|
|
225
|
+
RETURNING id;
|
|
226
|
+
`);
|
|
227
|
+
const meta1 = (0, index_1.getMetadata)(m2m.entity);
|
|
228
|
+
const meta2 = m2m.otherMeta;
|
|
229
|
+
const bindings = newRows.flatMap((row) => {
|
|
230
|
+
return [
|
|
231
|
+
(0, index_1.keyToNumber)(meta1, (0, index_1.maybeResolveReferenceToId)(row[m2m.columnName])),
|
|
232
|
+
(0, index_1.keyToNumber)(meta2, (0, index_1.maybeResolveReferenceToId)(row[m2m.otherColumnName])),
|
|
233
|
+
];
|
|
234
|
+
});
|
|
235
|
+
const { rows } = await knex.raw(sql, bindings);
|
|
236
|
+
for (let i = 0; i < rows.length; i++) {
|
|
237
|
+
newRows[i].id = rows[i].id;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
if (deletedRows.length > 0) {
|
|
241
|
+
// `remove`s that were done against unloaded ManyToManyCollections will not have row ids
|
|
242
|
+
const [haveIds, noIds] = (0, utils_1.partition)(deletedRows, (r) => r.id !== -1);
|
|
243
|
+
if (haveIds.length > 0) {
|
|
244
|
+
await knex(joinTableName)
|
|
245
|
+
.del()
|
|
246
|
+
.whereIn("id", haveIds.map((e) => e.id));
|
|
247
|
+
}
|
|
248
|
+
if (noIds.length > 0) {
|
|
249
|
+
const data = noIds.map((e) => [
|
|
250
|
+
(0, index_1.deTagId)(m2m.meta, (0, index_1.maybeResolveReferenceToId)(e[m2m.columnName])),
|
|
251
|
+
(0, index_1.deTagId)(m2m.otherMeta, (0, index_1.maybeResolveReferenceToId)(e[m2m.otherColumnName])),
|
|
252
|
+
]);
|
|
253
|
+
await knex(joinTableName).del().whereIn([m2m.columnName, m2m.otherColumnName], data);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
getMaybeInTxnKnex(em) {
|
|
259
|
+
return em.currentTxnKnex || this.knex;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
exports.PostgresDriver = PostgresDriver;
|
|
263
|
+
async function batchInsert(knex, meta, entities) {
|
|
264
|
+
// We don't use the ids that come back from batchInsert b/c we pre-assign ids for both inserts and updates.
|
|
265
|
+
// We also use `.transacting` b/c even when `knex` is already a Transaction object,
|
|
266
|
+
// `batchInsert` w/o the `transacting` adds savepoints that we don't want/need.
|
|
267
|
+
const fields = Object.values(meta.fields).filter(index_1.hasSerde);
|
|
268
|
+
const columns = fields.flatMap((f) => f.serde.columns);
|
|
269
|
+
// Issue 1 UPDATE statement with N `VALUES (..., ...), (..., ...), ...` clauses
|
|
270
|
+
// and bindings is each individual value.
|
|
271
|
+
const bindings = entities.flatMap((entity) => columns.map((c) => c.dbValue(entity.__orm.data) ?? null));
|
|
272
|
+
const sql = `
|
|
273
|
+
INSERT INTO ${meta.tableName} (${columns.map((c) => `"${c.columnName}"`).join(", ")})
|
|
274
|
+
VALUES ${entities.map(() => `(${columns.map(() => `?`).join(", ")})`).join(",")}
|
|
275
|
+
`;
|
|
276
|
+
await knex.raw(cleanSql(sql), bindings);
|
|
277
|
+
}
|
|
278
|
+
// Uses a pg-specific syntax to issue a bulk update
|
|
279
|
+
async function batchUpdate(knex, meta, entities) {
|
|
280
|
+
// Get the unique set of fields that are changed across all of the entities (of this type) we want to bulk update
|
|
281
|
+
const changedFields = new Set();
|
|
282
|
+
// Id doesn't change, but we need it for our WHERE clause
|
|
283
|
+
changedFields.add("id");
|
|
284
|
+
changedFields.add("updatedAt");
|
|
285
|
+
entities.forEach((entity) => {
|
|
286
|
+
Object.keys(entity.__orm.originalData).forEach((key) => changedFields.add(key));
|
|
287
|
+
});
|
|
288
|
+
// Sometimes with derived fields, an instance will be marked as an update, but if the derived field hasn't changed,
|
|
289
|
+
// it'll be a noop, so just short-circuit if it looks like that happened, i.e. we have no changed fields.
|
|
290
|
+
// (unless one of the entities was `EntityManager.touch`-d, which seems force the save / updatedAt tick.)
|
|
291
|
+
if (changedFields.size === 2 && !entities.some((e) => e.__orm.isTouched)) {
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
const fields = Object.values(meta.fields)
|
|
295
|
+
.filter((f) => changedFields.has(f.fieldName))
|
|
296
|
+
.filter(index_1.hasSerde);
|
|
297
|
+
const columns = fields.flatMap((f) => f.serde.columns);
|
|
298
|
+
// We need to handle array columns different because the "unnest" approach fundamentally
|
|
299
|
+
// won't work b/c we can't use it to send "a list of lists".
|
|
300
|
+
let sql;
|
|
301
|
+
let bindings;
|
|
302
|
+
if (fields.some((f) => f.serde instanceof index_1.EnumArrayFieldSerde)) {
|
|
303
|
+
// Issue 1 UPDATE statement with N `VALUES (..., ...), (..., ...), ...` clauses
|
|
304
|
+
// and bindings is each individual value.
|
|
305
|
+
bindings = entities.flatMap((entity) => [
|
|
306
|
+
...columns.map((c) => c.dbValue(entity.__orm.data) ?? null),
|
|
307
|
+
entity.__orm.originalData.updatedAt,
|
|
308
|
+
]);
|
|
309
|
+
sql = `
|
|
310
|
+
UPDATE ${meta.tableName}
|
|
311
|
+
SET ${columns
|
|
312
|
+
.filter((c) => c.columnName !== "id")
|
|
313
|
+
.map((c) => `"${c.columnName}" = data."${c.columnName}"`)
|
|
314
|
+
.join(", ")}
|
|
315
|
+
FROM (
|
|
316
|
+
VALUES ${entities.map(() => `(${columns.map((c) => `?::${c.dbType}`).join(", ")}, ?::timestamp)`).join(",")}
|
|
317
|
+
) AS data(${columns.map((c) => c.columnName).join(",")},original_updated_at)
|
|
318
|
+
WHERE
|
|
319
|
+
${meta.tableName}.id = data.id
|
|
320
|
+
AND date_trunc('milliseconds', ${meta.tableName}.updated_at) = data.original_updated_at
|
|
321
|
+
RETURNING ${meta.tableName}.id
|
|
322
|
+
`;
|
|
323
|
+
}
|
|
324
|
+
else {
|
|
325
|
+
// Issue 1 UPDATE statement with bindings having an array for each column's new values
|
|
326
|
+
bindings = columns.map(() => []);
|
|
327
|
+
// Add 1 more column for original_updated_at
|
|
328
|
+
const originalUpdatedAt = [];
|
|
329
|
+
bindings.push(originalUpdatedAt);
|
|
330
|
+
for (const entity of entities) {
|
|
331
|
+
columns.forEach((c, i) => {
|
|
332
|
+
bindings[i].push(c.dbValue(entity.__orm.data) ?? null);
|
|
333
|
+
});
|
|
334
|
+
originalUpdatedAt.push(entity.__orm.originalData.updatedAt);
|
|
335
|
+
}
|
|
336
|
+
sql = `
|
|
337
|
+
UPDATE ${meta.tableName}
|
|
338
|
+
SET ${columns
|
|
339
|
+
.filter((c) => c.columnName !== "id")
|
|
340
|
+
.map((c) => `"${c.columnName}" = data."${c.columnName}"`)
|
|
341
|
+
.join(", ")}
|
|
342
|
+
FROM (
|
|
343
|
+
SELECT
|
|
344
|
+
${columns.map((c) => `unnest(?::${c.dbType}[]) as "${c.columnName}"`).join(", ")},
|
|
345
|
+
unnest(?::timestamptz[]) as original_updated_at
|
|
346
|
+
) as data
|
|
347
|
+
WHERE
|
|
348
|
+
${meta.tableName}.id = data.id
|
|
349
|
+
AND date_trunc('milliseconds', ${meta.tableName}.updated_at) = data.original_updated_at
|
|
350
|
+
RETURNING ${meta.tableName}.id
|
|
351
|
+
`;
|
|
352
|
+
}
|
|
353
|
+
const result = await knex.raw(cleanSql(sql), bindings);
|
|
354
|
+
if (result.rows.length !== entities.length) {
|
|
355
|
+
const updated = new Set(result.rows.map((r) => r.id));
|
|
356
|
+
const missing = entities.map((e) => e.idOrFail).filter((id) => !updated.has(id));
|
|
357
|
+
throw new Error(`Oplock failure for ${(0, index_1.tagIds)(meta, missing).join(", ")}`);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
async function batchDelete(knex, meta, entities) {
|
|
361
|
+
await knex(meta.tableName)
|
|
362
|
+
.del()
|
|
363
|
+
.whereIn("id", entities.map((e) => (0, index_1.keyToNumber)(meta, e.id).toString()));
|
|
364
|
+
entities.forEach((entity) => (entity.__orm.deleted = "deleted"));
|
|
365
|
+
}
|
|
366
|
+
/** Strips new lines/indentation from our `UPDATE` string; doesn't do any actual SQL param escaping/etc. */
|
|
367
|
+
function cleanSql(sql) {
|
|
368
|
+
return sql.trim().replace(/\n/g, "").replace(/ +/g, " ");
|
|
369
|
+
}
|
|
370
|
+
function ensureUnderLimit(rows) {
|
|
371
|
+
if (rows.length >= index_1.entityLimit) {
|
|
372
|
+
throw new Error(`Query returned more than ${index_1.entityLimit} rows`);
|
|
373
|
+
}
|
|
374
|
+
return rows;
|
|
375
|
+
}
|
|
376
|
+
//# sourceMappingURL=PostgresDriver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PostgresDriver.js","sourceRoot":"","sources":["../../../src/drivers/PostgresDriver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Knex } from "knex";
|
|
2
|
+
import { ManyToManyLargeCollection, OneToManyLargeCollection } from "src/relations";
|
|
3
|
+
import { Entity, EntityConstructor, EntityManager, EntityMetadata } from "../EntityManager";
|
|
4
|
+
import { FilterAndSettings } from "../QueryBuilder";
|
|
5
|
+
import { JoinRow, ManyToManyCollection } from "../relations/ManyToManyCollection";
|
|
6
|
+
import { OneToManyCollection } from "../relations/OneToManyCollection";
|
|
7
|
+
import { OneToOneReferenceImpl } from "../relations/OneToOneReference";
|
|
8
|
+
import { JoinRowTodo, Todo } from "../Todo";
|
|
9
|
+
/** Isolates all SQL calls that joist needs to make to fetch/save data. */
|
|
10
|
+
export interface Driver {
|
|
11
|
+
load<T extends Entity>(em: EntityManager, meta: EntityMetadata<T>, untaggedIds: readonly string[]): Promise<unknown[]>;
|
|
12
|
+
/** Loads a given m2m relation for potentially multiple entities. */
|
|
13
|
+
loadManyToMany<T extends Entity, U extends Entity>(em: EntityManager, collection: ManyToManyCollection<T, U>, keys: readonly string[]): Promise<JoinRow[]>;
|
|
14
|
+
/** Just finds presence in a m2m w/o loading the full relation. */
|
|
15
|
+
findManyToMany<T extends Entity, U extends Entity>(em: EntityManager, collection: ManyToManyCollection<T, U> | ManyToManyLargeCollection<T, U>, keys: readonly string[]): Promise<JoinRow[]>;
|
|
16
|
+
loadOneToMany<T extends Entity, U extends Entity>(em: EntityManager, collection: OneToManyCollection<T, U>, untaggedIds: readonly string[]): Promise<unknown[]>;
|
|
17
|
+
findOneToMany<T extends Entity, U extends Entity>(em: EntityManager, collection: OneToManyCollection<T, U> | OneToManyLargeCollection<T, U>, untaggedIds: readonly string[]): Promise<unknown[]>;
|
|
18
|
+
loadOneToOne<T extends Entity, U extends Entity>(em: EntityManager, reference: OneToOneReferenceImpl<T, U>, untaggedIds: readonly string[]): Promise<unknown[]>;
|
|
19
|
+
find<T extends Entity>(em: EntityManager, type: EntityConstructor<T>, queries: readonly FilterAndSettings<T>[]): Promise<unknown[][]>;
|
|
20
|
+
transaction<T>(em: EntityManager, fn: (txn: Knex.Transaction) => Promise<T>, isolationLevel?: "serializable"): Promise<T>;
|
|
21
|
+
flushEntities(em: EntityManager, todos: Record<string, Todo>): Promise<void>;
|
|
22
|
+
flushJoinTables(em: EntityManager, joinRows: Record<string, JoinRowTodo>): Promise<void>;
|
|
23
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"driver.js","sourceRoot":"","sources":["../../../src/drivers/driver.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
__exportStar(require("./driver"), exports);
|
|
14
|
+
__exportStar(require("./IdAssigner"), exports);
|
|
15
|
+
__exportStar(require("./InMemoryDriver"), exports);
|
|
16
|
+
__exportStar(require("./PostgresDriver"), exports);
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/drivers/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAAyB;AACzB,+CAA6B;AAC7B,mDAAiC;AACjC,mDAAiC"}
|
|
File without changes
|
|
@@ -14,7 +14,7 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
14
14
|
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
15
|
if (mod && mod.__esModule) return mod;
|
|
16
16
|
var result = {};
|
|
17
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
18
|
__setModuleDefault(result, mod);
|
|
19
19
|
return result;
|
|
20
20
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getProperties.js","sourceRoot":"","sources":["../../src/getProperties.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAAA,oDAAsC;AAGtC,uDAAuD;AACvD,MAAM,EAAE,GAAG,EAAE,CAAC;AAEd;;;;;GAKG;AACH,SAAgB,aAAa,CAAmB,IAAuB;IACrE,OAAO;QACL,GAAG,MAAM,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;QAClD,GAAG,MAAM,CAAC,IAAI,CACZ,IAAI,IAAI,CAAC,IAAI,CACX;YACE,QAAQ,EAAE,CAAC,QAAa,EAAE,MAAW,EAAE,EAAE;gBACvC,EAAE,CAAC,4BAA4B,GAAG,MAAM,CAAC;YAC3C,CAAC;SACK,EACR,EAAE,CACH,CACF;KACF,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,aAAa,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;AACpE,CAAC;AAdD,sCAcC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Entity, EntityConstructor, EntityManager, EntityMetadata, EntityOrmField, Field, ManyToManyField, ManyToOneField, OneToManyField, OneToOneField, OptsOf, PolymorphicField } from "./EntityManager";
|
|
2
|
+
import { Reference } from "./relations";
|
|
3
|
+
import { AbstractRelationImpl } from "./relations/AbstractRelationImpl";
|
|
4
|
+
export { newPgConnectionConfig } from "joist-utils";
|
|
5
|
+
export { BaseEntity } from "./BaseEntity";
|
|
6
|
+
export * from "./changes";
|
|
7
|
+
export { ConfigApi, EntityHook } from "./config";
|
|
8
|
+
export { DeepPartialOrNull } from "./createOrUpdatePartial";
|
|
9
|
+
export * from "./drivers";
|
|
10
|
+
export * from "./EntityManager";
|
|
11
|
+
export * from "./getProperties";
|
|
12
|
+
export * from "./keys";
|
|
13
|
+
export { isNew, Loadable, Loaded, LoadHint, New, RelationsIn } from "./loaded";
|
|
14
|
+
export * from "./loadLens";
|
|
15
|
+
export * from "./newTestInstance";
|
|
16
|
+
export * from "./QueryBuilder";
|
|
17
|
+
export * from "./relations";
|
|
18
|
+
export * from "./reverseHint";
|
|
19
|
+
export { GenericError, newRequiredRule, ValidationError, ValidationErrors, ValidationRule, ValidationRuleResult, } from "./rules";
|
|
20
|
+
export * from "./serde";
|
|
21
|
+
export { fail } from "./utils";
|
|
22
|
+
interface Flavoring<FlavorT> {
|
|
23
|
+
_type?: FlavorT;
|
|
24
|
+
}
|
|
25
|
+
export declare type Flavor<T, FlavorT> = T & Flavoring<FlavorT>;
|
|
26
|
+
export declare function setField<T extends Entity>(entity: T, fieldName: keyof T, newValue: any): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Sets each value in `values` on the current entity.
|
|
29
|
+
*
|
|
30
|
+
* The default behavior is that passing a value as either `null` or `undefined` will set
|
|
31
|
+
* the field as `undefined`, i.e. automatic `null` to `undefined` conversion.
|
|
32
|
+
*
|
|
33
|
+
* However, if you pass `ignoreUndefined: true`, then any opt that is `undefined` will be treated
|
|
34
|
+
* as "do not set", and `null` will still mean "set to `undefined`". This is useful for implementing
|
|
35
|
+
* APIs were an input of `undefined` means "do not set / noop" and `null` means "unset".
|
|
36
|
+
*/
|
|
37
|
+
export declare function setOpts<T extends Entity>(entity: T, values: Partial<OptsOf<T>> | string | undefined, opts?: {
|
|
38
|
+
calledFromConstructor?: boolean;
|
|
39
|
+
partial?: boolean;
|
|
40
|
+
}): void;
|
|
41
|
+
export declare function ensureNotDeleted(entity: Entity, opts?: {
|
|
42
|
+
ignore?: EntityOrmField["deleted"];
|
|
43
|
+
}): void;
|
|
44
|
+
/** Adds `null` to every key in `T` to accept partial-update-style input. */
|
|
45
|
+
export declare type PartialOrNull<T> = {
|
|
46
|
+
[P in keyof T]?: T[P] | null;
|
|
47
|
+
};
|
|
48
|
+
export declare function getRequiredKeys<T extends Entity>(entity: T): string[];
|
|
49
|
+
export declare function getRequiredKeys<T extends Entity>(type: EntityConstructor<T>): string[];
|
|
50
|
+
/** Processes the metas based on any custom calls to the `configApi` hooks. */
|
|
51
|
+
export declare function configureMetadata(metas: EntityMetadata<any>[]): void;
|
|
52
|
+
export declare function getEm(entity: Entity): EntityManager<any>;
|
|
53
|
+
export declare function getRelations(entity: Entity): AbstractRelationImpl<any>[];
|
|
54
|
+
export declare function getConstructorFromTaggedId(id: string): EntityConstructor<any>;
|
|
55
|
+
export declare function maybeGetConstructorFromReference(value: string | Entity | Reference<any, any, any> | undefined): EntityConstructor<any> | undefined;
|
|
56
|
+
export declare function isOneToManyField(ormField: Field): ormField is OneToManyField;
|
|
57
|
+
export declare function isManyToOneField(ormField: Field): ormField is ManyToOneField;
|
|
58
|
+
export declare function isManyToManyField(ormField: Field): ormField is ManyToManyField;
|
|
59
|
+
export declare function isOneToOneField(ormField: Field): ormField is OneToOneField;
|
|
60
|
+
export declare function isPolymorphicField(ormField: Field): ormField is PolymorphicField;
|
|
61
|
+
export declare function isReferenceField(ormField: Field): ormField is ManyToOneField | OneToOneField | PolymorphicField;
|
|
62
|
+
export declare function isCollectionField(ormField: Field): ormField is OneToManyField | ManyToManyField;
|