Skip to content

Instantly share code, notes, and snippets.

@ohadios
Last active July 12, 2017 21:53
Show Gist options
  • Save ohadios/d1f8c40dd29122e97daa6915d586b920 to your computer and use it in GitHub Desktop.
Save ohadios/d1f8c40dd29122e97daa6915d586b920 to your computer and use it in GitHub Desktop.
ObjectQuery
<apex:page controller="ObjectQueryController" showHeader="true">
<apex:form >
<apex:pageBlock title="Query Objects">
<apex:pageBlockSection columns="1" title="Object Selection">
<apex:selectList title="" size="1" value="{!selectedObject}" >
<apex:selectOptions value="{!objectNames}"/>
<apex:actionSupport event="onchange" reRender="fieldSelection"/>
<apex:outputLabel >Select the object you would like to query</apex:outputLabel>
</apex:selectList>
</apex:pageBlockSection>
<apex:pageBlockSection columns="2" title="Select fields to query" id="fieldSelection">
<apex:selectList size="1" value="{!selectedField}">
<apex:selectOptions value="{!objFields}"/>
<apex:outputLabel >Select Fields to Query:</apex:outputLabel>
</apex:selectList>
<!-- Button performs a query we have the results and we have results Id. -->
<apex:commandButton action="{!btnPerformQuery}" reRender="rPanel" value="Query!"/>
<apex:inputText value="{!criteria}">
<apex:outputLabel value="Query Value"/>
</apex:inputText>
</apex:pageBlockSection>
<apex:outputPanel id="rPanel">
<apex:pageBlockSection title="Results" id="results" rendered="{!queried}">
<apex:pageBlockTable value="{!results}" var="r">
<apex:column value="{!r.id}"/>
<apex:column value="{!r['Name']}"/>
<apex:column value="{!r['createdBy.name']}"/>
<apex:column value="{!r['createdDate']}"/>
<apex:column value="{!r['lastModifiedBy.name']}"/>
<apex:column value="{!r['lastModifiedDate']}"/>
<apex:column value="{!r[selectedFieldAPI]}"/>
</apex:pageBlockTable>
</apex:pageBlockSection>
</apex:outputPanel>
</apex:pageBlock>
</apex:form>
</apex:page>
public with sharing class ObjectQueryController {
public List<Contact> conts{get;set;}
public Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
private Map<String, String> fldAPINameMap = new Map<String,String>();
//Private set on SelectOption is so that values can be set from the controller.
public List<SelectOption> objectNames{public get; private set;}
public String selectedObject {get; set;}
public String selectedField {get;set;}
public String selectedFieldAPI {get;set;}
private List<SelectOption> fields;
Public string criteria{get;set;}
public List<sObject> results{get;set;}
public boolean queried {get;set;}
// TO DO:
// - Error handling when user selects ID or Name fields to query (Any Duplicate Fields)
// - Handle queries of fields that are different than text
// - Allow the selection of multiple fields
// - Allow Mass Update of fields on queried records
// - Insert new records
public List<SelectOption> getObjFields() {
fields.clear();
if(queried == null){queried = false;}
system.debug('Page loading, Queried is: '+queried);
// If an object was not selected yet, just populate the text 'Select object first'
if(selectedObject == NULL){
fields.add(new selectOption('Select Object First', 'Select Object First'));
}
// if object was selected, create a list of the object's fields
else {
system.debug('$$$$$' + selectedObject);
//We get a string of the sOjbects using the schemaMap.
Map <String, Schema.SObjectField> fieldMap = schemaMap.get(selectedObject).getDescribe().fields.getMap();
for(Schema.SObjectField sfield : fieldMap.Values())
{
schema.describefieldresult dfield = sfield.getDescribe();
String fieldName = dfield.getLabel();
fields.add(new SelectOption(fieldName, fieldName));
fldAPINameMap.put(fieldName, dfield.getname());
}
}
return fields;
}
// Constructor - this method will run when the controller is instantiated
public ObjectQueryController(){
objectNames = initObjNames();
fields = new List<SelectOption>();
List<sObject> results = new List<sObject>();
String Criteria;
}
// Populate SelectOption list -
// find all sObjects available in the organization
private List<SelectOption> initObjNames() {
List<SelectOption> objNames = new List<SelectOption>();
List<String> entities = new List<String>(schemaMap.keySet());
entities.sort();
for(String name : entities)
objNames.add(new SelectOption(name,name));
return objNames;
}
//Instantiate the list cast records. We pull id, Name and other needed fields for our pageBlockTable in our VF page
public void btnPerformQuery(){
string queryStr = 'SELECT ID, NAME, createdBy.Name, createdDate, lastModifiedBy.Name, lastModifiedDate, '+fldAPINameMap.get(selectedField)+' FROM '+selectedObject+' WHERE '+fldAPINameMap.get(selectedField)+' like \'%'+criteria+'%\'';
selectedFieldAPI = fldAPINameMap.get(selectedField);
system.Debug(queryStr);
results = database.query(queryStr);
System.Debug(results.size());
queried = true;
system.debug('Query performed, Queried is: '+queried);
}
}
@isTest
public class ObjectQueryController_Test {
//Constructor
static testmethod void ObjectQueryController_Test(){
//Preparing some data so that we can query it later
//Meta-data is available in test, so we will be able to query all objects even in test
//
List<Account> accountsToInsert = new List<Account>();
//First we will create some accounts with Account Type = Customer - Direct
For (integer i=1; i<6; i++){
Account a = new Account();
a.Name = 'Test Account Direct '+i;
a.Type = 'Customer - Direct';
accountsToInsert.add(a);
system.debug(a.name);
}
For (integer i=1; i<4; i++){
Account a = new Account();
a.Name = 'Test Account Channel '+i;
a.Type = 'Customer - Channel';
accountsToInsert.add(a);
system.debug(a.name);
}
system.Debug(accountsToInsert.size());
insert accountsToInsert;
List<Account> accts = [select id, name, type from Account];
For (account a : accts){
System.Debug(a.name + ', '+a.type);
}
// Now we have a bunch of accounts and we can start testing
Test.startTest();
// We will start by creating an instance of the controller
ObjectQueryController objCon = new ObjectQueryController();
// In order to provide coverage - we need to ensure that as much of our code as possible will get executed.
// Since we are not going to have the page open and someone pressing buttons - we will 'simulate' them by calling the methods that they invoke
objCon.selectedObject = 'Account';
System.assert(objCon.getObjFields().size() > 1);
// Let's review code coverage at this point - how much of the code have we covered?
//
// TO DO:
// Add code to ensure that lines 21 - 22 are covered
// Now let's test querying the selected object
objCon.selectedField = 'Account Type';
objCon.criteria = 'Direct';
objCon.btnPerformQuery();
System.AssertEquals(objCon.results.size(), 5);
// TO DO:
// Add logic to test count of Channel customers, and also to test for all Customers
Test.stopTest();
}
}
Page Loads
Constructor runs
Populates a list of SelectOption with all Org’s object names
This calls a method to return these values
User makes a selection of object
On list change – populate a selection variable, and refresh the field-selection section
When field-selection section refreshes, it calls the method to get the object’s fields and populate into list of SelectOption
User selects fields and enters criteria
User click on ‘Query’ button
Launches query method which utilizes dynamic query string and returns results in a list of sObject including the field selected by the user
Page displays these results
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment