@ruiapp/rapid-core 0.5.3 → 0.5.5

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/index.js CHANGED
@@ -3470,9 +3470,12 @@ async function updateEntityById(server, dataAccessor, options, plugin) {
3470
3470
  }
3471
3471
  }
3472
3472
  }
3473
- // save many-relation properties
3473
+ // save many-relation properties (only 'overwrite' mode was supported right now)
3474
3474
  for (const property of manyRelationPropertiesToUpdate) {
3475
3475
  const relatedEntities = [];
3476
+ const targetModel = server.getModel({
3477
+ singularCode: property.targetSingularCode,
3478
+ });
3476
3479
  const targetDataAccessor = server.getDataAccessor({
3477
3480
  singularCode: property.targetSingularCode,
3478
3481
  });
@@ -3507,15 +3510,46 @@ async function updateEntityById(server, dataAccessor, options, plugin) {
3507
3510
  AND ${server.queryBuilder.quoteObject(property.targetIdColumnName)} <> ALL($2::int[])`, [id, targetIdsToKeep], routeContext?.getDbTransactionClient());
3508
3511
  }
3509
3512
  else {
3510
- const targetModel = server.getModel({
3511
- singularCode: property.targetSingularCode,
3512
- });
3513
3513
  const targetRows = await server.queryDatabaseObject(`SELECT id FROM ${server.queryBuilder.quoteTable({
3514
3514
  schema: targetModel.schema,
3515
3515
  tableName: targetModel.tableName,
3516
3516
  })} WHERE ${server.queryBuilder.quoteObject(property.selfIdColumnName)} = $1`, [id], routeContext?.getDbTransactionClient());
3517
3517
  currentTargetIds = targetRows.map((item) => item.id);
3518
3518
  }
3519
+ const targetIdsToRemove = currentTargetIds.filter((currentId) => !targetIdsToKeep.includes(currentId));
3520
+ if (targetIdsToRemove.length) {
3521
+ if (property.linkTableName) ;
3522
+ else {
3523
+ const updateRelationPropertiesOptions = lodash.get(options.relationPropertiesToUpdate, property.code);
3524
+ let relationRemoveMode = "unlink";
3525
+ if (updateRelationPropertiesOptions === true) {
3526
+ relationRemoveMode = "delete";
3527
+ }
3528
+ else {
3529
+ relationRemoveMode = updateRelationPropertiesOptions.relationRemoveMode;
3530
+ }
3531
+ const relationModel = server.getModel({
3532
+ singularCode: property.targetSingularCode,
3533
+ });
3534
+ if (relationRemoveMode === "unlink") {
3535
+ await server.queryDatabaseObject(`UPDATE ${server.queryBuilder.quoteTable({
3536
+ schema: relationModel.schema,
3537
+ tableName: relationModel.tableName,
3538
+ })}
3539
+ SET ${server.queryBuilder.quoteObject(property.selfIdColumnName)} = null
3540
+ WHERE id = ANY($1::int[])`, [targetIdsToRemove], routeContext?.getDbTransactionClient());
3541
+ }
3542
+ else {
3543
+ // relationRemoveMode === "delete"
3544
+ for (const targetIdToRemove of targetIdsToRemove) {
3545
+ await deleteEntityById(server, targetDataAccessor, {
3546
+ id: targetIdToRemove,
3547
+ routeContext,
3548
+ }, plugin);
3549
+ }
3550
+ }
3551
+ }
3552
+ }
3519
3553
  for (const relatedEntityToBeSaved of relatedEntitiesToBeSaved) {
3520
3554
  let relatedEntityId;
3521
3555
  if (lodash.isObject(relatedEntityToBeSaved)) {
@@ -4806,6 +4840,7 @@ async function syncDatabaseSchema(server, applicationConfig) {
4806
4840
  autoIncrement: false,
4807
4841
  notNull: property.required,
4808
4842
  });
4843
+ await server.tryQueryDatabaseObject(columnDDL);
4809
4844
  }
4810
4845
  if (!columnInDb || columnInDb.description != property.name) {
4811
4846
  await server.queryDatabaseObject(`COMMENT ON COLUMN ${queryBuilder.quoteTable(model)}.${queryBuilder.quoteObject(property.targetIdColumnName)} IS ${queryBuilder.formatValueToSqlLiteral(property.name)};`, []);
@@ -4830,6 +4865,7 @@ async function syncDatabaseSchema(server, applicationConfig) {
4830
4865
  schema: property.linkSchema,
4831
4866
  tableName: property.linkTableName,
4832
4867
  })} ADD CONSTRAINT ${queryBuilder.quoteObject(contraintName)} PRIMARY KEY (id);`;
4868
+ await server.tryQueryDatabaseObject(columnDDL);
4833
4869
  }
4834
4870
  else {
4835
4871
  const targetModel = applicationConfig.models.find((item) => item.singularCode === property.targetSingularCode);
@@ -4851,15 +4887,13 @@ async function syncDatabaseSchema(server, applicationConfig) {
4851
4887
  autoIncrement: false,
4852
4888
  notNull: property.required,
4853
4889
  });
4890
+ await server.tryQueryDatabaseObject(columnDDL);
4854
4891
  }
