Using Batch Apex

There’s a page on the web with the same title – Using Batch Apex. I tried to digest it in one sitting and it proved to be somewhat hard. So I went to Stack Overflow for help.

If you’re having the same problem, check out Dummy updates of Salesforce database records and execution governors. Nothing beats a simple working example. Just make sure you have an object called Acme_Portfolio__c with an Id field.

I’d like to elaborate on getting the most out it. Let’s say you just need to trigger updates. And you can use

Database.executeBatch(new batchClass());

to execute the batch and then check the results in Setup | Monitoring | Apex Jobs. What if you want to schedule it and get some kind of report on the executed (or failed) batches?

Turns our it’s pretty easy. Just wrap it in a class that implements Schedulable interface.

global class batchSchedule implements Schedulable
{
global void execute(SchedulableContext SC)
{
Database.executeBatch(new batchClass());
}
}

Now you can use the finish() function to add reporting functionality.

global void finish(Database.BatchableContext BC)
{
AsyncApexJob a = [SELECT Id, Status, NumberOfErrors, JobItemsProcessed, TotalJobItems, CreatedBy.Email FROM AsyncApexJob WHERE Id = :BC.getJobId()];
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
String[] toAddresses = new String[] {a.CreatedBy.Email};
mail.setToAddresses(toAddresses);
mail.setSubject('Apex Batch Update of Acme Portfolio ' + a.Status);
mail.setPlainTextBody('The batch Apex job processed ' + a.TotalJobItems +
' batches with '+ a.NumberOfErrors + ' failures.');
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
}

The code is pretty much self explanatory and doesn’t require any changes to work. It pulls out all the stats on the executed batches, then gets an email of the user who created the class. Messaging.sendEmail() takes care of the rest.

Hope this helps someone gets a quick hold of Batch Apex.

Efficiency of Locomotion

Steve Jobs makes a great point about computers increasing human brain efficiency just like bicycles increase the efficiency of locomotion.

Interestingly there is some locomotion involved while working with computers. Mostly hand movements and eye movements. It’s obvious that keyboard is superior to mouse in this respect, you don’t need to move much when you type and you do when you, for example, scroll around and copy/paste text using contextual menu.

Not that we don’t need motion. We certainly do and I love workouts. But there are times when you need more concentration and mousing around doesn’t help.

You probably know a lot of those who praise Vi/Vim as a best editor. I think of joining them. Check out how it looks like
vi editor

Not only editing text or code in Vi doesn’t involve mice but even arrow keys are not in favor. Moving around the text gets done by the middle row keys, which require the least hand motion possible.

Another great example of an app that’s designed for keyboard. It’s Notational Velocity – a very simple and incredibly useful tool for note taking. Here’s a screen shot

And the last app I wanted to mention is Alfred. It lets you find files, launch applications and much more just by typing parts of their names.

Please let me know what tools you use.

Statement of Accomplishment

In October 2011 I had a great luck of discovering free courses from Stanford School of Engineering. I was a bit late to register for Artificial Intelligence course so I signed up for Machine Learning. I didn’t find out about the third one, Databases class, until some time later.

In my college in Russia we didn’t have much of Machine Learning, although we had a separate subject on Neural Networks and, of course, Linear Algebra. So much fun to brush up the old skills and remember those good old days.

The course finished in the middle of December but it wasn’t until this morning that I got an email with a certificate -

Statement of Accomplishment Machine Learning Stanford School of Engineering

I can’t thank enough the team behind the Machine Learning course, although they probably can’t keep up with all praise and compliments themselves. The course is really engaging and well structured. Not to mention interactive video lectures, awesome programming exercises and very active community.

I’ve signed up for Design and Analysis of Algorithms I for January-February and I recommend you to check out many new courses starting 2012.

PhpMyAdmin Configuration Storage

I use phpMyAdmin (or pma in short) quite a lot. And I hope I will have some time to contribute to the project in the future. For those who don’t know, it’s an indispensable tool for those who use MySQL databases and have php installed.

Today I’ve discovered phpMyAdmin configuration storage. Now you can have a database that stores your configuration, but instead of replacing the config.inc.php the configuration storage rather extends it.

For a whole set of new features (bookmarks, comments, SQL-history, tracking mechanism, PDF-generation, column contents transformation, etc.) you need to create a set of special tables. Those tables can be located in your own database, or in a central database for a multi-user installation (this database would then be accessed by the controluser, so no other user should have rights to it).

Yes, the SQL-history. Just what I was waiting for. Tracking sounds promising, too.

If you don’t have this working, you should probably update your pma. If you see this
pma config storage warning
you’re on the right track.

Now find ./scripts/create_tables.sql file in your pma folder and import it using phpMyAdmin itself. Make sure to copy the sample config

