DBIx-DBO2

 view release on metacpan or  search on metacpan

DBO2/Record.pm  view on Meta::CPAN

#
# Access subclasses by name.

# Class::MakeMethods->make(
#   'Template::ClassName:subclass_name' => 'type',
# );

########################################################################

=head2 Table and SQLEngine

Each Record class stores a reference to the table its instances are stored in.

=over 4

=item table

  RecordClass->table ( $table )
  RecordClass->table () : $table

Establishes the table a specific class of record will be stored in.

=item count_rows

  RecordClass->count_rows () : $integer

Delegated to table.

=item datasource

  RecordClass->datasource () : $datasource

Delegated to table. Returns the table's SQLEngine.

=item do_sql

  RecordClass->do_sql ( $sql_statement ) 

Delegated to datasource.

=back

=cut

Class::MakeMethods->make(
  'Template::ClassInherit:object' => [ table => {class=>'DBIx::SQLEngine::Schema::Table'} ],
  'Standard::Universal:delegate' => [ 
    [ qw( count_rows datasource do_sql column_primary_name ) ] => { target=>'table' },
  ],
);

sub demand_table {
  my $self = shift;
  $self->table() or croak("No table set for " . ( ref( $self ) || $self ));
}

########################################################################

=head2 Hooks

Many of the methods below are labeled "Inheritable Hook." These methods allow you to register callbacks which are then invoked at specific points in each record's lifecycle. You can add these callbacks to all record classes, to a particular class, or...

To register a callback, call the install_hooks method, and pass it pairs of a hook method name, and a subroutine reference, as follows: I<callee>->install_hooks( I<methodname> => I<coderef>, ... ).

Here are a few examples to show the possibilities this provides you with:

=over 4

=item *

To have each record write to a log when it's loaded from the database:

  sub log_fetch { my $record = shift; warn "Loaded record $record->{id}" } );
  MyClass->install_hooks( post_fetch => \&log_fetch );

=item *

To make a class "read-only" by preventing all inserts, updates, and deletes:

  my $refusal = sub { return 0 };
  MyClass->install_hooks( 
    ok_insert => $refusal, 
    ok_update => $refusal, 
    ok_delete => $refusal, 
  );

=item *

To have a particular record automatically save any changes you've made to it when it goes out of scope:

  my $record = MyClass->fetch_one( ... );
  my $saver = sub { my $record = shift; $record->save_record };
  $record->install_hooks( pre_destroy => $saver );

=back

=cut

sub install_hooks {
  my $callee = shift;
  while ( my( $method_name, $code_ref ) = splice( @_, 0, 2 ) ) {
    $callee->$method_name( 
      Class::MakeMethods::Composite::Inheritable->Hook( $code_ref )
    );
  }
}

########################################################################

=head2 Constructor

Record objects are constructed when they are fetched from their table as described in the next section, or you may create your own for new instances.

=over 4

=item new 

  my $obj = MyRecord->new( method1 => value1, ... ); 

  my $shallow_copy = $record->new;



( run in 0.353 second using v1.01-cache-2.11-cpan-140bd7fdf52 )