Tuesday, May 05, 2009

Some Core Javascript Functions

I recently worked on two different projects that involved a fair amount of Javascript centering around using the Google Maps API. In doing so I began to factor out some of the components to be reusable in a general Google Maps project. While I usually use the excellent Prototype Javascript library I didn't want to leak Prototype code into these reusable components. This led me to using these functions, borrowed / evolved from various places, as the core functions to support the components:



I think these functions are a pretty good representation of the baseline support you will want in many Javascript projects.

Monday, April 13, 2009

Javascript Puzzler

Invoking an anonymous JavaScript function is a handy technique for avoiding namespace collisions in JavaScript code. The following two code snippets show the definition of a top level function followed by the invocation of an anonymous function. One of them, however, has a (easily fixed) problem (at least on Firefox 3.0.8). Can you spot what it is? Try figuring it out without running the code - don't cheat! Put your answer in the comments.

Snippet one:



Snippet two:



Surprising behavior. I'd be interested to find out if different browsers / JavaScript engines treat these code snippets in the same way.

Friday, April 10, 2009

I Canz haz Ur Nullz at Bottom?

SQL Server when doing ORDER BY will put rows with null values in the sort column at the top - of course a simple adjustment to your ORDER BY can fix that:



Aloha on Rails is coming! I'll blog a bit more about this in the future but this should be a great conference with great sessions and Waikiki Beach just across the street!

Tuesday, April 07, 2009

Rails - Read More, Code Less, do Peer Reviews

For some previous projects I rolled some simple code for generating a random string - used to generate a password reset token for example:



Now I've found that this type of functionality has been in Rails for some time - now as ActiveSupport::SecureRandom and previously as Rails::SecretKeyGenerator.

Ok so that is simple code and probably isn't a problem but the lesson here is: read more, code less, do peer reviews...don't waste a lot of time re-inventing the wheel.

Monday, April 06, 2009

Rails ActiveRecord Order by a Function

Of course you can pass functions in the order clause through ActiveRecord finders:



In the above case a Foo has fiscal_year and fiscal_month columns unfortunately stored as VARCHAR(255) containing, for example "2008" and "7". While the sorting will work that query will be able to leverage an index on these columns only if the database used can create indices that include functions. I'm not sure which databases can do this. From a quick look at the SQL Server and MySQL documentation it doesn't appear that either of these databases can do this.

Monday, March 30, 2009

Rails Caching and MySQL GROUP_CONCAT

A recent caching solution that we came up with involved using the hash of the concatenated "children" ids of another resource to identify when the identical and previously stored children payload could be delivered instead of constructing the payload from scratch (which is kind of expensive). Our current solution uses action caching and a custom ActionController::Caching::Fragments::FileStore. In our custom FileStore we override the real_file_path(name) method to use this "children signature" as part of the name. The class looks something like this:



This seems to work well and the next step is likely to look at using the children_sig value for the ETag as well.

One interesting thing that came out of this investigation was that I wondered if I could produce the hash using straight SQL - should be much faster right? Turns out that with MySQL there is a built in aggregate function that concatenates a column and it is called GROUP_CONCAT. To generate that hash in the database with MySQL the following will work:



Pretty cool! I'm not sure which other database products support this as a built in aggregate function but it doesn't appear that SQL Server does.

I found the following recent blog posts talking about other uses for GROUP_CONCAT as well:

http://tempe.st/2009/03/the-thrill-of-a-new-technology-couchdb/
http://www.christianmontoya.com/2007/09/14/mysql-group_concat-this-query-is-insane/
http://db4free.blogspot.com/2006/01/hail-to-groupconcat.html

Saturday, March 28, 2009

Display Google Docs Spreadsheet Data on Your Website

The Google Spreadsheet API makes it pretty painless to display spreadsheet data on your own web pages using only client side technologies. You might use this, for example, to display your terrible stock investments on one of your web pages to remind you why you have to go to work everyday.

The first thing you need to do is to make a Google Doc Spreadsheet. The second thing you need to do is to "Publish" the spreadsheet. This will make your spreadsheet available for anyone to view and is required if you are going to consume this data with unauthenticated Javascript running in a web page (so you probably don't want to do this with a sheet that contains your world domination secrets). To publish your spreadsheet, click on Share -> Publish as a Web Page -> Publish Now. Depending on the data you may also wish to check "Automatically re-publish when changes are made." For my example you certainly want to do this because the spreadsheet contains stock symbol lookup functions where the numbers will change as your stock investments go lower and lower.

After you have published your spreadsheet you need to get two pieces of information about the spreadsheet - the spreadsheet identifier and the identifier of the individual worksheet within the spreadsheet that you want to snarf the data off of. While it is possible to get at this information by pulling down meta-feeds about your spreadsheet documents it is probably easier if you just navigate to your published spreadsheet and choose View -> Source from your browser. In the source look for a link tag with rel="alternate". This tag will have an href that contains both the spreadsheet and worksheet identifier. An example looks like this:



In that href the "pBYwcZBFkvxZycw-gNxPCIw" is the spreadsheet identifier and the "od6" is the worksheet identifier. With these pieces of information you are now ready to write some code to pull the spreadsheet data back to your web page.

There are two different feeds that you can get to pull that data back to your site. They are identified as "list" and "cells" feeds. This basically breaks down to whether you get the data back as a series of rows or a series of cells. I believe in most cases you are going to want to work with a series of rows so you will use the "list" feed, however, check the API if you believe the "cells" feed may work better for you. The code below shows the feed URL being used to cause a callback to the function processStocks:



I won't go overboard explaining this code here - I think you can figure most of it out. It merely iterates through the returned result set from the spreadsheet, adding each stock value as to an unordered list in the page. It also keeps a running count of the total in a variable called bindex - the Burger Index. The way the cell entries are referenced is a little awkward and corresponds to the column headers - as seen in my example entry.gsx$symbol.$t and entry.gsx$price.$t. Part of this awkwardness comes from the format being a translation of the alternate XML format.

Currently you can see this code in action on my github page as well as list and cells feeds examples here.