# # DESCRIPTION # PerlORM - Object relational mapper (ORM) for Perl. PerlORM is Perl # library that implements object-relational mapping. Its features are # much similar to those of Java's Hibernate library, but interface is # much different and easier to use. # # AUTHOR # Alexey V. Akimov # # COPYRIGHT # Copyright (C) 2005-2006 Alexey V. Akimov # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # package ORM::Ta; $VERSION = 0.8; my $die; my $die_eval; my $die_handler_enabled; my $old_die_handler; sub new { my $class = shift; my %arg = @_; my $self = bless {}, $class; unless( $arg{class}->_current_transaction ) { $die = undef; $self->{class} = $arg{class}; $self->{error} = $arg{error} || ORM::Error->new; $self->{eval} = $^S; unless( $die_handler_enabled ) { $die_handler_enabled = 1; $old_die_handler = $::SIG{__DIE__}; $::SIG{__DIE__} = \&die_handler; } unless( $self->{error}->fatal ) { my $error = ORM::Error->new; $self->{class}->_db->begin_transaction( error=>$error ); $self->{class}->_current_transaction( 1 ); if( $error->fatal ) { $self->{error}->add( error=>$error ); $self->{not_started} = 1; } } } return $self; } sub DESTROY { my $self = shift; $self->{class} && $self->{class}->_current_transaction( undef ); if( $self->{not_started} || !$self->{class} ) { # nothing to do } elsif( $die && $die_eval eq $self->{eval} ) { $die = undef; $self->{error}->add_fatal( "Transaction rolled back because of thrown exception" ); $self->{class}->_db->rollback_transaction( error=>$self->{error} ); } elsif( $self->{error}->fatal ) { $self->{class}->_db->rollback_transaction( error=>$self->{error} ); } else { $self->{class}->_db->commit_transaction( error=>$self->{error} ); } } sub die_handler { $die = 1; $die_eval = $^S; $old_die_handler && &{$old_die_handler}( @_ ); } 1;