Sunday, July 2, 2017

Dynamic Apex In Salesforce

Dynamic Apex In Salesforce 


Schema.DescribeSObjectResult in Apex and its usage in visualforce.


This Describes SObject methods returns an array of DecribeSobjectResult objects. Where each object has the following properties.

String Name : This is the name of the object.

String Label :  Label text for the tab or an objct.

String LabelPlural : Label text for an object that represents plural version of object name.

String keyPrefix :  Object id's are prefixed with 3 character quotes that specify the type of the object.

Ex: - Account obj as 001, Opportunity object has 006.

When we call the keyPrefix it will return 3 character prefix code for the object which we are called.


Field[] fields: This will return array of the fields associated with an object.

Boolean Custom: Indicated whether the object is a custom object or not.

Boolean Creatable: Indicates whether the object can be created via created method.

Boolean deletable: Indicates whether the object can be deleted or not.

Boolean Mergable: Indicates whether the object can be merged with objects of its type.

Replicatable: Indicates whether the object can be replicatable via getUpdate function or getDeleted.

Boolean Retrievable : Indicates whether the object can be retrieved using retrieve method or not.

Boolean Searchable:- Indicates whether object can be searched via Search method .


Boolean updatable : Checks whether the object can be updatable or not.

To fetch the properties of an object

Schema.DescribeSobjectResult resultObj = Account.SobjectType.getDescribe();

                                              Or
Schema.DescribeSobjectResult result =  Schema.SobjectType.Account();

Example:

Field Example:

 Public class FieldExample{

   public String result {get;set;}

  Public FieldExample() {

 Schema.DescribeSobjectResult resultObj =          Account.SobjectType.getDescribe();
 result = ' ' +resultObj ;

}

}

In the above program 'resultObj' cibtaubs description about the object Account. If you want to know the properties individually we can use.

String getLabel();
String getKeyPrefix();
String getLabelPlural(); etc...



Child Relationship methods for given Object:


List <Schema.ChilRelationship> getChildRelationShips(); 

If an sobject is a parent object we can access the child relationships as well as the child objects using ChildRelationShip object.  This method returns the list of child objects for the given Sobject.


List of Child Records:

Program to display the List of Child objects for a given object

EX:-
public class ChildRelationshipExample {

public List<SelectOption> options;

public List<SelectOption> getOptions(){
 return options;
}

public ChildRelationshipExample(){

options = new List<SelectOption>();
Schema.DescribeSobjectResult r = Account.SobjectType.getDescribe();
List<Schema.childRelationship> c = r.getChildRelationShips();

for(schema.childRelationship x:c){
 String name = ' '+x.getChildSObject();
 SelectOption op = new SelectOption(name,name);
 options.add(op);
}

}


}

VF Page:

<apex:page controller="ChildRelationshipExample">
  <apex:form >
   <apex:selectlist size="1">
     <apex:selectoptions value="{!options}"></apex:selectoptions>
   </apex:selectlist>
  </apex:form>
</apex:page>




  


RecordType info:


List<Schema.RecordTypeInfo>.getRecordTypeInfos();

This returns a list of record types created on this object. User may or may not have access to see this record type information.

Example to display the list of record types for a given object:



Single Line to fetch record type:


Id devRecordTypeId = Schema.SObjectType.Account.getRecordTypeInfosByName().get('Development').getRecordTypeId();


Here, 'Development' is the record type's name. You shuld use 'someone'. Also, you will have to specify your SObject type, here I have mentioned Account.

Ex:
Class:

public class RecordTypeInfoExample {

 public List<SelectOption> options;

 public List<SelectOption> getOptions(){
  return options;
 }

 public RecordTypeInfoExample(){
  options = new List<SelectOption>();
  String myObject = 'Opportunity';
  Schema.DescribeSobjectResult dsr = Opportunity.SobjectType.getDescribe();
  List<Schema.RecordTypeInfo> rt =dsr.getRecordTypeInfos();
  for(Schema.RecordTypeInfo inf: rt){
  
  SelectOption op = new SelectOption(inf.getName(),inf.getName());
   options.add(op);
  }
  

 }

}


Vf page:

<apex:page controller="RecordTypeInfoExample" >
 <apex:form >
   <apex:selectlist size="1">
     <apex:selectoptions value="{!options}"></apex:selectoptions>
   </apex:selectlist>
  </apex:form>
  

