Thursday, January 24, 2008

Flex 3 Pre-release Tour

Last night I attended the Flex and AIR Pre-release Tour hosted by the Salt Lake City Flex/Flash User Group. The presenter was Adobe Evangelist, Kevin Hoyt. He was very good and the meeting was very worthwhile. Hoyt knows his stuff and presents it well and with a sense of humor.

Watching Hoyt use Illustrator to create and style a button confirmed for me just how tedious developing user interfaces is, no matter what tools you use. After several minutes he ended up with a really nice looking button. But thinking about having to go through the same steps to put a skin on each interface widget made my head hurt. I'd rather debug kernel code. I really would. But that's just me.

But it got me thinking, why is the developer taking the time to stylize or skin the app anyway? Why don't developers just create the basic framework of the interface and let the users skin the app the way they want it to look? Well, of course that's not as easy as it sounds and some new tools would be required to make it simple and fun for users to do so. And maybe for another reason which I thought was Hoyt's most interesting idea.

Hoyt's idea, which I had never heard before, is about the way economies evolve. He explained that when the U.S. was young it had an agrarian economy. This evolved into a goods-based economy. Next came the service-based economy, where most 'products' in the economy are really services.

I had heard all this before, but then he said we are moving into an Experience-based economy.

You go to Starbucks and pay $5 not for a cup of coffee, but for the Experience of getting a Starbucks coffee. The smells, atmosphere, music, all that sort of thing. Or you go into an Apple store to get the gadget-buying Experience that you can't get at Best Buy.

I'm not sure I fully buy into the Experience-based economy idea. But, it makes more sense why a developer would spend so much time on the look-and-feel, the skin, of an application. You may want to provide a specific experience to the user. A memorable way of branding your product or company. I'll definitely be thinking more about the overall experience of the user as I develop applications from now on.

Oh yeah, and Flex 3 and Air look like good products to me. I think we made the right decision in our company to develop our next major app for the Air platform.

Friday, January 18, 2008

Speed Up MySQL Query Using Where Clause

This is going to sound obvious but to me it wasn't at first. The situation was, I wanted to see the top 1000 rows of a join on three tables, all of which had many thousands of records in them. The query did not finish in reasonable time until I added a where clause that didn't limit the result set in any way, but certainly sped up the response.

Here's an example to demonstrate the details.

My tables looked similar to this:

CREATE TABLE `Customer` (
`cId` int(11) NOT NULL auto_increment,
`cName` varchar(255) default NULL,
PRIMARY KEY (`cId`)
)

CREATE TABLE `PaymentBatch` (
`pbId` int(11) NOT NULL auto_increment,
`pbStatus` varchar(255) default NULL,
`pbCreatedDate` datetime default NULL,
`pbCompletedDate` datetime default NULL,
PRIMARY KEY (`pbId`)
)

CREATE TABLE `PaymentBatchDetail` (
`pbdId` int(11) NOT NULL auto_increment,
`pbdPaymentBatchId` int(11) NOT NULL,
`pbdCustomerId` int(11) NOT NULL,
`pbdReceivedDate` datetime default NULL,
`pbdAmount` decimal(12,3) default NULL,
PRIMARY KEY (`pbdId`)
)


And this was my first try at the query; I just wanted to see the most recent 1000 rows from the join of these tables:

select *
from Customer left join
(PaymentBatch left join PaymentBatchDetail on pbId = pbdPaymentBatchId)
on cId = pbdCustomerId
order by pbdReceivedDate desc
limit 1000;


Well, this took so long I killed it before it completed.

But adding a simple "where pbId > 0", which doesn't eliminate any rows from the query, made it run in under two seconds. Go figure.

Faster query:

select *
from Customer left join
(PaymentBatch left join PaymentBatchDetail on pbId = pbdPaymentBatchId)
on cId = pbdCustomerId
where pbId > 0
order by pbdReceivedDate desc
limit 1000;

Friday, January 11, 2008

Apache and Subversion

Well, nothing good comes easy. Here's a very abbreviated recipe for setting up Apache as a SVN front-end, listening on port 7382.

In your apache source directory:
./configure --prefix=/usr/local/apache_svn --enable-mods-shared=all --with-included-apr --with-port=7382
make
make install

Following is because subversion puts its apache modules in apache2 by default.
cd /usr/local/apache_svn/modules ; ln /usr/local/apache2/modules/*svn.so .

In /usr/local/apache_svn/conf/httpd.conf uncomment:
Include conf/extra/httpd-dav.conf in httpd.conf

Add to httpd.conf:
LoadModule dav_svn_module modules/mod_dav_svn.so

DAV svn
SVNPath /absolute/path/to/repository

User svn_user #Have apache run as a user with rw access to svn repository.
Group svn_user

Thursday, January 3, 2008

Subversion Configuration

I'm setting up a Subversion repository. Hooking up Apache seems too complex right now, so that will come later. I'll set up svn+ssh for now.

Server setup (root)
svnadmin create /usr/local/svn/test
chown -R nucleus:nucleus /usr/local/svn/test
chmod g+w -R /usr/local/svn/test/

User setup (root)
Create each user account as needed, then
usermod -gnucleus -Gusers mike
[Repeat for each svn user]

Each user does their own setup (user)
Append your ssh public key to authorized_keys in your .ssh directory.
ssh-keygen -t dsa [if necessary]
scp ~/.ssh/id_dsa.pub nukson:.ssh/
ssh nukson "cat ~/.ssh/id_dsa.pub >> .ssh/authorized_keys"

Wednesday, January 2, 2008

Old Dog Learns New Trick

Here's something I should have known years ago.

Use hard links instead of cp to make fast "copies" of files.

I have files saved in directory archive/ that I copy to a work/ directory, then process them, then delete them from work/ but keep indefinitely in archive/.

These are large files so cp takes a while. What I should have been doing all along is using ln to create links in work/ to the files in archive/. This is much faster since there is no real copying. It works out OK because the processing is a read-only operation on the files so nothing is changed in archive/.

(This is all scripted in a Ruby script, of course.)

Blog Post #1

Well, I've decided to take the leap, so here goes...

(Semantic linguine is a word play on "spaghetti code", which I would never author.)