sonamu 0.2.48 → 0.2.49
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/dist/bin/cli-wrapper.js +12 -2
- package/dist/bin/cli-wrapper.js.map +1 -1
- package/dist/bin/cli.js +54 -62
- package/dist/bin/cli.js.map +1 -1
- package/dist/{chunk-76VBQWGE.js → chunk-HATLA54Z.js} +167 -97
- package/dist/chunk-HATLA54Z.js.map +1 -0
- package/dist/index.d.ts +15 -7
- package/dist/index.js +3 -3
- package/package.json +1 -1
- package/src/api/sonamu.ts +3 -2
- package/src/bin/cli-wrapper.ts +20 -1
- package/src/bin/cli.ts +5 -15
- package/src/database/_batch_update.ts +29 -14
- package/src/database/upsert-builder.ts +56 -42
- package/src/testing/fixture-manager.ts +122 -36
- package/src/types/types.ts +3 -2
- package/src/utils/utils.ts +15 -13
- package/dist/chunk-76VBQWGE.js.map +0 -1
|
@@ -842,19 +842,19 @@ function globAsync(pathPattern) {
|
|
|
842
842
|
});
|
|
843
843
|
}
|
|
844
844
|
async function importMultiple(filePaths, doRefresh = false) {
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
845
|
+
const results = [];
|
|
846
|
+
for (const filePath of filePaths) {
|
|
847
|
+
const importPath = "./" + _path2.default.relative(__dirname, filePath);
|
|
848
|
+
if (doRefresh) {
|
|
849
|
+
delete __require.cache[__require.resolve(importPath)];
|
|
850
|
+
}
|
|
851
|
+
const imported = await Promise.resolve().then(() => _interopRequireWildcard(require(importPath)));
|
|
852
|
+
results.push({
|
|
853
|
+
filePath,
|
|
854
|
+
imported
|
|
855
|
+
});
|
|
856
|
+
}
|
|
857
|
+
return results;
|
|
858
858
|
}
|
|
859
859
|
async function findAppRootPath() {
|
|
860
860
|
const apiRootPath = await findApiRootPath();
|
|
@@ -4215,13 +4215,13 @@ var _uuid = require('uuid');
|
|
|
4215
4215
|
|
|
4216
4216
|
|
|
4217
4217
|
// src/database/_batch_update.ts
|
|
4218
|
-
async function batchUpdate(knex5, tableName,
|
|
4218
|
+
async function batchUpdate(knex5, tableName, ids, rows, chunkSize = 50, trx = null) {
|
|
4219
4219
|
const chunks = [];
|
|
4220
4220
|
for (let i = 0; i < rows.length; i += chunkSize) {
|
|
4221
4221
|
chunks.push(rows.slice(i, i + chunkSize));
|
|
4222
4222
|
}
|
|
4223
4223
|
const executeUpdate = async (chunk, transaction) => {
|
|
4224
|
-
const sql = generateBatchUpdateSQL(knex5, tableName, chunk,
|
|
4224
|
+
const sql = generateBatchUpdateSQL(knex5, tableName, chunk, ids);
|
|
4225
4225
|
return knex5.raw(sql).transacting(transaction);
|
|
4226
4226
|
};
|
|
4227
4227
|
if (trx) {
|
|
@@ -4245,31 +4245,38 @@ function generateKeySetFromData(data) {
|
|
|
4245
4245
|
}
|
|
4246
4246
|
return keySet;
|
|
4247
4247
|
}
|
|
4248
|
-
function generateBatchUpdateSQL(knex5, tableName, data,
|
|
4248
|
+
function generateBatchUpdateSQL(knex5, tableName, data, identifiers) {
|
|
4249
4249
|
const keySet = generateKeySetFromData(data);
|
|
4250
4250
|
const bindings = [];
|
|
4251
|
+
const invalidIdentifiers = identifiers.filter((id) => !keySet.has(id));
|
|
4252
|
+
if (invalidIdentifiers.length > 0) {
|
|
4253
|
+
throw new Error(
|
|
4254
|
+
`Invalid identifiers: ${invalidIdentifiers.join(", ")}. Identifiers must exist in the data`
|
|
4255
|
+
);
|
|
4256
|
+
}
|
|
4251
4257
|
const cases = [];
|
|
4252
4258
|
for (const key of keySet) {
|
|
4253
|
-
if (key
|
|
4259
|
+
if (identifiers.includes(key)) continue;
|
|
4254
4260
|
const rows = [];
|
|
4255
4261
|
for (const row of data) {
|
|
4256
4262
|
if (Object.hasOwnProperty.call(row, key)) {
|
|
4257
|
-
|
|
4258
|
-
|
|
4263
|
+
const whereClause = identifiers.map((id) => `\`${id}\` = ?`).join(" AND ");
|
|
4264
|
+
rows.push(`WHEN (${whereClause}) THEN ?`);
|
|
4265
|
+
bindings.push(...identifiers.map((i) => row[i]), row[key]);
|
|
4259
4266
|
}
|
|
4260
4267
|
}
|
|
4261
4268
|
const whenThen = rows.join(" ");
|
|
4262
4269
|
cases.push(`\`${key}\` = CASE ${whenThen} ELSE \`${key}\` END`);
|
|
4263
4270
|
}
|
|
4264
|
-
const
|
|
4265
|
-
const
|
|
4271
|
+
const whereInClauses = identifiers.map((col) => `${col} IN (${data.map(() => "?").join(", ")})`).join(" AND ");
|
|
4272
|
+
const whereInBindings = identifiers.flatMap(
|
|
4273
|
+
(col) => data.map((row) => row[col])
|
|
4274
|
+
);
|
|
4266
4275
|
const sql = knex5.raw(
|
|
4267
|
-
`UPDATE \`${tableName}\` SET ${cases.join(
|
|
4268
|
-
|
|
4269
|
-
)} WHERE ${identifier} IN (${whereInPlaceholders})`,
|
|
4270
|
-
[...bindings, ...whereInIds]
|
|
4276
|
+
`UPDATE \`${tableName}\` SET ${cases.join(", ")} WHERE ${whereInClauses}`,
|
|
4277
|
+
[...bindings, ...whereInBindings]
|
|
4271
4278
|
);
|
|
4272
|
-
return sql.
|
|
4279
|
+
return sql.toQuery();
|
|
4273
4280
|
}
|
|
4274
4281
|
|
|
4275
4282
|
// src/database/upsert-builder.ts
|
|
@@ -4355,13 +4362,13 @@ var UpsertBuilder = class {
|
|
|
4355
4362
|
uuid: _nullishCoalesce(row.uuid, () => ( uuid))
|
|
4356
4363
|
};
|
|
4357
4364
|
}
|
|
4358
|
-
async upsert(wdb, tableName) {
|
|
4359
|
-
return this.upsertOrInsert(wdb, tableName, "upsert");
|
|
4365
|
+
async upsert(wdb, tableName, chunkSize) {
|
|
4366
|
+
return this.upsertOrInsert(wdb, tableName, "upsert", chunkSize);
|
|
4360
4367
|
}
|
|
4361
|
-
async insertOnly(wdb, tableName) {
|
|
4362
|
-
return this.upsertOrInsert(wdb, tableName, "insert");
|
|
4368
|
+
async insertOnly(wdb, tableName, chunkSize) {
|
|
4369
|
+
return this.upsertOrInsert(wdb, tableName, "insert", chunkSize);
|
|
4363
4370
|
}
|
|
4364
|
-
async upsertOrInsert(wdb, tableName, mode) {
|
|
4371
|
+
async upsertOrInsert(wdb, tableName, mode, chunkSize) {
|
|
4365
4372
|
if (this.hasTable(tableName) === false) {
|
|
4366
4373
|
return [];
|
|
4367
4374
|
}
|
|
@@ -4378,17 +4385,6 @@ var UpsertBuilder = class {
|
|
|
4378
4385
|
)) {
|
|
4379
4386
|
throw new Error(`${tableName} \uD574\uACB0\uB418\uC9C0 \uC54A\uC740 \uCC38\uC870\uAC00 \uC788\uC2B5\uB2C8\uB2E4.`);
|
|
4380
4387
|
}
|
|
4381
|
-
const groups = _lodash2.default.groupBy(
|
|
4382
|
-
table.rows,
|
|
4383
|
-
(row) => Object.entries(row).some(([, value]) => isRefField(value)) ? "selfRef" : "normal"
|
|
4384
|
-
);
|
|
4385
|
-
const targetRows = groups.normal;
|
|
4386
|
-
const q = wdb.insert(targetRows).into(tableName);
|
|
4387
|
-
if (mode === "insert") {
|
|
4388
|
-
await q;
|
|
4389
|
-
} else if (mode === "upsert") {
|
|
4390
|
-
await q.onDuplicateUpdate.apply(q, Object.keys(targetRows[0]));
|
|
4391
|
-
}
|
|
4392
4388
|
const { references, refTables } = Array.from(this.tables).reduce(
|
|
4393
4389
|
(r, [, table2]) => {
|
|
4394
4390
|
const reference = Array.from(table2.references.values()).find(
|
|
@@ -4408,11 +4404,27 @@ var UpsertBuilder = class {
|
|
|
4408
4404
|
const extractFields = _lodash2.default.uniq(references).map(
|
|
4409
4405
|
(reference) => reference.split(".")[1]
|
|
4410
4406
|
);
|
|
4411
|
-
const
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
upsertedRows.map((row) => [row.uuid, row])
|
|
4407
|
+
const groups = _lodash2.default.groupBy(
|
|
4408
|
+
table.rows,
|
|
4409
|
+
(row) => Object.entries(row).some(([, value]) => isRefField(value)) ? "selfRef" : "normal"
|
|
4415
4410
|
);
|
|
4411
|
+
const normalRows = _nullishCoalesce(groups.normal, () => ( []));
|
|
4412
|
+
const selfRefRows = _nullishCoalesce(groups.selfRef, () => ( []));
|
|
4413
|
+
const chunks = chunkSize ? _lodash2.default.chunk(normalRows, chunkSize) : [normalRows];
|
|
4414
|
+
const uuidMap = /* @__PURE__ */ new Map();
|
|
4415
|
+
for (const chunk of chunks) {
|
|
4416
|
+
const q = wdb.insert(chunk).into(tableName);
|
|
4417
|
+
if (mode === "insert") {
|
|
4418
|
+
await q;
|
|
4419
|
+
} else if (mode === "upsert") {
|
|
4420
|
+
await q.onDuplicateUpdate.apply(q, Object.keys(normalRows[0]));
|
|
4421
|
+
}
|
|
4422
|
+
const uuids = chunk.map((row) => row.uuid);
|
|
4423
|
+
const upsertedRows = await wdb(tableName).select(_lodash2.default.uniq(["uuid", "id", ...extractFields])).whereIn("uuid", uuids);
|
|
4424
|
+
upsertedRows.forEach((row) => {
|
|
4425
|
+
uuidMap.set(row.uuid, row);
|
|
4426
|
+
});
|
|
4427
|
+
}
|
|
4416
4428
|
refTables.map((table2) => {
|
|
4417
4429
|
table2.rows = table2.rows.map((row) => {
|
|
4418
4430
|
Object.keys(row).map((key) => {
|
|
@@ -4431,12 +4443,13 @@ var UpsertBuilder = class {
|
|
|
4431
4443
|
return row;
|
|
4432
4444
|
});
|
|
4433
4445
|
});
|
|
4434
|
-
const
|
|
4435
|
-
if (
|
|
4436
|
-
|
|
4437
|
-
|
|
4446
|
+
const allIds = Array.from(uuidMap.values()).map((row) => row.id);
|
|
4447
|
+
if (selfRefRows.length > 0) {
|
|
4448
|
+
table.rows = selfRefRows;
|
|
4449
|
+
const selfRefIds = await this.upsert(wdb, tableName, chunkSize);
|
|
4450
|
+
allIds.push(...selfRefIds);
|
|
4438
4451
|
}
|
|
4439
|
-
return
|
|
4452
|
+
return allIds;
|
|
4440
4453
|
}
|
|
4441
4454
|
async updateBatch(wdb, tableName, options) {
|
|
4442
4455
|
options = _lodash2.default.defaults(options, {
|
|
@@ -4450,17 +4463,12 @@ var UpsertBuilder = class {
|
|
|
4450
4463
|
if (table.rows.length === 0) {
|
|
4451
4464
|
return;
|
|
4452
4465
|
}
|
|
4466
|
+
const whereColumns = Array.isArray(options.where) ? options.where : [_nullishCoalesce(options.where, () => ( "id"))];
|
|
4453
4467
|
const rows = table.rows.map((_row) => {
|
|
4454
4468
|
const { uuid, ...row } = _row;
|
|
4455
4469
|
return row;
|
|
4456
4470
|
});
|
|
4457
|
-
await batchUpdate(
|
|
4458
|
-
wdb,
|
|
4459
|
-
tableName,
|
|
4460
|
-
_nullishCoalesce(options.where, () => ( "id")),
|
|
4461
|
-
rows,
|
|
4462
|
-
options.chunkSize
|
|
4463
|
-
);
|
|
4471
|
+
await batchUpdate(wdb, tableName, whereColumns, rows, options.chunkSize);
|
|
4464
4472
|
}
|
|
4465
4473
|
};
|
|
4466
4474
|
|
|
@@ -4881,9 +4889,9 @@ var SonamuClass = class {
|
|
|
4881
4889
|
this.isInitialized = true;
|
|
4882
4890
|
!doSilent && console.timeEnd(_chalk2.default.cyan("Sonamu.init"));
|
|
4883
4891
|
}
|
|
4884
|
-
async withFastify(server, config) {
|
|
4892
|
+
async withFastify(server, config, options) {
|
|
4885
4893
|
if (this.isInitialized === false) {
|
|
4886
|
-
await this.init();
|
|
4894
|
+
await this.init(_optionalChain([options, 'optionalAccess', _83 => _83.doSilent]), _optionalChain([options, 'optionalAccess', _84 => _84.enableSync]));
|
|
4887
4895
|
}
|
|
4888
4896
|
server.get(
|
|
4889
4897
|
`${this.config.route.prefix}/routes`,
|
|
@@ -5301,7 +5309,7 @@ var Entity = class {
|
|
|
5301
5309
|
const relSubsetQuery = relEntity.resolveSubsetQuery("", relFields);
|
|
5302
5310
|
let manyJoin;
|
|
5303
5311
|
if (isHasManyRelationProp(relation)) {
|
|
5304
|
-
const fromCol = _nullishCoalesce(_optionalChain([relation, 'optionalAccess',
|
|
5312
|
+
const fromCol = _nullishCoalesce(_optionalChain([relation, 'optionalAccess', _85 => _85.fromColumn]), () => ( "id"));
|
|
5305
5313
|
manyJoin = {
|
|
5306
5314
|
fromTable: this.table,
|
|
5307
5315
|
fromCol,
|
|
@@ -6506,7 +6514,7 @@ ${onlyTs.map((f) => f.name).join("\n")}`
|
|
|
6506
6514
|
const [, keyName, from, referencesTable, referencesField, onClause] = matched2;
|
|
6507
6515
|
const [onUpdateFull, _onUpdate] = _nullishCoalesce((_nullishCoalesce(onClause, () => ( ""))).match(/ON UPDATE ([A-Z ]+)$/), () => ( []));
|
|
6508
6516
|
const onUpdate = _nullishCoalesce(_onUpdate, () => ( "NO ACTION"));
|
|
6509
|
-
const onDelete = _nullishCoalesce(_optionalChain([(_nullishCoalesce(onClause, () => ( ""))), 'access',
|
|
6517
|
+
const onDelete = _nullishCoalesce(_optionalChain([(_nullishCoalesce(onClause, () => ( ""))), 'access', _86 => _86.replace, 'call', _87 => _87(_nullishCoalesce(onUpdateFull, () => ( "")), ""), 'access', _88 => _88.match, 'call', _89 => _89(/ON DELETE ([A-Z ]+) /), 'optionalAccess', _90 => _90[1]]), () => ( "NO ACTION"));
|
|
6510
6518
|
return {
|
|
6511
6519
|
keyName,
|
|
6512
6520
|
from,
|
|
@@ -7289,6 +7297,9 @@ var FixtureManagerClass = class {
|
|
|
7289
7297
|
await transaction.raw(`SET FOREIGN_KEY_CHECKS = 0`);
|
|
7290
7298
|
await transaction(tableName).truncate();
|
|
7291
7299
|
const rows = await frdb(tableName);
|
|
7300
|
+
if (rows.length === 0) {
|
|
7301
|
+
return;
|
|
7302
|
+
}
|
|
7292
7303
|
console.log(_chalk2.default.blue(tableName), rows.length);
|
|
7293
7304
|
await transaction.insert(
|
|
7294
7305
|
rows.map((row) => {
|
|
@@ -7378,7 +7389,7 @@ var FixtureManagerClass = class {
|
|
|
7378
7389
|
const targetDB = _knex2.default.call(void 0, Sonamu.dbConfig[targetDBName]);
|
|
7379
7390
|
const { entityId, field, value, searchType } = searchOptions;
|
|
7380
7391
|
const entity = EntityManager.get(entityId);
|
|
7381
|
-
const column = _optionalChain([entity, 'access',
|
|
7392
|
+
const column = _optionalChain([entity, 'access', _91 => _91.props, 'access', _92 => _92.find, 'call', _93 => _93((prop) => prop.name === field), 'optionalAccess', _94 => _94.type]) === "relation" ? `${field}_id` : field;
|
|
7382
7393
|
let query = sourceDB(entity.table);
|
|
7383
7394
|
if (searchType === "equals") {
|
|
7384
7395
|
query = query.where(column, value);
|
|
@@ -7389,42 +7400,51 @@ var FixtureManagerClass = class {
|
|
|
7389
7400
|
if (rows.length === 0) {
|
|
7390
7401
|
throw new Error("No records found");
|
|
7391
7402
|
}
|
|
7392
|
-
const
|
|
7393
|
-
const records = [];
|
|
7403
|
+
const fixtures = [];
|
|
7394
7404
|
for (const row of rows) {
|
|
7395
|
-
const initialRecordsLength =
|
|
7396
|
-
await this.createFixtureRecord(entity, row
|
|
7397
|
-
|
|
7405
|
+
const initialRecordsLength = fixtures.length;
|
|
7406
|
+
const newRecords = await this.createFixtureRecord(entity, row);
|
|
7407
|
+
fixtures.push(...newRecords);
|
|
7408
|
+
const currentFixtureRecord = fixtures.find(
|
|
7398
7409
|
(r) => r.fixtureId === `${entityId}#${row.id}`
|
|
7399
7410
|
);
|
|
7400
7411
|
if (currentFixtureRecord) {
|
|
7401
|
-
currentFixtureRecord.fetchedRecords =
|
|
7412
|
+
currentFixtureRecord.fetchedRecords = fixtures.filter((r) => r.fixtureId !== currentFixtureRecord.fixtureId).slice(initialRecordsLength).map((r) => r.fixtureId);
|
|
7402
7413
|
}
|
|
7403
7414
|
}
|
|
7404
|
-
for await (const
|
|
7405
|
-
const entity2 = EntityManager.get(
|
|
7406
|
-
const
|
|
7407
|
-
const row = await targetDB(entity2.table).where("id", record.id).first();
|
|
7415
|
+
for await (const fixture of fixtures) {
|
|
7416
|
+
const entity2 = EntityManager.get(fixture.entityId);
|
|
7417
|
+
const row = await targetDB(entity2.table).where("id", fixture.id).first();
|
|
7408
7418
|
if (row) {
|
|
7409
|
-
await this.createFixtureRecord(
|
|
7410
|
-
|
|
7411
|
-
|
|
7412
|
-
|
|
7413
|
-
|
|
7414
|
-
|
|
7415
|
-
|
|
7416
|
-
|
|
7417
|
-
|
|
7419
|
+
const [record] = await this.createFixtureRecord(entity2, row, {
|
|
7420
|
+
singleRecord: true,
|
|
7421
|
+
_db: targetDB
|
|
7422
|
+
});
|
|
7423
|
+
fixture.target = record;
|
|
7424
|
+
continue;
|
|
7425
|
+
}
|
|
7426
|
+
const uniqueRow = await this.checkUniqueViolation(
|
|
7427
|
+
targetDB,
|
|
7428
|
+
entity2,
|
|
7429
|
+
fixture
|
|
7430
|
+
);
|
|
7431
|
+
if (uniqueRow) {
|
|
7432
|
+
const [record] = await this.createFixtureRecord(entity2, uniqueRow, {
|
|
7433
|
+
singleRecord: true,
|
|
7434
|
+
_db: targetDB
|
|
7435
|
+
});
|
|
7436
|
+
fixture.unique = record;
|
|
7418
7437
|
}
|
|
7419
7438
|
}
|
|
7420
|
-
return
|
|
7439
|
+
return fixtures;
|
|
7421
7440
|
}
|
|
7422
|
-
async createFixtureRecord(entity, row,
|
|
7441
|
+
async createFixtureRecord(entity, row, options, visitedEntities = /* @__PURE__ */ new Set()) {
|
|
7423
7442
|
const fixtureId = `${entity.id}#${row.id}`;
|
|
7424
7443
|
if (visitedEntities.has(fixtureId)) {
|
|
7425
|
-
return;
|
|
7444
|
+
return [];
|
|
7426
7445
|
}
|
|
7427
7446
|
visitedEntities.add(fixtureId);
|
|
7447
|
+
const records = [];
|
|
7428
7448
|
const record = {
|
|
7429
7449
|
fixtureId,
|
|
7430
7450
|
entityId: entity.id,
|
|
@@ -7441,7 +7461,7 @@ var FixtureManagerClass = class {
|
|
|
7441
7461
|
prop,
|
|
7442
7462
|
value: row[prop.name]
|
|
7443
7463
|
};
|
|
7444
|
-
const db = _nullishCoalesce(_db, () => ( BaseModel.getDB("w")));
|
|
7464
|
+
const db = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _95 => _95._db]), () => ( BaseModel.getDB("w")));
|
|
7445
7465
|
if (isManyToManyRelationProp(prop)) {
|
|
7446
7466
|
const relatedEntity = EntityManager.get(prop.with);
|
|
7447
7467
|
const throughTable = prop.joinTable;
|
|
@@ -7460,7 +7480,7 @@ var FixtureManagerClass = class {
|
|
|
7460
7480
|
);
|
|
7461
7481
|
if (relatedProp) {
|
|
7462
7482
|
const relatedRow = await db(relatedEntity.table).where("id", row.id).first();
|
|
7463
|
-
record.columns[prop.name].value = _optionalChain([relatedRow, 'optionalAccess',
|
|
7483
|
+
record.columns[prop.name].value = _optionalChain([relatedRow, 'optionalAccess', _96 => _96.id]);
|
|
7464
7484
|
}
|
|
7465
7485
|
} else if (isRelationProp(prop)) {
|
|
7466
7486
|
const relatedId = row[`${prop.name}_id`];
|
|
@@ -7468,25 +7488,26 @@ var FixtureManagerClass = class {
|
|
|
7468
7488
|
if (relatedId) {
|
|
7469
7489
|
record.belongsRecords.push(`${prop.with}#${relatedId}`);
|
|
7470
7490
|
}
|
|
7471
|
-
if (!singleRecord && relatedId) {
|
|
7491
|
+
if (!_optionalChain([options, 'optionalAccess', _97 => _97.singleRecord]) && relatedId) {
|
|
7472
7492
|
const relatedEntity = EntityManager.get(prop.with);
|
|
7473
7493
|
const relatedRow = await db(relatedEntity.table).where("id", relatedId).first();
|
|
7474
7494
|
if (relatedRow) {
|
|
7475
|
-
await this.createFixtureRecord(
|
|
7495
|
+
const newRecords = await this.createFixtureRecord(
|
|
7476
7496
|
relatedEntity,
|
|
7477
7497
|
relatedRow,
|
|
7478
|
-
|
|
7479
|
-
|
|
7480
|
-
singleRecord,
|
|
7481
|
-
_db
|
|
7498
|
+
options,
|
|
7499
|
+
visitedEntities
|
|
7482
7500
|
);
|
|
7501
|
+
records.push(...newRecords);
|
|
7483
7502
|
}
|
|
7484
7503
|
}
|
|
7485
7504
|
}
|
|
7486
7505
|
}
|
|
7487
7506
|
records.push(record);
|
|
7507
|
+
return records;
|
|
7488
7508
|
}
|
|
7489
|
-
async insertFixtures(dbName,
|
|
7509
|
+
async insertFixtures(dbName, _fixtures) {
|
|
7510
|
+
const fixtures = _lodash2.default.uniqBy(_fixtures, (f) => f.fixtureId);
|
|
7490
7511
|
this.buildDependencyGraph(fixtures);
|
|
7491
7512
|
const insertionOrder = this.getInsertionOrder();
|
|
7492
7513
|
const db = _knex2.default.call(void 0, Sonamu.dbConfig[dbName]);
|
|
@@ -7494,7 +7515,22 @@ var FixtureManagerClass = class {
|
|
|
7494
7515
|
await trx.raw(`SET FOREIGN_KEY_CHECKS = 0`);
|
|
7495
7516
|
for (const fixtureId of insertionOrder) {
|
|
7496
7517
|
const fixture = fixtures.find((f) => f.fixtureId === fixtureId);
|
|
7497
|
-
await this.insertFixture(trx, fixture);
|
|
7518
|
+
const result = await this.insertFixture(trx, fixture);
|
|
7519
|
+
if (result.id !== fixture.id) {
|
|
7520
|
+
console.log(
|
|
7521
|
+
_chalk2.default.yellow(
|
|
7522
|
+
`Unique constraint violation: ${fixture.entityId}#${fixture.id} -> ${fixture.entityId}#${result.id}`
|
|
7523
|
+
)
|
|
7524
|
+
);
|
|
7525
|
+
fixtures.forEach((f) => {
|
|
7526
|
+
Object.values(f.columns).forEach((column) => {
|
|
7527
|
+
if (column.prop.type === "relation" && column.prop.with === result.entityId && column.value === fixture.id) {
|
|
7528
|
+
column.value = result.id;
|
|
7529
|
+
}
|
|
7530
|
+
});
|
|
7531
|
+
});
|
|
7532
|
+
fixture.id = result.id;
|
|
7533
|
+
}
|
|
7498
7534
|
}
|
|
7499
7535
|
for (const fixtureId of insertionOrder) {
|
|
7500
7536
|
const fixture = fixtures.find((f) => f.fixtureId === fixtureId);
|
|
@@ -7511,7 +7547,7 @@ var FixtureManagerClass = class {
|
|
|
7511
7547
|
data: record
|
|
7512
7548
|
});
|
|
7513
7549
|
}
|
|
7514
|
-
return records;
|
|
7550
|
+
return _lodash2.default.uniqBy(records, (r) => `${r.entityId}#${r.data.id}`);
|
|
7515
7551
|
}
|
|
7516
7552
|
getInsertionOrder() {
|
|
7517
7553
|
const visited = /* @__PURE__ */ new Set();
|
|
@@ -7605,6 +7641,13 @@ var FixtureManagerClass = class {
|
|
|
7605
7641
|
const insertData = this.prepareInsertData(fixture);
|
|
7606
7642
|
const entity = EntityManager.get(fixture.entityId);
|
|
7607
7643
|
try {
|
|
7644
|
+
const uniqueFound = await this.checkUniqueViolation(db, entity, fixture);
|
|
7645
|
+
if (uniqueFound) {
|
|
7646
|
+
return {
|
|
7647
|
+
entityId: fixture.entityId,
|
|
7648
|
+
id: uniqueFound.id
|
|
7649
|
+
};
|
|
7650
|
+
}
|
|
7608
7651
|
const found = await db(entity.table).where("id", fixture.id).first();
|
|
7609
7652
|
if (found && !fixture.override) {
|
|
7610
7653
|
return {
|
|
@@ -7672,6 +7715,33 @@ var FixtureManagerClass = class {
|
|
|
7672
7715
|
throw new Error("Failed to find fixtureLoader in fixture.ts");
|
|
7673
7716
|
}
|
|
7674
7717
|
}
|
|
7718
|
+
// 해당 픽스쳐의 값으로 유니크 제약에 위배되는 레코드가 있는지 확인
|
|
7719
|
+
async checkUniqueViolation(db, entity, fixture) {
|
|
7720
|
+
const uniqueIndexes = entity.indexes.filter((i) => i.type === "unique");
|
|
7721
|
+
if (uniqueIndexes.length === 0) {
|
|
7722
|
+
return null;
|
|
7723
|
+
}
|
|
7724
|
+
let uniqueQuery = db(entity.table);
|
|
7725
|
+
for (const index of uniqueIndexes) {
|
|
7726
|
+
if (index.columns.some(
|
|
7727
|
+
(column) => fixture.columns[column.split("_id")[0]].value === null
|
|
7728
|
+
)) {
|
|
7729
|
+
continue;
|
|
7730
|
+
}
|
|
7731
|
+
uniqueQuery = uniqueQuery.orWhere((qb) => {
|
|
7732
|
+
for (const column of index.columns) {
|
|
7733
|
+
const field = column.split("_id")[0];
|
|
7734
|
+
if (Array.isArray(fixture.columns[field].value)) {
|
|
7735
|
+
qb.whereIn(column, fixture.columns[field].value);
|
|
7736
|
+
} else {
|
|
7737
|
+
qb.andWhere(column, fixture.columns[field].value);
|
|
7738
|
+
}
|
|
7739
|
+
}
|
|
7740
|
+
});
|
|
7741
|
+
}
|
|
7742
|
+
const [uniqueFound] = await uniqueQuery;
|
|
7743
|
+
return uniqueFound;
|
|
7744
|
+
}
|
|
7675
7745
|
};
|
|
7676
7746
|
var FixtureManager = new FixtureManagerClass();
|
|
7677
7747
|
|
|
@@ -7758,4 +7828,4 @@ var FixtureManager = new FixtureManagerClass();
|
|
|
7758
7828
|
|
|
7759
7829
|
|
|
7760
7830
|
exports.SQLDateTimeString = SQLDateTimeString; exports.zArrayable = zArrayable; exports.isIntegerProp = isIntegerProp; exports.isBigIntegerProp = isBigIntegerProp; exports.isTextProp = isTextProp; exports.isStringProp = isStringProp; exports.isEnumProp = isEnumProp; exports.isFloatProp = isFloatProp; exports.isDoubleProp = isDoubleProp; exports.isDecimalProp = isDecimalProp; exports.isBooleanProp = isBooleanProp; exports.isDateProp = isDateProp; exports.isDateTimeProp = isDateTimeProp; exports.isTimeProp = isTimeProp; exports.isTimestampProp = isTimestampProp; exports.isJsonProp = isJsonProp; exports.isUuidProp = isUuidProp; exports.isVirtualProp = isVirtualProp; exports.isRelationProp = isRelationProp; exports.isOneToOneRelationProp = isOneToOneRelationProp; exports.isBelongsToOneRelationProp = isBelongsToOneRelationProp; exports.isHasManyRelationProp = isHasManyRelationProp; exports.isManyToManyRelationProp = isManyToManyRelationProp; exports.isCustomJoinClause = isCustomJoinClause; exports.SonamuQueryMode = SonamuQueryMode; exports.isKnexError = isKnexError; exports.ApiParamType = ApiParamType; exports.RenderingNode = RenderingNode; exports.TemplateOptions = TemplateOptions; exports.TemplateKey = TemplateKey; exports.GenerateOptions = GenerateOptions; exports.PathAndCode = PathAndCode; exports.getZodObjectFromApi = getZodObjectFromApi; exports.getZodObjectFromApiParams = getZodObjectFromApiParams; exports.getZodTypeFromApiParamType = getZodTypeFromApiParamType; exports.propNodeToZodTypeDef = propNodeToZodTypeDef; exports.getTextTypeLength = getTextTypeLength; exports.propToZodTypeDef = propToZodTypeDef; exports.zodTypeToZodCode = zodTypeToZodCode; exports.apiParamToTsCode = apiParamToTsCode; exports.apiParamTypeToTsType = apiParamTypeToTsType; exports.unwrapPromiseOnce = unwrapPromiseOnce; exports.serializeZodType = serializeZodType; exports.zodTypeToTsTypeDef = zodTypeToTsTypeDef; exports.registeredApis = registeredApis; exports.api = api; exports.SoException = SoException; exports.isSoException = isSoException; exports.BadRequestException = BadRequestException; exports.UnauthorizedException = UnauthorizedException; exports.NotFoundException = NotFoundException; exports.ServiceUnavailableException = ServiceUnavailableException; exports.InternalServerErrorException = InternalServerErrorException; exports.AlreadyProcessedException = AlreadyProcessedException; exports.DuplicateRowException = DuplicateRowException; exports.TargetNotFoundException = TargetNotFoundException; exports.globAsync = globAsync; exports.importMultiple = importMultiple; exports.findAppRootPath = findAppRootPath; exports.findApiRootPath = findApiRootPath; exports.nonNullable = nonNullable; exports.Entity = Entity; exports.EntityManager = EntityManager; exports.Syncer = Syncer; exports.isLocal = isLocal; exports.isRemote = isRemote; exports.isInDocker = isInDocker; exports.isDaemonServer = isDaemonServer; exports.isDevelopment = isDevelopment; exports.isStaging = isStaging; exports.isProduction = isProduction; exports.isTest = isTest; exports.DB = DB; exports.isRefField = isRefField; exports.UpsertBuilder = UpsertBuilder; exports.BaseModelClass = BaseModelClass; exports.BaseModel = BaseModel; exports.Sonamu = Sonamu; exports.Migrator = Migrator; exports.FixtureManagerClass = FixtureManagerClass; exports.FixtureManager = FixtureManager;
|
|
7761
|
-
//# sourceMappingURL=chunk-
|
|
7831
|
+
//# sourceMappingURL=chunk-HATLA54Z.js.map
|