UNPKG

@sap/xsodata

Version:

Expose data from a HANA database as OData V2 service with help of .xsodata files.

132 lines (118 loc) 5.36 kB
'use strict'; const model = require('../model/model.js'); const typeConverter = require('./../utils/typeConverter'); // STEP batch create tables --> after tmp tables are created // Calculate a ContentId from request payload // ATTENTION the ContentId may not be save since application data may still be missing (e.g. auto generated keys). // for missing values nil will be inserted, so the contentId is save for tmp table creation of following requests. // The counterpart of createNewContentIdFromRecordMapFromPayload is checkUriForContentIDs module.exports.createNewContentIdFromRecordMapFromPayload = function ( context, asyncDone ) { const dbSeg = context.oData.dbSegmentLast; try { const keysProperties = dbSeg.getKeysProperties(); let newContentId = dbSeg.entityType.name; newContentId += '(' + keysProperties.map(toValues).join(',') + ')'; context.contentId = newContentId; context.logger.debug( 'createNewContentIdFromRecordMapFromPayload done', newContentId ); return asyncDone(null, context); } catch (err) { return asyncDone(err, context); } function toValues(keyProperty, index, array) { // Here the _recordMapFromPayload is used and not the reselected data from the database (as in createAbsUrl). // This is because in batch processing the uris for all batch requests need to be parsed for creating the // tmp tables (and for uri parsing the context uris form previous requests are required) before the real // processing of the batch request starts. let value = null; if ( dbSeg._recordMapFromPayload[keyProperty.COLUMN_NAME] !== undefined && dbSeg._recordMapFromPayload[keyProperty.COLUMN_NAME] !== null ) { // 0 is a valid value // If a key is not in the incoming payload then substitute the key with nil. This satisfies the uri parser // in the "batch create tables" step in order to create the tmp tables. The assumption is that this // key is created later on in an application exit or with an sequence and hence the correct // contentID is anyway created later value = typeConverter.serializeDbValueToUriLiteral( dbSeg._recordMapFromPayload[keyProperty.COLUMN_NAME], keyProperty ); } if (array.length === 1) { return value ? value : 'nil'; } return keyProperty.COLUMN_NAME + '=' + (value ? value : 'nil'); } }; // STEP batch processing --> after data is inserted into real table // Update contentId information with values created from the db module.exports.createNewContentIdFromDbSegSelectedRows = function ( context, asyncDone ) { const dbSeg = context.oData.dbSegmentLast; try { let contentId = dbSeg.entityType.name; const keysProperties = dbSeg.getKeysProperties(); const rows = dbSeg.getRowsWithGenKey(); const row = rows[0]; let value; context.contentIdKeyObj = {}; contentId += '('; if (keysProperties.length === 1) { const keyProperty = keysProperties[0]; value = typeConverter.serializeDbValueToUriLiteral( row[keyProperty.COLUMN_NAME], keyProperty ); contentId += value; context.contentIdKeyObj[keyProperty.COLUMN_NAME] = value; } else { for (let i = 0; i < keysProperties.length; i++) { const keyProperty = keysProperties[i]; if (i !== 0) { contentId += ','; } if (row[keyProperty.COLUMN_NAME] === null) { contentId += keyProperty.COLUMN_NAME + '=' + 'null'; context.contentIdKeyObj[keyProperty.COLUMN_NAME] = 'null'; } else if (row[keyProperty.COLUMN_NAME] === undefined) { // for create, update, delete on a calcview input parameters are optional and are rendered with null in context url if ( dbSeg.entityType.kind === model.entityKind.inputParameters || dbSeg.entityType.kind === model.entityKind.calculationView ) { contentId += keyProperty.COLUMN_NAME + '=' + 'null'; context.contentIdKeyObj[keyProperty.COLUMN_NAME] = 'null'; } } else { value = typeConverter.serializeDbValueToUriLiteral( row[keyProperty.COLUMN_NAME], keyProperty ); contentId += keyProperty.COLUMN_NAME + '=' + value; context.contentIdKeyObj[keyProperty.COLUMN_NAME] = value; } } } contentId += ')'; context.contentId = contentId; context.logger.debug( 'createNewContentIdFromDbSegSelectedRows done', contentId ); return asyncDone(null, context); } catch (err) { return asyncDone(err, context); } };