At 8:15 AM +0100 11/19/03, Gerald Richter wrote:
I would prefer to extent DBIx::Recordset, so it could be easily subclassed.

Since Terrence is now working on DBIx::Recordset, we hopefully will have a
new release with patches of the last year incoorporated soon.

Well, you convinced me to give it a try, and it appears to now be working. I want to test it a few more days and then I'll put out the patches. I made the following changes.


- Most of the places where there were calls to DBIx::Recordset::Setup were easily replaced with $class or $self -> Setup. One instance (searching on links) had to be replaced with ref($self->{'*Recordset'})->Search(...).

- I added three new methods to DBIx:Recordset; RowClass, HashClass and CurrRowClass. (Someday I need to figure out what the distinction is between CurrRowClass and RowClass.) In DBIx::Recordset these return 'DBIx::Recordset::Row', 'DBIx::Recordset::Hash', and 'DBIx::Recordset::CurrRow' respectively. Subclasses of DBIx::Recordset can change them if desired, so long as the return value references a subclass of the the base DBIx::Recordset::* classes.

- I changed any direct class comparisons to ISA comparisons.

So far it seems to work, although I haven't tried subclassing the helper classes yet. I did migrate my encapsulation class (DBIx::Objectset) to a subclass of DBIx::Recordset.

One of the interesting things my subclass does is attempt to determine the appropriate class based on the table name. In other words, if I have a subclass of DBIx::Objectset called MF::Set and I create a new instance of MF::Set using {!Table => "foo"}, then the Setup method will look for (in memory, and via "require") MF::Set::Foo or MF::Foo before defaulting to a new instance of MF::Set. This allows you to create domain-specific behavior for certain tables. For instance, you could override "Insert" and have it check to see if all the arguments that you require have been specified. Or you could cascade an Update so that it updated related tables at the same time. With that model you can do the following kinds of things.

*account = MF::Set->Setup({ '!Table' => 'account' });
        # returns an MF::Set::Account object
*user = $account{-user};
        # returns an MF::Set::User object
*article = MF::Set::Article->Setup();
        # the default Setup method will set the !Table value

(None of those examples set the database info because DBIx::Objectset specifies the connect string, username, password and related values as methods that can be overridden by subclasses to provide default values.)

My database relationships were getting too complex, especially where MySQL doesn't do any cross-table consistency checking, and the procedural code was just getting too messy, with different dependencies scattered around. This allows me to encapsulate all of the table-specific knowledge in a single object that is tied to that table.

Still left to migrate to the new subclass, or possibly into Recordset itself are two other features. "Safe" mode throws an error if you try to write or read a fieldname that doesn't exist. And the other option is the ability to trigger function callbacks when certain fields are modified.

--
Kee Hinckley
http://www.messagefire.com/         Next Generation Spam Defense
http://commons.somewhere.com/buzz/  Writings on Technology and Society

I'm not sure which upsets me more: that people are so unwilling to accept
responsibility for their own actions, or that they are so eager to regulate
everyone else's.

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to