Changeset 177

Show
Ignore:
Timestamp:
05/04/06 00:16:44 (4 years ago)
Author:
sky
Message:

r180@crucially-3 (orig r1214): plindner | 2006-04-14 15:59:52 -0700
Add has_a feature to Data::ObjectDriver

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/lib/Data/ObjectDriver/BaseObject.pm

    r173 r177  
    1616    my($props) = @_; 
    1717    *{"${class}::__properties"} = sub { $props }; 
     18 
     19    # predefine getter/setter methods here 
     20    foreach my $col (@{ $props->{columns} }) { 
     21        # Skip adding this method if the class overloads it. 
     22        # this lets the SUPER::columnname magic do it's thing 
     23        if (!defined (*{"${class}::$col"})) { 
     24            *{"${class}::$col"} = sub { 
     25                shift()->column($col, @_); 
     26            }; 
     27        } 
     28    } 
    1829    $props; 
    1930} 
     
    2334    my $class = ref($this) || $this; 
    2435    $class->__properties; 
     36} 
     37 
     38# see docs below 
     39 
     40sub has_a { 
     41    my $class = shift; 
     42    my %args = @_; 
     43 
     44    # Iterate over each remote object 
     45    foreach my $parentclass (keys %args) { 
     46        my $config = $args{$parentclass}; 
     47        next unless $config; 
     48  
     49        # Parameters 
     50        my $column = $config->{column}; 
     51        my $method = $config->{method}; 
     52        my $parent_method = $config->{method}; 
     53 
     54        # column is required 
     55        if (!defined($column)) { 
     56            die "Please specify a valid column for $parentclass"  
     57        } 
     58 
     59        # create a method name based on the column 
     60        if (! defined $method) { 
     61            $method = $column; 
     62            $method =~ s/_id$//; 
     63        } 
     64 
     65        # die if we can't find a way to make a valid method 
     66        # TBD check current list of columns to avoid clash 
     67        if (! defined $method || ($method eq $column)) { 
     68            die "Please define a valid method for $class->$column"; 
     69        } 
     70 
     71        print STDERR "adding method $method linking $column to $parentclass->lookup()\n"; 
     72        no strict 'refs'; 
     73        *{"${class}::$method"} = sub { 
     74            my $obj = shift; 
     75            # TBD - Add in-memory caching logic here with weak ref? 
     76            return $parentclass->lookup($obj->column($column)); 
     77        }; 
     78 
     79        # now add to the parent 
     80        if (!defined $parent_method) { 
     81            $parent_method = lc($class); 
     82            $parent_method =~ s/^.*:://; 
     83            $parent_method .= 's';  # plural :) 
     84        } 
     85        print STDERR "adding method ${parentclass}::$parent_method\n"; 
     86        *{"${parentclass}::$parent_method"} = sub { 
     87            my $obj = shift; 
     88            my $terms = shift; 
     89            my $args = shift; 
     90            # TBD - allow user defined extra terms here?... 
     91            # TBD - use primary_key_to_terms 
     92            return $class->search({$column => $obj->id}, $args); 
     93        }; 
     94    } # end of loop over class names 
     95    return; 
    2596} 
    2697 
     
    289360sub DESTROY { } 
    290361 
    291 our $AUTOLOAD; 
    292362sub AUTOLOAD { 
    293363    my $obj = $_[0]; 
    294     (my $col = $AUTOLOAD) =~ s!.+::!!; 
     364    (my $col = our $AUTOLOAD) =~ s!.+::!!; 
    295365    no strict 'refs'; 
    296366    Carp::croak("Cannot find method '$col' for class '$obj'") unless ref $obj; 
     
    298368        Carp::croak("Cannot find column '$col' for class '" . ref($obj) . "'"); 
    299369    } 
     370    print STDERR "AUTOLOAD for $AUTOLOAD\n"; 
    300371    *$AUTOLOAD = sub { 
    301372        shift()->column($col, @_); 
     
    324395=head2 Class->install_properties({ ... }) 
    325396 
     397Sets up columns, indexes, primary keys, etc. 
     398 
    326399=head2 Class->properties 
     400 
     401Returns the list of properties. 
     402 
     403=head2 Class->has_a(ParentClass => { ... }, ParentClass2 => { ...} ) 
     404 
     405Creates utility methods that map this object to parent Data::ObjectDriver objects. 
     406 
     407Pass in a list of parent classes to map with a hash of parameters.  The following parameters 
     408are recognized: 
     409 
     410=over 4 
     411 
     412=item * column 
     413 
     414Name of the column(s) in this class to map with.  Pass in a single string if 
     415the column is a singular key, an array ref if this is a composite key. 
     416 
     417=item * method [OPTIONAL] 
     418 
     419Name of the method to create in this class.  Defaults to the column name without 
     420the _id suffix 
     421 
     422=item * parent_method [OPTIONAL] 
     423 
     424Name of the method created in the parent class.  Default is the lowercased  
     425name of the current class with an 's' appended.  
     426 
     427=item * cached [OPTIONAL] 
     428 
     429If set to 1 then we will cache in-memory the resulting object inside this class. 
     430 
     431=back 
    327432 
    328433=head2 Class->driver