Apex Commons has some brilliant solutions, but one of the things which I feel is missing is an object-oriented approach to the SOQL query's "WHERE" conditions.
I'm presently working on my own framework, of which I freely admit the Selector code is heavily derived from Apex Commons.
I'd like to include an OOP way of constructing the "WHERE" clause.
To this end, I've created an interface:
public interface DAO_WHERE_ClauseIntf {
String toSOQL();
}
and a few implementations of the interface.
The problem is with this implementation:
public class DAO_WHERE_VariableComparisonClause implements DAO_WHERE_ClauseIntf {
DAO_WHERE_ComparisonOperatorEnumHelper comparisonHelper;
String fieldName;
String comparisonOperator;
Object value;
public DAO_WHERE_VariableComparisonClause (
SObjectField sObjectField,
DAO_WHERE_ComparisonOperatorEnum comparisonOperator,
Object value
) {
this.fieldName = DAO_QueryFactoryFieldHelper.getInstance().getFieldTokenPath(sObjectField);
this.comparisonOperator = DAO_WHERE_ComparisonOperatorEnumHelper.getInstance().get(comparisonOperator);
this.value = value;
}
public String toSOQL() {
Object someValue = this.value;
return fieldName
+ comparisonOperator
+ ':someValue';
}
}
Here, the variable is being bound in a different method than the method which actually executes Database.query(), so the variable is out of scope and the query dies with:
|FATAL_ERROR|System.QueryException: Variable does not exist: someValue
I have made an implementation which works:
public class DAO_WHERE_BindingComparisonClause implements DAO_WHERE_ClauseIntf {
DAO_WHERE_ComparisonOperatorEnumHelper comparisonHelper;
String fieldName;
String comparisonOperator;
String bindVariableName;
public DAO_WHERE_BindingComparisonClause (
SObjectField sObjectField,
DAO_WHERE_ComparisonOperatorEnum comparisonOperator,
String bindVariableName
) {
this.fieldName = DAO_QueryFactoryFieldHelper.getInstance().getFieldTokenPath(sObjectField);
this.comparisonOperator = DAO_WHERE_ComparisonOperatorEnumHelper.getInstance().get(comparisonOperator);
this.bindVariableName = bindVariableName;
}
public String toSOQL() {
return fieldName
+ comparisonOperator
+ ':' + bindVariableName;
}
}
But the problem with this implementation is I need to include the name of some variable which will be in scope at the time Database.query() is executed, which isn't a very safe approach and may limit my flexibility to construct queries with any particular instances.
I was considering possibly including the DAO_WHERE_VariableComparisonClause's value directly in the String, but then:
I'm not sure how literal values should look in dynamic SOQL queries, especially if the value is a collection.
I'm not sure how long SOQL queries can be - what happens if I have a set which includes 200 values?
What is the best way to make DAO_WHERE_VariableComparisonClause work as expected?
[apex]
?