Sunday, 4 January 2015

Passed Salesforce DEV 501 Multiple Choice - Sharing my experience

I passed Salesforce Certified Force.com Advance Developer Multiple Choice First of all, don't go without experience and preparation, its not that easy, being a hard core coder doesn't mean that you will go and pass, its not about coding knowledge, its all about coding basics i.e. Apex and Visualforce pages and Salesforce life cycle knowledge and best practice.

According to Study Guide for Salesforce.com Certified Force.com Advanced Developer

Development Lifecycle                          13%                   9 Questions
Force.com Code (Apex)                         33%                  23 Questions
Force.com Pages (Visualforce)             38%                  26 Questions
Testing and Debugging                         16%                  11 Questions

Above table shows area covered in exam.

Listing out the high topics

1. Apex class basics and Best practice
2. Visualforce pages and tags, Templates.
3. Test classes - best practice.
4. Migration tool.
6. Sandbox and capabilities
7. Force.com IDE
8. Developer Console
9. Types of Controller

Here is the list of the things need to study with small descriptions as well. These are the high points that I feel should be at one place.

Sandboxes Types -- Developer Sandbox

Refresh Interval -- 1 day
Storage Limits -- 200 mb data and 200 mb file storage
Data Copy -- Metadata only
Sandbox Templates -- Not included

Description -- Developer sandbox environments are intended for coding and testing by a single developer. Multiple users can log in to and share a single Developer sandbox, but the primary purpose of a Developer sandbox is to provide an environment in which changes under active development can be isolated until those changes are ready to be shared. Developer sandboxes copy all of your production organization’s metadata, or Setup data. This includes custom settings, custom object definitions, Apex classes and triggers, Visualforce pages, reports, dashboards, price books, and so on.
Developer sandboxes provide a limited amount of file and data storage, which is enough for many development and testing tasks. 

Developer Pro Sandbox

Refresh Interval --- 1 day
Storage Limits --- 1 GB of data storage and 1 GB of file storage
Data Copy --- Metadata only
Sandbox Templates --- Not included
Description --- Developer Pro sandbox environments provide the same functionality as Developer sandboxes do, with increased file and data storage. With the added storage, a Developer Pro sandbox can host larger and more complete data sets, so you can use it for additional tasks such as data load and integration testing and user training.

Partial Copy Sandbox
Refresh Interval -- 5 days
Storage Limits -- 5 GB of data storage and 5 GB of file storage
Data Copy --- All metadata and sample of object data
Sandbox Templates --- Required
Description --- Partial Copy sandbox environments include all of your organization’s metadata and a sample of your production organization’s data that you define by using a sandbox template. To create a Partial Copy sandbox, you must apply a sandbox template at creation time. A Partial Copy sandbox is, at its base, a metadata copy of your production organization, just like Developer and Developer Pro sandboxes. In addition, the sandbox copy engine samples data from your production organization based on what is defined by a sandbox template. For each selected object in the sandbox template, the sandbox copy engine samples up to 10,000 records. For example, when you use a template that includes only Accounts to create a Partial Copy sandbox, up to 10,000 Account records are copied into the new sandbox, but no other records are copied.
The sandbox copy engine has a special copy strategy to handle Partial Copy sandbox creation. The copy strategy understands the data relationships that are defined in your production organization’s standard and custom object schema. The copy strategy ensures that sample records maintain valid relationships as defined in your production organization’s standard and custom object schema. For example, if you create a sandbox template that includes two custom objects that are called Master and Detail, and these objects have a Master-Detail relationship, the copy engine ensures that every sampled Detail record points to a Master. The copy engine also understands required relationships between objects, whether they are Master-Detail or required Lookup relationships. The copy engine samples the master records first and then uses the IDs of the master records to sample related detail records.
When you use sandbox templates to create valid subsets of your organization’s data, you can use Partial Copy sandboxes for virtually any development, testing, or training purpose. The only task for which they aren’t well-suited is full performance and load testing.
Full Sandbox
Refresh Interval --- 29 days
Storage Limits --- Same as production organization
Data Copy --- All metadata and data
Sandbox Templates -- Available
Description --Full sandbox environments are a replica of your entire production organization and all its data, including standard and custom object records, documents, attachments, code, settings, and so on.
When you create a Full sandbox, you can apply a sandbox template to limit the data that is copied, so that your sandbox contains only the records that you need for testing or other tasks. For example, you can omit confidential or sensitive data if it’s not needed for testing. Create a sandbox template that includes everything except the sensitive data. When you apply a sandbox template to aFull sandbox, the sandbox copy engine copies all of the records for the selected objects in the template. For example, when you use a template that includes only Accounts to create a Full sandbox, all of the Account records are copied into the new sandbox, but no other records are copied.
When you create a Full sandbox, you also have to decide how much field tracking history and Chatter activity to include.
The default is to omit field tracking, but you can include up to 180 days of field tracking. This might be an excessive amount of data if you track field history for many objects in your production organization.
§ Chatter activity data can be extensive, which can add a significant amount of time to your Full sandbox copy.
Limit the amount of field history that you copy, and copy your Chatter data only if you need it for your testing use cases.
You can use Full sandboxes for many purposes, but the size of the sandbox and length of the refresh interval don’t produce an environment that stays current with your production organization. We suggest that you use Full sandboxes for data load testing, integration testing, user acceptance testing, performance and load testing, and staging purposes. In particular, this environment is the only one that can support full performance and load testing.

