How to use Prepared statements with npm sqlite library on node js - javascript

I am using this library for connecting my node js application to an sqlite database. I saw its documentation for how to use prepared statements here but it is very brief and I cannot understand how to use it for my use case.
Lets say I have an sql string like this:
const sql = "INSERT INTO tbl(name) VALUES (?)"
So as per the documentation guess I should first create a statement and then use bind to populate it:
const stmt = await db.prepare(sql)
stmt.bind({? : "John"})
Is this the right way to do this? Also once I have created the Prepared statement how am I supposed to run this. All the examples mentioned in the docs are select statements, but if it is an insert statement I suppose stmt.get() or stmt.all() method are not correct as there is no result set to return here. How then am I supposed to do this?

I don't know the sqlite library too well, but the following example from the documentation performs a parameterised INSERT statement:
const result = await db.run('INSERT INTO tbl(col) VALUES (:col)', {
':col': 'something'
})
I think you're focusing on the phrase 'prepared statement' a little too much.
Instead of looking only for this exact phrase, look for any use of parameters whose values are passed separately to the main SQL string. The example above fits this: there is a parameter :col which appears in the SQL string and the value for it is provided in an object passed to db.run alongside the SQL string.

Related

TypeORM, Backticks vs. Colon in Query

I have been writing queries using backticks
const firstUser = await connection
.getRepository(User)
.createQueryBuilder("user")
.where(`user.id = '${id}'`)
.getOne();
but in typeorm documentations, examples are written with colons.
const firstUser = await connection
.getRepository(User)
.createQueryBuilder("user")
.where("user.id = :id", { id: 1 })
.getOne();
So I'm wondering if there is any difference between using backticks and colons.
Any insights would be greatly appreciated.
thanks.
DO NOT USE STRING INTERPOLATION TO INSERT VALUES INTO SQL STATEMENTS
Sorry to yell, but this is important.
Read this: https://en.wikipedia.org/wiki/SQL_injection
And then this: https://xkcd.com/327/
When you do this:
.where(`user.id = '${id}'`)
Then the string is created first and then passed to the where() function. Which means if id is 123, then it's the same as:
.where(`user.id = '123'`)
Which seems fine. But what if id is 123' OR 1=1--'
You now get this:
.where(`user.id = '123' OR 1=1--'`) // Now returns ALL users!
This is called SQL injection, it's a big security issue. It's very very bad. Attackers could alter your queries and get access to data they shouldn't have access to, or change records to give themselves admin access, or all kinds of other really bad things. It's pretty close to giving everyone full read/write access to your database.
Which brings us to this:
.where("user.id = :id", { id: 1 })
To combat this, you ask TypeORM to put values in for you, this correctly escapes any value an attacker may add so the input has no executable instructions.
If id is something nefarious, then it will get turned into something like:
.where(`user.id = '123\' OR 1=1--'`) // note the backslash
// (actual query may vary based on different databases)
Here TypeORM ensures escape that the id is processed as a value, by escaping the close quote that the attacker inserted. This makes it safe to get user provided values and use them in your queries.
In conclusion, NEVER put user provided values interpolated directly into queries (really should be all values, just to be safe), and always use query parameters to ensure that values are properly escaled.

Not able to use query results inside Javascript UDF in Snowflake

Thankyou for your time.
I am working on a problem in Snowflake database. I am basically trying to create a Javascript UDF like following -
CREATE OR REPLACE FUNCTION getACity()
RETURNS STRING
LANGUAGE JAVASCRIPT
AS
'function getCity() {
var str;
$$ str = select * from CITY where name="Laflin" //This is the problem
$$
return str;
}';
As you can see I am trying to use data from another table in my function, but its not happening and I get following error -
JavaScript compilation error: Uncaught SyntaxError: Unexpected
identifier in getACity at ' str = select * from CITY where
name="Laflin"' position 21
I understand the syntax I am using to execute a query inside a javascript function is not correct, but I am not even sure if it is possible in Snowflake.
I have following questions -
Can I execute a query inside a javascript UDF and use the results in ongoing function ?
Can I call a Javascript UDF inside another Javascript UDF ? If this is possible it will work for me as well.
I have gone through Snowflake documentation but could not find any help specific to this case.
Thankyou again for your time. Much appreciated !
To answer your questions:
Snowflake JavaScript UDFs do not allow executing queries inside them in any form today.
you can not use JS UDFs in ther JS UDFs
You CAN use SQL UDFs for that, but that can only produce one column, e.g.
create or replace function getcityid()
returns string as '
select id from CITY where name='Laflin'
';
Or use VIEWs, e.g.
create or replace view cities as select * from CITY where name='Laflin'
If you explain exactly what you try to achieve, this should help.
Also, note that "Laflin" in SQL refers to a column named Laflin, not to a string with a value Laflin. Use 'Laflin' for that.
Snowflake JavaScript UDF do not support to run sql however you can use procedure to do that however procedure will only return one value/not the table function result.
For details about the Snowflake please refer the documentation
https://docs.snowflake.net/manuals/sql-reference/stored-procedures-overview.html#benefits-of-stored-procedures