</apex:page>





RecordTypeInfoByID : -

Map<Id, Schema.RecordTypeInfo>.getRecordTypeInfoByID();

Returns the Map, matches the records id's of an object to their associated record types.

Program to display id's of recordtypes of a given object:

Ex:

public class RecordTypeInfoByIDExample {

    public List<Selectoption> options = new List<SelectOption>();
    public RecordTypeInfoByIDExample(){
        Schema.DescribeSObjectResult dsr = schema.SObjectType.opportunity;
        Map<Id,Schema.RecordTypeInfo> rtinfoMap = dsr.getRecordTypeInfosByID();
        Set<Id> s = rtinfoMap.keySet();
        
        for(id i: s){
            SelectOption op = new SelectOption(i,i);
            options.add(op);
        } 
        system.debug('options==>'+options);
    }
   
}




DescribeFieldResult:-

DescribeFieldResult stores the description about the field of an object, to get the description.

Schema.DescribeFieldResult obj = Account.Name.getDescribe();
                                                        Object Name , Field Name

DescriveFieldResult Methods:

String getLabel();
Integer getLength();
String getLocalName();
String getName();
Integer precission();
Integer getScale();
Boolean isAccessable();
Bollean isAutoNumber();
Boolean isCalculates();
Boolean isCustom();
Boolean isDependentPickList();
Boolean isIdLookup();
Boolean isRestrictedDelete();

Program to display the pickList values.

Ex:

public class DescribeFieldsExample {

public List<SelectOption> options;

public List<SelectOption> getOptions(){
 return options;
}

public String result {get;set;}

public DescribeFieldsExample (){
 options =  new List<SelectOption>();
 Schema.DescribeFieldResult obj = Account.Industry.getDescribe();
 List<Schema.pickListEntry> p = obj.getPickListValues();
 for(Schema.PickListEntry x:p){
  SelectOption op = new SelectOption(x.getLabel(),x.getLabel());
  options.add(op);
 }

}

}


VF Page:

<apex:page controller="DescribeFieldsExample" >
  <apex:form >
   <apex:selectList size="1">
    <apex:selectOptions value="{!options}"> </apex:selectOptions>
   </apex:selectList>
  
  </apex:form>
</apex:page>




                   


Write a program to display the list of all the fields of an object:

Map<String, Schema.SobjectField> M = Schema.SObjectType.Account.fields.getMap();

It is going to get all the fieldNames along with Properties.

Class:

public class FieldNamesExample {

public List<SelectOption> options;

public List<SelectOption> getOptions(){
 return options;
}

public FieldNamesExample (){
options = new List<SelectOption>();
 Map<String, Schema.SobjectField> M = Schema.SObjectType.Account.fields.getMap();
 system.debug('M==>'+M);
 Set<String> keys = M.keySet();
 for(String s : keys){
  SelectOption op = new SelectOption(s,s);
  options.add(op);
 }

}

}

Vf Page:

<apex:page controller="FieldNamesExample">
  <apex:form >
   <apex:selectList size="1">
    <apex:selectoptions value="{!options}"> </apex:selectoptions>
   
   </apex:selectList>
  
  </apex:form>
</apex:page>






Write a Program to display list of Custom Objects available in the organization and once the user select any object it has to display the list of fields of the corresponding object


Class:

public class ObjectFieldsExampleVF {

 Map<String,Schema.SobjectType> my;
 public String objName{get;set;}


 public List<SelectOption> myOptions;
 public List<SelectOption> options;

 public ObjectFieldsExampleVF(){
 options =  new List<SelectOption>();
 myOptions = new List<SelectOption>();
 my = schema.getGlobalDescribe();
 Set<String> myObj = my.keySet();
 for(String s:myObj){
  if(my.get(s).getDescribe().isCustom()){
   SelectOption ob = new SelectOption(s,s);
   myOptions.add(ob);
   

 }
 }
 }

 public PageReference show(){
 Map<String, Schema.SObjectField> fieldMap = my.get(objName).getDescribe().Fields.getMap();
 Set<String> keys = fieldMap .keySet();
 for(String s : keys){
  SelectOption op = new SelectOption(s,s);
  options.add(op);
 }
 return null;
 }

 public List<SelectOption> getOptions(){
  return options;
 }

 public List<SelectOption> getMyOptions(){
  return myOptions;
 }
}


Vf Page: 