Understanding Sandbox Refresh Intervals
The refresh interval for each sandbox environment is calculated from when the actual sandbox copying process begins. This corresponds to when the sandbox status changes from Pending to Processing.
If other sandbox copy requests were made before yours, your sandbox might remain in the Pending status for some time. The refresh interval timer for your sandbox won’t start until your request leaves this state.

Future Annotation

Methods with the future annotation must be static methods, and can only return a void type.
The specified parameters must be primitive data types, arrays of primitive data types, or collections of primitive data types.
Methods with the future annotation cannot  take  sObjects or objects as arguments.
Specify (callout=true) to allow callouts in a future method. Specify (callout=false) to prevent a method from making callouts.
Methods with the future annotation cannot be used in Visualforce controllers in  either  getMethodName  or  setMethodName  methods, nor in the constructor.
·         You cannot call a method annotated with future from a method that also has the future annotation. Nor can you call a trigger from an annotated method that calls another annotated method.
§  The getContent and getContentAsPDFPageReference methods cannot be used in methods with the future annotation.

Defining Templates with <apex:composition>

Define the section of the template using <apex:Insert >
Then create template using <apex:composition> with required child <apex:define>
All templates defined using <apex:composition> must have one or more child <apex:insert> tags.
An <apex:insert> tag indicates to pages that import the template that a section needs a definition. Any Visualforce page that imports a template using <apex:composition> must use <apex:define> to specify the content of each <apex:insert> section of the template.
<apex:insert> : Define a named section in VF template
<apex:define>: Provide content for named section in VF template
<apex:composition>: A particular area/section of visualforce page where VF template is to be used


SOQL and SOSL

ALL ROWS - returns all rows including those in the recycle bin and archived activities
(Ex: System.assertEquals(2, [SELECT COUNT() FROM Contact WHERE AccountId = a.Id ALL ROWS]);)

FOR UPDATE - locks the record for update from other means while the execution is happening.
(Ex:  Account [] accts = [SELECT Id FROM Account LIMIT 2 FOR UPDATE]; )

getGlobalDescribe()

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


Understanding Apex Describe Information

You can describe sObjects either by using tokens or the describeSObjects Schema method.
Apex provides two data structures and a method for sObject and field describe information:
·         Token—a lightweight, serializable reference to an sObject or a field that is validated at compile time. This is used for token describes.
·         The describeSObjects method—a method in the Schema class that performs describes on one or more sObject types.
§  Describe result—an object of type Schema.DescribeSObjectResult that contains all the describe properties for the sObject or field. Describe result objects are not serializable, and are validated at runtime. This result object is returned when performing the describe, using either the sObject token or the describeSObjects method.

Order of Execution for Visualforce Page Get Requests

 A get request is an initial request for a page either made when a user enters an URL or when a link or button is clicked that takes the user to a new page. The following diagram shows how a Visualforce page interacts with a controller extension or a custom controller class during a get request:
1. Evaluates constructor on the controller and Extensions.
2. Custom Component on Page.
3. Evaluates action attribute on <apex:page>.
4. Checks for apex:form on page, to create view state.
Note : If the user is redirected to a page that uses the same controller and the same or a proper subset of controller extensions, a postback request is made. When a postback request is made, the view state is maintained.

