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);
}
};
Related
I am new to node/express js, and trying to execute the following. The control executes the lines after function call "var nextVersion =getNextContractVersion(cid)", even before the function returns a response. As a result the value for newVersion is not updated to Contract object. Also, function getNextContractVersion(cid) returns undefined, unlike the updated nextVersion.
How do i fix this behavior, please suggest. Also, is the right way of invoking function?
// Package imports
const express = require('express');
var router = express.Router();
const mongoose = require('mongoose');
//Local imports
var { Customer } = require('../models/customer');
var { Contract } = require('../models/contract');
router.put('/:cid/contracts', (req, res) => {
var cid = req.params.cid;
var nextVersion =getNextContractVersion(cid);
var contract;
if (validateCustomerId(cid)) {
req.body.contract.forEach((item) => {
contract = new Contract({
customerID: cid,
startDate: item.startDate,
endDate: item.endDate,
conditions: item.conditions,
price: item.price,
author: item.author,
version: nextVersion
});
});
contract.save((err, docs) => {
if (!err) {
Customer.findOneAndUpdate({ customerID: cid }, { $push: { contract: contract } },
{ safe: true, upsert: true, new: true }).populate({ path: 'contract' }).exec((err1, docs1) => {
if (!err1) {
res.send(docs1).status(200);
} else {
console.log('Error is adding a new contract:' + JSON.stringify(err1, undefined, 2));
}
});
} else {
console.log('Error is updating a new customer:' + JSON.stringify(err, undefined, 2));
}
});
} else {
res.status(400).send('Bad Request - Invalid input!')
}
});
function getNextContractVersion(cid) {
var nextVersion=1;
Contract.findOne({ customerID: cid }).sort({version: 'descending'}).exec((err, doc) => {
if (!err && doc != null) {
var currentVersion = parseInt(doc.version);
nextVersion = currentVersion + 1;
}
});
return nextVersion;
}
You are mixing synchronous and asynchronous code.
Contract.findOne({ customerID: cid }).sort({version: 'descending'}).exec((err, doc) => {
if (!err && doc != null) {
var currentVersion = parseInt(doc.version);
nextVersion = currentVersion + 1;
}
});
The above code effectively says "Go to the database, find one of these objects and whenever in the future that is done, run this code that's in the exec block."
One of the ways to reason about asynchronous code from a synchronous mindset is that of promises.
Here's a semi pseudo implementation:
router.put('/:cid/contracts', (req, res) => {
var cid = req.params.cid;
return getTheMostRecentContract(cid)
.then(function(oldContract){
var nextVersion = oldContract.version +1;
if(!validateCustomerId(cid)){
return res.status(400).send('Bad Request - Invalid input!');
}
var contract;
var savePromises = [];
req.body.contract.forEach((item) => {
contract = new Contract({
customerID: cid,
startDate: item.startDate,
endDate: item.endDate,
conditions: item.conditions,
price: item.price,
author: item.author,
version: nextVersion
});
savePromises.push(contract.save());
});
return Promise.all(savePromises);
})
.then(function(resultOfAllSavePromises){
//rest of code here
}).catch(function(error){
console.log('Error is updating a new customer:' + JSON.stringify(err, undefined, 2));
return res.status(400);
})
});
function getTheMostRecentContract(cid) {
return Contract.findOne({ customerID: cid }).sort({version: 'descending'});
}
As a matter of practice though, have the database control your auto-increment values. This code won't work in a high traffic environment.
I have an action where I need to update MongoDB entry including _id field, which requires deleting old entry and making a new one, here is server side:
exports.update = function(req, res, next){
var outcome = [];
outcome.previousId = req.params.id;
outcome.newId = req.body.name;
var getPreviousRecord = function(callback) {
req.app.db.models.AccountGroup
.findOne({ _id: req.params.id })
.lean()
.exec(function(err, accountGroups) {
if (err) {
return callback(err, null);
}
outcome.accountGroups = accountGroups;
return callback(null, 'done');
});
};
var makeNewRecord = function(callback) {
var permissions = outcome.accountGroups.permissions;
var fieldsToSet = {
_id: outcome.newId.toLowerCase(),
name: outcome.newId,
permissions: permissions
};
req.app.db.models.AccountGroup
.create(fieldsToSet, function(err, record) {
if (err) {
return callback(err, null);
}
outcome.record = record;
return callback(null, 'done');
});
};
var deletePreviousRecord = function() {
req.app.db.models.AccountGroup
.findByIdAndRemove(outcome.previousId)
.exec(function(err) {
if (err) {
return next(err);
}
res.redirect('admin/account-groups/' + outcome.newId + '/');
});
};
var asyncFinally = function(err) {
if (err) {
return next(err);
}
};
require('async').series([getPreviousRecord, makeNewRecord, deletePreviousRecord], asyncFinally);
};
It works fine, but I can't make this work normally on the front-end, it returns me both old route and a new route, for example:
PUT /admin/account-groups/customers22/admin/account-groups/Customers2233/ 404 213.749 ms - 31
where customers22 is old _id and customers2233 is new _id. If I navigate from another page to new entry it gets route normally.
On client side:
(function() {
'use strict';
app = app || {};
app.Details = Backbone.Model.extend({
idAttribute: '_id',
defaults: {
success: false,
errors: [],
errfor: {},
name: ''
},
url: function() {
return '/admin/account-groups/'+ app.mainView.model.id +'/';
},
parse: function(response) {
if (response.accountGroup) {
app.mainView.model.set(response.accountGroup);
delete response.accountGroup;
}
return response;
}
});
app.DetailsView = Backbone.View.extend({
el: '#details',
events: {
'click .btn-update': 'update'
},
template: Handlebars.compile( $('#tmpl-details').html() ),
initialize: function() {
this.model = new app.Details();
this.syncUp();
this.listenTo(app.mainView.model, 'change', this.syncUp);
this.listenTo(this.model, 'sync', this.render);
this.render();
},
syncUp: function() {
this.model.set({
_id: app.mainView.model.id,
name: app.mainView.model.get('name')
});
},
render: function() {
this.$el.html(this.template( this.model.attributes ));
for (var key in this.model.attributes) {
if (this.model.attributes.hasOwnProperty(key)) {
this.$el.find('[name="'+ key +'"]').val(this.model.attributes[key]);
}
}
},
update: function() {
this.model.save({
name: this.$el.find('[name="name"]').val()
});
}
});
app.MainView = Backbone.View.extend({
el: '.page .container',
initialize: function() {
app.mainView = this;
this.model = new app.AccountGroup( JSON.parse( unescape($('#data-record').html()) ) );
// ...
app.detailsView = new app.DetailsView();
}
});
$(document).ready(function() {
app.mainView = new app.MainView();
});
}());
It probably requires to trigger both model.save and model.destroy or prevent URL being used. Any advice on how to do it is appreciated, thank you.
Edit
Just a typo mistake here that is not related to the question, recklessly checking routes, see as cancelled
I believe the problem is here:
res.redirect('admin/account-groups/' + outcome.newId + '/');
That's a relative path so it'll be appended onto the current URL. I suspect you want something like this:
res.redirect('/admin/account-groups/' + outcome.newId + '/');
I am learning node opc-ua and have followed the example provided in the GitHub page for the sample_server.js and simple_client.js.
In the sample_server I add a variable when constructing the address space of the server such as:
//this code is in the server
addressSpace.addVariable({
componentOf: device,
nodeId: "ns=1;s=variable_1",
browseName: "MyVariable1",
dataType: "Double",
value: {
get: function () {
return new opcua.Variant({ dataType: opcua.DataType.Double, value: variable1 });
}
}
});
Here is the whole server code for reference:
var opcua = require("node-opcua");
var server = new opcua.OPCUAServer({
port: 4334, // the port of the listening socket of the server
resourcePath: "UA/MyLittleServer", // this path will be added to the endpoint resource name
buildInfo: {
productName: "MySampleServer1",
buildNumber: "7658",
buildDate: new Date(2014, 5, 2)
}
});
server.initialize(post_initialize);
function post_initialize() {
console.log("initialized");
construct_my_address_space(server, function () {
server.start(function () {
console.log("Server is now listening ... ( press CTRL+C to stop)");
console.log("port ", server.endpoints[0].port);
var endpointUrl = server.endpoints[0].endpointDescriptions()[0].endpointUrl;
console.log(" the primary server endpoint url is ", endpointUrl);
});
});
}
function construct_my_address_space(server, callback) {
var addressSpace = server.engine.addressSpace;
// declare a new object
var device = addressSpace.addObject({
organizedBy: addressSpace.rootFolder.objects,
browseName: "MyDevice"
});
// add a variable named MyVariable1 to the newly created folder "MyDevice"
var variable1 = 1;
// emulate variable1 changing every 500 ms
setInterval(function () { variable1 += 1; }, 500);
addressSpace.addVariable({
componentOf: device,
nodeId: "ns=1;s=variable_1",
browseName: "MyVariable1",
dataType: "Double",
value: {
get: function () {
return new opcua.Variant({ dataType: opcua.DataType.Double, value: variable1 });
}
}
});
callback();
}
Now, in the client i want to discover this variable by name or the full nodeId.
I am using the sample provided to browse the session to the server but in the return i only see FolderType, Objects, Types and Views and can not locate this variable anywhere.
Here is the client code:
var opcua = require("node-opcua");
var async = require("async");
var client = new opcua.OPCUAClient();
var endpointUrl = "opc.tcp://" + require("os").hostname() + ":4334/UA/MyLittleServer";
var the_session, the_subscription;
async.series([
// step 1 : connect to
function (callback) {
client.connect(endpointUrl, function (err) {
if (err) {
console.log(" cannot connect to endpoint :", endpointUrl);
} else {
console.log("connected !");
}
callback(err);
});
},
// step 2 : createSession
function (callback) {
client.createSession(function (err, session) {
if (!err) {
the_session = session;
}
callback(err);
});
},
// step 3 : browse
function (callback) {
the_session.browse("RootFolder", function (err, browse_result) {
if (!err) {
console.log('Result of browsing: ', browse_result);
browse_result[0].references.forEach(function (reference) {
console.log('browsing: ', reference.browseName);
console.log(reference);
console.log("**************************************");
});
}
callback(err);
});
},
/* step 4 : read a variable with readVariableValue
function (callback) {
the_session.readVariableValue("ns=1;s=variable_1", function (err, dataValue) {
if (!err) {
console.log(" var 1 = ", dataValue.toString());
}
callback(err);
});
},
// step 4' : read a variable with read
function (callback) {
var max_age = 0;
var nodes_to_read = [
{ nodeId: "ns=1;s=variable_1", attributeId: opcua.AttributeIds.Value }
];
the_session.read(nodes_to_read, max_age, function (err, nodes_to_read, dataValues) {
if (!err) {
console.log(" variable 1 = ", dataValues[0]);
}
callback(err);
});
},
*/
// step 5: install a subscription and install a monitored item for 10 seconds
function (callback) {
the_subscription = new opcua.ClientSubscription(the_session, {
requestedPublishingInterval: 1000,
requestedLifetimeCount: 10,
requestedMaxKeepAliveCount: 2,
maxNotificationsPerPublish: 10,
publishingEnabled: true,
priority: 10
});
the_subscription.on("started", function () {
console.log("subscription started for 2 seconds - subscriptionId=", the_subscription.subscriptionId);
}).on("keepalive", function () {
console.log("keepalive");
}).on("terminated", function () {
callback();
});
setTimeout(function () {
the_subscription.terminate();
}, 10000);
// install monitored item
var monitoredItem = the_subscription.monitor({
nodeId: opcua.resolveNodeId("ns=1;s=variable_1"),
attributeId: opcua.AttributeIds.Value
},
{
samplingInterval: 100,
discardOldest: true,
queueSize: 10
},
opcua.read_service.TimestampsToReturn.Both
);
console.log("-------------------------------------");
monitoredItem.on("changed", function (dataValue) {
console.log("variable_1 = ", dataValue.value.value);
});
},
// close session
function (callback) {
the_session.close(function (err) {
if (err) {
console.log("session closed failed ?");
} else{
console.log("session closed!");
}
callback();
});
}
],
function (err) {
if (err) {
console.log(" failure ", err);
} else {
console.log("done!");
}
client.disconnect(function () { });
});
Thanks in advance
You need to drill down from from the rootFolder and investigate the various objects until you find the variable you want to monitor, with a series of browseNode.
The best option is to use a free OPCUA client from a commercial vendor such as UAExpert or Prosys OPC UA Client to name a few.
You can also use opcua-commander: This little utility will allow you to explore the address space of the server and find the node you're looking for. ( source code available on github )
I have the following code:
var method = PushLoop.prototype;
var agent = require('./_header')
var request = require('request');
var User = require('../models/user_model.js');
var Message = require('../models/message_model.js');
var async = require('async')
function PushLoop() {};
method.startPushLoop = function() {
getUserList()
function getUserList() {
User.find({}, function(err, users) {
if (err) throw err;
if (users.length > 0) {
getUserMessages(users)
} else {
setTimeout(getUserList, 3000)
}
});
}
function getUserMessages(users) {
// console.log("getUserMessages")
async.eachSeries(users, function (user, callback) {
var params = {
email: user.email,
pwd: user.password,
token: user.device_token
}
messageRequest(params)
callback();
}, function (err) {
if (err) {
console.log(err)
setTimeout(getUserList, 3000)
}
});
}
function messageRequest(params) {
var url = "https://voip.ms/api/v1/rest.php?api_username="+ params.email +"&api_password="+ params.pwd +"&method=getSMS&type=1&limit=5"
request(url, function(err, response, body){
if (!err) {
var responseObject = JSON.parse(body);
var messages = responseObject.sms
if (responseObject["status"] == "success") {
async.eachSeries(messages, function(message, callback){
console.log(params.token)
saveMessage(message, params.token)
callback();
}, function(err) {
if (err) {
console.log(err)
}
// setTimeout(getUserList, 3000)
})
} else {
// setTimeout(getUserList, 3000)
}
} else {
console.log(err)
// setTimeout(getUserList, 3000)
}
});
setTimeout(getUserList, 3000)
}
function saveMessage(message, token) {
// { $and: [ { price: { $ne: 1.99 } }, { price: { $exists: true } }
// Message.find({ $and: [{ message_id: message.id}, {device_token: token}]}, function (err, doc){
Message.findOne({message_id: message.id}, function (err, doc){
if (!doc) {
console.log('emtpy today')
var m = new Message({
message_id: message.id,
did: message.did,
contact: message.contact,
message: message.message,
date: message.date,
created_at: new Date().toLocaleString(),
updated_at: new Date().toLocaleString(),
device_token: token
});
m.save(function(e) {
if (e) {
console.log(e)
} else {
agent.createMessage()
.device(token)
.alert(message.message)
.set('contact', message.contact)
.set('did', message.did)
.set('id', message.id)
.set('date', message.date)
.set('message', message.message)
.send();
}
});
}
}) //.limit(1);
}
};
module.exports = PushLoop;
Which actually works perfectly fine in my development environment - However in production (i'm using Openshift) the mongo documents get saved in an endless loop so it looks like the (if (!doc)) condition always return true therefore the document gets created each time. Not sure if this could be a mongoose issue - I also tried the "find" method instead of "findOne". My dev env has node 0.12.7 and Openshift has 0.10.x - this could be the issue, and i'm still investigating - but if anybody can spot an error I cannot see in my logic/code please let me know
thanks!
I solved this issue by using a "series" like pattern and using the shift method on the users array. The mongoose upsert findOneOrCreate is good however if there is a found document, the document is returned, if one isn't found and therefore created, it's also returned. Therefore I could not distinguish between the newly insert doc vs. a found doc, so used the same findOne function which returns null if no doc is found I just create it and send the push notification. Still abit ugly, and I know I could have used promises or the async lib, might refactor in the future. This works for now
function PushLoop() {};
var results = [];
method.go = function() {
var userArr = [];
startLoop()
function startLoop() {
User.find({},function(err, users) {
if (err) throw err;
users.forEach(function(u) {
userArr.push(u)
})
function async(arg, callback) {
var url = "https://voip.ms/api/v1/rest.php?api_username="+ arg.email +"&api_password="+ arg.password +"&method=getSMS&type=1&limit=5"
request.get(url, {timeout: 30000}, function(err, response, body){
if (!err) {
var responseObject = JSON.parse(body);
var messages = responseObject.sms
var status = responseObject.status
if (status === "success") {
messages.forEach(function(m) {
var message = new Message({
message_id: m.id,
did: m.did,
contact: m.contact,
message: m.message,
date: m.date,
created_at: new Date().toLocaleString(),
updated_at: new Date().toLocaleString(),
device_token: arg.device_token
});
var query = { $and : [{message_id: m.id}, {device_token: arg.device_token}] }
var query1 = { message_id: m.id }
Message.findOne(query).lean().exec(function (err, doc){
if (!doc || doc == null) {
message.save(function(e) {
console.log("message saved")
if (e) {
console.log("there is an error")
console.log(e)
} else {
console.log(message.device_token)
var messageStringCleaned = message.message.toString().replace(/\\/g,"");
var payload = {
"contact" : message.contact,
"did" : message.did,
"id" : message.message_id,
"date" : message.date,
"message" : messageStringCleaned
}
var note = new apns.Notification();
var myDevice = new apns.Device(message.device_token);
note.expiry = Math.floor(Date.now() / 1000) + 3600; // Expires 1 hour from now.
note.badge = 3;
note.alert = messageStringCleaned;
note.payload = payload;
apnsConnection.pushNotification(note, myDevice);
}
})
}
});
});
}
else {
console.log(err)
}
}
});
setTimeout(function() {
callback(arg + "testing 12");
}, 1000);
}
// Final task (same in all the examples)
function series(item) {
if(item) {
async( item, function(result) {
results.push(result);
return series(userArr.shift());
});
} else {
return final();
}
}
function final() {
console.log('Done');
startLoop();
}
series(userArr.shift())
});
}
}
module.exports = PushLoop;
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