@uql/core 3.1.0 → 3.1.2
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/CHANGELOG.md +134 -176
- package/README.md +413 -0
- package/package.json +31 -26
- package/dist/package.json +0 -131
- package/src/@types/index.d.ts +0 -1
- package/src/@types/jest.d.ts +0 -6
- package/src/browser/http/bus.spec.ts +0 -22
- package/src/browser/http/bus.ts +0 -17
- package/src/browser/http/http.spec.ts +0 -70
- package/src/browser/http/http.ts +0 -55
- package/src/browser/http/index.ts +0 -2
- package/src/browser/index.ts +0 -4
- package/src/browser/options.spec.ts +0 -37
- package/src/browser/options.ts +0 -18
- package/src/browser/querier/genericClientRepository.spec.ts +0 -105
- package/src/browser/querier/genericClientRepository.ts +0 -49
- package/src/browser/querier/httpQuerier.ts +0 -82
- package/src/browser/querier/index.ts +0 -3
- package/src/browser/querier/querier.util.spec.ts +0 -35
- package/src/browser/querier/querier.util.ts +0 -18
- package/src/browser/type/clientQuerier.ts +0 -45
- package/src/browser/type/clientQuerierPool.ts +0 -5
- package/src/browser/type/clientRepository.ts +0 -22
- package/src/browser/type/index.ts +0 -4
- package/src/browser/type/request.ts +0 -25
- package/src/dialect/abstractDialect.ts +0 -28
- package/src/dialect/abstractSqlDialect-spec.ts +0 -1309
- package/src/dialect/abstractSqlDialect.ts +0 -805
- package/src/dialect/index.ts +0 -3
- package/src/dialect/namingStrategy.spec.ts +0 -52
- package/src/dialect/queryContext.ts +0 -69
- package/src/entity/decorator/definition.spec.ts +0 -736
- package/src/entity/decorator/definition.ts +0 -265
- package/src/entity/decorator/entity.ts +0 -8
- package/src/entity/decorator/field.ts +0 -9
- package/src/entity/decorator/id.ts +0 -9
- package/src/entity/decorator/index.ts +0 -5
- package/src/entity/decorator/relation.spec.ts +0 -41
- package/src/entity/decorator/relation.ts +0 -34
- package/src/entity/index.ts +0 -1
- package/src/express/@types/express.d.ts +0 -8
- package/src/express/@types/index.d.ts +0 -1
- package/src/express/index.ts +0 -2
- package/src/express/querierMiddleware.ts +0 -217
- package/src/express/query.util.spec.ts +0 -40
- package/src/express/query.util.ts +0 -21
- package/src/index.ts +0 -9
- package/src/maria/index.ts +0 -3
- package/src/maria/mariaDialect.spec.ts +0 -207
- package/src/maria/mariaDialect.ts +0 -42
- package/src/maria/mariaQuerierPool.test.ts +0 -23
- package/src/maria/mariadbQuerier.test.ts +0 -23
- package/src/maria/mariadbQuerier.ts +0 -45
- package/src/maria/mariadbQuerierPool.ts +0 -21
- package/src/migrate/cli.ts +0 -301
- package/src/migrate/generator/index.ts +0 -4
- package/src/migrate/generator/mongoSchemaGenerator.spec.ts +0 -112
- package/src/migrate/generator/mongoSchemaGenerator.ts +0 -115
- package/src/migrate/generator/mysqlSchemaGenerator.spec.ts +0 -34
- package/src/migrate/generator/mysqlSchemaGenerator.ts +0 -92
- package/src/migrate/generator/postgresSchemaGenerator.spec.ts +0 -44
- package/src/migrate/generator/postgresSchemaGenerator.ts +0 -127
- package/src/migrate/generator/sqliteSchemaGenerator.spec.ts +0 -33
- package/src/migrate/generator/sqliteSchemaGenerator.ts +0 -81
- package/src/migrate/index.ts +0 -41
- package/src/migrate/introspection/index.ts +0 -4
- package/src/migrate/introspection/mongoIntrospector.spec.ts +0 -75
- package/src/migrate/introspection/mongoIntrospector.ts +0 -47
- package/src/migrate/introspection/mysqlIntrospector.spec.ts +0 -113
- package/src/migrate/introspection/mysqlIntrospector.ts +0 -278
- package/src/migrate/introspection/postgresIntrospector.spec.ts +0 -112
- package/src/migrate/introspection/postgresIntrospector.ts +0 -329
- package/src/migrate/introspection/sqliteIntrospector.spec.ts +0 -112
- package/src/migrate/introspection/sqliteIntrospector.ts +0 -296
- package/src/migrate/migrator-mongo.test.ts +0 -54
- package/src/migrate/migrator.spec.ts +0 -255
- package/src/migrate/migrator.test.ts +0 -94
- package/src/migrate/migrator.ts +0 -719
- package/src/migrate/namingStrategy.spec.ts +0 -22
- package/src/migrate/schemaGenerator-advanced.spec.ts +0 -138
- package/src/migrate/schemaGenerator.spec.ts +0 -190
- package/src/migrate/schemaGenerator.ts +0 -478
- package/src/migrate/storage/databaseStorage.spec.ts +0 -69
- package/src/migrate/storage/databaseStorage.ts +0 -100
- package/src/migrate/storage/index.ts +0 -2
- package/src/migrate/storage/jsonStorage.ts +0 -58
- package/src/migrate/type.ts +0 -1
- package/src/mongo/index.ts +0 -3
- package/src/mongo/mongoDialect.spec.ts +0 -251
- package/src/mongo/mongoDialect.ts +0 -238
- package/src/mongo/mongodbQuerier.test.ts +0 -45
- package/src/mongo/mongodbQuerier.ts +0 -256
- package/src/mongo/mongodbQuerierPool.test.ts +0 -25
- package/src/mongo/mongodbQuerierPool.ts +0 -24
- package/src/mysql/index.ts +0 -3
- package/src/mysql/mysql2Querier.test.ts +0 -20
- package/src/mysql/mysql2Querier.ts +0 -49
- package/src/mysql/mysql2QuerierPool.test.ts +0 -20
- package/src/mysql/mysql2QuerierPool.ts +0 -21
- package/src/mysql/mysqlDialect.spec.ts +0 -20
- package/src/mysql/mysqlDialect.ts +0 -16
- package/src/namingStrategy/defaultNamingStrategy.ts +0 -18
- package/src/namingStrategy/index.spec.ts +0 -36
- package/src/namingStrategy/index.ts +0 -2
- package/src/namingStrategy/snakeCaseNamingStrategy.ts +0 -15
- package/src/options.spec.ts +0 -41
- package/src/options.ts +0 -18
- package/src/postgres/index.ts +0 -3
- package/src/postgres/manual-types.d.ts +0 -4
- package/src/postgres/pgQuerier.test.ts +0 -25
- package/src/postgres/pgQuerier.ts +0 -45
- package/src/postgres/pgQuerierPool.test.ts +0 -28
- package/src/postgres/pgQuerierPool.ts +0 -21
- package/src/postgres/postgresDialect.spec.ts +0 -428
- package/src/postgres/postgresDialect.ts +0 -144
- package/src/querier/abstractQuerier-test.ts +0 -584
- package/src/querier/abstractQuerier.ts +0 -353
- package/src/querier/abstractQuerierPool-test.ts +0 -20
- package/src/querier/abstractQuerierPool.ts +0 -18
- package/src/querier/abstractSqlQuerier-spec.ts +0 -979
- package/src/querier/abstractSqlQuerier-test.ts +0 -21
- package/src/querier/abstractSqlQuerier.ts +0 -138
- package/src/querier/decorator/index.ts +0 -3
- package/src/querier/decorator/injectQuerier.spec.ts +0 -74
- package/src/querier/decorator/injectQuerier.ts +0 -45
- package/src/querier/decorator/serialized.spec.ts +0 -98
- package/src/querier/decorator/serialized.ts +0 -13
- package/src/querier/decorator/transactional.spec.ts +0 -240
- package/src/querier/decorator/transactional.ts +0 -56
- package/src/querier/index.ts +0 -4
- package/src/repository/genericRepository.spec.ts +0 -111
- package/src/repository/genericRepository.ts +0 -74
- package/src/repository/index.ts +0 -1
- package/src/sqlite/index.ts +0 -3
- package/src/sqlite/manual-types.d.ts +0 -4
- package/src/sqlite/sqliteDialect.spec.ts +0 -155
- package/src/sqlite/sqliteDialect.ts +0 -76
- package/src/sqlite/sqliteQuerier.spec.ts +0 -36
- package/src/sqlite/sqliteQuerier.test.ts +0 -21
- package/src/sqlite/sqliteQuerier.ts +0 -37
- package/src/sqlite/sqliteQuerierPool.test.ts +0 -12
- package/src/sqlite/sqliteQuerierPool.ts +0 -38
- package/src/test/entityMock.ts +0 -375
- package/src/test/index.ts +0 -3
- package/src/test/it.util.ts +0 -69
- package/src/test/spec.util.ts +0 -57
- package/src/type/entity.ts +0 -218
- package/src/type/index.ts +0 -9
- package/src/type/migration.ts +0 -241
- package/src/type/namingStrategy.ts +0 -17
- package/src/type/querier.ts +0 -143
- package/src/type/querierPool.ts +0 -26
- package/src/type/query.ts +0 -506
- package/src/type/repository.ts +0 -142
- package/src/type/universalQuerier.ts +0 -133
- package/src/type/utility.ts +0 -21
- package/src/util/dialect.util-extra.spec.ts +0 -96
- package/src/util/dialect.util.spec.ts +0 -23
- package/src/util/dialect.util.ts +0 -134
- package/src/util/index.ts +0 -5
- package/src/util/object.util.spec.ts +0 -29
- package/src/util/object.util.ts +0 -27
- package/src/util/raw.ts +0 -11
- package/src/util/sql.util-extra.spec.ts +0 -17
- package/src/util/sql.util.spec.ts +0 -208
- package/src/util/sql.util.ts +0 -104
- package/src/util/string.util.spec.ts +0 -46
- package/src/util/string.util.ts +0 -35
- package/tsconfig.build.json +0 -5
- package/tsconfig.json +0 -8
|
@@ -1,353 +0,0 @@
|
|
|
1
|
-
import { getMeta } from '../entity/decorator/index.js';
|
|
2
|
-
import { GenericRepository } from '../repository/index.js';
|
|
3
|
-
import type {
|
|
4
|
-
IdValue,
|
|
5
|
-
Key,
|
|
6
|
-
Querier,
|
|
7
|
-
Query,
|
|
8
|
-
QueryConflictPaths,
|
|
9
|
-
QueryOne,
|
|
10
|
-
QueryOptions,
|
|
11
|
-
QuerySearch,
|
|
12
|
-
QuerySelect,
|
|
13
|
-
QueryUpdateResult,
|
|
14
|
-
RelationKey,
|
|
15
|
-
RelationValue,
|
|
16
|
-
Repository,
|
|
17
|
-
Type,
|
|
18
|
-
} from '../type/index.js';
|
|
19
|
-
import { augmentWhere, clone, filterPersistableRelationKeys, filterRelationKeys, getKeys } from '../util/index.js';
|
|
20
|
-
import { Serialized } from './decorator/index.js';
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Base class for all database queriers.
|
|
24
|
-
* It provides a standardized way to execute tasks serially to prevent race conditions on database connections.
|
|
25
|
-
*/
|
|
26
|
-
export abstract class AbstractQuerier implements Querier {
|
|
27
|
-
/**
|
|
28
|
-
* Internal promise used to queue database operations.
|
|
29
|
-
* This ensures that each operation is executed serially, preventing race conditions
|
|
30
|
-
* and ensuring that the database connection is used safely across concurrent calls.
|
|
31
|
-
*/
|
|
32
|
-
private taskQueue: Promise<unknown> = Promise.resolve();
|
|
33
|
-
|
|
34
|
-
findOneById<E>(entity: Type<E>, id: IdValue<E>, q: QueryOne<E> = {}) {
|
|
35
|
-
const meta = getMeta(entity);
|
|
36
|
-
q.$where = augmentWhere(meta, q.$where, id);
|
|
37
|
-
return this.findOne(entity, q);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
async findOne<E>(entity: Type<E>, q: QueryOne<E>) {
|
|
41
|
-
const rows = await this.findMany(entity, { ...q, $limit: 1 });
|
|
42
|
-
return rows[0];
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
abstract findMany<E>(entity: Type<E>, q: Query<E>): Promise<E[]>;
|
|
46
|
-
|
|
47
|
-
findManyAndCount<E>(entity: Type<E>, q: Query<E>) {
|
|
48
|
-
const qCount = {
|
|
49
|
-
...q,
|
|
50
|
-
} satisfies QuerySearch<E>;
|
|
51
|
-
delete qCount.$sort;
|
|
52
|
-
delete qCount.$limit;
|
|
53
|
-
delete qCount.$skip;
|
|
54
|
-
return Promise.all([this.findMany(entity, q), this.count(entity, qCount)]);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
abstract count<E>(entity: Type<E>, q: QuerySearch<E>): Promise<number>;
|
|
58
|
-
|
|
59
|
-
async insertOne<E>(entity: Type<E>, payload: E) {
|
|
60
|
-
const [id] = await this.insertMany(entity, [payload]);
|
|
61
|
-
return id;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
abstract insertMany<E>(entity: Type<E>, payload: E[]): Promise<IdValue<E>[]>;
|
|
65
|
-
|
|
66
|
-
updateOneById<E>(entity: Type<E>, id: IdValue<E>, payload: E) {
|
|
67
|
-
return this.updateMany(entity, { $where: id }, payload);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
abstract updateMany<E>(entity: Type<E>, q: QuerySearch<E>, payload: E): Promise<number>;
|
|
71
|
-
|
|
72
|
-
abstract upsertOne<E>(entity: Type<E>, conflictPaths: QueryConflictPaths<E>, payload: E): Promise<QueryUpdateResult>;
|
|
73
|
-
|
|
74
|
-
deleteOneById<E>(entity: Type<E>, id: IdValue<E>, opts?: QueryOptions) {
|
|
75
|
-
return this.deleteMany(entity, { $where: id }, opts);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
abstract deleteMany<E>(entity: Type<E>, q: QuerySearch<E>, opts?: QueryOptions): Promise<number>;
|
|
79
|
-
|
|
80
|
-
async saveOne<E>(entity: Type<E>, payload: E) {
|
|
81
|
-
const [id] = await this.saveMany(entity, [payload]);
|
|
82
|
-
return id;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
async saveMany<E>(entity: Type<E>, payload: E[]) {
|
|
86
|
-
const meta = getMeta(entity);
|
|
87
|
-
const ids: IdValue<E>[] = [];
|
|
88
|
-
const updates: E[] = [];
|
|
89
|
-
const inserts: E[] = [];
|
|
90
|
-
|
|
91
|
-
for (const it of payload) {
|
|
92
|
-
if (it[meta.id]) {
|
|
93
|
-
if (getKeys(it).length === 1) {
|
|
94
|
-
ids.push(it[meta.id]);
|
|
95
|
-
} else {
|
|
96
|
-
updates.push(it);
|
|
97
|
-
}
|
|
98
|
-
} else {
|
|
99
|
-
inserts.push(it);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
return Promise.all([
|
|
104
|
-
...ids,
|
|
105
|
-
...(inserts.length ? await this.insertMany(entity, inserts) : []),
|
|
106
|
-
...updates.map(async (it) => {
|
|
107
|
-
const { [meta.id]: id, ...data } = it;
|
|
108
|
-
await this.updateOneById(entity, id, data as E);
|
|
109
|
-
return id;
|
|
110
|
-
}),
|
|
111
|
-
]);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
protected async fillToManyRelations<E>(entity: Type<E>, payload: E[], select: QuerySelect<E>) {
|
|
115
|
-
if (!payload.length) {
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
const meta = getMeta(entity);
|
|
120
|
-
const relKeys = filterRelationKeys(meta, select);
|
|
121
|
-
|
|
122
|
-
for (const relKey of relKeys) {
|
|
123
|
-
const relOpts = meta.relations[relKey];
|
|
124
|
-
const relEntity = relOpts.entity();
|
|
125
|
-
type RelEntity = typeof relEntity;
|
|
126
|
-
const relSelect = clone(select[relKey as string]);
|
|
127
|
-
const relQuery: Query<RelEntity> =
|
|
128
|
-
relSelect === true || relSelect === undefined
|
|
129
|
-
? {}
|
|
130
|
-
: Array.isArray(relSelect)
|
|
131
|
-
? { $select: relSelect }
|
|
132
|
-
: relSelect;
|
|
133
|
-
const ids = payload.map((it) => it[meta.id]);
|
|
134
|
-
|
|
135
|
-
if (relOpts.through) {
|
|
136
|
-
const localField = relOpts.references[0].local;
|
|
137
|
-
const throughEntity = relOpts.through();
|
|
138
|
-
const throughMeta = getMeta(throughEntity);
|
|
139
|
-
const targetRelKey = getKeys(throughMeta.relations).find((key) =>
|
|
140
|
-
throughMeta.relations[key].references.some(({ local }) => local === relOpts.references[1].local),
|
|
141
|
-
);
|
|
142
|
-
const throughFounds = await this.findMany(throughEntity, {
|
|
143
|
-
...relQuery,
|
|
144
|
-
$select: {
|
|
145
|
-
[localField]: true,
|
|
146
|
-
[targetRelKey]: {
|
|
147
|
-
...relQuery,
|
|
148
|
-
$required: true,
|
|
149
|
-
},
|
|
150
|
-
},
|
|
151
|
-
$where: {
|
|
152
|
-
...relQuery.$where,
|
|
153
|
-
[localField]: ids,
|
|
154
|
-
},
|
|
155
|
-
});
|
|
156
|
-
const founds = throughFounds.map((it) => ({ ...it[targetRelKey], [localField]: it[localField] }));
|
|
157
|
-
this.putChildrenInParents(payload, founds, meta.id, localField, relKey);
|
|
158
|
-
} else if (relOpts.cardinality === '1m') {
|
|
159
|
-
const foreignField = relOpts.references[0].foreign;
|
|
160
|
-
if (relQuery.$select) {
|
|
161
|
-
if (Array.isArray(relQuery.$select)) {
|
|
162
|
-
if (!relQuery.$select.includes(foreignField as Key<RelEntity>)) {
|
|
163
|
-
relQuery.$select.push(foreignField as Key<RelEntity>);
|
|
164
|
-
}
|
|
165
|
-
} else if (!relQuery.$select[foreignField]) {
|
|
166
|
-
relQuery.$select[foreignField] = true;
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
relQuery.$where = { ...relQuery.$where, [foreignField]: ids };
|
|
170
|
-
const founds = await this.findMany(relEntity, relQuery);
|
|
171
|
-
this.putChildrenInParents(payload, founds, meta.id, foreignField, relKey);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
protected putChildrenInParents<E>(
|
|
177
|
-
parents: E[],
|
|
178
|
-
children: E[],
|
|
179
|
-
parentIdKey: string,
|
|
180
|
-
referenceKey: string,
|
|
181
|
-
relKey: string,
|
|
182
|
-
): void {
|
|
183
|
-
const childrenByParentMap = children.reduce((acc, child) => {
|
|
184
|
-
const parenId = child[referenceKey];
|
|
185
|
-
if (!acc[parenId]) {
|
|
186
|
-
acc[parenId] = [];
|
|
187
|
-
}
|
|
188
|
-
acc[parenId].push(child);
|
|
189
|
-
return acc;
|
|
190
|
-
}, {});
|
|
191
|
-
|
|
192
|
-
for (const parent of parents) {
|
|
193
|
-
const parentId = parent[parentIdKey];
|
|
194
|
-
parent[relKey] = childrenByParentMap[parentId];
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
protected async insertRelations<E>(entity: Type<E>, payload: E[]) {
|
|
199
|
-
const meta = getMeta(entity);
|
|
200
|
-
await Promise.all(
|
|
201
|
-
payload.map((it) => {
|
|
202
|
-
const relKeys = filterPersistableRelationKeys(meta, it, 'persist');
|
|
203
|
-
if (!relKeys.length) {
|
|
204
|
-
return Promise.resolve();
|
|
205
|
-
}
|
|
206
|
-
return Promise.all(relKeys.map((relKey) => this.saveRelation(entity, it, relKey)));
|
|
207
|
-
}),
|
|
208
|
-
);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
protected async updateRelations<E>(entity: Type<E>, q: QuerySearch<E>, payload: E) {
|
|
212
|
-
const meta = getMeta(entity);
|
|
213
|
-
const relKeys = filterPersistableRelationKeys(meta, payload, 'persist');
|
|
214
|
-
|
|
215
|
-
if (!relKeys.length) {
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
const founds = await this.findMany(entity, { ...q, $select: [meta.id] });
|
|
220
|
-
const ids = founds.map((found) => found[meta.id]);
|
|
221
|
-
|
|
222
|
-
await Promise.all(
|
|
223
|
-
ids.map((id) =>
|
|
224
|
-
Promise.all(relKeys.map((relKey) => this.saveRelation(entity, { ...payload, [meta.id]: id }, relKey, true))),
|
|
225
|
-
),
|
|
226
|
-
);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
protected async deleteRelations<E>(entity: Type<E>, ids: IdValue<E>[], opts?: QueryOptions) {
|
|
230
|
-
const meta = getMeta(entity);
|
|
231
|
-
const relKeys = filterPersistableRelationKeys(meta, meta.relations as E, 'delete');
|
|
232
|
-
|
|
233
|
-
for (const relKey of relKeys) {
|
|
234
|
-
const relOpts = meta.relations[relKey];
|
|
235
|
-
const relEntity = relOpts.entity();
|
|
236
|
-
const localField = relOpts.references[0].local;
|
|
237
|
-
if (relOpts.through) {
|
|
238
|
-
const throughEntity = relOpts.through();
|
|
239
|
-
await this.deleteMany(throughEntity, { $where: { [localField]: ids } }, opts);
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
await this.deleteMany(relEntity, { [localField]: ids }, opts);
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
protected async saveRelation<E>(entity: Type<E>, payload: E, relKey: RelationKey<E>, isUpdate?: boolean) {
|
|
247
|
-
const meta = getMeta(entity);
|
|
248
|
-
const id = payload[meta.id];
|
|
249
|
-
const { entity: entityGetter, cardinality, references, through } = meta.relations[relKey];
|
|
250
|
-
const relEntity = entityGetter();
|
|
251
|
-
const relPayload = payload[relKey] as unknown as RelationValue<E>[];
|
|
252
|
-
|
|
253
|
-
if (cardinality === '1m' || cardinality === 'mm') {
|
|
254
|
-
if (through) {
|
|
255
|
-
const localField = references[0].local;
|
|
256
|
-
|
|
257
|
-
const throughEntity = through();
|
|
258
|
-
if (isUpdate) {
|
|
259
|
-
await this.deleteMany(throughEntity, { $where: { [localField]: id } });
|
|
260
|
-
}
|
|
261
|
-
if (relPayload) {
|
|
262
|
-
const savedIds = await this.saveMany(relEntity, relPayload);
|
|
263
|
-
const throughBodies = savedIds.map((relId) => ({
|
|
264
|
-
[references[0].local]: id,
|
|
265
|
-
[references[1].local]: relId,
|
|
266
|
-
}));
|
|
267
|
-
await this.insertMany(throughEntity, throughBodies);
|
|
268
|
-
}
|
|
269
|
-
return;
|
|
270
|
-
}
|
|
271
|
-
const foreignField = references[0].foreign;
|
|
272
|
-
if (isUpdate) {
|
|
273
|
-
await this.deleteMany(relEntity, { $where: { [foreignField]: id } });
|
|
274
|
-
}
|
|
275
|
-
if (relPayload) {
|
|
276
|
-
for (const it of relPayload) {
|
|
277
|
-
it[foreignField] = id;
|
|
278
|
-
}
|
|
279
|
-
await this.saveMany(relEntity, relPayload);
|
|
280
|
-
}
|
|
281
|
-
return;
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
if (cardinality === '11') {
|
|
285
|
-
const foreignField = references[0].foreign;
|
|
286
|
-
if (relPayload === null) {
|
|
287
|
-
await this.deleteMany(relEntity, { $where: { [foreignField]: id } });
|
|
288
|
-
return;
|
|
289
|
-
}
|
|
290
|
-
await this.saveOne(relEntity, { ...relPayload, [foreignField]: id });
|
|
291
|
-
return;
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
if (cardinality === 'm1' && relPayload) {
|
|
295
|
-
const localField = references[0].local;
|
|
296
|
-
const referenceId = await this.insertOne(relEntity, relPayload);
|
|
297
|
-
await this.updateOneById(entity, id, { [localField]: referenceId });
|
|
298
|
-
return;
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
getRepository<E>(entity: Type<E>): Repository<E> {
|
|
303
|
-
return new GenericRepository(entity, this);
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
abstract readonly hasOpenTransaction: boolean;
|
|
307
|
-
|
|
308
|
-
async transaction<T>(callback: () => Promise<T>) {
|
|
309
|
-
try {
|
|
310
|
-
await this.beginTransaction();
|
|
311
|
-
const res = await callback();
|
|
312
|
-
await this.commitTransaction();
|
|
313
|
-
return res;
|
|
314
|
-
} catch (err) {
|
|
315
|
-
await this.rollbackTransaction();
|
|
316
|
-
throw err;
|
|
317
|
-
} finally {
|
|
318
|
-
await this.release();
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
async releaseIfFree() {
|
|
323
|
-
if (!this.hasOpenTransaction) {
|
|
324
|
-
await this.internalRelease();
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
/**
|
|
329
|
-
* Schedules a task to be executed serially in the querier instance.
|
|
330
|
-
* This is used by the @Serialized decorator to protect database-level operations.
|
|
331
|
-
*
|
|
332
|
-
* @param task - The async task to execute.
|
|
333
|
-
* @returns A promise that resolves with the task's result.
|
|
334
|
-
*/
|
|
335
|
-
protected async serialize<T>(task: () => Promise<T>): Promise<T> {
|
|
336
|
-
const res = this.taskQueue.then(task);
|
|
337
|
-
this.taskQueue = res.catch(() => {});
|
|
338
|
-
return res;
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
abstract beginTransaction(): Promise<void>;
|
|
342
|
-
|
|
343
|
-
abstract commitTransaction(): Promise<void>;
|
|
344
|
-
|
|
345
|
-
abstract rollbackTransaction(): Promise<void>;
|
|
346
|
-
|
|
347
|
-
protected abstract internalRelease(): Promise<void>;
|
|
348
|
-
|
|
349
|
-
@Serialized()
|
|
350
|
-
async release(): Promise<void> {
|
|
351
|
-
return this.internalRelease();
|
|
352
|
-
}
|
|
353
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { expect } from 'bun:test';
|
|
2
|
-
import { AbstractQuerier } from '../querier/index.js';
|
|
3
|
-
import type { Spec } from '../test/index.js';
|
|
4
|
-
import type { Querier } from '../type/index.js';
|
|
5
|
-
import type { AbstractQuerierPool } from './abstractQuerierPool.js';
|
|
6
|
-
|
|
7
|
-
export abstract class AbstractQuerierPoolIt<Q extends Querier> implements Spec {
|
|
8
|
-
constructor(protected pool: AbstractQuerierPool<Q>) {}
|
|
9
|
-
|
|
10
|
-
async afterAll() {
|
|
11
|
-
await this.pool.end();
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
async shouldGetQuerier() {
|
|
15
|
-
const querier = await this.pool.getQuerier();
|
|
16
|
-
expect(querier).toBeInstanceOf(AbstractQuerier);
|
|
17
|
-
expect(querier.hasOpenTransaction).toBeFalsy();
|
|
18
|
-
await querier.release();
|
|
19
|
-
}
|
|
20
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { Dialect, ExtraOptions, Querier, QuerierPool } from '../type/index.js';
|
|
2
|
-
|
|
3
|
-
export abstract class AbstractQuerierPool<Q extends Querier> implements QuerierPool<Q> {
|
|
4
|
-
constructor(
|
|
5
|
-
readonly dialect: Dialect,
|
|
6
|
-
readonly extra?: ExtraOptions,
|
|
7
|
-
) {}
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* get a querier from the pool.
|
|
11
|
-
*/
|
|
12
|
-
abstract getQuerier(): Promise<Q>;
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* end the pool.
|
|
16
|
-
*/
|
|
17
|
-
abstract end(): Promise<void>;
|
|
18
|
-
}
|