Copying a Class::Accessor class to a CDBI class (CDBI::Plugin::Temp)

[prev] [thread] [next] [Date index for 2005/05/23]

From: Peter Speltz
Subject: Copying a Class::Accessor class to a CDBI class (CDBI::Plugin::Temp)
Date: 21:17 on 23 May 2005
--0-607429943-1116883022=:5300
Content-Type: text/plain; charset=us-ascii
Content-Id: 
Content-Disposition: inline

In regards to the thread subjected "construct + autoupdate(0)" (see below for
text )  where it was suggested to " Make another object using Class::Accessor,
and copy it into a Class::DBI object" when you need to mess around with data or
related data before it is inserted into the database:
                                                                               

I tried this. I made a Music::CdTemp class based on C::A.   I first thought
Perrin and Tony were talking literally about using CDBI's copy method.  However
that is an object method so that doesn't work.  I tried move .  That is
deprecated.  So I encapsulated the "copy" functionality into a "create_real"
object method in the  *Temp class.
                                                                               

Perrin and Tony, what code were you imagining?
I put all this in a *Experemental and barely tested* plugin which I have
attached.  It exports a "create_temp" method which  defines the temp class if
need be and returns a temp object. Then you can do things like create a real
object with the temp object. I could see the Temp class evolving into a useful
tool for some common situations.  Thoughts?
                                                                               

thanks,
                                                                               

PJS


> --- Perrin Harkins <perrin@xxxx.xxx> wrote:
> > Subject: Re: construct + autoupdate(0)
> > From: Perrin Harkins <perrin@xxxx.xxx>
> > To: Christopher Laco <mendlefarg@xxxxx.xxx>
> > CC: cdbi-talk@xxxxxx.xxxxx.xxx
> > Date: Thu, 12 May 2005 23:22:58 -0400
> > 
> > On Thu, 2005-05-12 at 20:53 -0400, Christopher Laco wrote:
> > > The docs on construct are a little thin as to what it really does or
> > > expects. I know it just transforms data into objects without calling
> > > the db, but what does it expect underneath?
> > 
> > It expects a set of data that corresponds to the class that has been
> > defined.  Look at the things that call construct() to understand better.
> > 
> > > Does the
> > > data-turned-object have to already exist in the database
> > 
> > Yes.
> > 
> > > What I need to do is to pass some data to construct() to get the
> > > desired objects, but I don't want any record to exist in the database
> > > until I do more futxing and then call update().
> > 
> > You can't currently do that with Class::DBI.  Make another object using
> > Class::Accessor, and copy it into a Class::DBI object when you want to
> > save it to the database.
> > 
> > - Perrin
> > 
> > 
> 
> pjs
> 
> 
> 		
> Yahoo! Mail
> Stay connected, organized, and protected. Take the tour:
> http://tour.mail.yahoo.com/mailtour.html
> 
> 

pjs

__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 
--0-607429943-1116883022=:5300
Content-Type: text/x-perl; name="Temp.pm"
Content-Description: 2808870186-Temp.pm
Content-Disposition: inline; filename="Temp.pm"

package Class::DBI::Plugin::Temp;

use 5.008003;
use strict;
use warnings;

require Exporter;

our @ISA = qw(Exporter);
our @EXPORT_OK = ( qw/create_temp/ );
our @EXPORT = qw( create_temp );
	
our $VERSION = '0.01';

print 'Using Temp with Class::Accessor\n\n';
sub create_temp {
	my ($self, $values) = @_;
    $values ||= {};	
	my $class = ref $self || $self;
	my $tmp_class = _temp_class_name($class);
	# define temp class if it is not
	no strict 'refs';
	unless ( %{"$tmp_class\::"} ) {
	 	_define_temp_class($class);
    }
	return $tmp_class->new($values);
}
	
sub _temp_class_name {
    my $class = shift;
	return $class->can('temp_class_name') ? $class->temp_class_name :
     		$class . 'Temp';
}

# We should export this i think and call it as a class method rather than a 
# function  above in create_temp.
#
sub _define_temp_class {
	my ($class) = shift;
	no strict 'refs';
	my $tmp_class = _temp_class_name($class);
	print "Defining a temp class for $class named $tmp_class \n";
	@{"$tmp_class\::ISA"} = qw(Class::Accessor);
	
	# make accessors and methods
	$tmp_class->mk_accessors( $class->columns, $class->columns('TEMP') );
	*{"$tmp_class\::real_class"} = sub { $class };
	*{"$tmp_class\::create_real"} = sub { 
		my ($self, $xtra) = @_;
		$xtra ||= {};
		return $class->create({%$self, %$xtra});
     };
	 return $tmp_class;
}

		
# Preloaded methods go here.

# Autoload methods go after =cut, and are processed by the autosplit program.

1;
__END__

=head1 NAME

Class::DBI::Plugin::Temp - Perl extension for Class::DBI for temporarily storing
data for an object until you are ready to create a Class::DBI object (row in the
database ).

=head1 SYNOPSIS

  package Music::CD;
  use Class::DBI::Plugin::Temp;   # just use it
  ...
  my $tmp_cd = Music::CD->create_temp( 
		  { title => 'Yoshimi Battles the Pink Robots', year => '2002' } );
  my $artist = Music::Artist->create( { name => 'The Flaming Lips' } );
  $tmp_cd->artist($artist->id);  
  my $cd = $tmp_cd->create_real(
  	{ # any additional (trumping) data here }
				
  );
  my $cd_class = $tmp_cd->real_class;

				  
=head1 DESCRIPTION

This module adds one method to your class -- C<create_temp> -- to create an
object from data you eventually want in a row in your class's table.  This 
temporary object has two (self-explanatory) methods of it's own -- 
C<create_real>, and C<real_class>.   

=head1 METHODS

=head2 create_temp

my $tmp_cd = Music::Cd->create_temp( $opt_col_val_hashref );

This method will be exported into the calling class.  It returns an object with
read/write accessors for all columns including 'Temp' columns.  If the temp
object is not defined then it will be defined.  See C<The Temp Class> below.

=head1 THE TEMP CLASS

This class  has some useful methods.  However. first, the name.  By default it is named after the class it models with 'Temp' appended to it.  Write your own C<temp_class_name> method in your CDBI class if you want something defferent.

=head2 THE TEMP CLASS'S METHODS

C<create_real>,  C<real_class>


=head1 SEE ALSO

Class::DBI, Class::DBI::FromCGI


=head1 AUTHOR

Peter Speltz, E<lt>peterspeltz@xxxxx.xxxx<gt>

=head1 COPYRIGHT AND LICENSE

Copyright (C) 2005 by Peter Speltz

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.3 or,
at your option, any later version of Perl 5 you may have available.


=cut

--0-607429943-1116883022=:5300--

Copying a Class::Accessor class to a CDBI class (CDBI::Plugin::Temp)
Peter Speltz 21:17 on 23 May 2005

Generated at 15:51 on 25 May 2005 by mariachi v0.52