cp config.sample.inc.php config.inc.php

as it has all the references for the tables you have just created. And finally run the following SQL query

GRANT USAGE ON mysql.* TO 'pma'@'localhost' IDENTIFIED BY 'pmapass';
GRANT SELECT (
Host, User, Select_priv, Insert_priv, Update_priv, Delete_priv,
Create_priv, Drop_priv, Reload_priv, Shutdown_priv, Process_priv,
File_priv, Grant_priv, References_priv, Index_priv, Alter_priv,
Show_db_priv, Super_priv, Create_tmp_table_priv, Lock_tables_priv,
Execute_priv, Repl_slave_priv, Repl_client_priv
) ON mysql.user TO 'pma'@'localhost';
GRANT SELECT ON mysql.db TO 'pma'@'localhost';
GRANT SELECT ON mysql.host TO 'pma'@'localhost';
GRANT SELECT (Host, Db, User, Table_name, Table_priv, Column_priv)
ON mysql.tables_priv TO 'pma'@'localhost';

Don’t forget to replace pma, pmapass and localhost with your own values. And you should be good to go now.

On Apex Test Classes

I have finished writing my first trigger in Apex today. Here’s the first line

trigger UpdateYearlyDepositsAverage on Bank_Branch_Monthly_Deposits__c (after insert, after update)
{
...
}

Once more information on recent deposits is available, the trigger updates a field. The trigger works just fine so it’s not that interesting to me. What still bothers me is the Test Class for the trigger. Here it is

@isTest
private class UpdateYearlyDepositsAverageTest
{
static testMethod void testInsertRecord()
{
Bank_Branches__c branch = new Bank_Branches__c(Id = 'a1S50000000Q9DdEAK', Name = 'Test', Average_Deposits__c = 100);
Monthly_Deposits__c d = new Monthly_Deposits__c(Bank_Branches__c = branch.Id, Name = '2012-01', Year__c = 2012, Month__c = 1, Amount__c = 1000);
insert d;
}
}

Let me quickly explain some details. Bank_Branches__c is a custom object representing a branch with many different fields, although I only used Id, Name and Average_Deposits__c for the test class. Then, Monthly_Deposits__c object stores the statistics of monthly deposits for different branches. I used a reference field Bank_Branches__c, Name field, as well as Year__c, Month__c, Amount__c. All is pretty clear, but this

Id = 'a1S50000000Q9DdEAK'

I couldn’t make it to work without this Id. I took it from an existing object instance in the database. What’s interesting, the Test Class runs fine now but it doesn’t change the database entry with that Id. Why and how do I write a test without pulling a particular Id from the database?

I’ll keep you posted.

Installing WordPress on a Mac over SSH.

I have a Mac Mini as a web server. It runs Apache and MySQL and today I decided to install WordPress as well.

Here’s the steps I took:

1. Connect to server via SSH and go to a folder where you want to install your blog. In my case it’s ~/Sites/blog

ssh username@hostname
mkdir ~/Sites/blog
cd ~/Sites/blog

2. Download the latest WordPress to the server, unpack it, move the contents of wordpress folder to your blog folder and remove the empty folder along with the archive.

curl -o wordpress.tar.gz http://wordpress.org/latest.tar.gz
tar -xzvf wordpress.tar.gz
cd wordpress
mv * ..
cd ..
rm -r wordp*

3. Edit wp-config.php to include the MySQL settings of database name, user and password you plan to use.

cp wp-config-sample.php wp-config.php
vi wp-config.php

4. Add the domain to /etc/hosts

127.0.0.1 themworks.com
127.0.0.1 www.themworks.com

I have a few virtual hosts in /etc/apache2/extra/httpd-vhosts.conf. Add another one

<VirtualHost *:80>
ServerName themworks.com
ServerAlias www.themworks.com
<Directory /Users/username/Sites/blog>
Options +FollowSymlinks +SymLinksIfOwnerMatch
AllowOverride All
</Directory>
DocumentRoot /Users/username/Sites/blog
</VirtualHost>

Finally, restart Apache

sudo apachectl -k restart

5. Now, configure MySQL. You can use PHPMyAdmin, I didn’t have it so I’m back at terminal

/usr/local/mysql/bin/mysql -u username -p

After entering a password I can execute SQL

CREATE DATABASE blog;
GRANT ALL PRIVILIGES ON blog.* TO "username"@"localhost" IDENTIFIED BY "password";
FLUSH PRIVILEGES;
exit

6. Now it’s time to change the DNS settings with your registrar and when the ping returns the Mac Mini’s ip address go to http://themworks.com and find a fresh installation of WordPress. Pretty easy.

Please let me know if you think I missed something.