Sorry for asking such dumb question but I spent some time on this and looked to other similar questions and none of them were helpful
I'm defining a function inside var Tools = module.exports and I have no clue of what is going wrong in this function definition:
getLastNRows: function (whereIsData, DB_info, table, NRows, callback) {
if (whereIsData == "MySQL") {
var queryString = "SELECT timestamp, temp1, temp2, temp3, temp4, level_ice_bank, flow, power, level_change_rate FROM " +
table + " ORDER BY id DESC LIMIT " + NRows + ";";
var connnection = mysql.createConnection(DB_info);
connnection.connect(function(err) {
if (err) {
console.log("Couldn't connect to the required MySQL DB.");
console.log("DID NOT GET LAST " + NRows + " ROWS");
throw err;
}
});
connnection.query(queryString, function (err, rows) {
if (err) {
console.log("DID NOT GET LAST " + NRows + " ROWS");
throw err;
}
Tools.setValue(rows);
Tools.dataArray2Object(Tools.result_arr);
callback();
});
}
else {
console.log("Function doesn't accept this DB service.\n(u still have to improve...)");
return;
}
},
I'm getting:
getLastNRows: function (whereIsData, DB_info, table, NRows, callback) {
^^^^^^^^^^^^
SyntaxError: Unexpected identifier
Maybe someone catches the error here?
I assume that's an object, and you've just missed the comma before the first row you posted:
var myMethods = {
foo: function () {}, // < This comma
getLastNRows: function (whereIsData, DB_info, table, NRows, callback) {
...
},
};
When you get syntax errors, it means something is wrong with the syntax (the program doesn't even execute).
Related
I dont know what to say, i think code says everything. i just want to render something and this error appears, but i dont know why. I tried so many solutions from stackoverflow, and others that i couldn't count them all. Im using mysql2 lib. Please help.
router.get("/:link", function(req, res){
connection.query(
"SELECT * FROM yourshort WHERE link = '" + req.params.link + "'",
function (err, result, rows, fields){
Object.keys(result).forEach(function(key) {
var row = result[key];
console.log(row.link)
if(row.link = req.params.link) {
res.send(row.link + row.views + rows.created)
return;
} else {
res.send("URL does not exist")
return;
}
});
});
});
just because you send it in foreach you get that error .
do you want to send it just one time and first item of db ? if yes use this :
router.get("/:link", function (req, res) {
var i = 0;
connection.query(
"SELECT * FROM yourshort WHERE link = '" + req.params.link + "'",
function (err, result, rows, fields) {
Object.keys(result).forEach(function (key) {
var row = result[key];
console.log(row.link)
if (row.link = req.params.link) {
if (i === 0) {
res.send(row.link + row.views + rows.created)
i = 1;
}
} else {
if (i === 0) {
res.send("URL does not exist")
i = 1;
}
}
});
});
});
A service that sends your data. You run into problems when you try to return your data in a loop. The good thing about this is to come back after you get all the result you will get from the loop. You can use asynchronous structure for this. Maybe you can try this.
router.get("/:link", (req, res) => {
let myObject = {};
connection.query(
"SELECT * FROM yourshort WHERE link = '" + req.params.link + "'",
async(err, result, rows, fields) => {
await Object.keys(result).forEach(function(key) {
var row = result[key];
if(row.link = req.params.link) {
myObject[key] = {link: row.link, views: row.views, created: rows.created}
return;
} else {
myObject['error'] = 'URL does not exist';
return;
}
});
await res.send(myObject);
});
});
I have a table where Persons are saved an their time (in seconds) where they were active.
I would like to write a function that gathers the total time in another table called gather.
For each row I am checking if an entry in the gather table exists. Depending on that result I make an insert or an update.
db.serialize(function() {
db.each("SELECT * from TEST", function(err, row) {
db.get("SELECT * from GATHER where name = " + row.name "", function(err, row) {
if(row === undefined || row === null){
var stmt = db.prepare("INSTER INTO gather (name, time) VALUE(?,?)");
stmt.run([name, seconds], function(error){
console.log('lastInsert ' + this.lastID);
});
stmt.finalize();
}else{
seconds += row.time;//increment time
var stmt = db.prepare("UPDATE gather SET time = ? WHERE name = ?");
stmt.run([seconds, row.name], function(error){
console.log('lastInsert ' + row.idProcessed);
});
stmt.finalize();
}
});
});
});
The problem that I ecounter is that sqlite runs asynchronously. Therefore multiple entries are created in my gather table although lines should be updated.
What would be the right way to run this function sychronously? Should I limit the lines and call the function every second or is there a smarted way?
You could use async. For example (but first you should read final notes at the end):
var async = require('async');
var data = {}
var yourFirstSelect() = function(callback){
//You do your first select
//...
db.get("SELECT * from TEST", function(err, row) {
if(row){
data.name = row.name;
data.otherInterestingAttribute = row.otherInterestingAttribute;
callback(err, data);
}else{
callback('Row is null');
}
})
//..
}
var yourSecondSelect() = function(data, callback){
//You do your second select
//...
db.get("SELECT * from GATHER where name = " + data.name "", function(err, row) { //Note that I'm using data instead of row
if(row){
data.seconds = row.seconds;
data.otherInterestingAttribute = row.otherInterestingAttribute;
callback(err, data);
}else{
callback('Row is null');
}
})
//..
}
var decide() = function(data, callback){
if (data.somethingExists) { //Do your validations
data.type = 'update';
callback(err, data);
} else {
data.type = 'insert';
callback(err, data);
}
}
var update() = function(data,callback){
if (data.type === 'update') {
//...
//Do your stuff in order to update
seconds += row.time;//increment time
var stmt = db.prepare("UPDATE gather SET time = ? WHERE name = ?");
stmt.run([seconds, row.name], function(error){
console.log('update ' + row.idProcessed);
});
stmt.finalize();
//...
} else {
callback(err,data);
}
}
var insert() = function(data,callback){
if (data.type === 'insert') {
//...
//Do your stuff in order to insert
var stmt = db.prepare("INSTER INTO gather (name, time) VALUE(?,?)");
stmt.run([data.name, data.seconds], function(error){
console.log('lastInsert ' + this.lastID);
callback(err,data);
});
stmt.finalize();
//...
} else {
callback(err,data);
}
}
var niceWorkflow = function(){
async.waterfall([
yourFirstSelect,
yourSecondSelect,
decide,
update,
insert
],
function (err, result) {
console.log('Done');
})
}
//and call your workflow
niceWorkflow();
Off course this is not a 100% working code, I wrote it in order you look another way to do what you are trying. Many variables, validations and more are just examples and I intentionally forgot the db.each to avoid being too extense and confusing you and trying to answer your final question Is there a smarter way?.
You can also use Q.all from Q library.
It will return a promise after all the promises are resolved. It one promise fails, then Q.all will be rejected.
I am trying to test a function that looks like:
function sendVerifySms(patientId, data) {
var smsNumber = data.smsNumber;
var verifyCode = ((Math.random() * 1000000) | 0).toString();
var sql = "UPDATE [patient]";
sql += " SET phone_sms_verify_code = '" + verifyCode + "',";
// verification must take place within a one hour period
sql += " phone_sms_verify_code_expire = '" + moment.utc().add(1, 'hour').formatSqlDatetime() + "',";
sql += " phone_sms_verified = 0,"
sql += " phone_sms = '" + escapeSql(smsNumber) + "'";
sql += " WHERE id = " + escapeSql(patientId.toString());
return sqlServer.query(sql).then(function(result) {
twilioClient.sendMessage({
to: smsNumber,
from: twilioUser.verifyNumber,
body: verifyCode
}).then(function(res) {
console.log('sent verification');
return verifyCode;
}).fail(function(err) {
console.log('error sending verification');
console.log(err);
return err;
});
}).fail(function(err) {
console.log(err);
return err;
});
}
Easy enough, right? Well, first I need to decide what EXACTLY I'm testing for.
That the sql command matches the format given some data
That the twilioClient.sendMessage has been called.
Here is what I have for my test so far:
var should = require('should');
var methods;
var mockery = require('mockery');
var sinon = require('sinon');
describe('RPC Methods', function() {
before(function() {
mockery.enable();
mockery.registerMock('msnodesql', {
open: function() {
return true;
}
});
mockery.registerMock('../../db/sqlserver', {
query: function() {
return {
then: function() {
return true;
}
}
}
});
methods = require('../../../rpc/methods');
});
it('should send a verify SMS', function() {
var data = {
}
methods.sendVerifySms(1, data);
should(1).equal(1);
});
});
So now I'm a bit lost from here. I have a ton of require and since I want to isolate my individual functions for testing, I figured something like mockery would work. Where do I go from here?
If anything is unclear, please post a comment and I'll clarify.
Thanks!
With mocha tests you have an optional done callback that makes testing async functions easier, like this:
it('should send a verify SMS', function(done) {
var data = {};
var code = 1;
methods.sendVerifySms(code, data)
.then(function(actualCode) {
should(actualCode).equal(code);
done();
});
});
I would also have some feedback to offer on the async function you're testing. First I'd say you don't have to nest promise chains the way you are, and in this case its probably better that you didn't. If you simply return a promise from within a promise callback, you can chain it at the same level, like this:
return sqlServer.query(sql).then(function(result) {
return twilioClient.sendMessage({
to: smsNumber,
from: twilioUser.verifyNumber,
body: verifyCode
});
}).then(function(res) {
console.log('sent verification');
return verifyCode;
}).fail(function(err) {
console.log(err);
throw err;
});
Second, in the error handler you had before you were simply returning the err. This is probably a bad idea because it tells the consumer of your promise that everything is hunky dory and that they should proceed as such. Throwing an error on the other hand will allow that consumer to handle the error however they want in their own .fail block.
I am a beginner with node.js and I would ask you for advice. Using a selection from the database I get the required data (ID, building, floor, map). The map is stored in jpg format as a byte array 0x89504E470D0A1A0A0000000D4948... . I save to a new database id, building, floor and reduced map (where quality is reduced through https://www.npmjs.com/package/images), which is now Unicode-encoded(http://puu.sh/g6UZ2/90408c7b12.png). Could you please advise me how to convert a reduced size map to a byte array and then store it in the database as a BLOB. Thank you and sorry for my English
var myQueryMaps2 = ' SELECT ' +
'id, budova, patro, mapa ' +
'FROM dbo.cis_mapyBudov';
app.get('/originalMaps', function (req, res) {
var request = new sql.Request(connection);
request.query(' DELETE FROM dbo.cis_mapyNewBudov', function (err) {
if (err) {
console.log(err);
}
});
request.query(myQueryMaps2, function (err, rows, recordset) {
if (!err && res.statusCode === 200) {
for (var i = 0; i < rows.length; i++) {
var insertSQL = "INSERT INTO dbo.cis_mapyNewBudov (id, budova, patro, mapa) VALUES ('" + rows[i].id +
"', '" + rows[i].budova + "', '" + rows[i].patro + "', '" + images(rows[i].mapa).toBuffer('jpg', {quality: 50}) +
"')";
request.query(insertSQL, function (err) {
if (err)
console.log(err);
else
console.log('save');
});
}
} else {
console.log('error original maps', err);
throw new Error('Can not download original maps');
}
});
});
Use input parameters, it's almost always a bad idea to concatenate values into TSQL.
var request = new sql.Request(connection);
request.input('id', rows[i].id);
request.input('budova', rows[i].budova);
request.input('patro', rows[i].patro);
request.input('mapa', sql.VarBinary(MAX), images(rows[i].mapa).toBuffer('jpg', {quality: 50}));
request.query('INSERT INTO dbo.cis_mapyNewBudov (id, budova, patro, mapa) VALUES (#id, #budova, #patro, #mapa)', function (err) {
// ...
});
Hint: Always create a new Request for each query. That's how the driver is designed. Reusing Request object might cause unexpected behavior.
Im learning bacon.js
i wrote test script like that.
var bacon = require('../nodejs/node_modules/baconjs').Bacon;
function TestClass(URL,port,username,password)
{
this.funcCheck = function( data , rescallback)
{
console.log(" data: " + data);
if(data.length > 4)
{
rescallback(null,data.substring(0, 2));
}
else
{
console.log("Calling callback with error data: " + "error");
rescallback("Too short",null);
}
}
}
var tclass = new TestClass();
var names = ['Geroge','Valentine', 'Oz','Nickolas'];
var results = [];
var read = bacon.fromNodeCallback( tclass.funcCheck, bacon.fromArray(names) )
stream.onValue(function(value)
{
console.log(" onValue " + value);
results.push( value);
});
stream.onError( function(error)
{
console.log(" OnError " + error);
// results.push( err);
});
console.log(" results " + results);
The problem is that onError never get called, despite the fact that "Oz" is less than 4 characters and i know that rescallback get called with 1 parameter that is not null.
I can see log printout.
The other thing is that if i change defition of onError and put it before onValue, onError will be called exactly 1 time, and onValue will never be called.
Im sure im missing something very basic but i dont know what exactly.
What im doing wrong?
Thanks