@ruiapp/rapid-core 0.2.6 → 0.2.8
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/dataAccess/dataAccessor.d.ts +1 -1
- package/dist/dataAccess/entityManager.d.ts +2 -2
- package/dist/index.js +100 -34
- package/dist/types.d.ts +1 -1
- package/package.json +1 -1
- package/src/dataAccess/dataAccessor.ts +3 -5
- package/src/dataAccess/entityManager.ts +100 -28
- package/src/plugins/dataManage/actionHandlers/countCollectionEntities.ts +4 -3
- package/src/plugins/dataManage/actionHandlers/findCollectionEntities.ts +2 -2
- package/src/types.ts +1 -1
|
@@ -17,6 +17,6 @@ export default class DataAccessor<T = any> implements IRpdDataAccessor<T> {
|
|
|
17
17
|
find(options: FindRowOptions): Promise<T[]>;
|
|
18
18
|
findOne(options: FindRowOptions): Promise<T>;
|
|
19
19
|
findById(id: any): Promise<T | null>;
|
|
20
|
-
count(options: CountRowOptions): Promise<
|
|
20
|
+
count(options: CountRowOptions): Promise<number>;
|
|
21
21
|
deleteById(id: any): Promise<void>;
|
|
22
22
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AddEntityRelationsOptions, CountEntityOptions,
|
|
1
|
+
import { AddEntityRelationsOptions, CountEntityOptions, CreateEntityOptions, DeleteEntityByIdOptions, FindEntityByIdOptions, FindEntityOptions, IRpdDataAccessor, RemoveEntityRelationsOptions, RpdDataModel, RpdDataModelIndex, RpdDataModelProperty, UpdateEntityByIdOptions, FindEntityFindOneRelationEntitiesOptions, FindEntityFindManyRelationEntitiesOptions } from "../types";
|
|
2
2
|
import { IRpdServer, RapidPlugin } from "../core/server";
|
|
3
3
|
import { RouteContext } from "../core/routeContext";
|
|
4
4
|
export type FindOneRelationEntitiesOptions = {
|
|
@@ -30,7 +30,7 @@ export default class EntityManager<TEntity = any> {
|
|
|
30
30
|
findById(options: FindEntityByIdOptions | string | number): Promise<TEntity | null>;
|
|
31
31
|
createEntity(options: CreateEntityOptions, plugin?: RapidPlugin): Promise<TEntity>;
|
|
32
32
|
updateEntityById(options: UpdateEntityByIdOptions, plugin?: RapidPlugin): Promise<TEntity>;
|
|
33
|
-
count(options: CountEntityOptions): Promise<
|
|
33
|
+
count(options: CountEntityOptions): Promise<number>;
|
|
34
34
|
deleteById(options: DeleteEntityByIdOptions | string | number, plugin?: RapidPlugin): Promise<void>;
|
|
35
35
|
addRelations(options: AddEntityRelationsOptions, plugin?: RapidPlugin): Promise<void>;
|
|
36
36
|
removeRelations(options: RemoveEntityRelationsOptions, plugin?: RapidPlugin): Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -159,11 +159,9 @@ class DataAccessor {
|
|
|
159
159
|
const result = await this.#databaseAccessor.queryDatabaseObject(query.command, query.params);
|
|
160
160
|
const row = lodash.first(result);
|
|
161
161
|
if (row) {
|
|
162
|
-
return row;
|
|
162
|
+
return row.count;
|
|
163
163
|
}
|
|
164
|
-
return
|
|
165
|
-
count: 0,
|
|
166
|
-
};
|
|
164
|
+
return 0;
|
|
167
165
|
}
|
|
168
166
|
async deleteById(id) {
|
|
169
167
|
const options = {
|
|
@@ -2972,7 +2970,7 @@ async function createEntity(server, dataAccessor, options, plugin) {
|
|
|
2972
2970
|
const newEntityOneRelationProps = {};
|
|
2973
2971
|
// save one-relation properties
|
|
2974
2972
|
for (const property of oneRelationPropertiesToCreate) {
|
|
2975
|
-
const
|
|
2973
|
+
const rowToBeSaved = property.isBaseProperty ? baseRow : row;
|
|
2976
2974
|
const fieldValue = entity[property.code];
|
|
2977
2975
|
const targetDataAccessor = server.getDataAccessor({
|
|
2978
2976
|
singularCode: property.targetSingularCode,
|
|
@@ -2980,13 +2978,15 @@ async function createEntity(server, dataAccessor, options, plugin) {
|
|
|
2980
2978
|
if (lodash.isObject(fieldValue)) {
|
|
2981
2979
|
const targetEntityId = fieldValue["id"];
|
|
2982
2980
|
if (!targetEntityId) {
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2981
|
+
if (!property.selfIdColumnName) {
|
|
2982
|
+
const targetEntity = fieldValue;
|
|
2983
|
+
const newTargetEntity = await createEntity(server, targetDataAccessor, {
|
|
2984
|
+
routeContext,
|
|
2985
|
+
entity: targetEntity,
|
|
2986
|
+
});
|
|
2987
|
+
newEntityOneRelationProps[property.code] = newTargetEntity;
|
|
2988
|
+
rowToBeSaved[property.targetIdColumnName] = newTargetEntity["id"];
|
|
2989
|
+
}
|
|
2990
2990
|
}
|
|
2991
2991
|
else {
|
|
2992
2992
|
const targetEntity = await findById(server, targetDataAccessor, {
|
|
@@ -2997,7 +2997,7 @@ async function createEntity(server, dataAccessor, options, plugin) {
|
|
|
2997
2997
|
throw newEntityOperationError(`Create ${model.singularCode} entity failed. Property '${property.code}' was invalid. Related ${property.targetSingularCode} entity with id '${targetEntityId}' was not found.`);
|
|
2998
2998
|
}
|
|
2999
2999
|
newEntityOneRelationProps[property.code] = targetEntity;
|
|
3000
|
-
|
|
3000
|
+
rowToBeSaved[property.targetIdColumnName] = targetEntityId;
|
|
3001
3001
|
}
|
|
3002
3002
|
}
|
|
3003
3003
|
else if (lodash.isNumber(fieldValue) || lodash.isString(fieldValue)) {
|
|
@@ -3011,16 +3011,17 @@ async function createEntity(server, dataAccessor, options, plugin) {
|
|
|
3011
3011
|
throw newEntityOperationError(`Create ${model.singularCode} entity failed. Property '${property.code}' was invalid. Related ${property.targetSingularCode} entity with id '${targetEntityId}' was not found.`);
|
|
3012
3012
|
}
|
|
3013
3013
|
newEntityOneRelationProps[property.code] = targetEntity;
|
|
3014
|
-
|
|
3014
|
+
rowToBeSaved[property.targetIdColumnName] = targetEntityId;
|
|
3015
3015
|
}
|
|
3016
3016
|
else {
|
|
3017
3017
|
newEntityOneRelationProps[property.code] = null;
|
|
3018
|
-
|
|
3018
|
+
rowToBeSaved[property.targetIdColumnName] = null;
|
|
3019
3019
|
}
|
|
3020
3020
|
}
|
|
3021
3021
|
let newBaseRow;
|
|
3022
|
+
let baseDataAccessor;
|
|
3022
3023
|
if (model.base) {
|
|
3023
|
-
|
|
3024
|
+
baseDataAccessor = server.getDataAccessor({
|
|
3024
3025
|
singularCode: model.base,
|
|
3025
3026
|
});
|
|
3026
3027
|
newBaseRow = await baseDataAccessor.create(baseRow);
|
|
@@ -3028,6 +3029,35 @@ async function createEntity(server, dataAccessor, options, plugin) {
|
|
|
3028
3029
|
}
|
|
3029
3030
|
const newRow = await dataAccessor.create(row);
|
|
3030
3031
|
const newEntity = mapDbRowToEntity(server, model, Object.assign({}, newBaseRow, newRow, newEntityOneRelationProps), true);
|
|
3032
|
+
// save one-relation properties that has selfIdColumnName
|
|
3033
|
+
for (const property of oneRelationPropertiesToCreate) {
|
|
3034
|
+
const fieldValue = entity[property.code];
|
|
3035
|
+
const targetDataAccessor = server.getDataAccessor({
|
|
3036
|
+
singularCode: property.targetSingularCode,
|
|
3037
|
+
});
|
|
3038
|
+
if (lodash.isObject(fieldValue)) {
|
|
3039
|
+
const targetEntityId = fieldValue["id"];
|
|
3040
|
+
if (!targetEntityId) {
|
|
3041
|
+
if (property.selfIdColumnName) {
|
|
3042
|
+
const targetEntity = fieldValue;
|
|
3043
|
+
targetEntity[property.selfIdColumnName] = newEntity.id;
|
|
3044
|
+
const newTargetEntity = await createEntity(server, targetDataAccessor, {
|
|
3045
|
+
routeContext,
|
|
3046
|
+
entity: targetEntity,
|
|
3047
|
+
});
|
|
3048
|
+
let dataAccessorOfMainEntity = dataAccessor;
|
|
3049
|
+
if (property.isBaseProperty) {
|
|
3050
|
+
dataAccessorOfMainEntity = baseDataAccessor;
|
|
3051
|
+
}
|
|
3052
|
+
const relationFieldChanges = {
|
|
3053
|
+
[property.targetIdColumnName]: newTargetEntity.id,
|
|
3054
|
+
};
|
|
3055
|
+
await dataAccessorOfMainEntity.updateById(newEntity.id, relationFieldChanges);
|
|
3056
|
+
newEntity[property.code] = newTargetEntity;
|
|
3057
|
+
}
|
|
3058
|
+
}
|
|
3059
|
+
}
|
|
3060
|
+
}
|
|
3031
3061
|
// save many-relation properties
|
|
3032
3062
|
for (const property of manyRelationPropertiesToCreate) {
|
|
3033
3063
|
newEntity[property.code] = [];
|
|
@@ -3221,7 +3251,7 @@ async function updateEntityById(server, dataAccessor, options, plugin) {
|
|
|
3221
3251
|
const { row, baseRow } = mapEntityToDbRow(server, model, changes);
|
|
3222
3252
|
const updatedEntityOneRelationProps = {};
|
|
3223
3253
|
for (const property of oneRelationPropertiesToUpdate) {
|
|
3224
|
-
const
|
|
3254
|
+
const rowToBeSaved = property.isBaseProperty ? baseRow : row;
|
|
3225
3255
|
const fieldValue = changes[property.code];
|
|
3226
3256
|
const targetDataAccessor = server.getDataAccessor({
|
|
3227
3257
|
singularCode: property.targetSingularCode,
|
|
@@ -3229,13 +3259,15 @@ async function updateEntityById(server, dataAccessor, options, plugin) {
|
|
|
3229
3259
|
if (lodash.isObject(fieldValue)) {
|
|
3230
3260
|
const targetEntityId = fieldValue["id"];
|
|
3231
3261
|
if (!targetEntityId) {
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3262
|
+
if (!property.selfIdColumnName) {
|
|
3263
|
+
const targetEntity = fieldValue;
|
|
3264
|
+
const newTargetEntity = await createEntity(server, targetDataAccessor, {
|
|
3265
|
+
routeContext,
|
|
3266
|
+
entity: targetEntity,
|
|
3267
|
+
});
|
|
3268
|
+
updatedEntityOneRelationProps[property.code] = newTargetEntity;
|
|
3269
|
+
rowToBeSaved[property.targetIdColumnName] = newTargetEntity["id"];
|
|
3270
|
+
}
|
|
3239
3271
|
}
|
|
3240
3272
|
else {
|
|
3241
3273
|
const targetEntity = await findById(server, targetDataAccessor, {
|
|
@@ -3246,7 +3278,7 @@ async function updateEntityById(server, dataAccessor, options, plugin) {
|
|
|
3246
3278
|
throw newEntityOperationError(`Create ${model.singularCode} entity failed. Property '${property.code}' was invalid. Related ${property.targetSingularCode} entity with id '${targetEntityId}' was not found.`);
|
|
3247
3279
|
}
|
|
3248
3280
|
updatedEntityOneRelationProps[property.code] = targetEntity;
|
|
3249
|
-
|
|
3281
|
+
rowToBeSaved[property.targetIdColumnName] = targetEntityId;
|
|
3250
3282
|
}
|
|
3251
3283
|
}
|
|
3252
3284
|
else if (lodash.isNumber(fieldValue) || lodash.isString(fieldValue)) {
|
|
@@ -3260,11 +3292,11 @@ async function updateEntityById(server, dataAccessor, options, plugin) {
|
|
|
3260
3292
|
throw newEntityOperationError(`Create ${model.singularCode} entity failed. Property '${property.code}' was invalid. Related ${property.targetSingularCode} entity with id '${targetEntityId}' was not found.`);
|
|
3261
3293
|
}
|
|
3262
3294
|
updatedEntityOneRelationProps[property.code] = targetEntity;
|
|
3263
|
-
|
|
3295
|
+
rowToBeSaved[property.targetIdColumnName] = targetEntityId;
|
|
3264
3296
|
}
|
|
3265
3297
|
else {
|
|
3266
3298
|
updatedEntityOneRelationProps[property.code] = null;
|
|
3267
|
-
|
|
3299
|
+
rowToBeSaved[property.targetIdColumnName] = null;
|
|
3268
3300
|
}
|
|
3269
3301
|
}
|
|
3270
3302
|
let updatedRow = row;
|
|
@@ -3272,14 +3304,47 @@ async function updateEntityById(server, dataAccessor, options, plugin) {
|
|
|
3272
3304
|
updatedRow = await dataAccessor.updateById(id, row);
|
|
3273
3305
|
}
|
|
3274
3306
|
let updatedBaseRow = baseRow;
|
|
3275
|
-
|
|
3276
|
-
|
|
3307
|
+
let baseDataAccessor;
|
|
3308
|
+
if (model.base) {
|
|
3309
|
+
baseDataAccessor = server.getDataAccessor({
|
|
3277
3310
|
singularCode: model.base,
|
|
3278
3311
|
});
|
|
3279
|
-
|
|
3312
|
+
if (Object.keys(baseRow).length) {
|
|
3313
|
+
updatedBaseRow = await baseDataAccessor.updateById(id, updatedBaseRow);
|
|
3314
|
+
}
|
|
3280
3315
|
}
|
|
3281
3316
|
let updatedEntity = mapDbRowToEntity(server, model, { ...updatedRow, ...updatedBaseRow, ...updatedEntityOneRelationProps }, true);
|
|
3282
3317
|
updatedEntity = Object.assign({}, entity, updatedEntity);
|
|
3318
|
+
// save one-relation properties that has selfIdColumnName
|
|
3319
|
+
for (const property of oneRelationPropertiesToUpdate) {
|
|
3320
|
+
const fieldValue = changes[property.code];
|
|
3321
|
+
const targetDataAccessor = server.getDataAccessor({
|
|
3322
|
+
singularCode: property.targetSingularCode,
|
|
3323
|
+
});
|
|
3324
|
+
if (lodash.isObject(fieldValue)) {
|
|
3325
|
+
const targetEntityId = fieldValue["id"];
|
|
3326
|
+
if (!targetEntityId) {
|
|
3327
|
+
if (property.selfIdColumnName) {
|
|
3328
|
+
const targetEntity = fieldValue;
|
|
3329
|
+
targetEntity[property.selfIdColumnName] = updatedEntity.id;
|
|
3330
|
+
const newTargetEntity = await createEntity(server, targetDataAccessor, {
|
|
3331
|
+
routeContext,
|
|
3332
|
+
entity: targetEntity,
|
|
3333
|
+
});
|
|
3334
|
+
let dataAccessorOfMainEntity = dataAccessor;
|
|
3335
|
+
if (property.isBaseProperty) {
|
|
3336
|
+
dataAccessorOfMainEntity = baseDataAccessor;
|
|
3337
|
+
}
|
|
3338
|
+
const relationFieldChanges = {
|
|
3339
|
+
[property.targetIdColumnName]: newTargetEntity.id,
|
|
3340
|
+
};
|
|
3341
|
+
await dataAccessorOfMainEntity.updateById(updatedEntity.id, relationFieldChanges);
|
|
3342
|
+
updatedEntity[property.code] = newTargetEntity;
|
|
3343
|
+
changes[property.code] = newTargetEntity;
|
|
3344
|
+
}
|
|
3345
|
+
}
|
|
3346
|
+
}
|
|
3347
|
+
}
|
|
3283
3348
|
// save many-relation properties
|
|
3284
3349
|
for (const property of manyRelationPropertiesToUpdate) {
|
|
3285
3350
|
const relatedEntities = [];
|
|
@@ -4723,8 +4788,8 @@ async function handler$q(plugin, ctx, options) {
|
|
|
4723
4788
|
const result = { list: entities };
|
|
4724
4789
|
if (input.pagination && !input.pagination.withoutTotal) {
|
|
4725
4790
|
// TOOD: count entities when calling findEntities for performance.
|
|
4726
|
-
const
|
|
4727
|
-
result.total =
|
|
4791
|
+
const total = await entityManager.count(input);
|
|
4792
|
+
result.total = total;
|
|
4728
4793
|
}
|
|
4729
4794
|
return result;
|
|
4730
4795
|
});
|
|
@@ -4760,10 +4825,11 @@ var findCollectionEntityById = /*#__PURE__*/Object.freeze({
|
|
|
4760
4825
|
|
|
4761
4826
|
const code$o = "countCollectionEntities";
|
|
4762
4827
|
async function handler$o(plugin, ctx, options) {
|
|
4763
|
-
await runCollectionEntityActionHandler(ctx, options, code$o, (entityManager, input) => {
|
|
4828
|
+
await runCollectionEntityActionHandler(ctx, options, code$o, async (entityManager, input) => {
|
|
4764
4829
|
input.filters = removeFiltersWithNullValue(input.filters);
|
|
4765
4830
|
input.routeContext = ctx.routerContext;
|
|
4766
|
-
|
|
4831
|
+
const count = await entityManager.count(input);
|
|
4832
|
+
return { count };
|
|
4767
4833
|
});
|
|
4768
4834
|
}
|
|
4769
4835
|
|
package/dist/types.d.ts
CHANGED
|
@@ -377,7 +377,7 @@ export interface IRpdDataAccessor<T = any> {
|
|
|
377
377
|
find(options: FindRowOptions): Promise<T[]>;
|
|
378
378
|
findOne(options: FindRowOptions): Promise<T | null>;
|
|
379
379
|
findById(id: any): Promise<T | null>;
|
|
380
|
-
count(options: CountRowOptions): Promise<
|
|
380
|
+
count(options: CountRowOptions): Promise<number>;
|
|
381
381
|
deleteById(id: any): Promise<void>;
|
|
382
382
|
}
|
|
383
383
|
export type EntityFilterRelationalOperators = "eq" | "ne" | "lt" | "lte" | "gt" | "gte" | "contains" | "notContains" | "containsCS" | "notContainsCS" | "startsWith" | "notStartsWith" | "endsWith" | "notEndsWith";
|
package/package.json
CHANGED
|
@@ -98,7 +98,7 @@ export default class DataAccessor<T = any> implements IRpdDataAccessor<T> {
|
|
|
98
98
|
return result;
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
async count(options: CountRowOptions): Promise<
|
|
101
|
+
async count(options: CountRowOptions): Promise<number> {
|
|
102
102
|
let query: DatabaseQuery;
|
|
103
103
|
if (this.#model.base) {
|
|
104
104
|
const baseModel = this.#server.getModel({
|
|
@@ -112,11 +112,9 @@ export default class DataAccessor<T = any> implements IRpdDataAccessor<T> {
|
|
|
112
112
|
|
|
113
113
|
const row = first(result);
|
|
114
114
|
if (row) {
|
|
115
|
-
return row;
|
|
115
|
+
return row.count;
|
|
116
116
|
}
|
|
117
|
-
return
|
|
118
|
-
count: 0,
|
|
119
|
-
};
|
|
117
|
+
return 0;
|
|
120
118
|
}
|
|
121
119
|
|
|
122
120
|
async deleteById(id: any) {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AddEntityRelationsOptions,
|
|
3
3
|
CountEntityOptions,
|
|
4
|
-
CountEntityResult,
|
|
5
4
|
CreateEntityOptions,
|
|
6
5
|
DeleteEntityByIdOptions,
|
|
7
6
|
EntityFilterOperators,
|
|
@@ -796,7 +795,7 @@ async function createEntity(server: IRpdServer, dataAccessor: IRpdDataAccessor,
|
|
|
796
795
|
const newEntityOneRelationProps = {};
|
|
797
796
|
// save one-relation properties
|
|
798
797
|
for (const property of oneRelationPropertiesToCreate) {
|
|
799
|
-
const
|
|
798
|
+
const rowToBeSaved = property.isBaseProperty ? baseRow : row;
|
|
800
799
|
const fieldValue = entity[property.code];
|
|
801
800
|
const targetDataAccessor = server.getDataAccessor({
|
|
802
801
|
singularCode: property.targetSingularCode!,
|
|
@@ -804,13 +803,15 @@ async function createEntity(server: IRpdServer, dataAccessor: IRpdDataAccessor,
|
|
|
804
803
|
if (isObject(fieldValue)) {
|
|
805
804
|
const targetEntityId = fieldValue["id"];
|
|
806
805
|
if (!targetEntityId) {
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
806
|
+
if (!property.selfIdColumnName) {
|
|
807
|
+
const targetEntity = fieldValue;
|
|
808
|
+
const newTargetEntity = await createEntity(server, targetDataAccessor, {
|
|
809
|
+
routeContext,
|
|
810
|
+
entity: targetEntity,
|
|
811
|
+
});
|
|
812
|
+
newEntityOneRelationProps[property.code] = newTargetEntity;
|
|
813
|
+
rowToBeSaved[property.targetIdColumnName!] = newTargetEntity["id"];
|
|
814
|
+
}
|
|
814
815
|
} else {
|
|
815
816
|
const targetEntity = await findById(server, targetDataAccessor, {
|
|
816
817
|
id: targetEntityId,
|
|
@@ -822,7 +823,7 @@ async function createEntity(server: IRpdServer, dataAccessor: IRpdDataAccessor,
|
|
|
822
823
|
);
|
|
823
824
|
}
|
|
824
825
|
newEntityOneRelationProps[property.code] = targetEntity;
|
|
825
|
-
|
|
826
|
+
rowToBeSaved[property.targetIdColumnName!] = targetEntityId;
|
|
826
827
|
}
|
|
827
828
|
} else if (isNumber(fieldValue) || isString(fieldValue)) {
|
|
828
829
|
// fieldValue is id;
|
|
@@ -837,16 +838,17 @@ async function createEntity(server: IRpdServer, dataAccessor: IRpdDataAccessor,
|
|
|
837
838
|
);
|
|
838
839
|
}
|
|
839
840
|
newEntityOneRelationProps[property.code] = targetEntity;
|
|
840
|
-
|
|
841
|
+
rowToBeSaved[property.targetIdColumnName!] = targetEntityId;
|
|
841
842
|
} else {
|
|
842
843
|
newEntityOneRelationProps[property.code] = null;
|
|
843
|
-
|
|
844
|
+
rowToBeSaved[property.targetIdColumnName!] = null;
|
|
844
845
|
}
|
|
845
846
|
}
|
|
846
847
|
|
|
847
848
|
let newBaseRow: any;
|
|
849
|
+
let baseDataAccessor: any;
|
|
848
850
|
if (model.base) {
|
|
849
|
-
|
|
851
|
+
baseDataAccessor = server.getDataAccessor({
|
|
850
852
|
singularCode: model.base,
|
|
851
853
|
});
|
|
852
854
|
newBaseRow = await baseDataAccessor.create(baseRow);
|
|
@@ -856,6 +858,38 @@ async function createEntity(server: IRpdServer, dataAccessor: IRpdDataAccessor,
|
|
|
856
858
|
const newRow = await dataAccessor.create(row);
|
|
857
859
|
const newEntity = mapDbRowToEntity(server, model, Object.assign({}, newBaseRow, newRow, newEntityOneRelationProps), true);
|
|
858
860
|
|
|
861
|
+
// save one-relation properties that has selfIdColumnName
|
|
862
|
+
for (const property of oneRelationPropertiesToCreate) {
|
|
863
|
+
const fieldValue = entity[property.code];
|
|
864
|
+
const targetDataAccessor = server.getDataAccessor({
|
|
865
|
+
singularCode: property.targetSingularCode!,
|
|
866
|
+
});
|
|
867
|
+
if (isObject(fieldValue)) {
|
|
868
|
+
const targetEntityId = fieldValue["id"];
|
|
869
|
+
if (!targetEntityId) {
|
|
870
|
+
if (property.selfIdColumnName) {
|
|
871
|
+
const targetEntity = fieldValue;
|
|
872
|
+
targetEntity[property.selfIdColumnName] = newEntity.id;
|
|
873
|
+
const newTargetEntity = await createEntity(server, targetDataAccessor, {
|
|
874
|
+
routeContext,
|
|
875
|
+
entity: targetEntity,
|
|
876
|
+
});
|
|
877
|
+
|
|
878
|
+
let dataAccessorOfMainEntity = dataAccessor;
|
|
879
|
+
if (property.isBaseProperty) {
|
|
880
|
+
dataAccessorOfMainEntity = baseDataAccessor;
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
const relationFieldChanges = {
|
|
884
|
+
[property.targetIdColumnName]: newTargetEntity.id,
|
|
885
|
+
};
|
|
886
|
+
await dataAccessorOfMainEntity.updateById(newEntity.id, relationFieldChanges);
|
|
887
|
+
newEntity[property.code] = newTargetEntity;
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
|
|
859
893
|
// save many-relation properties
|
|
860
894
|
for (const property of manyRelationPropertiesToCreate) {
|
|
861
895
|
newEntity[property.code] = [];
|
|
@@ -1068,7 +1102,7 @@ async function updateEntityById(server: IRpdServer, dataAccessor: IRpdDataAccess
|
|
|
1068
1102
|
|
|
1069
1103
|
const updatedEntityOneRelationProps = {};
|
|
1070
1104
|
for (const property of oneRelationPropertiesToUpdate) {
|
|
1071
|
-
const
|
|
1105
|
+
const rowToBeSaved = property.isBaseProperty ? baseRow : row;
|
|
1072
1106
|
const fieldValue = changes[property.code];
|
|
1073
1107
|
const targetDataAccessor = server.getDataAccessor({
|
|
1074
1108
|
singularCode: property.targetSingularCode!,
|
|
@@ -1077,13 +1111,15 @@ async function updateEntityById(server: IRpdServer, dataAccessor: IRpdDataAccess
|
|
|
1077
1111
|
if (isObject(fieldValue)) {
|
|
1078
1112
|
const targetEntityId = fieldValue["id"];
|
|
1079
1113
|
if (!targetEntityId) {
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1114
|
+
if (!property.selfIdColumnName) {
|
|
1115
|
+
const targetEntity = fieldValue;
|
|
1116
|
+
const newTargetEntity = await createEntity(server, targetDataAccessor, {
|
|
1117
|
+
routeContext,
|
|
1118
|
+
entity: targetEntity,
|
|
1119
|
+
});
|
|
1120
|
+
updatedEntityOneRelationProps[property.code] = newTargetEntity;
|
|
1121
|
+
rowToBeSaved[property.targetIdColumnName!] = newTargetEntity["id"];
|
|
1122
|
+
}
|
|
1087
1123
|
} else {
|
|
1088
1124
|
const targetEntity = await findById(server, targetDataAccessor, {
|
|
1089
1125
|
id: targetEntityId,
|
|
@@ -1095,7 +1131,7 @@ async function updateEntityById(server: IRpdServer, dataAccessor: IRpdDataAccess
|
|
|
1095
1131
|
);
|
|
1096
1132
|
}
|
|
1097
1133
|
updatedEntityOneRelationProps[property.code] = targetEntity;
|
|
1098
|
-
|
|
1134
|
+
rowToBeSaved[property.targetIdColumnName!] = targetEntityId;
|
|
1099
1135
|
}
|
|
1100
1136
|
} else if (isNumber(fieldValue) || isString(fieldValue)) {
|
|
1101
1137
|
// fieldValue is id;
|
|
@@ -1110,10 +1146,10 @@ async function updateEntityById(server: IRpdServer, dataAccessor: IRpdDataAccess
|
|
|
1110
1146
|
);
|
|
1111
1147
|
}
|
|
1112
1148
|
updatedEntityOneRelationProps[property.code] = targetEntity;
|
|
1113
|
-
|
|
1149
|
+
rowToBeSaved[property.targetIdColumnName!] = targetEntityId;
|
|
1114
1150
|
} else {
|
|
1115
1151
|
updatedEntityOneRelationProps[property.code] = null;
|
|
1116
|
-
|
|
1152
|
+
rowToBeSaved[property.targetIdColumnName!] = null;
|
|
1117
1153
|
}
|
|
1118
1154
|
}
|
|
1119
1155
|
|
|
@@ -1122,16 +1158,52 @@ async function updateEntityById(server: IRpdServer, dataAccessor: IRpdDataAccess
|
|
|
1122
1158
|
updatedRow = await dataAccessor.updateById(id, row);
|
|
1123
1159
|
}
|
|
1124
1160
|
let updatedBaseRow = baseRow;
|
|
1125
|
-
|
|
1126
|
-
|
|
1161
|
+
let baseDataAccessor: any;
|
|
1162
|
+
if (model.base) {
|
|
1163
|
+
baseDataAccessor = server.getDataAccessor({
|
|
1127
1164
|
singularCode: model.base,
|
|
1128
1165
|
});
|
|
1129
|
-
|
|
1166
|
+
if (Object.keys(baseRow).length) {
|
|
1167
|
+
updatedBaseRow = await baseDataAccessor.updateById(id, updatedBaseRow);
|
|
1168
|
+
}
|
|
1130
1169
|
}
|
|
1131
1170
|
|
|
1132
1171
|
let updatedEntity = mapDbRowToEntity(server, model, { ...updatedRow, ...updatedBaseRow, ...updatedEntityOneRelationProps }, true);
|
|
1133
1172
|
updatedEntity = Object.assign({}, entity, updatedEntity);
|
|
1134
1173
|
|
|
1174
|
+
// save one-relation properties that has selfIdColumnName
|
|
1175
|
+
for (const property of oneRelationPropertiesToUpdate) {
|
|
1176
|
+
const fieldValue = changes[property.code];
|
|
1177
|
+
const targetDataAccessor = server.getDataAccessor({
|
|
1178
|
+
singularCode: property.targetSingularCode!,
|
|
1179
|
+
});
|
|
1180
|
+
if (isObject(fieldValue)) {
|
|
1181
|
+
const targetEntityId = fieldValue["id"];
|
|
1182
|
+
if (!targetEntityId) {
|
|
1183
|
+
if (property.selfIdColumnName) {
|
|
1184
|
+
const targetEntity = fieldValue;
|
|
1185
|
+
targetEntity[property.selfIdColumnName] = updatedEntity.id;
|
|
1186
|
+
const newTargetEntity = await createEntity(server, targetDataAccessor, {
|
|
1187
|
+
routeContext,
|
|
1188
|
+
entity: targetEntity,
|
|
1189
|
+
});
|
|
1190
|
+
|
|
1191
|
+
let dataAccessorOfMainEntity = dataAccessor;
|
|
1192
|
+
if (property.isBaseProperty) {
|
|
1193
|
+
dataAccessorOfMainEntity = baseDataAccessor;
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1196
|
+
const relationFieldChanges = {
|
|
1197
|
+
[property.targetIdColumnName]: newTargetEntity.id,
|
|
1198
|
+
};
|
|
1199
|
+
await dataAccessorOfMainEntity.updateById(updatedEntity.id, relationFieldChanges);
|
|
1200
|
+
updatedEntity[property.code] = newTargetEntity;
|
|
1201
|
+
changes[property.code] = newTargetEntity;
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1135
1207
|
// save many-relation properties
|
|
1136
1208
|
for (const property of manyRelationPropertiesToUpdate) {
|
|
1137
1209
|
const relatedEntities: any[] = [];
|
|
@@ -1386,7 +1458,7 @@ export default class EntityManager<TEntity = any> {
|
|
|
1386
1458
|
return await updateEntityById(this.#server, this.#dataAccessor, options, plugin);
|
|
1387
1459
|
}
|
|
1388
1460
|
|
|
1389
|
-
async count(options: CountEntityOptions): Promise<
|
|
1461
|
+
async count(options: CountEntityOptions): Promise<number> {
|
|
1390
1462
|
const model = this.#dataAccessor.getModel();
|
|
1391
1463
|
let baseModel: RpdDataModel;
|
|
1392
1464
|
if (model.base) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CountEntityOptions, RunEntityActionHandlerOptions } from "~/types";
|
|
1
|
+
import { CountEntityOptions, CountEntityResult, RunEntityActionHandlerOptions } from "~/types";
|
|
2
2
|
import runCollectionEntityActionHandler from "~/helpers/runCollectionEntityActionHandler";
|
|
3
3
|
import { removeFiltersWithNullValue } from "~/helpers/filterHelper";
|
|
4
4
|
import { ActionHandlerContext } from "~/core/actionHandler";
|
|
@@ -7,9 +7,10 @@ import { RapidPlugin } from "~/core/server";
|
|
|
7
7
|
export const code = "countCollectionEntities";
|
|
8
8
|
|
|
9
9
|
export async function handler(plugin: RapidPlugin, ctx: ActionHandlerContext, options: RunEntityActionHandlerOptions) {
|
|
10
|
-
await runCollectionEntityActionHandler(ctx, options, code, (entityManager, input: CountEntityOptions) => {
|
|
10
|
+
await runCollectionEntityActionHandler(ctx, options, code, async (entityManager, input: CountEntityOptions): Promise<CountEntityResult> => {
|
|
11
11
|
input.filters = removeFiltersWithNullValue(input.filters);
|
|
12
12
|
input.routeContext = ctx.routerContext;
|
|
13
|
-
|
|
13
|
+
const count = await entityManager.count(input);
|
|
14
|
+
return { count };
|
|
14
15
|
});
|
|
15
16
|
}
|
|
@@ -18,8 +18,8 @@ export async function handler(plugin: RapidPlugin, ctx: ActionHandlerContext, op
|
|
|
18
18
|
|
|
19
19
|
if (input.pagination && !input.pagination.withoutTotal) {
|
|
20
20
|
// TOOD: count entities when calling findEntities for performance.
|
|
21
|
-
const
|
|
22
|
-
result.total =
|
|
21
|
+
const total = await entityManager.count(input);
|
|
22
|
+
result.total = total;
|
|
23
23
|
}
|
|
24
24
|
return result;
|
|
25
25
|
});
|
package/src/types.ts
CHANGED
|
@@ -456,7 +456,7 @@ export interface IRpdDataAccessor<T = any> {
|
|
|
456
456
|
find(options: FindRowOptions): Promise<T[]>;
|
|
457
457
|
findOne(options: FindRowOptions): Promise<T | null>;
|
|
458
458
|
findById(id: any): Promise<T | null>;
|
|
459
|
-
count(options: CountRowOptions): Promise<
|
|
459
|
+
count(options: CountRowOptions): Promise<number>;
|
|
460
460
|
deleteById(id: any): Promise<void>;
|
|
461
461
|
}
|
|
462
462
|
|