Persistent

Description

Persistent is a framework of classes that makes it easier to store
and retrieve Perl objects to and from various types of data stores. Using a
common interface that all of these classes inherit, you can store objects to
various types of data stores such as text and DBM files, relational databases,
LDAP directories and so on, all with the same programming interface. You can
also query and retrieve these objects from the various types of data stores
by using the query/search language of the native data store. The data stores
currently supported are the following:

Text files

DBM files

Memory (RAM) hashes

MySQL databases

Oracle databases

Sybase databases

mSQL databases

LDAP directories

For a more in-depth introduction to Persistent, please see the
documentation section that follows. Or for a discussion
of why these classes were developed, check out the Why? section
below.

Download

The Persistent modules are available here and from the Comprehensive
Perl Archive Network (CPAN). Here's where
it can be found on one of the many mirrors of CPAN:

Documentation

For a fully hyperlinked and fairly detailed introduction and overview
to the Persistent framework of classes, check out the main
Persistent documentation. This is also available after you install the Persistent::Base
module by either typing man Persistent
or perldoc Persistent.

Otherwise, here's a table of contents to the documentation. Again,
all of this will be installed as man pages or POD (but not hyperlinked) when
you install the modules.

Examples

The examples that follow can also found in the examples
directory after you unpack the downloadable tar/gzip files listed above. I realize
that some of the examples are rather long and don't really do too much that's
useful. That's because they were originally my testing/verification scripts.
I'll be adding some more useful and simpler examples soon.

Scripts included in the Persistent::Base module

instance.pl --
A script that uses instantiations of the Persistent::DBM and Persistent::File
classes.

subclass.pl --
A script that uses a subclass of the Persistent::DBM class.

Why?

The first question that people ask is "Why do I need a persistent
class?" I spent years writing, rewriting, and throwing away code to save
and restore objects from databases, text files, DBM files, and LDAP directories.
Every time a new object was added we had to write specialized code for that
class to save and restore its state. Well, that's what these classes do. They
save and restore objects to and from various types of data stores for you. Shortening
your develop time and allowing you to focus on the application/business logic
that demands your attention.

Some of you may be asking "Why do we need another persistent
Perl class?" And yes, there are a few other Perl classes already in CPAN
that do similar things. And I'm not trying to take anything away from those
classes that are already there. In fact, I downloaded and evaluated many of
them and some of them are excellent. But, the ones that are excellent are usually
the ones that are quite complex and cumbersome to use. One of things (in my
opinion) that makes Persistent useful is the fact that it takes a rather complicated
subject area, object persistence, and makes it fairly simple for the application
programmer to use. The application programmer needs to learn only one class
interface, which consists of basically six or seven frequently used methods.
Some of those other persistent classes require the application developer to
learn to use eight, nine, ten, or more classes.

I definitely agree that some of the other more complex persistent
classes can do a lot more than Persistent. Some of them provide transactions
and foreign object references. But, they also are usually tied to a specific
type of data store with a specific data format which cannot be changed. They
are usually either an object-relational mapper or an object-serializer. One
of the benefits of Persistent is that it supports many different types of data
stores, such as:

Text and DBM files

Relational databases

LDAP directories

And it works well with legacy systems because you can define the format of
the data store. Instead of using Data::Dumper files that only Perl can understand,
you can use preexisting delimited text or DBM files that are easily accessible
by other systems (Perl-based or not). Instead of being dictated by the software
as to the database schema, you can use tables in a preexisting database. Or
you can use LDAP directory objects that were defined by another legacy application.
Persistent is very flexible in the format of its data storage. This is one of
the reasons why we developed it. We were writing web-based applications that
integrated legacy systems with the web and the format of the data was already
defined and in a production environment.

And because of the support of different types of data stores, it is rather
simple to copy data from one type of data store to another. You can populate
a LDAP directory from a corporate HR database by defining two Persistent objects
(one uses a database and the other a LDAP directory) and copying the data via
the conveniently named data method.
This makes Persistent very handy when it comes to integrating disparate systems.

The architecture of Persistent also allows it to be extended very easily. A
new type of data store can be supported by writing only four methods: datastore,
insert, delete,
and restore_where. And for a
DBI-supported database, only two single-line methods need to be written. And
if you want to tune the performance a bit, you can implement a few more methods
like the update method to take
advantage of a feature of the data store.

These are just a few reasons why I think Persistent can be useful. It's definitely
not a perfect solution. It lacks a lot of things. But, I think it's pretty simple
to use (in comparison to other solutions). It works well with other systems
because of its flexible data store formats and it's easy to extend for support
of other data stores. So if you've got the time, download it, play with it,
check it out, and let me know what you think!

History

Though I've given Persistent a rather low version number at this time, it has
actually been around for quite a while, about two and a half years. And it has
been rewritten or had major portions rewritten about five times (thus the 0.5x
version number). About ten developers have used used it in the past two and
a half years to develop web-based (mostly CGI and a couple mod_perl) intranet
and Internet applications. It has been extremely valuable in integrating systems
such as corporate LDAP directories, HR databases, and asset management systems.

The initial idea for this class came from the Advanced Perl Programming
book by Sriram Srinivasan. Greg Bossert, a fellow programmer, and myself had
been developing applications for quite a while and were tired of having to write
custom code for every single object that we created to be able to save and restore
their state. And many times we would have to rewrite the code multiple times
when the customer would change their mind on the data store we were using. They
usually were trying to save a few bucks and would agree to use something free
for the data storage, like Berkeley DB files. And then they would let their
users loose on the system and it would crap out after a few thousand objects
or so. And we would come in and recode all of the objects to use a database.

It was good for business, but bad for lazy programmers like ourselves. And
so we started kicking around ideas for a persistent base class of some sort.
We started researching it and we came across the Advanced Perl Programming
book. Sriram covers the topic of persistence in two excellent chapters of the
book. We liked the interface that he described and so we modified and extended
it a bit to support more types of data stores and we were off and running.

We chose the namespace of Persistent since we felt it described the intention
of the classes very accurately. Of course, at that time we were more concerned
with delivering applications to customers and not whether the namespace was
already taken in CPAN. I promised for years (wow, it's been a while) that I
would package it up for CPAN for others to use. And now that's what I'm trying
to do. I think the name Persistent fits it well, but I'm definitely not attached
to the name if someone else has already reserved it. Though, I don't see it
currently in CPAN. I'm also very open to cooperating with others if they would
like to integrate this into another currently running "persistent"
project. Though, this framework of classes is pretty much complete. It has existed
in its current state with the same interface for quite a while now. And although
it has a low version number, I believe once some feedback is received from the
Perl community, some more quality examples have been added, and a bit more documentation
(I'm kind of big on documentation if it doesn't show), it should have a 1.0
version number.

So we'll see where the future takes it, hopefully, it will be in CPAN soon,
in some form or another, for others to use.

UPDATE! Persistent has been accepted to CPAN. :)
Here's where it can be found on one of the many mirrors of CPAN: