Rails and DB2 data types

May 28th, 2007 by Leons Petrazickis

When creating a table in a Rails migration, you have to specify data types using platform-agnostic names. The mapping of Rails types onto DB2 types is defined in ibm_db_adapter.rb:

:primary_key => @servertype.primary_key,
:string      => { :name => "varchar", :limit => 255 },
:text        => { :name => "clob" },
:integer     => { :name => "integer" },
:float       => { :name => "float" },
:datetime    => { :name => "timestamp" },
:timestamp   => { :name => "timestamp" },
:time        => { :name => "time" },
:date        => { :name => "date" },
:binary      => { :name => "blob" },

# A boolean can be represented  by a smallint,
# adopting the convention that False is 0 and True is 1
:boolean     => { :name => "smallint"},
:xml         => { :name => "xml"},
:decimal     => { :name => "decimal" }
 

Useful Resources

InfoCenter | DB2 Data Types
dW | DB2 and Ruby on Rails, Part 1 (May 2007)
dW | An Introduction to Ruby on Rails for DB2 Developers (June 2006)

The DB2 adapter is now called ibm_db. You can refresh your installation by typing gem install ibm_db at the command line and choosing the latest win32 release.

Posted in db2, ruby | No Comments »

The Web is Dead; Long Live the Facebook

May 25th, 2007 by Leons Petrazickis

TechCrunch | Facebook Launches Facebook Platform

developers.facebook.com

Facebook is going to do to the Web what the Web did to the Internet.

When the Web with its HTTP showed up, it was just one among Email, Usenet, FTP, Telnet, Gopher, and many others. Now, most people think of the other things as applications running on top of the Web.

Facebook is a social-network driven by real-life relationships. I have my real-life friends, my classmates, and my coworkers on it. At least 20% of Torontonians are on it already. When one of my contacts posts a photo, joins a group, accepts an event invitation, or changes their status, I can see it on the front page. I check it daily.

They are about to add third-party applications to the site. They’ll nest in tidy spots on our profiles or improve on Facebook’s features. More than that, whenever I choose to use a third-party app, all my contacts will be notified via their front page.

This is unobtrusive, extremely viral, and has zero distribution cost. If I add the Last.fm widget, all the Last.fmers on my contacts list will add it too within a week.

Facebook is still just one among billions of sites. Shortly, it’ll be a platform. Digg, Delicious, Last.fm, Flickr, Gmail, et al. will be reduced to applications running upon the one true site — Facebook.

Is this a good thing? It’s easy and convenient, but it’s also centralized — the bad guys will need only one subpoena to find out things they should not.

Can it be stopped? Facebook’s reached critical mass. Usenetters have tried boycotting the Web, and yet the Web has soared past Usenet’s slow oblivion. Attempts to boycott Facebook are unlikely to succeed if a plurality uses it and gets locked in by it.

I, for one, welcome our new Facebook overlords. As a trusted web guru, I could be helpful in rounding up others to toil in their underground API caves.

Posted in opinion | No Comments »

Reflection in Javascript

May 11th, 2007 by Leons Petrazickis

It’s very easy to do reflection in Javascript. Reflection is when your code looks onto itself to discover its variables and functions. It allows two different Javascript codebases to learn about each other, and it’s useful for exploring third-party APIs.

Preamble

In Javascript, all objects are hashes/associative arrays/dictionaries. A hash is like an array, except that values are associated with unique key string rather than a numeric index.

Adding a new variable to an object is as simple as assigning a new value to a key in the object.

You can declare everything in place:

var o = {
        count: 0,
        name: ‘Jane Doe’,
        greeting: function() { return "Hi"; }
};
o.greeting();
 

Or you can start with a blank object and assign things later:

var o = {};

o.count = 0;
o.name = ‘Jane Doe’;
o.greeting = function() { return "Hi"; };

o.greeting();
 

Or you can do the same, but in a different notation:

var o = {};

