# $Id: /local/CPAN/Mango/lib/Mango/Provider/DBIC.pm 1644 2008-06-02T01:46:53.055259Z claco $ package Mango::Provider::DBIC; use strict; use warnings; BEGIN { use base qw/Mango::Provider/; use Scalar::Util (); use DateTime (); use Mango::Iterator (); use Mango::Exception qw/:try/; __PACKAGE__->mk_group_accessors( 'component_class', qw/schema_class/ ); __PACKAGE__->mk_group_accessors( 'inherited', qw/ source_name connection_info updated_column _resultset _schema / ); } __PACKAGE__->schema_class('Mango::Schema'); __PACKAGE__->updated_column('updated'); sub create { my ( $self, $data ) = @_; my $result = $self->resultset->create($data); return $self->result_class->new( { $result->get_inflated_columns, meta => { provider => $self } } ); } sub delete { my ( $self, $filter ) = @_; if ( Scalar::Util::blessed $filter) { $filter = { id => $filter->id }; } elsif ( ref $filter ne 'HASH' ) { $filter = { id => $filter }; } return $self->resultset->search($filter)->delete_all; } sub resultset { my ( $self, $resultset ) = @_; if ( defined $resultset ) { $self->_resultset($resultset); } elsif ( !$self->_resultset ) { if ( !$self->source_name ) { Mango::Exception->throw('SCHEMA_SOURCE_NOT_SPECIFIED'); } try { $self->_resultset( $self->schema->resultset( $self->source_name ) ); } except { Mango::Exception->throw( 'SCHEMA_SOURCE_NOT_FOUND', $self->source_name ); }; } return $self->_resultset; } sub schema { my ( $self, $schema ) = @_; if ($schema) { $schema->exception_action( sub { Mango::Exception->throw(@_); return; } ); $self->_schema($schema); } elsif ( !$self->_schema ) { if ( !$self->schema_class ) { Mango::Exception->throw('SCHEMA_CLASS_NOT_SPECIFIED'); } $self->_schema( $self->schema_class->connect( @{ $self->connection_info || [] } ) ); $self->_schema->exception_action( sub { Mango::Exception->throw(@_); return; } ); } return $self->_schema; } sub search { my ( $self, $filter, $options ) = @_; $filter ||= {}; $options ||= {}; my $resultset = $self->resultset->search( $filter, $options ); my @results = map { $self->result_class->new( { $_->get_inflated_columns, meta => { provider => $self } } ) } $resultset->all; if (wantarray) { return @results; } else { return Mango::Iterator->new( { provider => $self, data => \@results, pager => $options->{'page'} ? $resultset->pager : undef } ); } } sub update { my ( $self, $object ) = @_; my $updated_column = $self->updated_column; $object->$updated_column( DateTime->now ); return $self->resultset->find( $object->id ) ->update( { $object->get_columns } ); } 1; __END__ =head1 NAME Mango::Provider::DBIC - Provider class for DBIx::Class based providers =head1 SYNOPSIS package MyApp::Provider::Users; use strict; use warnings; BEGIN { use base qw/Mango::Provider::DBIC/; }; __PACKAGE__->schema_class('MySchema'); __PACKAGE__->source_name('Users'); my $object = $provider->create(\%data); =head1 DESCRIPTION Mango::Provider::DBIC is a base abstract class for all DBIx::Class based providers used in Mango. =head1 CONSTRUCTOR =head2 new =over =item Arguments: \%options =back Creates a new provider object. If options are passed to new, those are sent to C. my $provider = Mango::Provider::DBIC->new({ schema_class => 'MySchema', source_name => 'Users', result_class => 'MyResultClass' }); The following options are available at the class level, to new/setup and take the same data as their method counterparts: connection_info resultset schema schema_class source_name See L a list of other possible options. =head1 METHODS =head2 connection_info =over =item Arguments: \@info =back Gets/sets the connection information used when connecting to the database. $provider->connection_info(['dbi:mysql:foo', 'user', 'pass', {PrintError=>1}]); The info argument is an array ref that holds the following values: =over =item $dsn The DBI dsn to use to connect to. =item $username The username for the database you are connecting to. =item $password The password for the database you are connecting to. =item \%attr The attributes to be pass to DBI for this connection. =back See L for more information about dsns and connection attributes. =head2 create =over =item Arguments: \%data =back Creates a new object of type C using the supplied data. my $object = $provider->create({ id => 23, thingy => 'value' }); =head2 delete =over =item Arguments: \%filter or $object =back Deletes objects from the store matching the supplied filter. $provider->delete({ col => 'value' }); It can also delete an object passed into it: $provider->delete($object); This is the same as: $provider->delete({ id => $object->id }); =head2 get_by_id =over =item Arguments: $id =back Retrieves an object from the provider matching the specified id. my $object = $provider->get_by_id(23); Returns undef if no matching result can be found. =head2 resultset =over =item Arguments: $resultset =back Gets/sets the DBIx::Class::Resultset to be used by this provider. If no resultset is set, the resultset for the specified C will be created automatically. $provider->resultset; # same as $schema->resultset($provider->source_name) $provider->resultset( $schema->resultset($provder->source_name)->search({default => 'search'}) ); =head2 schema =over =item Arguments: $schema =back Gets/sets the DBIx::Class schema instance to be used for this provider. If no schema is set, a new instance of the C will be created automatically when it is needed. my $schema = $provider->schema; $schema->dbh->{'AutoCommit'} = 0; =head2 schema_class =over =item Arguments: $class =back Gets/sets the DBIx::Class schema class to be used for this provider. An exception will be thrown if the specified class can not be loaded. $provider->schema_class('MySchema'); my $schema = $provider->schema; print ref $schema; # MySchema If no schema class is specified in the subclass, the default schema class is Mango::Schema. =head2 search =over =item Arguments: \%filter, \%options =back Returns a list of objects in list context or a Mango::Iterator in scalar context matching the specified filter. my @objects = $provider->search({ col => 'value' }); my $iterator = $provider->search({ col => 'value' }); See L for a list of possible options. =head2 source_name =over =item Arguments: $source =back Gets/sets the DBIx::Class schema source to be used when creating the default resultset. $provider->source_name('Users'); $provider->resultset; ## same as $schema->resultset('Users') =head2 update =over =item Arguments: $object =back Sets the 'updated' column to DateTime->now and saves any changes made to the object back to the underlying store. my $object = $provider->create(\%data); $object->col('value'); $provider->update($object); =head1 SEE ALSO L, L =head1 AUTHOR Christopher H. Laco CPAN ID: CLACO claco@chrislaco.com http://today.icantfocus.com/blog/