@sap/xsodata
Version:
Expose data from a HANA database as OData V2 service with help of .xsodata files.
338 lines (300 loc) • 9.92 kB
JavaScript
;
//Include
const dataCollector2 = require('./dataCollector2');
const statementProcessor = require('./statementProcessor');
exports.moveRecordNV_ToSelectStm = function (context, asyncDone) {
context.logger.silly('dataCollectorLinks', 'moveRecordNV_ToSelectStm');
//get dbSegment to be updated, for inserting the payload
const dbSeg = context.oData.links.toBeUpdated;
const stm = dbSeg.sql.stmContainer.insertTmp;
if (!stm) {
return asyncDone(new Error('An error occurred.'), context);
}
for (const nv of dbSeg._recordNV) {
stm.setValue(nv.name, nv.value);
}
return asyncDone(null, context);
};
exports.movePayloadFromMNSegmentToSelectStm = function (context, asyncDone) {
//get dbSegment for inserting the payload
const dbSeg = context.oData.dbSegmentLast;
const stm = dbSeg.sql.stmContainer.insertTmp;
if (!stm) {
return asyncDone(new Error('An error occurred.'), context);
}
// property names are read from association's 'over' , e.g. ID_A, ID_B
// values are taken from the corresponding DBSegments' key values
// overDependent
// ORDER
const from = dbSeg.getFrom();
const to = dbSeg.getTo();
for (let i = 0; i < from.joinproperties.length; i++) {
for (let kv of context.oData.dbSegment._KeyValues) {
if (kv.name === from.joinproperties[i]) {
stm.setValue(
from.overRefProp[i],
context.oData.dbSegment._KeyValues[i].value
);
}
}
}
for (let i = 0; i < to.joinproperties.length; i++) {
for (let kv of context.oData.dbSegmentLast._KeyValues) {
if (kv.name === to.joinproperties[i]) {
stm.setValue(
to.overRefProp[i],
context.oData.dbSegmentLast._KeyValues[i].value
);
}
}
}
return asyncDone(null, context);
};
exports.createTmpTables = function (context, asyncDone) {
const dbSeg = context.oData.links.toBeUpdated;
const stms = [
dbSeg.sql.stmContainer.createTmpOld,
dbSeg.sql.stmContainer.createTmp,
dbSeg.sql.stmContainer.createPrincipal,
dbSeg.sql.stmContainer.createDependent,
];
return statementProcessor.execStmsDirectlyNoResult(
context,
stms,
asyncDone
);
};
exports.createTmpTableMN = function (context, asyncDone) {
const dbSeg = context.oData.dbSegmentLast;
const stms = [
dbSeg.sql.stmContainer.createTmp,
dbSeg.sql.stmContainer.createPrincipal,
dbSeg.sql.stmContainer.createDependent,
];
return statementProcessor.execStmsDirectlyNoResult(
context,
stms,
asyncDone
);
};
exports.insertOldDataToOldTable = function (context, asyncDone) {
const dbSeg = context.oData.links.toBeUpdated;
statementProcessor.execStmsAsPrepared(
context,
[dbSeg.sql.stmContainer.insertTmpOld],
(err, context, resultset) => {
if (err) {
return asyncDone(err, context);
}
return dataCollector2.resultSetCheckRowCountForUpdate(
context,
resultset,
0,
1,
asyncDone
);
}
);
};
/**
* insert corresponding data to the temp principal|dependent tables
* */
exports.insertOldDataToPrincipalDependentTables = function (
context,
asyncDone
) {
const dbSeg = context.oData.links.toBeUpdated;
const stms = [
dbSeg.sql.stmContainer.insertPrincipal,
dbSeg.sql.stmContainer.insertDependent,
];
return statementProcessor.execStmsAsPreparedNoResult(
context,
stms,
asyncDone
);
};
exports.insertPayloadIntoTempTable = function (context, asyncDone) {
const dbSeg = context.oData.links.toBeUpdated;
context.logger.silly('dataCollectorLinks', 'insertPayloadIntoTempTable');
statementProcessor.execStmsAsPrepared(
context,
[dbSeg.sql.stmContainer.insertTmp],
(err, context, resultset) => {
if (err) {
return asyncDone(err, context);
}
return dataCollector2.resultSetCheckRowCountForUpdate(
context,
resultset,
0,
1,
asyncDone
);
}
);
};
exports.insertTmpTableToRealTable = function (context, asyncDone) {
context.logger.silly('dataCollectorLinks', 'insertTmpTableToRealTable');
const dbSeg = context.oData.links.toBeUpdated;
statementProcessor.execStmsAsPrepared(
context,
[dbSeg.sql.stmContainer.updateReal],
(err, context, resultset) => {
if (err) {
return asyncDone(err, context);
}
return dataCollector2.resultSetCheckRowCountForUpdate(
context,
resultset,
0,
1,
asyncDone
);
}
);
};
exports.commit = function (context, asyncDone) {
if (context.batchContext) {
//When running in batch the commit is performed by the batch executor
return asyncDone(null, context);
}
const client = context.db.client;
context.logger.debug('dataCollectorLinks', 'commit');
client.commit(function (err) {
if (err) {
context.logger.info(
'SQL Exec',
'Commit Error: \n' + JSON.stringify(err)
);
return asyncDone(err, context);
}
return asyncDone(null, context);
});
};
/**
* Executes truncation of temporary created tables for MxN tables
*
* @param {Object} context The xsodata context
* @param {Function} asyncDone async waterfall callback
*/
exports.truncateTempTablesMN = function (context, asyncDone) {
let statements;
context.logger.silly('dataCollectorLinks', 'truncateTempTablesMN');
statements = [
context.sql.container.createTmpTruncate,
context.sql.container.createPrincipalTruncate,
context.sql.container.createDependentTruncate,
];
return statementProcessor.execTempTableStatements(
context,
statements,
(err, context) => {
if (err) {
context.logger.silly(
'truncateTempTablesMN',
'dropTempTablesMN rc !=0 but OK'
);
}
return asyncDone(null, context);
}
);
};
/**
* Executes deletion of temporary created MxN tables
*
* @param {Object} context The xsodata context
* @param {Function} asyncDone async waterfall callback
*/
exports.dropTempTablesMN = function (context, asyncDone) {
let statements;
context.logger.silly('dataCollectorLinks', 'dropTempTablesMN');
statements = [
context.sql.container.createTmpDrop,
context.sql.container.createPrincipalDrop,
context.sql.container.createDependentDrop,
];
return statementProcessor.execTempTableStatements(
context,
statements,
(err, context) => {
if (err) {
context.logger.silly(
'dropTempTablesMN',
'dropTempTablesMN rc !=0 but OK'
);
}
return asyncDone(null, context);
}
);
};
/**
* Executes truncation of temporary created tables
*
* @param {Object} context The xsodata context
* @param {Function} asyncDone async waterfall callback
*/
exports.truncateTempTables = function (context, asyncDone) {
let statements;
context.logger.silly('dataCollectorLinks', 'truncateTempTables');
// Special hack for $batch.
// In batch we do not know at this place if we are in m2n mode or not.
// If 'createTmpOldTruncate' property exists than we are in m2n mode
if (!context.sql.container.createTmpOldTruncate) {
return exports.truncateTempTablesMN(context, asyncDone);
}
statements = [
context.sql.container.createTmpTruncate,
context.sql.container.createTmpOldTruncate,
context.sql.container.createPrincipalTruncate,
context.sql.container.createDependentTruncate,
];
return statementProcessor.execTempTableStatements(
context,
statements,
(err, context) => {
if (err) {
context.logger.silly(
'dataCollectorLinks',
'truncateTempTables rc !=0 but OK'
);
}
return asyncDone(null, context);
}
);
};
/**
* Executes deletion of temporary created tables
*
* @param {Object} context The xsodata context
* @param {Function} asyncDone async waterfall callback
*/
exports.dropTempTables = function (context, asyncDone) {
let statements;
context.logger.silly('dataCollectorLinks', 'dropTempTables');
// Special hack for $batch.
// In batch we do not know at this place if we are in m2n mode or not.
// If 'createTmpOldDrop' property exists than we are in m2n mode
if (!context.sql.container.createTmpOldDrop) {
return exports.dropTempTablesMN(context, asyncDone);
}
statements = [
context.sql.container.createTmpDrop,
context.sql.container.createTmpOldDrop,
context.sql.container.createPrincipalDrop,
context.sql.container.createDependentDrop,
];
return statementProcessor.execTempTableStatements(
context,
statements,
(err, context) => {
if (err) {
context.logger.silly(
'dataCollectorLinks',
'dropTempTables rc !=0 but OK'
);
}
return asyncDone(null, context);
}
);
};