Version 1: Winter '13
Version 1: Winter '13
Database.com Workbook
names and marks. Other marks appearing herein may be trademarks of their respective owners.
Table of Contents
Table of Contents
About the Database.com Workbook.....................................................................................................3
Database.com Workbook Concepts..........................................................................................................................................4
Table of Contents Step 4: Validate and Deploy Inbound Change Set......................................................................................................33 Step 5: Disallow Inbound Changes.............................................................................................................................34 Summary......................................................................................................................................................................34 Tutorial 7: Using Custom Business Logic and Database Triggers..........................................................................................34 Step 1: Create a Trigger..............................................................................................................................................35 Step 2: Logically Test the Trigger...............................................................................................................................36 Step 3: Programmatically Test the Trigger..................................................................................................................37 Step 4: View Recycle Bin Records and Restore Them................................................................................................38 Step 5: Move the Trigger and Unit Tests to Production.............................................................................................39 Summary......................................................................................................................................................................39
Next Steps..........................................................................................................................................48
ii
What is Database.com?
Database.com is a cloud database that makes it easy to build collaborative, mobile enterprise applications. Secure sharing of data is at the heart of collaborative enterprise applications. The sophisticated identity and access management capabilities in Database.com ensure that you can get the right data, to the right people, at the right time, with the right access permissions. This workbook is intended to help you explore and learn about some of the unique capabilities of Database.com. Please look for other articles and future versions of this workbook which will highlight the Database.com unique social API set and the ability to create custom APIs using Apex REST. Tip: Youll find the latest version of this workbook, as well as snippets of the code that you can easily copy, online at: www.database.com/workbook.
Intended Audience
This workbook is intended for experienced developers new to the Database.com platform. The workbooks code examples are in Java, so familiarity with Java is helpful, though all the programming tasks can also be done with .NET, Ruby, and other development tools.
In a relational database, tables contain columns (to define the data types) and rows (to store the data). You relate tables to other tables by using primary keys and foreign keys, which map the rows of one table to the rows of another table. In Database.com, an organization is the equivalent of a database, but with built-in user identity, security, and social features. Objects contain fields and records. You relate objects to other objects by using relationship fields, such as lookup relationships and master-detail relationships, instead of primary and foreign keys.
Heres a quick guide to the System Overview page. 1. The primary section provides a dashboard of whats happening in your database. It provides quick summaries and handy links to your schemas objects and storage usage, business logic, such as database triggers and classes, API statistics, and your users. 2. The setup tree menus on the left provide access to the primary aspects of Database.com functionality, as well as administration configuration where you can manage users, data security, logs, and more. 3. The right-hand sidebar provides you with helpful links to documentation related to Database.com. You can log in to the production database again at any time by navigating to login.database.com.
3. Once QA testing completes, administrators roll the latest database changes into the production database to support the added application features. 4. The cycle repeats with each development effort. After you sign up and first log in to Database.com, you are automatically working with your production database, also referred to as your production organization. To support the typical ADLC, Database.com allows your organization to create test databases. Now create a test database to use in subsequent tutorials in this workbook. 1. 2. 3. 4. Click Administration Setup > Data Management > Test Database. Click New Test Database. For Name, enter Workbook. Ensure that Type is set to QA Database, and accept the defaults for everything else. Click Start Copy. Note: There are two types of test databases. A QA test database is a copy of your current production database configuration and code, but no data. A staging test database replicates all of your data as well. By default, you can create a single test database with Database.com. If you need additional test databases, please contact salesforce.com support. Test database creation time varies. Youll get email from Database.com once the process completes. When Database.com creates a test database, it creates a user in the test database by appending .<testdatabasename> to your production database username. For example: Production Username
admin-user@workbook.db
The password for the corresponding administrator account in the test database will be the same as it is in production. Once you receive an email that the test database is ready, you can use the Database.com Console to connect to the test database. Navigate to the default deployment connection. 1. Open a new browser window and load the URL test.database.com. 2. Enter the test database username and password, and log in. Once you connect to your test database, look at the top right portion of your screen and confirm that you see an indicator that you are using your test database.
2. 3. 4. 5. 6.
Click New Custom Object. For Label, type Album, then press TAB to set the Object Name. For Plural Label, type Albums. Select Starts with a vowel sound. For Record Name, type Album Name and set its Data Type to Text.
7. Leave all other values as they are. 8. Click Save to finish creating the object. You now have an object that can store data. The Album object has a field called Album Name that can store text strings and that you can set.
All Database.com objects automatically include an ID field that contains a unique identifier for each record in the object. This field is analogous to a typical primary key in a relational database table. Objects also include other standard fields, such as Created By, Last Modified By, and Owner. Database.com automatically manages these fields.
You now have an object that can store the name, release date, and description of music albums, as well as other standard field data such as each data records ownerwhich by default is the user who created the data record. Later on, well add another field to Album called Price and automatically calculate each albums price based on the aggregate price of individual music tracks. Note: For each object and field in Database.com, there is a label (the name you assigned) and an API name (by default, a system-generated name). The API names for custom objects and fields end with a __c suffix to prevent naming conflicts with system objects and fields. Standard fields do not have this suffix. The following tutorials reference these API names when building formulas and coding database triggers. Leave the Database.com Console open so that you can quickly switch back to it in subsequent tutorials.
Summary
Congratulationsyouve created your production and test database environments. Youve also learned about objects, fields, records, and default values as you created your first object, Album, to store information about music albums. Now lets learn how to browse and manage data using Workbench.
10
For example, lets display summary information about our Album object. 1. For Jump to, select Standard & Custom Objects. 2. For Object, select Album__c, the API name for the Album object. 3. Click Select.
The Describe page reveals useful metadata that corresponds to the chosen object. Expand the component folders to review their contents. Attributes displays general information about an object, including its API name. Child Relationships lists information for all related objects, including relationships to system objects. Fields lists information for all standard and custom fields in an object, including each fields label, API name, and data type. Record Type Infos is an array of the record types supported by this object. You dont need access to all the returned record types to see them here. This object contains all of the existing fields of RecordTypeMapping except layoutId and picklistForRecordType.
11
Workbench returns a message upon completion. Your Salesforce Id value will be different than the one shown here.
Now repeat these steps to create more records with the following data so that you have some varying data to work with in the next part of this tutorial. Description__c A classic Great rock opera Name Help! The Wall Released_On__c 1965-08-06 1979-11-30
12
4. Edit the query that Workbench builds to rearrange the order of the columns in the SELECT list. When you are finished, the query resembles the following:
SELECT Id, Name, Description__c, Released_On__c FROM Album__c
5. Click Query to execute the query. Heres what your query results look like in Workbench (your Ids will be different).
The Database.com query language is SOQL. Notice that SOQL is similar to SQL, so getting started with SOQL is easy if you already understand SQL. Note: In our scenario, we only have three records in the Album object. When querying larger data sets, consider using the LIMIT clause in a SELECT statement to limit the number of records in a querys return set. Now lets add a few bells and whistles to your first query. 1. On the SOQL Query page, the current query should still be present. In Sort results by:, choose Released_On__c. Your query now looks like the following (reformatted below for readability).
SELECT Description__c, Id, Name, Released_On__c FROM Album__c ORDER BY Released_On__c ASC NULLS FIRST
2. Click Query to run the new query and notice that the query results are now ordered by the Released_On__c field in ascending order.
13
Lets enhance the query a bit more, so that it shows only specific records that meet a condition. Use Filter results by: to see if you can build the following query, one that shows albums that were released before 19700101.
SELECT Description__c, Id, Name, Released_On__c FROM Album__c WHERE Released_On__c < 1970-01-01 ORDER BY Released_On__c ASC NULLS FIRST
When you execute the query, youll only see one record in the result set, the data record for the album named Help! The description for this album can be more helpful (pun intended), and indicate that this particular record corresponds to the North American release of the album and not the British release.
Next youll learn how to update a data record quickly using Workbench.
In this step, we want to update the record. 1. Click the Update link to display the Update page. 2. Update the Description__c field so that it is North American release.
14
3. Once youve made the change, click Confirm Update to execute the update. Youve finished this tutorial! Leave Workbench open so that you can quickly switch back to it in subsequent tutorials.
Summary
In this tutorial, you learned how to work with data in your organizations data objects using Workbench, an open source tool that you can use to access Database.com databases. Specifically, you learned how to insert, query, and update records in an object. In the next lesson, youll switch back to the Database.com Console and continue building your schema.
15
Now create two fieldsone for the price of the track, and another representing the relationship to the album. 1. In the Custom Fields & Relationships section, click New. a. b. c. d. e. f. Select Currency as the data type and click Next. For Field Label, type Price, and then press TAB. For Length, type 5. For Decimal Places, type 2. For Default Value, type 0.99. Click Next, accept the security defaults, and click Save.
2. In the Custom Fields & Relationships section, click New. a. For Data Type, select Master-Detail Relationship, and click Next. b. In Related To, choose Album, and click Next. c. For Field Label, leave the default as Album, and press TAB for the next field, ensuring that the Field Name has a value of Album too. d. Click Next, accept the security defaults, and click Save. The Field Label in the relationship field is how you will traverse to the related master record from any given detail record. You have now created a new object named Track, as well as two fields, Price and Album.
16
Repeat the steps above using the following values for the Name and Price fields to create two more records in the Track object. Name 02 The Thin Ice 03 Another Brick in the Wall (Part 1) Price 0.59 1.49
We could have just skipped entering a price for each new record to defer to the default value of 0.99, but well put in some varying prices so that subsequent queries are a bit more interesting. Now lets learn how to build some new queries with Workbench that target the records in the Track object. 1. Select queries > SOQL Query. 2. Execute the following query to summarize information about specific records in the Track object.
SELECT count(Id), max(Price__c), min(Price__c), sum(Price__c) FROM Track__c WHERE Album__r.Name = 'The Wall'
17
In the query itself, notice the following new concepts to understand about SOQL. The SELECT clause uses several functions (count, max, min, and sum) to aggregate information about the selected records in the Track object. The WHERE clause condition employs an object traversal with dot notation to target information in the Name field of the related Album object. Notice the __r suffix to indicate that this is a relationship. This points out one difference between SQL and SOQL: With SQL, you can use a subquery in the WHERE clause condition to build an equivalent query.
This SOQL query is the equivalent of an inner join in SQL. Notice again how it uses dot notation in the WHERE clause to specify an object traversal. Your results of this query will be similar to the following output.
18
Creating a Database and Test Database on page 5. Once you have the Database.com Console available, complete the following steps. 1. 2. 3. 4. 5. 6. 7. 8. Click App Setup > Create > Objects. Click Track. In Validation Rules, click New. For Rule Name, type No Negative Prices. For Error Condition Formula, enter Price__c < 0. Click Check Syntax and make sure you have no errors in your formula. For Error Message, enter Too cheap!. Click Save to finish creating the object.
The error condition formula specifies the condition under which the rule fires. In this case, it fires when the Price__c field is below zero. Note: The Database.com formula language is very rich, letting you look up and manipulate values used in the rule. Youll use the same formula language in fields of type Formula, as well as in the Workflow functionality in Tutorial 6 on page 31. Once you save the validation rule, youll see a summary page for the new rule. Notice that the rule is active, by default. Database.com enforces validation rules that are active, but allows you to deactivate them when you might feel it is necessary (for example, prior to a bulk data load).
19
Notice that the update is not successful this timeDatabase.com raises a validation rule exception (returns an error) because of our new validation rule. Perfectthats just the way we want it.
At this point, all of your Album records have an additional field, Price__c, which automatically calculates the total price of the album based on the sum of the prices for related tracks. As you saw during the creation of this field, you can use roll-up summary fields to count and find the minimum or maximum of particular fields. To test that the new summary field is working properly, return to Workbench and build the following query.
SELECT Id, Name, Price__c FROM Album__c
If you dont see Price__c in the list of Fields available for the query, clear the Workbench cache, and retry the query. Your output shows the price value that is automatically calculated for each album.
20
Note: When you add a roll-up summary field to a master table, Database.com schedules a background job to calculate the summary data for all existing records. You might have to wait a few seconds to see results similar to those above.
Summary
In this tutorial, you discovered how to relate two objects, and how a master-detail relationship is reflected in SOQL queries. You then learned how to declare validation rules that help ensure objects contain records that adhere to your business rules. Finally, you saw how to take advantage of roll-up summary fields to automatically aggregate detail record information as fields in the master records.
21
2. Click Clone next to the Database.com User entry. 3. For Profile Name, enter Vendor, and then click Save. The Database.com Console displays a page that lists the permissions that are available to users who have the Vendor profile. For example, you can use this to set permissible login hours, or the range of IP addresses from which Database.com permits sessions.
For the new Vendor profile, note how the Custom Object Permissions dont have any check marks next to the Album and Track objects. This indicates that users with this profile do not have access to any records at all. To test this, create a new user and assign him to this profile. 1. 2. 3. 4. 5. 6. Select Administration Setup > Manage Users > Users. Click New User. For First Name, type Jim and press TAB. For Last Name, type Smith. For Email, type your email address (so that you receive the activation email). For Username, type something memorable in the form of an email address, related to your current user. Note that this doesnt need to be an authentic email address, just something in the form of an email address. For example, our administrator username is admin-user@workbook.db, so we can call this new user jimsmith-user@workbook.db. 7. For User License, select Database.com User (the default). 8. For Profile, select the new Vendor profile you created earlier. 9. Click Save. Youve now created a new user, and assigned the user to the Vendor profile. Next, go to your own email account and look for the new users activation email message. Click the link and activate the new user through the default landing page for the Database.com Consoles set password page.
22
Once you set the initial password for a non-administrator, the Database.com Console redirects the session to the default landing page, which is the System Overview page. Because non-administrators dont have access to this page, youll likely see an Insufficient Privileges message. Dont worrysimply log out as the non-administrator and continue to the next step.
Note: To support an applications user password management page in a production setting, make sure to configure an alternative home page for Database.com password management using Administration Setup > Password Policies > Alternative Home Page.
In other words, because the new user has a profile that restricts object visibility, Database.com ensures that the object is not visible at all. Switch back to the Database.com Console browser window. Because you logged out earlier (after setting the password for the new user), youll have to log in again as the administrator. 1. Navigate to Administration Setup > Manage Users > Profiles. 2. Click Edit next to the Vendor profile. 3. Check the boxes in the Read, Create, Edit, and Delete columns for both Album and Track, and click Save.
23
Any user with this profile will now be able to create, read, edit, and delete any record of the Album and Track object. Now jump back over to your Workbench session (thats still tied to the Vendor profile) and simply re-execute the query. This time, it should successfully return all of the records in the Track object. If you still dont see all the records, clear the Workbench cache and then retry the query. Profiles and object visibility are very powerful ways of granting access for entire objects to sets of users.
Now return to your Workbench session and re-execute the same query. This time, the application will throw an exception.
If you reconnect as the administrator, which uses a more privileged profile, the query executes just fine. You can also remove Price__c from your query to make the query execute successfully.
24
Organization-wide (database-wide) sharing settings specify the default level of access to records, and can be set separately for different objects. To see how this works, lets do some work before and after making a configuration change. As a baseline, switch to the Workbench session, which should still be connected as Jim Smith. Execute the following query:
SELECT Id, Name from Album__c
The result set includes all data records in the Album object, even though our vendor, Jim Smith, doesnt own any of them. Thats because the default and current organization-wide sharing setting for the Album object is Public Read/Write. We dont want vendors to see records that they dont own. If you change the organization-wide sharing setting for Album to Private, then all users (other than administrators) will only see the records they own. In our scenario, Jim Smith doesnt own any records, and so shouldnt have access to any. Change the setting to verify this. 1. In the Database.com Console, as the administrator, navigate to Administration Setup > Security Controls > Sharing Settings. 2. Click Edit, and change the Default Access for Album to Private. 3. Click Save.
Note: When you set a master objects organization-wide sharing default to Private, Database.com automatically cascades this default to all detail objects that reference the master object. This means that, by default, a user wont be able to work with detail records unless the user can also access the master record. Now, go back to your Workbench session, still connected as Jim Smith, and re-execute the same query. Because Jim Smith doesnt own any records in the Album object, the query now doesnt return any records.
The records still exist, but the only user who can work with them is the person who owns them. To prove this last point, lets have Jim Smith create a new album and make sure that the new record is indeed visible to this user. 1. Back in your Workbench session, still connected as Jim Smith, click data > Insert. 2. For Object type, select Album__c, select Single Record, and click Next. 3. For the new albums fields, enter: Description__c: Far out
25
4. Click Confirm Insert. In the result, click the link for the new record to show its detail page.
And if you click the OwnerId link, youll see that Jim Smith is the owner. Because in the current Workbench session youre connected as Jim Smith, you can see this new record even though the organization-wide record sharing default is Private. Note: Users such as administrators, who use a profile with the View All or Modify All access rights for an object, can see all records in the object, despite the organization-wide record sharing setting of Private. Organization-wide record sharing access is a powerful way to control data visibility at the record level. But Database.com sharing features are far more powerful than just this. For example, you can extend sharing by writing code (Apex Managed Shares) that explicitly grants control of certain records to groups of users under particular conditions.
Using Hierarchies
A refinement to organization-wide default record sharing is the ability to grant access to object records using a role hierarchy. In Database.com, you can create a hierarchical structure of roles, and assign users to these roles to give them a position in the hierarchy. Database.com then automatically opens access for a user to any records owned by other users lower down in the hierarchy. For example, imagine a hierarchy in a company where a manager has access to records created by people that work for the manager. And above the manager, the CEO has access to all records that all managers have access toall records! Role hierarchies let you easily manage data sharing policies like this efficiently with very little administrative overhead. To set up a role hierarchy, click Administration Setup > Manage Users > Roles. You can create a role hierarchy, add users, and run the queries in your application as each of the users to see that the record visibility holds.
Summary
Database.com offers powerful ways of controlling data visibility. In this tutorial, you created a user and security profile, and modified that profile to control object-level visibility. You then refined the visibility by controlling field-level visibility. Finally, you changed the organization-wide default sharing settings to ensure users only saw records that they own. Role hierarchies let you refine this still further, as do sharing rules, queues, and groups.
26
7. Click Save & Next. Although youve created the rule, its not yet active, and it doesnt do anything when the criteria are met. So theres still some more work to do.
27
2. Click Create a RequestBin. 3. Record the resulting URL. For example, http://requestb.in/srbqexsr. Back in the Database.com Console, configure the outbound message. 1. If necessary, return to the Edit Rule Expensive Album Alert page. a. Navigate to App Setup > Create > Workflow > Workflow Rules. b. Click Expensive Album Alert. c. Click Edit in the Workflow Actions section. 2. 3. 4. 5. In the Immediate Workflow Actions section, click Add Workflow Action > New Outbound Message. For Name, enter Album Price Outbound Alert and press TAB. For Endpoint URL, enter your RequestBin URL (for example, http://requestb.in/srbqexsr). For Selected Fields, ensure that Id, Name, Price__c, and SystemModStamp are selected. These selections identify the field data that Database.com sends to the endpoint whenever it fires the rule.
6. Click Save, and Done. 7. Click Activate to make the new work flow rule active.
28
Your Database.com instance will now be able to communicate with the RequestBin site.
29
4. For Name, enter 01 - Dance on a Volcano. 5. For Price, enter 22. 6. Click Confirm Insert. The record is inserted and fires the Expensive Album Alert workflow rule. In another browser, visit the RequestBin URL you created in Step 2. This time, add a parameter, ?inspect, to the end of the URL. For example:
http://requestb.in/srbqexsr?inspect
Youll see the SOAP data, including the fields you specified.
When you use asynchronous background processing operations with Database.com, its a good idea to regularly monitor their status. You can monitor the status of Database.com outbound messages (and many other asynchronous operations) using the Database.com Console as follows. 1. Navigate to Administration Setup > Monitoring > Outbound Messages. 2. Review items scheduled for delivery and failures.
Because RequestBin does not respond to our outbound message (authentic SOAP servers would do so), Database.com thinks there is an error. Thats why youll see one or more failures and an outbound message remaining for delivery. To end the test, simply click the Del link in the Next items for delivery section. You might want to disable the workflow rule as well. If you were implementing this in a production environment, youd want to use the WSDL thats automatically generated by Database.com to generate the web service endpoint. Access the WSDL as follows:
30
1. Navigate to App Setup > Create > Workflow > Outbound Messages. 2. Click Album Price Outbound Alert. 3. In the Endpoint WSDL field, click Click for WSDL.
Summary
Workflow is a powerful, declarative, approach to executing actions when records meet specified conditions. In this tutorial you created a workflow rule that triggers an outbound SOAP message action in response to a field update.
31
Once youre sure you have everything in the change set, complete the following steps to send the change set to the production database. 1. In Change Set Detail, click Upload. 2. In Upload Details, select Production, the name of the production database.
32
3. Click Upload. When the upload completes, youll see a confirmation page.
5. Upon successful validation, click Deploy, and then OK to deploy the change set.
33
And thats it! Youve just migrated the custom objects and fields from your test database to the production organization. Now youre ready to develop some code in the next tutorial. Note: Change sets never include users in the source database.
Summary
In this tutorial, you learned about Database.com deployment connections and change sets, and how you use them to move changes from one database to another.
34
Embedded Salesforce Object Query Language (SOQL) and Salesforce Object Search Language (SOSL). Looping constructs that provide for bulk processing of record sets. A locking syntax that prevents record update conflicts.
In this tutorial, you create a simple database trigger to change some default behavior of the master-detail relationship between the Album and Track objects. As it stands now, when someone deletes an Album record, Database.com also deletes related tracks. Lets say that, for our business, its OK to delete albums that dont have any tracks, but we want to prevent the deletion of an album that does have tracks. We enforce this rule with a database trigger. Note: In traditional relational database parlance, Database.com enforces the delete cascade referential action for every master-detail relationship. In this tutorial, what we are doing is implementing the delete restrict action with a trigger. As a bonus, you learn about another great Database.com feature in this tutorial: the Recycle Bin. Youll see how to locate and recover deleted records from the Recycle Bin. You can download the code for this tutorial at https://gist.github.com/1132445 and https://gist.github.com/1132449.
where:
name is a unique name for the trigger. object is the object associated with the trigger. event is the event that determines when the trigger fires. Valid events include any combination of before/after and
insert/update/delete/merge/upsert/undelete. body is the Apex code that executes when the trigger fires. Use this to implement your business logic. Note: Its important to realize that a Database.com trigger can fire in the context of a single-row transaction or a bulk processing transaction. Consequently, you need to design all triggers with bulk processing in mind.
1. In your browser, navigate to https://gist.github.com/1132445. 2. Copy the code from the code window on this page into the Apex trigger window. Lets do a code walk-through so that you understand exactly what the trigger does and learn some Apex. The name of the trigger is DeleteRestrictAlbums.
35
The trigger is associated with the Album__c object. The trigger fires before the execution of a triggering statement that deletes one or more records from the Album__c object. The trigger body consists of a SOQL for loop that processes a set of albums. The compound WHERE clause of the loops defining query limits the return set to albums with tracks that the triggering statement is targeting for deletion (using Trigger.old). For each record in the result set, the body of the for loop adds an error to the corresponding album record, thus preventing Database.com from deleting these albums.
Click Quick Save to check your syntax before leaving the page. Once there are no errors, make sure to enable Is Active and then click Save.
Note: As with declarative workflow rules, you can deactivate and activate triggers to meet your situational requirements.
Next, try to delete an album that does not have any tracks to make sure that the trigger does not prevent the deletion of such albums. Dont worry, well recover the deleted album later in this tutorial.
36
The comments in the code explain the gist of the test methods. Notice that its important, when building and testing triggers, to keep in mind that triggers can fire as the result of both single-row and bulk triggering statements. Here are a few important points to understand about building unit tests. Use the @isTest annotation to define classes or individual methods that only contain code used for testing. Classes annotated with @isTest dont count against your Apex limit. Test classes must be top-level classes. Unit test methods are static methods that are defined with the @isTest annotation or the testMethod keyword.
After you enter the TestDeleteRestrictAlbums test class, test, save, and run it. 1. Click Quick Save to test the code for compilation errors. 2. Once the class compiles without errors, click Save. 3. Click Run Test on the TestDeleteRestrictAlbums class page to run the test class and see what happens.
When you run a test class, Database.com executes all of the unit test methods in the class and returns a report for the test run.
37
This first result set contains three records, all with IsDeleted equal to false. Now re-execute the query after setting Deleted and archived records to the Include option. The new result set includes an extra record, a record with IsDeleted equal to true. This is the record you deleted in Step 2a record thats in the Recycle Bin.
You have a few options for working with the Recycle Bin. Wait 15 days for Database.com to permanently delete the record. Use Workbench to manually restore or undelete the record. Use Workbench to manually purge or permanently delete the record.
Lets learn how to restore the record. 1. Hover over the link for the deleted record. 2. Click Undelete. 3. Click Confirm Undelete. If you re-execute the previous query, you can confirm that Database.com restored the record and updated the records IsDeleted field to false.
38
Note: The Database.com APIs provide complete access to Recycle Bin functionality, including bulk processing of Recycle Bin records.
Summary
Database.com triggers provide a way for you to centralize logic that should be executed under various conditions associated with a record. In this tutorial, you learned how to write triggers in Apex, the object-oriented programming language supported by Database.com. You also discovered how to write test classes for Apex code, as well as how to use the Recycle Bin.
39
Prerequisites
1. You need to have Maven installed. You can install the latest version from maven.apache.org. 2. You need to have completed Tutorials 1-3 of Part 1 on page 5.
40
The detail page for your remote access configuration displays a consumer key as well as a consumer secret (which you have to click to reveal). Youll need these in the next step. The callback URL is particularly importantas part of the OAuth 2.0 authentication dance, this URL will be invoked upon successful completion. In the next step, youll create an application that does all the OAuth work, including implementing this URL.
OR
41
In the command prompt window where you test your application, set a REPO environment variable to the repository path:
set REPO=c:\Users\<username>\.m2\repository
A servlet filter named AuthFilter is created. This has a connectionName parameter, the value of which needs to be defined in an environment variable. This variable ultimately references the login end point the application uses, and your OAuth credentials. Because the parameter has a value of FORCEDATABASE, you have to create an environment variable called FORCE_FORCEDATABASE_URL that holds these credentials. The format of the FORCE_FORCEDATABASE_URL environment variable is as follows:
force://<LOGIN_ENDPOINT>;oauth_key=<OAUTH_KEY>;oauth_secret=<OAUTH_SECRET>
Because were logging into the production database, <LOGIN_ENDPOINT> will be login.database.com. The OAuth key and secret must be set to the values of the consumer key and consumer secret in the remote application in Step 1 on page 40. As a result, your final environment variable value will look something like this:
force://login.database.com;oauth_key= 3MVG9CVKiXR7Ri5qcjfWDZa0rvFSordUA5LfVJe0GIZ4mwUvFzM6WIPEiYCNcYS.gzFtFEjEWrFMFvEku1.FY; oauth_secret=341524404139967490
Youre almost there! From the same command prompt, create an environment variable with this same value. In Unix-like operating systems, you can execute something like this in the command line:
export FORCE_FORCEDATABASE_URL="force://login.database.com;oauth_key= 3MVG9CVKiXR7Ri5qcjfWDZa0rvFSordUA5LfVJe0GIZ4mwUvFzM6WIPEiYCNcYS.gzFtFEjEWrFMFvEkU2.FY; oauth_secret=391524404139967490"
42
The final bit of configuration needed is to set the port number. We want the Web server to run on the same port you configured in the remote application Callback URL, which is 5000. From the command prompt, execute the following line (on Unix):
export PORT=5000
On Windows, run:
target/bin/webapp.bat
The Java application now runs. The OAuth servlet filter picks up the environment variables you set for the OAuth credentials, as well as the port number. If all goes well, youll see something like this in your log window:
As a result, as soon as you visit the website created by your application, you are redirected to Database.com, and invited to log in. To see this in action: 1. Open a browser. 2. Go to localhost:5000/. Once logged in (use your admin credentials for now), youll be asked whether youd like to grant your application permission to access the database. This is part of the typical OAuth flowyou have to explicitly grant an application permission to access your data.
43
3. Click Allow. Youll now be presented with the home page of the Web application, which allows you to query and create records on your Database.com instance. The application is basic, but provides you with a way to create a record, as well as perform a query. To query, insert a query in the text field and click Query.
For example, enter select name,description__c from album__c. The application creates an HTTP request (a GET request) to the appropriate resource on Database.com for queries, and then displays the raw output. Heres an output example.
{ "done": true, "records": [ { "Description__c": "Reggae rock", "Name": "Ghost in the Machine", "attributes": { "type": "Album__c", "url": "/services/data/v20.0/sobjects/Album__c/a00T0000004xb2TIAQ" } }, { "Description__c": "Swamp rock", "Name": "Green River", "attributes": { "type": "Album__c", "url": "/services/data/v20.0/sobjects/Album__c/a00T0000004xb2UIAQ" } }, { "Description__c": "Great cover art", "Name": "Who's Next", "attributes": { "type": "Album__c", "url": "/services/data/v20.0/sobjects/Album__c/a00T0000004xb2PIAQ" } }, {
44
"Description__c": "North American release", "Name": "Help!", "attributes": { "type": "Album__c", "url": "/services/data/v20.0/sobjects/Album__c/a00T0000004xb2QIAQ" } }, { "Description__c": "Great rock opera", "Name": "The Wall", "attributes": { "type": "Album__c", "url": "/services/data/v20.0/sobjects/Album__c/a00T0000004xb2RIAQ" } }, { "Description__c": "Far out", "Name": "A Trick of the Tail", "attributes": { "type": "Album__c", "url": "/services/data/v20.0/sobjects/Album__c/a00T0000004xb2SIAQ" } } ], "totalSize": 6 }
Note how the query must use the "API name" for fields and objects that you created. In most cases, this is found by appending __c to the names. The API names are also listed in the administration console of Database.com when you navigate to fields and objects. The output is in the JSON (JavaScript Object Notation) format. REST API can also use an XML format. You can also create new records in the Create New Record section:
1. The first field is the resource name. Enter album__c. 2. For the text box, enter the value of the fields in JSON format:
{ "name": "Out of the Blue", "description__c": "The best ELO album ever" }
3. Click Create. At this point, the application performs an HTTP POST on a URL that includes the resource name, album__c. The body of the POST message includes the JSON. The Database.com REST API automatically takes this data and creates the resourcein this case, a new record. If all goes well, youll see the response (also JSON) formatted and displayed like this.
{"id":"a003000000HGUp1AAH","errors":[],"success":true}
45
src/main/java/com/developerforce/dbworkbook/HelloController.java src/main/webapp/WEB-INF/views/home.jsp These files contain the user-facing Web application home page. The JSP page simply contains two forms. The Java file displays the home page, and then responds to the forms. For example, heres the method that runs when the query form is used:
@RequestMapping(value = "/q", method = RequestMethod.POST) public ModelAndView performQuery(ModelAndView mv, @RequestParam String query) { mv.setViewName("dumpresponse"); mv.addObject("json", rest.query(query)); return mv; }
This method ensures that the dumpresponse view is called to display output. The hard workthe actual queryis a result of a call to the RESTHelper instance, rest.query(query). src/main/java/com/developerforce/dbworkbook/HTTPClientFactory.java This Java class creates a singleton HTTP client. All REST APIs work on the basis of issuing simple HTTP actions. As a result, you need an HTTP workhorse to issue these actions. The only tricky bit here is the establishment of a request interceptor. Successful OAuth authentication results in two things: An Instance URL. This URL should be used for all subsequent REST calls. An OAuth access token. This token should be inserted into every HTTP header of every call to the REST API. It effectively identifies you as a valid client for the period the token is valid.
Both of these data are made available by the ForceSecurityContextHolder, part of the OAuth framework. Youll notice how the request interceptor ensures that an HTTP header is automatically set, and uses the access token (using getSessionId()):
request.setHeader("Authorization", "OAuth " + sc.getSessionId());
46
src/main/java/com/developerforce/dbworkbook/RESTHelper.java This class contains the meat of the interaction with the Database.com REST API. Well walk through the create() method here, line by line:
String createURL = httpClientFactory.getInstanceURL() + "/services/data/" + VERSION + "/sobjects/" + resource + "/";
This line establishes the URL that we want to POST to in the Database.com REST API. Every URL is based on the Instance URL, concatenated with "/services/data," concatenated with a version number of the API you want to use, concatenated with "/sobjects/," and finally, the name of the resource. For example, if you created a new object called Foo, it would be automatically represented by a URL such as https://na1.salesforce.com/services/data/v20.0/sobjects/Foo__c/. The next few lines create an HTTP POST request to this URL, specifying the JSON description in the payload:
HttpPost httppost = new HttpPost(createURL); httppost.setEntity(new StringEntity(recordDescription, "application/json", null));
The final set of lines just check for an error. Because youre simply performing HTTP actions, the response codes (weve all seen 404s!) determine success or not. If all goes well, we simply return the body of the response from the server, which is whats displayed in your Web application:
if (response.getStatusLine().getStatusCode() != 201) throw new Exception(EntityUtils.toString(response.getEntity())); return EntityUtils.toString(response.getEntity());
Thats it! Interacting with the Database.com REST API is a matter of: Using OAuth to perform authentication, which returns an instance URL and access token. Writing code to perform standard HTTP actions to a well-defined set of URLs defined by the Database.com REST API.
Summary
In this tutorial, you created, configured, and ran a Java Web application, and set up a Remote Access configuration on Database.com. The Web application used OAuth to authenticate against the database, and the Database.com REST API to execute HTTP GETs and POSTs to create records, and perform a query. These same techniques can be applied in other languages and platforms. The complete description of REST API, which also includes the full URL scheme, can be found in the documentation. See the Database.com REST API Developer's Guide for more information.
47
Next Steps
Next Steps
Now that youve completed this workbook, you should have a good introduction to Database.com concepts and a general idea of how to build applications using the Database.com REST API. To learn how to develop mobile applications for Database.com on iOS and Android, work through the Mobile SDK Workbook. To continue exploring, visit the Dev Center at www.database.com and view the official documentation for Database.com and the APIs, read the articles and tutorials, and check out the other resources there to help you build awesome applications.
48