4855
4892
  }
4856
4893
  }
4857
4894
  else {
4858
4895
  continue;
4859
4896
  }
4860
- if (columnDDL) {
4861
- await server.tryQueryDatabaseObject(columnDDL);
4862
- }
4863
4897
  }
4864
4898
  else {
4865
4899
  const columnName = property.columnName || property.code;
package/dist/types.d.ts CHANGED
@@ -514,11 +514,15 @@ export interface UpdateEntityByIdOptions {
514
514
  /**
515
515
  * 指定需要更新关联对象的哪些属性。更新实体时,会创建关联对象,但是默认不更新关联对象的属性。
516
516
  */
517
- relationPropertiesToUpdate?: Record<string, UpdateRelationPropertiesOptions>;
517
+ relationPropertiesToUpdate?: Record<string, UpdateRelationPropertyOptions>;
518
518
  }
519
- export type UpdateRelationPropertiesOptions = true | {
519
+ export type UpdateRelationPropertyOptions = true | {
520
+ /**
521
+ * 当需移除关系时是删除关联实体,还是取消关联。默认为`delete`。此配置仅对没有配置`linkTableName`的属性有效。
522
+ */
523
+ relationRemoveMode?: "unlink" | "delete";
520
524
  propertiesToUpdate?: string[];
521
- relationPropertiesToUpdate?: Record<string, UpdateRelationPropertiesOptions>;
525
+ relationPropertiesToUpdate?: Record<string, UpdateRelationPropertyOptions>;
522
526
  };
523
527
  export interface DeleteEntityOptions {
524
528
  routeContext?: RouteContext;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ruiapp/rapid-core",
3
- "version": "0.5.3",
3
+ "version": "0.5.5",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1271,9 +1271,12 @@ async function updateEntityById(server: IRpdServer, dataAccessor: IRpdDataAccess
1271
1271
  }
1272
1272
  }
1273
1273
 
1274
- // save many-relation properties
1274
+ // save many-relation properties (only 'overwrite' mode was supported right now)
1275
1275
  for (const property of manyRelationPropertiesToUpdate) {
1276
1276
  const relatedEntities: any[] = [];
1277
+ const targetModel = server.getModel({
1278
+ singularCode: property.targetSingularCode,
1279
+ });
1277
1280
  const targetDataAccessor = server.getDataAccessor({
1278
1281
  singularCode: property.targetSingularCode!,
1279
1282
  });
@@ -1318,9 +1321,6 @@ async function updateEntityById(server: IRpdServer, dataAccessor: IRpdDataAccess
1318
1321
  routeContext?.getDbTransactionClient(),
1319
1322
  );
1320
1323
  } else {
1321
- const targetModel = server.getModel({
1322
- singularCode: property.targetSingularCode,
1323
- });
1324
1324
  const targetRows = await server.queryDatabaseObject(
1325
1325
  `SELECT id FROM ${server.queryBuilder.quoteTable({
1326
1326
  schema: targetModel.schema,
@@ -1332,6 +1332,49 @@ async function updateEntityById(server: IRpdServer, dataAccessor: IRpdDataAccess
1332
1332
  currentTargetIds = targetRows.map((item) => item.id);
1333
1333
  }
1334
1334
 
1335
+ const targetIdsToRemove = currentTargetIds.filter((currentId) => !targetIdsToKeep.includes(currentId));
1336
+ if (targetIdsToRemove.length) {
1337
+ if (property.linkTableName) {
1338
+ // do nothing. we've remove the link rows before.
1339
+ } else {
1340
+ const updateRelationPropertiesOptions = get(options.relationPropertiesToUpdate, property.code);
1341
+ let relationRemoveMode: "unlink" | "delete" = "unlink";
1342
+ if (updateRelationPropertiesOptions === true) {
1343
+ relationRemoveMode = "delete";
1344
+ } else {
1345
+ relationRemoveMode = updateRelationPropertiesOptions.relationRemoveMode;
1346
+ }
1347
+ const relationModel = server.getModel({
1348
+ singularCode: property.targetSingularCode,
1349
+ });
1350
+ if (relationRemoveMode === "unlink") {
1351
+ await server.queryDatabaseObject(
1352
+ `UPDATE ${server.queryBuilder.quoteTable({
1353
+ schema: relationModel.schema,
1354
+ tableName: relationModel.tableName,
1355
+ })}
1356
+ SET ${server.queryBuilder.quoteObject(property.selfIdColumnName!)} = null
1357
+ WHERE id = ANY($1::int[])`,
1358
+ [targetIdsToRemove],
1359
+ routeContext?.getDbTransactionClient(),
1360
+ );
1361
+ } else {
1362
+ // relationRemoveMode === "delete"
1363
+ for (const targetIdToRemove of targetIdsToRemove) {
1364
+ await deleteEntityById(
1365
+ server,
1366
+ targetDataAccessor,
1367
+ {
1368
+ id: targetIdToRemove,
1369
+ routeContext,
1370
+ },
1371
+ plugin,
1372
+ );
1373
+ }
1374
+ }
1375
+ }
1376
+ }
1377
+
1335
1378
  for (const relatedEntityToBeSaved of relatedEntitiesToBeSaved) {
1336
1379
  let relatedEntityId: any;
1337
1380
  if (isObject(relatedEntityToBeSaved)) {
@@ -260,6 +260,7 @@ async function syncDatabaseSchema(server: IRpdServer, applicationConfig: RpdAppl
260
260
  autoIncrement: false,
261
261
  notNull: property.required,
262
262
  });
263
+ await server.tryQueryDatabaseObject(columnDDL);
263
264
  }
264
265
 
265
266
  if (!columnInDb || columnInDb.description != property.name) {
@@ -290,6 +291,7 @@ async function syncDatabaseSchema(server: IRpdServer, applicationConfig: RpdAppl
290
291
  schema: property.linkSchema,
291
292
  tableName: property.linkTableName,
292
293
  })} ADD CONSTRAINT ${queryBuilder.quoteObject(contraintName)} PRIMARY KEY (id);`;
294
+ await server.tryQueryDatabaseObject(columnDDL);
293
295
  } else {
294
296
  const targetModel = applicationConfig.models.find((item) => item.singularCode === property.targetSingularCode);
295
297
  if (!targetModel) {
@@ -312,15 +314,12 @@ async function syncDatabaseSchema(server: IRpdServer, applicationConfig: RpdAppl
312
314
  autoIncrement: false,
313
315
  notNull: property.required,
314
316
  });
317
+ await server.tryQueryDatabaseObject(columnDDL);
315
318
  }
316
319
  }
317
320
  } else {
318
321
  continue;
319
322
  }
320
-
321
- if (columnDDL) {
322
- await server.tryQueryDatabaseObject(columnDDL);
323
- }
324
323
  } else {
325
324
  const columnName = property.columnName || property.code;
326
325
  const columnInDb: ColumnInformation | undefined = find(columnsInDb, {
package/src/types.ts CHANGED
@@ -659,14 +659,21 @@ export interface UpdateEntityByIdOptions {
659
659
  /**
660
660
  * 指定需要更新关联对象的哪些属性。更新实体时,会创建关联对象,但是默认不更新关联对象的属性。
661
661
  */
662
- relationPropertiesToUpdate?: Record<string, UpdateRelationPropertiesOptions>;
662
+ relationPropertiesToUpdate?: Record<string, UpdateRelationPropertyOptions>;
663
663
  }
664
664
 
665
- export type UpdateRelationPropertiesOptions =
665
+ export type UpdateRelationPropertyOptions =
666
666
  | true
667
667
  | {
668
+ // TODO: impl savingMode 'patch'
669
+ // savingMode?: "overwrite" | "patch";
670
+
671
+ /**
672
+ * 当需移除关系时是删除关联实体,还是取消关联。默认为`delete`。此配置仅对没有配置`linkTableName`的属性有效。
673
+ */
674
+ relationRemoveMode?: "unlink" | "delete";
668
675
  propertiesToUpdate?: string[];
669
- relationPropertiesToUpdate?: Record<string, UpdateRelationPropertiesOptions>;
676
+ relationPropertiesToUpdate?: Record<string, UpdateRelationPropertyOptions>;
670
677
  };
671
678
 
672
679
  export interface DeleteEntityOptions {