[ANNOUNCE] Ima::DBI 0.25 and Class::DBI 0.26
[email protected] (Michael G Schwern)
| Newsgroups | perl.dbi.announce |
|---|---|
| Message-ID | <[email protected]> |
Ima::DBI 0.25 and Class::DBI 0.26 have just gone up to CPAN.
The big change here is rudimentary support for transactions in the
form of dbi_commit() and dbi_rollback.
Changes to Class::DBI
0.26 Mon Apr 9 14:32:17 BST 2001
- Class->columns('All', @cols) now assumes the first column to be
your primary.
- Class->columns('Essential', @cols) now automatically includes
the primary column.
* move() was broken. Works and tested.
- Updated our base requirement to get at its bugfix
- Updated our Ima::DBI requirement to get at commit() and rollback()
* Documented construct()
* Added docs about transactions
* Added dbi_commit() and dbi_rollback()
- Added docs about Class::DBI and mod_perl
Changes to Ima::DBI
0.25 Sun Apr 8 23:55:15 BST 2001
- Fixed a minor bug with %% in SQL
- Cleaned up the docs a bit
* Added db_names() and db_handles()
* Added sql_names()
* Implemented commit() and rollback()
- Fixed minor bug in assertion on set_db()
NAME
Class::DBI - Simple Object Persistence
SYNOPSIS
package Film;
use base qw(Class::DBI);
# Tell Class::DBI a little about yourself.
Film->table('Movies');
Film->columns(All => qw( Title Director Rating NumExplodingSheep));
Film->set_db('Main', 'dbi:mysql', 'me', 'noneofyourgoddamnedbusiness',
{AutoCommit => 1});
#-- Meanwhile, in a nearby piece of code! --#
use Film;
# Create a new film entry for Bad Taste.
$btaste = Film->new({ Title => 'Bad Taste',
Director => 'Peter Jackson',
Rating => 'R',
NumExplodingSheep => 1
});
# Retrieve the 'Gone With The Wind' entry from the database.
my $gone = Film->retrieve('Gone With The Wind');
# Shocking new footage found reveals bizarre Scarlet/sheep scene!
$gone->NumExplodingSheep(5);
$gone->Rating('NC-17');
$gone->commit;
# Grab the 'Bladerunner' entry.
my $blrunner = Film->retrieve('Bladerunner');
# Make a copy of 'Bladerunner' and create an entry of the director's
# cut from it.
my $blrunner_dc = $blrunner->copy("Bladerunner: Director's Cut");
# Ishtar doesn't deserve an entry anymore.
Film->retrieve('Ishtar')->delete;
# Find all films which have a rating of PG.
@films = Film->search('Rating', 'PG');
# Find all films which were directed by Bob
@films = Film->search_like('Director', 'Bob %');
DESCRIPTION
I hate SQL. You hate SQL. We all hate SQL. Alas, we often find the need
to make our objects persistant and like it or not an SQL database is
usually the most flexible solution.
This module is for setting up a reasonably efficient, reasonably simple,
reasonably extendable persistant object with as little SQL and DBI
knowledge as possible.
Its uses a scheme to automatically set up accessors for each data field
in your class. These accessors control access to the underlying
database.
<skipping straight to the bit about transactions>
Transactions
Class::DBI is just now becoming dimly aware of transactions as people
are starting to use it with PostgreSQL and Oracle. Class::DBI currently
works best with DBI's AutoCommit turned on, however I am working on
making it seemless when AutoCommit is off.
When using transactions with Class::DBI you must be careful to remember
two things...
1 Your database handles are shared with possibly many other totally
unrelated classes. This means if you commit one class's handle you
might actually be committing another class's transaction as well.
2 A single class might have many database handles. Even worse, if
you're working with a subclass it might have handles you're not
aware of!
At the moment, all I can say about #1 is keep the scope of your
transactions small, preferably down to the scope of a single method. I
am working on a system to remove this problem.
For #2 we offer the following...
dbi_commit
my $rv = Class->dbi_commit;
my $rv = Class->dbi_commit(@db_names);
This commits the underlying handles associated with the Class. If
any of the commits fail, it returns false. Otherwise true.
If @db_names is not given it will commit all the database handles
associated with this class, otherwise it will only commit those
handles named (like 'Main' for instance).
This is different than commit() so we call it dbi_commit() to
disambiguate.
This is an alias to Ima::DBI->commit().
dbi_rollback
Class->dbi_rollback;
Class->dbi_rollback(@db_names);
Like dbi_commit() above, this rollsback all the database handles
associated with the Class.
This is an alias to Ima::DBI->rollback().
So how might you use this? At the moment, something like this...
eval {
# Change a bunch of things in memory
$obj->foo('bar');
$obj->this('that');
$obj->price(1456);
# Write them to the database.
$obj->commit;
};
if($@) {
# Ack! Something went wrong! Warn, rollback the transaction
# and flush out the object in memory as it may be in an odd state.
$obj->DBIwarn($obj->id, 'update price');
$obj->dbi_rollback;
$obj->rollback;
}
else {
# Everything's hoopy, commit the transaction.
$obj->dbi_commit;
}
Kinda clunky, but servicable. As I said, better things are on the way.
--
Michael G. Schwern <[email protected]> http://www.pobox.com/~schwern/
Perl6 Quality Assurance <[email protected]> Kwalitee Is Job One
Any sufficiently encapsulated hack is no longer a hack.