mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
#570 - ENH: Add ability to configure eBean to use true "ilike" expression
This commit is contained in:
@@ -409,6 +409,11 @@ public class ServerConfig {
|
||||
*/
|
||||
private boolean expressionEqualsWithNullAsNoop;
|
||||
|
||||
/**
|
||||
* Set to true to use native ILIKE expression (if support by datasbase platform / like Postgres).
|
||||
*/
|
||||
private boolean expressionNativeIlike;
|
||||
|
||||
private String jodaLocalTimeMode;
|
||||
|
||||
/**
|
||||
@@ -2391,6 +2396,7 @@ public class ServerConfig {
|
||||
|
||||
changeLogIncludeInserts = p.getBoolean("changeLogIncludeInserts", changeLogIncludeInserts);
|
||||
expressionEqualsWithNullAsNoop = p.getBoolean("expressionEqualsWithNullAsNoop", expressionEqualsWithNullAsNoop);
|
||||
expressionNativeIlike = p.getBoolean("expressionNativeIlike", expressionNativeIlike);
|
||||
|
||||
dataTimeZone = p.get("dataTimeZone", dataTimeZone);
|
||||
asOfViewSuffix = p.get("asOfViewSuffix", asOfViewSuffix);
|
||||
@@ -2531,6 +2537,20 @@ public class ServerConfig {
|
||||
this.expressionEqualsWithNullAsNoop = expressionEqualsWithNullAsNoop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if native ILIKE expression should be used if supported by the database platform (e.g. Postgres).
|
||||
*/
|
||||
public boolean isExpressionNativeIlike() {
|
||||
return expressionNativeIlike;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to true to use native ILIKE expression if supported by the database platform (e.g. Postgres).
|
||||
*/
|
||||
public void setExpressionNativeIlike(boolean expressionNativeIlike) {
|
||||
this.expressionNativeIlike = expressionNativeIlike;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if L2 cache is disabled.
|
||||
*/
|
||||
|
||||
@@ -170,6 +170,8 @@ public class DatabasePlatform {
|
||||
*/
|
||||
protected int maxConstraintNameLength = 60;
|
||||
|
||||
protected boolean supportsNativeIlike;
|
||||
|
||||
/**
|
||||
* Instantiates a new database platform.
|
||||
*/
|
||||
@@ -191,6 +193,13 @@ public class DatabasePlatform {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if this database platform supports native ILIKE expression.
|
||||
*/
|
||||
public boolean isSupportsNativeIlike() {
|
||||
return supportsNativeIlike;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the maximum table name length.
|
||||
* <p>
|
||||
|
||||
@@ -20,6 +20,7 @@ public class PostgresPlatform extends DatabasePlatform {
|
||||
public PostgresPlatform() {
|
||||
super();
|
||||
this.name = "postgres";
|
||||
this.supportsNativeIlike = true;
|
||||
this.likeClause = "like ? escape''";
|
||||
this.selectCountWithAlias = true;
|
||||
this.blobDbType = Types.LONGVARBINARY;
|
||||
|
||||
@@ -126,8 +126,9 @@ public class InternalConfiguration {
|
||||
this.cacheManager = cacheManager;
|
||||
this.serverConfig = serverConfig;
|
||||
this.bootupClasses = bootupClasses;
|
||||
this.expressionFactory = new DefaultExpressionFactory(serverConfig.isExpressionEqualsWithNullAsNoop());
|
||||
|
||||
DatabasePlatform databasePlatform = serverConfig.getDatabasePlatform();
|
||||
this.expressionFactory = initExpressionFactory(serverConfig, databasePlatform);
|
||||
this.typeManager = new DefaultTypeManager(serverConfig, bootupClasses);
|
||||
|
||||
this.deployOrmXml = new DeployOrmXml();
|
||||
@@ -140,13 +141,20 @@ public class InternalConfiguration {
|
||||
Map<String, String> asOfTableMapping = beanDescriptorManager.deploy();
|
||||
Map<String, String> draftTableMap = beanDescriptorManager.getDraftTableMap();
|
||||
|
||||
DatabasePlatform databasePlatform = serverConfig.getDatabasePlatform();
|
||||
|
||||
this.dataTimeZone = initDataTimeZone();
|
||||
this.binder = getBinder(typeManager, databasePlatform, dataTimeZone);
|
||||
this.cQueryEngine = new CQueryEngine(databasePlatform, binder, asOfTableMapping, serverConfig.getAsOfSysPeriod(), draftTableMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return the ExpressionFactory based on configuration and database platform.
|
||||
*/
|
||||
private ExpressionFactory initExpressionFactory(ServerConfig serverConfig, DatabasePlatform databasePlatform) {
|
||||
|
||||
boolean nativeIlike = serverConfig.isExpressionNativeIlike() && databasePlatform.isSupportsNativeIlike();
|
||||
return new DefaultExpressionFactory(serverConfig.isExpressionEqualsWithNullAsNoop(), nativeIlike);
|
||||
}
|
||||
|
||||
private DocStoreFactory initDocStoreFactory(DocStoreFactory service) {
|
||||
return service == null ? new NoneDocStoreFactory() : service;
|
||||
}
|
||||
@@ -324,10 +332,6 @@ public class InternalConfiguration {
|
||||
return cQueryEngine;
|
||||
}
|
||||
|
||||
public ClusterManager getClusterManager() {
|
||||
return clusterManager;
|
||||
}
|
||||
|
||||
public SpiBackgroundExecutor getBackgroundExecutor() {
|
||||
return backgroundExecutor;
|
||||
}
|
||||
|
||||
+9
-2
@@ -28,10 +28,13 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
|
||||
|
||||
private static final Object[] EMPTY_ARRAY = new Object[] {};
|
||||
|
||||
private final boolean nativeIlike;
|
||||
|
||||
private final boolean equalsWithNullAsNoop;
|
||||
|
||||
public DefaultExpressionFactory(boolean equalsWithNullAsNoop) {
|
||||
public DefaultExpressionFactory(boolean equalsWithNullAsNoop, boolean nativeIlike) {
|
||||
this.equalsWithNullAsNoop = equalsWithNullAsNoop;
|
||||
this.nativeIlike = nativeIlike;
|
||||
}
|
||||
|
||||
public ExpressionFactory createExpressionFactory(){
|
||||
@@ -242,7 +245,11 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
|
||||
* a lower() function to make the expression case insensitive.
|
||||
*/
|
||||
public Expression ilike(String propertyName, String value) {
|
||||
return new LikeExpression(propertyName, value, true, LikeType.RAW);
|
||||
if (nativeIlike) {
|
||||
return new NativeILikeExpression(propertyName, value);
|
||||
} else {
|
||||
return new LikeExpression(propertyName, value, true, LikeType.RAW);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.avaje.ebeaninternal.server.expression;
|
||||
|
||||
import com.avaje.ebean.LikeType;
|
||||
import com.avaje.ebeaninternal.api.HashQueryPlanBuilder;
|
||||
import com.avaje.ebeaninternal.api.SpiExpression;
|
||||
import com.avaje.ebeaninternal.api.SpiExpressionRequest;
|
||||
import com.avaje.ebeaninternal.server.el.ElPropertyValue;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
class NativeILikeExpression extends AbstractExpression {
|
||||
|
||||
private final String val;
|
||||
|
||||
NativeILikeExpression(String propertyName, String value) {
|
||||
super(propertyName);
|
||||
this.val = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDocQuery(DocQueryContext context) throws IOException {
|
||||
context.writeLike(propName, val, LikeType.RAW, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBindValues(SpiExpressionRequest request) {
|
||||
|
||||
ElPropertyValue prop = getElProp(request);
|
||||
if (prop != null && prop.isDbEncrypted()) {
|
||||
// bind the key as well as the value
|
||||
String encryptKey = prop.getBeanProperty().getEncryptKey().getStringValue();
|
||||
request.addBindEncryptKey(encryptKey);
|
||||
}
|
||||
request.addBindValue(val);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSql(SpiExpressionRequest request) {
|
||||
|
||||
String pname = propName;
|
||||
ElPropertyValue prop = getElProp(request);
|
||||
if (prop != null && prop.isDbEncrypted()) {
|
||||
pname = prop.getBeanProperty().getDecryptProperty(propName);
|
||||
}
|
||||
|
||||
request.append(pname).append(" ilike ? ");
|
||||
}
|
||||
|
||||
/**
|
||||
* Based on caseInsensitive and the property name.
|
||||
*/
|
||||
@Override
|
||||
public void queryPlanHash(HashQueryPlanBuilder builder) {
|
||||
builder.add(NativeILikeExpression.class).add(propName);
|
||||
builder.bind(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int queryBindHash() {
|
||||
return val.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByPlan(SpiExpression other) {
|
||||
if (!(other instanceof NativeILikeExpression)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NativeILikeExpression that = (NativeILikeExpression) other;
|
||||
return this.propName.equals(that.propName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSameByBind(SpiExpression other) {
|
||||
NativeILikeExpression that = (NativeILikeExpression) other;
|
||||
return val.equals(that.val);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user