Firebird transliteration issue: conversion from utf8 client to win1252 db server - sql

I am facing a problem when trying to update data in a firebird database.
Setup is the following:
NodeJS Server with Node-Firebird module (https://github.com/hgourvest/node-firebird) --> only allows UTF8 Charset
Firebird Server 2.5 with WIN1252 Charset (charset must also stay the same)
My update statement:
db.transaction((err, transaction) => {
if (err) return closeDB(db, transaction, err);
// Update one record by pk
console.log("do update");
const params = [];
transaction.query(`UPDATE OBJEKT
SET BEZ = 'Böckstraße'
WHERE OB_KEY = 25984`, params, (err, _) => {
// The code below is executed only when the number of parameters is less than 10
if (err) return closeDB(db, transaction, err);
transaction.query('select * from OBJEKT where OB_KEY = 12345', [1], (err, data) => {
if (err) return closeDB(db, transaction, err);
console.log(data);
// Finally simply commit the transaction
closeDB(db, transaction, err);
});
});
});
When doing the update queries, I am receiving "Cannot transliterate character between charsets" error.
When I introduce the variable with my target charset (_win1252) the update is working, but the characters are not correct: Bockstraße ends up as:
I started playing around with the collations, but yet no success. How can I map these 2 charsets correctly?

Related

How safe is this generated query from SQL injection?

I am trying to make a search bar which works with multiple words, but I am worried about SQL injection.
I am using node express with the npm mssql package.
Here's the code which gets the criteria, generates the SQL and runs it:
router
.get('/search/:criteria', function (req, res) {
var criteria = req.params.criteria;
var words = criteria.split(" ");
var x = ""
words.map(word => x += `name like '%${word}%' and `);
x = x.substring(0, x.length - 5); // Remove trailing 'and'
var query = `SELECT * FROM table WHERE ${x}`
new sql.ConnectionPool(db).connect().then(pool => {
return pool.request().query(query)
}).then(result => {
})
});
A search for something to search would result in this query:
SELECT * FROM table
WHERE
name like '%something%'
and name like '%to%'
and name like '%search%'
I tried some SQL injections myself, but none of them seem to work.
Note: I am aware that we should always use inputs for this. It works fine for one word, but I don't know how to use inputs for many words. Ex:
new sql.ConnectionPool(db).connect().then(pool => {
return pool.request()
.input('input', '%'+criteria+'%')
.query(query)
})
The answer is: It's not safe. Your code does exactly nothing to make it safe, either. Don't build SQL by concatenating/interpolating user-supplied data into the statement.
In addition, you don't do any escaping for LIKE itself, either, so that is just as unclean.
If you need dynamic SQL, build a prepared SQL statement with the expected number of placeholders and then bind user-supplied values to those placeholders.
router.get('/search/:criteria', (req, res) => {
const ps = new sql.PreparedStatement();
const sqlConditions = [];
const escapedValues = {};
// set up escaped values, safe SQL bits, PS parameters
req.params.criteria.split(" ").forEach((v, i) => {
const paramName = 'val' + i;
escapedValues[paramName] = v.replace(/[\\%_]/g, '\\$&');
sqlConditions.push(`name LIKE '%' + #${paramName} + '%' ESCAPE '\'`);
ps.input(paramName, sql.VarChar);
});
// build safe SQL string, prepare statement
const sql = 'SELECT * FROM table WHERE ' + sqlConditions.join(' AND ');
ps.prepare(sql);
// connect, execute, return
ps.execute(escapedValues).then(result => {
res(result)
});
});
(Disclaimer: code is untested, as I have no SQL Server available right now, but you get the idea.)

Calling multi-parameterized Azure SQL stored procedure from Nodejs

I am looking forward to know how can I run an Azure SQL stored procedure with multiple input parameters from Nodejs.
For example, if I have a stored procedure FIND_USERS(activity_status, color, gender) which runs a query
select * from users where isActive = activity_status and bay_color = color and userGender = gender;
I should be able to call this stored procedure from nodejs with the input parameters. The thing to understand here is that I want have a SQL transaction service that can take any CALL PROCEDURE type command along with the set of input parameters and call the procedure using those input parameters irrespective of the number of input parameters.
What I know is that for MySQL, there is a mysql library which lets me run procedures with multiple parameters. I have encapsulated it in MySQLConnector.js service as
var mysql = require('mysql');
exports.query = function(sql, values, next) {
if (arguments.length === 2) {
next = values;
values = null;
}
var connection = mysql.createConnection({
host:host,
user:user,
password:password,
database:database
});
connection.connect(function(err) {
if (err !== null) {
console.log("[MYSQL] Error connecting to mysql:" + err+'\n');
console.log(err == 'Error: ER_CON_COUNT_ERROR: Too many connections')
if(err == 'Error: ER_CON_COUNT_ERROR: Too many connections'){
connection.end();
}
}
});
connection.query(sql, values, function(err) {
connection.end();
if (err) {
throw err;
}
next.apply(this, arguments);
});
}
With this, I can call a stored procedure from nodejs with a function like
MySQLConnector.query('CALL FIND_USERS (?, ?, ?)', [1, 'blue', 'female'], function(err, userData) {
//do something with userData
});
How is it possible to do this for Azure MS SQL?
You can use tedious driver to connect to SQL Server. It supports both input+output parameter for statements and SPs, you can find the example in http://tediousjs.github.io/tedious/parameters.html
Feels free to raise an issue in GitHub if you need more assistance.
Make use of Edje.js and you should create a function and send the parameters when you call the function.
getHorarioFarmacia({pSede:'Sucursal Parrita'}, function (error, result){....
}
For more details, read the comments made by Luis Diego Pizarro here.

API returns array of JSON for only one result

Currently working on an API which given an address returns information about is. Some of the rows in our tables are duplicates, however being as there is over 15 million I cant go and find the duplicates. Instead I have opted to use
var query = `SELECT TOP 1 * from my_TABLE where..conditions`;
This ensures that only one row of the duplicates are returned.
The problem is when this is sent back as a JSON it comes as an array with one object.
In the Server.js file
// create Request object
var request = new sql.Request();
// query to the database
request.query(query, function (err, result) {
if (err) {
console.log("Error while querying database :- " + err);
res.send(err);
}
else {
res.send(result)
}
Returns this:
[{
Address:'our info'
}]
is there a way to have it respond with
{
Address:'our info'
}
Because from DB you've get list of object anyway, even there is only 1 item.
It works as you expected when you try to return json with the first element of your array.

Nodejs localhost keeps loading my function

Good morning to everyone,
Please I would be so grateful if you could provide a little help for me. I am already stuck for long time with this issue.
I have a function which does not stop loading my localhost after this function is triggered. I did not figure out so far how to fix it.
Any help would be perfect.
This is my code:
// Copy scene
router.post('/copy', function(req,res,call) {
if( req.param('scene') !== undefined ){
db.serialize(function () {
db.run("CREATE TABLE temp_table as SELECT * FROM scene where id=?", req.param('scene'));
db.run("UPDATE temp_table SET id = NULL, user_id = (SELECT id FROM users WHERE email =?)",GLOBAL.email);
db.run("INSERT INTO scene SELECT * FROM temp_table");
db.run("DROP TABLE temp_table");
if(error) {
console.log(error);
}
});
db.close();
}
});
Thank you so much in advance
Whenever browser sends any request to a server it expects a response. if it doesn't get any response it will be stuck with the timeout.
You need to send the response to terminate the request if you are not doing next execution with callback call or if you are expecting next manipulation then replace res.send() to call(error parameter,success parameter).
router.post('/copy', function(req, res, call) {
if (req.param('scene') !== undefined) {
db.serialize(function() {
db.run("CREATE TABLE temp_table as SELECT * FROM scene where id=?", req.param('scene'));
db.run("UPDATE temp_table SET id = NULL, user_id = (SELECT id FROM users WHERE email =?)", GLOBAL.email);
db.run("INSERT INTO scene SELECT * FROM temp_table");
db.run("DROP TABLE temp_table");
if (error) {
console.log(error);
res.send(error);//send response if error
//or call(error);
}
res.send({message:'success'});//send response if success
//or call(null,whatever you want to pass)
});
db.close();
}
});
You must either call the callback call() to pass on control to next middleware, or render and end the response using res.end() once your middleware logic is done.
Please see: https://expressjs.com/en/guide/writing-middleware.html

Functional testing conditionals with Intern/Leadfoot

I am wishing to conditionally execute some commands/assertions depending on whether previous assertions succeeded or not.
I can't seem to find a way to nest then calls or conditionally execute things using the chaining syntax of leadfoot.
Here is my test (the returns at the end of each function is due to this being compiled coffeescript):
tdd.test(tableUrl, function() {
this.timeout = 60000;
return this.remote.get(require.toUrl("tests/pages/" + tableUrl))
.setPageLoadTimeout(60000)
.setFindTimeout(20000)
.findByCssSelector('.dataTables_wrapper table.dataTable')
.then(null, function(err) {
return assert.fail('', '', 'Table should exist');
}).then(pollUntil(function() {
var table;
table = document.querySelector('.dataTables_wrapper table.dataTable');
if (table.querySelectorAll('tbody td').length > 1) {
return true;
} else {
return null;
}
}, null, 20000, 500)).then(function() {
console.log('Assertion succeeded: Table should have data');
return assert.ok(true, 'Table should have data');
}, function(err) {
return assert.fail('', '', 'Table should have data');
});
});
When a table does not exist, both 'Table should exist' and 'Table should have data' assertions should be reported as failing. However, only the last assertion is failing. When I comment out the 'Table should have data' error callback, the 'Table should exist' assertion is reported as failing correctly.
What I would like to do is
test if a table exists (via findByCssSelector).
a) If it exists, report that it exists and test to see that it has more than one td element. This is currently done via pollUntil to ensure that the command is complete/promise is resolved as soon as more than one td is found instead of waiting for the whole implicit wait time.
b) If it does not exist, report that it does not exist.
I can't seem to find a way of not executing the error callback of the second 'Table should have data' poll if the first findByCssSelector fails, due to lack of conditionals and only the last assertion failure being reported in a test.
So conditional branching can happen with then calls, this answer addresses how to do conditional branching with intern.
The problem I was having was the pollUntil function not behaving the same way as a normal leadfoot Command method due to the function returning a callback function that returns a promise rather than a promise directly.
This can be circumvented by wrapping the pollUntil in an anonymous function, immediately calling the pollUntil function using the call method, passing in the current this value due to then setting the context of the callback to the Command object, and then finally chaining another Command.
This is what the above code turned into using correct conditional branching with pollUntil.
tdd.test(tableUrl, function() {
this.timeout = 60000;
return this.remote.get(require.toUrl("tests/pages/" + tableUrl))
.setPageLoadTimeout(60000)
.setFindTimeout(5000)
.findByCssSelector('.dataTables_wrapper table.dataTable')
.then((function() {
return pollUntil(function() {
var table;
table = document.querySelector('.dataTables_wrapper table.dataTable');
if (table.querySelectorAll('tbody td').length > 1) {
return true;
} else {
return null;
}
}, null, 20000, 500).call(this).then(function() {
console.log('Assertion succeeded: Table should have data');
return assert.ok(true, 'Table should have data');
}, function(err) {
return assert.fail('', '', 'Table should have data');
});
}), function(err) {
return assert.fail('', '', "Table should exist. Error: " + err.name);
});
});