Best way pass array as query params for pg PoolClient with postgres using typescript - sql

I am fetching some data from the postgres database with typescript using pg PoolClient, currently, I am fetching using the below way please let me know if there is any better way to achieve the same
const SPECIAL_LIST = [
"ABC",
"XYZ",
"PQR",
"LMN",
"EFG",
"IJK",
];
var params = SPECIAL_LIST.reduce(function (a, b, idx) {
if (idx === 0) return '$' + (idx + 2);
else return a + ', $' + (idx + 2);
}, '');
const sql = "Select sg.code,sg.dep,sg.vo,sg.arr from table1 sg where sg.is_omitted is false and v_code = $1 and sg.r_code not in (" +params+ ") order by sg.est_datetime asc"
const values = [vesselCode].concat(SPECIAL_LIST);
const client = await pool.connect();
await client
.query(sql, values)
.then((res) => {
const data = res.rows;
console.log(res.rowCount)
data.forEach((row) => {
// function logic
});
})
.catch((e) => console.error(e))
.then(() => client.release());

Found the solution using ANY below is the solution
const sql =
`SELECT v1, v2, v3, v4, v5, v6, v7
FROM ${TABLE_NAME}
WHERE omitted IS FALSE
AND v1 = $1
AND NOT rcode = ANY ($2)
ORDER BY datetime_dt ASC`;
const values = [vCode, SPECIAL_SITES];
const client = await pool.connect();
await client
.query({ text: sql, values: values })
.then((res) => {
res.rows.forEach((row) => {
//......
});
})
.catch((e) => console.error(e))
.then(() => client.release());

Related

Message event broken ( quick.db )

So i wanna get started with quick.db for my discord.js bot. I asked someone to help me solve this issue but they seem to be unable to. So if theres anyone here that can help could you tell me whats wrong with my code
module.exports = (client) => client.on('messageCreate', async (message) => {
const prefix = [].concat(client.config.prefix);
const ms = require('ms');
if (
message.author.bot ||
!message.guild ||
!prefix.some((x) => message.content.toLowerCase().startsWith(x))
)
return;
const [cmd, ...args] = message.content
.slice(prefix
.filter((x) => message.content.toLowerCase().startsWith(x))
.sort((a, b) => b.length - a.length)[0].length
)
.trim()
.split(/ +/g);
const command =
client.commands.get(cmd.toLowerCase()) ||
client.commands.find((c) =>
[].concat(c.aliases).includes(cmd.toLowerCase())
);
if (!command) return;
const cd = client.cd.get(`${message.author.id}_${command.name}`);
const left = cd - Date.now();
if (left > 0) {
const msg = await message.channel.send(
`You are on cooldown, please wait **${ms(left)}** to use this command again`
);
return setTimeout(() => msg.delete(), left);
}
if (command.cooldown)
client.cd.set(
`${message.author.id}_${command.name}`,
Date.now() + ms(command.cooldown)
);
try {
await command.run(client, message, args);
} catch (error) {
message.channel.send(error.toString());
}
}); 
the above code is the working one but whenever i use this
module.exports = (client) => client.on('messageCreate', async (message) => {
const ms = require('ms');
const { QuickDB } = require('quick.db');
const db = new QuickDB();
const prefix = db.get(`newprefix_${message.guild.id}`) || config.prefix
if (!prefix) return; 
if (!message.content.startsWith(prefix) || message.author.bot) return;
const [cmd, ...args] = message.content
.slice(prefix
.filter((x) => message.content.toLowerCase().startsWith(x))
.sort((a, b) => b.length - a.length)[0].length
)
.trim()
.split(/ +/g);
const command =
client.commands.get(cmd.toLowerCase()) ||
client.commands.find((c) =>
[].concat(c.aliases).includes(cmd.toLowerCase())
);
if (!command) return;
const cd = client.cd.get(`${message.author.id}_${command.name}`);
const left = cd - Date.now();
if (left > 0) {
const msg = await message.channel.send(
`You are on cooldown, please wait **${ms(left)}** to use this command again`
);
return setTimeout(() => msg.delete(), left);
}
if (command.cooldown)
client.cd.set(
`${message.author.id}_${command.name}`,
Date.now() + ms(command.cooldown)
);
try {
await command.run(client, message, args);
} catch (error) {
message.channel.send(error.toString());
}
});  
it doesn't work, meaning my bot doesn't reply

How do I resolve a callback error with 'callback' is an instance of Object)?

