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.
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'm having some trouble with querying my DB on azure sql (I am very new to sql). I'm following the steps on https://learn.microsoft.com/en-us/azure/sql-database/sql-database-connect-query-nodejs, but it only includes tutorial steps on how to read tables, not manipulate them. I am trying to do INSERT and DELETE requests on my Node.js server, but I am getting a request error in one of the node modules, which makes me think that I'm going about requesting the operations wrong.
Here's some code:
var Connection = require('tedious').Connection;
var Request = require('tedious').Request;
// Create connection to database
var config =
{
userName: 'user_name',
password: 'password',
server: 'server_name',
options:
{
database: '_dbname'
, encrypt: true
}
}
var connection = new Connection(config);
// Attempt to connect and execute queries if connection goes through
connection.on('connect', function (err) {
if (err) {
console.log(err)
}
else {
queryDatabase();
}
}
//this works fine, it's for initially loading the data from the database
function queryDatabase() {
console.log('\nReading rows from the Table...');
let obj = {};
let objs = [];
let request;
// Read all rows from table
request = new Request(
"SELECT * FROM [dbo].[TABLE_NAME]",
function (err, rowCount, rows) {
console.log('-- Done');
}
);
//this is for when an admin adds content to the app, SQL table not changing,
//node.js throws error
socket.on('add item', item => {
let index = getCollectionIndexById(item.id);
collections[index].items.push(item.item);
io.sockets.emit('add item', item);
request = new Request(`INSERT INTO [dbo].[TABLE_NAME](Id, attr1, attr2, attr3, attr4)
VALUES (`
+ item.id + ','
+ item.item.attr2 + ','
+ item.item.attr3 + ','
+ item.item.attr4 + ','
+ null, function (err, rowCount, rows) {
if (err) throw err;
console.log('> requested db to insert item');
});
connection.execSql(request);
console.log('> item sent to app');
});
//for when the admin removes content from the app, same error
socket.on('rm item', item => {
collections[getCollectionIndexById(item.id)].items.splice(item.index, 1);
io.sockets.emit('rm item', { "id": item.id, index: item.index });
request = new Request(`DELETE FROM [dbo].[TABLE_NAME] WHERE Id= `
+ item.id + ` AND attr1= ` + item.item.attr1, function (err, rowCount, rows) {
if (err) throw err;
console.log('> requested db to remove item')
});
connection.execSql(request);
console.log('> sent request to remove item');
});
The exact error msg is RequestError: Incorrect syntax near 'esse'., and its in one of the node modules called tedious in request.js.
So in summary, if anyone knows of a way to query Azure SQL Db's to make inserts and deletes, any help is appreciated!
You missed ) in the 'insert' SQL. Also, you'd need to set string value with single quotes of course.
Change the following lines of code
request = new Request(`INSERT INTO [dbo].[TABLE_NAME](Id, attr1, attr2, attr3, attr4)
VALUES (`
+ item.id + ','
+ item.item.attr2 + ','
+ item.item.attr3 + ','
+ item.item.attr4 + ','
+ null, function (err, rowCount, rows) {
if (err) throw err;
console.log('> requested db to insert item');
});
connection.execSql(request);
to
request = new Request(`INSERT INTO [dbo].[TABLE_NAME](Id, attr1, attr2, attr3, attr4) VALUES ('${item.id}', '${item.item.attr2}', '${item.item.attr3}', '${item.item.attr4}' null)`, function (err, rowCount, rows) {
if (err) throw err;
console.log('> requested db to insert item');
});
connection.execSql(request);
You will find an example here of how to INSERT records on a table using NodeJs and queryRaw.
conn.queryRaw("INSERT SalesLT.Product (Name, ProductNumber, StandardCost, ListPrice, SellStartDate) OUTPUT INSERTED.ProductID VALUES ('SQL Server Express 102', 'SQLEXPRESS 102', 0, 0, CURRENT_TIMESTAMP)", function (err, results)
You can use queryRaw also to DELETE records on a table.
Hope this helps.
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).
I'm trying to export some legacy data from a mysql db as JSON using express and node-mysql. The SQL below works fine. I'm struggling with a simple way to join the 'result' of getOwnerID and to the data for each row returned in compVouchers.
I'm also using async.js having followed another thread, though I'm not sure this is helping. But if I can get away with not using this that might be better.
//join some tables to get comprehensive voucher data
exports.compVouchers = function(req, res) {
var advertType = '"discount_voucher_all_CANCELLED"';
if (connection) {
connection.query('SELECT V.id AS voucher_id, V.title, V.description, V.discount, V.customers_total, V.advert_type, ' +
'V.customers_redeemed, V.start_date, V.expiry_date, V.redemption_code, ' +
'K.image, G.latitude, G.longitude FROM '+dbname+'.vouchers AS V ' +
'LEFT JOIN '+dbname+'.iag_key_tags AS K ON ( V.id = K.id ) ' +
'LEFT JOIN '+dbname+'.iag_geo_tags AS G ON ( V.id = G.id ) ' +
'WHERE V.advert_type like '+advertType , function(err, rows, fields) {
if (err) throw err;
console.log("Got "+rows.length+" Vouchers:");
// now get each vouchers owner id
async.map(rows, getOwnerID, function(err, results){
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end(JSON.stringify(results));
res.end();
});
});
}
};
function getOwnerID(voucher, callback) {
connection.query('SELECT parent_tagid AS owner_id FROM '+dbname+'.iag_key_tag_relationships WHERE TYPE =2 AND tagid = '+ voucher.voucher_id, function(err, info) {
if(err) {
console.log(err);
return callback(err);
}
else {
return callback(null, info);
}
});
}
so
res.end(JSON.stringify(results)); // prints all the owner_id of each voucher only
res.end(JSON.stringify(rows)); // prints the data for each voucher but not the owner_id
Combining node-mysql result rows into single JSON return for node.js doesn't solve the problem but as you can see I have tried to follow the suggestion in that thread.
Here this is some more beauty than in coments :)
Try this:
var result={}, c=rows.length;
function getOwnerID(voucher, cb){
connection.query('SELECT ...', function(err, info) {
if(err) console.log(err);
else result[info] = voucher;
if(!--c)return cb();
});
}
while(rows.length){
getOwnerID(rows.pop(), function(){
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end(JSON.stringify(results));// {"owner1":{voucher1}, "owner2":{voucher2}}
res.end();
})
}
OK guys (thanks #vp_arth for nudging me in an interesting direction that got me close, the typo results should be result btw)
So anyhow, I ended up with a hack solution, I'm using .push underscore.js and .replace to help me clean up the JSON data so I could use it later / next in a nosql database like MongoDB.
//declare global array variable... there must be a more elegant solution
var compV = [];
exports.compVouchers = function(req, res) {
var advertType = '"discount_voucher_all_CANCELLED"';
if (connection) {
connection.query('SELECT V.id AS voucher_id, V.title, V.description, V.discount, V.customers_total, V.advert_type, ' +
'V.customers_redeemed, V.start_date, V.expiry_date, V.redemption_code, ' +
'K.image, G.latitude, G.longitude FROM '+dbname+'.vouchers AS V ' +
'LEFT JOIN '+dbname+'.iag_key_tags AS K ON ( V.id = K.id ) ' +
'LEFT JOIN '+dbname+'.iag_geo_tags AS G ON ( V.id = G.id ) ' +
'WHERE V.advert_type like '+advertType , function(err, rows, fields) {
if (err) throw err;
// now get each vouchers owner id
console.log("Got "+rows.length+" Vouchers:");
async.each(rows, getOwnerID, function(err, results){
res.writeHead(200, {'Content-Type': 'text/plain'});
// now user underscore.js to clean up JSON
var finalComp = JSON.stringify(un.flatten(un.compact(compV)));
// finally use replace to customise the known output to merging the voucher and owner into single JSON documents
var finalComp2 = finalComp.replace(/},{"owner_id/g,',"owner_id'); //not happy with this but it works
res.write(finalComp2);
res.end();
});
});
}
};
function getOwnerID(voucher, callback) {
connection.query('SELECT parent_tagid AS owner_id FROM '+dbname+'.iag_key_tag_relationships WHERE TYPE =2 AND tagid = '+ voucher.voucher_id, function(err, owner) {
if(err) {
console.log(err);
return callback(err);
}
else {
var arr = [];
arr.push(voucher);
arr.push(owner);
compV.push(arr); //append to global array variable
return callback(null, compV); // doesn't return anything??
}
});
}
perhaps there is a more elegant way to merge
[{"F1_field1":"F1_value1","F1_field2":"F1_value2"},{"F2_field1":"F2_value2"}]
into
[{"F1_field1":"F1_value1","F1_field2":"F1_value2","F2_field1":"F2_value2"}]
here is my final code with comments / thoughts
you would now also need to npm install underscore addition to async and declare them in variables... not to mention node-mysql and express... I have used "un" instead of "_" so I don't get confused with code that might look like jquery shorthand later.
I need to allow users to export their data in csv format. I have written app in nodejs. The export data for users can be huge. So i was wondering How to handle such situation in nodejs. Should i user process.nexttick or child process api of nodejs? Also are there any good module available for nodejs to convert data from mysql to csv.
read line by line from your mysql-db, and append line by line to your file
i dont know that much about the mysqlmodule, so i'm assuming here each line is just an array, therefore the 'row.join(';')'. if thats not the case (maybe its an object), you should fix that.
var fs = require('fs');
var connection = require('mysql').createConnection({yourdbsettingshere});
function processRow (row) {
fs.appendFile('your-file.csv', row.join(';'), function (err) {
connection.resume();
});
}
var query = connection.query('SELECT * FROM WHATEVER');
query
.on('error', function(err) {
// do something when an error happens
})
.on('fields', function(fields) {
processRow(fields);
})
.on('result', function(row) {
// Pausing the connnection is useful if your processing involves I/O
connection.pause();
processRow(row, function (err) {
connection.resume();
});
})
.on('end', function() {
// now you can mail your user
});
if you have a lot of requests, you could use the compute-cluster module for distributing your workload
The accepted answer is not working because CSV files are separated by , not ;. Also there is no newline character \n after the end of each row and the fields object contains information about the column attributes not the data rows. results contains the rows resulted from query. Hence I wrote my own code for generating CSV files. If you need more explanation then please comment, I will provide.
pool.query('SELECT * FROM category', function (error, results, fields) {
var reportFile = Date.now();
fs.closeSync(fs.openSync(__dirname + '/../reports/' + reportFile + '.csv', 'w'));
var attributes = [];
var row = [];
for(var x = 0; x<fields.length; x++) attributes.push(fields[x].name);
fs.appendFile(__dirname + '/../reports/' + reportFile + '.csv', attributes.join(','), function (err) {
if(err) console.log('Error appending fields', err);
fs.appendFileSync(__dirname + '/../reports/' + reportFile + '.csv', '\n');
for(var x = 0; x<results.length; x++) {
row = [];
for(var y = 0; y<attributes.length; y++){
row.push(results[x][attributes[y]]);
}
fs.appendFileSync(__dirname + '/../reports/' + reportFile + '.csv', row.join(','));
fs.appendFileSync(__dirname + '/../reports/' + reportFile + '.csv', '\n');
}
req.reportFile = reportFile;
next();
});
});