Archive for July, 2008
Twitterified…at last!
I cannot believe that it took me so long to get my ducks in a row.
First, Twitterified was entirely written in Javascript, like most AIR clients. But some testing showed that rewriting in AS3 would dramatically increase responsiveness.
Then, I had to work on my web framework while creating twitterified.com. And finally I was only able to offer a decent video thanks to the overall godness offered by Vimeo.
But hey, here it is! For a limited period of time, if you go to the invite page and enter the code “nexus”, you will be automatically added to the private beta program.
Twitterified powers up your Twitter experience, allowing it to compete with the “new kids”: Pownce, Friendfeed, etc.
If you enjoyed this post, make sure you subscribe to my RSS feed!
How I added real ActiveRecord support to adodb
For my new projects, I have decided to use PHP5, mostly because at least a couple projects will be worked on by a team and the learning curve is fairly forgiving.
I decided, however, to follow the model offered by Rails. I looked into a few PHP frameworks, such as Akelos, but realized that they were too constraining for our purpose. That’s when I decided to develop my own thin layer framework.
An excellent productivity tool is the ActiveRecord pattern. After all, it doesn’t matter what it is, that’s being mapped; whether it’s database tables or web services should not be relevant to the controller.
I have, in the past, used adodb successfully and I was happy when I realized that it comes with a ADOdb_Active_Record class.
Unfortunately, that class does a very basic job of mapping one class to a database table and that’s it. Therefore, support for has_many or belongs_to clauses.
I know that AR offers more features that those but I thought that these fit the very minimum requirement for them to be useful.
And that’s how I ended up modifying ADOdb_Active_Record to support these.
This article is mostly a series of listings that show the modifications-a bit-and how to use them-a bit more. First, here is how I am using them in my framework:
Let’s imagine a database that contains songs, artists and genres. Let’s look at the definition of a Song object:
<?php class Song extends ActiveRecord { function __construct() { parent::__construct('song'); $this->belongsTo('artist'); $this->belongsTo('genre'); } } ?> |
and an Artist object:
<?php class Artist extends ActiveRecord { function __construct() { parent::__construct('artist'); $this->hasMany('songs'); } } ?> |
let’s have a look at a very basic controller that will allow us to retrieve our artists. Their songs will also be retrieved, since artists are defined as having many songs:
<?php class ArtistController extends ApplicationController { function index() { $artist = new Artist(); $this->artists = &$artist->find(ALL, "artists.id=1", array('loading'=>ADODB_LAZY_AR)); } } ?> |
Through the magic of my framework, which is outside the scope of this post, we will then be able to display our artists with their respective songs like so:
<div id="colOne"> <?php foreach($artists as $artist) { print "<h1>{$artist->name}</h1>"; foreach($artist->songs as $song) { print " TITLE:{$song->title}<br />"; } } ?> </div> |
Note that, for this example, I removed as many irrelevant pieces of code as possible. For instance, we are always retrieving artist #1. The array that we are passing to the find() statement allows us to configure some of AR’s behaviours. In this example, we are passing ADODB_LAZY_AR, which is a hint that we do not wish to perform massive joins, but retrieve related objects on demand. If we wished to retrieve everything upfront, we could have used ADODB_JOIN_AR instead.
Now, our model classes are subclasses of ActiveRecord, which is another one of my framework classes, which provides a light abstraction on top of ADOdb_Active_Record. The relevant piece, for you, would be this one since we invoke it:
function find($mode, $condition=null, $extra=array(), $bindArr=false, $pKeyArr=false) { // id? if(ctype_digit($mode)) return $this->load($mode); // return one row if(FIRST == $mode) return parent::load($condition); // Assumption: ALL == $mode - return multiple rows return parent::find($condition, $bindArr, $pKeyArr, $extra); } |
It is interesting because the last line contains the actual call to ADOdb_Active_Record’s find() method.
In adodb itself, two files were modified: adodb-active-record.php and adodb.inc.php.
The former now contains two new structures: _hasMany and _belongsTo. ARs are now aware of the concept of foreign name, which is the name by which this object will be known to another object if a relationship is defined. This allows us, among other things, to naturally inflect tables names.
The latter was modified so that it accepts extra parameters, for instance in GetActiveRecordsClass(), and handle massive joins. Note that joins can be deferred through the use of ADODB_LAZY_AR. In which case I will use the model objects’ __get() method to load missing properties on-demand.
“Buyer Beware”
I hope to publish my full PHP framework in the near future; in the meantime, this hacked version of adodb has been very helpful in my work. I hope you too find it helpful. Beware, though: this is an early work and I would rather offer it to John Lim and let him integrate it in adodb-or can it if he’s too horrified!
I am aware of at least one bug, which may happen when using the join method on belongs_to objects. It could also do more things for you. Definitely not the cat’s meow.
But if you like it and need help, drop me a line.
If you enjoyed this post, make sure you subscribe to my RSS feed!
2 More Reasons To Hate Recruiters
I read Nick Halstead’s “10 Reasons Why I hate Recruitment Agents” with interest.
I would like to add two more reasons, that I have personally experienced:
1. Asking me to come meet them
This is my favourite one. Nick wrote about agents asking to come meet him. I can see why they try to push for a meeting, this makes competitive sense.
But how about that recruiter who asked me to visit their office so that I could talk to their candidates? What makes them think that, on top of having to deal with their unsolicited phone calls, I would like to maximize the waste of time by driving to their damn office to let them bludgeon me with bogus resumes and run unprepared interviews with deer-in-the-headlights candidates? This beggars reason.
2. They also lie to the job applicants
In case you had any doubt about this, it happens. I’ve been there myself. I went to an interview with a big banking organization; I had only agreed to this interview after several weeks of them chasing me (I was already happily employed) and was supposed to be interviewed for a job as a team lead. It took me a solid 10 minutes of awkward q&a with the company recruiter to realize that they had basically decided to see if they could instead sell me as a junior programmer. Again, I have no idea whatsoever what it is that they were trying to achieve.
So, that’s my experience. Deplorably, it is a situation that has also happened to me when interviewing people, only to realize that they had basically been lied to regarding the position offered.
These two reasons, put together, lead me to think that rather than standard scum, these people are fiercely deluded.
If you enjoyed this post, make sure you subscribe to my RSS feed!