o[‘count’] = 0;
o[‘name’] = ‘Jane Doe’;
o[‘greeting’] = function() { return "Hi"; }

o.greeting();
 

The last is especially handy because it allows you to go from the string name of the variable to the variable without the performance penalties of eval().

{} is synonymous with new Object().

Reflection

The loop below pops up a dialog box with the name and value of every variable in object:

for (var member in object) {
        alert(‘Name: ‘ + member);
        alert(‘Value: ‘ + object[member]);
}
 

Everything in Javascript is an object. Functions are objects! document and window are objects. The most reliable reference for Javascript in a given browser is reflection into its innards.

Finally, some slightly more useful code:

/**
        Returns the names of all the obj’s
         variables and functions in a sorted
         array
*/

function getMembers(obj) {
        var members = new Array();
        var i = 0;
       
        for (var member in obj) {
                members[i] = member;
                i++;
        }
       
        return members.sort();
}

/**
        Print the names of all the obj’s variables
         and functions in an HTML element with id
*/

function printMembers(obj, id) {
        var members = getMembers(obj);
        var display = document.getElementById(id);
       
        for (var i = 0; i < members.length; i++) {
                var member = members[i];
                var value = obj[member];
                display.innerHTML += member + ‘ = ‘;
                display.innerHTML += value + ‘<br>’;
        }
}
 

More sophisticated uses are left as an exercise for the reader. :-)

Posted in javascript | 1 Comment »

Changing redirects in a Rails scaffold

May 4th, 2007 by Leons Petrazickis

After a successful form entry, a Rails scaffold redirects you to the list view of all items. This is controlled by app/controllers/customers_controller.rb, where “customers” is the name of the scaffold. You can easily change it to redirect to the edit view or the show view.

  def create
    @customer = Customer.new(params[:customer])
    if @customer.save
      flash[:notice] = ‘Customer was successfully created.’
      redirect_to :action => ‘list’
    else
      render :action => ‘new’
    end
  end
 

You want to change the redirect action from:

redirect_to :action => ‘list’
 

to

redirect_to :action => ’show’, :id => @customer
 

where ’show’ is the view that you want and customer is your model.

Posted in ruby | No Comments »

No implementation defined for org.apache.commons.logging.LogFactory

May 3rd, 2007 by Leons Petrazickis

While writing a DB2 stored procedure that invoked a SOAP/WSDL web service using Apache Axis as part of WSIF, I ran into this doozie:

org.apache.commons.discovery.DiscoveryException:
No implementation defined for org.apache.commons.logging.LogFactory

Ultimately, it’s caused by a too restrictive lib/security/java.policy file that ships with DB2.

Wrong Solution

The standard way to define an implementation is to create the following commons-logging.properties file and place it anywhere in your CLASSPATH (such as the root of a JAR file):

# Default
#org.apache.commons.logging.LogFactory = org.apache.commons.logging.impl.LogFactoryImpl

# SimpleLog
#org.apache.commons.logging.Log = org.apache.commons.logging.impl.SimpleLog

# JDK 1.4 logger
#org.apache.commons.logging.Log = org.apache.commons.logging.impl.Jdk14Logger

# Avalon Toolkit
#org.apache.commons.logging.Log = org.apache.commons.logging.impl.LogKitLogger

# Log4j (Recommended by Axis)
org.apache.commons.logging.Log = org.apache.commons.logging.impl.Log4JLogger

Alternatively, you can set the org.apache.commons.logging.Log configuration attribute for LogFactory programmatically.

Right Solution

Solution: Running an Axis SOAP client in Domino [or DB2]

My DB2 is installed into C:\Program Files\IBM\SQLLIB

1. Copy all your JARs to C:\Program Files\IBM\SQLLIB\java\jdk\jre\lib\ext
2. Open C:\Program Files\IBM\SQLLIB\java\jdk\jre\lib\security\
3. Open java.policy
4. Add:

permission java.util.PropertyPermission "java.protocol.handler.pkgs", "write";

5. Restart DB2

Posted in java | 1 Comment »