<apex:page controller="ObjectFieldsExampleVF" >
  <apex:form >
   <apex:pageblock >
    <apex:pageblockSection >
     <apex:pageblockSectionItem >
       <apex:outputlabel > Object Name :</apex:outputlabel>
        <apex:selectList value="{!objName}" size="1">
         <apex:selectoptions value="{!myOptions}"></apex:selectoptions>
        </apex:selectList>
     </apex:pageblockSectionItem>
     
      <apex:pageblockSectionItem id="one">
       <apex:outputlabel > <font Color="red">{!objName} - Fields</font></apex:outputlabel>
        <apex:selectList size="1" style="Width:150PX">
         <apex:selectOptions value="{!options}"></apex:selectOptions>
        </apex:selectList>
      </apex:pageblockSectionItem>
     
     <apex:commandButton value="Click Me" action="{!show}" />
    </apex:pageblockSection>   
   </apex:pageblock>
  </apex:form>

</apex:page>








Program to display objects and its fields with dynamic query to display dynamic data in pageblock table.


This we can achieved using dynamic apex.

Class:

public class DynamicTableController {

public List<SelectOption> supportObject{get;set;}

public String selectObject{get;set;}

Map<String, Schema.SObjectType> gd = Schema.getGlobalDescribe();
Set<String> objectKeys = gd.keySet();

Public List<SelectOption> fieldLabelAPI {get;Set;}

public List<String> selectedFields {get;set;}

public List<Sobject> objectList{get;set;}


 public DynamicTableController (){

  supportObject = new List<SelectOption>();
  selectObject  = '';
  fieldLabelAPI =  new List<SelectOption>();
  selectedFields = new List<String>();
  objectList = new List<Sobject>();
  //Get only reference to objects  
  for(Schema.SObjectType item : ProcessInstance.TargetObjectId.getDescribe().getReferenceTo()){
  //Excluding custom setting objects  
   if(!item.getDescribe().CustomSetting)  {
   supportObject.add(new SelectOption(item.getDescribe().getLocalName().toLowerCase() , item.getDescribe().getLabel() )); 
   }
  
  }
   
 } //end of constructor.

 public void ObjectFields() {
   fieldLabelAPI.clear();
   objectList.clear();
  if(selectObject !='--None--'){
   Schema.sobjectType systemObjectType = gd.get(selectObject);
   Schema.DescribeSObjectResult r = SystemObjectType.getDescribe();
   Map<String, Schema.SObjectField> M = r.fields.getMap();
   for(Schema.SObjectField fieldApi : M.values()){
    fieldLabelAPI.add(new SelectOption(fieldApi.getDescribe().getName(),fieldApi.getDescribe().getLabel()));
   }
  }
 }

 public void showTable(){
  String myQuery = 'Select Id';
  
  for(String field: selectedFields){
   if(field.toLowerCase() != 'id' && field.toLowerCase() !='--None--')
     myQuery +=',' + field+' ' ;  
  }

  myQuery += ' From  '+ selectObject + ' Limit 200'; 
  objectList = Database.query(myQuery);
 }


}

VF Page:

<apex:page controller="DynamicTableController">
 <apex:pageBlock >
  <apex:form >
   <apex:actionFunction name="ObjectFields" action="{!ObjectFields}"/>
  <apex:commandButton value="Show Table" action="{!showTable}"/>
  
  <apex:pageblockSection >
   <apex:pageblockSectionItem >
    <apex:outputlabel value="Select Object"></apex:outputlabel>
     <apex:selectlist multiSelect="false" size="1" value="{!selectObject}" onchange="ObjectFields();">
      <apex:selectOption itemlabel="--None--" itemValue="--None--"></apex:selectOption>
      <apex:selectoptions value="{!supportObject}"></apex:selectoptions>
     </apex:selectlist>
        
   </apex:pageblockSectionItem>  
   
   <apex:pageblockSectionItem >
    <apex:outputLabel value="Select Field"></apex:outputLabel>
    <apex:selectList multiselect="true" size="5" value="{!selectedFields }">
     <apex:selectOption itemLabel="--None--" itemValue="--None--"></apex:selectOption>
     <apex:selectOptions value="{!fieldLabelAPI}"></apex:selectOptions>
    </apex:selectList>
   </apex:pageblockSectionItem>
    
    <apex:pageBlockTable rendered="{!IF(objectList.size >0,true,false)}" value="{!objectList}" var ="rec">
     <apex:column value="{!rec.id}" rendered="{!IF(selectedFields.size==0,true,false)}" />
     <apex:repeat value="{!selectedFields}" var="fieldLabel">
      <apex:column value="{!rec[fieldLabel]}" rendered="{!IF(fieldLabel !='--None--',true,false)}"/>
     </apex:repeat>
   </apex:pageBlockTable>
   
   <apex:outputPanel rendered="{!IF(objectList.size ==0,true,false)}">
    <apex:pagemessage severity="Error" summary="No Records to Display"></apex:pagemessage>
   </apex:outputPanel>
   
   
  </apex:pageblockSection>
  </apex:form>

 </apex:pageBlock>


