Skip to content

Commit 4f42bfd

Browse files
committed
Optimizing implementation
1 parent f2980ea commit 4f42bfd

File tree

7 files changed

+108
-402
lines changed

7 files changed

+108
-402
lines changed

lib/change-log.js

Lines changed: 22 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,7 @@
11
const cds = require("@sap/cds")
22
const getTemplate = require("@sap/cds/libx/_runtime/common/utils/template") // REVISIT: bad usage of internal stuff
33
const templateProcessor = require("./template-processor")
4-
const { big } = require("@sap/cds-foss") // REVISIT: Do we really need that?
54
const LOG = cds.log("change-log")
6-
const {
7-
OBJECT_PATH_DELIMITER,
8-
TX_CONTEXT_PATH_DELIMITER,
9-
VALUE_DELIMITER,
10-
} = require("./constants")
11-
const CHANGE_LOG_ANNOTATION = "@changelog"
125

136
const {
147
getNameFromPathVal,
@@ -17,11 +10,8 @@ const {
1710
getCurObjFromDbQuery,
1811
getObjectId,
1912
getDBEntity,
20-
getEntity,
2113
getEntityByContextPath,
22-
hasComposition,
2314
getObjIdElementNamesInArray,
24-
getAssociationCompositionEntity,
2515
getValueEntityType,
2616
} = require("./entity-helper")
2717
const { localizeLogFields } = require("./localization")
@@ -31,7 +21,7 @@ const _getRootEntityPathVals = function (txContext, entity, entityKey) {
3121
const serviceEntityPathVals = []
3222
const entityIDs = _getEntityIDs(txContext.params)
3323

34-
let path = txContext.path.split(TX_CONTEXT_PATH_DELIMITER)
24+
let path = txContext.path.split('/')
3525

3626
if (txContext.event === "CREATE") {
3727
const curEntityPathVal = `${entity.name}(${entityKey})`
@@ -61,7 +51,7 @@ const _getRootEntityPathVals = function (txContext, entity, entityKey) {
6151

6252
const _getAllPathVals = function (txContext) {
6353
const pathVals = []
64-
const paths = txContext.path.split(TX_CONTEXT_PATH_DELIMITER)
54+
const paths = txContext.path.split('/')
6555
const entityIDs = _getEntityIDs(txContext.params)
6656

6757
for (let idx = 0; idx < paths.length; idx++) {
@@ -91,10 +81,6 @@ const _getEntityIDs = function (txParams) {
9181
return entityIDs
9282
}
9383

94-
const _pick = (element) => {
95-
return element[CHANGE_LOG_ANNOTATION]
96-
}
97-
9884
/**
9985
*
10086
* @param {*} tx
@@ -113,10 +99,10 @@ const _pick = (element) => {
11399
*/
114100
const _formatAssociationContext = async function (changes) {
115101
for (const change of changes) {
116-
const a = getEntity(change.serviceEntity).elements[change.attribute]
102+
const a = cds.model.definitions[change.serviceEntity].elements[change.attribute]
117103
if (a?.type !== "cds.Association") continue
118104

119-
const semkeys = getObjIdElementNamesInArray(a[CHANGE_LOG_ANNOTATION])
105+
const semkeys = getObjIdElementNamesInArray(a["@changelog"])
120106
if (!semkeys.length) continue
121107

122108
const ID = a.keys[0].ref[0] || 'ID'
@@ -142,8 +128,8 @@ const _getChildChangeObjId = async function (
142128
curNodePathVal,
143129
reqData
144130
) {
145-
const composition = getAssociationCompositionEntity(change.serviceEntity, change.attribute )
146-
const objIdElements = composition ? composition[CHANGE_LOG_ANNOTATION] : null
131+
const composition = cds.model.definitions[change.serviceEntity].elements[change.attribute]
132+
const objIdElements = composition ? composition["@changelog"] : null
147133
const objIdElementNames = getObjIdElementNamesInArray(objIdElements)
148134

149135
return _getObjectIdByPath(
@@ -164,7 +150,7 @@ const _formatCompositionContext = async function (changes, reqData) {
164150
}
165151
for (const childNodeChange of change.valueChangedTo) {
166152
const curChange = Object.assign({}, change)
167-
const path = childNodeChange._path.split(OBJECT_PATH_DELIMITER)
153+
const path = childNodeChange._path.split('/')
168154
const curNodePathVal = path.pop()
169155
curChange.modification = childNodeChange._op
170156
const objId = await _getChildChangeObjId(
@@ -211,11 +197,8 @@ const _formatCompositionValue = function (
211197
}
212198

213199
const _formatCompositionEntityType = function (change) {
214-
const composition = getAssociationCompositionEntity(
215-
change.serviceEntity,
216-
change.attribute
217-
)
218-
const objIdElements = composition ? composition[CHANGE_LOG_ANNOTATION] : null
200+
const composition = cds.model.definitions[change.serviceEntity].elements[change.attribute]
201+
const objIdElements = composition ? composition['@changelog'] : null
219202

220203
if (Array.isArray(objIdElements)) {
221204
// In this case, the attribute is a composition
@@ -242,7 +225,7 @@ const _getObjectIdByPath = async function (
242225
const _formatObjectID = async function (changes, reqData) {
243226
const objectIdCache = new Map()
244227
for (const change of changes) {
245-
const path = change.serviceEntityPath.split(OBJECT_PATH_DELIMITER)
228+
const path = change.serviceEntityPath.split('/')
246229
const curNodePathVal = path.pop()
247230
const parentNodePathVal = path.pop()
248231

@@ -278,68 +261,35 @@ const _isCompositionContextPath = function (aPath) {
278261
if (aPath.length < 2) return false
279262
const target = getEntityByContextPath(aPath)
280263
const parent = getEntityByContextPath(aPath.slice(0, -1))
281-
return hasComposition(parent, target)
264+
if (!parent.compositions) return false
265+
return Object.values(parent.compositions).some(c => c._target === target)
282266
}
283267

284268
const _formatChangeLog = async function (changes, req) {
285269
await _formatObjectID(changes, req.data)
286270
await _formatAssociationContext(changes)
287271
await _formatCompositionContext(changes, req.data)
288-
// _formatFromTo(req, changes)
289272
}
290273

291-
// function _formatFromTo (req, changes) {
292-
// const contentType = req.context.req?.headers["content-type"] // the service API do not have a req header
293-
// const isExponentialDecimals = contentType?.includes("ExponentialDecimals=true")
294-
// for (const change of changes) {
295-
// if (!isExponentialDecimals)
296-
// _formatDecimalValue(change)
297-
// }
298-
// }
299-
300-
// const _formatDecimalValue = function (change) {
301-
// const valueDataTypes = change.valueDataType.split(VALUE_DELIMITER)
302-
// const valueChangedFroms = change.valueChangedFrom.split(VALUE_DELIMITER)
303-
// const valueChangedTos = change.valueChangedTo.split(VALUE_DELIMITER)
304-
// for (const idx in valueDataTypes) {
305-
// if (valueDataTypes[idx] === "cds.Decimal") {
306-
// if (valueChangedFroms[idx]) {
307-
// const bigFrom = big(valueChangedFroms[idx])
308-
// valueChangedFroms[idx] = bigFrom.toFixed()
309-
// }
310-
311-
// if (valueChangedTos[idx]) {
312-
// const bigTo = big(valueChangedTos[idx])
313-
// valueChangedTos[idx] = bigTo.toFixed()
314-
// }
315-
// }
316-
// }
317-
// change.valueChangedFrom = valueChangedFroms.join(VALUE_DELIMITER)
318-
// change.valueChangedTo = valueChangedTos.join(VALUE_DELIMITER)
319-
// }
320-
321-
const _afterReadChangeView = async function (data, req) {
322-
if (!data) {
323-
return
324-
}
325-
326-
localizeLogFields(Array.isArray(data) ? data : [data], req.user.locale)
274+
const _afterReadChangeView = function (data, req) {
275+
if (!data) return
276+
if (!Array.isArray(data)) data = [data]
277+
localizeLogFields(data, req.locale)
327278
}
328279

329280

330281
function _trackedChanges4 (srv, target, diff) {
331-
const template = getTemplate("change-logging", srv, target, { pick: _pick })
282+
const template = getTemplate("change-logging", srv, target, { pick: e => e['@changelog'] })
332283
if (!template.elements.size) return
333284

334285
const changes = []
335286
diff._path = `${target.name}(${diff.ID})`
336287

337288
templateProcessor({
338289
template, row: diff, processFn: ({ row, key, element }) => {
339-
const from = row._old?.[key] ? row._old[key] : undefined
340-
const to = row[key] ? row[key] : undefined
341-
if (from === to)
342-
return
290+
const from = row._old?.[key]
291+
const to = row[key]
292+
if (from === to) return
343293

344294
const keys = Object.keys(element.parent.keys)
345295
.filter(k => k !== "IsActiveEntity")
@@ -373,10 +323,10 @@ const _prepareChangeLogForComposition = async function (entity, entityKey, chang
373323

374324
const parentEntityPathVal = rootEntityPathVals[rootEntityPathVals.length - 2]
375325
const parentKey = getUUIDFromPathVal(parentEntityPathVal)
376-
const serviceEntityPath = rootEntityPathVals.join(OBJECT_PATH_DELIMITER)
326+
const serviceEntityPath = rootEntityPathVals.join('/')
377327
const parentServiceEntityPath = _getAllPathVals(req.context)
378328
.slice(0, rootEntityPathVals.length - 2)
379-
.join(OBJECT_PATH_DELIMITER)
329+
.join('/')
380330

381331
for (const change of changes) {
382332
change.parentEntityID = await _getObjectIdByPath(req.data, parentEntityPathVal, parentServiceEntityPath)

lib/constants.js

Lines changed: 0 additions & 5 deletions
This file was deleted.

0 commit comments

Comments
 (0)