Matthew Simon Cavalletto

NAME

DBIx::DBO2::Record - A row in a table in a datasource

SYNOPSIS

  package MyRecord;
  use DBIx::DBO2::Record '-isasubclass';
  use DBIx::DBO2::Fields (
    'sequential' => 'id',
    'string -length 64' => 'name',
    'timestamp --modified' => 'lastupdate',
  );
  
  my $sqldb = DBIx::SQLEngine->new( ... );
  MyRecord->table( $sqldb->table( 'foo' );
  unless ( MyRecord->table->table_exists ) {
    MyRecord->table->create_table( MyRecord->field_columns );
  }

  my $record = MyRecord->new( name => 'Dave' );
  $record->save_record;
  
  my $results = MyRecord->fetch_records( criteria => { name => 'Dave' } );
  foreach my $rec ( $results->records ) {
    print $rec->name() . ' ' . $rec->lastupdate_readable();
  }

DESCRIPTION

The DBIx::DBO2::Record class represents database records in tables accessible via DBIx::SQLEngine.

By subclassing this package, you can easily create a class whose instances represent each of the rows in a SQL database table.

REFERENCE

Subclass Factory

import
  package My::Record;
  use DBIx::DBO2::Record '-isasubclass';

Allows for a simple declaration of inheritance.

Table and SQLEngine

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

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

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

count_rows
  RecordClass->count_rows () : $integer

Delegated to table.

datasource
  RecordClass->datasource () : $datasource

Delegated to table. Returns the table's SQLEngine.

do_sql
  RecordClass->do_sql ( $sql_statement ) 

Delegated to datasource.

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 even to a particular object instance.

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

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

  • 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 );
  • 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, 
      );
  • 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 );

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.

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

  my $shallow_copy = $record->new;

Create a new instance. (Class::MakeMethods::Standard::Hash:new).

clone
  my $similar_record = $record->clone;

Makes a copy of a record and then clears its id so that it will be recognized as a distinct, new row in the database rather than overwriting the original when you save it.

post_new

Inheritable Hook. Subclasses should override this with any functions they wish performed immediately after each record is created and initialized.

Selecting Records

fetch_records
  $recordset = My::Students->fetch_records( criteria => {status=>'active'} );

Fetch all matching records and return them in a RecordSet.

fetch_one
  $dave = My::Students->fetch_one( criteria => { name => 'Dave' } );

Fetch a single matching record.

fetch_id
  $prisoner = My::Students->fetch_id( 6 );

Fetch a single record based on its primary key.

visit_records
  @results = My::Students->visit_records( \&mysub, criteria=> ... );

Calls the provided subroutine on each matching record as it is retrieved. Returns the accumulated results of each subroutine call (in list context).

refetch_record
  $record->refetch_record();

Re-retrieve the values for this record from the database based on its primary key.

post_fetch

Inheritable Hook. Subclasses should override this with any functions they wish performed immediately after each record is retrieved from the database.

Row Inserts

After constructing a record with new(), you may save any changes by calling insert_record.

insert_record

Attempt to insert the record into the database.

  $record->insert_record () : $record_or_undef

Calls ok_insert to ensure that it's OK to insert this row, and aborts if any of hook subroutines return 0.

Calls any pre_insert hooks, then calls its table's insert_row method, then calls any post_insert hooks.

Returns undef if the update was aborted, or the record if the insert was successful.

ok_insert

Inheritable Hook. Subclasses should override this with any functions they wish performed to validate rows before they are inserted.

pre_insert

Inheritable Hook. Subclasses should override this with any functions they wish performed immediately before a row is inserted.

post_insert

Inheritable Hook. Subclasses should override this with any functions they wish performed after a row is inserted.

Row Updates

After retrieving a record with one of the fetch methods, you may save any changes by calling update_record.

update_record

Attempts to update the record using its primary key as a unique identifier.

  $record->update_record () : $record_or_undef

Calls ok_update to ensure that it's OK to update this row, and aborts if any of hook subroutines return 0.

Calls any pre_update hooks, then calls its table's update_row method, then calls any post_update hooks.

Returns undef if the update was aborted, or the record if the update was successful.

ok_update

Inheritable Hook. Subclasses should override this with any functions they wish to use to validate rows before they are updated. Return 0 to abort the update.

pre_update

Inheritable Hook. Subclasses should override this with any functions they wish performed immediately before a row is updated.

post_update

Inheritable Hook. Subclasses should override this with any functions they wish performed immediately after a row is updated.

Deletion

delete_record
  $record->delete_record () : $boolean_completed

Checks to see if any of the pre_delete results is "0". If not, asks the table to delete the row.

Returns 1 if the deletion was successful, or 0 if it was aborted.

ok_delete
  $record->ok_delete () : @booleans

Inheritable Hook. Subclasses should override this with any functions they wish to use to validate rows before they are updated. Return 0 to abort the deletion.

pre_delete
  $record->pre_delete ()

Inheritable Hook. Subclasses should override this with any functions they wish performed before a row is deleted.

post_delete
  $record->post_delete ()

Inheritable Hook. Subclasses should override this with any functions they wish performed after a row is deleted.

Load and Save Wrappers

Wrappers for new/fetch and insert/update.

get_record
  RecordClass->get_record ( $id_or_undef ) : $new_or_fetched_record_or_undef

Calls new if no ID is provided, or if the ID is the special string "-new"; otherwise calls fetch_id.

save_record
  $record->save_record () : $record_or_undef

Determines whether the record has an id assigned to it and then calls either insert_record or update_record. Returns the record unless it fails to save the record.

Modification Wrappers

Simple interface for applying changes.

call_methods
  $record->call_methods( method1 => value1, ... ); 

Call provided method names with supplied values. (Class::MakeMethods::Standard::Universal:call_methods).

change_and_save
  RecordClass->new_and_save ( %method_argument_pairs ) : $record

Calls call_methods, and then save_record.

change_and_save
  $record->change_and_save ( %method_argument_pairs ) : $record

Calls call_methods, and then save_record.

Destructor

Automatically invoked when record is being garbage collected.

pre_destroy
  $record->pre_destroy ()

Inheritable Hook. Subclasses should override this with any functions they wish called when an individual record is being garbage collected.

SEE ALSO

See DBIx::DBO2 for an overview of this framework.