JavaScript + MySQL: use fields as parameter in result

I'm quite new to JavaScript and I have the following issue:
I have a Node.JS server on which a webclient can connect and execute functions. One function is to look into a MySQL database and gather information.
The query is done right and I obtain the correct raw information as for example:
Here is my code:
So I correctly get the column names using the fields (fields[0].name = Count_0)variable and I am able to get the correct value using the result (result[0].Count_0 = Gray).
However, I am unable to merge the two lines in order to create the list of colors using something like this in a loop: result[0].fields[0].name = Gray
Is there an easier way to do this or not ?
Thanks,
Nicola.
In Javascript, you can use the [] operator to access a variably-named property in an object.
Instead of using result[0].fields[0].name, use
result[0][fields[0].name]
You won't get any runtime errors for accessing a property that doesn't exist, so you'll want to check whether that value is undefined before using it somewhere else.
It seems you want to get the color. If so, you can get the color by this
let color = result[0][fields[0].name];
The idea is use fields[0].name as key of result[0].
This is the breakdown of above single line.
let key = fields[0].name;
let color = result[0][key];

ES6 String templating litterals : dealing with array

I'm trying to use the ES6 String template to query my database
My SQL is like :
SELECT * FROM table WHERE id IN ();
The in must contains each items of an array, so, i tried something like this :
return connector.query`SELECT * FROM table WHERE AnalogHistory.TagName IN (${sensor})`.then(result => {return result.recordset});
This doesn't work. But if i try something like this :
return connector.query`SELECT * FROM table WHERE AnalogHistory.TagName IN (${sensor[0]},${sensor[1]}, ${sensor[2]}, ...)`.then(result => {return result.recordset});
Well this time, it work. So do you guys know what differ and on to do it by the first way (the cleaner) ?
We can't be absolutely sure without knowing how query handles the tag parameters, but the difference is that in the first case, you've provided query with the array as a single parameter; and in the second case, you've provided query with a series of individual parameters with commas in-between them.
Apparently it's happy with the second, and not with the first. Whether there's a third option that would be less laborious but also functional depends entirely on how query is designed to be called.
Re your comment saying it's the mssql npm package: I don't see anything in its documentation to suggest that it supports passing arrays into the query tag function as parameters. Which is really unfortunate.

How to handle indices in Neo4j server via javascript REST client?

I have data in a standalone Neo4j REST server, including an index of nodes. I want pure JavaScript client to connect to Neo4j and serve the formatted data to d3.js, a visualisation library built on Node.js.
JugglingDB is very popular, but the Neo4j implementation was done "wrong": https://github.com/1602/jugglingdb/issues/56
The next most popular option on github is: https://github.com/thingdom/node-neo4j
looking at the method definitions https://github.com/thingdom/node-neo4j/blob/develop/lib/GraphDatabase._coffee
I'm able to use "getNodeById: (id, _) ->"
> node1 = db.getNodeById(12, callback);
returns the output from the REST server, including node properties. Awesome.
I can't figure out how to use "getIndexedNodes: (index, property, value, _) ->"
> indexedNodes = db.getIndexedNodes:(index1, username, Homer, callback);
...
indexedNodes don't get defined. I've tried a few different combinations. No joy. How do I use this command?
Also, getIndexedNodes() requires a key-value pair. Is there any way to get all, or a subset of the items in the index without looping?
One of the authors/maintainers of node-neo4j here. =)
indexedNodes don't get defined. I've tried a few different combinations. No joy. How do I use this command?
Your example seems to have some syntax errors. Are index1, username and Homer variables defined elsewhere? Assuming not, i.e. assuming those are the actual index name, property name and value, they need to be quoted as string literals, e.g. 'index1', 'username' and 'Homer'. But you also have a colon right before the opening parenthesis that shouldn't be there. (That's what's causing the Node.js REPL to not understand your command.)
Then, note that indexedNodes should be undefined -- getIndexedNodes(), like most Node.js APIs, is asynchronous, so its return value is undefined. Hence the callback parameter.
You can see an example of how getIndexedNodes() is used in the sample node-neo4j-template app the README references:
https://github.com/aseemk/node-neo4j-template/blob/2012-03-01/models/user.js#L149-L160
Also, getIndexedNodes() requires a key-value pair. Is there any way to get all, or a subset of the items in the index without looping?
getIndexedNodes() does return all matching nodes, so there's no looping required. Getting a subset isn't supported by Neo4j's REST API directly, but you can achieve the result with Cypher.
E.g. to return the 6th-15th user (assuming they have a type property set to user) sorted alphabetically by username:
db.query([
'START node=node:index1(type="user")',
'RETURN node ORDER BY node.username',
'SKIP 5 LIMIT 10'
].join('\n'), callback);
Cypher is still rapidly evolving, though, so be sure to reference the documentation that matches the Neo4j version you're using.
As mentioned above, in general, take a look at the sample node-neo4j-template app. It covers a breadth of features that the library exposes and that a typical app would need.
Hope this helps. =)
Neo4j 2 lets you do indices VIA REST. Docs here
REST Indicies

Categories