Skip to content

Commit 3f88084

Browse files
authored
toIdMapBy (#214)
1 parent 9fd3cf6 commit 3f88084

File tree

2 files changed

+211
-9
lines changed

2 files changed

+211
-9
lines changed

force-app/main/default/classes/main/standard-soql/SOQL.cls

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,10 @@ public virtual inherited sharing class SOQL implements Queryable {
177177
Set<String> toValuesOf(String relationshipName, SObjectField targetKeyField);
178178
// ID MAP
179179
Map<Id, SObject> toMap();
180+
Map<Id, SObject> toIdMapBy(SObjectField field);
181+
Map<Id, SObject> toIdMapBy(String relationshipName, SObjectField targetKeyField);
182+
Map<Id, List<SObject>> toAggregatedIdMapBy(SObjectField keyField);
183+
Map<Id, List<SObject>> toAggregatedIdMapBy(String relationshipName, SObjectField targetKeyField);
180184
// VALUE MAP
181185
Map<String, SObject> toMap(SObjectField keyField);
182186
Map<String, SObject> toMap(String relationshipName, SObjectField targetKeyField);
@@ -1018,42 +1022,73 @@ public virtual inherited sharing class SOQL implements Queryable {
10181022
return this.converter.transform(this.executor.toList()).toMap();
10191023
}
10201024

1025+
public Map<Id, SObject> toIdMapBy(SObjectField field) {
1026+
this.with(field);
1027+
this.whereAre(Filter.with(field).isNotNull());
1028+
return this.converter.transform(this.executor.toList()).toIdMapBy(field);
1029+
}
1030+
1031+
public Map<Id, SObject> toIdMapBy(String relationshipName, SObjectField targetKeyField) {
1032+
this.with(relationshipName + '.' + targetKeyField.toString());
1033+
this.whereAre(Filter.with(relationshipName, targetKeyField).isNotNull());
1034+
return this.converter.transform(this.executor.toList()).toIdMapBy(relationshipName, targetKeyField);
1035+
}
1036+
1037+
public Map<Id, List<SObject>> toAggregatedIdMapBy(SObjectField keyField) {
1038+
this.with(keyField);
1039+
this.whereAre(Filter.with(keyField).isNotNull());
1040+
return this.converter.transform(this.executor.toList()).toAggregatedIdMapBy(keyField);
1041+
}
1042+
1043+
public Map<Id, List<SObject>> toAggregatedIdMapBy(String relationshipName, SObjectField targetKeyField) {
1044+
this.with(relationshipName + '.' + targetKeyField.toString());
1045+
this.whereAre(Filter.with(relationshipName, targetKeyField).isNotNull());
1046+
return this.converter.transform(this.executor.toList()).toAggregatedIdMapBy(relationshipName, targetKeyField);
1047+
}
1048+
10211049
public Map<String, SObject> toMap(SObjectField keyField) {
10221050
this.with(keyField);
1051+
this.whereAre(Filter.with(keyField).isNotNull());
10231052
return this.converter.transform(this.executor.toList()).toMap(keyField);
10241053
}
10251054

10261055
public Map<String, SObject> toMap(String relationshipName, SObjectField targetKeyField) {
10271056
this.with(relationshipName + '.' + targetKeyField.toString());
1057+
this.whereAre(Filter.with(relationshipName, targetKeyField).isNotNull());
10281058
return this.converter.transform(this.executor.toList()).toMap(relationshipName, targetKeyField);
10291059
}
10301060

10311061
public Map<String, String> toMap(SObjectField keyField, SObjectField valueField) {
10321062
this.builder.fields.clearAllFields(); // other fields not needed
10331063
this.with(keyField, valueField);
1064+
this.whereAre(Filter.with(keyField).isNotNull());
10341065
return this.converter.transform(this.executor.toList()).toMap(keyField, valueField);
10351066
}
10361067

10371068
public Map<String, List<SObject>> toAggregatedMap(SObjectField keyField) {
10381069
this.with(keyField);
1070+
this.whereAre(Filter.with(keyField).isNotNull());
10391071
return this.converter.transform(this.executor.toList()).toAggregatedMap(keyField);
10401072
}
10411073

10421074
public Map<String, List<SObject>> toAggregatedMap(String relationshipName, SObjectField targetKeyField) {
10431075
this.with(relationshipName + '.' + targetKeyField.toString());
1076+
this.whereAre(Filter.with(relationshipName, targetKeyField).isNotNull());
10441077
return this.converter.transform(this.executor.toList()).toAggregatedMap(relationshipName, targetKeyField);
10451078
}
10461079

10471080
public Map<String, List<String>> toAggregatedMap(SObjectField keyField, SObjectField valueField) {
10481081
this.builder.fields.clearAllFields(); // other fields not needed
10491082
this.with(keyField, valueField);
1083+
this.whereAre(Filter.with(keyField).isNotNull());
10501084
return this.converter.transform(this.executor.toList()).toAggregatedMap(keyField, valueField);
10511085
}
10521086

10531087
public Map<String, List<String>> toAggregatedMap(SObjectField keyField, String relationshipName, SObjectField targetKeyField) {
10541088
this.builder.fields.clearAllFields(); // other fields not needed
10551089
this.with(keyField);
10561090
this.with(relationshipName + '.' + targetKeyField.toString());
1091+
this.whereAre(Filter.with(keyField).isNotNull());
10571092
return this.converter.transform(this.executor.toList()).toAggregatedMap(keyField, relationshipName, targetKeyField);
10581093
}
10591094

@@ -2726,6 +2761,60 @@ public virtual inherited sharing class SOQL implements Queryable {
27262761
return recordPerId;
27272762
}
27282763

2764+
public Map<Id, SObject> toIdMapBy(SObjectField field) {
2765+
Map<Id, SObject> recordPerCustomKey = (Map<Id, SObject>) Type.forName('Map<Id, ' + this.ofObject + ' >').newInstance();
2766+
2767+
for (SObject record : this.recordsToTransform) {
2768+
recordPerCustomKey.put((Id) record.get(field), record);
2769+
}
2770+
2771+
return recordPerCustomKey;
2772+
}
2773+
2774+
public Map<Id, SObject> toIdMapBy(String relationshipName, SObjectField targetKeyField) {
2775+
Map<Id, SObject> recordPerCustomKey = (Map<Id, SObject>) Type.forName('Map<Id, ' + this.ofObject + ' >').newInstance();
2776+
List<String> relationshipPathFields = relationshipName.split('\\.');
2777+
2778+
for (SObject record : this.recordsToTransform) {
2779+
recordPerCustomKey.put((Id) extractNestedFieldValue(record, relationshipPathFields, targetKeyField), record);
2780+
}
2781+
2782+
return recordPerCustomKey;
2783+
}
2784+
2785+
public Map<Id, List<SObject>> toAggregatedIdMapBy(SObjectField keyField) {
2786+
Map<Id, List<SObject>> recordsPerCustomKey = (Map<Id, List<SObject>>) Type.forName('Map<Id, List<' + this.ofObject + ' >>').newInstance();
2787+
2788+
for (SObject record : this.recordsToTransform) {
2789+
Id key = (Id) record.get(keyField);
2790+
2791+
if (!recordsPerCustomKey.containsKey(key)) {
2792+
recordsPerCustomKey.put(key, new List<SObject>());
2793+
}
2794+
2795+
recordsPerCustomKey.get(key).add(record);
2796+
}
2797+
2798+
return recordsPerCustomKey;
2799+
}
2800+
2801+
public Map<Id, List<SObject>> toAggregatedIdMapBy(String relationshipName, SObjectField targetKeyField) {
2802+
Map<Id, List<SObject>> recordsPerCustomKey = (Map<Id, List<SObject>>) Type.forName('Map<Id, List<' + this.ofObject + ' >>').newInstance();
2803+
List<String> relationshipPathFields = relationshipName.split('\\.');
2804+
2805+
for (SObject record : this.recordsToTransform) {
2806+
Id key = extractNestedFieldValue(record, relationshipPathFields, targetKeyField);
2807+
2808+
if (!recordsPerCustomKey.containsKey(key)) {
2809+
recordsPerCustomKey.put(key, new List<SObject>());
2810+
}
2811+
2812+
recordsPerCustomKey.get(key).add(record);
2813+
}
2814+
2815+
return recordsPerCustomKey;
2816+
}
2817+
27292818
public Map<String, SObject> toMap(SObjectField keyField) {
27302819
Map<String, SObject> recordPerCustomKey = (Map<String, SObject>) Type.forName('Map<String, ' + this.ofObject + ' >').newInstance();
27312820

force-app/main/default/classes/main/standard-soql/SOQL_Test.cls

Lines changed: 122 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4356,6 +4356,7 @@ private class SOQL_Test {
43564356

43574357
// Test
43584358
SOQL.mock('mockingQuery').thenReturn(accounts);
4359+
43594360
Map<Id, Account> result = (Map<Id, Account>) SOQL.of(Account.SObjectType)
43604361
.with(Account.Name, Account.Description)
43614362
.mockId('mockingQuery')
@@ -4372,6 +4373,121 @@ private class SOQL_Test {
43724373
}
43734374
}
43744375

4376+
@IsTest
4377+
static void toIdMapBy() {
4378+
// Setup
4379+
insertAccountsWithParents();
4380+
4381+
// Test
4382+
Map<Id, Account> result = (Map<Id, Account>) SOQL.of(Account.SObjectType).with(Account.Id, Account.Name).toIdMapBy(Account.ParentId);
4383+
4384+
// Verify
4385+
Assert.areEqual(2, result.size(), 'Size of the result map should be equal to the size of the inserted accounts with parents.');
4386+
}
4387+
4388+
@IsTest
4389+
static void mockedToIdMapBy() {
4390+
// Setup
4391+
SOQL.mock('mockingQuery').thenReturn(new List<Account>{
4392+
new Account(Name = 'Account 1', ParentId = SOQL.IdGenerator.get(Account.SObjectType)),
4393+
new Account(Name = 'Account 2', ParentId = SOQL.IdGenerator.get(Account.SObjectType))
4394+
});
4395+
4396+
// Test
4397+
Map<Id, Account> result = (Map<Id, Account>) SOQL.of(Account.SObjectType)
4398+
.with(Account.Id, Account.Name).mockId('mockingQuery')
4399+
.toIdMapBy(Account.ParentId);
4400+
4401+
// Verify
4402+
Assert.areEqual(2, result.size(), 'Size of the result map should be equal to the size of the inserted accounts with parents.');
4403+
}
4404+
4405+
@IsTest
4406+
static void toIdMapByRelationshipField() {
4407+
// Setup
4408+
insertAccountsWithParents();
4409+
4410+
// Test
4411+
Map<Id, Account> result = (Map<Id, Account>) SOQL.of(Account.SObjectType).toIdMapBy('Parent', Account.CreatedById);
4412+
4413+
// Verify
4414+
Assert.areEqual(1, result.size(), 'Size of the result map should be equal to 1, because the accounts have the same created by user.');
4415+
Assert.isTrue(result.containsKey(UserInfo.getUserId()), 'The result map should have a key: UserInfo.getUserId().');
4416+
}
4417+
4418+
@IsTest
4419+
static void mockedToIdMapByRelationshipField() {
4420+
// Setup
4421+
SOQL.mock('mockingQuery').thenReturn(new List<Account>{
4422+
new Account(Name = 'Account 1', Parent = new Account(Name = 'Parent 1', CreatedById = SOQL.IdGenerator.get(User.SObjectType))),
4423+
new Account(Name = 'Account 2', Parent = new Account(Name = 'Parent 2', CreatedById = SOQL.IdGenerator.get(User.SObjectType)))
4424+
});
4425+
4426+
// Test
4427+
Map<Id, Account> result = (Map<Id, Account>) SOQL.of(Account.SObjectType).mockId('mockingQuery').toIdMapBy('Parent', Account.CreatedById);
4428+
4429+
// Verify
4430+
Assert.areEqual(2, result.size(), 'Size of the result map should be equal to 2, because the accounts have 2 parents.');
4431+
}
4432+
4433+
@IsTest
4434+
static void toAggregatedIdMapBy() {
4435+
// Setup
4436+
insertAccountsWithParents();
4437+
4438+
// Test
4439+
Map<Id, List<Account>> result = (Map<Id, List<Account>>) SOQL.of(Account.SObjectType).toAggregatedIdMapBy(Account.ParentId);
4440+
4441+
// Verify
4442+
Assert.areEqual(2, result.size(), 'Size of the result map should be equal to 2, because the accounts have 2 parents.');
4443+
}
4444+
4445+
@IsTest
4446+
static void mockedtoAggregatedIdMapBy() {
4447+
// Setup
4448+
Id parentId = SOQL.IdGenerator.get(Account.SObjectType);
4449+
4450+
SOQL.mock('mockingQuery').thenReturn(new List<Account>{
4451+
new Account(Name = 'Account 1', ParentId = parentId),
4452+
new Account(Name = 'Account 2', ParentId = parentId)
4453+
});
4454+
4455+
// Test
4456+
Map<Id, List<Account>> result = (Map<Id, List<Account>>) SOQL.of(Account.SObjectType).mockId('mockingQuery').toAggregatedIdMapBy(Account.ParentId);
4457+
4458+
// Verify
4459+
Assert.areEqual(1, result.size(), 'Size of the result map should be equal to 1, because the accounts have common parent.');
4460+
}
4461+
4462+
@IsTest
4463+
static void toAggregatedIdMapByRelationshipField() {
4464+
// Setup
4465+
insertAccountsWithParents();
4466+
4467+
// Test
4468+
Map<Id, List<Account>> result = (Map<Id, List<Account>>) SOQL.of(Account.SObjectType).mockId('mockingQuery').toAggregatedIdMapBy('Parent', Account.CreatedById);
4469+
4470+
// Verify
4471+
Assert.areEqual(1, result.size(), 'Size of the result map should be equal to 1, because the same user created all accounts.');
4472+
}
4473+
4474+
@IsTest
4475+
static void mockedtoAggregatedIdMapByRelationshipField() {
4476+
// Setup
4477+
Id userId = SOQL.IdGenerator.get(User.SObjectType);
4478+
4479+
SOQL.mock('mockingQuery').thenReturn(new List<Account>{
4480+
new Account(Name = 'Account 1', Parent = new Account(Name = 'Parent 1', CreatedById = userId)),
4481+
new Account(Name = 'Account 2', Parent = new Account(Name = 'Parent 2', CreatedById = userId))
4482+
});
4483+
4484+
// Test
4485+
Map<Id, List<Account>> result = (Map<Id, List<Account>>) SOQL.of(Account.SObjectType).mockId('mockingQuery').toAggregatedIdMapBy('Parent', Account.CreatedById);
4486+
4487+
// Verify
4488+
Assert.areEqual(1, result.size(), 'Size of the result map should be equal to 1, because all parent accounts have the same created by user.');
4489+
}
4490+
43754491
@IsTest
43764492
static void toMapWithCustomKey() {
43774493
// Setup
@@ -4407,14 +4523,13 @@ private class SOQL_Test {
44074523
@IsTest
44084524
static void toMapWithEmptyCustomRelationshipKey() {
44094525
// Setup
4410-
insertAccounts();
4526+
insertAccountsWithParents();
44114527

44124528
// Test
44134529
Map<String, Account> result = (Map<String, Account>) SOQL.of(Account.SObjectType).toMap('Parent', Account.Name);
44144530

44154531
// Verify
4416-
Assert.areEqual(1, result.size(), 'Size of the result map should be equal to 1');
4417-
Assert.isNotNull(result.get(null), 'The result map should have a value for the key: null');
4532+
Assert.areEqual(2, result.size(), 'Size of the result map should be equal to 2, because there are two accounts with different parents.');
44184533
}
44194534

44204535
@IsTest
@@ -4471,11 +4586,10 @@ private class SOQL_Test {
44714586
insertAccounts();
44724587

44734588
// Test
4474-
Map<String, List<Account>> result = SOQL.of(Account.SObjectType).toAggregatedMap(Account.Industry);
4589+
Map<String, List<Account>> result = SOQL.of(Account.SObjectType).toAggregatedMap(Account.Name);
44754590

44764591
// Verify
4477-
Assert.areEqual(1, result.size(), 'The result map should have only one key.'); // grouped by empty Industry
4478-
Assert.isTrue(result.containsKey(null), 'The result map should have a null key for empty Industry.');
4592+
Assert.areEqual(2, result.size(), 'The result map should have only two keys, because there are two accounts with different names.');
44794593
}
44804594

44814595
@IsTest
@@ -4500,11 +4614,10 @@ private class SOQL_Test {
45004614
insertAccounts();
45014615

45024616
// Test
4503-
Map<String, List<String>> result = SOQL.of(Account.SObjectType).toAggregatedMap(Account.Industry, Account.Id);
4617+
Map<String, List<String>> result = SOQL.of(Account.SObjectType).toAggregatedMap(Account.Name, Account.Id);
45044618

45054619
// Verify
4506-
Assert.areEqual(1, result.size(), 'The result map should have only one key.'); // grouped by empty Industry
4507-
Assert.isTrue(result.containsKey(null), 'The result map should have a null key for empty Industry.');
4620+
Assert.areEqual(2, result.size(), 'The result map should have only two keys, because there are two accounts with different names.');
45084621
}
45094622

45104623
@IsTest

0 commit comments

Comments
 (0)