Visualforce Email Templates

Although Visualforce email templates use standard Visualforce components, they are not created in the same way. Visualforce email templates always use components that are prefaced with the messaging namespace. In addition:
·         All Visualforce email templates must be contained within a single <messaging:emailTemplate> tag. This is analogous to regular Visualforce pages being defined within a single <apex:page> tag.
·         The <messaging:emailTemplate> tag must contain either a single <messaging:htmlEmailBody> tag or a single <messaging:plainTextEmailBody> tag.
§  Several standard Visualforce components are not available for use within <messaging:emailTemplate>. These include <apex:detail>, <apex:pageBlock> and all related pageBlock components, and all input components such as <apex:form>. If you attempt to save a Visualforce email template with these components, an error message displays.

apex:actionPoller

A timer that sends an AJAX request to the server according to a time interval that you specify. Each request can result in a full or partial page update.
An <apex:actionPoller> must be within the region it acts upon. For example, to use an <apex:actionPoller> with an <apex:actionRegion>, the <apex:actionPoller> must be within the <apex:actionRegion>.

apex:actionFunction

A component that provides support for invoking controller action methods directly from JavaScript code using an AJAX request. An <apex:actionFunction> component must be a child of an <apex:form> component.
Unlike <apex:actionSupport>, which only provides support for invoking controller action methods from other Visualforce components, <apex:actionFunction> defines a new JavaScript function which can then be called from within a block of JavaScript code.

apex:actionRegion

Note that an <apex:actionRegion> component only defines which components the server processes during a request—it does not define what area(s) of the page are re-rendered when the request completes. To control that behavior, use the rerender attribute on an <apex:actionSupport>, <apex:actionPoller>, <apex:commandButton>, <apex:commandLink>, <apex:tab>, or <apex:tabPanel> component.

 <apex:actionRegion>
    <apex:inputField value="{!opportunity.stageName}" id="stage">
    <apex:actionSupport event="onchange" rerender="thePageBlock"

                              status="status"/>
     </apex:inputField>
</apex:actionRegion>


apex:include

A component that inserts a second Visualforce page into the current page. The entire page subtree is injected into the Visualforce DOM at the point of reference and the scope of the included page is maintained.
If content should be stripped from the included page, use the <apex:composition> component instead.

Visualforce pages

Visualforce consists of a tag-based markup language that gives developers a more powerful way of building applications and customizing
the Salesforce user interface. With Visualforce you can:
• Build wizards and other multistep processes.
• Create your own custom flow control through an application.
• Define navigation patterns and data-specific rules for optimal, efficient application interaction.


Adding SOSL Queries to Unit Tests

To ensure that test methods always behave in a predictable way, any Salesforce Object Search Language (SOSL) query that is added to an Apex test method returns an empty set of search results when the test method executes. If you do not want the query to return an empty list of results, you can use the Test.setFixedSearchResults system method to define a list of record IDs that are returned by the search. All SOSL queries that take place later in the test method return the list of record IDs that were specified by the Test.setFixedSearchResults method. Additionally, the test method can call Test.setFixedSearchResults multiple times to define different result sets for different SOSL queries. If you do not call the Test.setFixedSearchResults method in a test method, or if you call this method without specifying a list of record IDs, any SOSL queries that take place later in the test method return an empty list of results.
The list of record IDs specified by the Test.setFixedSearchResults method replaces the results that would normally be returned by the SOSL query if it were not subject to any WHERE or LIMIT clauses. If these clauses exist in the SOSL query, they are applied to the list of fixed search results. For example:
@isTest                  
private class SoslFixedResultsTest1 {
    public static testMethod void testSoslFixedResults() {
       Id [] fixedSearchResults= new Id[1];
       fixedSearchResults[0] = '001x0000003G89h';
       Test.setFixedSearchResults(fixedSearchResults);
       List<List<SObject>> searchList = [FIND 'test' IN ALL FIELDS RETURNING    Account(id, name WHERE name = 'test' LIMIT 1)];
   }
}
                                                                                         

Contents to go through before exam -

1. Force.com Apex Code Developer's Guide and Visualforce Guide.
2. Force.com Developer Guide.
3. Salesforce Object Query Language.

Happy Coding..!! 

Sunday, 2 November 2014

Salesforce Entitlement, Entitlement Process & Milestone Handling

Entitlement : 

