Skip to content

Commit

Permalink
grouping (#84)
Browse files Browse the repository at this point in the history
* grouping

* refactoring
  • Loading branch information
pgajek2 authored Sep 14, 2023
1 parent 88029f8 commit 031b69d
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 17 deletions.
40 changes: 23 additions & 17 deletions force-app/main/default/classes/SOQL.cls
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ public virtual inherited sharing class SOQL implements Queryable {
Queryable count();
Queryable count(SObjectField field);
Queryable count(SObjectField field, String alias);
// GROUPING
Queryable grouping(SObjectField field, String alias);
// USING SCOPE
Queryable delegatedScope();
Queryable mineScope();
Expand Down Expand Up @@ -347,6 +349,11 @@ public virtual inherited sharing class SOQL implements Queryable {
return this;
}

public SOQL grouping(SObjectField field, String alias) {
builder.fields.grouping(field, alias);
return this;
}

public SOQL delegatedScope() {
builder.scope.delegated();
return this;
Expand Down Expand Up @@ -539,7 +546,7 @@ public virtual inherited sharing class SOQL implements Queryable {
}

public Integer toInteger() {
if (builder.fields.areCountsEmpty()) {
if (!builder.fields.hasCount()) {
count();
}
return executor.toInteger(builder.toString(), binder.getBindingMap());
Expand Down Expand Up @@ -693,27 +700,31 @@ public virtual inherited sharing class SOQL implements Queryable {

private class QFields implements QueryClause {
private Set<String> fields = new Set<String>();
private Set<String> counts = new Set<String>();
private Set<String> aggregatedFields = new Set<String>();
private Boolean hasCount = false;

public void count() {
// COUNT() must be the only element in the SELECT list.
clearAllFields();
count('COUNT()');
}

public void count(SObjectField field) {
withAggregatedField(field);
count('COUNT(' + field + ')');
}

public void count(SObjectField field, String alias) {
withAggregatedField(field);
count('COUNT(' + field + ') ' + alias);
fields.add('COUNT(' + field + ') ' + alias);
}

private void count(String countSoql) {
counts.add(countSoql);
private void count(String count) {
this.hasCount = true;
withAggregatedField(count);
fields.add(count);
}

public void grouping(SObjectField field, String alias) {
withAggregatedField('GROUPING(' + field + ') ' + alias);
fields.add('GROUPING(' + field + ') ' + alias);
}

public void with(SObjectField field, String alias) {
Expand Down Expand Up @@ -758,23 +769,18 @@ public virtual inherited sharing class SOQL implements Queryable {
fields.clear();
}

public Boolean areCountsEmpty() {
return counts.isEmpty();
public Boolean hasCount() {
return hasCount;
}

public override String toString() {
removeNotAggregatedFieldsFromAggregateSoql();

if (fields.isEmpty() && counts.isEmpty()) {
if (fields.isEmpty()) {
return 'SELECT Id';
}

List<String> selectStatement = new List<String>();

selectStatement.addAll(counts);
selectStatement.addAll(fields);

return 'SELECT ' + String.join(selectStatement, ', ');
return 'SELECT ' + String.join(fields, ', ');
}

public void removeNotAggregatedFieldsFromAggregateSoql() {
Expand Down
16 changes: 16 additions & 0 deletions force-app/main/default/classes/SOQL_Test.cls
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,22 @@ private class SOQL_Test {
Assert.areEqual('SELECT COUNT(Name) names FROM Account', soql);
}

@IsTest
static void grouping() {
// Test
String soql = SOQL.of(Lead.SObjectType)
.with(Lead.LeadSource, Lead.Rating)
.grouping(Lead.LeadSource, 'grpLS')
.grouping(Lead.Rating, 'grpRating')
.count(Lead.Name, 'cnt')
.groupByRollup(Lead.LeadSource)
.groupByRollup(Lead.Rating)
.toString();

// Verify
Assert.areEqual('SELECT LeadSource, Rating, GROUPING(LeadSource) grpLS, GROUPING(Rating) grpRating, COUNT(Name) cnt FROM Lead GROUP BY ROLLUP(LeadSource, Rating)', soql);
}

@IsTest
static void withField() {
// Test
Expand Down
34 changes: 34 additions & 0 deletions website/docs/api/soql.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ The following are methods for `SOQL`.
- [`count(SObjectField field)`](#count-field)
- [`count(SObjectField field, String alias)`](#count-with-alias)

[**GROUPING**](#grouping)

- [`grouping(SObjectField field, String alias)`](#grouping)

[**SUBQUERY**](#sub-query)

- [`with(SubQuery subQuery)`](#with-subquery)
Expand Down Expand Up @@ -437,6 +441,36 @@ SOQL.of(Account.SObjectType)
.toAggregated();
```

## GROUPING

### grouping

**Signature**

```apex
grouping(SObjectField field, String alias)
```

**Example**

```sql
SELECT LeadSource, Rating,
GROUPING(LeadSource) grpLS, GROUPING(Rating) grpRating,
COUNT(Name) cnt
FROM Lead
GROUP BY ROLLUP(LeadSource, Rating)
```
```apex
SOQL.of(Lead.SObjectType)
.with(Lead.LeadSource, Lead.Rating)
.grouping(Lead.LeadSource, 'grpLS')
.grouping(Lead.Rating, 'grpRating')
.count(Lead.Name, 'cnt')
.groupByRollup(Lead.LeadSource)
.groupByRollup(Lead.Rating)
.toAggregated();
```

## USING SCOPE

[USING SCOPE](https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_soql_select_using_scope.htm)
Expand Down

0 comments on commit 031b69d

Please sign in to comment.