using nodejs with pattern matching in CQL - cassandra

const query= 'SELECT * FROM TEST WHERE "partitionId" = \'sr\' AND "name" LIKE \'%?%\'';
db.execute(query, ['B']).then(function(res) {
console.log(res);
}).catch(function(error) {
console.log(error);
});
I was not able to select data based on the pattern specified in the array.What is the exact way using CQL pattern matching with nodejs.I am getting "Invalid amount of bind variables" error.
NOTE: db has all the connection parameters

I think that you need to use following instead
const query= 'SELECT * FROM TEST WHERE "partitionId" = \'sr\' AND "name" LIKE ?';
db.execute(query, ['%B%']).then(function(res) {
...
P.S. Do you have corresponding indices built that support the LIKE expression? Cassandra doesn't work the same way as "standard" SQL databases.

Related

Postgres Node search query using LIKE, how to set %

I have a weird problem I encountered using Postgresql and Node. I would like to use LIKE in my query together with % at the beginning and end of searched term. I have no issue using it in the plain SQL:
THIS WORKS:
SELECT * FROM vehicle WHERE module_imei LIKE '%searchterm%' OR custom_id LIKE '%searchterm%'
However, using it in Node is a bit of challenge. I haven't been successful in resolving it yet:
THIS DOES NOT WORK:
getVehiclesSearch: async function({ search }) {
let response;
try {
response = await pool.query(`SELECT * FROM vehicle WHERE module_imei LIKE %$1% OR custom_id LIKE %$1%`, [search]);
if(response) return response.rows;
} catch(error) {
// handle error
console.error(error);
// do not throw anything
}
},
Doing above will produce: syntax error at or near "%"
SELECT * FROM vehicle WHERE module_imei LIKE '%${$1}%' OR custom_id LIKE '%${$1}%
Doing above will produce: $1 is not defined
SELECT * FROM vehicle WHERE module_imei LIKE '%$1%' OR custom_id LIKE '%$1%'
Doing above will produce: bind message supplies 1 parameters, but prepared statement "" requires 0
I kind of struggle factoring the % in so it won't crash the query. Simply run out of ideas after trying above and variables of those. Thanks for your kind help.
This has been already answered over here:
Go postgresql LIKE query
In this particular case:
response = await pool.query(`SELECT * FROM vehicle WHERE module_imei LIKE '%'||$1||'%' OR custom_id LIKE '%'||$1||'%'`, [search]);
This would work.
You are missing single quotes, also I don't recognize a db adapter you use, but you can use template literals (watch out for sql injection!!!)
response = await pool.query(`SELECT * FROM vehicle WHERE module_imei LIKE '%${search}%' OR custom_id LIKE '%${search}%'`);

PostgreSQL REST API Node.js CRUD - String query parameter giving error

I am setting up my first REST API to query a Postgres database I set up. I have two CRUD methods that currently work that query for all rows in a table and for rows where ID = something, respectively.
The problem I'm having occurs when trying to query when the request parameter is a String. Here is the error I'm getting:
error: invalid input syntax for type integer: "NaN"
Here is how I've set up my GET route and endpoint URL:
const getShowByTitle = (request, response) => {
const title = request.params.title
pool.query('SELECT * FROM show WHERE title = $1', [title], (error, results) => {
if (error) {
throw error
}
response.status(200).json(results.rows)
})
}
app.get('/show/:title', getShowByTitle)
Expected result is that sending a GET request using a show title as a parameter (String) returns a JSON response of just that show.
Any help or direction to some useful resources would be greatly appreciated. Thank you.
There are some issues here, first in SQL the name of the tables should be in plural "shows", second you are making the select without quotes, you need something like:
"SELECT * FROM show WHERE title = '$1'"
Third, since the user can use uppercase and down cases you need a more robust way to search for text using LIKE, ILIKE and ~, ~* operators.
https://www.2ndquadrant.com/en/blog/text-search-strategies-in-postgresql/
Fourth and more important, you are not filtering the string and you are at risk of suffering an SQL injection because "UPDATE admins SET password='newsom22th88';" is going to be executed in your database.
After some debugging my original code wasn't working because I had multiple verb-route matches. I solved the issue by creating a new unique verb-route match. Below is my complete code for querying using a String. Aarkerio's other points still hold; I need to alter my code to avoid SQL injection as well as create a more robust search.
const getShowByTitle = (request, response) => {
const title = request.params.title
pool.query('SELECT * FROM show WHERE title = $1', [title], (error, results) => {
if (error) {
throw error
}
response.status(200).json(results.rows)
})
}

[Op.like]: example from Sequelize documentation throws SQL error

I have a Node/Express/Sequelize project.
Using the following example from the documentation, it fails and throws a SQL error on MySQL
Image.findAll({
where: {
image_title: {
[Op.like]: { [Op.any]: ['cat', 'hat']}
}
}
})
The above query generates the following SQL in Node/Express:
`Executing (default): SELECT `id`, `story_title`, `image_title`,
`original_filename`, `created_at` AS `createdAt`, `updated_at`
AS `updatedAt` FROM `image`
AS `image`
WHERE `image`.`image_title` LIKE ANY ('cat', 'hat');`
I expected to get a list of images where the image_title contains either 'cat' or 'hat'
Instead, I get a console error in Chrome that reads:
"You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax
to use near '('cat', 'hat')' at line 1"
And no images.
What I'm trying to do is pass an array of strings into a query and return all images where the image_title contains any of the strings in the array.
This example from the documentation seems to be exactly what I'm looking for, but I can't get it to work with even static strings using the documented syntax.
Is there a bug in this, am I misunderstanding how this works, or is there another way to accomplish this?
Possible workaround for now might be to use RegEx
let words = ['cat','hat'];
Image.findAll({
where: {
image_title: {
[Op.regexp]: `*(${words.join('|')})*`
}
}
})

How to create a parameterized insert using select query that includes some dynamic values for postgresql?

I am using the nodejs pg package. I have created some simple parameterized queries using the following format:
var client = new Client({user: 'brianc', database: 'test'});
client.on('drain', client.end.bind(client)); //disconnect client when all queries are finished
client.connect();
var query = client.query({
text: 'SELECT name FROM users WHERE email = $1',
values: ['brianc#example.com']
}, function(err, result) {
console.log(result.rows[0].name) // output: brianc
});
But now I have some more complex queries to write where I am creating a copy of a record with a new name and description like the following:
var sNewName = 'new name', sNewDescription = 'new description';
INSERT INTO testtable (
name,
description,
col3name,
col4name,
col5name,
) (
SELECT
sNewName,
sNewDescription,
col3name,
col4name,
col5name
FROM testtable
WHERE
id = 24
) RETURNING *;
On the pg wiki they say the following regarding Parameterized Queries:
A parameterized query allows you "pass arguments" to a query, providing a barrier to SQL injection attacks.
Parameters may not be DDL:
select name from emp where emp_id=$1 – legal
select $1 from emp where emp_id=$2 – illegal – column cannot be parameter
select name from $1 where emp_id=$2 – illegal – table cannot be parameter
select name from $1.emp where emp_id=$2 – illegal – schema cannot be parameter
How then, is it possible to do the above query for copying a record, as a parameterized query?
I am using postgresql 9.5.3 and pg 6.1.2.
Thank your for your time.

Using an array in where clause with node-mysql

I want to do a query that would look like this :
"Select * FROM ... WHERE name in ?" which would be equal to
"Select * FROM ... WHERE name in 'joe','william', ..."
Would there be a way to do something like that?
Model.query(query, array, function(err, result) {...});
I tried the following :
string = array.join("','")
Model.query(query, string, function(err, result) {...});
But then here is the result I have (the backslashes appear due to the single quotes):
Select * FROM ... WHERE name in \'joe\',\'william\',..."
Simple queries
As #Raphael mentioned, for simple queries you can use Model.find(), relevant docs section.
Queries with join
For queries involving joins, you can use find.populate(), docs for populate. Example:
Model.find().where({
attr : [your array]
}).populate('association').exec(your callback);
Very complicated queries
For more complicated queries where not even populate is enough you can indeed use .query() (documentation) but I think you may have gotten the syntax wrong. The second argument is an array. Example:
var title = "The King's Speech";
Movie.query('SELECT * FROM movie WHERE title = $1', [title], function(err, results) {})
If you are using Waterline (it should be the case if your are creating a sails app) just do:
Model.find().where({
attr : [your array]
}).exec(your callback);

Resources