@sap/xsodata
Version:
Expose data from a HANA database as OData V2 service with help of .xsodata files.
205 lines (171 loc) • 6.09 kB
JavaScript
'use strict';
const sql = require('./sqlStatement');
const sqlTools = require('./sqlTools');
exports.createDeleteStatementsForCreateTmpTables = function (
context,
asyncDone
) {
const dbSegLast = context.oData.dbSegmentLast;
context.logger.silly(
'createDeleteStatements',
'createDeleteStatementsForCreateTmpTables'
);
const sqlContext = {
context: context,
netId: context.uniqueNetworkRequestID,
reqId: context.uniqueRequestID,
rIdOld: 1,
dbSegLast: dbSegLast,
systemQueryParameters: context.oData.systemQueryParameters,
};
context.sql = sqlContext;
dbSegLast.sql.stmContainer = new sql.DeleteContainer();
startDeleteMasterDbSegForCreate(sqlContext);
return asyncDone(null, context);
};
exports.createDeleteStatementsForDelete = function (context, asyncDone) {
const sqlContext = context.sql;
context.logger.silly(
'createDeleteStatements',
'createDeleteStatementsForDelete'
);
startDeleteMasterDbSegForDelete(sqlContext);
return asyncDone(null, context);
};
/**
* Create SQL statements for the master table (=end of resource path)
* @param sqlContext
*/
function startDeleteMasterDbSegForCreate(sqlContext) {
const dbSeg = sqlContext.dbSegLast,
stmtContainer = dbSeg.sql.stmContainer;
sqlContext.context.sql.container = stmtContainer;
sqlContext.context.logger.debug(
'createDeleteStatements',
'startDeleteMasterDbSegForCreate'
);
// Must be renamed rIdOld (from rId), in order to land in 'beforeTableName' of exitProcessor
dbSeg.sql.rIdOld = sqlTools.rIdToOldTableName(
dbSeg._Alias,
sqlContext.netId,
sqlContext.reqId,
sqlContext.rIdOld
);
sqlContext.rIdOld++;
//create statement for master table
dbSeg.sql.stmContainer.createTmpDel = masterTableCreate(
sqlContext,
dbSeg.sql.rIdOld
);
}
/**
* Create SQL statements for the master table (=end of resource path)
* @param sqlContext
*/
function startDeleteMasterDbSegForDelete(sqlContext) {
const dbSeg = sqlContext.dbSegLast,
stmtContainer = dbSeg.sql.stmContainer;
sqlContext.context.sql.container = stmtContainer;
sqlContext.context.logger.debug(
'createDeleteStatements',
'startDeleteMasterDbSegForDelete'
);
//create insert statement for master table
dbSeg.sql.stmContainer.insertTmpDel = masterTableInsertToDel(
sqlContext,
dbSeg.sql.rIdOld
);
//create select statement for master table
dbSeg.sql.stmContainer.delete = masterTableDelete(sqlContext);
if (sqlContext.context.db.isExternalHandledConnection === true) {
// We only truncate and delete temp tables when db connection is handled external
// otherwise we will self disconnect and temp tables will be deleted automatically
// build the truncate statement for created temporary table;
stmtContainer.createTmpDelTruncate = sql.buildTableStatement(
sql.Truncate,
sqlContext,
stmtContainer.createTmpDel.table
);
sqlContext.context.networkContext.cleanSessionTruncateContainer.push(
stmtContainer.createTmpDelTruncate
);
// build the drop statement for created temporary table;
stmtContainer.createTmpDelDrop = sql.buildTableStatement(
sql.Drop,
sqlContext,
stmtContainer.createTmpDel.table
);
sqlContext.context.networkContext.cleanSessionDropContainer.push(
stmtContainer.createTmpDelDrop
);
}
}
function masterTableCreate(sqlContext, rId) {
sqlContext.context.logger.debug(
'createPostStatements',
'masterTableCreate (ordered selects)'
);
const dbSeg = sqlContext.dbSegLast;
const stmCreate = new sql.Create();
stmCreate.setModifiers([
'local',
'temporary',
dbSeg.entityType.tableStoreType,
]);
stmCreate.setTableName(rId);
const prop = dbSeg.getPropertiesForCreate();
const propDbOrdered = dbSeg.makeDbOrdered(prop);
stmCreate.addProperties(propDbOrdered);
if (dbSeg._ExpandedNavigations.length > 0) {
stmCreate.addProperties(dbSeg.getNavPropertiesForCreate());
}
return stmCreate;
}
function masterTableInsertToDel(sqlContext, rIdOld) {
sqlContext.context.logger.debug(
'createDeleteStatements',
'masterTableInsertToDel (ordered selects)'
);
const dbSeg = sqlContext.dbSegLast;
const subSelect = new sql.Select();
if (
dbSeg.entityType.kind === 3 &&
dbSeg.entityType._entityType.parameters &&
dbSeg.entityType._entityType.parameters.viaKey === true
) {
subSelect.addSelects(dbSeg.getPropertiesForSelect());
subSelect.addSelects(dbSeg.getKeyPropertiesNotSelectedForSelect());
subSelect.addFrom(
dbSeg.getAliasedTableName(),
dbSeg.getInputParameters()
);
subSelect.addWhereKeyValuePairs(dbSeg.getQKeyWithValues());
} else {
const prop = dbSeg.getQKeyPropertiesForSelect();
const all = prop.concat(dbSeg.getQNonKeyPropertiesForSelect());
const allDbOrdered = dbSeg.makeDbOrdered(all);
subSelect.addSelects(allDbOrdered);
subSelect.setFrom(dbSeg.getAliasedTableName());
subSelect.addWhereKeyValuePairs(dbSeg.getQKeyWithValuesDB());
}
const stm = new sql.Insert();
stm.setTableName({ table: rIdOld });
stm.setSubSelect(subSelect);
return stm;
}
/**
* Create select SQL statement for master table
* @param sqlContext
* @returns {Delete}
*/
function masterTableDelete(sqlContext) {
sqlContext.context.logger.debug(
'createDeleteStatements',
'masterTableDelete'
);
const dbSeg = sqlContext.dbSegLast;
const delete1 = new sql.Delete();
delete1.setFrom(dbSeg.getAliasedTableName());
delete1.addWhereKeyValuePairs(dbSeg.getQKeyWithValues());
return delete1;
}