@sap/xsodata
Version:
Expose data from a HANA database as OData V2 service with help of .xsodata files.
162 lines (124 loc) • 5.62 kB
JavaScript
;
//Include
const NotFoundError = require('./../utils/errors/http/notFound');
const SqlError = require('../utils/errors/sqlError');
const CreateSqlErrorLog = (context, err, sql, parameters) => {
if (!err) {
return;
}
context.logger.error('SQL Exec', 'Error: ' + err);
context.logger.error('SQL Exec', 'SQL: ' + sql);
context.logger.logSqlParameters(parameters, true, true); // force parameter logging as error
return new SqlError(context, err);
};
const executeSqlAsPreparedStatement = (context, sql, parameters, rowCb) => {
const client = context.db.client;
let startTime = 0;
context.logger.logSqlCommand(sql);
context.logger.logSqlParameters(parameters, true); // force parameter logging
startTime = context.logger.getStartTimeSql();
client.prepare(sql, (errPrep, statement) => {
context.logger.logSqlTime('prepare', startTime, sql);
if (errPrep) {
return rowCb(CreateSqlErrorLog(context, errPrep, sql, parameters));
}
startTime = context.logger.getStartTimeSql();
let sqlLower = sql.toLowerCase().trim();
if (sqlLower.startsWith('select') && typeof statement.execQuery === "function") {
// use execQuery
statement.execQuery(parameters, (errExec, resultSet) => {
context.logger.logSqlTime('execQuery', startTime, sql);
const rs = [];
global.execCounter += 1;
if (resultSet && !errExec) {
while (resultSet.next()) {
rs.push(resultSet.getValues());
}
resultSet.close((errClose) => {
context.logger.logSqlTime('close', startTime, sql);
if (errClose) {
context.logger.debug('Could not close ResultSet:', errClose.message);
}
});
}
// try dropping the statement always; report exec error in CB
startTime = context.logger.getStartTimeSql();
statement.drop((errDrop) => {
global.dropCounter += 1;
context.logger.logSqlTime('drop', startTime, sql);
if (errDrop) {
// don't hide any execution error, just log
context.logger.debug('Could not drop statement:', errDrop.message);
}
if (errExec) {
return rowCb(CreateSqlErrorLog(context, errExec, sql, parameters));
}
if (rs) {
context.logger.logSqlData(rs);
}
return rowCb(null, rs);
});
});
} else {
// all other statements use exec
startTime = context.logger.getStartTimeSql();
statement.exec(parameters, (errExec, rows) => {
global.execCounter += 1;
context.logger.logSqlTime('exec', startTime, sql);
if (rows) {
context.logger.logSqlData(rows);
}
// try dropping the statement always; report exec error in CB
startTime = context.logger.getStartTimeSql();
statement.drop((errDrop) => {
global.dropCounter += 1;
context.logger.logSqlTime('drop', startTime, sql);
if (errDrop) {
// don't hide any execution error, just log
context.logger.debug('Could not drop statement:', errDrop.message);
}
if (errExec) {
return rowCb(CreateSqlErrorLog(context, errExec, sql, parameters));
}
return rowCb(null, rows);
});
});
}
});
};
const executeSqlAsPreparedStatementNoResult = (context, sql, parameters, cb) => {
executeSqlAsPreparedStatement(context, sql, parameters, (err) => {
return cb(err);
});
};
const executeSqlDirectly = (context, sql, cb) => {
const client = context.db.client;
context.logger.logSqlCommand(sql);
let startTime = context.logger.getStartTimeSql();
client.exec(sql, (errExec, rows) => {
context.logger.logSqlTime('exec', startTime, sql);
return cb(CreateSqlErrorLog(context, errExec, sql), rows);
});
};
const executeSqlDirectlyNoResult = (context, sql, cb) => {
executeSqlDirectly(context, sql, (err) => {
return cb(err);
});
};
exports.resultSetCheckRowCountForUpdate = function (context, resultSet, index, expectedAffectedRows, asyncDone) {
if (!resultSet || !Array.isArray(resultSet)) {
return asyncDone(new NotFoundError("Empty resultset"), context);
}
if (index >= resultSet.length) {
return asyncDone(new NotFoundError("Wrong resultset count"), context);
}
const affectedRows = resultSet[index];
if (affectedRows !== expectedAffectedRows) {
return asyncDone(new NotFoundError("Could not modify resource. Resource does not exist"), context);
}
return asyncDone(null, context);
};
module.exports.executeSqlDirectly = executeSqlDirectly;
module.exports.executeSqlDirectlyNoResult = executeSqlDirectlyNoResult;
module.exports.executeSqlAsPreparedStatement = executeSqlAsPreparedStatement;
module.exports.executeSqlAsPreparedStatementNoResult = executeSqlAsPreparedStatementNoResult;