Рефакторинг: приведение полей объектов и параметров процедур к общему стилю + песочница npm test
This commit is contained in:
parent
ea74ff4ed1
commit
326565d3b4
14
config.js
14
config.js
@ -10,23 +10,23 @@
|
||||
//Параметры подключения к БД
|
||||
let dbConnect = {
|
||||
//Пользователь БД
|
||||
user: "parus",
|
||||
sUser: "parus",
|
||||
//Пароль пользователя БД
|
||||
password: "parus",
|
||||
sPassword: "parus",
|
||||
//Строка подключения к БД
|
||||
connectString: "DEMOP_CITKSERV_WAN",
|
||||
sConnectString: "DEMOP_CITKSERV_WAN",
|
||||
//Наименование модуля (для сессии БД)
|
||||
sessionModuleName: "PARUS$ExchangeServer",
|
||||
sSessionModuleName: "PARUS$ExchangeServer",
|
||||
//Подключаемый модуль обслуживания БД (низкоуровневые функции работы с СУБД)
|
||||
connectorModule: "parus_oracle_db.js"
|
||||
sConnectorModule: "parus_oracle_db.js"
|
||||
};
|
||||
|
||||
//Параметры обработки очереди исходящих сообщений
|
||||
let outgoing = {
|
||||
//Размер блока одновременно обрабатываемых исходящих сообщений
|
||||
portionSize: 1,
|
||||
nPortionSize: 1,
|
||||
//Скорость проверки наличия исходящих сообщений (мс)
|
||||
checkTimeout: 500
|
||||
nCheckTimeout: 500
|
||||
};
|
||||
|
||||
//-----------------
|
||||
|
@ -17,9 +17,9 @@ const { ServerError } = require("@core/server_errors.js"); //Типовая ош
|
||||
//----------
|
||||
|
||||
//Состояния записей журнала работы сервиса
|
||||
const MSG_TYPE_INF = 0; //Информация
|
||||
const MSG_TYPE_WRN = 1; //Предупреждение
|
||||
const MSG_TYPE_ERR = 2; //Ошибка
|
||||
const NLOG_STATE_INF = 0; //Информация
|
||||
const NLOG_STATE_WRN = 1; //Предупреждение
|
||||
const NLOG_STATE_ERR = 2; //Ошибка
|
||||
|
||||
//------------
|
||||
// Тело модуля
|
||||
@ -27,23 +27,23 @@ const MSG_TYPE_ERR = 2; //Ошибка
|
||||
|
||||
class DBConnector {
|
||||
//Конструктор
|
||||
constructor(dbConnect) {
|
||||
constructor(prms) {
|
||||
//Проверяем структуру переданного объекта для подключения
|
||||
let checkResult = checkObject(dbConnect, {
|
||||
let checkResult = checkObject(prms, {
|
||||
fields: [
|
||||
{ name: "user", required: true },
|
||||
{ name: "password", required: true },
|
||||
{ name: "connectString", required: true },
|
||||
{ name: "sessionModuleName", required: true },
|
||||
{ name: "connectorModule", required: false }
|
||||
{ name: "sUser", required: true },
|
||||
{ name: "sPassword", required: true },
|
||||
{ name: "sConnectString", required: true },
|
||||
{ name: "sSessionModuleName", required: true },
|
||||
{ name: "sConnectorModule", required: false }
|
||||
]
|
||||
});
|
||||
//Если структура объекта в норме
|
||||
if (!checkResult) {
|
||||
//Проверяем наличие модуля для работы с БД в настройках подключения
|
||||
if (dbConnect.connectorModule) {
|
||||
if (prms.sConnectorModule) {
|
||||
//Подключим модуль
|
||||
this.connector = require(makeModuleFullPath(dbConnect.connectorModule));
|
||||
this.connector = require(makeModuleFullPath(prms.sConnectorModule));
|
||||
//Проверим его интерфейс
|
||||
if (
|
||||
!checkModuleInterface(this.connector, {
|
||||
@ -61,12 +61,12 @@ class DBConnector {
|
||||
) {
|
||||
throw new ServerError(
|
||||
glConst.ERR_MODULES_BAD_INTERFACE,
|
||||
"Модуль " + dbConnect.module + " реализует неверный интерфейс!"
|
||||
"Модуль " + prms.sConnectorModule + " реализует неверный интерфейс!"
|
||||
);
|
||||
}
|
||||
//Всё успешно - сохраним настройки подключения
|
||||
this.connectSettings = {};
|
||||
_.extend(this.connectSettings, dbConnect);
|
||||
_.extend(this.connectSettings, prms);
|
||||
//Инициализируем остальные свойства
|
||||
this.connection = {};
|
||||
} else {
|
||||
@ -85,12 +85,12 @@ class DBConnector {
|
||||
//Подключиться к БД
|
||||
async connect() {
|
||||
try {
|
||||
this.connection = await this.connector.connect(
|
||||
this.connectSettings.user,
|
||||
this.connectSettings.password,
|
||||
this.connectSettings.connectString,
|
||||
this.connectSettings.sessionModuleName
|
||||
);
|
||||
this.connection = await this.connector.connect({
|
||||
sUser: this.connectSettings.sUser,
|
||||
sPassword: this.connectSettings.sPassword,
|
||||
sConnectString: this.connectSettings.sConnectString,
|
||||
sSessionModuleName: this.connectSettings.sSessionModuleName
|
||||
});
|
||||
return this.connection;
|
||||
} catch (e) {
|
||||
throw new ServerError(glConst.ERR_DB_CONNECT, e.message);
|
||||
@ -99,7 +99,7 @@ class DBConnector {
|
||||
//Отключиться от БД
|
||||
async disconnect() {
|
||||
try {
|
||||
await this.connector.disconnect(this.connection);
|
||||
await this.connector.disconnect({ connection: this.connection });
|
||||
this.connection = {};
|
||||
return;
|
||||
} catch (e) {
|
||||
@ -109,9 +109,12 @@ class DBConnector {
|
||||
//Получить список сервисов
|
||||
async getServices() {
|
||||
try {
|
||||
let srvs = await this.connector.getServices(this.connection);
|
||||
let srvs = await this.connector.getServices({ connection: this.connection });
|
||||
let srvsFuncs = srvs.map(async srv => {
|
||||
const response = await this.connector.getServiceFunctions(this.connection, srv.NRN);
|
||||
const response = await this.connector.getServiceFunctions({
|
||||
connection: this.connection,
|
||||
ddd: srv.NRN
|
||||
});
|
||||
let tmp = {};
|
||||
_.extend(tmp, srv, { FN: [] });
|
||||
response.map(f => {
|
||||
@ -126,21 +129,61 @@ class DBConnector {
|
||||
}
|
||||
}
|
||||
//Запись в журнал работы
|
||||
async putLog(msgType, msg, queueID) {
|
||||
try {
|
||||
let res = await this.connector.log(this.connection, msgType, msg, queueID);
|
||||
return res;
|
||||
} catch (e) {
|
||||
throw new ServerError(glConst.ERR_DB_EXECUTE, e.message);
|
||||
async putLog(prms) {
|
||||
//Проверяем структуру переданного объекта для подключения
|
||||
let checkResult = checkObject(prms, {
|
||||
fields: [
|
||||
{ name: "nLogState", required: true },
|
||||
{ name: "sMsg", required: false },
|
||||
{ name: "nServiceId", required: false },
|
||||
{ name: "nServiceFnId", required: false },
|
||||
{ name: "nQueueId", required: false }
|
||||
]
|
||||
});
|
||||
//Если структура объекта в норме
|
||||
if (!checkResult) {
|
||||
try {
|
||||
let res = await this.connector.log({
|
||||
connection: this.connection,
|
||||
nLogState: prms.nLogState,
|
||||
sMsg: prms.sMsg,
|
||||
nServiceId: prms.nServiceId,
|
||||
nServiceFnId: prms.nServiceFnId,
|
||||
nQueueId: prms.nQueueId
|
||||
});
|
||||
return res;
|
||||
} catch (e) {
|
||||
throw new ServerError(glConst.ERR_DB_EXECUTE, e.message);
|
||||
}
|
||||
} else {
|
||||
throw new ServerError(
|
||||
glConst.ERR_OBJECT_BAD_INTERFACE,
|
||||
"qqqОбъект имеет недопустимый интерфейс: " + checkResult
|
||||
);
|
||||
}
|
||||
}
|
||||
//Считать очередную порцию исходящих сообщений
|
||||
async getOutgoing(portionSize) {
|
||||
try {
|
||||
let res = await this.connector.getQueueOutgoing(this.connection, portionSize);
|
||||
return res;
|
||||
} catch (e) {
|
||||
throw new ServerError(glConst.ERR_DB_EXECUTE, e.message);
|
||||
async getOutgoing(prms) {
|
||||
//Проверяем структуру переданного объекта для подключения
|
||||
let checkResult = checkObject(prms, {
|
||||
fields: [{ name: "nPortionSize", required: true }]
|
||||
});
|
||||
//Если структура объекта в норме
|
||||
if (!checkResult) {
|
||||
try {
|
||||
let res = await this.connector.getQueueOutgoing({
|
||||
connection: this.connection,
|
||||
nPortionSize: prms.nPortionSize
|
||||
});
|
||||
return res;
|
||||
} catch (e) {
|
||||
throw new ServerError(glConst.ERR_DB_EXECUTE, e.message);
|
||||
}
|
||||
} else {
|
||||
throw new ServerError(
|
||||
glConst.ERR_OBJECT_BAD_INTERFACE,
|
||||
"Объект имеет недопустимый интерфейс: " + checkResult
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -149,7 +192,7 @@ class DBConnector {
|
||||
// Интерфейс модуля
|
||||
//-----------------
|
||||
|
||||
exports.MSG_TYPE_INF = MSG_TYPE_INF;
|
||||
exports.MSG_TYPE_WRN = MSG_TYPE_WRN;
|
||||
exports.MSG_TYPE_ERR = MSG_TYPE_ERR;
|
||||
exports.NLOG_STATE_INF = NLOG_STATE_INF;
|
||||
exports.NLOG_STATE_WRN = NLOG_STATE_WRN;
|
||||
exports.NLOG_STATE_ERR = NLOG_STATE_ERR;
|
||||
exports.DBConnector = DBConnector;
|
||||
|
@ -73,13 +73,16 @@ const checkObject = (obj, interface) => {
|
||||
let noValues = [];
|
||||
//Обходим проверяемые поля
|
||||
interface.fields.forEach(fld => {
|
||||
//Проверим наличие поля в объекте
|
||||
if (!(fld.name in obj)) {
|
||||
//Проверим наличие поля в объекте (только для обязательных)
|
||||
if (fld.required && !(fld.name in obj)) {
|
||||
//Поля нет
|
||||
noFields.push(fld.name);
|
||||
} else {
|
||||
//Поле есть, проверим наличие значения
|
||||
if (fld.required && !obj[fld.name])
|
||||
if (
|
||||
fld.required &&
|
||||
(obj[fld.name] === "undefined" || obj[fld.name] === null || obj[fld.name] === "")
|
||||
)
|
||||
//Обязательное поле не содержит значения
|
||||
noValues.push(fld.name);
|
||||
}
|
||||
|
@ -38,39 +38,45 @@ const SLOG_STATE_ERR = "ERR"; //Ошибка (строковый код)
|
||||
//------------
|
||||
|
||||
//Подключение к БД
|
||||
const connect = async (user, password, connectString, moduleName) => {
|
||||
const connect = async prms => {
|
||||
try {
|
||||
const conn = await oracledb.getConnection({
|
||||
user,
|
||||
password,
|
||||
connectString
|
||||
});
|
||||
conn.module = moduleName;
|
||||
return conn;
|
||||
if (prms && prms.sUser && prms.sPassword && prms.sConnectString) {
|
||||
const conn = await oracledb.getConnection({
|
||||
user: prms.sUser,
|
||||
password: prms.sPassword,
|
||||
connectString: prms.sConnectString
|
||||
});
|
||||
if (prms.sSessionModuleName) conn.module = prms.sSessionModuleName;
|
||||
return conn;
|
||||
} else {
|
||||
throw new Error(
|
||||
"Не указаны параметры подключения (отсутствует одно из полей: sUser, sPassword, sConnectString)"
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
throw new Error(e.message);
|
||||
}
|
||||
};
|
||||
|
||||
//Отключение от БД
|
||||
const disconnect = async connection => {
|
||||
if (connection) {
|
||||
const disconnect = async prms => {
|
||||
if (prms && prms.connection) {
|
||||
try {
|
||||
const conn = await connection.close();
|
||||
const conn = await prms.connection.close();
|
||||
return;
|
||||
} catch (e) {
|
||||
throw new Error(e.message);
|
||||
}
|
||||
} else {
|
||||
throw new Error("Не указано подключение");
|
||||
throw new Error("Не указано подключение (отсутствует поле: connection)");
|
||||
}
|
||||
};
|
||||
|
||||
//Получение списка сервисов
|
||||
const getServices = async connection => {
|
||||
const getServices = prms => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (connection) {
|
||||
connection.execute(
|
||||
if (prms && prms.connection) {
|
||||
prms.connection.execute(
|
||||
"BEGIN PKG_EXS.SERVICE_GET(RCSERVICES => :RCSERVICES); END;",
|
||||
{ RCSERVICES: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT } },
|
||||
{ outFormat: oracledb.OBJECT },
|
||||
@ -94,115 +100,129 @@ const getServices = async connection => {
|
||||
}
|
||||
);
|
||||
} else {
|
||||
reject(new Error("Не указано подключение"));
|
||||
reject(new Error("Не указано подключение (отсутствует поле: connection)"));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
//Получение списка функций сервиса
|
||||
const getServiceFunctions = (connection, serviceID) => {
|
||||
const getServiceFunctions = prms => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (connection) {
|
||||
connection.execute(
|
||||
"BEGIN PKG_EXS.SERVICEFN_GET(NSERVICE => :NSERVICE, RCSERVICEFNS => :RCSERVICEFNS); END;",
|
||||
{ NSERVICE: serviceID, RCSERVICEFNS: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT } },
|
||||
{ outFormat: oracledb.OBJECT },
|
||||
(err, result) => {
|
||||
if (err) {
|
||||
reject(new Error(err.message));
|
||||
} else {
|
||||
let cursor = result.outBinds.RCSERVICEFNS;
|
||||
let queryStream = cursor.toQueryStream();
|
||||
let rows = [];
|
||||
queryStream.on("data", row => {
|
||||
rows.push(row);
|
||||
});
|
||||
queryStream.on("error", err => {
|
||||
if (prms && prms.connection) {
|
||||
if (prms.nServiceId) {
|
||||
prms.connection.execute(
|
||||
"BEGIN PKG_EXS.SERVICEFN_GET(NSERVICE => :NSERVICE, RCSERVICEFNS => :RCSERVICEFNS); END;",
|
||||
{ NSERVICE: prms.nServiceId, RCSERVICEFNS: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT } },
|
||||
{ outFormat: oracledb.OBJECT },
|
||||
(err, result) => {
|
||||
if (err) {
|
||||
reject(new Error(err.message));
|
||||
});
|
||||
queryStream.on("close", () => {
|
||||
resolve(rows);
|
||||
});
|
||||
} else {
|
||||
let cursor = result.outBinds.RCSERVICEFNS;
|
||||
let queryStream = cursor.toQueryStream();
|
||||
let rows = [];
|
||||
queryStream.on("data", row => {
|
||||
rows.push(row);
|
||||
});
|
||||
queryStream.on("error", err => {
|
||||
reject(new Error(err.message));
|
||||
});
|
||||
queryStream.on("close", () => {
|
||||
resolve(rows);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
);
|
||||
} else {
|
||||
reject(new Error("Не указан идентификатор сервиса"));
|
||||
}
|
||||
} else {
|
||||
reject(new Error("Не указано подключение"));
|
||||
reject(new Error("Не указано подключение (отсутствует поле: connection)"));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
//Запись в протокол работы
|
||||
const log = (connection, logState, msg, queueID) => {
|
||||
const log = prms => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (connection) {
|
||||
connection.execute(
|
||||
"BEGIN PKG_EXS.LOG_PUT(NLOG_STATE => :NLOG_STATE, SMSG => :SMSG, NEXSQUEUE => :NEXSQUEUE, RCLOG => :RCLOG); END;",
|
||||
{
|
||||
NLOG_STATE: logState,
|
||||
SMSG: msg,
|
||||
NEXSQUEUE: queueID,
|
||||
RCLOG: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||
},
|
||||
{ outFormat: oracledb.OBJECT, autoCommit: true },
|
||||
(err, result) => {
|
||||
if (err) {
|
||||
reject(new Error(err.message));
|
||||
} else {
|
||||
let cursor = result.outBinds.RCLOG;
|
||||
let queryStream = cursor.toQueryStream();
|
||||
let rows = [];
|
||||
queryStream.on("data", row => {
|
||||
rows.push(row);
|
||||
});
|
||||
queryStream.on("error", err => {
|
||||
if (prms && prms.connection) {
|
||||
if (!(prms.nLogState === "undefined")) {
|
||||
prms.connection.execute(
|
||||
"BEGIN PKG_EXS.LOG_PUT(NLOG_STATE => :NLOG_STATE, SMSG => :SMSG, NEXSSERVICE => :NEXSSERVICE, NEXSSERVICEFN => :NEXSSERVICEFN, NEXSQUEUE => :NEXSQUEUE, RCLOG => :RCLOG); END;",
|
||||
{
|
||||
NLOG_STATE: prms.nLogState,
|
||||
SMSG: prms.sMsg,
|
||||
NEXSSERVICE: prms.nServiceId,
|
||||
NEXSSERVICEFN: prms.nServiceFnId,
|
||||
NEXSQUEUE: prms.nQueueId,
|
||||
RCLOG: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||
},
|
||||
{ outFormat: oracledb.OBJECT, autoCommit: true },
|
||||
(err, result) => {
|
||||
if (err) {
|
||||
reject(new Error(err.message));
|
||||
});
|
||||
queryStream.on("close", () => {
|
||||
resolve(rows[0]);
|
||||
});
|
||||
} else {
|
||||
let cursor = result.outBinds.RCLOG;
|
||||
let queryStream = cursor.toQueryStream();
|
||||
let rows = [];
|
||||
queryStream.on("data", row => {
|
||||
rows.push(row);
|
||||
});
|
||||
queryStream.on("error", err => {
|
||||
reject(new Error(err.message));
|
||||
});
|
||||
queryStream.on("close", () => {
|
||||
resolve(rows[0]);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
);
|
||||
} else {
|
||||
reject(new Error("Не указан тип сообщения журнала (отсутствует поле: nLogState)"));
|
||||
}
|
||||
} else {
|
||||
reject(new Error("Не указано подключение"));
|
||||
reject(new Error("Не указано подключение (отсутствует поле: connection)"));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
//Считывание очередной порции исходящих сообщений из очереди
|
||||
const getQueueOutgoing = (connection, portionSize) => {
|
||||
const getQueueOutgoing = prms => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (connection) {
|
||||
connection.execute(
|
||||
"BEGIN PKG_EXS.QUEUE_NEXT_GET(NPORTION => :NPORTION, NSRV_TYPE => :NSRV_TYPE, RCQUEUES => :RCQUEUES); END;",
|
||||
{
|
||||
NPORTION: portionSize,
|
||||
NSRV_TYPE: NSRV_TYPE_SEND,
|
||||
RCQUEUES: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||
},
|
||||
{ outFormat: oracledb.OBJECT, autoCommit: true, fetchInfo: { BMSG: { type: oracledb.BUFFER } } },
|
||||
(err, result) => {
|
||||
if (err) {
|
||||
reject(new Error(err.message));
|
||||
} else {
|
||||
let cursor = result.outBinds.RCQUEUES;
|
||||
let queryStream = cursor.toQueryStream();
|
||||
let rows = [];
|
||||
queryStream.on("data", row => {
|
||||
rows.push(row);
|
||||
});
|
||||
queryStream.on("error", err => {
|
||||
if (prms && prms.connection) {
|
||||
if (prms.nPortionSize) {
|
||||
prms.connection.execute(
|
||||
"BEGIN PKG_EXS.QUEUE_NEXT_GET(NPORTION_SIZE => :NPORTION_SIZE, NSRV_TYPE => :NSRV_TYPE, RCQUEUES => :RCQUEUES); END;",
|
||||
{
|
||||
NPORTION_SIZE: prms.nPortionSize,
|
||||
NSRV_TYPE: NSRV_TYPE_SEND,
|
||||
RCQUEUES: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||
},
|
||||
{ outFormat: oracledb.OBJECT, autoCommit: true, fetchInfo: { bMsg: { type: oracledb.BUFFER } } },
|
||||
(err, result) => {
|
||||
if (err) {
|
||||
reject(new Error(err.message));
|
||||
});
|
||||
queryStream.on("close", () => {
|
||||
resolve(rows);
|
||||
});
|
||||
} else {
|
||||
let cursor = result.outBinds.RCQUEUES;
|
||||
let queryStream = cursor.toQueryStream();
|
||||
let rows = [];
|
||||
queryStream.on("data", row => {
|
||||
rows.push(row);
|
||||
});
|
||||
queryStream.on("error", err => {
|
||||
reject(new Error(err.message));
|
||||
});
|
||||
queryStream.on("close", () => {
|
||||
resolve(rows);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
);
|
||||
} else {
|
||||
reject(new Error("Не указан размер извлекаемой порции сообщений (отсутствует поле: nPortionSize)"));
|
||||
}
|
||||
} else {
|
||||
reject(new Error("Не указано подключение"));
|
||||
reject(new Error("Не указано подключение (отсутствует поле: connection)"));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -5,7 +5,7 @@
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "node index.js",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
"test": "node test.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -23,7 +23,7 @@ try {
|
||||
a.connect()
|
||||
.then(res => {
|
||||
console.log("CONNECTED");
|
||||
a.getOutgoing(cfg.outgoing.portionSize)
|
||||
a.getOutgoing({ nPortionSize: cfg.outgoing.nPortionSize })
|
||||
.then(res => {
|
||||
if (res.length > 0) {
|
||||
res.map(r => {
|
||||
@ -32,7 +32,7 @@ try {
|
||||
} else {
|
||||
console.log("NO MESSAGES IN QUEUE!!!");
|
||||
}
|
||||
a.putLog(db.MSG_TYPE_INF, "Сервер приложений подключен")
|
||||
a.putLog({ nLogState: db.NLOG_STATE_INF, sMsg: "Сервер приложений подключен" })
|
||||
.then(res => {
|
||||
console.log(res);
|
||||
setTimeout(() => {
|
Loading…
x
Reference in New Issue
Block a user