Online Book Reader

Home Category

Beautiful Code [160]

By Root 5014 0
store key-value pairs, which can be committed to the database with a commit method call. It also uses Perl's Tie mechanism to tie Postgres' large objects (BLOBs) to filehandles, enabling natural filehandle-based access to large binary objects in the data-base. One of the major benefits of Persistence::Database::SQL over Persistence::Object:: Simple, of course, is that it enables proper queries into a real database. For example, with Persistence::Object::Simple, there's no clean way to quickly search for a particular user's record, whereas with Persistence::Database::SQL, getting a specific user record from the database is straightforward:

[#] In Perl, a reference becomes an object when associated to a class by bless, so "blessed reference" is just a Perlish term for an object.

sub _getuser { # Get a user object from the database.

my $self = shift; my $username = shift;

$self->db->table('users'); $self->db->template($usertmpl);

my ($user) = $self->db->select("WHERE USERNAME = '$username'");

return $user;

}

With Persistence::Object::Simple one would have to either iterate over all the persistent objects in the data directory or resort to a hack such as directly grepping the plaintext persistence files in the data directory.

In most respects, the interface of Persistence::Object::Postgres is very similar to that of Persistence::Object::Simple. To modify an object with either module, the code is identical:

my $user = $self->_getuser($username);

return $self->cluebat (EBADLOGIN) unless $user and $user->timestamp;

$user->set_level($level);

$user->commit;

The switch from a plaintext database to a real DBMS was made after most of the prototype code was basically working well, and marked the second stage of Cryptonite development: getting the system ready for real-world deployment. For prototype development, Persistence::Object::Simple was great, as it didn't require a database server to be available for development, and objects were stored in plaintext files so they could be easily examined for debugging.

The use of homomorphic interfaces for Crypt::GPG and Persistence::Object::Postgres allowed these major changes (of the encryption and the database backends) to be made with very minor edits to the code in Cryptonite::Mail::Service.

11.7.1. Revamping the Mail Store

Storing user mail in plain mbox files worked for the first prototype, but a production system needed to be able to access and update individual messages more efficiently than a single flat file mailbox allowed. I also wanted to move toward the very important objective of providing mail store replication for fault-tolerance.

A usability consideration also imposed some requirements on the mail store. In Cryptonite, unlike most email clients, information about MIME structures of messages would be made visible to users in the message list. This would make it possible for a user to visually identify which messages were encrypted and/or signed, directly in the message list. Availability of information about message parts in the message list would also enable the user to open a message subpart directly. The message parts are visible as icons in the rightmost column of the message list view, as shown in Figure 11-4.

Figure 11-4. Message list with parts

To enable such visual feedback, the mail store would need to efficiently provide accurate information about the MIME structure of a list of messages. A further complication was the fact that the OpenPGP/MIME spec allows for MIME parts to be nested within signed and/or encrypted parts, so only an OpenPGP/MIME-aware mail store could return accurate information about MIME structures of encrypted or signed messages.

So I decided to implement, based on the Mail::Folder module, an SQL-based mail storage backend with most of the abilities of an IMAP4rev1 server. The core of this system is the Mail::Folder::SQL class, based on Mail::Folder and using Persistence::Object::Postgres. This was back when IMAP had not yet gained much traction. I opted not to use an existing IMAP server as a mail

Return Main Page Previous Page Next Page

®Online Book Reader