TypeError: callback is not a function. (In 'callback(data)',
'callback' is an instance of Object)
The code here works just fine when I write it like this:
const onSelectFilterDone = (filter) => {
setFilter(filter);
setFilterModalVisible(false);
unsubscribe.current = listingsAPI.subscribeListings(
{ categoryId: category.id },
// { categoryId2: category2.id },
favorites,
onListingsUpdate,
);
};
When i uncomment that other line, it breaks and gives me this error.
const onSelectFilterDone = (filter) => {
setFilter(filter);
setFilterModalVisible(false);
unsubscribe.current = listingsAPI.subscribeListings(
{ categoryId: category.id },
{ categoryId2: category2.id },
favorites,
onListingsUpdate,
);
};
Here is the relevant snippet from listingsAPI (below) if it helps but this code works fine when there is only one object. Is there a specific way to make this work with two objects like above?
if (categoryId) {
return (
listingsRef
.where('categoryID', '==', categoryId)
.where('isApproved', '==', isApproved)
.onSnapshot((querySnapshot) => {
const data = [];
querySnapshot.forEach((doc) => {
const listing = doc.data();
if (favorites && favorites[doc.id] === true) {
listing.saved = true;
}
data.push({ ...listing, id: doc.id });
});
callback(data);
})
);
}
if (categoryId2) {
return (
listingsRef
.where('categoryID2', '==', categoryId2)
.where('isApproved', '==', isApproved)
.onSnapshot((querySnapshot) => {
const data = [];
querySnapshot.forEach((doc) => {
const listing = doc.data();
if (favorites && favorites[doc.id] === true) {
listing.saved = true;
}
data.push({ ...listing, id: doc.id });
});
callback(data);
})
);
}
You can combine your queries via this way if you want to have it optional:
let query = listingsRef.where('isApproved', '==', isApproved)
if (categoryId) {
query = query.where('categoryID', '==', categoryId)
}
if (categoryId2) {
query = query.where('categoryID2', '==', categoryId2)
}
query.onSnapshot...

How to sanitize inputs in nodejs to prevent sql injection?

