Does Eclipselink support queries containing regular expression? - jpa

I've seen that DBMS like MySQL supports query containing regular expressions. Does Eclipselink support this?
I have to retrieve entities having some String attribute matching some regular expression as
SELECT X FROM Person X WHERE X.name <some keyword> (A-Z)*

MySQL uses REGEX or RLIKE for regular expression queries. JPQL does not support these operators, so you can use a native SQL query.
In EclipseLink you could define your own ExpressionOperator for these, and use it in an Expression query, but not currently with JPQL. JPQL does support calling database functions using FUNC, but these have different syntax than functions. You could extend the MySQLPlatform to make #like us REGEX or RLIKE.
Please log a bug for this on EclipseLink. Most databases now support regex, so this support should be available in JPQL.

Related

Is typeorm querybuilder select, orderBy, groupBy are SQL injection safe?

If TypeORM query builder select, orderBy, and groupBy are not SQL injection safe, How to convert them into SQL injection safe?
qb.orderBy(
`incident.${query.sortColum}`,
query.sortOrder === 'desc' ? DESCENDING : ASCENDING,
);
qb.select([
`incident.${query.type}`,
`COUNT('') As "count"`,
`"incident"."locationGroupIds"[${level}] as groupId`,
]);
qb.addGroupBy(`incident.${query.type}`);
These elements cannot be bound into JDBC which is why TypeORM doesn't support them as parameterized queries.
There are two options to do this safely - ideally you should use both:
Validate the columns in these via positive / whitelist validation. Each column name should be checked for existence in the associated tables.
You should enquote the column name - adding single quotes around the columns. If you do this, you need to be careful to validate there are no quotes in the name, and error out or escape any quotes. You also need to be aware that adding quotes will make the name case sensitive.

How do SQL dialects actually work internally in frameworks like hibernate and JOOQ

As we have seen that after you get a data source. We need to configure SQL dialects based on the database we use. After we select a particular dialect, How would that be used to make SQL queries specific to DB. Do frameworks like hibernate and JOOQ construct SQL queries in string based on the selected dialect ? If so which would be the most optimal way to support this in a framework of our own ?
Do frameworks like hibernate and JOOQ construct SQL queries in string based on the selected dialect
Yes. In jOOQ, there's an internal StringBuilder that collects SQL fragments from your expression tree, which are generated for your target SQL dialect specifically. You can see how that works in action on this website: https://www.jooq.org/translate. Try translating for example this input: SELECT * FROM t LIMIT 1 (which could correspond to your jOOQ API usage ctx.selectFrom(T).limit(1). It translates to:
-- Oracle 12c and more
SELECT * FROM t FETCH NEXT 1 ROWS ONLY
-- Oracle 11g and less
SELECT *
FROM (
SELECT x.*, rownum rn
FROM (SELECT * FROM t) x
WHERE rownum <= 1
)
WHERE rn > 0
If so which would be the most optimal way to support this in a framework of our own ?
You need:
An expression tree representation of your SQL query.
Optionally, you can parse a string to build this expression tree, like jOOQ's parser if you want to support actual SQL, or you can have your own language abstraction like Hibernate did with HQL / JPQL
Traverse that expression tree using something like a visitor to collect the SQL strings and bind variables.
But!
Do not build your own when you have off the shelf products like jOOQ or to some lesser extent Hibernate that can do the same. Building such a generic SQL abstraction is really difficult, and unless you want to actually sell such a product (you probably don't given your question), investing this time into building this product is not worth it at all.
The above LIMIT emulation is one of the more simple examples from jOOQ. Here's a lot more to help you decide against rolling your own, and that answer is still just scratching the surface of what jOOQ does behind the scenes.

How to convert Lambda Expression to SQL Server Query syntax?

Here's the lambda expression, I want to convert this to SQL Server query syntax.
{x => ((True AndAlso x.Name.ToLower().Contains("_")) AndAlso Not(x.IsDeleted))}
Note : The lambda expression is equivalent to Where Clause of Sql server.
I want to convert it to sql syntax and then pass it to sql server stored procedure.
Is there any way I can achieve this?
Generally, you can use the ToString method on the IQueryable object returned by the LINQ statement to find the exact query that would be executed on the database. But, in this case, I would guess something like this might be generated for the WHERE:
WHERE CONTAINS(Name, '_') AND NOT IsDeleted
But, you haven't provided any detail that would allow me to verify that.
If you don't have full-text on, then the following might be more applicable:
WHERE Name like '%_%' AND NOT IsDeleted

How to use "DISTINCT ON (field)" in Doctrine 2?

I know how to use "DISTINCT" in Doctrine 2, but I really need to use "DISTINCT ON (field)" and I don't know how to do this with the QueryBuilder.
My SQL query looks like:
SELECT DISTINCT ON (currency) currency, amount FROM payments ORDER BY currency
And this query works perfect, but I can't use it with the QueryBuilder. Maybe I could write this query on some other way?
I would suggest that the SELECT DISTINCT ON (..) construct that PostgreSQL supports is outside the Object Relational Model (ORM) that is central to Doctrine. Or, perhaps put another way, because SELECT DISTINCT ON (..) is rare in SQL implementations Doctrine haven't coded for it.
Regardless of the actual logic for it not working, I would suggest you try Doctrine's "Native SQL". You need to map the results of your query to the ORM.
With NativeQuery you can execute native SELECT SQL statements and map
the results to Doctrine entities or any other result format supported
by Doctrine.
In order to make this mapping possible, you need to describe to
Doctrine what columns in the result map to which entity property. This
description is represented by a ResultSetMapping object.
With this feature you can map arbitrary SQL code to objects, such as
highly vendor-optimized SQL or stored-procedures.
SELECT DISTINCT ON (..) falls into vendor-optimized SQL I think, so using NativeQuery should allow you to access it.
Doctrine QueryBuilder has some limitations. Even if I didn't check if it's was possible with query builder, I do not hesitate to use DQL when I do not know how to write the query with query builder.
Check theses examples at
http://doctrine-orm.readthedocs.org/en/latest/reference/dql-doctrine-query-language.html#dql-select-examples
Hope this help.
INDEX BY can be used in DQL, allowing first result rows indexed by the defined string/int field to be overwritten by following ones with the same index:
SELECT
p.currency,
p.amount
FROM Namespace\To\Payments p INDEX BY p.currency
ORDER BY p.currency ASC
DQL - EBNF - INDEX BY

Taking the difference of temporal fields in JPQL

I have an entity Event which has fields startDate and endDate. I'd like to select only those events that have at most x days left to the their endDate. I want to do this in JPQL and with only one query. How can I do this?
JPA does not provide any standard date/time functions. You can use a native SQL query using SQL EXTRACT,
Or, if you are using EclipseLink you can use the FUNC JPQL operator to call a database specific function, or use EXTRACT if using EclipseLink 2.4,
See,
http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/JPQL#Functions