How does one tell sequelize (using sqlite3) to escape wildcard characters (%,_) in a $like clause?
For example, I'd like to generate a query comparable to the one below which finds the literal string _cool_ in any "things.description" (not just the word "cool" surrounded by any characters):
SELECT * FROM things WHERE description LIKE '\_cool\_' ESCAPE '\';
I'm guessing it would look something like this but the resulting query is not what I would hope:
Thing.findAll({
where: {
description: {
$like: ['?', '_cool_'],
// ... or ...
$like: '\\_cool\\_',
$escape: '\\',
}
}
});
// => Executing (default):
// SELECT `id`, `description`
// FROM `Things` AS `Thing`
// WHERE `Thing`.`description` LIKE '?','_cool_';
Unfortunately I cannot drop into a raw query because the "LIKE" clause will be part of a larger dynamic query.
Any ideas?
A full solution based on @piotrbienias that takes any user input and properly escapes it -
if (typeof query.string !== 'string') {
throw Error('expecting string')
}
const inputRaw = query.string.replace(/(_|%|\\)/g, '\\$1');
const inputSec = sequelize.escape(`%${inputRaw}%`);
description = {
$like: sequelize.literal(`${inputSec} ESCAPE '\\'`)
};
For the example string _cool_ this will translate to -
LIKE '%\\_cool\\_%' ESCAPE '\\'
You can change the logic to add other wildcards depending on your actual use case
if your using mysql and not sqlite the default escape is anyway \ so the ESCAPE declaration can be removed
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With