</apex:page>


output:




Here once the user select the object it will display the fields related to object. then after selecting the fields to query click on show table button it will display the data in pageblock table.


Schema Programming in Apex and its usage in Visualforce Page.





Schema Describe:

  •   Is a way to programmatically learn about metadata of your datamodel with in Apex.
  • Schema Describe calls provides the ability to programitically describe the information about the current org schema such as list of top level objects including custom objects and their fields.

           Map<String,Schema.SobjectType> gd = Schema.getGlobalDescribe();
  •  We can also use schemaDescribe()  to create tree structure of all the objects and fields in the schema browser, to do this we need to use the codemap

         Map<String,Schema.SobjectType> gd = Schema.getGlobalDescribe();

Returns map of all Sobjects names or Keys to sObject tokens or values for the standard and custom objects defined in the organization.

Schema Class

The following are methods for Schema. All methods are static.

Returns a map of all sObject names (keys) to sObject tokens (values) for the standard and custom objects defined in your organization.

Returns a list of the category groups associated with the specified objects.

Describes metadata (field list and object properties) for the specified sObject or array of sObjects.

Returns information about the standard and custom apps available to the running user.

Returns available category groups along with their data category structure for objects specified in the request.


Schema Namespace

The Schema namespace provides classes and methods for schema metadata information.
The following are the classes in the Schema namespace.

ChildRelationship Class
Contains methods for accessing the child relationship as well as the child sObject for a parent sObject.

DescribeFieldResult Class
Contains methods for describing sObject fields.

DescribeSObjectResult Class
Contains methods for describing sObjects.

DescribeTabResult Class
Contains tab metadata information for a tab in a standard or custom app available in the Salesforce user interface.

 FieldSet Class
Contains methods for discovering and retrieving the details of field sets created on sObjects.

PicklistEntry Class
Represents a picklist entry.

RecordTypeInfo Class
Contains methods for accessing record type information for an sObject with associated record types.

SObjectField Class
Schema.sObjectField object is returned from the field describe result using the getControler and getSObjectField methods.

SObjectType Class
Schema.sObjectType object is returned from the field describe result using the getReferenceTo method, or from the sObject describe result using the getSObjectTypemethod.

More about Schema Namespace:


Schema Programming in Apex and its usage in Visualforce Page.


Schema give the meta data information about the data (Object, Fields).

Schema Methods :

1). public static Map<String, Schema.SObjectType> getGlobalDescribe()
   
 This method returns a map of all the Sobject names as keys and Sobject val tokens as Values.


Ex:

Display all the list of objects available in the salesforce organization in the Visualfoce page.


Controller Class:

public class SchemaDescribeExample {
    public List<SelectOption> options;
    
    public list<SelectOption> getOptions(){
        return options;
    }
    
    public SchemaDescribeExample(){
        options = new List<SelectOption>();
        Map<String, Schema.SObjectType> schemaMap = schema.getGlobalDescribe();
        Set<String> objectSet = schemaMap.keySet();
        for(String str:objectSet){
            //praparing label and values in selection option.
            SelectOption op =new SelectOption(str,str);
            options.add(op);
        }
    }
    
    

}


VF Page:

<apex:page controller="SchemaDescribeExample">
 <apex:form >
  <Apex:selectList size="1">
    <apex:selectOptions value="{!options}"></apex:selectOptions>
   
  </Apex:selectList>
 </apex:form>
</apex:page>



That's it.. now it will display the list of all the objects in picklist.


More about Dynamic Apex:



Schema Programming in Apex and its usage in Visualforce Page.



1. Retrieve the objects from the salesforce Org.
Display all the Custom objects with “__C”  names in a picklist field:

page:
=====
<apex:page controller="ObjectRetrieve">
<apex:form >
<apex:outputlabel value="All Objects"/>&nbsp;&nbsp;
<apex:selectList size="1">
<apex:selectoptions value="{!objnames}"></apex:selectoptions>
</apex:selectList>
</apex:form>
</apex:page>

class:
======
public with sharing class ObjectRetrieve {

//Map<String, Schema.SObjectType> gd = Schema.getGlobalDescribe();

public List<SelectOption> getobjNames()
{
List<Schema.SObjectType> gd = Schema.getGlobalDescribe().Values();
List<SelectOption> options = new List<SelectOption>();
options.add(new SelectOption('--None','--None--'));
for(Schema.SObjectType f : gd)
{
if(f.getDescribe().getName().contains('__c'))
options.add(new SelectOption(f.getDescribe().getName(),f.getDescribe().getName()));
}
return options;
}
}


2. Retrieveing all the field api names dynamically.The below samples helps to retrieve the field api names dynamically from the salesforce object.

page:
=====


<apex:page standardcontroller="Opportunity" extensions="DynamicVFClass">
<apex:form >
<apex:pageBlock >
<apex:pageBlockSection columns="1">
<apex:repeat value="{!fieldapis}" var="f">
<apex:inputField value="{!Opportunity[f]}"/>
</apex:repeat>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>
</apex:page>
class:
======
public with sharing class DynamicVFClass {
public DynamicVFClass(ApexPages.StandardController controller) {
}
public List<String> getFieldapis() {
map<String, Schema.SObjectType> m1 = Schema.getGlobalDescribe() ;
SObjectType objToken1 = m1.get('Opportunity');
DescribeSObjectResult objDef1= objToken1.getDescribe();
map<String, SObjectField> fieldmap = objDef1.fields.getmap();
List<String> lstobjectfields1= new List<String>();
List<String> fieldLabels1= new List<String>();
map<String,String> fieldLabelNamemap1= new map<String,String>();
for (String fName1:fieldmap.keySet())
{
if(fieldmap.get(fName1).getDescribe().getType()!=Schema.DisplayType.Time &&
fieldmap.get(fName1).getDescribe().getType()!=Schema.DisplayType.anytype&&
fieldmap.get(fName1).getDescribe().getType()!=Schema.DisplayType.base64 &&
fieldmap.get(fName1).getDescribe().getType()!=Schema.DisplayType.EncryptedString &&
fieldmap.get(fName1).getDescribe().getType()!=Schema.DisplayType.Id &&
fieldmap.get(fName1).getDescribe().getType()!=Schema.DisplayType.multiPicklist &&

fieldmap.get(fName1).getDescribe().getType()!=Schema.DisplayType.TextArea)
{
fieldLabels1.add(fieldmap.get(fName1).getDescribe().getLabel());
fieldLabelNamemap1.put(fieldmap.get(fName1).getDescribe().getLabel(), fName1);
}
}
for (String fLabel1:fieldLabels1){
if(flabel1 !='Created Date'&& flabel1!='Last Activity Date' && flabel1!='Last modified Date' && flabel1!='Deleted' && flabel1!='System modstamp'&& flabel1!='')
{
//lstobjectfields.add(new selectOption(fieldLabelNamemap.get(flabel),fLabel));
lstobjectfields1.add(fieldLabelNamemap1.get(flabel1));
}
}
system.debug('#### All Fields are ####'+lstobjectfields1);
return lstobjectfields1;
}
}





(3). Retrieve the picklist values from the picklist field:
If we don't have standard controller then we have to use the following sample.
page:
=====
<apex:page controller="RetrievePicklistData">
<apex:form >
<apex:outputlabel value="Stage"/> &nbsp;&nbsp;
<apex:selectList size="1" >
<apex:selectOptions value="{!pickNames}">
</apex:selectOptions>
</apex:selectList>
</apex:form>
</apex:page>
 
class:
=======
public with sharing class RetrievePicklistData {

public List<SelectOption> getpicknames()
{
set<String> setobj = new set<string>();
List<SelectOption> options = new List<SelectOption>();
Schema.DescribeFieldResult ccity = Schema.sObjectType.Opportunity.fields.StageName.getSObjectField().getDescribe();
options.add(new SelectOption('--None--', '--None--'));
for(PicklistEntry ent:ccity.getpicklistvalues())
{
options .add(new SelectOption(ent.getValue(), ent.getLabel()));
setobj.add(ent.getvalue());
}
return options;
}
}