i have this sanitize function
sanitizeXSS: string => {
const map = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": ''',
"/": '/',
};
const reg = /[&<>"'/]/ig;
return string.replace(reg, (match)=>(map[match]));
}
And this sanitize function is being used here
addOrUpdateAddress : function (request, resolve)
{
const customerKey = sanitizeXSS(decrypt_key(request.customer_key));
const lat = sanitizeXSS(decrypt_key(request.lat));
const lng = sanitizeXSS(decrypt_key(request.lng));
const line1 = sanitizeXSS(decrypt_key(request.line1));
const line2 = sanitizeXSS(decrypt_key(request.line2));
const city = sanitizeXSS(decrypt_key(request.city));
const pincode = sanitizeXSS(decrypt_key(request.pincode));
const state = sanitizeXSS(decrypt_key(request.state));
const contact = sanitizeXSS(decrypt_key(request.contact));
const landmark = request.landmark?sanitizeXSS(decrypt_key(request.landmark)):null;
let req=request;
if(req.name && req.email)
{
updateUser(req,function(err,result)
{
console.log(err);
console.log(result);
});
}
let addressId = (!req.address_id || req.address_id == null || req.address_id == '')
? -1 : req.address_id;
console.log(addressId);
async.auto({
serviceability : function (cb)
{
searchServiceArea(req,function(err,result)
{
if(err)
{
resolve(null, {'errorMessage':'Address selected not serviceble'}, 203, 'error');
}
else
{
if(!result.hub_id)
{
resolve(null, {'errorMessage':'Address selected not serviceble'}, 203, 'error');
}
if(addressId == -1)
{
let s=mysql.write('customer_address').insert({customer_key: customerKey,line1:line1,line2:line2,lat: lat,lng: lng,city: city,state: state,pincode: pincode,contact: contact,landmark : landmark,updated_at:moment().format("YYYY-MM-DD HH:mm:ss"),created_at:moment().format("YYYY-MM-DD HH:mm:ss")}).then(function(res)
{
if(res.length > 0)
{
cb(null,{address_id:res[0],customer_key: customerKey,line1:line1,line2:line2,lat: lat,lng: lng,city: city,state: state,pincode: pincode,contact: contact,landmark : landmark,updated_at:moment().format("YYYY-MM-DD HH:mm:ss"),created_at:moment().format("YYYY-MM-DD HH:mm:ss"),'hub_id':result.hub_id})
}
else
{
cb(true,{'errorMessage':'Unable to add address try again'})
}
});
}
else
{
let s=mysql.write('customer_address').update({line1:line1,line2:line2,lat: lat,lng: lng,city: city,state: state,pincode: pincode,contact: contact,landmark : landmark,updated_at:moment().format("YYYY-MM-DD HH:mm:ss")}).where({customer_key:customerKey, address_id:addressId}).then(function(res)
{
console.log(res)
if(res == 1)
{
cb(null,{address_id:addressId,customer_key: customerKey,line1:line1,line2:line2,lat: lat,lng: lng,city: city,state: state,pincode: pincode,contact: contact,landmark : landmark,updated_at:moment().format("YYYY-MM-DD HH:mm:ss"),created_at:moment().format("YYYY-MM-DD HH:mm:ss"),'hub_id':result.hub_id})
}
else
{
cb(true,{'errorMessage':'Unable to update address try again'})
}
},
},
);
}
So while inserting the address I'm identifying sql injection. I checked everywhere the possible solutions i was not able to solve it. Please do check the sql query also which i have mentioned.
How to solve this?
That would be a lot of help. Thanks in advance
I'd just use a standard library that already provides sanitization, like node-mysql.
https://github.com/mysqljs/mysql#escaping-query-values
const mysql = require('mysql');
const connection = mysql.createConnection({
host : 'example.org',
user : 'bob',
password : 'secret'
});
const post = {title: 'Hello MySQL', 'content': '...'};
connection.query(
'insert into posts (title, content, updated_at, created_at) values (?, ?, ?, ?);',
[
connection.escape(post.title),
connection.escape(post.content),
connection.escape(new Date()),
connection.escape(new Date())
]
).then((err, res, fields) => {
//do stuff
})

Update a value from a node in Firebase Realtime-Database in Redux

Each time a new group is created in my databse, i want to trigger a counter into the /categories/categoryId/groupsCount node in my realtime database with redux. I built this code to get the current count number of the groupsCount value of that particular categoryId and tried to update() with a +1. It didn't work and I don't find any other way to do this simple thing.
export const updateCategoryGroupCount = categoryId => {
return async dispatch => {
const currentCount = firebase
.database()
.ref('/categories/' + categoryId + '/groupsCount')
await firebase
.database()
.ref('/categories/' + categoryId)
.update({ groupsCount: currentCount + 1 })
.then(
dispatch({
type: UPDATE_CATEGORY_COUNT,
cid: categoryId,
total: currentCount + 1;
})
);
};
};
How do I get a value from /categories/id/groupCounts using firebase query?
currentCount is assigned a promise which is returned from firebase and second query should be called after first one is done.
Change your code like this
export const updateCategoryGroupCount = categoryId => {
return async dispatch => {
firebase
.database()
.ref('/categories/' + categoryId + '/groupsCount')
.once("value")
.then((snapshot)=> {
let fetchedObj = snapshot.val(); //the object which is included fields belong to the path of '/categories/' + categoryId + '/groupsCount'
let currentCount = fetchedObj.currentCount;
await firebase
.database()
.ref('/categories/' + categoryId)
.update({ groupsCount: currentCount + 1 })
.then(
dispatch({
type: UPDATE_CATEGORY_COUNT,
cid: categoryId,
total: currentCount + 1;
})
);
})
};
};

Node.js Sequelize: multiple condition on 'where'

How do i query a table with multiple conditions? This give me no error but, only run the first condition!
exports.findAllLimit = (req, res) => {
const titulo = req.query.titulo ;
var condition = titulo ? { titulo : { [Op.iLike]: `%${titulo }%` } } : null;
var condition2 = {stock: { [Op.ne]: 0}};
Produtos.findAll({
where: condition , condition2,
include: [Categorias],
order: [
['id', 'ASC']
],
limit: 9
})
.then(data => {
res.send(data);
})
.catch(err => {
res.status(500).send({
message:
err.message || "Ocorreu um erro a retirar os dados do backend!."
});
});
};
You create here an object with property condition2 and it's value.
You need to merge these 2 conditions, and assign them on where.
so you can use:
where: Object.assign({}, condition , condition2),
OR:
where: {...condition, ...condition2}
you can do like this for multiple condition .
const titulo = req.query.titulo ;
var condition = titulo
? {
titulo: {
[Op.iLike]: `%${titulo}%`,
},
}
: null;
var condition2 = {
stock: {
[Op.ne]: 0,
},
};
let where = [];
where.push(condition);
where.push(condition2);
Produtos.findAll({
where,
});