Design
Single class
SOSL Lib is a single-class solution.
You don't need to think about dependencies; everything you need is stored in SOSL.cls. The SOSL.cls
only takes around 1500 lines of code.
Different clauses are encapsulated in small, inner classes. All crucial information is kept at the top of the class, so developers can use it even without reading the documentation.
public static IReturning Returning(SObjectType ofObject) {
return new SoslReturningClause(ofObject);
}
public static IFilterGroup FilterGroup {
get {
return new SoslFilterGroupClause();
}
}
public static IFilter Filter {
get {
return new SoslFilterClause();
}
}
public interface ISearchable {
// FIND
ISearchable find(String searchText);
// IN SearchGroup
ISearchable inAllFields();
ISearchable inNameFields();
ISearchable inEmailFields();
ISearchable inPhoneFields();
ISearchable inSidebarFields();
// RETURNING
ISearchable returning(IReturning returning);
// WITH
ISearchable withDivision(String division);
ISearchable withHighlight();
ISearchable withSnippet(Integer targetLength);
ISearchable withNetworkEqual(Id networkId);
ISearchable withNetworkIn(Iterable<Id> networkIds);
ISearchable withPriceBookId(Id priceBookId);
ISearchable withMetadata(String metadata);
ISearchable withSpellCorrection();
ISearchable withoutSpellCorrection();
// LIMIT
ISearchable setLimit(Integer amount);
// UPDATE
ISearchable updateViewStat();
ISearchable updateTracking();
// FIELD-LEVEL SECURITY
ISearchable systemMode();
// SHARING MODE
ISearchable withSharing();
ISearchable withoutSharing();
// DEBUGGING
ISearchable preview();
// RESULT
List<List<SObject>> toSearchList();
Search.SearchResults toSearchResult();
}
public interface IReturning {
// FIELDS
IReturning with(SObjectField field);
IReturning with(SObjectField field1, SObjectField field2);
IReturning with(SObjectField field1, SObjectField field2, SObjectField field3);
IReturning with(SObjectField field1, SObjectField field2, SObjectField field3, SObjectField field4);
IReturning with(SObjectField field1, SObjectField field2, SObjectField field3, SObjectField field4, SObjectField field5);
IReturning with(List<SObjectField> fields);
// WHERE
IReturning whereAre(IFilterGroup filterGroup);
IReturning whereAre(IFilter filter);
// USING LISTVIEW
IReturning usingListView(String listView);
// ORDER BY
IReturning orderBy(String field);
IReturning orderBy(String field, String direction);
IReturning orderBy(SObjectField field);
IReturning orderBy(String relationshipName, SObjectField field);
IReturning sortDesc();
IReturning nullsLast();
// LIMIT
IReturning setLimit(Integer amount);
// OFFSET
IReturning offset(Integer amount);
}
public interface IFilterGroup {
// ADD
IFilterGroup add(IFilterGroup filterGroup);
IFilterGroup add(IFilter filter);
IFilterGroup add(String dynamicCondition);
// CONDITION ORDER
IFilterGroup anyConditionMatching();
IFilterGroup conditionLogic(String order);
// ADDITIONAL
Boolean hasValues();
}
public interface IFilter {
// FIELDS
IFilter id();
IFilter recordType();
IFilter name();
IFilter with(SObjectField field);
IFilter with(String field);
IFilter with(String relationshipName, SObjectField field);
// COMPERATORS
IFilter isNull();
IFilter isNotNull();
IFilter isTrue();
IFilter isFalse();
IFilter equal(Object value);
IFilter equal(String value);
IFilter notEqual(Object value);
IFilter notEqual(String value);
IFilter lessThan(Object value);
IFilter greaterThan(Object value);
IFilter lessOrEqual(Object value);
IFilter greaterOrEqual(Object value);
IFilter containsSome(Iterable<String> values);
IFilter contains(String value);
IFilter endsWith(String value);
IFilter startsWith(String value);
IFilter contains(String prefix, String value, String suffix);
IFilter isIn(Iterable<Object> iterable);
IFilter isIn(List<Object> inList);
IFilter isIn(List<String> inList);
IFilter notIn(Iterable<Object> iterable);
IFilter notIn(List<Object> inList);
IFilter notIn(List<String> inList);
IFilter includesAll(Iterable<String> values);
IFilter includesSome(Iterable<String> values);
IFilter excludesAll(Iterable<String> values);
IFilter excludesSome(Iterable<String> values);
// ADDITIONAL
IFilter ignoreWhen(Boolean logicExpression);
Boolean hasValue();
}
Functional Programming
SOSL Lib uses the concept called Apex Functional Programming.
You can see an example of it with SOSL.Returning
, SOSL.FilterGroup
andSOSL.Filter
.
Those classes encapsulate the logic, and only necessary methods are exposed via interfaces.
IReturning whereAre(FilterGroup filterGroup); // SOSL.FilterGroup
IReturning whereAre(Filter filter); // SOSL.Filter
SOSL.find(SEARCH_TEXT)
.inAllFields()
.returning(
SOSL.Returning(Account.SObjectType)
.with(Account.Id, Account.Name)
.whereAre(SOSL.FilterGroup
.add(SOSL.Filter.with(Account.Name).equal(accountName).ignoreWhen(String.isEmpty(accountName)))
.add(SOSL.Filter.with(Account.Industry).equal('IT'))
)
)
.toSearchList();