To get the Object properties such as keyfix, label,plural label etc…..:

Schema.DescribeSObjectResult sobjectResultTemp = Schema.sobjecttype.Account;
system.debug('==>Account Properties==>'+sobjectResultTemp);
System.debug('==>Account Prefix==>'+sobjectResultTemp.getKeyPrefix());
System.debug('==> Acount Plural label==>'+sobjectResultTemp.getLabelPlural());
System.debug('==> Account Label ==>'+sobjectResultTemp.getLabel());


Get all the required fields of sObject dynamically?

There is no direct property available in Apex dynamic API to represent the required field. However there is another way to know about it.
If any field have below three properties then it is mandatory field.

1.       If it is Creatable
2.       If it is not nillable and
3.       If it does not have any default value

Map<String, Schema.SObjectType> m  = Schema.getGlobalDescribe() ;
system.debug('==>m is==>'+m);
Schema.SObjectType s = m.get('Account') ;
system.debug('==>Sobject Type is ==>'+s);
Schema.DescribeSObjectResult r = s.getDescribe() ;
system.debug('==>DescribeSObjectResult==>'+r);
Map<String,Schema.SObjectField> fields = r.fields.getMap() ;
system.debug('==>fields==>'+fields);
List<String> lstrequiredfields=new List<String>();

