Sunday, 6 March 2016

Difference between Database DML statements and simple DML statements

Let us see what is the difference between the two types of dml statements that we come across in apex. 
To understand this we will consider dml being applied on collection(List). Let us see 'insert' dml as an example. When we execute the below two statements, how do they differ from each other?

1. Insert accList;

2. Database.insert(accList,false);

**accList is a list of account records.

First let's see simple insert- when we do simple insert on that list it will either insert all of the account records in the list or none will be inserted. That is, there will be either total success or total failure. You cannot have partial success, partial failure in case of simple insert. If any of the record in the list fails due to any validation or any other thing, then none of the records in that list will be inserted. Records will be inserted only if all of the records are good to get inserted(i.e pass all sorts of validations)

Database.insert on the other hand can give you partial success. To get partial success we will have to pass a parameter "opt_allOrNone" as 'false' separated by the list name. If this parameter is set to true then it functions like simple insert. So if the parameter is false, then all the records passing validations will be inserted and others will be restricted.

We can track the errors that are encountered, using saveresult object as shown in the below code snippet,
?
1
2
3
4
5
6
List<database.saveresult>  accResultList = database.insert(accList,false);
for(database.saveresult res:accResultList){
if(!res.issuccess()){
  database.error e = esr.getErrors()[0];
system.debug('error is *******'+e.getmessage());
}


Let us summarise on the points discussed above,
Simple Insert
1. Can insert either all the records or no records at all. Partial success is not possible.

Database.insert(listname,false)
1. Partial success is possible in this case.

Database.insert(listname,true)
1. Operates same like simple insert dml i.e no partial success possible.

Data Loader, if you have observed works on the principle of database methods with "opt_allOrNone" flag set as 'false', hence we get partial success even if any of the record fail.

** all of the points discussed above for insert also apply for other DML: update,upsert,delete.

Roles and Profiles in salesforce

Roles
In salesforce, roles are defined so as to increase the data visibility a particular user has. The data visibility can be increased using sharing rules or by building role hierarchy. Role hierarchy allows the user sitting in higher level have access of records owned by users having role lower in hierarchy. It is not mandatory that a user should have a role.

Organisation wide default sets the default access for objects, for example OWD set as private would mean that only the owner of the record can access the record. One way to grant additional access of these records to other users is through roles i.e users higher in role hierarchy would get the access of records owned by users lower in hierarchy. Other way is by writing sharing rules, wherein we can specify the logic to decide which record should be shared and with what role user. We can specify against custom objects whether the records should be shared using role hierarchy or not but this is default set for standard objects and cannot be changed. That is, standard object records will always be shared according to role hierarchy. Defining role for users is not a mandatory thing, however not defining role for a user could affect the data shown on opportunity and other reports for that user.
Summarising the points for role,
1. Role controls the level of record access user has
2. Helps extend the OWD settings for different objects
3. Sharing rules can be written to share records with particular role and subordinates
4. Defining role for user is not mandatory. 




Profiles
Unlike role,  profile is mandatory for every user in salesforce. You cannot have a user without a profile. It is the building pillar of the entire org. Profile states the objects/field permissions and also other permissions with in the org. It defines what a user can do within the org, it states the access settings and user permissions. Profile controls following -
  • Object permissions [create, delete,read, edit permissions] 
  • field permissions [view, edit]
  • Record type permission 
  • Which Apps can be viewed 
  • Login hours can be defined 
  • Ip address permissions 
  • Which tabs are visible 
  • Which page layouts can be viewed  
  • Classes, vf pages permissions
Salesforce provides some standard profiles with different set of permissions for each, we can create our own profiles to have permissions as per our requirement. New profile should be cloned from existing profile.

Difference between the two can be summarised as below
1. Role defines what user can see depending on the hierarchy(Helps in defining data visibility)
2. Profile defines what a user can do within the org(Defines various permissions)
3. Defining profile for a user is mandatory, role is not.

Salesforce Lightning component example

In this post we will see a basic lightning component example and will also include it on a salesforce 1 app. Lightning framework uses Java script on the client side and apex on the server side. Lightning components can be used on salesforce 1 mobile as well as for dekstop(Lightning Experience).

Let us build a simple search page and make it available for salesforce 1 app. Page will have 2 input boxes: "Opportunity stage" and "Amount" and will also include a search button. Pressing the button will show all the opportunities with that stage and having amount greater than the input value. We will also include navigation facility to the searched opportunities.

To begin with we will have to first enable custom domain for your org after which you can start building lightning component. You can visit here (https://developer.salesforce.com/trailhead/project/quickstart-lightning-components/quickstart-lightning-components1) to see how to enable custom domain for your org.  To build the component we will need lightning component, client side controller (Java script) and server side controller (apex class). These things can be coded from developer console.
We can start with lightning component first but since it has dependencies with other two we can write the server controller first, then the client side controller and lightning component in the end. Or can also start with lightning component and build the others hand in hand.

Within Developer console you can navigate to File->New->Lightning Component to create the new lightning component.
Once you have this in new tab within developer console you will get option on right hand side to create client side controller (Controller) and you can create new server side controller by navigating to file->new->apex class

Lighting Component

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<aura:component implements="force:appHostable" controller="oppSearchController">  
    <aura:attribute name="opportunities" type="Opportunity[]"/>
    <aura:attribute name="showtbl" type="boolean" default="false"/>
    <ui:inputText aura:id="nameopp" label="Opportunity Stage" value="enter stage" required="true"/>
    <ui:inputText aura:id="amntopp" label="Opportunity Amount >" value="enter amount" required="false"/>
    <ui:button label="Get Opportunities" press="{!c.getOpps}"/>
    <aura:if isTrue="{!v.showtbl}">    <span class="ligtn-button" style="white-space: pre;"> </span>
    <table>
            <thead>
                <tr>
                    <th><strong> Name </strong></th>
                    <th> <strong>  Stage </strong> </th>
                    <th> <strong>  Amount </strong> </th>                  
                </tr>
            </thead>
            <tbody>
                <aura:iteration var="opp" items="{!v.opportunities}">                  
                    <tr>
                        <td><a data-record="{!opp.Id}" onclick="{!c.navigateToRecord}">{!opp.Name}</a>
</td>
                        <td>{!opp.StageName}</td>
                        <td>{!opp.Amount}</td>
                    </tr>
                </aura:iteration>
            </tbody>
        </table>
        </aura:if>
</aura:component>

Lightning component as you see above starts and ends with aura tag. Since we want to use the component on salesforce 1 we will have to overide it on a tab and hence
implements="force:appHostable" has been used which allows overriding a tab with the lightning component. We need two input boxes for which inputText has been used and Ui button that calls the java script controller function. <aura:iteration has been used to iterate through all the opportunities.


Client Side Controller

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
({
    navigateToRecord : function(component, event, helper){
    var navEvt = $A.get("e.force:navigateToSObject");
     var selectedItem = event.currentTarget;
     var Name = selectedItem.dataset.record;
       
navEvt.setParams({
  "recordId": Name,
  "slideDevName": "detail"
});
navEvt.fire();
    },  
    getOpps: function(cmp){      
        cmp.set("v.showtbl","true");
        var action = cmp.get("c.getOpportunities");
        action.setParams({ OppStage : cmp.find("nameopp").get("v.value") , Oppamount : cmp.find("amntopp").get("v.value")});      
       
        action.setCallback(this, function(response){
            var state = response.getState();
            if (state === "SUCCESS") {
                cmp.set("v.opportunities", response.getReturnValue());
            }
        });
<span class="lightn-buton" style="white-space: pre;"> </span> $A.enqueueAction(action);
    }
})

Client side controller uses the inputs from UI and calls the server side controller which does the searching and passes the results which are then set on UI table. Function navigaterecord has been used to provide a facility to navigate to the records displayed in table. The lightning component are referenced using v. (view) and server side methods variable can be referenced via c. (controller)

Server Side Controller

?
1
2
3
4
5
6
7
8
9
10
public with sharing class oppSearchController{
    @AuraEnabled
    public static List<Opportunity> getOpportunities(String OppStage , Integer Oppamount) {
    string stageopp = '\''+OppStage+'\'';
        List<Opportunity> opportunities =
                [SELECT Id, Name, CloseDate,Amount,StageName FROM Opportunity where Amount >: Oppamount and StageName =: OppStage];
        return opportunities;
    }
}

This is a simple apex class with method having @AuraEnabled annotation which enables it for use in lightning component. Method simply queries the opportunities based on the received parameters and returns the list of opportunities back to the client side controller.

To include this component on salesforce 1 create a new lightning tab and override it with this lightning component and include the tab in mobile navigating setup. You can install any browser extension for salesforce 1 to see the results or from salesforce 1 app on your mobile. The output image above is from add on extension for chrome.