Last active
April 23, 2020 20:37
-
-
Save FRodrigues21/7df3b3c5e4a0cd49bde53d684cd10c88 to your computer and use it in GitHub Desktop.
π Example of Tedious SQL Server DB controller in Node.js (non-concurrent)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Connection = require("tedious").Connection; | |
var Request = require("tedious").Request; | |
var ConnectionPool = require("tedious-connection-pool"); | |
// Avoiding concurrent SQL SERVER calls | |
var poolConfig = { | |
min: 1, | |
max: 1, | |
log: true | |
}; | |
// Edit this config | |
var connectionConfig = { | |
userName: "username", | |
password: "password", | |
server: "ipaddress", | |
options: { | |
rowCollectionOnDone: true, // Only get row set instead of row by row | |
useColumnNames: true // For easier JSON formatting | |
} | |
}; | |
var _rows = []; | |
var pool = new ConnectionPool(poolConfig, connectionConfig); | |
pool.on("error", function(err) { | |
console.error(err); | |
}); | |
var _rows = []; | |
const query = (params, sql, callback) => { | |
pool.acquire((err, connection) => { | |
request = new Request(sql, (err, rowCount) => { | |
if (err) { | |
console.log(err); | |
return; | |
} | |
connection.release(); | |
}); | |
if (params.length > 0) { | |
params.forEach(param => { | |
request.addParameter(param.name, param.type, param.value); | |
}); | |
} | |
_rows = []; | |
request.on("row", columns => { | |
var _item = {}; | |
// Converting the response row to a JSON formatted object: [property]: value | |
for (var name in columns) { | |
_item[name] = columns[name].value; | |
} | |
_rows.push(_item); | |
}); | |
// We return the set of rows after the query is complete, instead of returing row by row | |
request.on("doneInProc", (rowCount, more, rows) => { | |
callback(_rows); | |
}); | |
connection.execSql(request); | |
}); | |
}; | |
const proc = (params, sql, callback) => { | |
pool.acquire((err, connection) => { | |
request = new Request(sql, (err, rowCount) => { | |
if (err) { | |
console.log(err); | |
return; | |
} | |
connection.release(); | |
}); | |
if (params.length > 0) { | |
params.forEach(param => { | |
request.addParameter(param.name, param.type, param.value); | |
}); | |
} | |
_rows = []; | |
request.on("row", columns => { | |
var _item = {}; | |
// Converting the response row to a JSON formatted object: [property]: value | |
for (var name in columns) { | |
_item[name] = columns[name].value; | |
} | |
_rows.push(_item); | |
}); | |
// We return the set of rows after the procedure is complete, instead of returing row by row | |
request.on("doneProc", (rowCount, more, rows) => { | |
callback(_rows); | |
}); | |
connection.callProcedure(request); | |
}); | |
}; | |
const buildParams = (params, name, type, value) => { | |
params.push({ | |
name: name, | |
type: type, | |
value: value | |
}); | |
}; | |
module.exports = { | |
buildParams: buildParams, | |
query: query, | |
proc: proc | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var db = require("./dbController.js"); | |
var TYPES = require("tedious").TYPES; | |
// QUERY | |
// Imagine we have a table called pokemon with 2 attributes: name and number | |
// We want to find a pokemon by number, using a select query | |
const getPokemon = (number) => { | |
var params = []; | |
var sql = "select * from pokemon where number = @number"; | |
// For each param do: db.buildParams(params, "name", TYPES.type, variable) | |
db.buildParams(params, "number", TYPES.Int, number); | |
db.query(params, sql, result => { | |
console.log(result); | |
}); | |
} | |
// PROCEDURE | |
// The same as above but using instead a procedure called findPokemon(number) | |
const getPokemonProc = (number) => { | |
var params = []; | |
var sql = "findPokemon"; // instead of query selector use only procedure name | |
// For each param do: db.buildParams(params, "name", TYPES.type, variable) | |
db.buildParams(params, "number", TYPES.Int, number); // Params will be added automatically to the procedure exec | |
db.proc(params, sql, result => { // Just need to change from query to proc | |
console.log(result); | |
}); | |
} | |
getPokemon(132); | |
getPokemonProc(34); | |
module.exports = { | |
getPokemon: getPokemon, | |
getPokemonProc: getPokemonProc | |
} |
Hi man, could you take some time to help me?
IΒ΄ve implemented something similar but i always get this error, this happend at the execSql method:
TypeError: cb is not a function
at Object.writeParameterData
maybe if you have interest to help
i would show you my code, Thanks in advanced
private getLocations(argUrlParams?: object | undefined): Promise<any[]> {
console.log(" get Locations from DB");
const TYPES = tedious.TYPES;
let queryText = queries.locations;
const Request = tedious.Request;
// Read all rows from table
queryText = queries.locations.replace(`%ConditionalInnerJoin%`, "");
queryText = queryText.replace(`%ConditionalWhere%`, "");
const parameters: any[] = [];
parameters.push(
{
name: "accountId",
type: TYPES.Int,
value: Object.values(argUrlParams)[0]
});
parameters.push(
{
name: "companyNumber",
type: TYPES.Int,
value: Object.values(argUrlParams)[1]
});
return new Promise<any[]>((resolve) => {
this.readTable(queryText, parameters, (result) => {
resolve(result);
})
})
}
private readTable(argQueryText: string, argParameters: any[], argCallBack: (n: any[]) => any): any[] {
// Attempt to connect and execute queries if connection goes through
const TYPES = tedious.TYPES;
const jsonArray: any[] = [];
console.log("-1");
// tslint:disable-next-line: no-shadowed-variable
this.pool.acquire((err, connection) => {
console.log("0");
if (err) {
console.log(err);
argCallBack(jsonArray);
}
console.log("===SQLConnectionManager π Establishing connection===");
try {
const request = new tedious.Request(argQueryText, (error, rowCount) => {
if (error) {
console.log('a jijo');
console.log(error);
return;
}
console.log(rowCount + " row(s) returned");
connection.release();
});
if (argParameters.length > 0) {
argParameters.forEach(param => {
request.addParameter(param.name, param.type, param.value);
});
}
console.log("1");
request.on("row", (columns: any) => {
const rowObject: any = {};
// console.log('2');
columns.forEach((column: any) => {
rowObject[column.metadata.colName] = column.value;
});
jsonArray.push(rowObject);
});
console.log("3");
request.on("doneInProc", (rowCount, more, rows) => {
console.log("5");
return argCallBack(jsonArray);;
});
connection.execSql(request);
console.log("4");
} catch (error) {
console.log('error en el catch');
console.log(error);
connection.release();
argCallBack(jsonArray);
}
})
return jsonArray;
}
replace type.writeParameterData(buffer, param, options);
with: type.writeParameterData(buffer, param, options, ()=>{});
"at new RpcRequestPayload (D:\Projects\Statistics\node_modules\tedious-connection-pool\node_modules\tedious\lib\rpcrequest-payload.js:95:12)"
yes, thanks i solved this exactly like that, but you know this problem will occur every time a new npm install its executed
Why you suggest avoid concurrent SQL calls ?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
How I do for return the values to controller, from the model?