for(String f : fields.keyset())
{
 Schema.DescribeFieldResult desribeResult = fields.get(f).getDescribe();
 if( desribeResult.isCreateable()  && !desribeResult.isNillable() && !desribeResult.isDefaultedOnCreate()
 {
//This is mandatory / required field

      lstrequiredfields.add(f);

 }
   
}
system.debug('==>lstrequiredfields==>'+lstrequiredfields);


Getting Childrelationships from an object using dynamic Apex

If an sObject is a parent object, you can access the child relationship as well as the child sObject using the ChildRelationship object methods.

A ChildRelationship object is returned from the sObject describe result using the getChildRelationship  method. For example:


Schema.DescribeSObjectResult   describeresult = Account.SObjectType.getDescribe();
//it gives Account  object properties or describe results;
List<Schema.ChildRelationship>   lstchildrelationships                      =describeresult.getChildRelationships();
//It gives you all the childrelationships associated with the account.To get relationship names from the above list;
for(Schema.ChildRelationship relname:lstchildrelationships){
      System.debug('Relationshipname:'+relname.getrelationshipname());
}


Limitation:
You can only use 100getChildRelationships method calls per Apex request.

Record Type Id without SOQL query:

We have getRecordTypeInfosByName() method to get record type id with out SOQL query.

We can avoid SOQL query on RecordType object with this method.The following example shows how to access Record Type information through dynamic apex.

Schema.DescribeSObjectResult resSchema = Account.sObjectType.getDescribe();
//getting all Recordtype  Account
if(resSchema.getRecordTypeInfosByName() !=null) {
Map<String,Schema.RecordTypeInfo> recordTypeInfo = resSchema.getRecordTypeInfosByName();
    system.debug('==>recordTypeInfo==>'+recordTypeInfo);
//Getting Business Record Type Id
 if(recordTypeInfo.containsKey('Business')) {
  Id rtId = recordTypeInfo.get('Business').getRecordTypeId();
     system.debug('==>Record Type id is ==>'+rtId);
 }   
   
}

Display Trigger names of selected objects:

List<String> triggerName = new List<String>();
  List<ApexTrigger> apexTriggers = new List<ApexTrigger>();
               
Schema.DescribeSObjectResult resSchema = Account.sObjectType.getDescribe();
system.debug('==>resSchema==>'+resSchema);
        for(ApexTrigger aptrig:[select id,name,Status,TableEnumOrId from apextrigger where TableEnumOrId=:resSchema.getName()]){
             triggerName.add(aptrig.name);
            apexTriggers.add(aptrig);
 }
system.debug('==>trigger Name==>'+triggerName);
System.debug('==>apexTriggers==>'+apexTriggers);


Access Salesforce app information

You can obtain describe information for standard and custom apps available in the Salesforce user interface. Each app corresponds to a collection of tabs. Describe information for an app includes the app’s label, namespace, and tabs. Describe information for a tab includes the sObject associated with the tab, tab icons and colors.

This example shows how to get the tab sets for each app. The example then obtains tab describe metadata information for the Sales app. For each tab, metadata information includes the icon URL, whether the tab is custom or not, and colors among others. The tab describe information is written to the debug output.

// Get tab set describes for each app
List<Schema.DescribeTabSetResult> tabSetDesc = Schema.describeTabs();

// Iterate through each tab set describe for each app and display the info
for(DescribeTabSetResult tsr : tabSetDesc) {
                String appLabel = tsr.getLabel();
    System.debug('Label: ' + appLabel);
                System.debug('Logo URL: ' + tsr.getLogoUrl());
                System.debug('isSelected: ' + tsr.isSelected());
                String ns = tsr.getNamespace();
                if (ns == '') {
        System.debug('The ' + appLabel + ' app has no namespace defined.');
                }
                else {
        System.debug('Namespace: ' + ns);
                }
               
                // Display tab info for the Sales app
if (appLabel == 'Sales') {
        List<Schema.DescribeTabResult> tabDesc = tsr.getTabs();
        System.debug('-- Tab information for the Sales app --');
        for(Schema.DescribeTabResult tr : tabDesc) {
                 System.debug('getLabel: ' + tr.getLabel());
            System.debug('getColors: ' + tr.getColors());
            System.debug('getIconUrl: ' + tr.getIconUrl());
            System.debug('getIcons: ' + tr.getIcons());
            System.debug('getMiniIconUrl: ' + tr.getMiniIconUrl());
            System.debug('getSobjectName: ' + tr.getSobjectName());
            System.debug('getUrl: ' + tr.getUrl());
            System.debug('isCustom: ' + tr.isCustom());
                }
                }              
}


Dynamic SOQL

Dynamic SOQL refers to the creation of a SOQL string at runtime with Apex code. Dynamic SOQL enables you to create more flexible applications. For example, you can create a search based on input from an end user, or update records with varying field names

To create a dynamic SOQL query at runtime, use the database query method, in one of the following ways:

• Return a single sObject when the query returns a single record:
sObject S = Database.query(string_limit_1);

• Return a list of sObjects when the query returns more than a single record:
List<sObject> L = Database.query(string);

The database query method can be used wherever an inline SOQL query can be used, such as in regular assignment statements and for loops. The results are processed in much the same way as static SOQL queries are processed.

Dynamic SOQL results can be specified as concrete sObjects, such as Account or MyCustomObject__c, or as the generic sObject data type. At runtime, the system validates that the type of the query matches the declared type of the variable. If the query does not return the correct sObject type, a runtime error is thrown. This means you do not need to cast from a generic sObject to a concrete sObject.




EX:-

String myTestString = 'TestName';
List<sObject> L = Database.query('SELECT Id FROM MyCustomObject__c WHERE Name = :myTestString');

Retrieving all fields without specifying field names in SOQL Query:

string fieldnames=' ';
List<sObject> lstaccount = new List<Account>();
Map<String, Schema.SObjectField> M = Schema.SObjectType.Account.fields.getMap();
for(Schema.SObjectField s:m.values()){
 Schema.DescribeFieldResult sfield=s.getDescribe();
 fieldnames+=s+',';  //Here we concatenating all field names with comma seperation for preparing SOQL query
}
system.debug('==>fieldnames==>+fieldnames);
//Fieldnames string contains all the fields with comma separation
 fieldnames=fieldnames.substring(0,fieldnames.length()-1);
system.debug('==>fieldnames==>+fieldnames);
 string query='select '+fieldnames+' from Account';
 //Here we are preparing string query(dynamic SOQL using "fieldnames" string)
 if(query!=null && query!=''){
  lstaccount=database.query(query);//Here we will get all field values from account.
 }
 system.debug('==>lstaccount==>'+lstaccount);

You CAN directly use primitive data types in SOQL.

So what does this means?
This means you can directly use any Integer, String , Date, Datetime,Double, Id variable along with Collection of this variable within the query.

For Example: 

a) You are allowed to do this

//initialize the Datetime with current time
DateTime now = System.now();
//query accounts by merging the variable name inside the query string
List<Account> accountList = Database.query('SELECT Id FROM Account WHERE CreatedDate =:now');

b)You can also include LISTs(Collections) in your queries

List<String> accNameList = new List<String>{'Acc1','Acc2'}
//query accounts by merging the variable name inside the query string
List<Account> accountList = Database.query('SELECT Id FROM Account WHERE Name IN:accNameList');

You CANNOT use complex types in a Dynamic SOQL directly.This means that you cannot use any Sobject, Apex Class or Any other user defined data type inside the Dynamic Query. In short you cannot use a dot (".") operator to specify a field value in a Dynamic query.

For Example :

a)  Using an Sobject inside the query String will not work
  //initialize a Account with a Name value for demo
