KnexJS Postgres: Adds extra double quotation marks to raw like query - postgresql

Consider below code:
const items = await Item.query().where(
"type",
"like",
raw("'??'", [`%${term}%`])
);
I'm not getting any errors with the code above, but the database returns an empty result set. The created SQL query is below:
select "items".* from "items" where type LIKE '%"mobiles"%'
Please look at the like mobiles in the above SQL '%"mobiles"%' "" are treated as part of the value and returns an empty result set.
How can avoid "" in the query above?
Edit: Please note that I'm using ObjectionJS as well which uses Knex.

?? are supposed to be used for a column name.
I've 2 suggestions for you,
use the query without raw at all,
const items = await Item.query().where('type', 'like', `%${term}%`);
use single ?,
const items = await Item.query().where('type', 'like', raw("'?'", [`%${term}%`]));

Related

"Column reference is ambiguous" GraphQL, PostgreSQL & TypeORM

If I run below query in pgAdmin it works perfectly fine:
UPDATE customer SET token = array_append(token, '123132');
Now, if I run this with TypeOrm I get "column reference "token" is ambiguous"
const result = await getConnection()
.createQueryBuilder()
.insert()
.into(Customer)
.values([
{
orgId: records.orgId,
token: [records.token],
},
])
.onConflict(
`("orgId") DO UPDATE SET token = array_append(token, '123132')`
)
.returning("*")
.execute();
To my eyes, the query is exactly the same. What am I missing?
Thank you in advance!
The statement you are constructing is INSERT ... ON CONFLICT, which is quite different from UPDATE. The ambiguity arises because it is not clear if you are speaking about the original column value or the new value supolied by the INSERT.
Qualify the column appropriately:
SET token = array_append(customer.token, '123132')
The new value from the INSERT would be qualified with excluded.

How to insert jsonb[] data into column using pg-promise

Given a table with a column of type jsonb[], how do I insert a json array into the column?
Using the provided formatters :array, :json won't work in this instance - unless I am missing the correct combination or something.
const links = [
{
title: 'IMDB',
url: 'https://www.imdb.com/title/tt0076759'
},
{
title: 'Rotten Tomatoes',
url: 'https://www.rottentomatoes.com/m/star_wars'
}
];
const result = await db.none(`INSERT INTO tests (links) VALUES ($1:json)`, [links]);
You do not need the library's :json filter in this case, as you need an array of JSON objects, and not a JSON with an array of JSON objects.
The former is formatted correctly by default, which then only needs ::json[] type casting:
await db.none(`INSERT INTO tests(links) VALUES($1::json[])`, [links]);
Other Notes
Use pg-monitor or event query to output queries being executed, for easier diagnostics.
Method none can only resolve with null, no point storing the result in a variable.
Library pg-promise does not have any :array filter, see supported filters.

Sails ORM: How to pass value with array in valuesToEscape parameter

I've rawQuery which requires comma separated string but according to the documentation here, the second argument should be an array:
An array of dynamic, untrusted strings to SQL-escape and inject within the SQL string using the appropriate template syntax for this model's database. (If you have no dynamic values to inject, then just use an empty array here.)
var rawQuery = 'SELECT * FROM "user" WHERE "user"."email" IN ($1)';
User.query(rawQuery, ['a#a.com', 'b#b.com'], function (err, rawResult) {
if (err) { return res.serverError(err); }
return res.ok(rawResult.rows);
});
How can I make this query work without passing a variable through an array? I can directly add the variable like this
var rawQuery = 'SELECT * FROM "user" WHERE "user"."email" IN (' + foo +')';
But it will be prone to SQL injection attack.
To run the query directly without using the parameter injection mode, you need to remove SQL command especial characters, otherwise you will be prune to injection attacks, as you said.
There are packages that do that for you:
the most popular are npm: sql-escape and npm sqlstring
They will add escape characters to any especial character into your string:
var escape = require('sql-escape');
var result = escape('my sweet "string"');
//result: 'my sweet \\"string\\"'

How to insert a vertex with link type property with the orientjs query builder?