Entitlements are the same as the normal objects we use in Salesforce like Account, Contacts etc.
Adding to it, its a child object to Case, Contracts etc.


Purpose of Entitlement in Salesforce is specifically for
  • Enforce service levels with time-dependent, automated processes that instruct agents how to resolve cases.
  • Defining Service levels.

Entitlement according to Salesforce-phere
Entitlement is driven by "Entitlement Process" Object (Look-up on Entitlement Object ) where we set "Milestones" and "Business Hours"

1. Milestones :- Milestones are actually automated time dependent workflow, which run on the time set by the user, in other words to automate the SLA, this is the key of whole Entitlement thing in Salesforce. You can define the actions in Milestone i.e. Field Update, Email Alerts same like normal workflow. 

2. Business Hours : It is used to define the limits of the Milestone Time that have been set by the user like working hours in which a case should be handled.

Enabling & Setting-up Entitlement

Go to Setup --> App Setup --> Customize --> Entitlement Management --> Entitlements

Click Check and Save

after saving you'll get this check according to your requirement and Save. Do check last check-box of Enable Milestone Feed Items, this will add milestone box in your feed item, where Milestone Status will be more visible to the users.


Now go to Entitlement Process create one Entitlement Process

Here is the Entitlement Process created


Above in the setup list there is Milestones, create one

Now create an Apex class, that will set the Trigger time for the milestone, create a custom Number field on Case named as "Milestone Time" and create this class which implements "Support.MilestoneTriggerTimeCalculator"


























Now whatever will be the value in the this field will be set as Time trigger of Case Milestone
We will use this class, while adding Milestone with an Entitlement Process.

Now return back to Entitlement that we have created earlier and and down to it click "new" button in Milestone section, and fill the values same as shown in below


