NAME
Class::DBI - Simple Database Abstraction
SYNOPIS and DESCRIPTION
The main user-guide for Class::DBI can be found in Class::DBI::Tutorial. You should probably be reading that instead of this.
The documention in this package provides more advanced information for writing more complex subclasses.
METHODS
create
This is a constructor to create a new object and store it in the database. It calls _insert_row with the hashref, which in turn will call _next_in_sequence if applicable. The hasa() checks should be split out into another helper method.
new
This is a deprecated synonym for create(). Class::DBI originally used new() to create new objects but it caused confusion as to whether new() would retrieve or create new objects. Now you can choose what new() can do.
To pick, simply subclass like so...
package My::Class::DBI;
use base qw(My::Class::DBI);
# Make new() synonymous with retrieve()
sub new {
my($proto) = shift;
$proto->retrieve(@_);
}
If you wish to alter the way retrieve() works, be sure to put that code in retrieve() and not new() or else Class::DBI won't use it.
construct
my $obj = Class->construct(\%data);
This is a protected method and shouldn't be called by any but Class::DBI subclasses. This is ENFORCED!
Constructs a new object based solely on the %data given. It treats that data just like the columns of a table, key is the column name, value is the value of that column. This is very handy for cheaply setting up lots of objects that you have the data for without going to the database.
Basically, instead of doing one SELECT to get a bunch of IDs and then feeding those individually to retreive() (and thus doing more SELECT calls), you can do one SELECT to get the essential data of an object (by asking columns('Essential')) and feed that data to construct().
Look at the implementation of search() for a good example of its use as well as "Constructing a bunch of persistent objects efficiently" in the Class::DBI paper.
retrieve
Given a primary key value it will retrieve an object with that ID from the database. It simply calls search(), with the primary key.
copy / move
my $new_obj = $obj->copy;
my $new_obj = $obj->copy($new_id);
my $blrunner_dc = $blrunner->copy("Bladerunner: Director's Cut");
my $new_obj = Sub::Class->move($old_obj);
my $new_obj = Sub::Class->move($old_obj, $new_id);
These create a copy of the given $obj both in memory and in the database. However, where copy() will insert the data into the same table, move() will insert it into the table of a subclass.
If provided, $new_id will be used as the new primary key, otherwise the usual sequence or autoincrement will be used.
delete
$obj->delete;
Deletes this object from the database and from memory. $obj is no longer usable after this call. If any links have been set up with hasa_list, then delete those first.
autocommit
This is basically a wrapper around the __AutoCommit class data.
_column_placeholder
my $placeholder = $self->_column_placeholder($column_name);
Return the placeholder to be used in UPDATE and INSERT queries. Usually you'll want this just to return '?', as per the default. However, this lets you set, for example, that a column should always be CURDATE() [MySQL doesn't allow this as a DEFAULT value] by subclassing:
sub _column_placeholder {
my ($self, $column) = @_;
if ($column eq "entry_date") {
return "IF(1, CURDATE(), ?)";
}
return "?";
}
commit
Writes any changes you've made via accessors to disk. There's nothing wrong with using commit() when autocommit is on, it'll just silently do nothing. If the object is DESTROYed before you call commit() we will issue a warning.
rollback
Removes any changes you've made to this object since the last commit. Currently this simply reloads the values from the database. This can have concurrency issues.
If you're using autocommit this method will throw an exception.
get
We override the get() method from Class::Accessor to fetch the data for the column (and associated) columns from the database, using the _flesh() method. We also allow get to be called with a list of keys, instead of just one.
set
We also override set() from Class::Accessor so we can keep track of changes, and either write to the database now (if autocommit is on), or when commit() is called.
set_db
We override set_db from Ima::DBI so that we can set up some default attributes on a per database basis. For instance, if MySQL is detected, AutoCommit will be turned on. Under Oracle, ChopBlanks is turned on. As more databases are tested, more defaults will be added.
The defaults can be overridden by supplying your own $attr hashref as the 6th argument.
table / sequence
These are simple wrapper around the __table and __sequence class data.
- columns
-
Columns is a wrapper to the __columns class data, but it's much more complex than table() or sequence(). We provide primary() and essential() as simple accessors to these methods (primary currently returns a scalar, and essential a list).
When we declare a new group of columns we create an accessors for each via _mk_column_accessors.
_mk_column_accessors
Make a set of accessors for each of a list of columns. We construct the method name by calling accessor_name() and mutator_name() with the normalized column name.
mutator_name will be the same as accessor_name unless you override it.
If both the accessor and mutator are to have the same method name, (which will always be true unless you override mutator_name), a read-write method is constructed for it. If they differ we create both a read-only accessor and a write-only mutator.
has_column / is_column
has_column used to be called is_column. is_column is still provided as an alias to it.
_get_col2group / _make_col2group / _flush_col2gorup
We store the group => columns mappings in __Col2Group class data.
hasa
When we set up a hasa() relationship we store the relevant columns in _hasa_columns class data. Then we make the accessor return an instance of the connected class, rather than the value in the table.
_load_class() tries to require the relevant class for us.
- hasa_list
-
This creates a new (read-only) accessor method which will return a instances of the foreign class.
- normalize
-
$obj->normalize(\@columns);
SQL is largely case insensitive. Perl is largely not. This can lead to problems when reading information out of a database. Class::DBI does some data normalization.
There is no guarantee how a database will muck with the case of columns, so to protect against things like DBI->fetchrow_hashref() returning strangely cased column names (along with table names appended to the front) we normalize all column names before using them as data keys.
- normalize_hash
-
$obj->normalize_hash(\%hash);
Given a %hash, it will normalize all its keys using normalize(). This is for convenience.
set_sql
We override set_sql() from Ima::DBI so it has a default database connection.
dbi_commit / dbi_rollback
Simple aliases to commit() and rollback() in DBI, given different names to distinguish them from the Class::DBI concepts of commit() and rollback().
add_hook
__PACKAGE__->add_hook(create => \&call_after_create);
__PACKAGE__->add_hook(delete => \&call_before_delete);
__PACKAGE__->add_hook(before_update => \&call_before_update);
__PACKAGE__->add_hook(after_update => \&call_after_update);
This allows you set to set up hooks that get called at the relevant points. You can have any number of hooks for each point, but you cannot specify the order in which they will be run. Each will be passed a copy of the object being dealt with, and return values will be ignored.
make_filter
__PACKAGE__->make_filter(method_name => 'SQL_where_clause');
This allows you to set up simple filters (searches). It will create a method, named after the first parameter, which will execute a SELECT based on the restriction passed, which should be a valid SQL 'WHERE' clause. In many cases you'll also want to create a method that hides some of this from the end user:
Film->make_filter(many_sheep => '%s > ?');
sub lots_of_exploding_sheep {
my $self = shift;
$self->many_sheep('NumExplodingSheep', 5);
}
AUTHOR
Michael G Schwern <schwern@pobox.com> with much late-night help from Uri Gutman, Damian Conway, Mike Lambert and the POOP group.
Now developed and maintained by Tony Bowden <kasei@tmtm.com>
LICENSE
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
4 POD Errors
The following errors were encountered while parsing the POD:
- Around line 661:
'=item' outside of any '=over'
- Around line 744:
You forgot a '=back' before '=head2'
- Around line 930:
'=item' outside of any '=over'
- Around line 1027:
You forgot a '=back' before '=head2'