Thursday, April 30, 2009

Database Updates, Redux

Before I came up with my solution for updating the embedded database in my iPhone app, I had a different strategy that I couldn't figure out how to implement. Of course, after I had the new solution in place, I figured out how to implement my first idea.

I wanted to figure out how to construct method names on the fly and invoke them. That way, I could have dbChangeScript0,dbChangeScript1, and so forth, and then invoke them in a while loop that ran until the application didn't have a method with the relevant name. I wanted JavaScript's eval function in Objective C. I didn't see how to do it, though.

Today, I discovered NSSelectorFromString, a function that transforms a string into a selector (essentially, a function pointer). I used it to implement Plan A as follows:

- (void) installChangeScripts {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

int versionNum = [self dbVersionNumber];
SEL curSelector = NSSelectorFromString([NSString stringWithFormat:@"dbChangeScript%d",versionNum + 1]);
while ([self respondsToSelector:curSelector]) {
[self performSelector:curSelector];
[self updateDbVersion:versionNum +1];

versionNum = [self dbVersionNumber];
curSelector = NSSelectorFromString([NSString stringWithFormat:@"dbChangeScript%d",versionNum+1]);
}
[pool release];

}


Is this a better version? I've lost the self-documenting method names such as makeVersionTable, but I've removed an in-memory array and a #define that I had to remember to update when I updated the array. In other words, I've increased the code's maintainability. (The code looks shorter, but only because I also factored out the version update into a new method.) Overall, I consider this a win.

The Ruby on Rails community has a mantra: convention over configuration. In Rails, you can get a full website up and running just by following a few naming conventions — ones you probably would have used anyway. A class of name X will translate to a database table named Y and so on. Compare that to Spring, a powerful Java framework that requires constant work in the XML-based configuration files.

In essence, I voted for the convention side of the fence in this code. By following a consistent naming scheme, I can write a small method that will do all the work. All I have to do is add a new method with a predictable name. Compare that to an array that I had to remember to configure properly.

No comments:

Post a Comment