We have done all the setup for the Entitlement Process and Milestone
Now we will create an Entitlement Record, (Don't get confused with Entitlement Process and Entitlement)

Entitlement Process

System object that have Milestones and is used while creating Entitlement (API name SLAProcess ) record.


Entitlement: 


Its an object, that will be associated with Case. It is as normal as other objects like Account, Contact. This is used to attach Case Milestone to the object.

We will create Entitlement record now, that we will attach to the case, search for the Entitlement Tab and click  new, create a new record as shown below, as marked below these field should be field to make Entitlement active otherwise you can't attache it to the Case as shown Status Icon it green check that means its active, you need to provide Start Date  for it, Entitlement process also need to be provided otherwise no Milestone Time will be on the Case, after saving entitlement record you can see the Milestone will be visible under the Milestone.


Now go the case, in the below snapshot, all those field which is used in Entitlement process are shown, we will create a new record of Case and in the Entitlement Name we will put the record that we have created above,
There is a Timeline field on Case layout,which show scale view of the Time that have been setup. Modify the layout and set Case Milestone related list as well

If user didn't close the case or whatever is the procedure to be done to close the case then case will be Violated that automated process, and then Milestone Status will be change.

Look we are done with Entitlement and Milestone thing of Salesforce
You can Milestone actions as well, go to the Entitlement process and Click on the related Milestone of it where you can action like Field Update and Emails alerts etc.

The biggest problem I faced with this functionality when I tried writing trigger on Case Milestone Violation, and attaching other Milestone with the Case. you can write on case on check of "Milestone Status" field that when the status changed to Open violation. but attaching other Milestone on the violation of the first one is not happening.

This is what I learned while working with Entitlement and Milestone of Salesforce.
Thank you, any queries will be appreciated, keep learning-keep coding.

Happy Coding!

Tuesday, 1 July 2014

Basics of Apex Batch Class in Salesforce

What is batch class?

Batch class is just similar to Apex class except that batch class includes the Salesforce provide interface “Database.Batchable”.

Why we use batch class?

When we want to perform DML operations for bulk records or hit the web service then batch class comes in the picture.

Database.Batchable interface contains three method.
  • Start
  • Execute
  • Finish


Start Method

               global Database.QueryLocater start(Database.BatchableContext bc) {}

  • Use this method to get the records from database or object to be passed to “Execute” method.
  • This method returns Database.QueryLocater object that contains the records.
  • Query fired in the start method will return maximum 5,000,0000 records in a transaction.


Execute Method

           global void execute(Database.BatchableContext bc , List scope) {}


  • This method is used for do all the processing for data.
  • This method takes two arguments.
  • A reference of Database.BatchableContext object.
  • A list of sObject records.
  • The logical part of the code to process the data will be write in the execute method.


Finish Method

                global void finish(Database.BatchableContext bc) {}

  • This method takes only one argument a reference of Database.BatchableContext object.
  • This method is called when all the batches are processed.
  • This method is used for sending confirmation email to user or post-processing operations.


Here is the sample code

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

global class batchAccountUpdate implements Database.Batchable<sObject> {

    global Database.QueryLocator start(Database.BatchableContext BC){

        String query = 'SELECT Id,Name FROM Account';
        return Database.getQueryLocator(query);
    }

   global void execute(Database.BatchableContext BC, List<Account> scope) {

        for(Account a : scope) {

             a.Name = a.Name + 'Updated';
         }
         update scope;
   }  

   global void finish(Database.BatchableContext BC) {
    }
}

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::


How to execute/run batch class?

                   Id batchID = Database.executeBatch(new BatchClass() , Batch_Size);

  • This method is used for execute the Batch class.
  • This method returns the ID of the AsyncApexJob object.
  • This method takes two arguments.
  • An instance of the batch class
  • Batch size(Optional)
  • User can see the batch status or abort the batch anytime from the Apex Jobs.


How to schedule batch class ?

      Id schJobId = System.ScheduleBatch(new BatchClass() , ‘Job Name’ , Time_Interval , Batch_Size)

  • This method is used for schedule the batch job to run once in a specific time period in future.
  • This method will return the Scheduled Job Id(CronTrigger Id) click here for CRON.
  • This method takes four arguments                    
                              1. An instance of batch class
                              2. Job Name
                              3. Time Interval
                              4. Batch_Size(Optional)

  • To schedule batch class at a specific time scheduler class will be used.
  • Schedule class similar to Apex class except that it also includes Salesforce Provide Interface “Schedulable”.
  • Next, schedule the class either using Salesforce Apex page in user interface or using System.schedule method.


Why Database.Stateful ?

  • This is used for maintain the state across the transactions.
  • If you don’t specify the Database.Stateful, all Static and Instance member variables are set back to their original values.


Why Database.AllowCallouts ?

  • To use web service callouts in the batch apex, you must specify Database.AllowCallouts interface in the batch class definition.


Governor Limits for Batch Apex

  • Default batch size is 200.
  • Avoid SOQL queries inside for loop.
  • Maximum 5 batches can be run at a time in org.
  • Total number of sendEmail methods allowed per transaction is 10.
  • Total number of future methods allowed per transaction is 10.
  • Always use database methods like insert,update,upsert in the batch class.

Saturday, 21 June 2014

#Salesforce Integration With Twilio

I was searching Twilio integration with salesforce on the web but didn't find any, so am posting this a simple POC of sending SMS to the mobile using Twilio from the Salesforce UI.


Its simple but just you need to do something extra two make this functionality working.

We will go step by step for this
First of all create a new account on Twilio click here 
Twilio will provide you a number, via which it will sent you SMS.

Now login to your salesforce account and create a Remote Site Setting.
In Remote Site URL enter https://api.twilio.com, like shown below

And then create a custom setting named as Twilio Configuration.
We are gonna use them in our apex classes.
Create fields on the custom setting you've just created, with same API name as below shown.


Now we need to provide some values to the fields ofthe custom setting click on Manage button shown above.

Before entering any values to the fields click on these links
For Auth Token and Account SID Click Here
For Test Credetials i.e. Test Account SID and Test Auth Token Click Here

For Account Name enter the name from which you registered like your email id.
For From Phone Number enter that number which got when you created account on Twilio.
After that save your custom setting.

Custom Setting should look something like this


After that you can save the code provided here GitHub 

Page will look something like this




See that was a piece of cake :)
Hope everything works just fine.
Happy coding..!!!

Tuesday, 17 June 2014

Basics of Apex Trigger for beginners

The basic logic of trigger is too huge to cover, I have tried a bit to make everyone understand that how this Apex trigger, a "pain in ass" works, I'll go step by step process of writing apex triggers.

What is Apex Triggers ?

A Trigger is Apex code that executes before or after the following types of operations:
  • insert
  • update
  • delete
  • merge
  • upsert
  • undelete

