Older blog entries for cwinters (starting at number 2)

Collections are now known as SPOPS, or Simple Perl Object Persistence with Security. (Although I'm working on the security right now :)

SPOPS aims to be storage-mechanism independent, although almost all of the work so far has been done with the DBI backend. (I've used both Sybase and MySQL with it, and porting it to a different db should be pretty easy, as long as they support a the $sth->{TYPE} and {NAME} interface and you can reasonably abstract out an ID-generation mechanism. (Sequences, for instance, should not be a problem at all.)) I'm hoping to implement the User/Group stuff not only using the DBI interface but also LDAP, which would be neat-o. (It would also likely expose some subconscious design decisions influenced by my RDBMS mentality...)

They're now fairly well extricated from the other projects that were using them, which should make it easier for me to consolidate the three or four versions that are floating around my ~/work directory. I think I'm going to upgrade my website to use them later on today so I can test out the user/group stuff.

They are also much easier to use now, thanks to Rusty's prodding. Instead of forcing you to use get/set accessor methods for an object, the data are now in a tied hash, so you can simply do: $user->{first_name} = 'Chris' to set information and then do $user->save; to save the user object. No context switching, and using a tied hash means that you can interpolate the values into strings (or templates...) without a second thought. Cool.

You can nab them, along with a working-and-rapidly-developing banner ad management system that uses them (called AdHomonym), at the AdHomonym website. I'm not quite ready to put them up on CPAN yet. Once I get an LDAP interface written and reasonably tested (or maybe re-port the interface to GDBM files from a six-month old project), then I'll feel decent about it.

Anyway, demos of the ad system coming soon.

Okay, so how do collections work? Here's an example:

my $user = $R->user->fetch( $uid );
print "Username: ", $user->username, "\n";
$user->set( 'first_name', 'Ding' );
$user->set( 'last_name', 'Dong' );
my $rv = $user->save();
if ( ! $rv ) {
  $R->error->add( 513, "Cannot add user record!" );
}
...
# Find all the user objects where the user's last name
# begins with w my $user_list = $R->user->fetch_group( where => "last_name like 'w%'" );
foreach my $user ( @{ $user_list } ) {
  print "Username: ", $user->username, "\n";
  print "Full Name: ", $user->full_name, "\n";
}

And so on. These are obviously really simplistic examples. But the idea is there. The variable $R is an object that acts as a container for other objects that live throughout the life of an http request -- much like the variable commonly called $r that is the first argument to any mod_perl handler.

Generally, there's a DBI database handle ($R->db), a server-wide configuration object ($R->config), the apache server rec object in perl ($R->apache), and a CGI object ($R->cgi). I've subclassed the base $R object to provide class aliasing as well. This way, I can call: $R->user which simply returns a class name (e.g., Intes::User) that can then be used to call an actual class method (e.g., $R->user->fetch( $uid ) becomes Intes::User->fetch( $uid )).

I'll try to get some basic stuff up on my website soon, depending on what Rusty winds up saying... :)

Like Rusty mentioned, we've been working a lot on Collections in perl. I probably picked the wrong term to use when I started writing them a number of months ago, because I think collection has some computer science baggage attached to it. It might be good baggage, I'm not sure. But since I don't remember enough of my CS classes to even be dangerous...

Anyway, a Collection is an object that represents some thing: a person who uses a website, a term in a dictionary, a translation between terms of two different languages in a dictionary, a relation between two terms in a dictionary (you can tell where I've been doing a lot of work recently). And the base Collection classes (currently two: Collection and Collection::DBI) don't make any assumptions about what the thing is. Collections basically just serialize (and cache) objects for later use. And generally the implementation classes are fairly simple, in the easiest case just defining some configuration information (database information such as fields, field types, table name, etc) and that's it. The interface for calling one collection object from another is fairly simple and you can build some fairly complicated relationships in this manner.

That it for now, more later.

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!