So I went to the Microsoft documentation for node.js and trying to connect to a database and I went through step by step, installed tedious and when I try to run my code it's throwing an error saying:
tedious deprecated In the next major version of tedious, creating a new Connection instance will no longer establish a connection to the server automatically. Please use the new connect helper function or call the .connect method on the newly created Connection object to silence this message. internal\process\task_queues.js:79:11.
Does anyone know what this means?
CODE:
const Discord = require('discord.js');
const bot = new Discord.Client();
const token = 'HIDDEN';
bot.on('ready', () => {
console.log('This bot is online!');
var Connection = require('tedious').Connection;
var config = {
server: '', //update me
authentication: {
type: 'default',
options: {
userName: '', //update me
password: '' //update me
}
},
options: {
// If you are on Microsoft Azure, you need encryption:
encrypt: true,
database: '' //update me
}
};
var connection = new Connection(config);
connection.on('connect', function(err) {
// If no error, then good to proceed.
if(!err)
{
console.log("Connected");
executeStatement();
}
});
var Request = require('tedious').Request;
var TYPES = require('tedious').TYPES;
function executeStatement() {
request = new Request("SELECT * from tblCustomer;", function(err) {
if (err) {
console.log(err);}
});
var result = "";
request.on('row', function(columns) {
columns.forEach(function(column) {
if (column.value === null) {
console.log('NULL');
} else {
result+= column.value + " ";
}
});
console.log(result);
result ="";
});
request.on('done', function(rowCount, more) {
console.log(rowCount + ' rows returned');
});
connection.execSql(request);
}
})
bot.login(token);
I'm trying to use tedious library to inject simple insert from the incoming body. No error is thrown, but context.logs placed inside the functions are not displaying in logs. As a result in DB I have row with NULL values instead of what is passed. Any idea what am I doing wrong?
Is there any other library/method of accessing the Azure DB from Azure Functions or I am stuck with Tedious?
Of course I could probably use Azure Logic App but its more expensive to run than Azure Functions.
var Connection = require('tedious').Connection;
var Request = require('tedious').Request;
var TYPES = require('tedious').TYPES;
var globalheaders = {
Id: '1233',
Name: 'Ant',
Payment: "2019-10-09",
Type: 'Fixed cost',
Value: 156,
Cycle: '1',
Frequency: 'month'
}
module.exports = async function (context, req) {
context.log('JavaScript HTTP trigger function processed a request.');
globalheaders = req.body;
context.log(globalheaders);
var config = {
server: '********.database.windows.net', //update me
authentication: {
type: 'default',
options: {
userName: '*******', //update me
password: '*******' //update me
}
},
options: {
// If you are on Microsoft Azure, you need encryption:
encrypt: true,
database: 'cashmandb' //update me
}
};
var connection = new Connection(config);
await connection.on('connect', function(err) {
if (err) {
context.log(err);
context.res = {
status: 500,
body: "Unable to establish a connection."
};
context.done();
} else {
context.log('before execution');
executeStatement();
}
});
context.log('connection executed')
async function executeStatement() {
request = new Request("INSERT dbo.cost (Id, Name, Payment, Type, Value, Cycle, Frequency) OUTPUT INSERTED.Id VALUES (#Id, #Name, #Payment, #Type, #Value, #Cycle, #Frequency);", function(err) {
if (err) {
context.log(err);}
});
context.log('executestatement')
request.addParameter('Id', TYPES.NChar,globalheaders.id);
request.addParameter('Name', TYPES.NVarChar , globalheaders.name);
request.addParameter('Payment', TYPES.Date, globalheaders.payment);
request.addParameter('Type', TYPES.NVarChar,globalheaders.type);
request.addParameter('Value', TYPES.Int,globalheaders.value);
request.addParameter('Cycle', TYPES.NChar,globalheaders.cycle);
request.addParameter('Frequency', TYPES.NChar,globalheaders.frequency);
request.on('row', function(columns) {
columns.forEach(function(column) {
if (column.value === null) {
context.log('NULL');
} else {
context.log("Product id of inserted item is " + column.value);
}
});
});
await connection.execSql(request);
}
context.done();
};
Try this :
var Connection = require('tedious').Connection;
var Request = require('tedious').Request;
var TYPES = require('tedious').TYPES;
module.exports = async function (context, req) {
context.log('JavaScript HTTP trigger function processed a request.');
var config = {
server: 'xxxx.database.windows.net', //update me
authentication: {
type: 'default',
options: {
userName: 'xxx', //update me
password: 'xxx' //update me
}
},
options: {
// If you are on Microsoft Azure, you need encryption:
encrypt: true,
database: 'xxx' //update me
}
};
var connection = new Connection(config);
await connection.on('connect', function(err) {
if (err) {
context.log(err);
context.res = {
status: 500,
body: "Unable to establish a connection."
};
context.done();
} else {
executeStatement(req.body);
}
});
async function executeStatement(globalheaders) {
request = new Request("INSERT dbo.cost (Id, Name, Payment, Type, Value, Cycle, Frequency) OUTPUT INSERTED.Id VALUES (#Id, #Name, #Payment, #Type, #Value, #Cycle, #Frequency);", function(err) {
if (err) {
context.log(err);}
});
request.addParameter('Id', TYPES.NChar,globalheaders.Id);
request.addParameter('Name', TYPES.NVarChar , globalheaders.Name);
request.addParameter('Payment', TYPES.Date,globalheaders.Payment);
request.addParameter('Type', TYPES.NVarChar,globalheaders.Type);
request.addParameter('Value', TYPES.Int,globalheaders.Value);
request.addParameter('Cycle', TYPES.NChar,globalheaders.Cycle);
request.addParameter('Frequency', TYPES.NChar,globalheaders.Frequency);
request.on('row', function(columns) {
columns.forEach(function(column) {
if (column.value === null) {
context.log('NULL');
} else {
context.log("Product id of inserted item is " + column.value);
}
});
});
await connection.execSql(request);
}
context.done();
};
Test result on local :
Data has been insetted into Azure SQL DB successfully:
I believe the problem here is that you are mixing async/await and context.done(). You should just use 1 of the 2 as required.
Also, I believe tedious doesn't support async/await in the first place. So, removing the that and just having context.done() should do.
After long battle it appears that for some reason Azure Functions prefers adressing the property by value string:
request.addParameter('Id', TYPES.NChar,globalheaders['Id']);
request.addParameter('Name', TYPES.NVarChar , globalheaders['Name']);
request.addParameter('Payment', TYPES.Date, globalheaders['Payment']);
request.addParameter('Type', TYPES.NVarChar,globalheaders['Type']);
request.addParameter('Value', TYPES.Int,globalheaders['Value']);
request.addParameter('Cycle', TYPES.NChar,globalheaders['Cycle']);
request.addParameter('Frequency', TYPES.NChar,globalheaders['Frequency']);
After changing to this everything started to work
The correct way to achieve it is by using sync code. Tedious uses event based programming paradigm and do not support async programming paradigms. So to explicitly mark the completion of azure function we use context.done() method. So the right code would be as follows:
var Connection = require('tedious').Connection;
var Request = require('tedious').Request;
var TYPES = require('tedious').TYPES;
module.exports = function (context, req) {
context.log('JavaScript HTTP trigger function processed a request.');
var config = {
server: 'xxxx.database.windows.net', //update me
authentication: {
type: 'default',
options: {
userName: 'xxx', //update me
password: 'xxx' //update me
}
},
options: {
// If you are on Microsoft Azure, you need encryption:
encrypt: true,
database: 'xxx' //update me
}
};
var connection = new Connection(config);
connection.connect();
connection.on('connect', function(err) {
if (err) {
context.res = {
status: 500,
body: "Unable to establish a connection."
};
context.done();
} else {
executeStatement(req.body);
}
});
function executeStatement(globalheaders) {
request = new Request("INSERT dbo.cost (Id, Name, Payment, Type, Value, Cycle, Frequency) OUTPUT INSERTED.Id VALUES (#Id, #Name, #Payment, #Type, #Value, #Cycle, #Frequency);", function(err) {
if (err) {
context.log(err);}
});
request.addParameter('Id', TYPES.NChar,globalheaders.Id);
request.addParameter('Name', TYPES.NVarChar , globalheaders.Name);
request.addParameter('Payment', TYPES.Date,globalheaders.Payment);
request.addParameter('Type', TYPES.NVarChar,globalheaders.Type);
request.addParameter('Value', TYPES.Int,globalheaders.Value);
request.addParameter('Cycle', TYPES.NChar,globalheaders.Cycle);
request.addParameter('Frequency', TYPES.NChar,globalheaders.Frequency);
request.on('row', function(columns) {
columns.forEach(function(column) {
if (column.value === null) {
context.log('NULL');
} else {
context.log("Product id of inserted item is " + column.value);
}
});
});
request.on("requestCompleted", function (rowCount, more) {
connection.close();
context.res = {
status: 200, /* Defaults to 200 */
body: JSON.stringify(result),
headers: {
' Content-Type': 'application/json'
}
};
context.done();
});
connection.execSql(request);
}
};
I want to connect SQL Server in a windows authentication mode using node.js with "mssql" package. Below code is working fine with SQL Server authentication by providing username & password.
var sql = require("mssql");
// config for your database
var config = {
server: XXXX',
database: 'XXX' ,
options: {
trustedconnection:true,
encrypt: false, // Use this if you're on Windows Azure
}
};
function GetDatatable()
{
return new Promise( (resolve, reject) => {
sql.connect(config, function (err) {
if (err) console.log(err);
// create Request object
var request = new sql.Request();
// query to the database and get the records
var query='select Id,statusCode,from test';
request.query(query, function (err, recordset) {
var recordSetItem = recordset.recordset;
for(var i=0;i<recordSetItem.length;i++) {
var row=recordSetItem[i];
var basePath=row['baseUri'];
if(fullPath.lastIndexOf(basePath) > -1)
{
operationId=row['Id'];
}
}
if(operationId)
{
query='select * from tbltest';
request.query(query, function (err, scenarioRecordset) {
var subRecordSet = scenarioRecordset.recordset;
var xmlResponse= validateScenario (subRecordSet,fullPath,bodyRequest);
console.log(xmlResponse);
// let responseObject = {
// "id": "1",
// "statusCode": "200"
// };
resolve('responseObject');
});
}
});
});
});
Getting error message "login failed"
I believe you'll need to use the msnodesqlv8 module, you must install with
npm install msnodesqlv8
Then (for example):
const sql = require('mssql/msnodesqlv8')
const pool = new sql.ConnectionPool({
database: 'database',
server: 'localhost',
options: {
trustedConnection: true
}
})
async function testConnection() {
await pool.connect();
let result = await pool.request().query("select 42 as the_answer_to_life_the_universe_and_everything");
console.log("Result: ", result);
}
testConnection();
See here for more: mssql v8driver
I am trying to set up a connector for cassandra. When i try to query the database, it doesnt give back anything. here is the snippet
function CassandraConnector(host, hostPort, user, password) {
if (!host || !hostPort) {
logger.fatal("CassandraConnector cannot initialize without host and port configuration.");
throw new Error("CassandraConnector unable to start");
}
this._dbHost = host;
this._dbPort = hostPort;
this._user = user;
this._password = password;
var authProvider = new cassandra.auth.PlainTextAuthProvider(this._user, this._password);
client = new cassandra.Client({
contactPoints: [this._dbHost],
authProvider: authProvider,
protocolOptions: {
port: this._dbPort
},
keyspace: "test"
});
client.connect(function(err, result) {
if (err) {
console.log("Error while connecting to cassandra " + err)
}
});
client.on('log', function(level, className, message, furtherInfo) {
console.log('Cassandra log event: %s -- %s', level, message);
})
}
CassandraConnector.prototype.getAllUserPreferences = function(user_type, userId) {
var query = "SELECT * from test.user where user_type=? AND user_id=?";
var params = [user_type, userId];
var deferred = Q.defer();
client.execute(query, params, {
prepare: true
}, function(err, result) {
if (err) {
deferred.reject(err);
throw new Error("Unable to retrieve the user preferences for user id " + userId);
} else {
deferred.resolve(result)
}
});
return deferred.promise;
}
I put a breakpoint on deferred.reject and deferred.resolve but it doesnt hit there at all. Please help.
I am using this module tedious to connect. I am having issues when I try to populate a collection with the data from MSSQL.
My code thus far:
http://pastebin.com/q4ByRCbW
Meteor.startup(function () {
var Request = Meteor.require('tedious').Request;
var Connection = Meteor.require('tedious').Connection;
var config = {
userName: 'xxxxx',
password: 'xxxx',
server: '197.xxx.xxx.xxx',
// If you're on Windows Azure, you will need this:
options: {
encrypt: true,
debug: {
packet: true,
data: true,
payload: true,
token: false,
log: true
}
}
};
var connection = new Connection(config);
var asnycWrapFunc = Async.wrap(connection.execSql);
var rettarr = [];
function executeStatement() {
Fiber(function(){
request = new Request("select * from AccountSummary", function(err, rowCount) {
if (err) {
console.log(err);
} else {
console.log(rowCount + ' rows');
}
});
request.on('row', function(columns) {
aaary = []; cnting = 0;
columns.forEach(function(column) {
console.log(column.value);
aaary.push(column.value);
});
if (AccountSummary.find().count() === 0){
AccountSummary.insert({ID:aaary[0], ClientNo:aaary[1], ClientName:aaary[2]});
}
});
//rettarr.push(aaary);
}).run();
asnycWrapFunc(request);
//return rettarr;
}
connection.on('connect', function(err) {
// If no error, then good to go...
var res = executeStatement();
// aaary = res[0];
console.log(res);
errr = err;
});
});
I have found that you have to use Future if you want to you a package like Tedious.
This mini tutorial has the answer