UNPKG

sql-server-sse-bridge

Version:

Make SSE event stream from a SQL Server event queue stream.

109 lines (98 loc) 3.16 kB
const sql = require("mssql"); const fs = require("./fsasync"); const path = require("path"); const dns = require("dns"); const DOMParser = require("xmldom").DOMParser; // Depth first xml->json using xmldom function parseMessage(message) { let dom = new DOMParser().parseFromString(message); function jsonNode(Element, result) { if (Element.childNodes.length > 0) { let list = Array.from(Element.childNodes); result[Element.tagName] = list.map(Node => { // console.log("node type", Node.nodeType); switch (Node.nodeType) { case 1: return jsonNode(Node, {}); case 3: return Node.data; } }); } return result; } let result = jsonNode(dom.childNodes[0], {}); return result; } function queryWait(pool, queueName) { let request = pool.request(); return request.query(`waitfor( receive top(1) convert(xml, message_body ) [message] FROM ${queueName} );`); } async function setupConnection({ user, domain, server, password, port = 1433, database, queueName, requestTimeout = 60 * 1000, trustServerCertificates}) { try { let config = { // mssql config - sometimes needs hacks to pass to tedious user: user, domain: domain, server: server, password: password, port: port, database: database, requestTimeout: requestTimeout, options: { requestTimeout: requestTimeout, database: database, encrypt: true, trustServerCertificates: trustServerCertificates } }; let pool = await sql.connect(config); return [undefined, {pool: pool, queueName: queueName, config: config}]; } catch (e) { return [e]; } } exports.waitFor = async function (config, eventSender) { let [err, connection] = await setupConnection(config); if (err) { console.error(`${config.queueName}:: can't make a connection to ${config.database}`, err); return; } let {pool: poolConnection, queueName, conf} = connection; // Make a function to take a promise and resolve it, with the // resolution calling the same function let recur = function (p) { p.then(rs => { try { if (rs.recordset.length > 0) { let msg = new String(rs.recordset[0].message); eventSender(new Date(), parseMessage(msg)); } } catch (e) { console.error(`${queueName}:: queue wait result failed`, e); } recur(queryWait(poolConnection, queueName)); }).catch(e => { recur(queryWait(poolConnection, queueName)); }); }; recur(queryWait(poolConnection, queueName)); } if (require.main === module) { } else { } // End