[CDBI] re-casting cdbi classes?

William Ross will at spanner.org
Wed Mar 22 09:07:41 GMT 2006


On 18 Mar 2006, at 22:35, Ben Lavender wrote:

> Hi all,
>
> I've come across a situation where a client needs a change in
> requirements which would, ideally, require a slight slight breaking
> out of one class into a base class and two sub classes.  Put shortly,
> I have an event which is based on due dates right now, but some
> classes of events are turning up which need to be done based on
> mileage instead.

Class::DBI doesn't like data classes to inherit from one another, and  
I very much doubt that it would like objects to switch from one data  
class to another after they've been retrieved. I'm sure it could be  
made to work, but the way cdbi holds closures at class level and its  
increasing use of plugins make it fairly horrible to debug that kind  
of code, or it does for me anyway.

My advice, based on 8ish years of repeatedly trying to bend cdbi out  
of shape, is don't. Do it the official cdbi way or find another ORM  
that matches your problem better: there's plenty of choice now.

(And counting trips to the database is definitely a danger sign :)

None of which is very helpful now, I realise, but I also suspect that  
this particular problem will respond well if you think strictly in  
terms of relationships and look for a general solution rather than  
something specific to mileage: perhaps it would be worth trying a  
separate 'threshold' class with columns for object id, foreign column  
name (or other variable identifier), and a threshold value.

> Though I see that I can essentially get the benefits of all of these
> classes by just asking the object if it usesMiles or usesDates all
> over the place while shoving all the methods into one package, that's
> not the most maintanable way to code, usually.

it certainly isn't. A general-purpose thresholdPassed method would be  
quite manageable, though, and perhaps a good step towards a full  
solution. The main disadvantage with a computed threshold like that  
is you have no chance to search for threshold events in SQL, which  
you could probably do in a single query if you go for the related table.

.2p

will









> Thus, I previously had:
>
> Package Event;
> ...
> __PACKAGE__->columns(Essential => qw/ ... dueDate .../)
>
> I've got a lot of logic which touches lots of different fields based
> on these events, so my solution to the problem, if possible, would be
> as follows.  The database schema is already fixed up to accomidate
> this; I basically added usesDates, usesMiles, and dueMileage fields to
> the table to store the difference in the two classes.  This solution
> seems to be the best for my situation; a fair rundown I used to help
> me on this situation is at
> http://www.agiledata.org/essays/ 
> mappingObjects.html#MappingInheritance.
>
> Package Event;
> .
> .
> __PACKAGE__->columns(Essential => qw/ ..dueDate ... usesDates
> usesMiles dueMileage/);
>
> *various generic methods here*
> ######
> Package DateEvent
> use base Event;
> __PACKAGE__->columns(Essential => qw/... dueDate ... usesDates  
> usesMiles/);
>
> *various subs related to dates*
> ######
> Package MilesEvent
> use base Event;
> __PACKAGE__->columns(Essential => qw/ ... ... usesDates usesMiles  
> dueMileage/);
>
> *various subs related to mileage*
>
> I've already been playing with this a bit, and part of it works well
> and part of it doesn't.  The problem is this point:
> $event = Event->retrieve($id);
> &c($event);
> if ($event->usesMiles) {
>     &some_specific_miles_stuff($event);  #Crap!
> }
>
> The problem is that I dont see a way to tell this class that it should
> be a mileage event now instead of a generic one at the last method
> call without just reloading it from the database; alternately, I could
> hit the database once to determine the event type and then load it as
> a specific kind of event, in either case I require 2 trips to the DB
> instead of 1, which isn't going to do for the app I'm working with.
> In normal Perl I can play about with bless and Acme::Damn and whatnot,
> in the worst case, but I don't see a way to play with this object
> properly.
>
> Though I see that I can essentially get the benefits of all of these
> classes by just asking the object if it usesMiles or usesDates all
> over the place while shoving all the methods into one package, that's
> not the most maintanable way to code, usually.  If I have to do that,
> I suppose I will, but I thought I'd run it by the list and see if
> someone has run into this before.  Any ideas?
>
> Thanks,
> Ben
>
> _______________________________________________
> ClassDBI mailing list
> ClassDBI at lists.digitalcraftsmen.net
> http://lists.digitalcraftsmen.net/mailman/listinfo/classdbi





More information about the ClassDBI mailing list