Account acc = new Account(Name='MyAccount');
//query accounts by merging the variable name inside the query string

//This will not work
List<Account> accountList = Database.query('SELECT Id FROM Account WHERE Name =:acc.Name');

//But You can always make the above work by writing the code as.

  //initialize a Account with a Name value for demo
  Account acc = new Account(Name='MyAccount');
  String accountName = acc.Name
  //query accounts by merging the variable name inside the query string
   List<Account> accountList = Database.query('SELECT Id FROM Account WHERE                    Name =: accountName  ');

SOQL Injection

 SOQL injection is a technique by which a user causes your application to execute database methods you did not intend by passing SOQL statements into your code. This can occur in Apex code whenever your application relies on end user input to construct a dynamic SOQL statement and you do not handle the input properly.

To prevent SOQL injection, use the escapeSingleQuotes method. This method adds the escape character (\) to all single quotation marks in a string that is passed in from a user. The method ensures that all single quotation marks are treated as enclosing strings, instead of database commands.

More about soql Injection:

Dynamic SOSL:

 Dynamic SOSL refers to the creation of a SOSL string at runtime with Apex code. Dynamic SOSL enables you to create more flexible applications. For example, you can create a search based on input from an end user, or update records with varying field names.



To create a dynamic SOSL query at runtime, use the search query method. For example:

List<List <sObject>> myQuery = search.query(SOSL_search_string);

The following example exercises a simple SOSL query string.

String searchquery='FIND\'Edge*\'IN ALL FIELDS RETURNING Account(id,name),Contact, Lead';
List<List<SObject>>searchList=search.query(searchquery);

Dynamic SOSL statements evaluate to a list of lists of sObjects, where each list contains the search results for a particular sObject type. The result lists are always returned in the same order as they were specified in the dynamic SOSL query. From the example above, the results from Account are first, then Contact, then Lead.

The search query method can be used wherever an inline SOSL query can be used, such as in regular assignment statements and for loops. The results are processed in much the same way as static SOSL queries are processed.


Dynamic DML

In addition to querying describe information and building SOQL queries at runtime, you can also create sObjects dynamically, and insert them into the database using DML.

To create a new sObject of a given type, use the newSObject method on an sObject token. Note that the token must be cast into a concrete sObject type (such as Account). For example:

This example shows how to obtain the sObject token through the Schema.getGlobalDescribe method and then creates a new sObject using the newSObject method on the token. This example also contains a test method that verifies the dynamic creation of an account.


public class DynamicSObjectCreation {
                public static sObject createObject(String typeName) {
                Schema.SObjectType targetType = Schema.getGlobalDescribe().get(typeName);
                if (targetType == null) {
                // throw an exception
                }
                 
                // Instantiate an sObject with the type passed in as an argument   
           //  at run time.                
             return targetType.newSObject();
                }
}

@isTest
private class DynamicSObjectCreationTest {
                static testmethod void testObjectCreation() {
                String typeName = 'Account';
                String acctName = 'Acme';
                 
                // Create a new sObject by passing the sObject type as an argument.
                Account a = (Account)DynamicSObjectCreation.createObject(typeName);           
                System.assertEquals(typeName, String.valueOf(a.getSobjectType()));
                // Set the account name and insert the account.
                a.Name = acctName;
                insert a;

                // Verify the new sObject got inserted.
                Account[] b = [SELECT Name from Account WHERE Name = :acctName];
                system.assert(b.size() > 0);
                }
}

Or

// create instance of types dynamically
SObjectType accountType = Schema.getGlobalDescribe().get('Account');
SObject acc = accountType.newSObject();

// modify values using .put notation
acc.put('Name','Some Name');

insert acc;
id accId = acc.Id;

// read back dynamically and modify again using .put notation if necessary
acc = Database.query('Select Name From Account Where Id = :accId');

System.debug( acc.get('Name') );


More on Dynamic DML:

No comments:

Post a Comment