I am trying to insert a vertex with orientjs(previously oriento) query builder. My class has a link type property pointing to another class.
I know I can get it to work with a raw query string but I would love to use the query builder.
Here is what I've tried so far :
db.insert()
.into('VertexClassName')
.set({"prop":"value", "linkProperty":"33:1289287"})
db.insert()
.into('VertexClassName')
.set({"prop":"value", "linkProperty":"#33:1289287"})
I get the following error :
Error on saving record in cluster #13
Am I setting properties in the right way ?
Could the error be related to somtehing else ?
I have sucessfully ran an insert query in the cluster #13 with a raw query string in the studio...
According to the official documentation it seems that the problem might be at the end of your statement
db.insert().into('VertexClassName')
.set({"prop":"value", "linkProperty":"33:1289287"}).one()
.then(function (data) {
// callback
});
Check if your code works adding one() to the pipe line
EDITED: I found this method in orientjs.
db.create('VERTEX', 'V')
.set({
key: 'value',
foo: 'bar'
})
.one()
.then(function (vertex) {
console.log('created vertex', vertex);
});
When using Tinkerpop API they recommend using createVertex instead of insert, because createVertex is intended for graphs and insert for Documents... Could you try with the create() method instead?
I am using SQL and it worked.
sql = "INSERT INTO Station set linked = (select from LinkedClass where LinkedProb = 'value'), prop = 'value'"
OrientVertex vertex = new OrientVertex();
vertex = graph.command(new OCommandSQL(sql)).execute();
I don't think that's possible unless you've added a proper field with the right type 'Link' in your schema. (which I rarely do).
Now instead of having the right 'link' type inserted you can do the opposite, store is as a String, and leverage the query functions to use it correctly:
db.insert().into('table').set({prop: '#15:14'}).one();
And it will be converted as String (which is a bit sad) but then you can use that in your queries:
SELECT eval(prop) FROM table;
And it will be 'eval'-ed to a Node RecordID that you can directly use and call functions like expand() on.
For example:
SELECT name FROM (SELECT expand(eval(prop)) FROM table);
Will eval the node stored in the insert(), grab the node, expand it and collect its name property.

MongoDB C# offic. List<BsonObject> query issue and always olds values?

I have not clearly issue during query using two criterials like Id and Other. I use a Repository storing some data like id,iso,value. I have created an index("_id","Iso") to performs queries but queries are only returning my cursor if i use only one criterial like _id, but is returning nothing if a use two (_id, Iso) (commented code).
Are the index affecting the response or the query method are failing?
use :v1.6.5 and C# official.
Sample.
//Getting Data
public List<BsonObject> Get_object(string ID, string Iso)
{
using (var helper = BsonHelper.Create())
{
//helper.Db.Repository.EnsureIndex("_Id","Iso");
var query = Query.EQ("_Id", ID);
//if (!String.IsNullOrEmpty(Iso))
// query = Query.And(query, Query.EQ("Iso", Iso));
var cursor = helper.Db.Repository.FindAs<BsonObject>(query);
return cursor.ToList();
}
}
Data:
{
"_id": "2345019",
"Iso": "UK",
"Data": "Some data"
}
After that I have Updated my data using Update.Set() methods. I can see the changed data using MongoView. The new data are correct but the query is always returning the sames olds values. To see these values i use a page that can eventually cached, but if add a timestamp at end are not changing anything, page is always returning the same olds data. Your comments are welcome, thanks.
I do not recall offhand how the C# driver creates indexes, but the shell command for creating an index is like this:
db.things.ensureIndex({j:1});
Notice the '1' which is like saying 'true'.
In your code, you have:
helper.Db.Repository.EnsureIndex("_Id","Iso");
Perhaps it should be:
helper.Db.Repository.EnsureIndex("_Id", 1);
helper.Db.Repository.EnsureIndex("Iso", 1);
It could also be related to the fact that you are creating indexes on "_Id" and the actual id field is called "_id" ... MongoDB is case sensitive.
Have a quick look through the index documentation: http://www.mongodb.org/display/DOCS/Indexes