#------------------------------------------------------------
# Copyright (C) 2006 RoyaltyShare, Inc.   All Rights Reserved
# $Id$
#------------------------------------------------------------
package Common::DB::AutoLock;

use strict;
use warnings;

use Carp;
use lib '/app/tools/common/lib';
use Common::RSDB;
use Common::RSApp;
use Common::Assert;

# This class implements an 'autolocker' object.
# When instantiated (being passed a RSDB reference, and a list of table names), it will
# obtain a lock on those tables (blocking until the lock is obtained).
# When the object goes out of scope, the lock is released.
#
# This scheme means that:
# - you don't have to remember to explicitly unlock - this object does that for you.
# - the lock will be released even if an exception is thrown.
#

# !!! Note that there are currently some interesting constraints on how this works.
# !!! For one thing, mysql does not like 'compound statement' when there is a lock held
# !!! on a table. So, a 'select * from table where priority = (select MAX(priority) from table)' type
# !!! query is not going to work.

sub new {
    my ( $class, $db, @tables ) = @_;

    my $self = bless {}, $class;

    my @lockStrings;
    foreach my $table (@tables) {
        push @lockStrings, "$table WRITE";
    }
    my $lockStatement = "LOCK TABLES " . join( ",", @lockStrings );

    $self->{dbo} = $db;

    $self->{dbo}->DoCmd($lockStatement);

    return $self;
}

sub DESTROY {
    my ($self) = @_;
    $self->{dbo}->DoCmd('UNLOCK TABLES');
}

###
1;    #
###
