Merge pull request #32 from wimvelzeboer/feature/AddContainsAndLikeToCriteria
Add LIKE and Contains condition to Criteria
This commit is contained in:
@@ -33,8 +33,15 @@ public with sharing class fflib_Comparator
|
||||
|
||||
public static Boolean compareTo(Object object1, fflib_Operator operator, Object object2)
|
||||
{
|
||||
Integer result = compare(object1, object2);
|
||||
if (operator == fflib_Operator.LIKEx)
|
||||
{
|
||||
String value1 = String.valueOf(object1);
|
||||
String value2 = String.valueOf(object2);
|
||||
if (value1 == null || value2 == null) return false;
|
||||
return value1.contains(value2);
|
||||
}
|
||||
|
||||
Integer result = compare(object1, object2);
|
||||
if (operator == fflib_Operator.EQUALS && result == 0)
|
||||
return true;
|
||||
else if (operator == fflib_Operator.NOT_EQUALS && result != 0)
|
||||
|
||||
@@ -323,6 +323,32 @@ public virtual with sharing class fflib_Criteria
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a criteria checking if a fields value contains the given value
|
||||
*
|
||||
* @param field The sObjectField to evaluate
|
||||
* @param value The value to be compared to the fields value
|
||||
*
|
||||
* @return An instance of itself to enable method chaining
|
||||
*
|
||||
* @example
|
||||
* new fflib_Criteria()
|
||||
* .equalTo(Account.Name, 'Example')
|
||||
*
|
||||
* Evaluates:
|
||||
* SOQL
|
||||
* Name LIKE '%Example%'
|
||||
*
|
||||
* Condition
|
||||
* 'My Condition Example'.contains('Example')
|
||||
*/
|
||||
public virtual fflib_Criteria contains(Schema.SObjectField field, Object value)
|
||||
{
|
||||
evaluators.add(new FieldEvaluator(field, fflib_Operator.LIKEx, value));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add an equal to criteria comparing a fields value to a given value
|
||||
*
|
||||
@@ -875,7 +901,9 @@ public virtual with sharing class fflib_Criteria
|
||||
}
|
||||
|
||||
throw new CriteriaException(
|
||||
'invalid value; value must a primitive type (String|Id|Boolean|Integer|Long|Double|Decimal|Date|Datetime)'
|
||||
String.format(
|
||||
'invalid value \'{0}\'; value must a primitive type (String|Id|Boolean|Integer|Long|Double|Decimal|Date|Datetime)',
|
||||
new List<String> {String.valueOf(value)})
|
||||
);
|
||||
}
|
||||
|
||||
@@ -906,6 +934,52 @@ public virtual with sharing class fflib_Criteria
|
||||
String toSOQL();
|
||||
}
|
||||
|
||||
private abstract class ToSOQL
|
||||
{
|
||||
protected String toSOQL(Schema.SObjectField sObjectField, fflib_Operator operator, Object value)
|
||||
{
|
||||
return toSOQL(sObjectField, operator, toLiteral(value));
|
||||
}
|
||||
|
||||
protected String toSOQL(String fieldName, fflib_Operator operator, Object value)
|
||||
{
|
||||
return toSOQL(fieldName, operator, toLiteral(value));
|
||||
}
|
||||
|
||||
protected String toSOQL(Schema.SObjectField sObjectField, fflib_Operator operator, String value)
|
||||
{
|
||||
return toSOQL(sObjectField.getDescribe().getName(), operator, value);
|
||||
}
|
||||
|
||||
protected String toSOQL(String fieldName, fflib_Operator operator, String value)
|
||||
{
|
||||
if (operator == fflib_Operator.LIKEx)
|
||||
return toLikeSOQL(fieldName, operator, value);
|
||||
else
|
||||
return toNonLikeSOQL(fieldName, operator, value);
|
||||
}
|
||||
|
||||
private String toLikeSOQL(String fieldName, fflib_Operator operator, String value)
|
||||
{
|
||||
if (value.startsWith('\'')) value = value.right(value.length() - 1);
|
||||
if (value.endsWith('\'')) value = value.left(value.length() - 1);
|
||||
return toNonLikeSOQL(fieldName, operator, '\'%' + value + '%\'');
|
||||
}
|
||||
|
||||
protected String toNonLikeSOQL(String fieldName, fflib_Operator operator, String value)
|
||||
{
|
||||
return String.join(
|
||||
new List<String>
|
||||
{
|
||||
fieldName,
|
||||
operatorToString(operator),
|
||||
value
|
||||
},
|
||||
''
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic criteria handler for comparing against sets
|
||||
*/
|
||||
@@ -949,7 +1023,7 @@ public virtual with sharing class fflib_Criteria
|
||||
/**
|
||||
* Generic field Evaluator
|
||||
*/
|
||||
private class FieldEvaluator implements Evaluator
|
||||
private class FieldEvaluator extends ToSOQL implements Evaluator
|
||||
{
|
||||
private Schema.SObjectField sObjectField;
|
||||
private Object value;
|
||||
@@ -974,19 +1048,11 @@ public virtual with sharing class fflib_Criteria
|
||||
|
||||
public String toSOQL()
|
||||
{
|
||||
return String.join(
|
||||
new List<String>
|
||||
{
|
||||
this.sObjectField.getDescribe().getName(),
|
||||
operatorToString(this.operator),
|
||||
toLiteral(this.value)
|
||||
},
|
||||
''
|
||||
);
|
||||
return toSOQL(this.sObjectField, this.operator, this.value);
|
||||
}
|
||||
}
|
||||
|
||||
private abstract class AbstractRelatedFieldEvaluator implements Evaluator
|
||||
private abstract class AbstractRelatedFieldEvaluator extends ToSOQL implements Evaluator
|
||||
{
|
||||
protected String fieldName;
|
||||
protected fflib_Operator operator;
|
||||
@@ -1035,15 +1101,7 @@ public virtual with sharing class fflib_Criteria
|
||||
|
||||
public String toSOQL()
|
||||
{
|
||||
return String.join(
|
||||
new List<String>
|
||||
{
|
||||
this.fieldName,
|
||||
operatorToString(this.operator),
|
||||
toLiteral(this.value)
|
||||
},
|
||||
''
|
||||
);
|
||||
return toSOQL(this.fieldName, operator, this.value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -79,6 +79,30 @@ private with sharing class fflib_CriteriaTest
|
||||
);
|
||||
}
|
||||
|
||||
@IsTest
|
||||
static void itShouldEvaluateAnContainsCondition()
|
||||
{
|
||||
fflib_Criteria criteria = new fflib_Criteria()
|
||||
.contains(Account.Name, A_STRING);
|
||||
System.assert(criteria.evaluate(new Account(Name = SAME_STRING)));
|
||||
System.assert(criteria.evaluate(new Account(Name = 'prefix ' + SAME_STRING)));
|
||||
System.assert(criteria.evaluate(new Account(Name = SAME_STRING + ' suffix')));
|
||||
System.assert(criteria.evaluate(new Account(Name = 'prefix ' + SAME_STRING + ' suffix')));
|
||||
System.assertEquals('Name LIKE \'%' + A_STRING + '%\'', criteria.toSOQL());
|
||||
}
|
||||
|
||||
@IsTest
|
||||
static void itShouldEvaluateAnContainsCondition_nullField()
|
||||
{
|
||||
fflib_Criteria criteria = new fflib_Criteria()
|
||||
.contains(Account.Name, null);
|
||||
System.assert(false == criteria.evaluate(new Account(Name = SAME_STRING)));
|
||||
System.assert(false == criteria.evaluate(new Account(Name = 'prefix ' + SAME_STRING)));
|
||||
System.assert(false == criteria.evaluate(new Account(Name = SAME_STRING + ' suffix')));
|
||||
System.assert(false == criteria.evaluate(new Account(Name = 'prefix ' + SAME_STRING + ' suffix')));
|
||||
System.assertEquals('Name LIKE \'%null%\'', criteria.toSOQL());
|
||||
}
|
||||
|
||||
@IsTest
|
||||
static void itShouldEvaluateAnEqualsToCondition()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user