Fix for #192 - Backslash literal in LIKE expression - Postgres (and H2, MySql) behaviour

This commit is contained in:
Rob Bygrave
2014-10-08 21:42:39 +13:00
parent 6ed1f25e22
commit 5d09ca16d6
14 changed files with 152 additions and 23 deletions
@@ -6,6 +6,7 @@ import javax.sql.DataSource;
import com.avaje.ebean.BackgroundExecutor;
import com.avaje.ebean.Query;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -14,40 +15,61 @@ import org.slf4j.LoggerFactory;
*/
public class DatabasePlatform {
/** The Constant logger. */
private static final Logger logger = LoggerFactory.getLogger(DatabasePlatform.class);
/** The open quote used by quoted identifiers. */
/**
* The open quote used by quoted identifiers.
*/
protected String openQuote = "\"";
/** The close quote used by quoted identifiers. */
/**
* The close quote used by quoted identifiers.
*/
protected String closeQuote = "\"";
/** For limit/offset, row_number etc limiting of SQL queries. */
/**
* For limit/offset, row_number etc limiting of SQL queries.
*/
protected SqlLimiter sqlLimiter = new LimitOffsetSqlLimiter();
/** Mapping of JDBC to Database types. */
/**
* Mapping of JDBC to Database types.
*/
protected DbTypeMap dbTypeMap = new DbTypeMap();
/** DB specific DDL syntax. */
/**
* DB specific DDL syntax.
*/
protected DbDdlSyntax dbDdlSyntax = new DbDdlSyntax();
/** Defines DB identity/sequence features. */
/**
* Defines DB identity/sequence features.
*/
protected DbIdentity dbIdentity = new DbIdentity();
/** The JDBC type to map booleans to (by default). */
/**
* The JDBC type to map booleans to (by default).
*/
protected int booleanDbType = Types.BOOLEAN;
/** The JDBC type to map Blob to. */
/**
* The JDBC type to map Blob to.
*/
protected int blobDbType = Types.BLOB;
/** The JDBC type to map Clob to. */
/**
* The JDBC type to map Clob to.
*/
protected int clobDbType = Types.CLOB;
/** For Oracle treat empty strings as null. */
/**
* For Oracle treat empty strings as null.
*/
protected boolean treatEmptyStringsAsNull;
/** The name. */
/**
* The database platform name.
*/
protected String name = "generic";
/**
@@ -57,6 +79,11 @@ public class DatabasePlatform {
*/
private static final char BACK_TICK = '`';
/**
* The like clause. Can be overridden to disable default escape character.
*/
protected String likeClause = "like ?";
protected DbEncrypt dbEncrypt;
protected boolean idInExpandedForm;
@@ -299,4 +326,13 @@ public class DatabasePlatform {
return sql;
}
/**
* Returns the like clause used by this database platform.
* <p>
* This may include an escape clause to disable a default escape character.
*/
public String getLikeClause() {
return likeClause;
}
}
@@ -14,6 +14,7 @@ public class H2Platform extends DatabasePlatform {
super();
this.name = "h2";
this.dbEncrypt = new H2DbEncrypt();
this.likeClause = "like ? escape''";
// only support getGeneratedKeys with non-batch JDBC
// so generally use SEQUENCE instead of IDENTITY for H2
@@ -20,6 +20,7 @@ public class MySqlPlatform extends DatabasePlatform {
public MySqlPlatform() {
super();
this.name = "mysql";
this.likeClause = "like ? escape''";
this.selectCountWithAlias = true;
this.dbEncrypt = new MySqlDbEncrypt();
@@ -23,6 +23,7 @@ public class PostgresPlatform extends DatabasePlatform {
public PostgresPlatform() {
super();
this.name = "postgres";
this.likeClause = "like ? escape''";
this.dbDdlSyntax = new PostgresDdlSyntax();
@@ -44,9 +44,14 @@ public interface SpiExpressionRequest {
* Return the ordered list of bind values for all expressions in this request.
*/
public ArrayList<Object> getBindValues();
/**
* Increments the parameter index and returns that value.
*/
public int nextParameter();
/**
* Increments the parameter index and returns that value.
*/
public int nextParameter();
/**
* Append a DB Like clause.
*/
public void appendLike();
}
@@ -71,6 +71,15 @@ public final class OrmQueryRequest<T> extends BeanRequest implements BeanQueryRe
this.readOnly = query.isReadOnly();
}
/**
* Return the database platform like clause.
*/
@Override
public String getDBLikeClause() {
return ebeanServer.getDatabasePlatform().getLikeClause();
}
public void executeSecondaryQueries(int defaultQueryBatch) {
loadContext.executeSecondaryQueries(this, defaultQueryBatch);
}
@@ -95,4 +95,9 @@ public interface SpiOrmQueryRequest<T> {
*/
public BeanCollection<T> getFromQueryCache();
/**
* Return the Database platform like clause.
*/
public String getDBLikeClause();
}
@@ -71,6 +71,9 @@ public abstract class DeployParser {
sb.append(deployWord);
if (pos < sourceLength) {
sb.append(wordTerminator);
if (wordTerminator == SINGLE_QUOTE) {
readLiteral();
}
}
}
@@ -53,7 +53,8 @@ class LikeExpression extends AbstractExpression {
if (type.equals(LikeType.EQUAL_TO)) {
request.append(" = ? ");
} else {
request.append(" like ? ");
// append db platform like clause
request.appendLike();
}
}
@@ -39,6 +39,16 @@ public class DefaultExpressionRequest implements SpiExpressionRequest {
return s == null ? logicalProp : s;
}
/**
* Append the database platform like clause.
*/
@Override
public void appendLike() {
sb.append(" ");
sb.append(queryRequest.getDBLikeClause());
sb.append(" ");
}
/**
* Increments the parameter index and returns that value.
*/