Types of Apex Triggers


  • Before Triggers: Before triggers can be used to update or validate record values before they are saved to the database.
  • After Triggers: After triggers can be used to access field values that are set by the database (such as a record's Id or last Updated field), and to affect changes in other records, such as logging into an audit table or firing asynchronous events with a queue.
Example : before insert, after insert, before update, after update, before delete, after delete

Syntax of Trigger

Things to keep in mind while writing apex trigger

  • Bulkify your Code : Use Looping through Trigger’s collections variables instead of process through particular indexing.
  • All triggers are bulk triggers by default, and can process multiple records at a time.
  • Bulk triggers can handle both single record updates and bulk operations like: Data import, Force.com Bulk API calls.
  • Bulkify your Code : Use Looping through Trigger’s collections variables instead of process through particular indexing.
  • Avoid SOQL Queries or DML statements inside FOR Loops: An individual Apex request gets a maximum of 100 SOQL queries before exceeding that governor limit. 
  • Bulkify your Helper Methods: if a trigger uses some Apex methods written in a helper class, it's important that those shared Apex methods are properly designed to handle bulk records. These methods should be written to be invoked with a set of records, especially if the method has a SOQL query or DML operation.
Use @future appropriately:
Here is a list of governor limits specific to the @future annotation:
  • No more than 10 method calls per Apex invocation.
  • No more than 200 method calls per Salesforce license per 24 hours.
  • The parameters specified must be primitive datatypes, arrays of primitive datatypes, or collections of primitive datatypes.
  • Methods with the future annotation cannot take sObjects or objects as arguments.
  • Methods with the future annotation cannot be used in Visualforce.

Use efficient collection variable of apex triggers




Try using sets and maps to handle bulk record processing.



TRIGGER BEST PRACTICE

  • Always use helper class in your trigger, and in helper class perform all your logic. like below
  • Don't write more then one trigger on an object, try to add up all your new trigger in a single trigger using different-different helper classes to read more click Order of Execution
There is allot to take care of when writing apex triggers, but I found these to helpful.
Hope this helps 
Happy coding.!!!




Sunday, 1 June 2014

Salesforce Multi-Select Picklist Using JQuery

I have implemented this good looking mulkti-select picklist on our Salesforce Visualforce pages.
It is so easy to handle and more user friendly as it looks.


User can select multiple option as it does in Salesforce Mutli-picklist fields, and values will be succesfully get saved in database.

User can choose more then one option by check options write in the front of the values.


You need to refer Jquery and Javascript from the static resource.

Here is the Visualforce Page code Visualforce Page

Here is the Apex class

Here is the link of github repo https://github.com/abhitripathi/MultiSelect-Jquery

Happy Coding..!!!

Wednesday, 28 May 2014

Book Review : Getting started with SOQL

Recently I got an opportunity to review the book "Getting started with SOQL"by Magulan D.
The book contains all the aspects of Salesforce Object Query Language(SOQL). Here are my thoughts...

The books starts with the basics of SOQL, difference of SOQL and SQL and valuable implementation of SOQL and then all the clauses that we use in SOQL.
Most of the time developers didn't know what they can do with SOQL. As a developer or as an administrator in Salesforce.com, we write many SOQL statements to fetch and validate the data present in the objects.

The sample queries used in the book will help you to understand the SOQL features easily. the sample queries are intended for beginners and for developers or administrators who are new to Salesforce.com.
This book also addresses the standards and guidelines to be followed when writing SOQL statements. The standards and guidelines discussed in this book will help you to write SOQL statements without hitting any limitation set by Salesforce.com and to avoid unwanted data fetched through the queries.

Feature of SOQL is so vast, but for the beginners as well as for experts this book will teach something, even I learned allot those things that I was not using most of the time in SOQL like toLabel() method. The use of Date literals with their example implementation in the queries.

The traditional method of explaining clauses like how to write SOQL, Where to use Caps and where not, that we need to take care of whenever writing an apex class. Limitation is the one difficult thing to handle in salesforce and if we are talking about SOQL then its limitation are most important thing to take care off. In the book limitation of SOQL have been explained in a brief way.

In the end of the book author explained the some tools that we can use to execute queries, he have explained the steps of installation and how to take their best use with SOQL queries, I never used Force.com Explorer software but now am gonna to use this one.

I recommend especially those who want to expertise in SOQL or want to know the key things of SOQL at first place, surely it will help them out.
Book can be purchased from Packt, Goodreads, Amazon, Books.google