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( DBIx::DBO2::Table->new( name=>'foo', datasource=>$sqldb ) );
unless ( MyRecord->table->table_exists ) {
MyRecord->table->table_create( 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.