@ruiapp/rapid-core 0.1.80 → 0.1.82

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
@@ -598,7 +598,12 @@ function buildInFilterQuery(ctx, filter) {
598
598
  if (ctx.paramToLiteral) ;
599
599
  else {
600
600
  ctx.params.push(filter.value);
601
- command += `ANY($${ctx.params.length}::${filter.itemType || "int"}[])`;
601
+ if (filter.operator === "in") {
602
+ command += `ANY($${ctx.params.length}::${filter.itemType || "int"}[])`;
603
+ }
604
+ else {
605
+ command += `ALL($${ctx.params.length}::${filter.itemType || "int"}[])`;
606
+ }
602
607
  }
603
608
  return command;
604
609
  }
@@ -3176,12 +3181,41 @@ async function updateEntityById(server, dataAccessor, options, plugin) {
3176
3181
  if (!lodash.isArray(relatedEntitiesToBeSaved)) {
3177
3182
  throw new Error(`Value of field '${property.code}' should be an array.`);
3178
3183
  }
3184
+ const targetIdsToKeep = [];
3185
+ for (const relatedEntityToBeSaved of relatedEntitiesToBeSaved) {
3186
+ let relatedEntityId;
3187
+ if (lodash.isObject(relatedEntityToBeSaved)) {
3188
+ relatedEntityId = relatedEntityToBeSaved["id"];
3189
+ }
3190
+ else {
3191
+ relatedEntityId = relatedEntityToBeSaved;
3192
+ }
3193
+ if (relatedEntityId) {
3194
+ targetIdsToKeep.push(relatedEntityId);
3195
+ }
3196
+ }
3197
+ let currentTargetIds = [];
3179
3198
  if (property.linkTableName) {
3180
- // TODO: should support removing relation
3199
+ const targetLinks = await server.queryDatabaseObject(`SELECT ${server.queryBuilder.quoteObject(property.targetIdColumnName)} FROM ${server.queryBuilder.quoteTable({
3200
+ schema: property.linkSchema,
3201
+ tableName: property.linkTableName,
3202
+ })} WHERE ${server.queryBuilder.quoteObject(property.selfIdColumnName)} = $1`, [id]);
3203
+ currentTargetIds = targetLinks.map((item) => item[property.targetIdColumnName]);
3181
3204
  await server.queryDatabaseObject(`DELETE FROM ${server.queryBuilder.quoteTable({
3182
3205
  schema: property.linkSchema,
3183
3206
  tableName: property.linkTableName,
3207
+ })} WHERE ${server.queryBuilder.quoteObject(property.selfIdColumnName)} = $1
3208
+ AND ${server.queryBuilder.quoteObject(property.targetIdColumnName)} <> ALL($2::int[])`, [id, targetIdsToKeep]);
3209
+ }
3210
+ else {
3211
+ const targetModel = server.getModel({
3212
+ singularCode: property.targetSingularCode,
3213
+ });
3214
+ const targetRows = await server.queryDatabaseObject(`SELECT id FROM ${server.queryBuilder.quoteTable({
3215
+ schema: targetModel.schema,
3216
+ tableName: targetModel.tableName,
3184
3217
  })} WHERE ${server.queryBuilder.quoteObject(property.selfIdColumnName)} = $1`, [id]);
3218
+ currentTargetIds = targetRows.map((item) => item.id);
3185
3219
  }
3186
3220
  for (const relatedEntityToBeSaved of relatedEntitiesToBeSaved) {
3187
3221
  let relatedEntityId;
@@ -3213,6 +3247,31 @@ async function updateEntityById(server, dataAccessor, options, plugin) {
3213
3247
  if (!targetEntity) {
3214
3248
  throw new Error(`Entity with id '${relatedEntityId}' in field '${property.code}' is not exists.`);
3215
3249
  }
3250
+ if (!currentTargetIds.includes(relatedEntityId)) {
3251
+ if (property.linkTableName) {
3252
+ const command = `INSERT INTO ${server.queryBuilder.quoteTable({
3253
+ schema: property.linkSchema,
3254
+ tableName: property.linkTableName,
3255
+ })} (${server.queryBuilder.quoteObject(property.selfIdColumnName)}, ${property.targetIdColumnName}) VALUES ($1, $2) ON CONFLICT DO NOTHING;`;
3256
+ const params = [id, relatedEntityId];
3257
+ await server.queryDatabaseObject(command, params);
3258
+ }
3259
+ else {
3260
+ await targetDataAccessor.updateById(targetEntity.id, { [property.selfIdColumnName]: id });
3261
+ targetEntity[property.selfIdColumnName] = id;
3262
+ }
3263
+ }
3264
+ relatedEntities.push(targetEntity);
3265
+ }
3266
+ }
3267
+ else {
3268
+ // fieldValue is id
3269
+ relatedEntityId = relatedEntityToBeSaved;
3270
+ const targetEntity = await targetDataAccessor.findById(relatedEntityId);
3271
+ if (!targetEntity) {
3272
+ throw new Error(`Entity with id '${relatedEntityId}' in field '${property.code}' is not exists.`);
3273
+ }
3274
+ if (!currentTargetIds.includes(relatedEntityId)) {
3216
3275
  if (property.linkTableName) {
3217
3276
  const command = `INSERT INTO ${server.queryBuilder.quoteTable({
3218
3277
  schema: property.linkSchema,
@@ -3225,27 +3284,6 @@ async function updateEntityById(server, dataAccessor, options, plugin) {
3225
3284
  await targetDataAccessor.updateById(targetEntity.id, { [property.selfIdColumnName]: id });
3226
3285
  targetEntity[property.selfIdColumnName] = id;
3227
3286
  }
3228
- relatedEntities.push(targetEntity);
3229
- }
3230
- }
3231
- else {
3232
- // fieldValue is id
3233
- relatedEntityId = relatedEntityToBeSaved;
3234
- const targetEntity = await targetDataAccessor.findById(relatedEntityId);
3235
- if (!targetEntity) {
3236
- throw new Error(`Entity with id '${relatedEntityId}' in field '${property.code}' is not exists.`);
3237
- }
3238
- if (property.linkTableName) {
3239
- const command = `INSERT INTO ${server.queryBuilder.quoteTable({
3240
- schema: property.linkSchema,
3241
- tableName: property.linkTableName,
3242
- })} (${server.queryBuilder.quoteObject(property.selfIdColumnName)}, ${property.targetIdColumnName}) VALUES ($1, $2) ON CONFLICT DO NOTHING;`;
3243
- const params = [id, relatedEntityId];
3244
- await server.queryDatabaseObject(command, params);
3245
- }
3246
- else {
3247
- await targetDataAccessor.updateById(targetEntity.id, { [property.selfIdColumnName]: id });
3248
- targetEntity[property.selfIdColumnName] = id;
3249
3287
  }
3250
3288
  relatedEntities.push(targetEntity);
3251
3289
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ruiapp/rapid-core",
3
- "version": "0.1.80",
3
+ "version": "0.1.82",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1085,15 +1085,50 @@ async function updateEntityById(server: IRpdServer, dataAccessor: IRpdDataAccess
1085
1085
  throw new Error(`Value of field '${property.code}' should be an array.`);
1086
1086
  }
1087
1087
 
1088
+ const targetIdsToKeep = [];
1089
+ for (const relatedEntityToBeSaved of relatedEntitiesToBeSaved) {
1090
+ let relatedEntityId: any;
1091
+ if (isObject(relatedEntityToBeSaved)) {
1092
+ relatedEntityId = relatedEntityToBeSaved["id"];
1093
+ } else {
1094
+ relatedEntityId = relatedEntityToBeSaved;
1095
+ }
1096
+ if (relatedEntityId) {
1097
+ targetIdsToKeep.push(relatedEntityId);
1098
+ }
1099
+ }
1100
+
1101
+ let currentTargetIds: any[] = [];
1088
1102
  if (property.linkTableName) {
1089
- // TODO: should support removing relation
1103
+ const targetLinks = await server.queryDatabaseObject(
1104
+ `SELECT ${server.queryBuilder.quoteObject(property.targetIdColumnName)} FROM ${server.queryBuilder.quoteTable({
1105
+ schema: property.linkSchema,
1106
+ tableName: property.linkTableName,
1107
+ })} WHERE ${server.queryBuilder.quoteObject(property.selfIdColumnName!)} = $1`,
1108
+ [id],
1109
+ );
1110
+ currentTargetIds = targetLinks.map((item) => item[property.targetIdColumnName]);
1111
+
1090
1112
  await server.queryDatabaseObject(
1091
1113
  `DELETE FROM ${server.queryBuilder.quoteTable({
1092
1114
  schema: property.linkSchema,
1093
1115
  tableName: property.linkTableName,
1116
+ })} WHERE ${server.queryBuilder.quoteObject(property.selfIdColumnName!)} = $1
1117
+ AND ${server.queryBuilder.quoteObject(property.targetIdColumnName!)} <> ALL($2::int[])`,
1118
+ [id, targetIdsToKeep],
1119
+ );
1120
+ } else {
1121
+ const targetModel = server.getModel({
1122
+ singularCode: property.targetSingularCode,
1123
+ });
1124
+ const targetRows = await server.queryDatabaseObject(
1125
+ `SELECT id FROM ${server.queryBuilder.quoteTable({
1126
+ schema: targetModel.schema,
1127
+ tableName: targetModel.tableName,
1094
1128
  })} WHERE ${server.queryBuilder.quoteObject(property.selfIdColumnName!)} = $1`,
1095
1129
  [id],
1096
1130
  );
1131
+ currentTargetIds = targetRows.map((item) => item.id);
1097
1132
  }
1098
1133
 
1099
1134
  for (const relatedEntityToBeSaved of relatedEntitiesToBeSaved) {
@@ -1128,16 +1163,18 @@ async function updateEntityById(server: IRpdServer, dataAccessor: IRpdDataAccess
1128
1163
  throw new Error(`Entity with id '${relatedEntityId}' in field '${property.code}' is not exists.`);
1129
1164
  }
1130
1165
 
1131
- if (property.linkTableName) {
1132
- const command = `INSERT INTO ${server.queryBuilder.quoteTable({
1133
- schema: property.linkSchema,
1134
- tableName: property.linkTableName,
1135
- })} (${server.queryBuilder.quoteObject(property.selfIdColumnName!)}, ${property.targetIdColumnName}) VALUES ($1, $2) ON CONFLICT DO NOTHING;`;
1136
- const params = [id, relatedEntityId];
1137
- await server.queryDatabaseObject(command, params);
1138
- } else {
1139
- await targetDataAccessor.updateById(targetEntity.id, { [property.selfIdColumnName!]: id });
1140
- targetEntity[property.selfIdColumnName!] = id;
1166
+ if (!currentTargetIds.includes(relatedEntityId)) {
1167
+ if (property.linkTableName) {
1168
+ const command = `INSERT INTO ${server.queryBuilder.quoteTable({
1169
+ schema: property.linkSchema,
1170
+ tableName: property.linkTableName,
1171
+ })} (${server.queryBuilder.quoteObject(property.selfIdColumnName!)}, ${property.targetIdColumnName}) VALUES ($1, $2) ON CONFLICT DO NOTHING;`;
1172
+ const params = [id, relatedEntityId];
1173
+ await server.queryDatabaseObject(command, params);
1174
+ } else {
1175
+ await targetDataAccessor.updateById(targetEntity.id, { [property.selfIdColumnName!]: id });
1176
+ targetEntity[property.selfIdColumnName!] = id;
1177
+ }
1141
1178
  }
1142
1179
  relatedEntities.push(targetEntity);
1143
1180
  }
@@ -1149,16 +1186,18 @@ async function updateEntityById(server: IRpdServer, dataAccessor: IRpdDataAccess
1149
1186
  throw new Error(`Entity with id '${relatedEntityId}' in field '${property.code}' is not exists.`);
1150
1187
  }
1151
1188
 
1152
- if (property.linkTableName) {
1153
- const command = `INSERT INTO ${server.queryBuilder.quoteTable({
1154
- schema: property.linkSchema,
1155
- tableName: property.linkTableName,
1156
- })} (${server.queryBuilder.quoteObject(property.selfIdColumnName!)}, ${property.targetIdColumnName}) VALUES ($1, $2) ON CONFLICT DO NOTHING;`;
1157
- const params = [id, relatedEntityId];
1158
- await server.queryDatabaseObject(command, params);
1159
- } else {
1160
- await targetDataAccessor.updateById(targetEntity.id, { [property.selfIdColumnName!]: id });
1161
- targetEntity[property.selfIdColumnName!] = id;
1189
+ if (!currentTargetIds.includes(relatedEntityId)) {
1190
+ if (property.linkTableName) {
1191
+ const command = `INSERT INTO ${server.queryBuilder.quoteTable({
1192
+ schema: property.linkSchema,
1193
+ tableName: property.linkTableName,
1194
+ })} (${server.queryBuilder.quoteObject(property.selfIdColumnName!)}, ${property.targetIdColumnName}) VALUES ($1, $2) ON CONFLICT DO NOTHING;`;
1195
+ const params = [id, relatedEntityId];
1196
+ await server.queryDatabaseObject(command, params);
1197
+ } else {
1198
+ await targetDataAccessor.updateById(targetEntity.id, { [property.selfIdColumnName!]: id });
1199
+ targetEntity[property.selfIdColumnName!] = id;
1200
+ }
1162
1201
  }
1163
1202
 
1164
1203
  relatedEntities.push(targetEntity);
@@ -472,7 +472,11 @@ function buildInFilterQuery(ctx: BuildQueryContext, filter: FindRowSetFilterOpti
472
472
  // TODO: implement it
473
473
  } else {
474
474
  ctx.params.push(filter.value);
475
- command += `ANY($${ctx.params.length}::${filter.itemType || "int"}[])`;
475
+ if (filter.operator === "in") {
476
+ command += `ANY($${ctx.params.length}::${filter.itemType || "int"}[])`;
477
+ } else {
478
+ command += `ALL($${ctx.params.length}::${filter.itemType || "int"}[])`;
479
+ }
476
480
  }
477
481
 
478
482
  return command;